@poodle64/ui 2026.10.17 → 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 +94 -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/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 +1 -1
- package/registry/component-map.json +43 -4
- package/registry/component-map.md +9 -4
|
@@ -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
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poodle64/ui",
|
|
3
|
-
"version": "2026.10.
|
|
3
|
+
"version": "2026.10.18",
|
|
4
4
|
"description": "Household shared component layer: shadcn-svelte primitives (bits-ui) plus the composed page chrome every app builds its routes from, restyled by each app's @poodle64/design-tokens alias layer. One fix reaches every app.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"meta": {
|
|
3
3
|
"package": "@poodle64/ui",
|
|
4
|
-
"version": "2026.10.
|
|
4
|
+
"version": "2026.10.18",
|
|
5
5
|
"generatedBy": "scripts/generate-registry.mjs",
|
|
6
6
|
"source": "scripts/situations.json + package source (DO NOT EDIT the outputs by hand)",
|
|
7
|
-
"componentCount":
|
|
7
|
+
"componentCount": 76,
|
|
8
8
|
"situationCount": 20
|
|
9
9
|
},
|
|
10
10
|
"situations": [
|
|
@@ -291,7 +291,7 @@
|
|
|
291
291
|
{
|
|
292
292
|
"key": "library-data",
|
|
293
293
|
"title": "Library data the app fetched",
|
|
294
|
-
"description": "The estate's shared document-library surfaces — a faceted catalogue, one collection's detail, one document's detail, a ranked search answer — rendered from plain props the app maps its own API responses into. The package never fetches and never routes: the app owns the query, the offset and every link. Configuration is the schema-driven half (SchemaForm); library data is fixed components because its shape is stable.",
|
|
294
|
+
"description": "The estate's shared document-library surfaces — a faceted catalogue, one collection's detail, one document's detail, a document to read with its contents, a ranked search answer — rendered from plain props the app maps its own API responses into. The package never fetches and never routes: the app owns the query, the offset and every link. Configuration is the schema-driven half (SchemaForm); library data is fixed components because its shape is stable.",
|
|
295
295
|
"components": [
|
|
296
296
|
{
|
|
297
297
|
"name": "LibraryBrowse",
|
|
@@ -314,6 +314,13 @@
|
|
|
314
314
|
"props": "document, loading?, error?, collectionHref?, onOpenCollection?, actions?, children?",
|
|
315
315
|
"insteadOf": "a bespoke document page: identity dl, locations, tags and memberships hand-laid-out per app"
|
|
316
316
|
},
|
|
317
|
+
{
|
|
318
|
+
"name": "DocumentReader",
|
|
319
|
+
"dir": "document-reader",
|
|
320
|
+
"import": "@poodle64/ui/document-reader",
|
|
321
|
+
"props": "title?, subtitle?, breadcrumbs?, meta?, actions?, html?, children?, contents?, contentsLabel?, aside?, footer?, loading?, error?, onRetry?",
|
|
322
|
+
"insteadOf": "a hand-built markdown page: its own h1, back row, table of contents, scroll-spy and max-w-4xl; or a document body in a box under DocumentDetail"
|
|
323
|
+
},
|
|
317
324
|
{
|
|
318
325
|
"name": "SearchResults",
|
|
319
326
|
"dir": "search-results",
|
|
@@ -361,7 +368,7 @@
|
|
|
361
368
|
{
|
|
362
369
|
"key": "page-frame",
|
|
363
370
|
"title": "The frame every route shares",
|
|
364
|
-
"description": "The standing chrome — the app shell and its nav, the one page-title treatment, the persistent right-hand context column, a foldable working list beside the page's own content.",
|
|
371
|
+
"description": "The standing chrome — the app shell and its nav, the one page-title treatment and its trail, the page's own container and sections, the persistent right-hand context column, a foldable working list beside the page's own content.",
|
|
365
372
|
"components": [
|
|
366
373
|
{
|
|
367
374
|
"name": "AppShell",
|
|
@@ -391,6 +398,27 @@
|
|
|
391
398
|
"props": "title?, eyebrow?, breadcrumbs?, icon?, subtitle?, info?, meta?, actions?",
|
|
392
399
|
"insteadOf": "a hand-written <h1> and title bar (the drift gate fails this)"
|
|
393
400
|
},
|
|
401
|
+
{
|
|
402
|
+
"name": "Breadcrumbs",
|
|
403
|
+
"dir": "breadcrumbs",
|
|
404
|
+
"import": "@poodle64/ui/breadcrumbs",
|
|
405
|
+
"props": "items, label?",
|
|
406
|
+
"insteadOf": "a hand-written chevron trail in PageHeader's breadcrumbs snippet; PageHeader takes the same items as `breadcrumbs={[…]}`"
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
"name": "PageContainer",
|
|
410
|
+
"dir": "page-container",
|
|
411
|
+
"import": "@poodle64/ui/page-container",
|
|
412
|
+
"props": "children",
|
|
413
|
+
"insteadOf": "a per-page wrapper picking its own vertical rhythm (space-y-6, gap-10, …)"
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
"name": "PageSection",
|
|
417
|
+
"dir": "page-section",
|
|
418
|
+
"import": "@poodle64/ui/page-section",
|
|
419
|
+
"props": "title, level?, description?, count?, actions?, children?, id?",
|
|
420
|
+
"insteadOf": "a hand-styled section heading (an uppercase kicker, text-lg font-semibold, a display h2) and its own gap to the content under it"
|
|
421
|
+
},
|
|
394
422
|
{
|
|
395
423
|
"name": "RecordSwitcher",
|
|
396
424
|
"dir": "record-switcher",
|
|
@@ -503,6 +531,13 @@
|
|
|
503
531
|
"props": "message?",
|
|
504
532
|
"insteadOf": "a bare spinner or 'Loading…' you place by hand"
|
|
505
533
|
},
|
|
534
|
+
{
|
|
535
|
+
"name": "ContentSkeleton",
|
|
536
|
+
"dir": "content-skeleton",
|
|
537
|
+
"import": "@poodle64/ui/content-skeleton",
|
|
538
|
+
"props": "shape?, count?, label?",
|
|
539
|
+
"insteadOf": "bare Skeleton boxes sized by hand (h-44 rounded-xl, h-24) standing in for a list, tiles or a document body while the page's header is already drawn"
|
|
540
|
+
},
|
|
506
541
|
{
|
|
507
542
|
"name": "ErrorState",
|
|
508
543
|
"dir": "error-state",
|
|
@@ -590,6 +625,10 @@
|
|
|
590
625
|
"dir": "separator",
|
|
591
626
|
"import": "@poodle64/ui/separator"
|
|
592
627
|
},
|
|
628
|
+
{
|
|
629
|
+
"dir": "sheet",
|
|
630
|
+
"import": "@poodle64/ui/sheet"
|
|
631
|
+
},
|
|
593
632
|
{
|
|
594
633
|
"dir": "skeleton",
|
|
595
634
|
"import": "@poodle64/ui/skeleton"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @poodle64/ui — situation → component map
|
|
2
2
|
|
|
3
3
|
<!-- GENERATED by scripts/generate-registry.mjs from scripts/situations.json + package source. DO NOT EDIT. -->
|
|
4
|
-
Generated from `@poodle64/ui@2026.10.
|
|
4
|
+
Generated from `@poodle64/ui@2026.10.18`. 76 components, 20 situations.
|
|
5
5
|
|
|
6
6
|
**Read this before writing a `<div>`.** Find the SITUATION you are in below, then compose the component named for it — do not hand-build it from raw `Card` or utility classes. Import is `import { Name } from '<import path>'`. Props marked `?` are optional. This map is the retrieval step the [`frontend-design` skill] makes mandatory; the [CHI 2026 study] measured composing-from-a-registry at 95% design-system compliance against 71% for writing the CSS from a prose style guide.
|
|
7
7
|
|
|
@@ -128,13 +128,14 @@ _A config object whose shape arrives at runtime as a JSON Schema plus a JSON For
|
|
|
128
128
|
|
|
129
129
|
## Library data the app fetched
|
|
130
130
|
|
|
131
|
-
_The estate's shared document-library surfaces — a faceted catalogue, one collection's detail, one document's detail, a ranked search answer — rendered from plain props the app maps its own API responses into. The package never fetches and never routes: the app owns the query, the offset and every link. Configuration is the schema-driven half (SchemaForm); library data is fixed components because its shape is stable._
|
|
131
|
+
_The estate's shared document-library surfaces — a faceted catalogue, one collection's detail, one document's detail, a document to read with its contents, a ranked search answer — rendered from plain props the app maps its own API responses into. The package never fetches and never routes: the app owns the query, the offset and every link. Configuration is the schema-driven half (SchemaForm); library data is fixed components because its shape is stable._
|
|
132
132
|
|
|
133
133
|
| Component | Import | Key props | Reach for it instead of |
|
|
134
134
|
| --- | --- | --- | --- |
|
|
135
135
|
| `LibraryBrowse` | `@poodle64/ui/library-browse` | `documents, facets?, query?, total?, offset?, limit?, loading?, error?, onQueryChange?, onFacetChange?, onPageChange?, documentHref?, onOpenDocument?, toolbar?` | a hand-built catalogue page: search box, facet rail, filter chips, results table and pager re-derived per app |
|
|
136
136
|
| `CollectionDetail` | `@poodle64/ui/collection-detail` | `collection, stats?, documents?, documentsTotal?, loading?, error?, documentsLoading?, documentsError?, onPageChange?, documentHref?, onOpenDocument?, actions?, children?` | a bespoke collection page assembled from raw Card, a hand-built table and its own stat rows |
|
|
137
137
|
| `DocumentDetail` | `@poodle64/ui/document-detail` | `document, loading?, error?, collectionHref?, onOpenCollection?, actions?, children?` | a bespoke document page: identity dl, locations, tags and memberships hand-laid-out per app |
|
|
138
|
+
| `DocumentReader` | `@poodle64/ui/document-reader` | `title?, subtitle?, breadcrumbs?, meta?, actions?, html?, children?, contents?, contentsLabel?, aside?, footer?, loading?, error?, onRetry?` | a hand-built markdown page: its own h1, back row, table of contents, scroll-spy and max-w-4xl; or a document body in a box under DocumentDetail |
|
|
138
139
|
| `SearchResults` | `@poodle64/ui/search-results` | `results, query?, total?, loading?, error?, resultHref?, onOpen?, onRetry?` | a hand-built ranked hit list minting its own highlight and relevance styling |
|
|
139
140
|
|
|
140
141
|
## A document a machine read, with evidence outlined
|
|
@@ -156,7 +157,7 @@ _People, organisations, sources or any entities as nodes and their relations as
|
|
|
156
157
|
|
|
157
158
|
## The frame every route shares
|
|
158
159
|
|
|
159
|
-
_The standing chrome — the app shell and its nav, the one page-title treatment, the persistent right-hand context column, a foldable working list beside the page's own content._
|
|
160
|
+
_The standing chrome — the app shell and its nav, the one page-title treatment and its trail, the page's own container and sections, the persistent right-hand context column, a foldable working list beside the page's own content._
|
|
160
161
|
|
|
161
162
|
| Component | Import | Key props | Reach for it instead of |
|
|
162
163
|
| --- | --- | --- | --- |
|
|
@@ -164,6 +165,9 @@ _The standing chrome — the app shell and its nav, the one page-title treatment
|
|
|
164
165
|
| `ShellControls` | `@poodle64/ui/app-shell` | `children` | a scope row (entity, financial year, chart/table) hand-placed above the page body; the shell's top bar carries it |
|
|
165
166
|
| `Segmented` | `@poodle64/ui/segmented` | `value, options, label, size?` | a hand-built row of aria-pressed buttons for a small fixed choice |
|
|
166
167
|
| `PageHeader` | `@poodle64/ui/page-header` | `title?, eyebrow?, breadcrumbs?, icon?, subtitle?, info?, meta?, actions?` | a hand-written <h1> and title bar (the drift gate fails this) |
|
|
168
|
+
| `Breadcrumbs` | `@poodle64/ui/breadcrumbs` | `items, label?` | a hand-written chevron trail in PageHeader's breadcrumbs snippet; PageHeader takes the same items as `breadcrumbs={[…]}` |
|
|
169
|
+
| `PageContainer` | `@poodle64/ui/page-container` | `children` | a per-page wrapper picking its own vertical rhythm (space-y-6, gap-10, …) |
|
|
170
|
+
| `PageSection` | `@poodle64/ui/page-section` | `title, level?, description?, count?, actions?, children?, id?` | a hand-styled section heading (an uppercase kicker, text-lg font-semibold, a display h2) and its own gap to the content under it |
|
|
167
171
|
| `RecordSwitcher` | `@poodle64/ui/record-switcher` | `name, groups, current?, noun?, placeholder?, icon?, all?, pages?, separator?` | a bare record name beside a small chevrons button in the top bar, and a dropdown of names with no search, groups or thumbnails; the record's own page tabs come with it |
|
|
168
172
|
| `ContextColumn` | `@poodle64/ui/context-column` | `stats?, statsTitle?, statsInfo?, detail?, title?, subtitle?, onClose?, children?, documentPane?, ariaLabel?` | a hand-built right-hand <aside> with a stat card and a detail pane; on a record page, the one opened item (title, close, an inner scroll) and its DocumentPane, in the column's place or beside it once the page's row has room |
|
|
169
173
|
| `ListShell` | `@poodle64/ui/list-shell` | `title, children, label?, open?, actions?` | a module hand-rolling its own foldable second column beside the rail — a queue, an inbox, a working list |
|
|
@@ -198,11 +202,12 @@ _A surface with nothing to show yet, still loading, or that failed to load — t
|
|
|
198
202
|
| --- | --- | --- | --- |
|
|
199
203
|
| `EmptyState` | `@poodle64/ui/empty-state` | `title, icon?, description?, action?` | a hand-centred 'Nothing here' message |
|
|
200
204
|
| `LoadingState` | `@poodle64/ui/loading-state` | `message?` | a bare spinner or 'Loading…' you place by hand |
|
|
205
|
+
| `ContentSkeleton` | `@poodle64/ui/content-skeleton` | `shape?, count?, label?` | bare Skeleton boxes sized by hand (h-44 rounded-xl, h-24) standing in for a list, tiles or a document body while the page's header is already drawn |
|
|
201
206
|
| `ErrorState` | `@poodle64/ui/error-state` | `message, action?` | a hand-built error message with a retry button |
|
|
202
207
|
|
|
203
208
|
## Primitives you already know
|
|
204
209
|
|
|
205
210
|
_Standard shadcn-svelte / bits-ui primitives — reach for them the same way; no situation lookup needed. Import each from its path below._
|
|
206
211
|
|
|
207
|
-
`@poodle64/ui/alert` · `@poodle64/ui/alert-dialog` · `@poodle64/ui/avatar` · `@poodle64/ui/badge` · `@poodle64/ui/button` · `@poodle64/ui/card` · `@poodle64/ui/checkbox` · `@poodle64/ui/command` · `@poodle64/ui/data-table` · `@poodle64/ui/dialog` · `@poodle64/ui/dropdown-menu` · `@poodle64/ui/input` · `@poodle64/ui/input-group` · `@poodle64/ui/label` · `@poodle64/ui/password-input` · `@poodle64/ui/popover` · `@poodle64/ui/progress` · `@poodle64/ui/select` · `@poodle64/ui/separator` · `@poodle64/ui/skeleton` · `@poodle64/ui/sonner` · `@poodle64/ui/switch` · `@poodle64/ui/table` · `@poodle64/ui/tabs` · `@poodle64/ui/textarea` · `@poodle64/ui/tooltip`
|
|
212
|
+
`@poodle64/ui/alert` · `@poodle64/ui/alert-dialog` · `@poodle64/ui/avatar` · `@poodle64/ui/badge` · `@poodle64/ui/button` · `@poodle64/ui/card` · `@poodle64/ui/checkbox` · `@poodle64/ui/command` · `@poodle64/ui/data-table` · `@poodle64/ui/dialog` · `@poodle64/ui/dropdown-menu` · `@poodle64/ui/input` · `@poodle64/ui/input-group` · `@poodle64/ui/label` · `@poodle64/ui/password-input` · `@poodle64/ui/popover` · `@poodle64/ui/progress` · `@poodle64/ui/select` · `@poodle64/ui/separator` · `@poodle64/ui/sheet` · `@poodle64/ui/skeleton` · `@poodle64/ui/sonner` · `@poodle64/ui/switch` · `@poodle64/ui/table` · `@poodle64/ui/tabs` · `@poodle64/ui/textarea` · `@poodle64/ui/tooltip`
|
|
208
213
|
|