@ecoma-io/loom 0.1.1 → 0.2.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 (495) hide show
  1. package/README.md +54 -57
  2. package/dist/blocks/AppHeader/AppHeader.js.map +1 -1
  3. package/dist/blocks/AppHeader/AppHeader.vue.d.ts +5 -6
  4. package/dist/blocks/AppHeader/AppHeader.vue.d.ts.map +1 -1
  5. package/dist/blocks/AppHeader/AppHeader.vue_vue_type_script_setup_true_lang.js +6 -7
  6. package/dist/blocks/AppHeader/AppHeader.vue_vue_type_script_setup_true_lang.js.map +1 -1
  7. package/dist/blocks/DashboardGrid/DashboardGrid.vue.d.ts +1 -1
  8. package/dist/blocks/DashboardGrid/DashboardGrid.vue.d.ts.map +1 -1
  9. package/dist/blocks/DesktopAppShell/DesktopAppShell.js +7 -0
  10. package/dist/blocks/DesktopAppShell/DesktopAppShell.js.map +1 -0
  11. package/dist/blocks/DesktopAppShell/DesktopAppShell.vue.d.ts +102 -0
  12. package/dist/blocks/DesktopAppShell/DesktopAppShell.vue.d.ts.map +1 -0
  13. package/dist/blocks/DesktopAppShell/DesktopAppShell.vue_vue_type_script_setup_true_lang.js +74 -0
  14. package/dist/blocks/DesktopAppShell/DesktopAppShell.vue_vue_type_script_setup_true_lang.js.map +1 -0
  15. package/dist/blocks/ErrorState/ErrorState.js +7 -0
  16. package/dist/blocks/ErrorState/ErrorState.js.map +1 -0
  17. package/dist/blocks/ErrorState/ErrorState.vue.d.ts +44 -0
  18. package/dist/blocks/ErrorState/ErrorState.vue.d.ts.map +1 -0
  19. package/dist/blocks/ErrorState/ErrorState.vue_vue_type_script_setup_true_lang.js +60 -0
  20. package/dist/blocks/ErrorState/ErrorState.vue_vue_type_script_setup_true_lang.js.map +1 -0
  21. package/dist/blocks/FormActions/FormActions.js +7 -0
  22. package/dist/blocks/FormActions/FormActions.js.map +1 -0
  23. package/dist/blocks/FormActions/FormActions.vue.d.ts +51 -0
  24. package/dist/blocks/FormActions/FormActions.vue.d.ts.map +1 -0
  25. package/dist/blocks/FormActions/FormActions.vue_vue_type_script_setup_true_lang.js +21 -0
  26. package/dist/blocks/FormActions/FormActions.vue_vue_type_script_setup_true_lang.js.map +1 -0
  27. package/dist/blocks/FormSection/FormSection.js +7 -0
  28. package/dist/blocks/FormSection/FormSection.js.map +1 -0
  29. package/dist/blocks/FormSection/FormSection.vue.d.ts +85 -0
  30. package/dist/blocks/FormSection/FormSection.vue.d.ts.map +1 -0
  31. package/dist/blocks/FormSection/FormSection.vue_vue_type_script_setup_true_lang.js +62 -0
  32. package/dist/blocks/FormSection/FormSection.vue_vue_type_script_setup_true_lang.js.map +1 -0
  33. package/dist/blocks/LoadingState/LoadingState.js +7 -0
  34. package/dist/blocks/LoadingState/LoadingState.js.map +1 -0
  35. package/dist/blocks/LoadingState/LoadingState.vue.d.ts +22 -0
  36. package/dist/blocks/LoadingState/LoadingState.vue.d.ts.map +1 -0
  37. package/dist/blocks/LoadingState/LoadingState.vue_vue_type_script_setup_true_lang.js +57 -0
  38. package/dist/blocks/LoadingState/LoadingState.vue_vue_type_script_setup_true_lang.js.map +1 -0
  39. package/dist/blocks/MetricCard/MetricCard.js +7 -0
  40. package/dist/blocks/MetricCard/MetricCard.js.map +1 -0
  41. package/dist/blocks/MetricCard/MetricCard.vue.d.ts +59 -0
  42. package/dist/blocks/MetricCard/MetricCard.vue.d.ts.map +1 -0
  43. package/dist/blocks/MetricCard/MetricCard.vue_vue_type_script_setup_true_lang.js +63 -0
  44. package/dist/blocks/MetricCard/MetricCard.vue_vue_type_script_setup_true_lang.js.map +1 -0
  45. package/dist/blocks/SidebarNav/SidebarNav.js.map +1 -1
  46. package/dist/blocks/SidebarNav/SidebarNav.vue_vue_type_script_setup_true_lang.js.map +1 -1
  47. package/dist/blocks/TitleBar/TitleBar.js.map +1 -1
  48. package/dist/blocks/TitleBar/TitleBar.vue.d.ts +37 -3
  49. package/dist/blocks/TitleBar/TitleBar.vue.d.ts.map +1 -1
  50. package/dist/blocks/TitleBar/TitleBar.vue_vue_type_script_setup_true_lang.js +14 -14
  51. package/dist/blocks/TitleBar/TitleBar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  52. package/dist/blocks/ToastStack/ToastStack.js.map +1 -1
  53. package/dist/blocks/ToastStack/ToastStack.vue.d.ts +20 -0
  54. package/dist/blocks/ToastStack/ToastStack.vue.d.ts.map +1 -1
  55. package/dist/blocks/ToastStack/ToastStack.vue_vue_type_script_setup_true_lang.js +16 -5
  56. package/dist/blocks/ToastStack/ToastStack.vue_vue_type_script_setup_true_lang.js.map +1 -1
  57. package/dist/composition/Center/Center.js +7 -0
  58. package/dist/composition/Center/Center.js.map +1 -0
  59. package/dist/composition/Center/Center.vue.d.ts +40 -0
  60. package/dist/composition/Center/Center.vue.d.ts.map +1 -0
  61. package/dist/composition/Center/Center.vue_vue_type_script_setup_true_lang.js +29 -0
  62. package/dist/composition/Center/Center.vue_vue_type_script_setup_true_lang.js.map +1 -0
  63. package/dist/composition/Frame/Frame.js +7 -0
  64. package/dist/composition/Frame/Frame.js.map +1 -0
  65. package/dist/composition/Frame/Frame.vue.d.ts +35 -0
  66. package/dist/composition/Frame/Frame.vue.d.ts.map +1 -0
  67. package/dist/composition/Frame/Frame.vue_vue_type_script_setup_true_lang.js +29 -0
  68. package/dist/composition/Frame/Frame.vue_vue_type_script_setup_true_lang.js.map +1 -0
  69. package/dist/composition/Grid/Grid.js +7 -0
  70. package/dist/composition/Grid/Grid.js.map +1 -0
  71. package/dist/composition/Grid/Grid.vue.d.ts +41 -0
  72. package/dist/composition/Grid/Grid.vue.d.ts.map +1 -0
  73. package/dist/composition/Grid/Grid.vue_vue_type_script_setup_true_lang.js +27 -0
  74. package/dist/composition/Grid/Grid.vue_vue_type_script_setup_true_lang.js.map +1 -0
  75. package/dist/composition/Inline/Inline.js +7 -0
  76. package/dist/composition/Inline/Inline.js.map +1 -0
  77. package/dist/composition/Inline/Inline.vue.d.ts +46 -0
  78. package/dist/composition/Inline/Inline.vue.d.ts.map +1 -0
  79. package/dist/composition/Inline/Inline.vue_vue_type_script_setup_true_lang.js +35 -0
  80. package/dist/composition/Inline/Inline.vue_vue_type_script_setup_true_lang.js.map +1 -0
  81. package/dist/composition/ScrollReel/ScrollReel.js +7 -0
  82. package/dist/composition/ScrollReel/ScrollReel.js.map +1 -0
  83. package/dist/composition/ScrollReel/ScrollReel.vue.d.ts +42 -0
  84. package/dist/composition/ScrollReel/ScrollReel.vue.d.ts.map +1 -0
  85. package/dist/composition/ScrollReel/ScrollReel.vue_vue_type_script_setup_true_lang.js +79 -0
  86. package/dist/composition/ScrollReel/ScrollReel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  87. package/dist/composition/Sidebar/Sidebar.js +7 -0
  88. package/dist/composition/Sidebar/Sidebar.js.map +1 -0
  89. package/dist/composition/Sidebar/Sidebar.vue.d.ts +52 -0
  90. package/dist/composition/Sidebar/Sidebar.vue.d.ts.map +1 -0
  91. package/dist/composition/Sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js +36 -0
  92. package/dist/composition/Sidebar/Sidebar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  93. package/dist/composition/Split/Split.js +7 -0
  94. package/dist/composition/Split/Split.js.map +1 -0
  95. package/dist/composition/Split/Split.vue.d.ts +58 -0
  96. package/dist/composition/Split/Split.vue.d.ts.map +1 -0
  97. package/dist/composition/Split/Split.vue_vue_type_script_setup_true_lang.js +40 -0
  98. package/dist/composition/Split/Split.vue_vue_type_script_setup_true_lang.js.map +1 -0
  99. package/dist/composition/Stack/Stack.js +7 -0
  100. package/dist/composition/Stack/Stack.js.map +1 -0
  101. package/dist/composition/Stack/Stack.vue.d.ts +43 -0
  102. package/dist/composition/Stack/Stack.vue.d.ts.map +1 -0
  103. package/dist/composition/Stack/Stack.vue_vue_type_script_setup_true_lang.js +30 -0
  104. package/dist/composition/Stack/Stack.vue_vue_type_script_setup_true_lang.js.map +1 -0
  105. package/dist/index.d.ts +119 -11
  106. package/dist/index.d.ts.map +1 -1
  107. package/dist/index.js +83 -5
  108. package/dist/layouts/AppShell/AppShell.js +7 -0
  109. package/dist/layouts/AppShell/AppShell.js.map +1 -0
  110. package/dist/layouts/AppShell/AppShell.vue.d.ts +51 -0
  111. package/dist/layouts/AppShell/AppShell.vue.d.ts.map +1 -0
  112. package/dist/layouts/AppShell/AppShell.vue_vue_type_script_setup_true_lang.js +47 -0
  113. package/dist/layouts/AppShell/AppShell.vue_vue_type_script_setup_true_lang.js.map +1 -0
  114. package/dist/layouts/Centered/Centered.js +7 -0
  115. package/dist/layouts/Centered/Centered.js.map +1 -0
  116. package/dist/layouts/Centered/Centered.vue.d.ts +48 -0
  117. package/dist/layouts/Centered/Centered.vue.d.ts.map +1 -0
  118. package/dist/layouts/Centered/Centered.vue_vue_type_script_setup_true_lang.js +35 -0
  119. package/dist/layouts/Centered/Centered.vue_vue_type_script_setup_true_lang.js.map +1 -0
  120. package/dist/layouts/Dashboard/Dashboard.js +7 -0
  121. package/dist/layouts/Dashboard/Dashboard.js.map +1 -0
  122. package/dist/layouts/Dashboard/Dashboard.vue.d.ts +60 -0
  123. package/dist/layouts/Dashboard/Dashboard.vue.d.ts.map +1 -0
  124. package/dist/layouts/Dashboard/Dashboard.vue_vue_type_script_setup_true_lang.js +64 -0
  125. package/dist/layouts/Dashboard/Dashboard.vue_vue_type_script_setup_true_lang.js.map +1 -0
  126. package/dist/layouts/FormLayout/FormLayout.js +7 -0
  127. package/dist/layouts/FormLayout/FormLayout.js.map +1 -0
  128. package/dist/layouts/FormLayout/FormLayout.vue.d.ts +46 -0
  129. package/dist/layouts/FormLayout/FormLayout.vue.d.ts.map +1 -0
  130. package/dist/layouts/FormLayout/FormLayout.vue_vue_type_script_setup_true_lang.js +28 -0
  131. package/dist/layouts/FormLayout/FormLayout.vue_vue_type_script_setup_true_lang.js.map +1 -0
  132. package/dist/layouts/MasterDetail/MasterDetail.js +7 -0
  133. package/dist/layouts/MasterDetail/MasterDetail.js.map +1 -0
  134. package/dist/layouts/MasterDetail/MasterDetail.vue.d.ts +49 -0
  135. package/dist/layouts/MasterDetail/MasterDetail.vue.d.ts.map +1 -0
  136. package/dist/layouts/MasterDetail/MasterDetail.vue_vue_type_script_setup_true_lang.js +42 -0
  137. package/dist/layouts/MasterDetail/MasterDetail.vue_vue_type_script_setup_true_lang.js.map +1 -0
  138. package/dist/layouts/Reading/Reading.js +7 -0
  139. package/dist/layouts/Reading/Reading.js.map +1 -0
  140. package/dist/layouts/Reading/Reading.vue.d.ts +24 -0
  141. package/dist/layouts/Reading/Reading.vue.d.ts.map +1 -0
  142. package/dist/layouts/Reading/Reading.vue_vue_type_script_setup_true_lang.js +29 -0
  143. package/dist/layouts/Reading/Reading.vue_vue_type_script_setup_true_lang.js.map +1 -0
  144. package/dist/layouts/Settings/Settings.js +7 -0
  145. package/dist/layouts/Settings/Settings.js.map +1 -0
  146. package/dist/layouts/Settings/Settings.vue.d.ts +39 -0
  147. package/dist/layouts/Settings/Settings.vue.d.ts.map +1 -0
  148. package/dist/layouts/Settings/Settings.vue_vue_type_script_setup_true_lang.js +35 -0
  149. package/dist/layouts/Settings/Settings.vue_vue_type_script_setup_true_lang.js.map +1 -0
  150. package/dist/layouts/SplitLayout/SplitLayout.js +7 -0
  151. package/dist/layouts/SplitLayout/SplitLayout.js.map +1 -0
  152. package/dist/layouts/SplitLayout/SplitLayout.vue.d.ts +63 -0
  153. package/dist/layouts/SplitLayout/SplitLayout.vue.d.ts.map +1 -0
  154. package/dist/layouts/SplitLayout/SplitLayout.vue_vue_type_script_setup_true_lang.js +46 -0
  155. package/dist/layouts/SplitLayout/SplitLayout.vue_vue_type_script_setup_true_lang.js.map +1 -0
  156. package/dist/lib/ancestor-disabled.d.ts +35 -0
  157. package/dist/lib/ancestor-disabled.d.ts.map +1 -0
  158. package/dist/lib/ancestor-disabled.js +86 -0
  159. package/dist/lib/ancestor-disabled.js.map +1 -0
  160. package/dist/lib/cn.d.ts.map +1 -1
  161. package/dist/lib/cn.js +46 -1
  162. package/dist/lib/cn.js.map +1 -1
  163. package/dist/lib/count-labels.d.ts +78 -0
  164. package/dist/lib/count-labels.d.ts.map +1 -0
  165. package/dist/lib/count-labels.js +29 -0
  166. package/dist/lib/count-labels.js.map +1 -0
  167. package/dist/lib/date-labels.d.ts +278 -0
  168. package/dist/lib/date-labels.d.ts.map +1 -0
  169. package/dist/lib/date-labels.js +157 -0
  170. package/dist/lib/date-labels.js.map +1 -0
  171. package/dist/lib/field-context.d.ts +178 -0
  172. package/dist/lib/field-context.d.ts.map +1 -0
  173. package/dist/lib/field-context.js +106 -0
  174. package/dist/lib/field-context.js.map +1 -0
  175. package/dist/lib/label-registry.d.ts +75 -0
  176. package/dist/lib/label-registry.d.ts.map +1 -0
  177. package/dist/lib/labels.d.ts +116 -0
  178. package/dist/lib/labels.d.ts.map +1 -0
  179. package/dist/lib/labels.js +84 -0
  180. package/dist/lib/labels.js.map +1 -0
  181. package/dist/lib/theme.d.ts +68 -0
  182. package/dist/lib/theme.d.ts.map +1 -0
  183. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/CalendarDate.js +236 -0
  184. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/CalendarDate.js.map +1 -0
  185. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/calendars/GregorianCalendar.js +117 -0
  186. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/calendars/GregorianCalendar.js.map +1 -0
  187. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/conversion.js +142 -0
  188. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/conversion.js.map +1 -0
  189. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/manipulation.js +280 -0
  190. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/manipulation.js.map +1 -0
  191. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/queries.js +40 -0
  192. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/queries.js.map +1 -0
  193. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/string.js +69 -0
  194. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/string.js.map +1 -0
  195. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/utils.js +8 -0
  196. package/dist/node_modules/.pnpm/@internationalized_date@3.12.3/node_modules/@internationalized/date/dist/private/utils.js.map +1 -0
  197. package/dist/primitives/Accordion/Accordion.js +7 -0
  198. package/dist/primitives/Accordion/Accordion.js.map +1 -0
  199. package/dist/primitives/Accordion/Accordion.vue.d.ts +68 -0
  200. package/dist/primitives/Accordion/Accordion.vue.d.ts.map +1 -0
  201. package/dist/primitives/Accordion/Accordion.vue_vue_type_script_setup_true_lang.js +67 -0
  202. package/dist/primitives/Accordion/Accordion.vue_vue_type_script_setup_true_lang.js.map +1 -0
  203. package/dist/primitives/AlertDialog/AlertDialog.js +7 -0
  204. package/dist/primitives/AlertDialog/AlertDialog.js.map +1 -0
  205. package/dist/primitives/AlertDialog/AlertDialog.vue.d.ts +94 -0
  206. package/dist/primitives/AlertDialog/AlertDialog.vue.d.ts.map +1 -0
  207. package/dist/primitives/AlertDialog/AlertDialog.vue_vue_type_script_setup_true_lang.js +99 -0
  208. package/dist/primitives/AlertDialog/AlertDialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  209. package/dist/primitives/Avatar/Avatar.js +2 -2
  210. package/dist/primitives/Avatar/Avatar.js.map +1 -1
  211. package/dist/primitives/Avatar/Avatar.vue.d.ts +30 -3
  212. package/dist/primitives/Avatar/Avatar.vue.d.ts.map +1 -1
  213. package/dist/primitives/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js +95 -14
  214. package/dist/primitives/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  215. package/dist/primitives/AvatarGroup/AvatarGroup.js +7 -0
  216. package/dist/primitives/AvatarGroup/AvatarGroup.js.map +1 -0
  217. package/dist/primitives/AvatarGroup/AvatarGroup.vue.d.ts +104 -0
  218. package/dist/primitives/AvatarGroup/AvatarGroup.vue.d.ts.map +1 -0
  219. package/dist/primitives/AvatarGroup/AvatarGroup.vue_vue_type_script_setup_true_lang.js +139 -0
  220. package/dist/primitives/AvatarGroup/AvatarGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  221. package/dist/primitives/Badge/Badge.js.map +1 -1
  222. package/dist/primitives/Badge/Badge.vue.d.ts +6 -6
  223. package/dist/primitives/Badge/Badge.vue.d.ts.map +1 -1
  224. package/dist/primitives/Badge/Badge.vue_vue_type_script_setup_true_lang.js +1 -1
  225. package/dist/primitives/Badge/Badge.vue_vue_type_script_setup_true_lang.js.map +1 -1
  226. package/dist/primitives/Breadcrumb/Breadcrumb.js +7 -0
  227. package/dist/primitives/Breadcrumb/Breadcrumb.js.map +1 -0
  228. package/dist/primitives/Breadcrumb/Breadcrumb.vue.d.ts +25 -0
  229. package/dist/primitives/Breadcrumb/Breadcrumb.vue.d.ts.map +1 -0
  230. package/dist/primitives/Breadcrumb/Breadcrumb.vue_vue_type_script_setup_true_lang.js +48 -0
  231. package/dist/primitives/Breadcrumb/Breadcrumb.vue_vue_type_script_setup_true_lang.js.map +1 -0
  232. package/dist/primitives/Button/Button.js +2 -2
  233. package/dist/primitives/Button/Button.js.map +1 -1
  234. package/dist/primitives/Button/Button.vue.d.ts +31 -8
  235. package/dist/primitives/Button/Button.vue.d.ts.map +1 -1
  236. package/dist/primitives/Button/Button.vue_vue_type_script_setup_true_lang.js +32 -16
  237. package/dist/primitives/Button/Button.vue_vue_type_script_setup_true_lang.js.map +1 -1
  238. package/dist/primitives/Checkbox/Checkbox.js.map +1 -1
  239. package/dist/primitives/Checkbox/Checkbox.vue.d.ts +18 -3
  240. package/dist/primitives/Checkbox/Checkbox.vue.d.ts.map +1 -1
  241. package/dist/primitives/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js +46 -7
  242. package/dist/primitives/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js.map +1 -1
  243. package/dist/primitives/Chip/Chip.js +7 -0
  244. package/dist/primitives/Chip/Chip.js.map +1 -0
  245. package/dist/primitives/Chip/Chip.vue.d.ts +79 -0
  246. package/dist/primitives/Chip/Chip.vue.d.ts.map +1 -0
  247. package/dist/primitives/Chip/Chip.vue_vue_type_script_setup_true_lang.js +139 -0
  248. package/dist/primitives/Chip/Chip.vue_vue_type_script_setup_true_lang.js.map +1 -0
  249. package/dist/primitives/ColorPicker/ColorPicker.js +7 -0
  250. package/dist/primitives/ColorPicker/ColorPicker.js.map +1 -0
  251. package/dist/primitives/ColorPicker/ColorPicker.vue.d.ts +125 -0
  252. package/dist/primitives/ColorPicker/ColorPicker.vue.d.ts.map +1 -0
  253. package/dist/primitives/ColorPicker/ColorPicker.vue_vue_type_script_setup_true_lang.js +301 -0
  254. package/dist/primitives/ColorPicker/ColorPicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  255. package/dist/primitives/Combobox/Combobox.js +7 -0
  256. package/dist/primitives/Combobox/Combobox.js.map +1 -0
  257. package/dist/primitives/Combobox/Combobox.vue.d.ts +205 -0
  258. package/dist/primitives/Combobox/Combobox.vue.d.ts.map +1 -0
  259. package/dist/primitives/Combobox/Combobox.vue_vue_type_script_setup_true_lang.js +345 -0
  260. package/dist/primitives/Combobox/Combobox.vue_vue_type_script_setup_true_lang.js.map +1 -0
  261. package/dist/primitives/ContextMenu/ContextMenu.js +7 -0
  262. package/dist/primitives/ContextMenu/ContextMenu.js.map +1 -0
  263. package/dist/primitives/ContextMenu/ContextMenu.vue.d.ts +55 -0
  264. package/dist/primitives/ContextMenu/ContextMenu.vue.d.ts.map +1 -0
  265. package/dist/primitives/ContextMenu/ContextMenu.vue_vue_type_script_setup_true_lang.js +82 -0
  266. package/dist/primitives/ContextMenu/ContextMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  267. package/dist/primitives/DatePicker/DatePicker.js +7 -0
  268. package/dist/primitives/DatePicker/DatePicker.js.map +1 -0
  269. package/dist/primitives/DatePicker/DatePicker.vue.d.ts +102 -0
  270. package/dist/primitives/DatePicker/DatePicker.vue.d.ts.map +1 -0
  271. package/dist/primitives/DatePicker/DatePicker.vue_vue_type_script_setup_true_lang.js +292 -0
  272. package/dist/primitives/DatePicker/DatePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  273. package/dist/primitives/DateRangePicker/DateRangePicker.js +7 -0
  274. package/dist/primitives/DateRangePicker/DateRangePicker.js.map +1 -0
  275. package/dist/primitives/DateRangePicker/DateRangePicker.vue.d.ts +173 -0
  276. package/dist/primitives/DateRangePicker/DateRangePicker.vue.d.ts.map +1 -0
  277. package/dist/primitives/DateRangePicker/DateRangePicker.vue_vue_type_script_setup_true_lang.js +412 -0
  278. package/dist/primitives/DateRangePicker/DateRangePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  279. package/dist/primitives/DateTimePicker/DateTimePicker.js +7 -0
  280. package/dist/primitives/DateTimePicker/DateTimePicker.js.map +1 -0
  281. package/dist/primitives/DateTimePicker/DateTimePicker.vue.d.ts +113 -0
  282. package/dist/primitives/DateTimePicker/DateTimePicker.vue.d.ts.map +1 -0
  283. package/dist/primitives/DateTimePicker/DateTimePicker.vue_vue_type_script_setup_true_lang.js +358 -0
  284. package/dist/primitives/DateTimePicker/DateTimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  285. package/dist/primitives/DateTimeRangePicker/DateTimeRangePicker.js +7 -0
  286. package/dist/primitives/DateTimeRangePicker/DateTimeRangePicker.js.map +1 -0
  287. package/dist/primitives/DateTimeRangePicker/DateTimeRangePicker.vue.d.ts +181 -0
  288. package/dist/primitives/DateTimeRangePicker/DateTimeRangePicker.vue.d.ts.map +1 -0
  289. package/dist/primitives/DateTimeRangePicker/DateTimeRangePicker.vue_vue_type_script_setup_true_lang.js +562 -0
  290. package/dist/primitives/DateTimeRangePicker/DateTimeRangePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  291. package/dist/primitives/Dialog/Dialog.js +2 -2
  292. package/dist/primitives/Dialog/Dialog.js.map +1 -1
  293. package/dist/primitives/Dialog/Dialog.vue.d.ts +39 -0
  294. package/dist/primitives/Dialog/Dialog.vue.d.ts.map +1 -1
  295. package/dist/primitives/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js +14 -5
  296. package/dist/primitives/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js.map +1 -1
  297. package/dist/primitives/Drawer/Drawer.js +7 -0
  298. package/dist/primitives/Drawer/Drawer.js.map +1 -0
  299. package/dist/primitives/Drawer/Drawer.vue.d.ts +110 -0
  300. package/dist/primitives/Drawer/Drawer.vue.d.ts.map +1 -0
  301. package/dist/primitives/Drawer/Drawer.vue_vue_type_script_setup_true_lang.js +223 -0
  302. package/dist/primitives/Drawer/Drawer.vue_vue_type_script_setup_true_lang.js.map +1 -0
  303. package/dist/primitives/DropdownMenu/DropdownMenu.js.map +1 -1
  304. package/dist/primitives/DropdownMenu/DropdownMenu.vue.d.ts.map +1 -1
  305. package/dist/primitives/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js +2 -2
  306. package/dist/primitives/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js.map +1 -1
  307. package/dist/primitives/Editable/Editable.js +7 -0
  308. package/dist/primitives/Editable/Editable.js.map +1 -0
  309. package/dist/primitives/Editable/Editable.vue.d.ts +200 -0
  310. package/dist/primitives/Editable/Editable.vue.d.ts.map +1 -0
  311. package/dist/primitives/Editable/Editable.vue_vue_type_script_setup_true_lang.js +275 -0
  312. package/dist/primitives/Editable/Editable.vue_vue_type_script_setup_true_lang.js.map +1 -0
  313. package/dist/primitives/Field/Field.js.map +1 -1
  314. package/dist/primitives/Field/Field.vue.d.ts +32 -17
  315. package/dist/primitives/Field/Field.vue.d.ts.map +1 -1
  316. package/dist/primitives/Field/Field.vue_vue_type_script_setup_true_lang.js +51 -18
  317. package/dist/primitives/Field/Field.vue_vue_type_script_setup_true_lang.js.map +1 -1
  318. package/dist/primitives/Fieldset/Fieldset.js +7 -0
  319. package/dist/primitives/Fieldset/Fieldset.js.map +1 -0
  320. package/dist/primitives/Fieldset/Fieldset.vue.d.ts +91 -0
  321. package/dist/primitives/Fieldset/Fieldset.vue.d.ts.map +1 -0
  322. package/dist/primitives/Fieldset/Fieldset.vue_vue_type_script_setup_true_lang.js +138 -0
  323. package/dist/primitives/Fieldset/Fieldset.vue_vue_type_script_setup_true_lang.js.map +1 -0
  324. package/dist/primitives/FileUpload/FileUpload.js +7 -0
  325. package/dist/primitives/FileUpload/FileUpload.js.map +1 -0
  326. package/dist/primitives/FileUpload/FileUpload.vue.d.ts +132 -0
  327. package/dist/primitives/FileUpload/FileUpload.vue.d.ts.map +1 -0
  328. package/dist/primitives/FileUpload/FileUpload.vue_vue_type_script_setup_true_lang.js +359 -0
  329. package/dist/primitives/FileUpload/FileUpload.vue_vue_type_script_setup_true_lang.js.map +1 -0
  330. package/dist/primitives/HoverCard/HoverCard.js +7 -0
  331. package/dist/primitives/HoverCard/HoverCard.js.map +1 -0
  332. package/dist/primitives/HoverCard/HoverCard.vue.d.ts +68 -0
  333. package/dist/primitives/HoverCard/HoverCard.vue.d.ts.map +1 -0
  334. package/dist/primitives/HoverCard/HoverCard.vue_vue_type_script_setup_true_lang.js +62 -0
  335. package/dist/primitives/HoverCard/HoverCard.vue_vue_type_script_setup_true_lang.js.map +1 -0
  336. package/dist/primitives/IconButton/IconButton.js +7 -0
  337. package/dist/primitives/IconButton/IconButton.js.map +1 -0
  338. package/dist/primitives/IconButton/IconButton.vue.d.ts +45 -0
  339. package/dist/primitives/IconButton/IconButton.vue.d.ts.map +1 -0
  340. package/dist/primitives/IconButton/IconButton.vue_vue_type_script_setup_true_lang.js +58 -0
  341. package/dist/primitives/IconButton/IconButton.vue_vue_type_script_setup_true_lang.js.map +1 -0
  342. package/dist/primitives/Indicator/Indicator.js +7 -0
  343. package/dist/primitives/Indicator/Indicator.js.map +1 -0
  344. package/dist/primitives/Indicator/Indicator.vue.d.ts +144 -0
  345. package/dist/primitives/Indicator/Indicator.vue.d.ts.map +1 -0
  346. package/dist/primitives/Indicator/Indicator.vue_vue_type_script_setup_true_lang.js +198 -0
  347. package/dist/primitives/Indicator/Indicator.vue_vue_type_script_setup_true_lang.js.map +1 -0
  348. package/dist/primitives/Link/Link.js +7 -0
  349. package/dist/primitives/Link/Link.js.map +1 -0
  350. package/dist/primitives/Link/Link.vue.d.ts +46 -0
  351. package/dist/primitives/Link/Link.vue.d.ts.map +1 -0
  352. package/dist/primitives/Link/Link.vue_vue_type_script_setup_true_lang.js +85 -0
  353. package/dist/primitives/Link/Link.vue_vue_type_script_setup_true_lang.js.map +1 -0
  354. package/dist/primitives/Menubar/Menubar.js.map +1 -1
  355. package/dist/primitives/Menubar/Menubar.vue.d.ts.map +1 -1
  356. package/dist/primitives/Menubar/Menubar.vue_vue_type_script_setup_true_lang.js +1 -1
  357. package/dist/primitives/Menubar/Menubar.vue_vue_type_script_setup_true_lang.js.map +1 -1
  358. package/dist/primitives/NumberField/NumberField.js +2 -2
  359. package/dist/primitives/NumberField/NumberField.js.map +1 -1
  360. package/dist/primitives/NumberField/NumberField.vue.d.ts +86 -25
  361. package/dist/primitives/NumberField/NumberField.vue.d.ts.map +1 -1
  362. package/dist/primitives/NumberField/NumberField.vue_vue_type_script_setup_true_lang.js +83 -39
  363. package/dist/primitives/NumberField/NumberField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  364. package/dist/primitives/OtpInput/OtpInput.js +7 -0
  365. package/dist/primitives/OtpInput/OtpInput.js.map +1 -0
  366. package/dist/primitives/OtpInput/OtpInput.vue.d.ts +110 -0
  367. package/dist/primitives/OtpInput/OtpInput.vue.d.ts.map +1 -0
  368. package/dist/primitives/OtpInput/OtpInput.vue_vue_type_script_setup_true_lang.js +130 -0
  369. package/dist/primitives/OtpInput/OtpInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
  370. package/dist/primitives/Pagination/Pagination.js +7 -0
  371. package/dist/primitives/Pagination/Pagination.js.map +1 -0
  372. package/dist/primitives/Pagination/Pagination.vue.d.ts +143 -0
  373. package/dist/primitives/Pagination/Pagination.vue.d.ts.map +1 -0
  374. package/dist/primitives/Pagination/Pagination.vue_vue_type_script_setup_true_lang.js +231 -0
  375. package/dist/primitives/Pagination/Pagination.vue_vue_type_script_setup_true_lang.js.map +1 -0
  376. package/dist/primitives/Progress/Progress.js +2 -2
  377. package/dist/primitives/Progress/Progress.js.map +1 -1
  378. package/dist/primitives/Progress/Progress.vue.d.ts +81 -15
  379. package/dist/primitives/Progress/Progress.vue.d.ts.map +1 -1
  380. package/dist/primitives/Progress/Progress.vue_vue_type_script_setup_true_lang.js +88 -22
  381. package/dist/primitives/Progress/Progress.vue_vue_type_script_setup_true_lang.js.map +1 -1
  382. package/dist/primitives/RadialProgress/RadialProgress.js +7 -0
  383. package/dist/primitives/RadialProgress/RadialProgress.js.map +1 -0
  384. package/dist/primitives/RadialProgress/RadialProgress.vue.d.ts +96 -0
  385. package/dist/primitives/RadialProgress/RadialProgress.vue.d.ts.map +1 -0
  386. package/dist/primitives/RadialProgress/RadialProgress.vue_vue_type_script_setup_true_lang.js +189 -0
  387. package/dist/primitives/RadialProgress/RadialProgress.vue_vue_type_script_setup_true_lang.js.map +1 -0
  388. package/dist/primitives/RadioGroup/RadioGroup.js.map +1 -1
  389. package/dist/primitives/RadioGroup/RadioGroup.vue.d.ts +7 -7
  390. package/dist/primitives/RadioGroup/RadioGroup.vue.d.ts.map +1 -1
  391. package/dist/primitives/RadioGroup/RadioGroup.vue_vue_type_script_setup_true_lang.js +26 -9
  392. package/dist/primitives/RadioGroup/RadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -1
  393. package/dist/primitives/Rating/Rating.js +7 -0
  394. package/dist/primitives/Rating/Rating.js.map +1 -0
  395. package/dist/primitives/Rating/Rating.vue.d.ts +113 -0
  396. package/dist/primitives/Rating/Rating.vue.d.ts.map +1 -0
  397. package/dist/primitives/Rating/Rating.vue_vue_type_script_setup_true_lang.js +282 -0
  398. package/dist/primitives/Rating/Rating.vue_vue_type_script_setup_true_lang.js.map +1 -0
  399. package/dist/primitives/ScrollArea/ScrollArea.js +7 -0
  400. package/dist/primitives/ScrollArea/ScrollArea.js.map +1 -0
  401. package/dist/primitives/ScrollArea/ScrollArea.vue.d.ts +25 -0
  402. package/dist/primitives/ScrollArea/ScrollArea.vue.d.ts.map +1 -0
  403. package/dist/primitives/ScrollArea/ScrollArea.vue_vue_type_script_setup_true_lang.js +45 -0
  404. package/dist/primitives/ScrollArea/ScrollArea.vue_vue_type_script_setup_true_lang.js.map +1 -0
  405. package/dist/primitives/SegmentedControl/SegmentedControl.js.map +1 -1
  406. package/dist/primitives/SegmentedControl/SegmentedControl.vue.d.ts +5 -5
  407. package/dist/primitives/SegmentedControl/SegmentedControl.vue.d.ts.map +1 -1
  408. package/dist/primitives/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js +51 -8
  409. package/dist/primitives/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map +1 -1
  410. package/dist/primitives/Select/Select.js.map +1 -1
  411. package/dist/primitives/Select/Select.vue.d.ts +10 -10
  412. package/dist/primitives/Select/Select.vue.d.ts.map +1 -1
  413. package/dist/primitives/Select/Select.vue_vue_type_script_setup_true_lang.js +105 -52
  414. package/dist/primitives/Select/Select.vue_vue_type_script_setup_true_lang.js.map +1 -1
  415. package/dist/primitives/Skeleton/Skeleton.vue.d.ts +1 -1
  416. package/dist/primitives/Slider/Slider.js.map +1 -1
  417. package/dist/primitives/Slider/Slider.vue.d.ts +24 -4
  418. package/dist/primitives/Slider/Slider.vue.d.ts.map +1 -1
  419. package/dist/primitives/Slider/Slider.vue_vue_type_script_setup_true_lang.js +79 -9
  420. package/dist/primitives/Slider/Slider.vue_vue_type_script_setup_true_lang.js.map +1 -1
  421. package/dist/primitives/SpeedDial/SpeedDial.js +7 -0
  422. package/dist/primitives/SpeedDial/SpeedDial.js.map +1 -0
  423. package/dist/primitives/SpeedDial/SpeedDial.vue.d.ts +58 -0
  424. package/dist/primitives/SpeedDial/SpeedDial.vue.d.ts.map +1 -0
  425. package/dist/primitives/SpeedDial/SpeedDial.vue_vue_type_script_setup_true_lang.js +175 -0
  426. package/dist/primitives/SpeedDial/SpeedDial.vue_vue_type_script_setup_true_lang.js.map +1 -0
  427. package/dist/primitives/Stepper/Stepper.js +7 -0
  428. package/dist/primitives/Stepper/Stepper.js.map +1 -0
  429. package/dist/primitives/Stepper/Stepper.vue.d.ts +119 -0
  430. package/dist/primitives/Stepper/Stepper.vue.d.ts.map +1 -0
  431. package/dist/primitives/Stepper/Stepper.vue_vue_type_script_setup_true_lang.js +202 -0
  432. package/dist/primitives/Stepper/Stepper.vue_vue_type_script_setup_true_lang.js.map +1 -0
  433. package/dist/primitives/Switch/Switch.js.map +1 -1
  434. package/dist/primitives/Switch/Switch.vue.d.ts +13 -3
  435. package/dist/primitives/Switch/Switch.vue.d.ts.map +1 -1
  436. package/dist/primitives/Switch/Switch.vue_vue_type_script_setup_true_lang.js +34 -5
  437. package/dist/primitives/Switch/Switch.vue_vue_type_script_setup_true_lang.js.map +1 -1
  438. package/dist/primitives/Tabs/Tabs.js.map +1 -1
  439. package/dist/primitives/Tabs/Tabs.vue.d.ts.map +1 -1
  440. package/dist/primitives/Tabs/Tabs.vue_vue_type_script_setup_true_lang.js +1 -1
  441. package/dist/primitives/Tabs/Tabs.vue_vue_type_script_setup_true_lang.js.map +1 -1
  442. package/dist/primitives/TagsInput/TagsInput.js +7 -0
  443. package/dist/primitives/TagsInput/TagsInput.js.map +1 -0
  444. package/dist/primitives/TagsInput/TagsInput.vue.d.ts +156 -0
  445. package/dist/primitives/TagsInput/TagsInput.vue.d.ts.map +1 -0
  446. package/dist/primitives/TagsInput/TagsInput.vue_vue_type_script_setup_true_lang.js +387 -0
  447. package/dist/primitives/TagsInput/TagsInput.vue_vue_type_script_setup_true_lang.js.map +1 -0
  448. package/dist/primitives/TextField/TextField.js +2 -2
  449. package/dist/primitives/TextField/TextField.js.map +1 -1
  450. package/dist/primitives/TextField/TextField.vue.d.ts +119 -10
  451. package/dist/primitives/TextField/TextField.vue.d.ts.map +1 -1
  452. package/dist/primitives/TextField/TextField.vue_vue_type_script_setup_true_lang.js +270 -21
  453. package/dist/primitives/TextField/TextField.vue_vue_type_script_setup_true_lang.js.map +1 -1
  454. package/dist/primitives/Textarea/Textarea.js +2 -2
  455. package/dist/primitives/Textarea/Textarea.js.map +1 -1
  456. package/dist/primitives/Textarea/Textarea.vue.d.ts +114 -14
  457. package/dist/primitives/Textarea/Textarea.vue.d.ts.map +1 -1
  458. package/dist/primitives/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js +216 -20
  459. package/dist/primitives/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js.map +1 -1
  460. package/dist/primitives/TimePicker/TimePicker.js +7 -0
  461. package/dist/primitives/TimePicker/TimePicker.js.map +1 -0
  462. package/dist/primitives/TimePicker/TimePicker.vue.d.ts +111 -0
  463. package/dist/primitives/TimePicker/TimePicker.vue.d.ts.map +1 -0
  464. package/dist/primitives/TimePicker/TimePicker.vue_vue_type_script_setup_true_lang.js +185 -0
  465. package/dist/primitives/TimePicker/TimePicker.vue_vue_type_script_setup_true_lang.js.map +1 -0
  466. package/dist/primitives/Toast/Toast.js +2 -1
  467. package/dist/primitives/Toast/Toast.js.map +1 -1
  468. package/dist/primitives/Toast/Toast.vue.d.ts +29 -3
  469. package/dist/primitives/Toast/Toast.vue.d.ts.map +1 -1
  470. package/dist/primitives/Toast/Toast.vue_vue_type_script_setup_true_lang.js +17 -7
  471. package/dist/primitives/Toast/Toast.vue_vue_type_script_setup_true_lang.js.map +1 -1
  472. package/dist/primitives/Toast/ToastItem.js +2 -2
  473. package/dist/primitives/Toast/ToastItem.js.map +1 -1
  474. package/dist/primitives/Toast/ToastItem.vue.d.ts +69 -12
  475. package/dist/primitives/Toast/ToastItem.vue.d.ts.map +1 -1
  476. package/dist/primitives/Toast/ToastItem.vue_vue_type_script_setup_true_lang.js +23 -23
  477. package/dist/primitives/Toast/ToastItem.vue_vue_type_script_setup_true_lang.js.map +1 -1
  478. package/dist/primitives/Tooltip/Tooltip.vue.d.ts +1 -1
  479. package/dist/primitives/Tooltip/Tooltip.vue.d.ts.map +1 -1
  480. package/dist/primitives/WindowControls/WindowControls.js +2 -2
  481. package/dist/primitives/WindowControls/WindowControls.js.map +1 -1
  482. package/dist/primitives/WindowControls/WindowControls.vue.d.ts +66 -10
  483. package/dist/primitives/WindowControls/WindowControls.vue.d.ts.map +1 -1
  484. package/dist/primitives/WindowControls/WindowControls.vue_vue_type_script_setup_true_lang.js +23 -13
  485. package/dist/primitives/WindowControls/WindowControls.vue_vue_type_script_setup_true_lang.js.map +1 -1
  486. package/dist/styles/global.css +116 -17
  487. package/dist/styles/theme.contrast.test.ts +460 -0
  488. package/dist/styles/theme.css +239 -41
  489. package/dist/theme.js +171 -0
  490. package/dist/theme.js.map +1 -0
  491. package/package.json +14 -4
  492. package/dist/icons/BrandMark.d.ts +0 -18
  493. package/dist/icons/BrandMark.d.ts.map +0 -1
  494. package/dist/icons/BrandMark.js +0 -47
  495. package/dist/icons/BrandMark.js.map +0 -1
