@devalok/shilp-sutra 0.55.1 → 0.57.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 (270) hide show
  1. package/BREAKING.json +13 -0
  2. package/MIGRATION.md +163 -0
  3. package/README.md +16 -1
  4. package/dist/_chunks/badge-group.js +92 -78
  5. package/dist/_chunks/badge-group.js.map +1 -1
  6. package/dist/_chunks/chat.js +91 -75
  7. package/dist/_chunks/chat.js.map +1 -1
  8. package/dist/_chunks/document-preview.js +1 -1
  9. package/dist/_chunks/document-preview.js.map +1 -1
  10. package/dist/_chunks/emoji-suggestion.js +32 -30
  11. package/dist/_chunks/emoji-suggestion.js.map +1 -1
  12. package/dist/_chunks/mention-suggestion.js +36 -35
  13. package/dist/_chunks/mention-suggestion.js.map +1 -1
  14. package/dist/_chunks/oauth-button.js +1 -1
  15. package/dist/_chunks/oauth-button.js.map +1 -1
  16. package/dist/_chunks/primitives-internal.js +437 -537
  17. package/dist/_chunks/primitives-internal.js.map +1 -1
  18. package/dist/_chunks/success.js +2 -2
  19. package/dist/_chunks/success.js.map +1 -1
  20. package/dist/_chunks/tree-view.js +1 -1
  21. package/dist/_chunks/tree-view.js.map +1 -1
  22. package/dist/_chunks/use-calendar.js +4 -4
  23. package/dist/_chunks/use-calendar.js.map +1 -1
  24. package/dist/ai/blocks/text.js +1 -1
  25. package/dist/ai/blocks/text.js.map +1 -1
  26. package/dist/ai/command-bar.js +9 -9
  27. package/dist/ai/command-bar.js.map +1 -1
  28. package/dist/ai/conversation.js +2 -2
  29. package/dist/ai/conversation.js.map +1 -1
  30. package/dist/composed/activity-feed.js +1 -1
  31. package/dist/composed/activity-feed.js.map +1 -1
  32. package/dist/composed/avatar-group.d.ts +7 -2
  33. package/dist/composed/avatar-group.d.ts.map +1 -1
  34. package/dist/composed/avatar-group.js +3 -3
  35. package/dist/composed/avatar-group.js.map +1 -1
  36. package/dist/composed/command-palette.js +7 -7
  37. package/dist/composed/command-palette.js.map +1 -1
  38. package/dist/composed/content-card.js +20 -20
  39. package/dist/composed/content-card.js.map +1 -1
  40. package/dist/composed/date-picker/index.js +4 -4
  41. package/dist/composed/date-picker/index.js.map +1 -1
  42. package/dist/composed/diff.d.ts +23 -2
  43. package/dist/composed/diff.d.ts.map +1 -1
  44. package/dist/composed/diff.js +341 -260
  45. package/dist/composed/diff.js.map +1 -1
  46. package/dist/composed/emoji-picker.js +3 -3
  47. package/dist/composed/emoji-picker.js.map +1 -1
  48. package/dist/composed/error-boundary.js +2 -2
  49. package/dist/composed/error-boundary.js.map +1 -1
  50. package/dist/composed/extensions/emoji-node.js +8 -7
  51. package/dist/composed/extensions/emoji-node.js.map +1 -1
  52. package/dist/composed/file-preview.js +1 -1
  53. package/dist/composed/file-preview.js.map +1 -1
  54. package/dist/composed/filter-bar.js +1 -1
  55. package/dist/composed/filter-bar.js.map +1 -1
  56. package/dist/composed/inline-edit.js +1 -1
  57. package/dist/composed/inline-edit.js.map +1 -1
  58. package/dist/composed/loading-skeleton.js +3 -3
  59. package/dist/composed/loading-skeleton.js.map +1 -1
  60. package/dist/composed/master-detail.js +1 -1
  61. package/dist/composed/master-detail.js.map +1 -1
  62. package/dist/composed/member-picker.js +1 -1
  63. package/dist/composed/member-picker.js.map +1 -1
  64. package/dist/composed/multi-select-popover.js +1 -1
  65. package/dist/composed/multi-select-popover.js.map +1 -1
  66. package/dist/composed/page-skeletons.js +4 -4
  67. package/dist/composed/page-skeletons.js.map +1 -1
  68. package/dist/composed/responsive-modal.js +1 -1
  69. package/dist/composed/responsive-modal.js.map +1 -1
  70. package/dist/composed/rich-chat-input.js +549 -540
  71. package/dist/composed/rich-chat-input.js.map +1 -1
  72. package/dist/composed/rich-text-editor.js +206 -198
  73. package/dist/composed/rich-text-editor.js.map +1 -1
  74. package/dist/composed/schedule-view.js +5 -5
  75. package/dist/composed/schedule-view.js.map +1 -1
  76. package/dist/hooks/index.d.ts +1 -0
  77. package/dist/hooks/index.d.ts.map +1 -1
  78. package/dist/hooks/index.js +4 -3
  79. package/dist/hooks/use-container-size.d.ts +18 -0
  80. package/dist/hooks/use-container-size.d.ts.map +1 -0
  81. package/dist/hooks/use-container-size.js +28 -0
  82. package/dist/hooks/use-container-size.js.map +1 -0
  83. package/dist/shell/app-shell.d.ts +101 -0
  84. package/dist/shell/app-shell.d.ts.map +1 -0
  85. package/dist/shell/app-shell.js +76 -0
  86. package/dist/shell/app-shell.js.map +1 -0
  87. package/dist/shell/bottom-navbar.js +2 -2
  88. package/dist/shell/bottom-navbar.js.map +1 -1
  89. package/dist/shell/index.d.ts +1 -0
  90. package/dist/shell/index.d.ts.map +1 -1
  91. package/dist/shell/index.js +6 -5
  92. package/dist/shell/notification-center.js +4 -4
  93. package/dist/shell/notification-center.js.map +1 -1
  94. package/dist/shell/notification-preferences.js +1 -1
  95. package/dist/shell/notification-preferences.js.map +1 -1
  96. package/dist/shell/top-bar.js +7 -7
  97. package/dist/shell/top-bar.js.map +1 -1
  98. package/dist/tokens/generate-scale.d.ts +49 -0
  99. package/dist/tokens/generate-scale.d.ts.map +1 -1
  100. package/dist/tokens/primitives.css +29 -26
  101. package/dist/tokens/semantic.css +98 -39
  102. package/dist/tokens/variants.css +1 -1
  103. package/dist/ui/accordion.js +1 -1
  104. package/dist/ui/accordion.js.map +1 -1
  105. package/dist/ui/alert-dialog.js +1 -1
  106. package/dist/ui/alert-dialog.js.map +1 -1
  107. package/dist/ui/alert.d.ts.map +1 -1
  108. package/dist/ui/alert.js +36 -36
  109. package/dist/ui/alert.js.map +1 -1
  110. package/dist/ui/avatar.js +44 -44
  111. package/dist/ui/avatar.js.map +1 -1
  112. package/dist/ui/badge-indicator.js +1 -1
  113. package/dist/ui/badge-indicator.js.map +1 -1
  114. package/dist/ui/badge.d.ts +47 -33
  115. package/dist/ui/badge.d.ts.map +1 -1
  116. package/dist/ui/banner.js +26 -26
  117. package/dist/ui/banner.js.map +1 -1
  118. package/dist/ui/button.js +35 -35
  119. package/dist/ui/button.js.map +1 -1
  120. package/dist/ui/card.js +42 -42
  121. package/dist/ui/card.js.map +1 -1
  122. package/dist/ui/chat/date-separator.d.ts +8 -1
  123. package/dist/ui/chat/date-separator.d.ts.map +1 -1
  124. package/dist/ui/checkbox.js +1 -1
  125. package/dist/ui/checkbox.js.map +1 -1
  126. package/dist/ui/code.js +2 -2
  127. package/dist/ui/code.js.map +1 -1
  128. package/dist/ui/color-input.js +3 -3
  129. package/dist/ui/color-input.js.map +1 -1
  130. package/dist/ui/combobox.js +139 -139
  131. package/dist/ui/combobox.js.map +1 -1
  132. package/dist/ui/context-menu.js +4 -4
  133. package/dist/ui/context-menu.js.map +1 -1
  134. package/dist/ui/data-table-body.d.ts +3 -1
  135. package/dist/ui/data-table-body.d.ts.map +1 -1
  136. package/dist/ui/data-table-body.js +93 -92
  137. package/dist/ui/data-table-body.js.map +1 -1
  138. package/dist/ui/data-table-bulk-actions.d.ts +7 -1
  139. package/dist/ui/data-table-bulk-actions.d.ts.map +1 -1
  140. package/dist/ui/data-table-bulk-actions.js +14 -8
  141. package/dist/ui/data-table-bulk-actions.js.map +1 -1
  142. package/dist/ui/data-table-card.d.ts.map +1 -1
  143. package/dist/ui/data-table-card.js +66 -47
  144. package/dist/ui/data-table-card.js.map +1 -1
  145. package/dist/ui/data-table-context.d.ts +4 -0
  146. package/dist/ui/data-table-context.d.ts.map +1 -1
  147. package/dist/ui/data-table-context.js.map +1 -1
  148. package/dist/ui/data-table-header.d.ts.map +1 -1
  149. package/dist/ui/data-table-header.js +18 -15
  150. package/dist/ui/data-table-header.js.map +1 -1
  151. package/dist/ui/data-table-pagination.js +3 -3
  152. package/dist/ui/data-table-pagination.js.map +1 -1
  153. package/dist/ui/data-table-toolbar.d.ts +11 -1
  154. package/dist/ui/data-table-toolbar.d.ts.map +1 -1
  155. package/dist/ui/data-table-toolbar.js +7 -7
  156. package/dist/ui/data-table-toolbar.js.map +1 -1
  157. package/dist/ui/data-table.d.ts +52 -5
  158. package/dist/ui/data-table.d.ts.map +1 -1
  159. package/dist/ui/data-table.js +181 -169
  160. package/dist/ui/data-table.js.map +1 -1
  161. package/dist/ui/dialog.js +1 -1
  162. package/dist/ui/dialog.js.map +1 -1
  163. package/dist/ui/dot.js +13 -13
  164. package/dist/ui/dot.js.map +1 -1
  165. package/dist/ui/dropdown-menu.js +4 -4
  166. package/dist/ui/dropdown-menu.js.map +1 -1
  167. package/dist/ui/file-upload.js +3 -3
  168. package/dist/ui/file-upload.js.map +1 -1
  169. package/dist/ui/input-otp.js +1 -1
  170. package/dist/ui/input-otp.js.map +1 -1
  171. package/dist/ui/input.js +30 -30
  172. package/dist/ui/input.js.map +1 -1
  173. package/dist/ui/lib/utils.js +2 -1
  174. package/dist/ui/lib/utils.js.map +1 -1
  175. package/dist/ui/menubar.js +5 -5
  176. package/dist/ui/menubar.js.map +1 -1
  177. package/dist/ui/navigation-menu.js +1 -1
  178. package/dist/ui/navigation-menu.js.map +1 -1
  179. package/dist/ui/number-input.js +36 -36
  180. package/dist/ui/number-input.js.map +1 -1
  181. package/dist/ui/pagination.js +1 -1
  182. package/dist/ui/pagination.js.map +1 -1
  183. package/dist/ui/progress-ring.js +2 -2
  184. package/dist/ui/progress-ring.js.map +1 -1
  185. package/dist/ui/progress.d.ts.map +1 -1
  186. package/dist/ui/progress.js +66 -62
  187. package/dist/ui/progress.js.map +1 -1
  188. package/dist/ui/radio.js +1 -1
  189. package/dist/ui/radio.js.map +1 -1
  190. package/dist/ui/select.js +61 -61
  191. package/dist/ui/select.js.map +1 -1
  192. package/dist/ui/sheet.js +47 -47
  193. package/dist/ui/sheet.js.map +1 -1
  194. package/dist/ui/sidebar.js +132 -132
  195. package/dist/ui/sidebar.js.map +1 -1
  196. package/dist/ui/skeleton.js +39 -39
  197. package/dist/ui/slider.js +18 -18
  198. package/dist/ui/slider.js.map +1 -1
  199. package/dist/ui/split-button.js +3 -3
  200. package/dist/ui/split-button.js.map +1 -1
  201. package/dist/ui/stat-card.js +1 -1
  202. package/dist/ui/stat-card.js.map +1 -1
  203. package/dist/ui/stepper.js +2 -2
  204. package/dist/ui/stepper.js.map +1 -1
  205. package/dist/ui/surface.d.ts.map +1 -1
  206. package/dist/ui/surface.js +11 -11
  207. package/dist/ui/surface.js.map +1 -1
  208. package/dist/ui/switch.js +1 -1
  209. package/dist/ui/switch.js.map +1 -1
  210. package/dist/ui/table.js +1 -1
  211. package/dist/ui/table.js.map +1 -1
  212. package/dist/ui/tabs.d.ts.map +1 -1
  213. package/dist/ui/tabs.js +48 -48
  214. package/dist/ui/tabs.js.map +1 -1
  215. package/dist/ui/text.js +8 -8
  216. package/dist/ui/textarea.js +17 -17
  217. package/dist/ui/textarea.js.map +1 -1
  218. package/dist/ui/toast.js +1 -1
  219. package/dist/ui/toast.js.map +1 -1
  220. package/dist/ui/toggle.js +15 -15
  221. package/dist/ui/toggle.js.map +1 -1
  222. package/docs/components/composed/avatar-group.md +4 -4
  223. package/docs/components/composed/diff.md +10 -2
  224. package/docs/components/composed/schedule-view.md +1 -1
  225. package/docs/components/shell/app-shell.md +132 -0
  226. package/docs/components/ui/avatar.md +1 -1
  227. package/docs/components/ui/button.md +1 -1
  228. package/docs/components/ui/chat.md +7 -1
  229. package/docs/components/ui/color-swatch.md +1 -1
  230. package/docs/components/ui/data-table-toolbar.md +6 -2
  231. package/docs/components/ui/data-table.md +41 -7
  232. package/docs/components/ui/dot.md +1 -1
  233. package/docs/components/ui/progress.md +1 -0
  234. package/docs/components/ui/surface.md +3 -3
  235. package/docs/components/ui/table.md +2 -2
  236. package/docs/recipes/install-astro.md +3 -2
  237. package/docs/recipes/install-next-app-router.md +3 -2
  238. package/docs/recipes/install-remix.md +3 -2
  239. package/docs/recipes/install-tanstack-start.md +3 -2
  240. package/docs/recipes/install-vite.md +3 -2
  241. package/docs/recipes/troubleshoot.md +26 -5
  242. package/llms.txt +2 -1
  243. package/make-kit/Guidelines.md +2 -2
  244. package/make-kit/components/button.md +1 -1
  245. package/make-kit/components/card.md +6 -6
  246. package/make-kit/components/surface.md +4 -4
  247. package/make-kit/foundations/color.md +4 -4
  248. package/make-kit/foundations/dark-mode.md +1 -1
  249. package/make-kit/foundations/radius.md +1 -1
  250. package/make-kit/foundations/surfaces.md +9 -9
  251. package/mcp-manifest.json +373 -34
  252. package/package.json +43 -13
  253. package/skill/SKILL.md +12 -6
  254. package/skill/references/components.md +2 -1
  255. package/skill/references/setup-astro.md +3 -2
  256. package/skill/references/setup-next-app-router.md +3 -2
  257. package/skill/references/setup-remix.md +3 -2
  258. package/skill/references/setup-tanstack-start.md +3 -2
  259. package/skill/references/setup-vite.md +3 -2
  260. package/skill/references/troubleshoot.md +26 -5
  261. package/dist/_chunks/tiptap.js +0 -18809
  262. package/dist/_chunks/tiptap.js.map +0 -1
  263. package/dist/_chunks/vendor-utils.js +0 -1766
  264. package/dist/_chunks/vendor-utils.js.map +0 -1
  265. package/dist/primitives/react-toast.d.ts +0 -120
  266. package/dist/ui/charts/_internal/scales.d.ts +0 -5
  267. package/dist/ui/charts/_internal/scales.d.ts.map +0 -1
  268. package/dist/ui/lib/slot.d.ts +0 -8
  269. package/dist/ui/lib/slot.d.ts.map +0 -1
  270. package/scripts/welcome.mjs +0 -312
