@ecoma-io/loom 0.5.0 → 0.6.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 (1023) hide show
  1. package/README.md +188 -101
  2. package/dist/a11y.js +4 -3
  3. package/dist/composition/center/src/Center.js.map +1 -0
  4. package/dist/composition/center/src/Center.vue_vue_type_script_setup_true_lang.js.map +1 -0
  5. package/dist/composition/dashboard-grid/src/DashboardGrid.js +7 -0
  6. package/dist/composition/dashboard-grid/src/DashboardGrid.js.map +1 -0
  7. package/dist/composition/dashboard-grid/src/DashboardGrid.vue_vue_type_script_setup_true_lang.js +45 -0
  8. package/dist/composition/dashboard-grid/src/DashboardGrid.vue_vue_type_script_setup_true_lang.js.map +1 -0
  9. package/dist/composition/frame/src/Frame.js.map +1 -0
  10. package/dist/composition/frame/src/Frame.vue_vue_type_script_setup_true_lang.js.map +1 -0
  11. package/dist/composition/grid/src/Grid.js.map +1 -0
  12. package/dist/composition/grid/src/Grid.vue_vue_type_script_setup_true_lang.js.map +1 -0
  13. package/dist/composition/inline/src/Inline.js.map +1 -0
  14. package/dist/composition/inline/src/Inline.vue_vue_type_script_setup_true_lang.js.map +1 -0
  15. package/dist/composition/scroll-reel/src/ScrollReel.js.map +1 -0
  16. package/dist/composition/scroll-reel/src/ScrollReel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  17. package/dist/composition/sidebar/src/Sidebar.js.map +1 -0
  18. package/dist/composition/sidebar/src/Sidebar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  19. package/dist/composition/split/src/Split.js.map +1 -0
  20. package/dist/composition/split/src/Split.vue_vue_type_script_setup_true_lang.js.map +1 -0
  21. package/dist/composition/stack/src/Stack.js.map +1 -0
  22. package/dist/composition/stack/src/Stack.vue_vue_type_script_setup_true_lang.js.map +1 -0
  23. package/dist/core/src/a11y-contract.js +558 -0
  24. package/dist/core/src/a11y-contract.js.map +1 -0
  25. package/dist/core/src/a11y-scope.js +151 -0
  26. package/dist/core/src/a11y-scope.js.map +1 -0
  27. package/dist/core/src/attrs.js.map +1 -0
  28. package/dist/core/src/cn.js +61 -0
  29. package/dist/core/src/cn.js.map +1 -0
  30. package/dist/core/src/icon-defaults.js.map +1 -0
  31. package/dist/core/src/index.js +9 -0
  32. package/dist/core/src/motion.js +31 -0
  33. package/dist/core/src/motion.js.map +1 -0
  34. package/dist/core/src/props.js.map +1 -0
  35. package/dist/core/src/theme.js.map +1 -0
  36. package/dist/index.js +287 -285
  37. package/dist/labels/src/ancestor-disabled.js.map +1 -0
  38. package/dist/labels/src/count-labels.js.map +1 -0
  39. package/dist/labels/src/date-labels.js +206 -0
  40. package/dist/labels/src/date-labels.js.map +1 -0
  41. package/dist/labels/src/field-context.js.map +1 -0
  42. package/dist/labels/src/labels.js.map +1 -0
  43. package/dist/layouts/app-shell/src/AppShell.js.map +1 -0
  44. package/dist/layouts/app-shell/src/AppShell.vue_vue_type_script_setup_true_lang.js.map +1 -0
  45. package/dist/layouts/centered/src/Centered.js.map +1 -0
  46. package/dist/layouts/centered/src/Centered.vue_vue_type_script_setup_true_lang.js.map +1 -0
  47. package/dist/layouts/dashboard/src/Dashboard.js.map +1 -0
  48. package/dist/layouts/dashboard/src/Dashboard.vue_vue_type_script_setup_true_lang.js +65 -0
  49. package/dist/layouts/dashboard/src/Dashboard.vue_vue_type_script_setup_true_lang.js.map +1 -0
  50. package/dist/layouts/desktop-app-shell/src/DesktopAppShell.js +7 -0
  51. package/dist/layouts/desktop-app-shell/src/DesktopAppShell.js.map +1 -0
  52. package/dist/layouts/desktop-app-shell/src/DesktopAppShell.vue_vue_type_script_setup_true_lang.js +76 -0
  53. package/dist/layouts/desktop-app-shell/src/DesktopAppShell.vue_vue_type_script_setup_true_lang.js.map +1 -0
  54. package/dist/layouts/form-layout/src/FormLayout.js.map +1 -0
  55. package/dist/layouts/form-layout/src/FormLayout.vue_vue_type_script_setup_true_lang.js.map +1 -0
  56. package/dist/layouts/master-detail/src/MasterDetail.js.map +1 -0
  57. package/dist/layouts/master-detail/src/MasterDetail.vue_vue_type_script_setup_true_lang.js.map +1 -0
  58. package/dist/layouts/reading/src/Reading.js.map +1 -0
  59. package/dist/layouts/reading/src/Reading.vue_vue_type_script_setup_true_lang.js.map +1 -0
  60. package/dist/layouts/settings/src/Settings.js.map +1 -0
  61. package/dist/layouts/settings/src/Settings.vue_vue_type_script_setup_true_lang.js.map +1 -0
  62. package/dist/layouts/split-layout/src/SplitLayout.js.map +1 -0
  63. package/dist/layouts/split-layout/src/SplitLayout.vue_vue_type_script_setup_true_lang.js.map +1 -0
  64. package/dist/packages/composition/dashboard-grid/src/DashboardGrid.vue.d.ts +26 -0
  65. package/dist/packages/composition/dashboard-grid/src/DashboardGrid.vue.d.ts.map +1 -0
  66. package/dist/packages/composition/dashboard-grid/src/index.d.ts.map +1 -0
  67. package/dist/packages/composition/split/src/Split.vue.d.ts.map +1 -1
  68. package/dist/packages/core/src/a11y-contract.d.ts +417 -0
  69. package/dist/packages/core/src/a11y-contract.d.ts.map +1 -0
  70. package/dist/packages/core/src/a11y-scope.d.ts +5 -3
  71. package/dist/packages/core/src/a11y-scope.d.ts.map +1 -1
  72. package/dist/packages/core/src/index.d.ts +7 -1
  73. package/dist/packages/core/src/index.d.ts.map +1 -1
  74. package/dist/packages/core/src/motion.d.ts +15 -6
  75. package/dist/packages/core/src/motion.d.ts.map +1 -1
  76. package/dist/packages/core/src/responsive-contract.d.ts +155 -0
  77. package/dist/packages/core/src/responsive-contract.d.ts.map +1 -0
  78. package/dist/packages/labels/src/component-shapes.d.ts +2 -0
  79. package/dist/packages/labels/src/component-shapes.d.ts.map +1 -1
  80. package/dist/packages/layouts/dashboard/src/Dashboard.vue.d.ts.map +1 -1
  81. package/dist/packages/layouts/desktop-app-shell/src/DesktopAppShell.vue.d.ts +103 -0
  82. package/dist/packages/layouts/desktop-app-shell/src/index.d.ts.map +1 -0
  83. package/dist/packages/loom/src/a11y.d.ts +2 -1
  84. package/dist/packages/loom/src/index.d.ts +23 -23
  85. package/dist/packages/patterns/app-header/src/AppHeader.vue.d.ts +82 -0
  86. package/dist/packages/patterns/app-header/src/AppHeader.vue.d.ts.map +1 -0
  87. package/dist/packages/patterns/app-header/src/index.d.ts.map +1 -0
  88. package/dist/packages/patterns/empty-state/src/EmptyState.vue.d.ts +54 -0
  89. package/dist/packages/patterns/empty-state/src/EmptyState.vue.d.ts.map +1 -0
  90. package/dist/packages/patterns/empty-state/src/index.d.ts.map +1 -0
  91. package/dist/packages/patterns/error-state/src/ErrorState.vue.d.ts +44 -0
  92. package/dist/packages/patterns/error-state/src/ErrorState.vue.d.ts.map +1 -0
  93. package/dist/packages/patterns/error-state/src/index.d.ts.map +1 -0
  94. package/dist/packages/patterns/form-actions/src/FormActions.vue.d.ts +56 -0
  95. package/dist/packages/patterns/form-actions/src/FormActions.vue.d.ts.map +1 -0
  96. package/dist/packages/patterns/form-actions/src/index.d.ts.map +1 -0
  97. package/dist/packages/patterns/form-section/src/FormSection.vue.d.ts +85 -0
  98. package/dist/packages/patterns/form-section/src/FormSection.vue.d.ts.map +1 -0
  99. package/dist/packages/patterns/form-section/src/index.d.ts.map +1 -0
  100. package/dist/packages/patterns/loading-state/src/LoadingState.vue.d.ts.map +1 -0
  101. package/dist/packages/patterns/loading-state/src/index.d.ts.map +1 -0
  102. package/dist/packages/patterns/metric-card/src/MetricCard.vue.d.ts +77 -0
  103. package/dist/packages/patterns/metric-card/src/MetricCard.vue.d.ts.map +1 -0
  104. package/dist/packages/patterns/metric-card/src/index.d.ts.map +1 -0
  105. package/dist/packages/patterns/page-header/src/PageHeader.vue.d.ts.map +1 -0
  106. package/dist/packages/patterns/page-header/src/index.d.ts.map +1 -0
  107. package/dist/packages/patterns/row-actions/src/RowActions.vue.d.ts.map +1 -0
  108. package/dist/packages/patterns/row-actions/src/index.d.ts.map +1 -0
  109. package/dist/packages/patterns/sidebar-nav/src/SidebarNav.vue.d.ts.map +1 -0
  110. package/dist/packages/patterns/sidebar-nav/src/index.d.ts.map +1 -0
  111. package/dist/packages/patterns/title-bar/src/TitleBar.vue.d.ts +83 -0
  112. package/dist/packages/patterns/title-bar/src/index.d.ts.map +1 -0
  113. package/dist/packages/patterns/toast-stack/src/index.d.ts.map +1 -0
  114. package/dist/packages/primitives/list/src/ListItem.vue.d.ts +1 -1
  115. package/dist/packages/primitives/list/src/ListItem.vue.d.ts.map +1 -1
  116. package/dist/packages/primitives/surface/src/Surface.vue.d.ts +2 -2
  117. package/dist/packages/primitives/surface/src/Surface.vue.d.ts.map +1 -1
  118. package/dist/packages/primitives/table/src/TableRow.vue.d.ts +2 -2
  119. package/dist/packages/primitives/table/src/TableRow.vue.d.ts.map +1 -1
  120. package/dist/patterns/app-header/src/AppHeader.js +7 -0
  121. package/dist/patterns/app-header/src/AppHeader.js.map +1 -0
  122. package/dist/patterns/app-header/src/AppHeader.vue_vue_type_script_setup_true_lang.js +96 -0
  123. package/dist/patterns/app-header/src/AppHeader.vue_vue_type_script_setup_true_lang.js.map +1 -0
  124. package/dist/patterns/empty-state/src/EmptyState.js +7 -0
  125. package/dist/patterns/empty-state/src/EmptyState.js.map +1 -0
  126. package/dist/patterns/empty-state/src/EmptyState.vue_vue_type_script_setup_true_lang.js +73 -0
  127. package/dist/patterns/empty-state/src/EmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -0
  128. package/dist/patterns/error-state/src/ErrorState.js +7 -0
  129. package/dist/patterns/error-state/src/ErrorState.js.map +1 -0
  130. package/dist/patterns/error-state/src/ErrorState.vue_vue_type_script_setup_true_lang.js +60 -0
  131. package/dist/patterns/error-state/src/ErrorState.vue_vue_type_script_setup_true_lang.js.map +1 -0
  132. package/dist/patterns/error-summary/src/ErrorSummary.js +7 -0
  133. package/dist/patterns/error-summary/src/ErrorSummary.js.map +1 -0
  134. package/dist/patterns/error-summary/src/ErrorSummary.vue_vue_type_script_setup_true_lang.js +90 -0
  135. package/dist/patterns/error-summary/src/ErrorSummary.vue_vue_type_script_setup_true_lang.js.map +1 -0
  136. package/dist/patterns/form-actions/src/FormActions.js +7 -0
  137. package/dist/patterns/form-actions/src/FormActions.js.map +1 -0
  138. package/dist/patterns/form-actions/src/FormActions.vue_vue_type_script_setup_true_lang.js +22 -0
  139. package/dist/patterns/form-actions/src/FormActions.vue_vue_type_script_setup_true_lang.js.map +1 -0
  140. package/dist/patterns/form-section/src/FormSection.js +7 -0
  141. package/dist/patterns/form-section/src/FormSection.js.map +1 -0
  142. package/dist/patterns/form-section/src/FormSection.vue_vue_type_script_setup_true_lang.js +64 -0
  143. package/dist/patterns/form-section/src/FormSection.vue_vue_type_script_setup_true_lang.js.map +1 -0
  144. package/dist/patterns/loading-state/src/LoadingState.js +7 -0
  145. package/dist/patterns/loading-state/src/LoadingState.js.map +1 -0
  146. package/dist/patterns/loading-state/src/LoadingState.vue_vue_type_script_setup_true_lang.js +59 -0
  147. package/dist/patterns/loading-state/src/LoadingState.vue_vue_type_script_setup_true_lang.js.map +1 -0
  148. package/dist/patterns/metric-card/src/MetricCard.js +7 -0
  149. package/dist/patterns/metric-card/src/MetricCard.js.map +1 -0
  150. package/dist/patterns/metric-card/src/MetricCard.vue_vue_type_script_setup_true_lang.js +87 -0
  151. package/dist/patterns/metric-card/src/MetricCard.vue_vue_type_script_setup_true_lang.js.map +1 -0
  152. package/dist/patterns/page-header/src/PageHeader.js +7 -0
  153. package/dist/patterns/page-header/src/PageHeader.js.map +1 -0
  154. package/dist/patterns/page-header/src/PageHeader.vue_vue_type_script_setup_true_lang.js +68 -0
  155. package/dist/patterns/page-header/src/PageHeader.vue_vue_type_script_setup_true_lang.js.map +1 -0
  156. package/dist/patterns/row-actions/src/RowActions.js +7 -0
  157. package/dist/patterns/row-actions/src/RowActions.js.map +1 -0
  158. package/dist/patterns/row-actions/src/RowActions.vue_vue_type_script_setup_true_lang.js +47 -0
  159. package/dist/patterns/row-actions/src/RowActions.vue_vue_type_script_setup_true_lang.js.map +1 -0
  160. package/dist/patterns/sidebar-nav/src/SidebarNav.js +7 -0
  161. package/dist/patterns/sidebar-nav/src/SidebarNav.js.map +1 -0
  162. package/dist/patterns/sidebar-nav/src/SidebarNav.vue_vue_type_script_setup_true_lang.js +129 -0
  163. package/dist/patterns/sidebar-nav/src/SidebarNav.vue_vue_type_script_setup_true_lang.js.map +1 -0
  164. package/dist/patterns/title-bar/src/TitleBar.js +7 -0
  165. package/dist/patterns/title-bar/src/TitleBar.js.map +1 -0
  166. package/dist/patterns/title-bar/src/TitleBar.vue_vue_type_script_setup_true_lang.js +69 -0
  167. package/dist/patterns/title-bar/src/TitleBar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  168. package/dist/patterns/toast-stack/src/ToastStack.js +7 -0
  169. package/dist/patterns/toast-stack/src/ToastStack.js.map +1 -0
  170. package/dist/patterns/toast-stack/src/ToastStack.vue_vue_type_script_setup_true_lang.js +52 -0
  171. package/dist/patterns/toast-stack/src/ToastStack.vue_vue_type_script_setup_true_lang.js.map +1 -0
  172. package/dist/primitives/accordion/src/Accordion.js.map +1 -0
  173. package/dist/primitives/accordion/src/Accordion.vue_vue_type_script_setup_true_lang.js.map +1 -0
  174. package/dist/primitives/alert/src/Alert.js.map +1 -0
  175. package/dist/primitives/alert/src/Alert.vue_vue_type_script_setup_true_lang.js.map +1 -0
  176. package/dist/primitives/alert-dialog/src/AlertDialog.js.map +1 -0
  177. package/dist/primitives/alert-dialog/src/AlertDialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  178. package/dist/primitives/avatar/src/Avatar.js.map +1 -0
  179. package/dist/primitives/avatar/src/Avatar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  180. package/dist/primitives/avatar-group/src/AvatarGroup.js.map +1 -0
  181. package/dist/primitives/avatar-group/src/AvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  182. package/dist/primitives/badge/src/Badge.js.map +1 -0
  183. package/dist/primitives/badge/src/Badge.vue_vue_type_script_setup_true_lang.js.map +1 -0
  184. package/dist/primitives/breadcrumb/src/Breadcrumb.js.map +1 -0
  185. package/dist/primitives/breadcrumb/src/Breadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -0
  186. package/dist/primitives/button/src/Button.js.map +1 -0
  187. package/dist/primitives/button/src/Button.vue_vue_type_script_setup_true_lang.js.map +1 -0
  188. package/dist/primitives/calendar/src/Calendar.js.map +1 -0
  189. package/dist/primitives/calendar/src/Calendar.vue_vue_type_script_setup_true_lang.js +202 -0
  190. package/dist/primitives/calendar/src/Calendar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  191. package/dist/primitives/card/src/Card.js.map +1 -0
  192. package/dist/primitives/card/src/Card.vue_vue_type_script_setup_true_lang.js.map +1 -0
  193. package/dist/primitives/carousel/src/Carousel.js.map +1 -0
  194. package/dist/primitives/carousel/src/Carousel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  195. package/dist/primitives/checkbox/src/Checkbox.js.map +1 -0
  196. package/dist/primitives/checkbox/src/Checkbox.vue_vue_type_script_setup_true_lang.js.map +1 -0
  197. package/dist/primitives/chip/src/Chip.js.map +1 -0
  198. package/dist/primitives/chip/src/Chip.vue_vue_type_script_setup_true_lang.js.map +1 -0
  199. package/dist/primitives/collapse/src/Collapse.js.map +1 -0
  200. package/dist/primitives/collapse/src/Collapse.vue_vue_type_script_setup_true_lang.js.map +1 -0
  201. package/dist/primitives/color-picker/src/ColorPicker.js.map +1 -0
  202. package/dist/primitives/color-picker/src/ColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  203. package/dist/primitives/combobox/src/Combobox.js.map +1 -0
  204. package/dist/primitives/combobox/src/Combobox.vue_vue_type_script_setup_true_lang.js.map +1 -0
  205. package/dist/primitives/command/src/Command.js.map +1 -0
  206. package/dist/primitives/command/src/Command.vue_vue_type_script_setup_true_lang.js.map +1 -0
  207. package/dist/primitives/context-menu/src/ContextMenu.js.map +1 -0
  208. package/dist/primitives/context-menu/src/ContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  209. package/dist/primitives/copy-button/src/CopyButton.js.map +1 -0
  210. package/dist/primitives/copy-button/src/CopyButton.vue_vue_type_script_setup_true_lang.js.map +1 -0
  211. package/dist/primitives/copy-button/src/index.js +3 -0
  212. package/dist/primitives/data-grid/src/DataGrid.js.map +1 -0
  213. package/dist/primitives/data-grid/src/DataGrid.vue_vue_type_script_setup_true_lang.js.map +1 -0
  214. package/dist/primitives/date-picker/src/DatePicker.js.map +1 -0
  215. package/dist/primitives/date-picker/src/DatePicker.vue_vue_type_script_setup_true_lang.js +292 -0
  216. package/dist/primitives/date-picker/src/DatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  217. package/dist/primitives/date-range-picker/src/DateRangePicker.js.map +1 -0
  218. package/dist/primitives/date-range-picker/src/DateRangePicker.vue_vue_type_script_setup_true_lang.js +417 -0
  219. package/dist/primitives/date-range-picker/src/DateRangePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  220. package/dist/primitives/date-time-picker/src/DateTimePicker.js.map +1 -0
  221. package/dist/primitives/date-time-picker/src/DateTimePicker.vue_vue_type_script_setup_true_lang.js +359 -0
  222. package/dist/primitives/date-time-picker/src/DateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  223. package/dist/primitives/date-time-range-picker/src/DateTimeRangePicker.js.map +1 -0
  224. package/dist/primitives/date-time-range-picker/src/DateTimeRangePicker.vue_vue_type_script_setup_true_lang.js +563 -0
  225. package/dist/primitives/date-time-range-picker/src/DateTimeRangePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  226. package/dist/primitives/dialog/src/Dialog.js.map +1 -0
  227. package/dist/primitives/dialog/src/Dialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  228. package/dist/primitives/drawer/src/Drawer.js.map +1 -0
  229. package/dist/primitives/drawer/src/Drawer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  230. package/dist/primitives/dropdown-menu/src/DropdownMenu.js.map +1 -0
  231. package/dist/primitives/dropdown-menu/src/DropdownMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  232. package/dist/primitives/editable/src/Editable.js.map +1 -0
  233. package/dist/primitives/editable/src/Editable.vue_vue_type_script_setup_true_lang.js.map +1 -0
  234. package/dist/primitives/field/src/Field.js.map +1 -0
  235. package/dist/primitives/field/src/Field.vue_vue_type_script_setup_true_lang.js.map +1 -0
  236. package/dist/primitives/fieldset/src/Fieldset.js.map +1 -0
  237. package/dist/primitives/fieldset/src/Fieldset.vue_vue_type_script_setup_true_lang.js.map +1 -0
  238. package/dist/primitives/file-upload/src/FileUpload.js.map +1 -0
  239. package/dist/primitives/file-upload/src/FileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -0
  240. package/dist/primitives/hover-card/src/HoverCard.js.map +1 -0
  241. package/dist/primitives/hover-card/src/HoverCard.vue_vue_type_script_setup_true_lang.js.map +1 -0
  242. package/dist/primitives/icon-button/src/IconButton.js.map +1 -0
  243. package/dist/primitives/icon-button/src/IconButton.vue_vue_type_script_setup_true_lang.js.map +1 -0
  244. package/dist/primitives/indicator/src/Indicator.js.map +1 -0
  245. package/dist/primitives/indicator/src/Indicator.vue_vue_type_script_setup_true_lang.js.map +1 -0
  246. package/dist/primitives/inline-error/src/InlineError.js.map +1 -0
  247. package/dist/primitives/inline-error/src/InlineError.vue_vue_type_script_setup_true_lang.js.map +1 -0
  248. package/dist/primitives/kbd/src/Kbd.js.map +1 -0
  249. package/dist/primitives/kbd/src/Kbd.vue_vue_type_script_setup_true_lang.js.map +1 -0
  250. package/dist/primitives/link/src/Link.js.map +1 -0
  251. package/dist/primitives/link/src/Link.vue_vue_type_script_setup_true_lang.js.map +1 -0
  252. package/dist/primitives/list/src/List.js.map +1 -0
  253. package/dist/primitives/list/src/List.vue_vue_type_script_setup_true_lang.js.map +1 -0
  254. package/dist/primitives/list/src/ListItem.js.map +1 -0
  255. package/dist/primitives/list/src/ListItem.vue_vue_type_script_setup_true_lang.js +101 -0
  256. package/dist/primitives/list/src/ListItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  257. package/dist/primitives/live-region/src/LiveRegion.js.map +1 -0
  258. package/dist/primitives/live-region/src/LiveRegion.vue_vue_type_script_setup_true_lang.js.map +1 -0
  259. package/dist/primitives/live-region/src/context.js.map +1 -0
  260. package/dist/primitives/live-region/src/useAnnounce.js.map +1 -0
  261. package/dist/primitives/menubar/src/Menubar.js.map +1 -0
  262. package/dist/primitives/menubar/src/Menubar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  263. package/dist/primitives/meter/src/Meter.js.map +1 -0
  264. package/dist/primitives/meter/src/Meter.vue_vue_type_script_setup_true_lang.js.map +1 -0
  265. package/dist/primitives/navigation-menu/src/NavigationMenu.js.map +1 -0
  266. package/dist/primitives/navigation-menu/src/NavigationMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  267. package/dist/primitives/number-field/src/NumberField.js.map +1 -0
  268. package/dist/primitives/number-field/src/NumberField.vue_vue_type_script_setup_true_lang.js.map +1 -0
  269. package/dist/primitives/otp-input/src/OtpInput.js.map +1 -0
  270. package/dist/primitives/otp-input/src/OtpInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
  271. package/dist/primitives/pagination/src/Pagination.js.map +1 -0
  272. package/dist/primitives/pagination/src/Pagination.vue_vue_type_script_setup_true_lang.js.map +1 -0
  273. package/dist/primitives/popover/src/Popover.js.map +1 -0
  274. package/dist/primitives/popover/src/Popover.vue_vue_type_script_setup_true_lang.js.map +1 -0
  275. package/dist/primitives/progress/src/Progress.js.map +1 -0
  276. package/dist/primitives/progress/src/Progress.vue_vue_type_script_setup_true_lang.js.map +1 -0
  277. package/dist/primitives/radial-progress/src/RadialProgress.js.map +1 -0
  278. package/dist/primitives/radial-progress/src/RadialProgress.vue_vue_type_script_setup_true_lang.js.map +1 -0
  279. package/dist/primitives/radio-group/src/RadioGroup.js.map +1 -0
  280. package/dist/primitives/radio-group/src/RadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  281. package/dist/primitives/rating/src/Rating.js.map +1 -0
  282. package/dist/primitives/rating/src/Rating.vue_vue_type_script_setup_true_lang.js.map +1 -0
  283. package/dist/primitives/scroll-area/src/ScrollArea.js.map +1 -0
  284. package/dist/primitives/scroll-area/src/ScrollArea.vue_vue_type_script_setup_true_lang.js.map +1 -0
  285. package/dist/primitives/segmented-control/src/SegmentedControl.js.map +1 -0
  286. package/dist/primitives/segmented-control/src/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map +1 -0
  287. package/dist/primitives/select/src/Select.js.map +1 -0
  288. package/dist/primitives/select/src/Select.vue_vue_type_script_setup_true_lang.js.map +1 -0
  289. package/dist/primitives/separator/src/Separator.js.map +1 -0
  290. package/dist/primitives/separator/src/Separator.vue_vue_type_script_setup_true_lang.js.map +1 -0
  291. package/dist/primitives/skeleton/src/Skeleton.js.map +1 -0
  292. package/dist/primitives/skeleton/src/Skeleton.vue_vue_type_script_setup_true_lang.js.map +1 -0
  293. package/dist/primitives/skip-link/src/SkipLink.js.map +1 -0
  294. package/dist/primitives/skip-link/src/SkipLink.vue_vue_type_script_setup_true_lang.js.map +1 -0
  295. package/dist/primitives/slider/src/Slider.js.map +1 -0
  296. package/dist/primitives/slider/src/Slider.vue_vue_type_script_setup_true_lang.js.map +1 -0
  297. package/dist/primitives/speed-dial/src/SpeedDial.js.map +1 -0
  298. package/dist/primitives/speed-dial/src/SpeedDial.vue_vue_type_script_setup_true_lang.js.map +1 -0
  299. package/dist/primitives/spinner/src/Spinner.js.map +1 -0
  300. package/dist/primitives/spinner/src/Spinner.vue_vue_type_script_setup_true_lang.js.map +1 -0
  301. package/dist/primitives/stepper/src/Stepper.js.map +1 -0
  302. package/dist/primitives/stepper/src/Stepper.vue_vue_type_script_setup_true_lang.js.map +1 -0
  303. package/dist/primitives/surface/src/Surface.js.map +1 -0
  304. package/dist/primitives/surface/src/Surface.vue_vue_type_script_setup_true_lang.js.map +1 -0
  305. package/dist/primitives/switch/src/Switch.js.map +1 -0
  306. package/dist/primitives/switch/src/Switch.vue_vue_type_script_setup_true_lang.js.map +1 -0
  307. package/dist/primitives/table/src/Table.js.map +1 -0
  308. package/dist/primitives/table/src/Table.vue_vue_type_script_setup_true_lang.js.map +1 -0
  309. package/dist/primitives/table/src/TableCell.js.map +1 -0
  310. package/dist/primitives/table/src/TableCell.vue_vue_type_script_setup_true_lang.js.map +1 -0
  311. package/dist/primitives/table/src/TableHead.js.map +1 -0
  312. package/dist/primitives/table/src/TableHead.vue_vue_type_script_setup_true_lang.js.map +1 -0
  313. package/dist/primitives/table/src/TableRow.js.map +1 -0
  314. package/dist/primitives/table/src/TableRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
  315. package/dist/primitives/tabs/src/Tabs.js.map +1 -0
  316. package/dist/primitives/tabs/src/Tabs.vue_vue_type_script_setup_true_lang.js.map +1 -0
  317. package/dist/primitives/tags-input/src/TagsInput.js.map +1 -0
  318. package/dist/primitives/tags-input/src/TagsInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
  319. package/dist/primitives/text-field/src/TextField.js.map +1 -0
  320. package/dist/primitives/text-field/src/TextField.vue_vue_type_script_setup_true_lang.js.map +1 -0
  321. package/dist/primitives/textarea/src/Textarea.js.map +1 -0
  322. package/dist/primitives/textarea/src/Textarea.vue_vue_type_script_setup_true_lang.js.map +1 -0
  323. package/dist/primitives/time-picker/src/TimePicker.js.map +1 -0
  324. package/dist/primitives/time-picker/src/TimePicker.vue_vue_type_script_setup_true_lang.js +189 -0
  325. package/dist/primitives/time-picker/src/TimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  326. package/dist/primitives/timeline/src/Timeline.js.map +1 -0
  327. package/dist/primitives/timeline/src/Timeline.vue_vue_type_script_setup_true_lang.js.map +1 -0
  328. package/dist/primitives/timeline/src/TimelineItem.js.map +1 -0
  329. package/dist/primitives/timeline/src/TimelineItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  330. package/dist/primitives/timeline/src/index.js +5 -0
  331. package/dist/primitives/toast/src/Toast.js.map +1 -0
  332. package/dist/primitives/toast/src/Toast.vue_vue_type_script_setup_true_lang.js.map +1 -0
  333. package/dist/primitives/toast/src/ToastItem.js.map +1 -0
  334. package/dist/primitives/toast/src/ToastItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  335. package/dist/primitives/toggle-group/src/ToggleGroup.js.map +1 -0
  336. package/dist/primitives/toggle-group/src/ToggleGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  337. package/dist/primitives/toolbar/src/Toolbar.js.map +1 -0
  338. package/dist/primitives/toolbar/src/Toolbar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  339. package/dist/primitives/toolbar/src/ToolbarSeparator.js.map +1 -0
  340. package/dist/primitives/toolbar/src/ToolbarSeparator.vue_vue_type_script_setup_true_lang.js.map +1 -0
  341. package/dist/primitives/tooltip/src/Tooltip.js.map +1 -0
  342. package/dist/primitives/tooltip/src/Tooltip.vue_vue_type_script_setup_true_lang.js.map +1 -0
  343. package/dist/primitives/tree-view/src/TreeView.js.map +1 -0
  344. package/dist/primitives/tree-view/src/TreeView.vue_vue_type_script_setup_true_lang.js.map +1 -0
  345. package/dist/primitives/tree-view/src/TreeViewNode.js.map +1 -0
  346. package/dist/primitives/tree-view/src/TreeViewNode.vue_vue_type_script_setup_true_lang.js.map +1 -0
  347. package/dist/primitives/tree-view/src/context.js.map +1 -0
  348. package/dist/primitives/visually-hidden/src/VisuallyHidden.js.map +1 -0
  349. package/dist/primitives/visually-hidden/src/VisuallyHidden.vue_vue_type_script_setup_true_lang.js.map +1 -0
  350. package/dist/primitives/window-controls/src/WindowControls.js.map +1 -0
  351. package/dist/primitives/window-controls/src/WindowControls.vue_vue_type_script_setup_true_lang.js +127 -0
  352. package/dist/primitives/window-controls/src/WindowControls.vue_vue_type_script_setup_true_lang.js.map +1 -0
  353. package/dist/styles/theme.css +30 -6
  354. package/dist/theme.js +2 -2
  355. package/package.json +5 -4
  356. package/dist/node_modules/.pnpm/@internationalized_date@3.12.4/node_modules/@internationalized/date/dist/private/CalendarDate.js +0 -236
  357. package/dist/node_modules/.pnpm/@internationalized_date@3.12.4/node_modules/@internationalized/date/dist/private/CalendarDate.js.map +0 -1
  358. package/dist/node_modules/.pnpm/@internationalized_date@3.12.4/node_modules/@internationalized/date/dist/private/calendars/GregorianCalendar.js +0 -117
  359. package/dist/node_modules/.pnpm/@internationalized_date@3.12.4/node_modules/@internationalized/date/dist/private/calendars/GregorianCalendar.js.map +0 -1
  360. package/dist/node_modules/.pnpm/@internationalized_date@3.12.4/node_modules/@internationalized/date/dist/private/conversion.js +0 -142
  361. package/dist/node_modules/.pnpm/@internationalized_date@3.12.4/node_modules/@internationalized/date/dist/private/conversion.js.map +0 -1
  362. package/dist/node_modules/.pnpm/@internationalized_date@3.12.4/node_modules/@internationalized/date/dist/private/manipulation.js +0 -280
  363. package/dist/node_modules/.pnpm/@internationalized_date@3.12.4/node_modules/@internationalized/date/dist/private/manipulation.js.map +0 -1
  364. package/dist/node_modules/.pnpm/@internationalized_date@3.12.4/node_modules/@internationalized/date/dist/private/queries.js +0 -40
  365. package/dist/node_modules/.pnpm/@internationalized_date@3.12.4/node_modules/@internationalized/date/dist/private/queries.js.map +0 -1
  366. package/dist/node_modules/.pnpm/@internationalized_date@3.12.4/node_modules/@internationalized/date/dist/private/string.js +0 -69
  367. package/dist/node_modules/.pnpm/@internationalized_date@3.12.4/node_modules/@internationalized/date/dist/private/string.js.map +0 -1
  368. package/dist/node_modules/.pnpm/@internationalized_date@3.12.4/node_modules/@internationalized/date/dist/private/utils.js +0 -8
  369. package/dist/node_modules/.pnpm/@internationalized_date@3.12.4/node_modules/@internationalized/date/dist/private/utils.js.map +0 -1
  370. package/dist/packages/blocks/app-header/src/AppHeader.js +0 -7
  371. package/dist/packages/blocks/app-header/src/AppHeader.js.map +0 -1
  372. package/dist/packages/blocks/app-header/src/AppHeader.vue.d.ts +0 -82
  373. package/dist/packages/blocks/app-header/src/AppHeader.vue.d.ts.map +0 -1
  374. package/dist/packages/blocks/app-header/src/AppHeader.vue_vue_type_script_setup_true_lang.js +0 -96
  375. package/dist/packages/blocks/app-header/src/AppHeader.vue_vue_type_script_setup_true_lang.js.map +0 -1
  376. package/dist/packages/blocks/app-header/src/index.d.ts.map +0 -1
  377. package/dist/packages/blocks/dashboard-grid/src/DashboardGrid.js +0 -7
  378. package/dist/packages/blocks/dashboard-grid/src/DashboardGrid.js.map +0 -1
  379. package/dist/packages/blocks/dashboard-grid/src/DashboardGrid.vue.d.ts +0 -42
  380. package/dist/packages/blocks/dashboard-grid/src/DashboardGrid.vue.d.ts.map +0 -1
  381. package/dist/packages/blocks/dashboard-grid/src/DashboardGrid.vue_vue_type_script_setup_true_lang.js +0 -45
  382. package/dist/packages/blocks/dashboard-grid/src/DashboardGrid.vue_vue_type_script_setup_true_lang.js.map +0 -1
  383. package/dist/packages/blocks/dashboard-grid/src/index.d.ts.map +0 -1
  384. package/dist/packages/blocks/desktop-app-shell/src/DesktopAppShell.js +0 -7
  385. package/dist/packages/blocks/desktop-app-shell/src/DesktopAppShell.js.map +0 -1
  386. package/dist/packages/blocks/desktop-app-shell/src/DesktopAppShell.vue.d.ts +0 -102
  387. package/dist/packages/blocks/desktop-app-shell/src/DesktopAppShell.vue_vue_type_script_setup_true_lang.js +0 -76
  388. package/dist/packages/blocks/desktop-app-shell/src/DesktopAppShell.vue_vue_type_script_setup_true_lang.js.map +0 -1
  389. package/dist/packages/blocks/desktop-app-shell/src/index.d.ts.map +0 -1
  390. package/dist/packages/blocks/empty-state/src/EmptyState.js +0 -7
  391. package/dist/packages/blocks/empty-state/src/EmptyState.js.map +0 -1
  392. package/dist/packages/blocks/empty-state/src/EmptyState.vue.d.ts +0 -50
  393. package/dist/packages/blocks/empty-state/src/EmptyState.vue.d.ts.map +0 -1
  394. package/dist/packages/blocks/empty-state/src/EmptyState.vue_vue_type_script_setup_true_lang.js +0 -70
  395. package/dist/packages/blocks/empty-state/src/EmptyState.vue_vue_type_script_setup_true_lang.js.map +0 -1
  396. package/dist/packages/blocks/empty-state/src/index.d.ts.map +0 -1
  397. package/dist/packages/blocks/error-state/src/ErrorState.js +0 -7
  398. package/dist/packages/blocks/error-state/src/ErrorState.js.map +0 -1
  399. package/dist/packages/blocks/error-state/src/ErrorState.vue.d.ts +0 -44
  400. package/dist/packages/blocks/error-state/src/ErrorState.vue.d.ts.map +0 -1
  401. package/dist/packages/blocks/error-state/src/ErrorState.vue_vue_type_script_setup_true_lang.js +0 -60
  402. package/dist/packages/blocks/error-state/src/ErrorState.vue_vue_type_script_setup_true_lang.js.map +0 -1
  403. package/dist/packages/blocks/error-state/src/index.d.ts.map +0 -1
  404. package/dist/packages/blocks/error-summary/src/ErrorSummary.js +0 -7
  405. package/dist/packages/blocks/error-summary/src/ErrorSummary.js.map +0 -1
  406. package/dist/packages/blocks/error-summary/src/ErrorSummary.vue_vue_type_script_setup_true_lang.js +0 -90
  407. package/dist/packages/blocks/error-summary/src/ErrorSummary.vue_vue_type_script_setup_true_lang.js.map +0 -1
  408. package/dist/packages/blocks/form-actions/src/FormActions.js +0 -7
  409. package/dist/packages/blocks/form-actions/src/FormActions.js.map +0 -1
  410. package/dist/packages/blocks/form-actions/src/FormActions.vue.d.ts +0 -51
  411. package/dist/packages/blocks/form-actions/src/FormActions.vue.d.ts.map +0 -1
  412. package/dist/packages/blocks/form-actions/src/FormActions.vue_vue_type_script_setup_true_lang.js +0 -22
  413. package/dist/packages/blocks/form-actions/src/FormActions.vue_vue_type_script_setup_true_lang.js.map +0 -1
  414. package/dist/packages/blocks/form-actions/src/index.d.ts.map +0 -1
  415. package/dist/packages/blocks/form-section/src/FormSection.js +0 -7
  416. package/dist/packages/blocks/form-section/src/FormSection.js.map +0 -1
  417. package/dist/packages/blocks/form-section/src/FormSection.vue.d.ts +0 -85
  418. package/dist/packages/blocks/form-section/src/FormSection.vue.d.ts.map +0 -1
  419. package/dist/packages/blocks/form-section/src/FormSection.vue_vue_type_script_setup_true_lang.js +0 -64
  420. package/dist/packages/blocks/form-section/src/FormSection.vue_vue_type_script_setup_true_lang.js.map +0 -1
  421. package/dist/packages/blocks/form-section/src/index.d.ts.map +0 -1
  422. package/dist/packages/blocks/loading-state/src/LoadingState.js +0 -7
  423. package/dist/packages/blocks/loading-state/src/LoadingState.js.map +0 -1
  424. package/dist/packages/blocks/loading-state/src/LoadingState.vue.d.ts.map +0 -1
  425. package/dist/packages/blocks/loading-state/src/LoadingState.vue_vue_type_script_setup_true_lang.js +0 -59
  426. package/dist/packages/blocks/loading-state/src/LoadingState.vue_vue_type_script_setup_true_lang.js.map +0 -1
  427. package/dist/packages/blocks/loading-state/src/index.d.ts.map +0 -1
  428. package/dist/packages/blocks/metric-card/src/MetricCard.js +0 -7
  429. package/dist/packages/blocks/metric-card/src/MetricCard.js.map +0 -1
  430. package/dist/packages/blocks/metric-card/src/MetricCard.vue.d.ts +0 -77
  431. package/dist/packages/blocks/metric-card/src/MetricCard.vue.d.ts.map +0 -1
  432. package/dist/packages/blocks/metric-card/src/MetricCard.vue_vue_type_script_setup_true_lang.js +0 -87
  433. package/dist/packages/blocks/metric-card/src/MetricCard.vue_vue_type_script_setup_true_lang.js.map +0 -1
  434. package/dist/packages/blocks/metric-card/src/index.d.ts.map +0 -1
  435. package/dist/packages/blocks/page-header/src/PageHeader.js +0 -7
  436. package/dist/packages/blocks/page-header/src/PageHeader.js.map +0 -1
  437. package/dist/packages/blocks/page-header/src/PageHeader.vue.d.ts.map +0 -1
  438. package/dist/packages/blocks/page-header/src/PageHeader.vue_vue_type_script_setup_true_lang.js +0 -68
  439. package/dist/packages/blocks/page-header/src/PageHeader.vue_vue_type_script_setup_true_lang.js.map +0 -1
  440. package/dist/packages/blocks/page-header/src/index.d.ts.map +0 -1
  441. package/dist/packages/blocks/row-actions/src/RowActions.js +0 -7
  442. package/dist/packages/blocks/row-actions/src/RowActions.js.map +0 -1
  443. package/dist/packages/blocks/row-actions/src/RowActions.vue.d.ts.map +0 -1
  444. package/dist/packages/blocks/row-actions/src/RowActions.vue_vue_type_script_setup_true_lang.js +0 -47
  445. package/dist/packages/blocks/row-actions/src/RowActions.vue_vue_type_script_setup_true_lang.js.map +0 -1
  446. package/dist/packages/blocks/row-actions/src/index.d.ts.map +0 -1
  447. package/dist/packages/blocks/sidebar-nav/src/SidebarNav.js +0 -7
  448. package/dist/packages/blocks/sidebar-nav/src/SidebarNav.js.map +0 -1
  449. package/dist/packages/blocks/sidebar-nav/src/SidebarNav.vue.d.ts.map +0 -1
  450. package/dist/packages/blocks/sidebar-nav/src/SidebarNav.vue_vue_type_script_setup_true_lang.js +0 -129
  451. package/dist/packages/blocks/sidebar-nav/src/SidebarNav.vue_vue_type_script_setup_true_lang.js.map +0 -1
  452. package/dist/packages/blocks/sidebar-nav/src/index.d.ts.map +0 -1
  453. package/dist/packages/blocks/title-bar/src/TitleBar.js +0 -7
  454. package/dist/packages/blocks/title-bar/src/TitleBar.js.map +0 -1
  455. package/dist/packages/blocks/title-bar/src/TitleBar.vue.d.ts +0 -83
  456. package/dist/packages/blocks/title-bar/src/TitleBar.vue_vue_type_script_setup_true_lang.js +0 -69
  457. package/dist/packages/blocks/title-bar/src/TitleBar.vue_vue_type_script_setup_true_lang.js.map +0 -1
  458. package/dist/packages/blocks/title-bar/src/index.d.ts.map +0 -1
  459. package/dist/packages/blocks/toast-stack/src/ToastStack.js +0 -7
  460. package/dist/packages/blocks/toast-stack/src/ToastStack.js.map +0 -1
  461. package/dist/packages/blocks/toast-stack/src/ToastStack.vue_vue_type_script_setup_true_lang.js +0 -52
  462. package/dist/packages/blocks/toast-stack/src/ToastStack.vue_vue_type_script_setup_true_lang.js.map +0 -1
  463. package/dist/packages/blocks/toast-stack/src/index.d.ts.map +0 -1
  464. package/dist/packages/composition/center/src/Center.js.map +0 -1
  465. package/dist/packages/composition/center/src/Center.vue_vue_type_script_setup_true_lang.js.map +0 -1
  466. package/dist/packages/composition/frame/src/Frame.js.map +0 -1
  467. package/dist/packages/composition/frame/src/Frame.vue_vue_type_script_setup_true_lang.js.map +0 -1
  468. package/dist/packages/composition/grid/src/Grid.js.map +0 -1
  469. package/dist/packages/composition/grid/src/Grid.vue_vue_type_script_setup_true_lang.js.map +0 -1
  470. package/dist/packages/composition/inline/src/Inline.js.map +0 -1
  471. package/dist/packages/composition/inline/src/Inline.vue_vue_type_script_setup_true_lang.js.map +0 -1
  472. package/dist/packages/composition/scroll-reel/src/ScrollReel.js.map +0 -1
  473. package/dist/packages/composition/scroll-reel/src/ScrollReel.vue_vue_type_script_setup_true_lang.js.map +0 -1
  474. package/dist/packages/composition/sidebar/src/Sidebar.js.map +0 -1
  475. package/dist/packages/composition/sidebar/src/Sidebar.vue_vue_type_script_setup_true_lang.js.map +0 -1
  476. package/dist/packages/composition/split/src/Split.js.map +0 -1
  477. package/dist/packages/composition/split/src/Split.vue_vue_type_script_setup_true_lang.js.map +0 -1
  478. package/dist/packages/composition/stack/src/Stack.js.map +0 -1
  479. package/dist/packages/composition/stack/src/Stack.vue_vue_type_script_setup_true_lang.js.map +0 -1
  480. package/dist/packages/core/src/a11y-scope.js +0 -149
  481. package/dist/packages/core/src/a11y-scope.js.map +0 -1
  482. package/dist/packages/core/src/attrs.js.map +0 -1
  483. package/dist/packages/core/src/cn.js +0 -61
  484. package/dist/packages/core/src/cn.js.map +0 -1
  485. package/dist/packages/core/src/icon-defaults.js.map +0 -1
  486. package/dist/packages/core/src/index.js +0 -8
  487. package/dist/packages/core/src/motion.js +0 -27
  488. package/dist/packages/core/src/motion.js.map +0 -1
  489. package/dist/packages/core/src/props.js.map +0 -1
  490. package/dist/packages/core/src/theme.js.map +0 -1
  491. package/dist/packages/labels/src/ancestor-disabled.js.map +0 -1
  492. package/dist/packages/labels/src/count-labels.js.map +0 -1
  493. package/dist/packages/labels/src/date-labels.js +0 -206
  494. package/dist/packages/labels/src/date-labels.js.map +0 -1
  495. package/dist/packages/labels/src/field-context.js.map +0 -1
  496. package/dist/packages/labels/src/labels.js.map +0 -1
  497. package/dist/packages/layouts/app-shell/src/AppShell.js.map +0 -1
  498. package/dist/packages/layouts/app-shell/src/AppShell.vue_vue_type_script_setup_true_lang.js.map +0 -1
  499. package/dist/packages/layouts/centered/src/Centered.js.map +0 -1
  500. package/dist/packages/layouts/centered/src/Centered.vue_vue_type_script_setup_true_lang.js.map +0 -1
  501. package/dist/packages/layouts/dashboard/src/Dashboard.js.map +0 -1
  502. package/dist/packages/layouts/dashboard/src/Dashboard.vue_vue_type_script_setup_true_lang.js +0 -65
  503. package/dist/packages/layouts/dashboard/src/Dashboard.vue_vue_type_script_setup_true_lang.js.map +0 -1
  504. package/dist/packages/layouts/form-layout/src/FormLayout.js.map +0 -1
  505. package/dist/packages/layouts/form-layout/src/FormLayout.vue_vue_type_script_setup_true_lang.js.map +0 -1
  506. package/dist/packages/layouts/master-detail/src/MasterDetail.js.map +0 -1
  507. package/dist/packages/layouts/master-detail/src/MasterDetail.vue_vue_type_script_setup_true_lang.js.map +0 -1
  508. package/dist/packages/layouts/reading/src/Reading.js.map +0 -1
  509. package/dist/packages/layouts/reading/src/Reading.vue_vue_type_script_setup_true_lang.js.map +0 -1
  510. package/dist/packages/layouts/settings/src/Settings.js.map +0 -1
  511. package/dist/packages/layouts/settings/src/Settings.vue_vue_type_script_setup_true_lang.js.map +0 -1
  512. package/dist/packages/layouts/split-layout/src/SplitLayout.js.map +0 -1
  513. package/dist/packages/layouts/split-layout/src/SplitLayout.vue_vue_type_script_setup_true_lang.js.map +0 -1
  514. package/dist/packages/primitives/accordion/src/Accordion.js.map +0 -1
  515. package/dist/packages/primitives/accordion/src/Accordion.vue_vue_type_script_setup_true_lang.js.map +0 -1
  516. package/dist/packages/primitives/alert/src/Alert.js.map +0 -1
  517. package/dist/packages/primitives/alert/src/Alert.vue_vue_type_script_setup_true_lang.js.map +0 -1
  518. package/dist/packages/primitives/alert-dialog/src/AlertDialog.js.map +0 -1
  519. package/dist/packages/primitives/alert-dialog/src/AlertDialog.vue_vue_type_script_setup_true_lang.js.map +0 -1
  520. package/dist/packages/primitives/avatar/src/Avatar.js.map +0 -1
  521. package/dist/packages/primitives/avatar/src/Avatar.vue_vue_type_script_setup_true_lang.js.map +0 -1
  522. package/dist/packages/primitives/avatar-group/src/AvatarGroup.js.map +0 -1
  523. package/dist/packages/primitives/avatar-group/src/AvatarGroup.vue_vue_type_script_setup_true_lang.js.map +0 -1
  524. package/dist/packages/primitives/badge/src/Badge.js.map +0 -1
  525. package/dist/packages/primitives/badge/src/Badge.vue_vue_type_script_setup_true_lang.js.map +0 -1
  526. package/dist/packages/primitives/breadcrumb/src/Breadcrumb.js.map +0 -1
  527. package/dist/packages/primitives/breadcrumb/src/Breadcrumb.vue_vue_type_script_setup_true_lang.js.map +0 -1
  528. package/dist/packages/primitives/button/src/Button.js.map +0 -1
  529. package/dist/packages/primitives/button/src/Button.vue_vue_type_script_setup_true_lang.js.map +0 -1
  530. package/dist/packages/primitives/calendar/src/Calendar.js.map +0 -1
  531. package/dist/packages/primitives/calendar/src/Calendar.vue_vue_type_script_setup_true_lang.js +0 -204
  532. package/dist/packages/primitives/calendar/src/Calendar.vue_vue_type_script_setup_true_lang.js.map +0 -1
  533. package/dist/packages/primitives/card/src/Card.js.map +0 -1
  534. package/dist/packages/primitives/card/src/Card.vue_vue_type_script_setup_true_lang.js.map +0 -1
  535. package/dist/packages/primitives/carousel/src/Carousel.js.map +0 -1
  536. package/dist/packages/primitives/carousel/src/Carousel.vue_vue_type_script_setup_true_lang.js.map +0 -1
  537. package/dist/packages/primitives/checkbox/src/Checkbox.js.map +0 -1
  538. package/dist/packages/primitives/checkbox/src/Checkbox.vue_vue_type_script_setup_true_lang.js.map +0 -1
  539. package/dist/packages/primitives/chip/src/Chip.js.map +0 -1
  540. package/dist/packages/primitives/chip/src/Chip.vue_vue_type_script_setup_true_lang.js.map +0 -1
  541. package/dist/packages/primitives/collapse/src/Collapse.js.map +0 -1
  542. package/dist/packages/primitives/collapse/src/Collapse.vue_vue_type_script_setup_true_lang.js.map +0 -1
  543. package/dist/packages/primitives/color-picker/src/ColorPicker.js.map +0 -1
  544. package/dist/packages/primitives/color-picker/src/ColorPicker.vue_vue_type_script_setup_true_lang.js.map +0 -1
  545. package/dist/packages/primitives/combobox/src/Combobox.js.map +0 -1
  546. package/dist/packages/primitives/combobox/src/Combobox.vue_vue_type_script_setup_true_lang.js.map +0 -1
  547. package/dist/packages/primitives/command/src/Command.js.map +0 -1
  548. package/dist/packages/primitives/command/src/Command.vue_vue_type_script_setup_true_lang.js.map +0 -1
  549. package/dist/packages/primitives/context-menu/src/ContextMenu.js.map +0 -1
  550. package/dist/packages/primitives/context-menu/src/ContextMenu.vue_vue_type_script_setup_true_lang.js.map +0 -1
  551. package/dist/packages/primitives/copy-button/src/CopyButton.js.map +0 -1
  552. package/dist/packages/primitives/copy-button/src/CopyButton.vue_vue_type_script_setup_true_lang.js.map +0 -1
  553. package/dist/packages/primitives/copy-button/src/index.js +0 -3
  554. package/dist/packages/primitives/data-grid/src/DataGrid.js.map +0 -1
  555. package/dist/packages/primitives/data-grid/src/DataGrid.vue_vue_type_script_setup_true_lang.js.map +0 -1
  556. package/dist/packages/primitives/date-picker/src/DatePicker.js.map +0 -1
  557. package/dist/packages/primitives/date-picker/src/DatePicker.vue_vue_type_script_setup_true_lang.js +0 -294
  558. package/dist/packages/primitives/date-picker/src/DatePicker.vue_vue_type_script_setup_true_lang.js.map +0 -1
  559. package/dist/packages/primitives/date-range-picker/src/DateRangePicker.js.map +0 -1
  560. package/dist/packages/primitives/date-range-picker/src/DateRangePicker.vue_vue_type_script_setup_true_lang.js +0 -419
  561. package/dist/packages/primitives/date-range-picker/src/DateRangePicker.vue_vue_type_script_setup_true_lang.js.map +0 -1
  562. package/dist/packages/primitives/date-time-picker/src/DateTimePicker.js.map +0 -1
  563. package/dist/packages/primitives/date-time-picker/src/DateTimePicker.vue_vue_type_script_setup_true_lang.js +0 -361
  564. package/dist/packages/primitives/date-time-picker/src/DateTimePicker.vue_vue_type_script_setup_true_lang.js.map +0 -1
  565. package/dist/packages/primitives/date-time-range-picker/src/DateTimeRangePicker.js.map +0 -1
  566. package/dist/packages/primitives/date-time-range-picker/src/DateTimeRangePicker.vue_vue_type_script_setup_true_lang.js +0 -565
  567. package/dist/packages/primitives/date-time-range-picker/src/DateTimeRangePicker.vue_vue_type_script_setup_true_lang.js.map +0 -1
  568. package/dist/packages/primitives/dialog/src/Dialog.js.map +0 -1
  569. package/dist/packages/primitives/dialog/src/Dialog.vue_vue_type_script_setup_true_lang.js.map +0 -1
  570. package/dist/packages/primitives/drawer/src/Drawer.js.map +0 -1
  571. package/dist/packages/primitives/drawer/src/Drawer.vue_vue_type_script_setup_true_lang.js.map +0 -1
  572. package/dist/packages/primitives/dropdown-menu/src/DropdownMenu.js.map +0 -1
  573. package/dist/packages/primitives/dropdown-menu/src/DropdownMenu.vue_vue_type_script_setup_true_lang.js.map +0 -1
  574. package/dist/packages/primitives/editable/src/Editable.js.map +0 -1
  575. package/dist/packages/primitives/editable/src/Editable.vue_vue_type_script_setup_true_lang.js.map +0 -1
  576. package/dist/packages/primitives/field/src/Field.js.map +0 -1
  577. package/dist/packages/primitives/field/src/Field.vue_vue_type_script_setup_true_lang.js.map +0 -1
  578. package/dist/packages/primitives/fieldset/src/Fieldset.js.map +0 -1
  579. package/dist/packages/primitives/fieldset/src/Fieldset.vue_vue_type_script_setup_true_lang.js.map +0 -1
  580. package/dist/packages/primitives/file-upload/src/FileUpload.js.map +0 -1
  581. package/dist/packages/primitives/file-upload/src/FileUpload.vue_vue_type_script_setup_true_lang.js.map +0 -1
  582. package/dist/packages/primitives/hover-card/src/HoverCard.js.map +0 -1
  583. package/dist/packages/primitives/hover-card/src/HoverCard.vue_vue_type_script_setup_true_lang.js.map +0 -1
  584. package/dist/packages/primitives/icon-button/src/IconButton.js.map +0 -1
  585. package/dist/packages/primitives/icon-button/src/IconButton.vue_vue_type_script_setup_true_lang.js.map +0 -1
  586. package/dist/packages/primitives/indicator/src/Indicator.js.map +0 -1
  587. package/dist/packages/primitives/indicator/src/Indicator.vue_vue_type_script_setup_true_lang.js.map +0 -1
  588. package/dist/packages/primitives/inline-error/src/InlineError.js.map +0 -1
  589. package/dist/packages/primitives/inline-error/src/InlineError.vue_vue_type_script_setup_true_lang.js.map +0 -1
  590. package/dist/packages/primitives/kbd/src/Kbd.js.map +0 -1
  591. package/dist/packages/primitives/kbd/src/Kbd.vue_vue_type_script_setup_true_lang.js.map +0 -1
  592. package/dist/packages/primitives/link/src/Link.js.map +0 -1
  593. package/dist/packages/primitives/link/src/Link.vue_vue_type_script_setup_true_lang.js.map +0 -1
  594. package/dist/packages/primitives/list/src/List.js.map +0 -1
  595. package/dist/packages/primitives/list/src/List.vue_vue_type_script_setup_true_lang.js.map +0 -1
  596. package/dist/packages/primitives/list/src/ListItem.js.map +0 -1
  597. package/dist/packages/primitives/list/src/ListItem.vue_vue_type_script_setup_true_lang.js +0 -101
  598. package/dist/packages/primitives/list/src/ListItem.vue_vue_type_script_setup_true_lang.js.map +0 -1
  599. package/dist/packages/primitives/live-region/src/LiveRegion.js.map +0 -1
  600. package/dist/packages/primitives/live-region/src/LiveRegion.vue_vue_type_script_setup_true_lang.js.map +0 -1
  601. package/dist/packages/primitives/live-region/src/context.js.map +0 -1
  602. package/dist/packages/primitives/live-region/src/useAnnounce.js.map +0 -1
  603. package/dist/packages/primitives/menubar/src/Menubar.js.map +0 -1
  604. package/dist/packages/primitives/menubar/src/Menubar.vue_vue_type_script_setup_true_lang.js.map +0 -1
  605. package/dist/packages/primitives/meter/src/Meter.js.map +0 -1
  606. package/dist/packages/primitives/meter/src/Meter.vue_vue_type_script_setup_true_lang.js.map +0 -1
  607. package/dist/packages/primitives/navigation-menu/src/NavigationMenu.js.map +0 -1
  608. package/dist/packages/primitives/navigation-menu/src/NavigationMenu.vue_vue_type_script_setup_true_lang.js.map +0 -1
  609. package/dist/packages/primitives/number-field/src/NumberField.js.map +0 -1
  610. package/dist/packages/primitives/number-field/src/NumberField.vue_vue_type_script_setup_true_lang.js.map +0 -1
  611. package/dist/packages/primitives/otp-input/src/OtpInput.js.map +0 -1
  612. package/dist/packages/primitives/otp-input/src/OtpInput.vue_vue_type_script_setup_true_lang.js.map +0 -1
  613. package/dist/packages/primitives/pagination/src/Pagination.js.map +0 -1
  614. package/dist/packages/primitives/pagination/src/Pagination.vue_vue_type_script_setup_true_lang.js.map +0 -1
  615. package/dist/packages/primitives/popover/src/Popover.js.map +0 -1
  616. package/dist/packages/primitives/popover/src/Popover.vue_vue_type_script_setup_true_lang.js.map +0 -1
  617. package/dist/packages/primitives/progress/src/Progress.js.map +0 -1
  618. package/dist/packages/primitives/progress/src/Progress.vue_vue_type_script_setup_true_lang.js.map +0 -1
  619. package/dist/packages/primitives/radial-progress/src/RadialProgress.js.map +0 -1
  620. package/dist/packages/primitives/radial-progress/src/RadialProgress.vue_vue_type_script_setup_true_lang.js.map +0 -1
  621. package/dist/packages/primitives/radio-group/src/RadioGroup.js.map +0 -1
  622. package/dist/packages/primitives/radio-group/src/RadioGroup.vue_vue_type_script_setup_true_lang.js.map +0 -1
  623. package/dist/packages/primitives/rating/src/Rating.js.map +0 -1
  624. package/dist/packages/primitives/rating/src/Rating.vue_vue_type_script_setup_true_lang.js.map +0 -1
  625. package/dist/packages/primitives/scroll-area/src/ScrollArea.js.map +0 -1
  626. package/dist/packages/primitives/scroll-area/src/ScrollArea.vue_vue_type_script_setup_true_lang.js.map +0 -1
  627. package/dist/packages/primitives/segmented-control/src/SegmentedControl.js.map +0 -1
  628. package/dist/packages/primitives/segmented-control/src/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map +0 -1
  629. package/dist/packages/primitives/select/src/Select.js.map +0 -1
  630. package/dist/packages/primitives/select/src/Select.vue_vue_type_script_setup_true_lang.js.map +0 -1
  631. package/dist/packages/primitives/separator/src/Separator.js.map +0 -1
  632. package/dist/packages/primitives/separator/src/Separator.vue_vue_type_script_setup_true_lang.js.map +0 -1
  633. package/dist/packages/primitives/skeleton/src/Skeleton.js.map +0 -1
  634. package/dist/packages/primitives/skeleton/src/Skeleton.vue_vue_type_script_setup_true_lang.js.map +0 -1
  635. package/dist/packages/primitives/skip-link/src/SkipLink.js.map +0 -1
  636. package/dist/packages/primitives/skip-link/src/SkipLink.vue_vue_type_script_setup_true_lang.js.map +0 -1
  637. package/dist/packages/primitives/slider/src/Slider.js.map +0 -1
  638. package/dist/packages/primitives/slider/src/Slider.vue_vue_type_script_setup_true_lang.js.map +0 -1
  639. package/dist/packages/primitives/speed-dial/src/SpeedDial.js.map +0 -1
  640. package/dist/packages/primitives/speed-dial/src/SpeedDial.vue_vue_type_script_setup_true_lang.js.map +0 -1
  641. package/dist/packages/primitives/spinner/src/Spinner.js.map +0 -1
  642. package/dist/packages/primitives/spinner/src/Spinner.vue_vue_type_script_setup_true_lang.js.map +0 -1
  643. package/dist/packages/primitives/stepper/src/Stepper.js.map +0 -1
  644. package/dist/packages/primitives/stepper/src/Stepper.vue_vue_type_script_setup_true_lang.js.map +0 -1
  645. package/dist/packages/primitives/surface/src/Surface.js.map +0 -1
  646. package/dist/packages/primitives/surface/src/Surface.vue_vue_type_script_setup_true_lang.js.map +0 -1
  647. package/dist/packages/primitives/switch/src/Switch.js.map +0 -1
  648. package/dist/packages/primitives/switch/src/Switch.vue_vue_type_script_setup_true_lang.js.map +0 -1
  649. package/dist/packages/primitives/table/src/Table.js.map +0 -1
  650. package/dist/packages/primitives/table/src/Table.vue_vue_type_script_setup_true_lang.js.map +0 -1
  651. package/dist/packages/primitives/table/src/TableCell.js.map +0 -1
  652. package/dist/packages/primitives/table/src/TableCell.vue_vue_type_script_setup_true_lang.js.map +0 -1
  653. package/dist/packages/primitives/table/src/TableHead.js.map +0 -1
  654. package/dist/packages/primitives/table/src/TableHead.vue_vue_type_script_setup_true_lang.js.map +0 -1
  655. package/dist/packages/primitives/table/src/TableRow.js.map +0 -1
  656. package/dist/packages/primitives/table/src/TableRow.vue_vue_type_script_setup_true_lang.js.map +0 -1
  657. package/dist/packages/primitives/tabs/src/Tabs.js.map +0 -1
  658. package/dist/packages/primitives/tabs/src/Tabs.vue_vue_type_script_setup_true_lang.js.map +0 -1
  659. package/dist/packages/primitives/tags-input/src/TagsInput.js.map +0 -1
  660. package/dist/packages/primitives/tags-input/src/TagsInput.vue_vue_type_script_setup_true_lang.js.map +0 -1
  661. package/dist/packages/primitives/text-field/src/TextField.js.map +0 -1
  662. package/dist/packages/primitives/text-field/src/TextField.vue_vue_type_script_setup_true_lang.js.map +0 -1
  663. package/dist/packages/primitives/textarea/src/Textarea.js.map +0 -1
  664. package/dist/packages/primitives/textarea/src/Textarea.vue_vue_type_script_setup_true_lang.js.map +0 -1
  665. package/dist/packages/primitives/time-picker/src/TimePicker.js.map +0 -1
  666. package/dist/packages/primitives/time-picker/src/TimePicker.vue_vue_type_script_setup_true_lang.js +0 -189
  667. package/dist/packages/primitives/time-picker/src/TimePicker.vue_vue_type_script_setup_true_lang.js.map +0 -1
  668. package/dist/packages/primitives/timeline/src/Timeline.js.map +0 -1
  669. package/dist/packages/primitives/timeline/src/Timeline.vue_vue_type_script_setup_true_lang.js.map +0 -1
  670. package/dist/packages/primitives/timeline/src/TimelineItem.js.map +0 -1
  671. package/dist/packages/primitives/timeline/src/TimelineItem.vue_vue_type_script_setup_true_lang.js.map +0 -1
  672. package/dist/packages/primitives/timeline/src/index.js +0 -5
  673. package/dist/packages/primitives/toast/src/Toast.js.map +0 -1
  674. package/dist/packages/primitives/toast/src/Toast.vue_vue_type_script_setup_true_lang.js.map +0 -1
  675. package/dist/packages/primitives/toast/src/ToastItem.js.map +0 -1
  676. package/dist/packages/primitives/toast/src/ToastItem.vue_vue_type_script_setup_true_lang.js.map +0 -1
  677. package/dist/packages/primitives/toggle-group/src/ToggleGroup.js.map +0 -1
  678. package/dist/packages/primitives/toggle-group/src/ToggleGroup.vue_vue_type_script_setup_true_lang.js.map +0 -1
  679. package/dist/packages/primitives/toolbar/src/Toolbar.js.map +0 -1
  680. package/dist/packages/primitives/toolbar/src/Toolbar.vue_vue_type_script_setup_true_lang.js.map +0 -1
  681. package/dist/packages/primitives/toolbar/src/ToolbarSeparator.js.map +0 -1
  682. package/dist/packages/primitives/toolbar/src/ToolbarSeparator.vue_vue_type_script_setup_true_lang.js.map +0 -1
  683. package/dist/packages/primitives/tooltip/src/Tooltip.js.map +0 -1
  684. package/dist/packages/primitives/tooltip/src/Tooltip.vue_vue_type_script_setup_true_lang.js.map +0 -1
  685. package/dist/packages/primitives/tree-view/src/TreeView.js.map +0 -1
  686. package/dist/packages/primitives/tree-view/src/TreeView.vue_vue_type_script_setup_true_lang.js.map +0 -1
  687. package/dist/packages/primitives/tree-view/src/TreeViewNode.js.map +0 -1
  688. package/dist/packages/primitives/tree-view/src/TreeViewNode.vue_vue_type_script_setup_true_lang.js.map +0 -1
  689. package/dist/packages/primitives/tree-view/src/context.js.map +0 -1
  690. package/dist/packages/primitives/visually-hidden/src/VisuallyHidden.js.map +0 -1
  691. package/dist/packages/primitives/visually-hidden/src/VisuallyHidden.vue_vue_type_script_setup_true_lang.js.map +0 -1
  692. package/dist/packages/primitives/window-controls/src/WindowControls.js.map +0 -1
  693. package/dist/packages/primitives/window-controls/src/WindowControls.vue_vue_type_script_setup_true_lang.js +0 -124
  694. package/dist/packages/primitives/window-controls/src/WindowControls.vue_vue_type_script_setup_true_lang.js.map +0 -1
  695. /package/dist/{packages/composition → composition}/center/src/Center.js +0 -0
  696. /package/dist/{packages/composition → composition}/center/src/Center.vue_vue_type_script_setup_true_lang.js +0 -0
  697. /package/dist/{packages/composition → composition}/center/src/index.js +0 -0
  698. /package/dist/{packages/blocks → composition}/dashboard-grid/src/index.js +0 -0
  699. /package/dist/{packages/composition → composition}/frame/src/Frame.js +0 -0
  700. /package/dist/{packages/composition → composition}/frame/src/Frame.vue_vue_type_script_setup_true_lang.js +0 -0
  701. /package/dist/{packages/composition → composition}/frame/src/index.js +0 -0
  702. /package/dist/{packages/composition → composition}/grid/src/Grid.js +0 -0
  703. /package/dist/{packages/composition → composition}/grid/src/Grid.vue_vue_type_script_setup_true_lang.js +0 -0
  704. /package/dist/{packages/composition → composition}/grid/src/index.js +0 -0
  705. /package/dist/{packages/composition → composition}/inline/src/Inline.js +0 -0
  706. /package/dist/{packages/composition → composition}/inline/src/Inline.vue_vue_type_script_setup_true_lang.js +0 -0
  707. /package/dist/{packages/composition → composition}/inline/src/index.js +0 -0
  708. /package/dist/{packages/composition → composition}/scroll-reel/src/ScrollReel.js +0 -0
  709. /package/dist/{packages/composition → composition}/scroll-reel/src/ScrollReel.vue_vue_type_script_setup_true_lang.js +0 -0
  710. /package/dist/{packages/composition → composition}/scroll-reel/src/index.js +0 -0
  711. /package/dist/{packages/composition → composition}/sidebar/src/Sidebar.js +0 -0
  712. /package/dist/{packages/composition → composition}/sidebar/src/Sidebar.vue_vue_type_script_setup_true_lang.js +0 -0
  713. /package/dist/{packages/composition → composition}/sidebar/src/index.js +0 -0
  714. /package/dist/{packages/composition → composition}/split/src/Split.js +0 -0
  715. /package/dist/{packages/composition → composition}/split/src/Split.vue_vue_type_script_setup_true_lang.js +0 -0
  716. /package/dist/{packages/composition → composition}/split/src/index.js +0 -0
  717. /package/dist/{packages/composition → composition}/stack/src/Stack.js +0 -0
  718. /package/dist/{packages/composition → composition}/stack/src/Stack.vue_vue_type_script_setup_true_lang.js +0 -0
  719. /package/dist/{packages/composition → composition}/stack/src/index.js +0 -0
  720. /package/dist/{packages/core → core}/src/attrs.js +0 -0
  721. /package/dist/{packages/core → core}/src/icon-defaults.js +0 -0
  722. /package/dist/{packages/core → core}/src/props.js +0 -0
  723. /package/dist/{packages/core → core}/src/theme.js +0 -0
  724. /package/dist/{packages/labels → labels}/src/ancestor-disabled.js +0 -0
  725. /package/dist/{packages/labels → labels}/src/count-labels.js +0 -0
  726. /package/dist/{packages/labels → labels}/src/field-context.js +0 -0
  727. /package/dist/{packages/labels → labels}/src/index.js +0 -0
  728. /package/dist/{packages/labels → labels}/src/labels.js +0 -0
  729. /package/dist/{packages/layouts → layouts}/app-shell/src/AppShell.js +0 -0
  730. /package/dist/{packages/layouts → layouts}/app-shell/src/AppShell.vue_vue_type_script_setup_true_lang.js +0 -0
  731. /package/dist/{packages/layouts → layouts}/app-shell/src/index.js +0 -0
  732. /package/dist/{packages/layouts → layouts}/centered/src/Centered.js +0 -0
  733. /package/dist/{packages/layouts → layouts}/centered/src/Centered.vue_vue_type_script_setup_true_lang.js +0 -0
  734. /package/dist/{packages/layouts → layouts}/centered/src/index.js +0 -0
  735. /package/dist/{packages/layouts → layouts}/dashboard/src/Dashboard.js +0 -0
  736. /package/dist/{packages/layouts → layouts}/dashboard/src/index.js +0 -0
  737. /package/dist/{packages/blocks → layouts}/desktop-app-shell/src/index.js +0 -0
  738. /package/dist/{packages/layouts → layouts}/form-layout/src/FormLayout.js +0 -0
  739. /package/dist/{packages/layouts → layouts}/form-layout/src/FormLayout.vue_vue_type_script_setup_true_lang.js +0 -0
  740. /package/dist/{packages/layouts → layouts}/form-layout/src/index.js +0 -0
  741. /package/dist/{packages/layouts → layouts}/master-detail/src/MasterDetail.js +0 -0
  742. /package/dist/{packages/layouts → layouts}/master-detail/src/MasterDetail.vue_vue_type_script_setup_true_lang.js +0 -0
  743. /package/dist/{packages/layouts → layouts}/master-detail/src/index.js +0 -0
  744. /package/dist/{packages/layouts → layouts}/reading/src/Reading.js +0 -0
  745. /package/dist/{packages/layouts → layouts}/reading/src/Reading.vue_vue_type_script_setup_true_lang.js +0 -0
  746. /package/dist/{packages/layouts → layouts}/reading/src/index.js +0 -0
  747. /package/dist/{packages/layouts → layouts}/settings/src/Settings.js +0 -0
  748. /package/dist/{packages/layouts → layouts}/settings/src/Settings.vue_vue_type_script_setup_true_lang.js +0 -0
  749. /package/dist/{packages/layouts → layouts}/settings/src/index.js +0 -0
  750. /package/dist/{packages/layouts → layouts}/split-layout/src/SplitLayout.js +0 -0
  751. /package/dist/{packages/layouts → layouts}/split-layout/src/SplitLayout.vue_vue_type_script_setup_true_lang.js +0 -0
  752. /package/dist/{packages/layouts → layouts}/split-layout/src/index.js +0 -0
  753. /package/dist/packages/{blocks → composition}/dashboard-grid/src/index.d.ts +0 -0
  754. /package/dist/packages/{blocks → layouts}/desktop-app-shell/src/index.d.ts +0 -0
  755. /package/dist/packages/{blocks → patterns}/app-header/src/index.d.ts +0 -0
  756. /package/dist/packages/{blocks → patterns}/empty-state/src/index.d.ts +0 -0
  757. /package/dist/packages/{blocks → patterns}/error-state/src/index.d.ts +0 -0
  758. /package/dist/packages/{blocks → patterns}/error-summary/src/ErrorSummary.vue.d.ts +0 -0
  759. /package/dist/packages/{blocks → patterns}/error-summary/src/index.d.ts +0 -0
  760. /package/dist/packages/{blocks → patterns}/form-actions/src/index.d.ts +0 -0
  761. /package/dist/packages/{blocks → patterns}/form-section/src/index.d.ts +0 -0
  762. /package/dist/packages/{blocks → patterns}/loading-state/src/LoadingState.vue.d.ts +0 -0
  763. /package/dist/packages/{blocks → patterns}/loading-state/src/index.d.ts +0 -0
  764. /package/dist/packages/{blocks → patterns}/metric-card/src/index.d.ts +0 -0
  765. /package/dist/packages/{blocks → patterns}/page-header/src/PageHeader.vue.d.ts +0 -0
  766. /package/dist/packages/{blocks → patterns}/page-header/src/index.d.ts +0 -0
  767. /package/dist/packages/{blocks → patterns}/row-actions/src/RowActions.vue.d.ts +0 -0
  768. /package/dist/packages/{blocks → patterns}/row-actions/src/index.d.ts +0 -0
  769. /package/dist/packages/{blocks → patterns}/sidebar-nav/src/SidebarNav.vue.d.ts +0 -0
  770. /package/dist/packages/{blocks → patterns}/sidebar-nav/src/index.d.ts +0 -0
  771. /package/dist/packages/{blocks → patterns}/title-bar/src/index.d.ts +0 -0
  772. /package/dist/packages/{blocks → patterns}/toast-stack/src/ToastStack.vue.d.ts +0 -0
  773. /package/dist/packages/{blocks → patterns}/toast-stack/src/index.d.ts +0 -0
  774. /package/dist/{packages/blocks → patterns}/app-header/src/index.js +0 -0
  775. /package/dist/{packages/blocks → patterns}/empty-state/src/index.js +0 -0
  776. /package/dist/{packages/blocks → patterns}/error-state/src/index.js +0 -0
  777. /package/dist/{packages/blocks → patterns}/error-summary/src/index.js +0 -0
  778. /package/dist/{packages/blocks → patterns}/form-actions/src/index.js +0 -0
  779. /package/dist/{packages/blocks → patterns}/form-section/src/index.js +0 -0
  780. /package/dist/{packages/blocks → patterns}/loading-state/src/index.js +0 -0
  781. /package/dist/{packages/blocks → patterns}/metric-card/src/index.js +0 -0
  782. /package/dist/{packages/blocks → patterns}/page-header/src/index.js +0 -0
  783. /package/dist/{packages/blocks → patterns}/row-actions/src/index.js +0 -0
  784. /package/dist/{packages/blocks → patterns}/sidebar-nav/src/index.js +0 -0
  785. /package/dist/{packages/blocks → patterns}/title-bar/src/index.js +0 -0
  786. /package/dist/{packages/blocks → patterns}/toast-stack/src/index.js +0 -0
  787. /package/dist/{packages/primitives → primitives}/accordion/src/Accordion.js +0 -0
  788. /package/dist/{packages/primitives → primitives}/accordion/src/Accordion.vue_vue_type_script_setup_true_lang.js +0 -0
  789. /package/dist/{packages/primitives → primitives}/accordion/src/index.js +0 -0
  790. /package/dist/{packages/primitives → primitives}/alert/src/Alert.js +0 -0
  791. /package/dist/{packages/primitives → primitives}/alert/src/Alert.vue_vue_type_script_setup_true_lang.js +0 -0
  792. /package/dist/{packages/primitives → primitives}/alert/src/index.js +0 -0
  793. /package/dist/{packages/primitives → primitives}/alert-dialog/src/AlertDialog.js +0 -0
  794. /package/dist/{packages/primitives → primitives}/alert-dialog/src/AlertDialog.vue_vue_type_script_setup_true_lang.js +0 -0
  795. /package/dist/{packages/primitives → primitives}/alert-dialog/src/index.js +0 -0
  796. /package/dist/{packages/primitives → primitives}/avatar/src/Avatar.js +0 -0
  797. /package/dist/{packages/primitives → primitives}/avatar/src/Avatar.vue_vue_type_script_setup_true_lang.js +0 -0
  798. /package/dist/{packages/primitives → primitives}/avatar/src/index.js +0 -0
  799. /package/dist/{packages/primitives → primitives}/avatar-group/src/AvatarGroup.js +0 -0
  800. /package/dist/{packages/primitives → primitives}/avatar-group/src/AvatarGroup.vue_vue_type_script_setup_true_lang.js +0 -0
  801. /package/dist/{packages/primitives → primitives}/avatar-group/src/index.js +0 -0
  802. /package/dist/{packages/primitives → primitives}/badge/src/Badge.js +0 -0
  803. /package/dist/{packages/primitives → primitives}/badge/src/Badge.vue_vue_type_script_setup_true_lang.js +0 -0
  804. /package/dist/{packages/primitives → primitives}/badge/src/index.js +0 -0
  805. /package/dist/{packages/primitives → primitives}/breadcrumb/src/Breadcrumb.js +0 -0
  806. /package/dist/{packages/primitives → primitives}/breadcrumb/src/Breadcrumb.vue_vue_type_script_setup_true_lang.js +0 -0
  807. /package/dist/{packages/primitives → primitives}/breadcrumb/src/index.js +0 -0
  808. /package/dist/{packages/primitives → primitives}/button/src/Button.js +0 -0
  809. /package/dist/{packages/primitives → primitives}/button/src/Button.vue_vue_type_script_setup_true_lang.js +0 -0
  810. /package/dist/{packages/primitives → primitives}/button/src/index.js +0 -0
  811. /package/dist/{packages/primitives → primitives}/calendar/src/Calendar.js +0 -0
  812. /package/dist/{packages/primitives → primitives}/calendar/src/index.js +0 -0
  813. /package/dist/{packages/primitives → primitives}/card/src/Card.js +0 -0
  814. /package/dist/{packages/primitives → primitives}/card/src/Card.vue_vue_type_script_setup_true_lang.js +0 -0
  815. /package/dist/{packages/primitives → primitives}/card/src/index.js +0 -0
  816. /package/dist/{packages/primitives → primitives}/carousel/src/Carousel.js +0 -0
  817. /package/dist/{packages/primitives → primitives}/carousel/src/Carousel.vue_vue_type_script_setup_true_lang.js +0 -0
  818. /package/dist/{packages/primitives → primitives}/carousel/src/index.js +0 -0
  819. /package/dist/{packages/primitives → primitives}/checkbox/src/Checkbox.js +0 -0
  820. /package/dist/{packages/primitives → primitives}/checkbox/src/Checkbox.vue_vue_type_script_setup_true_lang.js +0 -0
  821. /package/dist/{packages/primitives → primitives}/checkbox/src/index.js +0 -0
  822. /package/dist/{packages/primitives → primitives}/chip/src/Chip.js +0 -0
  823. /package/dist/{packages/primitives → primitives}/chip/src/Chip.vue_vue_type_script_setup_true_lang.js +0 -0
  824. /package/dist/{packages/primitives → primitives}/chip/src/index.js +0 -0
  825. /package/dist/{packages/primitives → primitives}/collapse/src/Collapse.js +0 -0
  826. /package/dist/{packages/primitives → primitives}/collapse/src/Collapse.vue_vue_type_script_setup_true_lang.js +0 -0
  827. /package/dist/{packages/primitives → primitives}/collapse/src/index.js +0 -0
  828. /package/dist/{packages/primitives → primitives}/color-picker/src/ColorPicker.js +0 -0
  829. /package/dist/{packages/primitives → primitives}/color-picker/src/ColorPicker.vue_vue_type_script_setup_true_lang.js +0 -0
  830. /package/dist/{packages/primitives → primitives}/color-picker/src/index.js +0 -0
  831. /package/dist/{packages/primitives → primitives}/combobox/src/Combobox.js +0 -0
  832. /package/dist/{packages/primitives → primitives}/combobox/src/Combobox.vue_vue_type_script_setup_true_lang.js +0 -0
  833. /package/dist/{packages/primitives → primitives}/combobox/src/index.js +0 -0
  834. /package/dist/{packages/primitives → primitives}/command/src/Command.js +0 -0
  835. /package/dist/{packages/primitives → primitives}/command/src/Command.vue_vue_type_script_setup_true_lang.js +0 -0
  836. /package/dist/{packages/primitives → primitives}/command/src/index.js +0 -0
  837. /package/dist/{packages/primitives → primitives}/context-menu/src/ContextMenu.js +0 -0
  838. /package/dist/{packages/primitives → primitives}/context-menu/src/ContextMenu.vue_vue_type_script_setup_true_lang.js +0 -0
  839. /package/dist/{packages/primitives → primitives}/context-menu/src/index.js +0 -0
  840. /package/dist/{packages/primitives → primitives}/copy-button/src/CopyButton.js +0 -0
  841. /package/dist/{packages/primitives → primitives}/copy-button/src/CopyButton.vue_vue_type_script_setup_true_lang.js +0 -0
  842. /package/dist/{packages/primitives → primitives}/data-grid/src/DataGrid.js +0 -0
  843. /package/dist/{packages/primitives → primitives}/data-grid/src/DataGrid.vue_vue_type_script_setup_true_lang.js +0 -0
  844. /package/dist/{packages/primitives → primitives}/data-grid/src/index.js +0 -0
  845. /package/dist/{packages/primitives → primitives}/date-picker/src/DatePicker.js +0 -0
  846. /package/dist/{packages/primitives → primitives}/date-picker/src/index.js +0 -0
  847. /package/dist/{packages/primitives → primitives}/date-range-picker/src/DateRangePicker.js +0 -0
  848. /package/dist/{packages/primitives → primitives}/date-range-picker/src/index.js +0 -0
  849. /package/dist/{packages/primitives → primitives}/date-time-picker/src/DateTimePicker.js +0 -0
  850. /package/dist/{packages/primitives → primitives}/date-time-picker/src/index.js +0 -0
  851. /package/dist/{packages/primitives → primitives}/date-time-range-picker/src/DateTimeRangePicker.js +0 -0
  852. /package/dist/{packages/primitives → primitives}/date-time-range-picker/src/index.js +0 -0
  853. /package/dist/{packages/primitives → primitives}/dialog/src/Dialog.js +0 -0
  854. /package/dist/{packages/primitives → primitives}/dialog/src/Dialog.vue_vue_type_script_setup_true_lang.js +0 -0
  855. /package/dist/{packages/primitives → primitives}/dialog/src/index.js +0 -0
  856. /package/dist/{packages/primitives → primitives}/drawer/src/Drawer.js +0 -0
  857. /package/dist/{packages/primitives → primitives}/drawer/src/Drawer.vue_vue_type_script_setup_true_lang.js +0 -0
  858. /package/dist/{packages/primitives → primitives}/drawer/src/index.js +0 -0
  859. /package/dist/{packages/primitives → primitives}/dropdown-menu/src/DropdownMenu.js +0 -0
  860. /package/dist/{packages/primitives → primitives}/dropdown-menu/src/DropdownMenu.vue_vue_type_script_setup_true_lang.js +0 -0
  861. /package/dist/{packages/primitives → primitives}/dropdown-menu/src/index.js +0 -0
  862. /package/dist/{packages/primitives → primitives}/editable/src/Editable.js +0 -0
  863. /package/dist/{packages/primitives → primitives}/editable/src/Editable.vue_vue_type_script_setup_true_lang.js +0 -0
  864. /package/dist/{packages/primitives → primitives}/editable/src/index.js +0 -0
  865. /package/dist/{packages/primitives → primitives}/field/src/Field.js +0 -0
  866. /package/dist/{packages/primitives → primitives}/field/src/Field.vue_vue_type_script_setup_true_lang.js +0 -0
  867. /package/dist/{packages/primitives → primitives}/field/src/index.js +0 -0
  868. /package/dist/{packages/primitives → primitives}/fieldset/src/Fieldset.js +0 -0
  869. /package/dist/{packages/primitives → primitives}/fieldset/src/Fieldset.vue_vue_type_script_setup_true_lang.js +0 -0
  870. /package/dist/{packages/primitives → primitives}/fieldset/src/index.js +0 -0
  871. /package/dist/{packages/primitives → primitives}/file-upload/src/FileUpload.js +0 -0
  872. /package/dist/{packages/primitives → primitives}/file-upload/src/FileUpload.vue_vue_type_script_setup_true_lang.js +0 -0
  873. /package/dist/{packages/primitives → primitives}/file-upload/src/index.js +0 -0
  874. /package/dist/{packages/primitives → primitives}/hover-card/src/HoverCard.js +0 -0
  875. /package/dist/{packages/primitives → primitives}/hover-card/src/HoverCard.vue_vue_type_script_setup_true_lang.js +0 -0
  876. /package/dist/{packages/primitives → primitives}/hover-card/src/index.js +0 -0
  877. /package/dist/{packages/primitives → primitives}/icon-button/src/IconButton.js +0 -0
  878. /package/dist/{packages/primitives → primitives}/icon-button/src/IconButton.vue_vue_type_script_setup_true_lang.js +0 -0
  879. /package/dist/{packages/primitives → primitives}/icon-button/src/index.js +0 -0
  880. /package/dist/{packages/primitives → primitives}/indicator/src/Indicator.js +0 -0
  881. /package/dist/{packages/primitives → primitives}/indicator/src/Indicator.vue_vue_type_script_setup_true_lang.js +0 -0
  882. /package/dist/{packages/primitives → primitives}/indicator/src/index.js +0 -0
  883. /package/dist/{packages/primitives → primitives}/inline-error/src/InlineError.js +0 -0
  884. /package/dist/{packages/primitives → primitives}/inline-error/src/InlineError.vue_vue_type_script_setup_true_lang.js +0 -0
  885. /package/dist/{packages/primitives → primitives}/inline-error/src/index.js +0 -0
  886. /package/dist/{packages/primitives → primitives}/kbd/src/Kbd.js +0 -0
  887. /package/dist/{packages/primitives → primitives}/kbd/src/Kbd.vue_vue_type_script_setup_true_lang.js +0 -0
  888. /package/dist/{packages/primitives → primitives}/kbd/src/index.js +0 -0
  889. /package/dist/{packages/primitives → primitives}/link/src/Link.js +0 -0
  890. /package/dist/{packages/primitives → primitives}/link/src/Link.vue_vue_type_script_setup_true_lang.js +0 -0
  891. /package/dist/{packages/primitives → primitives}/link/src/index.js +0 -0
  892. /package/dist/{packages/primitives → primitives}/list/src/List.js +0 -0
  893. /package/dist/{packages/primitives → primitives}/list/src/List.vue_vue_type_script_setup_true_lang.js +0 -0
  894. /package/dist/{packages/primitives → primitives}/list/src/ListItem.js +0 -0
  895. /package/dist/{packages/primitives → primitives}/list/src/index.js +0 -0
  896. /package/dist/{packages/primitives → primitives}/live-region/src/LiveRegion.js +0 -0
  897. /package/dist/{packages/primitives → primitives}/live-region/src/LiveRegion.vue_vue_type_script_setup_true_lang.js +0 -0
  898. /package/dist/{packages/primitives → primitives}/live-region/src/context.js +0 -0
  899. /package/dist/{packages/primitives → primitives}/live-region/src/index.js +0 -0
  900. /package/dist/{packages/primitives → primitives}/live-region/src/useAnnounce.js +0 -0
  901. /package/dist/{packages/primitives → primitives}/menubar/src/Menubar.js +0 -0
  902. /package/dist/{packages/primitives → primitives}/menubar/src/Menubar.vue_vue_type_script_setup_true_lang.js +0 -0
  903. /package/dist/{packages/primitives → primitives}/menubar/src/index.js +0 -0
  904. /package/dist/{packages/primitives → primitives}/meter/src/Meter.js +0 -0
  905. /package/dist/{packages/primitives → primitives}/meter/src/Meter.vue_vue_type_script_setup_true_lang.js +0 -0
  906. /package/dist/{packages/primitives → primitives}/meter/src/index.js +0 -0
  907. /package/dist/{packages/primitives → primitives}/navigation-menu/src/NavigationMenu.js +0 -0
  908. /package/dist/{packages/primitives → primitives}/navigation-menu/src/NavigationMenu.vue_vue_type_script_setup_true_lang.js +0 -0
  909. /package/dist/{packages/primitives → primitives}/navigation-menu/src/index.js +0 -0
  910. /package/dist/{packages/primitives → primitives}/number-field/src/NumberField.js +0 -0
  911. /package/dist/{packages/primitives → primitives}/number-field/src/NumberField.vue_vue_type_script_setup_true_lang.js +0 -0
  912. /package/dist/{packages/primitives → primitives}/number-field/src/index.js +0 -0
  913. /package/dist/{packages/primitives → primitives}/otp-input/src/OtpInput.js +0 -0
  914. /package/dist/{packages/primitives → primitives}/otp-input/src/OtpInput.vue_vue_type_script_setup_true_lang.js +0 -0
  915. /package/dist/{packages/primitives → primitives}/otp-input/src/index.js +0 -0
  916. /package/dist/{packages/primitives → primitives}/pagination/src/Pagination.js +0 -0
  917. /package/dist/{packages/primitives → primitives}/pagination/src/Pagination.vue_vue_type_script_setup_true_lang.js +0 -0
  918. /package/dist/{packages/primitives → primitives}/pagination/src/index.js +0 -0
  919. /package/dist/{packages/primitives → primitives}/popover/src/Popover.js +0 -0
  920. /package/dist/{packages/primitives → primitives}/popover/src/Popover.vue_vue_type_script_setup_true_lang.js +0 -0
  921. /package/dist/{packages/primitives → primitives}/popover/src/index.js +0 -0
  922. /package/dist/{packages/primitives → primitives}/progress/src/Progress.js +0 -0
  923. /package/dist/{packages/primitives → primitives}/progress/src/Progress.vue_vue_type_script_setup_true_lang.js +0 -0
  924. /package/dist/{packages/primitives → primitives}/progress/src/index.js +0 -0
  925. /package/dist/{packages/primitives → primitives}/radial-progress/src/RadialProgress.js +0 -0
  926. /package/dist/{packages/primitives → primitives}/radial-progress/src/RadialProgress.vue_vue_type_script_setup_true_lang.js +0 -0
  927. /package/dist/{packages/primitives → primitives}/radial-progress/src/index.js +0 -0
  928. /package/dist/{packages/primitives → primitives}/radio-group/src/RadioGroup.js +0 -0
  929. /package/dist/{packages/primitives → primitives}/radio-group/src/RadioGroup.vue_vue_type_script_setup_true_lang.js +0 -0
  930. /package/dist/{packages/primitives → primitives}/radio-group/src/index.js +0 -0
  931. /package/dist/{packages/primitives → primitives}/rating/src/Rating.js +0 -0
  932. /package/dist/{packages/primitives → primitives}/rating/src/Rating.vue_vue_type_script_setup_true_lang.js +0 -0
  933. /package/dist/{packages/primitives → primitives}/rating/src/index.js +0 -0
  934. /package/dist/{packages/primitives → primitives}/scroll-area/src/ScrollArea.js +0 -0
  935. /package/dist/{packages/primitives → primitives}/scroll-area/src/ScrollArea.vue_vue_type_script_setup_true_lang.js +0 -0
  936. /package/dist/{packages/primitives → primitives}/scroll-area/src/index.js +0 -0
  937. /package/dist/{packages/primitives → primitives}/segmented-control/src/SegmentedControl.js +0 -0
  938. /package/dist/{packages/primitives → primitives}/segmented-control/src/SegmentedControl.vue_vue_type_script_setup_true_lang.js +0 -0
  939. /package/dist/{packages/primitives → primitives}/segmented-control/src/index.js +0 -0
  940. /package/dist/{packages/primitives → primitives}/select/src/Select.js +0 -0
  941. /package/dist/{packages/primitives → primitives}/select/src/Select.vue_vue_type_script_setup_true_lang.js +0 -0
  942. /package/dist/{packages/primitives → primitives}/select/src/index.js +0 -0
  943. /package/dist/{packages/primitives → primitives}/separator/src/Separator.js +0 -0
  944. /package/dist/{packages/primitives → primitives}/separator/src/Separator.vue_vue_type_script_setup_true_lang.js +0 -0
  945. /package/dist/{packages/primitives → primitives}/separator/src/index.js +0 -0
  946. /package/dist/{packages/primitives → primitives}/skeleton/src/Skeleton.js +0 -0
  947. /package/dist/{packages/primitives → primitives}/skeleton/src/Skeleton.vue_vue_type_script_setup_true_lang.js +0 -0
  948. /package/dist/{packages/primitives → primitives}/skeleton/src/index.js +0 -0
  949. /package/dist/{packages/primitives → primitives}/skip-link/src/SkipLink.js +0 -0
  950. /package/dist/{packages/primitives → primitives}/skip-link/src/SkipLink.vue_vue_type_script_setup_true_lang.js +0 -0
  951. /package/dist/{packages/primitives → primitives}/skip-link/src/index.js +0 -0
  952. /package/dist/{packages/primitives → primitives}/slider/src/Slider.js +0 -0
  953. /package/dist/{packages/primitives → primitives}/slider/src/Slider.vue_vue_type_script_setup_true_lang.js +0 -0
  954. /package/dist/{packages/primitives → primitives}/slider/src/index.js +0 -0
  955. /package/dist/{packages/primitives → primitives}/speed-dial/src/SpeedDial.js +0 -0
  956. /package/dist/{packages/primitives → primitives}/speed-dial/src/SpeedDial.vue_vue_type_script_setup_true_lang.js +0 -0
  957. /package/dist/{packages/primitives → primitives}/speed-dial/src/index.js +0 -0
  958. /package/dist/{packages/primitives → primitives}/spinner/src/Spinner.js +0 -0
  959. /package/dist/{packages/primitives → primitives}/spinner/src/Spinner.vue_vue_type_script_setup_true_lang.js +0 -0
  960. /package/dist/{packages/primitives → primitives}/spinner/src/index.js +0 -0
  961. /package/dist/{packages/primitives → primitives}/stepper/src/Stepper.js +0 -0
  962. /package/dist/{packages/primitives → primitives}/stepper/src/Stepper.vue_vue_type_script_setup_true_lang.js +0 -0
  963. /package/dist/{packages/primitives → primitives}/stepper/src/index.js +0 -0
  964. /package/dist/{packages/primitives → primitives}/surface/src/Surface.js +0 -0
  965. /package/dist/{packages/primitives → primitives}/surface/src/Surface.vue_vue_type_script_setup_true_lang.js +0 -0
  966. /package/dist/{packages/primitives → primitives}/surface/src/index.js +0 -0
  967. /package/dist/{packages/primitives → primitives}/switch/src/Switch.js +0 -0
  968. /package/dist/{packages/primitives → primitives}/switch/src/Switch.vue_vue_type_script_setup_true_lang.js +0 -0
  969. /package/dist/{packages/primitives → primitives}/switch/src/index.js +0 -0
  970. /package/dist/{packages/primitives → primitives}/table/src/Table.js +0 -0
  971. /package/dist/{packages/primitives → primitives}/table/src/Table.vue_vue_type_script_setup_true_lang.js +0 -0
  972. /package/dist/{packages/primitives → primitives}/table/src/TableCell.js +0 -0
  973. /package/dist/{packages/primitives → primitives}/table/src/TableCell.vue_vue_type_script_setup_true_lang.js +0 -0
  974. /package/dist/{packages/primitives → primitives}/table/src/TableHead.js +0 -0
  975. /package/dist/{packages/primitives → primitives}/table/src/TableHead.vue_vue_type_script_setup_true_lang.js +0 -0
  976. /package/dist/{packages/primitives → primitives}/table/src/TableRow.js +0 -0
  977. /package/dist/{packages/primitives → primitives}/table/src/TableRow.vue_vue_type_script_setup_true_lang.js +0 -0
  978. /package/dist/{packages/primitives → primitives}/table/src/index.js +0 -0
  979. /package/dist/{packages/primitives → primitives}/tabs/src/Tabs.js +0 -0
  980. /package/dist/{packages/primitives → primitives}/tabs/src/Tabs.vue_vue_type_script_setup_true_lang.js +0 -0
  981. /package/dist/{packages/primitives → primitives}/tabs/src/index.js +0 -0
  982. /package/dist/{packages/primitives → primitives}/tags-input/src/TagsInput.js +0 -0
  983. /package/dist/{packages/primitives → primitives}/tags-input/src/TagsInput.vue_vue_type_script_setup_true_lang.js +0 -0
  984. /package/dist/{packages/primitives → primitives}/tags-input/src/index.js +0 -0
  985. /package/dist/{packages/primitives → primitives}/text-field/src/TextField.js +0 -0
  986. /package/dist/{packages/primitives → primitives}/text-field/src/TextField.vue_vue_type_script_setup_true_lang.js +0 -0
  987. /package/dist/{packages/primitives → primitives}/text-field/src/index.js +0 -0
  988. /package/dist/{packages/primitives → primitives}/textarea/src/Textarea.js +0 -0
  989. /package/dist/{packages/primitives → primitives}/textarea/src/Textarea.vue_vue_type_script_setup_true_lang.js +0 -0
  990. /package/dist/{packages/primitives → primitives}/textarea/src/index.js +0 -0
  991. /package/dist/{packages/primitives → primitives}/time-picker/src/TimePicker.js +0 -0
  992. /package/dist/{packages/primitives → primitives}/time-picker/src/index.js +0 -0
  993. /package/dist/{packages/primitives → primitives}/timeline/src/Timeline.js +0 -0
  994. /package/dist/{packages/primitives → primitives}/timeline/src/Timeline.vue_vue_type_script_setup_true_lang.js +0 -0
  995. /package/dist/{packages/primitives → primitives}/timeline/src/TimelineItem.js +0 -0
  996. /package/dist/{packages/primitives → primitives}/timeline/src/TimelineItem.vue_vue_type_script_setup_true_lang.js +0 -0
  997. /package/dist/{packages/primitives → primitives}/toast/src/Toast.js +0 -0
  998. /package/dist/{packages/primitives → primitives}/toast/src/Toast.vue_vue_type_script_setup_true_lang.js +0 -0
  999. /package/dist/{packages/primitives → primitives}/toast/src/ToastItem.js +0 -0
  1000. /package/dist/{packages/primitives → primitives}/toast/src/ToastItem.vue_vue_type_script_setup_true_lang.js +0 -0
  1001. /package/dist/{packages/primitives → primitives}/toast/src/index.js +0 -0
  1002. /package/dist/{packages/primitives → primitives}/toggle-group/src/ToggleGroup.js +0 -0
  1003. /package/dist/{packages/primitives → primitives}/toggle-group/src/ToggleGroup.vue_vue_type_script_setup_true_lang.js +0 -0
  1004. /package/dist/{packages/primitives → primitives}/toggle-group/src/index.js +0 -0
  1005. /package/dist/{packages/primitives → primitives}/toolbar/src/Toolbar.js +0 -0
  1006. /package/dist/{packages/primitives → primitives}/toolbar/src/Toolbar.vue_vue_type_script_setup_true_lang.js +0 -0
  1007. /package/dist/{packages/primitives → primitives}/toolbar/src/ToolbarSeparator.js +0 -0
  1008. /package/dist/{packages/primitives → primitives}/toolbar/src/ToolbarSeparator.vue_vue_type_script_setup_true_lang.js +0 -0
  1009. /package/dist/{packages/primitives → primitives}/toolbar/src/index.js +0 -0
  1010. /package/dist/{packages/primitives → primitives}/tooltip/src/Tooltip.js +0 -0
  1011. /package/dist/{packages/primitives → primitives}/tooltip/src/Tooltip.vue_vue_type_script_setup_true_lang.js +0 -0
  1012. /package/dist/{packages/primitives → primitives}/tooltip/src/index.js +0 -0
  1013. /package/dist/{packages/primitives → primitives}/tree-view/src/TreeView.js +0 -0
  1014. /package/dist/{packages/primitives → primitives}/tree-view/src/TreeView.vue_vue_type_script_setup_true_lang.js +0 -0
  1015. /package/dist/{packages/primitives → primitives}/tree-view/src/TreeViewNode.js +0 -0
  1016. /package/dist/{packages/primitives → primitives}/tree-view/src/TreeViewNode.vue_vue_type_script_setup_true_lang.js +0 -0
  1017. /package/dist/{packages/primitives → primitives}/tree-view/src/context.js +0 -0
  1018. /package/dist/{packages/primitives → primitives}/tree-view/src/index.js +0 -0
  1019. /package/dist/{packages/primitives → primitives}/visually-hidden/src/VisuallyHidden.js +0 -0
  1020. /package/dist/{packages/primitives → primitives}/visually-hidden/src/VisuallyHidden.vue_vue_type_script_setup_true_lang.js +0 -0
  1021. /package/dist/{packages/primitives → primitives}/visually-hidden/src/index.js +0 -0
  1022. /package/dist/{packages/primitives → primitives}/window-controls/src/WindowControls.js +0 -0
  1023. /package/dist/{packages/primitives → primitives}/window-controls/src/index.js +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"ColorPicker.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../../../packages/primitives/color-picker/src/ColorPicker.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { ColorPickerLabels } from \"@ecoma-io/loom-labels\";\n\n/**\n\n/**\n * Loom's English, co-located with the component so it tree-shakes with it, and\n * exported so a host can build a partial vocabulary against the real thing.\n */\nexport const COLOR_PICKER_LABELS: ColorPickerLabels = {\n area: \"Saturation and brightness\",\n areaRoleDescription: \"Colour picker\",\n areaThumb: \"Saturation and brightness\",\n areaThumbRoleDescription: \"Colour thumb\",\n // Differs from Reka's own \"Saturation 60, Brightness 80\" by the one capital,\n // which is the same trick the rest of the library uses to let a test assert\n // whose string reached the DOM rather than merely what it said.\n areaValue: ({ saturation, brightness }) =>\n `Saturation ${String(saturation)}, brightness ${String(brightness)}`,\n hue: \"Hue\",\n hex: \"Hex value\",\n presets: \"Presets\",\n swatch: ({ color }) => color,\n swatchRoleDescription: \"Colour swatch\",\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, ref, useTemplateRef, watch } from \"vue\";\nimport {\n ColorAreaRoot,\n ColorAreaArea,\n ColorAreaThumb,\n ColorSliderRoot,\n ColorSliderTrack,\n ColorSliderThumb,\n ColorFieldRoot,\n ColorFieldInput,\n ColorSwatch,\n ColorSwatchPickerRoot,\n ColorSwatchPickerItem,\n colorToString,\n getChannelValue,\n isValidColor,\n normalizeColor,\n type Color,\n} from \"reka-ui\";\nimport { cn } from \"@ecoma-io/loom-core\";\nimport { optional } from \"@ecoma-io/loom-core\";\nimport { useSplitAttrs } from \"@ecoma-io/loom-core\";\nimport { useAncestorDisabled } from \"@ecoma-io/loom-labels\";\nimport { useFieldControl } from \"@ecoma-io/loom-labels\";\nimport { useLabels, type LabelOverrides } from \"@ecoma-io/loom-labels\";\n\n/**\n * ColorPicker — choose one colour, as `#rrggbb`. A saturation/brightness\n * area, a hue slider, an editable hex field, and an optional row of presets.\n * Reach for it when the colour itself is the value being authored: a label\n * colour, a chart series, a theme override.\n *\n * When the choice is actually a small closed set — a status colour, a brand\n * palette — a Select or a RadioGroup names the options and this does not.\n * A picker offers sixteen million answers, which is the wrong control for a\n * question with six.\n *\n * Built on Reka UI's colour parts, which supply the whole semantic layer:\n * `role=\"slider\"` on both thumbs, the area's two-axis arrow stepping, the\n * listbox roving focus over the presets, and the parsing that turns typed text\n * into a colour. Every part models its value as a colour string and emits hex,\n * which is what lets this expose one plain `#rrggbb` rather than a channel\n * object.\n *\n * **Where the \"no raw colour values\" rule falls here.** The colour a person is\n * picking is *data*: the area's gradient, the hue track and every swatch fill\n * are bound from the model value at run time, and a token could not express\n * them. Everything that is *chrome* — the borders, the focus ring, the field,\n * the labels, the disabled state, the rings that keep the thumbs visible —\n * comes from `theme.css` and nothing else. A literal colour in this file is a\n * defect unless it is a value being picked.\n *\n * **The hex is the non-colour channel.** A control that communicates only in\n * colour is unusable by the readers most likely to need help choosing one, so\n * the hex value is always on screen as text and is itself the edit surface;\n * every swatch is named rather than left a bare square — by its hex unless\n * `labels.swatch` gives it words; and the disabled state is carried by\n * `aria-disabled` as well as by the appearance. It is also why the hex and the\n * saturation area are the parts of an unavailable picker that drain rather\n * than dim, while the hue track and presets keep a documented dim — their\n * fills are data colours no token can express. See the root's class list and\n * the comments on those parts.\n *\n * The event contract matches Slider and NumberField. `update:modelValue` is\n * transient — every position a thumb passes through — and `commit` fires once\n * per gesture, so one drag across the area is one undo entry rather than a\n * hundred.\n *\n * Inside a [Field](../Field/Field.vue) it wires itself through\n * `useFieldControl()`, and the row's answers land on two different nodes — see\n * the comment above `groupFieldAttrs`, which is where that split is decided.\n * **A row's label does not name the picker.** `<label for>` names a labelable\n * element and this renders a `div[role=\"group\"]`, so the row's label resolves\n * to it and announces nobody; `ariaLabel`/`ariaLabelledby` below are what name\n * the picker, exactly as they were before.\n *\n * There is no `readonly`, and a row's is ignored rather than approximated. A\n * colour that may be looked at but not changed is a swatch — the `ColorSwatch`\n * beside the hex value already is one — and none of the four parts has a\n * read-only state to put it in, so the honest options were a picker that looks\n * live and swallows every gesture, or none at all.\n */\nconst props = withDefaults(\n defineProps<{\n /** The chosen colour as `#rrggbb`. There is no alpha channel in this version. */\n modelValue?: string;\n /** Preset colours shown as a row of named swatches. Omit it and no row is rendered. */\n swatches?: string[];\n /** Unavailable: drains the picker's chrome, keeps the colour surfaces readable, and refuses the pointer, the keyboard and the field. Unset defers to a wrapping Field. */\n disabled?: boolean | undefined;\n /** The accessible name for the picker as a whole, when nothing visible already labels it. */\n ariaLabel?: string;\n /** The id of the visible element that labels the picker (a Field wrapper's label, say). */\n ariaLabelledby?: string;\n /**\n * Names for the parts, as any subset of `ColorPickerLabels` — the rest stay\n * as the host's `provideLoomLabels` vocabulary left them, and then as\n * Loom's English.\n *\n * `ariaLabel` above names the *picker*; this names what is inside it, and\n * six of its nine keys are the only thing standing between a reader and\n * Reka UI's own English.\n */\n labels?: LabelOverrides<ColorPickerLabels>;\n }>(),\n {\n // Not `false`: absent has to stay tellable from `false` for a Field above\n // to disable the row and for `:disabled=\"false\"` to overrule one that does.\n // Vue casts an absent Boolean prop with no declared default to `false`,\n // which would leave the context wired and inert.\n disabled: undefined,\n },\n);\n\nconst emit = defineEmits<{\n /** Transient: every colour a drag or an arrow step passes through. Not a checkpoint. */\n \"update:modelValue\": [value: string];\n /** Committed: once per gesture — drag release, arrow step, hex entry, preset click. */\n commit: [value: string];\n}>();\n\n// `text`, not `labels`: the prop of that name is one of the three sources this\n// resolves, and a template reading the raw prop would be reading the overrides\n// rather than the answer.\nconst text = useLabels(\"colorPicker\", COLOR_PICKER_LABELS, () => props.labels);\n\n// The seed for an unset or unparseable model value. Reka's ColorArea, ColorField\n// and ColorSlider each fall back to this same string internally, so matching it\n// is what keeps the four parts agreeing about what \"no colour yet\" looks like\n// rather than each inventing its own. It is picked data, not a theme colour.\nconst FALLBACK = \"#000000\";\n\n// A colour a consumer supplied is parsed by Reka inside a render function, and\n// an unparseable one throws there — taking the host's page down, not just this\n// component. A library cannot do that with a prop, so every value entering\n// `current` is checked first. `isValidColor` is Reka's own parser rather than a\n// regex here, so what this accepts and what the parts accept cannot drift.\nfunction toColor(value: string | undefined): string {\n return value !== undefined && isValidColor(value) ? value : FALLBACK;\n}\n\n// The working colour, fed to all four parts. Seeded from the prop and advanced\n// on every tick, exactly as Slider's `lastValue` is: given a defined model value\n// Reka runs fully controlled, so a host that correctly withholds transient\n// values until commit would otherwise freeze the thumbs at the gesture's start.\nconst current = ref(toColor(props.modelValue));\n\n// The value the host last acknowledged. Every commit path compares against it,\n// which is what makes a gesture that ends where it started — a click that lands\n// on the thumb, an arrow at the edge of the area, the same hex retyped, the\n// already-selected preset clicked again — produce no checkpoint at all.\nconst lastCommitted = ref(current.value);\n\n// An incoming value equal to `current` is this component's own emit echoing\n// back through a `v-model`, and re-baselining on it would swallow the commit at\n// the end of the gesture that produced it. Anything else is the host moving the\n// colour itself, which is a new baseline by definition — which is why this\n// needs no \"is a gesture in flight?\" flag to tell the two apart.\nwatch(\n () => props.modelValue,\n (value) => {\n const next = toColor(value);\n if (next === current.value) return;\n current.value = next;\n lastCommitted.value = next;\n },\n);\n\n// Every one of Reka's parts writes a hex string back into its own model, but\n// each types its update as `string | Color` because that union is what it will\n// *accept* coming in. Narrowing it here rather than casting keeps the object\n// half real: a future part that emits one still resolves to hex instead of\n// stringifying to \"[object Object]\" and failing to parse two frames later.\nfunction applyFromPart(value: string | Color): void {\n apply(typeof value === \"string\" ? value : colorToString(value, \"hex\"));\n}\n\nfunction apply(next: string): void {\n const value = toColor(next);\n if (value === current.value) return;\n current.value = value;\n emit(\"update:modelValue\", value);\n}\n\n/**\n * The area thumb's `aria-valuetext`, which Reka would otherwise build from its\n * own English channel names — \"Saturation 60, Brightness 80\", said again on\n * every arrow key.\n *\n * The two numbers are recomputed here rather than read out of Reka, because\n * Reka exposes neither: `ColorAreaRoot` yields only `style` to its slot and\n * keeps `xValue`/`yValue` in a context this component cannot inject. What it\n * does export is the arithmetic — `getChannelValue` and `normalizeColor` are\n * the same two functions `ColorAreaRoot` calls, applied to the same `current`\n * this component hands it as `model-value`, with the same `Math.round`. So the\n * number here and the `aria-valuenow` beside it agree by construction rather\n * than by coincidence, which is what makes replacing this string safe: Reka\n * re-derives its own pair from the model on the next tick after any gesture,\n * to this identical formula.\n */\nconst areaValueText = computed(() => {\n const color = normalizeColor(current.value);\n return text.value.areaValue({\n saturation: Math.round(getChannelValue(color, \"saturation\")),\n brightness: Math.round(getChannelValue(color, \"brightness\")),\n });\n});\n\nfunction onFieldCommit(value: string | Color): void {\n applyFromPart(value);\n commitCurrent();\n}\n\nfunction commitCurrent(): void {\n if (current.value === lastCommitted.value) return;\n lastCommitted.value = current.value;\n emit(\"commit\", current.value);\n}\n\n// Reka commits the area on pointer release only — `ColorAreaArea` calls its\n// root's `commitValues` from `pointerup` and not from its own key handler — so\n// an arrow-stepped colour would never reach a host's undo stack. Deferring by a\n// tick is what makes this independent of whether Vue runs this listener before\n// or after Reka's on the same element: by then the step has been applied and\n// `current` holds it. `commitCurrent` swallows the no-op at the axis limits.\nconst AREA_STEP_KEYS = new Set([\n \"ArrowLeft\",\n \"ArrowRight\",\n \"ArrowUp\",\n \"ArrowDown\",\n \"PageUp\",\n \"PageDown\",\n \"Home\",\n \"End\",\n]);\n\nfunction onAreaKeydown(event: KeyboardEvent): void {\n if (field.disabled || !AREA_STEP_KEYS.has(event.key)) return;\n void nextTick(commitCurrent);\n}\n\n// A preset that will not parse is dropped rather than rendered: it would be an\n// invisible square that sets an unusable value, and an empty row would leave a\n// `role=\"listbox\"` with no options, which is an ARIA violation of its own. The\n// row is therefore rendered only when something survives this.\nconst presets = computed(() => (props.swatches ?? []).filter((swatch) => isValidColor(swatch)));\n\nfunction onPresetPick(value: unknown): void {\n if (typeof value !== \"string\") return;\n apply(value);\n commitCurrent();\n}\n\n// Unlike Slider and Select, `class` and the remaining fallthrough attributes go\n// to the same node. The picker has four interactive parts and no single one of\n// them is what an `aria-describedby` or a `data-testid` is about — the group\n// around them is. `class` still needs the `cn()` merge rather than Vue's plain\n// concatenation, so it is bound separately from the spread.\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: groupAttrs } = useSplitAttrs();\n\n/**\n * Two of this control's four parts are Reka roots that the platform cannot\n * disable: the saturation area and the hue slider render `<span role=\"slider\"\n * tabindex=\"0\">`, and `<fieldset disabled>` reaches only `<input>`, `<button>`,\n * `<select>` and `<textarea>`. Measured in jsdom, both still took an arrow key\n * inside a disabled group and moved the colour — while the hex `<input>` beside\n * them went properly inert, so the picker was half unavailable and half not.\n *\n * Read off the DOM rather than taken from the Field context, which publishes no\n * `disabled` on purpose — see `../../lib/ancestor-disabled.ts`.\n */\nconst root = useTemplateRef<HTMLElement>(\"root\");\nconst groupDisabled = useAncestorDisabled(() => root.value);\n\n// `id` and `aria-describedby` arrive as fallthrough attrs rather than props, so\n// they are handed in as this caller's own values: a caller who sets either\n// still beats the row, and the row's description is merged into theirs rather\n// than replacing it. `name`, `required` and `invalid` are absent because this\n// component has no prop for any of them — the row's answer stands unopposed.\nconst field = useFieldControl(() => ({\n id: attrs.id as string | undefined,\n describedBy: attrs[\"aria-describedby\"] as string | undefined,\n // The fieldset beats the prop in both directions, exactly as it does for the\n // hex input inside this very control.\n disabled: groupDisabled.value ? true : props.disabled,\n}));\n\n/**\n * The half of the resolved bag the group takes, and the reason there are two\n * halves at all.\n *\n * A row describes *the picker*, and no one of the four parts is the picker —\n * the colour is authored across all of them — so the group around them is what\n * carries the identity and the description, exactly as a `data-testid` does.\n *\n * `name` and `aria-required` cannot follow them there. ARIA allows neither on\n * `role=\"group\"`, and `aria-allowed-attr` is a WCAG 4.1.2 rule\n * `e2e/accessibility.e2e.ts` runs over every docs page, so shipping the whole\n * bag here would turn that gate red. They go to the hex field instead, which is\n * the picker's one real form control: a native `<input>` holding exactly the\n * `#rrggbb` this component emits, so — unlike NumberField's spinbutton, which\n * holds a *formatted* number and would post its grouping separators — a `name`\n * on it submits the model value itself. `aria-invalid` rides along with them,\n * because a state announced on entering a group is a state most readers meet\n * once, while the field is where an error about the value is actually read.\n */\nconst groupFieldAttrs = computed(() =>\n optional({ id: field.id, \"aria-describedby\": field.attrs[\"aria-describedby\"] }),\n);\n\n// Both thumbs sit on a surface whose colour is the value being chosen, so they\n// have to read against white, against black and against every hue in between. A\n// single-colour thumb cannot: the light ring vanishes on a pale fill and the\n// dark one vanishes on a dark fill. The pair — a `background` band inside a\n// `foreground` hairline — always leaves one of the two in contrast.\nconst THUMB =\n \"block size-6 rounded-full border-2 border-background bg-transparent ring-1 ring-foreground shadow-sm \" +\n \"transition-transform duration-fast ease-spring hover:scale-110 active:scale-95 \" +\n \"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo \" +\n \"data-[disabled]:pointer-events-none\";\n</script>\n\n<template>\n <div\n ref=\"root\"\n v-bind=\"{ ...groupAttrs, ...groupFieldAttrs }\"\n role=\"group\"\n :aria-label=\"ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :aria-disabled=\"field.disabled || undefined\"\n :data-disabled=\"field.disabled || undefined\"\n :class=\"\n cn(\n 'flex w-full max-w-xs flex-col gap-3',\n // No `opacity` on the group, and the split below is the whole reason.\n // A dim here ran over everything the picker holds, the hex among it:\n // measured on the built site, `opacity-50` put the hex value at 3.06:1\n // — the same 3.08:1 the text input's own dim produced before it was\n // drained, and the same failure axe does not raise because it exempts\n // a disabled control under 1.4.3.\n //\n // So the parts part ways. The saturation area drains to the neutral\n // well like every other unavailable control (its gradient is this\n // component's own inline binding, so unavailability can withhold it);\n // the hue track and the preset swatches keep a dim because their fills\n // are data colours no token can express; and the hex field takes the\n // drained fill, muted text and slackened rim every other control in\n // the library wears, because it is text and it is the one thing a\n // reader still needs from a picker they cannot use.\n field.disabled && 'cursor-not-allowed',\n attrs.class as string,\n )\n \"\n >\n <!-- Saturation across, brightness up. `style` is Reka's own gradient for\n those two axes at the current hue — the picked colour rendered as a\n surface, which is data and not a token. -->\n <ColorAreaRoot\n v-slot=\"{ style }\"\n :model-value=\"current\"\n color-space=\"hsb\"\n x-channel=\"saturation\"\n y-channel=\"brightness\"\n :disabled=\"field.disabled\"\n @update:model-value=\"applyFromPart\"\n @change-end=\"commitCurrent\"\n >\n <!-- Reka gives this `role=\"application\"`, which hands every key straight\n to the area rather than to the screen reader's own navigation. That\n only works if the region says what it is, so it is named here; the\n thumb inside carries the per-axis values.\n\n Both `aria-roledescription`s below replace one Reka writes in English\n inside its own render function. They reach the DOM as fallthrough\n attributes, which Vue merges last, so each is a replacement rather\n than a second phrase — and removing one falls back to Reka's English\n rather than to nothing, which is the failure no test of Loom's own\n strings would catch.\n\n `aria-valuetext` on the thumb is the third of them and the one a\n reader hears most, since it is re-announced on every arrow key.\n `areaValueText` explains why replacing it does not risk contradicting\n the `aria-valuenow` beside it. -->\n <!-- The gradient is Loom's own inline binding, so unavailability can\n take the surface back: with the picker disabled the gradient is\n withheld and the area falls to the neutral well, drained like every\n other unavailable control rather than faded through. -->\n <ColorAreaArea\n :style=\"field.disabled ? undefined : style\"\n :aria-label=\"text.area\"\n :aria-roledescription=\"text.areaRoleDescription\"\n class=\"relative h-40 w-full rounded-md border border-border bg-background data-[disabled]:bg-muted\"\n @keydown=\"onAreaKeydown\"\n >\n <ColorAreaThumb\n :aria-label=\"text.areaThumb\"\n :aria-roledescription=\"text.areaThumbRoleDescription\"\n :aria-valuetext=\"areaValueText\"\n :class=\"THUMB\"\n />\n </ColorAreaArea>\n </ColorAreaRoot>\n\n <ColorSliderRoot\n :model-value=\"current\"\n channel=\"hue\"\n color-space=\"hsb\"\n :disabled=\"field.disabled\"\n class=\"relative flex w-full touch-none items-center py-1\"\n @update:model-value=\"applyFromPart\"\n @change-end=\"commitCurrent\"\n >\n <!-- The one dim left on a *tokenless* surface, and it stays because it\n must: Reka paints the spectrum as an inline `style` inside its own\n component (verified against its source — the track's background\n never passes through a slot), and no class can outrank an inline\n style. The hue under the thumb is data, not chrome, so draining it\n to a token would be lying about what is there. -->\n <ColorSliderTrack\n class=\"relative h-3 w-full grow rounded-full border border-border data-[disabled]:opacity-50\"\n />\n <!-- Reka names this from its channel — \"Hue\" — so the binding replaces\n that rather than adding to it. -->\n <ColorSliderThumb :aria-label=\"text.hue\" :class=\"THUMB\" />\n </ColorSliderRoot>\n\n <!-- The hex is the picker's text channel, so it is always on screen and it\n is the edit surface too. Typing writes the model on blur and on Enter\n rather than per keystroke, so a half-typed value is never emitted and\n text that will not parse is reverted to the current colour; the arrow\n keys nudge it a step at a time. Both paths arrive here already at a\n boundary, which is why the field's update is itself the checkpoint. -->\n <ColorFieldRoot\n :model-value=\"current\"\n :disabled=\"field.disabled\"\n class=\"flex h-9 items-center gap-2 rounded-md border border-input bg-background px-3 text-sm text-foreground transition-[color,background-color,border-color,box-shadow] duration-fast ease-out focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-ring focus-within:shadow-halo data-[disabled]:cursor-not-allowed data-[disabled]:border-border data-[disabled]:bg-muted data-[disabled]:text-muted-foreground\"\n @update:model-value=\"onFieldCommit\"\n >\n <!-- `label` is Reka's own documented prop for this, so it is set rather\n than bound over: left unset the swatch names itself through a\n `getColorName` that answers \"vibrant red\" in English and is not\n exported for Loom to delegate to. The roledescription is a\n fallthrough replacement, as on the area above. -->\n <ColorSwatch\n :color=\"current\"\n :label=\"text.swatch({ color: current })\"\n :aria-roledescription=\"text.swatchRoleDescription\"\n :style=\"{ backgroundColor: current }\"\n class=\"size-6 shrink-0 rounded-sm border border-border\"\n />\n <!-- The row's three form-control answers, which the group cannot hold —\n see `groupFieldAttrs`. `aria-label` stays: it names the *field*, not\n the picker, and a row's label never reached this element anyway. -->\n <ColorFieldInput\n :aria-label=\"text.hex\"\n :name=\"field.name\"\n :aria-required=\"field.required || undefined\"\n :aria-invalid=\"field.invalid || undefined\"\n class=\"tabular min-w-0 flex-1 self-stretch bg-transparent outline-none disabled:cursor-not-allowed\"\n />\n </ColorFieldRoot>\n\n <!-- One tab stop, not one per swatch: Reka's swatch picker is a listbox\n with roving focus, so arrows move between presets and Enter or Space\n chooses. `replace` rather than Reka's default `toggle`: a row of\n presets is a choice, not a set of switches, so clicking the one\n already showing must re-affirm the colour rather than clear it to\n nothing. `onPresetPick`'s string check holds the same line from the\n other side, for the empty selection `toggle` would emit. -->\n <ColorSwatchPickerRoot\n v-if=\"presets.length > 0\"\n :model-value=\"current\"\n :disabled=\"field.disabled\"\n :aria-disabled=\"field.disabled || undefined\"\n selection-behavior=\"replace\"\n :aria-label=\"text.presets\"\n class=\"flex flex-wrap gap-2 data-[disabled]:opacity-50\"\n @update:model-value=\"onPresetPick\"\n >\n <!-- Each item names itself from Reka's English `getColorName` unless\n this binding replaces it, so a row of presets is where that\n vocabulary leaks in bulk. -->\n <!-- Each swatch's fill is a preset the host supplied, bound inline right\n here — data colours no token can express (the same constraint as\n the hue track above). Withholding the fill when unavailable would\n blank the palette instead of draining chrome around it, so the row\n keeps the dim: the one honest treatment for content that *is*\n colour. -->\n <ColorSwatchPickerItem\n v-for=\"preset in presets\"\n :key=\"preset\"\n :value=\"preset\"\n :disabled=\"field.disabled\"\n :aria-label=\"text.swatch({ color: preset })\"\n :style=\"{ backgroundColor: preset }\"\n class=\"size-6 cursor-pointer rounded-sm border border-border transition-transform duration-fast ease-spring hover:scale-110 active:scale-95 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo aria-selected:ring-2 aria-selected:ring-primary aria-selected:ring-offset-2 aria-selected:ring-offset-background data-[disabled]:pointer-events-none\"\n />\n </ColorSwatchPickerRoot>\n </div>\n</template>\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Combobox.js","names":[],"sources":["../../../../../packages/primitives/combobox/src/Combobox.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { ComboboxLabels } from \"@ecoma-io/loom-labels\";\nimport { cva } from \"class-variance-authority\";\n\n/**\n\n/**\n * Loom's English, co-located with the component so it tree-shakes with it, and\n * exported so a host can build a partial vocabulary against the real thing.\n */\nexport const COMBOBOX_LABELS: ComboboxLabels = {\n trigger: \"Show options\",\n empty: \"No results\",\n count: ({ count }) => `${String(count)} selected`,\n overflow: ({ hidden }) => `+${String(hidden)} more`,\n};\n\n/**\n * One row of the list. `value` is what the model carries; `label` is what a\n * reader sees, what the filter matches, and what the input shows once the row\n * is chosen.\n *\n * Identical to `SelectOption` today, and deliberately not the same\n * declaration: the two surfaces are independent, and the first field either\n * one grows — a secondary line here, a group key there — is a field the other\n * should not inherit by accident. A shared alias would make that change look\n * free when it is not.\n */\nexport interface ComboboxOption {\n /** The value bound to `v-model` when this row is chosen. Unique within the list. */\n value: string;\n /** The text shown on the row, matched by the filter, and put in the input once chosen. */\n label: string;\n /** Present but unchoosable — visible, skipped by the keyboard, unclickable. */\n disabled?: boolean;\n}\n\n/**\n * The control's height scale. It matches the text input and Select scales\n * exactly, so a form row mixing a Combobox beside either never comes out\n * uneven — which is why reaching past `size` for an `h-*` class is always the\n * wrong fix.\n */\nexport type ComboboxSize = \"sm\" | \"md\" | \"lg\";\n\nexport const comboboxVariants = cva(\n [\n \"flex w-full items-center gap-2 rounded-md border border-input bg-background text-foreground\",\n \"transition-[color,background-color,border-color,box-shadow] duration-fast ease-out\",\n // The focusable node is the input *inside* this box, so the ring is drawn\n // with `focus-within` rather than `focus-visible` — the same choice\n // TextField makes for the same reason, and what keeps the two controls\n // lighting up identically in a form row.\n \"focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-ring\",\n ],\n {\n // `satisfies` keeps the two halves honest: the union above is the name a\n // consumer imports and the documentation prints, the map below is the\n // classes. Adding a member to one and not the other stops compiling.\n variants: {\n size: {\n sm: \"h-8 px-2.5 text-xs\",\n md: \"h-9 px-3 text-sm\",\n lg: \"h-11 px-4 text-base\",\n } satisfies Record<ComboboxSize, string>,\n },\n defaultVariants: { size: \"md\" },\n },\n);\n\n/**\n * The same three numbers as a floor rather than as a fixed height, for the\n * multi-select box only.\n *\n * A box holding tokens is sized by its content, which is TagsInput's call and\n * the reason its field is `min-h-9`. What keeps that from turning into an\n * unbounded control here is `visibleValues`: the token row never wraps, so in\n * practice the box resolves to exactly the height above and a multi-select\n * still lines up with the single-select beside it. The `h-auto` that goes with\n * it in the template is what releases the fixed height `comboboxVariants`\n * already set — Tailwind's merge resolves the two, `min-h-*` does not.\n */\nconst multiSelectHeights = {\n sm: \"min-h-8\",\n md: \"min-h-9\",\n lg: \"min-h-11\",\n} satisfies Record<ComboboxSize, string>;\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useId, watch } from \"vue\";\nimport {\n ComboboxRoot,\n ComboboxAnchor,\n ComboboxInput,\n ComboboxTrigger,\n ComboboxPortal,\n ComboboxContent,\n ComboboxViewport,\n ComboboxItem,\n ComboboxItemIndicator,\n ComboboxEmpty,\n} from \"reka-ui\";\nimport { Check, ChevronDown } from \"@lucide/vue\";\nimport Chip from \"@ecoma-io/loom-chip\";\nimport { cn } from \"@ecoma-io/loom-core\";\nimport { listStaggerDelay } from \"@ecoma-io/loom-core\";\nimport { useSplitAttrs } from \"@ecoma-io/loom-core\";\nimport { useFieldControl } from \"@ecoma-io/loom-labels\";\nimport { useLabels, type LabelOverrides } from \"@ecoma-io/loom-labels\";\nimport { optional } from \"@ecoma-io/loom-core\";\n\n/**\n * Combobox — a text input that narrows a list as you type, for the list too\n * long to scan. Countries, currencies, repositories, people: anywhere a reader\n * knows roughly what they are looking for and would rather type three letters\n * than scroll past two hundred rows.\n *\n * Its neighbour is `Select`, and the boundary is the length of the list rather\n * than the shape of the control. Three to fifteen rows a reader can read\n * through belong in a Select — a search box over eight options is a keystroke\n * charged for nothing. Two to five options that should all be visible at once\n * belong in a segmented control. Past roughly fifteen, searching beats\n * scrolling and this is the control that offers it.\n *\n * Built on Reka UI's Combobox, which supplies the editable-combobox semantics:\n * the `role=\"combobox\"` input wired to the listbox by `aria-expanded` and\n * `aria-controls`, `aria-autocomplete=\"list\"`, and the active row tracked by\n * `aria-activedescendant` while real focus stays in the input. That last part\n * is the one genuine behavioural difference from Select, which moves focus\n * onto the row itself — a combobox cannot, because the reader is still typing.\n *\n * Inside a [Field](../Field/Field.vue) it wires itself: the row's id, the id of\n * its hint or error line, `required`, `invalid`, `disabled` and the name the\n * chosen value is submitted under all arrive through `useFieldControl()`, so\n * `<Field label=\"Country\" error=\"…\"><Combobox … /></Field>` needs no attributes\n * at the call site. Both booleans below still win over the row when they are\n * set, in both directions — which is why they default to `undefined` rather\n * than `false`.\n *\n * A row's `readonly` is deliberately ignored. The text in the box is not the\n * value — it is the chosen option's label, rewritten on every choice — so a\n * `readonly` input here would freeze a caption rather than protect a value,\n * while the list underneath still opened on click. A choice nobody may change\n * is a disabled Combobox, or the label rendered as text.\n *\n * `multiple` turns it into a many-of-many picker. The chosen values render as\n * tokens in the box — the same `Chip` a\n * [TagsInput](../TagsInput/TagsInput.vue) commits its values to, so a selection\n * looks the same wherever a form shows one — and the input goes back to being\n * only a search box. The tokens are **inert**, deliberately: the list is where\n * a choice is made and where it is unmade, so the control stays the single Tab\n * stop it is in single-select, and a value hidden behind the overflow count is\n * reachable by exactly the same gesture as a visible one. That is the one place\n * this diverges from TagsInput, whose tokens carry their own remove control\n * because it has no list to send a reader back to.\n */\nconst props = withDefaults(\n defineProps<{\n /**\n * The chosen option's `value`, or every chosen value when `multiple`.\n *\n * The union is one prop rather than a generic component, and the invariant\n * is the mode: single-select emits and accepts a `string` and never an\n * array, multi-select an array and never a bare string. A generic would\n * express that in the type system and cost more than it buys — it would\n * print a conditional type in the generated API table below, and it would\n * break `InstanceType<typeof Combobox>`, which is how a consumer types a\n * template ref.\n */\n modelValue?: string | string[] | undefined;\n /** The rows, in the order they are shown. */\n options: ComboboxOption[];\n /** Lets several rows be chosen at once: chosen rows toggle instead of closing the list, and the box shows the selection as tokens. */\n multiple?: boolean;\n /**\n * How many tokens the box shows before the rest collapse into a count.\n *\n * The box must not grow with the selection — it sits in a form row beside\n * controls on a fixed height scale — so past this many the tail becomes one\n * `labels.overflow` summary: five chosen shows three and \"+2 more\", fifty\n * shows three and \"+47 more\". Raise it for a wide box; the row never wraps,\n * so a number the box has no room for is a number that truncates.\n */\n visibleValues?: number;\n /** Shown in the empty input, before anything is typed or chosen. */\n placeholder?: string;\n /** Shown as a row of its own when the filter matches nothing. Defaults to `labels.empty`, so say what was searched for rather than restating the default in a second language. */\n emptyMessage?: string | undefined;\n /** Unavailable: dims the control, refuses to open and refuses to take text. Unset defers to a wrapping Field. */\n disabled?: boolean | undefined;\n /** Error state: paints the destructive border and ring, and sets `aria-invalid`. Unset defers to a wrapping Field's `error`. */\n invalid?: boolean | undefined;\n /** Control height. It shares the text input scale so mixed form rows stay aligned. */\n size?: ComboboxSize;\n /**\n * Filter `options` against the typed text. Turn it off when the host is\n * producing the list itself — from a server, in response to\n * `update:query` — so a result that does not literally contain what was\n * typed is not then hidden a second time by a filter running underneath it.\n */\n filter?: boolean;\n /**\n * Names for the two strings this control supplies itself, as any subset of\n * `ComboboxLabels` — the rest stay as the host's `provideLoomLabels`\n * vocabulary left them, and then as Loom's English.\n *\n * This is the per-instance correction, not the place to localise an\n * application. `emptyMessage` is the shorter way to reach `empty` for one\n * box; this is what reaches `trigger`.\n */\n labels?: LabelOverrides<ComboboxLabels>;\n }>(),\n {\n // `modelValue: undefined` is load-bearing rather than redundant: paired\n // with `optional()` below it is what keeps the uncontrolled third state\n // reachable, instead of pinning the control to a value nobody chose.\n modelValue: undefined,\n multiple: false,\n // Three, and the number is a judgement rather than a measurement: two\n // tokens plus a count reads as a control that shows almost nothing, and\n // four leaves a `md` box no room to type in at the default width. It is a\n // prop because the right answer is the box's width, which only the caller\n // knows.\n visibleValues: 3,\n // No English default here any more. The wording moved into `COMBOBOX_LABELS`\n // so a host can set it once for the whole application rather than on every\n // box, and an absent prop is what lets the resolved label through.\n emptyMessage: undefined,\n // Not `false`, for either. `false` is a caller saying \"this control is fine\n // / enabled even though its row is not\"; absent is a caller saying nothing,\n // and only `undefined` survives to mean that past Vue's\n // absent-Boolean-casts-to-false rule — see TextField.vue, which carries the\n // full reasoning.\n disabled: undefined,\n invalid: undefined,\n size: \"md\",\n filter: true,\n },\n);\n\nconst emit = defineEmits<{\n /** The chosen option's `value` — or the whole chosen list, when `multiple`. Single-select fires once per choice and the list closes with it; multi-select fires once per toggle and the list stays open. */\n \"update:modelValue\": [value: string | string[]];\n /** The text now in the input — as the reader types, and again when a choice puts its label there. */\n \"update:query\": [query: string];\n}>();\n\n// `text`, not `labels`: the prop of that name is one of the three sources this\n// resolves, and a template reading the raw prop would be reading the overrides\n// rather than the answer.\nconst text = useLabels(\"combobox\", COMBOBOX_LABELS, () => props.labels);\n\nconst query = ref(\"\");\n\n/**\n * The stagger is the list's *reveal*, and re-filtering is not a reveal. This\n * is true from the moment the list opens until the first keystroke, after\n * which every row arrives immediately.\n *\n * Two things go wrong without it. A delay recomputed per keystroke makes the\n * list feel like it is rebuilding under the reader's fingers — the opposite of\n * what a filter is for. And raising `animation-delay` on a row that survived\n * the keystroke rewinds its entrance: the row is still mounted, so the\n * animation is not restarted, it is re-timed, and a row that had finished\n * fading in drops back to half-opacity. Going the other way — stagger to `0ms`\n * — only ever fast-forwards, which is why this flag falls and does not rise\n * again until the content has unmounted and remounted with the next open.\n */\nconst revealing = ref(true);\n\nconst countId = useId();\n\n/**\n * The multi-select's own copy of the selection, and the reason it keeps one:\n * the tokens have to render whether or not the host bound `v-model`.\n *\n * Left uncontrolled, `modelValue` stays `undefined` while Reka manages the\n * choice internally — which is the third state `optional()` exists to preserve\n * — so a trigger reading the prop would sit empty while the list showed three\n * checked rows. This mirrors rather than drives: it is never fed back into\n * Reka, so nothing about the uncontrolled control changes.\n *\n * Seeded from the prop rather than sanitised, for TagsInput's reason: a list\n * the host already holds is the host's to hold.\n */\nconst selected = ref<string[]>(Array.isArray(props.modelValue) ? [...props.modelValue] : []);\nwatch(\n () => props.modelValue,\n (next) => {\n if (Array.isArray(next)) selected.value = [...next];\n },\n // Shallow, deliberately: the contract is whole-list replacement — Reka hands\n // back the complete selection on every toggle and a host echoes it straight\n // back down — so in-place mutation is not a case this mirror owes anyone.\n);\n\n/**\n * The chosen values as the box shows them, and the fallback is the point: a\n * host driving `options` from a search hands back only the rows matching the\n * current query, so a value chosen from an earlier one has no option to look\n * its label up in. Falling back to the value keeps the token on screen — a\n * chosen value that vanished from the trigger while it was still in the model\n * would be the control lying about what it holds.\n */\nconst tokens = computed(() =>\n selected.value.map((value) => ({\n value,\n label: props.options.find((option) => option.value === value)?.label ?? value,\n })),\n);\n\nconst visibleTokens = computed(() => tokens.value.slice(0, Math.max(0, props.visibleValues)));\nconst hiddenTokens = computed(() => tokens.value.length - visibleTokens.value.length);\n\n/**\n * What the input shows once a row is chosen. Without this Reka falls back to\n * the model value's own `toString()`, which would leave `en` in the box where\n * the reader picked \"English\".\n *\n * A multi-select shows nothing: the tokens are the selection, and the input\n * beside them is a search box. Reka calls this on close rather than on choose,\n * so the query the reader typed survives every toggle and one search can pick\n * several rows — which is the whole reason the list stays open.\n */\nfunction displayValue(value: unknown): string {\n if (props.multiple) return \"\";\n return props.options.find((option) => option.value === value)?.label ?? \"\";\n}\n\n/**\n * Reka hands back the whole selection on every toggle, never a delta, so the\n * emitted array is always the complete list — the same contract TagsInput's\n * `update:modelValue` carries, and the reason a host can assign it straight\n * back.\n */\nfunction onChoice(value: unknown): void {\n if (!props.multiple) {\n emit(\"update:modelValue\", String(value));\n return;\n }\n const values = Array.isArray(value) ? value.map(String) : [];\n selected.value = values;\n emit(\"update:modelValue\", values);\n}\n\nfunction onQuery(text: string): void {\n // Reka rewrites the input's text on its own account — once as the component\n // mounts, and again when a choice puts the chosen label back in the box —\n // and each of those arrives here as an update. Reporting a query that did\n // not change would have a host running the same search twice on mount, so\n // only a real change is passed on.\n if (text === query.value) return;\n query.value = text;\n revealing.value = false;\n emit(\"update:query\", text);\n}\n\n// The root renders no DOM node of its own, so fallthrough attributes would be\n// dropped on the floor. They go to the input, which is the element they\n// describe and the only one a name can land on — the chevron trigger already\n// carries Reka's own `aria-label`, and naming the control means naming the\n// `role=\"combobox\"` node.\n//\n// `class` is pulled out of that spread and merged through `cn()` onto the\n// anchor instead, because the anchor is the box a caller means when they pass\n// `w-64`. Spreading it alongside the anchor's own `:class` would only\n// concatenate the two lists — Vue's merge is generic, not Tailwind-aware — so\n// a caller's width would win or lose depending on which utility Tailwind\n// happened to emit last.\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: inputAttrs } = useSplitAttrs();\n\n// `id` and `aria-describedby` reach this control as fallthrough attrs rather\n// than props, so they are read off `attrs` and handed in as this caller's own\n// values — a caller who sets either still beats the row, and the row's\n// description is merged into theirs rather than replacing it. `name`,\n// `readonly` and `required` are absent from this object because there is no\n// prop to oppose the row with; the row's answer stands unopposed, which is\n// what is wanted.\n//\n// The multi-select's count joins that list rather than replacing anything: it\n// is one more thing this control says about itself, and it reads after the\n// caller's own description and before the row's message — the same\n// most-specific-first order `useFieldControl` applies one layer out. Wired\n// through `aria-describedby` rather than announced, which is TagsInput's call\n// for the same fact: it is heard on focus and on every return to the box, which\n// is when the question is asked, and a live region would speak the whole total\n// over the top of the `aria-selected` change the row itself already announces.\nconst field = useFieldControl(() => ({\n id: attrs.id as string | undefined,\n describedBy: [attrs[\"aria-describedby\"] as string | undefined, props.multiple ? countId : \"\"]\n .filter((id): id is string => typeof id === \"string\" && id.length > 0)\n .join(\" \"),\n disabled: props.disabled,\n invalid: props.invalid,\n}));\n\n// `name` is the one resolved key that does not travel with the bag, and here\n// it is a defect rather than a nicety: the bag lands on the input, and what\n// the input holds is the chosen option's *label*. A `name` on it would post\n// \"Viet Nam\" where the model carries `vn`. Reka submits the value itself\n// through a hidden control it renders from the root's own `name`, so that is\n// where the row's name goes. Everything else in the bag — the id, the merged\n// description, `aria-required`, `aria-invalid` — belongs on the\n// `role=\"combobox\"` node, which is the input.\nconst inputFieldAttrs = computed(() => {\n // Removed from a copy rather than listed positively, so a key added to the\n // resolved bag later reaches this input without anyone remembering to come\n // back here.\n const aria: Record<string, unknown> = { ...field.attrs };\n delete aria.name;\n return aria;\n});\n</script>\n\n<template>\n <!-- `open-on-click` and not `open-on-focus`: clicking the box is a reader\n asking to see the list, while focus arrives by Tab as often as by\n intent, and a list that unfolds over the next field every time someone\n tabs through a form is an obstruction. Typing opens it either way. -->\n <ComboboxRoot\n v-bind=\"optional({ modelValue, name: field.name })\"\n :multiple=\"multiple\"\n :disabled=\"field.disabled\"\n :ignore-filter=\"!filter\"\n open-on-click\n @update:model-value=\"onChoice\"\n @update:open=\"revealing = true\"\n >\n <ComboboxAnchor\n :data-disabled=\"field.disabled || undefined\"\n :data-invalid=\"field.invalid || undefined\"\n :class=\"\n cn(\n comboboxVariants({ size }),\n // A box holding tokens is sized by them — see `multiSelectHeights`.\n // `h-auto` is what releases the fixed height the variant just set;\n // Tailwind's merge resolves two `h-*` utilities and leaves a `min-h-*`\n // beside either of them alone.\n multiple && ['h-auto', multiSelectHeights[size], 'gap-1.5'],\n !field.invalid && 'focus-within:shadow-halo',\n field.invalid && 'border-destructive focus-within:outline-destructive',\n // The box holds the chosen value, so it is drained rather than\n // dimmed: `opacity-50` composited the input's text down to 3.06:1,\n // and what a reader needs from an unavailable Combobox is precisely\n // what it is set to. The neutral well says unavailable on its own —\n // the input's own `disabled:text-muted-foreground` below carries the\n // text to 4.67:1 over it.\n //\n // The hairline recedes with the fill, and that second channel is the\n // point: unavailable is a difference in *shape* as well as in colour,\n // so it survives a reader who cannot resolve `muted` from\n // `background`. This control has no read-only state to be told apart\n // from — see the docblock — so it takes the unavailable row alone.\n field.disabled && 'cursor-not-allowed border-border bg-muted text-muted-foreground',\n attrs.class as string,\n )\n \"\n >\n <!-- The selection, as the tokens a TagsInput commits its values to, so a\n chosen set looks the same wherever a form shows one. Inert on\n purpose: the list is where a value is chosen and where it is\n unchosen, which keeps the whole control one Tab stop and keeps a\n value behind the overflow count reachable by the same gesture as a\n visible one. -->\n <template v-if=\"multiple\">\n <Chip\n v-for=\"token in visibleTokens\"\n :key=\"token.value\"\n size=\"sm\"\n :disabled=\"field.disabled\"\n class=\"min-w-0 animate-fade-rise\"\n >\n {{ token.label }}\n </Chip>\n <!-- Not a token: it stands for values rather than being one, and a\n fourth pill saying \"+47 more\" would read as a forty-eighth\n choice. -->\n <span v-if=\"hiddenTokens > 0\" class=\"tabular shrink-0 text-small text-muted-foreground\">\n {{ text.overflow({ hidden: hiddenTokens }) }}\n </span>\n </template>\n\n <ComboboxInput\n v-bind=\"{ ...inputAttrs, ...inputFieldAttrs }\"\n :model-value=\"query\"\n :display-value=\"displayValue\"\n :placeholder=\"multiple && tokens.length > 0 ? undefined : placeholder\"\n class=\"min-w-6 flex-1 self-stretch bg-transparent outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:text-muted-foreground\"\n @update:model-value=\"onQuery\"\n />\n <!-- Reka takes this button out of the tab order itself, so the whole\n control is one Tab stop: the input. It also names it, in English —\n `aria-label=\"Show popup\"`, written inside its own render function\n with no prop to reach it by — and the binding below replaces that\n rather than competing with it, because Vue merges a fallthrough\n attribute onto the root vnode after the render function produced it.\n Removing it does not fall back to nothing; it falls back to Reka's\n English, which no test of Loom's own strings would catch. -->\n <ComboboxTrigger\n :aria-label=\"text.trigger\"\n class=\"group min-h-6 min-w-6 shrink-0 text-muted-foreground disabled:cursor-not-allowed\"\n >\n <ChevronDown\n class=\"h-4 w-4 transition-transform duration-fast ease-out group-data-[state=open]:rotate-180\"\n />\n </ComboboxTrigger>\n\n <!-- The size of the selection, and the only thing that carries it to a\n reader who cannot see the tokens: the visible row shows the first few\n and a count for the rest, and neither is announced. Reka publishes\n nothing of the sort — the listbox's `aria-multiselectable` says the\n control takes several values, never how many it holds. -->\n <span v-if=\"multiple\" :id=\"countId\" class=\"sr-only\">\n {{ text.count({ count: tokens.length }) }}\n </span>\n </ComboboxAnchor>\n\n <ComboboxPortal>\n <ComboboxContent\n position=\"popper\"\n :side-offset=\"6\"\n :class=\"\n cn(\n 'z-overlay max-h-72 min-w-[var(--reka-combobox-trigger-width)] overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md',\n // Each half of the motion is scoped to its own state, never\n // unconditional. Closing swaps the computed animation-name to\n // fade-fall's, which is what Reka's Presence reads: it holds the\n // panel mounted until that exit's animationend and only then takes\n // it away. Unconditional, a finished entrance animation sat on the\n // closed element and stranded it invisible over the page, eating\n // clicks.\n 'data-[state=open]:animate-fade-rise data-[state=closed]:animate-fade-fall',\n )\n \"\n >\n <ComboboxViewport class=\"p-1\">\n <!-- A filter that matches nothing has to say so. An empty popover\n reads as a broken one, and a screen reader is told nothing at\n all — so the message is a row inside the listbox rather than a\n caption beside it. `role=\"option\"` because a bare div is not a\n legitimate child of `role=\"listbox\"` and is skipped; disabled\n because it is a statement, not a choice. -->\n <ComboboxEmpty\n role=\"option\"\n aria-disabled=\"true\"\n class=\"animate-fade-rise px-3 py-1.5 text-sm text-muted-foreground\"\n >\n {{ emptyMessage ?? text.empty }}\n </ComboboxEmpty>\n\n <!-- Keyed by value rather than by index: a row that survives a\n keystroke keeps its DOM node, so its entrance animation is not\n re-run and the list settles instead of flashing. Keyed by index,\n every row below a filtered-out one would be reused for different\n content while the tail remounted — an animation playing on the\n wrong rows.\n\n `text-value` pins the filter to the label. Left off, Reka falls\n back to whatever the row happens to render, which is the label\n today and the label plus a badge, a hint or a count the first\n time a row grows one. -->\n <ComboboxItem\n v-for=\"(option, index) in options\"\n :key=\"option.value\"\n :value=\"option.value\"\n :text-value=\"option.label\"\n :disabled=\"option.disabled ?? false\"\n :style=\"{ animationDelay: revealing ? listStaggerDelay(index) : '0ms' }\"\n :class=\"\n cn(\n 'relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-3 py-1.5 pr-8 text-sm text-foreground outline-none',\n 'transition-colors duration-fast ease-out',\n 'animate-fade-rise',\n 'data-[highlighted]:bg-subtle',\n 'data-[state=checked]:bg-primary-muted data-[state=checked]:text-primary-text',\n // Inert, but still readable. `data-[disabled]:opacity-50` took\n // the label to 3.13:1 on the popover; the colour on the span\n // below leaves it at 5.76:1 and still visibly lighter than the\n // rows around it.\n 'data-[disabled]:pointer-events-none',\n )\n \"\n >\n <!-- The mute lives on this span rather than on the row, and it has\n to. `data-[disabled]:` sorts *before* `data-[state=checked]:`\n in Tailwind's variant order, so a disabled row that is also the\n chosen one would take `text-primary-text` from the container — and a\n container colour is only inherited. Declared here it wins\n whatever the row resolved to. -->\n <span :class=\"option.disabled && 'text-muted-foreground'\">{{ option.label }}</span>\n <ComboboxItemIndicator class=\"absolute right-2 inline-flex items-center\">\n <Check class=\"h-4 w-4\" />\n </ComboboxItemIndicator>\n </ComboboxItem>\n </ComboboxViewport>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n</template>\n"],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Combobox.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../../../packages/primitives/combobox/src/Combobox.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { ComboboxLabels } from \"@ecoma-io/loom-labels\";\nimport { cva } from \"class-variance-authority\";\n\n/**\n\n/**\n * Loom's English, co-located with the component so it tree-shakes with it, and\n * exported so a host can build a partial vocabulary against the real thing.\n */\nexport const COMBOBOX_LABELS: ComboboxLabels = {\n trigger: \"Show options\",\n empty: \"No results\",\n count: ({ count }) => `${String(count)} selected`,\n overflow: ({ hidden }) => `+${String(hidden)} more`,\n};\n\n/**\n * One row of the list. `value` is what the model carries; `label` is what a\n * reader sees, what the filter matches, and what the input shows once the row\n * is chosen.\n *\n * Identical to `SelectOption` today, and deliberately not the same\n * declaration: the two surfaces are independent, and the first field either\n * one grows — a secondary line here, a group key there — is a field the other\n * should not inherit by accident. A shared alias would make that change look\n * free when it is not.\n */\nexport interface ComboboxOption {\n /** The value bound to `v-model` when this row is chosen. Unique within the list. */\n value: string;\n /** The text shown on the row, matched by the filter, and put in the input once chosen. */\n label: string;\n /** Present but unchoosable — visible, skipped by the keyboard, unclickable. */\n disabled?: boolean;\n}\n\n/**\n * The control's height scale. It matches the text input and Select scales\n * exactly, so a form row mixing a Combobox beside either never comes out\n * uneven — which is why reaching past `size` for an `h-*` class is always the\n * wrong fix.\n */\nexport type ComboboxSize = \"sm\" | \"md\" | \"lg\";\n\nexport const comboboxVariants = cva(\n [\n \"flex w-full items-center gap-2 rounded-md border border-input bg-background text-foreground\",\n \"transition-[color,background-color,border-color,box-shadow] duration-fast ease-out\",\n // The focusable node is the input *inside* this box, so the ring is drawn\n // with `focus-within` rather than `focus-visible` — the same choice\n // TextField makes for the same reason, and what keeps the two controls\n // lighting up identically in a form row.\n \"focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-ring\",\n ],\n {\n // `satisfies` keeps the two halves honest: the union above is the name a\n // consumer imports and the documentation prints, the map below is the\n // classes. Adding a member to one and not the other stops compiling.\n variants: {\n size: {\n sm: \"h-8 px-2.5 text-xs\",\n md: \"h-9 px-3 text-sm\",\n lg: \"h-11 px-4 text-base\",\n } satisfies Record<ComboboxSize, string>,\n },\n defaultVariants: { size: \"md\" },\n },\n);\n\n/**\n * The same three numbers as a floor rather than as a fixed height, for the\n * multi-select box only.\n *\n * A box holding tokens is sized by its content, which is TagsInput's call and\n * the reason its field is `min-h-9`. What keeps that from turning into an\n * unbounded control here is `visibleValues`: the token row never wraps, so in\n * practice the box resolves to exactly the height above and a multi-select\n * still lines up with the single-select beside it. The `h-auto` that goes with\n * it in the template is what releases the fixed height `comboboxVariants`\n * already set — Tailwind's merge resolves the two, `min-h-*` does not.\n */\nconst multiSelectHeights = {\n sm: \"min-h-8\",\n md: \"min-h-9\",\n lg: \"min-h-11\",\n} satisfies Record<ComboboxSize, string>;\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, ref, useId, watch } from \"vue\";\nimport {\n ComboboxRoot,\n ComboboxAnchor,\n ComboboxInput,\n ComboboxTrigger,\n ComboboxPortal,\n ComboboxContent,\n ComboboxViewport,\n ComboboxItem,\n ComboboxItemIndicator,\n ComboboxEmpty,\n} from \"reka-ui\";\nimport { Check, ChevronDown } from \"@lucide/vue\";\nimport Chip from \"@ecoma-io/loom-chip\";\nimport { cn } from \"@ecoma-io/loom-core\";\nimport { listStaggerDelay } from \"@ecoma-io/loom-core\";\nimport { useSplitAttrs } from \"@ecoma-io/loom-core\";\nimport { useFieldControl } from \"@ecoma-io/loom-labels\";\nimport { useLabels, type LabelOverrides } from \"@ecoma-io/loom-labels\";\nimport { optional } from \"@ecoma-io/loom-core\";\n\n/**\n * Combobox — a text input that narrows a list as you type, for the list too\n * long to scan. Countries, currencies, repositories, people: anywhere a reader\n * knows roughly what they are looking for and would rather type three letters\n * than scroll past two hundred rows.\n *\n * Its neighbour is `Select`, and the boundary is the length of the list rather\n * than the shape of the control. Three to fifteen rows a reader can read\n * through belong in a Select — a search box over eight options is a keystroke\n * charged for nothing. Two to five options that should all be visible at once\n * belong in a segmented control. Past roughly fifteen, searching beats\n * scrolling and this is the control that offers it.\n *\n * Built on Reka UI's Combobox, which supplies the editable-combobox semantics:\n * the `role=\"combobox\"` input wired to the listbox by `aria-expanded` and\n * `aria-controls`, `aria-autocomplete=\"list\"`, and the active row tracked by\n * `aria-activedescendant` while real focus stays in the input. That last part\n * is the one genuine behavioural difference from Select, which moves focus\n * onto the row itself — a combobox cannot, because the reader is still typing.\n *\n * Inside a [Field](../Field/Field.vue) it wires itself: the row's id, the id of\n * its hint or error line, `required`, `invalid`, `disabled` and the name the\n * chosen value is submitted under all arrive through `useFieldControl()`, so\n * `<Field label=\"Country\" error=\"…\"><Combobox … /></Field>` needs no attributes\n * at the call site. Both booleans below still win over the row when they are\n * set, in both directions — which is why they default to `undefined` rather\n * than `false`.\n *\n * A row's `readonly` is deliberately ignored. The text in the box is not the\n * value — it is the chosen option's label, rewritten on every choice — so a\n * `readonly` input here would freeze a caption rather than protect a value,\n * while the list underneath still opened on click. A choice nobody may change\n * is a disabled Combobox, or the label rendered as text.\n *\n * `multiple` turns it into a many-of-many picker. The chosen values render as\n * tokens in the box — the same `Chip` a\n * [TagsInput](../TagsInput/TagsInput.vue) commits its values to, so a selection\n * looks the same wherever a form shows one — and the input goes back to being\n * only a search box. The tokens are **inert**, deliberately: the list is where\n * a choice is made and where it is unmade, so the control stays the single Tab\n * stop it is in single-select, and a value hidden behind the overflow count is\n * reachable by exactly the same gesture as a visible one. That is the one place\n * this diverges from TagsInput, whose tokens carry their own remove control\n * because it has no list to send a reader back to.\n */\nconst props = withDefaults(\n defineProps<{\n /**\n * The chosen option's `value`, or every chosen value when `multiple`.\n *\n * The union is one prop rather than a generic component, and the invariant\n * is the mode: single-select emits and accepts a `string` and never an\n * array, multi-select an array and never a bare string. A generic would\n * express that in the type system and cost more than it buys — it would\n * print a conditional type in the generated API table below, and it would\n * break `InstanceType<typeof Combobox>`, which is how a consumer types a\n * template ref.\n */\n modelValue?: string | string[] | undefined;\n /** The rows, in the order they are shown. */\n options: ComboboxOption[];\n /** Lets several rows be chosen at once: chosen rows toggle instead of closing the list, and the box shows the selection as tokens. */\n multiple?: boolean;\n /**\n * How many tokens the box shows before the rest collapse into a count.\n *\n * The box must not grow with the selection — it sits in a form row beside\n * controls on a fixed height scale — so past this many the tail becomes one\n * `labels.overflow` summary: five chosen shows three and \"+2 more\", fifty\n * shows three and \"+47 more\". Raise it for a wide box; the row never wraps,\n * so a number the box has no room for is a number that truncates.\n */\n visibleValues?: number;\n /** Shown in the empty input, before anything is typed or chosen. */\n placeholder?: string;\n /** Shown as a row of its own when the filter matches nothing. Defaults to `labels.empty`, so say what was searched for rather than restating the default in a second language. */\n emptyMessage?: string | undefined;\n /** Unavailable: dims the control, refuses to open and refuses to take text. Unset defers to a wrapping Field. */\n disabled?: boolean | undefined;\n /** Error state: paints the destructive border and ring, and sets `aria-invalid`. Unset defers to a wrapping Field's `error`. */\n invalid?: boolean | undefined;\n /** Control height. It shares the text input scale so mixed form rows stay aligned. */\n size?: ComboboxSize;\n /**\n * Filter `options` against the typed text. Turn it off when the host is\n * producing the list itself — from a server, in response to\n * `update:query` — so a result that does not literally contain what was\n * typed is not then hidden a second time by a filter running underneath it.\n */\n filter?: boolean;\n /**\n * Names for the two strings this control supplies itself, as any subset of\n * `ComboboxLabels` — the rest stay as the host's `provideLoomLabels`\n * vocabulary left them, and then as Loom's English.\n *\n * This is the per-instance correction, not the place to localise an\n * application. `emptyMessage` is the shorter way to reach `empty` for one\n * box; this is what reaches `trigger`.\n */\n labels?: LabelOverrides<ComboboxLabels>;\n }>(),\n {\n // `modelValue: undefined` is load-bearing rather than redundant: paired\n // with `optional()` below it is what keeps the uncontrolled third state\n // reachable, instead of pinning the control to a value nobody chose.\n modelValue: undefined,\n multiple: false,\n // Three, and the number is a judgement rather than a measurement: two\n // tokens plus a count reads as a control that shows almost nothing, and\n // four leaves a `md` box no room to type in at the default width. It is a\n // prop because the right answer is the box's width, which only the caller\n // knows.\n visibleValues: 3,\n // No English default here any more. The wording moved into `COMBOBOX_LABELS`\n // so a host can set it once for the whole application rather than on every\n // box, and an absent prop is what lets the resolved label through.\n emptyMessage: undefined,\n // Not `false`, for either. `false` is a caller saying \"this control is fine\n // / enabled even though its row is not\"; absent is a caller saying nothing,\n // and only `undefined` survives to mean that past Vue's\n // absent-Boolean-casts-to-false rule — see TextField.vue, which carries the\n // full reasoning.\n disabled: undefined,\n invalid: undefined,\n size: \"md\",\n filter: true,\n },\n);\n\nconst emit = defineEmits<{\n /** The chosen option's `value` — or the whole chosen list, when `multiple`. Single-select fires once per choice and the list closes with it; multi-select fires once per toggle and the list stays open. */\n \"update:modelValue\": [value: string | string[]];\n /** The text now in the input — as the reader types, and again when a choice puts its label there. */\n \"update:query\": [query: string];\n}>();\n\n// `text`, not `labels`: the prop of that name is one of the three sources this\n// resolves, and a template reading the raw prop would be reading the overrides\n// rather than the answer.\nconst text = useLabels(\"combobox\", COMBOBOX_LABELS, () => props.labels);\n\nconst query = ref(\"\");\n\n/**\n * The stagger is the list's *reveal*, and re-filtering is not a reveal. This\n * is true from the moment the list opens until the first keystroke, after\n * which every row arrives immediately.\n *\n * Two things go wrong without it. A delay recomputed per keystroke makes the\n * list feel like it is rebuilding under the reader's fingers — the opposite of\n * what a filter is for. And raising `animation-delay` on a row that survived\n * the keystroke rewinds its entrance: the row is still mounted, so the\n * animation is not restarted, it is re-timed, and a row that had finished\n * fading in drops back to half-opacity. Going the other way — stagger to `0ms`\n * — only ever fast-forwards, which is why this flag falls and does not rise\n * again until the content has unmounted and remounted with the next open.\n */\nconst revealing = ref(true);\n\nconst countId = useId();\n\n/**\n * The multi-select's own copy of the selection, and the reason it keeps one:\n * the tokens have to render whether or not the host bound `v-model`.\n *\n * Left uncontrolled, `modelValue` stays `undefined` while Reka manages the\n * choice internally — which is the third state `optional()` exists to preserve\n * — so a trigger reading the prop would sit empty while the list showed three\n * checked rows. This mirrors rather than drives: it is never fed back into\n * Reka, so nothing about the uncontrolled control changes.\n *\n * Seeded from the prop rather than sanitised, for TagsInput's reason: a list\n * the host already holds is the host's to hold.\n */\nconst selected = ref<string[]>(Array.isArray(props.modelValue) ? [...props.modelValue] : []);\nwatch(\n () => props.modelValue,\n (next) => {\n if (Array.isArray(next)) selected.value = [...next];\n },\n // Shallow, deliberately: the contract is whole-list replacement — Reka hands\n // back the complete selection on every toggle and a host echoes it straight\n // back down — so in-place mutation is not a case this mirror owes anyone.\n);\n\n/**\n * The chosen values as the box shows them, and the fallback is the point: a\n * host driving `options` from a search hands back only the rows matching the\n * current query, so a value chosen from an earlier one has no option to look\n * its label up in. Falling back to the value keeps the token on screen — a\n * chosen value that vanished from the trigger while it was still in the model\n * would be the control lying about what it holds.\n */\nconst tokens = computed(() =>\n selected.value.map((value) => ({\n value,\n label: props.options.find((option) => option.value === value)?.label ?? value,\n })),\n);\n\nconst visibleTokens = computed(() => tokens.value.slice(0, Math.max(0, props.visibleValues)));\nconst hiddenTokens = computed(() => tokens.value.length - visibleTokens.value.length);\n\n/**\n * What the input shows once a row is chosen. Without this Reka falls back to\n * the model value's own `toString()`, which would leave `en` in the box where\n * the reader picked \"English\".\n *\n * A multi-select shows nothing: the tokens are the selection, and the input\n * beside them is a search box. Reka calls this on close rather than on choose,\n * so the query the reader typed survives every toggle and one search can pick\n * several rows — which is the whole reason the list stays open.\n */\nfunction displayValue(value: unknown): string {\n if (props.multiple) return \"\";\n return props.options.find((option) => option.value === value)?.label ?? \"\";\n}\n\n/**\n * Reka hands back the whole selection on every toggle, never a delta, so the\n * emitted array is always the complete list — the same contract TagsInput's\n * `update:modelValue` carries, and the reason a host can assign it straight\n * back.\n */\nfunction onChoice(value: unknown): void {\n if (!props.multiple) {\n emit(\"update:modelValue\", String(value));\n return;\n }\n const values = Array.isArray(value) ? value.map(String) : [];\n selected.value = values;\n emit(\"update:modelValue\", values);\n}\n\nfunction onQuery(text: string): void {\n // Reka rewrites the input's text on its own account — once as the component\n // mounts, and again when a choice puts the chosen label back in the box —\n // and each of those arrives here as an update. Reporting a query that did\n // not change would have a host running the same search twice on mount, so\n // only a real change is passed on.\n if (text === query.value) return;\n query.value = text;\n revealing.value = false;\n emit(\"update:query\", text);\n}\n\n// The root renders no DOM node of its own, so fallthrough attributes would be\n// dropped on the floor. They go to the input, which is the element they\n// describe and the only one a name can land on — the chevron trigger already\n// carries Reka's own `aria-label`, and naming the control means naming the\n// `role=\"combobox\"` node.\n//\n// `class` is pulled out of that spread and merged through `cn()` onto the\n// anchor instead, because the anchor is the box a caller means when they pass\n// `w-64`. Spreading it alongside the anchor's own `:class` would only\n// concatenate the two lists — Vue's merge is generic, not Tailwind-aware — so\n// a caller's width would win or lose depending on which utility Tailwind\n// happened to emit last.\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: inputAttrs } = useSplitAttrs();\n\n// `id` and `aria-describedby` reach this control as fallthrough attrs rather\n// than props, so they are read off `attrs` and handed in as this caller's own\n// values — a caller who sets either still beats the row, and the row's\n// description is merged into theirs rather than replacing it. `name`,\n// `readonly` and `required` are absent from this object because there is no\n// prop to oppose the row with; the row's answer stands unopposed, which is\n// what is wanted.\n//\n// The multi-select's count joins that list rather than replacing anything: it\n// is one more thing this control says about itself, and it reads after the\n// caller's own description and before the row's message — the same\n// most-specific-first order `useFieldControl` applies one layer out. Wired\n// through `aria-describedby` rather than announced, which is TagsInput's call\n// for the same fact: it is heard on focus and on every return to the box, which\n// is when the question is asked, and a live region would speak the whole total\n// over the top of the `aria-selected` change the row itself already announces.\nconst field = useFieldControl(() => ({\n id: attrs.id as string | undefined,\n describedBy: [attrs[\"aria-describedby\"] as string | undefined, props.multiple ? countId : \"\"]\n .filter((id): id is string => typeof id === \"string\" && id.length > 0)\n .join(\" \"),\n disabled: props.disabled,\n invalid: props.invalid,\n}));\n\n// `name` is the one resolved key that does not travel with the bag, and here\n// it is a defect rather than a nicety: the bag lands on the input, and what\n// the input holds is the chosen option's *label*. A `name` on it would post\n// \"Viet Nam\" where the model carries `vn`. Reka submits the value itself\n// through a hidden control it renders from the root's own `name`, so that is\n// where the row's name goes. Everything else in the bag — the id, the merged\n// description, `aria-required`, `aria-invalid` — belongs on the\n// `role=\"combobox\"` node, which is the input.\nconst inputFieldAttrs = computed(() => {\n // Removed from a copy rather than listed positively, so a key added to the\n // resolved bag later reaches this input without anyone remembering to come\n // back here.\n const aria: Record<string, unknown> = { ...field.attrs };\n delete aria.name;\n return aria;\n});\n</script>\n\n<template>\n <!-- `open-on-click` and not `open-on-focus`: clicking the box is a reader\n asking to see the list, while focus arrives by Tab as often as by\n intent, and a list that unfolds over the next field every time someone\n tabs through a form is an obstruction. Typing opens it either way. -->\n <ComboboxRoot\n v-bind=\"optional({ modelValue, name: field.name })\"\n :multiple=\"multiple\"\n :disabled=\"field.disabled\"\n :ignore-filter=\"!filter\"\n open-on-click\n @update:model-value=\"onChoice\"\n @update:open=\"revealing = true\"\n >\n <ComboboxAnchor\n :data-disabled=\"field.disabled || undefined\"\n :data-invalid=\"field.invalid || undefined\"\n :class=\"\n cn(\n comboboxVariants({ size }),\n // A box holding tokens is sized by them — see `multiSelectHeights`.\n // `h-auto` is what releases the fixed height the variant just set;\n // Tailwind's merge resolves two `h-*` utilities and leaves a `min-h-*`\n // beside either of them alone.\n multiple && ['h-auto', multiSelectHeights[size], 'gap-1.5'],\n !field.invalid && 'focus-within:shadow-halo',\n field.invalid && 'border-destructive focus-within:outline-destructive',\n // The box holds the chosen value, so it is drained rather than\n // dimmed: `opacity-50` composited the input's text down to 3.06:1,\n // and what a reader needs from an unavailable Combobox is precisely\n // what it is set to. The neutral well says unavailable on its own —\n // the input's own `disabled:text-muted-foreground` below carries the\n // text to 4.67:1 over it.\n //\n // The hairline recedes with the fill, and that second channel is the\n // point: unavailable is a difference in *shape* as well as in colour,\n // so it survives a reader who cannot resolve `muted` from\n // `background`. This control has no read-only state to be told apart\n // from — see the docblock — so it takes the unavailable row alone.\n field.disabled && 'cursor-not-allowed border-border bg-muted text-muted-foreground',\n attrs.class as string,\n )\n \"\n >\n <!-- The selection, as the tokens a TagsInput commits its values to, so a\n chosen set looks the same wherever a form shows one. Inert on\n purpose: the list is where a value is chosen and where it is\n unchosen, which keeps the whole control one Tab stop and keeps a\n value behind the overflow count reachable by the same gesture as a\n visible one. -->\n <template v-if=\"multiple\">\n <Chip\n v-for=\"token in visibleTokens\"\n :key=\"token.value\"\n size=\"sm\"\n :disabled=\"field.disabled\"\n class=\"min-w-0 animate-fade-rise\"\n >\n {{ token.label }}\n </Chip>\n <!-- Not a token: it stands for values rather than being one, and a\n fourth pill saying \"+47 more\" would read as a forty-eighth\n choice. -->\n <span v-if=\"hiddenTokens > 0\" class=\"tabular shrink-0 text-small text-muted-foreground\">\n {{ text.overflow({ hidden: hiddenTokens }) }}\n </span>\n </template>\n\n <ComboboxInput\n v-bind=\"{ ...inputAttrs, ...inputFieldAttrs }\"\n :model-value=\"query\"\n :display-value=\"displayValue\"\n :placeholder=\"multiple && tokens.length > 0 ? undefined : placeholder\"\n class=\"min-w-6 flex-1 self-stretch bg-transparent outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:text-muted-foreground\"\n @update:model-value=\"onQuery\"\n />\n <!-- Reka takes this button out of the tab order itself, so the whole\n control is one Tab stop: the input. It also names it, in English —\n `aria-label=\"Show popup\"`, written inside its own render function\n with no prop to reach it by — and the binding below replaces that\n rather than competing with it, because Vue merges a fallthrough\n attribute onto the root vnode after the render function produced it.\n Removing it does not fall back to nothing; it falls back to Reka's\n English, which no test of Loom's own strings would catch. -->\n <ComboboxTrigger\n :aria-label=\"text.trigger\"\n class=\"group min-h-6 min-w-6 shrink-0 text-muted-foreground disabled:cursor-not-allowed\"\n >\n <ChevronDown\n class=\"h-4 w-4 transition-transform duration-fast ease-out group-data-[state=open]:rotate-180\"\n />\n </ComboboxTrigger>\n\n <!-- The size of the selection, and the only thing that carries it to a\n reader who cannot see the tokens: the visible row shows the first few\n and a count for the rest, and neither is announced. Reka publishes\n nothing of the sort — the listbox's `aria-multiselectable` says the\n control takes several values, never how many it holds. -->\n <span v-if=\"multiple\" :id=\"countId\" class=\"sr-only\">\n {{ text.count({ count: tokens.length }) }}\n </span>\n </ComboboxAnchor>\n\n <ComboboxPortal>\n <ComboboxContent\n position=\"popper\"\n :side-offset=\"6\"\n :class=\"\n cn(\n 'z-overlay max-h-72 min-w-[var(--reka-combobox-trigger-width)] overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md',\n // Each half of the motion is scoped to its own state, never\n // unconditional. Closing swaps the computed animation-name to\n // fade-fall's, which is what Reka's Presence reads: it holds the\n // panel mounted until that exit's animationend and only then takes\n // it away. Unconditional, a finished entrance animation sat on the\n // closed element and stranded it invisible over the page, eating\n // clicks.\n 'data-[state=open]:animate-fade-rise data-[state=closed]:animate-fade-fall',\n )\n \"\n >\n <ComboboxViewport class=\"p-1\">\n <!-- A filter that matches nothing has to say so. An empty popover\n reads as a broken one, and a screen reader is told nothing at\n all — so the message is a row inside the listbox rather than a\n caption beside it. `role=\"option\"` because a bare div is not a\n legitimate child of `role=\"listbox\"` and is skipped; disabled\n because it is a statement, not a choice. -->\n <ComboboxEmpty\n role=\"option\"\n aria-disabled=\"true\"\n class=\"animate-fade-rise px-3 py-1.5 text-sm text-muted-foreground\"\n >\n {{ emptyMessage ?? text.empty }}\n </ComboboxEmpty>\n\n <!-- Keyed by value rather than by index: a row that survives a\n keystroke keeps its DOM node, so its entrance animation is not\n re-run and the list settles instead of flashing. Keyed by index,\n every row below a filtered-out one would be reused for different\n content while the tail remounted — an animation playing on the\n wrong rows.\n\n `text-value` pins the filter to the label. Left off, Reka falls\n back to whatever the row happens to render, which is the label\n today and the label plus a badge, a hint or a count the first\n time a row grows one. -->\n <ComboboxItem\n v-for=\"(option, index) in options\"\n :key=\"option.value\"\n :value=\"option.value\"\n :text-value=\"option.label\"\n :disabled=\"option.disabled ?? false\"\n :style=\"{ animationDelay: revealing ? listStaggerDelay(index) : '0ms' }\"\n :class=\"\n cn(\n 'relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-3 py-1.5 pr-8 text-sm text-foreground outline-none',\n 'transition-colors duration-fast ease-out',\n 'animate-fade-rise',\n 'data-[highlighted]:bg-subtle',\n 'data-[state=checked]:bg-primary-muted data-[state=checked]:text-primary-text',\n // Inert, but still readable. `data-[disabled]:opacity-50` took\n // the label to 3.13:1 on the popover; the colour on the span\n // below leaves it at 5.76:1 and still visibly lighter than the\n // rows around it.\n 'data-[disabled]:pointer-events-none',\n )\n \"\n >\n <!-- The mute lives on this span rather than on the row, and it has\n to. `data-[disabled]:` sorts *before* `data-[state=checked]:`\n in Tailwind's variant order, so a disabled row that is also the\n chosen one would take `text-primary-text` from the container — and a\n container colour is only inherited. Declared here it wins\n whatever the row resolved to. -->\n <span :class=\"option.disabled && 'text-muted-foreground'\">{{ option.label }}</span>\n <ComboboxItemIndicator class=\"absolute right-2 inline-flex items-center\">\n <Check class=\"h-4 w-4\" />\n </ComboboxItemIndicator>\n </ComboboxItem>\n </ComboboxViewport>\n </ComboboxContent>\n </ComboboxPortal>\n </ComboboxRoot>\n</template>\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Command.js","names":[],"sources":["../../../../../packages/primitives/command/src/Command.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { CommandLabels, LabelOverrides } from \"@ecoma-io/loom-labels\";\n/**\n * One searchable item in the command list. `value` is what the host receives on\n * select; `label` is what the reader sees and what the filter matches against.\n *\n * Deliberately not `ComboboxOption` or `DropdownMenuEntry`: those shapes carry\n * `modelValue` and `separator` fields respectively, and either would be\n * dead weight here — a command is an action, not a value or a menu row.\n */\nexport interface CommandItem {\n /** Unique key. */\n value: string;\n /** Visible label. */\n label: string;\n /** Optional description shown below the label. */\n description?: string;\n /** Group heading this item belongs to. */\n group?: string;\n /** Disabled state. */\n disabled?: boolean;\n}\n\n/**\n * A named section heading above a run of items. Only rendered when the group\n * contains at least one item that survived the current filter.\n */\nexport interface CommandGroup {\n /** Group heading text. */\n heading: string;\n}\n\n/**\n * Loom's English, co-located with the component so it tree-shakes with it.\n * Every string a Command actually says is the chrome around the host's items,\n * so the whole slot is here and none of it hides in the template.\n */\nexport const COMMAND_LABELS: CommandLabels = {\n placeholder: \"Type to search…\",\n emptyMessage: \"No results found.\",\n searchLabel: \"Search\",\n resultSingular: \"{count} result available\",\n resultPlural: \"{count} results available\",\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, ref, useId, watch } from \"vue\";\nimport { cn } from \"@ecoma-io/loom-core\";\nimport { useLabels } from \"@ecoma-io/loom-labels\";\n\n/**\n * Command — a keyboard-driven command search, the universal \"Cmd+K\" pattern.\n *\n * A text input that narrows a grouped list as you type, for executing actions\n * rather than selecting values. Its neighbour is `Combobox`, which selects a\n * value for a form field; this control runs an action and has no `modelValue`.\n *\n * The two are one family in the same way a Combobox and a Select are: the same\n * surface vocabulary, the same tokens, the same keyboard model. What differs is\n * intent — \"open settings\" is not a value you could submit in a form — and that\n * intent shapes the API: `onSelect` rather than `v-model`.\n *\n * Built from native ARIA roles rather than Reka UI, because Reka ships no\n * Command primitive. The semantics follow the WAI-ARIA combobox pattern with\n * `aria-activedescendant` navigation: focus stays in the input while the\n * highlighted item moves, which is the only model that keeps typing fluid.\n *\n * `aria-expanded` is deliberately absent. The input is a fixed searchbox, not\n * a popover trigger, so it has no collapsed state to announce: the listbox is\n * visible on mount and returns on any interaction after Escape closes it.\n */\nconst props = withDefaults(\n defineProps<{\n /** The items to search through. */\n items: CommandItem[];\n /** Optional group definitions for section headers. */\n groups?: CommandGroup[];\n /** Controlled search query. */\n query?: string | undefined;\n /** Whether the command menu is open. */\n open?: boolean | undefined;\n /** Names for the strings this control supplies itself. */\n labels?: LabelOverrides<CommandLabels> | undefined;\n /** Accessible label by reference for the search input. */\n ariaLabelledby?: string;\n }>(),\n {\n query: undefined,\n open: undefined,\n labels: undefined,\n },\n);\n\nconst emit = defineEmits<{\n /** Fired when an item is selected. */\n select: [value: string];\n /** Fired when the query changes. */\n \"update:query\": [value: string];\n /** Fired when open state changes. */\n \"update:open\": [value: boolean];\n}>();\n\nconst resolvedLabels = useLabels(\"command\", COMMAND_LABELS, () => props.labels);\n\nconst inputId = useId();\nconst listboxId = useId();\nconst liveRegionId = useId();\n\n/**\n * The controlled/uncontrolled query. When `query` is bound from outside, the\n * prop wins; otherwise the component owns its own state.\n */\nconst internalQuery = ref(\"\");\nconst queryValue = computed(() => props.query ?? internalQuery.value);\n\nfunction setQuery(value: string): void {\n internalQuery.value = value;\n emit(\"update:query\", value);\n}\n\n/**\n * The controlled/uncontrolled open state. `true` when the listbox is visible.\n */\nconst internalOpen = ref(true);\nconst isOpen = computed(() => props.open ?? internalOpen.value);\n\nfunction setOpen(value: boolean): void {\n if (props.open !== undefined) {\n emit(\"update:open\", value);\n } else {\n internalOpen.value = value;\n }\n}\n\n/**\n * Bring the listbox back after Escape closed it. Focus never leaves the\n * search input, so without this a closed Command is a dead end — the only\n * escape, before this fix, was unmounting the component. Controlled mode is\n * untouched: the emit the host chose stays with the host, and this rewrites\n * only the fallback state a host never bound.\n */\nfunction restoreOpen(): void {\n if (props.open === undefined) internalOpen.value = true;\n}\n\n/**\n * The index of the highlighted item within the filtered list. Reset to `0`\n * whenever the query changes so the first match is always ready to select.\n */\nconst highlightedIndex = ref(0);\n\nconst listboxRef = ref<HTMLElement | null>(null);\n\n// Arrow-key focus never leaves the input (aria-activedescendant), so the\n// scrollable listbox must be tab-reachable itself — an overflow container no\n// keyboard can reach is the scrollable-region-focusable violation the harness\n// axe gate exists to catch. Scrolling the highlighted option into view is the\n// other half: an active item moved off-screen is navigation the user cannot\n// see. jsdom has no scrollIntoView, hence the optional call.\nwatch([highlightedIndex, isOpen], async () => {\n if (!isOpen.value) return;\n await nextTick();\n listboxRef.value?.querySelector(\"[data-active]\")?.scrollIntoView?.({ block: \"nearest\" });\n});\n\n/**\n * Items filtered by the current query. Case-insensitive substring match\n * across `label`, `description` and `value`.\n */\nconst filteredItems = computed(() => {\n const needle = queryValue.value.trim().toLowerCase();\n if (!needle) return props.items;\n return props.items.filter((item) => {\n const haystack = [item.label, item.description ?? \"\", item.value].join(\" \").toLowerCase();\n return haystack.includes(needle);\n });\n});\n\n/**\n * Items grouped for rendering. Each entry is either a group heading or a flat\n * item. Groups with no matching items are omitted entirely.\n */\ninterface GroupedEntry {\n kind: \"heading\";\n heading: string;\n groupId: string;\n}\n\ninterface GroupedItem {\n kind: \"item\";\n item: CommandItem;\n globalIndex: number;\n}\n\ntype RenderEntry = GroupedEntry | GroupedItem;\n\nconst renderEntries = computed<RenderEntry[]>(() => {\n if (filteredItems.value.length === 0) return [];\n\n const groupDefs = props.groups;\n if (!groupDefs || groupDefs.length === 0) {\n return filteredItems.value.map((item, i) => ({ kind: \"item\", item, globalIndex: i }));\n }\n\n const ungrouped: CommandItem[] = [];\n const grouped = new Map<string, CommandItem[]>();\n\n for (const item of filteredItems.value) {\n if (item.group) {\n const list = grouped.get(item.group) ?? [];\n list.push(item);\n grouped.set(item.group, list);\n } else {\n ungrouped.push(item);\n }\n }\n\n const entries: RenderEntry[] = [];\n let globalIndex = 0;\n\n for (const def of groupDefs) {\n const items = grouped.get(def.heading);\n if (!items || items.length === 0) continue;\n entries.push({\n kind: \"heading\",\n heading: def.heading,\n groupId: `${inputId}-group-${def.heading}`,\n });\n for (const item of items) {\n entries.push({ kind: \"item\", item, globalIndex });\n globalIndex++;\n }\n }\n\n for (const item of ungrouped) {\n entries.push({ kind: \"item\", item, globalIndex });\n globalIndex++;\n }\n\n return entries;\n});\n\n/**\n * The item list for the non-grouped case, used by keyboard navigation. Derived\n * from `renderEntries` so the two are always in sync.\n */\nconst flatItems = computed(() =>\n renderEntries.value.filter((e): e is GroupedItem => e.kind === \"item\"),\n);\n\n/**\n * Keep the highlight within bounds. A filter that removes items can strand the\n * index past the end.\n */\nwatch(flatItems, (items) => {\n if (highlightedIndex.value >= items.length) {\n highlightedIndex.value = Math.max(0, items.length - 1);\n }\n});\n\n/**\n * The documented reset: the highlight returns to the first match whenever the\n * query changes — whether the query came from typing or from a parent updating\n * the controlled `query` prop. Typing reaches this watcher through `setQuery`,\n * which is why onInput no longer resets the highlight itself.\n */\nwatch(queryValue, () => {\n highlightedIndex.value = 0;\n});\n\n/**\n * The total number of results, announced to assistive technology through a live\n * region. Changes only when the filtered set changes, not on every keystroke.\n */\nconst resultCount = computed(() => filteredItems.value.length);\nconst announcement = ref(\"\");\nwatch(resultCount, (count) => {\n const template =\n count === 1 ? resolvedLabels.value.resultSingular : resolvedLabels.value.resultPlural;\n announcement.value = template.replace(\"{count}\", String(count));\n});\n\n/**\n * The currently highlighted item, or `undefined` when the list is empty.\n */\nconst highlightedItem = computed(() => flatItems.value[highlightedIndex.value]?.item);\n\nfunction highlightUp(): void {\n if (flatItems.value.length === 0) return;\n highlightedIndex.value =\n highlightedIndex.value <= 0 ? flatItems.value.length - 1 : highlightedIndex.value - 1;\n}\n\nfunction highlightDown(): void {\n if (flatItems.value.length === 0) return;\n highlightedIndex.value =\n highlightedIndex.value >= flatItems.value.length - 1 ? 0 : highlightedIndex.value + 1;\n}\n\nfunction selectHighlighted(): void {\n const item = highlightedItem.value;\n if (!item || item.disabled) return;\n emit(\"select\", item.value);\n}\n\nfunction onKeydown(event: KeyboardEvent): void {\n // A closed Command returns on any interaction except the two that leave it —\n // Escape (the key that closed it, still under the same finger) and Tab\n // (which moves focus elsewhere). Keydown fires before the input event, so\n // typing also lands on an open list.\n if (!isOpen.value && event.key !== \"Escape\" && event.key !== \"Tab\") restoreOpen();\n switch (event.key) {\n case \"ArrowDown\": {\n event.preventDefault();\n highlightDown();\n break;\n }\n case \"ArrowUp\": {\n event.preventDefault();\n highlightUp();\n break;\n }\n case \"Enter\": {\n event.preventDefault();\n selectHighlighted();\n break;\n }\n case \"Escape\": {\n event.preventDefault();\n if (queryValue.value.length > 0) {\n setQuery(\"\");\n } else {\n setOpen(false);\n }\n break;\n }\n case \"Home\": {\n event.preventDefault();\n if (flatItems.value.length > 0) highlightedIndex.value = 0;\n break;\n }\n case \"End\": {\n event.preventDefault();\n if (flatItems.value.length > 0) highlightedIndex.value = flatItems.value.length - 1;\n break;\n }\n }\n}\n\nfunction onInput(event: Event): void {\n const value = (event.target as HTMLInputElement).value;\n setQuery(value);\n}\n\nfunction selectItem(item: CommandItem): void {\n if (item.disabled) return;\n emit(\"select\", item.value);\n}\n\nfunction itemId(index: number): string {\n return `${inputId}-option-${String(index)}`;\n}\n</script>\n\n<template>\n <div\n :data-state=\"isOpen ? 'open' : 'closed'\"\n :class=\"\n cn(\n 'rounded-md border border-border bg-popover text-popover-foreground shadow-md overflow-hidden',\n 'outline-none',\n )\n \"\n >\n <div class=\"flex items-center border-b border-border\">\n <input\n :id=\"inputId\"\n type=\"text\"\n role=\"searchbox\"\n autocomplete=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n aria-autocomplete=\"list\"\n :aria-controls=\"listboxId\"\n :aria-activedescendant=\"highlightedItem ? itemId(highlightedIndex) : undefined\"\n :aria-labelledby=\"ariaLabelledby\"\n :aria-label=\"ariaLabelledby ? undefined : resolvedLabels.searchLabel\"\n :placeholder=\"resolvedLabels.placeholder\"\n :value=\"queryValue\"\n class=\"w-full px-3 py-2 text-sm bg-transparent text-foreground border-none outline-none placeholder:text-muted-foreground\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n @focus=\"restoreOpen\"\n @click=\"restoreOpen\"\n />\n </div>\n <div\n v-if=\"isOpen\"\n :id=\"listboxId\"\n ref=\"listboxRef\"\n role=\"listbox\"\n tabindex=\"0\"\n :aria-labelledby=\"inputId\"\n class=\"max-h-[300px] overflow-y-auto p-1\"\n >\n <template\n v-for=\"entry in renderEntries\"\n :key=\"entry.kind === 'heading' ? entry.groupId : entry.item.value\"\n >\n <div\n v-if=\"entry.kind === 'heading'\"\n :id=\"entry.groupId\"\n role=\"presentation\"\n class=\"px-2 py-1.5 text-micro font-medium uppercase tracking-wide text-muted-foreground\"\n >\n {{ entry.heading }}\n </div>\n <!-- eslint-disable vuejs-accessibility/click-events-have-key-events, vuejs-accessibility/interactive-supports-focus, vuejs-accessibility/mouse-events-have-key-events -->\n <div\n v-else\n :id=\"itemId(entry.globalIndex)\"\n role=\"option\"\n :aria-selected=\"highlightedIndex === entry.globalIndex\"\n :aria-disabled=\"entry.item.disabled || undefined\"\n :data-active=\"highlightedIndex === entry.globalIndex || undefined\"\n class=\"flex flex-col gap-0.5 rounded-sm px-2 py-1.5 text-sm cursor-pointer outline-none transition-colors duration-fast ease-out data-[active]:bg-primary-muted data-[active]:text-primary-text\"\n @mouseenter=\"highlightedIndex = entry.globalIndex\"\n @click=\"selectItem(entry.item)\"\n >\n <span>{{ entry.item.label }}</span>\n <span v-if=\"entry.item.description\" class=\"text-xs text-muted-foreground\">\n {{ entry.item.description }}\n </span>\n </div>\n </template>\n\n <div\n v-if=\"filteredItems.length === 0\"\n role=\"option\"\n aria-selected=\"false\"\n aria-disabled=\"true\"\n class=\"px-2 py-6 text-center text-sm text-muted-foreground\"\n >\n {{ resolvedLabels.emptyMessage }}\n </div>\n </div>\n\n <span :id=\"liveRegionId\" role=\"status\" aria-live=\"polite\" class=\"sr-only\">\n {{ announcement }}\n </span>\n </div>\n</template>\n"],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"Command.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../../../packages/primitives/command/src/Command.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { CommandLabels, LabelOverrides } from \"@ecoma-io/loom-labels\";\n/**\n * One searchable item in the command list. `value` is what the host receives on\n * select; `label` is what the reader sees and what the filter matches against.\n *\n * Deliberately not `ComboboxOption` or `DropdownMenuEntry`: those shapes carry\n * `modelValue` and `separator` fields respectively, and either would be\n * dead weight here — a command is an action, not a value or a menu row.\n */\nexport interface CommandItem {\n /** Unique key. */\n value: string;\n /** Visible label. */\n label: string;\n /** Optional description shown below the label. */\n description?: string;\n /** Group heading this item belongs to. */\n group?: string;\n /** Disabled state. */\n disabled?: boolean;\n}\n\n/**\n * A named section heading above a run of items. Only rendered when the group\n * contains at least one item that survived the current filter.\n */\nexport interface CommandGroup {\n /** Group heading text. */\n heading: string;\n}\n\n/**\n * Loom's English, co-located with the component so it tree-shakes with it.\n * Every string a Command actually says is the chrome around the host's items,\n * so the whole slot is here and none of it hides in the template.\n */\nexport const COMMAND_LABELS: CommandLabels = {\n placeholder: \"Type to search…\",\n emptyMessage: \"No results found.\",\n searchLabel: \"Search\",\n resultSingular: \"{count} result available\",\n resultPlural: \"{count} results available\",\n};\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, nextTick, ref, useId, watch } from \"vue\";\nimport { cn } from \"@ecoma-io/loom-core\";\nimport { useLabels } from \"@ecoma-io/loom-labels\";\n\n/**\n * Command — a keyboard-driven command search, the universal \"Cmd+K\" pattern.\n *\n * A text input that narrows a grouped list as you type, for executing actions\n * rather than selecting values. Its neighbour is `Combobox`, which selects a\n * value for a form field; this control runs an action and has no `modelValue`.\n *\n * The two are one family in the same way a Combobox and a Select are: the same\n * surface vocabulary, the same tokens, the same keyboard model. What differs is\n * intent — \"open settings\" is not a value you could submit in a form — and that\n * intent shapes the API: `onSelect` rather than `v-model`.\n *\n * Built from native ARIA roles rather than Reka UI, because Reka ships no\n * Command primitive. The semantics follow the WAI-ARIA combobox pattern with\n * `aria-activedescendant` navigation: focus stays in the input while the\n * highlighted item moves, which is the only model that keeps typing fluid.\n *\n * `aria-expanded` is deliberately absent. The input is a fixed searchbox, not\n * a popover trigger, so it has no collapsed state to announce: the listbox is\n * visible on mount and returns on any interaction after Escape closes it.\n */\nconst props = withDefaults(\n defineProps<{\n /** The items to search through. */\n items: CommandItem[];\n /** Optional group definitions for section headers. */\n groups?: CommandGroup[];\n /** Controlled search query. */\n query?: string | undefined;\n /** Whether the command menu is open. */\n open?: boolean | undefined;\n /** Names for the strings this control supplies itself. */\n labels?: LabelOverrides<CommandLabels> | undefined;\n /** Accessible label by reference for the search input. */\n ariaLabelledby?: string;\n }>(),\n {\n query: undefined,\n open: undefined,\n labels: undefined,\n },\n);\n\nconst emit = defineEmits<{\n /** Fired when an item is selected. */\n select: [value: string];\n /** Fired when the query changes. */\n \"update:query\": [value: string];\n /** Fired when open state changes. */\n \"update:open\": [value: boolean];\n}>();\n\nconst resolvedLabels = useLabels(\"command\", COMMAND_LABELS, () => props.labels);\n\nconst inputId = useId();\nconst listboxId = useId();\nconst liveRegionId = useId();\n\n/**\n * The controlled/uncontrolled query. When `query` is bound from outside, the\n * prop wins; otherwise the component owns its own state.\n */\nconst internalQuery = ref(\"\");\nconst queryValue = computed(() => props.query ?? internalQuery.value);\n\nfunction setQuery(value: string): void {\n internalQuery.value = value;\n emit(\"update:query\", value);\n}\n\n/**\n * The controlled/uncontrolled open state. `true` when the listbox is visible.\n */\nconst internalOpen = ref(true);\nconst isOpen = computed(() => props.open ?? internalOpen.value);\n\nfunction setOpen(value: boolean): void {\n if (props.open !== undefined) {\n emit(\"update:open\", value);\n } else {\n internalOpen.value = value;\n }\n}\n\n/**\n * Bring the listbox back after Escape closed it. Focus never leaves the\n * search input, so without this a closed Command is a dead end — the only\n * escape, before this fix, was unmounting the component. Controlled mode is\n * untouched: the emit the host chose stays with the host, and this rewrites\n * only the fallback state a host never bound.\n */\nfunction restoreOpen(): void {\n if (props.open === undefined) internalOpen.value = true;\n}\n\n/**\n * The index of the highlighted item within the filtered list. Reset to `0`\n * whenever the query changes so the first match is always ready to select.\n */\nconst highlightedIndex = ref(0);\n\nconst listboxRef = ref<HTMLElement | null>(null);\n\n// Arrow-key focus never leaves the input (aria-activedescendant), so the\n// scrollable listbox must be tab-reachable itself — an overflow container no\n// keyboard can reach is the scrollable-region-focusable violation the harness\n// axe gate exists to catch. Scrolling the highlighted option into view is the\n// other half: an active item moved off-screen is navigation the user cannot\n// see. jsdom has no scrollIntoView, hence the optional call.\nwatch([highlightedIndex, isOpen], async () => {\n if (!isOpen.value) return;\n await nextTick();\n listboxRef.value?.querySelector(\"[data-active]\")?.scrollIntoView?.({ block: \"nearest\" });\n});\n\n/**\n * Items filtered by the current query. Case-insensitive substring match\n * across `label`, `description` and `value`.\n */\nconst filteredItems = computed(() => {\n const needle = queryValue.value.trim().toLowerCase();\n if (!needle) return props.items;\n return props.items.filter((item) => {\n const haystack = [item.label, item.description ?? \"\", item.value].join(\" \").toLowerCase();\n return haystack.includes(needle);\n });\n});\n\n/**\n * Items grouped for rendering. Each entry is either a group heading or a flat\n * item. Groups with no matching items are omitted entirely.\n */\ninterface GroupedEntry {\n kind: \"heading\";\n heading: string;\n groupId: string;\n}\n\ninterface GroupedItem {\n kind: \"item\";\n item: CommandItem;\n globalIndex: number;\n}\n\ntype RenderEntry = GroupedEntry | GroupedItem;\n\nconst renderEntries = computed<RenderEntry[]>(() => {\n if (filteredItems.value.length === 0) return [];\n\n const groupDefs = props.groups;\n if (!groupDefs || groupDefs.length === 0) {\n return filteredItems.value.map((item, i) => ({ kind: \"item\", item, globalIndex: i }));\n }\n\n const ungrouped: CommandItem[] = [];\n const grouped = new Map<string, CommandItem[]>();\n\n for (const item of filteredItems.value) {\n if (item.group) {\n const list = grouped.get(item.group) ?? [];\n list.push(item);\n grouped.set(item.group, list);\n } else {\n ungrouped.push(item);\n }\n }\n\n const entries: RenderEntry[] = [];\n let globalIndex = 0;\n\n for (const def of groupDefs) {\n const items = grouped.get(def.heading);\n if (!items || items.length === 0) continue;\n entries.push({\n kind: \"heading\",\n heading: def.heading,\n groupId: `${inputId}-group-${def.heading}`,\n });\n for (const item of items) {\n entries.push({ kind: \"item\", item, globalIndex });\n globalIndex++;\n }\n }\n\n for (const item of ungrouped) {\n entries.push({ kind: \"item\", item, globalIndex });\n globalIndex++;\n }\n\n return entries;\n});\n\n/**\n * The item list for the non-grouped case, used by keyboard navigation. Derived\n * from `renderEntries` so the two are always in sync.\n */\nconst flatItems = computed(() =>\n renderEntries.value.filter((e): e is GroupedItem => e.kind === \"item\"),\n);\n\n/**\n * Keep the highlight within bounds. A filter that removes items can strand the\n * index past the end.\n */\nwatch(flatItems, (items) => {\n if (highlightedIndex.value >= items.length) {\n highlightedIndex.value = Math.max(0, items.length - 1);\n }\n});\n\n/**\n * The documented reset: the highlight returns to the first match whenever the\n * query changes — whether the query came from typing or from a parent updating\n * the controlled `query` prop. Typing reaches this watcher through `setQuery`,\n * which is why onInput no longer resets the highlight itself.\n */\nwatch(queryValue, () => {\n highlightedIndex.value = 0;\n});\n\n/**\n * The total number of results, announced to assistive technology through a live\n * region. Changes only when the filtered set changes, not on every keystroke.\n */\nconst resultCount = computed(() => filteredItems.value.length);\nconst announcement = ref(\"\");\nwatch(resultCount, (count) => {\n const template =\n count === 1 ? resolvedLabels.value.resultSingular : resolvedLabels.value.resultPlural;\n announcement.value = template.replace(\"{count}\", String(count));\n});\n\n/**\n * The currently highlighted item, or `undefined` when the list is empty.\n */\nconst highlightedItem = computed(() => flatItems.value[highlightedIndex.value]?.item);\n\nfunction highlightUp(): void {\n if (flatItems.value.length === 0) return;\n highlightedIndex.value =\n highlightedIndex.value <= 0 ? flatItems.value.length - 1 : highlightedIndex.value - 1;\n}\n\nfunction highlightDown(): void {\n if (flatItems.value.length === 0) return;\n highlightedIndex.value =\n highlightedIndex.value >= flatItems.value.length - 1 ? 0 : highlightedIndex.value + 1;\n}\n\nfunction selectHighlighted(): void {\n const item = highlightedItem.value;\n if (!item || item.disabled) return;\n emit(\"select\", item.value);\n}\n\nfunction onKeydown(event: KeyboardEvent): void {\n // A closed Command returns on any interaction except the two that leave it —\n // Escape (the key that closed it, still under the same finger) and Tab\n // (which moves focus elsewhere). Keydown fires before the input event, so\n // typing also lands on an open list.\n if (!isOpen.value && event.key !== \"Escape\" && event.key !== \"Tab\") restoreOpen();\n switch (event.key) {\n case \"ArrowDown\": {\n event.preventDefault();\n highlightDown();\n break;\n }\n case \"ArrowUp\": {\n event.preventDefault();\n highlightUp();\n break;\n }\n case \"Enter\": {\n event.preventDefault();\n selectHighlighted();\n break;\n }\n case \"Escape\": {\n event.preventDefault();\n if (queryValue.value.length > 0) {\n setQuery(\"\");\n } else {\n setOpen(false);\n }\n break;\n }\n case \"Home\": {\n event.preventDefault();\n if (flatItems.value.length > 0) highlightedIndex.value = 0;\n break;\n }\n case \"End\": {\n event.preventDefault();\n if (flatItems.value.length > 0) highlightedIndex.value = flatItems.value.length - 1;\n break;\n }\n }\n}\n\nfunction onInput(event: Event): void {\n const value = (event.target as HTMLInputElement).value;\n setQuery(value);\n}\n\nfunction selectItem(item: CommandItem): void {\n if (item.disabled) return;\n emit(\"select\", item.value);\n}\n\nfunction itemId(index: number): string {\n return `${inputId}-option-${String(index)}`;\n}\n</script>\n\n<template>\n <div\n :data-state=\"isOpen ? 'open' : 'closed'\"\n :class=\"\n cn(\n 'rounded-md border border-border bg-popover text-popover-foreground shadow-md overflow-hidden',\n 'outline-none',\n )\n \"\n >\n <div class=\"flex items-center border-b border-border\">\n <input\n :id=\"inputId\"\n type=\"text\"\n role=\"searchbox\"\n autocomplete=\"off\"\n autocorrect=\"off\"\n spellcheck=\"false\"\n aria-autocomplete=\"list\"\n :aria-controls=\"listboxId\"\n :aria-activedescendant=\"highlightedItem ? itemId(highlightedIndex) : undefined\"\n :aria-labelledby=\"ariaLabelledby\"\n :aria-label=\"ariaLabelledby ? undefined : resolvedLabels.searchLabel\"\n :placeholder=\"resolvedLabels.placeholder\"\n :value=\"queryValue\"\n class=\"w-full px-3 py-2 text-sm bg-transparent text-foreground border-none outline-none placeholder:text-muted-foreground\"\n @input=\"onInput\"\n @keydown=\"onKeydown\"\n @focus=\"restoreOpen\"\n @click=\"restoreOpen\"\n />\n </div>\n <div\n v-if=\"isOpen\"\n :id=\"listboxId\"\n ref=\"listboxRef\"\n role=\"listbox\"\n tabindex=\"0\"\n :aria-labelledby=\"inputId\"\n class=\"max-h-[300px] overflow-y-auto p-1\"\n >\n <template\n v-for=\"entry in renderEntries\"\n :key=\"entry.kind === 'heading' ? entry.groupId : entry.item.value\"\n >\n <div\n v-if=\"entry.kind === 'heading'\"\n :id=\"entry.groupId\"\n role=\"presentation\"\n class=\"px-2 py-1.5 text-micro font-medium uppercase tracking-wide text-muted-foreground\"\n >\n {{ entry.heading }}\n </div>\n <!-- eslint-disable vuejs-accessibility/click-events-have-key-events, vuejs-accessibility/interactive-supports-focus, vuejs-accessibility/mouse-events-have-key-events -->\n <div\n v-else\n :id=\"itemId(entry.globalIndex)\"\n role=\"option\"\n :aria-selected=\"highlightedIndex === entry.globalIndex\"\n :aria-disabled=\"entry.item.disabled || undefined\"\n :data-active=\"highlightedIndex === entry.globalIndex || undefined\"\n class=\"flex flex-col gap-0.5 rounded-sm px-2 py-1.5 text-sm cursor-pointer outline-none transition-colors duration-fast ease-out data-[active]:bg-primary-muted data-[active]:text-primary-text\"\n @mouseenter=\"highlightedIndex = entry.globalIndex\"\n @click=\"selectItem(entry.item)\"\n >\n <span>{{ entry.item.label }}</span>\n <span v-if=\"entry.item.description\" class=\"text-xs text-muted-foreground\">\n {{ entry.item.description }}\n </span>\n </div>\n </template>\n\n <div\n v-if=\"filteredItems.length === 0\"\n role=\"option\"\n aria-selected=\"false\"\n aria-disabled=\"true\"\n class=\"px-2 py-6 text-center text-sm text-muted-foreground\"\n >\n {{ resolvedLabels.emptyMessage }}\n </div>\n </div>\n\n <span :id=\"liveRegionId\" role=\"status\" aria-live=\"polite\" class=\"sr-only\">\n {{ announcement }}\n </span>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,IAAa,iBAAgC;CAC3C,aAAa;CACb,cAAc;CACd,aAAa;CACb,gBAAgB;CAChB,cAAc;AAChB;;;;;;;;;;;;;;;;;;;;EA6BA,MAAM,QAAQ;EAsBd,MAAM,OAAO;EASb,MAAM,iBAAiB,UAAU,WAAW,sBAAsB,MAAM,MAAM;EAE9E,MAAM,UAAU,MAAM;EACtB,MAAM,YAAY,MAAM;EACxB,MAAM,eAAe,MAAM;;;;;EAM3B,MAAM,gBAAgB,IAAI,EAAE;EAC5B,MAAM,aAAa,eAAe,MAAM,SAAS,cAAc,KAAK;EAEpE,SAAS,SAAS,OAAqB;GACrC,cAAc,QAAQ;GACtB,KAAK,gBAAgB,KAAK;EAC5B;;;;EAKA,MAAM,eAAe,IAAI,IAAI;EAC7B,MAAM,SAAS,eAAe,MAAM,QAAQ,aAAa,KAAK;EAE9D,SAAS,QAAQ,OAAsB;GACrC,IAAI,MAAM,SAAS,KAAA,GACjB,KAAK,eAAe,KAAK;QAEzB,aAAa,QAAQ;EAEzB;;;;;;;;EASA,SAAS,cAAoB;GAC3B,IAAI,MAAM,SAAS,KAAA,GAAW,aAAa,QAAQ;EACrD;;;;;EAMA,MAAM,mBAAmB,IAAI,CAAC;EAE9B,MAAM,aAAa,IAAwB,IAAI;EAQ/C,MAAM,CAAC,kBAAkB,MAAM,GAAG,YAAY;GAC5C,IAAI,CAAC,OAAO,OAAO;GACnB,MAAM,SAAS;GACf,WAAW,OAAO,cAAc,eAAe,CAAC,EAAE,iBAAiB,EAAE,OAAO,UAAU,CAAC;EACzF,CAAC;;;;;EAMD,MAAM,gBAAgB,eAAe;GACnC,MAAM,SAAS,WAAW,MAAM,KAAK,CAAC,CAAC,YAAY;GACnD,IAAI,CAAC,QAAQ,OAAO,MAAM;GAC1B,OAAO,MAAM,MAAM,QAAQ,SAAS;IAElC,OADiB;KAAC,KAAK;KAAO,KAAK,eAAe;KAAI,KAAK;IAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,YACrE,CAAA,CAAS,SAAS,MAAM;GACjC,CAAC;EACH,CAAC;;;;;EAoBD,MAAM,gBAAgB,eAA8B;GAClD,IAAI,cAAc,MAAM,WAAW,GAAG,OAAO,CAAC;GAE9C,MAAM,YAAY,MAAM;GACxB,IAAI,CAAC,aAAa,UAAU,WAAW,GACrC,OAAO,cAAc,MAAM,KAAK,MAAM,OAAO;IAAE,MAAM;IAAQ;IAAM,aAAa;GAAE,EAAE;GAGtF,MAAM,YAA2B,CAAC;GAClC,MAAM,0BAAU,IAAI,IAA2B;GAE/C,KAAK,MAAM,QAAQ,cAAc,OAC/B,IAAI,KAAK,OAAO;IACd,MAAM,OAAO,QAAQ,IAAI,KAAK,KAAK,KAAK,CAAC;IACzC,KAAK,KAAK,IAAI;IACd,QAAQ,IAAI,KAAK,OAAO,IAAI;GAC9B,OACE,UAAU,KAAK,IAAI;GAIvB,MAAM,UAAyB,CAAC;GAChC,IAAI,cAAc;GAElB,KAAK,MAAM,OAAO,WAAW;IAC3B,MAAM,QAAQ,QAAQ,IAAI,IAAI,OAAO;IACrC,IAAI,CAAC,SAAS,MAAM,WAAW,GAAG;IAClC,QAAQ,KAAK;KACX,MAAM;KACN,SAAS,IAAI;KACb,SAAS,GAAG,QAAQ,SAAS,IAAI;IACnC,CAAC;IACD,KAAK,MAAM,QAAQ,OAAO;KACxB,QAAQ,KAAK;MAAE,MAAM;MAAQ;MAAM;KAAY,CAAC;KAChD;IACF;GACF;GAEA,KAAK,MAAM,QAAQ,WAAW;IAC5B,QAAQ,KAAK;KAAE,MAAM;KAAQ;KAAM;IAAY,CAAC;IAChD;GACF;GAEA,OAAO;EACT,CAAC;;;;;EAMD,MAAM,YAAY,eAChB,cAAc,MAAM,QAAQ,MAAwB,EAAE,SAAS,MAAM,CACvE;;;;;EAMA,MAAM,YAAY,UAAU;GAC1B,IAAI,iBAAiB,SAAS,MAAM,QAClC,iBAAiB,QAAQ,KAAK,IAAI,GAAG,MAAM,SAAS,CAAC;EAEzD,CAAC;;;;;;;EAQD,MAAM,kBAAkB;GACtB,iBAAiB,QAAQ;EAC3B,CAAC;;;;;EAMD,MAAM,cAAc,eAAe,cAAc,MAAM,MAAM;EAC7D,MAAM,eAAe,IAAI,EAAE;EAC3B,MAAM,cAAc,UAAU;GAC5B,MAAM,WACJ,UAAU,IAAI,eAAe,MAAM,iBAAiB,eAAe,MAAM;GAC3E,aAAa,QAAQ,SAAS,QAAQ,WAAW,OAAO,KAAK,CAAC;EAChE,CAAC;;;;EAKD,MAAM,kBAAkB,eAAe,UAAU,MAAM,iBAAiB,MAAM,EAAE,IAAI;EAEpF,SAAS,cAAoB;GAC3B,IAAI,UAAU,MAAM,WAAW,GAAG;GAClC,iBAAiB,QACf,iBAAiB,SAAS,IAAI,UAAU,MAAM,SAAS,IAAI,iBAAiB,QAAQ;EACxF;EAEA,SAAS,gBAAsB;GAC7B,IAAI,UAAU,MAAM,WAAW,GAAG;GAClC,iBAAiB,QACf,iBAAiB,SAAS,UAAU,MAAM,SAAS,IAAI,IAAI,iBAAiB,QAAQ;EACxF;EAEA,SAAS,oBAA0B;GACjC,MAAM,OAAO,gBAAgB;GAC7B,IAAI,CAAC,QAAQ,KAAK,UAAU;GAC5B,KAAK,UAAU,KAAK,KAAK;EAC3B;EAEA,SAAS,UAAU,OAA4B;GAK7C,IAAI,CAAC,OAAO,SAAS,MAAM,QAAQ,YAAY,MAAM,QAAQ,OAAO,YAAY;GAChF,QAAQ,MAAM,KAAd;IACE,KAAK;KACH,MAAM,eAAe;KACrB,cAAc;KACd;IAEF,KAAK;KACH,MAAM,eAAe;KACrB,YAAY;KACZ;IAEF,KAAK;KACH,MAAM,eAAe;KACrB,kBAAkB;KAClB;IAEF,KAAK;KACH,MAAM,eAAe;KACrB,IAAI,WAAW,MAAM,SAAS,GAC5B,SAAS,EAAE;UAEX,QAAQ,KAAK;KAEf;IAEF,KAAK;KACH,MAAM,eAAe;KACrB,IAAI,UAAU,MAAM,SAAS,GAAG,iBAAiB,QAAQ;KACzD;IAEF,KAAK;KACH,MAAM,eAAe;KACrB,IAAI,UAAU,MAAM,SAAS,GAAG,iBAAiB,QAAQ,UAAU,MAAM,SAAS;GAGtF;EACF;EAEA,SAAS,QAAQ,OAAoB;GACnC,MAAM,QAAS,MAAM,OAA4B;GACjD,SAAS,KAAK;EAChB;EAEA,SAAS,WAAW,MAAyB;GAC3C,IAAI,KAAK,UAAU;GACnB,KAAK,UAAU,KAAK,KAAK;EAC3B;EAEA,SAAS,OAAO,OAAuB;GACrC,OAAO,GAAG,QAAQ,UAAU,OAAO,KAAK;EAC1C;;GAIE,OAAA,UAAA,GAAA,mBAqFM,OAAA;IApFH,cAAY,OAAA,QAAM,SAAA;IAClB,OAAK,eAAS,MAAA,EAAA,CAAE,CAAA,gGAAA,cAAA,CAAA;;IAOjB,mBAqBM,OArBN,YAqBM,CApBJ,mBAmBE,SAAA;KAlBC,IAAI,MAAA,OAAA;KACL,MAAK;KACL,MAAK;KACL,cAAa;KACb,aAAY;KACZ,YAAW;KACX,qBAAkB;KACjB,iBAAe,MAAA,SAAA;KACf,yBAAuB,gBAAA,QAAkB,OAAO,iBAAA,KAAgB,IAAI,KAAA;KACpE,mBAAiB,QAAA;KACjB,cAAY,QAAA,iBAAiB,KAAA,IAAY,MAAA,cAAA,CAAc,CAAC;KACxD,aAAa,MAAA,cAAA,CAAc,CAAC;KAC5B,OAAO,WAAA;KACR,OAAM;KACE;KACE;KACT,SAAO;KACP,SAAO;;IAIJ,OAAA,SADR,UAAA,GAAA,mBAiDM,OAAA;;KA/CH,IAAI,MAAA,SAAA;KACD,SAAA;KAAJ,KAAI;KACJ,MAAK;KACL,UAAS;KACR,mBAAiB,MAAA,OAAA;KAClB,OAAM;IAEN,GAAA,EAAA,UAAA,IAAA,GAAA,mBA6BW,UAAA,MAAA,WA5BO,cAAA,QAAT,UAAK;KACN,OAAA,UAAA,GAAA,mBAAA,UAAA,EAAA,KAAA,MAAM,SAAI,YAAiB,MAAM,UAAU,MAAM,KAAK,MAAA,GAAA,CAGpD,MAAM,SAAI,aADlB,UAAA,GAAA,mBAOM,OAAA;;MALH,IAAI,MAAM;MACX,MAAK;MACL,OAAM;KAEH,GAAA,gBAAA,MAAM,OAAO,GAAA,GAAA,UAAA,MAGlB,UAAA,GAAA,mBAeM,OAAA;;MAbH,IAAI,OAAO,MAAM,WAAW;MAC7B,MAAK;MACJ,iBAAe,iBAAA,UAAqB,MAAM;MAC1C,iBAAe,MAAM,KAAK,YAAY,KAAA;MACtC,eAAa,iBAAA,UAAqB,MAAM,eAAe,KAAA;MACxD,OAAM;MACL,eAAU,WAAE,iBAAA,QAAmB,MAAM;MACrC,UAAK,WAAE,WAAW,MAAM,IAAI;KAE7B,GAAA,CAAA,mBAAmC,QAAA,MAAA,gBAA1B,MAAM,KAAK,KAAK,GAAA,CAAA,GACb,MAAM,KAAK,eAAvB,UAAA,GAAA,mBAEO,QAFP,YAEO,gBADF,MAAM,KAAK,WAAW,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,IAAA,UAAA,EAAA,GAAA,EAAA;IAMvB,CAAA,GAAA,GAAA,IAAA,cAAA,MAAc,WAAM,KAD5B,UAAA,GAAA,mBAQM,OARN,YAQM,gBADD,MAAA,cAAA,CAAc,CAAC,YAAY,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,GAAA,UAAA,KAAA,mBAAA,IAAA,IAAA;IAIlC,mBAEO,QAAA;KAFA,IAAI,MAAA,YAAA;KAAc,MAAK;KAAS,aAAU;KAAS,OAAM;IAC3D,GAAA,gBAAA,aAAA,KAAY,GAAA,GAAA,UAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ContextMenu.js","names":[],"sources":["../../../../../packages/primitives/context-menu/src/ContextMenu.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * One row of the menu, and the three kinds a menu is built from are told apart\n * by which fields are set rather than by a `kind` discriminator: a `separator`\n * is a rule, a `heading` is a non-interactive group label, and anything else\n * is a command.\n *\n * The list is data rather than markup because the primitive stays free of app\n * logic — selecting a row emits its `value` and the host decides what that\n * command means.\n */\nexport interface ContextMenuEntry {\n /** The visible text of a command or a heading. */\n label?: string;\n /** The command id emitted on select. An entry without one is not selectable. */\n value?: string;\n /** Accelerator hint shown at the trailing edge, e.g. `⌘S`. Display only — the primitive binds no keys. */\n shortcut?: string;\n /** Render a divider. Every other field is ignored. */\n separator?: boolean;\n /** Render a non-interactive section heading rather than a command. */\n heading?: boolean;\n /** A destructive command — painted in the destructive token so it is not one indistinguishable row. */\n danger?: boolean;\n /** Visible but inert: announced as disabled, and selecting it emits nothing. */\n disabled?: boolean;\n}\n</script>\n\n<script setup lang=\"ts\">\nimport {\n ContextMenuRoot,\n ContextMenuTrigger,\n ContextMenuPortal,\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuLabel,\n ContextMenuSeparator,\n} from \"reka-ui\";\nimport { cn } from \"@ecoma-io/loom-core\";\nimport { listStaggerDelay } from \"@ecoma-io/loom-core\";\nimport { optional } from \"@ecoma-io/loom-core\";\n\n/**\n * ContextMenu — a right-click command list, with roving focus, typeahead and\n * arrow-key navigation.\n *\n * The escape contract mirrors DropdownMenu: opening moves focus into the menu\n * and onto the first command; Esc and an outside click both close it; closing\n * returns focus to the trigger's element. The menu is modal, so while it is\n * open the page behind does not scroll and the rest of the page is hidden from\n * assistive technology.\n *\n * Selecting an entry emits `select` with its `value`; the host maps that id to\n * an action, which is what keeps the primitive free of app logic.\n *\n * Reach for `DropdownMenu` when the trigger should be a visible button rather\n * than a right-click, and for a select control when the list *is* a field's\n * value.\n */\nwithDefaults(\n defineProps<{\n /** The rows, in order. Three kinds, told apart by which fields are set. */\n items: ContextMenuEntry[];\n /** Drive the menu from the host with `v-model:open`; omit it and the menu owns its own state. */\n open?: boolean | undefined;\n /**\n * Reading direction for the menu and its arrow-key navigation. Reka\n * mirrors traversal from this; without forwarding it a right-to-left\n * host gets left-to-right menus no matter what the page declares.\n */\n dir?: \"ltr\" | \"rtl\";\n }>(),\n // `open: undefined` is load-bearing, not a redundant default — it is what\n // keeps the uncontrolled third state reachable past Vue's absent-Boolean\n // casting. `optional()` in the template is the other half; its docblock\n // carries the reasoning for both.\n { open: undefined },\n);\nconst emit = defineEmits<{ select: [value: string]; \"update:open\": [value: boolean] }>();\n\n/**\n * A disabled entry, and an entry with no command id, select nothing. Reka\n * already blocks pointer events on the disabled row; this is the second half,\n * for the keyboard path that reaches it anyway.\n */\nfunction choose(item: ContextMenuEntry): void {\n if (item.disabled || item.value === undefined) return;\n emit(\"select\", item.value);\n}\n</script>\n\n<template>\n <ContextMenuRoot v-bind=\"optional({ open, dir })\" @update:open=\"$emit('update:open', $event)\">\n <!-- @slot The element that receives the right-click. Rendered `as-child`,\n so the caller's own element *is* the trigger. -->\n <ContextMenuTrigger as-child>\n <slot name=\"trigger\" />\n </ContextMenuTrigger>\n\n <ContextMenuPortal>\n <ContextMenuContent\n :side-offset=\"6\"\n align=\"start\"\n :class=\"\n cn(\n 'z-overlay min-w-[12rem] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md outline-none',\n // Both states scoped, never unconditional. Reka's Presence\n // keeps closed content mounted until an animationend arrives, and a\n // mount-only animation never fires a second one — so an\n // unconditional animation class strands an invisible menu over the\n // page, catching clicks meant for what is behind it. Scoped, the\n // closed element computes `animation-name: none` and Presence\n // unmounts it at once; the paired exit is precisely what Presence\n // is waiting to hold it for. The origin below makes the menu grow\n // out of the click point rather than out of its own centre — on\n // the way out as well as in.\n 'data-[state=open]:animate-scale-in data-[state=closed]:animate-scale-out',\n )\n \"\n style=\"transform-origin: var(--reka-popper-transform-origin)\"\n >\n <template v-for=\"(item, i) in items\" :key=\"i\">\n <ContextMenuSeparator v-if=\"item.separator\" class=\"my-1 h-px bg-border\" />\n <ContextMenuLabel\n v-else-if=\"item.heading\"\n class=\"px-2 py-1.5 text-micro font-medium uppercase tracking-wide text-muted-foreground\"\n >\n {{ item.label }}\n </ContextMenuLabel>\n <!-- The reveal delay comes from the shared stagger vocabulary, capped\n there so a long menu does not tail off, rather than from a\n per-menu number written by hand.\n\n `disabled` is coerced rather than forwarded raw: an entry that\n simply omits the field is not disabled, and Reka's own prop does\n not accept `undefined` as a way of saying so. -->\n <ContextMenuItem\n v-else\n :disabled=\"item.disabled ?? false\"\n :class=\"\n cn(\n 'flex cursor-pointer items-center justify-between gap-6 rounded-sm px-2 py-1.5 text-sm text-foreground outline-none',\n 'transition-colors duration-fast ease-out',\n // The rows reveal in sequence as the menu opens, which reads as\n // a list arriving rather than a block appearing. The hover\n // colour transition above is a separate channel, so a row\n // highlighted mid-reveal still responds at once.\n 'animate-fade-rise',\n 'data-[highlighted]:bg-subtle',\n // The row's colour, not its alpha. A menu row is nothing but\n // its label, and `data-[disabled]:opacity-40` composited that\n // label to 2.40:1 on the popover and its shortcut to 1.79:1 —\n // a disabled row a reader cannot make out tells them nothing\n // about what is unavailable, which is the only thing it is\n // there to say. Muted instead: 5.76:1, and a clear drop from\n // the 15.46:1 an available row wears.\n //\n // It takes the danger colour with it, deliberately. An\n // attribute selector outranks the plain `text-destructive-text`\n // below whatever order Tailwind emits them in, and that is the\n // right way round: red is a warning about an action, and there\n // is no action here to warn about.\n 'data-[disabled]:pointer-events-none data-[disabled]:text-muted-foreground',\n item.danger &&\n 'text-destructive-text data-[highlighted]:bg-destructive/10 data-[highlighted]:text-destructive-text',\n )\n \"\n :style=\"{ animationDelay: listStaggerDelay(i) }\"\n @select=\"choose(item)\"\n >\n <span>{{ item.label }}</span>\n <span v-if=\"item.shortcut\" class=\"tabular text-micro text-muted-foreground\">\n {{ item.shortcut }}\n </span>\n </ContextMenuItem>\n </template>\n </ContextMenuContent>\n </ContextMenuPortal>\n </ContextMenuRoot>\n</template>\n"],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"ContextMenu.vue_vue_type_script_setup_true_lang.js","names":["$emit"],"sources":["../../../../../packages/primitives/context-menu/src/ContextMenu.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * One row of the menu, and the three kinds a menu is built from are told apart\n * by which fields are set rather than by a `kind` discriminator: a `separator`\n * is a rule, a `heading` is a non-interactive group label, and anything else\n * is a command.\n *\n * The list is data rather than markup because the primitive stays free of app\n * logic — selecting a row emits its `value` and the host decides what that\n * command means.\n */\nexport interface ContextMenuEntry {\n /** The visible text of a command or a heading. */\n label?: string;\n /** The command id emitted on select. An entry without one is not selectable. */\n value?: string;\n /** Accelerator hint shown at the trailing edge, e.g. `⌘S`. Display only — the primitive binds no keys. */\n shortcut?: string;\n /** Render a divider. Every other field is ignored. */\n separator?: boolean;\n /** Render a non-interactive section heading rather than a command. */\n heading?: boolean;\n /** A destructive command — painted in the destructive token so it is not one indistinguishable row. */\n danger?: boolean;\n /** Visible but inert: announced as disabled, and selecting it emits nothing. */\n disabled?: boolean;\n}\n</script>\n\n<script setup lang=\"ts\">\nimport {\n ContextMenuRoot,\n ContextMenuTrigger,\n ContextMenuPortal,\n ContextMenuContent,\n ContextMenuItem,\n ContextMenuLabel,\n ContextMenuSeparator,\n} from \"reka-ui\";\nimport { cn } from \"@ecoma-io/loom-core\";\nimport { listStaggerDelay } from \"@ecoma-io/loom-core\";\nimport { optional } from \"@ecoma-io/loom-core\";\n\n/**\n * ContextMenu — a right-click command list, with roving focus, typeahead and\n * arrow-key navigation.\n *\n * The escape contract mirrors DropdownMenu: opening moves focus into the menu\n * and onto the first command; Esc and an outside click both close it; closing\n * returns focus to the trigger's element. The menu is modal, so while it is\n * open the page behind does not scroll and the rest of the page is hidden from\n * assistive technology.\n *\n * Selecting an entry emits `select` with its `value`; the host maps that id to\n * an action, which is what keeps the primitive free of app logic.\n *\n * Reach for `DropdownMenu` when the trigger should be a visible button rather\n * than a right-click, and for a select control when the list *is* a field's\n * value.\n */\nwithDefaults(\n defineProps<{\n /** The rows, in order. Three kinds, told apart by which fields are set. */\n items: ContextMenuEntry[];\n /** Drive the menu from the host with `v-model:open`; omit it and the menu owns its own state. */\n open?: boolean | undefined;\n /**\n * Reading direction for the menu and its arrow-key navigation. Reka\n * mirrors traversal from this; without forwarding it a right-to-left\n * host gets left-to-right menus no matter what the page declares.\n */\n dir?: \"ltr\" | \"rtl\";\n }>(),\n // `open: undefined` is load-bearing, not a redundant default — it is what\n // keeps the uncontrolled third state reachable past Vue's absent-Boolean\n // casting. `optional()` in the template is the other half; its docblock\n // carries the reasoning for both.\n { open: undefined },\n);\nconst emit = defineEmits<{ select: [value: string]; \"update:open\": [value: boolean] }>();\n\n/**\n * A disabled entry, and an entry with no command id, select nothing. Reka\n * already blocks pointer events on the disabled row; this is the second half,\n * for the keyboard path that reaches it anyway.\n */\nfunction choose(item: ContextMenuEntry): void {\n if (item.disabled || item.value === undefined) return;\n emit(\"select\", item.value);\n}\n</script>\n\n<template>\n <ContextMenuRoot v-bind=\"optional({ open, dir })\" @update:open=\"$emit('update:open', $event)\">\n <!-- @slot The element that receives the right-click. Rendered `as-child`,\n so the caller's own element *is* the trigger. -->\n <ContextMenuTrigger as-child>\n <slot name=\"trigger\" />\n </ContextMenuTrigger>\n\n <ContextMenuPortal>\n <ContextMenuContent\n :side-offset=\"6\"\n align=\"start\"\n :class=\"\n cn(\n 'z-overlay min-w-[12rem] rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md outline-none',\n // Both states scoped, never unconditional. Reka's Presence\n // keeps closed content mounted until an animationend arrives, and a\n // mount-only animation never fires a second one — so an\n // unconditional animation class strands an invisible menu over the\n // page, catching clicks meant for what is behind it. Scoped, the\n // closed element computes `animation-name: none` and Presence\n // unmounts it at once; the paired exit is precisely what Presence\n // is waiting to hold it for. The origin below makes the menu grow\n // out of the click point rather than out of its own centre — on\n // the way out as well as in.\n 'data-[state=open]:animate-scale-in data-[state=closed]:animate-scale-out',\n )\n \"\n style=\"transform-origin: var(--reka-popper-transform-origin)\"\n >\n <template v-for=\"(item, i) in items\" :key=\"i\">\n <ContextMenuSeparator v-if=\"item.separator\" class=\"my-1 h-px bg-border\" />\n <ContextMenuLabel\n v-else-if=\"item.heading\"\n class=\"px-2 py-1.5 text-micro font-medium uppercase tracking-wide text-muted-foreground\"\n >\n {{ item.label }}\n </ContextMenuLabel>\n <!-- The reveal delay comes from the shared stagger vocabulary, capped\n there so a long menu does not tail off, rather than from a\n per-menu number written by hand.\n\n `disabled` is coerced rather than forwarded raw: an entry that\n simply omits the field is not disabled, and Reka's own prop does\n not accept `undefined` as a way of saying so. -->\n <ContextMenuItem\n v-else\n :disabled=\"item.disabled ?? false\"\n :class=\"\n cn(\n 'flex cursor-pointer items-center justify-between gap-6 rounded-sm px-2 py-1.5 text-sm text-foreground outline-none',\n 'transition-colors duration-fast ease-out',\n // The rows reveal in sequence as the menu opens, which reads as\n // a list arriving rather than a block appearing. The hover\n // colour transition above is a separate channel, so a row\n // highlighted mid-reveal still responds at once.\n 'animate-fade-rise',\n 'data-[highlighted]:bg-subtle',\n // The row's colour, not its alpha. A menu row is nothing but\n // its label, and `data-[disabled]:opacity-40` composited that\n // label to 2.40:1 on the popover and its shortcut to 1.79:1 —\n // a disabled row a reader cannot make out tells them nothing\n // about what is unavailable, which is the only thing it is\n // there to say. Muted instead: 5.76:1, and a clear drop from\n // the 15.46:1 an available row wears.\n //\n // It takes the danger colour with it, deliberately. An\n // attribute selector outranks the plain `text-destructive-text`\n // below whatever order Tailwind emits them in, and that is the\n // right way round: red is a warning about an action, and there\n // is no action here to warn about.\n 'data-[disabled]:pointer-events-none data-[disabled]:text-muted-foreground',\n item.danger &&\n 'text-destructive-text data-[highlighted]:bg-destructive/10 data-[highlighted]:text-destructive-text',\n )\n \"\n :style=\"{ animationDelay: listStaggerDelay(i) }\"\n @select=\"choose(item)\"\n >\n <span>{{ item.label }}</span>\n <span v-if=\"item.shortcut\" class=\"tabular text-micro text-muted-foreground\">\n {{ item.shortcut }}\n </span>\n </ContextMenuItem>\n </template>\n </ContextMenuContent>\n </ContextMenuPortal>\n </ContextMenuRoot>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;EA+EA,MAAM,OAAO;;;;;;EAOb,SAAS,OAAO,MAA8B;GAC5C,IAAI,KAAK,YAAY,KAAK,UAAU,KAAA,GAAW;GAC/C,KAAK,UAAU,KAAK,KAAK;EAC3B;;GAIE,OAAA,UAAA,GAAA,YAsFkB,MAAA,eAAA,GAtFlB,WAAyB,MAsFP,QAAA,CAtFe,CAAA;IAAA,MAAG,QAAA;IAAI,KAAE,QAAA;GAAG,CAAA,GAAA,EAAM,iBAAW,OAAA,OAAA,OAAA,MAAA,WAAEA,KAAAA,MAAK,eAAgB,MAAM,GAAA,CAAA,GAAA;IAGzF,SAAA,cAEqB,CAFrB,YAEqB,MAAA,kBAAA,GAAA,EAFD,YAAA,GAAQ,GAAA;KAC1B,SAAA,cAAuB,CAAvB,WAAuB,KAAA,QAAA,SAAA,CAAA,CAAA;;IAGzB,CAAA,GAAA,YA8EoB,MAAA,iBAAA,GAAA,MAAA;KA7ElB,SAAA,cA4EqB,CA5ErB,YA4EqB,MAAA,kBAAA,GAAA;MA3ElB,eAAa;MACd,OAAM;MACL,OAAK,eAAa,MAAA,EAAA,CAAE,CAAA,yHAAA,0EAAA,CAAA;MAgBrB,OAAA,EAAA,oBAAA,sCAAA;;MAEU,SAAA,cAA0B,EAApC,UAAA,IAAA,GAAA,mBAsDW,UAAA,MAAA,WAtDmB,QAAA,QAAZ,MAAM,MAAC;OAAkB,OAAA,UAAA,GAAA,mBAAA,UAAA,EAAA,KAAA,EAAC,GAAA,CACd,KAAK,aAAjC,UAAA,GAAA,YAA0E,MAAA,oBAAA,GAAA;;QAA9B,OAAM;OAErC,CAAA,KAAA,KAAK,WADlB,UAAA,GAAA,YAKmB,MAAA,gBAAA,GAAA;;QAHjB,OAAM;;QAEN,SAAA,cAAgB,CAAb,gBAAA,gBAAA,KAAK,KAAK,GAAA,CAAA,CAAA,CAAA;;OASf,GAAA,IAAA,MAAA,UAAA,GAAA,YAsCkB,MAAA,eAAA,GAAA;;QApCf,UAAU,KAAK,YAAQ;QACvB,OAAK,eAAiB,MAAA,EAAA,CAAE,CAAA,sHAAA,4CAAA,qBAAA,gCAAA,6EAA2jD,KAAK,UAAA,qGAAA,CAAA;QA4BxlD,OAAK,eAAA,EAAA,gBAAoB,MAAA,gBAAA,CAAgB,CAAC,CAAC,EAAA,CAAA;QAC3C,WAAM,WAAE,OAAO,IAAI;;QAEpB,SAAA,cAA6B,CAA7B,mBAA6B,QAAA,MAAA,gBAApB,KAAK,KAAK,GAAA,CAAA,GACP,KAAK,YAAjB,UAAA,GAAA,mBAEO,QAFP,YAEO,gBADF,KAAK,QAAQ,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"CopyButton.js","names":[],"sources":["../../../../../packages/primitives/copy-button/src/CopyButton.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { CopyButtonLabels } from \"@ecoma-io/loom-labels\";\nimport type { IconButtonSize, IconButtonVariant } from \"@ecoma-io/loom-icon-button\";\n\n/**\n * The visual weights and hit areas are IconButton's, verbatim — a copy button\n * is an icon button that happens to own a clipboard contract, and there is no\n * second press language to maintain.\n */\nexport type CopyButtonVariant = IconButtonVariant;\nexport type CopyButtonSize = IconButtonSize;\n\nexport const COPY_BUTTON_LABELS: CopyButtonLabels = {\n copy: \"Copy to clipboard\",\n copied: \"Copied to clipboard\",\n failed: \"Could not copy to clipboard\",\n};\n\n/** How long the copied/failed feedback holds before the button returns to its resting glyph. */\nexport const COPY_REVERT_MS = 2000;\n</script>\n\n<script setup lang=\"ts\">\nimport { onBeforeUnmount, ref } from \"vue\";\nimport { Check, Copy, X } from \"@lucide/vue\";\nimport IconButton from \"@ecoma-io/loom-icon-button\";\nimport { useAnnounce } from \"@ecoma-io/loom-live-region\";\nimport { useLabels, type LabelOverrides } from \"@ecoma-io/loom-labels\";\n\nconst props = withDefaults(\n defineProps<{\n /** The text to copy. Provide `value` or `getText` — a `CopyButton` with neither has nothing to do. */\n value?: string;\n /** Resolved at click time instead of a static `value` — for text the host computes on demand, possibly asynchronously. */\n getText?: () => string | Promise<string>;\n /**\n * Names for what the button says, as any subset of `CopyButtonLabels` —\n * the per-instance correction over `COPY_BUTTON_LABELS`, in the same\n * shape every component's `labels` prop takes. `copy` is the button's\n * accessible name and never changes with the state; `copied` and\n * `failed` are what assistive technology hears.\n */\n labels?: LabelOverrides<CopyButtonLabels>;\n /** Visual weight, shared with IconButton. */\n variant?: CopyButtonVariant;\n /** Square hit area, shared with IconButton. */\n size?: CopyButtonSize;\n /** Unavailable rather than dimmed — drains to the neutral well and blocks pointer events. */\n disabled?: boolean;\n /** The native button type. Defaults to `button`, never an accidental submit. */\n type?: \"button\" | \"submit\" | \"reset\";\n }>(),\n { variant: \"default\", size: \"md\", disabled: false, type: \"button\" },\n);\n\n/**\n * The outcome is announced through the shared LiveRegion seam, not a\n * region of this component's own: a region must pre-exist the messages it\n * announces, and the seam's standalone pair on `document.body` guarantees\n * that without every copy button mounting its own.\n */\nconst announce = useAnnounce();\n\n// `text`, not `labels`: the prop of that name is one of the three sources\n// this resolves (own prop, then the host vocabulary from\n// `provideLoomLabels`, then these English defaults), and a template reading\n// the raw prop would be reading the overrides rather than the answer.\nconst text = useLabels(\"copyButton\", COPY_BUTTON_LABELS, () => props.labels);\n\n/**\n * idle → copied | failed → idle, on a two-second revert timer. The guard\n * covers only the await window: a click during the feedback window is a\n * legitimate \"copy again\", not a duplicate — the announcement seam re-adds\n * the message, so a repeat is heard.\n */\ntype CopyState = \"idle\" | \"copied\" | \"failed\";\nconst state = ref<CopyState>(\"idle\");\nlet pending = false;\nlet revertTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction scheduleRevert(): void {\n if (revertTimer !== null) clearTimeout(revertTimer);\n revertTimer = setTimeout(() => {\n state.value = \"idle\";\n revertTimer = null;\n }, COPY_REVERT_MS);\n}\n\nonBeforeUnmount(() => {\n // The timer holds the only writer into `state`; firing after unmount\n // would write into a dead component. Cleared, not waited out.\n if (revertTimer !== null) clearTimeout(revertTimer);\n revertTimer = null;\n});\n\nasync function copy(): Promise<void> {\n if (props.disabled || pending) return;\n pending = true;\n try {\n // A throwing `getText` and a refusing clipboard take the same road:\n // the failed state is announced, the glyph says so, and the button\n // stays operable so the very next click retries the whole attempt.\n const value = props.getText ? await props.getText() : (props.value ?? \"\");\n await navigator.clipboard.writeText(value);\n state.value = \"copied\";\n announce(text.value.copied);\n } catch {\n state.value = \"failed\";\n announce(text.value.failed);\n } finally {\n pending = false;\n scheduleRevert();\n }\n}\n</script>\n\n<template>\n <IconButton\n :label=\"text.copy\"\n :variant=\"variant\"\n :size=\"size\"\n :disabled=\"disabled\"\n :type=\"type\"\n @click=\"copy\"\n >\n <!-- The glyph swap is the feedback's visual half only — never its only\n carrier. The announcement carries the state to assistive technology,\n and the accessible name stays `copy` throughout: a button whose name\n changes under a screen reader's cursor is its own confusion. -->\n <Check v-if=\"state === 'copied'\" class=\"h-4 w-4\" aria-hidden=\"true\" />\n <X v-else-if=\"state === 'failed'\" class=\"h-4 w-4\" aria-hidden=\"true\" />\n <Copy v-else class=\"h-4 w-4\" aria-hidden=\"true\" />\n </IconButton>\n</template>\n"],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"CopyButton.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../../../packages/primitives/copy-button/src/CopyButton.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { CopyButtonLabels } from \"@ecoma-io/loom-labels\";\nimport type { IconButtonSize, IconButtonVariant } from \"@ecoma-io/loom-icon-button\";\n\n/**\n * The visual weights and hit areas are IconButton's, verbatim — a copy button\n * is an icon button that happens to own a clipboard contract, and there is no\n * second press language to maintain.\n */\nexport type CopyButtonVariant = IconButtonVariant;\nexport type CopyButtonSize = IconButtonSize;\n\nexport const COPY_BUTTON_LABELS: CopyButtonLabels = {\n copy: \"Copy to clipboard\",\n copied: \"Copied to clipboard\",\n failed: \"Could not copy to clipboard\",\n};\n\n/** How long the copied/failed feedback holds before the button returns to its resting glyph. */\nexport const COPY_REVERT_MS = 2000;\n</script>\n\n<script setup lang=\"ts\">\nimport { onBeforeUnmount, ref } from \"vue\";\nimport { Check, Copy, X } from \"@lucide/vue\";\nimport IconButton from \"@ecoma-io/loom-icon-button\";\nimport { useAnnounce } from \"@ecoma-io/loom-live-region\";\nimport { useLabels, type LabelOverrides } from \"@ecoma-io/loom-labels\";\n\nconst props = withDefaults(\n defineProps<{\n /** The text to copy. Provide `value` or `getText` — a `CopyButton` with neither has nothing to do. */\n value?: string;\n /** Resolved at click time instead of a static `value` — for text the host computes on demand, possibly asynchronously. */\n getText?: () => string | Promise<string>;\n /**\n * Names for what the button says, as any subset of `CopyButtonLabels` —\n * the per-instance correction over `COPY_BUTTON_LABELS`, in the same\n * shape every component's `labels` prop takes. `copy` is the button's\n * accessible name and never changes with the state; `copied` and\n * `failed` are what assistive technology hears.\n */\n labels?: LabelOverrides<CopyButtonLabels>;\n /** Visual weight, shared with IconButton. */\n variant?: CopyButtonVariant;\n /** Square hit area, shared with IconButton. */\n size?: CopyButtonSize;\n /** Unavailable rather than dimmed — drains to the neutral well and blocks pointer events. */\n disabled?: boolean;\n /** The native button type. Defaults to `button`, never an accidental submit. */\n type?: \"button\" | \"submit\" | \"reset\";\n }>(),\n { variant: \"default\", size: \"md\", disabled: false, type: \"button\" },\n);\n\n/**\n * The outcome is announced through the shared LiveRegion seam, not a\n * region of this component's own: a region must pre-exist the messages it\n * announces, and the seam's standalone pair on `document.body` guarantees\n * that without every copy button mounting its own.\n */\nconst announce = useAnnounce();\n\n// `text`, not `labels`: the prop of that name is one of the three sources\n// this resolves (own prop, then the host vocabulary from\n// `provideLoomLabels`, then these English defaults), and a template reading\n// the raw prop would be reading the overrides rather than the answer.\nconst text = useLabels(\"copyButton\", COPY_BUTTON_LABELS, () => props.labels);\n\n/**\n * idle → copied | failed → idle, on a two-second revert timer. The guard\n * covers only the await window: a click during the feedback window is a\n * legitimate \"copy again\", not a duplicate — the announcement seam re-adds\n * the message, so a repeat is heard.\n */\ntype CopyState = \"idle\" | \"copied\" | \"failed\";\nconst state = ref<CopyState>(\"idle\");\nlet pending = false;\nlet revertTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction scheduleRevert(): void {\n if (revertTimer !== null) clearTimeout(revertTimer);\n revertTimer = setTimeout(() => {\n state.value = \"idle\";\n revertTimer = null;\n }, COPY_REVERT_MS);\n}\n\nonBeforeUnmount(() => {\n // The timer holds the only writer into `state`; firing after unmount\n // would write into a dead component. Cleared, not waited out.\n if (revertTimer !== null) clearTimeout(revertTimer);\n revertTimer = null;\n});\n\nasync function copy(): Promise<void> {\n if (props.disabled || pending) return;\n pending = true;\n try {\n // A throwing `getText` and a refusing clipboard take the same road:\n // the failed state is announced, the glyph says so, and the button\n // stays operable so the very next click retries the whole attempt.\n const value = props.getText ? await props.getText() : (props.value ?? \"\");\n await navigator.clipboard.writeText(value);\n state.value = \"copied\";\n announce(text.value.copied);\n } catch {\n state.value = \"failed\";\n announce(text.value.failed);\n } finally {\n pending = false;\n scheduleRevert();\n }\n}\n</script>\n\n<template>\n <IconButton\n :label=\"text.copy\"\n :variant=\"variant\"\n :size=\"size\"\n :disabled=\"disabled\"\n :type=\"type\"\n @click=\"copy\"\n >\n <!-- The glyph swap is the feedback's visual half only — never its only\n carrier. The announcement carries the state to assistive technology,\n and the accessible name stays `copy` throughout: a button whose name\n changes under a screen reader's cursor is its own confusion. -->\n <Check v-if=\"state === 'copied'\" class=\"h-4 w-4\" aria-hidden=\"true\" />\n <X v-else-if=\"state === 'failed'\" class=\"h-4 w-4\" aria-hidden=\"true\" />\n <Copy v-else class=\"h-4 w-4\" aria-hidden=\"true\" />\n </IconButton>\n</template>\n"],"mappings":";;;;;;;;;AAYA,IAAa,qBAAuC;CAClD,MAAM;CACN,QAAQ;CACR,QAAQ;AACV;;AAGA,IAAa,iBAAiB;;;;;;;;;;;;;;;;EAU9B,MAAM,QAAQ;;;;;;;EAgCd,MAAM,WAAW,YAAY;EAM7B,MAAM,OAAO,UAAU,cAAc,0BAA0B,MAAM,MAAM;;;;;;;EAS3E,MAAM,QAAQ,IAAe,MAAM;EACnC,IAAI,UAAU;EACd,IAAI,cAAoD;EAExD,SAAS,iBAAuB;GAC9B,IAAI,gBAAgB,MAAM,aAAa,WAAW;GAClD,cAAc,iBAAiB;IAC7B,MAAM,QAAQ;IACd,cAAc;GAChB,GAAG,cAAc;EACnB;EAEA,sBAAsB;GAGpB,IAAI,gBAAgB,MAAM,aAAa,WAAW;GAClD,cAAc;EAChB,CAAC;EAED,eAAe,OAAsB;GACnC,IAAI,MAAM,YAAY,SAAS;GAC/B,UAAU;GACV,IAAI;IAIF,MAAM,QAAQ,MAAM,UAAU,MAAM,MAAM,QAAQ,IAAK,MAAM,SAAS;IACtE,MAAM,UAAU,UAAU,UAAU,KAAK;IACzC,MAAM,QAAQ;IACd,SAAS,KAAK,MAAM,MAAM;GAC5B,QAAQ;IACN,MAAM,QAAQ;IACd,SAAS,KAAK,MAAM,MAAM;GAC5B,UAAU;IACR,UAAU;IACV,eAAe;GACjB;EACF;;GAIE,OAAA,UAAA,GAAA,YAea,MAAA,kBAAA,GAAA;IAdV,OAAO,MAAA,IAAA,CAAI,CAAC;IACZ,SAAS,QAAA;IACT,MAAM,QAAA;IACN,UAAU,QAAA;IACV,MAAM,QAAA;IACN,SAAO;;IAMK,SAAA,cAAA,CAAA,MAAA,UAAK,YAAlB,UAAA,GAAA,YAAsE,MAAA,KAAA,GAAA;;KAArC,OAAM;KAAU,eAAY;IAC/C,CAAA,KAAA,MAAA,UAAK,YAAnB,UAAA,GAAA,YAAuE,MAAA,CAAA,GAAA;;KAArC,OAAM;KAAU,eAAY;IAC9D,CAAA,MAAA,UAAA,GAAA,YAAkD,MAAA,IAAA,GAAA;;KAArC,OAAM;KAAU,eAAY"}
