@loidolt/theme-svelte 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/dist/components/Accordion.svelte +100 -0
- package/dist/components/Accordion.svelte.d.ts +50 -0
- package/dist/components/Alert.svelte +6 -3
- package/dist/components/Alert.svelte.d.ts +3 -2
- package/dist/components/AlertDialog.svelte +130 -0
- package/dist/components/AlertDialog.svelte.d.ts +35 -0
- package/dist/components/AppShell.svelte +2 -1
- package/dist/components/AppShell.svelte.d.ts +1 -0
- package/dist/components/Badge.svelte +9 -2
- package/dist/components/Badge.svelte.d.ts +2 -1
- package/dist/components/Brand.svelte +29 -15
- package/dist/components/Brand.svelte.d.ts +8 -4
- package/dist/components/Breadcrumbs.svelte +53 -0
- package/dist/components/Breadcrumbs.svelte.d.ts +18 -0
- package/dist/components/Button.svelte +43 -21
- package/dist/components/Button.svelte.d.ts +9 -4
- package/dist/components/Card.svelte +23 -5
- package/dist/components/Card.svelte.d.ts +11 -4
- package/dist/components/CodeBlock.svelte +55 -0
- package/dist/components/CodeBlock.svelte.d.ts +14 -0
- package/dist/components/CommentList.svelte +67 -0
- package/dist/components/CommentList.svelte.d.ts +53 -0
- package/dist/components/Dialog.svelte +25 -3
- package/dist/components/Dialog.svelte.d.ts +4 -1
- package/dist/components/Drawer.svelte +105 -0
- package/dist/components/Drawer.svelte.d.ts +31 -0
- package/dist/components/DropdownMenu.svelte +2 -2
- package/dist/components/DropdownMenu.svelte.d.ts +1 -1
- package/dist/components/EmptyState.svelte +40 -0
- package/dist/components/EmptyState.svelte.d.ts +19 -0
- package/dist/components/Fieldset.svelte +60 -0
- package/dist/components/Fieldset.svelte.d.ts +19 -0
- package/dist/components/FileInput.svelte +47 -0
- package/dist/components/FileInput.svelte.d.ts +15 -0
- package/dist/components/Filmstrip.svelte +72 -0
- package/dist/components/Filmstrip.svelte.d.ts +50 -0
- package/dist/components/FloatingBar.svelte +43 -0
- package/dist/components/FloatingBar.svelte.d.ts +16 -0
- package/dist/components/IconButton.svelte +1 -1
- package/dist/components/Input.svelte.d.ts +1 -1
- package/dist/components/ListRow.svelte +50 -0
- package/dist/components/ListRow.svelte.d.ts +18 -0
- package/dist/components/Marker.svelte +38 -0
- package/dist/components/Marker.svelte.d.ts +14 -0
- package/dist/components/NavMenu.svelte +6 -1
- package/dist/components/NavMenu.svelte.d.ts +2 -1
- package/dist/components/NumberField.svelte +12 -1
- package/dist/components/NumberField.svelte.d.ts +1 -1
- package/dist/components/Pagination.svelte +86 -0
- package/dist/components/Pagination.svelte.d.ts +22 -0
- package/dist/components/Popover.svelte +24 -3
- package/dist/components/Popover.svelte.d.ts +4 -1
- package/dist/components/RadioGroup.svelte.d.ts +2 -2
- package/dist/components/RecordStepper.svelte +58 -0
- package/dist/components/RecordStepper.svelte.d.ts +18 -0
- package/dist/components/SegmentedNav.svelte +53 -0
- package/dist/components/SegmentedNav.svelte.d.ts +22 -0
- package/dist/components/Select.svelte.d.ts +2 -2
- package/dist/components/Stat.svelte +41 -0
- package/dist/components/Stat.svelte.d.ts +17 -0
- package/dist/components/StatusDot.svelte +27 -0
- package/dist/components/StatusDot.svelte.d.ts +12 -0
- package/dist/components/SwatchGroup.svelte +69 -0
- package/dist/components/SwatchGroup.svelte.d.ts +44 -0
- package/dist/components/Switch.svelte +19 -0
- package/dist/components/Table.svelte +30 -3
- package/dist/components/Table.svelte.d.ts +13 -0
- package/dist/components/TableHeader.svelte +72 -0
- package/dist/components/TableHeader.svelte.d.ts +24 -0
- package/dist/components/Tabs.svelte +23 -5
- package/dist/components/Tabs.svelte.d.ts +4 -3
- package/dist/components/Textarea.svelte.d.ts +1 -1
- package/dist/components/ThemeToggle.svelte +133 -0
- package/dist/components/ThemeToggle.svelte.d.ts +20 -0
- package/dist/components/Thumbnail.svelte +51 -0
- package/dist/components/Thumbnail.svelte.d.ts +19 -0
- package/dist/components/ToggleGroup.svelte +107 -0
- package/dist/components/ToggleGroup.svelte.d.ts +46 -0
- package/dist/components/TooltipProvider.svelte +1 -0
- package/dist/components/Workspace.svelte +27 -6
- package/dist/components/Workspace.svelte.d.ts +12 -0
- package/dist/index.d.ts +29 -2
- package/dist/index.js +26 -1
- package/dist/media.svelte.d.ts +48 -0
- package/dist/media.svelte.js +69 -0
- package/dist/theme.svelte.d.ts +86 -0
- package/dist/theme.svelte.js +166 -0
- package/dist/toaster.svelte.d.ts +2 -0
- package/dist/toaster.svelte.js +51 -9
- package/dist/types.d.ts +21 -0
- package/package.json +10 -8
|
@@ -4,22 +4,32 @@
|
|
|
4
4
|
import type { ActionVariant, ControlSize } from '../types.js';
|
|
5
5
|
import { cx } from '../utils.js';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
7
|
+
interface CommonProps {
|
|
8
|
+
variant?: ActionVariant;
|
|
9
|
+
size?: ControlSize;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
loading?: boolean;
|
|
12
|
+
/** Visible text swapped in while loading. */
|
|
13
|
+
loadingText?: string;
|
|
14
|
+
/** Announced while loading when there is no visible `loadingText`. */
|
|
15
|
+
loadingLabel?: string;
|
|
16
|
+
class?: string;
|
|
17
|
+
children: Snippet;
|
|
18
|
+
ref?: HTMLButtonElement | HTMLAnchorElement | null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Discriminated on `href`: with it the component renders an `<a>` and accepts anchor
|
|
22
|
+
// attributes; without it, a `<button>` and button attributes. Button-only attributes
|
|
23
|
+
// (`formaction`, `type`, …) on an anchor are a type error instead of silent junk.
|
|
24
|
+
type Props = CommonProps &
|
|
25
|
+
(
|
|
26
|
+
| (Omit<HTMLAnchorAttributes, 'class' | 'type'> & {
|
|
27
|
+
/** Renders an `<a>` styled as a button. */
|
|
28
|
+
href: string;
|
|
29
|
+
type?: never;
|
|
30
|
+
})
|
|
31
|
+
| (Omit<HTMLButtonAttributes, 'class'> & { href?: never })
|
|
32
|
+
);
|
|
23
33
|
|
|
24
34
|
let {
|
|
25
35
|
variant = 'default',
|
|
@@ -38,7 +48,12 @@
|
|
|
38
48
|
}: Props = $props();
|
|
39
49
|
|
|
40
50
|
const classes = $derived(
|
|
41
|
-
cx(
|
|
51
|
+
cx(
|
|
52
|
+
'ldt-button',
|
|
53
|
+
variant !== 'default' && `ldt-button--${variant}`,
|
|
54
|
+
size !== 'md' && `ldt-button--${size}`,
|
|
55
|
+
className
|
|
56
|
+
)
|
|
42
57
|
);
|
|
43
58
|
const inert = $derived(disabled || loading);
|
|
44
59
|
|
|
@@ -47,7 +62,8 @@
|
|
|
47
62
|
event.preventDefault();
|
|
48
63
|
return;
|
|
49
64
|
}
|
|
50
|
-
|
|
65
|
+
// The union collapses the handler's currentTarget; the branch that rendered us fixes it.
|
|
66
|
+
(onclick as ((event: MouseEvent) => void) | undefined)?.(event);
|
|
51
67
|
}
|
|
52
68
|
</script>
|
|
53
69
|
|
|
@@ -69,17 +85,23 @@
|
|
|
69
85
|
aria-disabled={inert || undefined}
|
|
70
86
|
aria-busy={loading || undefined}
|
|
71
87
|
tabindex={inert ? -1 : undefined}
|
|
72
|
-
{...rest}
|
|
88
|
+
{...rest as HTMLAnchorAttributes}
|
|
73
89
|
onclick={handleClick}>{@render content()}</a
|
|
74
90
|
>
|
|
75
91
|
{:else}
|
|
92
|
+
<!--
|
|
93
|
+
`loading` uses `aria-disabled` + a click guard instead of native `disabled`: disabling
|
|
94
|
+
the control mid-interaction would drop keyboard focus to <body> and can hide the busy
|
|
95
|
+
announcement from assistive tech. Explicit `disabled` keeps native semantics.
|
|
96
|
+
-->
|
|
76
97
|
<button
|
|
77
98
|
bind:this={ref}
|
|
78
99
|
{type}
|
|
79
100
|
class={classes}
|
|
80
|
-
disabled={
|
|
101
|
+
disabled={disabled || undefined}
|
|
102
|
+
aria-disabled={loading && !disabled ? true : undefined}
|
|
81
103
|
aria-busy={loading || undefined}
|
|
82
|
-
{...rest}
|
|
104
|
+
{...rest as HTMLButtonAttributes}
|
|
83
105
|
onclick={handleClick}>{@render content()}</button
|
|
84
106
|
>
|
|
85
107
|
{/if}
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
|
3
3
|
import type { ActionVariant, ControlSize } from '../types.js';
|
|
4
|
-
|
|
4
|
+
interface CommonProps {
|
|
5
5
|
variant?: ActionVariant;
|
|
6
6
|
size?: ControlSize;
|
|
7
|
-
/** Renders an `<a>` styled as a button. */
|
|
8
|
-
href?: string;
|
|
9
7
|
disabled?: boolean;
|
|
10
8
|
loading?: boolean;
|
|
11
9
|
/** Visible text swapped in while loading. */
|
|
@@ -15,7 +13,14 @@ type Props = HTMLButtonAttributes & HTMLAnchorAttributes & {
|
|
|
15
13
|
class?: string;
|
|
16
14
|
children: Snippet;
|
|
17
15
|
ref?: HTMLButtonElement | HTMLAnchorElement | null;
|
|
18
|
-
}
|
|
16
|
+
}
|
|
17
|
+
type Props = CommonProps & ((Omit<HTMLAnchorAttributes, 'class' | 'type'> & {
|
|
18
|
+
/** Renders an `<a>` styled as a button. */
|
|
19
|
+
href: string;
|
|
20
|
+
type?: never;
|
|
21
|
+
}) | (Omit<HTMLButtonAttributes, 'class'> & {
|
|
22
|
+
href?: never;
|
|
23
|
+
}));
|
|
19
24
|
declare const Button: import("svelte").Component<Props, {}, "ref">;
|
|
20
25
|
type Button = ReturnType<typeof Button>;
|
|
21
26
|
export default Button;
|
|
@@ -1,22 +1,36 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import type { HTMLAnchorAttributes, HTMLAttributes } from 'svelte/elements';
|
|
4
4
|
import type { HeadingLevel } from '../types.js';
|
|
5
5
|
import { cx } from '../utils.js';
|
|
6
6
|
|
|
7
|
-
interface
|
|
7
|
+
interface CommonProps {
|
|
8
8
|
title?: string;
|
|
9
9
|
description?: string;
|
|
10
10
|
header?: Snippet;
|
|
11
11
|
children: Snippet;
|
|
12
12
|
footer?: Snippet;
|
|
13
|
-
/** Root element. `div` by default — use `article` only for self-contained content. */
|
|
14
|
-
as?: 'div' | 'article' | 'section' | 'li';
|
|
15
13
|
headingLevel?: HeadingLevel;
|
|
16
14
|
class?: string;
|
|
17
15
|
ref?: HTMLElement | null;
|
|
18
16
|
}
|
|
19
17
|
|
|
18
|
+
// Discriminated on `href`, like Button: with it the whole card is an anchor and accepts
|
|
19
|
+
// anchor attributes; without it the root stays a plain container element.
|
|
20
|
+
type Props = CommonProps &
|
|
21
|
+
(
|
|
22
|
+
| (Omit<HTMLAnchorAttributes, 'class'> & {
|
|
23
|
+
/** Renders the card as one block-level link. */
|
|
24
|
+
href: string;
|
|
25
|
+
as?: never;
|
|
26
|
+
})
|
|
27
|
+
| (Omit<HTMLAttributes<HTMLElement>, 'class'> & {
|
|
28
|
+
href?: never;
|
|
29
|
+
/** Root element. `div` by default — use `article` only for self-contained content. */
|
|
30
|
+
as?: 'div' | 'article' | 'section' | 'li';
|
|
31
|
+
})
|
|
32
|
+
);
|
|
33
|
+
|
|
20
34
|
let {
|
|
21
35
|
title,
|
|
22
36
|
description,
|
|
@@ -24,14 +38,18 @@
|
|
|
24
38
|
children,
|
|
25
39
|
footer,
|
|
26
40
|
as = 'div',
|
|
41
|
+
href,
|
|
27
42
|
headingLevel = 3,
|
|
28
43
|
class: className,
|
|
29
44
|
ref = $bindable(null),
|
|
30
45
|
...rest
|
|
31
46
|
}: Props = $props();
|
|
47
|
+
|
|
48
|
+
const element = $derived(href ? 'a' : as);
|
|
49
|
+
const classes = $derived(cx('ldt-card', href && 'ldt-card--link', className));
|
|
32
50
|
</script>
|
|
33
51
|
|
|
34
|
-
<svelte:element this={
|
|
52
|
+
<svelte:element this={element} bind:this={ref} class={classes} {href} {...rest}>
|
|
35
53
|
{#if header || title || description}<header class="ldt-card__header">
|
|
36
54
|
{#if header}{@render header()}{:else}{#if title}<svelte:element
|
|
37
55
|
this={`h${headingLevel}`}
|
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
|
-
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
import type { HTMLAnchorAttributes, HTMLAttributes } from 'svelte/elements';
|
|
3
3
|
import type { HeadingLevel } from '../types.js';
|
|
4
|
-
interface
|
|
4
|
+
interface CommonProps {
|
|
5
5
|
title?: string;
|
|
6
6
|
description?: string;
|
|
7
7
|
header?: Snippet;
|
|
8
8
|
children: Snippet;
|
|
9
9
|
footer?: Snippet;
|
|
10
|
-
/** Root element. `div` by default — use `article` only for self-contained content. */
|
|
11
|
-
as?: 'div' | 'article' | 'section' | 'li';
|
|
12
10
|
headingLevel?: HeadingLevel;
|
|
13
11
|
class?: string;
|
|
14
12
|
ref?: HTMLElement | null;
|
|
15
13
|
}
|
|
14
|
+
type Props = CommonProps & ((Omit<HTMLAnchorAttributes, 'class'> & {
|
|
15
|
+
/** Renders the card as one block-level link. */
|
|
16
|
+
href: string;
|
|
17
|
+
as?: never;
|
|
18
|
+
}) | (Omit<HTMLAttributes<HTMLElement>, 'class'> & {
|
|
19
|
+
href?: never;
|
|
20
|
+
/** Root element. `div` by default — use `article` only for self-contained content. */
|
|
21
|
+
as?: 'div' | 'article' | 'section' | 'li';
|
|
22
|
+
}));
|
|
16
23
|
declare const Card: import("svelte").Component<Props, {}, "ref">;
|
|
17
24
|
type Card = ReturnType<typeof Card>;
|
|
18
25
|
export default Card;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
import { cx } from '../utils.js';
|
|
4
|
+
|
|
5
|
+
interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
6
|
+
code: string;
|
|
7
|
+
/** One click/tap selects the whole value. On by default — this block exists for copying. */
|
|
8
|
+
selectable?: boolean;
|
|
9
|
+
copyable?: boolean;
|
|
10
|
+
copyLabel?: string;
|
|
11
|
+
copiedLabel?: string;
|
|
12
|
+
class?: string;
|
|
13
|
+
ref?: HTMLDivElement | null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let {
|
|
17
|
+
code,
|
|
18
|
+
selectable = true,
|
|
19
|
+
copyable = false,
|
|
20
|
+
copyLabel = 'Copy',
|
|
21
|
+
copiedLabel = 'Copied',
|
|
22
|
+
class: className,
|
|
23
|
+
ref = $bindable(null),
|
|
24
|
+
...rest
|
|
25
|
+
}: Props = $props();
|
|
26
|
+
|
|
27
|
+
let copied = $state(false);
|
|
28
|
+
let resetTimer: ReturnType<typeof setTimeout> | undefined;
|
|
29
|
+
|
|
30
|
+
async function copy() {
|
|
31
|
+
try {
|
|
32
|
+
await navigator.clipboard.writeText(code);
|
|
33
|
+
copied = true;
|
|
34
|
+
clearTimeout(resetTimer);
|
|
35
|
+
resetTimer = setTimeout(() => (copied = false), 2000);
|
|
36
|
+
} catch {
|
|
37
|
+
// Clipboard unavailable (permissions, insecure context) — the text stays selectable.
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
</script>
|
|
41
|
+
|
|
42
|
+
<div
|
|
43
|
+
bind:this={ref}
|
|
44
|
+
class={cx('ldt-code-block', selectable && 'ldt-code-block--selectable', className)}
|
|
45
|
+
{...rest}
|
|
46
|
+
>
|
|
47
|
+
<code class="ldt-code-block__code">{code}</code>
|
|
48
|
+
{#if copyable}
|
|
49
|
+
<button type="button" class="ldt-button ldt-button--quiet ldt-button--sm" onclick={copy}>
|
|
50
|
+
{copied ? copiedLabel : copyLabel}
|
|
51
|
+
</button>
|
|
52
|
+
<!-- Persistently mounted so the announcement fires when the content changes. -->
|
|
53
|
+
<span class="ldt-sr-only" role="status">{copied ? copiedLabel : ''}</span>
|
|
54
|
+
{/if}
|
|
55
|
+
</div>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
2
|
+
interface Props extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {
|
|
3
|
+
code: string;
|
|
4
|
+
/** One click/tap selects the whole value. On by default — this block exists for copying. */
|
|
5
|
+
selectable?: boolean;
|
|
6
|
+
copyable?: boolean;
|
|
7
|
+
copyLabel?: string;
|
|
8
|
+
copiedLabel?: string;
|
|
9
|
+
class?: string;
|
|
10
|
+
ref?: HTMLDivElement | null;
|
|
11
|
+
}
|
|
12
|
+
declare const CodeBlock: import("svelte").Component<Props, {}, "ref">;
|
|
13
|
+
type CodeBlock = ReturnType<typeof CodeBlock>;
|
|
14
|
+
export default CodeBlock;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<script lang="ts" generics="T extends string = string">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import Marker from './Marker.svelte';
|
|
5
|
+
import { cx } from '../utils.js';
|
|
6
|
+
|
|
7
|
+
interface CommentListItem<V extends string = string> {
|
|
8
|
+
id: V;
|
|
9
|
+
author: string;
|
|
10
|
+
/** Preformatted suffix after the author — timestamps, origins. The theme adds nothing. */
|
|
11
|
+
meta?: string;
|
|
12
|
+
body: string;
|
|
13
|
+
/** Renders a numbered Marker when set — ties the comment to a pin on a canvas. */
|
|
14
|
+
marker?: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface Props extends Omit<HTMLAttributes<HTMLUListElement>, 'children'> {
|
|
18
|
+
items: CommentListItem<T>[];
|
|
19
|
+
/** Highlighted item; kept in view as it changes. */
|
|
20
|
+
activeId?: T | null;
|
|
21
|
+
/** Fired when a markered item is hovered — for syncing the matching canvas pin. */
|
|
22
|
+
onItemHover?: (id: T) => void;
|
|
23
|
+
/** Full row-content override. */
|
|
24
|
+
item?: Snippet<[CommentListItem<T>]>;
|
|
25
|
+
class?: string;
|
|
26
|
+
itemClass?: string;
|
|
27
|
+
ref?: HTMLUListElement | null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let {
|
|
31
|
+
items,
|
|
32
|
+
activeId = $bindable(null),
|
|
33
|
+
onItemHover,
|
|
34
|
+
item,
|
|
35
|
+
class: className,
|
|
36
|
+
itemClass,
|
|
37
|
+
ref = $bindable(null),
|
|
38
|
+
...rest
|
|
39
|
+
}: Props = $props();
|
|
40
|
+
|
|
41
|
+
let rows = $state<Record<string, HTMLLIElement | null>>({});
|
|
42
|
+
|
|
43
|
+
$effect(() => {
|
|
44
|
+
if (activeId) rows[activeId]?.scrollIntoView({ block: 'nearest' });
|
|
45
|
+
});
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<ul bind:this={ref} class={cx('ldt-comment-list', className)} {...rest}>
|
|
49
|
+
{#each items as entry (entry.id)}
|
|
50
|
+
<li
|
|
51
|
+
class={cx('ldt-comment', activeId === entry.id && 'ldt-comment--active', itemClass)}
|
|
52
|
+
bind:this={rows[entry.id]}
|
|
53
|
+
onpointerenter={entry.marker !== undefined ? () => onItemHover?.(entry.id) : undefined}
|
|
54
|
+
>
|
|
55
|
+
{#if item}{@render item(entry)}{:else}
|
|
56
|
+
{#if entry.marker !== undefined}<Marker
|
|
57
|
+
number={entry.marker}
|
|
58
|
+
active={activeId === entry.id}
|
|
59
|
+
/>{/if}
|
|
60
|
+
<div class="ldt-comment__content">
|
|
61
|
+
<span class="ldt-comment__meta">{entry.author}{entry.meta ? ` ${entry.meta}` : ''}</span>
|
|
62
|
+
<p class="ldt-comment__body">{entry.body}</p>
|
|
63
|
+
</div>
|
|
64
|
+
{/if}
|
|
65
|
+
</li>
|
|
66
|
+
{/each}
|
|
67
|
+
</ul>
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { HTMLAttributes } from 'svelte/elements';
|
|
3
|
+
declare function $$render<T extends string = string>(): {
|
|
4
|
+
props: Omit<HTMLAttributes<HTMLUListElement>, "children"> & {
|
|
5
|
+
items: {
|
|
6
|
+
id: T;
|
|
7
|
+
author: string;
|
|
8
|
+
/** Preformatted suffix after the author — timestamps, origins. The theme adds nothing. */
|
|
9
|
+
meta?: string;
|
|
10
|
+
body: string;
|
|
11
|
+
/** Renders a numbered Marker when set — ties the comment to a pin on a canvas. */
|
|
12
|
+
marker?: number;
|
|
13
|
+
}[];
|
|
14
|
+
/** Highlighted item; kept in view as it changes. */
|
|
15
|
+
activeId?: T | null;
|
|
16
|
+
/** Fired when a markered item is hovered — for syncing the matching canvas pin. */
|
|
17
|
+
onItemHover?: (id: T) => void;
|
|
18
|
+
/** Full row-content override. */
|
|
19
|
+
item?: Snippet<[{
|
|
20
|
+
id: T;
|
|
21
|
+
author: string;
|
|
22
|
+
/** Preformatted suffix after the author — timestamps, origins. The theme adds nothing. */
|
|
23
|
+
meta?: string;
|
|
24
|
+
body: string;
|
|
25
|
+
/** Renders a numbered Marker when set — ties the comment to a pin on a canvas. */
|
|
26
|
+
marker?: number;
|
|
27
|
+
}]>;
|
|
28
|
+
class?: string;
|
|
29
|
+
itemClass?: string;
|
|
30
|
+
ref?: HTMLUListElement | null;
|
|
31
|
+
};
|
|
32
|
+
exports: {};
|
|
33
|
+
bindings: "ref" | "activeId";
|
|
34
|
+
slots: {};
|
|
35
|
+
events: {};
|
|
36
|
+
};
|
|
37
|
+
declare class __sveltets_Render<T extends string = string> {
|
|
38
|
+
props(): ReturnType<typeof $$render<T>>['props'];
|
|
39
|
+
events(): ReturnType<typeof $$render<T>>['events'];
|
|
40
|
+
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
41
|
+
bindings(): "ref" | "activeId";
|
|
42
|
+
exports(): {};
|
|
43
|
+
}
|
|
44
|
+
interface $$IsomorphicComponent {
|
|
45
|
+
new <T extends string = string>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
|
|
46
|
+
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
47
|
+
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
48
|
+
<T extends string = string>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
49
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
50
|
+
}
|
|
51
|
+
declare const CommentList: $$IsomorphicComponent;
|
|
52
|
+
type CommentList<T extends string = string> = InstanceType<typeof CommentList<T>>;
|
|
53
|
+
export default CommentList;
|
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
import { Dialog as DialogPrimitive } from 'bits-ui';
|
|
3
3
|
import type { Snippet } from 'svelte';
|
|
4
4
|
import type { DialogContentProps } from 'bits-ui';
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
ActionVariant,
|
|
7
|
+
ControlSize,
|
|
8
|
+
DialogSize,
|
|
9
|
+
HeadingLevel,
|
|
10
|
+
TriggerChildProps,
|
|
11
|
+
} from '../types.js';
|
|
6
12
|
import { cx } from '../utils.js';
|
|
7
13
|
|
|
8
14
|
type Props = Omit<DialogContentProps, 'children' | 'class' | 'child'> & {
|
|
@@ -13,6 +19,9 @@
|
|
|
13
19
|
trigger?: Snippet;
|
|
14
20
|
/** Full control of the trigger element — receives the props Bits needs on it. */
|
|
15
21
|
triggerChild?: Snippet<[TriggerChildProps]>;
|
|
22
|
+
/** Button variant for the default trigger. An explicit `triggerClass` wins wholesale. */
|
|
23
|
+
triggerVariant?: ActionVariant;
|
|
24
|
+
triggerSize?: ControlSize;
|
|
16
25
|
triggerClass?: string;
|
|
17
26
|
children: Snippet;
|
|
18
27
|
footer?: Snippet;
|
|
@@ -34,7 +43,9 @@
|
|
|
34
43
|
description,
|
|
35
44
|
trigger,
|
|
36
45
|
triggerChild,
|
|
37
|
-
|
|
46
|
+
triggerVariant,
|
|
47
|
+
triggerSize,
|
|
48
|
+
triggerClass,
|
|
38
49
|
children,
|
|
39
50
|
footer,
|
|
40
51
|
size,
|
|
@@ -47,6 +58,17 @@
|
|
|
47
58
|
ref = $bindable(null),
|
|
48
59
|
...rest
|
|
49
60
|
}: Props = $props();
|
|
61
|
+
|
|
62
|
+
// An explicit triggerClass keeps today's contract and wins outright; otherwise the class is
|
|
63
|
+
// composed from the button variant vocabulary.
|
|
64
|
+
const triggerClasses = $derived(
|
|
65
|
+
triggerClass ??
|
|
66
|
+
cx(
|
|
67
|
+
'ldt-button',
|
|
68
|
+
triggerVariant && triggerVariant !== 'default' && `ldt-button--${triggerVariant}`,
|
|
69
|
+
triggerSize && triggerSize !== 'md' && `ldt-button--${triggerSize}`
|
|
70
|
+
)
|
|
71
|
+
);
|
|
50
72
|
</script>
|
|
51
73
|
|
|
52
74
|
<DialogPrimitive.Root bind:open {onOpenChange}>
|
|
@@ -54,7 +76,7 @@
|
|
|
54
76
|
>{#snippet child(childProps)}{@render triggerChild(
|
|
55
77
|
childProps
|
|
56
78
|
)}{/snippet}</DialogPrimitive.Trigger
|
|
57
|
-
>{:else if trigger}<DialogPrimitive.Trigger class={
|
|
79
|
+
>{:else if trigger}<DialogPrimitive.Trigger class={triggerClasses}
|
|
58
80
|
>{@render trigger()}</DialogPrimitive.Trigger
|
|
59
81
|
>{/if}
|
|
60
82
|
<DialogPrimitive.Portal>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Snippet } from 'svelte';
|
|
2
2
|
import type { DialogContentProps } from 'bits-ui';
|
|
3
|
-
import type { DialogSize, HeadingLevel, TriggerChildProps } from '../types.js';
|
|
3
|
+
import type { ActionVariant, ControlSize, DialogSize, HeadingLevel, TriggerChildProps } from '../types.js';
|
|
4
4
|
type Props = Omit<DialogContentProps, 'children' | 'class' | 'child'> & {
|
|
5
5
|
open?: boolean;
|
|
6
6
|
title: string;
|
|
@@ -9,6 +9,9 @@ type Props = Omit<DialogContentProps, 'children' | 'class' | 'child'> & {
|
|
|
9
9
|
trigger?: Snippet;
|
|
10
10
|
/** Full control of the trigger element — receives the props Bits needs on it. */
|
|
11
11
|
triggerChild?: Snippet<[TriggerChildProps]>;
|
|
12
|
+
/** Button variant for the default trigger. An explicit `triggerClass` wins wholesale. */
|
|
13
|
+
triggerVariant?: ActionVariant;
|
|
14
|
+
triggerSize?: ControlSize;
|
|
12
15
|
triggerClass?: string;
|
|
13
16
|
children: Snippet;
|
|
14
17
|
footer?: Snippet;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Dialog as DialogPrimitive } from 'bits-ui';
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
|
+
import type { DialogContentProps } from 'bits-ui';
|
|
5
|
+
import type { ActionVariant, ControlSize, HeadingLevel, TriggerChildProps } from '../types.js';
|
|
6
|
+
import { cx } from '../utils.js';
|
|
7
|
+
|
|
8
|
+
type Props = Omit<DialogContentProps, 'children' | 'class' | 'child'> & {
|
|
9
|
+
open?: boolean;
|
|
10
|
+
title: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
/** Edge the panel is anchored to. `left`/`right` size by width, `top`/`bottom` by height. */
|
|
13
|
+
side?: 'left' | 'right' | 'top' | 'bottom';
|
|
14
|
+
/** Trigger contents, rendered inside a button styled with `triggerClass`. */
|
|
15
|
+
trigger?: Snippet;
|
|
16
|
+
/** Full control of the trigger element — receives the props Bits needs on it. */
|
|
17
|
+
triggerChild?: Snippet<[TriggerChildProps]>;
|
|
18
|
+
/** Button variant for the default trigger. An explicit `triggerClass` wins wholesale. */
|
|
19
|
+
triggerVariant?: ActionVariant;
|
|
20
|
+
triggerSize?: ControlSize;
|
|
21
|
+
triggerClass?: string;
|
|
22
|
+
children: Snippet;
|
|
23
|
+
footer?: Snippet;
|
|
24
|
+
headingLevel?: HeadingLevel;
|
|
25
|
+
showClose?: boolean;
|
|
26
|
+
closeLabel?: string;
|
|
27
|
+
/** `class` lands on the portaled Content element. */
|
|
28
|
+
class?: string;
|
|
29
|
+
overlayClass?: string;
|
|
30
|
+
onOpenChange?: (open: boolean) => void;
|
|
31
|
+
ref?: HTMLElement | null;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
let {
|
|
35
|
+
open = $bindable(false),
|
|
36
|
+
title,
|
|
37
|
+
description,
|
|
38
|
+
side = 'left',
|
|
39
|
+
trigger,
|
|
40
|
+
triggerChild,
|
|
41
|
+
triggerVariant,
|
|
42
|
+
triggerSize,
|
|
43
|
+
triggerClass,
|
|
44
|
+
children,
|
|
45
|
+
footer,
|
|
46
|
+
headingLevel = 2,
|
|
47
|
+
showClose = true,
|
|
48
|
+
closeLabel = 'Close',
|
|
49
|
+
class: className,
|
|
50
|
+
overlayClass,
|
|
51
|
+
onOpenChange,
|
|
52
|
+
ref = $bindable(null),
|
|
53
|
+
...rest
|
|
54
|
+
}: Props = $props();
|
|
55
|
+
|
|
56
|
+
// An explicit triggerClass keeps today's contract and wins outright.
|
|
57
|
+
const triggerClasses = $derived(
|
|
58
|
+
triggerClass ??
|
|
59
|
+
cx(
|
|
60
|
+
'ldt-button',
|
|
61
|
+
triggerVariant && triggerVariant !== 'default' && `ldt-button--${triggerVariant}`,
|
|
62
|
+
triggerSize && triggerSize !== 'md' && `ldt-button--${triggerSize}`
|
|
63
|
+
)
|
|
64
|
+
);
|
|
65
|
+
</script>
|
|
66
|
+
|
|
67
|
+
<!--
|
|
68
|
+
A modal panel anchored to one edge — the narrow-viewport form of a sidebar, and the usual home
|
|
69
|
+
for navigation that has no room to sit in the topbar. Same primitive as `Dialog`, so focus is
|
|
70
|
+
trapped, Escape closes, and the page behind is inert; set `--ldt-drawer-size` for the measure
|
|
71
|
+
across the anchored edge.
|
|
72
|
+
-->
|
|
73
|
+
<DialogPrimitive.Root bind:open {onOpenChange}>
|
|
74
|
+
{#if triggerChild}<DialogPrimitive.Trigger
|
|
75
|
+
>{#snippet child(childProps)}{@render triggerChild(
|
|
76
|
+
childProps
|
|
77
|
+
)}{/snippet}</DialogPrimitive.Trigger
|
|
78
|
+
>{:else if trigger}<DialogPrimitive.Trigger class={triggerClasses}
|
|
79
|
+
>{@render trigger()}</DialogPrimitive.Trigger
|
|
80
|
+
>{/if}
|
|
81
|
+
<DialogPrimitive.Portal>
|
|
82
|
+
<DialogPrimitive.Overlay class={cx('ldt-overlay', overlayClass)} />
|
|
83
|
+
<DialogPrimitive.Content
|
|
84
|
+
bind:ref
|
|
85
|
+
class={cx('ldt-drawer', `ldt-drawer--${side}`, className)}
|
|
86
|
+
{...rest}
|
|
87
|
+
>
|
|
88
|
+
<header class="ldt-drawer__header">
|
|
89
|
+
<div>
|
|
90
|
+
<DialogPrimitive.Title level={headingLevel} class="ldt-drawer__title"
|
|
91
|
+
>{title}</DialogPrimitive.Title
|
|
92
|
+
>{#if description}<DialogPrimitive.Description class="ldt-drawer__description"
|
|
93
|
+
>{description}</DialogPrimitive.Description
|
|
94
|
+
>{/if}
|
|
95
|
+
</div>
|
|
96
|
+
{#if showClose}<DialogPrimitive.Close
|
|
97
|
+
class="ldt-button ldt-icon-button ldt-button--ghost"
|
|
98
|
+
aria-label={closeLabel}>×</DialogPrimitive.Close
|
|
99
|
+
>{/if}
|
|
100
|
+
</header>
|
|
101
|
+
<div class="ldt-drawer__body ldt-scrollbar">{@render children()}</div>
|
|
102
|
+
{#if footer}<footer class="ldt-drawer__footer">{@render footer()}</footer>{/if}
|
|
103
|
+
</DialogPrimitive.Content>
|
|
104
|
+
</DialogPrimitive.Portal>
|
|
105
|
+
</DialogPrimitive.Root>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { DialogContentProps } from 'bits-ui';
|
|
3
|
+
import type { ActionVariant, ControlSize, HeadingLevel, TriggerChildProps } from '../types.js';
|
|
4
|
+
type Props = Omit<DialogContentProps, 'children' | 'class' | 'child'> & {
|
|
5
|
+
open?: boolean;
|
|
6
|
+
title: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
/** Edge the panel is anchored to. `left`/`right` size by width, `top`/`bottom` by height. */
|
|
9
|
+
side?: 'left' | 'right' | 'top' | 'bottom';
|
|
10
|
+
/** Trigger contents, rendered inside a button styled with `triggerClass`. */
|
|
11
|
+
trigger?: Snippet;
|
|
12
|
+
/** Full control of the trigger element — receives the props Bits needs on it. */
|
|
13
|
+
triggerChild?: Snippet<[TriggerChildProps]>;
|
|
14
|
+
/** Button variant for the default trigger. An explicit `triggerClass` wins wholesale. */
|
|
15
|
+
triggerVariant?: ActionVariant;
|
|
16
|
+
triggerSize?: ControlSize;
|
|
17
|
+
triggerClass?: string;
|
|
18
|
+
children: Snippet;
|
|
19
|
+
footer?: Snippet;
|
|
20
|
+
headingLevel?: HeadingLevel;
|
|
21
|
+
showClose?: boolean;
|
|
22
|
+
closeLabel?: string;
|
|
23
|
+
/** `class` lands on the portaled Content element. */
|
|
24
|
+
class?: string;
|
|
25
|
+
overlayClass?: string;
|
|
26
|
+
onOpenChange?: (open: boolean) => void;
|
|
27
|
+
ref?: HTMLElement | null;
|
|
28
|
+
};
|
|
29
|
+
declare const Drawer: import("svelte").Component<Props, {}, "ref" | "open">;
|
|
30
|
+
type Drawer = ReturnType<typeof Drawer>;
|
|
31
|
+
export default Drawer;
|
|
@@ -58,13 +58,13 @@
|
|
|
58
58
|
{#if item.href}
|
|
59
59
|
<a {...props} href={item.href}
|
|
60
60
|
>{#if item.icon}{@render item.icon()}{/if}<span>{item.label}</span>{#if item.hint}<span
|
|
61
|
-
|
|
61
|
+
class="ldt-menu__hint">{item.hint}</span
|
|
62
62
|
>{/if}</a
|
|
63
63
|
>
|
|
64
64
|
{:else}
|
|
65
65
|
<button {...props} type="button"
|
|
66
66
|
>{#if item.icon}{@render item.icon()}{/if}<span>{item.label}</span>{#if item.hint}<span
|
|
67
|
-
|
|
67
|
+
class="ldt-menu__hint">{item.hint}</span
|
|
68
68
|
>{/if}</button
|
|
69
69
|
>
|
|
70
70
|
{/if}
|
|
@@ -2,7 +2,7 @@ import { DropdownMenu as MenuPrimitive } from 'bits-ui';
|
|
|
2
2
|
import type { Snippet } from 'svelte';
|
|
3
3
|
import type { Alignment, MenuItem, Placement, TriggerChildProps } from '../types.js';
|
|
4
4
|
declare function $$render<T extends string = string>(): {
|
|
5
|
-
props: Omit<MenuPrimitive.ContentProps, "
|
|
5
|
+
props: Omit<MenuPrimitive.ContentProps, "children" | "class" | "child"> & {
|
|
6
6
|
open?: boolean;
|
|
7
7
|
/** Heading rendered above `items`, associated with them via a menu group. */
|
|
8
8
|
groupLabel?: string;
|