@@ -146,7 +146,7 @@ var b = m.forwardRef(function({ groups: b = [], placeholder: x = "Search or jump
146
146
  spellCheck: !1
147
147
  }),
148
148
  /* @__PURE__ */ h("kbd", {
149
- className: "hidden shrink-0 select-none rounded-control border border-card-strong bg-surface-raised px-ds-02b py-ds-01 text-body-sm font-medium text-surface-fg-subtle shadow-kbd sm:inline-flex",
149
+ className: "hidden shrink-0 select-none rounded-control border border-card-strong bg-surface-panel px-ds-02b py-ds-01 text-body-sm font-medium text-surface-fg-subtle shadow-kbd sm:inline-flex",
150
150
  children: "Esc"
151
151
  })
152
152
  ]
@@ -205,7 +205,7 @@ var b = m.forwardRef(function({ groups: b = [], placeholder: x = "Search or jump
205
205
  n.onSelect(), R(!1);
206
206
  },
207
207
  onMouseEnter: () => H(a),
208
- className: r("flex w-full items-center gap-ds-04 rounded-surface px-ds-03 py-ds-03 text-left transition-[color,background-color] duration-fast-02 ease-productive-standard", s ? "bg-surface-raised-hover text-surface-fg" : "text-surface-fg-muted hover:bg-surface-raised"),
208
+ className: r("flex w-full items-center gap-ds-04 rounded-surface px-ds-03 py-ds-03 text-left transition-[color,background-color] duration-fast-02 ease-productive-standard", s ? "bg-surface-panel-hover text-surface-fg" : "text-surface-fg-muted hover:bg-surface-panel-hover"),
209
209
  children: [
210
210
  n.icon && /* @__PURE__ */ h("span", {
211
211
  className: r("[&>svg]:h-ico-sm [&>svg]:w-ico-sm shrink-0 transition-colors duration-fast-02 ease-productive-standard", s ? "text-accent-11" : "text-surface-fg-subtle"),
@@ -228,7 +228,7 @@ var b = m.forwardRef(function({ groups: b = [], placeholder: x = "Search or jump
228
228
  n.shortcut && /* @__PURE__ */ h("span", {
229
229
  className: "flex shrink-0 items-center gap-ds-01",
230
230
  children: y(n.shortcut).map((e, t) => /* @__PURE__ */ h("kbd", {
231
- className: r("inline-flex min-w-ds-05b items-center justify-center rounded border px-ds-02b py-ds-01 text-body-xs font-medium shadow-kbd transition-colors duration-fast-02 ease-productive-standard", s ? "bg-accent-2 text-accent-11 border-accent-6" : "bg-surface-raised text-surface-fg-subtle border-surface-border-strong"),
231
+ className: r("inline-flex min-w-ds-05b items-center justify-center rounded border px-ds-02b py-ds-01 text-body-xs font-medium shadow-kbd transition-colors duration-fast-02 ease-productive-standard", s ? "bg-accent-2 text-accent-11 border-accent-6" : "bg-surface-panel text-surface-fg-subtle border-surface-border-strong"),
232
232
  children: e === "Ctrl" || e === "ctrl" ? f(ue) : e
233
233
  }, t))
234
234
  }),
@@ -260,14 +260,14 @@ var b = m.forwardRef(function({ groups: b = [], placeholder: x = "Search or jump
260
260
  children: [e.keys === "↑↓" ? /* @__PURE__ */ g("div", {
261
261
  className: "flex items-center gap-ds-01",
262
262
  children: [/* @__PURE__ */ h("kbd", {
263
- className: "inline-flex h-ico-md w-ico-md items-center justify-center rounded border border-card-strong bg-surface-raised shadow-kbd",
263
+ className: "inline-flex h-ico-md w-ico-md items-center justify-center rounded border border-card-strong bg-surface-panel shadow-kbd",
264
264
  children: /* @__PURE__ */ h(i, {
265
265
  icon: ie,
266
266
  size: "xs",
267
267
  className: "text-surface-fg-subtle"
268
268
  })
269
269
  }), /* @__PURE__ */ h("kbd", {
270
- className: "inline-flex h-ico-md w-ico-md items-center justify-center rounded border border-card-strong bg-surface-raised shadow-kbd",
270
+ className: "inline-flex h-ico-md w-ico-md items-center justify-center rounded border border-card-strong bg-surface-panel shadow-kbd",
271
271
  children: /* @__PURE__ */ h(i, {
272
272
  icon: re,
273
273
  size: "xs",
@@ -275,14 +275,14 @@ var b = m.forwardRef(function({ groups: b = [], placeholder: x = "Search or jump
275
275
  })
276
276
  })]
277
277
  }) : e.keys === "↵" ? /* @__PURE__ */ h("kbd", {
278
- className: "inline-flex h-ds-05b items-center justify-center rounded-control border border-card-strong bg-surface-raised px-ds-02b shadow-kbd",
278
+ className: "inline-flex h-ds-05b items-center justify-center rounded-control border border-card-strong bg-surface-panel px-ds-02b shadow-kbd",
279
279
  children: /* @__PURE__ */ h(i, {
280
280
  icon: _,
281
281
  size: "xs",
282
282
  className: "text-surface-fg-subtle"
283
283
  })
284
284
  }) : /* @__PURE__ */ h("kbd", {
285
- className: "inline-flex h-ds-05b items-center justify-center rounded-control border border-card-strong bg-surface-raised px-ds-02b text-caption font-medium text-surface-fg-subtle shadow-kbd",
285
+ className: "inline-flex h-ds-05b items-center justify-center rounded-control border border-card-strong bg-surface-panel px-ds-02b text-caption font-medium text-surface-fg-subtle shadow-kbd",
286
286
  children: e.keys
287
287
  }), /* @__PURE__ */ h("span", {
288
288
  className: "text-caption text-surface-fg-subtle",
@@ -1 +1 @@
1
- {"version":3,"file":"command-palette.js","names":[],"sources":["../../src/composed/command-palette.tsx"],"sourcesContent":["'use client'\n\n/**\n * CommandPalette -- Keyboard-driven command palette (Ctrl+K / Cmd+K).\n *\n * Adapted from Karm V2. Uses ui/Dialog as the overlay.\n * All V1 color tokens replaced with semantic design-system tokens.\n */\nimport { IconArrowDown,IconArrowUp, IconCornerDownLeft, IconSearch } from '@tabler/icons-react'\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { useMotion } from '../motion/motion-provider'\nimport {\n Dialog,\n DialogContentRaw,\n DialogDescription,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n} from '../ui/dialog'\nimport { Icon } from '../ui/icon'\nimport { IconProvider } from '../ui/icon-context'\nimport type { IconInput } from '../ui/lib/icon-input'\nimport { springs,tweens } from '../ui/lib/motion'\nimport { normalizeIcon } from '../ui/lib/normalize-icon'\nimport { cn } from '../ui/lib/utils'\nimport { VisuallyHidden } from '../ui/visually-hidden'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface CommandItem {\n id: string\n /** Display label — string or ReactNode. When ReactNode, provide `filterValue` for search filtering. */\n label: string | React.ReactNode\n /** Optional description — string or ReactNode. */\n description?: string | React.ReactNode\n icon?: IconInput\n /** Keyboard shortcut hint displayed as keycap badges (e.g., \"G D\", \"Ctrl+N\"). */\n shortcut?: string\n /** Custom render override for the label. Receives the current search query for match highlighting. */\n renderLabel?: (query: string) => React.ReactNode\n /** Plain-text value used for search filtering when `label` is a ReactNode. Falls back to `label` if string. */\n filterValue?: string\n onSelect: () => void\n}\n\nexport interface CommandGroup {\n label: string\n items: CommandItem[]\n}\n\n/** A single keyboard hint shown in the footer. */\nexport interface FooterHint {\n /** Key(s) to display — rendered as text inside `<kbd>` or as an icon. */\n keys: string\n /** Human-readable label for the hint (e.g., \"Navigate\", \"Select\"). */\n label: string\n}\n\n/**\n * A searchable command palette with keyboard navigation (Ctrl+K / Cmd+K).\n * Supports grouped items, custom keybindings, controlled/uncontrolled open state,\n * and custom empty states.\n */\nexport interface CommandPaletteProps extends React.ComponentPropsWithoutRef<'div'> {\n /** Item groups displayed in the palette. Each group has a label and an array of CommandItems. */\n groups?: CommandGroup[]\n /** Placeholder text for the search input. */\n placeholder?: string\n /** Called on every search input change with the current query string. */\n onSearch?: (query: string) => void\n /** Simple text shown when no results match. Overridden by `emptyState` if provided. */\n emptyMessage?: string\n /** Full custom empty state ReactNode — overrides `emptyMessage` when provided. */\n emptyState?: React.ReactNode\n // -- Controlled/uncontrolled open state (P1 #4) --\n /** Controlled open state. */\n open?: boolean\n /** Default open state for uncontrolled usage. */\n defaultOpen?: boolean\n /** Called when the open state changes. */\n onOpenChange?: (open: boolean) => void\n // -- Keyboard shortcut customization (P1 #6) --\n /** Keybinding(s) to toggle the palette. Pass `false` to disable.\n * String format: modifier+key, e.g., 'mod+k', 'ctrl+shift+p'.\n * 'mod' maps to Meta on macOS, Ctrl otherwise. */\n keybinding?: string | string[] | false\n // -- Configurable max-height (P2 #8) --\n /** Max height of the results container. CSS value. Default '320px'. */\n maxHeight?: string | number\n // -- Custom footer hints (P2 #11) --\n /** Custom footer keyboard hints. Pass `false` to hide the footer entirely. */\n footerHints?: FooterHint[] | false\n}\n\n// -----------------------------------------------------------------------\n// Helpers\n// -----------------------------------------------------------------------\n\nimport { getIsMac, getModifierDisplay,matchesKeybinding } from '../ui/lib/keybinding'\n\n/** Get the text-searchable value from a CommandItem. */\nfunction getFilterValue(item: CommandItem): string {\n if (item.filterValue) return item.filterValue\n if (typeof item.label === 'string') return item.label\n return ''\n}\n\n/** Get the text-searchable description from a CommandItem. */\nfunction getFilterDescription(item: CommandItem): string {\n if (typeof item.description === 'string') return item.description\n return ''\n}\n\n/** Parse a shortcut string like \"G D\" or \"Ctrl+N\" into individual keycap segments. */\nfunction parseShortcutKeys(shortcut: string): string[] {\n // If it has \"+\" separator (Ctrl+Shift+N style), split on +\n if (shortcut.includes('+')) {\n return shortcut.split('+').map(s => s.trim()).filter(Boolean)\n }\n // Otherwise split on spaces (G D style)\n return shortcut.split(/\\s+/).filter(Boolean)\n}\n\n// -----------------------------------------------------------------------\n// CommandPalette\n// -----------------------------------------------------------------------\n\nconst CommandPalette = React.forwardRef<HTMLDivElement, CommandPaletteProps>(\n function CommandPalette(\n {\n groups = [],\n placeholder = 'Search or jump to...',\n onSearch,\n emptyMessage = 'No results found.',\n emptyState,\n open: openProp,\n defaultOpen,\n onOpenChange,\n keybinding = 'mod+k',\n maxHeight = '320px',\n footerHints,\n className,\n ...props\n },\n ref,\n ) {\n // -- Controlled/uncontrolled open state --\n const isControlled = openProp !== undefined\n const [internalOpen, setInternalOpen] = React.useState(defaultOpen ?? false)\n const open = isControlled ? openProp : internalOpen\n\n // Use a ref for the current open value to avoid stale closures in setOpen\n const openRef = React.useRef(open)\n openRef.current = open\n\n const setOpen = React.useCallback(\n (nextOpen: boolean | ((prev: boolean) => boolean)) => {\n const resolved = typeof nextOpen === 'function' ? nextOpen(openRef.current) : nextOpen\n if (!isControlled) {\n setInternalOpen(resolved)\n }\n onOpenChange?.(resolved)\n },\n [isControlled, onOpenChange],\n )\n\n const [query, setQuery] = React.useState('')\n const [activeIndex, setActiveIndex] = React.useState(0)\n const inputRef = React.useRef<HTMLInputElement>(null)\n const listRef = React.useRef<HTMLDivElement>(null)\n const instanceId = React.useId()\n const listboxId = `command-palette-listbox-${instanceId}`\n\n // -- Reduced motion (P2 #12) --\n const { reducedMotion: isReduced } = useMotion()\n const noMotionTransition = { duration: 0 }\n\n // -- Platform detection (P2 #13) --\n const isMac = React.useMemo(() => getIsMac(), [])\n\n // Filter groups based on query\n const filteredGroups = React.useMemo(() => {\n if (!query.trim()) return groups\n const q = query.toLowerCase()\n return groups\n .map((group) => ({\n ...group,\n items: group.items.filter(\n (item) =>\n getFilterValue(item).toLowerCase().includes(q) ||\n getFilterDescription(item).toLowerCase().includes(q),\n ),\n }))\n .filter((group) => group.items.length > 0)\n }, [groups, query])\n\n const filteredItems = React.useMemo(\n () => filteredGroups.flatMap((g) => g.items),\n [filteredGroups],\n )\n\n // Global keyboard shortcut\n React.useEffect(() => {\n if (keybinding === false) return\n\n const bindings = Array.isArray(keybinding) ? keybinding : [keybinding]\n\n function handleKeyDown(e: KeyboardEvent) {\n for (const binding of bindings) {\n if (matchesKeybinding(e, binding)) {\n e.preventDefault()\n setOpen((prev) => !prev)\n return\n }\n }\n }\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [keybinding, setOpen])\n\n // Reset state when opening\n React.useEffect(() => {\n if (open) {\n setQuery('')\n setActiveIndex(0)\n requestAnimationFrame(() => {\n inputRef.current?.focus()\n })\n }\n }, [open])\n\n // Keyboard navigation inside the palette\n const handleKeyDown = (e: React.KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault()\n setActiveIndex((prev) =>\n prev < filteredItems.length - 1 ? prev + 1 : 0,\n )\n break\n }\n case 'ArrowUp': {\n e.preventDefault()\n setActiveIndex((prev) =>\n prev > 0 ? prev - 1 : filteredItems.length - 1,\n )\n break\n }\n case 'Enter': {\n e.preventDefault()\n const item = filteredItems[activeIndex]\n if (item) {\n item.onSelect()\n setOpen(false)\n }\n break\n }\n case 'Escape': {\n e.preventDefault()\n setOpen(false)\n break\n }\n }\n }\n\n // Scroll active item into view\n React.useEffect(() => {\n const activeEl = listRef.current?.querySelector(\n `[data-command-index=\"${activeIndex}\"]`,\n )\n activeEl?.scrollIntoView({ block: 'nearest' })\n }, [activeIndex])\n\n const handleQueryChange = (value: string) => {\n setQuery(value)\n setActiveIndex(0)\n onSearch?.(value)\n }\n\n // Build a map of item id -> flat index for keyboard navigation\n const itemIndexMap = React.useMemo(() => {\n const map = new Map<string, number>()\n let idx = 0\n for (const group of filteredGroups) {\n for (const item of group.items) {\n map.set(item.id, idx++)\n }\n }\n return map\n }, [filteredGroups])\n\n // -- Resolve motion transitions --\n const springSnappy = isReduced ? noMotionTransition : springs.snappy\n const tweenFade = isReduced ? noMotionTransition : tweens.fade\n const noInit = isReduced ? { opacity: 1, scale: 1, y: 0 } : undefined\n\n // -- Resolve max height CSS value --\n const maxHeightValue = typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight\n\n // -- Resolve footer hints --\n const resolvedFooterHints: FooterHint[] | false =\n footerHints === false\n ? false\n : footerHints ?? [\n { keys: '↑↓', label: 'Navigate' },\n { keys: '↵', label: 'Select' },\n { keys: 'Esc', label: 'Close' },\n ]\n\n // Handle dialog open change (from Dialog's own close mechanisms)\n const handleDialogOpenChange = React.useCallback(\n (nextOpen: boolean) => {\n setOpen(nextOpen)\n },\n [setOpen],\n )\n\n return (\n <Dialog open={open} onOpenChange={handleDialogOpenChange}>\n <DialogPortal>\n <DialogOverlay\n className=\"fixed inset-0 z-overlay bg-overlay data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n />\n <DialogContentRaw\n ref={ref}\n {...props}\n className={cn(\n 'fixed left-1/2 top-[20%] z-modal w-full max-w-[560px] -translate-x-1/2',\n 'overflow-hidden rounded-overlay-lg bg-surface-overlay shadow-overlay',\n 'duration-moderate-02 data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n 'data-[state=closed]:slide-out-to-left-1/2 data-[state=open]:slide-in-from-left-1/2',\n 'data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2',\n className,\n )}\n onKeyDown={handleKeyDown}\n >\n <VisuallyHidden>\n <DialogTitle>Command Palette</DialogTitle>\n <DialogDescription>\n Search or jump to pages, projects, tasks, and actions\n </DialogDescription>\n </VisuallyHidden>\n\n {/* Search input */}\n <div className=\"flex items-center gap-ds-04 border-b border-surface-border-strong px-ds-05 py-ds-04\">\n <motion.span\n initial={noInit ?? { opacity: 0, scale: 0.96 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={springSnappy}\n className=\"inline-flex shrink-0\"\n >\n <Icon icon={IconSearch} size=\"sm\" stroke=\"light\" className=\"text-surface-fg-subtle\" />\n </motion.span>\n <input\n ref={inputRef}\n value={query}\n onChange={(e) => handleQueryChange(e.target.value)}\n placeholder={placeholder}\n role=\"combobox\"\n aria-expanded={true}\n aria-controls={listboxId}\n aria-activedescendant={filteredItems[activeIndex] ? `command-item-${instanceId}-${filteredItems[activeIndex].id}` : undefined}\n aria-autocomplete=\"list\"\n className={cn(\n 'flex-1 bg-transparent text-body-lg text-surface-fg outline-hidden',\n 'placeholder:text-surface-fg-subtle',\n )}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n />\n <kbd className=\"hidden shrink-0 select-none rounded-control border border-card-strong bg-surface-raised px-ds-02b py-ds-01 text-body-sm font-medium text-surface-fg-subtle shadow-kbd sm:inline-flex\">\n Esc\n </kbd>\n </div>\n\n {/* Results */}\n <div\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n aria-label=\"Command results\"\n className=\"overflow-y-auto px-ds-03 py-ds-03\"\n style={{ maxHeight: maxHeightValue }}\n >\n {filteredGroups.length === 0 && (\n <motion.div\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={tweenFade}\n className=\"flex items-center justify-center py-ds-07\"\n >\n {emptyState ?? (\n <p className=\"text-body-md text-surface-fg-subtle\">\n {emptyMessage}\n </p>\n )}\n </motion.div>\n )}\n\n {filteredGroups.map((group, groupIdx) => (\n <motion.div\n key={group.label}\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={isReduced ? noMotionTransition : { ...tweens.fade, delay: groupIdx * 0.06 }}\n className=\"mb-ds-02\"\n >\n <div className=\"px-ds-03 pb-ds-02 pt-ds-03\">\n <span className=\"text-label-xs font-semibold uppercase tracking-wider text-surface-fg-subtle\">\n {group.label}\n </span>\n </div>\n\n {group.items.map((item) => {\n const itemIndex = itemIndexMap.get(item.id) ?? 0\n const isActive = itemIndex === activeIndex\n return (\n <motion.button\n key={item.id}\n id={`command-item-${instanceId}-${item.id}`}\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n data-command-index={itemIndex}\n initial={noInit ?? { opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n transition={isReduced ? noMotionTransition : { ...springs.snappy, delay: itemIndex * 0.03 }}\n onClick={() => {\n item.onSelect()\n setOpen(false)\n }}\n onMouseEnter={() => setActiveIndex(itemIndex)}\n className={cn(\n 'flex w-full items-center gap-ds-04 rounded-surface px-ds-03 py-ds-03 text-left transition-[color,background-color] duration-fast-02 ease-productive-standard',\n isActive\n ? 'bg-surface-raised-hover text-surface-fg'\n : 'text-surface-fg-muted hover:bg-surface-raised',\n )}\n >\n {item.icon && (\n <span\n className={cn(\n '[&>svg]:h-ico-sm [&>svg]:w-ico-sm shrink-0 transition-colors duration-fast-02 ease-productive-standard',\n isActive ? 'text-accent-11' : 'text-surface-fg-subtle',\n )}\n aria-hidden=\"true\"\n >\n <IconProvider size=\"sm\">{normalizeIcon(item.icon)}</IconProvider>\n </span>\n )}\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"truncate text-body-md\">\n {item.renderLabel ? item.renderLabel(query) : item.label}\n </span>\n {item.description && (\n <span className=\"line-clamp-1 text-body-sm text-surface-fg-subtle\">\n {item.description}\n </span>\n )}\n </div>\n {item.shortcut && (\n <span className=\"flex shrink-0 items-center gap-ds-01\">\n {parseShortcutKeys(item.shortcut).map((key, i) => (\n <kbd\n key={i}\n className={cn(\n 'inline-flex min-w-ds-05b items-center justify-center rounded border px-ds-02b py-ds-01 text-body-xs font-medium shadow-kbd transition-colors duration-fast-02 ease-productive-standard',\n isActive\n ? 'bg-accent-2 text-accent-11 border-accent-6'\n : 'bg-surface-raised text-surface-fg-subtle border-surface-border-strong',\n )}\n >\n {key === 'Ctrl' || key === 'ctrl' ? getModifierDisplay(isMac) : key}\n </kbd>\n ))}\n </span>\n )}\n <AnimatePresence>\n {isActive && (\n <motion.span\n initial={isReduced ? undefined : { opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={isReduced ? undefined : { opacity: 0 }}\n transition={tweenFade}\n className=\"inline-flex shrink-0\"\n >\n <Icon icon={IconCornerDownLeft} size=\"sm\" stroke=\"light\" className=\"text-surface-fg-subtle\" />\n </motion.span>\n )}\n </AnimatePresence>\n </motion.button>\n )\n })}\n </motion.div>\n ))}\n </div>\n\n {/* Footer with keyboard hints */}\n {resolvedFooterHints !== false && (\n <motion.div\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={tweenFade}\n className=\"flex items-center gap-ds-05 border-t border-surface-border-strong px-ds-05 py-ds-03\"\n >\n {resolvedFooterHints.map((hint, i) => (\n <div key={i} className=\"flex items-center gap-ds-02b\">\n {hint.keys === '↑↓' ? (\n <div className=\"flex items-center gap-ds-01\">\n <kbd className=\"inline-flex h-ico-md w-ico-md items-center justify-center rounded border border-card-strong bg-surface-raised shadow-kbd\">\n <Icon icon={IconArrowUp} size=\"xs\" className=\"text-surface-fg-subtle\" />\n </kbd>\n <kbd className=\"inline-flex h-ico-md w-ico-md items-center justify-center rounded border border-card-strong bg-surface-raised shadow-kbd\">\n <Icon icon={IconArrowDown} size=\"xs\" className=\"text-surface-fg-subtle\" />\n </kbd>\n </div>\n ) : hint.keys === '↵' ? (\n <kbd className=\"inline-flex h-ds-05b items-center justify-center rounded-control border border-card-strong bg-surface-raised px-ds-02b shadow-kbd\">\n <Icon icon={IconCornerDownLeft} size=\"xs\" className=\"text-surface-fg-subtle\" />\n </kbd>\n ) : (\n <kbd className=\"inline-flex h-ds-05b items-center justify-center rounded-control border border-card-strong bg-surface-raised px-ds-02b text-caption font-medium text-surface-fg-subtle shadow-kbd\">\n {hint.keys}\n </kbd>\n )}\n <span className=\"text-caption text-surface-fg-subtle\">\n {hint.label}\n </span>\n </div>\n ))}\n </motion.div>\n )}\n </DialogContentRaw>\n </DialogPortal>\n </Dialog>\n )\n },\n)\n\nCommandPalette.displayName = 'CommandPalette'\n\nexport { CommandPalette }\n"],"mappings":"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"}
1
+ {"version":3,"file":"command-palette.js","names":[],"sources":["../../src/composed/command-palette.tsx"],"sourcesContent":["'use client'\n\n/**\n * CommandPalette -- Keyboard-driven command palette (Ctrl+K / Cmd+K).\n *\n * Adapted from Karm V2. Uses ui/Dialog as the overlay.\n * All V1 color tokens replaced with semantic design-system tokens.\n */\nimport { IconArrowDown,IconArrowUp, IconCornerDownLeft, IconSearch } from '@tabler/icons-react'\nimport { AnimatePresence,motion } from 'framer-motion'\nimport * as React from 'react'\n\nimport { useMotion } from '../motion/motion-provider'\nimport {\n Dialog,\n DialogContentRaw,\n DialogDescription,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n} from '../ui/dialog'\nimport { Icon } from '../ui/icon'\nimport { IconProvider } from '../ui/icon-context'\nimport type { IconInput } from '../ui/lib/icon-input'\nimport { springs,tweens } from '../ui/lib/motion'\nimport { normalizeIcon } from '../ui/lib/normalize-icon'\nimport { cn } from '../ui/lib/utils'\nimport { VisuallyHidden } from '../ui/visually-hidden'\n\n// -----------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------\n\nexport interface CommandItem {\n id: string\n /** Display label — string or ReactNode. When ReactNode, provide `filterValue` for search filtering. */\n label: string | React.ReactNode\n /** Optional description — string or ReactNode. */\n description?: string | React.ReactNode\n icon?: IconInput\n /** Keyboard shortcut hint displayed as keycap badges (e.g., \"G D\", \"Ctrl+N\"). */\n shortcut?: string\n /** Custom render override for the label. Receives the current search query for match highlighting. */\n renderLabel?: (query: string) => React.ReactNode\n /** Plain-text value used for search filtering when `label` is a ReactNode. Falls back to `label` if string. */\n filterValue?: string\n onSelect: () => void\n}\n\nexport interface CommandGroup {\n label: string\n items: CommandItem[]\n}\n\n/** A single keyboard hint shown in the footer. */\nexport interface FooterHint {\n /** Key(s) to display — rendered as text inside `<kbd>` or as an icon. */\n keys: string\n /** Human-readable label for the hint (e.g., \"Navigate\", \"Select\"). */\n label: string\n}\n\n/**\n * A searchable command palette with keyboard navigation (Ctrl+K / Cmd+K).\n * Supports grouped items, custom keybindings, controlled/uncontrolled open state,\n * and custom empty states.\n */\nexport interface CommandPaletteProps extends React.ComponentPropsWithoutRef<'div'> {\n /** Item groups displayed in the palette. Each group has a label and an array of CommandItems. */\n groups?: CommandGroup[]\n /** Placeholder text for the search input. */\n placeholder?: string\n /** Called on every search input change with the current query string. */\n onSearch?: (query: string) => void\n /** Simple text shown when no results match. Overridden by `emptyState` if provided. */\n emptyMessage?: string\n /** Full custom empty state ReactNode — overrides `emptyMessage` when provided. */\n emptyState?: React.ReactNode\n // -- Controlled/uncontrolled open state (P1 #4) --\n /** Controlled open state. */\n open?: boolean\n /** Default open state for uncontrolled usage. */\n defaultOpen?: boolean\n /** Called when the open state changes. */\n onOpenChange?: (open: boolean) => void\n // -- Keyboard shortcut customization (P1 #6) --\n /** Keybinding(s) to toggle the palette. Pass `false` to disable.\n * String format: modifier+key, e.g., 'mod+k', 'ctrl+shift+p'.\n * 'mod' maps to Meta on macOS, Ctrl otherwise. */\n keybinding?: string | string[] | false\n // -- Configurable max-height (P2 #8) --\n /** Max height of the results container. CSS value. Default '320px'. */\n maxHeight?: string | number\n // -- Custom footer hints (P2 #11) --\n /** Custom footer keyboard hints. Pass `false` to hide the footer entirely. */\n footerHints?: FooterHint[] | false\n}\n\n// -----------------------------------------------------------------------\n// Helpers\n// -----------------------------------------------------------------------\n\nimport { getIsMac, getModifierDisplay,matchesKeybinding } from '../ui/lib/keybinding'\n\n/** Get the text-searchable value from a CommandItem. */\nfunction getFilterValue(item: CommandItem): string {\n if (item.filterValue) return item.filterValue\n if (typeof item.label === 'string') return item.label\n return ''\n}\n\n/** Get the text-searchable description from a CommandItem. */\nfunction getFilterDescription(item: CommandItem): string {\n if (typeof item.description === 'string') return item.description\n return ''\n}\n\n/** Parse a shortcut string like \"G D\" or \"Ctrl+N\" into individual keycap segments. */\nfunction parseShortcutKeys(shortcut: string): string[] {\n // If it has \"+\" separator (Ctrl+Shift+N style), split on +\n if (shortcut.includes('+')) {\n return shortcut.split('+').map(s => s.trim()).filter(Boolean)\n }\n // Otherwise split on spaces (G D style)\n return shortcut.split(/\\s+/).filter(Boolean)\n}\n\n// -----------------------------------------------------------------------\n// CommandPalette\n// -----------------------------------------------------------------------\n\nconst CommandPalette = React.forwardRef<HTMLDivElement, CommandPaletteProps>(\n function CommandPalette(\n {\n groups = [],\n placeholder = 'Search or jump to...',\n onSearch,\n emptyMessage = 'No results found.',\n emptyState,\n open: openProp,\n defaultOpen,\n onOpenChange,\n keybinding = 'mod+k',\n maxHeight = '320px',\n footerHints,\n className,\n ...props\n },\n ref,\n ) {\n // -- Controlled/uncontrolled open state --\n const isControlled = openProp !== undefined\n const [internalOpen, setInternalOpen] = React.useState(defaultOpen ?? false)\n const open = isControlled ? openProp : internalOpen\n\n // Use a ref for the current open value to avoid stale closures in setOpen\n const openRef = React.useRef(open)\n openRef.current = open\n\n const setOpen = React.useCallback(\n (nextOpen: boolean | ((prev: boolean) => boolean)) => {\n const resolved = typeof nextOpen === 'function' ? nextOpen(openRef.current) : nextOpen\n if (!isControlled) {\n setInternalOpen(resolved)\n }\n onOpenChange?.(resolved)\n },\n [isControlled, onOpenChange],\n )\n\n const [query, setQuery] = React.useState('')\n const [activeIndex, setActiveIndex] = React.useState(0)\n const inputRef = React.useRef<HTMLInputElement>(null)\n const listRef = React.useRef<HTMLDivElement>(null)\n const instanceId = React.useId()\n const listboxId = `command-palette-listbox-${instanceId}`\n\n // -- Reduced motion (P2 #12) --\n const { reducedMotion: isReduced } = useMotion()\n const noMotionTransition = { duration: 0 }\n\n // -- Platform detection (P2 #13) --\n const isMac = React.useMemo(() => getIsMac(), [])\n\n // Filter groups based on query\n const filteredGroups = React.useMemo(() => {\n if (!query.trim()) return groups\n const q = query.toLowerCase()\n return groups\n .map((group) => ({\n ...group,\n items: group.items.filter(\n (item) =>\n getFilterValue(item).toLowerCase().includes(q) ||\n getFilterDescription(item).toLowerCase().includes(q),\n ),\n }))\n .filter((group) => group.items.length > 0)\n }, [groups, query])\n\n const filteredItems = React.useMemo(\n () => filteredGroups.flatMap((g) => g.items),\n [filteredGroups],\n )\n\n // Global keyboard shortcut\n React.useEffect(() => {\n if (keybinding === false) return\n\n const bindings = Array.isArray(keybinding) ? keybinding : [keybinding]\n\n function handleKeyDown(e: KeyboardEvent) {\n for (const binding of bindings) {\n if (matchesKeybinding(e, binding)) {\n e.preventDefault()\n setOpen((prev) => !prev)\n return\n }\n }\n }\n document.addEventListener('keydown', handleKeyDown)\n return () => document.removeEventListener('keydown', handleKeyDown)\n }, [keybinding, setOpen])\n\n // Reset state when opening\n React.useEffect(() => {\n if (open) {\n setQuery('')\n setActiveIndex(0)\n requestAnimationFrame(() => {\n inputRef.current?.focus()\n })\n }\n }, [open])\n\n // Keyboard navigation inside the palette\n const handleKeyDown = (e: React.KeyboardEvent) => {\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault()\n setActiveIndex((prev) =>\n prev < filteredItems.length - 1 ? prev + 1 : 0,\n )\n break\n }\n case 'ArrowUp': {\n e.preventDefault()\n setActiveIndex((prev) =>\n prev > 0 ? prev - 1 : filteredItems.length - 1,\n )\n break\n }\n case 'Enter': {\n e.preventDefault()\n const item = filteredItems[activeIndex]\n if (item) {\n item.onSelect()\n setOpen(false)\n }\n break\n }\n case 'Escape': {\n e.preventDefault()\n setOpen(false)\n break\n }\n }\n }\n\n // Scroll active item into view\n React.useEffect(() => {\n const activeEl = listRef.current?.querySelector(\n `[data-command-index=\"${activeIndex}\"]`,\n )\n activeEl?.scrollIntoView({ block: 'nearest' })\n }, [activeIndex])\n\n const handleQueryChange = (value: string) => {\n setQuery(value)\n setActiveIndex(0)\n onSearch?.(value)\n }\n\n // Build a map of item id -> flat index for keyboard navigation\n const itemIndexMap = React.useMemo(() => {\n const map = new Map<string, number>()\n let idx = 0\n for (const group of filteredGroups) {\n for (const item of group.items) {\n map.set(item.id, idx++)\n }\n }\n return map\n }, [filteredGroups])\n\n // -- Resolve motion transitions --\n const springSnappy = isReduced ? noMotionTransition : springs.snappy\n const tweenFade = isReduced ? noMotionTransition : tweens.fade\n const noInit = isReduced ? { opacity: 1, scale: 1, y: 0 } : undefined\n\n // -- Resolve max height CSS value --\n const maxHeightValue = typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight\n\n // -- Resolve footer hints --\n const resolvedFooterHints: FooterHint[] | false =\n footerHints === false\n ? false\n : footerHints ?? [\n { keys: '↑↓', label: 'Navigate' },\n { keys: '↵', label: 'Select' },\n { keys: 'Esc', label: 'Close' },\n ]\n\n // Handle dialog open change (from Dialog's own close mechanisms)\n const handleDialogOpenChange = React.useCallback(\n (nextOpen: boolean) => {\n setOpen(nextOpen)\n },\n [setOpen],\n )\n\n return (\n <Dialog open={open} onOpenChange={handleDialogOpenChange}>\n <DialogPortal>\n <DialogOverlay\n className=\"fixed inset-0 z-overlay bg-overlay data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\"\n />\n <DialogContentRaw\n ref={ref}\n {...props}\n className={cn(\n 'fixed left-1/2 top-[20%] z-modal w-full max-w-[560px] -translate-x-1/2',\n 'overflow-hidden rounded-overlay-lg bg-surface-overlay shadow-overlay',\n 'duration-moderate-02 data-[state=open]:animate-in data-[state=closed]:animate-out',\n 'data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n 'data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95',\n 'data-[state=closed]:slide-out-to-left-1/2 data-[state=open]:slide-in-from-left-1/2',\n 'data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2',\n className,\n )}\n onKeyDown={handleKeyDown}\n >\n <VisuallyHidden>\n <DialogTitle>Command Palette</DialogTitle>\n <DialogDescription>\n Search or jump to pages, projects, tasks, and actions\n </DialogDescription>\n </VisuallyHidden>\n\n {/* Search input */}\n <div className=\"flex items-center gap-ds-04 border-b border-surface-border-strong px-ds-05 py-ds-04\">\n <motion.span\n initial={noInit ?? { opacity: 0, scale: 0.96 }}\n animate={{ opacity: 1, scale: 1 }}\n transition={springSnappy}\n className=\"inline-flex shrink-0\"\n >\n <Icon icon={IconSearch} size=\"sm\" stroke=\"light\" className=\"text-surface-fg-subtle\" />\n </motion.span>\n <input\n ref={inputRef}\n value={query}\n onChange={(e) => handleQueryChange(e.target.value)}\n placeholder={placeholder}\n role=\"combobox\"\n aria-expanded={true}\n aria-controls={listboxId}\n aria-activedescendant={filteredItems[activeIndex] ? `command-item-${instanceId}-${filteredItems[activeIndex].id}` : undefined}\n aria-autocomplete=\"list\"\n className={cn(\n 'flex-1 bg-transparent text-body-lg text-surface-fg outline-hidden',\n 'placeholder:text-surface-fg-subtle',\n )}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n />\n <kbd className=\"hidden shrink-0 select-none rounded-control border border-card-strong bg-surface-panel px-ds-02b py-ds-01 text-body-sm font-medium text-surface-fg-subtle shadow-kbd sm:inline-flex\">\n Esc\n </kbd>\n </div>\n\n {/* Results */}\n <div\n ref={listRef}\n id={listboxId}\n role=\"listbox\"\n aria-label=\"Command results\"\n className=\"overflow-y-auto px-ds-03 py-ds-03\"\n style={{ maxHeight: maxHeightValue }}\n >\n {filteredGroups.length === 0 && (\n <motion.div\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={tweenFade}\n className=\"flex items-center justify-center py-ds-07\"\n >\n {emptyState ?? (\n <p className=\"text-body-md text-surface-fg-subtle\">\n {emptyMessage}\n </p>\n )}\n </motion.div>\n )}\n\n {filteredGroups.map((group, groupIdx) => (\n <motion.div\n key={group.label}\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={isReduced ? noMotionTransition : { ...tweens.fade, delay: groupIdx * 0.06 }}\n className=\"mb-ds-02\"\n >\n <div className=\"px-ds-03 pb-ds-02 pt-ds-03\">\n <span className=\"text-label-xs font-semibold uppercase tracking-wider text-surface-fg-subtle\">\n {group.label}\n </span>\n </div>\n\n {group.items.map((item) => {\n const itemIndex = itemIndexMap.get(item.id) ?? 0\n const isActive = itemIndex === activeIndex\n return (\n <motion.button\n key={item.id}\n id={`command-item-${instanceId}-${item.id}`}\n type=\"button\"\n role=\"option\"\n aria-selected={isActive}\n data-command-index={itemIndex}\n initial={noInit ?? { opacity: 0, y: 4 }}\n animate={{ opacity: 1, y: 0 }}\n transition={isReduced ? noMotionTransition : { ...springs.snappy, delay: itemIndex * 0.03 }}\n onClick={() => {\n item.onSelect()\n setOpen(false)\n }}\n onMouseEnter={() => setActiveIndex(itemIndex)}\n className={cn(\n 'flex w-full items-center gap-ds-04 rounded-surface px-ds-03 py-ds-03 text-left transition-[color,background-color] duration-fast-02 ease-productive-standard',\n isActive\n ? 'bg-surface-panel-hover text-surface-fg'\n : 'text-surface-fg-muted hover:bg-surface-panel-hover',\n )}\n >\n {item.icon && (\n <span\n className={cn(\n '[&>svg]:h-ico-sm [&>svg]:w-ico-sm shrink-0 transition-colors duration-fast-02 ease-productive-standard',\n isActive ? 'text-accent-11' : 'text-surface-fg-subtle',\n )}\n aria-hidden=\"true\"\n >\n <IconProvider size=\"sm\">{normalizeIcon(item.icon)}</IconProvider>\n </span>\n )}\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <span className=\"truncate text-body-md\">\n {item.renderLabel ? item.renderLabel(query) : item.label}\n </span>\n {item.description && (\n <span className=\"line-clamp-1 text-body-sm text-surface-fg-subtle\">\n {item.description}\n </span>\n )}\n </div>\n {item.shortcut && (\n <span className=\"flex shrink-0 items-center gap-ds-01\">\n {parseShortcutKeys(item.shortcut).map((key, i) => (\n <kbd\n key={i}\n className={cn(\n 'inline-flex min-w-ds-05b items-center justify-center rounded border px-ds-02b py-ds-01 text-body-xs font-medium shadow-kbd transition-colors duration-fast-02 ease-productive-standard',\n isActive\n ? 'bg-accent-2 text-accent-11 border-accent-6'\n : 'bg-surface-panel text-surface-fg-subtle border-surface-border-strong',\n )}\n >\n {key === 'Ctrl' || key === 'ctrl' ? getModifierDisplay(isMac) : key}\n </kbd>\n ))}\n </span>\n )}\n <AnimatePresence>\n {isActive && (\n <motion.span\n initial={isReduced ? undefined : { opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={isReduced ? undefined : { opacity: 0 }}\n transition={tweenFade}\n className=\"inline-flex shrink-0\"\n >\n <Icon icon={IconCornerDownLeft} size=\"sm\" stroke=\"light\" className=\"text-surface-fg-subtle\" />\n </motion.span>\n )}\n </AnimatePresence>\n </motion.button>\n )\n })}\n </motion.div>\n ))}\n </div>\n\n {/* Footer with keyboard hints */}\n {resolvedFooterHints !== false && (\n <motion.div\n initial={noInit ?? { opacity: 0 }}\n animate={{ opacity: 1 }}\n transition={tweenFade}\n className=\"flex items-center gap-ds-05 border-t border-surface-border-strong px-ds-05 py-ds-03\"\n >\n {resolvedFooterHints.map((hint, i) => (\n <div key={i} className=\"flex items-center gap-ds-02b\">\n {hint.keys === '↑↓' ? (\n <div className=\"flex items-center gap-ds-01\">\n <kbd className=\"inline-flex h-ico-md w-ico-md items-center justify-center rounded border border-card-strong bg-surface-panel shadow-kbd\">\n <Icon icon={IconArrowUp} size=\"xs\" className=\"text-surface-fg-subtle\" />\n </kbd>\n <kbd className=\"inline-flex h-ico-md w-ico-md items-center justify-center rounded border border-card-strong bg-surface-panel shadow-kbd\">\n <Icon icon={IconArrowDown} size=\"xs\" className=\"text-surface-fg-subtle\" />\n </kbd>\n </div>\n ) : hint.keys === '↵' ? (\n <kbd className=\"inline-flex h-ds-05b items-center justify-center rounded-control border border-card-strong bg-surface-panel px-ds-02b shadow-kbd\">\n <Icon icon={IconCornerDownLeft} size=\"xs\" className=\"text-surface-fg-subtle\" />\n </kbd>\n ) : (\n <kbd className=\"inline-flex h-ds-05b items-center justify-center rounded-control border border-card-strong bg-surface-panel px-ds-02b text-caption font-medium text-surface-fg-subtle shadow-kbd\">\n {hint.keys}\n </kbd>\n )}\n <span className=\"text-caption text-surface-fg-subtle\">\n {hint.label}\n </span>\n </div>\n ))}\n </motion.div>\n )}\n </DialogContentRaw>\n </DialogPortal>\n </Dialog>\n )\n },\n)\n\nCommandPalette.displayName = 'CommandPalette'\n\nexport { CommandPalette }\n"],"mappings":";;;;;;;;;;;;;;;AAyGA,SAAS,GAAe,GAA2B;CAGjD,OAFI,EAAK,cAAoB,EAAK,cAC9B,OAAO,EAAK,SAAU,WAAiB,EAAK,QACzC;AACT;AAGA,SAAS,GAAqB,GAA2B;CAEvD,OADI,OAAO,EAAK,eAAgB,WAAiB,EAAK,cAC/C;AACT;AAGA,SAAS,EAAkB,GAA4B;CAMrD,OAJI,EAAS,SAAS,GAAG,IAChB,EAAS,MAAM,GAAG,CAAC,CAAC,KAAI,MAAK,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,OAAO,IAGvD,EAAS,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO;AAC7C;AAMA,IAAM,IAAiB,EAAM,WAC3B,SACE,EACE,YAAS,CAAC,GACV,iBAAc,wBACd,cACA,kBAAe,qBACf,eACA,MAAM,GACN,gBACA,iBACA,gBAAa,SACb,eAAY,SACZ,gBACA,cACA,GAAG,KAEL,GACA;CAEF,IAAM,IAAe,MAAa,KAAA,GAC5B,CAAC,GAAc,KAAmB,EAAM,SAAS,KAAe,EAAK,GACrE,IAAO,IAAe,IAAW,GAGjC,IAAU,EAAM,OAAO,CAAI;CACjC,EAAQ,UAAU;CAElB,IAAM,IAAU,EAAM,aACnB,MAAqD;EACpD,IAAM,IAAW,OAAO,KAAa,aAAa,EAAS,EAAQ,OAAO,IAAI;EAI9E,AAHK,KACH,EAAgB,CAAQ,GAE1B,IAAe,CAAQ;CACzB,GACA,CAAC,GAAc,CAAY,CAC7B,GAEM,CAAC,GAAO,KAAY,EAAM,SAAS,EAAE,GACrC,CAAC,GAAa,KAAkB,EAAM,SAAS,CAAC,GAChD,IAAW,EAAM,OAAyB,IAAI,GAC9C,IAAU,EAAM,OAAuB,IAAI,GAC3C,IAAa,EAAM,MAAM,GACzB,IAAY,2BAA2B,KAGvC,EAAE,eAAe,MAAc,EAAU,GACzC,IAAqB,EAAE,UAAU,EAAE,GAGnC,KAAQ,EAAM,cAAc,EAAS,GAAG,CAAC,CAAC,GAG1C,IAAiB,EAAM,cAAc;EACzC,IAAI,CAAC,EAAM,KAAK,GAAG,OAAO;EAC1B,IAAM,IAAI,EAAM,YAAY;EAC5B,OAAO,EACJ,KAAK,OAAW;GACf,GAAG;GACH,OAAO,EAAM,MAAM,QAChB,MACC,GAAe,CAAI,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,KAC7C,GAAqB,CAAI,CAAC,CAAC,YAAY,CAAC,CAAC,SAAS,CAAC,CACvD;EACF,EAAE,CAAC,CACF,QAAQ,MAAU,EAAM,MAAM,SAAS,CAAC;CAC7C,GAAG,CAAC,GAAQ,CAAK,CAAC,GAEZ,IAAgB,EAAM,cACpB,EAAe,SAAS,MAAM,EAAE,KAAK,GAC3C,CAAC,CAAc,CACjB;CAsBA,AAnBA,EAAM,gBAAgB;EACpB,IAAI,MAAe,IAAO;EAE1B,IAAM,IAAW,MAAM,QAAQ,CAAU,IAAI,IAAa,CAAC,CAAU;EAErE,SAAS,EAAc,GAAkB;GACvC,KAAK,IAAM,KAAW,GACpB,IAAI,EAAkB,GAAG,CAAO,GAAG;IAEjC,AADA,EAAE,eAAe,GACjB,GAAS,MAAS,CAAC,CAAI;IACvB;GACF;EAEJ;EAEA,OADA,SAAS,iBAAiB,WAAW,CAAa,SACrC,SAAS,oBAAoB,WAAW,CAAa;CACpE,GAAG,CAAC,GAAY,CAAO,CAAC,GAGxB,EAAM,gBAAgB;EACpB,AAAI,MACF,EAAS,EAAE,GACX,EAAe,CAAC,GAChB,4BAA4B;GAC1B,EAAS,SAAS,MAAM;EAC1B,CAAC;CAEL,GAAG,CAAC,CAAI,CAAC;CAGT,IAAM,MAAiB,MAA2B;EAChD,QAAQ,EAAE,KAAV;GACE,KAAK;IAEH,AADA,EAAE,eAAe,GACjB,GAAgB,MACd,IAAO,EAAc,SAAS,IAAI,IAAO,IAAI,CAC/C;IACA;GAEF,KAAK;IAEH,AADA,EAAE,eAAe,GACjB,GAAgB,MACd,IAAO,IAAI,IAAO,IAAI,EAAc,SAAS,CAC/C;IACA;GAEF,KAAK,SAAS;IACZ,EAAE,eAAe;IACjB,IAAM,IAAO,EAAc;IAC3B,AAAI,MACF,EAAK,SAAS,GACd,EAAQ,EAAK;IAEf;GACF;GACA,KAAK;IAEH,AADA,EAAE,eAAe,GACjB,EAAQ,EAAK;IACb;EAEJ;CACF;CAGA,EAAM,gBAAgB;EAIpB,CAHiB,EAAQ,SAAS,cAChC,wBAAwB,EAAY,GACtC,EAAA,EACU,eAAe,EAAE,OAAO,UAAU,CAAC;CAC/C,GAAG,CAAC,CAAW,CAAC;CAEhB,IAAM,MAAqB,MAAkB;EAG3C,AAFA,EAAS,CAAK,GACd,EAAe,CAAC,GAChB,KAAW,CAAK;CAClB,GAGM,KAAe,EAAM,cAAc;EACvC,IAAM,oBAAM,IAAI,IAAoB,GAChC,IAAM;EACV,KAAK,IAAM,KAAS,GAClB,KAAK,IAAM,KAAQ,EAAM,OACvB,EAAI,IAAI,EAAK,IAAI,GAAK;EAG1B,OAAO;CACT,GAAG,CAAC,CAAc,CAAC,GAGb,KAAe,IAAY,IAAqB,EAAQ,QACxD,IAAY,IAAY,IAAqB,EAAO,MACpD,IAAS,IAAY;EAAE,SAAS;EAAG,OAAO;EAAG,GAAG;CAAE,IAAI,KAAA,GAGtD,KAAiB,OAAO,KAAc,WAAW,GAAG,EAAU,MAAM,GAGpE,IACJ,MAAgB,KACZ,KACA,KAAe;EACb;GAAE,MAAM;GAAM,OAAO;EAAW;EAChC;GAAE,MAAM;GAAK,OAAO;EAAS;EAC7B;GAAE,MAAM;GAAO,OAAO;EAAQ;CAChC;CAUN,OACE,kBAAC,GAAD;EAAc;EAAM,cARS,EAAM,aAClC,MAAsB;GACrB,EAAQ,CAAQ;EAClB,GACA,CAAC,CAAO,CAI0B;YAChC,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,IAAD,EACE,WAAU,6JACX,CAAA,GACD,kBAAC,GAAD;GACO;GACL,GAAI;GACJ,WAAW,EACT,0EACA,wEACA,qFACA,8DACA,gEACA,sFACA,gFACA,CACF;GACA,WAAW;aAbb;IAeE,kBAAC,IAAD,EAAA,UAAA,CACE,kBAAC,IAAD,EAAA,UAAa,kBAA4B,CAAA,GACzC,kBAAC,GAAD,EAAA,UAAmB,wDAEA,CAAA,CACL,EAAA,CAAA;IAGhB,kBAAC,OAAD;KAAK,WAAU;eAAf;MACE,kBAAC,EAAO,MAAR;OACE,SAAS,KAAU;QAAE,SAAS;QAAG,OAAO;OAAK;OAC7C,SAAS;QAAE,SAAS;QAAG,OAAO;OAAE;OAChC,YAAY;OACZ,WAAU;iBAEV,kBAAC,GAAD;QAAM,MAAM;QAAY,MAAK;QAAK,QAAO;QAAQ,WAAU;OAA0B,CAAA;MAC1E,CAAA;MACb,kBAAC,SAAD;OACE,KAAK;OACL,OAAO;OACP,WAAW,MAAM,GAAkB,EAAE,OAAO,KAAK;OACpC;OACb,MAAK;OACL,iBAAe;OACf,iBAAe;OACf,yBAAuB,EAAc,KAAe,gBAAgB,EAAW,GAAG,EAAc,EAAY,CAAC,OAAO,KAAA;OACpH,qBAAkB;OAClB,WAAW,EACT,qEACA,oCACF;OACA,cAAa;OACb,aAAY;OACZ,YAAY;MACb,CAAA;MACD,kBAAC,OAAD;OAAK,WAAU;iBAAsL;MAEhM,CAAA;KACF;;IAGL,kBAAC,OAAD;KACE,KAAK;KACL,IAAI;KACJ,MAAK;KACL,cAAW;KACX,WAAU;KACV,OAAO,EAAE,WAAW,GAAe;eANrC,CAQG,EAAe,WAAW,KACzB,kBAAC,EAAO,KAAR;MACE,SAAS,KAAU,EAAE,SAAS,EAAE;MAChC,SAAS,EAAE,SAAS,EAAE;MACtB,YAAY;MACZ,WAAU;gBAET,KACC,kBAAC,KAAD;OAAG,WAAU;iBACV;MACA,CAAA;KAEK,CAAA,GAGb,EAAe,KAAK,GAAO,MAC1B,kBAAC,EAAO,KAAR;MAEE,SAAS,KAAU,EAAE,SAAS,EAAE;MAChC,SAAS,EAAE,SAAS,EAAE;MACtB,YAAY,IAAY,IAAqB;OAAE,GAAG,EAAO;OAAM,OAAO,IAAW;MAAK;MACtF,WAAU;gBALZ,CAOE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,QAAD;QAAM,WAAU;kBACb,EAAM;OACH,CAAA;MACH,CAAA,GAEJ,EAAM,MAAM,KAAK,MAAS;OACzB,IAAM,IAAY,GAAa,IAAI,EAAK,EAAE,KAAK,GACzC,IAAW,MAAc;OAC/B,OACE,kBAAC,EAAO,QAAR;QAEE,IAAI,gBAAgB,EAAW,GAAG,EAAK;QACvC,MAAK;QACL,MAAK;QACL,iBAAe;QACf,sBAAoB;QACpB,SAAS,KAAU;SAAE,SAAS;SAAG,GAAG;QAAE;QACtC,SAAS;SAAE,SAAS;SAAG,GAAG;QAAE;QAC5B,YAAY,IAAY,IAAqB;SAAE,GAAG,EAAQ;SAAQ,OAAO,IAAY;QAAK;QAC1F,eAAe;SAEb,AADA,EAAK,SAAS,GACd,EAAQ,EAAK;QACf;QACA,oBAAoB,EAAe,CAAS;QAC5C,WAAW,EACT,gKACA,IACI,2CACA,oDACN;kBApBF;SAsBG,EAAK,QACJ,kBAAC,QAAD;UACE,WAAW,EACT,0GACA,IAAW,mBAAmB,wBAChC;UACA,eAAY;oBAEZ,kBAAC,GAAD;WAAc,MAAK;qBAAM,EAAc,EAAK,IAAI;UAAgB,CAAA;SAC5D,CAAA;SAER,kBAAC,OAAD;UAAK,WAAU;oBAAf,CACE,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAK,cAAc,EAAK,YAAY,CAAK,IAAI,EAAK;UAC/C,CAAA,GACL,EAAK,eACJ,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAK;UACF,CAAA,CAEL;;SACJ,EAAK,YACJ,kBAAC,QAAD;UAAM,WAAU;oBACb,EAAkB,EAAK,QAAQ,CAAC,CAAC,KAAK,GAAK,MAC1C,kBAAC,OAAD;WAEE,WAAW,EACT,0LACA,IACI,+CACA,sEACN;qBAEC,MAAQ,UAAU,MAAQ,SAAS,EAAmB,EAAK,IAAI;UAC7D,GATE,CASF,CACN;SACG,CAAA;SAER,kBAAC,IAAD,EAAA,UACG,KACC,kBAAC,EAAO,MAAR;UACE,SAAS,IAAY,KAAA,IAAY,EAAE,SAAS,EAAE;UAC9C,SAAS,EAAE,SAAS,EAAE;UACtB,MAAM,IAAY,KAAA,IAAY,EAAE,SAAS,EAAE;UAC3C,YAAY;UACZ,WAAU;oBAEV,kBAAC,GAAD;WAAM,MAAM;WAAoB,MAAK;WAAK,QAAO;WAAQ,WAAU;UAA0B,CAAA;SAClF,CAAA,EAEA,CAAA;QACJ;UAxER,EAAK,EAwEG;MAEnB,CAAC,CACS;QA5FL,EAAM,KA4FD,CACb,CACE;;IAGJ,MAAwB,MACvB,kBAAC,EAAO,KAAR;KACE,SAAS,KAAU,EAAE,SAAS,EAAE;KAChC,SAAS,EAAE,SAAS,EAAE;KACtB,YAAY;KACZ,WAAU;eAET,EAAoB,KAAK,GAAM,MAC9B,kBAAC,OAAD;MAAa,WAAU;gBAAvB,CACG,EAAK,SAAS,OACb,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,GAAD;SAAM,MAAM;SAAa,MAAK;SAAK,WAAU;QAA0B,CAAA;OACpE,CAAA,GACL,kBAAC,OAAD;QAAK,WAAU;kBACb,kBAAC,GAAD;SAAM,MAAM;SAAe,MAAK;SAAK,WAAU;QAA0B,CAAA;OACtE,CAAA,CACF;WACH,EAAK,SAAS,MAChB,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD;QAAM,MAAM;QAAoB,MAAK;QAAK,WAAU;OAA0B,CAAA;MAC3E,CAAA,IAEL,kBAAC,OAAD;OAAK,WAAU;iBACZ,EAAK;MACH,CAAA,GAEP,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAK;MACF,CAAA,CACH;QAtBK,CAsBL,CACN;IACS,CAAA;GAEE;IACN,EAAA,CAAA;CACR,CAAA;AAEV,CACF;AAEA,EAAe,cAAc"}
@@ -1,14 +1,14 @@
1
- import { cva as e } from "../_chunks/vendor-utils.js";
2
- import { cn as t } from "../ui/lib/utils.js";
3
- import * as n from "react";
4
- import { Fragment as r, jsx as i, jsxs as a } from "react/jsx-runtime";
1
+ import { cn as e } from "../ui/lib/utils.js";
2
+ import * as t from "react";
3
+ import { Fragment as n, jsx as r, jsxs as i } from "react/jsx-runtime";
4
+ import { cva as a } from "class-variance-authority";
5
5
  //#region src/composed/content-card.tsx
6
- var o = e("rounded-surface will-change-[box-shadow] transition-[color,background-color,border-color,box-shadow] duration-fast-02 ease-productive-standard", {
6
+ var o = a("rounded-surface will-change-[box-shadow] transition-[color,background-color,border-color,box-shadow] duration-fast-02 ease-productive-standard", {
7
7
  variants: {
8
8
  variant: {
9
- default: "bg-surface-raised shadow-raised hover:shadow-raised-hover",
9
+ default: "bg-surface-panel hover:bg-surface-panel-hover",
10
10
  outline: "border border-surface-border bg-transparent hover:border-surface-border-strong",
11
- ghost: "border border-transparent bg-transparent hover:bg-surface-raised"
11
+ ghost: "border border-transparent bg-transparent hover:bg-surface-panel-hover"
12
12
  },
13
13
  padding: {
14
14
  default: "p-ds-05b",
@@ -33,32 +33,32 @@ var o = e("rounded-surface will-change-[box-shadow] transition-[color,background
33
33
  case "spacious": return "p-ds-06";
34
34
  default: return "p-ds-05b";
35
35
  }
36
- }, l = n.forwardRef(({ variant: e, padding: n, header: l, headerTitle: u, headerActions: d, footer: f, className: p, children: m, ...h }, g) => {
36
+ }, l = t.forwardRef(({ variant: t, padding: a, header: l, headerTitle: u, headerActions: d, footer: f, className: p, children: m, ...h }, g) => {
37
37
  let _ = l || u || d;
38
- return /* @__PURE__ */ a("div", {
38
+ return /* @__PURE__ */ i("div", {
39
39
  ref: g,
40
- className: t(o({
41
- variant: e,
42
- padding: _ || f ? "none" : n
40
+ className: e(o({
41
+ variant: t,
42
+ padding: _ || f ? "none" : a
43
43
  }), p),
44
44
  ...h,
45
45
  children: [
46
- _ && /* @__PURE__ */ i("div", {
47
- className: t("flex items-center justify-between border-b border-surface-border-strong", s(n)),
48
- children: l ?? /* @__PURE__ */ a(r, { children: [u && /* @__PURE__ */ i("h3", {
46
+ _ && /* @__PURE__ */ r("div", {
47
+ className: e("flex items-center justify-between border-b border-surface-border-strong", s(a)),
48
+ children: l ?? /* @__PURE__ */ i(n, { children: [u && /* @__PURE__ */ r("h3", {
49
49
  className: "text-body-lg font-semibold text-surface-fg",
50
50
  children: u
51
- }), d && /* @__PURE__ */ i("div", {
51
+ }), d && /* @__PURE__ */ r("div", {
52
52
  className: "flex items-center gap-ds-03",
53
53
  children: d
54
54
  })] })
55
55
  }),
56
- /* @__PURE__ */ i("div", {
57
- className: t((_ || f) && c(n)),
56
+ /* @__PURE__ */ r("div", {
57
+ className: e((_ || f) && c(a)),
58
58
  children: m
59
59
  }),
60
- f && /* @__PURE__ */ i("div", {
61
- className: t("border-t border-surface-border-strong", s(n)),
60
+ f && /* @__PURE__ */ r("div", {
61
+ className: e("border-t border-surface-border-strong", s(a)),
62
62
  children: f
63
63
  })
64
64
  ]
@@ -1 +1 @@
1
- {"version":3,"file":"content-card.js","names":[],"sources":["../../src/composed/content-card.tsx"],"sourcesContent":["// @server-safe\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\n\nimport { cn } from '../ui/lib/utils'\n\nconst contentCardVariants = cva(\n 'rounded-surface will-change-[box-shadow] transition-[color,background-color,border-color,box-shadow] duration-fast-02 ease-productive-standard',\n {\n variants: {\n variant: {\n default:\n 'bg-surface-raised shadow-raised hover:shadow-raised-hover',\n outline:\n 'border border-surface-border bg-transparent hover:border-surface-border-strong',\n ghost:\n 'border border-transparent bg-transparent hover:bg-surface-raised',\n },\n padding: {\n default: 'p-ds-05b',\n compact: 'p-ds-04',\n spacious: 'p-ds-06',\n none: 'p-0',\n },\n },\n defaultVariants: {\n variant: 'default',\n padding: 'default',\n },\n },\n)\n\nconst getPadding = (padding: string | null | undefined) => {\n switch (padding) {\n case 'compact': return 'px-ds-04 py-ds-03'\n case 'spacious': return 'px-ds-06 py-ds-05'\n default: return 'px-ds-05b py-ds-04'\n }\n}\n\nconst getContentPadding = (padding: string | null | undefined) => {\n switch (padding) {\n case 'compact': return 'p-ds-04'\n case 'spacious': return 'p-ds-06'\n default: return 'p-ds-05b'\n }\n}\n\nexport interface ContentCardProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof contentCardVariants> {\n header?: React.ReactNode\n headerTitle?: string\n headerActions?: React.ReactNode\n footer?: React.ReactNode\n}\n\n/**\n * @deprecated Use `Card` with `CardHeader` / `CardContent` / `CardFooter` instead.\n * `ContentCard` duplicated `Card` on the legacy per-slot-padding model; `Card` now covers\n * every feature (variants, slots, gap-model padding). `ContentCard` will be removed in the\n * next major — see MIGRATION.md.\n */\nconst ContentCard = React.forwardRef<HTMLDivElement, ContentCardProps>(\n (\n {\n variant,\n padding,\n header,\n headerTitle,\n headerActions,\n footer,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const hasHeader = header || headerTitle || headerActions\n\n return (\n <div\n ref={ref}\n className={cn(\n contentCardVariants({ variant, padding: hasHeader || footer ? 'none' : padding }),\n className,\n )}\n {...props}\n >\n {hasHeader && (\n <div\n className={cn(\n 'flex items-center justify-between border-b border-surface-border-strong',\n getPadding(padding),\n )}\n >\n {header ?? (\n <>\n {headerTitle && (\n <h3 className=\"text-body-lg font-semibold text-surface-fg\">\n {headerTitle}\n </h3>\n )}\n {headerActions && (\n <div className=\"flex items-center gap-ds-03\">{headerActions}</div>\n )}\n </>\n )}\n </div>\n )}\n\n <div\n className={cn(\n (hasHeader || footer) && getContentPadding(padding),\n )}\n >\n {children}\n </div>\n\n {footer && (\n <div\n className={cn(\n 'border-t border-surface-border-strong',\n getPadding(padding),\n )}\n >\n {footer}\n </div>\n )}\n </div>\n )\n },\n)\nContentCard.displayName = 'ContentCard'\n\nexport { ContentCard, contentCardVariants }\n"],"mappings":";;;;;AAMA,IAAM,IAAsB,EAC1B,kJACA;CACE,UAAU;EACR,SAAS;GACP,SACE;GACF,SACE;GACF,OACE;EACJ;EACA,SAAS;GACP,SAAS;GACT,SAAS;GACT,UAAU;GACV,MAAM;EACR;CACF;CACA,iBAAiB;EACf,SAAS;EACT,SAAS;CACX;AACF,CACF,GAEM,KAAc,MAAuC;CACzD,QAAQ,GAAR;EACE,KAAK,WAAW,OAAO;EACvB,KAAK,YAAY,OAAO;EACxB,SAAS,OAAO;CAClB;AACF,GAEM,KAAqB,MAAuC;CAChE,QAAQ,GAAR;EACE,KAAK,WAAW,OAAO;EACvB,KAAK,YAAY,OAAO;EACxB,SAAS,OAAO;CAClB;AACF,GAiBM,IAAc,EAAM,YAEtB,EACE,YACA,YACA,WACA,gBACA,kBACA,WACA,cACA,aACA,GAAG,KAEL,MACG;CACH,IAAM,IAAY,KAAU,KAAe;CAE3C,OACE,kBAAC,OAAD;EACO;EACL,WAAW,EACT,EAAoB;GAAE;GAAS,SAAS,KAAa,IAAS,SAAS;EAAQ,CAAC,GAChF,CACF;EACA,GAAI;YANN;GAQG,KACC,kBAAC,OAAD;IACE,WAAW,EACT,2EACA,EAAW,CAAO,CACpB;cAEC,KACC,kBAAA,GAAA,EAAA,UAAA,CACG,KACC,kBAAC,MAAD;KAAI,WAAU;eACX;IACC,CAAA,GAEL,KACC,kBAAC,OAAD;KAAK,WAAU;eAA+B;IAAmB,CAAA,CAEnE,EAAA,CAAA;GAED,CAAA;GAGP,kBAAC,OAAD;IACE,WAAW,GACR,KAAa,MAAW,EAAkB,CAAO,CACpD;IAEC;GACE,CAAA;GAEJ,KACC,kBAAC,OAAD;IACE,WAAW,EACT,yCACA,EAAW,CAAO,CACpB;cAEC;GACE,CAAA;EAEJ;;AAET,CACF;AACA,EAAY,cAAc"}
1
+ {"version":3,"file":"content-card.js","names":[],"sources":["../../src/composed/content-card.tsx"],"sourcesContent":["// @server-safe\nimport { cva, type VariantProps } from 'class-variance-authority'\nimport * as React from 'react'\n\nimport { cn } from '../ui/lib/utils'\n\nconst contentCardVariants = cva(\n 'rounded-surface will-change-[box-shadow] transition-[color,background-color,border-color,box-shadow] duration-fast-02 ease-productive-standard',\n {\n variants: {\n variant: {\n default:\n 'bg-surface-panel hover:bg-surface-panel-hover',\n outline:\n 'border border-surface-border bg-transparent hover:border-surface-border-strong',\n ghost:\n 'border border-transparent bg-transparent hover:bg-surface-panel-hover',\n },\n padding: {\n default: 'p-ds-05b',\n compact: 'p-ds-04',\n spacious: 'p-ds-06',\n none: 'p-0',\n },\n },\n defaultVariants: {\n variant: 'default',\n padding: 'default',\n },\n },\n)\n\nconst getPadding = (padding: string | null | undefined) => {\n switch (padding) {\n case 'compact': return 'px-ds-04 py-ds-03'\n case 'spacious': return 'px-ds-06 py-ds-05'\n default: return 'px-ds-05b py-ds-04'\n }\n}\n\nconst getContentPadding = (padding: string | null | undefined) => {\n switch (padding) {\n case 'compact': return 'p-ds-04'\n case 'spacious': return 'p-ds-06'\n default: return 'p-ds-05b'\n }\n}\n\nexport interface ContentCardProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof contentCardVariants> {\n header?: React.ReactNode\n headerTitle?: string\n headerActions?: React.ReactNode\n footer?: React.ReactNode\n}\n\n/**\n * @deprecated Use `Card` with `CardHeader` / `CardContent` / `CardFooter` instead.\n * `ContentCard` duplicated `Card` on the legacy per-slot-padding model; `Card` now covers\n * every feature (variants, slots, gap-model padding). `ContentCard` will be removed in the\n * next major — see MIGRATION.md.\n */\nconst ContentCard = React.forwardRef<HTMLDivElement, ContentCardProps>(\n (\n {\n variant,\n padding,\n header,\n headerTitle,\n headerActions,\n footer,\n className,\n children,\n ...props\n },\n ref,\n ) => {\n const hasHeader = header || headerTitle || headerActions\n\n return (\n <div\n ref={ref}\n className={cn(\n contentCardVariants({ variant, padding: hasHeader || footer ? 'none' : padding }),\n className,\n )}\n {...props}\n >\n {hasHeader && (\n <div\n className={cn(\n 'flex items-center justify-between border-b border-surface-border-strong',\n getPadding(padding),\n )}\n >\n {header ?? (\n <>\n {headerTitle && (\n <h3 className=\"text-body-lg font-semibold text-surface-fg\">\n {headerTitle}\n </h3>\n )}\n {headerActions && (\n <div className=\"flex items-center gap-ds-03\">{headerActions}</div>\n )}\n </>\n )}\n </div>\n )}\n\n <div\n className={cn(\n (hasHeader || footer) && getContentPadding(padding),\n )}\n >\n {children}\n </div>\n\n {footer && (\n <div\n className={cn(\n 'border-t border-surface-border-strong',\n getPadding(padding),\n )}\n >\n {footer}\n </div>\n )}\n </div>\n )\n },\n)\nContentCard.displayName = 'ContentCard'\n\nexport { ContentCard, contentCardVariants }\n"],"mappings":";;;;;AAMA,IAAM,IAAsB,EAC1B,kJACA;CACE,UAAU;EACR,SAAS;GACP,SACE;GACF,SACE;GACF,OACE;EACJ;EACA,SAAS;GACP,SAAS;GACT,SAAS;GACT,UAAU;GACV,MAAM;EACR;CACF;CACA,iBAAiB;EACf,SAAS;EACT,SAAS;CACX;AACF,CACF,GAEM,KAAc,MAAuC;CACzD,QAAQ,GAAR;EACE,KAAK,WAAW,OAAO;EACvB,KAAK,YAAY,OAAO;EACxB,SAAS,OAAO;CAClB;AACF,GAEM,KAAqB,MAAuC;CAChE,QAAQ,GAAR;EACE,KAAK,WAAW,OAAO;EACvB,KAAK,YAAY,OAAO;EACxB,SAAS,OAAO;CAClB;AACF,GAiBM,IAAc,EAAM,YAEtB,EACE,YACA,YACA,WACA,gBACA,kBACA,WACA,cACA,aACA,GAAG,KAEL,MACG;CACH,IAAM,IAAY,KAAU,KAAe;CAE3C,OACE,kBAAC,OAAD;EACO;EACL,WAAW,EACT,EAAoB;GAAE;GAAS,SAAS,KAAa,IAAS,SAAS;EAAQ,CAAC,GAChF,CACF;EACA,GAAI;YANN;GAQG,KACC,kBAAC,OAAD;IACE,WAAW,EACT,2EACA,EAAW,CAAO,CACpB;cAEC,KACC,kBAAA,GAAA,EAAA,UAAA,CACG,KACC,kBAAC,MAAD;KAAI,WAAU;eACX;IACC,CAAA,GAEL,KACC,kBAAC,OAAD;KAAK,WAAU;eAA+B;IAAmB,CAAA,CAEnE,EAAA,CAAA;GAED,CAAA;GAGP,kBAAC,OAAD;IACE,WAAW,GACR,KAAa,MAAW,EAAkB,CAAO,CACpD;IAEC;GACE,CAAA;GAEJ,KACC,kBAAC,OAAD;IACE,WAAW,EACT,yCACA,EAAW,CAAO,CACpB;cAEC;GACE,CAAA;EAEJ;;AAET,CACF;AACA,EAAY,cAAc"}
@@ -78,7 +78,7 @@ var k = [
78
78
  tabIndex: o === f ? 0 : -1,
79
79
  disabled: l || !1,
80
80
  onClick: () => !l && r(o),
81
- className: e("h-ds-sm-plus rounded-control text-body-md transition-colors focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2", l && "opacity-action-disabled pointer-events-none cursor-not-allowed", s && "bg-accent-9 text-accent-fg", !s && !l && "hover:bg-surface-raised-hover text-surface-fg"),
81
+ className: e("h-ds-sm-plus rounded-control text-body-md transition-colors focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2", l && "opacity-action-disabled pointer-events-none cursor-not-allowed", s && "bg-accent-9 text-accent-fg", !s && !l && "hover:bg-surface-panel-hover text-surface-fg"),
82
82
  children: i
83
83
  }, i);
84
84
  })
@@ -154,7 +154,7 @@ var j = s.forwardRef(function({ currentYear: t, selectedYear: n, onYearSelect: r
154
154
  tabIndex: i === m ? 0 : -1,
155
155
  disabled: o || !1,
156
156
  onClick: () => !o && r(t),
157
- className: e("h-ds-sm-plus rounded-control text-body-md transition-colors focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2", o && "opacity-action-disabled pointer-events-none cursor-not-allowed", a && "bg-accent-9 text-accent-fg", !a && !o && "hover:bg-surface-raised-hover text-surface-fg"),
157
+ className: e("h-ds-sm-plus rounded-control text-body-md transition-colors focus-visible:ring-2 focus-visible:ring-accent-9 focus-visible:ring-offset-2", o && "opacity-action-disabled pointer-events-none cursor-not-allowed", a && "bg-accent-9 text-accent-fg", !a && !o && "hover:bg-surface-panel-hover text-surface-fg"),
158
158
  children: t
159
159
  }, t);
160
160
  })
@@ -322,7 +322,7 @@ var N = {
322
322
  let { start: e, end: t } = r.getRange();
323
323
  n(e, t);
324
324
  },
325
- className: e("h-ds-sm w-full rounded-control px-ds-03 text-left text-body-sm", "text-surface-fg transition-colors", "hover:bg-surface-raised-hover", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9"),
325
+ className: e("h-ds-sm w-full rounded-control px-ds-03 text-left text-body-sm", "text-surface-fg transition-colors", "hover:bg-surface-panel-hover", "focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-accent-9"),
326
326
  children: r.label
327
327
  }, t) : null;
328
328
  })
@@ -638,7 +638,7 @@ var V = s.forwardRef(function({ value: a, onChange: o, format: u = "12h", minute
638
638
  a,
639
639
  u,
640
640
  m
641
- ]), H = u === "12h" ? A : E, U = "flex flex-col gap-ds-01 overflow-y-auto max-h-[200px] px-ds-01", W = "flex h-ds-sm w-full items-center justify-center rounded-control text-body-md transition-colors duration-fast-01 ease-productive-standard cursor-pointer", G = "bg-accent-9 text-accent-fg", K = "text-surface-fg hover:bg-surface-raised-hover";
641
+ ]), H = u === "12h" ? A : E, U = "flex flex-col gap-ds-01 overflow-y-auto max-h-[200px] px-ds-01", W = "flex h-ds-sm w-full items-center justify-center rounded-control text-body-md transition-colors duration-fast-01 ease-productive-standard cursor-pointer", G = "bg-accent-9 text-accent-fg", K = "text-surface-fg hover:bg-surface-panel-hover";
642
642
  return /* @__PURE__ */ l(n, {
643
643
  open: w,
644
644
  onOpenChange: T,