@@ -0,0 +1,48 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { Fragment, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, defineComponent, normalizeClass, openBlock, renderList, toDisplayString, unref } from "vue";
3
+ //#region src/primitives/Breadcrumb/Breadcrumb.vue?vue&type=script&setup=true&lang.ts
4
+ var _hoisted_1 = { "aria-label": "Breadcrumb" };
5
+ var _hoisted_2 = { class: "flex items-center gap-1.5 text-sm" };
6
+ var _hoisted_3 = {
7
+ key: 0,
8
+ xmlns: "http://www.w3.org/2000/svg",
9
+ width: "16",
10
+ height: "16",
11
+ viewBox: "0 0 24 24",
12
+ fill: "none",
13
+ stroke: "currentColor",
14
+ "stroke-width": "2",
15
+ "stroke-linecap": "round",
16
+ "stroke-linejoin": "round"
17
+ };
18
+ var _hoisted_4 = { key: 1 };
19
+ var _hoisted_5 = { key: 2 };
20
+ var _hoisted_6 = ["href"];
21
+ var Breadcrumb_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
22
+ __name: "Breadcrumb",
23
+ props: {
24
+ items: {},
25
+ separator: { default: "/" }
26
+ },
27
+ setup(__props) {
28
+ return (_ctx, _cache) => {
29
+ return openBlock(), createElementBlock("nav", _hoisted_1, [createElementVNode("ol", _hoisted_2, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.items, (item, index) => {
30
+ return openBlock(), createElementBlock(Fragment, { key: index }, [index > 0 ? (openBlock(), createElementBlock("li", {
31
+ key: 0,
32
+ "aria-hidden": "true",
33
+ class: normalizeClass(unref(cn)("text-muted-foreground/50"))
34
+ }, [__props.separator === "chevron" ? (openBlock(), createElementBlock("svg", _hoisted_3, [..._cache[0] || (_cache[0] = [createElementVNode("path", { d: "m9 18 6-6-6-6" }, null, -1)])])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [createTextVNode(toDisplayString(__props.separator), 1)], 64))], 2)) : createCommentVNode("", true), index === __props.items.length - 1 ? (openBlock(), createElementBlock("li", _hoisted_4, [createElementVNode("span", {
35
+ "aria-current": "page",
36
+ class: normalizeClass(unref(cn)("text-foreground font-medium"))
37
+ }, toDisplayString(item.label), 3)])) : (openBlock(), createElementBlock("li", _hoisted_5, [createElementVNode("a", {
38
+ href: item.href,
39
+ class: normalizeClass(unref(cn)("text-muted-foreground hover:text-foreground transition-colors duration-fast"))
40
+ }, toDisplayString(item.label), 11, _hoisted_6)]))], 64);
41
+ }), 128))])]);
42
+ };
43
+ }
44
+ });
45
+ //#endregion
46
+ export { Breadcrumb_vue_vue_type_script_setup_true_lang_default as default };
47
+
48
+ //# sourceMappingURL=Breadcrumb.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Breadcrumb.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/primitives/Breadcrumb/Breadcrumb.vue"],"sourcesContent":["<script lang=\"ts\">\n/** The visible label text and optional link target for one step in the trail. */\nexport interface BreadcrumbItem {\n /** The visible label text. */\n label: string;\n /** The link target. Omit for the current (last) item. */\n href?: string;\n}\n\n/** Visual separators between breadcrumb steps. `chevron` renders an inline SVG. */\nexport type BreadcrumbSeparator = \"/\" | \"\\\\\" | \">\" | \"→\" | \"chevron\";\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"../../lib/cn\";\n\n/**\n * Breadcrumb — a navigation trail showing the page's position in the site\n * hierarchy. The last item is always the current page (no href,\n * `aria-current=\"page\"`); items with an href render as links. Built without\n * Reka UI, which has no Breadcrumb primitive.\n */\nwithDefaults(\n defineProps<{\n /** The breadcrumb trail, last item is the current page. */\n items: BreadcrumbItem[];\n /** Visual separator between items. `chevron` renders an inline SVG arrow. */\n separator?: BreadcrumbSeparator;\n }>(),\n { separator: \"/\" },\n);\n</script>\n\n<template>\n <nav aria-label=\"Breadcrumb\">\n <ol class=\"flex items-center gap-1.5 text-sm\">\n <template v-for=\"(item, index) in items\" :key=\"index\">\n <li v-if=\"index > 0\" aria-hidden=\"true\" :class=\"cn('text-muted-foreground/50')\">\n <svg\n v-if=\"separator === 'chevron'\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n >\n <path d=\"m9 18 6-6-6-6\" />\n </svg>\n <template v-else>{{ separator }}</template>\n </li>\n\n <!-- The last item is always the current page, regardless of href -->\n <li v-if=\"index === items.length - 1\">\n <span aria-current=\"page\" :class=\"cn('text-foreground font-medium')\">\n {{ item.label }}\n </span>\n </li>\n <li v-else>\n <a\n :href=\"item.href\"\n :class=\"\n cn('text-muted-foreground hover:text-foreground transition-colors duration-fast')\n \"\n >\n {{ item.label }}\n </a>\n </li>\n </template>\n </ol>\n </nav>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCE,OAAA,UAAA,GAAA,mBAuCM,OAvCN,YAuCM,CAtCJ,mBAqCK,MArCL,YAqCK,EApCH,UAAA,IAAA,GAAA,mBAmCW,UAAA,MAAA,WAnCuB,QAAA,QAAhB,MAAM,UAAK;IAAkB,OAAA,UAAA,GAAA,mBAAA,UAAA,EAAA,KAAA,MAAK,GAAA,CACxC,QAAK,KAAf,UAAA,GAAA,mBAgBK,MAAA;;KAhBgB,eAAY;KAAQ,OAAK,eAAE,MAAA,EAAA,CAAE,CAAA,0BAAA,CAAA;IAExC,GAAA,CAAA,QAAA,cAAS,aADjB,UAAA,GAAA,mBAaM,OAbN,YAaM,CAAA,GAAA,OAAA,OAAA,OAAA,KAAA,CADJ,mBAA0B,QAAA,EAApB,GAAE,gBAAe,GAAA,MAAA,EAAA,CAAA,EAAA,CAAA,MAEzB,UAAA,GAAA,mBAA2C,UAAA,EAAA,KAAA,EAAA,GAAA,CAAvB,gBAAA,gBAAA,QAAA,SAAS,GAAA,CAAA,CAAA,GAAA,EAAA,EAAA,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,GAIrB,UAAU,QAAA,MAAM,SAAM,KAAhC,UAAA,GAAA,mBAIK,MAAA,YAAA,CAHH,mBAEO,QAAA;KAFD,gBAAa;KAAQ,OAAK,eAAE,MAAA,EAAA,CAAE,CAAA,6BAAA,CAAA;IAC/B,GAAA,gBAAA,KAAK,KAAK,GAAA,CAAA,CAAA,CAAA,MAGjB,UAAA,GAAA,mBASK,MAAA,YAAA,CARH,mBAOI,KAAA;KAND,MAAM,KAAK;KACX,OAAK,eAAiB,MAAA,EAAA,CAAE,CAAA,6EAAA,CAAA;IAItB,GAAA,gBAAA,KAAK,KAAK,GAAA,IAAA,UAAA,CAAA,CAAA,EAAA,GAAA,EAAA"}
@@ -1,7 +1,7 @@
1
- import Button_vue_vue_type_script_setup_true_lang_default, { buttonVariants } from "./Button.vue_vue_type_script_setup_true_lang.js";
1
+ import Button_vue_vue_type_script_setup_true_lang_default, { buttonVariantClasses, buttonVariants } from "./Button.vue_vue_type_script_setup_true_lang.js";
2
2
  //#region src/primitives/Button/Button.vue
