@adea-ai/ui 0.81.1 → 0.82.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +41 -8
  2. package/dist/components/composites/account-menu/account-menu.d.ts +5 -0
  3. package/dist/components/composites/account-menu/account-menu.d.ts.map +1 -1
  4. package/dist/components/composites/account-menu/account-menu.js +122 -70
  5. package/dist/components/composites/account-menu/account-menu.js.map +1 -1
  6. package/dist/components/composites/action-button/action-button.d.ts +27 -0
  7. package/dist/components/composites/action-button/action-button.d.ts.map +1 -0
  8. package/dist/components/composites/action-button/action-button.js +121 -0
  9. package/dist/components/composites/action-button/action-button.js.map +1 -0
  10. package/dist/components/composites/action-button/index.d.ts +3 -0
  11. package/dist/components/composites/action-button/index.d.ts.map +1 -0
  12. package/dist/components/composites/action-button/index.js +2 -0
  13. package/dist/components/conversation/thread-panel.d.ts +2 -0
  14. package/dist/components/conversation/thread-panel.d.ts.map +1 -1
  15. package/dist/components/conversation/thread-panel.js +36 -31
  16. package/dist/components/conversation/thread-panel.js.map +1 -1
  17. package/dist/components/layout/sidebar-nav/index.d.ts +1 -1
  18. package/dist/components/layout/sidebar-nav/index.d.ts.map +1 -1
  19. package/dist/components/layout/sidebar-nav/sidebar-nav.d.ts +6 -1
  20. package/dist/components/layout/sidebar-nav/sidebar-nav.d.ts.map +1 -1
  21. package/dist/components/layout/sidebar-nav/sidebar-nav.js +66 -62
  22. package/dist/components/layout/sidebar-nav/sidebar-nav.js.map +1 -1
  23. package/dist/components/ui/board/board.d.ts.map +1 -1
  24. package/dist/components/ui/board/board.js +54 -7
  25. package/dist/components/ui/board/board.js.map +1 -1
  26. package/dist/components/ui/command/command.d.ts +5 -1
  27. package/dist/components/ui/command/command.d.ts.map +1 -1
  28. package/dist/components/ui/command/command.js +8 -3
  29. package/dist/components/ui/command/command.js.map +1 -1
  30. package/dist/components/ui/input/index.d.ts +1 -1
  31. package/dist/components/ui/input/index.d.ts.map +1 -1
  32. package/dist/components/ui/input/input.d.ts +5 -1
  33. package/dist/components/ui/input/input.d.ts.map +1 -1
  34. package/dist/components/ui/input/input.js +36 -17
  35. package/dist/components/ui/input/input.js.map +1 -1
  36. package/dist/index.d.ts +1 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +2 -1
  39. package/dist/r/account-menu.json +1 -0
  40. package/dist/r/action-button.json +24 -0
  41. package/dist/r/conversation.json +1 -0
  42. package/dist/r/registry.json +26 -0
  43. package/dist/r/src/components/composites/account-menu/account-menu.tsx +100 -44
  44. package/dist/r/src/components/composites/action-button/action-button.tsx +139 -0
  45. package/dist/r/src/components/composites/action-button/index.ts +2 -0
  46. package/dist/r/src/components/conversation/thread-panel.tsx +22 -12
  47. package/dist/r/src/components/layout/sidebar-nav/index.ts +1 -0
  48. package/dist/r/src/components/layout/sidebar-nav/sidebar-nav.tsx +29 -21
  49. package/dist/r/src/components/ui/board/board.tsx +74 -6
  50. package/dist/r/src/components/ui/command/command.tsx +15 -4
  51. package/dist/r/src/components/ui/input/index.ts +1 -1
  52. package/dist/r/src/components/ui/input/input.tsx +38 -21
  53. package/package.json +1 -1
  54. package/registry.json +26 -0
  55. package/src/components/composites/account-menu/account-menu.tsx +100 -44
  56. package/src/components/composites/action-button/action-button.tsx +139 -0
  57. package/src/components/composites/action-button/index.ts +2 -0
  58. package/src/components/conversation/thread-panel.tsx +22 -12
  59. package/src/components/layout/sidebar-nav/index.ts +1 -0
  60. package/src/components/layout/sidebar-nav/sidebar-nav.tsx +29 -21
  61. package/src/components/ui/board/board.tsx +74 -6
  62. package/src/components/ui/command/command.tsx +15 -4
  63. package/src/components/ui/input/index.ts +1 -1
  64. package/src/components/ui/input/input.tsx +38 -21
  65. package/src/index.ts +1 -0
@@ -1,7 +1,7 @@
1
1
  import { cn } from "../../../lib/utils.js";
2
2
  import { cva } from "../../../lib/variants.js";
3
- import { className, createComponent, delegateEvents, effect, insert, setAttribute, template } from "solid-js/web";
4
- import { For, Show, createMemo, createSignal, splitProps } from "solid-js";
3
+ import { className, createComponent, delegateEvents, effect, insert, setAttribute, template, use } from "solid-js/web";
4
+ import { For, Show, createEffect, createMemo, createSignal, onCleanup, splitProps } from "solid-js";
5
5
  //#region src/components/ui/board/board.tsx
6
6
  var _tmpl$ = /*#__PURE__*/ template(`<div role=region tabindex=0><div class=visually-hidden role=status aria-live=polite>`);
7
7
  var _tmpl$2 = /*#__PURE__*/ template(`<span class="text-2xs text-muted-foreground">`);
