@ecoma-io/loom 0.3.0 → 0.4.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 (398) hide show
  1. package/dist/index.js +38 -6
  2. package/dist/packages/blocks/app-header/src/AppHeader.js.map +1 -1
  3. package/dist/packages/blocks/app-header/src/AppHeader.vue.d.ts.map +1 -1
  4. package/dist/packages/blocks/app-header/src/AppHeader.vue_vue_type_script_setup_true_lang.js +1 -0
  5. package/dist/packages/blocks/app-header/src/AppHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  6. package/dist/packages/blocks/desktop-app-shell/src/DesktopAppShell.vue.d.ts +3 -3
  7. package/dist/packages/blocks/metric-card/src/MetricCard.js.map +1 -1
  8. package/dist/packages/blocks/metric-card/src/MetricCard.vue.d.ts +22 -4
  9. package/dist/packages/blocks/metric-card/src/MetricCard.vue.d.ts.map +1 -1
  10. package/dist/packages/blocks/metric-card/src/MetricCard.vue_vue_type_script_setup_true_lang.js +38 -15
  11. package/dist/packages/blocks/metric-card/src/MetricCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  12. package/dist/packages/blocks/title-bar/src/TitleBar.vue.d.ts +3 -3
  13. package/dist/packages/blocks/toast-stack/src/ToastStack.vue.d.ts +3 -3
  14. package/dist/packages/composition/scroll-reel/src/ScrollReel.js +2 -2
  15. package/dist/packages/composition/scroll-reel/src/ScrollReel.js.map +1 -1
  16. package/dist/packages/composition/scroll-reel/src/ScrollReel.vue.d.ts +26 -0
  17. package/dist/packages/composition/scroll-reel/src/ScrollReel.vue_vue_type_script_setup_true_lang.js +27 -7
  18. package/dist/packages/composition/scroll-reel/src/ScrollReel.vue_vue_type_script_setup_true_lang.js.map +1 -1
  19. package/dist/packages/composition/scroll-reel/src/index.d.ts +2 -1
  20. package/dist/packages/composition/scroll-reel/src/index.js +2 -1
  21. package/dist/packages/core/src/index.d.ts +1 -1
  22. package/dist/packages/core/src/index.d.ts.map +1 -1
  23. package/dist/packages/core/src/index.js +2 -2
  24. package/dist/packages/core/src/motion.d.ts +13 -0
  25. package/dist/packages/core/src/motion.d.ts.map +1 -1
  26. package/dist/packages/core/src/motion.js +20 -13
  27. package/dist/packages/core/src/motion.js.map +1 -1
  28. package/dist/packages/core/src/theme.d.ts +9 -0
  29. package/dist/packages/core/src/theme.d.ts.map +1 -1
  30. package/dist/packages/core/src/theme.js +36 -10
  31. package/dist/packages/core/src/theme.js.map +1 -1
  32. package/dist/packages/labels/src/ancestor-disabled.d.ts +5 -1
  33. package/dist/packages/labels/src/ancestor-disabled.d.ts.map +1 -1
  34. package/dist/packages/labels/src/ancestor-disabled.js +5 -1
  35. package/dist/packages/labels/src/ancestor-disabled.js.map +1 -1
  36. package/dist/packages/labels/src/component-shapes.d.ts +73 -0
  37. package/dist/packages/labels/src/component-shapes.d.ts.map +1 -1
  38. package/dist/packages/labels/src/date-labels.d.ts +8 -6
  39. package/dist/packages/labels/src/date-labels.d.ts.map +1 -1
  40. package/dist/packages/labels/src/date-labels.js +8 -6
  41. package/dist/packages/labels/src/date-labels.js.map +1 -1
  42. package/dist/packages/labels/src/index.d.ts +2 -2
  43. package/dist/packages/labels/src/index.d.ts.map +1 -1
  44. package/dist/packages/labels/src/label-registry.d.ts +7 -1
  45. package/dist/packages/labels/src/label-registry.d.ts.map +1 -1
  46. package/dist/packages/layouts/reading/src/Reading.js.map +1 -1
  47. package/dist/packages/layouts/reading/src/Reading.vue.d.ts +16 -15
  48. package/dist/packages/layouts/reading/src/Reading.vue.d.ts.map +1 -1
  49. package/dist/packages/layouts/reading/src/Reading.vue_vue_type_script_setup_true_lang.js.map +1 -1
  50. package/dist/packages/layouts/reading/src/index.d.ts +1 -0
  51. package/dist/packages/layouts/reading/src/index.d.ts.map +1 -1
  52. package/dist/packages/loom/src/a11y.d.ts +1 -1
  53. package/dist/packages/loom/src/index.d.ts +191 -174
  54. package/dist/packages/loom/src/theme.d.ts +3 -0
  55. package/dist/packages/primitives/alert/src/Alert.js +7 -0
  56. package/dist/packages/primitives/alert/src/Alert.js.map +1 -0
  57. package/dist/packages/primitives/alert/src/Alert.vue.d.ts +73 -0
  58. package/dist/packages/primitives/alert/src/Alert.vue_vue_type_script_setup_true_lang.js +127 -0
  59. package/dist/packages/primitives/alert/src/Alert.vue_vue_type_script_setup_true_lang.js.map +1 -0
  60. package/dist/packages/primitives/alert/src/index.d.ts +4 -0
  61. package/dist/packages/primitives/alert/src/index.js +3 -0
  62. package/dist/packages/primitives/alert-dialog/src/AlertDialog.js.map +1 -1
  63. package/dist/packages/primitives/alert-dialog/src/AlertDialog.vue.d.ts +2 -2
  64. package/dist/packages/primitives/alert-dialog/src/AlertDialog.vue_vue_type_script_setup_true_lang.js +2 -2
  65. package/dist/packages/primitives/alert-dialog/src/AlertDialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  66. package/dist/packages/primitives/alert-dialog/src/index.d.ts +1 -1
  67. package/dist/packages/primitives/avatar-group/src/AvatarGroup.vue.d.ts +3 -3
  68. package/dist/packages/primitives/avatar-group/src/index.d.ts +1 -1
  69. package/dist/packages/primitives/badge/src/Badge.js.map +1 -1
  70. package/dist/packages/primitives/badge/src/Badge.vue.d.ts.map +1 -1
  71. package/dist/packages/primitives/badge/src/Badge.vue_vue_type_script_setup_true_lang.js +1 -1
  72. package/dist/packages/primitives/badge/src/Badge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  73. package/dist/packages/primitives/breadcrumb/src/Breadcrumb.js +2 -2
  74. package/dist/packages/primitives/breadcrumb/src/Breadcrumb.js.map +1 -1
  75. package/dist/packages/primitives/breadcrumb/src/Breadcrumb.vue.d.ts +28 -0
  76. package/dist/packages/primitives/breadcrumb/src/Breadcrumb.vue_vue_type_script_setup_true_lang.js +16 -5
  77. package/dist/packages/primitives/breadcrumb/src/Breadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -1
  78. package/dist/packages/primitives/breadcrumb/src/index.d.ts +2 -1
  79. package/dist/packages/primitives/breadcrumb/src/index.js +2 -1
  80. package/dist/packages/primitives/button/src/Button.js.map +1 -1
  81. package/dist/packages/primitives/button/src/Button.vue.d.ts.map +1 -1
  82. package/dist/packages/primitives/button/src/Button.vue_vue_type_script_setup_true_lang.js.map +1 -1
  83. package/dist/packages/primitives/button/src/index.js +2 -2
  84. package/dist/packages/primitives/card/src/Card.js +7 -0
  85. package/dist/packages/primitives/card/src/Card.js.map +1 -0
  86. package/dist/packages/primitives/card/src/Card.vue.d.ts +72 -0
  87. package/dist/packages/primitives/card/src/Card.vue_vue_type_script_setup_true_lang.js +65 -0
  88. package/dist/packages/primitives/card/src/Card.vue_vue_type_script_setup_true_lang.js.map +1 -0
  89. package/dist/packages/primitives/card/src/index.d.ts +3 -0
  90. package/dist/packages/primitives/card/src/index.d.ts.map +1 -0
  91. package/dist/packages/primitives/card/src/index.js +2 -0
  92. package/dist/packages/primitives/carousel/src/Carousel.js +7 -0
  93. package/dist/packages/primitives/carousel/src/Carousel.js.map +1 -0
  94. package/dist/packages/primitives/carousel/src/Carousel.vue.d.ts +34 -0
  95. package/dist/packages/primitives/carousel/src/Carousel.vue_vue_type_script_setup_true_lang.js +175 -0
  96. package/dist/packages/primitives/carousel/src/Carousel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  97. package/dist/packages/primitives/carousel/src/index.d.ts +3 -0
  98. package/dist/packages/primitives/carousel/src/index.js +3 -0
  99. package/dist/packages/primitives/checkbox/src/Checkbox.js.map +1 -1
  100. package/dist/packages/primitives/checkbox/src/Checkbox.vue.d.ts +1 -1
  101. package/dist/packages/primitives/checkbox/src/Checkbox.vue.d.ts.map +1 -1
  102. package/dist/packages/primitives/checkbox/src/Checkbox.vue_vue_type_script_setup_true_lang.js +3 -3
  103. package/dist/packages/primitives/checkbox/src/Checkbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  104. package/dist/packages/primitives/chip/src/Chip.js.map +1 -1
  105. package/dist/packages/primitives/chip/src/Chip.vue.d.ts.map +1 -1
  106. package/dist/packages/primitives/chip/src/Chip.vue_vue_type_script_setup_true_lang.js +1 -1
  107. package/dist/packages/primitives/chip/src/Chip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  108. package/dist/packages/primitives/collapse/src/Collapse.js +7 -0
  109. package/dist/packages/primitives/collapse/src/Collapse.js.map +1 -0
  110. package/dist/packages/primitives/collapse/src/Collapse.vue.d.ts +56 -0
  111. package/dist/packages/primitives/collapse/src/Collapse.vue.d.ts.map +1 -0
  112. package/dist/packages/primitives/collapse/src/Collapse.vue_vue_type_script_setup_true_lang.js +81 -0
  113. package/dist/packages/primitives/collapse/src/Collapse.vue_vue_type_script_setup_true_lang.js.map +1 -0
  114. package/dist/packages/primitives/collapse/src/index.d.ts +2 -0
  115. package/dist/packages/primitives/collapse/src/index.d.ts.map +1 -0
  116. package/dist/packages/primitives/collapse/src/index.js +2 -0
  117. package/dist/packages/primitives/color-picker/src/ColorPicker.js.map +1 -1
  118. package/dist/packages/primitives/color-picker/src/ColorPicker.vue.d.ts +4 -4
  119. package/dist/packages/primitives/color-picker/src/ColorPicker.vue_vue_type_script_setup_true_lang.js +2 -2
  120. package/dist/packages/primitives/color-picker/src/ColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  121. package/dist/packages/primitives/color-picker/src/index.d.ts +1 -1
  122. package/dist/packages/primitives/combobox/src/Combobox.js.map +1 -1
  123. package/dist/packages/primitives/combobox/src/Combobox.vue.d.ts +2 -2
  124. package/dist/packages/primitives/combobox/src/Combobox.vue_vue_type_script_setup_true_lang.js +2 -2
  125. package/dist/packages/primitives/combobox/src/Combobox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  126. package/dist/packages/primitives/combobox/src/index.d.ts +1 -1
  127. package/dist/packages/primitives/context-menu/src/ContextMenu.js.map +1 -1
  128. package/dist/packages/primitives/context-menu/src/ContextMenu.vue.d.ts +12 -0
  129. package/dist/packages/primitives/context-menu/src/ContextMenu.vue.d.ts.map +1 -1
  130. package/dist/packages/primitives/context-menu/src/ContextMenu.vue_vue_type_script_setup_true_lang.js +7 -3
  131. package/dist/packages/primitives/context-menu/src/ContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  132. package/dist/packages/primitives/date-picker/src/DatePicker.js.map +1 -1
  133. package/dist/packages/primitives/date-picker/src/DatePicker.vue.d.ts +2 -2
  134. package/dist/packages/primitives/date-picker/src/DatePicker.vue_vue_type_script_setup_true_lang.js +1 -1
  135. package/dist/packages/primitives/date-picker/src/DatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  136. package/dist/packages/primitives/date-range-picker/src/DateRangePicker.js.map +1 -1
  137. package/dist/packages/primitives/date-range-picker/src/DateRangePicker.vue.d.ts +3 -3
  138. package/dist/packages/primitives/date-range-picker/src/DateRangePicker.vue_vue_type_script_setup_true_lang.js +1 -1
  139. package/dist/packages/primitives/date-range-picker/src/DateRangePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  140. package/dist/packages/primitives/date-range-picker/src/index.d.ts +1 -1
  141. package/dist/packages/primitives/date-time-picker/src/DateTimePicker.js.map +1 -1
  142. package/dist/packages/primitives/date-time-picker/src/DateTimePicker.vue.d.ts +2 -2
  143. package/dist/packages/primitives/date-time-picker/src/DateTimePicker.vue_vue_type_script_setup_true_lang.js +1 -1
  144. package/dist/packages/primitives/date-time-picker/src/DateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  145. package/dist/packages/primitives/date-time-range-picker/src/DateTimeRangePicker.js.map +1 -1
  146. package/dist/packages/primitives/date-time-range-picker/src/DateTimeRangePicker.vue.d.ts +3 -3
  147. package/dist/packages/primitives/date-time-range-picker/src/DateTimeRangePicker.vue_vue_type_script_setup_true_lang.js +1 -1
  148. package/dist/packages/primitives/date-time-range-picker/src/DateTimeRangePicker.vue_vue_type_script_setup_true_lang.js.map +1 -1
  149. package/dist/packages/primitives/date-time-range-picker/src/index.d.ts +1 -1
  150. package/dist/packages/primitives/dialog/src/Dialog.js.map +1 -1
  151. package/dist/packages/primitives/dialog/src/Dialog.vue.d.ts +12 -4
  152. package/dist/packages/primitives/dialog/src/Dialog.vue_vue_type_script_setup_true_lang.js +1 -1
  153. package/dist/packages/primitives/dialog/src/Dialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  154. package/dist/packages/primitives/dialog/src/index.d.ts +1 -1
  155. package/dist/packages/primitives/drawer/src/Drawer.js.map +1 -1
  156. package/dist/packages/primitives/drawer/src/Drawer.vue.d.ts +2 -2
  157. package/dist/packages/primitives/drawer/src/Drawer.vue_vue_type_script_setup_true_lang.js +2 -2
  158. package/dist/packages/primitives/drawer/src/Drawer.vue_vue_type_script_setup_true_lang.js.map +1 -1
  159. package/dist/packages/primitives/drawer/src/index.d.ts +1 -1
  160. package/dist/packages/primitives/dropdown-menu/src/DropdownMenu.js.map +1 -1
  161. package/dist/packages/primitives/dropdown-menu/src/DropdownMenu.vue.d.ts +26 -0
  162. package/dist/packages/primitives/dropdown-menu/src/DropdownMenu.vue.d.ts.map +1 -1
  163. package/dist/packages/primitives/dropdown-menu/src/DropdownMenu.vue_vue_type_script_setup_true_lang.js +10 -4
  164. package/dist/packages/primitives/dropdown-menu/src/DropdownMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  165. package/dist/packages/primitives/editable/src/Editable.js.map +1 -1
  166. package/dist/packages/primitives/editable/src/Editable.vue.d.ts +2 -2
  167. package/dist/packages/primitives/editable/src/Editable.vue_vue_type_script_setup_true_lang.js +1 -1
  168. package/dist/packages/primitives/editable/src/Editable.vue_vue_type_script_setup_true_lang.js.map +1 -1
  169. package/dist/packages/primitives/editable/src/index.d.ts +1 -1
  170. package/dist/packages/primitives/file-upload/src/FileUpload.js.map +1 -1
  171. package/dist/packages/primitives/file-upload/src/FileUpload.vue.d.ts +2 -2
  172. package/dist/packages/primitives/file-upload/src/FileUpload.vue_vue_type_script_setup_true_lang.js +1 -1
  173. package/dist/packages/primitives/file-upload/src/FileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -1
  174. package/dist/packages/primitives/file-upload/src/index.d.ts +1 -1
  175. package/dist/packages/primitives/hover-card/src/HoverCard.js.map +1 -1
  176. package/dist/packages/primitives/hover-card/src/HoverCard.vue.d.ts.map +1 -1
  177. package/dist/packages/primitives/hover-card/src/HoverCard.vue_vue_type_script_setup_true_lang.js +1 -1
  178. package/dist/packages/primitives/hover-card/src/HoverCard.vue_vue_type_script_setup_true_lang.js.map +1 -1
  179. package/dist/packages/primitives/icon-button/src/IconButton.js.map +1 -1
  180. package/dist/packages/primitives/icon-button/src/IconButton.vue.d.ts +10 -4
  181. package/dist/packages/primitives/icon-button/src/IconButton.vue.d.ts.map +1 -1
  182. package/dist/packages/primitives/icon-button/src/IconButton.vue_vue_type_script_setup_true_lang.js +18 -6
  183. package/dist/packages/primitives/icon-button/src/IconButton.vue_vue_type_script_setup_true_lang.js.map +1 -1
  184. package/dist/packages/primitives/indicator/src/Indicator.vue.d.ts +2 -2
  185. package/dist/packages/primitives/indicator/src/index.d.ts +1 -1
  186. package/dist/packages/primitives/kbd/src/Kbd.js +7 -0
  187. package/dist/packages/primitives/kbd/src/Kbd.js.map +1 -0
  188. package/dist/packages/primitives/kbd/src/Kbd.vue.d.ts +30 -0
  189. package/dist/packages/primitives/kbd/src/Kbd.vue.d.ts.map +1 -0
  190. package/dist/packages/primitives/kbd/src/Kbd.vue_vue_type_script_setup_true_lang.js +29 -0
  191. package/dist/packages/primitives/kbd/src/Kbd.vue_vue_type_script_setup_true_lang.js.map +1 -0
  192. package/dist/packages/primitives/kbd/src/index.d.ts +3 -0
  193. package/dist/packages/primitives/kbd/src/index.d.ts.map +1 -0
  194. package/dist/packages/primitives/kbd/src/index.js +3 -0
  195. package/dist/packages/primitives/link/src/Link.js.map +1 -1
  196. package/dist/packages/primitives/link/src/Link.vue.d.ts.map +1 -1
  197. package/dist/packages/primitives/link/src/Link.vue_vue_type_script_setup_true_lang.js +3 -3
  198. package/dist/packages/primitives/link/src/Link.vue_vue_type_script_setup_true_lang.js.map +1 -1
  199. package/dist/packages/primitives/list/src/List.js +7 -0
  200. package/dist/packages/primitives/list/src/List.js.map +1 -0
  201. package/dist/packages/primitives/list/src/List.vue.d.ts +22 -0
  202. package/dist/packages/primitives/list/src/List.vue.d.ts.map +1 -0
  203. package/dist/packages/primitives/list/src/List.vue_vue_type_script_setup_true_lang.js +27 -0
  204. package/dist/packages/primitives/list/src/List.vue_vue_type_script_setup_true_lang.js.map +1 -0
  205. package/dist/packages/primitives/list/src/ListItem.js +7 -0
  206. package/dist/packages/primitives/list/src/ListItem.js.map +1 -0
  207. package/dist/packages/primitives/list/src/ListItem.vue.d.ts +75 -0
  208. package/dist/packages/primitives/list/src/ListItem.vue.d.ts.map +1 -0
  209. package/dist/packages/primitives/list/src/ListItem.vue_vue_type_script_setup_true_lang.js +101 -0
  210. package/dist/packages/primitives/list/src/ListItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  211. package/dist/packages/primitives/list/src/index.d.ts +4 -0
  212. package/dist/packages/primitives/list/src/index.d.ts.map +1 -0
  213. package/dist/packages/primitives/list/src/index.js +3 -0
  214. package/dist/packages/primitives/menubar/src/Menubar.js.map +1 -1
  215. package/dist/packages/primitives/menubar/src/Menubar.vue.d.ts +20 -6
  216. package/dist/packages/primitives/menubar/src/Menubar.vue.d.ts.map +1 -1
  217. package/dist/packages/primitives/menubar/src/Menubar.vue_vue_type_script_setup_true_lang.js +178 -64
  218. package/dist/packages/primitives/menubar/src/Menubar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  219. package/dist/packages/primitives/number-field/src/NumberField.js.map +1 -1
  220. package/dist/packages/primitives/number-field/src/NumberField.vue.d.ts +2 -2
  221. package/dist/packages/primitives/number-field/src/NumberField.vue_vue_type_script_setup_true_lang.js +1 -0
  222. package/dist/packages/primitives/number-field/src/NumberField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  223. package/dist/packages/primitives/number-field/src/index.d.ts +1 -1
  224. package/dist/packages/primitives/otp-input/src/OtpInput.vue.d.ts +2 -2
  225. package/dist/packages/primitives/otp-input/src/index.d.ts +1 -1
  226. package/dist/packages/primitives/pagination/src/Pagination.js.map +1 -1
  227. package/dist/packages/primitives/pagination/src/Pagination.vue.d.ts +3 -3
  228. package/dist/packages/primitives/pagination/src/Pagination.vue_vue_type_script_setup_true_lang.js +1 -1
  229. package/dist/packages/primitives/pagination/src/Pagination.vue_vue_type_script_setup_true_lang.js.map +1 -1
  230. package/dist/packages/primitives/pagination/src/index.d.ts +1 -1
  231. package/dist/packages/primitives/popover/src/Popover.js.map +1 -1
  232. package/dist/packages/primitives/popover/src/Popover.vue.d.ts.map +1 -1
  233. package/dist/packages/primitives/popover/src/Popover.vue_vue_type_script_setup_true_lang.js +1 -1
  234. package/dist/packages/primitives/popover/src/Popover.vue_vue_type_script_setup_true_lang.js.map +1 -1
  235. package/dist/packages/primitives/progress/src/Progress.vue.d.ts +2 -2
  236. package/dist/packages/primitives/progress/src/index.d.ts +1 -1
  237. package/dist/packages/primitives/radial-progress/src/RadialProgress.vue.d.ts +2 -2
  238. package/dist/packages/primitives/radial-progress/src/index.d.ts +1 -1
  239. package/dist/packages/primitives/radio-group/src/RadioGroup.js.map +1 -1
  240. package/dist/packages/primitives/radio-group/src/RadioGroup.vue.d.ts.map +1 -1
  241. package/dist/packages/primitives/radio-group/src/RadioGroup.vue_vue_type_script_setup_true_lang.js +1 -1
  242. package/dist/packages/primitives/radio-group/src/RadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  243. package/dist/packages/primitives/rating/src/Rating.vue.d.ts +2 -2
  244. package/dist/packages/primitives/rating/src/index.d.ts +1 -1
  245. package/dist/packages/primitives/segmented-control/src/SegmentedControl.js.map +1 -1
  246. package/dist/packages/primitives/segmented-control/src/SegmentedControl.vue.d.ts.map +1 -1
  247. package/dist/packages/primitives/segmented-control/src/SegmentedControl.vue_vue_type_script_setup_true_lang.js +2 -3
  248. package/dist/packages/primitives/segmented-control/src/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map +1 -1
  249. package/dist/packages/primitives/select/src/Select.js.map +1 -1
  250. package/dist/packages/primitives/select/src/Select.vue.d.ts.map +1 -1
  251. package/dist/packages/primitives/select/src/Select.vue_vue_type_script_setup_true_lang.js +1 -1
  252. package/dist/packages/primitives/select/src/Select.vue_vue_type_script_setup_true_lang.js.map +1 -1
  253. package/dist/packages/primitives/slider/src/Slider.js.map +1 -1
  254. package/dist/packages/primitives/slider/src/Slider.vue.d.ts +6 -3
  255. package/dist/packages/primitives/slider/src/Slider.vue.d.ts.map +1 -1
  256. package/dist/packages/primitives/slider/src/Slider.vue_vue_type_script_setup_true_lang.js +15 -10
  257. package/dist/packages/primitives/slider/src/Slider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  258. package/dist/packages/primitives/stepper/src/Stepper.vue.d.ts +2 -2
  259. package/dist/packages/primitives/stepper/src/index.d.ts +1 -1
  260. package/dist/packages/primitives/switch/src/Switch.js.map +1 -1
  261. package/dist/packages/primitives/switch/src/Switch.vue.d.ts +1 -1
  262. package/dist/packages/primitives/switch/src/Switch.vue.d.ts.map +1 -1
  263. package/dist/packages/primitives/switch/src/Switch.vue_vue_type_script_setup_true_lang.js +3 -3
  264. package/dist/packages/primitives/switch/src/Switch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  265. package/dist/packages/primitives/table/src/Table.js +7 -0
  266. package/dist/packages/primitives/table/src/Table.js.map +1 -0
  267. package/dist/packages/primitives/table/src/Table.vue.d.ts +45 -0
  268. package/dist/packages/primitives/table/src/Table.vue_vue_type_script_setup_true_lang.js +72 -0
  269. package/dist/packages/primitives/table/src/Table.vue_vue_type_script_setup_true_lang.js.map +1 -0
  270. package/dist/packages/primitives/table/src/TableCell.js +7 -0
  271. package/dist/packages/primitives/table/src/TableCell.js.map +1 -0
  272. package/dist/packages/primitives/table/src/TableCell.vue.d.ts +19 -0
  273. package/dist/packages/primitives/table/src/TableCell.vue.d.ts.map +1 -0
  274. package/dist/packages/primitives/table/src/TableCell.vue_vue_type_script_setup_true_lang.js +17 -0
  275. package/dist/packages/primitives/table/src/TableCell.vue_vue_type_script_setup_true_lang.js.map +1 -0
  276. package/dist/packages/primitives/table/src/TableHead.js +7 -0
  277. package/dist/packages/primitives/table/src/TableHead.js.map +1 -0
  278. package/dist/packages/primitives/table/src/TableHead.vue.d.ts +56 -0
  279. package/dist/packages/primitives/table/src/TableHead.vue_vue_type_script_setup_true_lang.js +79 -0
  280. package/dist/packages/primitives/table/src/TableHead.vue_vue_type_script_setup_true_lang.js.map +1 -0
  281. package/dist/packages/primitives/table/src/TableRow.js +7 -0
  282. package/dist/packages/primitives/table/src/TableRow.js.map +1 -0
  283. package/dist/packages/primitives/table/src/TableRow.vue.d.ts +39 -0
  284. package/dist/packages/primitives/table/src/TableRow.vue.d.ts.map +1 -0
  285. package/dist/packages/primitives/table/src/TableRow.vue_vue_type_script_setup_true_lang.js +61 -0
  286. package/dist/packages/primitives/table/src/TableRow.vue_vue_type_script_setup_true_lang.js.map +1 -0
  287. package/dist/packages/primitives/table/src/index.d.ts +10 -0
  288. package/dist/packages/primitives/table/src/index.js +8 -0
  289. package/dist/packages/primitives/tabs/src/Tabs.js.map +1 -1
  290. package/dist/packages/primitives/tabs/src/Tabs.vue.d.ts.map +1 -1
  291. package/dist/packages/primitives/tabs/src/Tabs.vue_vue_type_script_setup_true_lang.js +1 -1
  292. package/dist/packages/primitives/tabs/src/Tabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  293. package/dist/packages/primitives/tags-input/src/TagsInput.js.map +1 -1
  294. package/dist/packages/primitives/tags-input/src/TagsInput.vue.d.ts +2 -2
  295. package/dist/packages/primitives/tags-input/src/TagsInput.vue_vue_type_script_setup_true_lang.js +1 -1
  296. package/dist/packages/primitives/tags-input/src/TagsInput.vue_vue_type_script_setup_true_lang.js.map +1 -1
  297. package/dist/packages/primitives/tags-input/src/index.d.ts +1 -1
  298. package/dist/packages/primitives/text-field/src/TextField.js.map +1 -1
  299. package/dist/packages/primitives/text-field/src/TextField.vue.d.ts +2 -2
  300. package/dist/packages/primitives/text-field/src/TextField.vue_vue_type_script_setup_true_lang.js +1 -1
  301. package/dist/packages/primitives/text-field/src/TextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  302. package/dist/packages/primitives/text-field/src/index.d.ts +1 -1
  303. package/dist/packages/primitives/text-field/src/index.js +2 -2
  304. package/dist/packages/primitives/textarea/src/Textarea.js.map +1 -1
  305. package/dist/packages/primitives/textarea/src/Textarea.vue.d.ts +2 -2
  306. package/dist/packages/primitives/textarea/src/Textarea.vue_vue_type_script_setup_true_lang.js +1 -1
  307. package/dist/packages/primitives/textarea/src/Textarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  308. package/dist/packages/primitives/textarea/src/index.d.ts +1 -1
  309. package/dist/packages/primitives/textarea/src/index.js +2 -2
  310. package/dist/packages/primitives/time-picker/src/TimePicker.vue.d.ts +2 -2
  311. package/dist/packages/primitives/timeline/src/Timeline.js +7 -0
  312. package/dist/packages/primitives/timeline/src/Timeline.js.map +1 -0
  313. package/dist/packages/primitives/timeline/src/Timeline.vue.d.ts +37 -0
  314. package/dist/packages/primitives/timeline/src/Timeline.vue_vue_type_script_setup_true_lang.js +44 -0
  315. package/dist/packages/primitives/timeline/src/Timeline.vue_vue_type_script_setup_true_lang.js.map +1 -0
  316. package/dist/packages/primitives/timeline/src/TimelineItem.js +7 -0
  317. package/dist/packages/primitives/timeline/src/TimelineItem.js.map +1 -0
  318. package/dist/packages/primitives/timeline/src/TimelineItem.vue.d.ts +50 -0
  319. package/dist/packages/primitives/timeline/src/TimelineItem.vue_vue_type_script_setup_true_lang.js +96 -0
  320. package/dist/packages/primitives/timeline/src/TimelineItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  321. package/dist/packages/primitives/timeline/src/index.d.ts +5 -0
  322. package/dist/packages/primitives/timeline/src/index.js +5 -0
  323. package/dist/packages/primitives/toast/src/Toast.vue.d.ts +2 -2
  324. package/dist/packages/primitives/toast/src/ToastItem.js.map +1 -1
  325. package/dist/packages/primitives/toast/src/ToastItem.vue.d.ts +2 -2
  326. package/dist/packages/primitives/toast/src/ToastItem.vue_vue_type_script_setup_true_lang.js +2 -2
  327. package/dist/packages/primitives/toast/src/ToastItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  328. package/dist/packages/primitives/toast/src/index.d.ts +1 -1
  329. package/dist/packages/primitives/tooltip/src/Tooltip.js.map +1 -1
  330. package/dist/packages/primitives/tooltip/src/Tooltip.vue.d.ts.map +1 -1
  331. package/dist/packages/primitives/tooltip/src/Tooltip.vue_vue_type_script_setup_true_lang.js +1 -1
  332. package/dist/packages/primitives/tooltip/src/Tooltip.vue_vue_type_script_setup_true_lang.js.map +1 -1
  333. package/dist/packages/primitives/window-controls/src/WindowControls.vue.d.ts +2 -2
  334. package/dist/packages/primitives/window-controls/src/index.d.ts +1 -1
  335. package/dist/styles/global.css +59 -0
  336. package/dist/styles/theme.css +13 -0
  337. package/dist/theme.js +3 -0
  338. package/package.json +13 -7
  339. package/dist/packages/blocks/desktop-app-shell/src/DesktopAppShell.vue.d.ts.map +0 -1
  340. package/dist/packages/blocks/title-bar/src/TitleBar.vue.d.ts.map +0 -1
  341. package/dist/packages/blocks/toast-stack/src/ToastStack.vue.d.ts.map +0 -1
  342. package/dist/packages/composition/scroll-reel/src/ScrollReel.vue.d.ts.map +0 -1
  343. package/dist/packages/composition/scroll-reel/src/index.d.ts.map +0 -1
  344. package/dist/packages/loom/src/a11y.d.ts.map +0 -1
  345. package/dist/packages/loom/src/index.d.ts.map +0 -1
  346. package/dist/packages/primitives/alert-dialog/src/AlertDialog.vue.d.ts.map +0 -1
  347. package/dist/packages/primitives/alert-dialog/src/index.d.ts.map +0 -1
  348. package/dist/packages/primitives/avatar-group/src/AvatarGroup.vue.d.ts.map +0 -1
  349. package/dist/packages/primitives/avatar-group/src/index.d.ts.map +0 -1
  350. package/dist/packages/primitives/breadcrumb/src/Breadcrumb.vue.d.ts.map +0 -1
  351. package/dist/packages/primitives/breadcrumb/src/index.d.ts.map +0 -1
  352. package/dist/packages/primitives/color-picker/src/ColorPicker.vue.d.ts.map +0 -1
  353. package/dist/packages/primitives/color-picker/src/index.d.ts.map +0 -1
  354. package/dist/packages/primitives/combobox/src/Combobox.vue.d.ts.map +0 -1
  355. package/dist/packages/primitives/combobox/src/index.d.ts.map +0 -1
  356. package/dist/packages/primitives/date-picker/src/DatePicker.vue.d.ts.map +0 -1
  357. package/dist/packages/primitives/date-range-picker/src/DateRangePicker.vue.d.ts.map +0 -1
  358. package/dist/packages/primitives/date-range-picker/src/index.d.ts.map +0 -1
  359. package/dist/packages/primitives/date-time-picker/src/DateTimePicker.vue.d.ts.map +0 -1
  360. package/dist/packages/primitives/date-time-range-picker/src/DateTimeRangePicker.vue.d.ts.map +0 -1
  361. package/dist/packages/primitives/date-time-range-picker/src/index.d.ts.map +0 -1
  362. package/dist/packages/primitives/dialog/src/Dialog.vue.d.ts.map +0 -1
  363. package/dist/packages/primitives/dialog/src/index.d.ts.map +0 -1
  364. package/dist/packages/primitives/drawer/src/Drawer.vue.d.ts.map +0 -1
  365. package/dist/packages/primitives/drawer/src/index.d.ts.map +0 -1
  366. package/dist/packages/primitives/editable/src/Editable.vue.d.ts.map +0 -1
  367. package/dist/packages/primitives/editable/src/index.d.ts.map +0 -1
  368. package/dist/packages/primitives/file-upload/src/FileUpload.vue.d.ts.map +0 -1
  369. package/dist/packages/primitives/file-upload/src/index.d.ts.map +0 -1
  370. package/dist/packages/primitives/indicator/src/Indicator.vue.d.ts.map +0 -1
  371. package/dist/packages/primitives/indicator/src/index.d.ts.map +0 -1
  372. package/dist/packages/primitives/number-field/src/NumberField.vue.d.ts.map +0 -1
  373. package/dist/packages/primitives/number-field/src/index.d.ts.map +0 -1
  374. package/dist/packages/primitives/otp-input/src/OtpInput.vue.d.ts.map +0 -1
  375. package/dist/packages/primitives/otp-input/src/index.d.ts.map +0 -1
  376. package/dist/packages/primitives/pagination/src/Pagination.vue.d.ts.map +0 -1
  377. package/dist/packages/primitives/pagination/src/index.d.ts.map +0 -1
  378. package/dist/packages/primitives/progress/src/Progress.vue.d.ts.map +0 -1
  379. package/dist/packages/primitives/progress/src/index.d.ts.map +0 -1
  380. package/dist/packages/primitives/radial-progress/src/RadialProgress.vue.d.ts.map +0 -1
  381. package/dist/packages/primitives/radial-progress/src/index.d.ts.map +0 -1
  382. package/dist/packages/primitives/rating/src/Rating.vue.d.ts.map +0 -1
  383. package/dist/packages/primitives/rating/src/index.d.ts.map +0 -1
  384. package/dist/packages/primitives/stepper/src/Stepper.vue.d.ts.map +0 -1
  385. package/dist/packages/primitives/stepper/src/index.d.ts.map +0 -1
  386. package/dist/packages/primitives/tags-input/src/TagsInput.vue.d.ts.map +0 -1
  387. package/dist/packages/primitives/tags-input/src/index.d.ts.map +0 -1
  388. package/dist/packages/primitives/text-field/src/TextField.vue.d.ts.map +0 -1
  389. package/dist/packages/primitives/text-field/src/index.d.ts.map +0 -1
  390. package/dist/packages/primitives/textarea/src/Textarea.vue.d.ts.map +0 -1
  391. package/dist/packages/primitives/textarea/src/index.d.ts.map +0 -1
  392. package/dist/packages/primitives/time-picker/src/TimePicker.vue.d.ts.map +0 -1
  393. package/dist/packages/primitives/toast/src/Toast.vue.d.ts.map +0 -1
  394. package/dist/packages/primitives/toast/src/ToastItem.vue.d.ts.map +0 -1
  395. package/dist/packages/primitives/toast/src/index.d.ts.map +0 -1
  396. package/dist/packages/primitives/window-controls/src/WindowControls.vue.d.ts.map +0 -1
  397. package/dist/packages/primitives/window-controls/src/index.d.ts.map +0 -1
  398. package/dist/styles/theme.contrast.test.ts +0 -460
