@poodle64/ui 2026.10.16 → 2026.10.18

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.
Files changed (65) hide show
  1. package/README.md +135 -11
  2. package/dist/components/feedback/report-widget.svelte +4 -1
  3. package/dist/components/feedback/report-widget.svelte.d.ts +1 -0
  4. package/dist/components/ui/app-identity/app-identity.svelte +7 -2
  5. package/dist/components/ui/app-shell/texture.d.ts +5 -5
  6. package/dist/components/ui/app-shell/texture.js +3 -3
  7. package/dist/components/ui/breadcrumbs/breadcrumbs.svelte +70 -0
  8. package/dist/components/ui/breadcrumbs/breadcrumbs.svelte.d.ts +32 -0
  9. package/dist/components/ui/breadcrumbs/index.d.ts +2 -0
  10. package/dist/components/ui/breadcrumbs/index.js +2 -0
  11. package/dist/components/ui/content-skeleton/content-skeleton.svelte +94 -0
  12. package/dist/components/ui/content-skeleton/content-skeleton.svelte.d.ts +25 -0
  13. package/dist/components/ui/content-skeleton/index.d.ts +2 -0
  14. package/dist/components/ui/content-skeleton/index.js +2 -0
  15. package/dist/components/ui/document-reader/document-reader.svelte +336 -0
  16. package/dist/components/ui/document-reader/document-reader.svelte.d.ts +65 -0
  17. package/dist/components/ui/document-reader/index.d.ts +2 -0
  18. package/dist/components/ui/document-reader/index.js +2 -0
  19. package/dist/components/ui/graph-canvas/graph-canvas.svelte +922 -0
  20. package/dist/components/ui/graph-canvas/graph-canvas.svelte.d.ts +73 -0
  21. package/dist/components/ui/graph-canvas/index.d.ts +3 -0
  22. package/dist/components/ui/graph-canvas/index.js +2 -0
  23. package/dist/components/ui/graph-canvas/scene.d.ts +107 -0
  24. package/dist/components/ui/graph-canvas/scene.js +562 -0
  25. package/dist/components/ui/graph-canvas/types.d.ts +33 -0
  26. package/dist/components/ui/graph-canvas/types.js +1 -0
  27. package/dist/components/ui/page-container/index.d.ts +2 -0
  28. package/dist/components/ui/page-container/index.js +2 -0
  29. package/dist/components/ui/page-container/page-container.svelte +39 -0
  30. package/dist/components/ui/page-container/page-container.svelte.d.ts +24 -0
  31. package/dist/components/ui/page-header/page-header.svelte +12 -7
  32. package/dist/components/ui/page-header/page-header.svelte.d.ts +3 -2
  33. package/dist/components/ui/page-section/index.d.ts +2 -0
  34. package/dist/components/ui/page-section/index.js +2 -0
  35. package/dist/components/ui/page-section/page-section.svelte +92 -0
  36. package/dist/components/ui/page-section/page-section.svelte.d.ts +36 -0
  37. package/dist/components/ui/sheet/index.d.ts +13 -0
  38. package/dist/components/ui/sheet/index.js +15 -0
  39. package/dist/components/ui/sheet/sheet-body.svelte +21 -0
  40. package/dist/components/ui/sheet/sheet-body.svelte.d.ts +5 -0
  41. package/dist/components/ui/sheet/sheet-close.svelte +11 -0
  42. package/dist/components/ui/sheet/sheet-close.svelte.d.ts +4 -0
  43. package/dist/components/ui/sheet/sheet-content.svelte +70 -0
  44. package/dist/components/ui/sheet/sheet-content.svelte.d.ts +37 -0
  45. package/dist/components/ui/sheet/sheet-description.svelte +20 -0
  46. package/dist/components/ui/sheet/sheet-description.svelte.d.ts +4 -0
  47. package/dist/components/ui/sheet/sheet-footer.svelte +23 -0
  48. package/dist/components/ui/sheet/sheet-footer.svelte.d.ts +5 -0
  49. package/dist/components/ui/sheet/sheet-header.svelte +21 -0
  50. package/dist/components/ui/sheet/sheet-header.svelte.d.ts +5 -0
  51. package/dist/components/ui/sheet/sheet-overlay.svelte +20 -0
  52. package/dist/components/ui/sheet/sheet-overlay.svelte.d.ts +4 -0
  53. package/dist/components/ui/sheet/sheet-portal.svelte +7 -0
  54. package/dist/components/ui/sheet/sheet-portal.svelte.d.ts +3 -0
  55. package/dist/components/ui/sheet/sheet-title.svelte +21 -0
  56. package/dist/components/ui/sheet/sheet-title.svelte.d.ts +4 -0
  57. package/dist/components/ui/sheet/sheet-trigger.svelte +11 -0
  58. package/dist/components/ui/sheet/sheet-trigger.svelte.d.ts +4 -0
  59. package/dist/components/ui/sheet/sheet.svelte +7 -0
  60. package/dist/components/ui/sheet/sheet.svelte.d.ts +3 -0
  61. package/dist/components/ui/skeleton/skeleton.svelte +1 -1
  62. package/dist/styles.css +8 -0
  63. package/package.json +4 -2
  64. package/registry/component-map.json +58 -5
  65. package/registry/component-map.md +17 -4
