@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,178 @@
1
+ import { type ComputedRef } from "vue";
2
+ /**
3
+ * What a form-row wrapper (Field, Fieldset) knows about the control inside it.
4
+ *
5
+ * A wrapper renders a `<label for>` and a hint-or-error line, and it is the
6
+ * only thing in the tree that knows the id it pointed that label at, the id of
7
+ * the message, and whether the row is mandatory or in error. None of that can
8
+ * reach a slotted control through props — the wrapper never rendered it — so
9
+ * before this existed the caller copied three attributes by hand at every call
10
+ * site, and forgetting one was a silent accessibility defect.
11
+ *
12
+ * Every member is a `ComputedRef` rather than a value. A row's `error` arrives
13
+ * and clears while the control stays mounted, so the context has to move with
14
+ * it; and a per-key ref is what lets one wrapper inherit a single key from
15
+ * another (Field reads `readonly` off a Fieldset above it) without a hidden
16
+ * whole-object merge.
17
+ *
18
+ * On the booleans, `undefined` means "this wrapper has no opinion" and never
19
+ * "false". That is the whole precedence story — see `useFieldControl` — and it
20
+ * is the same distinction `./props.ts` exists to explain, arriving from the
21
+ * other side: there, a key is dropped so a child sees an absence; here, an
22
+ * absence is a value a wrapper is allowed to hold.
23
+ */
24
+ export interface FieldContext {
25
+ /** The id the primary control adopts, so the wrapper's `<label for>` names it. */
26
+ readonly controlId: ComputedRef<string | undefined>;
27
+ /** The id of the wrapper's `<label>`, for group controls to reference via `aria-labelledby`. */
28
+ readonly labelledBy: ComputedRef<string | undefined>;
29
+ /** The id of the hint-or-error line, and `undefined` while no message is rendered. */
30
+ readonly describedBy: ComputedRef<string | undefined>;
31
+ /** The form field name the control submits under. */
32
+ readonly name: ComputedRef<string | undefined>;
33
+ /** Whether the wrapper marks the row mandatory. Becomes `aria-required`. */
34
+ readonly required: ComputedRef<boolean | undefined>;
35
+ /** Whether the wrapper is showing an error, which is the same fact as the control being invalid. */
36
+ readonly invalid: ComputedRef<boolean | undefined>;
37
+ /** Whether the wrapper disables what is inside it. */
38
+ readonly disabled: ComputedRef<boolean | undefined>;
39
+ /** Whether the wrapper renders what is inside it read-only. */
40
+ readonly readonly: ComputedRef<boolean | undefined>;
41
+ /**
42
+ * Claims the row's single control id, and reports whether this control won it.
43
+ *
44
+ * `<Field><TextField /><TextField /></Field>` is a shape somebody will write,
45
+ * and without a claim both inputs adopt the same generated id — a duplicate
46
+ * id, and a `<label for>` that resolves to whichever the browser reaches
47
+ * first. The `axe` gate cannot be the backstop: `duplicate-id-active` is
48
+ * tagged `wcag2a-obsolete`/`deprecated` in axe-core, not `wcag2a`, so it does
49
+ * not match `WCAG_TAGS` and `e2e/accessibility.e2e.ts` never runs it.
50
+ *
51
+ * Reactive rather than a plain boolean because the claim can move: a `v-if`
52
+ * swapping the first control for the second must promote the second, or the
53
+ * label points at an id no longer in the document.
54
+ */
55
+ claimControlId(): ComputedRef<boolean>;
56
+ }
57
+ /**
58
+ * What a wrapper hands `provideFieldContext`, as getters rather than values —
59
+ * the wrapper writes plain expressions over its own props and this file does
60
+ * the wrapping, so a wrapper never has to remember which of its answers are
61
+ * derived.
62
+ */
63
+ export interface FieldContextSource {
64
+ controlId: () => string | undefined;
65
+ labelledBy?: () => string | undefined;
66
+ describedBy: () => string | undefined;
67
+ name: () => string | undefined;
68
+ required: () => boolean | undefined;
69
+ invalid: () => boolean | undefined;
70
+ disabled: () => boolean | undefined;
71
+ readonly: () => boolean | undefined;
72
+ }
73
+ /**
74
+ * The control's own side of the contract: what this control was told directly,
75
+ * with `undefined` for everything the caller left unset.
76
+ *
77
+ * Each key is `?: T | undefined` rather than `?: T`. Under
78
+ * `exactOptionalPropertyTypes` that is the form that accepts both an omitted
79
+ * key and an explicit `undefined` — and an explicit `undefined` is exactly what
80
+ * a control passes when its own prop is unset.
81
+ */
82
+ export interface FieldControlProps {
83
+ /** The caller's `id`, which reaches a bare control as a fallthrough attr rather than a prop. */
84
+ readonly id?: string | undefined;
85
+ /** The caller's `aria-describedby`, likewise a fallthrough attr. */
86
+ readonly describedBy?: string | undefined;
87
+ /** The caller's `aria-labelledby`, for group controls that name themselves rather than being named by `label for`. */
88
+ readonly ariaLabelledby?: string | undefined;
89
+ readonly name?: string | undefined;
90
+ readonly required?: boolean | undefined;
91
+ readonly invalid?: boolean | undefined;
92
+ readonly disabled?: boolean | undefined;
93
+ readonly readonly?: boolean | undefined;
94
+ }
95
+ /**
96
+ * The resolved attributes, ready to spread onto whichever node carries the
97
+ * control's ARIA.
98
+ *
99
+ * A key whose value resolved to `undefined` is **absent**, not present-and-
100
+ * undefined — `optional()` drops it. That is what makes the spread purely
101
+ * additive: `v-bind="{ ...rest, ...field.attrs }"` can never blank out an
102
+ * attribute the caller passed through fallthrough, so a control renders exactly
103
+ * what it renders today whenever there is no wrapper above it.
104
+ *
105
+ * `aria-required` and `aria-invalid` are omitted rather than set to `"false"`.
106
+ * Both are legal and both say nothing, and the absent attribute already means
107
+ * the same thing — the house `x || undefined` idiom, moved one layer in.
108
+ */
109
+ export interface FieldControlAttrs {
110
+ readonly id?: string;
111
+ readonly name?: string;
112
+ readonly "aria-describedby"?: string;
113
+ readonly "aria-required"?: "true";
114
+ readonly "aria-invalid"?: "true";
115
+ }
116
+ /**
117
+ * What `useFieldControl` resolved, after the control's own props won.
118
+ *
119
+ * Returned `reactive` rather than as a bag of refs, which is the one place in
120
+ * `src/lib/` that does so. A template unwraps only a *top-level* ref, and a
121
+ * control needs four of these at once under names — `disabled`, `invalid`,
122
+ * `readonly`, `required` — that each shadow a prop of the same name. `reactive`
123
+ * gives `field.invalid` in both the script and the template, and the shadowing
124
+ * question never arises. Destructuring it does lose reactivity; read through
125
+ * `field.` and there is nothing to get wrong.
126
+ */
127
+ export interface FieldControl {
128
+ /** Spread onto the node that carries the control's ARIA, **after** the fallthrough attrs. */
129
+ readonly attrs: FieldControlAttrs;
130
+ readonly id: string | undefined;
131
+ readonly labelledBy: string | undefined;
132
+ readonly name: string | undefined;
133
+ readonly disabled: boolean;
134
+ readonly invalid: boolean;
135
+ readonly readonly: boolean;
136
+ readonly required: boolean;
137
+ }
138
+ /**
139
+ * The wrapper above this one, for a wrapper that composes over another.
140
+ *
141
+ * Only Field needs it, and only for `readonly`: Vue resolves `inject` to the
142
+ * nearest provider **wholesale**, not per key, so a Field shadows the Fieldset
143
+ * above it entirely. Any key both wrappers answer has to be merged by hand, and
144
+ * reading the outer context here rather than merging inside
145
+ * `provideFieldContext` keeps that decision visible in Field.vue, where the
146
+ * reason for it lives.
147
+ */
148
+ export declare function useOuterFieldContext(): FieldContext | undefined;
149
+ /** Called by a wrapper — Field and Fieldset — from its own `setup`. */
150
+ export declare function provideFieldContext(source: FieldContextSource): void;
151
+ /**
152
+ * Opt a control into the wrapper around it. One call, one spread — see
153
+ * `TextField.vue`, which is the worked example the rest of the family copies.
154
+ *
155
+ * **The rule is `own ?? wrapper ?? false`.** `??` and not `||`, so an explicit
156
+ * `false` on the control beats a `true` from the wrapper: one control inside a
157
+ * row that is showing an error can declare itself individually fine, and one
158
+ * inside a clean row can declare itself individually invalid.
159
+ *
160
+ * That rule is worth nothing unless "unset" and "set to `false`" are still
161
+ * different values by the time they arrive here, and by default they are not:
162
+ * Vue resolves an absent `Boolean` prop with no declared default to `false`, so
163
+ * `props.invalid ?? field` would short-circuit forever and the context would be
164
+ * inert while looking perfectly wired. **Every participating prop must be
165
+ * declared `boolean | undefined` with an explicit `undefined` default** — the
166
+ * `| undefined` is what `exactOptionalPropertyTypes` needs to let `withDefaults`
167
+ * take that default at all, and the default is what beats the Boolean cast.
168
+ *
169
+ * With no wrapper above, every chain falls through to the control's own props
170
+ * and the `?? false` at the end is the same `false` the control's `withDefaults`
171
+ * used to supply. Nothing about a control standing alone changes.
172
+ *
173
+ * The argument is a **getter**, not a props object, for the reason
174
+ * `./attrs.ts` takes `useAttrs()` rather than a snapshot: a control feeds this a
175
+ * mix of props and fallthrough attrs and both have to stay live.
176
+ */
177
+ export declare function useFieldControl(own: () => FieldControlProps): FieldControl;
178
+ //# sourceMappingURL=field-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-context.d.ts","sourceRoot":"","sources":["../../src/lib/field-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ import { optional } from "./props.js";
2
+ import { computed, inject, onScopeDispose, provide, reactive, ref } from "vue";
3
+ //#region src/lib/field-context.ts
4
+ /**
5
+ * A `Symbol`, and not exported from `src/index.ts`: a consumer pinned to the
6
+ * key is pinned to a shape that moves whenever a wrapper does. `useFieldControl`
7
+ * is the supported way in.
8
+ */
9
+ var FIELD_CONTEXT = Symbol("loom.field");
10
+ /**
11
+ * The wrapper above this one, for a wrapper that composes over another.
12
+ *
13
+ * Only Field needs it, and only for `readonly`: Vue resolves `inject` to the
14
+ * nearest provider **wholesale**, not per key, so a Field shadows the Fieldset
15
+ * above it entirely. Any key both wrappers answer has to be merged by hand, and
16
+ * reading the outer context here rather than merging inside
17
+ * `provideFieldContext` keeps that decision visible in Field.vue, where the
18
+ * reason for it lives.
19
+ */
20
+ function useOuterFieldContext() {
21
+ return inject(FIELD_CONTEXT, void 0);
22
+ }
23
+ /** Called by a wrapper — Field and Fieldset — from its own `setup`. */
24
+ function provideFieldContext(source) {
25
+ const claims = ref([]);
26
+ provide(FIELD_CONTEXT, {
27
+ controlId: computed(source.controlId),
28
+ labelledBy: computed(source.labelledBy ?? (() => void 0)),
29
+ describedBy: computed(source.describedBy),
30
+ name: computed(source.name),
31
+ required: computed(source.required),
32
+ invalid: computed(source.invalid),
33
+ disabled: computed(source.disabled),
34
+ readonly: computed(source.readonly),
35
+ claimControlId() {
36
+ const token = Symbol("loom.field.control");
37
+ claims.value = [...claims.value, token];
38
+ onScopeDispose(() => {
39
+ claims.value = claims.value.filter((held) => held !== token);
40
+ });
41
+ return computed(() => claims.value[0] === token);
42
+ }
43
+ });
44
+ }
45
+ /**
46
+ * Opt a control into the wrapper around it. One call, one spread — see
47
+ * `TextField.vue`, which is the worked example the rest of the family copies.
48
+ *
49
+ * **The rule is `own ?? wrapper ?? false`.** `??` and not `||`, so an explicit
50
+ * `false` on the control beats a `true` from the wrapper: one control inside a
51
+ * row that is showing an error can declare itself individually fine, and one
52
+ * inside a clean row can declare itself individually invalid.
53
+ *
54
+ * That rule is worth nothing unless "unset" and "set to `false`" are still
55
+ * different values by the time they arrive here, and by default they are not:
56
+ * Vue resolves an absent `Boolean` prop with no declared default to `false`, so
57
+ * `props.invalid ?? field` would short-circuit forever and the context would be
58
+ * inert while looking perfectly wired. **Every participating prop must be
59
+ * declared `boolean | undefined` with an explicit `undefined` default** — the
60
+ * `| undefined` is what `exactOptionalPropertyTypes` needs to let `withDefaults`
61
+ * take that default at all, and the default is what beats the Boolean cast.
62
+ *
63
+ * With no wrapper above, every chain falls through to the control's own props
64
+ * and the `?? false` at the end is the same `false` the control's `withDefaults`
65
+ * used to supply. Nothing about a control standing alone changes.
66
+ *
67
+ * The argument is a **getter**, not a props object, for the reason
68
+ * `./attrs.ts` takes `useAttrs()` rather than a snapshot: a control feeds this a
69
+ * mix of props and fallthrough attrs and both have to stay live.
70
+ */
71
+ function useFieldControl(own) {
72
+ const field = inject(FIELD_CONTEXT, void 0);
73
+ const holdsControlId = field?.claimControlId();
74
+ const id = computed(() => own().id ?? (holdsControlId?.value === true ? field?.controlId.value : void 0));
75
+ const name = computed(() => own().name ?? field?.name.value);
76
+ const labelledBy = computed(() => own().ariaLabelledby ?? field?.labelledBy.value);
77
+ const describedBy = computed(() => {
78
+ const ids = [own().describedBy, field?.describedBy.value].filter((candidate) => candidate !== void 0 && candidate.length > 0);
79
+ return ids.length > 0 ? ids.join(" ") : void 0;
80
+ });
81
+ const required = computed(() => own().required ?? field?.required.value ?? false);
82
+ const invalid = computed(() => own().invalid ?? field?.invalid.value ?? false);
83
+ const disabled = computed(() => own().disabled ?? field?.disabled.value ?? false);
84
+ const readonly = computed(() => own().readonly ?? field?.readonly.value ?? false);
85
+ const attrs = computed(() => optional({
86
+ id: id.value,
87
+ name: name.value,
88
+ "aria-describedby": describedBy.value,
89
+ "aria-required": required.value ? "true" : void 0,
90
+ "aria-invalid": invalid.value ? "true" : void 0
91
+ }));
92
+ return reactive({
93
+ attrs,
94
+ id,
95
+ labelledBy,
96
+ name,
97
+ disabled,
98
+ invalid,
99
+ readonly,
100
+ required
101
+ });
102
+ }
103
+ //#endregion
104
+ export { provideFieldContext, useFieldControl, useOuterFieldContext };
105
+
106
+ //# sourceMappingURL=field-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-context.js","names":[],"sources":["../../src/lib/field-context.ts"],"sourcesContent":["import {\n computed,\n inject,\n onScopeDispose,\n provide,\n reactive,\n ref,\n watchEffect,\n type ComputedRef,\n type InjectionKey,\n} from \"vue\";\nimport { optional } from \"./props\";\n\n/**\n * What a form-row wrapper (Field, Fieldset) knows about the control inside it.\n *\n * A wrapper renders a `<label for>` and a hint-or-error line, and it is the\n * only thing in the tree that knows the id it pointed that label at, the id of\n * the message, and whether the row is mandatory or in error. None of that can\n * reach a slotted control through props — the wrapper never rendered it — so\n * before this existed the caller copied three attributes by hand at every call\n * site, and forgetting one was a silent accessibility defect.\n *\n * Every member is a `ComputedRef` rather than a value. A row's `error` arrives\n * and clears while the control stays mounted, so the context has to move with\n * it; and a per-key ref is what lets one wrapper inherit a single key from\n * another (Field reads `readonly` off a Fieldset above it) without a hidden\n * whole-object merge.\n *\n * On the booleans, `undefined` means \"this wrapper has no opinion\" and never\n * \"false\". That is the whole precedence story — see `useFieldControl` — and it\n * is the same distinction `./props.ts` exists to explain, arriving from the\n * other side: there, a key is dropped so a child sees an absence; here, an\n * absence is a value a wrapper is allowed to hold.\n */\nexport interface FieldContext {\n /** The id the primary control adopts, so the wrapper's `<label for>` names it. */\n readonly controlId: ComputedRef<string | undefined>;\n /** The id of the wrapper's `<label>`, for group controls to reference via `aria-labelledby`. */\n readonly labelledBy: ComputedRef<string | undefined>;\n /** The id of the hint-or-error line, and `undefined` while no message is rendered. */\n readonly describedBy: ComputedRef<string | undefined>;\n /** The form field name the control submits under. */\n readonly name: ComputedRef<string | undefined>;\n /** Whether the wrapper marks the row mandatory. Becomes `aria-required`. */\n readonly required: ComputedRef<boolean | undefined>;\n /** Whether the wrapper is showing an error, which is the same fact as the control being invalid. */\n readonly invalid: ComputedRef<boolean | undefined>;\n /** Whether the wrapper disables what is inside it. */\n readonly disabled: ComputedRef<boolean | undefined>;\n /** Whether the wrapper renders what is inside it read-only. */\n readonly readonly: ComputedRef<boolean | undefined>;\n /**\n * Claims the row's single control id, and reports whether this control won it.\n *\n * `<Field><TextField /><TextField /></Field>` is a shape somebody will write,\n * and without a claim both inputs adopt the same generated id — a duplicate\n * id, and a `<label for>` that resolves to whichever the browser reaches\n * first. The `axe` gate cannot be the backstop: `duplicate-id-active` is\n * tagged `wcag2a-obsolete`/`deprecated` in axe-core, not `wcag2a`, so it does\n * not match `WCAG_TAGS` and `e2e/accessibility.e2e.ts` never runs it.\n *\n * Reactive rather than a plain boolean because the claim can move: a `v-if`\n * swapping the first control for the second must promote the second, or the\n * label points at an id no longer in the document.\n */\n claimControlId(): ComputedRef<boolean>;\n}\n\n/**\n * What a wrapper hands `provideFieldContext`, as getters rather than values —\n * the wrapper writes plain expressions over its own props and this file does\n * the wrapping, so a wrapper never has to remember which of its answers are\n * derived.\n */\nexport interface FieldContextSource {\n controlId: () => string | undefined;\n labelledBy?: () => string | undefined;\n describedBy: () => string | undefined;\n name: () => string | undefined;\n required: () => boolean | undefined;\n invalid: () => boolean | undefined;\n disabled: () => boolean | undefined;\n readonly: () => boolean | undefined;\n}\n\n/**\n * The control's own side of the contract: what this control was told directly,\n * with `undefined` for everything the caller left unset.\n *\n * Each key is `?: T | undefined` rather than `?: T`. Under\n * `exactOptionalPropertyTypes` that is the form that accepts both an omitted\n * key and an explicit `undefined` — and an explicit `undefined` is exactly what\n * a control passes when its own prop is unset.\n */\nexport interface FieldControlProps {\n /** The caller's `id`, which reaches a bare control as a fallthrough attr rather than a prop. */\n readonly id?: string | undefined;\n /** The caller's `aria-describedby`, likewise a fallthrough attr. */\n readonly describedBy?: string | undefined;\n /** The caller's `aria-labelledby`, for group controls that name themselves rather than being named by `label for`. */\n readonly ariaLabelledby?: string | undefined;\n readonly name?: string | undefined;\n readonly required?: boolean | undefined;\n readonly invalid?: boolean | undefined;\n readonly disabled?: boolean | undefined;\n readonly readonly?: boolean | undefined;\n}\n\n/**\n * The resolved attributes, ready to spread onto whichever node carries the\n * control's ARIA.\n *\n * A key whose value resolved to `undefined` is **absent**, not present-and-\n * undefined — `optional()` drops it. That is what makes the spread purely\n * additive: `v-bind=\"{ ...rest, ...field.attrs }\"` can never blank out an\n * attribute the caller passed through fallthrough, so a control renders exactly\n * what it renders today whenever there is no wrapper above it.\n *\n * `aria-required` and `aria-invalid` are omitted rather than set to `\"false\"`.\n * Both are legal and both say nothing, and the absent attribute already means\n * the same thing — the house `x || undefined` idiom, moved one layer in.\n */\nexport interface FieldControlAttrs {\n readonly id?: string;\n readonly name?: string;\n readonly \"aria-describedby\"?: string;\n // Narrowed to the literal rather than `string`: Vue types `aria-invalid` on a\n // native element as `Booleanish | \"grammar\" | \"spelling\"`, so a widened\n // `string` here fails to spread onto the very `<input>` this exists for.\n readonly \"aria-required\"?: \"true\";\n readonly \"aria-invalid\"?: \"true\";\n}\n\n/**\n * What `useFieldControl` resolved, after the control's own props won.\n *\n * Returned `reactive` rather than as a bag of refs, which is the one place in\n * `src/lib/` that does so. A template unwraps only a *top-level* ref, and a\n * control needs four of these at once under names — `disabled`, `invalid`,\n * `readonly`, `required` — that each shadow a prop of the same name. `reactive`\n * gives `field.invalid` in both the script and the template, and the shadowing\n * question never arises. Destructuring it does lose reactivity; read through\n * `field.` and there is nothing to get wrong.\n */\nexport interface FieldControl {\n /** Spread onto the node that carries the control's ARIA, **after** the fallthrough attrs. */\n readonly attrs: FieldControlAttrs;\n readonly id: string | undefined;\n readonly labelledBy: string | undefined;\n readonly name: string | undefined;\n readonly disabled: boolean;\n readonly invalid: boolean;\n readonly readonly: boolean;\n readonly required: boolean;\n}\n\n/**\n * A `Symbol`, and not exported from `src/index.ts`: a consumer pinned to the\n * key is pinned to a shape that moves whenever a wrapper does. `useFieldControl`\n * is the supported way in.\n */\nconst FIELD_CONTEXT: InjectionKey<FieldContext> = Symbol(\"loom.field\");\n\n/**\n * The wrapper above this one, for a wrapper that composes over another.\n *\n * Only Field needs it, and only for `readonly`: Vue resolves `inject` to the\n * nearest provider **wholesale**, not per key, so a Field shadows the Fieldset\n * above it entirely. Any key both wrappers answer has to be merged by hand, and\n * reading the outer context here rather than merging inside\n * `provideFieldContext` keeps that decision visible in Field.vue, where the\n * reason for it lives.\n */\nexport function useOuterFieldContext(): FieldContext | undefined {\n return inject(FIELD_CONTEXT, undefined);\n}\n\n/** Called by a wrapper — Field and Fieldset — from its own `setup`. */\nexport function provideFieldContext(source: FieldContextSource): void {\n const claims = ref<symbol[]>([]);\n\n provide(FIELD_CONTEXT, {\n controlId: computed(source.controlId),\n labelledBy: computed(source.labelledBy ?? (() => undefined)),\n describedBy: computed(source.describedBy),\n name: computed(source.name),\n required: computed(source.required),\n invalid: computed(source.invalid),\n disabled: computed(source.disabled),\n readonly: computed(source.readonly),\n claimControlId() {\n const token = Symbol(\"loom.field.control\");\n claims.value = [...claims.value, token];\n // The claiming scope is the control's, not the wrapper's, so this fires\n // when that one control unmounts and the next in document order is\n // promoted.\n onScopeDispose(() => {\n claims.value = claims.value.filter((held) => held !== token);\n });\n return computed(() => claims.value[0] === token);\n },\n });\n}\n\n/**\n * Opt a control into the wrapper around it. One call, one spread — see\n * `TextField.vue`, which is the worked example the rest of the family copies.\n *\n * **The rule is `own ?? wrapper ?? false`.** `??` and not `||`, so an explicit\n * `false` on the control beats a `true` from the wrapper: one control inside a\n * row that is showing an error can declare itself individually fine, and one\n * inside a clean row can declare itself individually invalid.\n *\n * That rule is worth nothing unless \"unset\" and \"set to `false`\" are still\n * different values by the time they arrive here, and by default they are not:\n * Vue resolves an absent `Boolean` prop with no declared default to `false`, so\n * `props.invalid ?? field` would short-circuit forever and the context would be\n * inert while looking perfectly wired. **Every participating prop must be\n * declared `boolean | undefined` with an explicit `undefined` default** — the\n * `| undefined` is what `exactOptionalPropertyTypes` needs to let `withDefaults`\n * take that default at all, and the default is what beats the Boolean cast.\n *\n * With no wrapper above, every chain falls through to the control's own props\n * and the `?? false` at the end is the same `false` the control's `withDefaults`\n * used to supply. Nothing about a control standing alone changes.\n *\n * The argument is a **getter**, not a props object, for the reason\n * `./attrs.ts` takes `useAttrs()` rather than a snapshot: a control feeds this a\n * mix of props and fallthrough attrs and both have to stay live.\n */\nexport function useFieldControl(own: () => FieldControlProps): FieldControl {\n const field = inject(FIELD_CONTEXT, undefined);\n const holdsControlId = field?.claimControlId();\n\n const id = computed(\n () => own().id ?? (holdsControlId?.value === true ? field?.controlId.value : undefined),\n );\n const name = computed(() => own().name ?? field?.name.value);\n const labelledBy = computed(() => own().ariaLabelledby ?? field?.labelledBy.value);\n\n // The one attribute whose rule is merge rather than replace, because\n // `aria-describedby` is a token list: the row's message is additional to\n // whatever else the caller pointed at, not an alternative to it. Replacing\n // would silently drop the row's hint the moment a caller described their\n // control for some other reason — which is the defect this file exists to\n // remove, reintroduced from the other end. The control's own id reads first:\n // a control that has something to say about itself is saying the more\n // specific thing, and a screen reader reads the list in order.\n const describedBy = computed(() => {\n const ids = [own().describedBy, field?.describedBy.value].filter(\n (candidate): candidate is string => candidate !== undefined && candidate.length > 0,\n );\n return ids.length > 0 ? ids.join(\" \") : undefined;\n });\n\n const required = computed(() => own().required ?? field?.required.value ?? false);\n const invalid = computed(() => own().invalid ?? field?.invalid.value ?? false);\n const disabled = computed(() => own().disabled ?? field?.disabled.value ?? false);\n const readonly = computed(() => own().readonly ?? field?.readonly.value ?? false);\n\n // A development-mode safety net for the one context key a control can\n // deliberately decline. When a wrapper sets `readonly` but the control did\n // not pass that key in its `FieldControlProps`, the wrapper's instruction is\n // silently dropped — and without this warning the consumer has no signal\n // that it was. The `\"readonly\" in own()` check distinguishes \"I defer to the\n // wrapper\" (key present, value `undefined`) from \"I don't participate\" (key\n // absent), which is the same distinction `exactOptionalPropertyTypes` makes\n // at the type level.\n if (import.meta.env.DEV && field) {\n watchEffect(() => {\n if (field.readonly.value && !(\"readonly\" in own())) {\n console.warn(\"[Loom] readonly was set on the Field, but this control does not claim it.\");\n }\n });\n }\n\n const attrs = computed<FieldControlAttrs>(() =>\n optional({\n id: id.value,\n name: name.value,\n \"aria-describedby\": describedBy.value,\n \"aria-required\": required.value ? (\"true\" as const) : undefined,\n \"aria-invalid\": invalid.value ? (\"true\" as const) : undefined,\n }),\n );\n\n return reactive({ attrs, id, labelledBy, name, disabled, invalid, readonly, required });\n}\n"],"mappings":";;;;;;;;AAkKA,IAAM,gBAA4C,OAAO,YAAY;;;;;;;;;;;AAYrE,SAAgB,uBAAiD;CAC/D,OAAO,OAAO,eAAe,KAAA,CAAS;AACxC;;AAGA,SAAgB,oBAAoB,QAAkC;CACpE,MAAM,SAAS,IAAc,CAAC,CAAC;CAE/B,QAAQ,eAAe;EACrB,WAAW,SAAS,OAAO,SAAS;EACpC,YAAY,SAAS,OAAO,qBAAqB,KAAA,EAAU;EAC3D,aAAa,SAAS,OAAO,WAAW;EACxC,MAAM,SAAS,OAAO,IAAI;EAC1B,UAAU,SAAS,OAAO,QAAQ;EAClC,SAAS,SAAS,OAAO,OAAO;EAChC,UAAU,SAAS,OAAO,QAAQ;EAClC,UAAU,SAAS,OAAO,QAAQ;EAClC,iBAAiB;GACf,MAAM,QAAQ,OAAO,oBAAoB;GACzC,OAAO,QAAQ,CAAC,GAAG,OAAO,OAAO,KAAK;GAItC,qBAAqB;IACnB,OAAO,QAAQ,OAAO,MAAM,QAAQ,SAAS,SAAS,KAAK;GAC7D,CAAC;GACD,OAAO,eAAe,OAAO,MAAM,OAAO,KAAK;EACjD;CACF,CAAC;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,gBAAgB,KAA4C;CAC1E,MAAM,QAAQ,OAAO,eAAe,KAAA,CAAS;CAC7C,MAAM,iBAAiB,OAAO,eAAe;CAE7C,MAAM,KAAK,eACH,IAAI,CAAC,CAAC,OAAO,gBAAgB,UAAU,OAAO,OAAO,UAAU,QAAQ,KAAA,EAC/E;CACA,MAAM,OAAO,eAAe,IAAI,CAAC,CAAC,QAAQ,OAAO,KAAK,KAAK;CAC3D,MAAM,aAAa,eAAe,IAAI,CAAC,CAAC,kBAAkB,OAAO,WAAW,KAAK;CAUjF,MAAM,cAAc,eAAe;EACjC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,OAAO,YAAY,KAAK,CAAC,CAAC,QACvD,cAAmC,cAAc,KAAA,KAAa,UAAU,SAAS,CACpF;EACA,OAAO,IAAI,SAAS,IAAI,IAAI,KAAK,GAAG,IAAI,KAAA;CAC1C,CAAC;CAED,MAAM,WAAW,eAAe,IAAI,CAAC,CAAC,YAAY,OAAO,SAAS,SAAS,KAAK;CAChF,MAAM,UAAU,eAAe,IAAI,CAAC,CAAC,WAAW,OAAO,QAAQ,SAAS,KAAK;CAC7E,MAAM,WAAW,eAAe,IAAI,CAAC,CAAC,YAAY,OAAO,SAAS,SAAS,KAAK;CAChF,MAAM,WAAW,eAAe,IAAI,CAAC,CAAC,YAAY,OAAO,SAAS,SAAS,KAAK;CAkBhF,MAAM,QAAQ,eACZ,SAAS;EACP,IAAI,GAAG;EACP,MAAM,KAAK;EACX,oBAAoB,YAAY;EAChC,iBAAiB,SAAS,QAAS,SAAmB,KAAA;EACtD,gBAAgB,QAAQ,QAAS,SAAmB,KAAA;CACtD,CAAC,CACH;CAEA,OAAO,SAAS;EAAE;EAAO;EAAI;EAAY;EAAM;EAAU;EAAS;EAAU;CAAS,CAAC;AACxF"}
@@ -0,0 +1,75 @@
1
+ import type { CalendarPanelLabels, DateSegmentLabels, RangeCellLabels, TimeSegmentLabels } from "./date-labels";
2
+ import type { DateRangeLabels } from "../primitives/DateRangePicker/DateRangePicker.vue";
3
+ import type { DateTimeRangeLabels } from "../primitives/DateTimeRangePicker/DateTimeRangePicker.vue";
4
+ import type { ComboboxLabels } from "../primitives/Combobox/Combobox.vue";
5
+ import type { EditableLabels } from "../primitives/Editable/Editable.vue";
6
+ import type { FileUploadLabels } from "../primitives/FileUpload/FileUpload.vue";
7
+ import type { NumberFieldLabels } from "../primitives/NumberField/NumberField.vue";
8
+ import type { OtpInputLabels } from "../primitives/OtpInput/OtpInput.vue";
9
+ import type { PaginationLabels } from "../primitives/Pagination/Pagination.vue";
10
+ import type { RatingLabels } from "../primitives/Rating/Rating.vue";
11
+ import type { WindowControlsLabels } from "../primitives/WindowControls/WindowControls.vue";
12
+ import type { AvatarGroupLabels } from "../primitives/AvatarGroup/AvatarGroup.vue";
13
+ import type { ColorPickerLabels } from "../primitives/ColorPicker/ColorPicker.vue";
14
+ import type { IndicatorLabels } from "../primitives/Indicator/Indicator.vue";
15
+ import type { ProgressLabels } from "../primitives/Progress/Progress.vue";
16
+ import type { RadialProgressLabels } from "../primitives/RadialProgress/RadialProgress.vue";
17
+ import type { AlertDialogLabels } from "../primitives/AlertDialog/AlertDialog.vue";
18
+ import type { DialogLabels } from "../primitives/Dialog/Dialog.vue";
19
+ import type { DrawerLabels } from "../primitives/Drawer/Drawer.vue";
20
+ import type { StepperLabels } from "../primitives/Stepper/Stepper.vue";
21
+ import type { ToastLabels } from "../primitives/Toast/Toast.vue";
22
+ import type { TagsInputLabels } from "../primitives/TagsInput/TagsInput.vue";
23
+ import type { TextFieldLabels } from "../primitives/TextField/TextField.vue";
24
+ import type { TextareaLabels } from "../primitives/Textarea/Textarea.vue";
25
+ /**
26
+ * Every slot a host can localise, and nothing else. One line per component that
27
+ * speaks; the keys themselves live with the component that says them.
28
+ *
29
+ * This file exists so that both halves of the seam can be true at once. The
30
+ * *keys* belong beside the component — `PaginationLabels` is declared in
31
+ * `Pagination.vue`, where its doc comments sit next to the markup that renders
32
+ * them and where a component's whole contract can be read in one file. The
33
+ * *namespace* has to be central, or `provideLoomLabels({ pagination: … })` could
34
+ * not check a misspelled slot and a consumer would have no single place to see
35
+ * what the library can be asked to say.
36
+ *
37
+ * Every import here is `import type`, so this module emits nothing and the
38
+ * apparent cycle — component imports `useLabels`, `useLabels` imports this,
39
+ * this imports the component — exists only in the type graph, where TypeScript
40
+ * resolves it lazily. A value import in this file would turn the whole library
41
+ * into one chunk and cost every consumer the components they did not use.
42
+ *
43
+ * Adding a component to the sweep is one line. Adding it in the wrong shape is
44
+ * a compile error at that component's own `useLabels` call, not here.
45
+ */
46
+ export interface LoomLabels {
47
+ readonly pagination: PaginationLabels;
48
+ readonly windowControls: WindowControlsLabels;
49
+ readonly dateSegments: DateSegmentLabels;
50
+ readonly timeSegments: TimeSegmentLabels;
51
+ readonly calendarPanel: CalendarPanelLabels;
52
+ readonly rangeCell: RangeCellLabels;
53
+ readonly dateRange: DateRangeLabels;
54
+ readonly dateTimeRange: DateTimeRangeLabels;
55
+ readonly numberField: NumberFieldLabels;
56
+ readonly combobox: ComboboxLabels;
57
+ readonly otpInput: OtpInputLabels;
58
+ readonly fileUpload: FileUploadLabels;
59
+ readonly rating: RatingLabels;
60
+ readonly tagsInput: TagsInputLabels;
61
+ readonly editable: EditableLabels;
62
+ readonly textField: TextFieldLabels;
63
+ readonly textarea: TextareaLabels;
64
+ readonly dialog: DialogLabels;
65
+ readonly alertDialog: AlertDialogLabels;
66
+ readonly drawer: DrawerLabels;
67
+ readonly stepper: StepperLabels;
68
+ readonly toast: ToastLabels;
69
+ readonly indicator: IndicatorLabels;
70
+ readonly avatarGroup: AvatarGroupLabels;
71
+ readonly progress: ProgressLabels;
72
+ readonly radialProgress: RadialProgressLabels;
73
+ readonly colorPicker: ColorPickerLabels;
74
+ }
75
+ //# sourceMappingURL=label-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"label-registry.d.ts","sourceRoot":"","sources":["../../src/lib/label-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ import { type ComputedRef } from "vue";
2
+ import type { LoomLabels } from "./label-registry";
3
+ /**
4
+ * A message the component cannot write on its own, because it depends on a
5
+ * value only the render knows — a page number, a file name, a count.
6
+ *
7
+ * **The argument is one object, and every member is a raw value: a `number`, a
8
+ * `Date`, a `File`. Never a string Loom has already formatted.** That is the
9
+ * entire pluralisation answer, and it is why this library ships no
10
+ * pluralisation engine and takes no i18n dependency. "3 unread" has one form in
11
+ * Vietnamese, two in English, three in Russian and six in Arabic, and no
12
+ * placeholder syntax Loom could invent would carry that. Loom hands over the
13
+ * facts and receives a finished string; selecting the plural category, shaping
14
+ * the digits and ordering the sentence all happen in the consumer's own
15
+ * `Intl.PluralRules`, `Intl.NumberFormat`, vue-i18n, or hand-written `if`.
16
+ *
17
+ * Hand over the number and a consumer can reach `Intl.NumberFormat` for Eastern
18
+ * Arabic digits. Hand over `"3"` and they cannot: the decision was already made,
19
+ * in English, inside a component that had no business making it.
20
+ *
21
+ * One object rather than positional parameters, for two reasons. A bare
22
+ * `(4, 12)` in a consumer's locale file says nothing about what either number
23
+ * is. And a fact added later is a new key an existing override simply ignores,
24
+ * where a new positional parameter would silently re-order every call site.
25
+ *
26
+ * There is deliberately no third kind. A message is a `string` or it is one of
27
+ * these; a `string | (() => string)` union was considered and rejected, because
28
+ * the reactivity it exists to buy is already bought by `provideLoomLabels`
29
+ * taking a getter — and it would put a `resolve()` call around every binding in
30
+ * every component for the rest of the library's life.
31
+ */
32
+ export type LabelOf<Args extends object> = (args: Args) => string;
33
+ /**
34
+ * What a consumer may pass for one component's bag: any subset of it.
35
+ *
36
+ * **This, not the bag interface itself, is the type a consumer annotates their
37
+ * own object with.** A bag typed `PaginationLabels` must answer every key, so a
38
+ * key added in a later release breaks that consumer's build; a bag typed
39
+ * `LabelOverrides<PaginationLabels>` does not, which is what makes growing the
40
+ * vocabulary a `feat` rather than a `feat!`.
41
+ *
42
+ * `T[K] | undefined` rather than a plain `Partial<T>`, because
43
+ * `exactOptionalPropertyTypes` is on: under it `Partial<T>` rejects an
44
+ * explicitly-`undefined` value, and an explicit `undefined` is exactly what a
45
+ * consumer's own conditional expression produces when its condition is unmet.
46
+ * It has to mean "no opinion", never "blank this out" — the same distinction
47
+ * `./props.ts` exists to explain, arriving one layer in.
48
+ */
49
+ export type LabelOverrides<T extends object> = {
50
+ readonly [K in keyof T]?: T[K] | undefined;
51
+ };
52
+ /**
53
+ * A whole vocabulary, as a host supplies it: any subset of any slot.
54
+ *
55
+ * Both levels are partial and both are checked. A misspelled slot and a
56
+ * misspelled key inside a slot are each a compile error — on a fresh object
57
+ * literal, which is the caveat the localisation guide documents and the reason
58
+ * it tells a consumer to write `satisfies LoomLabelOverrides` on a bag they
59
+ * hoist to a module.
60
+ */
61
+ export type LoomLabelOverrides = {
62
+ readonly [K in keyof LoomLabels]?: LabelOverrides<LoomLabels[K]> | undefined;
63
+ };
64
+ /**
65
+ * Declare a host's vocabulary once, from the `setup` of its root component —
66
+ * the same place, and for the same reason, as `applyLoomIconDefaults`. It
67
+ * resolves to Vue's `provide()`, so called from a plain entry module it
68
+ * silently provides nothing and every component keeps its English.
69
+ *
70
+ * A **getter**, not a value, for the reason `./attrs.ts` takes `useAttrs()`
71
+ * rather than a snapshot: the getter runs inside the `computed` that
72
+ * `useLabels` returns, which runs inside the render effect, so a host whose bag
73
+ * reads `t("pager.next")` tracks their locale ref and every Loom component
74
+ * repaints on a language switch with no work here at all. Snapshot the bag
75
+ * instead and the first language renders correctly and every switch after it
76
+ * does nothing — a failure with no error and no warning.
77
+ *
78
+ * **A nested call merges into the bag above it rather than replacing it**, and
79
+ * that is a deliberate divergence from `./field-context.ts`, which documents
80
+ * the opposite and hand-merges the single key that needs it. Vue resolves
81
+ * `inject` wholesale to the nearest provider, so without this a host wrapping
82
+ * one dialog in a second `provideLoomLabels` to change one string would lose
83
+ * every other string in the application back to English. Hand-merging is right
84
+ * for two wrappers and one key; it does not scale to a vocabulary this size at
85
+ * an unknown depth.
86
+ */
87
+ export declare function provideLoomLabels(source: () => LoomLabelOverrides): void;
88
+ /**
89
+ * Resolve one component's slot: **own prop, then the host's vocabulary, then
90
+ * the component's own English** — key by key, never whole-object.
91
+ *
92
+ * Key by key is the whole point. A host providing `{ pagination: { next: "Sau" } }`
93
+ * keeps English for the other seven rather than rendering a row of unnamed
94
+ * buttons, and an instance overriding its own `nav` does not discard the host's
95
+ * other six. `optional()` is what makes each spread purely additive: it drops
96
+ * the `undefined`-valued keys, so an absent override cannot blank a present
97
+ * default. Same function, same reasoning, as the attribute spread in
98
+ * `./field-context.ts`.
99
+ *
100
+ * The prop beating the provider is not a preference. A page with two paginations
101
+ * that need different names has no other way out, and an application-wide
102
+ * vocabulary that could not be corrected per instance would force a host to
103
+ * choose between localising and naming.
104
+ *
105
+ * `defaults` arrives from the component rather than from a central English
106
+ * bundle, and that is what bounds the cost of the seam: a consumer importing
107
+ * only `Button` ships no label bytes at all, and one importing `Pagination`
108
+ * ships `Pagination`'s. A central `en` object would always ship whole.
109
+ *
110
+ * The result is typed from `defaults` rather than from `LoomLabels[K]`, with
111
+ * the registry entry as a constraint on it. Structurally that is the same
112
+ * check — a bag that does not match its registered slot does not compile — but
113
+ * it keeps the resolved type nameable from the module that declared it.
114
+ */
115
+ export declare function useLabels<K extends keyof LoomLabels, T extends LoomLabels[K]>(slot: K, defaults: T, own?: () => LabelOverrides<T> | undefined): ComputedRef<LoomLabels[K]>;
116
+ //# sourceMappingURL=labels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"labels.d.ts","sourceRoot":"","sources":["../../src/lib/labels.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,KAAK,WAAW,EAAqB,MAAM,KAAK,CAAC;AAErF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,MAAM,OAAO,CAAC,IAAI,SAAS,MAAM,IAAI,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;AAElE;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,MAAM,IAAI;IAC7C,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS;CAC3C,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,CAAC,IAAI,MAAM,UAAU,CAAC,CAAC,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS;CAC7E,CAAC;AA4BF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,kBAAkB,GAAG,IAAI,CAMxE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,UAAU,EAAE,CAAC,SAAS,UAAU,CAAC,CAAC,CAAC,EAC3E,IAAI,EAAE,CAAC,EACP,QAAQ,EAAE,CAAC,EACX,GAAG,CAAC,EAAE,MAAM,cAAc,CAAC,CAAC,CAAC,GAAG,SAAS,GACxC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAa5B"}
@@ -0,0 +1,84 @@
1
+ import { optional } from "./props.js";
2
+ import { computed, inject, provide } from "vue";
3
+ //#region src/lib/labels.ts
4
+ /**
5
+ * A `Symbol`, and not exported from `src/index.ts`, for the reason
6
+ * `./field-context.ts` gives about its own: a consumer pinned to the key is
7
+ * pinned to a shape that moves. `provideLoomLabels` is the supported way in.
8
+ */
9
+ var LOOM_LABELS = Symbol("loom.labels");
10
+ function mergeVocabularies(outer, inner) {
11
+ const merged = { ...outer };
12
+ const patches = inner;
13
+ for (const slot of Object.keys(patches)) {
14
+ const patch = patches[slot];
15
+ if (patch === void 0) continue;
16
+ merged[slot] = {
17
+ ...merged[slot] ?? {},
18
+ ...optional(patch)
19
+ };
20
+ }
21
+ return merged;
22
+ }
23
+ /**
24
+ * Declare a host's vocabulary once, from the `setup` of its root component —
25
+ * the same place, and for the same reason, as `applyLoomIconDefaults`. It
26
+ * resolves to Vue's `provide()`, so called from a plain entry module it
27
+ * silently provides nothing and every component keeps its English.
28
+ *
29
+ * A **getter**, not a value, for the reason `./attrs.ts` takes `useAttrs()`
30
+ * rather than a snapshot: the getter runs inside the `computed` that
31
+ * `useLabels` returns, which runs inside the render effect, so a host whose bag
32
+ * reads `t("pager.next")` tracks their locale ref and every Loom component
33
+ * repaints on a language switch with no work here at all. Snapshot the bag
34
+ * instead and the first language renders correctly and every switch after it
35
+ * does nothing — a failure with no error and no warning.
36
+ *
37
+ * **A nested call merges into the bag above it rather than replacing it**, and
38
+ * that is a deliberate divergence from `./field-context.ts`, which documents
39
+ * the opposite and hand-merges the single key that needs it. Vue resolves
40
+ * `inject` wholesale to the nearest provider, so without this a host wrapping
41
+ * one dialog in a second `provideLoomLabels` to change one string would lose
42
+ * every other string in the application back to English. Hand-merging is right
43
+ * for two wrappers and one key; it does not scale to a vocabulary this size at
44
+ * an unknown depth.
45
+ */
46
+ function provideLoomLabels(source) {
47
+ const outer = inject(LOOM_LABELS, void 0);
48
+ provide(LOOM_LABELS, computed(() => outer === void 0 ? source() : mergeVocabularies(outer.value, source())));
49
+ }
50
+ /**
51
+ * Resolve one component's slot: **own prop, then the host's vocabulary, then
52
+ * the component's own English** — key by key, never whole-object.
53
+ *
54
+ * Key by key is the whole point. A host providing `{ pagination: { next: "Sau" } }`
55
+ * keeps English for the other seven rather than rendering a row of unnamed
56
+ * buttons, and an instance overriding its own `nav` does not discard the host's
57
+ * other six. `optional()` is what makes each spread purely additive: it drops
58
+ * the `undefined`-valued keys, so an absent override cannot blank a present
59
+ * default. Same function, same reasoning, as the attribute spread in
60
+ * `./field-context.ts`.
61
+ *
62
+ * The prop beating the provider is not a preference. A page with two paginations
63
+ * that need different names has no other way out, and an application-wide
64
+ * vocabulary that could not be corrected per instance would force a host to
65
+ * choose between localising and naming.
66
+ *
67
+ * `defaults` arrives from the component rather than from a central English
68
+ * bundle, and that is what bounds the cost of the seam: a consumer importing
69
+ * only `Button` ships no label bytes at all, and one importing `Pagination`
70
+ * ships `Pagination`'s. A central `en` object would always ship whole.
71
+ *
72
+ * The result is typed from `defaults` rather than from `LoomLabels[K]`, with
73
+ * the registry entry as a constraint on it. Structurally that is the same
74
+ * check — a bag that does not match its registered slot does not compile — but
75
+ * it keeps the resolved type nameable from the module that declared it.
76
+ */
77
+ function useLabels(slot, defaults, own) {
78
+ const provided = inject(LOOM_LABELS, void 0);
79
+ return computed(() => Object.assign({}, defaults, optional(provided?.value[slot] ?? {}), optional(own?.() ?? {})));
80
+ }
81
+ //#endregion
82
+ export { provideLoomLabels, useLabels };
83
+
84
+ //# sourceMappingURL=labels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"labels.js","names":[],"sources":["../../src/lib/labels.ts"],"sourcesContent":["import { computed, inject, provide, type ComputedRef, type InjectionKey } from \"vue\";\nimport { optional } from \"./props\";\nimport type { LoomLabels } from \"./label-registry\";\n\n/**\n * A message the component cannot write on its own, because it depends on a\n * value only the render knows — a page number, a file name, a count.\n *\n * **The argument is one object, and every member is a raw value: a `number`, a\n * `Date`, a `File`. Never a string Loom has already formatted.** That is the\n * entire pluralisation answer, and it is why this library ships no\n * pluralisation engine and takes no i18n dependency. \"3 unread\" has one form in\n * Vietnamese, two in English, three in Russian and six in Arabic, and no\n * placeholder syntax Loom could invent would carry that. Loom hands over the\n * facts and receives a finished string; selecting the plural category, shaping\n * the digits and ordering the sentence all happen in the consumer's own\n * `Intl.PluralRules`, `Intl.NumberFormat`, vue-i18n, or hand-written `if`.\n *\n * Hand over the number and a consumer can reach `Intl.NumberFormat` for Eastern\n * Arabic digits. Hand over `\"3\"` and they cannot: the decision was already made,\n * in English, inside a component that had no business making it.\n *\n * One object rather than positional parameters, for two reasons. A bare\n * `(4, 12)` in a consumer's locale file says nothing about what either number\n * is. And a fact added later is a new key an existing override simply ignores,\n * where a new positional parameter would silently re-order every call site.\n *\n * There is deliberately no third kind. A message is a `string` or it is one of\n * these; a `string | (() => string)` union was considered and rejected, because\n * the reactivity it exists to buy is already bought by `provideLoomLabels`\n * taking a getter — and it would put a `resolve()` call around every binding in\n * every component for the rest of the library's life.\n */\nexport type LabelOf<Args extends object> = (args: Args) => string;\n\n/**\n * What a consumer may pass for one component's bag: any subset of it.\n *\n * **This, not the bag interface itself, is the type a consumer annotates their\n * own object with.** A bag typed `PaginationLabels` must answer every key, so a\n * key added in a later release breaks that consumer's build; a bag typed\n * `LabelOverrides<PaginationLabels>` does not, which is what makes growing the\n * vocabulary a `feat` rather than a `feat!`.\n *\n * `T[K] | undefined` rather than a plain `Partial<T>`, because\n * `exactOptionalPropertyTypes` is on: under it `Partial<T>` rejects an\n * explicitly-`undefined` value, and an explicit `undefined` is exactly what a\n * consumer's own conditional expression produces when its condition is unmet.\n * It has to mean \"no opinion\", never \"blank this out\" — the same distinction\n * `./props.ts` exists to explain, arriving one layer in.\n */\nexport type LabelOverrides<T extends object> = {\n readonly [K in keyof T]?: T[K] | undefined;\n};\n\n/**\n * A whole vocabulary, as a host supplies it: any subset of any slot.\n *\n * Both levels are partial and both are checked. A misspelled slot and a\n * misspelled key inside a slot are each a compile error — on a fresh object\n * literal, which is the caveat the localisation guide documents and the reason\n * it tells a consumer to write `satisfies LoomLabelOverrides` on a bag they\n * hoist to a module.\n */\nexport type LoomLabelOverrides = {\n readonly [K in keyof LoomLabels]?: LabelOverrides<LoomLabels[K]> | undefined;\n};\n\n/** The shape both merge steps work in, once the slot's identity has been checked. */\ntype AnyBag = Record<string, unknown>;\n\n/**\n * A `Symbol`, and not exported from `src/index.ts`, for the reason\n * `./field-context.ts` gives about its own: a consumer pinned to the key is\n * pinned to a shape that moves. `provideLoomLabels` is the supported way in.\n */\nconst LOOM_LABELS: InjectionKey<ComputedRef<LoomLabelOverrides>> = Symbol(\"loom.labels\");\n\nfunction mergeVocabularies(\n outer: LoomLabelOverrides,\n inner: LoomLabelOverrides,\n): LoomLabelOverrides {\n const merged = { ...outer } as AnyBag;\n const patches = inner as AnyBag;\n for (const slot of Object.keys(patches)) {\n const patch = patches[slot] as AnyBag | undefined;\n if (patch === undefined) continue;\n // Per key inside the slot as well as per slot: a nested provider changing\n // one string must not blank the rest of that slot back to English.\n merged[slot] = { ...((merged[slot] ?? {}) as AnyBag), ...optional(patch) };\n }\n return merged;\n}\n\n/**\n * Declare a host's vocabulary once, from the `setup` of its root component —\n * the same place, and for the same reason, as `applyLoomIconDefaults`. It\n * resolves to Vue's `provide()`, so called from a plain entry module it\n * silently provides nothing and every component keeps its English.\n *\n * A **getter**, not a value, for the reason `./attrs.ts` takes `useAttrs()`\n * rather than a snapshot: the getter runs inside the `computed` that\n * `useLabels` returns, which runs inside the render effect, so a host whose bag\n * reads `t(\"pager.next\")` tracks their locale ref and every Loom component\n * repaints on a language switch with no work here at all. Snapshot the bag\n * instead and the first language renders correctly and every switch after it\n * does nothing — a failure with no error and no warning.\n *\n * **A nested call merges into the bag above it rather than replacing it**, and\n * that is a deliberate divergence from `./field-context.ts`, which documents\n * the opposite and hand-merges the single key that needs it. Vue resolves\n * `inject` wholesale to the nearest provider, so without this a host wrapping\n * one dialog in a second `provideLoomLabels` to change one string would lose\n * every other string in the application back to English. Hand-merging is right\n * for two wrappers and one key; it does not scale to a vocabulary this size at\n * an unknown depth.\n */\nexport function provideLoomLabels(source: () => LoomLabelOverrides): void {\n const outer = inject(LOOM_LABELS, undefined);\n provide(\n LOOM_LABELS,\n computed(() => (outer === undefined ? source() : mergeVocabularies(outer.value, source()))),\n );\n}\n\n/**\n * Resolve one component's slot: **own prop, then the host's vocabulary, then\n * the component's own English** — key by key, never whole-object.\n *\n * Key by key is the whole point. A host providing `{ pagination: { next: \"Sau\" } }`\n * keeps English for the other seven rather than rendering a row of unnamed\n * buttons, and an instance overriding its own `nav` does not discard the host's\n * other six. `optional()` is what makes each spread purely additive: it drops\n * the `undefined`-valued keys, so an absent override cannot blank a present\n * default. Same function, same reasoning, as the attribute spread in\n * `./field-context.ts`.\n *\n * The prop beating the provider is not a preference. A page with two paginations\n * that need different names has no other way out, and an application-wide\n * vocabulary that could not be corrected per instance would force a host to\n * choose between localising and naming.\n *\n * `defaults` arrives from the component rather than from a central English\n * bundle, and that is what bounds the cost of the seam: a consumer importing\n * only `Button` ships no label bytes at all, and one importing `Pagination`\n * ships `Pagination`'s. A central `en` object would always ship whole.\n *\n * The result is typed from `defaults` rather than from `LoomLabels[K]`, with\n * the registry entry as a constraint on it. Structurally that is the same\n * check — a bag that does not match its registered slot does not compile — but\n * it keeps the resolved type nameable from the module that declared it.\n */\nexport function useLabels<K extends keyof LoomLabels, T extends LoomLabels[K]>(\n slot: K,\n defaults: T,\n own?: () => LabelOverrides<T> | undefined,\n): ComputedRef<LoomLabels[K]> {\n const provided = inject(LOOM_LABELS, undefined);\n // Read inside the `computed`, never above it: that is what puts the host's\n // getter and this component's props inside the render effect, and it is the\n // one line that decides whether a language switch repaints.\n //\n // `Object.assign` rather than an object spread, and that is a type-level\n // choice rather than a stylistic one: spreading a generic `LoomLabels[K]`\n // widens it to an index signature that no longer satisfies the return type,\n // where `Object.assign` composes an intersection that does.\n return computed(() =>\n Object.assign({}, defaults, optional(provided?.value[slot] ?? {}), optional(own?.() ?? {})),\n );\n}\n"],"mappings":";;;;;;;;AA4EA,IAAM,cAA6D,OAAO,aAAa;AAEvF,SAAS,kBACP,OACA,OACoB;CACpB,MAAM,SAAS,EAAE,GAAG,MAAM;CAC1B,MAAM,UAAU;CAChB,KAAK,MAAM,QAAQ,OAAO,KAAK,OAAO,GAAG;EACvC,MAAM,QAAQ,QAAQ;EACtB,IAAI,UAAU,KAAA,GAAW;EAGzB,OAAO,QAAQ;GAAE,GAAK,OAAO,SAAS,CAAC;GAAe,GAAG,SAAS,KAAK;EAAE;CAC3E;CACA,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,kBAAkB,QAAwC;CACxE,MAAM,QAAQ,OAAO,aAAa,KAAA,CAAS;CAC3C,QACE,aACA,eAAgB,UAAU,KAAA,IAAY,OAAO,IAAI,kBAAkB,MAAM,OAAO,OAAO,CAAC,CAAE,CAC5F;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,UACd,MACA,UACA,KAC4B;CAC5B,MAAM,WAAW,OAAO,aAAa,KAAA,CAAS;CAS9C,OAAO,eACL,OAAO,OAAO,CAAC,GAAG,UAAU,SAAS,UAAU,MAAM,SAAS,CAAC,CAAC,GAAG,SAAS,MAAM,KAAK,CAAC,CAAC,CAAC,CAC5F;AACF"}