@@ -1,3 +0,0 @@
1
- import "./CopyButton.vue_vue_type_script_setup_true_lang.js";
2
- import CopyButton_default from "./CopyButton.js";
3
- export { CopyButton_default as default };
@@ -1 +0,0 @@
1
- {"version":3,"file":"DataGrid.js","names":[],"sources":["../../../../../packages/primitives/data-grid/src/DataGrid.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { DataGridLabels } from \"@ecoma-io/loom-labels\";\nimport type { TableAlign, TableDensity } from \"@ecoma-io/loom-table\";\n\n/**\n * Loom's English, co-located with the component so it tree-shakes with it,\n * and exported so a host can build a partial vocabulary against the real\n * thing rather than a transcription of it.\n */\nexport const DATA_GRID_LABELS: DataGridLabels = {\n region: \"Data grid\",\n selectAll: \"Select all rows\",\n selectRow: \"Select row\",\n sortedAscending: \"Sorted ascending\",\n sortedDescending: \"Sorted descending\",\n sort: \"Sort\",\n};\n\n/** One column: what it reads, whether it sorts, how it aligns. */\nexport interface DataGridColumn {\n /** The row field this column renders; also the sort key. */\n key: string;\n /** The column header's text. */\n header: string;\n /** Renders the header as the tri-state sort control. */\n sortable?: boolean;\n /** Text alignment; numeric columns want `\"right\"`. */\n align?: TableAlign;\n /** Any CSS width, e.g. `\"6rem\"` — pins the column in the scrolling grid. */\n width?: string;\n}\n\n/** Sort direction, compact union — `aria-sort` takes the full ARIA tokens. */\nexport type DataGridSort = \"asc\" | \"desc\";\n\n/** Which column is sorted, and which way. Absent: nothing is. */\nexport type DataGridSortState = { key: string; direction: DataGridSort } | undefined;\n\n/**\n * DataGrid — the WAI-ARIA grids pattern: `Table`'s visual language with the\n * interactive half added. Table reads, DataGrid acts — rows are selectable\n * (`v-model:selectedRowKeys`, select-all with a real `aria-checked=\"mixed\"`),\n * sortable headers carry `aria-sort`, and a row answers Enter/double-click\n * through `@row-activate`.\n *\n * The keyboard model is the APG one, and it is the reason this is not a\n * Table variant: the cell matrix holds exactly one Tab stop (roving\n * tabindex), so Tab enters and leaves the grid once while the arrow keys,\n * Home/End and their Ctrl variants move focus cell to cell. Focus — not\n * the pointer — is what a grid sells.\n *\n * There is no `aria-rowcount` on purpose: every row is in the DOM, so the\n * count is the DOM's to state. The attribute earns its place the day the\n * grid virtualizes, not before — an asserted virtual size over a real\n * partial DOM is the lie `aria-rowcount` exists to correct.\n */\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport { ChevronDown, ChevronsUpDown, ChevronUp } from \"@lucide/vue\";\nimport { cn } from \"@ecoma-io/loom-core\";\nimport Checkbox from \"@ecoma-io/loom-checkbox\";\nimport { useLabels, type LabelOverrides } from \"@ecoma-io/loom-labels\";\nimport { headAlignClass, nextSort, tableRowVariants } from \"@ecoma-io/loom-table\";\n\nconst props = withDefaults(\n defineProps<{\n /** The columns, left to right. */\n columns: DataGridColumn[];\n /** The row objects; a column renders `row[column.key]`. */\n rows: Array<Record<string, unknown>>;\n /** The row field whose value keys selection. Defaults to `\"id\"`. */\n rowKey?: string;\n /** Adds the selection column: per-row checkboxes plus select-all with its mixed state. */\n selectable?: boolean;\n /**\n * The selected row keys when the host owns the selection through\n * `v-model:selectedRowKeys`; omit the binding and the grid owns the\n * state itself while still reporting every change.\n */\n selectedRowKeys?: Array<string | number>;\n /**\n * The active sort when the host owns it through `v-model:sort`; omit it\n * and the headers cycle on their own while still reporting each change.\n */\n sort?: DataGridSortState;\n /** Row padding. Compact suits dense application chrome. */\n density?: TableDensity;\n /** The grid's accessible name, read before a screen reader enters it. */\n caption?: string;\n /** Names what the grid says on its own account, as any subset of `DataGridLabels`. */\n labels?: LabelOverrides<DataGridLabels>;\n }>(),\n { rowKey: \"id\", selectable: false, density: \"comfortable\" },\n);\n\nconst emit = defineEmits<{\n \"update:selectedRowKeys\": [value: Array<string | number>];\n \"update:sort\": [value: DataGridSortState];\n \"sort-change\": [value: DataGridSortState];\n rowActivate: [row: Record<string, unknown>];\n}>();\n\n// `text`, not `labels`: the prop of that name is one of the three sources\n// this resolves (own prop, then the host vocabulary from\n// `provideLoomLabels`, then these English defaults), and a template reading\n// the raw prop would be reading the overrides rather than the answer.\nconst text = useLabels(\"dataGrid\", DATA_GRID_LABELS, () => props.labels);\n\n// ---------- selection ----------\n\nconst innerSelected = ref<Array<string | number>>([]);\nconst selected = computed(() => props.selectedRowKeys ?? innerSelected.value);\n\nconst keyOf = (row: Record<string, unknown>): string | number =>\n row[props.rowKey] as string | number;\nconst isSelected = (row: Record<string, unknown>): boolean => selected.value.includes(keyOf(row));\n\nfunction setSelection(next: Array<string | number>): void {\n innerSelected.value = next;\n emit(\"update:selectedRowKeys\", next);\n}\n\nconst allSelected = computed(\n () => props.rows.length > 0 && props.rows.every((row) => isSelected(row)),\n);\nconst someSelected = computed(\n () => !allSelected.value && props.rows.some((row) => isSelected(row)),\n);\n\n// Checkbox's own third state: reka renders it as `aria-checked=\"mixed\"`,\n// which is the select-all announcement the grid owes — a dash glyph alone is\n// shape-only semantics.\nconst selectAllState = computed<\"indeterminate\" | boolean>(() =>\n allSelected.value ? true : someSelected.value ? \"indeterminate\" : false,\n);\n\nfunction toggleAll(): void {\n setSelection(allSelected.value ? [] : props.rows.map((row) => keyOf(row)));\n}\n\nfunction toggleRow(row: Record<string, unknown>): void {\n setSelection(\n isSelected(row)\n ? selected.value.filter((key) => key !== keyOf(row))\n : [...selected.value, keyOf(row)],\n );\n}\n\nconst innerSort = ref<DataGridSortState>(undefined);\nconst currentSort = computed<DataGridSortState>(() => props.sort ?? innerSort.value);\n\nconst sortDirectionOf = (col: DataGridColumn): DataGridSort | undefined =>\n currentSort.value?.key === col.key ? currentSort.value.direction : undefined;\n\nconst ARIA_SORT = { asc: \"ascending\", desc: \"descending\" } as const;\nconst SORT_ICON = { asc: ChevronUp, desc: ChevronDown } as const;\nconst ariaSortOf = (col: DataGridColumn): (typeof ARIA_SORT)[DataGridSort] | undefined => {\n const direction = sortDirectionOf(col);\n return direction ? ARIA_SORT[direction] : undefined;\n};\nconst sortIconOf = (col: DataGridColumn) => {\n const direction = sortDirectionOf(col);\n return direction ? SORT_ICON[direction] : ChevronsUpDown;\n};\nconst sortWordsOf = (col: DataGridColumn): string => {\n const direction = sortDirectionOf(col);\n return direction === \"asc\"\n ? text.value.sortedAscending\n : direction === \"desc\"\n ? text.value.sortedDescending\n : text.value.sort;\n};\n\nfunction toggleSort(col: DataGridColumn): void {\n const direction = nextSort(sortDirectionOf(col));\n const next: DataGridSortState = direction ? { key: col.key, direction } : undefined;\n innerSort.value = next;\n // `sort-change` for hosts following the sketch's `@sort-change`,\n // `update:sort` so `v-model:sort` works the way every other control's does.\n emit(\"update:sort\", next);\n emit(\"sort-change\", next);\n}\n\nconst colCount = computed(() => props.columns.length + (props.selectable ? 1 : 0));\n\n// Rows: -1 is the header row, 0.. are body rows. Columns count the selection\n// column first when `selectable`. Exactly one cell carries tabindex 0 — the\n// active cell — so Tab enters and leaves the grid once; everything else is\n// -1 and reachable only through the matrix moves.\nconst activeCell = ref({ row: props.rows.length > 0 ? 0 : -1, col: 0 });\nconst bodyColumnIndex = (i: number): number => (props.selectable ? i + 1 : i);\nconst isCellActive = (row: number, col: number): boolean =>\n activeCell.value.row === row && activeCell.value.col === col;\n\n// Rows arriving or leaving can strand the active cell outside the matrix. The\n// floor is -1, not 0: the header row is a valid roving stop too, and a floor\n// of 0 would push the header onto a body row that does not exist once every\n// row is gone, leaving the grid with no Tab stop at all.\nwatch(\n () => [props.rows.length, props.selectable, props.columns.length] as const,\n () => {\n const previous = activeCell.value;\n const next = {\n row: Math.min(Math.max(previous.row, -1), Math.max(props.rows.length - 1, -1)),\n col: Math.min(previous.col, colCount.value - 1),\n };\n activeCell.value = next;\n // A shrink that moves the active cell strands real focus too: the focused\n // cell unmounts, focus falls to <body>, and onFocusin — which only hears\n // focus arriving inside the grid — never learns. The clamped cell is\n // within the surviving matrix, so it exists to take focus back.\n if (\n (previous.row !== next.row || previous.col !== next.col) &&\n table.value?.contains(document.activeElement)\n ) {\n focusCell(next.row, next.col);\n }\n },\n);\n\nconst table = ref<HTMLElement | null>(null);\nconst region = ref<HTMLElement | null>(null);\n\nfunction focusCell(row: number, col: number): void {\n activeCell.value = { row, col };\n table.value?.querySelector<HTMLElement>(`[data-r='${row}'][data-c='${col}']`)?.focus();\n}\n\nfunction moveTo(row: number, col: number): void {\n focusCell(\n // The floor is -1, not 0, for the same reason the watcher below uses it:\n // with no body row, 0 would clamp onto a row that does not exist and\n // strand the grid with no Tab stop (the header is `data-r=\"-1\"`).\n Math.min(Math.max(row, -1), Math.max(props.rows.length - 1, -1)),\n Math.min(Math.max(col, 0), colCount.value - 1),\n );\n}\n\n// Focus can also arrive outside the keymap — a pointer tap lands directly on\n// a cell — and the roving Tab stop has to follow whoever actually holds it.\nfunction onFocusin(event: FocusEvent): void {\n const cell = (event.target as Element).closest(\"[data-r]\");\n if (cell) {\n activeCell.value = {\n row: Number(cell.getAttribute(\"data-r\")),\n col: Number(cell.getAttribute(\"data-c\")),\n };\n }\n}\n\nfunction activateCell(row: number, col: number): void {\n if (row < 0) {\n const col_ = props.columns[col - (props.selectable ? 1 : 0)];\n if (col_?.sortable) toggleSort(col_);\n return;\n }\n const target = props.rows[row];\n if (target) emit(\"rowActivate\", target);\n}\n\nfunction spaceCell(row: number, col: number): void {\n if (!props.selectable) return;\n if (row < 0) {\n if (col === 0) toggleAll();\n return;\n }\n const target = props.rows[row];\n if (target) toggleRow(target);\n}\n\nfunction onKeydown(event: KeyboardEvent): void {\n const cell = (event.target as Element).closest(\"[data-r]\");\n if (!cell) return;\n const row = Number(cell.getAttribute(\"data-r\"));\n const col = Number(cell.getAttribute(\"data-c\"));\n const lastRow = Math.max(props.rows.length - 1, 0);\n const lastCol = colCount.value - 1;\n\n switch (event.key) {\n case \"ArrowRight\":\n moveTo(row, col + 1);\n break;\n case \"ArrowLeft\":\n moveTo(row, col - 1);\n break;\n case \"ArrowDown\":\n moveTo(row + 1, col);\n break;\n case \"ArrowUp\":\n moveTo(row - 1, col);\n break;\n case \"Home\":\n event.ctrlKey || event.metaKey ? moveTo(0, 0) : moveTo(row, 0);\n break;\n case \"End\":\n event.ctrlKey || event.metaKey ? moveTo(lastRow, lastCol) : moveTo(row, lastCol);\n break;\n case \"Enter\":\n activateCell(row, col);\n break;\n case \" \":\n spaceCell(row, col);\n break;\n default:\n return;\n }\n event.preventDefault();\n}\n\n// ---------- scroll region (Table's mechanism, verbatim in spirit) ----------\n\n// The region is focusable only while it can actually scroll: a Tab stop that\n// never moves is a dead one. Overflow is measured, not assumed.\nconst scrollable = ref(false);\n\nfunction measure(): void {\n const el = region.value;\n if (el) scrollable.value = el.scrollWidth > el.clientWidth;\n}\n\nlet observer: ResizeObserver | undefined;\nonMounted(() => {\n measure();\n observer = new ResizeObserver(measure);\n if (table.value) observer.observe(table.value);\n window.addEventListener(\"resize\", measure, { passive: true });\n});\nonBeforeUnmount(() => {\n observer?.disconnect();\n window.removeEventListener(\"resize\", measure);\n});\n</script>\n\n<template>\n <!-- A scroll container, not the table itself, for the reason Table's\n wrapper documents: a wide grid overflows its region instead of\n stretching the page. -->\n <div\n ref=\"region\"\n role=\"region\"\n :aria-label=\"caption ?? text.region\"\n :tabindex=\"scrollable ? 0 : undefined\"\n class=\"w-full overflow-x-auto rounded-lg focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\"\n >\n <!-- Roving focus ring, not focus-visible: the moves that matter here are\n programmatic (arrow keys), and a ring that only answers\n focus-visible hides the one thing a grid must never hide — which\n cell holds focus. -->\n <!-- tabindex=\"-1\" marks the interactive grid focusable without adding a\n Tab stop: the cells own the single roving stop, the container is\n only a target for programmatic/assistive-tech focus. -->\n <table\n ref=\"table\"\n role=\"grid\"\n tabindex=\"-1\"\n :data-density=\"density\"\n class=\"w-full border-collapse text-left text-sm focus:outline-none [&_th]:border-b [&_th]:border-border-strong [&_th]:px-3 [&_th]:py-2.5 [&_th]:text-xs [&_th]:font-semibold [&_th]:text-muted-foreground [&_th]:whitespace-nowrap [&_td]:border-b [&_td]:border-border [&_td]:px-3 [&_td]:align-top [&_td]:text-foreground [&[data-density='comfortable']_td]:py-3 [&[data-density='compact']_td]:py-1.5 [&[data-density='compact']_th]:py-1.5 [&_tbody_tr:last-child_td]:border-b-0\"\n @keydown=\"onKeydown\"\n @focusin=\"onFocusin\"\n >\n <thead>\n <!-- Inside role=\"grid\" the native tr→row mapping does not apply; the\n plugin cannot see the ancestor role, so the explicit role is load-bearing. -->\n <!-- eslint-disable-next-line vuejs-accessibility/no-redundant-roles -->\n <tr role=\"row\">\n <!-- eslint-disable-next-line vuejs-accessibility/no-redundant-roles -->\n <th\n v-if=\"selectable\"\n scope=\"col\"\n role=\"columnheader\"\n data-r=\"-1\"\n :data-c=\"0\"\n :tabindex=\"isCellActive(-1, 0) ? 0 : -1\"\n class=\"focus:outline-2 focus:-outline-offset-2 focus:outline-ring\"\n >\n <Checkbox\n :model-value=\"selectAllState\"\n :aria-label=\"text.selectAll\"\n tabindex=\"-1\"\n @update:model-value=\"toggleAll()\"\n />\n </th>\n <!-- eslint-disable-next-line vuejs-accessibility/no-redundant-roles -->\n <th\n v-for=\"(col, i) in columns\"\n :key=\"col.key\"\n scope=\"col\"\n role=\"columnheader\"\n :aria-sort=\"ariaSortOf(col)\"\n :data-r=\"-1\"\n :data-c=\"bodyColumnIndex(i)\"\n :tabindex=\"isCellActive(-1, bodyColumnIndex(i)) ? 0 : -1\"\n :style=\"col.width ? { width: col.width } : undefined\"\n :class=\"\n cn(\n headAlignClass(col.align),\n 'focus:outline-2 focus:-outline-offset-2 focus:outline-ring',\n )\n \"\n >\n <!-- The sort button is reachable only through its header cell:\n a second Tab stop inside the matrix would break the\n enter-once contract. Enter on the cell sorts instead. -->\n <button\n v-if=\"col.sortable\"\n type=\"button\"\n tabindex=\"-1\"\n class=\"inline-flex min-h-6 items-center gap-1 rounded-sm px-1 transition-colors duration-fast ease-out hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\"\n @click=\"toggleSort(col)\"\n >\n <span class=\"inline-flex items-center gap-1 font-semibold\">{{ col.header }}</span>\n <component\n :is=\"sortIconOf(col)\"\n class=\"h-3.5 w-3.5 shrink-0 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n <span class=\"sr-only\">{{ sortWordsOf(col) }}</span>\n </button>\n <template v-else>{{ col.header }}</template>\n </th>\n </tr>\n </thead>\n <tbody>\n <!-- eslint-disable-next-line vuejs-accessibility/no-redundant-roles -->\n <tr\n v-for=\"(row, r) in rows\"\n :key=\"String(keyOf(row))\"\n role=\"row\"\n :aria-selected=\"selectable ? isSelected(row) : undefined\"\n :class=\"\n cn(\n tableRowVariants({\n state: selectable ? (isSelected(row) ? 'selected' : 'interactive') : 'none',\n }),\n )\n \"\n @dblclick=\"emit('rowActivate', row)\"\n >\n <td\n v-if=\"selectable\"\n role=\"gridcell\"\n :data-r=\"r\"\n :data-c=\"0\"\n :tabindex=\"isCellActive(r, 0) ? 0 : -1\"\n class=\"focus:outline-2 focus:-outline-offset-2 focus:outline-ring\"\n >\n <Checkbox\n :model-value=\"isSelected(row)\"\n :aria-label=\"text.selectRow\"\n tabindex=\"-1\"\n @update:model-value=\"toggleRow(row)\"\n />\n </td>\n <td\n v-for=\"(col, i) in columns\"\n :key=\"col.key\"\n role=\"gridcell\"\n :data-r=\"r\"\n :data-c=\"bodyColumnIndex(i)\"\n :tabindex=\"isCellActive(r, bodyColumnIndex(i)) ? 0 : -1\"\n :class=\"\n cn(\n headAlignClass(col.align),\n 'focus:outline-2 focus:-outline-offset-2 focus:outline-ring',\n )\n \"\n >\n <!-- @slot One cell's content — a Badge, a RowActions cluster —\n with `row`, `column` and `value` scoped in. -->\n <slot name=\"cell\" :row=\"row\" :column=\"col\" :value=\"row[col.key]\">\n {{ row[col.key] ?? \"\" }}\n </slot>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n</template>\n"],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"DataGrid.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../../../packages/primitives/data-grid/src/DataGrid.vue"],"sourcesContent":["<script lang=\"ts\">\nimport type { DataGridLabels } from \"@ecoma-io/loom-labels\";\nimport type { TableAlign, TableDensity } from \"@ecoma-io/loom-table\";\n\n/**\n * Loom's English, co-located with the component so it tree-shakes with it,\n * and exported so a host can build a partial vocabulary against the real\n * thing rather than a transcription of it.\n */\nexport const DATA_GRID_LABELS: DataGridLabels = {\n region: \"Data grid\",\n selectAll: \"Select all rows\",\n selectRow: \"Select row\",\n sortedAscending: \"Sorted ascending\",\n sortedDescending: \"Sorted descending\",\n sort: \"Sort\",\n};\n\n/** One column: what it reads, whether it sorts, how it aligns. */\nexport interface DataGridColumn {\n /** The row field this column renders; also the sort key. */\n key: string;\n /** The column header's text. */\n header: string;\n /** Renders the header as the tri-state sort control. */\n sortable?: boolean;\n /** Text alignment; numeric columns want `\"right\"`. */\n align?: TableAlign;\n /** Any CSS width, e.g. `\"6rem\"` — pins the column in the scrolling grid. */\n width?: string;\n}\n\n/** Sort direction, compact union — `aria-sort` takes the full ARIA tokens. */\nexport type DataGridSort = \"asc\" | \"desc\";\n\n/** Which column is sorted, and which way. Absent: nothing is. */\nexport type DataGridSortState = { key: string; direction: DataGridSort } | undefined;\n\n/**\n * DataGrid — the WAI-ARIA grids pattern: `Table`'s visual language with the\n * interactive half added. Table reads, DataGrid acts — rows are selectable\n * (`v-model:selectedRowKeys`, select-all with a real `aria-checked=\"mixed\"`),\n * sortable headers carry `aria-sort`, and a row answers Enter/double-click\n * through `@row-activate`.\n *\n * The keyboard model is the APG one, and it is the reason this is not a\n * Table variant: the cell matrix holds exactly one Tab stop (roving\n * tabindex), so Tab enters and leaves the grid once while the arrow keys,\n * Home/End and their Ctrl variants move focus cell to cell. Focus — not\n * the pointer — is what a grid sells.\n *\n * There is no `aria-rowcount` on purpose: every row is in the DOM, so the\n * count is the DOM's to state. The attribute earns its place the day the\n * grid virtualizes, not before — an asserted virtual size over a real\n * partial DOM is the lie `aria-rowcount` exists to correct.\n */\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref, watch } from \"vue\";\nimport { ChevronDown, ChevronsUpDown, ChevronUp } from \"@lucide/vue\";\nimport { cn } from \"@ecoma-io/loom-core\";\nimport Checkbox from \"@ecoma-io/loom-checkbox\";\nimport { useLabels, type LabelOverrides } from \"@ecoma-io/loom-labels\";\nimport { headAlignClass, nextSort, tableRowVariants } from \"@ecoma-io/loom-table\";\n\nconst props = withDefaults(\n defineProps<{\n /** The columns, left to right. */\n columns: DataGridColumn[];\n /** The row objects; a column renders `row[column.key]`. */\n rows: Array<Record<string, unknown>>;\n /** The row field whose value keys selection. Defaults to `\"id\"`. */\n rowKey?: string;\n /** Adds the selection column: per-row checkboxes plus select-all with its mixed state. */\n selectable?: boolean;\n /**\n * The selected row keys when the host owns the selection through\n * `v-model:selectedRowKeys`; omit the binding and the grid owns the\n * state itself while still reporting every change.\n */\n selectedRowKeys?: Array<string | number>;\n /**\n * The active sort when the host owns it through `v-model:sort`; omit it\n * and the headers cycle on their own while still reporting each change.\n */\n sort?: DataGridSortState;\n /** Row padding. Compact suits dense application chrome. */\n density?: TableDensity;\n /** The grid's accessible name, read before a screen reader enters it. */\n caption?: string;\n /** Names what the grid says on its own account, as any subset of `DataGridLabels`. */\n labels?: LabelOverrides<DataGridLabels>;\n }>(),\n { rowKey: \"id\", selectable: false, density: \"comfortable\" },\n);\n\nconst emit = defineEmits<{\n \"update:selectedRowKeys\": [value: Array<string | number>];\n \"update:sort\": [value: DataGridSortState];\n \"sort-change\": [value: DataGridSortState];\n rowActivate: [row: Record<string, unknown>];\n}>();\n\n// `text`, not `labels`: the prop of that name is one of the three sources\n// this resolves (own prop, then the host vocabulary from\n// `provideLoomLabels`, then these English defaults), and a template reading\n// the raw prop would be reading the overrides rather than the answer.\nconst text = useLabels(\"dataGrid\", DATA_GRID_LABELS, () => props.labels);\n\n// ---------- selection ----------\n\nconst innerSelected = ref<Array<string | number>>([]);\nconst selected = computed(() => props.selectedRowKeys ?? innerSelected.value);\n\nconst keyOf = (row: Record<string, unknown>): string | number =>\n row[props.rowKey] as string | number;\nconst isSelected = (row: Record<string, unknown>): boolean => selected.value.includes(keyOf(row));\n\nfunction setSelection(next: Array<string | number>): void {\n innerSelected.value = next;\n emit(\"update:selectedRowKeys\", next);\n}\n\nconst allSelected = computed(\n () => props.rows.length > 0 && props.rows.every((row) => isSelected(row)),\n);\nconst someSelected = computed(\n () => !allSelected.value && props.rows.some((row) => isSelected(row)),\n);\n\n// Checkbox's own third state: reka renders it as `aria-checked=\"mixed\"`,\n// which is the select-all announcement the grid owes — a dash glyph alone is\n// shape-only semantics.\nconst selectAllState = computed<\"indeterminate\" | boolean>(() =>\n allSelected.value ? true : someSelected.value ? \"indeterminate\" : false,\n);\n\nfunction toggleAll(): void {\n setSelection(allSelected.value ? [] : props.rows.map((row) => keyOf(row)));\n}\n\nfunction toggleRow(row: Record<string, unknown>): void {\n setSelection(\n isSelected(row)\n ? selected.value.filter((key) => key !== keyOf(row))\n : [...selected.value, keyOf(row)],\n );\n}\n\nconst innerSort = ref<DataGridSortState>(undefined);\nconst currentSort = computed<DataGridSortState>(() => props.sort ?? innerSort.value);\n\nconst sortDirectionOf = (col: DataGridColumn): DataGridSort | undefined =>\n currentSort.value?.key === col.key ? currentSort.value.direction : undefined;\n\nconst ARIA_SORT = { asc: \"ascending\", desc: \"descending\" } as const;\nconst SORT_ICON = { asc: ChevronUp, desc: ChevronDown } as const;\nconst ariaSortOf = (col: DataGridColumn): (typeof ARIA_SORT)[DataGridSort] | undefined => {\n const direction = sortDirectionOf(col);\n return direction ? ARIA_SORT[direction] : undefined;\n};\nconst sortIconOf = (col: DataGridColumn) => {\n const direction = sortDirectionOf(col);\n return direction ? SORT_ICON[direction] : ChevronsUpDown;\n};\nconst sortWordsOf = (col: DataGridColumn): string => {\n const direction = sortDirectionOf(col);\n return direction === \"asc\"\n ? text.value.sortedAscending\n : direction === \"desc\"\n ? text.value.sortedDescending\n : text.value.sort;\n};\n\nfunction toggleSort(col: DataGridColumn): void {\n const direction = nextSort(sortDirectionOf(col));\n const next: DataGridSortState = direction ? { key: col.key, direction } : undefined;\n innerSort.value = next;\n // `sort-change` for hosts following the sketch's `@sort-change`,\n // `update:sort` so `v-model:sort` works the way every other control's does.\n emit(\"update:sort\", next);\n emit(\"sort-change\", next);\n}\n\nconst colCount = computed(() => props.columns.length + (props.selectable ? 1 : 0));\n\n// Rows: -1 is the header row, 0.. are body rows. Columns count the selection\n// column first when `selectable`. Exactly one cell carries tabindex 0 — the\n// active cell — so Tab enters and leaves the grid once; everything else is\n// -1 and reachable only through the matrix moves.\nconst activeCell = ref({ row: props.rows.length > 0 ? 0 : -1, col: 0 });\nconst bodyColumnIndex = (i: number): number => (props.selectable ? i + 1 : i);\nconst isCellActive = (row: number, col: number): boolean =>\n activeCell.value.row === row && activeCell.value.col === col;\n\n// Rows arriving or leaving can strand the active cell outside the matrix. The\n// floor is -1, not 0: the header row is a valid roving stop too, and a floor\n// of 0 would push the header onto a body row that does not exist once every\n// row is gone, leaving the grid with no Tab stop at all.\nwatch(\n () => [props.rows.length, props.selectable, props.columns.length] as const,\n () => {\n const previous = activeCell.value;\n const next = {\n row: Math.min(Math.max(previous.row, -1), Math.max(props.rows.length - 1, -1)),\n col: Math.min(previous.col, colCount.value - 1),\n };\n activeCell.value = next;\n // A shrink that moves the active cell strands real focus too: the focused\n // cell unmounts, focus falls to <body>, and onFocusin — which only hears\n // focus arriving inside the grid — never learns. The clamped cell is\n // within the surviving matrix, so it exists to take focus back.\n if (\n (previous.row !== next.row || previous.col !== next.col) &&\n table.value?.contains(document.activeElement)\n ) {\n focusCell(next.row, next.col);\n }\n },\n);\n\nconst table = ref<HTMLElement | null>(null);\nconst region = ref<HTMLElement | null>(null);\n\nfunction focusCell(row: number, col: number): void {\n activeCell.value = { row, col };\n table.value?.querySelector<HTMLElement>(`[data-r='${row}'][data-c='${col}']`)?.focus();\n}\n\nfunction moveTo(row: number, col: number): void {\n focusCell(\n // The floor is -1, not 0, for the same reason the watcher below uses it:\n // with no body row, 0 would clamp onto a row that does not exist and\n // strand the grid with no Tab stop (the header is `data-r=\"-1\"`).\n Math.min(Math.max(row, -1), Math.max(props.rows.length - 1, -1)),\n Math.min(Math.max(col, 0), colCount.value - 1),\n );\n}\n\n// Focus can also arrive outside the keymap — a pointer tap lands directly on\n// a cell — and the roving Tab stop has to follow whoever actually holds it.\nfunction onFocusin(event: FocusEvent): void {\n const cell = (event.target as Element).closest(\"[data-r]\");\n if (cell) {\n activeCell.value = {\n row: Number(cell.getAttribute(\"data-r\")),\n col: Number(cell.getAttribute(\"data-c\")),\n };\n }\n}\n\nfunction activateCell(row: number, col: number): void {\n if (row < 0) {\n const col_ = props.columns[col - (props.selectable ? 1 : 0)];\n if (col_?.sortable) toggleSort(col_);\n return;\n }\n const target = props.rows[row];\n if (target) emit(\"rowActivate\", target);\n}\n\nfunction spaceCell(row: number, col: number): void {\n if (!props.selectable) return;\n if (row < 0) {\n if (col === 0) toggleAll();\n return;\n }\n const target = props.rows[row];\n if (target) toggleRow(target);\n}\n\nfunction onKeydown(event: KeyboardEvent): void {\n const cell = (event.target as Element).closest(\"[data-r]\");\n if (!cell) return;\n const row = Number(cell.getAttribute(\"data-r\"));\n const col = Number(cell.getAttribute(\"data-c\"));\n const lastRow = Math.max(props.rows.length - 1, 0);\n const lastCol = colCount.value - 1;\n\n switch (event.key) {\n case \"ArrowRight\":\n moveTo(row, col + 1);\n break;\n case \"ArrowLeft\":\n moveTo(row, col - 1);\n break;\n case \"ArrowDown\":\n moveTo(row + 1, col);\n break;\n case \"ArrowUp\":\n moveTo(row - 1, col);\n break;\n case \"Home\":\n event.ctrlKey || event.metaKey ? moveTo(0, 0) : moveTo(row, 0);\n break;\n case \"End\":\n event.ctrlKey || event.metaKey ? moveTo(lastRow, lastCol) : moveTo(row, lastCol);\n break;\n case \"Enter\":\n activateCell(row, col);\n break;\n case \" \":\n spaceCell(row, col);\n break;\n default:\n return;\n }\n event.preventDefault();\n}\n\n// ---------- scroll region (Table's mechanism, verbatim in spirit) ----------\n\n// The region is focusable only while it can actually scroll: a Tab stop that\n// never moves is a dead one. Overflow is measured, not assumed.\nconst scrollable = ref(false);\n\nfunction measure(): void {\n const el = region.value;\n if (el) scrollable.value = el.scrollWidth > el.clientWidth;\n}\n\nlet observer: ResizeObserver | undefined;\nonMounted(() => {\n measure();\n observer = new ResizeObserver(measure);\n if (table.value) observer.observe(table.value);\n window.addEventListener(\"resize\", measure, { passive: true });\n});\nonBeforeUnmount(() => {\n observer?.disconnect();\n window.removeEventListener(\"resize\", measure);\n});\n</script>\n\n<template>\n <!-- A scroll container, not the table itself, for the reason Table's\n wrapper documents: a wide grid overflows its region instead of\n stretching the page. -->\n <div\n ref=\"region\"\n role=\"region\"\n :aria-label=\"caption ?? text.region\"\n :tabindex=\"scrollable ? 0 : undefined\"\n class=\"w-full overflow-x-auto rounded-lg focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\"\n >\n <!-- Roving focus ring, not focus-visible: the moves that matter here are\n programmatic (arrow keys), and a ring that only answers\n focus-visible hides the one thing a grid must never hide — which\n cell holds focus. -->\n <!-- tabindex=\"-1\" marks the interactive grid focusable without adding a\n Tab stop: the cells own the single roving stop, the container is\n only a target for programmatic/assistive-tech focus. -->\n <table\n ref=\"table\"\n role=\"grid\"\n tabindex=\"-1\"\n :data-density=\"density\"\n class=\"w-full border-collapse text-left text-sm focus:outline-none [&_th]:border-b [&_th]:border-border-strong [&_th]:px-3 [&_th]:py-2.5 [&_th]:text-xs [&_th]:font-semibold [&_th]:text-muted-foreground [&_th]:whitespace-nowrap [&_td]:border-b [&_td]:border-border [&_td]:px-3 [&_td]:align-top [&_td]:text-foreground [&[data-density='comfortable']_td]:py-3 [&[data-density='compact']_td]:py-1.5 [&[data-density='compact']_th]:py-1.5 [&_tbody_tr:last-child_td]:border-b-0\"\n @keydown=\"onKeydown\"\n @focusin=\"onFocusin\"\n >\n <thead>\n <!-- Inside role=\"grid\" the native tr→row mapping does not apply; the\n plugin cannot see the ancestor role, so the explicit role is load-bearing. -->\n <!-- eslint-disable-next-line vuejs-accessibility/no-redundant-roles -->\n <tr role=\"row\">\n <!-- eslint-disable-next-line vuejs-accessibility/no-redundant-roles -->\n <th\n v-if=\"selectable\"\n scope=\"col\"\n role=\"columnheader\"\n data-r=\"-1\"\n :data-c=\"0\"\n :tabindex=\"isCellActive(-1, 0) ? 0 : -1\"\n class=\"focus:outline-2 focus:-outline-offset-2 focus:outline-ring\"\n >\n <Checkbox\n :model-value=\"selectAllState\"\n :aria-label=\"text.selectAll\"\n tabindex=\"-1\"\n @update:model-value=\"toggleAll()\"\n />\n </th>\n <!-- eslint-disable-next-line vuejs-accessibility/no-redundant-roles -->\n <th\n v-for=\"(col, i) in columns\"\n :key=\"col.key\"\n scope=\"col\"\n role=\"columnheader\"\n :aria-sort=\"ariaSortOf(col)\"\n :data-r=\"-1\"\n :data-c=\"bodyColumnIndex(i)\"\n :tabindex=\"isCellActive(-1, bodyColumnIndex(i)) ? 0 : -1\"\n :style=\"col.width ? { width: col.width } : undefined\"\n :class=\"\n cn(\n headAlignClass(col.align),\n 'focus:outline-2 focus:-outline-offset-2 focus:outline-ring',\n )\n \"\n >\n <!-- The sort button is reachable only through its header cell:\n a second Tab stop inside the matrix would break the\n enter-once contract. Enter on the cell sorts instead. -->\n <button\n v-if=\"col.sortable\"\n type=\"button\"\n tabindex=\"-1\"\n class=\"inline-flex min-h-6 items-center gap-1 rounded-sm px-1 transition-colors duration-fast ease-out hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\"\n @click=\"toggleSort(col)\"\n >\n <span class=\"inline-flex items-center gap-1 font-semibold\">{{ col.header }}</span>\n <component\n :is=\"sortIconOf(col)\"\n class=\"h-3.5 w-3.5 shrink-0 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n <span class=\"sr-only\">{{ sortWordsOf(col) }}</span>\n </button>\n <template v-else>{{ col.header }}</template>\n </th>\n </tr>\n </thead>\n <tbody>\n <!-- eslint-disable-next-line vuejs-accessibility/no-redundant-roles -->\n <tr\n v-for=\"(row, r) in rows\"\n :key=\"String(keyOf(row))\"\n role=\"row\"\n :aria-selected=\"selectable ? isSelected(row) : undefined\"\n :class=\"\n cn(\n tableRowVariants({\n state: selectable ? (isSelected(row) ? 'selected' : 'interactive') : 'none',\n }),\n )\n \"\n @dblclick=\"emit('rowActivate', row)\"\n >\n <td\n v-if=\"selectable\"\n role=\"gridcell\"\n :data-r=\"r\"\n :data-c=\"0\"\n :tabindex=\"isCellActive(r, 0) ? 0 : -1\"\n class=\"focus:outline-2 focus:-outline-offset-2 focus:outline-ring\"\n >\n <Checkbox\n :model-value=\"isSelected(row)\"\n :aria-label=\"text.selectRow\"\n tabindex=\"-1\"\n @update:model-value=\"toggleRow(row)\"\n />\n </td>\n <td\n v-for=\"(col, i) in columns\"\n :key=\"col.key\"\n role=\"gridcell\"\n :data-r=\"r\"\n :data-c=\"bodyColumnIndex(i)\"\n :tabindex=\"isCellActive(r, bodyColumnIndex(i)) ? 0 : -1\"\n :class=\"\n cn(\n headAlignClass(col.align),\n 'focus:outline-2 focus:-outline-offset-2 focus:outline-ring',\n )\n \"\n >\n <!-- @slot One cell's content — a Badge, a RowActions cluster —\n with `row`, `column` and `value` scoped in. -->\n <slot name=\"cell\" :row=\"row\" :column=\"col\" :value=\"row[col.key]\">\n {{ row[col.key] ?? \"\" }}\n </slot>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n</template>\n"],"mappings":"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"}