@poodle64/ui 2026.10.4 → 2026.10.6

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 (46) hide show
  1. package/README.md +101 -5
  2. package/dist/components/ui/context-column/context-column.svelte +118 -21
  3. package/dist/components/ui/context-column/context-column.svelte.d.ts +24 -1
  4. package/dist/components/ui/document-pane/document-pane.svelte +136 -0
  5. package/dist/components/ui/document-pane/document-pane.svelte.d.ts +43 -0
  6. package/dist/components/ui/document-pane/index.d.ts +2 -0
  7. package/dist/components/ui/document-pane/index.js +2 -0
  8. package/dist/components/ui/ledger/head-cell.svelte +73 -0
  9. package/dist/components/ui/ledger/head-cell.svelte.d.ts +19 -0
  10. package/dist/components/ui/ledger/index.d.ts +1 -1
  11. package/dist/components/ui/ledger/ledger-columns.svelte +29 -21
  12. package/dist/components/ui/ledger/ledger-columns.svelte.d.ts +50 -13
  13. package/dist/components/ui/ledger/ledger.d.ts +6 -0
  14. package/dist/components/ui/ledger/ledger.js +9 -1
  15. package/dist/components/ui/ledger/ledger.svelte +61 -88
  16. package/dist/components/ui/ledger/ledger.svelte.d.ts +7 -2
  17. package/dist/components/ui/ledger/look.d.ts +41 -0
  18. package/dist/components/ui/ledger/look.js +43 -0
  19. package/dist/components/ui/ledger/types.d.ts +21 -11
  20. package/dist/components/ui/list-toolbar/icon-action.svelte +42 -0
  21. package/dist/components/ui/list-toolbar/icon-action.svelte.d.ts +7 -0
  22. package/dist/components/ui/list-toolbar/index.d.ts +3 -0
  23. package/dist/components/ui/list-toolbar/index.js +2 -0
  24. package/dist/components/ui/list-toolbar/list-toolbar.svelte +85 -0
  25. package/dist/components/ui/list-toolbar/list-toolbar.svelte.d.ts +32 -0
  26. package/dist/components/ui/list-toolbar/types.d.ts +18 -0
  27. package/dist/components/ui/list-toolbar/types.js +1 -0
  28. package/dist/components/ui/panel/panel.svelte +8 -1
  29. package/dist/components/ui/panel/panel.svelte.d.ts +6 -0
  30. package/dist/components/ui/record-list/index.d.ts +3 -0
  31. package/dist/components/ui/record-list/index.js +2 -0
  32. package/dist/components/ui/record-list/record-list.svelte +482 -0
  33. package/dist/components/ui/record-list/record-list.svelte.d.ts +89 -0
  34. package/dist/components/ui/record-list/thumbnail.svelte +32 -0
  35. package/dist/components/ui/record-list/thumbnail.svelte.d.ts +14 -0
  36. package/dist/components/ui/record-list/types.d.ts +40 -0
  37. package/dist/components/ui/record-list/types.js +1 -0
  38. package/dist/components/ui/record-switcher/index.d.ts +3 -0
  39. package/dist/components/ui/record-switcher/index.js +2 -0
  40. package/dist/components/ui/record-switcher/record-switcher.svelte +167 -0
  41. package/dist/components/ui/record-switcher/record-switcher.svelte.d.ts +28 -0
  42. package/dist/components/ui/record-switcher/types.d.ts +22 -0
  43. package/dist/components/ui/record-switcher/types.js +1 -0
  44. package/package.json +1 -1
  45. package/registry/component-map.json +34 -6
  46. package/registry/component-map.md +8 -4