@@ -30,6 +30,43 @@ function Board(props) {
30
30
  const [dragging, setDragging] = createSignal(null);
31
31
  const [overColumn, setOverColumn] = createSignal(null);
32
32
  const [announcement, setAnnouncement] = createSignal("");
33
+ const cardElements = /* @__PURE__ */ new Map();
34
+ const [pendingFocus, setPendingFocus] = createSignal(null);
35
+ const cancelOnPointer = () => setPendingFocus(null);
36
+ createEffect(() => {
37
+ const pending = pendingFocus();
38
+ if (!pending) return;
39
+ const document = pending.source.ownerDocument;
40
+ const cancelOnFocus = (event) => {
41
+ if (!pending.source.contains(event.target)) setPendingFocus(null);
42
+ };
43
+ document.addEventListener("focusin", cancelOnFocus);
44
+ document.addEventListener("pointerdown", cancelOnPointer);
45
+ onCleanup(() => {
46
+ document.removeEventListener("focusin", cancelOnFocus);
47
+ document.removeEventListener("pointerdown", cancelOnPointer);
48
+ });
49
+ });
50
+ createEffect(() => {
51
+ const pending = pendingFocus();
52
+ if (!pending) return;
53
+ const moved = local.items.find((item) => local.itemId(item) === pending.itemId);
54
+ if (!moved || local.itemColumn(moved) !== pending.columnId) return;
55
+ queueMicrotask(() => {
56
+ if (pendingFocus() !== pending) return;
57
+ const target = cardElements.get(pending.itemId);
58
+ setPendingFocus(null);
59
+ if (target?.isConnected) target.focus();
60
+ });
61
+ });
62
+ const prepareFocus = (item, columnId, source) => {
63
+ const card = source ?? cardElements.get(local.itemId(item));
64
+ if (card?.contains(card.ownerDocument.activeElement)) setPendingFocus({
65
+ itemId: local.itemId(item),
66
+ columnId,
67
+ source: card
68
+ });
69
+ };
33
70
  const byColumn = createMemo(() => {
34
71
  const grouped = /* @__PURE__ */ new Map();
35
72
  for (const column of local.columns) grouped.set(column.id, []);
@@ -43,9 +80,11 @@ function Board(props) {
43
80
  const drop = (column) => {
44
81
  const item = dragging();
45
82
  const from = item ? local.itemColumn(item) : null;
83
+ const accepted = accepts(column);
46
84
  setDragging(null);
47
85
  setOverColumn(null);
48
- if (!item || !from || from === column.id || !accepts(column)) return;
86
+ if (!item || !from || from === column.id || !accepted) return;
87
+ prepareFocus(item, column.id);
49
88
  local.onMove({
50
89
  itemId: local.itemId(item),
51
90
  from,
@@ -57,15 +96,16 @@ function Board(props) {
57
96
  * thing within its container" that does not collide with scrolling or with the
58
97
  * text caret, and it is the same chord a browser tab or a spreadsheet uses.
59
98
  */
60
- const moveByKeyboard = (item, direction) => {
99
+ const moveByKeyboard = (item, direction, source) => {
61
100
  const from = local.itemColumn(item);
62
101
  const index = local.columns.findIndex((column) => column.id === from);
63
- const candidates = local.columns.slice(index + direction);
64
- const target = (direction === 1 ? candidates : candidates.toReversed()).find((column) => !column.disabled && local.canDrop(item, from, column.id));
102
+ if (index < 0) return;
103
+ const target = (direction === 1 ? local.columns.slice(index + 1) : local.columns.slice(0, index).toReversed()).find((column) => !column.disabled && local.canDrop(item, from, column.id));
65
104
  if (!target) {
66
105
  setAnnouncement(`No column after ${from} accepts this item`);
67
106
  return;
68
107
  }
108
+ prepareFocus(item, target.id, source);
69
109
  local.onMove({
70
110
  itemId: local.itemId(item),
71
111
  from,
@@ -118,13 +158,20 @@ function Board(props) {
118
158
  if (!(event.ctrlKey || event.metaKey)) return;
119
159
  if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") return;
120
160
  event.preventDefault();
121
- moveByKeyboard(item, event.key === "ArrowRight" ? 1 : -1);
161
+ moveByKeyboard(item, event.key === "ArrowRight" ? 1 : -1, event.currentTarget);
122
162
  };
123
163
  _el$9.addEventListener("dragend", () => {
124
164
  setDragging(null);
125
165
  setOverColumn(null);
126
166
  });
127
167
  _el$9.addEventListener("dragstart", () => setDragging(() => item));
168
+ use((element) => {
169
+ const id = local.itemId(item);
170
+ cardElements.set(id, element);
171
+ onCleanup(() => {
172
+ if (cardElements.get(id) === element) cardElements.delete(id);
173
+ });
174
+ }, _el$9);
128
175
  setAttribute(_el$9, "draggable", true);
129
176
  insert(_el$9, () => local.children(item, { dragging: isDragging() }));
130
177
  effect(() => className(_el$9, cn("rounded-md border border-border bg-card text-sm shadow-xs", cardDragState[isDragging() ? "dragging" : "idle"])));
@@ -1 +1 @@
1
- {"version":3,"file":"board.js","names":["createMemo","createSignal","For","Show","splitProps","JSX","cva","VariantProps","cn","BoardColumn","Readonly","id","label","meta","Element","disabled","BoardMove","itemId","from","to","BoardProps","columns","items","T","item","itemColumn","canDrop","onMove","move","children","state","dragging","emptyColumn","column","class","cardDragState","idle","const","Board","props","local","setDragging","overColumn","setOverColumn","announcement","setAnnouncement","byColumn","grouped","Map","set","get","push","accepts","Boolean","drop","moveByKeyboard","direction","index","findIndex","candidates","slice","ordered","toReversed","target","find","_el$","_tmpl$","_el$2","firstChild","_$insert","_$createComponent","each","_el$3","_tmpl$4","_el$4","_el$5","_el$7","nextSibling","addEventListener","event","preventDefault","current","when","_el$6","_tmpl$2","isDragging","_el$9","_tmpl$5","$$keydown","ctrlKey","metaKey","key","_$setAttribute","_$effect","_$className","length","_el$8","_tmpl$3","_p$","_v$3","_v$4","e","t","undefined","_v$","_v$2","boardCardTitleVariants","variants","size","sm","md","defaultVariants","BoardCardTitleProps","BoardCardTitle","_el$0","_tmpl$6","BoardCardBody","_el$1","_tmpl$7","_$delegateEvents","_$createComponent","_$className","_$setAttribute","_$delegateEvents"],"sources":["../../../../src/components/ui/board/board.tsx"],"sourcesContent":["import { createMemo, createSignal, For, Show, splitProps, type JSX } from 'solid-js'\nimport { cva, type VariantProps } from '#lib/variants'\nimport { cn } from '#lib/utils'\n\n/**\n * Board.\n *\n * Columns of cards, with drag between them — the shape a task tracker, a CRM\n * pipeline, a support queue and a release plan all share. It is generic in the\n * one place that matters: the *column ids are the caller's*, and so is the rule\n * that decides which moves are legal. The component knows nothing about tasks.\n *\n * The transitions are a predicate rather than a derived table because the legal\n * moves in a real product are not \"any column to any column\". A task that is\n * `completed` may be archived but not re-queued; a lead may become a customer but\n * not a stranger again. A board that let you drop anything anywhere would encode\n * a state machine in the UI that the server rejects — so `canDrop` is required,\n * and a column that cannot receive the dragged card renders as unavailable rather\n * than silently accepting a drop that will fail.\n *\n * Three input methods, because a drag-only board is unusable by keyboard:\n * dragging with the pointer, `Ctrl`/`Cmd` + arrow keys to move a focused card\n * between columns, and whatever the caller wires into `actions`. The card is\n * focusable and its move is announced through a live region, so the board is\n * operable without a mouse.\n *\n * The card is rendered by the caller through `children`, given the item and a set\n * of drag props. That is deliberate: a card's contents are domain — a title, a\n * priority tag, an assignee — and a board that rendered them itself could only\n * ever serve one product.\n */\n\nexport type BoardColumn = Readonly<{\n id: string\n label: string\n /** A count or a limit, shown beside the label. */\n meta?: JSX.Element\n /** Dim the column and refuse drops — a lane that is closed or read-only. */\n disabled?: boolean\n}>\n\nexport type BoardMove = Readonly<{\n itemId: string\n from: string\n to: string\n}>\n\nexport type BoardProps<T> = {\n columns: readonly BoardColumn[]\n items: readonly T[]\n /** The item's stable id. */\n itemId: (item: T) => string\n /** The id of the column the item currently sits in. */\n itemColumn: (item: T) => string\n /** Whether `item` may move from `from` to `to`. Required: see the note above. */\n canDrop: (item: T, from: string, to: string) => boolean\n onMove: (move: BoardMove) => void\n /** The card body. `dragging` is true while this card is the one being dragged. */\n children: (item: T, state: { dragging: boolean }) => JSX.Element\n /** Shown when a column has no items. */\n emptyColumn?: (column: BoardColumn) => JSX.Element\n /** The board's accessible name. Defaults to \"Board\". */\n label?: string\n class?: string\n}\n\nconst cardDragState = {\n idle: '',\n dragging: 'opacity-40',\n} as const\n\nexport function Board<T>(props: BoardProps<T>) {\n const [local] = splitProps(props, [\n 'columns',\n 'items',\n 'itemId',\n 'itemColumn',\n 'canDrop',\n 'onMove',\n 'children',\n 'emptyColumn',\n 'label',\n 'class',\n ])\n\n // The dragged item, not its id: `canDrop` takes the item itself, and the\n // pointer may leave the card before it is dropped.\n const [dragging, setDragging] = createSignal<T | null>(null)\n const [overColumn, setOverColumn] = createSignal<string | null>(null)\n const [announcement, setAnnouncement] = createSignal('')\n\n const byColumn = createMemo(() => {\n const grouped = new Map<string, T[]>()\n for (const column of local.columns) grouped.set(column.id, [])\n for (const item of local.items) grouped.get(local.itemColumn(item))?.push(item)\n return grouped\n })\n\n const accepts = (column: BoardColumn) => {\n const item = dragging()\n return Boolean(\n item && !column.disabled && local.canDrop(item, local.itemColumn(item), column.id)\n )\n }\n\n const drop = (column: BoardColumn) => {\n const item = dragging()\n const from = item ? local.itemColumn(item) : null\n setDragging(null)\n setOverColumn(null)\n if (!item || !from || from === column.id || !accepts(column)) return\n local.onMove({ itemId: local.itemId(item), from, to: column.id })\n }\n\n /**\n * Keyboard move. `Ctrl`/`Cmd` plus an arrow is the convention for \"reorder this\n * thing within its container\" that does not collide with scrolling or with the\n * text caret, and it is the same chord a browser tab or a spreadsheet uses.\n */\n const moveByKeyboard = (item: T, direction: -1 | 1) => {\n const from = local.itemColumn(item)\n const index = local.columns.findIndex((column) => column.id === from)\n const candidates = local.columns.slice(index + direction)\n const ordered = direction === 1 ? candidates : candidates.toReversed()\n const target = ordered.find(\n (column) => !column.disabled && local.canDrop(item, from, column.id)\n )\n if (!target) {\n setAnnouncement(`No column after ${from} accepts this item`)\n return\n }\n local.onMove({ itemId: local.itemId(item), from, to: target.id })\n setAnnouncement(`Moved to ${target.label}`)\n }\n\n return (\n /*\n `role=\"region\"` + `tabindex=\"0\"` because the board scrolls horizontally and a\n keyboard user has to be able to scroll it — axe's `scrollable-region-focusable`.\n It is not enough that the cards are focusable: a board with empty columns, or\n with more columns than fit, has nothing focusable to scroll from.\n */\n <div\n class={cn('flex min-h-0 gap-4 overflow-x-auto pb-2', local.class)}\n role=\"region\"\n aria-label={local.label ?? 'Board'}\n tabindex=\"0\"\n >\n <For each={local.columns}>\n {(column) => {\n const items = () => byColumn().get(column.id) ?? []\n return (\n <section\n class={cn(\n 'flex w-72 shrink-0 flex-col gap-2 rounded-lg border border-border bg-muted/40 p-2',\n accepts(column) && 'border-ring bg-muted',\n overColumn() === column.id && !accepts(column) && 'border-dashed opacity-60',\n column.disabled && 'opacity-50'\n )}\n aria-label={column.label}\n onDragOver={(event) => {\n setOverColumn(column.id)\n if (accepts(column)) event.preventDefault()\n }}\n onDragLeave={() =>\n setOverColumn((current) => (current === column.id ? null : current))\n }\n onDrop={(event) => {\n event.preventDefault()\n drop(column)\n }}\n >\n <header class=\"flex items-center justify-between gap-2 px-1 py-0.5\">\n <h3 class=\"text-xs font-semibold text-foreground\">{column.label}</h3>\n <Show when={column.meta}>\n <span class=\"text-2xs text-muted-foreground\">{column.meta}</span>\n </Show>\n </header>\n <div class=\"flex min-h-16 flex-col gap-2\">\n <For each={items()}>\n {(item) => {\n const isDragging = () => {\n const current = dragging()\n return Boolean(current && local.itemId(current) === local.itemId(item))\n }\n return (\n <article\n class={cn(\n 'rounded-md border border-border bg-card text-sm shadow-xs',\n cardDragState[isDragging() ? 'dragging' : 'idle']\n )}\n // A board card is a control that can be moved, so it is\n // focusable and carries the chord it responds to.\n tabindex=\"0\"\n aria-roledescription=\"Draggable card\"\n draggable={true}\n onDragStart={() => setDragging(() => item)}\n onDragEnd={() => {\n setDragging(null)\n setOverColumn(null)\n }}\n onKeyDown={(event) => {\n if (!(event.ctrlKey || event.metaKey)) return\n if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') return\n event.preventDefault()\n moveByKeyboard(item, event.key === 'ArrowRight' ? 1 : -1)\n }}\n >\n {local.children(item, { dragging: isDragging() })}\n </article>\n )\n }}\n </For>\n <Show when={items().length === 0}>\n <p class=\"rounded-md border border-dashed border-border px-2 py-4 text-center text-2xs text-muted-foreground\">\n {local.emptyColumn?.(column) ?? 'Nothing here'}\n </p>\n </Show>\n </div>\n </section>\n )\n }}\n </For>\n {/*\n The keyboard move's result, announced. A drag speaks for itself — the card\n visibly moves — while a keyboard move happens with the focus elsewhere.\n */}\n <div class=\"visually-hidden\" role=\"status\" aria-live=\"polite\">\n {announcement()}\n </div>\n </div>\n )\n}\n\nexport const boardCardTitleVariants = cva('truncate font-medium text-foreground', {\n variants: { size: { sm: 'text-xs', md: 'text-sm' } },\n defaultVariants: { size: 'md' },\n})\n\nexport type BoardCardTitleProps = { class?: string; children: JSX.Element } & VariantProps<\n typeof boardCardTitleVariants\n>\n\n/** The card's title line, at the size a board card uses. */\nexport function BoardCardTitle(props: BoardCardTitleProps) {\n return (\n <h4 class={cn(boardCardTitleVariants({ size: props.size }), props.class)}>{props.children}</h4>\n )\n}\n\n/** A card's padding, so every card in an application is the same shape. */\nexport function BoardCardBody(props: { class?: string; children: JSX.Element }) {\n return <div class={cn('grid gap-1.5 p-2.5', props.class)}>{props.children}</div>\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"board.js","names":["createEffect","createMemo","createSignal","For","onCleanup","Show","splitProps","JSX","cva","VariantProps","cn","BoardColumn","Readonly","id","label","meta","Element","disabled","BoardMove","itemId","from","to","BoardProps","columns","items","T","item","itemColumn","canDrop","onMove","move","children","state","dragging","emptyColumn","column","class","cardDragState","idle","const","Board","props","local","setDragging","overColumn","setOverColumn","announcement","setAnnouncement","cardElements","Map","HTMLElement","pendingFocus","setPendingFocus","columnId","source","cancelOnPointer","pending","document","ownerDocument","cancelOnFocus","event","FocusEvent","contains","target","Node","addEventListener","removeEventListener","moved","find","queueMicrotask","get","isConnected","focus","prepareFocus","card","activeElement","byColumn","grouped","set","push","accepts","Boolean","drop","accepted","moveByKeyboard","direction","index","findIndex","ordered","slice","toReversed","_el$","_tmpl$","_el$2","firstChild","_$insert","_$createComponent","each","_el$3","_tmpl$4","_el$4","_el$5","_el$7","nextSibling","preventDefault","current","when","_el$6","_tmpl$2","isDragging","_el$9","_tmpl$5","$$keydown","ctrlKey","metaKey","key","currentTarget","_$use","element","delete","_$setAttribute","_$effect","_$className","length","_el$8","_tmpl$3","_p$","_v$3","_v$4","e","t","undefined","_v$","_v$2","boardCardTitleVariants","variants","size","sm","md","defaultVariants","BoardCardTitleProps","BoardCardTitle","_el$0","_tmpl$6","BoardCardBody","_el$1","_tmpl$7","_$delegateEvents","_$createComponent","_$className","_$setAttribute","_$delegateEvents"],"sources":["../../../../src/components/ui/board/board.tsx"],"sourcesContent":["import {\n createEffect,\n createMemo,\n createSignal,\n For,\n onCleanup,\n Show,\n splitProps,\n type JSX,\n} from 'solid-js'\nimport { cva, type VariantProps } from '#lib/variants'\nimport { cn } from '#lib/utils'\n\n/**\n * Board.\n *\n * Columns of cards, with drag between them — the shape a task tracker, a CRM\n * pipeline, a support queue and a release plan all share. It is generic in the\n * one place that matters: the *column ids are the caller's*, and so is the rule\n * that decides which moves are legal. The component knows nothing about tasks.\n *\n * The transitions are a predicate rather than a derived table because the legal\n * moves in a real product are not \"any column to any column\". A task that is\n * `completed` may be archived but not re-queued; a lead may become a customer but\n * not a stranger again. A board that let you drop anything anywhere would encode\n * a state machine in the UI that the server rejects — so `canDrop` is required,\n * and a column that cannot receive the dragged card renders as unavailable rather\n * than silently accepting a drop that will fail.\n *\n * Three input methods, because a drag-only board is unusable by keyboard:\n * dragging with the pointer, `Ctrl`/`Cmd` + arrow keys to move a focused card\n * between columns, and whatever the caller wires into `actions`. The card is\n * focusable and its move is announced through a live region, so the board is\n * operable without a mouse.\n *\n * The card is rendered by the caller through `children`, given the item and a set\n * of drag props. That is deliberate: a card's contents are domain — a title, a\n * priority tag, an assignee — and a board that rendered them itself could only\n * ever serve one product.\n */\n\nexport type BoardColumn = Readonly<{\n id: string\n label: string\n /** A count or a limit, shown beside the label. */\n meta?: JSX.Element\n /** Dim the column and refuse drops — a lane that is closed or read-only. */\n disabled?: boolean\n}>\n\nexport type BoardMove = Readonly<{\n itemId: string\n from: string\n to: string\n}>\n\nexport type BoardProps<T> = {\n columns: readonly BoardColumn[]\n items: readonly T[]\n /** The item's stable id. */\n itemId: (item: T) => string\n /** The id of the column the item currently sits in. */\n itemColumn: (item: T) => string\n /** Whether `item` may move from `from` to `to`. Required: see the note above. */\n canDrop: (item: T, from: string, to: string) => boolean\n onMove: (move: BoardMove) => void\n /** The card body. `dragging` is true while this card is the one being dragged. */\n children: (item: T, state: { dragging: boolean }) => JSX.Element\n /** Shown when a column has no items. */\n emptyColumn?: (column: BoardColumn) => JSX.Element\n /** The board's accessible name. Defaults to \"Board\". */\n label?: string\n class?: string\n}\n\nconst cardDragState = {\n idle: '',\n dragging: 'opacity-40',\n} as const\n\nexport function Board<T>(props: BoardProps<T>) {\n const [local] = splitProps(props, [\n 'columns',\n 'items',\n 'itemId',\n 'itemColumn',\n 'canDrop',\n 'onMove',\n 'children',\n 'emptyColumn',\n 'label',\n 'class',\n ])\n\n // The dragged item, not its id: `canDrop` takes the item itself, and the\n // pointer may leave the card before it is dropped.\n const [dragging, setDragging] = createSignal<T | null>(null)\n const [overColumn, setOverColumn] = createSignal<string | null>(null)\n const [announcement, setAnnouncement] = createSignal('')\n const cardElements = new Map<string, HTMLElement>()\n const [pendingFocus, setPendingFocus] = createSignal<{\n itemId: string\n columnId: string\n source: HTMLElement\n } | null>(null)\n const cancelOnPointer = () => setPendingFocus(null)\n\n // A controlled move can settle after a server response. Restore only the\n // focus that belonged to the moved card; another focus action cancels it.\n createEffect(() => {\n const pending = pendingFocus()\n if (!pending) return\n const document = pending.source.ownerDocument\n const cancelOnFocus = (event: FocusEvent) => {\n if (!pending.source.contains(event.target as Node)) setPendingFocus(null)\n }\n document.addEventListener('focusin', cancelOnFocus)\n document.addEventListener('pointerdown', cancelOnPointer)\n onCleanup(() => {\n document.removeEventListener('focusin', cancelOnFocus)\n document.removeEventListener('pointerdown', cancelOnPointer)\n })\n })\n\n createEffect(() => {\n const pending = pendingFocus()\n if (!pending) return\n const moved = local.items.find((item) => local.itemId(item) === pending.itemId)\n if (!moved || local.itemColumn(moved) !== pending.columnId) return\n queueMicrotask(() => {\n if (pendingFocus() !== pending) return\n const target = cardElements.get(pending.itemId)\n setPendingFocus(null)\n if (target?.isConnected) target.focus()\n })\n })\n\n const prepareFocus = (item: T, columnId: string, source?: HTMLElement) => {\n const card = source ?? cardElements.get(local.itemId(item))\n if (card?.contains(card.ownerDocument.activeElement)) {\n setPendingFocus({ itemId: local.itemId(item), columnId, source: card })\n }\n }\n\n const byColumn = createMemo(() => {\n const grouped = new Map<string, T[]>()\n for (const column of local.columns) grouped.set(column.id, [])\n for (const item of local.items) grouped.get(local.itemColumn(item))?.push(item)\n return grouped\n })\n\n const accepts = (column: BoardColumn) => {\n const item = dragging()\n return Boolean(\n item && !column.disabled && local.canDrop(item, local.itemColumn(item), column.id)\n )\n }\n\n const drop = (column: BoardColumn) => {\n const item = dragging()\n const from = item ? local.itemColumn(item) : null\n const accepted = accepts(column)\n setDragging(null)\n setOverColumn(null)\n if (!item || !from || from === column.id || !accepted) return\n prepareFocus(item, column.id)\n local.onMove({ itemId: local.itemId(item), from, to: column.id })\n }\n\n /**\n * Keyboard move. `Ctrl`/`Cmd` plus an arrow is the convention for \"reorder this\n * thing within its container\" that does not collide with scrolling or with the\n * text caret, and it is the same chord a browser tab or a spreadsheet uses.\n */\n const moveByKeyboard = (item: T, direction: -1 | 1, source: HTMLElement) => {\n const from = local.itemColumn(item)\n const index = local.columns.findIndex((column) => column.id === from)\n if (index < 0) return\n const ordered =\n direction === 1 ? local.columns.slice(index + 1) : local.columns.slice(0, index).toReversed()\n const target = ordered.find(\n (column) => !column.disabled && local.canDrop(item, from, column.id)\n )\n if (!target) {\n setAnnouncement(`No column after ${from} accepts this item`)\n return\n }\n prepareFocus(item, target.id, source)\n local.onMove({ itemId: local.itemId(item), from, to: target.id })\n setAnnouncement(`Moved to ${target.label}`)\n }\n\n return (\n /*\n `role=\"region\"` + `tabindex=\"0\"` because the board scrolls horizontally and a\n keyboard user has to be able to scroll it — axe's `scrollable-region-focusable`.\n It is not enough that the cards are focusable: a board with empty columns, or\n with more columns than fit, has nothing focusable to scroll from.\n */\n <div\n class={cn('flex min-h-0 gap-4 overflow-x-auto pb-2', local.class)}\n role=\"region\"\n aria-label={local.label ?? 'Board'}\n tabindex=\"0\"\n >\n <For each={local.columns}>\n {(column) => {\n const items = () => byColumn().get(column.id) ?? []\n return (\n <section\n class={cn(\n 'flex w-72 shrink-0 flex-col gap-2 rounded-lg border border-border bg-muted/40 p-2',\n accepts(column) && 'border-ring bg-muted',\n overColumn() === column.id && !accepts(column) && 'border-dashed opacity-60',\n column.disabled && 'opacity-50'\n )}\n aria-label={column.label}\n onDragOver={(event) => {\n setOverColumn(column.id)\n if (accepts(column)) event.preventDefault()\n }}\n onDragLeave={() =>\n setOverColumn((current) => (current === column.id ? null : current))\n }\n onDrop={(event) => {\n event.preventDefault()\n drop(column)\n }}\n >\n <header class=\"flex items-center justify-between gap-2 px-1 py-0.5\">\n <h3 class=\"text-xs font-semibold text-foreground\">{column.label}</h3>\n <Show when={column.meta}>\n <span class=\"text-2xs text-muted-foreground\">{column.meta}</span>\n </Show>\n </header>\n <div class=\"flex min-h-16 flex-col gap-2\">\n <For each={items()}>\n {(item) => {\n const isDragging = () => {\n const current = dragging()\n return Boolean(current && local.itemId(current) === local.itemId(item))\n }\n return (\n <article\n ref={(element) => {\n const id = local.itemId(item)\n cardElements.set(id, element)\n onCleanup(() => {\n if (cardElements.get(id) === element) cardElements.delete(id)\n })\n }}\n class={cn(\n 'rounded-md border border-border bg-card text-sm shadow-xs',\n cardDragState[isDragging() ? 'dragging' : 'idle']\n )}\n // A board card is a control that can be moved, so it is\n // focusable and carries the chord it responds to.\n tabindex=\"0\"\n aria-roledescription=\"Draggable card\"\n draggable={true}\n onDragStart={() => setDragging(() => item)}\n onDragEnd={() => {\n setDragging(null)\n setOverColumn(null)\n }}\n onKeyDown={(event) => {\n if (!(event.ctrlKey || event.metaKey)) return\n if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') return\n event.preventDefault()\n moveByKeyboard(\n item,\n event.key === 'ArrowRight' ? 1 : -1,\n event.currentTarget\n )\n }}\n >\n {local.children(item, { dragging: isDragging() })}\n </article>\n )\n }}\n </For>\n <Show when={items().length === 0}>\n <p class=\"rounded-md border border-dashed border-border px-2 py-4 text-center text-2xs text-muted-foreground\">\n {local.emptyColumn?.(column) ?? 'Nothing here'}\n </p>\n </Show>\n </div>\n </section>\n )\n }}\n </For>\n {/*\n The keyboard move's result, announced. A drag speaks for itself — the card\n visibly moves — while a keyboard move happens with the focus elsewhere.\n */}\n <div class=\"visually-hidden\" role=\"status\" aria-live=\"polite\">\n {announcement()}\n </div>\n </div>\n )\n}\n\nexport const boardCardTitleVariants = cva('truncate font-medium text-foreground', {\n variants: { size: { sm: 'text-xs', md: 'text-sm' } },\n defaultVariants: { size: 'md' },\n})\n\nexport type BoardCardTitleProps = { class?: string; children: JSX.Element } & VariantProps<\n typeof boardCardTitleVariants\n>\n\n/** The card's title line, at the size a board card uses. */\nexport function BoardCardTitle(props: BoardCardTitleProps) {\n return (\n <h4 class={cn(boardCardTitleVariants({ size: props.size }), props.class)}>{props.children}</h4>\n )\n}\n\n/** A card's padding, so every card in an application is the same shape. */\nexport function BoardCardBody(props: { class?: string; children: JSX.Element }) {\n return <div class={cn('grid gap-1.5 p-2.5', props.class)}>{props.children}</div>\n}\n"],"mappings":"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"}
@@ -45,7 +45,11 @@ export declare function CommandGroup(props: ComponentProps<typeof CmdkGroup>): i
45
45
  export declare function CommandItem(props: ComponentProps<typeof CmdkItem>): import("solid-js").JSX.Element;
46
46
  export declare function CommandSeparator(props: ComponentProps<typeof CmdkSeparator>): import("solid-js").JSX.Element;
47
47
  export declare function CommandLoading(props: ComponentProps<typeof CmdkLoading>): import("solid-js").JSX.Element;
48
- /** The keyboard hint a palette item usually carries. */
48
+ /**
49
+ * The keyboard hint a palette item usually carries.
50
+ * Muted canvas text can fail contrast on a raised or selected command row;
51
+ * hierarchy comes from its size and monospace face, with the row's readable ink.
52
+ */
49
53
  export declare function CommandShortcut(props: {
50
54
  class?: string;
51
55
  children?: ComponentProps<'span'>['children'];
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/command/command.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,IAAI,UAAU,EAC3B,YAAY,IAAI,SAAS,EACzB,YAAY,IAAI,SAAS,EACzB,YAAY,IAAI,SAAS,EACzB,WAAW,IAAI,QAAQ,EACvB,WAAW,IAAI,QAAQ,EACvB,cAAc,IAAI,WAAW,EAC7B,WAAW,IAAI,QAAQ,EACvB,gBAAgB,IAAI,aAAa,EAElC,MAAM,YAAY,CAAA;AAEnB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAK9C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,QAAQ,CAAC,kCAY7D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,UAAU,CAAC,kCAqBrE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,kCAmBnE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,QAAQ,CAAC,kCAgCjE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,kCAcnE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,kCAanE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,QAAQ,CAAC,kCAajE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,aAAa,CAAC,kCAG3E;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,WAAW,CAAC,kCAQvE;AAED,wDAAwD;AACxD,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAA;CAC9C,kCAQA"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/command/command.tsx"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,IAAI,UAAU,EAC3B,YAAY,IAAI,SAAS,EACzB,YAAY,IAAI,SAAS,EACzB,YAAY,IAAI,SAAS,EACzB,WAAW,IAAI,QAAQ,EACvB,WAAW,IAAI,QAAQ,EACvB,cAAc,IAAI,WAAW,EAC7B,WAAW,IAAI,QAAQ,EACvB,gBAAgB,IAAI,aAAa,EAElC,MAAM,YAAY,CAAA;AAEnB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAW9C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,QAAQ,CAAC,kCAY7D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,UAAU,CAAC,kCAqBrE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,kCAmBnE;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,QAAQ,CAAC,kCAgCjE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,kCAcnE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,SAAS,CAAC,kCAanE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,QAAQ,CAAC,kCAcjE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,aAAa,CAAC,kCAG3E;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,WAAW,CAAC,kCAQvE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAA;CAC9C,kCAQA"}
@@ -8,6 +8,7 @@ import { CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, C
8
8
  var _tmpl$ = /*#__PURE__*/ template(`<div data-slot=command-input-wrapper class="flex h-11 items-center gap-2 border-b border-border px-3">`);
9
9
  var _tmpl$2 = /*#__PURE__*/ template(`<div class=contents>`);
10
10
  var _tmpl$3 = /*#__PURE__*/ template(`<span>`);
11
+ var commandItem = menuItem.replace("data-[disabled]:pointer-events-none", "").replace("data-[disabled]:opacity-50", "");
11
12
  /**
12
13
  * Command.
13
14
  *
@@ -107,7 +108,7 @@ function CommandGroup$1(props) {
107
108
  function CommandItem$1(props) {
108
109
  const [local, rest] = splitProps(props, ["class"]);
109
110
  return createComponent(CommandItem, mergeProps({ get ["class"]() {
110
- return cn(menuItem, "data-[selected=true]:bg-surface-hover data-[selected=true]:text-foreground", local.class);
111
+ return cn(commandItem, "data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50", "text-popover-foreground data-[selected=true]:bg-surface-hover data-[selected=true]:text-popover-foreground", local.class);
111
112
  } }, rest));
112
113
  }
113
114
  function CommandSeparator$1(props) {
@@ -122,12 +123,16 @@ function CommandLoading$1(props) {
122
123
  return cn("text-muted-foreground py-6 text-center text-sm", local.class);
123
124
  } }, rest));
124
125
  }
125
- /** The keyboard hint a palette item usually carries. */
126
+ /**
127
+ * The keyboard hint a palette item usually carries.
128
+ * Muted canvas text can fail contrast on a raised or selected command row;
129
+ * hierarchy comes from its size and monospace face, with the row's readable ink.
130
+ */
126
131
  function CommandShortcut(props) {
127
132
  return (() => {
128
133
  var _el$3 = _tmpl$3();
129
134
  insert(_el$3, () => props.children);
130
- effect(() => className(_el$3, cn("text-muted-foreground ms-auto font-mono text-2xs tracking-widest", props.class)));
135
+ effect(() => className(_el$3, cn("text-popover-foreground ms-auto font-mono text-2xs tracking-widest", props.class)));
131
136
  return _el$3;
132
137
  })();
133
138
  }
@@ -1 +1 @@
1
- {"version":3,"file":"command.js","names":["CommandDialog","CmdkDialog","CommandEmpty","CmdkEmpty","CommandGroup","CmdkGroup","CommandInput","CmdkInput","CommandItem","CmdkItem","CommandList","CmdkList","CommandLoading","CmdkLoading","CommandRoot","CmdkRoot","CommandSeparator","CmdkSeparator","useCommandState","Search","ComponentProps","createEffect","createSignal","splitProps","menuItem","cn","Command","props","local","rest","_$createComponent","_$mergeProps","class","contentClassName","_el$","_tmpl$","_$insert","wrapper","setWrapper","HTMLDivElement","resultCount","state","filtered","count","root","selector","querySelector","setAttribute","_el$2","_tmpl$2","_$use","role","CommandShortcut","children","_el$3","_tmpl$3","_$effect","_$className","_$createComponent","CmdkRoot","_$mergeProps","CommandDialog","CmdkDialog","CommandInput","CmdkInput","CommandList","CmdkList","CommandEmpty","CmdkEmpty","CommandGroup","CmdkGroup","CommandItem","CmdkItem","CommandSeparator","CmdkSeparator","CommandLoading","CmdkLoading","_$className"],"sources":["../../../../src/components/ui/command/command.tsx"],"sourcesContent":["import {\n CommandDialog as CmdkDialog,\n CommandEmpty as CmdkEmpty,\n CommandGroup as CmdkGroup,\n CommandInput as CmdkInput,\n CommandItem as CmdkItem,\n CommandList as CmdkList,\n CommandLoading as CmdkLoading,\n CommandRoot as CmdkRoot,\n CommandSeparator as CmdkSeparator,\n useCommandState,\n} from 'cmdk-solid'\nimport { Search } from 'lucide-solid'\nimport type { ComponentProps } from 'solid-js'\nimport { createEffect, createSignal, splitProps } from 'solid-js'\nimport { menuItem } from '#lib/overlay'\nimport { cn } from '#lib/utils'\n\n/**\n * Command.\n *\n * The command palette: a filtered list of everything the user can do, ranked\n * by fuzzy match. It is the one place in an app where a keyboard-first surface\n * is the *primary* one, so it carries rules the rest of the system does not:\n *\n * - Every item must be reachable by typing its name. If a user has to\n * remember which group it lives in, the palette has failed at its job.\n * - Groups exist for reading, not for navigation. The ranking crosses them.\n * - The empty state is not an apology — it should offer the closest thing\n * the app could guess, or say plainly that nothing matched.\n *\n * cmdk-solid supplies the filter, the scoring, the `aria-activedescendant`\n * wiring and the arrow-key navigation.\n */\nexport function Command(props: ComponentProps<typeof CmdkRoot>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <CmdkRoot\n class={cn(\n 'bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-xl',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function CommandDialog(props: ComponentProps<typeof CmdkDialog>) {\n // cmdk's Dialog splits `contentClassName` onto the role=\"dialog\" content\n // element and routes every other prop (including `class`) to the inner\n // Command. The surface must live on the content: a `class` here styles the\n // Command (fixed, so visible) while the dialog element itself renders as an\n // unstyled zero-height wrapper at the end of body — invisible to role\n // queries and axe.\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <CmdkDialog\n contentClassName={cn(\n 'bg-popover text-popover-foreground fixed top-1/3 left-1/2 z-(--z-dialog) w-full max-w-lg -translate-x-1/2 -translate-y-1/2',\n 'overflow-hidden rounded-xl border border-border shadow-xl',\n 'data-expanded:animate-in data-expanded:fade-in-0 data-expanded:zoom-in-95',\n 'data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function CommandInput(props: ComponentProps<typeof CmdkInput>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <div\n data-slot=\"command-input-wrapper\"\n class=\"flex h-11 items-center gap-2 border-b border-border px-3\"\n >\n <Search class=\"size-4 shrink-0 text-muted-foreground\" aria-hidden=\"true\" />\n <CmdkInput\n class={cn(\n 'h-full w-full bg-transparent text-sm outline-none placeholder:text-muted-foreground',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n local.class\n )}\n {...rest}\n />\n </div>\n )\n}\n\n/**\n * The scrolling list.\n *\n * Two DOM corrections, and both are deliberate. cmdk builds a `role=\"listbox\"`\n * whose children include two elements ARIA does not allow there:\n *\n * - a bare `<div cmdk-list-sizer>` with no role, wrapped around every group;\n * - a `<div cmdk-separator role=\"separator\">`, and `separator` is a menu and\n * toolbar role — inside a listbox the only owned elements may be `option`\n * and `group`.\n *\n * Both are pure presentation: the sizer is layout, and the separator is a\n * hairline between groups that the groups already structure. `role=\"presentation\"`\n * is their accurate role rather than a workaround — each is flattened out of the\n * accessibility tree, and the options inside are reached exactly as before.\n *\n * Written onto the mounted nodes rather than through props, because cmdk owns\n * this markup and does not forward a `ref`; in an effect rather than `onMount`,\n * because cmdk renders the sizer with the first item, after the list itself.\n */\nexport function CommandList(props: ComponentProps<typeof CmdkList>) {\n const [local, rest] = splitProps(props, ['class'])\n const [wrapper, setWrapper] = createSignal<HTMLDivElement>()\n const resultCount = useCommandState((state) => state.filtered.count)\n\n createEffect(() => {\n const root = wrapper()\n if (!root) return\n for (const selector of ['[cmdk-list-sizer]', '[cmdk-separator]']) {\n root.querySelector(selector)?.setAttribute('role', 'presentation')\n }\n\n /*\n * A `listbox` must own at least one `option`, so a listbox with nothing in it\n * is invalid ARIA — which is what a search with no matches produces. When\n * there are no results the list is inert, so it becomes presentational and\n * the empty message carries the information instead. It keeps its `id`, so\n * the input's `aria-controls` still resolves.\n */\n root\n .querySelector('[cmdk-list]')\n ?.setAttribute('role', resultCount() > 0 ? 'listbox' : 'presentation')\n })\n\n return (\n <div ref={setWrapper} class=\"contents\">\n <CmdkList\n class={cn('max-h-80 scroll-py-1 overflow-y-auto overflow-x-hidden p-1', local.class)}\n {...rest}\n />\n </div>\n )\n}\n\nexport function CommandEmpty(props: ComponentProps<typeof CmdkEmpty>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <CmdkEmpty\n /*\n * A status rather than plain text: when the list is presentational, this is\n * the only thing that tells a screen reader the search matched nothing.\n */\n role=\"status\"\n class={cn('text-muted-foreground py-8 text-center text-sm', local.class)}\n {...rest}\n />\n )\n}\n\nexport function CommandGroup(props: ComponentProps<typeof CmdkGroup>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <CmdkGroup\n class={cn(\n 'text-foreground overflow-hidden p-1',\n '[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-2xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:tracking-wide [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:uppercase',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function CommandItem(props: ComponentProps<typeof CmdkItem>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <CmdkItem\n class={cn(\n menuItem,\n 'data-[selected=true]:bg-surface-hover data-[selected=true]:text-foreground',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function CommandSeparator(props: ComponentProps<typeof CmdkSeparator>) {\n const [local, rest] = splitProps(props, ['class'])\n return <CmdkSeparator class={cn('bg-border -mx-1 my-1 h-px', local.class)} {...rest} />\n}\n\nexport function CommandLoading(props: ComponentProps<typeof CmdkLoading>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <CmdkLoading\n class={cn('text-muted-foreground py-6 text-center text-sm', local.class)}\n {...rest}\n />\n )\n}\n\n/** The keyboard hint a palette item usually carries. */\nexport function CommandShortcut(props: {\n class?: string\n children?: ComponentProps<'span'>['children']\n}) {\n return (\n <span\n class={cn('text-muted-foreground ms-auto font-mono text-2xs tracking-widest', props.class)}\n >\n {props.children}\n </span>\n )\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"command.js","names":["CommandDialog","CmdkDialog","CommandEmpty","CmdkEmpty","CommandGroup","CmdkGroup","CommandInput","CmdkInput","CommandItem","CmdkItem","CommandList","CmdkList","CommandLoading","CmdkLoading","CommandRoot","CmdkRoot","CommandSeparator","CmdkSeparator","useCommandState","Search","ComponentProps","createEffect","createSignal","splitProps","menuItem","cn","commandItem","replace","Command","props","local","rest","_$createComponent","_$mergeProps","class","contentClassName","_el$","_tmpl$","_$insert","wrapper","setWrapper","HTMLDivElement","resultCount","state","filtered","count","root","selector","querySelector","setAttribute","_el$2","_tmpl$2","_$use","role","CommandShortcut","children","_el$3","_tmpl$3","_$effect","_$className","_$createComponent","CmdkRoot","_$mergeProps","CommandDialog","CmdkDialog","CommandInput","CmdkInput","CommandList","CmdkList","CommandEmpty","CmdkEmpty","CommandGroup","CmdkGroup","CommandItem","CmdkItem","CommandSeparator","CmdkSeparator","CommandLoading","CmdkLoading","_$className"],"sources":["../../../../src/components/ui/command/command.tsx"],"sourcesContent":["import {\n CommandDialog as CmdkDialog,\n CommandEmpty as CmdkEmpty,\n CommandGroup as CmdkGroup,\n CommandInput as CmdkInput,\n CommandItem as CmdkItem,\n CommandList as CmdkList,\n CommandLoading as CmdkLoading,\n CommandRoot as CmdkRoot,\n CommandSeparator as CmdkSeparator,\n useCommandState,\n} from 'cmdk-solid'\nimport { Search } from 'lucide-solid'\nimport type { ComponentProps } from 'solid-js'\nimport { createEffect, createSignal, splitProps } from 'solid-js'\nimport { menuItem } from '#lib/overlay'\nimport { cn } from '#lib/utils'\n\n// cmdk emits data-disabled=\"false\" on enabled items; Kobalte omits it.\n// Presence selectors would dim and disable every command in an app palette.\nconst commandItem = menuItem\n .replace('data-[disabled]:pointer-events-none', '')\n .replace('data-[disabled]:opacity-50', '')\n\n/**\n * Command.\n *\n * The command palette: a filtered list of everything the user can do, ranked\n * by fuzzy match. It is the one place in an app where a keyboard-first surface\n * is the *primary* one, so it carries rules the rest of the system does not:\n *\n * - Every item must be reachable by typing its name. If a user has to\n * remember which group it lives in, the palette has failed at its job.\n * - Groups exist for reading, not for navigation. The ranking crosses them.\n * - The empty state is not an apology — it should offer the closest thing\n * the app could guess, or say plainly that nothing matched.\n *\n * cmdk-solid supplies the filter, the scoring, the `aria-activedescendant`\n * wiring and the arrow-key navigation.\n */\nexport function Command(props: ComponentProps<typeof CmdkRoot>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <CmdkRoot\n class={cn(\n 'bg-popover text-popover-foreground flex h-full w-full flex-col overflow-hidden rounded-xl',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function CommandDialog(props: ComponentProps<typeof CmdkDialog>) {\n // cmdk's Dialog splits `contentClassName` onto the role=\"dialog\" content\n // element and routes every other prop (including `class`) to the inner\n // Command. The surface must live on the content: a `class` here styles the\n // Command (fixed, so visible) while the dialog element itself renders as an\n // unstyled zero-height wrapper at the end of body — invisible to role\n // queries and axe.\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <CmdkDialog\n contentClassName={cn(\n 'bg-popover text-popover-foreground fixed top-1/3 left-1/2 z-(--z-dialog) w-full max-w-lg -translate-x-1/2 -translate-y-1/2',\n 'overflow-hidden rounded-xl border border-border shadow-xl',\n 'data-expanded:animate-in data-expanded:fade-in-0 data-expanded:zoom-in-95',\n 'data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function CommandInput(props: ComponentProps<typeof CmdkInput>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <div\n data-slot=\"command-input-wrapper\"\n class=\"flex h-11 items-center gap-2 border-b border-border px-3\"\n >\n <Search class=\"size-4 shrink-0 text-muted-foreground\" aria-hidden=\"true\" />\n <CmdkInput\n class={cn(\n 'h-full w-full bg-transparent text-sm outline-none placeholder:text-muted-foreground',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n local.class\n )}\n {...rest}\n />\n </div>\n )\n}\n\n/**\n * The scrolling list.\n *\n * Two DOM corrections, and both are deliberate. cmdk builds a `role=\"listbox\"`\n * whose children include two elements ARIA does not allow there:\n *\n * - a bare `<div cmdk-list-sizer>` with no role, wrapped around every group;\n * - a `<div cmdk-separator role=\"separator\">`, and `separator` is a menu and\n * toolbar role — inside a listbox the only owned elements may be `option`\n * and `group`.\n *\n * Both are pure presentation: the sizer is layout, and the separator is a\n * hairline between groups that the groups already structure. `role=\"presentation\"`\n * is their accurate role rather than a workaround — each is flattened out of the\n * accessibility tree, and the options inside are reached exactly as before.\n *\n * Written onto the mounted nodes rather than through props, because cmdk owns\n * this markup and does not forward a `ref`; in an effect rather than `onMount`,\n * because cmdk renders the sizer with the first item, after the list itself.\n */\nexport function CommandList(props: ComponentProps<typeof CmdkList>) {\n const [local, rest] = splitProps(props, ['class'])\n const [wrapper, setWrapper] = createSignal<HTMLDivElement>()\n const resultCount = useCommandState((state) => state.filtered.count)\n\n createEffect(() => {\n const root = wrapper()\n if (!root) return\n for (const selector of ['[cmdk-list-sizer]', '[cmdk-separator]']) {\n root.querySelector(selector)?.setAttribute('role', 'presentation')\n }\n\n /*\n * A `listbox` must own at least one `option`, so a listbox with nothing in it\n * is invalid ARIA — which is what a search with no matches produces. When\n * there are no results the list is inert, so it becomes presentational and\n * the empty message carries the information instead. It keeps its `id`, so\n * the input's `aria-controls` still resolves.\n */\n root\n .querySelector('[cmdk-list]')\n ?.setAttribute('role', resultCount() > 0 ? 'listbox' : 'presentation')\n })\n\n return (\n <div ref={setWrapper} class=\"contents\">\n <CmdkList\n class={cn('max-h-80 scroll-py-1 overflow-y-auto overflow-x-hidden p-1', local.class)}\n {...rest}\n />\n </div>\n )\n}\n\nexport function CommandEmpty(props: ComponentProps<typeof CmdkEmpty>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <CmdkEmpty\n /*\n * A status rather than plain text: when the list is presentational, this is\n * the only thing that tells a screen reader the search matched nothing.\n */\n role=\"status\"\n class={cn('text-muted-foreground py-8 text-center text-sm', local.class)}\n {...rest}\n />\n )\n}\n\nexport function CommandGroup(props: ComponentProps<typeof CmdkGroup>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <CmdkGroup\n class={cn(\n 'text-foreground overflow-hidden p-1',\n '[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-2xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:tracking-wide [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group-heading]]:uppercase',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function CommandItem(props: ComponentProps<typeof CmdkItem>) {\n const [local, rest] = splitProps(props, ['class'])\n\n return (\n <CmdkItem\n class={cn(\n commandItem,\n 'data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50',\n 'text-popover-foreground data-[selected=true]:bg-surface-hover data-[selected=true]:text-popover-foreground',\n local.class\n )}\n {...rest}\n />\n )\n}\n\nexport function CommandSeparator(props: ComponentProps<typeof CmdkSeparator>) {\n const [local, rest] = splitProps(props, ['class'])\n return <CmdkSeparator class={cn('bg-border -mx-1 my-1 h-px', local.class)} {...rest} />\n}\n\nexport function CommandLoading(props: ComponentProps<typeof CmdkLoading>) {\n const [local, rest] = splitProps(props, ['class'])\n return (\n <CmdkLoading\n class={cn('text-muted-foreground py-6 text-center text-sm', local.class)}\n {...rest}\n />\n )\n}\n\n/**\n * The keyboard hint a palette item usually carries.\n * Muted canvas text can fail contrast on a raised or selected command row;\n * hierarchy comes from its size and monospace face, with the row's readable ink.\n */\nexport function CommandShortcut(props: {\n class?: string\n children?: ComponentProps<'span'>['children']\n}) {\n return (\n <span\n class={cn('text-popover-foreground ms-auto font-mono text-2xs tracking-widest', props.class)}\n >\n {props.children}\n </span>\n )\n}\n"],"mappings":";;;;;;;;;;AAoBA,IAAM0B,cAAcF,SACjBG,QAAQ,uCAAuC,EAAE,CAAC,CAClDA,QAAQ,8BAA8B,EAAE;;;;;;;;;;;;;;;;;AAkB3C,SAAgBC,QAAQC,OAAwC;CAC9D,MAAM,CAACC,OAAOC,QAAQR,WAAWM,OAAO,CAAC,OAAO,CAAC;CAEjD,OAAAG,gBACGjB,aAAQkB,WAAA,EAAA,KAAA,WAAA;EAAA,OACAR,GACL,6FACAK,MAAMI,KACR;CAAC,EAAA,GACGH,IAAI,CAAA;AAGd;AAEA,SAAgB/B,gBAAc6B,OAA0C;CAOtE,MAAM,CAACC,OAAOC,QAAQR,WAAWM,OAAO,CAAC,OAAO,CAAC;CAEjD,OAAAG,gBACG/B,eAAUgC,WAAA,EAAA,IACTE,mBAAgB;EAAA,OAAEV,GAChB,8HACA,6DACA,6EACA,0EACAK,MAAMI,KACR;CAAC,EAAA,GACGH,IAAI,CAAA;AAGd;AAEA,SAAgBzB,eAAauB,OAAyC;CACpE,MAAM,CAACC,OAAOC,QAAQR,WAAWM,OAAO,CAAC,OAAO,CAAC;CAEjD,cAAA;EAAA,IAAAO,OAAAC,OAAA;EAAAC,OAAAF,MAAAJ,gBAKKb,QAAM;GAAA,SAAA;GAAA,eAAA;EAAA,CAAA,GAAA,IAAA;EAAAmB,OAAAF,MAAAJ,gBACNzB,cAAS0B,WAAA,EAAA,KAAA,WAAA;GAAA,OACDR,GACL,uFACA,mDACAK,MAAMI,KACR;EAAC,EAAA,GACGH,IAAI,CAAA,GAAA,IAAA;EAAA,OAAAK;CAAA,EAAA,CAAA;AAIhB;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB1B,cAAYmB,OAAwC;CAClE,MAAM,CAACC,OAAOC,QAAQR,WAAWM,OAAO,CAAC,OAAO,CAAC;CACjD,MAAM,CAACU,SAASC,cAAclB,aAA6B;CAC3D,MAAMoB,cAAcxB,iBAAiByB,UAAUA,MAAMC,SAASC,KAAK;CAEnExB,mBAAmB;EACjB,MAAMyB,OAAOP,QAAQ;EACrB,IAAI,CAACO,MAAM;EACX,KAAK,MAAMC,YAAY,CAAC,qBAAqB,kBAAkB,GAC7DD,KAAKE,cAAcD,QAAQ,CAAC,EAAEE,aAAa,QAAQ,cAAc;EAUnEH,KACGE,cAAc,aAAa,CAAC,EAC3BC,aAAa,QAAQP,YAAY,IAAI,IAAI,YAAY,cAAc;CACzE,CAAC;CAED,cAAA;EAAA,IAAAQ,QAAAC,QAAA;EAAAC,IACYZ,YAAUU,KAAA;EAAAZ,OAAAY,OAAAlB,gBACjBrB,aAAQsB,WAAA,EAAA,KAAA,WAAA;GAAA,OACAR,GAAG,8DAA8DK,MAAMI,KAAK;EAAC,EAAA,GAChFH,IAAI,CAAA,CAAA;EAAA,OAAAmB;CAAA,EAAA,CAAA;AAIhB;AAEA,SAAgBhD,eAAa2B,OAAyC;CACpE,MAAM,CAACC,OAAOC,QAAQR,WAAWM,OAAO,CAAC,OAAO,CAAC;CAEjD,OAAAG,gBACG7B,cACC8B,WAAA;EAIAoB,MAAI;EAAA,KAAA,WAAA;GAAA,OACG5B,GAAG,kDAAkDK,MAAMI,KAAK;EAAC;CAAA,GACpEH,IAAI,CAAA;AAGd;AAEA,SAAgB3B,eAAayB,OAAyC;CACpE,MAAM,CAACC,OAAOC,QAAQR,WAAWM,OAAO,CAAC,OAAO,CAAC;CAEjD,OAAAG,gBACG3B,cAAS4B,WAAA,EAAA,KAAA,WAAA;EAAA,OACDR,GACL,uCACA,iQACAK,MAAMI,KACR;CAAC,EAAA,GACGH,IAAI,CAAA;AAGd;AAEA,SAAgBvB,cAAYqB,OAAwC;CAClE,MAAM,CAACC,OAAOC,QAAQR,WAAWM,OAAO,CAAC,OAAO,CAAC;CAEjD,OAAAG,gBACGvB,aAAQwB,WAAA,EAAA,KAAA,WAAA;EAAA,OACAR,GACLC,aACA,4EACA,8GACAI,MAAMI,KACR;CAAC,EAAA,GACGH,IAAI,CAAA;AAGd;AAEA,SAAgBf,mBAAiBa,OAA6C;CAC5E,MAAM,CAACC,OAAOC,QAAQR,WAAWM,OAAO,CAAC,OAAO,CAAC;CACjD,OAAAG,gBAAQf,kBAAagB,WAAA,EAAA,KAAA,WAAA;EAAA,OAAQR,GAAG,6BAA6BK,MAAMI,KAAK;CAAC,EAAA,GAAMH,IAAI,CAAA;AACrF;AAEA,SAAgBnB,iBAAeiB,OAA2C;CACxE,MAAM,CAACC,OAAOC,QAAQR,WAAWM,OAAO,CAAC,OAAO,CAAC;CACjD,OAAAG,gBACGnB,gBAAWoB,WAAA,EAAA,KAAA,WAAA;EAAA,OACHR,GAAG,kDAAkDK,MAAMI,KAAK;CAAC,EAAA,GACpEH,IAAI,CAAA;AAGd;;;;;;AAOA,SAAgBuB,gBAAgBzB,OAG7B;CACD,cAAA;EAAA,IAAA2B,QAAAC,QAAA;EAAAnB,OAAAkB,aAIK3B,MAAM0B,QAAQ;EAAAG,aAAAC,UAAAH,OAFR/B,GAAG,sEAAsEI,MAAMK,KAAK,CAAC,CAAA;EAAA,OAAAsB;CAAA,EAAA,CAAA;AAKlG"}
@@ -1,2 +1,2 @@
1
- export { Input } from './input';
1
+ export { Input, type InputProps } from './input';
2
2
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/input/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/input/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAA"}
@@ -11,5 +11,9 @@ import type { ComponentProps } from 'solid-js';
11
11
  * Height comes from `h-control-md`; an input cannot be given a new height
12
12
  * without a new token, which is what keeps it aligned with Button and Select.
13
13
  */
14
- export declare function Input(props: ComponentProps<'input'>): import("solid-js").JSX.Element;
14
+ export type InputProps = ComponentProps<'input'> & {
15
+ /** Native text suggestions; custom values remain valid and submit unchanged. */
16
+ suggestions?: readonly string[];
17
+ };
18
+ export declare function Input(props: InputProps): import("solid-js").JSX.Element;
15
19
  //# sourceMappingURL=input.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/input/input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAI9C;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,kCAwBnD"}
1
+ {"version":3,"file":"input.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/input/input.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAI9C;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG;IACjD,gFAAgF;IAChF,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAChC,CAAA;AAED,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,kCAoCtC"}
@@ -1,34 +1,53 @@
1
1
  import { cn } from "../../../lib/utils.js";
2
- import { mergeProps, spread, template } from "solid-js/web";
3
- import { splitProps } from "solid-js";
2
+ import { createComponent, effect, insert, memo, mergeProps, setAttribute, spread, template } from "solid-js/web";
3
+ import { For, Show, createUniqueId, splitProps } from "solid-js";
4
4
  //#region src/components/ui/input/input.tsx
5
5
  var _tmpl$ = /*#__PURE__*/ template(`<input data-slot=input>`);
6
- /**
7
- * Input.
8
- *
9
- * Deliberately a plain `<input>` rather than a Kobalte TextField part. The
10
- * styling contract is what a consumer needs from an input; validation,
11
- * description and error wiring come from `Field`, which composes this. Keeping
12
- * them separate is what lets an input sit inside a custom control without
13
- * inheriting a form's ARIA graph.
14
- *
15
- * Height comes from `h-control-md`; an input cannot be given a new height
16
- * without a new token, which is what keeps it aligned with Button and Select.
17
- */
6
+ var _tmpl$2 = /*#__PURE__*/ template(`<datalist>`);
7
+ var _tmpl$3 = /*#__PURE__*/ template(`<option>`);
18
8
  function Input(props) {
19
- const [local, rest] = splitProps(props, ["class", "type"]);
20
- return (() => {
9
+ const [local, rest] = splitProps(props, [
10
+ "class",
11
+ "type",
12
+ "list",
13
+ "suggestions"
14
+ ]);
15
+ const suggestionsId = createUniqueId();
16
+ const listId = () => local.list ?? `input-suggestions-${suggestionsId}`;
17
+ return [(() => {
21
18
  var _el$ = _tmpl$();
22
19
  spread(_el$, mergeProps({
23
20
  get type() {
24
21
  return local.type ?? "text";
25
22
  },
23
+ get list() {
24
+ return memo(() => !!local.suggestions)() ? listId() : local.list;
25
+ },
26
26
  get ["class"]() {
27
27
  return cn("h-control-md w-full min-w-0 rounded-md border border-input bg-transparent px-control-md py-1 text-sm", "transition-[color,box-shadow,border-color] ease-out outline-none", "placeholder:text-muted-foreground", "selection:bg-primary selection:text-primary-foreground", "file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground", "focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle", "aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive-subtle", "disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50", "read-only:bg-surface-hover", local.class);
28
28
  }
29
29
  }, rest), false, false);
30
30
  return _el$;
31
- })();
31
+ })(), createComponent(Show, {
32
+ get when() {
33
+ return local.suggestions;
34
+ },
35
+ children: (suggestions) => (() => {
36
+ var _el$2 = _tmpl$2();
37
+ insert(_el$2, createComponent(For, {
38
+ get each() {
39
+ return suggestions();
40
+ },
41
+ children: (value) => (() => {
42
+ var _el$3 = _tmpl$3();
43
+ _el$3.value = value;
44
+ return _el$3;
45
+ })()
46
+ }));
47
+ effect(() => setAttribute(_el$2, "id", listId()));
48
+ return _el$2;
49
+ })()
50
+ })];
32
51
  }
33
52
  //#endregion
34
53
  export { Input };
@@ -1 +1 @@
1
- {"version":3,"file":"input.js","names":["ComponentProps","splitProps","cn","Input","props","local","rest","_el$","_tmpl$","_$spread","_$mergeProps","type","class","_$mergeProps"],"sources":["../../../../src/components/ui/input/input.tsx"],"sourcesContent":["import type { ComponentProps } from 'solid-js'\nimport { splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\n\n/**\n * Input.\n *\n * Deliberately a plain `<input>` rather than a Kobalte TextField part. The\n * styling contract is what a consumer needs from an input; validation,\n * description and error wiring come from `Field`, which composes this. Keeping\n * them separate is what lets an input sit inside a custom control without\n * inheriting a form's ARIA graph.\n *\n * Height comes from `h-control-md`; an input cannot be given a new height\n * without a new token, which is what keeps it aligned with Button and Select.\n */\nexport function Input(props: ComponentProps<'input'>) {\n const [local, rest] = splitProps(props, ['class', 'type'])\n\n return (\n <input\n data-slot=\"input\"\n type={local.type ?? 'text'}\n class={cn(\n 'h-control-md w-full min-w-0 rounded-md border border-input bg-transparent px-control-md py-1 text-sm',\n 'transition-[color,box-shadow,border-color] ease-out outline-none',\n 'placeholder:text-muted-foreground',\n 'selection:bg-primary selection:text-primary-foreground',\n 'file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground',\n /* A pointer click on a text field is a typing affordance, so the ring\n appears where the user agent already matches :focus-visible. */\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive-subtle',\n 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',\n 'read-only:bg-surface-hover',\n local.class\n )}\n {...rest}\n />\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAgBA,SAAgBG,MAAMC,OAAgC;CACpD,MAAM,CAACC,OAAOC,QAAQL,WAAWG,OAAO,CAAC,SAAS,MAAM,CAAC;CAEzD,cAAA;EAAA,IAAAG,OAAAC,OAAA;EAAAC,OAAAF,MAAAG,WAAA;GAAA,IAGIC,OAAI;IAAA,OAAEN,MAAMM,QAAQ;GAAM;GAAA,KAAA,WAAA;IAAA,OACnBT,GACL,wGACA,oEACA,qCACA,0DACA,kHAGA,oFACA,4FACA,gFACA,8BACAG,MAAMO,KACR;GAAC;EAAA,GACGN,IAAI,GAAA,OAAA,KAAA;EAAA,OAAAC;CAAA,EAAA,CAAA;AAGd"}
1
+ {"version":3,"file":"input.js","names":["ComponentProps","createUniqueId","For","Show","splitProps","cn","InputProps","suggestions","Input","props","local","rest","suggestionsId","listId","list","_el$","_tmpl$","_$spread","_$mergeProps","type","_$memo","class","_$createComponent","when","children","_el$2","_tmpl$2","_$insert","each","value","_el$3","_tmpl$3","_$effect","_$setAttribute","_$mergeProps","_$memo","_$createComponent","_$setAttribute"],"sources":["../../../../src/components/ui/input/input.tsx"],"sourcesContent":["import type { ComponentProps } from 'solid-js'\nimport { createUniqueId, For, Show, splitProps } from 'solid-js'\nimport { cn } from '#lib/utils'\n\n/**\n * Input.\n *\n * Deliberately a plain `<input>` rather than a Kobalte TextField part. The\n * styling contract is what a consumer needs from an input; validation,\n * description and error wiring come from `Field`, which composes this. Keeping\n * them separate is what lets an input sit inside a custom control without\n * inheriting a form's ARIA graph.\n *\n * Height comes from `h-control-md`; an input cannot be given a new height\n * without a new token, which is what keeps it aligned with Button and Select.\n */\nexport type InputProps = ComponentProps<'input'> & {\n /** Native text suggestions; custom values remain valid and submit unchanged. */\n suggestions?: readonly string[]\n}\n\nexport function Input(props: InputProps) {\n const [local, rest] = splitProps(props, ['class', 'type', 'list', 'suggestions'])\n const suggestionsId = createUniqueId()\n const listId = () => local.list ?? `input-suggestions-${suggestionsId}`\n\n return (\n <>\n <input\n data-slot=\"input\"\n type={local.type ?? 'text'}\n list={local.suggestions ? listId() : local.list}\n class={cn(\n 'h-control-md w-full min-w-0 rounded-md border border-input bg-transparent px-control-md py-1 text-sm',\n 'transition-[color,box-shadow,border-color] ease-out outline-none',\n 'placeholder:text-muted-foreground',\n 'selection:bg-primary selection:text-primary-foreground',\n 'file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground',\n /* A pointer click on a text field is a typing affordance, so the ring\n appears where the user agent already matches :focus-visible. */\n 'focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-primary-subtle',\n 'aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive-subtle',\n 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',\n 'read-only:bg-surface-hover',\n local.class\n )}\n {...rest}\n />\n <Show when={local.suggestions}>\n {(suggestions) => (\n <datalist id={listId()}>\n <For each={suggestions()}>{(value) => <option value={value} />}</For>\n </datalist>\n )}\n </Show>\n </>\n )\n}\n"],"mappings":";;;;;;;AAqBA,SAAgBQ,MAAMC,OAAmB;CACvC,MAAM,CAACC,OAAOC,QAAQP,WAAWK,OAAO;EAAC;EAAS;EAAQ;EAAQ;CAAa,CAAC;CAChF,MAAMG,gBAAgBX,eAAe;CACrC,MAAMY,eAAeH,MAAMI,QAAQ,qBAAqBF;CAExD,OAAA,QAAA;EAAA,IAAAG,OAAAC,OAAA;EAAAC,OAAAF,MAAAG,WAAA;GAAA,IAIMC,OAAI;IAAA,OAAET,MAAMS,QAAQ;GAAM;GAAA,IAC1BL,OAAI;IAAA,OAAEM,WAAA,CAAA,CAAAV,MAAMH,WAAW,CAAA,CAAA,IAAGM,OAAO,IAAIH,MAAMI;GAAI;GAAA,KAAA,WAAA;IAAA,OACxCT,GACL,wGACA,oEACA,qCACA,0DACA,kHAGA,oFACA,4FACA,gFACA,8BACAK,MAAMW,KACR;GAAC;EAAA,GACGV,IAAI,GAAA,OAAA,KAAA;EAAA,OAAAI;CAAA,EAAA,CAAA,GAAAO,gBAETnB,MAAI;EAAA,IAACoB,OAAI;GAAA,OAAEb,MAAMH;EAAW;EAAAiB,WACzBjB,uBAAW;GAAA,IAAAkB,QAAAC,QAAA;GAAAC,OAAAF,OAAAH,gBAERpB,KAAG;IAAA,IAAC0B,OAAI;KAAA,OAAErB,YAAY;IAAC;IAAAiB,WAAIK,iBAAK;KAAA,IAAAC,QAAAC,QAAA;KAAAD,MAAAD,QAAoBA;KAAK,OAAAC;IAAA,EAAA,CAAA;GAAI,CAAA,CAAA;GAAAE,aAAAC,aAAAR,OAAA,MADlDZ,OAAO,CAAC,CAAA;GAAA,OAAAY;EAAA,EAAA,CAAA;CAGvB,CAAA,CAAA;AAIT"}
package/dist/index.d.ts CHANGED
@@ -83,6 +83,7 @@ export * from './components/layout/top-bar';
83
83
  export * from './components/conversation';
84
84
  export * from './components/theme';
85
85
  export * from './components/composites/account-menu';
86
+ export * from './components/composites/action-button';
86
87
  export * from './components/composites/list-row';
87
88
  export * from './components/composites/settings';
88
89
  export * from './components/composites/stat';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -87,6 +87,7 @@ import { ThemeProvider, defaultThemeSelection, inlineScriptLiteral, resolvedDens
87
87
  import { AppearancePanel } from "./components/theme/appearance-panel.js";
88
88
  import { ThemeToggle } from "./components/theme/theme-toggle.js";
89
89
  import { AccountMenu } from "./components/composites/account-menu/account-menu.js";
90
+ import { ActionButton } from "./components/composites/action-button/action-button.js";
90
91
  import { ListGroup, ListRow } from "./components/composites/list-row/list-row.js";
91
92
  import { SettingsField, SettingsPage, SettingsRow, SettingsSection } from "./components/composites/settings/settings.js";
92
93
  import { PropertyList, PropertyRow, PropertyTerm, PropertyValue, Stat, StatGroup } from "./components/composites/stat/stat.js";
@@ -96,4 +97,4 @@ import { formatBytes, formatReleaseDate, plainTextFromMarkdown } from "./lib/ver
96
97
  import { UpdateDialog } from "./components/composites/update-dialog/update-dialog.js";
97
98
  import { WorkspaceMark } from "./components/composites/workspace-mark/workspace-mark.js";
98
99
  import { keyedRows } from "./lib/keyed-rows.js";
99
- export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AccountMenu, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppShell, AppShellBody, AppShellContent, AppShellMain, AppearanceEditor, AppearancePanel, AppearancePopover, AspectRatio, AttachmentCard, Avatar, AvatarFallback, AvatarImage, Badge, Board, BoardCardBody, BoardCardTitle, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbSeparator, BusySendButton, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CalendarSurface, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChatComposer, Checkbox, CheckboxDescription, CheckboxLabel, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxClear, ComboboxContent, ComboboxControl, ComboboxInput, ComboboxItem, ComboboxSection, ComboboxTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut, ComposerAttachmentButton, ComposerHint, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ConversationAvatar, ConversationSurface, DatePicker, DetailPanel, DetailPanelBody, DetailPanelField, DetailPanelHeader, DetailPanelSection, Dialog, DialogClose, DialogCloseButton, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffBlock, DiffSummary, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, EntityIcon, Field, FieldDescription, FieldError, FieldInput, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTextArea, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputOtp, InputOtpCaret, Item, ItemDescription, ItemEmpty, ItemGroup, ItemGroupEntry, ItemTitle, Kbd, KbdGroup, Label, ListGroup, ListRow, MAX_LAYOUT_DEPTH, MAX_LAYOUT_LEAVES, MAX_SPLIT_RATIO, MIN_SPLIT_RATIO, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, ModalDialog, Motion, NativeSelect, NavigationMenu, NavigationMenuContent, NavigationMenuGroup, NavigationMenuGroupLabel, NavigationMenuItem, NavigationMenuMenu, NavigationMenuSeparator, NavigationMenuTrigger, NavigationMenuViewport, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, Page, PageHeader, PageHeaderActions, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, PageSection, Pagination, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPrevious, PalettePreview, Panel, PanelActions, PanelBody, PanelCard, PanelDescription, PanelFooter, PanelHeader, PanelPlaceholder, PanelTitle, PanelToolbar, Popover, PopoverAnchor, PopoverCloseButton, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger, Presence, Progress, PropertyList, PropertyRow, PropertyTerm, PropertyValue, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, Select, SelectChevronsUpDown, SelectContent, SelectItem, SelectLabel, SelectSection, SelectTrigger, SelectValue, Separator, SettingsField, SettingsPage, SettingsRow, SettingsSection, Sheet, SheetBody, SheetCloseButton, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, SideRail, SideRailButton, SideRailContent, SideRailFooter, SideRailHeader, SideRailItem, SideRailSection, SidebarNav, SidebarNavButton, SidebarNavContent, SidebarNavFooter, SidebarNavHeader, SidebarNavItem, SidebarNavSection, SidebarNavTitle, Skeleton, Slider, Spinner, SplitLayout, Stat, StatGroup, StatusBar, StatusBarItem, StatusBarSpacer, StatusChip, StatusList, Switch, SwitchDescription, SwitchLabel, TALL_CODE_BLOCK_PX, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableNumericCell, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeMiniature, ThemeMiniatureSplit, ThemePicker, ThemePreview, ThemeProvider, ThemeSwatch, ThemeToggle, ThreadPanel, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, TopBarBreadcrumb, TopBarPill, TopBarSearch, TopBarSection, TopBarTitle, TranscriptComposition, UpdateDialog, WorkspaceMark, accentPresets, alertVariants, allTokens, badgeVariants, boardCardTitleVariants, builtinThemes, buttonVariants, closePane, cn, colorTokens, computeLayoutFrames, contrastRatio, controlInteractive, controlSize, controlSizeIcon, controlSizes, countLeaves, countLines, createLayoutState, cva, defaultDarkThemeId, defaultLightThemeId, defaultThemeSelection, densityTokens, designTokens, diffLineVariants, diffStats, diffTargetPath, elevationTokens, entityIconVariants, expandAll, findTokenRanges, focusPane, fontOptions, formatBytes, formatReleaseDate, formatToken, initialsFrom, inlineScriptLiteral, isPasteBlock, itemVariants, keyedRows, layoutDepth, listLeaves, monogram, motionTokens, movePane, neighborLeaf, nextSeq, normalizeLayout, parseDiff, plainTextFromMarkdown, pruneBlocks, radiusTokens, recollapsePastes, remapCarriedBlocks, resizeSplit, resolvedDensity, sheetVariants, shouldCollapse, sidebarNavItemClass, sidebarNavItemStateClass, splitPane, statusDotVariants, stripTrailingBlankLines, surfaceInteractive, swapPanes, themeById, themeCssVariables, themeFamilies, themeScript, themesForAppearance, toast, toaster, toggleVariants, tokenRangeAt, transcriptDisclosureKey, typographyTokens, undoClosePane, undocumentedTokenAliases, useSideRail, useTheme, validateTheme, validateThemeRegistry, zIndexTokens };
100
+ export { Accordion, AccordionContent, AccordionItem, AccordionTrigger, AccountMenu, ActionButton, Alert, AlertDescription, AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger, AlertTitle, AppShell, AppShellBody, AppShellContent, AppShellMain, AppearanceEditor, AppearancePanel, AppearancePopover, AspectRatio, AttachmentCard, Avatar, AvatarFallback, AvatarImage, Badge, Board, BoardCardBody, BoardCardTitle, Breadcrumb, BreadcrumbEllipsis, BreadcrumbItem, BreadcrumbLink, BreadcrumbList, BreadcrumbSeparator, BusySendButton, Button, ButtonGroup, ButtonGroupSeparator, ButtonGroupText, CalendarSurface, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChatComposer, Checkbox, CheckboxDescription, CheckboxLabel, CodeBlock, Collapsible, CollapsibleContent, CollapsibleTrigger, Combobox, ComboboxClear, ComboboxContent, ComboboxControl, ComboboxInput, ComboboxItem, ComboboxSection, ComboboxTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandLoading, CommandSeparator, CommandShortcut, ComposerAttachmentButton, ComposerHint, ContextMenu, ContextMenuCheckboxItem, ContextMenuContent, ContextMenuGroup, ContextMenuItem, ContextMenuLabel, ContextMenuRadioGroup, ContextMenuRadioItem, ContextMenuSeparator, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuTrigger, ConversationAvatar, ConversationSurface, DatePicker, DetailPanel, DetailPanelBody, DetailPanelField, DetailPanelHeader, DetailPanelSection, Dialog, DialogClose, DialogCloseButton, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DiffBlock, DiffSummary, Drawer, DrawerBody, DrawerCloseButton, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerTitle, DrawerTrigger, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle, EntityIcon, Field, FieldDescription, FieldError, FieldInput, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTextArea, HoverCard, HoverCardContent, HoverCardTrigger, InlineCode, Input, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputOtp, InputOtpCaret, Item, ItemDescription, ItemEmpty, ItemGroup, ItemGroupEntry, ItemTitle, Kbd, KbdGroup, Label, ListGroup, ListRow, MAX_LAYOUT_DEPTH, MAX_LAYOUT_LEAVES, MAX_SPLIT_RATIO, MIN_SPLIT_RATIO, Menubar, MenubarCheckboxItem, MenubarContent, MenubarGroup, MenubarItem, MenubarLabel, MenubarMenu, MenubarRadioGroup, MenubarRadioItem, MenubarSeparator, MenubarSub, MenubarSubContent, MenubarSubTrigger, MenubarTrigger, MessageBody, MessageComposer, MessageDayDivider, MessageGroup, MessageRow, ModalDialog, Motion, NativeSelect, NavigationMenu, NavigationMenuContent, NavigationMenuGroup, NavigationMenuGroupLabel, NavigationMenuItem, NavigationMenuMenu, NavigationMenuSeparator, NavigationMenuTrigger, NavigationMenuViewport, PASTE_THRESHOLD_CHARS, PASTE_THRESHOLD_LINES, PASTE_TOKEN_REGEX, Page, PageHeader, PageHeaderActions, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, PageSection, Pagination, PaginationEllipsis, PaginationItem, PaginationNext, PaginationPrevious, PalettePreview, Panel, PanelActions, PanelBody, PanelCard, PanelDescription, PanelFooter, PanelHeader, PanelPlaceholder, PanelTitle, PanelToolbar, Popover, PopoverAnchor, PopoverCloseButton, PopoverContent, PopoverDescription, PopoverTitle, PopoverTrigger, Presence, Progress, PropertyList, PropertyRow, PropertyTerm, PropertyValue, RadioGroup, RadioGroupItem, ResizableHandle, ResizablePanel, ResizablePanelGroup, ScrollArea, Select, SelectChevronsUpDown, SelectContent, SelectItem, SelectLabel, SelectSection, SelectTrigger, SelectValue, Separator, SettingsField, SettingsPage, SettingsRow, SettingsSection, Sheet, SheetBody, SheetCloseButton, SheetContent, SheetDescription, SheetFooter, SheetHeader, SheetTitle, SheetTrigger, SideRail, SideRailButton, SideRailContent, SideRailFooter, SideRailHeader, SideRailItem, SideRailSection, SidebarNav, SidebarNavButton, SidebarNavContent, SidebarNavFooter, SidebarNavHeader, SidebarNavItem, SidebarNavSection, SidebarNavTitle, Skeleton, Slider, Spinner, SplitLayout, Stat, StatGroup, StatusBar, StatusBarItem, StatusBarSpacer, StatusChip, StatusList, Switch, SwitchDescription, SwitchLabel, TALL_CODE_BLOCK_PX, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableNumericCell, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, ThemeMiniature, ThemeMiniatureSplit, ThemePicker, ThemePreview, ThemeProvider, ThemeSwatch, ThemeToggle, ThreadPanel, Toaster, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, TopBar, TopBarBreadcrumb, TopBarPill, TopBarSearch, TopBarSection, TopBarTitle, TranscriptComposition, UpdateDialog, WorkspaceMark, accentPresets, alertVariants, allTokens, badgeVariants, boardCardTitleVariants, builtinThemes, buttonVariants, closePane, cn, colorTokens, computeLayoutFrames, contrastRatio, controlInteractive, controlSize, controlSizeIcon, controlSizes, countLeaves, countLines, createLayoutState, cva, defaultDarkThemeId, defaultLightThemeId, defaultThemeSelection, densityTokens, designTokens, diffLineVariants, diffStats, diffTargetPath, elevationTokens, entityIconVariants, expandAll, findTokenRanges, focusPane, fontOptions, formatBytes, formatReleaseDate, formatToken, initialsFrom, inlineScriptLiteral, isPasteBlock, itemVariants, keyedRows, layoutDepth, listLeaves, monogram, motionTokens, movePane, neighborLeaf, nextSeq, normalizeLayout, parseDiff, plainTextFromMarkdown, pruneBlocks, radiusTokens, recollapsePastes, remapCarriedBlocks, resizeSplit, resolvedDensity, sheetVariants, shouldCollapse, sidebarNavItemClass, sidebarNavItemStateClass, splitPane, statusDotVariants, stripTrailingBlankLines, surfaceInteractive, swapPanes, themeById, themeCssVariables, themeFamilies, themeScript, themesForAppearance, toast, toaster, toggleVariants, tokenRangeAt, transcriptDisclosureKey, typographyTokens, undoClosePane, undocumentedTokenAliases, useSideRail, useTheme, validateTheme, validateThemeRegistry, zIndexTokens };
@@ -9,6 +9,7 @@
9
9
  "registryDependencies": [
10
10
  "@adea-ai/ui/button",
11
11
  "@adea-ai/ui/dropdown-menu",
12
+ "@adea-ai/ui/tooltip",
12
13
  "lib"
13
14
  ],
14
15
  "files": [
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "action-button",
3
+ "type": "registry:ui",
4
+ "title": "Action Button",
5
+ "description": "A shared Button with optional tooltip and busy-state feedback.",
6
+ "dependencies": [],
7
+ "registryDependencies": [
8
+ "@adea-ai/ui/button",
9
+ "@adea-ai/ui/spinner",
10
+ "@adea-ai/ui/tooltip"
11
+ ],
12
+ "files": [
13
+ {
14
+ "path": "src/components/composites/action-button/action-button.tsx",
15
+ "type": "registry:ui",
16
+ "target": "components/composites/action-button/action-button.tsx"
17
+ },
18
+ {
19
+ "path": "src/components/composites/action-button/index.ts",
20
+ "type": "registry:ui",
21
+ "target": "components/composites/action-button/index.ts"
22
+ }
23
+ ]
24
+ }
@@ -15,6 +15,7 @@
15
15
  "@adea-ai/ui/kbd",
16
16
  "@adea-ai/ui/spinner",
17
17
  "@adea-ai/ui/textarea",
18
+ "@adea-ai/ui/tooltip",
18
19
  "lib"
19
20
  ],
20
21
  "files": [
@@ -1649,6 +1649,7 @@
1649
1649
  "registryDependencies": [
1650
1650
  "@adea-ai/ui/button",
1651
1651
  "@adea-ai/ui/dropdown-menu",
1652
+ "@adea-ai/ui/tooltip",
1652
1653
  "lib"
1653
1654
  ],
1654
1655
  "files": [
@@ -1664,6 +1665,30 @@
1664
1665
  }
1665
1666
  ]
1666
1667
  },
1668
+ {
1669
+ "name": "action-button",
1670
+ "type": "registry:ui",
1671
+ "title": "Action Button",
1672
+ "description": "A shared Button with optional tooltip and busy-state feedback.",
1673
+ "dependencies": [],
1674
+ "registryDependencies": [
1675
+ "@adea-ai/ui/button",
1676
+ "@adea-ai/ui/spinner",
1677
+ "@adea-ai/ui/tooltip"
1678
+ ],
1679
+ "files": [
1680
+ {
1681
+ "path": "src/components/composites/action-button/action-button.tsx",
1682
+ "type": "registry:ui",
1683
+ "target": "components/composites/action-button/action-button.tsx"
1684
+ },
1685
+ {
1686
+ "path": "src/components/composites/action-button/index.ts",
1687
+ "type": "registry:ui",
1688
+ "target": "components/composites/action-button/index.ts"
1689
+ }
1690
+ ]
1691
+ },
1667
1692
  {
1668
1693
  "name": "appearance-editor",
1669
1694
  "type": "registry:ui",
@@ -1853,6 +1878,7 @@
1853
1878
  "@adea-ai/ui/kbd",
1854
1879
  "@adea-ai/ui/spinner",
1855
1880
  "@adea-ai/ui/textarea",
1881
+ "@adea-ai/ui/tooltip",
1856
1882
  "lib"
1857
1883
  ],
1858
1884
  "files": [