@@ -3,6 +3,7 @@
3
3
  import type { HTMLAttributes } from 'svelte/elements';
4
4
  import { cn, type WithElementRef } from '../../../utils.js';
5
5
  import InfoTip from '../info-tip/info-tip.svelte';
6
+ import Breadcrumbs, { type BreadcrumbItem } from '../breadcrumbs/breadcrumbs.svelte';
6
7
 
7
8
  /**
8
9
  * The one page-title pattern for every route. `subtitle` is a short, single
@@ -23,10 +24,11 @@
23
24
  * the drift this package exists to end. One component, one spacing rhythm,
24
25
  * two shapes.
25
26
  *
26
- * The trail itself stays the app's, as a snippet: a breadcrumb trail is made
27
- * of routed links, and a package with no SvelteKit runtime of its own cannot
28
- * own those (the same reasoning that makes AppShell take `currentPath` as a
29
- * prop rather than importing `$app/state`).
27
+ * The trail is a list of steps (`BreadcrumbItem[]`), drawn by Breadcrumbs.
28
+ * A snippet is still accepted for a trail that is not a list of links (a
29
+ * record switcher in the trail's place), but a list is the default: three
30
+ * apps wrote the same chevron trail by hand, one behind a 28-call-site
31
+ * wrapper that existed only to turn this snippet into an array.
30
32
  *
31
33
  * `icon` and `meta` are snippets for the same reason and earn their place the
32
34
  * same way `breadcrumbs` did: three apps had hand-rolled the meta row and two
@@ -50,8 +52,8 @@
50
52
  }: WithElementRef<HTMLAttributes<HTMLDivElement>> & {
51
53
  /** A short kicker above the title. Use this OR `breadcrumbs`, not both. */
52
54
  eyebrow?: string;
53
- /** The trail above the title — the app's own routed links. */
54
- breadcrumbs?: Snippet;
55
+ /** The trail above the title: its steps, or a snippet for a trail that is not links. */
56
+ breadcrumbs?: BreadcrumbItem[] | Snippet;
55
57
  /** The glyph alone. The tinted square around it is this component's. */
56
58
  icon?: Snippet;
57
59
  /** Omit for a header that is a breadcrumb bar with actions. */
@@ -66,6 +68,7 @@
66
68
 
67
69
  <div
68
70
  bind:this={ref}
71
+ data-slot="page-header"
69
72
  class={cn('mb-6 flex flex-wrap items-start justify-between gap-4', className)}
70
73
  {...restProps}
71
74
  >
@@ -83,10 +86,12 @@
83
86
  </span>
84
87
  {/if}
85
88
  <div class="min-w-0">
