@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
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { cn } from "./packages/core/src/cn.js";
2
2
  import { optional } from "./packages/core/src/props.js";
3
3
  import { useSplitAttrs } from "./packages/core/src/attrs.js";
4
- import { LIST_STAGGER_CAP, LIST_STAGGER_STEP_MS, listStaggerDelay } from "./packages/core/src/motion.js";
4
+ import { listStaggerDelay } from "./packages/core/src/motion.js";
5
5
  import { WCAG_TAGS } from "./packages/core/src/a11y-scope.js";
6
6
  import { themeScript, useTheme } from "./packages/core/src/theme.js";
7
7
  import { applyLoomIconDefaults } from "./packages/core/src/icon-defaults.js";
@@ -41,26 +41,40 @@ import "./packages/primitives/avatar/src/index.js";
41
41
  import { badgeVariants } from "./packages/primitives/badge/src/Badge.vue_vue_type_script_setup_true_lang.js";
42
42
  import Badge_default from "./packages/primitives/badge/src/Badge.js";
43
43
  import "./packages/primitives/badge/src/index.js";
44
+ import { BREADCRUMB_LABELS } from "./packages/primitives/breadcrumb/src/Breadcrumb.vue_vue_type_script_setup_true_lang.js";
44
45
  import Breadcrumb_default from "./packages/primitives/breadcrumb/src/Breadcrumb.js";
45
46
  import "./packages/primitives/breadcrumb/src/index.js";
46
- import { buttonVariantClasses, buttonVariants } from "./packages/primitives/button/src/Button.vue_vue_type_script_setup_true_lang.js";
47
+ import { buttonVariants } from "./packages/primitives/button/src/Button.vue_vue_type_script_setup_true_lang.js";
47
48
  import Button_default from "./packages/primitives/button/src/Button.js";
48
49
  import "./packages/primitives/button/src/index.js";
50
+ import { iconButtonVariants } from "./packages/primitives/icon-button/src/IconButton.vue_vue_type_script_setup_true_lang.js";
51
+ import IconButton_default from "./packages/primitives/icon-button/src/IconButton.js";
52
+ import "./packages/primitives/icon-button/src/index.js";
53
+ import { CAROUSEL_LABELS } from "./packages/primitives/carousel/src/Carousel.vue_vue_type_script_setup_true_lang.js";
54
+ import Carousel_default from "./packages/primitives/carousel/src/Carousel.js";
55
+ import "./packages/primitives/carousel/src/index.js";
56
+ import Card_default from "./packages/primitives/card/src/Card.js";
57
+ import "./packages/primitives/card/src/index.js";
49
58
  import { chipVariants } from "./packages/primitives/chip/src/Chip.vue_vue_type_script_setup_true_lang.js";
50
59
  import Chip_default from "./packages/primitives/chip/src/Chip.js";
51
60
  import "./packages/primitives/chip/src/index.js";
61
+ import Collapse_default from "./packages/primitives/collapse/src/Collapse.js";
62
+ import "./packages/primitives/collapse/src/index.js";
52
63
  import ContextMenu_default from "./packages/primitives/context-menu/src/ContextMenu.js";
53
64
  import "./packages/primitives/context-menu/src/index.js";
54
65
  import DropdownMenu_default from "./packages/primitives/dropdown-menu/src/DropdownMenu.js";
55
66
  import "./packages/primitives/dropdown-menu/src/index.js";
56
- import { iconButtonVariants } from "./packages/primitives/icon-button/src/IconButton.vue_vue_type_script_setup_true_lang.js";
57
- import IconButton_default from "./packages/primitives/icon-button/src/IconButton.js";
58
- import "./packages/primitives/icon-button/src/index.js";
59
67
  import InlineError_default from "./packages/primitives/inline-error/src/InlineError.js";
60
68
  import "./packages/primitives/inline-error/src/index.js";
69
+ import { kbdVariants } from "./packages/primitives/kbd/src/Kbd.vue_vue_type_script_setup_true_lang.js";
70
+ import Kbd_default from "./packages/primitives/kbd/src/Kbd.js";
71
+ import "./packages/primitives/kbd/src/index.js";
61
72
  import { linkVariants } from "./packages/primitives/link/src/Link.vue_vue_type_script_setup_true_lang.js";
62
73
  import Link_default from "./packages/primitives/link/src/Link.js";
63
74
  import "./packages/primitives/link/src/index.js";
75
+ import List_default from "./packages/primitives/list/src/List.js";
76
+ import ListItem_default from "./packages/primitives/list/src/ListItem.js";
77
+ import "./packages/primitives/list/src/index.js";
64
78
  import Menubar_default from "./packages/primitives/menubar/src/Menubar.js";
65
79
  import "./packages/primitives/menubar/src/index.js";
66
80
  import Popover_default from "./packages/primitives/popover/src/Popover.js";
@@ -71,6 +85,20 @@ import Tabs_default from "./packages/primitives/tabs/src/Tabs.js";
71
85
  import "./packages/primitives/tabs/src/index.js";
72
86
  import Tooltip_default from "./packages/primitives/tooltip/src/Tooltip.js";
73
87
  import "./packages/primitives/tooltip/src/index.js";
88
+ import { TIMELINE_LABELS } from "./packages/primitives/timeline/src/Timeline.vue_vue_type_script_setup_true_lang.js";
89
+ import Timeline_default from "./packages/primitives/timeline/src/Timeline.js";
90
+ import TimelineItem_default from "./packages/primitives/timeline/src/TimelineItem.js";
91
+ import "./packages/primitives/timeline/src/index.js";
92
+ import { TABLE_LABELS } from "./packages/primitives/table/src/Table.vue_vue_type_script_setup_true_lang.js";
93
+ import Table_default from "./packages/primitives/table/src/Table.js";
94
+ import { tableRowVariants } from "./packages/primitives/table/src/TableRow.vue_vue_type_script_setup_true_lang.js";
95
+ import TableRow_default from "./packages/primitives/table/src/TableRow.js";
96
+ import TableHead_default from "./packages/primitives/table/src/TableHead.js";
97
+ import TableCell_default from "./packages/primitives/table/src/TableCell.js";
98
+ import "./packages/primitives/table/src/index.js";
99
+ import { ALERT_LABELS } from "./packages/primitives/alert/src/Alert.vue_vue_type_script_setup_true_lang.js";
100
+ import Alert_default from "./packages/primitives/alert/src/Alert.js";
101
+ import "./packages/primitives/alert/src/index.js";
74
102
  import { ALERT_DIALOG_LABELS } from "./packages/primitives/alert-dialog/src/AlertDialog.vue_vue_type_script_setup_true_lang.js";
75
103
  import AlertDialog_default from "./packages/primitives/alert-dialog/src/AlertDialog.js";
76
104
  import "./packages/primitives/alert-dialog/src/index.js";
@@ -143,13 +171,16 @@ import "./packages/primitives/switch/src/index.js";
143
171
  import { TAGS_INPUT_LABELS } from "./packages/primitives/tags-input/src/TagsInput.vue_vue_type_script_setup_true_lang.js";
144
172
  import TagsInput_default from "./packages/primitives/tags-input/src/TagsInput.js";
145
173
  import "./packages/primitives/tags-input/src/index.js";
174
+ import { TEXTAREA_LABELS } from "./packages/primitives/textarea/src/Textarea.vue_vue_type_script_setup_true_lang.js";
146
175
  import Textarea_default from "./packages/primitives/textarea/src/Textarea.js";
147
176
  import "./packages/primitives/textarea/src/index.js";
177
+ import { TEXT_FIELD_LABELS } from "./packages/primitives/text-field/src/TextField.vue_vue_type_script_setup_true_lang.js";
148
178
  import TextField_default from "./packages/primitives/text-field/src/TextField.js";
149
179
  import "./packages/primitives/text-field/src/index.js";
150
180
  import TimePicker_default from "./packages/primitives/time-picker/src/TimePicker.js";
151
181
  import "./packages/primitives/time-picker/src/index.js";
152
182
  import { TOAST_LABELS } from "./packages/primitives/toast/src/ToastItem.vue_vue_type_script_setup_true_lang.js";
183
+ import ToastItem_default from "./packages/primitives/toast/src/ToastItem.js";
153
184
  import Toast_default from "./packages/primitives/toast/src/Toast.js";
154
185
  import "./packages/primitives/toast/src/index.js";
155
186
  import { WINDOW_CONTROLS_LABELS } from "./packages/primitives/window-controls/src/WindowControls.vue_vue_type_script_setup_true_lang.js";
@@ -163,6 +194,7 @@ import Grid_default from "./packages/composition/grid/src/Grid.js";
163
194
  import "./packages/composition/grid/src/index.js";
164
195
  import Inline_default from "./packages/composition/inline/src/Inline.js";
165
196
  import "./packages/composition/inline/src/index.js";
197
+ import { SCROLL_REEL_LABELS } from "./packages/composition/scroll-reel/src/ScrollReel.vue_vue_type_script_setup_true_lang.js";
166
198
  import ScrollReel_default from "./packages/composition/scroll-reel/src/ScrollReel.js";
167
199
  import "./packages/composition/scroll-reel/src/index.js";
168
200
  import Sidebar_default from "./packages/composition/sidebar/src/Sidebar.js";
@@ -215,4 +247,4 @@ import SidebarNav_default from "./packages/blocks/sidebar-nav/src/SidebarNav.js"
215
247
  import "./packages/blocks/sidebar-nav/src/index.js";
216
248
  import ToastStack_default from "./packages/blocks/toast-stack/src/ToastStack.js";
217
249
  import "./packages/blocks/toast-stack/src/index.js";
