@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.
- package/README.md +135 -11
- package/dist/components/feedback/report-widget.svelte +4 -1
- package/dist/components/feedback/report-widget.svelte.d.ts +1 -0
- package/dist/components/ui/app-identity/app-identity.svelte +7 -2
- package/dist/components/ui/app-shell/texture.d.ts +5 -5
- package/dist/components/ui/app-shell/texture.js +3 -3
- package/dist/components/ui/breadcrumbs/breadcrumbs.svelte +70 -0
- package/dist/components/ui/breadcrumbs/breadcrumbs.svelte.d.ts +32 -0
- package/dist/components/ui/breadcrumbs/index.d.ts +2 -0
- package/dist/components/ui/breadcrumbs/index.js +2 -0
- package/dist/components/ui/content-skeleton/content-skeleton.svelte +94 -0
- package/dist/components/ui/content-skeleton/content-skeleton.svelte.d.ts +25 -0
- package/dist/components/ui/content-skeleton/index.d.ts +2 -0
- package/dist/components/ui/content-skeleton/index.js +2 -0
- package/dist/components/ui/document-reader/document-reader.svelte +336 -0
- package/dist/components/ui/document-reader/document-reader.svelte.d.ts +65 -0
- package/dist/components/ui/document-reader/index.d.ts +2 -0
- package/dist/components/ui/document-reader/index.js +2 -0
- package/dist/components/ui/graph-canvas/graph-canvas.svelte +922 -0
- package/dist/components/ui/graph-canvas/graph-canvas.svelte.d.ts +73 -0
- package/dist/components/ui/graph-canvas/index.d.ts +3 -0
- package/dist/components/ui/graph-canvas/index.js +2 -0
- package/dist/components/ui/graph-canvas/scene.d.ts +107 -0
- package/dist/components/ui/graph-canvas/scene.js +562 -0
- package/dist/components/ui/graph-canvas/types.d.ts +33 -0
- package/dist/components/ui/graph-canvas/types.js +1 -0
- package/dist/components/ui/page-container/index.d.ts +2 -0
- package/dist/components/ui/page-container/index.js +2 -0
- package/dist/components/ui/page-container/page-container.svelte +39 -0
- package/dist/components/ui/page-container/page-container.svelte.d.ts +24 -0
- package/dist/components/ui/page-header/page-header.svelte +12 -7
- package/dist/components/ui/page-header/page-header.svelte.d.ts +3 -2
- package/dist/components/ui/page-section/index.d.ts +2 -0
- package/dist/components/ui/page-section/index.js +2 -0
- package/dist/components/ui/page-section/page-section.svelte +92 -0
- package/dist/components/ui/page-section/page-section.svelte.d.ts +36 -0
- package/dist/components/ui/sheet/index.d.ts +13 -0
- package/dist/components/ui/sheet/index.js +15 -0
- package/dist/components/ui/sheet/sheet-body.svelte +21 -0
- package/dist/components/ui/sheet/sheet-body.svelte.d.ts +5 -0
- package/dist/components/ui/sheet/sheet-close.svelte +11 -0
- package/dist/components/ui/sheet/sheet-close.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/sheet-content.svelte +70 -0
- package/dist/components/ui/sheet/sheet-content.svelte.d.ts +37 -0
- package/dist/components/ui/sheet/sheet-description.svelte +20 -0
- package/dist/components/ui/sheet/sheet-description.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/sheet-footer.svelte +23 -0
- package/dist/components/ui/sheet/sheet-footer.svelte.d.ts +5 -0
- package/dist/components/ui/sheet/sheet-header.svelte +21 -0
- package/dist/components/ui/sheet/sheet-header.svelte.d.ts +5 -0
- package/dist/components/ui/sheet/sheet-overlay.svelte +20 -0
- package/dist/components/ui/sheet/sheet-overlay.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/sheet-portal.svelte +7 -0
- package/dist/components/ui/sheet/sheet-portal.svelte.d.ts +3 -0
- package/dist/components/ui/sheet/sheet-title.svelte +21 -0
- package/dist/components/ui/sheet/sheet-title.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/sheet-trigger.svelte +11 -0
- package/dist/components/ui/sheet/sheet-trigger.svelte.d.ts +4 -0
- package/dist/components/ui/sheet/sheet.svelte +7 -0
- package/dist/components/ui/sheet/sheet.svelte.d.ts +3 -0
- package/dist/components/ui/skeleton/skeleton.svelte +1 -1
- package/dist/styles.css +8 -0
- package/package.json +4 -2
- package/registry/component-map.json +58 -5
- 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
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
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
|
|
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
|
|
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,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,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,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,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,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} />
|
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
|
|