@@ -22,11 +22,11 @@ var _hoisted_2 = {
22
22
  "aria-hidden": "true",
23
23
  focusable: "false"
24
24
  };
25
- var linkVariants = cva("inline-flex items-center gap-1 transition-colors duration-fast ease-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background", {
25
+ var linkVariants = cva("inline-flex items-center gap-1 transition-colors duration-fast ease-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo", {
26
26
  variants: {
27
27
  variant: {
28
28
  default: "text-primary-text underline underline-offset-4 hover:text-primary-text/80",
29
- muted: "text-muted-foreground hover:text-foreground",
29
+ muted: "text-muted-foreground underline underline-offset-4 hover:text-foreground",
30
30
  accent: "text-accent-text underline underline-offset-4 hover:text-accent-text/80",
31
31
  subtle: "text-foreground/80 hover:text-foreground underline underline-offset-4 decoration-border hover:decoration-foreground/50"
32
32
  },
@@ -65,7 +65,7 @@ var Link_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
65
65
  class: normalizeClass(unref(cn)(unref(linkVariants)({
66
66
  variant: __props.variant,
67
67
  underline: __props.underline
68
- }), "cursor-default pointer-events-none opacity-50", _ctx.$attrs.class)),
68
+ }), "cursor-default bg-muted text-muted-foreground pointer-events-none", _ctx.$attrs.class)),
69
69
  "aria-disabled": "true"
70
70
  }, [renderSlot(_ctx.$slots, "default")], 2)) : (openBlock(), createElementBlock("a", {
71
71
  key: 1,
@@ -1 +1 @@
1
- {"version":3,"file":"Link.vue_vue_type_script_setup_true_lang.js","names":["$attrs"],"sources":["../../../../../packages/primitives/link/src/Link.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { cva } from \"class-variance-authority\";\n\n/** The visual emphasis assigned to a link. */\nexport type LinkVariant = \"default\" | \"muted\" | \"accent\" | \"subtle\";\n\nexport const linkVariants = cva(\n \"inline-flex items-center gap-1 transition-colors duration-fast ease-out focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\",\n {\n variants: {\n variant: {\n default: \"text-primary-text underline underline-offset-4 hover:text-primary-text/80\",\n muted: \"text-muted-foreground hover:text-foreground\",\n accent: \"text-accent-text underline underline-offset-4 hover:text-accent-text/80\",\n subtle:\n \"text-foreground/80 hover:text-foreground underline underline-offset-4 decoration-border hover:decoration-foreground/50\",\n } satisfies Record<LinkVariant, string>,\n underline: {\n true: \"\",\n false: \"no-underline\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n underline: true,\n },\n },\n);\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"@ecoma-io/loom-core\";\n\nwithDefaults(\n defineProps<{\n /** Controls the link's visual emphasis. */\n variant?: LinkVariant;\n /** Draws an underline beneath the link label. */\n underline?: boolean;\n /** The destination the link navigates to. */\n href: string;\n /** Opens the destination in a new tab and marks it as an external link. */\n external?: boolean;\n /** Replaces the anchor with an unavailable, non-interactive span. */\n disabled?: boolean;\n }>(),\n {\n variant: \"default\",\n underline: true,\n external: false,\n disabled: false,\n },\n);\n</script>\n\n<template>\n <span\n v-if=\"disabled\"\n :class=\"\n cn(\n linkVariants({ variant, underline }),\n 'cursor-default pointer-events-none opacity-50',\n $attrs.class,\n )\n \"\n aria-disabled=\"true\"\n >\n <slot />\n </span>\n <a\n v-else\n :href=\"href\"\n :class=\"cn(linkVariants({ variant, underline }), $attrs.class)\"\n :target=\"external ? '_blank' : undefined\"\n :rel=\"external ? 'noopener noreferrer' : undefined\"\n >\n <slot />\n <svg\n v-if=\"external\"\n class=\"h-3.5 w-3.5 shrink-0\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M7 17 17 7\" />\n <path d=\"M7 7h10v10\" />\n </svg>\n </a>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAMA,IAAa,eAAe,IAC1B,oNACA;CACE,UAAU;EACR,SAAS;GACP,SAAS;GACT,OAAO;GACP,QAAQ;GACR,QACE;EACJ;EACA,WAAW;GACT,MAAM;GACN,OAAO;EACT;CACF;CACA,iBAAiB;EACf,SAAS;EACT,WAAW;CACb;AACF,CACF;;;;;;;;;;;;;;;;;;;;;GA8BU,OAAA,QAAA,YADR,UAAA,GAAA,mBAYO,QAAA;;IAVJ,OAAK,eAAS,MAAA,EAAA,CAAE,CAAU,MAAA,YAAA,CAAY,CAAA;KAAA,SAAG,QAAA;KAAO,WAAE,QAAA;IAAS,CAAA,GAAA,iDAAsEA,KAAAA,OAAO,KAAA,CAAA;IAOzI,iBAAc;GAEd,GAAA,CAAA,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,CAAA,MAEV,UAAA,GAAA,mBAyBI,KAAA;;IAvBD,MAAM,QAAA;IACN,OAAK,eAAE,MAAA,EAAA,CAAE,CAAC,MAAA,YAAA,CAAY,CAAA;KAAA,SAAG,QAAA;KAAO,WAAE,QAAA;IAAS,CAAA,GAAKA,KAAAA,OAAO,KAAK,CAAA;IAC5D,QAAQ,QAAA,WAAQ,WAAc,KAAA;IAC9B,KAAK,QAAA,WAAQ,wBAA2B,KAAA;GAEzC,GAAA,CAAA,WAAQ,KAAA,QAAA,SAAA,GAEA,QAAA,YADR,UAAA,GAAA,mBAgBM,OAhBN,YAgBM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAFJ,mBAAuB,QAAA,EAAjB,GAAE,aAAY,GAAA,MAAA,EAAA,GACpB,mBAAuB,QAAA,EAAjB,GAAE,aAAY,GAAA,MAAA,EAAA,CAAA,EAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,IAAA,UAAA"}
1
+ {"version":3,"file":"Link.vue_vue_type_script_setup_true_lang.js","names":["$attrs"],"sources":["../../../../../packages/primitives/link/src/Link.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { cva } from \"class-variance-authority\";\n\n/** The visual emphasis assigned to a link. */\nexport type LinkVariant = \"default\" | \"muted\" | \"accent\" | \"subtle\";\n\nexport const linkVariants = cva(\n \"inline-flex items-center gap-1 transition-colors duration-fast ease-out focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\",\n {\n variants: {\n variant: {\n default: \"text-primary-text underline underline-offset-4 hover:text-primary-text/80\",\n // Underlined like its siblings. WCAG 1.4.1 asks for a non-colour\n // carrier and the underline is the one links have; `muted` used to be\n // the variant that dropped it while keeping a hover colour change,\n // which identified the link by hue alone.\n muted: \"text-muted-foreground underline underline-offset-4 hover:text-foreground\",\n accent: \"text-accent-text underline underline-offset-4 hover:text-accent-text/80\",\n subtle:\n \"text-foreground/80 hover:text-foreground underline underline-offset-4 decoration-border hover:decoration-foreground/50\",\n } satisfies Record<LinkVariant, string>,\n underline: {\n true: \"\",\n false: \"no-underline\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n underline: true,\n },\n },\n);\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"@ecoma-io/loom-core\";\n\nwithDefaults(\n defineProps<{\n /** Controls the link's visual emphasis. */\n variant?: LinkVariant;\n /** Draws an underline beneath the link label. */\n underline?: boolean;\n /** The destination the link navigates to. */\n href: string;\n /** Opens the destination in a new tab and marks it as an external link. */\n external?: boolean;\n /** Replaces the anchor with an unavailable, non-interactive span. */\n disabled?: boolean;\n }>(),\n {\n variant: \"default\",\n underline: true,\n external: false,\n disabled: false,\n },\n);\n</script>\n\n<template>\n <span\n v-if=\"disabled\"\n :class=\"\n cn(\n linkVariants({ variant, underline }),\n // Drained, not dimmed — the same rule Button and Chip follow. The dim\n // faded whatever hue the variant wore, taking the label's contrast\n // down with it; a link has no fill to drain, so it takes the neutral\n // well the transparent controls take, and `aria-disabled` carries the\n // state rather than colour alone.\n 'cursor-default bg-muted text-muted-foreground pointer-events-none',\n $attrs.class,\n )\n \"\n aria-disabled=\"true\"\n >\n <slot />\n </span>\n <a\n v-else\n :href=\"href\"\n :class=\"cn(linkVariants({ variant, underline }), $attrs.class)\"\n :target=\"external ? '_blank' : undefined\"\n :rel=\"external ? 'noopener noreferrer' : undefined\"\n >\n <slot />\n <svg\n v-if=\"external\"\n class=\"h-3.5 w-3.5 shrink-0\"\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n focusable=\"false\"\n >\n <path d=\"M7 17 17 7\" />\n <path d=\"M7 7h10v10\" />\n </svg>\n </a>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAMA,IAAa,eAAe,IAC1B,uLACA;CACE,UAAU;EACR,SAAS;GACP,SAAS;GAKT,OAAO;GACP,QAAQ;GACR,QACE;EACJ;EACA,WAAW;GACT,MAAM;GACN,OAAO;EACT;CACF;CACA,iBAAiB;EACf,SAAS;EACT,WAAW;CACb;AACF,CACF;;;;;;;;;;;;;;;;;;;;;GA8BU,OAAA,QAAA,YADR,UAAA,GAAA,mBAiBO,QAAA;;IAfJ,OAAK,eAAS,MAAA,EAAA,CAAE,CAAU,MAAA,YAAA,CAAY,CAAA;KAAA,SAAG,QAAA;KAAO,WAAE,QAAA;IAAS,CAAA,GAAA,qEAA6bA,KAAAA,OAAO,KAAA,CAAA;IAYhgB,iBAAc;GAEd,GAAA,CAAA,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,CAAA,MAEV,UAAA,GAAA,mBAyBI,KAAA;;IAvBD,MAAM,QAAA;IACN,OAAK,eAAE,MAAA,EAAA,CAAE,CAAC,MAAA,YAAA,CAAY,CAAA;KAAA,SAAG,QAAA;KAAO,WAAE,QAAA;IAAS,CAAA,GAAKA,KAAAA,OAAO,KAAK,CAAA;IAC5D,QAAQ,QAAA,WAAQ,WAAc,KAAA;IAC9B,KAAK,QAAA,WAAQ,wBAA2B,KAAA;GAEzC,GAAA,CAAA,WAAQ,KAAA,QAAA,SAAA,GAEA,QAAA,YADR,UAAA,GAAA,mBAgBM,OAhBN,YAgBM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CAFJ,mBAAuB,QAAA,EAAjB,GAAE,aAAY,GAAA,MAAA,EAAA,GACpB,mBAAuB,QAAA,EAAjB,GAAE,aAAY,GAAA,MAAA,EAAA,CAAA,EAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,IAAA,UAAA"}
@@ -0,0 +1,7 @@
1
+ import List_vue_vue_type_script_setup_true_lang_default from "./List.vue_vue_type_script_setup_true_lang.js";
2
+ //#region packages/primitives/list/src/List.vue
3
+ var List_default = List_vue_vue_type_script_setup_true_lang_default;
4
+ //#endregion
5
+ export { List_default as default };
6
+
7
+ //# sourceMappingURL=List.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"List.js","names":[],"sources":["../../../../../packages/primitives/list/src/List.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * List — a generic composition of rows: leading content, a title and\n * description, trailing metadata or actions. It is the *presentational*\n * vocabulary for row-shaped content, not a navigation primitive — SidebarNav\n * owns wayfinding, Menu owns commands, Table owns columns. This owns \"a\n * titled thing per line\" wherever that appears: settings groups, pickers,\n * summaries under a page's chrome.\n */\nimport { cn } from \"@ecoma-io/loom-core\";\n\nwithDefaults(\n defineProps<{\n /** Names the list for assistive technology when surrounding prose does not already say it. */\n label?: string;\n /** Hairline dividers between rows. Off for card-stacked lists. */\n divided?: boolean;\n }>(),\n { divided: true },\n);\nvoid cn;\n</script>\n\n<template>\n <ul :aria-label=\"label\" :class=\"cn('m-0 list-none p-0', divided && 'divide-y divide-border')\">\n <!-- @slot The rows: one `ListItem` per line. -->\n <slot />\n </ul>\n</template>\n"],"mappings":""}
@@ -0,0 +1,22 @@
1
+ type __VLS_Props = {
2
+ /** Names the list for assistive technology when surrounding prose does not already say it. */
3
+ label?: string;
4
+ /** Hairline dividers between rows. Off for card-stacked lists. */
5
+ divided?: boolean;
6
+ };
7
+ declare var __VLS_1: {};
8
+ type __VLS_Slots = {} & {
9
+ default?: (props: typeof __VLS_1) => any;
10
+ };
11
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
12
+ divided: boolean;
13
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
17
+ type __VLS_WithSlots<T, S> = T & {
18
+ new (): {
19
+ $slots: S;
20
+ };
21
+ };
22
+ //# sourceMappingURL=List.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"List.vue.d.ts","sourceRoot":"","sources":["../../../../../packages/primitives/list/src/List.vue"],"names":[],"mappings":"AA0CA,KAAK,WAAW,GAAG;IACf,8FAA8F;IAC9F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAgCJ,QAAA,IAAI,OAAO,IAAW,CAAE;AACxB,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,CAAC;AAK/C,QAAA,MAAM,UAAU;aAxCF,OAAO;6EA2CnB,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { cn } from "../../../core/src/cn.js";
2
+ import "../../../core/src/index.js";
3
+ import { createElementBlock, defineComponent, normalizeClass, openBlock, renderSlot, unref } from "vue";
4
+ //#region packages/primitives/list/src/List.vue?vue&type=script&setup=true&lang.ts
5
+ var _hoisted_1 = ["aria-label"];
6
+ var List_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
7
+ __name: "List",
8
+ props: {
9
+ label: {},
10
+ divided: {
11
+ type: Boolean,
12
+ default: true
13
+ }
14
+ },
15
+ setup(__props) {
16
+ return (_ctx, _cache) => {
17
+ return openBlock(), createElementBlock("ul", {
18
+ "aria-label": __props.label,
19
+ class: normalizeClass(unref(cn)("m-0 list-none p-0", __props.divided && "divide-y divide-border"))
20
+ }, [renderSlot(_ctx.$slots, "default")], 10, _hoisted_1);
21
+ };
22
+ }
23
+ });
24
+ //#endregion
25
+ export { List_vue_vue_type_script_setup_true_lang_default as default };
26
+
27
+ //# sourceMappingURL=List.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"List.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../../../packages/primitives/list/src/List.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * List — a generic composition of rows: leading content, a title and\n * description, trailing metadata or actions. It is the *presentational*\n * vocabulary for row-shaped content, not a navigation primitive — SidebarNav\n * owns wayfinding, Menu owns commands, Table owns columns. This owns \"a\n * titled thing per line\" wherever that appears: settings groups, pickers,\n * summaries under a page's chrome.\n */\nimport { cn } from \"@ecoma-io/loom-core\";\n\nwithDefaults(\n defineProps<{\n /** Names the list for assistive technology when surrounding prose does not already say it. */\n label?: string;\n /** Hairline dividers between rows. Off for card-stacked lists. */\n divided?: boolean;\n }>(),\n { divided: true },\n);\nvoid cn;\n</script>\n\n<template>\n <ul :aria-label=\"label\" :class=\"cn('m-0 list-none p-0', divided && 'divide-y divide-border')\">\n <!-- @slot The rows: one `ListItem` per line. -->\n <slot />\n </ul>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;GAwBE,OAAA,UAAA,GAAA,mBAGK,MAAA;IAHA,cAAY,QAAA;IAAQ,OAAK,eAAE,MAAA,EAAA,CAAE,CAAA,qBAAsB,QAAA,WAAO,wBAAA,CAAA;GAE7D,GAAA,CAAA,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,IAAA,UAAA"}
@@ -0,0 +1,7 @@
1
+ import ListItem_vue_vue_type_script_setup_true_lang_default, { listItemVariants } from "./ListItem.vue_vue_type_script_setup_true_lang.js";
2
+ //#region packages/primitives/list/src/ListItem.vue
3
+ var ListItem_default = ListItem_vue_vue_type_script_setup_true_lang_default;
4
+ //#endregion
5
+ export { ListItem_default as default, listItemVariants };
6
+
7
+ //# sourceMappingURL=ListItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListItem.js","names":[],"sources":["../../../../../packages/primitives/list/src/ListItem.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { cva } from \"class-variance-authority\";\n\n/**\n * Interactive comes in exactly two shapes, the same honesty Card documents:\n * `href` makes the whole row one real anchor (nothing interactive inside),\n * `interactive` paints hover/press while the host owns role/handler. Plain\n * rows are just rows.\n */\nexport type ListItemShape = \"static\" | \"link\" | \"interactive\";\n\nexport const listItemVariants = cva(\n \"flex w-full items-center gap-3 rounded-md px-3 py-2.5 text-left transition-colors duration-fast ease-out\",\n {\n variants: {\n shape: {\n static: \"\",\n // The shared clickable-row language: lift by fill, never by shadow.\n link: \"cursor-pointer outline-none hover:bg-subtle/60 focus-visible:bg-subtle/60 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo [transition:transform_var(--duration-fast)_var(--ease-spring),background-color_var(--duration-fast)_var(--ease-out)] active:scale-[0.995]\",\n interactive:\n \"cursor-pointer hover:bg-subtle/60 focus-visible:bg-subtle/60 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo active:bg-subtle\",\n },\n dense: { true: \"px-2 py-1.5\", false: \"\" },\n },\n },\n);\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { Check } from \"@lucide/vue\";\nimport { cn } from \"@ecoma-io/loom-core\";\n\nconst props = withDefaults(\n defineProps<{\n /** The row's heading; omit when the default slot carries custom composition. */\n title?: string;\n /** Supporting line beneath the title. */\n description?: string;\n /** Trailing metadata — a count, a timestamp. Reads in tabular digits. */\n meta?: string;\n /** Makes the whole row one link. Nothing interactive may sit inside. */\n href?: string;\n /**\n * Hover/press language for a clickable row whose behaviour belongs to\n * the host; attach the handler yourself.\n */\n interactive?: boolean;\n /** Marks this row as the current choice among its peers (`aria-current`). */\n selected?: boolean;\n /** Unavailable rather than hidden: drained, inert, still announced. */\n disabled?: boolean;\n /** Tighter rhythm inside dense chrome. */\n dense?: boolean;\n }>(),\n {\n interactive: false,\n selected: false,\n disabled: false,\n dense: false,\n },\n);\n\ndefineEmits<{ activate: [] }>();\n\n// One of three shapes decides the element; a disabled row is an inert button\n// rather than a missing one, so it stays announced.\nconst shape = computed<\"link\" | \"interactive\" | \"static\">(() =>\n props.href ? \"link\" : props.interactive ? \"interactive\" : \"static\",\n);\n</script>\n\n<template>\n <li>\n <component\n :is=\"href ? 'a' : interactive ? 'button' : 'div'\"\n :href=\"disabled ? undefined : href\"\n :type=\"interactive && !href ? 'button' : undefined\"\n :disabled=\"interactive && !href ? disabled : undefined\"\n :aria-disabled=\"disabled || undefined\"\n :aria-current=\"selected || undefined\"\n :class=\"\n cn(\n listItemVariants({ shape, dense }),\n selected && !disabled && 'bg-primary-muted/40 aria-current:bg-primary-muted/40',\n disabled && 'cursor-not-allowed bg-transparent',\n )\n \"\n @click=\"interactive && !disabled && $emit('activate')\"\n >\n <!-- @slot Before the title: an icon, an Avatar. -->\n <slot name=\"leading\" />\n\n <span class=\"min-w-0 flex-1\">\n <span v-if=\"title\" class=\"block truncate text-sm font-medium\">{{ title }}</span>\n <span v-if=\"description\" class=\"mt-0.5 block text-small text-muted-foreground\">{{\n description\n }}</span>\n <!-- @slot Custom body; replaces title/description entirely. -->\n <slot />\n </span>\n\n <!-- Selection is stated twice: aria-current for technology, a glyph\n for eyes — colour alone is not a state. -->\n <Check v-if=\"selected\" class=\"h-4 w-4 shrink-0 text-primary-text\" aria-hidden=\"true\" />\n\n <!-- @slot After everything: actions, a Badge, a RowActions cluster. -->\n <slot name=\"trailing\">\n <span v-if=\"meta\" class=\"shrink-0 text-small tabular text-muted-foreground\">{{\n meta\n }}</span>\n </slot>\n </component>\n </li>\n</template>\n"],"mappings":""}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Interactive comes in exactly two shapes, the same honesty Card documents:
3
+ * `href` makes the whole row one real anchor (nothing interactive inside),
4
+ * `interactive` paints hover/press while the host owns role/handler. Plain
5
+ * rows are just rows.
6
+ */
7
+ export type ListItemShape = "static" | "link" | "interactive";
8
+ export declare const listItemVariants: (props?: ({
9
+ shape?: "link" | "interactive" | "static" | null | undefined;
10
+ dense?: boolean | null | undefined;
11
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
14
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
15
+ /** The row's heading; omit when the default slot carries custom composition. */
16
+ title?: string;
17
+ /** Supporting line beneath the title. */
18
+ description?: string;
19
+ /** Trailing metadata — a count, a timestamp. Reads in tabular digits. */
20
+ meta?: string;
21
+ /** Makes the whole row one link. Nothing interactive may sit inside. */
22
+ href?: string;
23
+ /**
24
+ * Hover/press language for a clickable row whose behaviour belongs to
25
+ * the host; attach the handler yourself.
26
+ */
27
+ interactive?: boolean;
28
+ /** Marks this row as the current choice among its peers (`aria-current`). */
29
+ selected?: boolean;
30
+ /** Unavailable rather than hidden: drained, inert, still announced. */
31
+ disabled?: boolean;
32
+ /** Tighter rhythm inside dense chrome. */
33
+ dense?: boolean;
34
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
35
+ activate: () => any;
36
+ }, string, import("vue").PublicProps, Readonly<{
37
+ /** The row's heading; omit when the default slot carries custom composition. */
38
+ title?: string;
39
+ /** Supporting line beneath the title. */
40
+ description?: string;
41
+ /** Trailing metadata — a count, a timestamp. Reads in tabular digits. */
42
+ meta?: string;
43
+ /** Makes the whole row one link. Nothing interactive may sit inside. */
44
+ href?: string;
45
+ /**
46
+ * Hover/press language for a clickable row whose behaviour belongs to
47
+ * the host; attach the handler yourself.
48
+ */
49
+ interactive?: boolean;
50
+ /** Marks this row as the current choice among its peers (`aria-current`). */
51
+ selected?: boolean;
52
+ /** Unavailable rather than hidden: drained, inert, still announced. */
53
+ disabled?: boolean;
54
+ /** Tighter rhythm inside dense chrome. */
55
+ dense?: boolean;
56
+ }> & Readonly<{
57
+ onActivate?: () => any;
58
+ }>, {
59
+ disabled: boolean;
60
+ interactive: boolean;
61
+ selected: boolean;
62
+ dense: boolean;
63
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
64
+ leading?: (props: {}) => any;
65
+ } & {
66
+ default?: (props: {}) => any;
67
+ } & {
68
+ trailing?: (props: {}) => any;
69
+ }>;
70
+ type __VLS_WithSlots<T, S> = T & {
71
+ new (): {
72
+ $slots: S;
73
+ };
74
+ };
75
+ //# sourceMappingURL=ListItem.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListItem.vue.d.ts","sourceRoot":"","sources":["../../../../../packages/primitives/list/src/ListItem.vue"],"names":[],"mappings":"AA6HA;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,MAAM,GAAG,aAAa,CAAC;AAE9D,eAAO,MAAM,gBAAgB;;;8EAc5B,CAAC;wBACmB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAEd,gFAAgF;YACxE,MAAM;IACd,yCAAyC;kBAC3B,MAAM;IACpB,yEAAyE;WAClE,MAAM;IACb,wEAAwE;WACjE,MAAM;IACb;;;OAGG;kBACW,OAAO;IACrB,6EAA6E;eAClE,OAAO;IAClB,uEAAuE;eAC5D,OAAO;IAClB,0CAA0C;YAClC,OAAO;;;;IAlBf,gFAAgF;YACxE,MAAM;IACd,yCAAyC;kBAC3B,MAAM;IACpB,yEAAyE;WAClE,MAAM;IACb,wEAAwE;WACjE,MAAM;IACb;;;OAGG;kBACW,OAAO;IACrB,6EAA6E;eAClE,OAAO;IAClB,uEAAuE;eAC5D,OAAO;IAClB,0CAA0C;YAClC,OAAO;;;;cAFJ,OAAO;iBAJJ,OAAO;cAEV,OAAO;WAIV,OAAO;;cAmKL,CAAC,KAAK,IAAgB,KAAK,GAAG;;cAC9B,CAAC,KAAK,IAAiB,KAAK,GAAG;;eAC9B,CAAC,KAAK,IAAiB,KAAK,GAAG;EAW1C,CAAC;AAWL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -0,0 +1,101 @@
1
+ import { cn } from "../../../core/src/cn.js";
2
+ import "../../../core/src/index.js";
3
+ import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, normalizeClass, openBlock, renderSlot, resolveDynamicComponent, toDisplayString, unref, withCtx } from "vue";
4
+ import { Check } from "@lucide/vue";
5
+ import { cva } from "class-variance-authority";
6
+ //#region packages/primitives/list/src/ListItem.vue?vue&type=script&setup=true&lang.ts
7
+ var _hoisted_1 = { class: "min-w-0 flex-1" };
8
+ var _hoisted_2 = {
9
+ key: 0,
10
+ class: "block truncate text-sm font-medium"
11
+ };
12
+ var _hoisted_3 = {
13
+ key: 1,
14
+ class: "mt-0.5 block text-small text-muted-foreground"
15
+ };
16
+ var _hoisted_4 = {
17
+ key: 0,
18
+ class: "shrink-0 text-small tabular text-muted-foreground"
19
+ };
20
+ var listItemVariants = cva("flex w-full items-center gap-3 rounded-md px-3 py-2.5 text-left transition-colors duration-fast ease-out", { variants: {
21
+ shape: {
22
+ static: "",
23
+ link: "cursor-pointer outline-none hover:bg-subtle/60 focus-visible:bg-subtle/60 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo [transition:transform_var(--duration-fast)_var(--ease-spring),background-color_var(--duration-fast)_var(--ease-out)] active:scale-[0.995]",
24
+ interactive: "cursor-pointer hover:bg-subtle/60 focus-visible:bg-subtle/60 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo active:bg-subtle"
25
+ },
26
+ dense: {
27
+ true: "px-2 py-1.5",
28
+ false: ""
29
+ }
30
+ } });
31
+ var ListItem_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
32
+ __name: "ListItem",
33
+ props: {
34
+ title: {},
35
+ description: {},
36
+ meta: {},
37
+ href: {},
38
+ interactive: {
39
+ type: Boolean,
40
+ default: false
41
+ },
42
+ selected: {
43
+ type: Boolean,
44
+ default: false
45
+ },
46
+ disabled: {
47
+ type: Boolean,
48
+ default: false
49
+ },
50
+ dense: {
51
+ type: Boolean,
52
+ default: false
53
+ }
54
+ },
55
+ emits: ["activate"],
56
+ setup(__props) {
57
+ const props = __props;
58
+ const shape = computed(() => props.href ? "link" : props.interactive ? "interactive" : "static");
59
+ return (_ctx, _cache) => {
60
+ return openBlock(), createElementBlock("li", null, [(openBlock(), createBlock(resolveDynamicComponent(__props.href ? "a" : __props.interactive ? "button" : "div"), {
61
+ href: __props.disabled ? void 0 : __props.href,
62
+ type: __props.interactive && !__props.href ? "button" : void 0,
63
+ disabled: __props.interactive && !__props.href ? __props.disabled : void 0,
64
+ "aria-disabled": __props.disabled || void 0,
65
+ "aria-current": __props.selected || void 0,
66
+ class: normalizeClass(unref(cn)(unref(listItemVariants)({
67
+ shape: shape.value,
68
+ dense: __props.dense
69
+ }), __props.selected && !__props.disabled && "bg-primary-muted/40 aria-current:bg-primary-muted/40", __props.disabled && "cursor-not-allowed bg-transparent")),
70
+ onClick: _cache[0] || (_cache[0] = ($event) => __props.interactive && !__props.disabled && _ctx.$emit("activate"))
71
+ }, {
72
+ default: withCtx(() => [
73
+ renderSlot(_ctx.$slots, "leading"),
74
+ createElementVNode("span", _hoisted_1, [
75
+ __props.title ? (openBlock(), createElementBlock("span", _hoisted_2, toDisplayString(__props.title), 1)) : createCommentVNode("", true),
76
+ __props.description ? (openBlock(), createElementBlock("span", _hoisted_3, toDisplayString(__props.description), 1)) : createCommentVNode("", true),
77
+ renderSlot(_ctx.$slots, "default")
78
+ ]),
79
+ __props.selected ? (openBlock(), createBlock(unref(Check), {
80
+ key: 0,
81
+ class: "h-4 w-4 shrink-0 text-primary-text",
82
+ "aria-hidden": "true"
83
+ })) : createCommentVNode("", true),
84
+ renderSlot(_ctx.$slots, "trailing", {}, () => [__props.meta ? (openBlock(), createElementBlock("span", _hoisted_4, toDisplayString(__props.meta), 1)) : createCommentVNode("", true)])
85
+ ]),
86
+ _: 3
87
+ }, 8, [
88
+ "href",
89
+ "type",
90
+ "disabled",
91
+ "aria-disabled",
92
+ "aria-current",
93
+ "class"
94
+ ]))]);
95
+ };
96
+ }
97
+ });
98
+ //#endregion
99
+ export { ListItem_vue_vue_type_script_setup_true_lang_default as default, listItemVariants };
100
+
101
+ //# sourceMappingURL=ListItem.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ListItem.vue_vue_type_script_setup_true_lang.js","names":["$emit"],"sources":["../../../../../packages/primitives/list/src/ListItem.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { cva } from \"class-variance-authority\";\n\n/**\n * Interactive comes in exactly two shapes, the same honesty Card documents:\n * `href` makes the whole row one real anchor (nothing interactive inside),\n * `interactive` paints hover/press while the host owns role/handler. Plain\n * rows are just rows.\n */\nexport type ListItemShape = \"static\" | \"link\" | \"interactive\";\n\nexport const listItemVariants = cva(\n \"flex w-full items-center gap-3 rounded-md px-3 py-2.5 text-left transition-colors duration-fast ease-out\",\n {\n variants: {\n shape: {\n static: \"\",\n // The shared clickable-row language: lift by fill, never by shadow.\n link: \"cursor-pointer outline-none hover:bg-subtle/60 focus-visible:bg-subtle/60 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo [transition:transform_var(--duration-fast)_var(--ease-spring),background-color_var(--duration-fast)_var(--ease-out)] active:scale-[0.995]\",\n interactive:\n \"cursor-pointer hover:bg-subtle/60 focus-visible:bg-subtle/60 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo active:bg-subtle\",\n },\n dense: { true: \"px-2 py-1.5\", false: \"\" },\n },\n },\n);\n</script>\n\n<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { Check } from \"@lucide/vue\";\nimport { cn } from \"@ecoma-io/loom-core\";\n\nconst props = withDefaults(\n defineProps<{\n /** The row's heading; omit when the default slot carries custom composition. */\n title?: string;\n /** Supporting line beneath the title. */\n description?: string;\n /** Trailing metadata — a count, a timestamp. Reads in tabular digits. */\n meta?: string;\n /** Makes the whole row one link. Nothing interactive may sit inside. */\n href?: string;\n /**\n * Hover/press language for a clickable row whose behaviour belongs to\n * the host; attach the handler yourself.\n */\n interactive?: boolean;\n /** Marks this row as the current choice among its peers (`aria-current`). */\n selected?: boolean;\n /** Unavailable rather than hidden: drained, inert, still announced. */\n disabled?: boolean;\n /** Tighter rhythm inside dense chrome. */\n dense?: boolean;\n }>(),\n {\n interactive: false,\n selected: false,\n disabled: false,\n dense: false,\n },\n);\n\ndefineEmits<{ activate: [] }>();\n\n// One of three shapes decides the element; a disabled row is an inert button\n// rather than a missing one, so it stays announced.\nconst shape = computed<\"link\" | \"interactive\" | \"static\">(() =>\n props.href ? \"link\" : props.interactive ? \"interactive\" : \"static\",\n);\n</script>\n\n<template>\n <li>\n <component\n :is=\"href ? 'a' : interactive ? 'button' : 'div'\"\n :href=\"disabled ? undefined : href\"\n :type=\"interactive && !href ? 'button' : undefined\"\n :disabled=\"interactive && !href ? disabled : undefined\"\n :aria-disabled=\"disabled || undefined\"\n :aria-current=\"selected || undefined\"\n :class=\"\n cn(\n listItemVariants({ shape, dense }),\n selected && !disabled && 'bg-primary-muted/40 aria-current:bg-primary-muted/40',\n disabled && 'cursor-not-allowed bg-transparent',\n )\n \"\n @click=\"interactive && !disabled && $emit('activate')\"\n >\n <!-- @slot Before the title: an icon, an Avatar. -->\n <slot name=\"leading\" />\n\n <span class=\"min-w-0 flex-1\">\n <span v-if=\"title\" class=\"block truncate text-sm font-medium\">{{ title }}</span>\n <span v-if=\"description\" class=\"mt-0.5 block text-small text-muted-foreground\">{{\n description\n }}</span>\n <!-- @slot Custom body; replaces title/description entirely. -->\n <slot />\n </span>\n\n <!-- Selection is stated twice: aria-current for technology, a glyph\n for eyes — colour alone is not a state. -->\n <Check v-if=\"selected\" class=\"h-4 w-4 shrink-0 text-primary-text\" aria-hidden=\"true\" />\n\n <!-- @slot After everything: actions, a Badge, a RowActions cluster. -->\n <slot name=\"trailing\">\n <span v-if=\"meta\" class=\"shrink-0 text-small tabular text-muted-foreground\">{{\n meta\n }}</span>\n </slot>\n </component>\n </li>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAWA,IAAa,mBAAmB,IAC9B,4GACA,EACE,UAAU;CACR,OAAO;EACL,QAAQ;EAER,MAAM;EACN,aACE;CACJ;CACA,OAAO;EAAE,MAAM;EAAe,OAAO;CAAG;AAC1C,EACF,CACF;;;;;;;;;;;;;;;;;;;;;;;;;;;EAQA,MAAM,QAAQ;EAkCd,MAAM,QAAQ,eACZ,MAAM,OAAO,SAAS,MAAM,cAAc,gBAAgB,QAC5D;;GAIE,OAAA,UAAA,GAAA,mBAwCK,MAAA,MAAA,EAvCH,UAAA,GAAA,YAsCY,wBArCL,QAAA,OAAI,MAAS,QAAA,cAAW,WAAA,KAAA,GAAA;IAC5B,MAAM,QAAA,WAAW,KAAA,IAAY,QAAA;IAC7B,MAAM,QAAA,eAAW,CAAK,QAAA,OAAI,WAAc,KAAA;IACxC,UAAU,QAAA,eAAW,CAAK,QAAA,OAAO,QAAA,WAAW,KAAA;IAC5C,iBAAe,QAAA,YAAY,KAAA;IAC3B,gBAAc,QAAA,YAAY,KAAA;IAC1B,OAAK,eAAW,MAAA,EAAA,CAAE,CAAY,MAAA,gBAAA,CAAgB,CAAA;KAAA,OAAG,MAAA;KAAK,OAAE,QAAA;IAAK,CAAA,GAAe,QAAA,YAAQ,CAAK,QAAA,YAAQ,wDAAsE,QAAA,YAAQ,mCAAA,CAAA;IAO/K,SAAK,OAAA,OAAA,OAAA,MAAA,WAAE,QAAA,eAAW,CAAK,QAAA,YAAYA,KAAAA,MAAK,UAAA;;IAGzC,SAAA,cAAuB;KAAvB,WAAuB,KAAA,QAAA,SAAA;KAEvB,mBAOO,QAPP,YAOO;MANO,QAAA,SAAZ,UAAA,GAAA,mBAAgF,QAAhF,YAAgF,gBAAf,QAAA,KAAK,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;MAC1D,QAAA,eAAZ,UAAA,GAAA,mBAES,QAFT,YAES,gBADP,QAAA,WAAW,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;MAGb,WAAQ,KAAA,QAAA,SAAA;;KAKG,QAAA,YAAb,UAAA,GAAA,YAAuF,MAAA,KAAA,GAAA;;MAAhE,OAAM;MAAqC,eAAY;;KAG9E,WAIO,KAAA,QAAA,YAAA,CAAA,SAAA,CAHO,QAAA,QAAZ,UAAA,GAAA,mBAES,QAFT,YAES,gBADP,QAAA,IAAI,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,CAAA"}
@@ -0,0 +1,4 @@
1
+ export { default, default as List } from "./List.vue";
2
+ export { default as ListItem } from "./ListItem.vue";
3
+ export type { ListItemShape } from "./ListItem.vue";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/primitives/list/src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,IAAI,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACrD,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import List_default from "./List.js";
2
+ import ListItem_default from "./ListItem.js";
3
+ export { List_default as List, ListItem_default as ListItem };
@@ -1 +1 @@
1
- {"version":3,"file":"Menubar.js","names":[],"sources":["../../../../../packages/primitives/menubar/src/Menubar.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Menubar — the classic desktop-app menu strip (File · View · Help …).\n *\n * Data-driven: pass a `menus` array; the component owns open/close, hover-to-switch,\n * keyboard nav and click-outside. Selecting an item emits `select` with its `command`\n * id — the host maps that id to an action (keeps the primitive free of app logic).\n *\n * A11y: WAI-ARIA menubar semantics (roles + aria-expanded/haspopup) with Escape,\n * Arrow, Home/End and Enter/Space handling. When richer focus-trapping is needed we\n * can later delegate to Reka UI without changing this call-site contract.\n */\nexport interface MenubarItem {\n /** Visible label. */\n label: string;\n /** Command id emitted on select. Omit for a non-actionable row. */\n command?: string;\n /** Right-aligned accelerator hint, e.g. \"Ctrl+S\". */\n shortcut?: string;\n /** Render a divider instead of an item (label ignored). */\n separator?: boolean;\n disabled?: boolean;\n}\n\nexport interface MenubarMenu {\n id: string;\n label: string;\n items: MenubarItem[];\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { onMounted, onBeforeUnmount, ref, nextTick } from \"vue\";\nimport { listStaggerDelay } from \"@ecoma-io/loom-core\";\n\nconst props = defineProps<{\n /** The top-level menus, left to right, each carrying its own item list. */\n menus: MenubarMenu[];\n}>();\nconst emit = defineEmits<{ (e: \"select\", command: string): void }>();\n\nconst openId = ref<string | null>(null);\nconst activeIndex = ref(-1); // highlighted item within the open menu\n\nconst openMenu = (menu: MenubarMenu | undefined) => menu?.items ?? [];\nconst firstEnabled = (items: MenubarItem[], from = 0, dir = 1): number => {\n for (let i = from; i >= 0 && i < items.length; i += dir) {\n const item = items[i];\n if (item && !item.separator && !item.disabled) return i;\n }\n return -1;\n};\n\nfunction toggle(id: string): void {\n openId.value = openId.value === id ? null : id;\n activeIndex.value = -1;\n}\nfunction hover(id: string): void {\n if (openId.value !== null && openId.value !== id) {\n openId.value = id;\n activeIndex.value = -1;\n }\n}\nfunction choose(item: MenubarItem): void {\n if (item.separator || item.disabled) return;\n close();\n if (item.command) emit(\"select\", item.command);\n}\nfunction close(): void {\n openId.value = null;\n activeIndex.value = -1;\n}\n\nfunction moveMenu(dir: 1 | -1): void {\n const ids = props.menus.map((m) => m.id);\n const cur = openId.value ? ids.indexOf(openId.value) : 0;\n const next = (cur + dir + ids.length) % ids.length;\n openId.value = ids[next] ?? null;\n activeIndex.value = -1;\n}\n\nasync function onTriggerKeydown(e: KeyboardEvent, menu: MenubarMenu): Promise<void> {\n switch (e.key) {\n case \"ArrowDown\":\n case \"Enter\":\n case \" \":\n e.preventDefault();\n openId.value = menu.id;\n await nextTick();\n activeIndex.value = firstEnabled(menu.items);\n break;\n case \"ArrowRight\":\n e.preventDefault();\n if (openId.value) moveMenu(1);\n break;\n case \"ArrowLeft\":\n e.preventDefault();\n if (openId.value) moveMenu(-1);\n break;\n case \"Escape\":\n close();\n break;\n }\n}\n\nfunction onMenuKeydown(e: KeyboardEvent, menu: MenubarMenu): void {\n const items = menu.items;\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n activeIndex.value = firstEnabled(items, Math.max(activeIndex.value, -1) + 1, 1);\n if (activeIndex.value === -1) activeIndex.value = firstEnabled(items, 0, 1);\n break;\n case \"ArrowUp\":\n e.preventDefault();\n activeIndex.value =\n activeIndex.value <= 0\n ? firstEnabled(items, items.length - 1, -1)\n : firstEnabled(items, activeIndex.value - 1, -1);\n break;\n case \"Home\":\n e.preventDefault();\n activeIndex.value = firstEnabled(items, 0, 1);\n break;\n case \"End\":\n e.preventDefault();\n activeIndex.value = firstEnabled(items, items.length - 1, -1);\n break;\n case \"ArrowRight\":\n e.preventDefault();\n moveMenu(1);\n break;\n case \"ArrowLeft\":\n e.preventDefault();\n moveMenu(-1);\n break;\n case \"Enter\":\n case \" \": {\n e.preventDefault();\n const item = activeIndex.value >= 0 ? items[activeIndex.value] : undefined;\n if (item) choose(item);\n break;\n }\n case \"Escape\":\n e.preventDefault();\n close();\n break;\n }\n}\n\nonMounted(() => window.addEventListener(\"click\", close));\nonBeforeUnmount(() => window.removeEventListener(\"click\", close));\n</script>\n\n<template>\n <div\n role=\"menubar\"\n class=\"flex items-center gap-0.5\"\n style=\"-webkit-app-region: no-drag\"\n @click.stop\n >\n <div v-for=\"menu in menus\" :key=\"menu.id\" class=\"relative\">\n <button\n :id=\"`menubar-trigger-${menu.id}`\"\n type=\"button\"\n role=\"menuitem\"\n :aria-haspopup=\"true\"\n :aria-expanded=\"openId === menu.id\"\n class=\"min-h-6 rounded-sm px-2 py-1 text-xs text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:bg-subtle focus-visible:text-foreground\"\n :class=\"openId === menu.id && 'bg-subtle text-foreground'\"\n @click.stop=\"toggle(menu.id)\"\n @mouseenter=\"hover(menu.id)\"\n @focus=\"hover(menu.id)\"\n @keydown=\"onTriggerKeydown($event, menu)\"\n >\n {{ menu.label }}\n </button>\n\n <div\n v-if=\"openId === menu.id\"\n role=\"menu\"\n :aria-label=\"menu.label\"\n tabindex=\"-1\"\n class=\"absolute left-0 top-full z-50 mt-1 min-w-[13rem] origin-top-left rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md animate-scale-in\"\n @click.stop\n @keydown=\"onMenuKeydown($event, menu)\"\n >\n <template v-for=\"(item, i) in openMenu(menu)\" :key=\"i\">\n <div v-if=\"item.separator\" role=\"separator\" class=\"my-1 h-px bg-border\" />\n <!-- The row's colour, not its alpha, says it is unavailable. A menu\n row is nothing but its label, and `disabled:opacity-40` composited\n that label to 2.40:1 on the popover — a disabled row a reader\n cannot make out tells them nothing about what is unavailable,\n which is the only thing it is there to say. Muted instead: 5.76:1\n at rest, and a clear drop from the 15.46:1 an available row wears,\n so the state still reads at a glance. The shortcut beside it\n declares `text-muted-foreground` on its own element, so it lands\n on the same colour rather than inheriting this one. -->\n <button\n v-else\n type=\"button\"\n role=\"menuitem\"\n :disabled=\"item.disabled\"\n :data-highlighted=\"activeIndex === i || undefined\"\n :style=\"{ animationDelay: listStaggerDelay(i) }\"\n class=\"flex w-full items-center justify-between gap-6 rounded-sm px-2 py-1.5 text-left text-xs text-foreground transition-colors duration-fast ease-out hover:bg-subtle disabled:pointer-events-none disabled:text-muted-foreground data-[highlighted]:bg-subtle animate-fade-rise\"\n @click=\"choose(item)\"\n @mouseenter=\"activeIndex = i\"\n @focus=\"activeIndex = i\"\n >\n <span>{{ item.label }}</span>\n <span v-if=\"item.shortcut\" class=\"tabular text-[0.6875rem] text-muted-foreground\">\n {{ item.shortcut }}\n </span>\n </button>\n </template>\n </div>\n </div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Menubar.js","names":[],"sources":["../../../../../packages/primitives/menubar/src/Menubar.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Menubar — the classic desktop-app menu strip (File · View · Help …).\n *\n * Data-driven: pass a `menus` array; the component owns open/close, hover-to-switch,\n * keyboard nav and click-outside. Selecting an item emits `select` with its `command`\n * id — the host maps that id to an action (keeps the primitive free of app logic).\n *\n * A11y: WAI-ARIA menubar semantics over real DOM focus, not aria-activedescendant.\n * Opening a menu moves focus onto its first enabled row and the arrows walk it from\n * there, so \"the highlighted row\" and \"the focused row\" are the same thing by\n * construction and a screen reader announces each walked row natively — no\n * bookkeeping that could drift out of sync with what is actually announced.\n */\nexport interface MenubarItem {\n /** Visible label. */\n label: string;\n /** Command id emitted on select. Omit for a non-actionable row. */\n command?: string;\n /** Right-aligned accelerator hint, e.g. \"Ctrl+S\". */\n shortcut?: string;\n /** Render a divider instead of an item (label ignored). */\n separator?: boolean;\n disabled?: boolean;\n}\n\nexport interface MenubarMenu {\n id: string;\n label: string;\n items: MenubarItem[];\n}\n</script>\n\n<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, onMounted, ref, nextTick } from \"vue\";\nimport { listStaggerDelay } from \"@ecoma-io/loom-core\";\n\nconst props = defineProps<{\n /** The top-level menus; their reading order follows `dir`. */\n menus: MenubarMenu[];\n /**\n * Reading direction. Right-to-left mirrors the strip's arrow keys —\n * ArrowRight travels toward the visual left — which a hand-rolled\n * handler must do itself, unlike its Reka siblings.\n */\n dir?: \"ltr\" | \"rtl\";\n}>();\nconst emit = defineEmits<{ select: [command: string] }>();\n\n// Horizontal arrows are visual, not logical: in right-to-left, ArrowRight\n// moves toward the previous menu.\nconst horizontal = computed(() => (props.dir === \"rtl\" ? -1 : 1) as 1 | -1);\n\nconst openId = ref<string | null>(null);\nconst activeIndex = ref(-1); // the focused row within the open menu\n// String refs would do here only outside a v-for; inside one Vue collects them\n// into arrays. Function refs keyed BY MENU ID instead: during a menu switch the\n// incoming panel can mount before the outgoing one unmounts, so a single\n// latest-wins slot would let the outgoing null clobber the just-bound element.\nconst panelEls = new Map<string, HTMLElement>();\nconst triggerEls = new Map<string, HTMLButtonElement>();\n\nfunction bindPanel(id: string, el: unknown): void {\n if (el instanceof HTMLElement) panelEls.set(id, el);\n else panelEls.delete(id);\n}\n\nfunction bindTrigger(id: string, el: unknown): void {\n if (el instanceof HTMLButtonElement) triggerEls.set(id, el);\n else triggerEls.delete(id);\n}\n\nfunction boundPanel(): HTMLElement | null {\n return openId.value ? (panelEls.get(openId.value) ?? null) : null;\n}\n\nconst openMenu = (menu: MenubarMenu | undefined) => menu?.items ?? [];\nconst firstEnabled = (items: MenubarItem[], from = 0, dir = 1): number => {\n for (let i = from; i >= 0 && i < items.length; i += dir) {\n const item = items[i];\n if (item && !item.separator && !item.disabled) return i;\n }\n return -1;\n};\n\n/** One arrow-step away from `from`, wrapping through every slot exactly once. */\nfunction neighborEnabled(items: MenubarItem[], from: number, dir: 1 | -1): number {\n const n = items.length;\n for (let step = 1; step <= n; step++) {\n const i = (((from + dir * step) % n) + n) % n;\n const item = items[i];\n if (item && !item.separator && !item.disabled) return i;\n }\n return -1;\n}\n\n/** Rows render only for non-separator items, so an item index maps to its button's ordinal among the rendered ones. */\nfunction rowOrdinal(items: MenubarItem[], index: number): number {\n let ordinal = -1;\n for (let k = 0; k <= index && k < items.length; k++) {\n if (!items[k]?.separator) ordinal++;\n }\n return ordinal;\n}\n\nfunction rowButtons(): HTMLButtonElement[] {\n const panel = boundPanel();\n return panel\n ? Array.from(panel.querySelectorAll<HTMLButtonElement>('button[role=\"menuitem\"]'))\n : [];\n}\n\nfunction focusRow(items: MenubarItem[], index: number): void {\n rowButtons()[rowOrdinal(items, index)]?.focus();\n}\n\nfunction goTo(items: MenubarItem[], index: number): void {\n if (index < 0) return;\n activeIndex.value = index;\n focusRow(items, index);\n}\n\nasync function openAndFocusFirst(id: string, items: MenubarItem[]): Promise<void> {\n await nextTick();\n // A hover or another key can supersede this open within the same tick; only\n // the menu that still owns `openId` may claim focus.\n if (openId.value !== id) return;\n goTo(items, firstEnabled(items));\n}\n\nasync function toggle(id: string): Promise<void> {\n if (openId.value === id) {\n close(true);\n return;\n }\n const menu = props.menus.find((m) => m.id === id);\n if (!menu) return;\n openId.value = id;\n activeIndex.value = -1;\n await openAndFocusFirst(id, menu.items);\n}\n\nasync function hover(id: string, via: \"pointer\" | \"trigger-focus\"): Promise<void> {\n if (openId.value === null || openId.value === id) return;\n const menu = props.menus.find((m) => m.id === id);\n if (!menu) return;\n openId.value = id;\n activeIndex.value = -1;\n // Pointer switching takes focus into the new menu like a desktop menubar.\n // A switch caused by tabbing between triggers must not yank focus out of\n // the tab order mid-Tab, so it switches the panel and leaves focus alone.\n if (via === \"pointer\") await openAndFocusFirst(id, menu.items);\n}\n\nfunction choose(item: MenubarItem): void {\n if (item.separator || item.disabled) return;\n close(true);\n if (item.command) emit(\"select\", item.command);\n}\n\nfunction close(restoreFocus = false): void {\n const id = openId.value;\n openId.value = null;\n activeIndex.value = -1;\n // Escape and selection hand focus back to the owning trigger; Tab-out and\n // outside clicks do not — focus has already gone where the user sent it.\n if (restoreFocus && id) triggerEls.get(id)?.focus();\n}\n\nasync function moveMenu(dir: 1 | -1): Promise<void> {\n const ids = props.menus.map((m) => m.id);\n const cur = openId.value ? ids.indexOf(openId.value) : 0;\n const id = ids[(cur + dir + ids.length) % ids.length];\n const menu = props.menus.find((m) => m.id === id);\n if (!menu) return;\n openId.value = menu.id;\n activeIndex.value = -1;\n await openAndFocusFirst(menu.id, menu.items);\n}\n\n/**\n * Pointer highlight of an enabled row moves focus with it — under the roving\n * model the highlighted row IS the focused row, and screen readers announce\n * focus changes, not CSS classes.\n */\nfunction pointAtRow(items: MenubarItem[], item: MenubarItem, index: number): void {\n if (item.disabled || item.separator || activeIndex.value === index) return;\n activeIndex.value = index;\n focusRow(items, index);\n}\n\n/** Native focus landing on a row keeps `activeIndex` truthful about it. */\nfunction noteFocus(item: MenubarItem, index: number): void {\n if (item.disabled || item.separator) return;\n activeIndex.value = index;\n}\n\n/**\n * The APG's closed-state traversal: Left/Right across the strip land on the\n * neighbouring trigger without opening anything — opening is ArrowDown,\n * Enter or Space's job.\n */\nfunction moveTriggerFocus(from: string, dir: 1 | -1): void {\n const ids = props.menus.map((m) => m.id);\n const cur = ids.indexOf(from);\n if (cur === -1) return;\n triggerEls.get(ids[(cur + dir + ids.length) % ids.length] ?? \"\")?.focus();\n}\n\nasync function onTriggerKeydown(e: KeyboardEvent, menu: MenubarMenu): Promise<void> {\n switch (e.key) {\n case \"ArrowDown\":\n case \"Enter\":\n case \" \":\n e.preventDefault(); // suppresses the button's own activation click\n openId.value = menu.id;\n activeIndex.value = -1;\n await openAndFocusFirst(menu.id, menu.items);\n break;\n case \"ArrowRight\":\n e.preventDefault();\n if (openId.value) void moveMenu(horizontal.value);\n else moveTriggerFocus(menu.id, horizontal.value);\n break;\n case \"ArrowLeft\":\n e.preventDefault();\n if (openId.value) void moveMenu(-horizontal.value as 1 | -1);\n else moveTriggerFocus(menu.id, -horizontal.value as 1 | -1);\n break;\n case \"Escape\":\n e.preventDefault();\n close(true);\n break;\n }\n}\n\nfunction onMenuKeydown(e: KeyboardEvent, menu: MenubarMenu): void {\n const items = menu.items;\n switch (e.key) {\n case \"ArrowDown\":\n e.preventDefault();\n goTo(items, neighborEnabled(items, activeIndex.value, 1));\n break;\n case \"ArrowUp\":\n e.preventDefault();\n goTo(items, neighborEnabled(items, activeIndex.value, -1));\n break;\n case \"Home\":\n e.preventDefault();\n goTo(items, firstEnabled(items, 0, 1));\n break;\n case \"End\":\n e.preventDefault();\n goTo(items, firstEnabled(items, items.length - 1, -1));\n break;\n case \"ArrowRight\":\n e.preventDefault();\n void moveMenu(horizontal.value);\n break;\n case \"ArrowLeft\":\n e.preventDefault();\n void moveMenu(-horizontal.value as 1 | -1);\n break;\n // Handled here rather than left to the button's native activation:\n // preventDefault stops the browser's synthesized click, which would run\n // choose() a second time alongside this delegated handler.\n case \"Enter\":\n case \" \": {\n e.preventDefault();\n const item = items[activeIndex.value];\n if (item) choose(item);\n break;\n }\n case \"Escape\":\n e.preventDefault();\n close(true);\n break;\n }\n}\n\nfunction onRootFocusout(e: FocusEvent): void {\n if (!openId.value) return;\n const root = e.currentTarget;\n const next = e.relatedTarget;\n // Tab out of the strip dismisses the menu and leaves focus where the browser\n // put it. Moves that stay inside the menubar (opening handing focus to a\n // row) keep it.\n if (!(root instanceof Element) || !(next instanceof Node) || !root.contains(next)) close();\n}\n\n// A wrapper, not `close` itself: the listener's event argument would otherwise\n// arrive as `restoreFocus`, and an outside click would yank focus back to the\n// trigger instead of leaving it where the press landed.\nconst onWindowClick = (): void => close();\nonMounted(() => window.addEventListener(\"click\", onWindowClick));\nonBeforeUnmount(() => window.removeEventListener(\"click\", onWindowClick));\n</script>\n\n<template>\n <!-- The attribute rides the strip itself, not just the prop: a host may\n pass dir without setting document direction, and both the flex order\n and the mirrored keys must agree with what is on screen. -->\n <div\n :dir=\"dir\"\n role=\"menubar\"\n class=\"flex items-center gap-0.5\"\n style=\"-webkit-app-region: no-drag\"\n @click.stop\n @focusout=\"onRootFocusout\"\n >\n <div v-for=\"menu in menus\" :key=\"menu.id\" class=\"relative\">\n <button\n :id=\"`menubar-trigger-${menu.id}`\"\n :ref=\"(el) => bindTrigger(menu.id, el)\"\n type=\"button\"\n role=\"menuitem\"\n :aria-haspopup=\"'menu'\"\n :aria-expanded=\"openId === menu.id\"\n class=\"min-h-6 rounded-sm px-2 py-1 text-xs text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:bg-subtle focus-visible:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\"\n :class=\"openId === menu.id && 'bg-subtle text-foreground'\"\n @click.stop=\"toggle(menu.id)\"\n @mouseenter=\"hover(menu.id, 'pointer')\"\n @focus=\"hover(menu.id, 'trigger-focus')\"\n @keydown=\"onTriggerKeydown($event, menu)\"\n >\n {{ menu.label }}\n </button>\n\n <!-- Scoped presence, matching every sibling overlay: enter animates in,\n leave answers with scale-out. The unconditional mount-only animation\n this used to carry never plays on close at all. In jsdom, with no\n stylesheet loaded, Vue computes zero animation duration and ends both\n phases immediately, so tests see plain unmount. -->\n <Transition enter-active-class=\"animate-scale-in\" leave-active-class=\"animate-scale-out\">\n <div\n v-if=\"openId === menu.id\"\n :ref=\"(el) => bindPanel(menu.id, el)\"\n role=\"menu\"\n :aria-label=\"menu.label\"\n tabindex=\"-1\"\n class=\"absolute left-0 top-full z-overlay mt-1 min-w-[13rem] origin-top-left rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md\"\n @click.stop\n @keydown=\"onMenuKeydown($event, menu)\"\n >\n <template v-for=\"(item, i) in openMenu(menu)\" :key=\"i\">\n <div v-if=\"item.separator\" role=\"separator\" class=\"my-1 h-px bg-border\" />\n <!-- The row's colour, not its alpha, says it is unavailable. A menu\n row is nothing but its label, and `disabled:opacity-40` composited\n that label to 2.40:1 on the popover — a disabled row a reader\n cannot make out tells them nothing about what is unavailable,\n which is the only thing it is there to say. Muted instead: 5.76:1\n at rest, and a clear drop from the 15.46:1 an available row wears,\n so the state still reads at a glance. The shortcut beside it\n declares `text-muted-foreground` on its own element, so it lands\n on the same colour rather than inheriting this one.\n\n Rows sit at text-sm/py-1.5 like DropdownMenu's — one row grammar\n across menus; the compact trigger above stays desktop chrome.\n Every row carries tabindex -1: focus arrives programmatically,\n never by tabbing through the strip. -->\n <button\n v-else\n type=\"button\"\n role=\"menuitem\"\n tabindex=\"-1\"\n :disabled=\"item.disabled\"\n :data-highlighted=\"activeIndex === i || undefined\"\n :style=\"{ animationDelay: listStaggerDelay(i) }\"\n class=\"flex w-full items-center justify-between gap-6 rounded-sm px-2 py-1.5 text-left text-sm text-foreground transition-colors duration-fast ease-out hover:bg-subtle disabled:pointer-events-none disabled:text-muted-foreground data-[highlighted]:bg-subtle focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo animate-fade-rise\"\n @click=\"choose(item)\"\n @mouseenter=\"pointAtRow(openMenu(menu), item, i)\"\n @focus=\"noteFocus(item, i)\"\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 </button>\n </template>\n </div>\n </Transition>\n </div>\n </div>\n</template>\n"],"mappings":""}
@@ -5,9 +5,11 @@
5
5
  * keyboard nav and click-outside. Selecting an item emits `select` with its `command`
6
6
  * id — the host maps that id to an action (keeps the primitive free of app logic).
7
7
  *
8
- * A11y: WAI-ARIA menubar semantics (roles + aria-expanded/haspopup) with Escape,
9
- * Arrow, Home/End and Enter/Space handling. When richer focus-trapping is needed we
10
- * can later delegate to Reka UI without changing this call-site contract.
8
+ * A11y: WAI-ARIA menubar semantics over real DOM focus, not aria-activedescendant.
9
+ * Opening a menu moves focus onto its first enabled row and the arrows walk it from
10
+ * there, so "the highlighted row" and "the focused row" are the same thing by
11
+ * construction and a screen reader announces each walked row natively — no
12
+ * bookkeeping that could drift out of sync with what is actually announced.
11
13
  */
12
14
  export interface MenubarItem {
13
15
  /** Visible label. */
@@ -28,13 +30,25 @@ export interface MenubarMenu {
28
30
  declare const _default: typeof __VLS_export;
29
31
  export default _default;
30
32
  declare const __VLS_export: import("vue").DefineComponent<{
31
- /** The top-level menus, left to right, each carrying its own item list. */
33
+ /** The top-level menus; their reading order follows `dir`. */
32
34
  menus: MenubarMenu[];
33
- }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
35
+ /**
36
+ * Reading direction. Right-to-left mirrors the strip's arrow keys —
37
+ * ArrowRight travels toward the visual left — which a hand-rolled
38
+ * handler must do itself, unlike its Reka siblings.
39
+ */
40
+ dir?: "ltr" | "rtl";
41
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
34
42
  select: (command: string) => any;
35
43
  }, string, import("vue").PublicProps, Readonly<{
36
- /** The top-level menus, left to right, each carrying its own item list. */
44
+ /** The top-level menus; their reading order follows `dir`. */
37
45
  menus: MenubarMenu[];
46
+ /**
47
+ * Reading direction. Right-to-left mirrors the strip's arrow keys —
48
+ * ArrowRight travels toward the visual left — which a hand-rolled
49
+ * handler must do itself, unlike its Reka siblings.
50
+ */
51
+ dir?: "ltr" | "rtl";
38
52
  }> & Readonly<{
39
53
  onSelect?: (command: string) => any;
40
54
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -1 +1 @@
1
- {"version":3,"file":"Menubar.vue.d.ts","sourceRoot":"","sources":["../../../../../packages/primitives/menubar/src/Menubar.vue"],"names":[],"mappings":"AAmOA;;;;;;;;;;GAUG;AACH,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;wBACoB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAEhB,2EAA2E;WACpE,WAAW,EAAE;;;;IADpB,2EAA2E;WACpE,WAAW,EAAE;;;kFAkUlB,CAAC"}
1
+ {"version":3,"file":"Menubar.vue.d.ts","sourceRoot":"","sources":["../../../../../packages/primitives/menubar/src/Menubar.vue"],"names":[],"mappings":"AAuYA;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;wBACoB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAEhB,8DAA8D;WACvD,WAAW,EAAE;IACpB;;;;OAIG;UACG,KAAK,GAAG,KAAK;;;;IAPnB,8DAA8D;WACvD,WAAW,EAAE;IACpB;;;;OAIG;UACG,KAAK,GAAG,KAAK;;;kFA2ejB,CAAC"}