86
- {#if breadcrumbs}
89
+ {#if typeof breadcrumbs === 'function'}
87
90
  <div class="text-muted-foreground mb-1.5 flex min-w-0 items-center text-sm">
88
91
  {@render breadcrumbs()}
89
92
  </div>
93
+ {:else if breadcrumbs?.length}
94
+ <Breadcrumbs items={breadcrumbs} class="mb-1.5" />
90
95
  {/if}
91
96
  {#if eyebrow}
92
97
  <div class="text-primary text-2xs tracking-eyebrow mb-1 font-medium uppercase">
@@ -1,11 +1,12 @@
1
1
  import type { Snippet } from 'svelte';
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
3
  import { type WithElementRef } from '../../../utils.js';
4
+ import { type BreadcrumbItem } from '../breadcrumbs/breadcrumbs.svelte';
4
5
  type $$ComponentProps = WithElementRef<HTMLAttributes<HTMLDivElement>> & {
5
6
  /** A short kicker above the title. Use this OR `breadcrumbs`, not both. */
6
7
  eyebrow?: string;
7
- /** The trail above the title — the app's own routed links. */
8
- breadcrumbs?: Snippet;
8
+ /** The trail above the title: its steps, or a snippet for a trail that is not links. */
9
+ breadcrumbs?: BreadcrumbItem[] | Snippet;
9
10
  /** The glyph alone. The tinted square around it is this component's. */
10
11
  icon?: Snippet;
11
12
  /** Omit for a header that is a breadcrumb bar with actions. */
@@ -0,0 +1,2 @@
1
+ export { default as PageSection } from './page-section.svelte';
2
+ export { default } from './page-section.svelte';
@@ -0,0 +1,2 @@
1
+ export { default as PageSection } from './page-section.svelte';
2
+ export { default } from './page-section.svelte';
@@ -0,0 +1,92 @@
1
+ <script lang="ts">
2
+ /**
3
+ * A section of a page, under its PageHeader: a heading, an optional line of
4
+ * explanation, trailing actions, and the section's content at one distance
5
+ * below them.
6
+ *
7
+ * One app had five recipes for this one role, from an 11px uppercase kicker
8
+ * to a 20px display heading, and each page spaced its content from the
9
+ * heading differently. The heading and the gap under it are this
10
+ * component's, because those are the halves that drift.
11
+ *
12
+ * Level 2 is a section, in the display face one step under the page title.
13
+ * Level 3 is a subsection, in the body face at a Panel title's size, so a
14
+ * titled card and a subsection read as the same rank. There is no uppercase
15
+ * kicker form: a small caps label above content is the column head of a
16
+ * table or a nav group, never a heading.
17
+ */
18
+ import type { Snippet } from 'svelte';
19
+ import type { HTMLAttributes } from 'svelte/elements';
20
+ import { cn, type WithElementRef } from '../../../utils.js';
21
+
22
+ let {
23
+ title,
24
+ level = 2,
25
+ description,
26
+ count,
27
+ actions,
28
+ children,
29
+ id,
30
+ ref = $bindable(null),
31
+ class: className,
32
+ ...restProps
33
+ }: Omit<WithElementRef<HTMLAttributes<HTMLElement>>, 'title'> & {
34
+ title: string;
35
+ /** 2, a section of the page; 3, a section within one. */
36
+ level?: 2 | 3;
37
+ /** A sentence or two under the heading. It wraps. */
38
+ description?: string;
39
+ /** How many things the section holds, set beside the heading. */
40
+ count?: number;
41
+ /** Controls for the section, trailing the heading. */
42
+ actions?: Snippet;
43
+ children?: Snippet;
44
+ /** The heading's id, for a link to the section. One is generated otherwise. */
45
+ id?: string;
46
+ } = $props();
47
+
48
+ const fallbackId = $props.id();
49
+ const headingId = $derived(id ?? `section-${fallbackId}`);
50
+ </script>
51
+
52
+ <section
53
+ bind:this={ref}
54
+ aria-labelledby={headingId}
55
+ data-slot="page-section"
56
+ class={cn('flex min-w-0 flex-col', level === 2 ? 'gap-4' : 'gap-3', className)}
57
+ {...restProps}
58
+ >
59
+ <!-- Actions share the heading's row, so on a phone they stay beside the
60
+ heading rather than dropping under the description. -->
61
+ <header class="flex min-w-0 flex-col gap-1">
62
+ <div class="flex min-w-0 flex-wrap items-center gap-x-4 gap-y-2">
63
+ <svelte:element
64
+ this={`h${level}`}
65
+ id={headingId}
66
+ class={cn(
67
+ 'flex min-w-0 items-baseline gap-2 scroll-mt-4 font-semibold',
68
+ level === 2
69
+ ? 'font-display text-section tracking-[var(--ds-font-display-tracking,-0.015em)]'
70
+ : 'text-body leading-tight tracking-tight'
71
+ )}
72
+ >
73
+ <span class="min-w-0">{title}</span>
74
+ {#if count !== undefined}
75
+ <span
76
+ class="text-muted-foreground font-sans text-sm font-normal tracking-normal tabular-nums"
77
+ >{count}</span
78
+ >
79
+ {/if}
80
+ </svelte:element>
81
+ {#if actions}
82
+ <div class="ml-auto flex min-w-0 flex-wrap items-center justify-end gap-2">
83
+ {@render actions()}
84
+ </div>
85
+ {/if}
86
+ </div>
87
+ {#if description}
88
+ <p class="text-muted-foreground ds-measure text-sm" data-measure="prose">{description}</p>
89
+ {/if}
90
+ </header>
91
+ {@render children?.()}
92
+ </section>
@@ -0,0 +1,36 @@
1
+ /**
2
+ * A section of a page, under its PageHeader: a heading, an optional line of
3
+ * explanation, trailing actions, and the section's content at one distance
4
+ * below them.
5
+ *
6
+ * One app had five recipes for this one role, from an 11px uppercase kicker
7
+ * to a 20px display heading, and each page spaced its content from the
8
+ * heading differently. The heading and the gap under it are this
9
+ * component's, because those are the halves that drift.
10
+ *
11
+ * Level 2 is a section, in the display face one step under the page title.
12
+ * Level 3 is a subsection, in the body face at a Panel title's size, so a
13
+ * titled card and a subsection read as the same rank. There is no uppercase
14
+ * kicker form: a small caps label above content is the column head of a
15
+ * table or a nav group, never a heading.
16
+ */
17
+ import type { Snippet } from 'svelte';
18
+ import type { HTMLAttributes } from 'svelte/elements';
19
+ import { type WithElementRef } from '../../../utils.js';
20
+ type $$ComponentProps = Omit<WithElementRef<HTMLAttributes<HTMLElement>>, 'title'> & {
21
+ title: string;
22
+ /** 2, a section of the page; 3, a section within one. */
23
+ level?: 2 | 3;
24
+ /** A sentence or two under the heading. It wraps. */
25
+ description?: string;
26
+ /** How many things the section holds, set beside the heading. */
27
+ count?: number;
28
+ /** Controls for the section, trailing the heading. */
29
+ actions?: Snippet;
30
+ children?: Snippet;
31
+ /** The heading's id, for a link to the section. One is generated otherwise. */
32
+ id?: string;
33
+ };
34
+ declare const PageSection: import("svelte").Component<$$ComponentProps, {}, "ref">;
35
+ type PageSection = ReturnType<typeof PageSection>;
36
+ export default PageSection;
@@ -0,0 +1,13 @@
1
+ import Root from './sheet.svelte';
2
+ import Trigger from './sheet-trigger.svelte';
3
+ import Close from './sheet-close.svelte';
4
+ import Portal from './sheet-portal.svelte';
5
+ import Overlay from './sheet-overlay.svelte';
6
+ import Content from './sheet-content.svelte';
7
+ import Header from './sheet-header.svelte';
8
+ import Body from './sheet-body.svelte';
9
+ import Footer from './sheet-footer.svelte';
10
+ import Title from './sheet-title.svelte';
11
+ import Description from './sheet-description.svelte';
12
+ export { sheetVariants, type SheetSide } from './sheet-content.svelte';
13
+ export { Root, Trigger, Close, Portal, Overlay, Content, Header, Body, Footer, Title, Description, Root as Sheet, Trigger as SheetTrigger, Close as SheetClose, Portal as SheetPortal, Overlay as SheetOverlay, Content as SheetContent, Header as SheetHeader, Body as SheetBody, Footer as SheetFooter, Title as SheetTitle, Description as SheetDescription };
@@ -0,0 +1,15 @@
1
+ import Root from './sheet.svelte';
2
+ import Trigger from './sheet-trigger.svelte';
3
+ import Close from './sheet-close.svelte';
4
+ import Portal from './sheet-portal.svelte';
5
+ import Overlay from './sheet-overlay.svelte';
6
+ import Content from './sheet-content.svelte';
7
+ import Header from './sheet-header.svelte';
8
+ import Body from './sheet-body.svelte';
9
+ import Footer from './sheet-footer.svelte';
10
+ import Title from './sheet-title.svelte';
11
+ import Description from './sheet-description.svelte';
12
+ export { sheetVariants } from './sheet-content.svelte';
13
+ export { Root, Trigger, Close, Portal, Overlay, Content, Header, Body, Footer, Title, Description,
14
+ //
15
+ Root as Sheet, Trigger as SheetTrigger, Close as SheetClose, Portal as SheetPortal, Overlay as SheetOverlay, Content as SheetContent, Header as SheetHeader, Body as SheetBody, Footer as SheetFooter, Title as SheetTitle, Description as SheetDescription };
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import { cn, type WithElementRef } from '../../../utils.js';
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
11
+ </script>
12
+
13
+ <!-- The part that scrolls, so the header and footer stay put. -->
14
+ <div
15
+ bind:this={ref}
16
+ data-slot="sheet-body"
17
+ class={cn('min-h-0 flex-1 overflow-y-auto p-4', className)}
18
+ {...restProps}
19
+ >
20
+ {@render children?.()}
21
+ </div>
@@ -0,0 +1,5 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ import { type WithElementRef } from '../../../utils.js';
3
+ declare const SheetBody: import("svelte").Component<WithElementRef<HTMLAttributes<HTMLDivElement>>, {}, "ref">;
4
+ type SheetBody = ReturnType<typeof SheetBody>;
5
+ export default SheetBody;
@@ -0,0 +1,11 @@
1
+ <script lang="ts">
2
+ import { Dialog as DialogPrimitive } from 'bits-ui';
3
+
4
+ let {
5
+ ref = $bindable(null),
6
+ type = 'button',
7
+ ...restProps
8
+ }: DialogPrimitive.CloseProps = $props();
9
+ </script>
10
+
11
+ <DialogPrimitive.Close bind:ref data-slot="sheet-close" {type} {...restProps} />
@@ -0,0 +1,4 @@
1
+ import { Dialog as DialogPrimitive } from 'bits-ui';
2
+ declare const SheetClose: import("svelte").Component<DialogPrimitive.TriggerProps, {}, "ref">;
3
+ type SheetClose = ReturnType<typeof SheetClose>;
4
+ export default SheetClose;
@@ -0,0 +1,70 @@
1
+ <script lang="ts" module>
2
+ import { tv, type VariantProps } from 'tailwind-variants';
3
+
4
+ // A sheet stands on the hairline-and-ladder depth every other kit surface
5
+ // uses (README §Depth): an edge border against the dimmed page, no shadow.
6
+ // A side sheet takes a phone's whole width: a sliver of dimmed page beside
7
+ // it is too narrow to read and too narrow to aim at.
8
+ export const sheetVariants = tv({
9
+ base: 'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out border-border fixed z-50 flex flex-col text-sm outline-none duration-200 ease-out data-closed:duration-150',
10
+ variants: {
11
+ side: {
12
+ right: 'data-closed:slide-out-to-right data-open:slide-in-from-right inset-y-0 right-0 h-full w-full border-l sm:max-w-sm',
13
+ left: 'data-closed:slide-out-to-left data-open:slide-in-from-left inset-y-0 left-0 h-full w-full border-r sm:max-w-sm',
14
+ bottom: 'data-closed:slide-out-to-bottom data-open:slide-in-from-bottom inset-x-0 bottom-0 max-h-[85%] rounded-t-xl border-t',
15
+ top: 'data-closed:slide-out-to-top data-open:slide-in-from-top inset-x-0 top-0 max-h-[85%] rounded-b-xl border-b'
16
+ }
17
+ },
18
+ defaultVariants: { side: 'right' }
19
+ });
20
+
21
+ export type SheetSide = VariantProps<typeof sheetVariants>['side'];
22
+ </script>
23
+
24
+ <script lang="ts">
25
+ import { Dialog as SheetPrimitive } from 'bits-ui';
26
+ import type { ComponentProps, Snippet } from 'svelte';
27
+ import XIcon from '@lucide/svelte/icons/x';
28
+ import { cn, type WithoutChildrenOrChild } from '../../../utils.js';
29
+ import { Button } from '../button/index.js';
30
+ import SheetOverlay from './sheet-overlay.svelte';
31
+ import SheetPortal from './sheet-portal.svelte';
32
+
33
+ let {
34
+ ref = $bindable(null),
35
+ class: className,
36
+ side = 'right',
37
+ portalProps,
38
+ showCloseButton = true,
39
+ children,
40
+ ...restProps
41
+ }: WithoutChildrenOrChild<SheetPrimitive.ContentProps> & {
42
+ side?: SheetSide;
43
+ portalProps?: WithoutChildrenOrChild<ComponentProps<typeof SheetPortal>>;
44
+ showCloseButton?: boolean;
45
+ children: Snippet;
46
+ } = $props();
47
+ </script>
48
+
49
+ <SheetPortal {...portalProps}>
50
+ <SheetOverlay />
51
+ <SheetPrimitive.Content
52
+ bind:ref
53
+ data-slot="sheet-content"
54
+ data-side={side}
55
+ class={cn(sheetVariants({ side }), className)}
56
+ {...restProps}
57
+ >
58
+ {@render children?.()}
59
+ {#if showCloseButton}
60
+ <SheetPrimitive.Close data-slot="sheet-close">
61
+ {#snippet child({ props })}
62
+ <Button variant="ghost" class="absolute top-3 right-3" size="icon-sm" {...props}>
63
+ <XIcon />
64
+ <span class="sr-only">Close</span>
65
+ </Button>
66
+ {/snippet}
67
+ </SheetPrimitive.Close>
68
+ {/if}
69
+ </SheetPrimitive.Content>
70
+ </SheetPortal>
@@ -0,0 +1,37 @@
1
+ import { type VariantProps } from 'tailwind-variants';
2
+ export declare const sheetVariants: import("tailwind-variants").TVReturnType<{
3
+ side: {
4
+ right: string;
5
+ left: string;
6
+ bottom: string;
7
+ top: string;
8
+ };
9
+ }, undefined, "bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out border-border fixed z-50 flex flex-col text-sm outline-none duration-200 ease-out data-closed:duration-150", {
10
+ side: {
11
+ right: string;
12
+ left: string;
13
+ bottom: string;
14
+ top: string;
15
+ };
16
+ }, undefined, import("tailwind-variants").TVReturnType<{
17
+ side: {
18
+ right: string;
19
+ left: string;
20
+ bottom: string;
21
+ top: string;
22
+ };
23
+ }, undefined, "bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out border-border fixed z-50 flex flex-col text-sm outline-none duration-200 ease-out data-closed:duration-150", unknown, unknown, undefined>>;
24
+ export type SheetSide = VariantProps<typeof sheetVariants>['side'];
25
+ import { Dialog as SheetPrimitive } from 'bits-ui';
26
+ import type { ComponentProps, Snippet } from 'svelte';
27
+ import { type WithoutChildrenOrChild } from '../../../utils.js';
28
+ import SheetPortal from './sheet-portal.svelte';
29
+ type $$ComponentProps = WithoutChildrenOrChild<SheetPrimitive.ContentProps> & {
30
+ side?: SheetSide;
31
+ portalProps?: WithoutChildrenOrChild<ComponentProps<typeof SheetPortal>>;
32
+ showCloseButton?: boolean;
33
+ children: Snippet;
34
+ };
35
+ declare const SheetContent: import("svelte").Component<$$ComponentProps, {}, "ref">;
36
+ type SheetContent = ReturnType<typeof SheetContent>;
37
+ export default SheetContent;
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { Dialog as DialogPrimitive } from 'bits-ui';
3
+ import { cn } from '../../../utils.js';
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: DialogPrimitive.DescriptionProps = $props();
10
+ </script>
11
+
12
+ <DialogPrimitive.Description
13
+ bind:ref
14
+ data-slot="sheet-description"
15
+ class={cn(
16
+ 'text-muted-foreground *:[a]:hover:text-foreground text-sm *:[a]:underline *:[a]:underline-offset-3',
17
+ className
18
+ )}
19
+ {...restProps}
20
+ />
@@ -0,0 +1,4 @@
1
+ import { Dialog as DialogPrimitive } from 'bits-ui';
2
+ declare const SheetDescription: import("svelte").Component<DialogPrimitive.DescriptionProps, {}, "ref">;
3
+ type SheetDescription = ReturnType<typeof SheetDescription>;
4
+ export default SheetDescription;
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import { cn, type WithElementRef } from '../../../utils.js';
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
11
+ </script>
12
+
13
+ <div
14
+ bind:this={ref}
15
+ data-slot="sheet-footer"
16
+ class={cn(
17
+ 'bg-muted/50 mt-auto flex shrink-0 flex-col-reverse gap-2 border-t p-4 sm:flex-row sm:justify-end',
18
+ className
19
+ )}
20
+ {...restProps}
21
+ >
22
+ {@render children?.()}
23
+ </div>
@@ -0,0 +1,5 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ import { type WithElementRef } from '../../../utils.js';
3
+ declare const SheetFooter: import("svelte").Component<WithElementRef<HTMLAttributes<HTMLDivElement>>, {}, "ref">;
4
+ type SheetFooter = ReturnType<typeof SheetFooter>;
5
+ export default SheetFooter;
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import { cn, type WithElementRef } from '../../../utils.js';
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ children,
9
+ ...restProps
10
+ }: WithElementRef<HTMLAttributes<HTMLDivElement>> = $props();
11
+ </script>
12
+
13
+ <!-- pr-12 keeps the title clear of the content's close button. -->
14
+ <div
15
+ bind:this={ref}
16
+ data-slot="sheet-header"
17
+ class={cn('flex shrink-0 flex-col gap-1.5 border-b p-4 pr-12', className)}
18
+ {...restProps}
19
+ >
20
+ {@render children?.()}
21
+ </div>
@@ -0,0 +1,5 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ import { type WithElementRef } from '../../../utils.js';
3
+ declare const SheetHeader: import("svelte").Component<WithElementRef<HTMLAttributes<HTMLDivElement>>, {}, "ref">;
4
+ type SheetHeader = ReturnType<typeof SheetHeader>;
5
+ export default SheetHeader;
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { Dialog as DialogPrimitive } from 'bits-ui';
3
+ import { cn } from '../../../utils.js';
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: DialogPrimitive.OverlayProps = $props();
10
+ </script>
11
+
12
+ <DialogPrimitive.Overlay
13
+ bind:ref
14
+ data-slot="sheet-overlay"
15
+ class={cn(
16
+ 'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs',
17
+ className
18
+ )}
19
+ {...restProps}
20
+ />
@@ -0,0 +1,4 @@
1
+ import { Dialog as DialogPrimitive } from 'bits-ui';
2
+ declare const SheetOverlay: import("svelte").Component<DialogPrimitive.OverlayProps, {}, "ref">;
3
+ type SheetOverlay = ReturnType<typeof SheetOverlay>;
4
+ export default SheetOverlay;
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import { Dialog as DialogPrimitive } from 'bits-ui';
3
+
4
+ let { ...restProps }: DialogPrimitive.PortalProps = $props();
5
+ </script>
6
+
7
+ <DialogPrimitive.Portal {...restProps} />
@@ -0,0 +1,3 @@
1
+ declare const SheetPortal: import("svelte").Component<import("bits-ui").PortalProps, {}, "">;
2
+ type SheetPortal = ReturnType<typeof SheetPortal>;
3
+ export default SheetPortal;
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import { Dialog as SheetPrimitive } from 'bits-ui';
3
+ import { cn } from '../../../utils.js';
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ ...restProps
9
+ }: SheetPrimitive.TitleProps = $props();
10
+ </script>
11
+
12
+ <!-- AppDialog's title treatment, so a sheet and a dialogue name themselves alike. -->
13
+ <SheetPrimitive.Title
14
+ bind:ref
15
+ data-slot="sheet-title"
16
+ class={cn(
17
+ 'font-display text-lg leading-tight font-semibold tracking-[var(--ds-font-display-tracking,-0.025em)]',
18
+ className
19
+ )}
20
+ {...restProps}
21
+ />
@@ -0,0 +1,4 @@
1
+ import { Dialog as SheetPrimitive } from 'bits-ui';
2
+ declare const SheetTitle: import("svelte").Component<SheetPrimitive.TitleProps, {}, "ref">;
3
+ type SheetTitle = ReturnType<typeof SheetTitle>;
4
+ export default SheetTitle;
@@ -0,0 +1,11 @@
1
+ <script lang="ts">
2
+ import { Dialog as DialogPrimitive } from 'bits-ui';
3
+
4
+ let {
5
+ ref = $bindable(null),
6
+ type = 'button',
7
+ ...restProps
8
+ }: DialogPrimitive.TriggerProps = $props();
9
+ </script>
10
+
11
+ <DialogPrimitive.Trigger bind:ref data-slot="sheet-trigger" {type} {...restProps} />
@@ -0,0 +1,4 @@
1
+ import { Dialog as DialogPrimitive } from 'bits-ui';
2
+ declare const SheetTrigger: import("svelte").Component<DialogPrimitive.TriggerProps, {}, "ref">;
3
+ type SheetTrigger = ReturnType<typeof SheetTrigger>;
4
+ export default SheetTrigger;
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import { Dialog as DialogPrimitive } from 'bits-ui';
3
+
4
+ let { open = $bindable(false), ...restProps }: DialogPrimitive.RootProps = $props();
5
+ </script>
6
+
7
+ <DialogPrimitive.Root bind:open {...restProps} />
@@ -0,0 +1,3 @@
1
+ declare const Sheet: import("svelte").Component<import("bits-ui").AlertDialogRootPropsWithoutHTML, {}, "open">;
2
+ type Sheet = ReturnType<typeof Sheet>;
3
+ export default Sheet;
@@ -12,6 +12,6 @@
12
12
  <div
13
13
  bind:this={ref}
14
14
  data-slot="skeleton"
15
- class={cn('bg-muted animate-pulse rounded-md', className)}
15
+ class={cn('bg-muted animate-pulse rounded-md motion-reduce:animate-none', className)}
16
16
  {...restProps}
17
17
  ></div>
package/dist/styles.css CHANGED
@@ -296,11 +296,19 @@
296
296
  /* Eyebrow / column-head tracking — pairs with text-2xs + uppercase. */
297
297
  --tracking-eyebrow: 0.06em;
298
298
 
299
+ /* The type scale, by role (README §The type scale). An app sets none of
300
+ these; a role with no key here is set in the component that owns it. */
301
+
299
302
  /* Page-title and large-readout size (PageHeader, StatCard). */
300
303
  --text-display: 1.75rem;
301
304
  --text-display--line-height: 2.125rem;
302
305
  --text-display--letter-spacing: -0.02em;
303
306
 
307
+ /* A section of a page, under its title (PageSection). */
308
+ --text-section: 1.25rem;
309
+ --text-section--line-height: 1.75rem;
310
+ --text-section--letter-spacing: -0.015em;
311
+
304
312
  /* Panel/card heading size — one step above the sm body default. */
305
313
  --text-body: 0.9375rem;
306
314