218
- export { ALERT_DIALOG_LABELS, AVATAR_GROUP_LABELS, Accordion_default as Accordion, AlertDialog_default as AlertDialog, AppHeader_default as AppHeader, AppShell_default as AppShell, Avatar_default as Avatar, AvatarGroup_default as AvatarGroup, Badge_default as Badge, Breadcrumb_default as Breadcrumb, Button_default as Button, CALENDAR_PANEL_LABELS, COLOR_PICKER_LABELS, COMBOBOX_LABELS, COUNT_LABELS, Center_default as Center, Centered_default as Centered, Checkbox_default as Checkbox, Chip_default as Chip, ColorPicker_default as ColorPicker, Combobox_default as Combobox, ContextMenu_default as ContextMenu, DATE_RANGE_LABELS, DATE_SEGMENT_LABELS, DATE_TIME_RANGE_LABELS, DIALOG_LABELS, DRAWER_LABELS, Dashboard_default as Dashboard, DashboardGrid_default as DashboardGrid, DatePicker_default as DatePicker, DateRangePicker_default as DateRangePicker, DateTimePicker_default as DateTimePicker, DateTimeRangePicker_default as DateTimeRangePicker, DesktopAppShell_default as DesktopAppShell, Dialog_default as Dialog, Drawer_default as Drawer, DropdownMenu_default as DropdownMenu, EDITABLE_LABELS, Editable_default as Editable, EmptyState_default as EmptyState, ErrorState_default as ErrorState, FILE_UPLOAD_LABELS, Field_default as Field, Fieldset_default as Fieldset, FileUpload_default as FileUpload, FormActions_default as FormActions, FormLayout_default as FormLayout, FormSection_default as FormSection, Frame_default as Frame, Grid_default as Grid, HoverCard_default as HoverCard, INDICATOR_LABELS, IconButton_default as IconButton, Indicator_default as Indicator, Inline_default as Inline, InlineError_default as InlineError, LIST_STAGGER_CAP, LIST_STAGGER_STEP_MS, Link_default as Link, LoadingState_default as LoadingState, MasterDetail_default as MasterDetail, Menubar_default as Menubar, MetricCard_default as MetricCard, NUMBER_FIELD_LABELS, NumberField_default as NumberField, OTP_INPUT_LABELS, OtpInput_default as OtpInput, PAGINATION_LABELS, PROGRESS_LABELS, PageHeader_default as PageHeader, Pagination_default as Pagination, Popover_default as Popover, Progress_default as Progress, RADIAL_PROGRESS_LABELS, RANGE_CELL_LABELS, RATING_LABELS, RadialProgress_default as RadialProgress, RadioGroup_default as RadioGroup, Rating_default as Rating, Reading_default as Reading, RowActions_default as RowActions, STEPPER_LABELS, ScrollArea_default as ScrollArea, ScrollReel_default as ScrollReel, SegmentedControl_default as SegmentedControl, Select_default as Select, Separator_default as Separator, Settings_default as Settings, Sidebar_default as Sidebar, SidebarNav_default as SidebarNav, Skeleton_default as Skeleton, Slider_default as Slider, SpeedDial_default as SpeedDial, Spinner_default as Spinner, Split_default as Split, SplitLayout_default as SplitLayout, Stack_default as Stack, Stepper_default as Stepper, Surface_default as Surface, Switch_default as Switch, TAGS_INPUT_LABELS, TIME_SEGMENT_LABELS, TOAST_LABELS, Tabs_default as Tabs, TagsInput_default as TagsInput, TextField_default as TextField, Textarea_default as Textarea, TimePicker_default as TimePicker, TitleBar_default as TitleBar, Toast_default as Toast, ToastStack_default as ToastStack, Tooltip_default as Tooltip, WCAG_TAGS, WINDOW_CONTROLS_LABELS, WindowControls_default as WindowControls, applyLoomIconDefaults, avatarVariants, badgeVariants, buttonVariantClasses, buttonVariants, chipVariants, cn, comboboxVariants, iconButtonVariants, indicatorToneVariants, indicatorVariants, linkVariants, listStaggerDelay, optional, paginationVariants, progressVariants, provideFieldContext, provideLoomLabels, radialProgressVariants, selectVariants, skeletonVariants, spinnerVariants, surfaceVariants, themeScript, useAncestorDisabled, useFieldControl, useLabels, useOuterFieldContext, useSplitAttrs, useTheme, warningWindow };
250
+ export { ALERT_DIALOG_LABELS, ALERT_LABELS, AVATAR_GROUP_LABELS, Accordion_default as Accordion, Alert_default as Alert, AlertDialog_default as AlertDialog, AppHeader_default as AppHeader, AppShell_default as AppShell, Avatar_default as Avatar, AvatarGroup_default as AvatarGroup, BREADCRUMB_LABELS, Badge_default as Badge, Breadcrumb_default as Breadcrumb, Button_default as Button, CALENDAR_PANEL_LABELS, CAROUSEL_LABELS, COLOR_PICKER_LABELS, COMBOBOX_LABELS, COUNT_LABELS, Card_default as Card, Carousel_default as Carousel, Center_default as Center, Centered_default as Centered, Checkbox_default as Checkbox, Chip_default as Chip, Collapse_default as Collapse, ColorPicker_default as ColorPicker, Combobox_default as Combobox, ContextMenu_default as ContextMenu, DATE_RANGE_LABELS, DATE_SEGMENT_LABELS, DATE_TIME_RANGE_LABELS, DIALOG_LABELS, DRAWER_LABELS, Dashboard_default as Dashboard, DashboardGrid_default as DashboardGrid, DatePicker_default as DatePicker, DateRangePicker_default as DateRangePicker, DateTimePicker_default as DateTimePicker, DateTimeRangePicker_default as DateTimeRangePicker, DesktopAppShell_default as DesktopAppShell, Dialog_default as Dialog, Drawer_default as Drawer, DropdownMenu_default as DropdownMenu, EDITABLE_LABELS, Editable_default as Editable, EmptyState_default as EmptyState, ErrorState_default as ErrorState, FILE_UPLOAD_LABELS, Field_default as Field, Fieldset_default as Fieldset, FileUpload_default as FileUpload, FormActions_default as FormActions, FormLayout_default as FormLayout, FormSection_default as FormSection, Frame_default as Frame, Grid_default as Grid, HoverCard_default as HoverCard, INDICATOR_LABELS, IconButton_default as IconButton, Indicator_default as Indicator, Inline_default as Inline, InlineError_default as InlineError, Kbd_default as Kbd, Link_default as Link, List_default as List, ListItem_default as ListItem, LoadingState_default as LoadingState, MasterDetail_default as MasterDetail, Menubar_default as Menubar, MetricCard_default as MetricCard, NUMBER_FIELD_LABELS, NumberField_default as NumberField, OTP_INPUT_LABELS, OtpInput_default as OtpInput, PAGINATION_LABELS, PROGRESS_LABELS, PageHeader_default as PageHeader, Pagination_default as Pagination, Popover_default as Popover, Progress_default as Progress, RADIAL_PROGRESS_LABELS, RANGE_CELL_LABELS, RATING_LABELS, RadialProgress_default as RadialProgress, RadioGroup_default as RadioGroup, Rating_default as Rating, Reading_default as Reading, RowActions_default as RowActions, SCROLL_REEL_LABELS, STEPPER_LABELS, ScrollArea_default as ScrollArea, ScrollReel_default as ScrollReel, SegmentedControl_default as SegmentedControl, Select_default as Select, Separator_default as Separator, Settings_default as Settings, Sidebar_default as Sidebar, SidebarNav_default as SidebarNav, Skeleton_default as Skeleton, Slider_default as Slider, SpeedDial_default as SpeedDial, Spinner_default as Spinner, Split_default as Split, SplitLayout_default as SplitLayout, Stack_default as Stack, Stepper_default as Stepper, Surface_default as Surface, Switch_default as Switch, TABLE_LABELS, TAGS_INPUT_LABELS, TEXTAREA_LABELS, TEXT_FIELD_LABELS, TIMELINE_LABELS, TIME_SEGMENT_LABELS, TOAST_LABELS, Table_default as Table, TableCell_default as TableCell, TableHead_default as TableHead, TableRow_default as TableRow, Tabs_default as Tabs, TagsInput_default as TagsInput, TextField_default as TextField, Textarea_default as Textarea, TimePicker_default as TimePicker, Timeline_default as Timeline, TimelineItem_default as TimelineItem, TitleBar_default as TitleBar, Toast_default as Toast, ToastItem_default as ToastItem, ToastStack_default as ToastStack, Tooltip_default as Tooltip, WCAG_TAGS, WINDOW_CONTROLS_LABELS, WindowControls_default as WindowControls, applyLoomIconDefaults, avatarVariants, badgeVariants, buttonVariants, chipVariants, cn, comboboxVariants, iconButtonVariants, indicatorToneVariants, indicatorVariants, kbdVariants, linkVariants, listStaggerDelay, optional, paginationVariants, progressVariants, provideFieldContext, provideLoomLabels, radialProgressVariants, selectVariants, skeletonVariants, spinnerVariants, surfaceVariants, tableRowVariants, themeScript, useAncestorDisabled, useFieldControl, useLabels, useOuterFieldContext, useSplitAttrs, useTheme, warningWindow };
@@ -1 +1 @@
1
- {"version":3,"file":"AppHeader.js","names":[],"sources":["../../../../../packages/blocks/app-header/src/AppHeader.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * AppHeader — the web app's TOP BAR: the shell-level strip that stays on\n * screen above every surface, distinct from two components it is easy to\n * confuse with:\n *\n * - **`PageHeader`** — a surface's own pinned title band, sitting *inside*\n * the content area this bar sits above.\n * - **`TitleBar`** — the desktop window's native chrome (drag region, window\n * controls). This bar is browser content, not window furniture.\n *\n * Layout is three regions, so callers never hand-tune widths: brand (left) ·\n * optional search · a trailing cluster for a leading control, notifications, and\n * the user menu, pushed right by `ml-auto`. Every region is a named slot —\n * this block owns the strip's geometry and elevation, never its content or\n * behavior.\n *\n * The trailing cluster is pushed right by its own `ml-auto`, not by a spacer\n * element. A spacer works, but it is a second `flex-1` beside the search\n * field, so the two end up splitting the free space instead of the field\n * taking what is actually left; `ml-auto` costs no element and no width, and\n * keeps the cluster flush right even when no search is slotted at all.\n *\n * **Below `sm` the bar is two rows, and that is the point of this block's\n * responsive behavior.** A brand, a real search field, and a leading control +\n * notifications + account cluster do not fit across a 390px viewport: on\n * that width the search field is left about 60px and renders as a magnifier\n * glyph pressed against the org name — a control that is technically present\n * and practically unusable. So the search takes a full-width second row\n * (`basis-full` + `order-last`), the header height goes from fixed to\n * `min-h-14`, and from `sm` up it snaps back to the single `flex-nowrap` row.\n * Wrapping rather than hiding is deliberate: the host slotted a search\n * because its users need one, and a block does not get to decide they need\n * it less on a phone.\n *\n * The `order-last` is the one thing to keep in mind if this changes: it\n * moves the search visually below the cluster while leaving it before the\n * cluster in the DOM, so on a phone the tab order reaches search first. That\n * is the better of the two mismatches — search is the more-used control —\n * but it is a mismatch, so do not extend `order-*` to the other regions.\n *\n * **Pinned, and separated by a hairline — never a shadow.** It sits on\n * `bg-card` (the raised plane), one step above the content it sits over,\n * unlike `PageHeader` which shares the content's own `bg-background` plane.\n * Because content scrolls *under* it, the surface is translucent + blurred\n * so the motion beneath stays legible as depth — the opaque `bg-card` is\n * declared first and stays the fallback wherever `backdrop-filter` is\n * unsupported, so the bar is never a see-through smear.\n *\n * Widths step rather than hold one value: gutters open up from `sm` and\n * again on wide desktops (`3xl`, 1920px), where a 16px gutter beside a\n * 1920px canvas reads as an accident.\n *\n * Deliberately neutral: this is shell chrome shared by every user and every\n * action alike, so it never wears `--primary`/`--accent` — the bar stays\n * uncommitted until a specific action is happening on the surface below.\n */\ndefineProps<{\n /** Accessible name for the `<header>` landmark, for a page with more than one header-like region. */\n ariaLabel?: string;\n}>();\n</script>\n\n<template>\n <header\n :aria-label=\"ariaLabel\"\n class=\"sticky top-0 z-30 flex min-h-14 flex-wrap items-center gap-x-2 gap-y-2 border-b border-border bg-card px-3 py-2 text-card-foreground backdrop-blur-md supports-[backdrop-filter]:bg-card/80 sm:h-14 sm:flex-nowrap sm:gap-x-3 sm:px-4 sm:py-0 lg:px-6 3xl:h-16 3xl:px-8\"\n >\n <div v-if=\"$slots.brand\" class=\"flex shrink-0 items-center gap-2\">\n <!-- @slot The product mark and name, leftmost. -->\n <slot name=\"brand\" />\n </div>\n\n <!-- Own full-width row below `sm` (see the doc header on `order-last`);\n from `sm` up it rejoins the row and takes a cap so it never stretches\n into a banner on a wide canvas. -->\n <div\n v-if=\"$slots.search\"\n class=\"order-last min-w-0 basis-full sm:order-none sm:max-w-sm sm:flex-1 sm:basis-auto lg:max-w-md\"\n >\n <!-- @slot The app's global search field. Exactly one control — a filter belongs to `PageHeader` or the content area, not here. -->\n <slot name=\"search\" />\n </div>\n\n <div\n v-if=\"$slots.leading || $slots.notifications || $slots.userMenu\"\n class=\"ml-auto flex shrink-0 items-center gap-1 sm:gap-2\"\n >\n <!-- @slot A leading control in the trailing cluster — workspace switcher, org selector, breadcrumb, etc. -->\n <slot name=\"leading\" />\n <!-- @slot The notifications trigger, between the leading control and the account menu. -->\n <slot name=\"notifications\" />\n <!-- @slot The account menu, trailing the cluster. -->\n <slot name=\"userMenu\" />\n </div>\n </header>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"AppHeader.js","names":[],"sources":["../../../../../packages/blocks/app-header/src/AppHeader.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * AppHeader — the web app's TOP BAR: the shell-level strip that stays on\n * screen above every surface, distinct from two components it is easy to\n * confuse with:\n *\n * - **`PageHeader`** — a surface's own pinned title band, sitting *inside*\n * the content area this bar sits above.\n * - **`TitleBar`** — the desktop window's native chrome (drag region, window\n * controls). This bar is browser content, not window furniture.\n *\n * Layout is three regions, so callers never hand-tune widths: brand (left) ·\n * optional search · a trailing cluster for a leading control, notifications, and\n * the user menu, pushed right by `ml-auto`. Every region is a named slot —\n * this block owns the strip's geometry and elevation, never its content or\n * behavior.\n *\n * The trailing cluster is pushed right by its own `ml-auto`, not by a spacer\n * element. A spacer works, but it is a second `flex-1` beside the search\n * field, so the two end up splitting the free space instead of the field\n * taking what is actually left; `ml-auto` costs no element and no width, and\n * keeps the cluster flush right even when no search is slotted at all.\n *\n * **Below `sm` the bar is two rows, and that is the point of this block's\n * responsive behavior.** A brand, a real search field, and a leading control +\n * notifications + account cluster do not fit across a 390px viewport: on\n * that width the search field is left about 60px and renders as a magnifier\n * glyph pressed against the org name — a control that is technically present\n * and practically unusable. So the search takes a full-width second row\n * (`basis-full` + `order-last`), the header height goes from fixed to\n * `min-h-14`, and from `sm` up it snaps back to the single `flex-nowrap` row.\n * Wrapping rather than hiding is deliberate: the host slotted a search\n * because its users need one, and a block does not get to decide they need\n * it less on a phone.\n *\n * The `order-last` is the one thing to keep in mind if this changes: it\n * moves the search visually below the cluster while leaving it before the\n * cluster in the DOM, so on a phone the tab order reaches search first. That\n * is the better of the two mismatches — search is the more-used control —\n * but it is a mismatch, so do not extend `order-*` to the other regions.\n *\n * **Pinned, and separated by a hairline — never a shadow.** It sits on\n * `bg-card` (the raised plane), one step above the content it sits over,\n * unlike `PageHeader` which shares the content's own `bg-background` plane.\n * Because content scrolls *under* it, the surface is translucent + blurred\n * so the motion beneath stays legible as depth — the opaque `bg-card` is\n * declared first and stays the fallback wherever `backdrop-filter` is\n * unsupported, so the bar is never a see-through smear.\n *\n * Widths step rather than hold one value: gutters open up from `sm` and\n * again on wide desktops (`3xl`, 1920px), where a 16px gutter beside a\n * 1920px canvas reads as an accident.\n *\n * Deliberately neutral: this is shell chrome shared by every user and every\n * action alike, so it never wears `--primary`/`--accent` — the bar stays\n * uncommitted until a specific action is happening on the surface below.\n */\ndefineProps<{\n /** Accessible name for the `<header>` landmark, for a page with more than one header-like region. */\n ariaLabel?: string;\n}>();\n</script>\n\n<template>\n <!-- `data-loom-app-header` is the hook `global.css` uses to add the\n safe-area inset to the bar's top padding (the same vendor-rule pattern\n as `[data-loom-titlebar]`): a PWA under a notch or a title-bar overlay\n must not paint its first row into reserved space. -->\n <header\n data-loom-app-header=\"\"\n :aria-label=\"ariaLabel\"\n class=\"sticky top-0 z-30 flex min-h-14 flex-wrap items-center gap-x-2 gap-y-2 border-b border-border bg-card px-3 py-2 text-card-foreground backdrop-blur-md supports-[backdrop-filter]:bg-card/80 sm:h-14 sm:flex-nowrap sm:gap-x-3 sm:px-4 sm:py-0 lg:px-6 3xl:h-16 3xl:px-8\"\n >\n <div v-if=\"$slots.brand\" class=\"flex shrink-0 items-center gap-2\">\n <!-- @slot The product mark and name, leftmost. -->\n <slot name=\"brand\" />\n </div>\n\n <!-- Own full-width row below `sm` (see the doc header on `order-last`);\n from `sm` up it rejoins the row and takes a cap so it never stretches\n into a banner on a wide canvas. -->\n <div\n v-if=\"$slots.search\"\n class=\"order-last min-w-0 basis-full sm:order-none sm:max-w-sm sm:flex-1 sm:basis-auto lg:max-w-md\"\n >\n <!-- @slot The app's global search field. Exactly one control — a filter belongs to `PageHeader` or the content area, not here. -->\n <slot name=\"search\" />\n </div>\n\n <div\n v-if=\"$slots.leading || $slots.notifications || $slots.userMenu\"\n class=\"ml-auto flex shrink-0 items-center gap-1 sm:gap-2\"\n >\n <!-- @slot A leading control in the trailing cluster — workspace switcher, org selector, breadcrumb, etc. -->\n <slot name=\"leading\" />\n <!-- @slot The notifications trigger, between the leading control and the account menu. -->\n <slot name=\"notifications\" />\n <!-- @slot The account menu, trailing the cluster. -->\n <slot name=\"userMenu\" />\n </div>\n </header>\n</template>\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"AppHeader.vue.d.ts","sourceRoot":"","sources":["../../../../../packages/blocks/app-header/src/AppHeader.vue"],"names":[],"mappings":"AAoGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,KAAK,WAAW,GAAG;IACjB,qGAAqG;IACrG,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAyFF,QAAA,IAAI,OAAO,IAAU,EAAE,OAAO,IAAU,EAAE,OAAO,IAAU,EAAE,OAAO,IAAU,EAAE,OAAO,IAAW,CAAE;AACpG,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAC1C;IAAE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAC3C;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAC5C;IAAE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,CAAC;AAKhD,QAAA,MAAM,UAAU,kSAEd,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AACzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"AppHeader.vue.d.ts","sourceRoot":"","sources":["../../../../../packages/blocks/app-header/src/AppHeader.vue"],"names":[],"mappings":"AAyGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AACH,KAAK,WAAW,GAAG;IACjB,qGAAqG;IACrG,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AA0FF,QAAA,IAAI,OAAO,IAAU,EAAE,OAAO,IAAU,EAAE,OAAO,IAAU,EAAE,OAAO,IAAU,EAAE,OAAO,IAAW,CAAE;AACpG,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAC1C;IAAE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAC3C;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAC5C;IAAE,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,CAAC;AAKhD,QAAA,MAAM,UAAU,kSAEd,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AACzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -75,6 +75,7 @@ var AppHeader_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
75
75
  */
76
76
  return (_ctx, _cache) => {
77
77
  return openBlock(), createElementBlock("header", {
78
+ "data-loom-app-header": "",
78
79
  "aria-label": __props.ariaLabel,
79
80
  class: "sticky top-0 z-30 flex min-h-14 flex-wrap items-center gap-x-2 gap-y-2 border-b border-border bg-card px-3 py-2 text-card-foreground backdrop-blur-md supports-[backdrop-filter]:bg-card/80 sm:h-14 sm:flex-nowrap sm:gap-x-3 sm:px-4 sm:py-0 lg:px-6 3xl:h-16 3xl:px-8"
80
81
  }, [
@@ -1 +1 @@
1
- {"version":3,"file":"AppHeader.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../../../packages/blocks/app-header/src/AppHeader.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * AppHeader — the web app's TOP BAR: the shell-level strip that stays on\n * screen above every surface, distinct from two components it is easy to\n * confuse with:\n *\n * - **`PageHeader`** — a surface's own pinned title band, sitting *inside*\n * the content area this bar sits above.\n * - **`TitleBar`** — the desktop window's native chrome (drag region, window\n * controls). This bar is browser content, not window furniture.\n *\n * Layout is three regions, so callers never hand-tune widths: brand (left) ·\n * optional search · a trailing cluster for a leading control, notifications, and\n * the user menu, pushed right by `ml-auto`. Every region is a named slot —\n * this block owns the strip's geometry and elevation, never its content or\n * behavior.\n *\n * The trailing cluster is pushed right by its own `ml-auto`, not by a spacer\n * element. A spacer works, but it is a second `flex-1` beside the search\n * field, so the two end up splitting the free space instead of the field\n * taking what is actually left; `ml-auto` costs no element and no width, and\n * keeps the cluster flush right even when no search is slotted at all.\n *\n * **Below `sm` the bar is two rows, and that is the point of this block's\n * responsive behavior.** A brand, a real search field, and a leading control +\n * notifications + account cluster do not fit across a 390px viewport: on\n * that width the search field is left about 60px and renders as a magnifier\n * glyph pressed against the org name — a control that is technically present\n * and practically unusable. So the search takes a full-width second row\n * (`basis-full` + `order-last`), the header height goes from fixed to\n * `min-h-14`, and from `sm` up it snaps back to the single `flex-nowrap` row.\n * Wrapping rather than hiding is deliberate: the host slotted a search\n * because its users need one, and a block does not get to decide they need\n * it less on a phone.\n *\n * The `order-last` is the one thing to keep in mind if this changes: it\n * moves the search visually below the cluster while leaving it before the\n * cluster in the DOM, so on a phone the tab order reaches search first. That\n * is the better of the two mismatches — search is the more-used control —\n * but it is a mismatch, so do not extend `order-*` to the other regions.\n *\n * **Pinned, and separated by a hairline — never a shadow.** It sits on\n * `bg-card` (the raised plane), one step above the content it sits over,\n * unlike `PageHeader` which shares the content's own `bg-background` plane.\n * Because content scrolls *under* it, the surface is translucent + blurred\n * so the motion beneath stays legible as depth — the opaque `bg-card` is\n * declared first and stays the fallback wherever `backdrop-filter` is\n * unsupported, so the bar is never a see-through smear.\n *\n * Widths step rather than hold one value: gutters open up from `sm` and\n * again on wide desktops (`3xl`, 1920px), where a 16px gutter beside a\n * 1920px canvas reads as an accident.\n *\n * Deliberately neutral: this is shell chrome shared by every user and every\n * action alike, so it never wears `--primary`/`--accent` — the bar stays\n * uncommitted until a specific action is happening on the surface below.\n */\ndefineProps<{\n /** Accessible name for the `<header>` landmark, for a page with more than one header-like region. */\n ariaLabel?: string;\n}>();\n</script>\n\n<template>\n <header\n :aria-label=\"ariaLabel\"\n class=\"sticky top-0 z-30 flex min-h-14 flex-wrap items-center gap-x-2 gap-y-2 border-b border-border bg-card px-3 py-2 text-card-foreground backdrop-blur-md supports-[backdrop-filter]:bg-card/80 sm:h-14 sm:flex-nowrap sm:gap-x-3 sm:px-4 sm:py-0 lg:px-6 3xl:h-16 3xl:px-8\"\n >\n <div v-if=\"$slots.brand\" class=\"flex shrink-0 items-center gap-2\">\n <!-- @slot The product mark and name, leftmost. -->\n <slot name=\"brand\" />\n </div>\n\n <!-- Own full-width row below `sm` (see the doc header on `order-last`);\n from `sm` up it rejoins the row and takes a cap so it never stretches\n into a banner on a wide canvas. -->\n <div\n v-if=\"$slots.search\"\n class=\"order-last min-w-0 basis-full sm:order-none sm:max-w-sm sm:flex-1 sm:basis-auto lg:max-w-md\"\n >\n <!-- @slot The app's global search field. Exactly one control — a filter belongs to `PageHeader` or the content area, not here. -->\n <slot name=\"search\" />\n </div>\n\n <div\n v-if=\"$slots.leading || $slots.notifications || $slots.userMenu\"\n class=\"ml-auto flex shrink-0 items-center gap-1 sm:gap-2\"\n >\n <!-- @slot A leading control in the trailing cluster — workspace switcher, org selector, breadcrumb, etc. -->\n <slot name=\"leading\" />\n <!-- @slot The notifications trigger, between the leading control and the account menu. -->\n <slot name=\"notifications\" />\n <!-- @slot The account menu, trailing the cluster. -->\n <slot name=\"userMenu\" />\n </div>\n </header>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgEE,OAAA,UAAA,GAAA,mBA+BS,UAAA;IA9BN,cAAY,QAAA;IACb,OAAM;;IAEKA,KAAAA,OAAO,SAAlB,UAAA,GAAA,mBAGM,OAHN,YAGM,CADJ,WAAqB,KAAA,QAAA,OAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;IAOfA,KAAAA,OAAO,UADf,UAAA,GAAA,mBAMM,OANN,YAMM,CADJ,WAAsB,KAAA,QAAA,QAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;IAIhBA,KAAAA,OAAO,WAAWA,KAAAA,OAAO,iBAAiBA,KAAAA,OAAO,YADzD,UAAA,GAAA,mBAUM,OAVN,YAUM;KALJ,WAAuB,KAAA,QAAA,SAAA;KAEvB,WAA6B,KAAA,QAAA,eAAA;KAE7B,WAAwB,KAAA,QAAA,UAAA"}
1
+ {"version":3,"file":"AppHeader.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../../../packages/blocks/app-header/src/AppHeader.vue"],"sourcesContent":["<script setup lang=\"ts\">\n/**\n * AppHeader — the web app's TOP BAR: the shell-level strip that stays on\n * screen above every surface, distinct from two components it is easy to\n * confuse with:\n *\n * - **`PageHeader`** — a surface's own pinned title band, sitting *inside*\n * the content area this bar sits above.\n * - **`TitleBar`** — the desktop window's native chrome (drag region, window\n * controls). This bar is browser content, not window furniture.\n *\n * Layout is three regions, so callers never hand-tune widths: brand (left) ·\n * optional search · a trailing cluster for a leading control, notifications, and\n * the user menu, pushed right by `ml-auto`. Every region is a named slot —\n * this block owns the strip's geometry and elevation, never its content or\n * behavior.\n *\n * The trailing cluster is pushed right by its own `ml-auto`, not by a spacer\n * element. A spacer works, but it is a second `flex-1` beside the search\n * field, so the two end up splitting the free space instead of the field\n * taking what is actually left; `ml-auto` costs no element and no width, and\n * keeps the cluster flush right even when no search is slotted at all.\n *\n * **Below `sm` the bar is two rows, and that is the point of this block's\n * responsive behavior.** A brand, a real search field, and a leading control +\n * notifications + account cluster do not fit across a 390px viewport: on\n * that width the search field is left about 60px and renders as a magnifier\n * glyph pressed against the org name — a control that is technically present\n * and practically unusable. So the search takes a full-width second row\n * (`basis-full` + `order-last`), the header height goes from fixed to\n * `min-h-14`, and from `sm` up it snaps back to the single `flex-nowrap` row.\n * Wrapping rather than hiding is deliberate: the host slotted a search\n * because its users need one, and a block does not get to decide they need\n * it less on a phone.\n *\n * The `order-last` is the one thing to keep in mind if this changes: it\n * moves the search visually below the cluster while leaving it before the\n * cluster in the DOM, so on a phone the tab order reaches search first. That\n * is the better of the two mismatches — search is the more-used control —\n * but it is a mismatch, so do not extend `order-*` to the other regions.\n *\n * **Pinned, and separated by a hairline — never a shadow.** It sits on\n * `bg-card` (the raised plane), one step above the content it sits over,\n * unlike `PageHeader` which shares the content's own `bg-background` plane.\n * Because content scrolls *under* it, the surface is translucent + blurred\n * so the motion beneath stays legible as depth — the opaque `bg-card` is\n * declared first and stays the fallback wherever `backdrop-filter` is\n * unsupported, so the bar is never a see-through smear.\n *\n * Widths step rather than hold one value: gutters open up from `sm` and\n * again on wide desktops (`3xl`, 1920px), where a 16px gutter beside a\n * 1920px canvas reads as an accident.\n *\n * Deliberately neutral: this is shell chrome shared by every user and every\n * action alike, so it never wears `--primary`/`--accent` — the bar stays\n * uncommitted until a specific action is happening on the surface below.\n */\ndefineProps<{\n /** Accessible name for the `<header>` landmark, for a page with more than one header-like region. */\n ariaLabel?: string;\n}>();\n</script>\n\n<template>\n <!-- `data-loom-app-header` is the hook `global.css` uses to add the\n safe-area inset to the bar's top padding (the same vendor-rule pattern\n as `[data-loom-titlebar]`): a PWA under a notch or a title-bar overlay\n must not paint its first row into reserved space. -->\n <header\n data-loom-app-header=\"\"\n :aria-label=\"ariaLabel\"\n class=\"sticky top-0 z-30 flex min-h-14 flex-wrap items-center gap-x-2 gap-y-2 border-b border-border bg-card px-3 py-2 text-card-foreground backdrop-blur-md supports-[backdrop-filter]:bg-card/80 sm:h-14 sm:flex-nowrap sm:gap-x-3 sm:px-4 sm:py-0 lg:px-6 3xl:h-16 3xl:px-8\"\n >\n <div v-if=\"$slots.brand\" class=\"flex shrink-0 items-center gap-2\">\n <!-- @slot The product mark and name, leftmost. -->\n <slot name=\"brand\" />\n </div>\n\n <!-- Own full-width row below `sm` (see the doc header on `order-last`);\n from `sm` up it rejoins the row and takes a cap so it never stretches\n into a banner on a wide canvas. -->\n <div\n v-if=\"$slots.search\"\n class=\"order-last min-w-0 basis-full sm:order-none sm:max-w-sm sm:flex-1 sm:basis-auto lg:max-w-md\"\n >\n <!-- @slot The app's global search field. Exactly one control — a filter belongs to `PageHeader` or the content area, not here. -->\n <slot name=\"search\" />\n </div>\n\n <div\n v-if=\"$slots.leading || $slots.notifications || $slots.userMenu\"\n class=\"ml-auto flex shrink-0 items-center gap-1 sm:gap-2\"\n >\n <!-- @slot A leading control in the trailing cluster — workspace switcher, org selector, breadcrumb, etc. -->\n <slot name=\"leading\" />\n <!-- @slot The notifications trigger, between the leading control and the account menu. -->\n <slot name=\"notifications\" />\n <!-- @slot The account menu, trailing the cluster. -->\n <slot name=\"userMenu\" />\n </div>\n </header>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEE,OAAA,UAAA,GAAA,mBAgCS,UAAA;IA/BP,wBAAqB;IACpB,cAAY,QAAA;IACb,OAAM;;IAEKA,KAAAA,OAAO,SAAlB,UAAA,GAAA,mBAGM,OAHN,YAGM,CADJ,WAAqB,KAAA,QAAA,OAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;IAOfA,KAAAA,OAAO,UADf,UAAA,GAAA,mBAMM,OANN,YAMM,CADJ,WAAsB,KAAA,QAAA,QAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;IAIhBA,KAAAA,OAAO,WAAWA,KAAAA,OAAO,iBAAiBA,KAAAA,OAAO,YADzD,UAAA,GAAA,mBAUM,OAVN,YAUM;KALJ,WAAuB,KAAA,QAAA,SAAA;KAEvB,WAA6B,KAAA,QAAA,eAAA;KAE7B,WAAwB,KAAA,QAAA,UAAA"}
@@ -1,4 +1,4 @@
1
- import { type WindowControlsLabels } from "@ecoma-io/loom-window-controls";
1
+ import { type WindowControlsLabels } from "../../../primitives/window-controls/src/index";
2
2
  /**
3
3
  * DesktopAppShell — the ready-made layout a desktop (Electron/Tauri) app
4
4
  * reaches for. It composes TitleBar, a sidebar, and a content area into a
@@ -20,8 +20,8 @@ import { type WindowControlsLabels } from "@ecoma-io/loom-window-controls";
20
20
  * Every TitleBar event is re-emitted so the host wires its own window bridge;
21
21
  * the shell itself owns no IPC.
22
22
  */
23
- import type { MenubarMenu } from "@ecoma-io/loom-menubar";
24
- import type { WindowPlatform } from "@ecoma-io/loom-window-controls";
23
+ import type { MenubarMenu } from "../../../primitives/menubar/src/index";
24
+ import type { WindowPlatform } from "../../../primitives/window-controls/src/index";
25
25
  declare const _default: typeof __VLS_export;
26
26
  export default _default;
27
27
  declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
@@ -1 +1 @@
1
- {"version":3,"file":"MetricCard.js","names":[],"sources":["../../../../../packages/blocks/metric-card/src/MetricCard.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * MetricCard — one KPI on a dashboard: a compact surface carrying a metric\n * value, its label, and an optional trend arrow. The shape is fixed (icon →\n * label → value + trend) because a hand-rolled metric row drifts from call\n * site to call site — the icon above the label here, the trend on a second\n * line there — and this block pins one layout so the row scans left-to-right.\n *\n * The trend is always inline with the value, never a separate line. A trend\n * on its own row reads as a second metric; sharing the value line reads as\n * context for that metric, which is what it is. The arrows are inline SVGs\n * (12px) rather than an icon-library dependency: a trend indicator is a\n * single directional glyph, and pulling in an icon package for three paths\n * is weight the host did not ask for.\n *\n * Colour encodes direction but is never the only signal: the arrow shape\n * distinguishes up from down even without hue, and \"flat\" is an em dash\n * rather than a horizontal arrow that could be mistaken for a minus sign or\n * a separator. `text-success-text` / `text-destructive-text` / `text-muted-foreground`\n * are the semantic tokens rather than fixed greens and reds, so the card\n * adapts to whatever the theme maps those to.\n */\nexport type MetricCardTrend = \"up\" | \"down\" | \"flat\";\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"@ecoma-io/loom-core\";\n\ndefineProps<{\n /** The metric value — a formatted string or number the host has already\n * localised (e.g. \"1,234\", \"98.5%\", \"$42k\"). Raw numbers are not\n * formatted by the card; the host owns formatting so the same value\n * can be \"$42k\" in one place and \"42,000\" in another. */\n value: string | number;\n /** What the metric measures — always shown. */\n label: string;\n /** Direction of change. When absent, no trend indicator is rendered. */\n trend?: MetricCardTrend;\n /** The trend magnitude (e.g. \"+12.5%\", \"-3.2%\"). Shown only when `trend`\n * is also provided; a magnitude with no direction has no meaning. */\n trendValue?: string;\n}>();\n</script>\n\n<template>\n <div :class=\"cn('rounded-lg border border-border bg-card p-4')\">\n <!-- Decorative icon — hidden from assistive tech because the label and\n value already carry the metric's meaning. -->\n <div\n v-if=\"$slots.icon\"\n aria-hidden=\"true\"\n class=\"mb-2 text-muted-foreground [&_svg]:h-4 [&_svg]:w-4\"\n >\n <slot name=\"icon\" />\n </div>\n <p class=\"text-small text-muted-foreground\">{{ label }}</p>\n <div class=\"flex items-baseline gap-1.5\">\n <span class=\"text-2xl font-semibold tracking-tight text-foreground\">\n {{ value }}\n </span>\n <span\n v-if=\"trend\"\n :class=\"\n cn('inline-flex items-center gap-0.5 text-small font-medium', {\n 'text-success-text': trend === 'up',\n 'text-destructive-text': trend === 'down',\n 'text-muted-foreground': trend === 'flat',\n })\n \"\n >\n <!-- Up arrow: a single upward stroke with a chevron head. -->\n <svg\n v-if=\"trend === 'up'\"\n class=\"inline h-3 w-3\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n aria-hidden=\"true\"\n >\n <path d=\"M6 2v8M3 5l3-3 3 3\" />\n </svg>\n <!-- Down arrow: a single downward stroke with a chevron head. -->\n <svg\n v-else-if=\"trend === 'down'\"\n class=\"inline h-3 w-3\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n aria-hidden=\"true\"\n >\n <path d=\"M6 10V2M3 7l3 3 3-3\" />\n </svg>\n <!-- Flat: an em dash rather than a horizontal arrow — a horizontal\n arrow at this size reads as a minus sign or a separator. -->\n <span v-else aria-hidden=\"true\">&mdash;</span>\n <span v-if=\"trendValue\">{{ trendValue }}</span>\n </span>\n </div>\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"MetricCard.js","names":[],"sources":["../../../../../packages/blocks/metric-card/src/MetricCard.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * MetricCard — one KPI on a dashboard: a compact surface carrying a metric\n * value, its label, and an optional trend arrow. The shape is fixed (icon →\n * label → value + trend) because a hand-rolled metric row drifts from call\n * site to call site — the icon above the label here, the trend on a second\n * line there — and this block pins one layout so the row scans left-to-right.\n *\n * The trend is always inline with the value, never a separate line. A trend\n * on its own row reads as a second metric; sharing the value line reads as\n * context for that metric, which is what it is. The arrows are inline SVGs\n * (12px) rather than an icon-library dependency: a trend indicator is a\n * single directional glyph, and pulling in an icon package for three paths\n * is weight the host did not ask for.\n *\n * Colour encodes direction but is never the only signal: the arrow shape\n * distinguishes up from down even without hue, and \"flat\" is an em dash\n * rather than a horizontal arrow that could be mistaken for a minus sign or\n * a separator. `text-success-text` / `text-destructive-text` / `text-muted-foreground`\n * are the semantic tokens rather than fixed greens and reds, so the card\n * adapts to whatever the theme maps those to.\n */\nexport type MetricCardTrend = \"up\" | \"down\" | \"flat\";\n</script>\n\n<script setup lang=\"ts\">\nimport { watchEffect } from \"vue\";\nimport Skeleton from \"@ecoma-io/loom-skeleton\";\nimport { cn } from \"@ecoma-io/loom-core\";\n\nconst props = defineProps<{\n /** The metric value — a formatted string or number the host has already\n * localised (e.g. \"1,234\", \"98.5%\", \"$42k\"). Raw numbers are not\n * formatted by the card; the host owns formatting so the same value\n * can be \"$42k\" in one place and \"42,000\" in another. Optional only\n * while `loading`. */\n value?: string | number;\n /** What the metric measures — always shown. */\n label: string;\n /** Direction of change. When absent, no trend indicator is rendered. */\n trend?: MetricCardTrend;\n /** The trend magnitude (e.g. \"+12.5%\", \"-3.2%\"). Shown only when `trend`\n * is also provided; a magnitude with no direction has no meaning. */\n trendValue?: string;\n /** Context line under the value row — a period, a comparison base. */\n description?: string;\n /**\n * Renders the label and value as Skeleton placeholders sized to the real\n * layout, so the card keeps its height and does not reflow when data\n * lands.\n */\n loading?: boolean;\n}>();\n\n// `value` went optional for the loading state; this keeps a forgotten value\n// from landing as an empty heading once data arrives.\nwatchEffect(() => {\n if (!props.loading && props.value === undefined) {\n console.warn(\n \"[MetricCard] no `value` given and `loading` is false — the card renders an empty metric.\",\n );\n }\n});\n</script>\n\n<template>\n <div :aria-busy=\"loading || undefined\" :class=\"cn('rounded-lg border border-border bg-card p-4')\">\n <!-- Decorative icon — hidden from assistive tech because the label and\n value already carry the metric's meaning. -->\n <div\n v-if=\"$slots.icon\"\n aria-hidden=\"true\"\n class=\"mb-2 text-muted-foreground [&_svg]:h-4 [&_svg]:w-4\"\n >\n <slot name=\"icon\" />\n </div>\n <!-- Loading keeps the card's height by sizing each placeholder to the\n row it stands in for — a single generic bar would let the value\n land with a jolt. aria-hidden pairs with the parent's own\n aria-busy below. -->\n <template v-if=\"loading\">\n <Skeleton variant=\"text\" class=\"mb-2 h-3 w-20\" />\n <div class=\"flex items-baseline gap-1.5\">\n <Skeleton variant=\"text\" class=\"h-7 w-24\" />\n </div>\n </template>\n <template v-else>\n <p class=\"text-small text-muted-foreground\">{{ label }}</p>\n <div class=\"flex items-baseline gap-1.5\">\n <!-- `text-heading`, not a hand-assembled `text-2xl font-semibold\n tracking-tight`: the named rung is near-parity with that stack\n (1.5rem, weight 600) by design, and composing it here meant the KPI\n drifted silently if the scale ever moved. The two real deltas are\n deliberate — letter-spacing slackens from tight's −0.025em to the\n heading rung's −0.01em, and the line-height comes down to 1.2 —\n both invisible on a single baseline row like this one. -->\n <span class=\"text-heading text-foreground\">\n {{ value }}\n </span>\n <span\n v-if=\"trend\"\n :class=\"\n cn('inline-flex items-center gap-0.5 text-small font-medium', {\n 'text-success-text': trend === 'up',\n 'text-destructive-text': trend === 'down',\n 'text-muted-foreground': trend === 'flat',\n })\n \"\n >\n <!-- Up arrow: a single upward stroke with a chevron head. -->\n <svg\n v-if=\"trend === 'up'\"\n class=\"inline h-3 w-3\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n aria-hidden=\"true\"\n >\n <path d=\"M6 2v8M3 5l3-3 3 3\" />\n </svg>\n <!-- Down arrow: a single downward stroke with a chevron head. -->\n <svg\n v-else-if=\"trend === 'down'\"\n class=\"inline h-3 w-3\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n aria-hidden=\"true\"\n >\n <path d=\"M6 10V2M3 7l3 3 3-3\" />\n </svg>\n <!-- Flat: an em dash rather than a horizontal arrow — a horizontal\n arrow at this size reads as a minus sign or a separator. -->\n <span v-else aria-hidden=\"true\">&mdash;</span>\n <span v-if=\"trendValue\">{{ trendValue }}</span>\n </span>\n </div>\n <p v-if=\"description\" class=\"mt-1 text-small text-muted-foreground\">\n {{ description }}\n </p>\n </template>\n </div>\n</template>\n"],"mappings":""}
@@ -26,8 +26,9 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
26
26
  /** The metric value — a formatted string or number the host has already
27
27
  * localised (e.g. "1,234", "98.5%", "$42k"). Raw numbers are not
28
28
  * formatted by the card; the host owns formatting so the same value
29
- * can be "$42k" in one place and "42,000" in another. */
30
- value: string | number;
29
+ * can be "$42k" in one place and "42,000" in another. Optional only
30
+ * while `loading`. */
31
+ value?: string | number;
31
32
  /** What the metric measures — always shown. */
32
33
  label: string;
33
34
  /** Direction of change. When absent, no trend indicator is rendered. */
@@ -35,12 +36,21 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
35
36
  /** The trend magnitude (e.g. "+12.5%", "-3.2%"). Shown only when `trend`
36
37
  * is also provided; a magnitude with no direction has no meaning. */
37
38
  trendValue?: string;
39
+ /** Context line under the value row — a period, a comparison base. */
40
+ description?: string;
41
+ /**
42
+ * Renders the label and value as Skeleton placeholders sized to the real
43
+ * layout, so the card keeps its height and does not reflow when data
44
+ * lands.
45
+ */
46
+ loading?: boolean;
38
47
  }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{
39
48
  /** The metric value — a formatted string or number the host has already
40
49
  * localised (e.g. "1,234", "98.5%", "$42k"). Raw numbers are not
41
50
  * formatted by the card; the host owns formatting so the same value
42
- * can be "$42k" in one place and "42,000" in another. */
43
- value: string | number;
51
+ * can be "$42k" in one place and "42,000" in another. Optional only
52
+ * while `loading`. */
53
+ value?: string | number;
44
54
  /** What the metric measures — always shown. */
45
55
  label: string;
46
56
  /** Direction of change. When absent, no trend indicator is rendered. */
@@ -48,6 +58,14 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
48
58
  /** The trend magnitude (e.g. "+12.5%", "-3.2%"). Shown only when `trend`
49
59
  * is also provided; a magnitude with no direction has no meaning. */
50
60
  trendValue?: string;
61
+ /** Context line under the value row — a period, a comparison base. */
62
+ description?: string;
63
+ /**
64
+ * Renders the label and value as Skeleton placeholders sized to the real
65
+ * layout, so the card keeps its height and does not reflow when data
66
+ * lands.
67
+ */
68
+ loading?: boolean;
51
69
  }> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
52
70
  icon?: (props: {}) => any;
53
71
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"MetricCard.vue.d.ts","sourceRoot":"","sources":["../../../../../packages/blocks/metric-card/src/MetricCard.vue"],"names":[],"mappings":"AA4GA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;wBAChC,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAEhB;;;8DAG0D;WACnD,MAAM,GAAG,MAAM;IACtB,+CAA+C;WACxC,MAAM;IACb,wEAAwE;YAChE,eAAe;IACvB;0EACsE;iBACzD,MAAM;;IAXnB;;;8DAG0D;WACnD,MAAM,GAAG,MAAM;IACtB,+CAA+C;WACxC,MAAM;IACb,wEAAwE;YAChE,eAAe;IACvB;0EACsE;iBACzD,MAAM;;WAgHV,CAAC,KAAK,IAAgB,KAAK,GAAG;EASrC,CAAC;AACL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"MetricCard.vue.d.ts","sourceRoot":"","sources":["../../../../../packages/blocks/metric-card/src/MetricCard.vue"],"names":[],"mappings":"AAyJA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;wBAChC,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAEhB;;;;2BAIuB;YACf,MAAM,GAAG,MAAM;IACvB,+CAA+C;WACxC,MAAM;IACb,wEAAwE;YAChE,eAAe;IACvB;0EACsE;iBACzD,MAAM;IACnB,sEAAsE;kBACxD,MAAM;IACpB;;;;OAIG;cACO,OAAO;;IApBjB;;;;2BAIuB;YACf,MAAM,GAAG,MAAM;IACvB,+CAA+C;WACxC,MAAM;IACb,wEAAwE;YAChE,eAAe;IACvB;0EACsE;iBACzD,MAAM;IACnB,sEAAsE;kBACxD,MAAM;IACpB;;;;OAIG;cACO,OAAO;;WA0KR,CAAC,KAAK,IAAgB,KAAK,GAAG;EASrC,CAAC;AACL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -1,16 +1,20 @@
1
1
  import { cn } from "../../../core/src/cn.js";
2
2
  import "../../../core/src/index.js";
3
- import { createCommentVNode, createElementBlock, createElementVNode, defineComponent, normalizeClass, openBlock, renderSlot, toDisplayString, unref } from "vue";
3
+ import Skeleton_default from "../../../primitives/skeleton/src/Skeleton.js";
4
+ import "../../../primitives/skeleton/src/index.js";
5
+ import { Fragment, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, normalizeClass, openBlock, renderSlot, toDisplayString, unref, watchEffect } from "vue";
4
6
  //#region packages/blocks/metric-card/src/MetricCard.vue?vue&type=script&setup=true&lang.ts
5
- var _hoisted_1 = {
7
+ var _hoisted_1 = ["aria-busy"];
8
+ var _hoisted_2 = {
6
9
  key: 0,
7
10
  "aria-hidden": "true",
8
11
  class: "mb-2 text-muted-foreground [&_svg]:h-4 [&_svg]:w-4"
9
12
  };
10
- var _hoisted_2 = { class: "text-small text-muted-foreground" };
11
13
  var _hoisted_3 = { class: "flex items-baseline gap-1.5" };
12
- var _hoisted_4 = { class: "text-2xl font-semibold tracking-tight text-foreground" };
13
- var _hoisted_5 = {
14
+ var _hoisted_4 = { class: "text-small text-muted-foreground" };
15
+ var _hoisted_5 = { class: "flex items-baseline gap-1.5" };
16
+ var _hoisted_6 = { class: "text-heading text-foreground" };
17
+ var _hoisted_7 = {
14
18
  key: 0,
15
19
  class: "inline h-3 w-3",
16
20
  viewBox: "0 0 12 12",
@@ -19,7 +23,7 @@ var _hoisted_5 = {
19
23
  "stroke-width": "2",
20
24
  "aria-hidden": "true"
21
25
  };
22
- var _hoisted_6 = {
26
+ var _hoisted_8 = {
23
27
  key: 1,
24
28
  class: "inline h-3 w-3",
25
29
  viewBox: "0 0 12 12",
@@ -28,33 +32,52 @@ var _hoisted_6 = {
28
32
  "stroke-width": "2",
29
33
  "aria-hidden": "true"
30
34
  };
31
- var _hoisted_7 = {
35
+ var _hoisted_9 = {
32
36
  key: 2,
33
37
  "aria-hidden": "true"
34
38
  };
35
- var _hoisted_8 = { key: 3 };
39
+ var _hoisted_10 = { key: 3 };
40
+ var _hoisted_11 = {
41
+ key: 0,
42
+ class: "mt-1 text-small text-muted-foreground"
43
+ };
36
44
  var MetricCard_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
37
45
  __name: "MetricCard",
38
46
  props: {
39
47
  value: {},
40
48
  label: {},
41
49
  trend: {},
42
- trendValue: {}
50
+ trendValue: {},
51
+ description: {},
52
+ loading: { type: Boolean }
43
53
  },
44
54
  setup(__props) {
55
+ const props = __props;
56
+ watchEffect(() => {
57
+ if (!props.loading && props.value === void 0) console.warn("[MetricCard] no `value` given and `loading` is false — the card renders an empty metric.");
58
+ });
45
59
  return (_ctx, _cache) => {
46
- return openBlock(), createElementBlock("div", { class: normalizeClass(unref(cn)("rounded-lg border border-border bg-card p-4")) }, [
47
- _ctx.$slots.icon ? (openBlock(), createElementBlock("div", _hoisted_1, [renderSlot(_ctx.$slots, "icon")])) : createCommentVNode("", true),
48
- createElementVNode("p", _hoisted_2, toDisplayString(__props.label), 1),
49
- createElementVNode("div", _hoisted_3, [createElementVNode("span", _hoisted_4, toDisplayString(__props.value), 1), __props.trend ? (openBlock(), createElementBlock("span", {
60
+ return openBlock(), createElementBlock("div", {
61
+ "aria-busy": __props.loading || void 0,
62
+ class: normalizeClass(unref(cn)("rounded-lg border border-border bg-card p-4"))
63
+ }, [_ctx.$slots.icon ? (openBlock(), createElementBlock("div", _hoisted_2, [renderSlot(_ctx.$slots, "icon")])) : createCommentVNode("", true), __props.loading ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [createVNode(unref(Skeleton_default), {
64
+ variant: "text",
65
+ class: "mb-2 h-3 w-20"
66
+ }), createElementVNode("div", _hoisted_3, [createVNode(unref(Skeleton_default), {
67
+ variant: "text",
68
+ class: "h-7 w-24"
69
+ })])], 64)) : (openBlock(), createElementBlock(Fragment, { key: 2 }, [
70
+ createElementVNode("p", _hoisted_4, toDisplayString(__props.label), 1),
71
+ createElementVNode("div", _hoisted_5, [createElementVNode("span", _hoisted_6, toDisplayString(__props.value), 1), __props.trend ? (openBlock(), createElementBlock("span", {
50
72
  key: 0,
51
73
  class: normalizeClass(unref(cn)("inline-flex items-center gap-0.5 text-small font-medium", {
52
74
  "text-success-text": __props.trend === "up",
53
75
  "text-destructive-text": __props.trend === "down",
54
76
  "text-muted-foreground": __props.trend === "flat"
55
77
  }))
56
- }, [__props.trend === "up" ? (openBlock(), createElementBlock("svg", _hoisted_5, [..._cache[0] || (_cache[0] = [createElementVNode("path", { d: "M6 2v8M3 5l3-3 3 3" }, null, -1)])])) : __props.trend === "down" ? (openBlock(), createElementBlock("svg", _hoisted_6, [..._cache[1] || (_cache[1] = [createElementVNode("path", { d: "M6 10V2M3 7l3 3 3-3" }, null, -1)])])) : (openBlock(), createElementBlock("span", _hoisted_7, "—")), __props.trendValue ? (openBlock(), createElementBlock("span", _hoisted_8, toDisplayString(__props.trendValue), 1)) : createCommentVNode("", true)], 2)) : createCommentVNode("", true)])
57
- ], 2);
78
+ }, [__props.trend === "up" ? (openBlock(), createElementBlock("svg", _hoisted_7, [..._cache[0] || (_cache[0] = [createElementVNode("path", { d: "M6 2v8M3 5l3-3 3 3" }, null, -1)])])) : __props.trend === "down" ? (openBlock(), createElementBlock("svg", _hoisted_8, [..._cache[1] || (_cache[1] = [createElementVNode("path", { d: "M6 10V2M3 7l3 3 3-3" }, null, -1)])])) : (openBlock(), createElementBlock("span", _hoisted_9, "—")), __props.trendValue ? (openBlock(), createElementBlock("span", _hoisted_10, toDisplayString(__props.trendValue), 1)) : createCommentVNode("", true)], 2)) : createCommentVNode("", true)]),
79
+ __props.description ? (openBlock(), createElementBlock("p", _hoisted_11, toDisplayString(__props.description), 1)) : createCommentVNode("", true)
80
+ ], 64))], 10, _hoisted_1);
58
81
  };
59
82
  }
60
83
  });
@@ -1 +1 @@
1
- {"version":3,"file":"MetricCard.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../../../packages/blocks/metric-card/src/MetricCard.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * MetricCard — one KPI on a dashboard: a compact surface carrying a metric\n * value, its label, and an optional trend arrow. The shape is fixed (icon →\n * label → value + trend) because a hand-rolled metric row drifts from call\n * site to call site — the icon above the label here, the trend on a second\n * line there — and this block pins one layout so the row scans left-to-right.\n *\n * The trend is always inline with the value, never a separate line. A trend\n * on its own row reads as a second metric; sharing the value line reads as\n * context for that metric, which is what it is. The arrows are inline SVGs\n * (12px) rather than an icon-library dependency: a trend indicator is a\n * single directional glyph, and pulling in an icon package for three paths\n * is weight the host did not ask for.\n *\n * Colour encodes direction but is never the only signal: the arrow shape\n * distinguishes up from down even without hue, and \"flat\" is an em dash\n * rather than a horizontal arrow that could be mistaken for a minus sign or\n * a separator. `text-success-text` / `text-destructive-text` / `text-muted-foreground`\n * are the semantic tokens rather than fixed greens and reds, so the card\n * adapts to whatever the theme maps those to.\n */\nexport type MetricCardTrend = \"up\" | \"down\" | \"flat\";\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"@ecoma-io/loom-core\";\n\ndefineProps<{\n /** The metric value — a formatted string or number the host has already\n * localised (e.g. \"1,234\", \"98.5%\", \"$42k\"). Raw numbers are not\n * formatted by the card; the host owns formatting so the same value\n * can be \"$42k\" in one place and \"42,000\" in another. */\n value: string | number;\n /** What the metric measures — always shown. */\n label: string;\n /** Direction of change. When absent, no trend indicator is rendered. */\n trend?: MetricCardTrend;\n /** The trend magnitude (e.g. \"+12.5%\", \"-3.2%\"). Shown only when `trend`\n * is also provided; a magnitude with no direction has no meaning. */\n trendValue?: string;\n}>();\n</script>\n\n<template>\n <div :class=\"cn('rounded-lg border border-border bg-card p-4')\">\n <!-- Decorative icon — hidden from assistive tech because the label and\n value already carry the metric's meaning. -->\n <div\n v-if=\"$slots.icon\"\n aria-hidden=\"true\"\n class=\"mb-2 text-muted-foreground [&_svg]:h-4 [&_svg]:w-4\"\n >\n <slot name=\"icon\" />\n </div>\n <p class=\"text-small text-muted-foreground\">{{ label }}</p>\n <div class=\"flex items-baseline gap-1.5\">\n <span class=\"text-2xl font-semibold tracking-tight text-foreground\">\n {{ value }}\n </span>\n <span\n v-if=\"trend\"\n :class=\"\n cn('inline-flex items-center gap-0.5 text-small font-medium', {\n 'text-success-text': trend === 'up',\n 'text-destructive-text': trend === 'down',\n 'text-muted-foreground': trend === 'flat',\n })\n \"\n >\n <!-- Up arrow: a single upward stroke with a chevron head. -->\n <svg\n v-if=\"trend === 'up'\"\n class=\"inline h-3 w-3\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n aria-hidden=\"true\"\n >\n <path d=\"M6 2v8M3 5l3-3 3 3\" />\n </svg>\n <!-- Down arrow: a single downward stroke with a chevron head. -->\n <svg\n v-else-if=\"trend === 'down'\"\n class=\"inline h-3 w-3\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n aria-hidden=\"true\"\n >\n <path d=\"M6 10V2M3 7l3 3 3-3\" />\n </svg>\n <!-- Flat: an em dash rather than a horizontal arrow — a horizontal\n arrow at this size reads as a minus sign or a separator. -->\n <span v-else aria-hidden=\"true\">&mdash;</span>\n <span v-if=\"trendValue\">{{ trendValue }}</span>\n </span>\n </div>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CE,OAAA,UAAA,GAAA,mBAuDM,OAAA,EAvDA,OAAK,eAAE,MAAA,EAAA,CAAE,CAAA,6CAAA,CAAA,EAAA,GAAA;IAILA,KAAAA,OAAO,QADf,UAAA,GAAA,mBAMM,OANN,YAMM,CADJ,WAAoB,KAAA,QAAA,MAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;IAEtB,mBAA2D,KAA3D,YAA2D,gBAAZ,QAAA,KAAK,GAAA,CAAA;IACpD,mBA2CM,OA3CN,YA2CM,CA1CJ,mBAEO,QAFP,YAEO,gBADF,QAAA,KAAK,GAAA,CAAA,GAGF,QAAA,SADR,UAAA,GAAA,mBAsCO,QAAA;;KApCJ,OAAK,eAAa,MAAA,EAAA,CAAE,CAAA,2DAAA;MAA+F,qBAAA,QAAA,UAAK;MAAgD,yBAAA,QAAA,UAAK;MAAkD,yBAAA,QAAA,UAAK;;IAU7N,GAAA,CAAA,QAAA,UAAK,QADb,UAAA,GAAA,mBAUM,OAVN,YAUM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CADJ,mBAA+B,QAAA,EAAzB,GAAE,qBAAoB,GAAA,MAAA,EAAA,CAAA,EAAA,CAAA,KAIjB,QAAA,UAAK,UADlB,UAAA,GAAA,mBAUM,OAVN,YAUM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CADJ,mBAAgC,QAAA,EAA1B,GAAE,sBAAqB,GAAA,MAAA,EAAA,CAAA,EAAA,CAAA,MAI/B,UAAA,GAAA,mBAA8C,QAA9C,YAAgC,GAAO,IAC3B,QAAA,cAAZ,UAAA,GAAA,mBAA+C,QAAA,YAAA,gBAApB,QAAA,UAAU,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,CAAA"}
1
+ {"version":3,"file":"MetricCard.vue_vue_type_script_setup_true_lang.js","names":["$slots"],"sources":["../../../../../packages/blocks/metric-card/src/MetricCard.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * MetricCard — one KPI on a dashboard: a compact surface carrying a metric\n * value, its label, and an optional trend arrow. The shape is fixed (icon →\n * label → value + trend) because a hand-rolled metric row drifts from call\n * site to call site — the icon above the label here, the trend on a second\n * line there — and this block pins one layout so the row scans left-to-right.\n *\n * The trend is always inline with the value, never a separate line. A trend\n * on its own row reads as a second metric; sharing the value line reads as\n * context for that metric, which is what it is. The arrows are inline SVGs\n * (12px) rather than an icon-library dependency: a trend indicator is a\n * single directional glyph, and pulling in an icon package for three paths\n * is weight the host did not ask for.\n *\n * Colour encodes direction but is never the only signal: the arrow shape\n * distinguishes up from down even without hue, and \"flat\" is an em dash\n * rather than a horizontal arrow that could be mistaken for a minus sign or\n * a separator. `text-success-text` / `text-destructive-text` / `text-muted-foreground`\n * are the semantic tokens rather than fixed greens and reds, so the card\n * adapts to whatever the theme maps those to.\n */\nexport type MetricCardTrend = \"up\" | \"down\" | \"flat\";\n</script>\n\n<script setup lang=\"ts\">\nimport { watchEffect } from \"vue\";\nimport Skeleton from \"@ecoma-io/loom-skeleton\";\nimport { cn } from \"@ecoma-io/loom-core\";\n\nconst props = defineProps<{\n /** The metric value — a formatted string or number the host has already\n * localised (e.g. \"1,234\", \"98.5%\", \"$42k\"). Raw numbers are not\n * formatted by the card; the host owns formatting so the same value\n * can be \"$42k\" in one place and \"42,000\" in another. Optional only\n * while `loading`. */\n value?: string | number;\n /** What the metric measures — always shown. */\n label: string;\n /** Direction of change. When absent, no trend indicator is rendered. */\n trend?: MetricCardTrend;\n /** The trend magnitude (e.g. \"+12.5%\", \"-3.2%\"). Shown only when `trend`\n * is also provided; a magnitude with no direction has no meaning. */\n trendValue?: string;\n /** Context line under the value row — a period, a comparison base. */\n description?: string;\n /**\n * Renders the label and value as Skeleton placeholders sized to the real\n * layout, so the card keeps its height and does not reflow when data\n * lands.\n */\n loading?: boolean;\n}>();\n\n// `value` went optional for the loading state; this keeps a forgotten value\n// from landing as an empty heading once data arrives.\nwatchEffect(() => {\n if (!props.loading && props.value === undefined) {\n console.warn(\n \"[MetricCard] no `value` given and `loading` is false — the card renders an empty metric.\",\n );\n }\n});\n</script>\n\n<template>\n <div :aria-busy=\"loading || undefined\" :class=\"cn('rounded-lg border border-border bg-card p-4')\">\n <!-- Decorative icon — hidden from assistive tech because the label and\n value already carry the metric's meaning. -->\n <div\n v-if=\"$slots.icon\"\n aria-hidden=\"true\"\n class=\"mb-2 text-muted-foreground [&_svg]:h-4 [&_svg]:w-4\"\n >\n <slot name=\"icon\" />\n </div>\n <!-- Loading keeps the card's height by sizing each placeholder to the\n row it stands in for — a single generic bar would let the value\n land with a jolt. aria-hidden pairs with the parent's own\n aria-busy below. -->\n <template v-if=\"loading\">\n <Skeleton variant=\"text\" class=\"mb-2 h-3 w-20\" />\n <div class=\"flex items-baseline gap-1.5\">\n <Skeleton variant=\"text\" class=\"h-7 w-24\" />\n </div>\n </template>\n <template v-else>\n <p class=\"text-small text-muted-foreground\">{{ label }}</p>\n <div class=\"flex items-baseline gap-1.5\">\n <!-- `text-heading`, not a hand-assembled `text-2xl font-semibold\n tracking-tight`: the named rung is near-parity with that stack\n (1.5rem, weight 600) by design, and composing it here meant the KPI\n drifted silently if the scale ever moved. The two real deltas are\n deliberate — letter-spacing slackens from tight's −0.025em to the\n heading rung's −0.01em, and the line-height comes down to 1.2 —\n both invisible on a single baseline row like this one. -->\n <span class=\"text-heading text-foreground\">\n {{ value }}\n </span>\n <span\n v-if=\"trend\"\n :class=\"\n cn('inline-flex items-center gap-0.5 text-small font-medium', {\n 'text-success-text': trend === 'up',\n 'text-destructive-text': trend === 'down',\n 'text-muted-foreground': trend === 'flat',\n })\n \"\n >\n <!-- Up arrow: a single upward stroke with a chevron head. -->\n <svg\n v-if=\"trend === 'up'\"\n class=\"inline h-3 w-3\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n aria-hidden=\"true\"\n >\n <path d=\"M6 2v8M3 5l3-3 3 3\" />\n </svg>\n <!-- Down arrow: a single downward stroke with a chevron head. -->\n <svg\n v-else-if=\"trend === 'down'\"\n class=\"inline h-3 w-3\"\n viewBox=\"0 0 12 12\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n aria-hidden=\"true\"\n >\n <path d=\"M6 10V2M3 7l3 3 3-3\" />\n </svg>\n <!-- Flat: an em dash rather than a horizontal arrow — a horizontal\n arrow at this size reads as a minus sign or a separator. -->\n <span v-else aria-hidden=\"true\">&mdash;</span>\n <span v-if=\"trendValue\">{{ trendValue }}</span>\n </span>\n </div>\n <p v-if=\"description\" class=\"mt-1 text-small text-muted-foreground\">\n {{ description }}\n </p>\n </template>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BA,MAAM,QAAQ;EA0Bd,kBAAkB;GAChB,IAAI,CAAC,MAAM,WAAW,MAAM,UAAU,KAAA,GACpC,QAAQ,KACN,0FACF;EAEJ,CAAC;;GAIC,OAAA,UAAA,GAAA,mBA6EM,OAAA;IA7EA,aAAW,QAAA,WAAW,KAAA;IAAY,OAAK,eAAE,MAAA,EAAA,CAAE,CAAA,6CAAA,CAAA;GAIvCA,GAAAA,CAAAA,KAAAA,OAAO,QADf,UAAA,GAAA,mBAMM,OANN,YAMM,CADJ,WAAoB,KAAA,QAAA,MAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,GAMN,QAAA,WAAhB,UAAA,GAAA,mBAKW,UAAA,EAAA,KAAA,EAAA,GAAA,CAJT,YAAiD,MAAA,gBAAA,GAAA;IAAvC,SAAQ;IAAO,OAAM;GAC/B,CAAA,GAAA,mBAEM,OAFN,YAEM,CADJ,YAA4C,MAAA,gBAAA,GAAA;IAAlC,SAAQ;IAAO,OAAM;GAGnC,CAAA,CAAA,CAAA,CAAA,GAAA,EAAA,MAAA,UAAA,GAAA,mBAwDW,UAAA,EAAA,KAAA,EAAA,GAAA;IAvDT,mBAA2D,KAA3D,YAA2D,gBAAZ,QAAA,KAAK,GAAA,CAAA;IACpD,mBAkDM,OAlDN,YAkDM,CA1CJ,mBAEO,QAFP,YAEO,gBADF,QAAA,KAAK,GAAA,CAAA,GAGF,QAAA,SADR,UAAA,GAAA,mBAsCO,QAAA;;KApCJ,OAAK,eAAe,MAAA,EAAA,CAAE,CAAA,2DAAA;MAAiG,qBAAA,QAAA,UAAK;MAAkD,yBAAA,QAAA,UAAK;MAAoD,yBAAA,QAAA,UAAK;;IAUrO,GAAA,CAAA,QAAA,UAAK,QADb,UAAA,GAAA,mBAUM,OAVN,YAUM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CADJ,mBAA+B,QAAA,EAAzB,GAAE,qBAAoB,GAAA,MAAA,EAAA,CAAA,EAAA,CAAA,KAIjB,QAAA,UAAK,UADlB,UAAA,GAAA,mBAUM,OAVN,YAUM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CADJ,mBAAgC,QAAA,EAA1B,GAAE,sBAAqB,GAAA,MAAA,EAAA,CAAA,EAAA,CAAA,MAI/B,UAAA,GAAA,mBAA8C,QAA9C,YAAgC,GAAO,IAC3B,QAAA,cAAZ,UAAA,GAAA,mBAA+C,QAAA,aAAA,gBAApB,QAAA,UAAU,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,CAAA;IAGhC,QAAA,eAAT,UAAA,GAAA,mBAEI,KAFJ,aAEI,gBADC,QAAA,WAAW,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA"}
@@ -1,4 +1,4 @@
1
- import { type WindowControlsLabels } from "@ecoma-io/loom-window-controls";
1
+ import { type WindowControlsLabels } from "../../../primitives/window-controls/src/index";
2
2
  /**
3
3
  * TitleBar — a desktop app's custom window chrome (a block: composed from
4
4
  * primitives, domain-aware, but still presentational). Layout:
@@ -19,8 +19,8 @@ import { type WindowControlsLabels } from "@ecoma-io/loom-window-controls";
19
19
  * the brand cluster shifts right to leave room for the native traffic-light
20
20
  * buttons, and WindowControls renders nothing (the OS owns those buttons).
21
21
  */
22
- import type { MenubarMenu } from "@ecoma-io/loom-menubar";
23
- import type { WindowPlatform } from "@ecoma-io/loom-window-controls";
22
+ import type { MenubarMenu } from "../../../primitives/menubar/src/index";
23
+ import type { WindowPlatform } from "../../../primitives/window-controls/src/index";
24
24
  declare const _default: typeof __VLS_export;
25
25
  export default _default;
26
26
  declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
@@ -1,6 +1,6 @@
1
- import { type LabelOverrides } from "@ecoma-io/loom-labels";
2
- import { type ToastLabels } from "@ecoma-io/loom-toast";
3
- import type { ToastVariant } from "@ecoma-io/loom-toast";
1
+ import { type LabelOverrides } from "../../../labels/src/index";
2
+ import { type ToastLabels } from "../../../primitives/toast/src/index";
3
+ import type { ToastVariant } from "../../../primitives/toast/src/index";
4
4
  /** One entry of a host-owned toast queue, rendered by `ToastStack`. */
5
5
  export interface ToastStackItem {
6
6
  readonly id: string | number;
@@ -1,7 +1,7 @@
1
- import ScrollReel_vue_vue_type_script_setup_true_lang_default, { gapClass, snapClass } from "./ScrollReel.vue_vue_type_script_setup_true_lang.js";
1
+ import ScrollReel_vue_vue_type_script_setup_true_lang_default, { SCROLL_REEL_LABELS, gapClass, snapClass } from "./ScrollReel.vue_vue_type_script_setup_true_lang.js";
2
2
  //#region packages/composition/scroll-reel/src/ScrollReel.vue
3
3
  var ScrollReel_default = ScrollReel_vue_vue_type_script_setup_true_lang_default;
4
4
  //#endregion
5
- export { ScrollReel_default as default, gapClass, snapClass };
5
+ export { SCROLL_REEL_LABELS, ScrollReel_default as default, gapClass, snapClass };
6
6
 
7
7
  //# sourceMappingURL=ScrollReel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ScrollReel.js","names":[],"sources":["../../../../../packages/composition/scroll-reel/src/ScrollReel.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * ScrollReel — horizontal scrolling strip with scroll-snap.\n *\n * A touch-friendly, keyboard-navigable horizontal scroll container with\n * optional scroll-snap alignment. Arrow keys scroll to the next or previous\n * snap point; the `Home` and `End` keys jump to the start or end of the\n * strip.\n *\n * A ScrollReel is a component, not `overflow-x-auto snap-x snap-mandatory`,\n * because keyboard accessibility for scroll-snap requires JavaScript (arrow\n * keys must find the next snap-aligned child and scroll it into view), and\n * the gap tightens one step below `sm` like Stack and DashboardGrid.\n */\nexport type ScrollReelSnap = \"start\" | \"center\" | \"end\" | \"none\";\n\nexport type ScrollReelGap = \"sm\" | \"md\" | \"lg\";\n\nconst snapClass: Record<ScrollReelSnap, string> = {\n start: \"snap-x snap-mandatory snap-start\",\n center: \"snap-x snap-mandatory snap-center\",\n end: \"snap-x snap-mandatory snap-end\",\n // `none` means no snap alignment — items scroll freely.\n none: \"\",\n} as const;\n\nconst gapClass: Record<ScrollReelGap, string> = {\n sm: \"gap-2 sm:gap-3\",\n md: \"gap-3 sm:gap-4\",\n lg: \"gap-4 sm:gap-6\",\n} as const;\n\nexport { snapClass, gapClass };\n</script>\n\n<script setup lang=\"ts\">\nimport { ref } from \"vue\";\nimport { cn } from \"@ecoma-io/loom-core\";\n\nwithDefaults(\n defineProps<{\n /** Scroll-snap alignment. \"none\" disables snap entirely. */\n snap?: ScrollReelSnap;\n /** Gap between items — mirrors Stack's scale. Tightens one notch below `sm`. */\n gap?: ScrollReelGap;\n }>(),\n { snap: \"start\", gap: \"md\" },\n);\n\nconst reel = ref<HTMLDivElement | null>(null);\n\n/**\n * Keyboard navigation for scroll-snap: arrow keys scroll to the next or\n * previous snap-aligned child. Without this, the browser's default arrow-key\n * behaviour scrolls by a fixed pixel amount that rarely aligns with snap\n * points, leaving the strip between two items.\n */\nfunction onKeydown(event: KeyboardEvent) {\n const el = reel.value;\n if (!el) return;\n\n const direction = event.key === \"ArrowRight\" ? 1 : event.key === \"ArrowLeft\" ? -1 : 0;\n if (direction === 0 && event.key !== \"Home\" && event.key !== \"End\") return;\n\n event.preventDefault();\n\n if (event.key === \"Home\") {\n el.scrollTo({ left: 0, behavior: \"smooth\" });\n return;\n }\n if (event.key === \"End\") {\n el.scrollTo({ left: el.scrollWidth, behavior: \"smooth\" });\n return;\n }\n\n // Find the next snap-aligned child in the scroll direction.\n const children = [...el.children] as HTMLElement[];\n const scrollEdge = direction === 1 ? el.scrollLeft + el.clientWidth : el.scrollLeft;\n\n for (const child of direction === 1 ? children : children.reverse()) {\n const childEdge = direction === 1 ? child.offsetLeft : child.offsetLeft + child.offsetWidth;\n const isNext = direction === 1 ? childEdge > scrollEdge - 1 : childEdge < scrollEdge + 1;\n if (isNext) {\n child.scrollIntoView({ behavior: \"smooth\", block: \"nearest\", inline: \"start\" });\n break;\n }\n }\n}\n</script>\n\n<template>\n <!-- `role=\"region\"` + `tabindex=\"0\"` + `aria-label` make this a named,\n focusable landmark region. The keyboard handler is what makes the\n scroll-snap strip navigable by arrow keys — a genuine interaction on\n a genuinely interactive element. The rule does not account for\n non-interactive ARIA roles with an explicit tabindex. -->\n <!-- eslint-disable-next-line vuejs-accessibility/no-static-element-interactions -->\n <div\n ref=\"reel\"\n class=\"overflow-x-auto\"\n :class=\"cn('flex flex-row', snapClass[snap], gapClass[gap])\"\n tabindex=\"0\"\n role=\"region\"\n aria-label=\"Scrollable content\"\n @keydown=\"onKeydown\"\n >\n <slot />\n </div>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"ScrollReel.js","names":[],"sources":["../../../../../packages/composition/scroll-reel/src/ScrollReel.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * ScrollReel — horizontal scrolling strip with scroll-snap.\n *\n * A touch-friendly, keyboard-navigable horizontal scroll container with\n * optional scroll-snap alignment. Arrow keys scroll to the next or previous\n * snap point; the `Home` and `End` keys jump to the start or end of the\n * strip.\n *\n * A ScrollReel is a component, not `overflow-x-auto snap-x snap-mandatory`,\n * because keyboard accessibility for scroll-snap requires JavaScript (arrow\n * keys must find the next snap-aligned child and scroll it into view), and\n * the gap tightens one step below `sm` like Stack and DashboardGrid.\n */\nexport type ScrollReelSnap = \"start\" | \"center\" | \"end\" | \"none\";\n\nexport type ScrollReelGap = \"sm\" | \"md\" | \"lg\";\n\n/**\n * Loom's English, co-located with the component so it tree-shakes with it,\n * and exported so a host can build a partial vocabulary against the real\n * thing rather than a transcription of it. The type itself lives in the\n * labels registry (`ScrollReelLabels`) like every other slot's, so\n * `provideLoomLabels({ scrollReel: … })` reaches this component exactly as\n * it reaches every primitive — composition sits above labels in the layer\n * direction, and a host localising one reel should not have to learn a\n * second seam to do it.\n */\nexport const SCROLL_REEL_LABELS: ScrollReelLabels = {\n region: \"Scrollable content\",\n};\n\nconst snapClass: Record<ScrollReelSnap, string> = {\n start: \"snap-x snap-mandatory snap-start\",\n center: \"snap-x snap-mandatory snap-center\",\n end: \"snap-x snap-mandatory snap-end\",\n // `none` means no snap alignment — items scroll freely.\n none: \"\",\n} as const;\n\nconst gapClass: Record<ScrollReelGap, string> = {\n sm: \"gap-2 sm:gap-3\",\n md: \"gap-3 sm:gap-4\",\n lg: \"gap-4 sm:gap-6\",\n} as const;\n\nexport { snapClass, gapClass };\n</script>\n\n<script setup lang=\"ts\">\nimport { ref } from \"vue\";\nimport { cn, smoothScrollBehavior } from \"@ecoma-io/loom-core\";\nimport { useLabels, type LabelOverrides, type ScrollReelLabels } from \"@ecoma-io/loom-labels\";\n\nconst props = withDefaults(\n defineProps<{\n /** Scroll-snap alignment. \"none\" disables snap entirely. */\n snap?: ScrollReelSnap;\n /** Gap between items — mirrors Stack's scale. Tightens one notch below `sm`. */\n gap?: ScrollReelGap;\n /**\n * Names for what the reel says out loud, as any subset of\n * `ScrollReelLabels` — the per-instance correction over\n * `SCROLL_REEL_LABELS`, in the same shape a primitive's `labels` prop\n * takes.\n */\n labels?: LabelOverrides<ScrollReelLabels>;\n }>(),\n { snap: \"start\", gap: \"md\" },\n);\n\n// `text`, not `labels`: the prop of that name is one of the three sources this\n// resolves (own prop, then the host vocabulary from `provideLoomLabels`, then\n// these English defaults), and a template reading the raw prop would be\n// reading the overrides rather than the answer.\nconst text = useLabels(\"scrollReel\", SCROLL_REEL_LABELS, () => props.labels);\n\nconst reel = ref<HTMLDivElement | null>(null);\n\n// The reduced-motion softening lives in core (`smoothScrollBehavior`): an\n// explicit `\"smooth\"` in a scrollTo dictionary overrides the stylesheet's\n// kill-switch, so the question has to be answered at the call site — and\n// Carousel asks it too, which is why the answer is shared rather than owned.\nconst scrollBehavior = smoothScrollBehavior;\n\n/**\n * Keyboard navigation for scroll-snap: arrow keys scroll to the next or\n * previous snap-aligned child. Without this, the browser's default arrow-key\n * behaviour scrolls by a fixed pixel amount that rarely aligns with snap\n * points, leaving the strip between two items.\n */\nfunction onKeydown(event: KeyboardEvent) {\n const el = reel.value;\n if (!el) return;\n\n const direction = event.key === \"ArrowRight\" ? 1 : event.key === \"ArrowLeft\" ? -1 : 0;\n if (direction === 0 && event.key !== \"Home\" && event.key !== \"End\") return;\n\n event.preventDefault();\n\n const behavior = scrollBehavior();\n if (event.key === \"Home\") {\n el.scrollTo({ left: 0, behavior });\n return;\n }\n if (event.key === \"End\") {\n el.scrollTo({ left: el.scrollWidth, behavior });\n return;\n }\n\n // Find the next snap-aligned child in the scroll direction.\n const children = [...el.children] as HTMLElement[];\n const scrollEdge = direction === 1 ? el.scrollLeft + el.clientWidth : el.scrollLeft;\n\n for (const child of direction === 1 ? children : children.reverse()) {\n const childEdge = direction === 1 ? child.offsetLeft : child.offsetLeft + child.offsetWidth;\n const isNext = direction === 1 ? childEdge > scrollEdge - 1 : childEdge < scrollEdge + 1;\n if (isNext) {\n child.scrollIntoView({ behavior, block: \"nearest\", inline: \"start\" });\n break;\n }\n }\n}\n</script>\n\n<template>\n <!-- `role=\"region\"` + `tabindex=\"0\"` + an accessible name make this a named,\n focusable landmark region. The keyboard handler is what makes the\n scroll-snap strip navigable by arrow keys — a genuine interaction on\n a genuinely interactive element. The rule does not account for\n non-interactive ARIA roles with an explicit tabindex. -->\n <!-- eslint-disable-next-line vuejs-accessibility/no-static-element-interactions -->\n <div\n ref=\"reel\"\n class=\"overflow-x-auto\"\n :class=\"cn('flex flex-row', snapClass[snap], gapClass[gap])\"\n tabindex=\"0\"\n role=\"region\"\n :aria-label=\"text.region\"\n @keydown=\"onKeydown\"\n >\n <slot />\n </div>\n</template>\n"],"mappings":""}
@@ -1,3 +1,4 @@
1
+ import { type LabelOverrides, type ScrollReelLabels } from "../../../labels/src/index";
1
2
  /**
2
3
  * ScrollReel — horizontal scrolling strip with scroll-snap.
3
4
  *
@@ -13,6 +14,17 @@
13
14
  */
14
15
  export type ScrollReelSnap = "start" | "center" | "end" | "none";
15
16
  export type ScrollReelGap = "sm" | "md" | "lg";
17
+ /**
18
+ * Loom's English, co-located with the component so it tree-shakes with it,
19
+ * and exported so a host can build a partial vocabulary against the real
20
+ * thing rather than a transcription of it. The type itself lives in the
21
+ * labels registry (`ScrollReelLabels`) like every other slot's, so
22
+ * `provideLoomLabels({ scrollReel: … })` reaches this component exactly as
23
+ * it reaches every primitive — composition sits above labels in the layer
24
+ * direction, and a host localising one reel should not have to learn a
25
+ * second seam to do it.
26
+ */
27
+ export declare const SCROLL_REEL_LABELS: ScrollReelLabels;
16
28
  declare const snapClass: Record<ScrollReelSnap, string>;
17
29
  declare const gapClass: Record<ScrollReelGap, string>;
18
30
  export { snapClass, gapClass };
@@ -23,11 +35,25 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
23
35
  snap?: ScrollReelSnap;
24
36
  /** Gap between items — mirrors Stack's scale. Tightens one notch below `sm`. */
25
37
  gap?: ScrollReelGap;
38
+ /**
39
+ * Names for what the reel says out loud, as any subset of
40
+ * `ScrollReelLabels` — the per-instance correction over
41
+ * `SCROLL_REEL_LABELS`, in the same shape a primitive's `labels` prop
42
+ * takes.
43
+ */
44
+ labels?: LabelOverrides<ScrollReelLabels>;
26
45
  }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{
27
46
  /** Scroll-snap alignment. "none" disables snap entirely. */
28
47
  snap?: ScrollReelSnap;
29
48
  /** Gap between items — mirrors Stack's scale. Tightens one notch below `sm`. */
30
49
  gap?: ScrollReelGap;
50
+ /**
51
+ * Names for what the reel says out loud, as any subset of
52
+ * `ScrollReelLabels` — the per-instance correction over
53
+ * `SCROLL_REEL_LABELS`, in the same shape a primitive's `labels` prop
54
+ * takes.
55
+ */
56
+ labels?: LabelOverrides<ScrollReelLabels>;
31
57
  }> & Readonly<{}>, {
32
58
  gap: ScrollReelGap;
33
59
  snap: ScrollReelSnap;