@@ -0,0 +1,42 @@
1
+ <script lang="ts">
2
+ /** An icon button, or an icon link, named by its tooltip. Inside a `Tooltip.Provider`. */
3
+ import { mergeProps } from 'bits-ui';
4
+ import { buttonVariants } from '../button/index.js';
5
+ import * as Tooltip from '../tooltip/index.js';
6
+ import type { ListIconAction } from './types.js';
7
+
8
+ let { action }: { action: ListIconAction } = $props();
9
+ const Icon = $derived(action.icon);
10
+ const klass = buttonVariants({ variant: 'ghost', size: 'icon-sm' });
11
+
12
+ /** The trigger's own handlers (a click closes the tooltip) chained with the action's. */
13
+ const merged = (props: Record<string, unknown>) =>
14
+ mergeProps(props, { onclick: action.onclick, class: klass, 'aria-label': action.label });
15
+ /** A link takes no button `type`. */
16
+ function asLink(props: Record<string, unknown>) {
17
+ const { type: _type, ...rest } = merged(props);
18
+ return rest;
19
+ }
20
+ </script>
21
+
22
+ <Tooltip.Root>
23
+ <Tooltip.Trigger>
24
+ {#snippet child({ props })}
25
+ {#if action.href && !action.disabled}
26
+ <a
27
+ {...asLink(props)}
28
+ href={action.href}
29
+ download={action.download === true ? '' : action.download || undefined}
30
+ data-slot="list-action"
31
+ >
32
+ <Icon />
33
+ </a>
34
+ {:else}
35
+ <button {...merged(props)} type="button" disabled={action.disabled} data-slot="list-action">
36
+ <Icon />
37
+ </button>
38
+ {/if}
39
+ {/snippet}
40
+ </Tooltip.Trigger>
41
+ <Tooltip.Content side="bottom">{action.label}</Tooltip.Content>
42
+ </Tooltip.Root>
@@ -0,0 +1,7 @@
1
+ import type { ListIconAction } from './types.js';
2
+ type $$ComponentProps = {
3
+ action: ListIconAction;
4
+ };
5
+ declare const IconAction: import("svelte").Component<$$ComponentProps, {}, "">;
6
+ type IconAction = ReturnType<typeof IconAction>;
7
+ export default IconAction;
@@ -0,0 +1,3 @@
1
+ export { default as ListToolbar } from './list-toolbar.svelte';
2
+ export { default } from './list-toolbar.svelte';
3
+ export type { ListAction, ListIconAction } from './types.js';
@@ -0,0 +1,2 @@
1
+ export { default as ListToolbar } from './list-toolbar.svelte';
2
+ export { default } from './list-toolbar.svelte';
@@ -0,0 +1,85 @@
1
+ <script lang="ts">
2
+ /**
3
+ * The bar above a list, on the page ground: the list's title and count,
4
+ * then its icon actions (each named by its tooltip) and its one labelled
5
+ * action. The ledger draws its own with this, so every list's bar is the
6
+ * same bar.
7
+ *
8
+ * <ListToolbar title="Owned properties" meta="3 properties"
9
+ * tools={[{ label: 'Download as CSV', icon: Download, onclick: save }]}
10
+ * action={{ label: 'Add property', icon: Plus, href: '/property/new' }} />
11
+ */
12
+ import type { Snippet } from 'svelte';
13
+ import type { HTMLAttributes } from 'svelte/elements';
14
+ import Button from '../button/button.svelte';
15
+ import * as Tooltip from '../tooltip/index.js';
16
+ import IconAction from './icon-action.svelte';
17
+ import { cn } from '../../../utils.js';
18
+ import type { ListAction, ListIconAction } from './types.js';
19
+
20
+ let {
21
+ title,
22
+ meta,
23
+ leading,
24
+ children,
25
+ tools = [],
26
+ action,
27
+ label,
28
+ class: className,
29
+ ...restProps
30
+ }: Omit<HTMLAttributes<HTMLDivElement>, 'title'> & {
31
+ title?: string;
32
+ /** Beside the title, quieter: the count, or what the list is of. */
33
+ meta?: string;
34
+ /** Before the title: a switch between views of the same list. */
35
+ leading?: Snippet;
36
+ /** The list's own controls, before its icon actions: a menu, a filter. */
37
+ children?: Snippet;
38
+ /** Icon actions, each named by its tooltip. */
39
+ tools?: ListIconAction[];
40
+ /** The one labelled action, last. */
41
+ action?: ListAction;
42
+ /** The toolbar's accessible name. Defaults to the title. */
43
+ label?: string;
44
+ class?: string;
45
+ } = $props();
46
+
47
+ const ActionIcon = $derived(action?.icon);
48
+ </script>
49
+
50
+ <div
51
+ role="toolbar"
52
+ aria-label={label ?? title}
53
+ class={cn('flex min-h-11 flex-none items-center gap-2 px-2 pb-2', className)}
54
+ data-slot="list-toolbar"
55
+ {...restProps}
56
+ >
57
+ {@render leading?.()}
58
+ <!-- Crowded, the count gives way before the title, and the title ends in an ellipsis. -->
59
+ <div class="flex min-w-0 items-baseline gap-2.5 whitespace-nowrap">
60
+ {#if title}<h2 class="text-body min-w-0 truncate font-semibold">{title}</h2>{/if}
61
+ {#if meta}<span class="text-muted-foreground min-w-0 shrink-[100] truncate text-sm">{meta}</span>{/if}
62
+ </div>
63
+ <span class="min-w-0 flex-1"></span>
64
+ {@render children?.()}
65
+ {#if tools.length}
66
+ <Tooltip.Provider delayDuration={150}>
67
+ {#each tools as tool (tool.label)}
68
+ <IconAction action={tool} />
69
+ {/each}
70
+ </Tooltip.Provider>
71
+ {/if}
72
+ {#if action}
73
+ <Button
74
+ variant="outline"
75
+ size="sm"
76
+ href={action.href}
77
+ download={action.href ? (action.download === true ? '' : action.download || undefined) : undefined}
78
+ disabled={action.disabled}
79
+ onclick={action.onclick}
80
+ data-slot="list-toolbar-action"
81
+ >
82
+ {#if ActionIcon}<ActionIcon />{/if}{action.label}
83
+ </Button>
84
+ {/if}
85
+ </div>
@@ -0,0 +1,32 @@
1
+ /**
2
+ * The bar above a list, on the page ground: the list's title and count,
3
+ * then its icon actions (each named by its tooltip) and its one labelled
4
+ * action. The ledger draws its own with this, so every list's bar is the
5
+ * same bar.
6
+ *
7
+ * <ListToolbar title="Owned properties" meta="3 properties"
8
+ * tools={[{ label: 'Download as CSV', icon: Download, onclick: save }]}
9
+ * action={{ label: 'Add property', icon: Plus, href: '/property/new' }} />
10
+ */
11
+ import type { Snippet } from 'svelte';
12
+ import type { HTMLAttributes } from 'svelte/elements';
13
+ import type { ListAction, ListIconAction } from './types.js';
14
+ type $$ComponentProps = Omit<HTMLAttributes<HTMLDivElement>, 'title'> & {
15
+ title?: string;
16
+ /** Beside the title, quieter: the count, or what the list is of. */
17
+ meta?: string;
18
+ /** Before the title: a switch between views of the same list. */
19
+ leading?: Snippet;
20
+ /** The list's own controls, before its icon actions: a menu, a filter. */
21
+ children?: Snippet;
22
+ /** Icon actions, each named by its tooltip. */
23
+ tools?: ListIconAction[];
24
+ /** The one labelled action, last. */
25
+ action?: ListAction;
26
+ /** The toolbar's accessible name. Defaults to the title. */
27
+ label?: string;
28
+ class?: string;
29
+ };
30
+ declare const ListToolbar: import("svelte").Component<$$ComponentProps, {}, "">;
31
+ type ListToolbar = ReturnType<typeof ListToolbar>;
32
+ export default ListToolbar;
@@ -0,0 +1,18 @@
1
+ import type { IconComponent } from '../app-shell/types.js';
2
+ /**
3
+ * One action a list or a pane offers: a button, or a link when it has `href`.
4
+ * As an icon action its `label` is the tooltip and the accessible name.
5
+ */
6
+ export interface ListAction {
7
+ label: string;
8
+ icon?: IconComponent;
9
+ onclick?: (event: MouseEvent) => void;
10
+ href?: string;
11
+ /** On a link, saves the target rather than opening it; a string names the file. */
12
+ download?: boolean | string;
13
+ disabled?: boolean;
14
+ }
15
+ /** An action drawn as its icon alone. */
16
+ export type ListIconAction = ListAction & {
17
+ icon: IconComponent;
18
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -25,6 +25,7 @@
25
25
  tone = 'default',
26
26
  children,
27
27
  pad = true,
28
+ scroll = false,
28
29
  class: klass = '',
29
30
  ref = $bindable(null),
30
31
  ...restProps
@@ -70,6 +71,12 @@
70
71
  tone?: 'default' | 'destructive';
71
72
  children: Snippet;
72
73
  pad?: boolean;
74
+ /**
75
+ * The body scrolls inside the card, under a header that stays: the card
76
+ * is as tall as what it holds up to the height its container gives it,
77
+ * and the full height when given one (`h-full`).
78
+ */
79
+ scroll?: boolean;
73
80
  } = $props();
74
81
 
75
82
  const destructive = $derived(tone === 'destructive');
@@ -124,7 +131,7 @@
124
131
  {/if}
125
132
  </header>
126
133
  {/if}
127
- <div class={pad ? 'p-4' : ''}>
134
+ <div class={cn(pad && 'p-4', scroll && 'min-h-0 flex-1 overflow-y-auto')} data-slot="panel-body">
128
135
  {@render children()}
129
136
  </div>
130
137
  {#if footer}
@@ -45,6 +45,12 @@ type $$ComponentProps = WithElementRef<HTMLAttributes<HTMLElement>> & {
45
45
  tone?: 'default' | 'destructive';
46
46
  children: Snippet;
47
47
  pad?: boolean;
48
+ /**
49
+ * The body scrolls inside the card, under a header that stays: the card
50
+ * is as tall as what it holds up to the height its container gives it,
51
+ * and the full height when given one (`h-full`).
52
+ */
53
+ scroll?: boolean;
48
54
  };
49
55
  declare const Panel: Component<$$ComponentProps, {}, "ref">;
50
56
  type Panel = ReturnType<typeof Panel>;
@@ -0,0 +1,3 @@
1
+ export { default as RecordList } from './record-list.svelte';
2
+ export { default } from './record-list.svelte';
3
+ export type { RecordFlag, RecordListColumn, RecordListPreferences, RecordListRow } from './types.js';
@@ -0,0 +1,2 @@
1
+ export { default as RecordList } from './record-list.svelte';
2
+ export { default } from './record-list.svelte';