Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
575 changes: 541 additions & 34 deletions demo/package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
"@sveltejs/adapter-auto": "^6.0.0",
"@sveltejs/kit": "^2.22.0",
"@sveltejs/vite-plugin-svelte": "^6.0.0",
"sass": "^1.93.2",
"svelte": "^5.39.6",
"svelte-check": "^4.0.0",
"typescript": "^5.0.0",
"vite": "^7.0.4"
},
"dependencies": {
"@wjfe/n-savant": "^0.12.0",
"@wjfe/n-savant-sk": "file:../wjfe-n-savant-sk-0.1.0.tgz"
}
}
31 changes: 31 additions & 0 deletions demo/src/lib/Card.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<script lang="ts">
import type { Snippet } from "svelte";

type Props = {
children?: Snippet;
header?: Snippet | string;
footer?: Snippet;
};

let { children, header, footer }: Props = $props();
</script>

<div class="card">
{#if header}
<header class="card-header">
{#if typeof header === 'string'}
<p class="card-header-title">{header}</p>
{:else}
{@render header?.()}
{/if}
</header>
{/if}
<div class="card-content">
{@render children?.()}
</div>
{#if footer}
<footer class="card-footer">
{@render footer?.()}
</footer>
{/if}
</div>
37 changes: 37 additions & 0 deletions demo/src/lib/NavBar.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<script lang="ts">
import theme from '$lib/state/theme.svelte.js';
import { calculateSkHref } from "@wjfe/n-savant-sk";

</script>
<nav class="has-background-info-light is-flex is-flex-direction-row is-align-items-center is-justify-content-space-between">
<ul>
<li><a href={calculateSkHref({ preserveQuery: true }, "/")}>Home</a></li>
<li><a href={calculateSkHref({ preserveQuery: true }, "/demo")}>Start Demo</a></li>
</ul>
<div>
<select bind:value={theme.current} class="select">
<option value="light">Light</option>
<option value="dark">Dark</option>
<option value="system">System</option>
</select>
</div>
</nav>

<style>
nav {
padding: 1rem;
border-bottom: 1px solid #dee2e6;
}

ul {
list-style: none;
display: flex;
gap: 1rem;
margin: 0;
padding: 0;
}

li {
margin: 0;
}
</style>
17 changes: 17 additions & 0 deletions demo/src/lib/bulma/Button.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<script lang="ts">
import type { Snippet } from "svelte";
import type { HTMLButtonAttributes } from "svelte/elements";
import type { IsColor } from "./common";

type Props = Omit<HTMLButtonAttributes, 'type'> & {
type?: HTMLButtonAttributes['type'];
isColor?: IsColor;
children?: Snippet;
};

let { type = 'button', isColor, children, class: cssClass, ...restProps }: Props = $props();
</script>

<button {type} class={['button', cssClass, isColor]} {...restProps}>
{@render children?.()}
</button>
15 changes: 15 additions & 0 deletions demo/src/lib/bulma/Content.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import type { Snippet } from "svelte";
import type { HTMLAttributes } from "svelte/elements";

type Props = HTMLAttributes<HTMLElement> & {
tag?: string;
children?: Snippet;
};

let { tag = "div", children, class: cssClass, ...restProps }: Props = $props();
</script>

<svelte:element this={tag} class={['content', cssClass]} {...restProps}>
{@render children?.()}
</svelte:element>
21 changes: 21 additions & 0 deletions demo/src/lib/bulma/Hero.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script lang="ts">
import type { Snippet } from "svelte";
import type { ClassValue, HTMLAttributes } from "svelte/elements";
import { type IsColor, type IsSize } from "./common";

type Props = HTMLAttributes<HTMLElement> & {
children?: Snippet;
tag?: string;
isColor?: IsColor;
isSize?: IsSize;
class?: ClassValue;
};

let { children, tag = 'section', isColor, isSize, class: cssClass, ...restProps }: Props = $props();
</script>

<svelte:element this={tag} class={['hero', isColor, isSize, cssClass]} {...restProps}>
<div class="hero-body">
{@render children?.()}
</div>
</svelte:element>
25 changes: 25 additions & 0 deletions demo/src/lib/bulma/Message.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<script lang="ts">
import type { HTMLAttributes } from "svelte/elements";
import type { IsColor } from "./common";
import type { Snippet } from "svelte";

type Props = HTMLAttributes<HTMLElement> & {
tag?: string;
isColor?: IsColor;
children?: Snippet;
header?: Snippet;
};

let { tag, isColor, children, header, class: cssClass, ...restProps }: Props = $props();
</script>

<svelte:element this={tag ?? 'article'} class={['message', isColor]} {...restProps}>
{#if header}
<div class="message-header">
{@render header?.()}
</div>
{/if}
<div class="message-body">
{@render children?.()}
</div>
</svelte:element>
21 changes: 21 additions & 0 deletions demo/src/lib/bulma/Notification.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<script lang="ts">
import type { Snippet } from "svelte";
import type { HTMLAttributes } from "svelte/elements";
import type { IsColor } from "./common";

type Props = HTMLAttributes<HTMLDivElement> & {
isColor?: IsColor;
children?: Snippet;
isCloseable?: boolean;
onClose?: () => void;
};

let { isColor, children, isCloseable = false, onClose, class: cssClass, ...restProps }: Props = $props();
</script>

<div class={['notification', isColor, cssClass]} {...restProps}>
{#if isCloseable}
<button class="delete" aria-label="close" onclick={onClose}></button>
{/if}
{@render children?.()}
</div>
15 changes: 15 additions & 0 deletions demo/src/lib/bulma/Section.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script lang="ts">
import type { ClassValue, HTMLAttributes } from 'svelte/elements';
import type { Snippet } from 'svelte';

type Props = HTMLAttributes<HTMLElement> & {
children?: Snippet;
tag?: string;
class?: ClassValue;
};
let { children, tag = 'section', class: cssClass, ...restProps }: Props = $props();
</script>

<svelte:element this={tag} class={['section', cssClass]} {...restProps}>
{@render children?.()}
</svelte:element>
16 changes: 16 additions & 0 deletions demo/src/lib/bulma/Tabs.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<script lang="ts">
import type { Snippet } from "svelte";
import type { HTMLAttributes } from "svelte/elements";

type Props = HTMLAttributes<HTMLDivElement> & {
children?: Snippet;
};

let { children, class: cssClass, ...restProps }: Props = $props();
</script>

<div class={["tabs", cssClass]} {...restProps}>
<ul role="tablist">
{@render children?.()}
</ul>
</div>
27 changes: 27 additions & 0 deletions demo/src/lib/bulma/common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export const isColors = Object.freeze({
hidden: 'is-hidden',
primary: 'is-primary',
link: 'is-link',
info: 'is-info',
success: 'is-success',
warning: 'is-warning',
danger: 'is-danger',
white: 'is-white',
light: 'is-light',
dark: 'is-dark',
black: 'is-black',
text: 'is-text',
ghost: 'is-ghost',
});

export type IsColor = (typeof isColors)[keyof typeof isColors];

export const isSizes = Object.freeze({
small: 'is-small',
medium: 'is-medium',
large: 'is-large',
halfHeight: 'is-halfheight',
fullHeight: 'is-fullheight',
});

export type IsSize = (typeof isSizes)[keyof typeof isSizes];
49 changes: 49 additions & 0 deletions demo/src/lib/demo/Demo.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<script lang="ts">
import Section from '$lib/bulma/Section.svelte';
import Tabs from '$lib/bulma/Tabs.svelte';
import { activeBehavior, Link, LinkContext, location, Route, Router, type Hash, type RouteStatus } from '@wjfe/n-savant';
import Intro from './Intro.svelte';
import Struct from './Struct.svelte';
import InCode from './InCode.svelte';
import FallbackContent from './FallbackContent.svelte';

type Props = {
hash: Exclude<Hash, false>;
}
let {
hash,
}: Props = $props();

let hashPath = $derived(hash === true ? location.hashPaths.single : location.hashPaths[hash] );
</script>

<Section>
<header class="is-flex is-justify-content-space-between">
<span><strong>Path (Sveltekit):</strong> <code>{location.url.pathname}</code></span>
<span><strong>Hash path:</strong> <code>{hashPath}</code></span>
</header>
<div class="box">
<Router {hash}>
{#snippet children(state, rs)}
<Tabs>
<LinkContext prependBasePath>
<li role="tab" {@attach activeBehavior(rs, { key: 'intro', class: 'is-active' })}><Link {hash} href="/">Intro</Link></li>
<li role="tab" {@attach activeBehavior(rs, { key: 'struct', class: 'is-active' })}><Link {hash} href="/struct">Structure</Link></li>
<li role="tab" {@attach activeBehavior(rs, { key: 'in-code', class: 'is-active' })}><Link {hash} href="/in-code">In Code</Link></li>
<li role="tab" {@attach activeBehavior(rs, { key: '404', class: 'is-active' })}><Link {hash} href="/404">404</Link></li>
</LinkContext>
</Tabs>
<Route {hash} key="intro" path="/">
<Intro />
</Route>
<Route {hash} key="struct" path="/struct">
<Struct />
</Route>
<Route {hash} key="in-code" path="/in-code">
<InCode />
</Route>
<FallbackContent {hash} />
{/snippet}
</Router>
</div>
</Section>
29 changes: 29 additions & 0 deletions demo/src/lib/demo/FallbackContent.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script lang="ts">
import Content from '$lib/bulma/Content.svelte';
import type { Hash } from '@wjfe/n-savant';
import { SkFallback } from '@wjfe/n-savant-sk';

type Props = {
hash: Hash;
};

let {
hash,
}: Props = $props();
</script>

<SkFallback {hash}>
{#snippet children(state, rs)}
<Content role="tabpanel">
<h3>Fallback Content</h3>
<p>
Oops! This is fallback content that is being rendered because no routes in the parent
<code>&lt;Router&gt;</code> component are currently matched.
</p>
<p>
The following is the current route status object from the parent router:
</p>
<pre>{JSON.stringify(rs, null, 2)}</pre>
</Content>
{/snippet}
</SkFallback>
28 changes: 28 additions & 0 deletions demo/src/lib/demo/InCode.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<script lang="ts">
import Content from "$lib/bulma/Content.svelte";

</script>

<Content role="tabpanel">
<h3>Structure In Code</h3>
<pre><code>&lt;Router basePath="/start"&gt;
{'{'}#snippet children(state, rs){'}'}
&lt;Tabs&gt;
&lt;LinkContext prependBasePath&gt;
&lt;li class={'{'}{'{'} 'is-active': rs['intro']?.match {'}'}{'}'}&gt;&lt;Link href="/"&gt;Intro&lt;/Link&gt;&lt;/li&gt;
&lt;li class={'{'}{'{'} 'is-active': rs['struct']?.match {'}'}{'}'}&gt;&lt;Link href="/struct"&gt;Structure&lt;/Link&gt;&lt;/li&gt;
&lt;li class={'{'}{'{'} 'is-active': rs['in-code']?.match {'}'}{'}'}&gt;&lt;Link href="/in-code"&gt;In Code&lt;/Link&gt;&lt;/li&gt;
&lt;/LinkContext&gt;
&lt;/Tabs&gt;
&lt;Route key="intro" path="/"&gt;
&lt;Intro /&gt;
&lt;/Route&gt;
&lt;Route key="struct" path="/struct"&gt;
&lt;Struct /&gt;
&lt;/Route&gt;
&lt;Route key="in-code" path="/in-code"&gt;
&lt;InCode /&gt;
&lt;/Route&gt;
{'{/'}snippet{'}'}
&lt;/Router&gt;</code></pre>
</Content>
Loading