3
3
  var Button_default = Button_vue_vue_type_script_setup_true_lang_default;
4
4
  //#endregion
5
- export { buttonVariants, Button_default as default };
5
+ export { buttonVariantClasses, buttonVariants, Button_default as default };
6
6
 
7
7
  //# sourceMappingURL=Button.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Button.js","names":[],"sources":["../../../src/primitives/Button/Button.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { cva } from \"class-variance-authority\";\n\n/**\n * The six weights, and the choice between them is about emphasis rather than\n * colour: `primary` is the one action a screen is asking for, `destructive` is\n * the one it is warning about, and the four between them step down.\n */\nexport type ButtonVariant =\n \"primary\" | \"secondary\" | \"subtle\" | \"outline\" | \"ghost\" | \"destructive\";\n\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\" | \"icon\" | \"icon-sm\";\n\n/**\n * Button — the workhorse, and the primitive that encodes Loom's press\n * language:\n *\n * • hover lifts by fill, not by shadow\n * • active presses down (scale 0.97) — physical, causal feedback\n * • focus blooms the warp ring\n * • loading plays a kinetic swap under a shimmer sweep: the label rolls up\n * and out, a progress arc springs in, the loading text rises last — and\n * both layers share one grid cell, so the width never jumps mid-film\n *\n * The 50% dim belongs to a *disabled* button only. It is applied off the\n * `disabled` prop rather than off the DOM disabled state, because a loading\n * button is also DOM-disabled yet has to read as \"working\", not\n * \"unavailable\".\n */\nexport const buttonVariants = cva(\n [\n \"relative inline-flex items-center justify-center gap-2 whitespace-nowrap select-none\",\n \"rounded-md text-sm font-medium\",\n \"[transition:transform_var(--duration-fast)_var(--ease-spring),background-color_var(--duration-fast)_var(--ease-out),color_var(--duration-fast)_var(--ease-out),box-shadow_var(--duration-fast)_var(--ease-out)]\",\n \"active:scale-[0.97] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\",\n \"disabled:pointer-events-none\",\n ],\n {\n // `satisfies` is what keeps the two halves honest. The union above is the\n // name a consumer imports and the documentation prints; the map below is\n // the classes. Adding a member to one and not the other stops compiling,\n // so neither can be the stale copy of the other.\n variants: {\n variant: {\n primary: \"bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/70\",\n subtle: \"bg-transparent text-foreground hover:bg-subtle\",\n outline: \"border border-input bg-transparent text-foreground hover:bg-subtle\",\n ghost: \"bg-transparent text-muted-foreground hover:bg-subtle hover:text-foreground\",\n destructive: \"bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-sm\",\n } satisfies Record<ButtonVariant, string>,\n size: {\n sm: \"h-8 px-3 text-xs\",\n md: \"h-9 px-4\",\n lg: \"h-11 px-6 text-base\",\n icon: \"h-9 w-9 p-0\",\n // A square icon button for dense rows, matching `sm`'s height so a row\n // action lines up with that row's text controls. Still 32px — well\n // over the 24px minimum target size (WCAG 2.2 SC 2.5.8) — so density\n // here costs no reachability. It exists because consumers were\n // reaching for `size=\"icon\"` and then hand-overriding `class=\"h-8 w-8\"`,\n // which silently re-litigates the target-size question at every call\n // site.\n \"icon-sm\": \"h-8 w-8 p-0\",\n } satisfies Record<ButtonSize, string>,\n },\n defaultVariants: { variant: \"primary\", size: \"md\" },\n },\n);\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"../../lib/cn\";\n\nwithDefaults(\n defineProps<{\n /** How much emphasis the action carries. */\n variant?: ButtonVariant;\n /** Control height. `icon` and `icon-sm` are square, for a glyph alone. */\n size?: ButtonSize;\n /** Locks the button and plays the kinetic swap (label → arc + loadingText). */\n loading?: boolean;\n /** Text shown beside the progress arc while loading, e.g. \"Saving…\". */\n loadingText?: string;\n /** Unavailable rather than busy — dims to 50% and blocks pointer events. */\n disabled?: boolean;\n /** The native button type. Defaults to `button`, never an accidental submit. */\n type?: \"button\" | \"submit\" | \"reset\";\n }>(),\n { variant: \"primary\", size: \"md\", loading: false, disabled: false, type: \"button\" },\n);\n</script>\n\n<template>\n <button\n :type=\"type\"\n :disabled=\"disabled || loading\"\n :data-loading=\"loading || undefined\"\n :aria-busy=\"loading || undefined\"\n :class=\"cn(buttonVariants({ variant, size }), 'group', disabled && 'opacity-50')\"\n >\n <!-- The shimmer sweep, while loading. -->\n <span\n v-if=\"loading\"\n aria-hidden=\"true\"\n class=\"pointer-events-none absolute inset-0 rounded-md bg-[linear-gradient(110deg,transparent_35%,--alpha(var(--color-primary)/25%)_50%,transparent_65%)] bg-[length:220%_100%] animate-shimmer\"\n />\n <!-- The kinetic swap. Both layers live in the same grid cell, so the\n button keeps the width of the wider one and nothing jumps mid-swap.\n Only the layer for the current state is exposed to assistive\n technology; the other is aria-hidden, because opacity alone does not\n hide anything from a screen reader. -->\n <span class=\"inline-grid place-items-center\">\n <!-- Beat 1 — the label rolls up and out. -->\n <span\n :aria-hidden=\"loading || undefined\"\n class=\"[grid-area:1/1] inline-flex items-center gap-2 transition-[opacity,transform] duration-fast ease-out group-data-[loading]:-translate-y-1 group-data-[loading]:opacity-0\"\n >\n <slot />\n </span>\n <span\n :aria-hidden=\"!loading || undefined\"\n class=\"pointer-events-none [grid-area:1/1] inline-flex items-center gap-2\"\n >\n <!-- Beat 2 — the progress arc springs in from below. The spinning svg\n sits inside a wrapper because `animate-spin` owns `transform`: the\n entry scale and translate have to live on a separate element, or\n the spin keyframe would overwrite them. It is the same arc the\n standalone Spinner draws, inlined and aria-hidden — Spinner's\n role=\"status\" contract is wrong inside an aria-busy button, where\n it would announce the state twice. -->\n <span\n class=\"transition-[opacity,transform] duration-fast ease-spring opacity-0 scale-50 translate-y-1 group-data-[loading]:translate-y-0 group-data-[loading]:scale-100 group-data-[loading]:opacity-100\"\n >\n <svg class=\"h-4 w-4 animate-spin\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle class=\"stroke-current opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke-width=\"4\" />\n <path\n class=\"fill-current opacity-75\"\n d=\"M4 12a8 8 0 0 1 8-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n </span>\n <!-- Beat 3 — the loading text rises last. The stagger delay applies on\n entry only (exit keeps delay 0, so the film cuts out clean), and\n it is cancelled under reduced motion so the instant swap is not\n lagged by a delay nobody asked for. -->\n <span\n v-if=\"loadingText\"\n class=\"transition-[opacity,transform] duration-100 ease-out opacity-0 translate-y-1 group-data-[loading]:translate-y-0 group-data-[loading]:opacity-100 group-data-[loading]:delay-75 motion-reduce:group-data-[loading]:delay-0\"\n >\n {{ loadingText }}\n </span>\n </span>\n </span>\n </button>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Button.js","names":[],"sources":["../../../src/primitives/Button/Button.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { cva } from \"class-variance-authority\";\n\n/**\n * The six weights, and the choice between them is about emphasis rather than\n * colour: `primary` is the one action a screen is asking for, `destructive` is\n * the one it is warning about, and the four between them step down.\n */\nexport type ButtonVariant =\n \"primary\" | \"secondary\" | \"subtle\" | \"outline\" | \"ghost\" | \"destructive\";\n\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\" | \"icon\" | \"icon-sm\";\n\n/**\n * One row per rest-state variant, naming the fill and the label token the\n * variant paints. Kept separate from the `cva` call because it is also the\n * contract `Button.contrast.test.ts` reads: that file derives every variant's\n * pairing from here, so a variant added to the map is measured on arrival\n * rather than when someone remembers to add a row to a test. The two halves\n * — this map and the `cva` call consuming it — cannot drift apart, because\n * `cva` is handed this very object.\n *\n * `satisfies` is what keeps this map and the union honest. The union above is\n * the name a consumer imports and the documentation prints; the map below is\n * the classes. Adding a member to one and not the other stops compiling, so\n * neither can be the stale copy of the other.\n */\nexport const buttonVariantClasses = {\n primary: \"bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/70\",\n subtle: \"bg-transparent text-foreground hover:bg-subtle\",\n outline: \"border border-input bg-transparent text-foreground hover:bg-subtle\",\n ghost: \"bg-transparent text-muted-foreground hover:bg-subtle hover:text-foreground\",\n destructive: \"bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-sm\",\n} satisfies Record<ButtonVariant, string>;\n\n/**\n * Button — the workhorse, and the primitive that encodes Loom's press\n * language:\n *\n * • hover lifts by fill, not by shadow\n * • active presses down (scale 0.97) — physical, causal feedback\n * • focus blooms the primary ring\n * • loading plays a kinetic swap under a shimmer sweep: the label rolls up\n * and out, a progress arc springs in, the loading text rises last — and\n * both layers share one grid cell, so the width never jumps mid-film\n *\n * Unavailable is painted in colours rather than dimmed, and it is keyed off the\n * `disabled` prop rather than off the DOM disabled state — a loading button is\n * also DOM-disabled yet has to read as \"working\", not \"unavailable\". See the\n * drained treatment on the root element for the measurements that removed the\n * dim.\n */\nexport const buttonVariants = cva(\n [\n \"relative inline-flex items-center justify-center gap-2 whitespace-nowrap select-none\",\n \"rounded-md text-sm font-medium\",\n \"[transition:transform_var(--duration-fast)_var(--ease-spring),background-color_var(--duration-fast)_var(--ease-out),color_var(--duration-fast)_var(--ease-out),box-shadow_var(--duration-fast)_var(--ease-out)]\",\n \"active:scale-press focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\",\n \"disabled:pointer-events-none\",\n ],\n {\n variants: {\n variant: buttonVariantClasses,\n size: {\n sm: \"h-8 px-3 text-xs\",\n md: \"h-9 px-4\",\n lg: \"h-11 px-6 text-base\",\n icon: \"h-9 w-9 p-0\",\n // A square icon button for dense rows, matching `sm`'s height so a row\n // action lines up with that row's text controls. Still 32px — well\n // over the 24px minimum target size (WCAG 2.2 SC 2.5.8) — so density\n // here costs no reachability. It exists because consumers were\n // reaching for `size=\"icon\"` and then hand-overriding `class=\"h-8 w-8\"`,\n // which silently re-litigates the target-size question at every call\n // site.\n \"icon-sm\": \"h-8 w-8 p-0\",\n } satisfies Record<ButtonSize, string>,\n },\n defaultVariants: { variant: \"primary\", size: \"md\" },\n },\n);\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"../../lib/cn\";\n\nwithDefaults(\n defineProps<{\n /** How much emphasis the action carries. */\n variant?: ButtonVariant;\n /** Control height. `icon` and `icon-sm` are square, for a glyph alone. */\n size?: ButtonSize;\n /** Locks the button and plays the kinetic swap (label → arc + loadingText). */\n loading?: boolean;\n /** Text shown beside the progress arc while loading, e.g. \"Saving…\". */\n loadingText?: string;\n /** Unavailable rather than busy — drains the button to the neutral well and blocks pointer events. */\n disabled?: boolean;\n /** The native button type. Defaults to `button`, never an accidental submit. */\n type?: \"button\" | \"submit\" | \"reset\";\n }>(),\n { variant: \"primary\", size: \"md\", loading: false, disabled: false, type: \"button\" },\n);\n</script>\n\n<template>\n <button\n :type=\"type\"\n :disabled=\"disabled || loading\"\n :data-loading=\"loading || undefined\"\n :aria-busy=\"loading || undefined\"\n :class=\"\n cn(\n buttonVariants({ variant, size }),\n 'group',\n // Drained, not dimmed. `opacity-50` here was the library's most visible\n // instance of the mistake, because a button is nothing but a label on a\n // fill and the dim took both together: measured on the built site, a\n // disabled `primary` label came out at 1.62:1 against its own faded fill\n // and a disabled `outline` at 3.14:1 on the page ground. Neither is\n // reachable by recolouring the label, since the fade multiplied whatever\n // colour it was given.\n //\n // One neutral treatment for all six variants rather than six drained\n // pairs: the fill is what carries a variant's emphasis, and an\n // unavailable button has no emphasis to carry. It is the same well Chip\n // and Stepper drain to, so an unavailable control looks the same\n // wherever it appears. Every variant still changes visibly on the way\n // in — the two filled ones give up their hue, the three transparent ones\n // gain a fill — and the native `disabled` attribute carries the fact to\n // assistive tech, so none of it rests on colour alone.\n //\n // `border-border` and not the strong weight, which is what `outline`\n // used to take here. `theme.css` reserves the strong hairline for a\n // block that must *assert* its edge, and an unavailable control is the\n // one thing that must not; slackening from `input` to the lighter\n // `border` is also the same step every other unavailable control in the\n // library now makes, so a disabled Button beside a disabled TextField\n // wears the same rim rather than a heavier one.\n disabled && 'border-border bg-muted text-muted-foreground shadow-none',\n )\n \"\n >\n <!-- The shimmer sweep, while loading. -->\n <span\n v-if=\"loading\"\n aria-hidden=\"true\"\n class=\"pointer-events-none absolute inset-0 rounded-md bg-[linear-gradient(110deg,transparent_35%,--alpha(var(--color-primary)/25%)_50%,transparent_65%)] bg-[length:220%_100%] animate-shimmer\"\n />\n <!-- The kinetic swap. Both layers live in the same grid cell, so the\n button keeps the width of the wider one and nothing jumps mid-swap.\n Only the layer for the current state is exposed to assistive\n technology; the other is aria-hidden, because opacity alone does not\n hide anything from a screen reader. -->\n <span class=\"inline-grid place-items-center\">\n <!-- Beat 1 — the label rolls up and out. -->\n <span\n :aria-hidden=\"loading || undefined\"\n class=\"[grid-area:1/1] inline-flex items-center gap-2 transition-[opacity,transform] duration-fast ease-out group-data-[loading]:-translate-y-1 group-data-[loading]:opacity-0\"\n >\n <slot />\n </span>\n <span\n :aria-hidden=\"!loading || undefined\"\n class=\"pointer-events-none [grid-area:1/1] inline-flex items-center gap-2\"\n >\n <!-- Beat 2 — the progress arc springs in from below. The spinning svg\n sits inside a wrapper because `animate-spin` owns `transform`: the\n entry scale and translate have to live on a separate element, or\n the spin keyframe would overwrite them. It is the same arc the\n standalone Spinner draws, inlined and aria-hidden — Spinner's\n role=\"status\" contract is wrong inside an aria-busy button, where\n it would announce the state twice. -->\n <span\n class=\"transition-[opacity,transform] duration-fast ease-spring opacity-0 scale-50 translate-y-1 group-data-[loading]:translate-y-0 group-data-[loading]:scale-100 group-data-[loading]:opacity-100\"\n >\n <svg class=\"h-4 w-4 animate-spin\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle class=\"stroke-current opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke-width=\"4\" />\n <path\n class=\"fill-current opacity-75\"\n d=\"M4 12a8 8 0 0 1 8-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n </span>\n <!-- Beat 3 — the loading text rises last. The stagger delay applies on\n entry only (exit keeps delay 0, so the film cuts out clean), and\n it is cancelled under reduced motion so the instant swap is not\n lagged by a delay nobody asked for. -->\n <span\n v-if=\"loadingText\"\n class=\"transition-[opacity,transform] duration-100 ease-out opacity-0 translate-y-1 group-data-[loading]:translate-y-0 group-data-[loading]:opacity-100 group-data-[loading]:delay-75 motion-reduce:group-data-[loading]:delay-0\"\n >\n {{ loadingText }}\n </span>\n </span>\n </span>\n </button>\n</template>\n"],"mappings":""}
