Skip to content

Commit 63de7ad

Browse files
authored
chore(demo): Improve demo (#10)
1 parent 6dded4c commit 63de7ad

File tree

15 files changed

+285
-36
lines changed

15 files changed

+285
-36
lines changed

demo/package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

demo/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"vite": "^7.0.4"
2323
},
2424
"dependencies": {
25+
"@fortawesome/fontawesome-free": "^7.1.0",
2526
"@wjfe/n-savant": "^0.12.0",
2627
"@wjfe/n-savant-sk": "file:../wjfe-n-savant-sk-0.1.0.tgz"
2728
}

demo/src/lib/NavBar.svelte

Lines changed: 63 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,68 @@
11
<script lang="ts">
2-
import theme from '$lib/state/theme.svelte.js';
3-
import { calculateSkHref } from "@wjfe/n-savant-sk";
2+
import { NavBar } from '$lib/bulma/NavBar';
3+
import { calculateSkHref } from '@wjfe/n-savant-sk';
4+
import ThemePicker from './ThemePicker.svelte';
5+
import logo from '@wjfe/n-savant/logo64';
6+
import { isSkRouteActive } from './isSkRouteActive';
7+
import { location } from '@wjfe/n-savant';
8+
import theme from './state/theme.svelte';
49
5-
</script>
6-
<nav class="has-background-info-light is-flex is-flex-direction-row is-align-items-center is-justify-content-space-between">
7-
<ul>
8-
<li><a href={calculateSkHref({ preserveQuery: true }, "/")}>Home</a></li>
9-
<li><a href={calculateSkHref({ preserveQuery: true }, "/demo")}>Start Demo</a></li>
10-
</ul>
11-
<div>
12-
<select bind:value={theme.current} class="select">
13-
<option value="light">Light</option>
14-
<option value="dark">Dark</option>
15-
<option value="system">System</option>
16-
</select>
17-
</div>
18-
</nav>
19-
20-
<style>
21-
nav {
22-
padding: 1rem;
23-
border-bottom: 1px solid #dee2e6;
24-
}
10+
const allPositions = [undefined, 'top', 'bottom'] as const;
11+
let posIndex = $state(0);
12+
const posIconData = [
13+
{
14+
icon: 'fa-circle-dot',
15+
title: 'Remove fixed position',
16+
},
17+
{
18+
icon: 'fa-chevron-up',
19+
title: 'Fix to top',
20+
},
21+
{
22+
icon: 'fa-chevron-down',
23+
title: 'Fix to bottom',
24+
},
25+
];
26+
let iconDataIndex = $derived((posIndex + 1) % allPositions.length);
27+
let navbarBg = $derived(theme.current === 'dark' ? 'is-dark' : 'is-light');
2528
26-
ul {
27-
list-style: none;
28-
display: flex;
29-
gap: 1rem;
30-
margin: 0;
31-
padding: 0;
29+
function nextPosition() {
30+
posIndex = (posIndex + 1) % allPositions.length;
3231
}
32+
</script>
3333

34-
li {
35-
margin: 0;
36-
}
37-
</style>
34+
<NavBar.Root fixed={allPositions[posIndex]} class={navbarBg} style="padding-top: 0.5rem; padding-bottom: 0.5rem;">
35+
<NavBar.Brand>
36+
<NavBar.Item>
37+
<img src={logo} alt="Logo" />
38+
</NavBar.Item>
39+
<NavBar.Item>
40+
<h1 class="title is-4">@wjfe/n-savant-sk Demo</h1>
41+
</NavBar.Item>
42+
</NavBar.Brand>
43+
<NavBar.Burger />
44+
<NavBar.Menu>
45+
<NavBar.Item tag="a" isTab isActive={isSkRouteActive('/')} href={calculateSkHref({ preserveQuery: true }, '/')}
46+
>Home</NavBar.Item
47+
>
48+
<NavBar.Item
49+
tag="a"
50+
isTab
51+
isActive={isSkRouteActive('/demo')}
52+
href={calculateSkHref({ preserveQuery: true }, '/demo')}>Start Demo</NavBar.Item
53+
>
54+
{#snippet end()}
55+
<NavBar.Item>
56+
Sveltekit Path: <code>{location.url.pathname}</code>
57+
</NavBar.Item>
58+
<NavBar.Item>
59+
<button type="button" title={posIconData[iconDataIndex].title} onclick={nextPosition}>
60+
<i class={['fas', posIconData[iconDataIndex].icon]}></i>
61+
</button>
62+
</NavBar.Item>
63+
<NavBar.Item>
64+
<ThemePicker />
65+
</NavBar.Item>
66+
{/snippet}
67+
</NavBar.Menu>
68+
</NavBar.Root>

demo/src/lib/ThemePicker.svelte

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<script lang="ts">
2+
import theme from "$lib/state/theme.svelte.js";
3+
import { fly, slide } from "svelte/transition";
4+
5+
const themeIcons = {
6+
light: "fa-sun",
7+
dark: "fa-moon",
8+
system: "fa-desktop",
9+
};
10+
11+
let label = $derived(`${theme.current} theme`);
12+
</script>
13+
14+
<button onclick={() => theme.nextTheme()} aria-label={label} title={label}>
15+
{#key theme.current}
16+
<i class={['fas', themeIcons[theme.current]]} transition:fly={{ y: 30, duration: 600 }}></i>
17+
{/key}
18+
</button>
19+
20+
<style>
21+
button {
22+
display: grid;
23+
padding: 0.7em;
24+
& > i {
25+
grid-area: 1 / 1 / 2 / 2;
26+
}
27+
}
28+
</style>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script lang="ts">
2+
import type { HTMLAttributes } from "svelte/elements";
3+
4+
type Props = HTMLAttributes<HTMLDivElement>;
5+
6+
let {
7+
class: cssClass,
8+
children,
9+
...restProps
10+
}: Props = $props();
11+
</script>
12+
13+
<div class={["navbar-brand", cssClass]} {...restProps}>
14+
{@render children?.()}
15+
</div>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<script lang="ts">
2+
import type { HTMLButtonAttributes } from "svelte/elements";
3+
4+
type Props = Omit<HTMLButtonAttributes, 'children'> & {
5+
lineCount?: number;
6+
};
7+
8+
let {
9+
lineCount = 4,
10+
class: cssClass,
11+
...restProps
12+
}: Props = $props();
13+
</script>
14+
15+
<button
16+
class={["navbar-burger", cssClass]}
17+
{...restProps}
18+
aria-label="menu"
19+
aria-expanded="false"
20+
>
21+
{#each { length: lineCount } as _, i}
22+
<span aria-hidden="true"></span>
23+
{/each}
24+
</button>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script lang="ts" generics="T extends 'a' | 'div' = 'div'">
2+
import type { HTMLAttributes, HTMLAnchorAttributes } from 'svelte/elements';
3+
4+
type Props = (T extends 'a' ? HTMLAnchorAttributes : HTMLAttributes<HTMLDivElement>) & {
5+
tag?: T;
6+
isActive?: boolean;
7+
isTab?: boolean;
8+
};
9+
10+
let { tag = 'div' as T, isActive, isTab, class: cssClass, children, ...restProps }: Props = $props();
11+
</script>
12+
13+
<svelte:element this={tag} class={['navbar-item', cssClass, { 'is-active': isActive, 'is-tab': isTab }]} {...restProps}>
14+
{@render children?.()}
15+
</svelte:element>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<script lang="ts">
2+
import type { HTMLAnchorAttributes } from "svelte/elements";
3+
4+
type Props = HTMLAnchorAttributes;
5+
6+
let {
7+
class: cssClass,
8+
children,
9+
...restProps
10+
}: Props = $props();
11+
</script>
12+
13+
<a class={['navbar-link', cssClass]} {...restProps}>
14+
{@render children?.()}
15+
</a>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script lang="ts">
2+
import type { Snippet } from "svelte";
3+
import type { HTMLAttributes } from "svelte/elements";
4+
5+
type Props = HTMLAttributes<HTMLDivElement> & {
6+
end?: Snippet;
7+
};
8+
9+
let {
10+
class: cssClass,
11+
end,
12+
children,
13+
...restProps
14+
}: Props = $props();
15+
</script>
16+
17+
<div class={["navbar-menu", cssClass]} {...restProps}>
18+
<div class="navbar-start">
19+
{@render children?.()}
20+
</div>
21+
{#if end}
22+
<div class="navbar-end">
23+
{@render end()}
24+
</div>
25+
{/if}
26+
</div>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<script lang="ts">
2+
import type { HTMLAttributes } from 'svelte/elements';
3+
4+
type Props = HTMLAttributes<HTMLElement> & {
5+
fixed?: 'top' | 'bottom' | undefined;
6+
transparent?: boolean;
7+
};
8+
9+
let { fixed, transparent, class: cssClass, children, ...restProps }: Props = $props();
10+
11+
$effect(() => {
12+
if (!fixed) {
13+
return;
14+
}
15+
const appliedClass = `has-navbar-fixed-${fixed}`;
16+
document.body.classList.add(appliedClass);
17+
return () => {
18+
document.body.classList.remove(appliedClass);
19+
};
20+
});
21+
</script>
22+
23+
<nav
24+
class={['navbar', { [`is-fixed-${fixed}`]: !!fixed, 'is-transparent': transparent }, cssClass]}
25+
{...restProps}
26+
>
27+
{@render children?.()}
28+
</nav>

0 commit comments

Comments
 (0)