@@ -5,21 +5,44 @@
5
5
  */
6
6
  export type ButtonVariant = "primary" | "secondary" | "subtle" | "outline" | "ghost" | "destructive";
7
7
  export type ButtonSize = "sm" | "md" | "lg" | "icon" | "icon-sm";
8
+ /**
9
+ * One row per rest-state variant, naming the fill and the label token the
10
+ * variant paints. Kept separate from the `cva` call because it is also the
11
+ * contract `Button.contrast.test.ts` reads: that file derives every variant's
12
+ * pairing from here, so a variant added to the map is measured on arrival
13
+ * rather than when someone remembers to add a row to a test. The two halves
14
+ * — this map and the `cva` call consuming it — cannot drift apart, because
15
+ * `cva` is handed this very object.
16
+ *
17
+ * `satisfies` is what keeps this map and the union honest. The union above is
18
+ * the name a consumer imports and the documentation prints; the map below is
19
+ * the classes. Adding a member to one and not the other stops compiling, so
20
+ * neither can be the stale copy of the other.
21
+ */
22
+ export declare const buttonVariantClasses: {
23
+ primary: string;
24
+ secondary: string;
25
+ subtle: string;
26
+ outline: string;
27
+ ghost: string;
28
+ destructive: string;
29
+ };
8
30
  /**
9
31
  * Button — the workhorse, and the primitive that encodes Loom's press
10
32
  * language:
11
33
  *
12
34
  * • hover lifts by fill, not by shadow
13
35
  * • active presses down (scale 0.97) — physical, causal feedback
14
- * • focus blooms the warp ring
36
+ * • focus blooms the primary ring
15
37
  * • loading plays a kinetic swap under a shimmer sweep: the label rolls up
16
38
  * and out, a progress arc springs in, the loading text rises last — and
17
39
  * both layers share one grid cell, so the width never jumps mid-film
18
40
  *
19
- * The 50% dim belongs to a *disabled* button only. It is applied off the
20
- * `disabled` prop rather than off the DOM disabled state, because a loading
21
- * button is also DOM-disabled yet has to read as "working", not
22
- * "unavailable".
41
+ * Unavailable is painted in colours rather than dimmed, and it is keyed off the
42
+ * `disabled` prop rather than off the DOM disabled state a loading button is
43
+ * also DOM-disabled yet has to read as "working", not "unavailable". See the
44
+ * drained treatment on the root element for the measurements that removed the
45
+ * dim.
23
46
  */
24
47
  export declare const buttonVariants: (props?: ({
25
48
  variant?: "outline" | "primary" | "destructive" | "secondary" | "subtle" | "ghost" | null | undefined;
@@ -36,7 +59,7 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
36
59
  loading?: boolean;
37
60
  /** Text shown beside the progress arc while loading, e.g. "Saving…". */
38
61
  loadingText?: string;
39
- /** Unavailable rather than busy — dims to 50% and blocks pointer events. */
62
+ /** Unavailable rather than busy — drains the button to the neutral well and blocks pointer events. */
40
63
  disabled?: boolean;
41
64
  /** The native button type. Defaults to `button`, never an accidental submit. */
42
65
  type?: "button" | "submit" | "reset";
@@ -49,16 +72,16 @@ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
49
72
  loading?: boolean;
50
73
  /** Text shown beside the progress arc while loading, e.g. "Saving…". */
51
74
  loadingText?: string;
52
- /** Unavailable rather than busy — dims to 50% and blocks pointer events. */
75
+ /** Unavailable rather than busy — drains the button to the neutral well and blocks pointer events. */
53
76
  disabled?: boolean;
54
77
  /** The native button type. Defaults to `button`, never an accidental submit. */
55
78
  type?: "button" | "submit" | "reset";
56
79
  }> & Readonly<{}>, {
57
80
  size: ButtonSize;
81
+ disabled: boolean;
58
82
  type: "button" | "submit" | "reset";
59
83
  variant: ButtonVariant;
60
84
  loading: boolean;
61
- disabled: boolean;
62
85
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
63
86
  default?: (props: {}) => any;
64
87
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"Button.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Button/Button.vue"],"names":[],"mappings":"AAoKA;;;;GAIG;AACH,MAAM,MAAM,aAAa,GACvB,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,aAAa,CAAC;AAE3E,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;AAEjE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,cAAc;;;8EAuC1B,CAAC;wBACmB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAEd,4CAA4C;cAClC,aAAa;IACvB,0EAA0E;WACnE,UAAU;IACjB,+EAA+E;cACrE,OAAO;IACjB,wEAAwE;kBAC1D,MAAM;IACpB,4EAA4E;eACjE,OAAO;IAClB,gFAAgF;WACzE,QAAQ,GAAG,QAAQ,GAAG,OAAO;;IAXpC,4CAA4C;cAClC,aAAa;IACvB,0EAA0E;WACnE,UAAU;IACjB,+EAA+E;cACrE,OAAO;IACjB,wEAAwE;kBAC1D,MAAM;IACpB,4EAA4E;eACjE,OAAO;IAClB,gFAAgF;WACzE,QAAQ,GAAG,QAAQ,GAAG,OAAO;;UAR7B,UAAU;UAQV,QAAQ,GAAG,QAAQ,GAAG,OAAO;aAV1B,aAAa;aAIb,OAAO;cAIN,OAAO;;cAmIR,CAAC,KAAK,IAAgB,KAAK,GAAG;EAUxC,CAAC;AAWL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
1
+ {"version":3,"file":"Button.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Button/Button.vue"],"names":[],"mappings":"AA+MA;;;;GAIG;AACH,MAAM,MAAM,aAAa,GACvB,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,aAAa,CAAC;AAE3E,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;AAEjE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,oBAAoB;;;;;;;CAOQ,CAAC;AAE1C;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,cAAc;;;8EA4B1B,CAAC;wBACmB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAEd,4CAA4C;cAClC,aAAa;IACvB,0EAA0E;WACnE,UAAU;IACjB,+EAA+E;cACrE,OAAO;IACjB,wEAAwE;kBAC1D,MAAM;IACpB,sGAAsG;eAC3F,OAAO;IAClB,gFAAgF;WACzE,QAAQ,GAAG,QAAQ,GAAG,OAAO;;IAXpC,4CAA4C;cAClC,aAAa;IACvB,0EAA0E;WACnE,UAAU;IACjB,+EAA+E;cACrE,OAAO;IACjB,wEAAwE;kBAC1D,MAAM;IACpB,sGAAsG;eAC3F,OAAO;IAClB,gFAAgF;WACzE,QAAQ,GAAG,QAAQ,GAAG,OAAO;;UAR7B,UAAU;cAMN,OAAO;UAEX,QAAQ,GAAG,QAAQ,GAAG,OAAO;aAV1B,aAAa;aAIb,OAAO;;cAqKP,CAAC,KAAK,IAAgB,KAAK,GAAG;EAUxC,CAAC;AAWL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -21,37 +21,53 @@ var _hoisted_6 = {
21
21
  class: "transition-[opacity,transform] duration-100 ease-out opacity-0 translate-y-1 group-data-[loading]:translate-y-0 group-data-[loading]:opacity-100 group-data-[loading]:delay-75 motion-reduce:group-data-[loading]:delay-0"
22
22
  };
23
23
  /**
24
+ * One row per rest-state variant, naming the fill and the label token the
25
+ * variant paints. Kept separate from the `cva` call because it is also the
26
+ * contract `Button.contrast.test.ts` reads: that file derives every variant's
27
+ * pairing from here, so a variant added to the map is measured on arrival
28
+ * rather than when someone remembers to add a row to a test. The two halves
29
+ * — this map and the `cva` call consuming it — cannot drift apart, because
30
+ * `cva` is handed this very object.
31
+ *
32
+ * `satisfies` is what keeps this map and the union honest. The union above is
33
+ * the name a consumer imports and the documentation prints; the map below is
34
+ * the classes. Adding a member to one and not the other stops compiling, so
35
+ * neither can be the stale copy of the other.
36
+ */
37
+ var buttonVariantClasses = {
38
+ primary: "bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm",
39
+ secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/70",
40
+ subtle: "bg-transparent text-foreground hover:bg-subtle",
41
+ outline: "border border-input bg-transparent text-foreground hover:bg-subtle",
42
+ ghost: "bg-transparent text-muted-foreground hover:bg-subtle hover:text-foreground",
43
+ destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-sm"
44
+ };
45
+ /**
24
46
  * Button — the workhorse, and the primitive that encodes Loom's press
25
47
  * language:
26
48
  *
27
49
  * • hover lifts by fill, not by shadow
28
50
  * • active presses down (scale 0.97) — physical, causal feedback
29
- * • focus blooms the warp ring
51
+ * • focus blooms the primary ring
30
52
  * • loading plays a kinetic swap under a shimmer sweep: the label rolls up
31
53
  * and out, a progress arc springs in, the loading text rises last — and
32
54
  * both layers share one grid cell, so the width never jumps mid-film
33
55
  *
34
- * The 50% dim belongs to a *disabled* button only. It is applied off the
35
- * `disabled` prop rather than off the DOM disabled state, because a loading
36
- * button is also DOM-disabled yet has to read as "working", not
37
- * "unavailable".
56
+ * Unavailable is painted in colours rather than dimmed, and it is keyed off the
57
+ * `disabled` prop rather than off the DOM disabled state a loading button is
58
+ * also DOM-disabled yet has to read as "working", not "unavailable". See the
59
+ * drained treatment on the root element for the measurements that removed the
60
+ * dim.
38
61
  */
39
62
  var buttonVariants = cva([
40
63
  "relative inline-flex items-center justify-center gap-2 whitespace-nowrap select-none",
41
64
  "rounded-md text-sm font-medium",
42
65
  "[transition:transform_var(--duration-fast)_var(--ease-spring),background-color_var(--duration-fast)_var(--ease-out),color_var(--duration-fast)_var(--ease-out),box-shadow_var(--duration-fast)_var(--ease-out)]",
43
- "active:scale-[0.97] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo",
66
+ "active:scale-press focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo",
44
67
  "disabled:pointer-events-none"
45
68
  ], {
46
69
  variants: {
47
- variant: {
48
- primary: "bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm",
49
- secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/70",
50
- subtle: "bg-transparent text-foreground hover:bg-subtle",
51
- outline: "border border-input bg-transparent text-foreground hover:bg-subtle",
52
- ghost: "bg-transparent text-muted-foreground hover:bg-subtle hover:text-foreground",
53
- destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-sm"
54
- },
70
+ variant: buttonVariantClasses,
55
71
  size: {
56
72
  sm: "h-8 px-3 text-xs",
57
73
  md: "h-9 px-4",
@@ -91,7 +107,7 @@ var Button_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCom
91
107
  class: normalizeClass(unref(cn)(unref(buttonVariants)({
92
108
  variant: __props.variant,
93
109
  size: __props.size
94
- }), "group", __props.disabled && "opacity-50"))
110
+ }), "group", __props.disabled && "border-border bg-muted text-muted-foreground shadow-none"))
95
111
  }, [__props.loading ? (openBlock(), createElementBlock("span", _hoisted_2)) : createCommentVNode("", true), createElementVNode("span", _hoisted_3, [createElementVNode("span", {
96
112
  "aria-hidden": __props.loading || void 0,
97
113
  class: "[grid-area:1/1] inline-flex items-center gap-2 transition-[opacity,transform] duration-fast ease-out group-data-[loading]:-translate-y-1 group-data-[loading]:opacity-0"
@@ -117,6 +133,6 @@ var Button_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCom
117
133
  }
118
134
  });
119
135
  //#endregion
120
- export { buttonVariants, Button_vue_vue_type_script_setup_true_lang_default as default };
136
+ export { buttonVariantClasses, buttonVariants, Button_vue_vue_type_script_setup_true_lang_default as default };
121
137
 
122
138
  //# sourceMappingURL=Button.vue_vue_type_script_setup_true_lang.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Button.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/primitives/Button/Button.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { cva } from \"class-variance-authority\";\n\n/**\n * The six weights, and the choice between them is about emphasis rather than\n * colour: `primary` is the one action a screen is asking for, `destructive` is\n * the one it is warning about, and the four between them step down.\n */\nexport type ButtonVariant =\n \"primary\" | \"secondary\" | \"subtle\" | \"outline\" | \"ghost\" | \"destructive\";\n\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\" | \"icon\" | \"icon-sm\";\n\n/**\n * Button — the workhorse, and the primitive that encodes Loom's press\n * language:\n *\n * • hover lifts by fill, not by shadow\n * • active presses down (scale 0.97) — physical, causal feedback\n * • focus blooms the warp ring\n * • loading plays a kinetic swap under a shimmer sweep: the label rolls up\n * and out, a progress arc springs in, the loading text rises last — and\n * both layers share one grid cell, so the width never jumps mid-film\n *\n * The 50% dim belongs to a *disabled* button only. It is applied off the\n * `disabled` prop rather than off the DOM disabled state, because a loading\n * button is also DOM-disabled yet has to read as \"working\", not\n * \"unavailable\".\n */\nexport const buttonVariants = cva(\n [\n \"relative inline-flex items-center justify-center gap-2 whitespace-nowrap select-none\",\n \"rounded-md text-sm font-medium\",\n \"[transition:transform_var(--duration-fast)_var(--ease-spring),background-color_var(--duration-fast)_var(--ease-out),color_var(--duration-fast)_var(--ease-out),box-shadow_var(--duration-fast)_var(--ease-out)]\",\n \"active:scale-[0.97] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\",\n \"disabled:pointer-events-none\",\n ],\n {\n // `satisfies` is what keeps the two halves honest. The union above is the\n // name a consumer imports and the documentation prints; the map below is\n // the classes. Adding a member to one and not the other stops compiling,\n // so neither can be the stale copy of the other.\n variants: {\n variant: {\n primary: \"bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/70\",\n subtle: \"bg-transparent text-foreground hover:bg-subtle\",\n outline: \"border border-input bg-transparent text-foreground hover:bg-subtle\",\n ghost: \"bg-transparent text-muted-foreground hover:bg-subtle hover:text-foreground\",\n destructive: \"bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-sm\",\n } satisfies Record<ButtonVariant, string>,\n size: {\n sm: \"h-8 px-3 text-xs\",\n md: \"h-9 px-4\",\n lg: \"h-11 px-6 text-base\",\n icon: \"h-9 w-9 p-0\",\n // A square icon button for dense rows, matching `sm`'s height so a row\n // action lines up with that row's text controls. Still 32px — well\n // over the 24px minimum target size (WCAG 2.2 SC 2.5.8) — so density\n // here costs no reachability. It exists because consumers were\n // reaching for `size=\"icon\"` and then hand-overriding `class=\"h-8 w-8\"`,\n // which silently re-litigates the target-size question at every call\n // site.\n \"icon-sm\": \"h-8 w-8 p-0\",\n } satisfies Record<ButtonSize, string>,\n },\n defaultVariants: { variant: \"primary\", size: \"md\" },\n },\n);\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"../../lib/cn\";\n\nwithDefaults(\n defineProps<{\n /** How much emphasis the action carries. */\n variant?: ButtonVariant;\n /** Control height. `icon` and `icon-sm` are square, for a glyph alone. */\n size?: ButtonSize;\n /** Locks the button and plays the kinetic swap (label → arc + loadingText). */\n loading?: boolean;\n /** Text shown beside the progress arc while loading, e.g. \"Saving…\". */\n loadingText?: string;\n /** Unavailable rather than busy — dims to 50% and blocks pointer events. */\n disabled?: boolean;\n /** The native button type. Defaults to `button`, never an accidental submit. */\n type?: \"button\" | \"submit\" | \"reset\";\n }>(),\n { variant: \"primary\", size: \"md\", loading: false, disabled: false, type: \"button\" },\n);\n</script>\n\n<template>\n <button\n :type=\"type\"\n :disabled=\"disabled || loading\"\n :data-loading=\"loading || undefined\"\n :aria-busy=\"loading || undefined\"\n :class=\"cn(buttonVariants({ variant, size }), 'group', disabled && 'opacity-50')\"\n >\n <!-- The shimmer sweep, while loading. -->\n <span\n v-if=\"loading\"\n aria-hidden=\"true\"\n class=\"pointer-events-none absolute inset-0 rounded-md bg-[linear-gradient(110deg,transparent_35%,--alpha(var(--color-primary)/25%)_50%,transparent_65%)] bg-[length:220%_100%] animate-shimmer\"\n />\n <!-- The kinetic swap. Both layers live in the same grid cell, so the\n button keeps the width of the wider one and nothing jumps mid-swap.\n Only the layer for the current state is exposed to assistive\n technology; the other is aria-hidden, because opacity alone does not\n hide anything from a screen reader. -->\n <span class=\"inline-grid place-items-center\">\n <!-- Beat 1 — the label rolls up and out. -->\n <span\n :aria-hidden=\"loading || undefined\"\n class=\"[grid-area:1/1] inline-flex items-center gap-2 transition-[opacity,transform] duration-fast ease-out group-data-[loading]:-translate-y-1 group-data-[loading]:opacity-0\"\n >\n <slot />\n </span>\n <span\n :aria-hidden=\"!loading || undefined\"\n class=\"pointer-events-none [grid-area:1/1] inline-flex items-center gap-2\"\n >\n <!-- Beat 2 — the progress arc springs in from below. The spinning svg\n sits inside a wrapper because `animate-spin` owns `transform`: the\n entry scale and translate have to live on a separate element, or\n the spin keyframe would overwrite them. It is the same arc the\n standalone Spinner draws, inlined and aria-hidden — Spinner's\n role=\"status\" contract is wrong inside an aria-busy button, where\n it would announce the state twice. -->\n <span\n class=\"transition-[opacity,transform] duration-fast ease-spring opacity-0 scale-50 translate-y-1 group-data-[loading]:translate-y-0 group-data-[loading]:scale-100 group-data-[loading]:opacity-100\"\n >\n <svg class=\"h-4 w-4 animate-spin\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle class=\"stroke-current opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke-width=\"4\" />\n <path\n class=\"fill-current opacity-75\"\n d=\"M4 12a8 8 0 0 1 8-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n </span>\n <!-- Beat 3 — the loading text rises last. The stagger delay applies on\n entry only (exit keeps delay 0, so the film cuts out clean), and\n it is cancelled under reduced motion so the instant swap is not\n lagged by a delay nobody asked for. -->\n <span\n v-if=\"loadingText\"\n class=\"transition-[opacity,transform] duration-100 ease-out opacity-0 translate-y-1 group-data-[loading]:translate-y-0 group-data-[loading]:opacity-100 group-data-[loading]:delay-75 motion-reduce:group-data-[loading]:delay-0\"\n >\n {{ loadingText }}\n </span>\n </span>\n </span>\n </button>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,IAAa,iBAAiB,IAC5B;CACE;CACA;CACA;CACA;CACA;AACF,GACA;CAKE,UAAU;EACR,SAAS;GACP,SAAS;GACT,WAAW;GACX,QAAQ;GACR,SAAS;GACT,OAAO;GACP,aAAa;EACf;EACA,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,MAAM;GAQN,WAAW;EACb;CACF;CACA,iBAAiB;EAAE,SAAS;EAAW,MAAM;CAAK;AACpD,CACF;;;;;;;;;;;;;;;;;;;GA0BE,OAAA,UAAA,GAAA,mBA4DS,UAAA;IA3DN,MAAM,QAAA;IACN,UAAU,QAAA,YAAY,QAAA;IACtB,gBAAc,QAAA,WAAW,KAAA;IACzB,aAAW,QAAA,WAAW,KAAA;IACtB,OAAK,eAAE,MAAA,EAAA,CAAE,CAAC,MAAA,cAAA,CAAc,CAAA;KAAA,SAAG,QAAA;KAAO,MAAE,QAAA;IAAI,CAAA,GAAA,SAAc,QAAA,YAAQ,YAAA,CAAA;GAIvD,GAAA,CAAA,QAAA,WADR,UAAA,GAAA,mBAIE,QAJF,UAIE,KAAA,mBAAA,IAAA,IAAA,GAMF,mBAyCO,QAzCP,YAyCO,CAvCL,mBAKO,QAAA;IAJJ,eAAa,QAAA,WAAW,KAAA;IACzB,OAAM;GAEN,GAAA,CAAA,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,GAAA,UAAA,GAEV,mBAgCO,QAAA;IA/BJ,eAAW,CAAG,QAAA,WAAW,KAAA;IAC1B,OAAM;GASN,GAAA,CAAA,OAAA,OAAA,OAAA,KAAA,mBAUO,QAAA,EATL,OAAM,+LAA8L,GAAA,CAEpM,mBAMM,OAAA;IAND,OAAM;IAAuB,SAAQ;IAAY,MAAK;IAAO,eAAY;GAC5E,GAAA,CAAA,mBAAoF,UAAA;IAA5E,OAAM;IAA4B,IAAG;IAAK,IAAG;IAAK,GAAE;IAAK,gBAAa;GAC9E,CAAA,GAAA,mBAGE,QAAA;IAFA,OAAM;IACN,GAAE;GASA,CAAA,CAAA,CAAA,CAAA,GAAA,EAAA,IAAA,QAAA,eADR,UAAA,GAAA,mBAKO,QALP,YAKO,gBADF,QAAA,WAAW,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,GAAA,UAAA,CAAA,CAAA,CAAA,GAAA,IAAA,UAAA"}
1
+ {"version":3,"file":"Button.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/primitives/Button/Button.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { cva } from \"class-variance-authority\";\n\n/**\n * The six weights, and the choice between them is about emphasis rather than\n * colour: `primary` is the one action a screen is asking for, `destructive` is\n * the one it is warning about, and the four between them step down.\n */\nexport type ButtonVariant =\n \"primary\" | \"secondary\" | \"subtle\" | \"outline\" | \"ghost\" | \"destructive\";\n\nexport type ButtonSize = \"sm\" | \"md\" | \"lg\" | \"icon\" | \"icon-sm\";\n\n/**\n * One row per rest-state variant, naming the fill and the label token the\n * variant paints. Kept separate from the `cva` call because it is also the\n * contract `Button.contrast.test.ts` reads: that file derives every variant's\n * pairing from here, so a variant added to the map is measured on arrival\n * rather than when someone remembers to add a row to a test. The two halves\n * — this map and the `cva` call consuming it — cannot drift apart, because\n * `cva` is handed this very object.\n *\n * `satisfies` is what keeps this map and the union honest. The union above is\n * the name a consumer imports and the documentation prints; the map below is\n * the classes. Adding a member to one and not the other stops compiling, so\n * neither can be the stale copy of the other.\n */\nexport const buttonVariantClasses = {\n primary: \"bg-primary text-primary-foreground hover:bg-primary/90 shadow-sm\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/70\",\n subtle: \"bg-transparent text-foreground hover:bg-subtle\",\n outline: \"border border-input bg-transparent text-foreground hover:bg-subtle\",\n ghost: \"bg-transparent text-muted-foreground hover:bg-subtle hover:text-foreground\",\n destructive: \"bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-sm\",\n} satisfies Record<ButtonVariant, string>;\n\n/**\n * Button — the workhorse, and the primitive that encodes Loom's press\n * language:\n *\n * • hover lifts by fill, not by shadow\n * • active presses down (scale 0.97) — physical, causal feedback\n * • focus blooms the primary ring\n * • loading plays a kinetic swap under a shimmer sweep: the label rolls up\n * and out, a progress arc springs in, the loading text rises last — and\n * both layers share one grid cell, so the width never jumps mid-film\n *\n * Unavailable is painted in colours rather than dimmed, and it is keyed off the\n * `disabled` prop rather than off the DOM disabled state — a loading button is\n * also DOM-disabled yet has to read as \"working\", not \"unavailable\". See the\n * drained treatment on the root element for the measurements that removed the\n * dim.\n */\nexport const buttonVariants = cva(\n [\n \"relative inline-flex items-center justify-center gap-2 whitespace-nowrap select-none\",\n \"rounded-md text-sm font-medium\",\n \"[transition:transform_var(--duration-fast)_var(--ease-spring),background-color_var(--duration-fast)_var(--ease-out),color_var(--duration-fast)_var(--ease-out),box-shadow_var(--duration-fast)_var(--ease-out)]\",\n \"active:scale-press focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\",\n \"disabled:pointer-events-none\",\n ],\n {\n variants: {\n variant: buttonVariantClasses,\n size: {\n sm: \"h-8 px-3 text-xs\",\n md: \"h-9 px-4\",\n lg: \"h-11 px-6 text-base\",\n icon: \"h-9 w-9 p-0\",\n // A square icon button for dense rows, matching `sm`'s height so a row\n // action lines up with that row's text controls. Still 32px — well\n // over the 24px minimum target size (WCAG 2.2 SC 2.5.8) — so density\n // here costs no reachability. It exists because consumers were\n // reaching for `size=\"icon\"` and then hand-overriding `class=\"h-8 w-8\"`,\n // which silently re-litigates the target-size question at every call\n // site.\n \"icon-sm\": \"h-8 w-8 p-0\",\n } satisfies Record<ButtonSize, string>,\n },\n defaultVariants: { variant: \"primary\", size: \"md\" },\n },\n);\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"../../lib/cn\";\n\nwithDefaults(\n defineProps<{\n /** How much emphasis the action carries. */\n variant?: ButtonVariant;\n /** Control height. `icon` and `icon-sm` are square, for a glyph alone. */\n size?: ButtonSize;\n /** Locks the button and plays the kinetic swap (label → arc + loadingText). */\n loading?: boolean;\n /** Text shown beside the progress arc while loading, e.g. \"Saving…\". */\n loadingText?: string;\n /** Unavailable rather than busy — drains the button to the neutral well and blocks pointer events. */\n disabled?: boolean;\n /** The native button type. Defaults to `button`, never an accidental submit. */\n type?: \"button\" | \"submit\" | \"reset\";\n }>(),\n { variant: \"primary\", size: \"md\", loading: false, disabled: false, type: \"button\" },\n);\n</script>\n\n<template>\n <button\n :type=\"type\"\n :disabled=\"disabled || loading\"\n :data-loading=\"loading || undefined\"\n :aria-busy=\"loading || undefined\"\n :class=\"\n cn(\n buttonVariants({ variant, size }),\n 'group',\n // Drained, not dimmed. `opacity-50` here was the library's most visible\n // instance of the mistake, because a button is nothing but a label on a\n // fill and the dim took both together: measured on the built site, a\n // disabled `primary` label came out at 1.62:1 against its own faded fill\n // and a disabled `outline` at 3.14:1 on the page ground. Neither is\n // reachable by recolouring the label, since the fade multiplied whatever\n // colour it was given.\n //\n // One neutral treatment for all six variants rather than six drained\n // pairs: the fill is what carries a variant's emphasis, and an\n // unavailable button has no emphasis to carry. It is the same well Chip\n // and Stepper drain to, so an unavailable control looks the same\n // wherever it appears. Every variant still changes visibly on the way\n // in — the two filled ones give up their hue, the three transparent ones\n // gain a fill — and the native `disabled` attribute carries the fact to\n // assistive tech, so none of it rests on colour alone.\n //\n // `border-border` and not the strong weight, which is what `outline`\n // used to take here. `theme.css` reserves the strong hairline for a\n // block that must *assert* its edge, and an unavailable control is the\n // one thing that must not; slackening from `input` to the lighter\n // `border` is also the same step every other unavailable control in the\n // library now makes, so a disabled Button beside a disabled TextField\n // wears the same rim rather than a heavier one.\n disabled && 'border-border bg-muted text-muted-foreground shadow-none',\n )\n \"\n >\n <!-- The shimmer sweep, while loading. -->\n <span\n v-if=\"loading\"\n aria-hidden=\"true\"\n class=\"pointer-events-none absolute inset-0 rounded-md bg-[linear-gradient(110deg,transparent_35%,--alpha(var(--color-primary)/25%)_50%,transparent_65%)] bg-[length:220%_100%] animate-shimmer\"\n />\n <!-- The kinetic swap. Both layers live in the same grid cell, so the\n button keeps the width of the wider one and nothing jumps mid-swap.\n Only the layer for the current state is exposed to assistive\n technology; the other is aria-hidden, because opacity alone does not\n hide anything from a screen reader. -->\n <span class=\"inline-grid place-items-center\">\n <!-- Beat 1 — the label rolls up and out. -->\n <span\n :aria-hidden=\"loading || undefined\"\n class=\"[grid-area:1/1] inline-flex items-center gap-2 transition-[opacity,transform] duration-fast ease-out group-data-[loading]:-translate-y-1 group-data-[loading]:opacity-0\"\n >\n <slot />\n </span>\n <span\n :aria-hidden=\"!loading || undefined\"\n class=\"pointer-events-none [grid-area:1/1] inline-flex items-center gap-2\"\n >\n <!-- Beat 2 — the progress arc springs in from below. The spinning svg\n sits inside a wrapper because `animate-spin` owns `transform`: the\n entry scale and translate have to live on a separate element, or\n the spin keyframe would overwrite them. It is the same arc the\n standalone Spinner draws, inlined and aria-hidden — Spinner's\n role=\"status\" contract is wrong inside an aria-busy button, where\n it would announce the state twice. -->\n <span\n class=\"transition-[opacity,transform] duration-fast ease-spring opacity-0 scale-50 translate-y-1 group-data-[loading]:translate-y-0 group-data-[loading]:scale-100 group-data-[loading]:opacity-100\"\n >\n <svg class=\"h-4 w-4 animate-spin\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\">\n <circle class=\"stroke-current opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke-width=\"4\" />\n <path\n class=\"fill-current opacity-75\"\n d=\"M4 12a8 8 0 0 1 8-8V0C5.373 0 0 5.373 0 12h4z\"\n />\n </svg>\n </span>\n <!-- Beat 3 — the loading text rises last. The stagger delay applies on\n entry only (exit keeps delay 0, so the film cuts out clean), and\n it is cancelled under reduced motion so the instant swap is not\n lagged by a delay nobody asked for. -->\n <span\n v-if=\"loadingText\"\n class=\"transition-[opacity,transform] duration-100 ease-out opacity-0 translate-y-1 group-data-[loading]:translate-y-0 group-data-[loading]:opacity-100 group-data-[loading]:delay-75 motion-reduce:group-data-[loading]:delay-0\"\n >\n {{ loadingText }}\n </span>\n </span>\n </span>\n </button>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,IAAa,uBAAuB;CAClC,SAAS;CACT,WAAW;CACX,QAAQ;CACR,SAAS;CACT,OAAO;CACP,aAAa;AACf;;;;;;;;;;;;;;;;;;AAmBA,IAAa,iBAAiB,IAC5B;CACE;CACA;CACA;CACA;CACA;AACF,GACA;CACE,UAAU;EACR,SAAS;EACT,MAAM;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,MAAM;GAQN,WAAW;EACb;CACF;CACA,iBAAiB;EAAE,SAAS;EAAW,MAAM;CAAK;AACpD,CACF;;;;;;;;;;;;;;;;;;;GA0BE,OAAA,UAAA,GAAA,mBA0FS,UAAA;IAzFN,MAAM,QAAA;IACN,UAAU,QAAA,YAAY,QAAA;IACtB,gBAAc,QAAA,WAAW,KAAA;IACzB,aAAW,QAAA,WAAW,KAAA;IACtB,OAAK,eAAS,MAAA,EAAA,CAAE,CAAU,MAAA,cAAA,CAAc,CAAA;KAAA,SAAG,QAAA;KAAO,MAAE,QAAA;IAAI,CAAA,GAAA,SAAuqD,QAAA,YAAQ,0DAAA,CAAA;GAkChuD,GAAA,CAAA,QAAA,WADR,UAAA,GAAA,mBAIE,QAJF,UAIE,KAAA,mBAAA,IAAA,IAAA,GAMF,mBAyCO,QAzCP,YAyCO,CAvCL,mBAKO,QAAA;IAJJ,eAAa,QAAA,WAAW,KAAA;IACzB,OAAM;GAEN,GAAA,CAAA,WAAQ,KAAA,QAAA,SAAA,CAAA,GAAA,GAAA,UAAA,GAEV,mBAgCO,QAAA;IA/BJ,eAAW,CAAG,QAAA,WAAW,KAAA;IAC1B,OAAM;GASN,GAAA,CAAA,OAAA,OAAA,OAAA,KAAA,mBAUO,QAAA,EATL,OAAM,+LAA8L,GAAA,CAEpM,mBAMM,OAAA;IAND,OAAM;IAAuB,SAAQ;IAAY,MAAK;IAAO,eAAY;GAC5E,GAAA,CAAA,mBAAoF,UAAA;IAA5E,OAAM;IAA4B,IAAG;IAAK,IAAG;IAAK,GAAE;IAAK,gBAAa;GAC9E,CAAA,GAAA,mBAGE,QAAA;IAFA,OAAM;IACN,GAAE;GASA,CAAA,CAAA,CAAA,CAAA,GAAA,EAAA,IAAA,QAAA,eADR,UAAA,GAAA,mBAKO,QALP,YAKO,gBADF,QAAA,WAAW,GAAA,CAAA,KAAA,mBAAA,IAAA,IAAA,CAAA,GAAA,GAAA,UAAA,CAAA,CAAA,CAAA,GAAA,IAAA,UAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.js","names":[],"sources":["../../../src/primitives/Checkbox/Checkbox.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { CheckboxIndicator, CheckboxRoot } from \"reka-ui\";\nimport { Check, Minus } from \"@lucide/vue\";\nimport { cn } from \"../../lib/cn\";\nimport { optional } from \"../../lib/props\";\n\n/**\n * Checkbox — a single boolean choice inside a form (as opposed to Switch,\n * which flips a setting immediately, no form/\"Save\" involved). Built on Reka\n * UI's Checkbox (role=\"checkbox\" + aria-checked, Space toggles); also\n * supports the third \"indeterminate\" state for a parent checkbox over a\n * partially-selected group — shown as a dash instead of a check.\n *\n * An inline `label` wraps the control in a real `<label>` (a11y name comes\n * free); omit it and pass `ariaLabel`/`ariaLabelledby` instead when the\n * visible label lives elsewhere (e.g. a table header cell).\n */\nconst props = withDefaults(\n defineProps<{\n /** `true`/`false` for a plain toggle, `\"indeterminate\"` for a parent over a partially-selected group. Omit to let the box own its own state. */\n modelValue?: boolean | \"indeterminate\" | undefined;\n /** Blocks both click and keyboard input, and dims the box. */\n disabled?: boolean;\n /** Visible text, rendered inside the wrapping `<label>`. Omit and use `ariaLabel`/`ariaLabelledby` when the label lives elsewhere. */\n label?: string;\n /** Accessible name when no visible `label` is rendered by this component. */\n ariaLabel?: string;\n /** Accessible name sourced from another element's id, when no visible `label` is rendered by this component. */\n ariaLabelledby?: string;\n }>(),\n {\n // Not `false`. A concrete value here would mean \"the host owns this\", and\n // a host that passes nothing would get a box that emits its update event\n // and never moves — a control that looks broken rather than one that\n // reports an error. `undefined` is what leaves it self-managing, and the\n // explicit default is what survives Vue's absent-Boolean-casts-to-false\n // rule.\n modelValue: undefined,\n disabled: false,\n },\n);\n\ndefineEmits<{ \"update:modelValue\": [value: boolean | \"indeterminate\"] }>();\n\nconst boxClass = cn(\n \"flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border border-input bg-background\",\n // Transform (the press squish) rides --ease-spring for a restrained release,\n // while fill/border stay on the instant --ease-out — the \"springy transform,\n // steady color\" split (boxStyle below), same language as Button/Switch.\n \"active:scale-90\",\n // Checked = a human decision (Loom law): the box fills flat warp.\n \"data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground\",\n \"data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground\",\n // Focus draws the weave tight: the brand ring blooms.\n \"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\",\n \"disabled:cursor-not-allowed\",\n);\n\nconst boxStyle =\n \"transition: transform var(--duration-fast) var(--ease-spring), background-color var(--duration-instant) var(--ease-out), border-color var(--duration-instant) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);\";\n</script>\n\n<template>\n <!-- CheckboxRoot is a labelable <button role=\"checkbox\">, so wrapping it in\n <label> names it exactly like a native control; the rule's nesting/id\n heuristic just doesn't recognize reka-ui's custom element as a\n \"control\". -->\n <!-- eslint-disable-next-line vuejs-accessibility/label-has-for -->\n <label\n v-if=\"label\"\n :class=\"\n cn(\n 'inline-flex items-center gap-2 text-sm text-foreground',\n // Disabled text stays readable (AA on the light ground) — only the box dims.\n props.disabled ? 'cursor-not-allowed text-muted-foreground' : 'cursor-pointer',\n )\n \"\n >\n <CheckboxRoot\n v-bind=\"optional({ modelValue })\"\n :disabled=\"disabled\"\n :class=\"cn(boxClass, 'disabled:opacity-50')\"\n :style=\"boxStyle\"\n @update:model-value=\"$emit('update:modelValue', $event)\"\n >\n <template #default=\"{ state }\">\n <!-- The tick pops in with scale-in — a small causal \"it's checked now\".\n stroke-width 2.5 is the ≤12px iconography rule, not a local taste:\n the inherited 1.5 renders 0.75 device px at 12px and reads washed\n out inside the filled box. Both branches carry it identically. -->\n <CheckboxIndicator class=\"flex animate-scale-in items-center justify-center text-current\">\n <Minus v-if=\"state === 'indeterminate'\" class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n <Check v-else class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n </CheckboxIndicator>\n </template>\n </CheckboxRoot>\n {{ label }}\n </label>\n <!-- The control always dims itself when disabled; label text stays\n readable muted — same stance in both branches. -->\n <CheckboxRoot\n v-else\n v-bind=\"optional({ modelValue })\"\n :disabled=\"disabled\"\n :aria-label=\"ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :class=\"cn(boxClass, 'disabled:opacity-50')\"\n :style=\"boxStyle\"\n @update:model-value=\"$emit('update:modelValue', $event)\"\n >\n <template #default=\"{ state }\">\n <CheckboxIndicator class=\"flex animate-scale-in items-center justify-center text-current\">\n <Minus v-if=\"state === 'indeterminate'\" class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n <Check v-else class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n </CheckboxIndicator>\n </template>\n </CheckboxRoot>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Checkbox.js","names":[],"sources":["../../../src/primitives/Checkbox/Checkbox.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { CheckboxIndicator, CheckboxRoot } from \"reka-ui\";\nimport { Check, Minus } from \"@lucide/vue\";\nimport { cn } from \"../../lib/cn\";\nimport { optional } from \"../../lib/props\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\nimport { useFieldControl } from \"../../lib/field-context\";\n\n/**\n * Checkbox — a single boolean choice inside a form (as opposed to Switch,\n * which flips a setting immediately, no form/\"Save\" involved). Built on Reka\n * UI's Checkbox (role=\"checkbox\" + aria-checked, Space toggles); also\n * supports the third \"indeterminate\" state for a parent checkbox over a\n * partially-selected group — shown as a dash instead of a check.\n *\n * An inline `label` wraps the control in a real `<label>` (a11y name comes\n * free); omit it and pass `ariaLabel`/`ariaLabelledby` instead when the\n * visible label lives elsewhere (e.g. a table header cell).\n *\n * Inside a [Field](../Field/Field.vue) it wires itself through\n * `useFieldControl()`. CheckboxRoot renders a labelable `<button\n * role=\"checkbox\">`, so the row's id lands on the box and the row's\n * `<label for>` names it, with the row's description, `name`, `required` and\n * `invalid` arriving alongside. **Name it in one place.** A `label` here *and*\n * a label on the row gives one control two accessible names, read one after\n * the other, and nothing reports it — not axe, which has no rule for a name\n * that is merely doubled.\n *\n * There is no `readonly`, and a row's is ignored rather than approximated. A\n * checkbox that may be read but not toggled is a disabled checkbox: the native\n * `readonly` attribute is a no-op on `<input type=\"checkbox\">` for exactly that\n * reason, and painting one as editable-but-filled would promise an edit that\n * never lands.\n */\nconst props = withDefaults(\n defineProps<{\n /** `true`/`false` for a plain toggle, `\"indeterminate\"` for a parent over a partially-selected group. Omit to let the box own its own state. */\n modelValue?: boolean | \"indeterminate\" | undefined;\n /** Blocks both click and keyboard input, and dims the box. Unset defers to a wrapping Field. */\n disabled?: boolean | undefined;\n /** Visible text, rendered inside the wrapping `<label>`. Omit and use `ariaLabel`/`ariaLabelledby` when the label lives elsewhere. */\n label?: string;\n /** Accessible name when no visible `label` is rendered by this component. */\n ariaLabel?: string;\n /** Accessible name sourced from another element's id, when no visible `label` is rendered by this component. */\n ariaLabelledby?: string;\n }>(),\n {\n // Not `false`. A concrete value here would mean \"the host owns this\", and\n // a host that passes nothing would get a box that emits its update event\n // and never moves — a control that looks broken rather than one that\n // reports an error. `undefined` is what leaves it self-managing, and the\n // explicit default is what survives Vue's absent-Boolean-casts-to-false\n // rule.\n modelValue: undefined,\n // Not `false` either, and for the second half of the same reason: absent\n // has to stay tellable from `false` all the way into `useFieldControl()`,\n // or a Field above could never disable the row while `:disabled=\"false\"`\n // could never overrule one that did.\n disabled: undefined,\n },\n);\n\ndefineEmits<{ \"update:modelValue\": [value: boolean | \"indeterminate\"] }>();\n\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: boxAttrs } = useSplitAttrs();\n\n// Routed by hand because nothing was routing it: the two branches and the\n// comment between them make this component's root a *fragment*, and Vue never\n// auto-inherits onto one — it warns and drops the attributes. So `id`,\n// `data-testid` and a caller's `class` all went nowhere until this split.\n// `class` now lands on whichever branch's root renders (a caller sizes the\n// labelled row, or the bare box) and everything else on the CheckboxRoot in\n// both, which is where a row's id has to be: `<label for>` resolves to a\n// labelable element, and the `<button role=\"checkbox\">` is the one here.\n//\n// `field.attrs` spreads **after** `boxAttrs` — see TextField.vue for the full\n// reasoning. The bag has already resolved the caller's own id and merged their\n// description with the row's, and it drops every key that resolved to nothing,\n// so it can only add.\n//\n// `name`, `required` and `invalid` are absent from the bag below because this\n// component has no prop for any of them; the row's answer then stands\n// unopposed, which is what wrapping it in a Field asked for. `readonly` is\n// absent for the different reason the docblock gives.\n//\n// `required` is then the one resolved value that cannot ride in on\n// `field.attrs`: CheckboxRoot renders `aria-required` itself, from its own\n// prop, *after* it spreads the fallthrough attrs — so an `aria-required` in\n// that bag is overwritten by a `false` and the row is silently unheard. It goes\n// through `:required` on the element below instead. That prop also reaches the\n// hidden input Reka mints inside a `<form>`, so unlike TextField this control\n// does carry native enforcement with it; the alternative is a checkbox that\n// tells a screen reader it is optional while its row's asterisk says otherwise.\nconst field = useFieldControl(() => ({\n id: attrs.id as string | undefined,\n describedBy: attrs[\"aria-describedby\"] as string | undefined,\n disabled: props.disabled,\n}));\n\nconst boxClass = cn(\n \"flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border border-input bg-background\",\n // Transform (the press squish) rides --ease-spring for a restrained release,\n // while fill/border stay on the instant --ease-out — the \"springy transform,\n // steady color\" split (boxStyle below), same language as Button/Switch.\n \"active:scale-90\",\n // Checked = a decision (Loom law): the box fills with primary.\n \"data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground\",\n \"data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground\",\n // Focus draws the weave tight: the brand ring blooms.\n \"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\",\n \"disabled:cursor-not-allowed\",\n);\n\nconst boxStyle =\n \"transition: transform var(--duration-fast) var(--ease-spring), background-color var(--duration-instant) var(--ease-out), border-color var(--duration-instant) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);\";\n</script>\n\n<template>\n <!-- CheckboxRoot is a labelable <button role=\"checkbox\">, so wrapping it in\n <label> names it exactly like a native control; the rule's nesting/id\n heuristic just doesn't recognize reka-ui's custom element as a\n \"control\". -->\n <!-- eslint-disable-next-line vuejs-accessibility/label-has-for -->\n <label\n v-if=\"label\"\n :class=\"\n cn(\n 'inline-flex items-center gap-2 text-sm text-foreground',\n // Disabled text stays readable (AA on the light ground) — only the box dims.\n field.disabled ? 'cursor-not-allowed text-muted-foreground' : 'cursor-pointer',\n attrs.class as string,\n )\n \"\n >\n <CheckboxRoot\n v-bind=\"{ ...optional({ modelValue }), ...boxAttrs, ...field.attrs }\"\n :disabled=\"field.disabled\"\n :required=\"field.required\"\n :class=\"cn(boxClass, 'disabled:opacity-50')\"\n :style=\"boxStyle\"\n @update:model-value=\"$emit('update:modelValue', $event)\"\n >\n <template #default=\"{ state }\">\n <!-- The tick pops in with scale-in — a small causal \"it's checked now\".\n stroke-width 2.5 is the ≤12px iconography rule, not a local taste:\n the inherited 1.5 renders 0.75 device px at 12px and reads washed\n out inside the filled box. Both branches carry it identically. -->\n <CheckboxIndicator class=\"flex animate-scale-in items-center justify-center text-current\">\n <Minus v-if=\"state === 'indeterminate'\" class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n <Check v-else class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n </CheckboxIndicator>\n </template>\n </CheckboxRoot>\n {{ label }}\n </label>\n <!-- The control always dims itself when disabled; label text stays\n readable muted — same stance in both branches. -->\n <CheckboxRoot\n v-else\n v-bind=\"{ ...optional({ modelValue }), ...boxAttrs, ...field.attrs }\"\n :disabled=\"field.disabled\"\n :required=\"field.required\"\n :aria-label=\"ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :class=\"cn(boxClass, 'disabled:opacity-50', attrs.class as string)\"\n :style=\"boxStyle\"\n @update:model-value=\"$emit('update:modelValue', $event)\"\n >\n <template #default=\"{ state }\">\n <CheckboxIndicator class=\"flex animate-scale-in items-center justify-center text-current\">\n <Minus v-if=\"state === 'indeterminate'\" class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n <Check v-else class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n </CheckboxIndicator>\n </template>\n </CheckboxRoot>\n</template>\n"],"mappings":""}
@@ -8,12 +8,27 @@
8
8
  * An inline `label` wraps the control in a real `<label>` (a11y name comes
9
9
  * free); omit it and pass `ariaLabel`/`ariaLabelledby` instead when the
10
10
  * visible label lives elsewhere (e.g. a table header cell).
11
+ *
12
+ * Inside a [Field](../Field/Field.vue) it wires itself through
13
+ * `useFieldControl()`. CheckboxRoot renders a labelable `<button
14
+ * role="checkbox">`, so the row's id lands on the box and the row's
15
+ * `<label for>` names it, with the row's description, `name`, `required` and
16
+ * `invalid` arriving alongside. **Name it in one place.** A `label` here *and*
17
+ * a label on the row gives one control two accessible names, read one after
18
+ * the other, and nothing reports it — not axe, which has no rule for a name
19
+ * that is merely doubled.
20
+ *
21
+ * There is no `readonly`, and a row's is ignored rather than approximated. A
22
+ * checkbox that may be read but not toggled is a disabled checkbox: the native
23
+ * `readonly` attribute is a no-op on `<input type="checkbox">` for exactly that
24
+ * reason, and painting one as editable-but-filled would promise an edit that
25
+ * never lands.
11
26
  */
12
27
  type __VLS_Props = {
13
28
  /** `true`/`false` for a plain toggle, `"indeterminate"` for a parent over a partially-selected group. Omit to let the box own its own state. */
14
29
  modelValue?: boolean | "indeterminate" | undefined;
15
- /** Blocks both click and keyboard input, and dims the box. */
16
- disabled?: boolean;
30
+ /** Blocks both click and keyboard input, and dims the box. Unset defers to a wrapping Field. */
31
+ disabled?: boolean | undefined;
17
32
  /** Visible text, rendered inside the wrapping `<label>`. Omit and use `ariaLabel`/`ariaLabelledby` when the label lives elsewhere. */
18
33
  label?: string;
19
34
  /** Accessible name when no visible `label` is rendered by this component. */
@@ -26,7 +41,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
26
41
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
27
42
  "onUpdate:modelValue"?: (value: boolean | "indeterminate") => any;
28
43
  }>, {
29
- disabled: boolean;
44
+ disabled: boolean | undefined;
30
45
  modelValue: boolean | "indeterminate" | undefined;
31
46
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
32
47
  declare const _default: typeof __VLS_export;
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Checkbox/Checkbox.vue"],"names":[],"mappings":"AA8HA;;;;;;;;;;GAUG;AACH,KAAK,WAAW,GAAG;IACf,gJAAgJ;IAChJ,UAAU,CAAC,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAAC;IACnD,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sIAAsI;IACtI,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gHAAgH;IAChH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAmRJ,QAAA,MAAM,YAAY;;;;;cA1RH,OAAO;gBAFL,OAAO,GAAG,eAAe,GAAG,SAAS;6EAgSpD,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"Checkbox.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Checkbox/Checkbox.vue"],"names":[],"mappings":"AA4LA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,KAAK,WAAW,GAAG;IACf,gJAAgJ;IAChJ,UAAU,CAAC,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAAC;IACnD,gGAAgG;IAChG,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,sIAAsI;IACtI,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gHAAgH;IAChH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAuUJ,QAAA,MAAM,YAAY;;;;;cA9UH,OAAO,GAAG,SAAS;gBAFjB,OAAO,GAAG,eAAe,GAAG,SAAS;6EAoVpD,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -1,5 +1,7 @@
1
1
  import { cn } from "../../lib/cn.js";
2
2
  import { optional } from "../../lib/props.js";
3
+ import { useSplitAttrs } from "../../lib/attrs.js";
4
+ import { useFieldControl } from "../../lib/field-context.js";
3
5
  import { Check, Minus } from "@lucide/vue";
4
6
  import { createBlock, createElementBlock, createTextVNode, createVNode, defineComponent, mergeProps, normalizeClass, openBlock, toDisplayString, unref, withCtx } from "vue";
5
7
  import { CheckboxIndicator, CheckboxRoot } from "reka-ui";
@@ -14,9 +16,25 @@ import { CheckboxIndicator, CheckboxRoot } from "reka-ui";
14
16
  * An inline `label` wraps the control in a real `<label>` (a11y name comes
15
17
  * free); omit it and pass `ariaLabel`/`ariaLabelledby` instead when the
16
18
  * visible label lives elsewhere (e.g. a table header cell).
19
+ *
20
+ * Inside a [Field](../Field/Field.vue) it wires itself through
21
+ * `useFieldControl()`. CheckboxRoot renders a labelable `<button
22
+ * role="checkbox">`, so the row's id lands on the box and the row's
23
+ * `<label for>` names it, with the row's description, `name`, `required` and
24
+ * `invalid` arriving alongside. **Name it in one place.** A `label` here *and*
25
+ * a label on the row gives one control two accessible names, read one after
26
+ * the other, and nothing reports it — not axe, which has no rule for a name
27
+ * that is merely doubled.
28
+ *
29
+ * There is no `readonly`, and a row's is ignored rather than approximated. A
30
+ * checkbox that may be read but not toggled is a disabled checkbox: the native
31
+ * `readonly` attribute is a no-op on `<input type="checkbox">` for exactly that
32
+ * reason, and painting one as editable-but-filled would promise an edit that
33
+ * never lands.
17
34
  */
18
35
  var boxStyle = "transition: transform var(--duration-fast) var(--ease-spring), background-color var(--duration-instant) var(--ease-out), border-color var(--duration-instant) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);";
19
36
  var Checkbox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
37
+ inheritAttrs: false,
20
38
  __name: "Checkbox",
21
39
  props: {
22
40
  modelValue: {
@@ -25,7 +43,7 @@ var Checkbox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
25
43
  },
26
44
  disabled: {
27
45
  type: Boolean,
28
- default: false
46
+ default: void 0
29
47
  },
30
48
  label: {},
31
49
  ariaLabel: {},
@@ -34,13 +52,24 @@ var Checkbox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
34
52
  emits: ["update:modelValue"],
35
53
  setup(__props) {
36
54
  const props = __props;
55
+ const { attrs, rest: boxAttrs } = useSplitAttrs();
56
+ const field = useFieldControl(() => ({
57
+ id: attrs.id,
58
+ describedBy: attrs["aria-describedby"],
59
+ disabled: props.disabled
60
+ }));
37
61
  const boxClass = cn("flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border border-input bg-background", "active:scale-90", "data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground", "data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground", "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo", "disabled:cursor-not-allowed");
38
62
  return (_ctx, _cache) => {
39
63
  return __props.label ? (openBlock(), createElementBlock("label", {
40
64
  key: 0,
41
- class: normalizeClass(unref(cn)("inline-flex items-center gap-2 text-sm text-foreground", props.disabled ? "cursor-not-allowed text-muted-foreground" : "cursor-pointer"))
42
- }, [createVNode(unref(CheckboxRoot), mergeProps(unref(optional)({ modelValue: __props.modelValue }), {
43
- disabled: __props.disabled,
65
+ class: normalizeClass(unref(cn)("inline-flex items-center gap-2 text-sm text-foreground", unref(field).disabled ? "cursor-not-allowed text-muted-foreground" : "cursor-pointer", unref(attrs).class))
66
+ }, [createVNode(unref(CheckboxRoot), mergeProps({
67
+ ...unref(optional)({ modelValue: __props.modelValue }),
68
+ ...unref(boxAttrs),
69
+ ...unref(field).attrs
70
+ }, {
71
+ disabled: unref(field).disabled,
72
+ required: unref(field).required,
44
73
  class: unref(cn)(unref(boxClass), "disabled:opacity-50"),
45
74
  style: boxStyle,
46
75
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.$emit("update:modelValue", $event))
@@ -58,11 +87,20 @@ var Checkbox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
58
87
  _: 2
59
88
  }, 1024)]),
60
89
  _: 1
61
- }, 16, ["disabled", "class"]), createTextVNode(" " + toDisplayString(__props.label), 1)], 2)) : (openBlock(), createBlock(unref(CheckboxRoot), mergeProps({ key: 1 }, unref(optional)({ modelValue: __props.modelValue }), {
62
- disabled: __props.disabled,
90
+ }, 16, [
91
+ "disabled",
92
+ "required",
93
+ "class"
94
+ ]), createTextVNode(" " + toDisplayString(__props.label), 1)], 2)) : (openBlock(), createBlock(unref(CheckboxRoot), mergeProps({ key: 1 }, {
95
+ ...unref(optional)({ modelValue: __props.modelValue }),
96
+ ...unref(boxAttrs),
97
+ ...unref(field).attrs
98
+ }, {
99
+ disabled: unref(field).disabled,
100
+ required: unref(field).required,
63
101
  "aria-label": __props.ariaLabel,
64
102
  "aria-labelledby": __props.ariaLabelledby,
65
- class: unref(cn)(unref(boxClass), "disabled:opacity-50"),
103
+ class: unref(cn)(unref(boxClass), "disabled:opacity-50", unref(attrs).class),
66
104
  style: boxStyle,
67
105
  "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => _ctx.$emit("update:modelValue", $event))
68
106
  }), {
@@ -81,6 +119,7 @@ var Checkbox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineC
81
119
  _: 1
82
120
  }, 16, [
83
121
  "disabled",
122
+ "required",
84
123
  "aria-label",
85
124
  "aria-labelledby",
86
125
  "class"
@@ -1 +1 @@
1
- {"version":3,"file":"Checkbox.vue_vue_type_script_setup_true_lang.js","names":["$emit"],"sources":["../../../src/primitives/Checkbox/Checkbox.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { CheckboxIndicator, CheckboxRoot } from \"reka-ui\";\nimport { Check, Minus } from \"@lucide/vue\";\nimport { cn } from \"../../lib/cn\";\nimport { optional } from \"../../lib/props\";\n\n/**\n * Checkbox — a single boolean choice inside a form (as opposed to Switch,\n * which flips a setting immediately, no form/\"Save\" involved). Built on Reka\n * UI's Checkbox (role=\"checkbox\" + aria-checked, Space toggles); also\n * supports the third \"indeterminate\" state for a parent checkbox over a\n * partially-selected group — shown as a dash instead of a check.\n *\n * An inline `label` wraps the control in a real `<label>` (a11y name comes\n * free); omit it and pass `ariaLabel`/`ariaLabelledby` instead when the\n * visible label lives elsewhere (e.g. a table header cell).\n */\nconst props = withDefaults(\n defineProps<{\n /** `true`/`false` for a plain toggle, `\"indeterminate\"` for a parent over a partially-selected group. Omit to let the box own its own state. */\n modelValue?: boolean | \"indeterminate\" | undefined;\n /** Blocks both click and keyboard input, and dims the box. */\n disabled?: boolean;\n /** Visible text, rendered inside the wrapping `<label>`. Omit and use `ariaLabel`/`ariaLabelledby` when the label lives elsewhere. */\n label?: string;\n /** Accessible name when no visible `label` is rendered by this component. */\n ariaLabel?: string;\n /** Accessible name sourced from another element's id, when no visible `label` is rendered by this component. */\n ariaLabelledby?: string;\n }>(),\n {\n // Not `false`. A concrete value here would mean \"the host owns this\", and\n // a host that passes nothing would get a box that emits its update event\n // and never moves — a control that looks broken rather than one that\n // reports an error. `undefined` is what leaves it self-managing, and the\n // explicit default is what survives Vue's absent-Boolean-casts-to-false\n // rule.\n modelValue: undefined,\n disabled: false,\n },\n);\n\ndefineEmits<{ \"update:modelValue\": [value: boolean | \"indeterminate\"] }>();\n\nconst boxClass = cn(\n \"flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border border-input bg-background\",\n // Transform (the press squish) rides --ease-spring for a restrained release,\n // while fill/border stay on the instant --ease-out — the \"springy transform,\n // steady color\" split (boxStyle below), same language as Button/Switch.\n \"active:scale-90\",\n // Checked = a human decision (Loom law): the box fills flat warp.\n \"data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground\",\n \"data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground\",\n // Focus draws the weave tight: the brand ring blooms.\n \"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\",\n \"disabled:cursor-not-allowed\",\n);\n\nconst boxStyle =\n \"transition: transform var(--duration-fast) var(--ease-spring), background-color var(--duration-instant) var(--ease-out), border-color var(--duration-instant) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);\";\n</script>\n\n<template>\n <!-- CheckboxRoot is a labelable <button role=\"checkbox\">, so wrapping it in\n <label> names it exactly like a native control; the rule's nesting/id\n heuristic just doesn't recognize reka-ui's custom element as a\n \"control\". -->\n <!-- eslint-disable-next-line vuejs-accessibility/label-has-for -->\n <label\n v-if=\"label\"\n :class=\"\n cn(\n 'inline-flex items-center gap-2 text-sm text-foreground',\n // Disabled text stays readable (AA on the light ground) — only the box dims.\n props.disabled ? 'cursor-not-allowed text-muted-foreground' : 'cursor-pointer',\n )\n \"\n >\n <CheckboxRoot\n v-bind=\"optional({ modelValue })\"\n :disabled=\"disabled\"\n :class=\"cn(boxClass, 'disabled:opacity-50')\"\n :style=\"boxStyle\"\n @update:model-value=\"$emit('update:modelValue', $event)\"\n >\n <template #default=\"{ state }\">\n <!-- The tick pops in with scale-in — a small causal \"it's checked now\".\n stroke-width 2.5 is the ≤12px iconography rule, not a local taste:\n the inherited 1.5 renders 0.75 device px at 12px and reads washed\n out inside the filled box. Both branches carry it identically. -->\n <CheckboxIndicator class=\"flex animate-scale-in items-center justify-center text-current\">\n <Minus v-if=\"state === 'indeterminate'\" class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n <Check v-else class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n </CheckboxIndicator>\n </template>\n </CheckboxRoot>\n {{ label }}\n </label>\n <!-- The control always dims itself when disabled; label text stays\n readable muted — same stance in both branches. -->\n <CheckboxRoot\n v-else\n v-bind=\"optional({ modelValue })\"\n :disabled=\"disabled\"\n :aria-label=\"ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :class=\"cn(boxClass, 'disabled:opacity-50')\"\n :style=\"boxStyle\"\n @update:model-value=\"$emit('update:modelValue', $event)\"\n >\n <template #default=\"{ state }\">\n <CheckboxIndicator class=\"flex animate-scale-in items-center justify-center text-current\">\n <Minus v-if=\"state === 'indeterminate'\" class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n <Check v-else class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n </CheckboxIndicator>\n </template>\n </CheckboxRoot>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;AA0DA,IAAM,WACJ;;;;;;;;;;;;;;;;;;EA1CF,MAAM,QAAQ;EA2Bd,MAAM,WAAW,GACf,kGAIA,mBAEA,oHACA,sIAEA,+GACA,6BACF;;GAaU,OAAA,QAAA,SADR,UAAA,GAAA,mBA6BQ,SAAA;;IA3BL,OAAK,eAAS,MAAA,EAAA,CAAE,CAAA,0DAAkK,MAAM,WAAQ,6CAAA,gBAAA,CAAA;GAQjM,GAAA,CAAA,YAiBe,MAAA,YAAA,GAjBf,WACU,MAgBK,QAAA,CAhBG,CAAA,EAAA,YAAG,QAAA,WAAU,CAAA,GAAA;IAC5B,UAAU,QAAA;IACV,OAAO,MAAA,EAAA,CAAE,CAAC,MAAA,QAAA,GAAQ,qBAAA;IAClB,OAAO;IACP,uBAAkB,OAAA,OAAA,OAAA,MAAA,WAAEA,KAAAA,MAAK,qBAAsB,MAAM;;IAE3C,SAAO,SAQI,EARA,YAAK,CAKzB,YAGoB,MAAA,iBAAA,GAAA,EAHD,OAAM,iEAAgE,GAAA;KACvF,SAAA,cAA8E,CAAjE,UAAK,mBAAlB,UAAA,GAAA,YAA8E,MAAA,KAAA,GAAA;;MAAtC,OAAM;MAAW,gBAAc;KACvE,CAAA,MAAA,UAAA,GAAA,YAAoD,MAAA,KAAA,GAAA;;MAAtC,OAAM;MAAW,gBAAc;;;;;GAGpC,GAAA,IAAA,CAAA,YAAA,OAAA,CAAA,GAAA,gBAAA,MACf,gBAAG,QAAA,KAAK,GAAA,CAAA,CAAA,GAAA,CAAA,MAIV,UAAA,GAAA,YAgBe,MAAA,YAAA,GAhBf,WAgBe,EAAA,KAAA,EAAA,GAdL,MAAA,QAAA,CAAQ,CAAA,EAAA,YAAG,QAAA,WAAU,CAAA,GAAA;IAC5B,UAAU,QAAA;IACV,cAAY,QAAA;IACZ,mBAAiB,QAAA;IACjB,OAAO,MAAA,EAAA,CAAE,CAAC,MAAA,QAAA,GAAQ,qBAAA;IAClB,OAAO;IACP,uBAAkB,OAAA,OAAA,OAAA,MAAA,WAAEA,KAAAA,MAAK,qBAAsB,MAAM;;IAE3C,SAAO,SAII,EAJA,YAAK,CACzB,YAGoB,MAAA,iBAAA,GAAA,EAHD,OAAM,iEAAgE,GAAA;KACvF,SAAA,cAA8E,CAAjE,UAAK,mBAAlB,UAAA,GAAA,YAA8E,MAAA,KAAA,GAAA;;MAAtC,OAAM;MAAW,gBAAc;KACvE,CAAA,MAAA,UAAA,GAAA,YAAoD,MAAA,KAAA,GAAA;;MAAtC,OAAM;MAAW,gBAAc"}
1
+ {"version":3,"file":"Checkbox.vue_vue_type_script_setup_true_lang.js","names":["$emit"],"sources":["../../../src/primitives/Checkbox/Checkbox.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { CheckboxIndicator, CheckboxRoot } from \"reka-ui\";\nimport { Check, Minus } from \"@lucide/vue\";\nimport { cn } from \"../../lib/cn\";\nimport { optional } from \"../../lib/props\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\nimport { useFieldControl } from \"../../lib/field-context\";\n\n/**\n * Checkbox — a single boolean choice inside a form (as opposed to Switch,\n * which flips a setting immediately, no form/\"Save\" involved). Built on Reka\n * UI's Checkbox (role=\"checkbox\" + aria-checked, Space toggles); also\n * supports the third \"indeterminate\" state for a parent checkbox over a\n * partially-selected group — shown as a dash instead of a check.\n *\n * An inline `label` wraps the control in a real `<label>` (a11y name comes\n * free); omit it and pass `ariaLabel`/`ariaLabelledby` instead when the\n * visible label lives elsewhere (e.g. a table header cell).\n *\n * Inside a [Field](../Field/Field.vue) it wires itself through\n * `useFieldControl()`. CheckboxRoot renders a labelable `<button\n * role=\"checkbox\">`, so the row's id lands on the box and the row's\n * `<label for>` names it, with the row's description, `name`, `required` and\n * `invalid` arriving alongside. **Name it in one place.** A `label` here *and*\n * a label on the row gives one control two accessible names, read one after\n * the other, and nothing reports it — not axe, which has no rule for a name\n * that is merely doubled.\n *\n * There is no `readonly`, and a row's is ignored rather than approximated. A\n * checkbox that may be read but not toggled is a disabled checkbox: the native\n * `readonly` attribute is a no-op on `<input type=\"checkbox\">` for exactly that\n * reason, and painting one as editable-but-filled would promise an edit that\n * never lands.\n */\nconst props = withDefaults(\n defineProps<{\n /** `true`/`false` for a plain toggle, `\"indeterminate\"` for a parent over a partially-selected group. Omit to let the box own its own state. */\n modelValue?: boolean | \"indeterminate\" | undefined;\n /** Blocks both click and keyboard input, and dims the box. Unset defers to a wrapping Field. */\n disabled?: boolean | undefined;\n /** Visible text, rendered inside the wrapping `<label>`. Omit and use `ariaLabel`/`ariaLabelledby` when the label lives elsewhere. */\n label?: string;\n /** Accessible name when no visible `label` is rendered by this component. */\n ariaLabel?: string;\n /** Accessible name sourced from another element's id, when no visible `label` is rendered by this component. */\n ariaLabelledby?: string;\n }>(),\n {\n // Not `false`. A concrete value here would mean \"the host owns this\", and\n // a host that passes nothing would get a box that emits its update event\n // and never moves — a control that looks broken rather than one that\n // reports an error. `undefined` is what leaves it self-managing, and the\n // explicit default is what survives Vue's absent-Boolean-casts-to-false\n // rule.\n modelValue: undefined,\n // Not `false` either, and for the second half of the same reason: absent\n // has to stay tellable from `false` all the way into `useFieldControl()`,\n // or a Field above could never disable the row while `:disabled=\"false\"`\n // could never overrule one that did.\n disabled: undefined,\n },\n);\n\ndefineEmits<{ \"update:modelValue\": [value: boolean | \"indeterminate\"] }>();\n\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: boxAttrs } = useSplitAttrs();\n\n// Routed by hand because nothing was routing it: the two branches and the\n// comment between them make this component's root a *fragment*, and Vue never\n// auto-inherits onto one — it warns and drops the attributes. So `id`,\n// `data-testid` and a caller's `class` all went nowhere until this split.\n// `class` now lands on whichever branch's root renders (a caller sizes the\n// labelled row, or the bare box) and everything else on the CheckboxRoot in\n// both, which is where a row's id has to be: `<label for>` resolves to a\n// labelable element, and the `<button role=\"checkbox\">` is the one here.\n//\n// `field.attrs` spreads **after** `boxAttrs` — see TextField.vue for the full\n// reasoning. The bag has already resolved the caller's own id and merged their\n// description with the row's, and it drops every key that resolved to nothing,\n// so it can only add.\n//\n// `name`, `required` and `invalid` are absent from the bag below because this\n// component has no prop for any of them; the row's answer then stands\n// unopposed, which is what wrapping it in a Field asked for. `readonly` is\n// absent for the different reason the docblock gives.\n//\n// `required` is then the one resolved value that cannot ride in on\n// `field.attrs`: CheckboxRoot renders `aria-required` itself, from its own\n// prop, *after* it spreads the fallthrough attrs — so an `aria-required` in\n// that bag is overwritten by a `false` and the row is silently unheard. It goes\n// through `:required` on the element below instead. That prop also reaches the\n// hidden input Reka mints inside a `<form>`, so unlike TextField this control\n// does carry native enforcement with it; the alternative is a checkbox that\n// tells a screen reader it is optional while its row's asterisk says otherwise.\nconst field = useFieldControl(() => ({\n id: attrs.id as string | undefined,\n describedBy: attrs[\"aria-describedby\"] as string | undefined,\n disabled: props.disabled,\n}));\n\nconst boxClass = cn(\n \"flex h-4 w-4 shrink-0 items-center justify-center rounded-sm border border-input bg-background\",\n // Transform (the press squish) rides --ease-spring for a restrained release,\n // while fill/border stay on the instant --ease-out — the \"springy transform,\n // steady color\" split (boxStyle below), same language as Button/Switch.\n \"active:scale-90\",\n // Checked = a decision (Loom law): the box fills with primary.\n \"data-[state=checked]:border-primary data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground\",\n \"data-[state=indeterminate]:border-primary data-[state=indeterminate]:bg-primary data-[state=indeterminate]:text-primary-foreground\",\n // Focus draws the weave tight: the brand ring blooms.\n \"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo\",\n \"disabled:cursor-not-allowed\",\n);\n\nconst boxStyle =\n \"transition: transform var(--duration-fast) var(--ease-spring), background-color var(--duration-instant) var(--ease-out), border-color var(--duration-instant) var(--ease-out), box-shadow var(--duration-fast) var(--ease-out);\";\n</script>\n\n<template>\n <!-- CheckboxRoot is a labelable <button role=\"checkbox\">, so wrapping it in\n <label> names it exactly like a native control; the rule's nesting/id\n heuristic just doesn't recognize reka-ui's custom element as a\n \"control\". -->\n <!-- eslint-disable-next-line vuejs-accessibility/label-has-for -->\n <label\n v-if=\"label\"\n :class=\"\n cn(\n 'inline-flex items-center gap-2 text-sm text-foreground',\n // Disabled text stays readable (AA on the light ground) — only the box dims.\n field.disabled ? 'cursor-not-allowed text-muted-foreground' : 'cursor-pointer',\n attrs.class as string,\n )\n \"\n >\n <CheckboxRoot\n v-bind=\"{ ...optional({ modelValue }), ...boxAttrs, ...field.attrs }\"\n :disabled=\"field.disabled\"\n :required=\"field.required\"\n :class=\"cn(boxClass, 'disabled:opacity-50')\"\n :style=\"boxStyle\"\n @update:model-value=\"$emit('update:modelValue', $event)\"\n >\n <template #default=\"{ state }\">\n <!-- The tick pops in with scale-in — a small causal \"it's checked now\".\n stroke-width 2.5 is the ≤12px iconography rule, not a local taste:\n the inherited 1.5 renders 0.75 device px at 12px and reads washed\n out inside the filled box. Both branches carry it identically. -->\n <CheckboxIndicator class=\"flex animate-scale-in items-center justify-center text-current\">\n <Minus v-if=\"state === 'indeterminate'\" class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n <Check v-else class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n </CheckboxIndicator>\n </template>\n </CheckboxRoot>\n {{ label }}\n </label>\n <!-- The control always dims itself when disabled; label text stays\n readable muted — same stance in both branches. -->\n <CheckboxRoot\n v-else\n v-bind=\"{ ...optional({ modelValue }), ...boxAttrs, ...field.attrs }\"\n :disabled=\"field.disabled\"\n :required=\"field.required\"\n :aria-label=\"ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :class=\"cn(boxClass, 'disabled:opacity-50', attrs.class as string)\"\n :style=\"boxStyle\"\n @update:model-value=\"$emit('update:modelValue', $event)\"\n >\n <template #default=\"{ state }\">\n <CheckboxIndicator class=\"flex animate-scale-in items-center justify-center text-current\">\n <Minus v-if=\"state === 'indeterminate'\" class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n <Check v-else class=\"h-3 w-3\" :stroke-width=\"2.5\" />\n </CheckboxIndicator>\n </template>\n </CheckboxRoot>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmHA,IAAM,WACJ;;;;;;;;;;;;;;;;;;;EAlFF,MAAM,QAAQ;EAgCd,MAAM,EAAE,OAAO,MAAM,aAAa,cAAc;EA6BhD,MAAM,QAAQ,uBAAuB;GACnC,IAAI,MAAM;GACV,aAAa,MAAM;GACnB,UAAU,MAAM;EAClB,EAAE;EAEF,MAAM,WAAW,GACf,kGAIA,mBAEA,oHACA,sIAEA,+GACA,6BACF;;GAaU,OAAA,QAAA,SADR,UAAA,GAAA,mBA+BQ,SAAA;;IA7BL,OAAK,eAAS,MAAA,EAAA,CAAE,CAAA,0DAAkK,MAAA,KAAA,CAAK,CAAC,WAAQ,6CAAA,kBAA0E,MAAA,KAAA,CAAK,CAAC,KAAA,CAAA;GASjR,GAAA,CAAA,YAkBe,MAAA,YAAA,GAlBf,WAkBe;IAAA,GAjBA,MAAA,QAAA,CAAQ,CAAA,EAAA,YAAG,QAAA,WAAU,CAAA;IAAA,GAAQ,MAAA,QAAA;IAAQ,GAAK,MAAA,KAAA,CAAK,CAAC;GAAK,GAAA;IACjE,UAAU,MAAA,KAAA,CAAK,CAAC;IAChB,UAAU,MAAA,KAAA,CAAK,CAAC;IAChB,OAAO,MAAA,EAAA,CAAE,CAAC,MAAA,QAAA,GAAQ,qBAAA;IAClB,OAAO;IACP,uBAAkB,OAAA,OAAA,OAAA,MAAA,WAAEA,KAAAA,MAAK,qBAAsB,MAAM;;IAE3C,SAAO,SAQI,EARA,YAAK,CAKzB,YAGoB,MAAA,iBAAA,GAAA,EAHD,OAAM,iEAAgE,GAAA;KACvF,SAAA,cAA8E,CAAjE,UAAK,mBAAlB,UAAA,GAAA,YAA8E,MAAA,KAAA,GAAA;;MAAtC,OAAM;MAAW,gBAAc;KACvE,CAAA,MAAA,UAAA,GAAA,YAAoD,MAAA,KAAA,GAAA;;MAAtC,OAAM;MAAW,gBAAc;;;;;;;;;GAGpC,CAAA,GAAA,gBAAA,MACf,gBAAG,QAAA,KAAK,GAAA,CAAA,CAAA,GAAA,CAAA,MAIV,UAAA,GAAA,YAiBe,MAAA,YAAA,GAjBf,WAiBe,EAAA,KAAA,EAAA,GAAA;IAAA,GAfA,MAAA,QAAA,CAAQ,CAAA,EAAA,YAAG,QAAA,WAAU,CAAA;IAAA,GAAQ,MAAA,QAAA;IAAQ,GAAK,MAAA,KAAA,CAAK,CAAC;GAAK,GAAA;IACjE,UAAU,MAAA,KAAA,CAAK,CAAC;IAChB,UAAU,MAAA,KAAA,CAAK,CAAC;IAChB,cAAY,QAAA;IACZ,mBAAiB,QAAA;IACjB,OAAO,MAAA,EAAA,CAAE,CAAC,MAAA,QAAA,GAAQ,uBAAyB,MAAA,KAAA,CAAK,CAAC,KAAK;IACtD,OAAO;IACP,uBAAkB,OAAA,OAAA,OAAA,MAAA,WAAEA,KAAAA,MAAK,qBAAsB,MAAM;;IAE3C,SAAO,SAII,EAJA,YAAK,CACzB,YAGoB,MAAA,iBAAA,GAAA,EAHD,OAAM,iEAAgE,GAAA;KACvF,SAAA,cAA8E,CAAjE,UAAK,mBAAlB,UAAA,GAAA,YAA8E,MAAA,KAAA,GAAA;;MAAtC,OAAM;MAAW,gBAAc;KACvE,CAAA,MAAA,UAAA,GAAA,YAAoD,MAAA,KAAA,GAAA;;MAAtC,OAAM;MAAW,gBAAc"}
@@ -0,0 +1,7 @@
1
+ import Chip_vue_vue_type_script_setup_true_lang_default, { chipVariants } from "./Chip.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/primitives/Chip/Chip.vue
3
+ var Chip_default = Chip_vue_vue_type_script_setup_true_lang_default;
4
+ //#endregion
5
+ export { chipVariants, Chip_default as default };
6
+
7
+ //# sourceMappingURL=Chip.js.map