@ecoma-io/loom 0.1.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 (259) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +180 -0
  3. package/dist/a11y.d.ts +2 -0
  4. package/dist/a11y.d.ts.map +1 -0
  5. package/dist/a11y.js +2 -0
  6. package/dist/blocks/AppHeader/AppHeader.js +7 -0
  7. package/dist/blocks/AppHeader/AppHeader.js.map +1 -0
  8. package/dist/blocks/AppHeader/AppHeader.vue.d.ts +83 -0
  9. package/dist/blocks/AppHeader/AppHeader.vue.d.ts.map +1 -0
  10. package/dist/blocks/AppHeader/AppHeader.vue_vue_type_script_setup_true_lang.js +96 -0
  11. package/dist/blocks/AppHeader/AppHeader.vue_vue_type_script_setup_true_lang.js.map +1 -0
  12. package/dist/blocks/DashboardGrid/DashboardGrid.js +7 -0
  13. package/dist/blocks/DashboardGrid/DashboardGrid.js.map +1 -0
  14. package/dist/blocks/DashboardGrid/DashboardGrid.vue.d.ts +42 -0
  15. package/dist/blocks/DashboardGrid/DashboardGrid.vue.d.ts.map +1 -0
  16. package/dist/blocks/DashboardGrid/DashboardGrid.vue_vue_type_script_setup_true_lang.js +45 -0
  17. package/dist/blocks/DashboardGrid/DashboardGrid.vue_vue_type_script_setup_true_lang.js.map +1 -0
  18. package/dist/blocks/EmptyState/EmptyState.js +7 -0
  19. package/dist/blocks/EmptyState/EmptyState.js.map +1 -0
  20. package/dist/blocks/EmptyState/EmptyState.vue.d.ts +50 -0
  21. package/dist/blocks/EmptyState/EmptyState.vue.d.ts.map +1 -0
  22. package/dist/blocks/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js +71 -0
  23. package/dist/blocks/EmptyState/EmptyState.vue_vue_type_script_setup_true_lang.js.map +1 -0
  24. package/dist/blocks/PageHeader/PageHeader.js +7 -0
  25. package/dist/blocks/PageHeader/PageHeader.js.map +1 -0
  26. package/dist/blocks/PageHeader/PageHeader.vue.d.ts +54 -0
  27. package/dist/blocks/PageHeader/PageHeader.vue.d.ts.map +1 -0
  28. package/dist/blocks/PageHeader/PageHeader.vue_vue_type_script_setup_true_lang.js +68 -0
  29. package/dist/blocks/PageHeader/PageHeader.vue_vue_type_script_setup_true_lang.js.map +1 -0
  30. package/dist/blocks/RowActions/RowActions.js +7 -0
  31. package/dist/blocks/RowActions/RowActions.js.map +1 -0
  32. package/dist/blocks/RowActions/RowActions.vue.d.ts +14 -0
  33. package/dist/blocks/RowActions/RowActions.vue.d.ts.map +1 -0
  34. package/dist/blocks/RowActions/RowActions.vue_vue_type_script_setup_true_lang.js +47 -0
  35. package/dist/blocks/RowActions/RowActions.vue_vue_type_script_setup_true_lang.js.map +1 -0
  36. package/dist/blocks/SidebarNav/SidebarNav.js +7 -0
  37. package/dist/blocks/SidebarNav/SidebarNav.js.map +1 -0
  38. package/dist/blocks/SidebarNav/SidebarNav.vue.d.ts +40 -0
  39. package/dist/blocks/SidebarNav/SidebarNav.vue.d.ts.map +1 -0
  40. package/dist/blocks/SidebarNav/SidebarNav.vue_vue_type_script_setup_true_lang.js +125 -0
  41. package/dist/blocks/SidebarNav/SidebarNav.vue_vue_type_script_setup_true_lang.js.map +1 -0
  42. package/dist/blocks/TitleBar/TitleBar.js +7 -0
  43. package/dist/blocks/TitleBar/TitleBar.js.map +1 -0
  44. package/dist/blocks/TitleBar/TitleBar.vue.d.ts +49 -0
  45. package/dist/blocks/TitleBar/TitleBar.vue.d.ts.map +1 -0
  46. package/dist/blocks/TitleBar/TitleBar.vue_vue_type_script_setup_true_lang.js +66 -0
  47. package/dist/blocks/TitleBar/TitleBar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  48. package/dist/blocks/ToastStack/ToastStack.js +7 -0
  49. package/dist/blocks/ToastStack/ToastStack.js.map +1 -0
  50. package/dist/blocks/ToastStack/ToastStack.vue.d.ts +24 -0
  51. package/dist/blocks/ToastStack/ToastStack.vue.d.ts.map +1 -0
  52. package/dist/blocks/ToastStack/ToastStack.vue_vue_type_script_setup_true_lang.js +38 -0
  53. package/dist/blocks/ToastStack/ToastStack.vue_vue_type_script_setup_true_lang.js.map +1 -0
  54. package/dist/icons/BrandMark.d.ts +18 -0
  55. package/dist/icons/BrandMark.d.ts.map +1 -0
  56. package/dist/icons/BrandMark.js +47 -0
  57. package/dist/icons/BrandMark.js.map +1 -0
  58. package/dist/index.d.ts +75 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +46 -0
  61. package/dist/lib/a11y-scope.d.ts +19 -0
  62. package/dist/lib/a11y-scope.d.ts.map +1 -0
  63. package/dist/lib/a11y-scope.js +28 -0
  64. package/dist/lib/a11y-scope.js.map +1 -0
  65. package/dist/lib/attrs.d.ts +18 -0
  66. package/dist/lib/attrs.d.ts.map +1 -0
  67. package/dist/lib/attrs.js +28 -0
  68. package/dist/lib/attrs.js.map +1 -0
  69. package/dist/lib/cn.d.ts +9 -0
  70. package/dist/lib/cn.d.ts.map +1 -0
  71. package/dist/lib/cn.js +16 -0
  72. package/dist/lib/cn.js.map +1 -0
  73. package/dist/lib/icon-defaults.d.ts +22 -0
  74. package/dist/lib/icon-defaults.d.ts.map +1 -0
  75. package/dist/lib/icon-defaults.js +32 -0
  76. package/dist/lib/icon-defaults.js.map +1 -0
  77. package/dist/lib/motion.d.ts +14 -0
  78. package/dist/lib/motion.d.ts.map +1 -0
  79. package/dist/lib/motion.js +20 -0
  80. package/dist/lib/motion.js.map +1 -0
  81. package/dist/lib/props.d.ts +31 -0
  82. package/dist/lib/props.d.ts.map +1 -0
  83. package/dist/lib/props.js +37 -0
  84. package/dist/lib/props.js.map +1 -0
  85. package/dist/primitives/Avatar/Avatar.js +7 -0
  86. package/dist/primitives/Avatar/Avatar.js.map +1 -0
  87. package/dist/primitives/Avatar/Avatar.vue.d.ts +27 -0
  88. package/dist/primitives/Avatar/Avatar.vue.d.ts.map +1 -0
  89. package/dist/primitives/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js +33 -0
  90. package/dist/primitives/Avatar/Avatar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  91. package/dist/primitives/Badge/Badge.js +7 -0
  92. package/dist/primitives/Badge/Badge.js.map +1 -0
  93. package/dist/primitives/Badge/Badge.vue.d.ts +27 -0
  94. package/dist/primitives/Badge/Badge.vue.d.ts.map +1 -0
  95. package/dist/primitives/Badge/Badge.vue_vue_type_script_setup_true_lang.js +30 -0
  96. package/dist/primitives/Badge/Badge.vue_vue_type_script_setup_true_lang.js.map +1 -0
  97. package/dist/primitives/Button/Button.js +7 -0
  98. package/dist/primitives/Button/Button.js.map +1 -0
  99. package/dist/primitives/Button/Button.vue.d.ts +70 -0
  100. package/dist/primitives/Button/Button.vue.d.ts.map +1 -0
  101. package/dist/primitives/Button/Button.vue_vue_type_script_setup_true_lang.js +122 -0
  102. package/dist/primitives/Button/Button.vue_vue_type_script_setup_true_lang.js.map +1 -0
  103. package/dist/primitives/Checkbox/Checkbox.js +7 -0
  104. package/dist/primitives/Checkbox/Checkbox.js.map +1 -0
  105. package/dist/primitives/Checkbox/Checkbox.vue.d.ts +34 -0
  106. package/dist/primitives/Checkbox/Checkbox.vue.d.ts.map +1 -0
  107. package/dist/primitives/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js +94 -0
  108. package/dist/primitives/Checkbox/Checkbox.vue_vue_type_script_setup_true_lang.js.map +1 -0
  109. package/dist/primitives/Dialog/Dialog.js +7 -0
  110. package/dist/primitives/Dialog/Dialog.js.map +1 -0
  111. package/dist/primitives/Dialog/Dialog.vue.d.ts +58 -0
  112. package/dist/primitives/Dialog/Dialog.vue.d.ts.map +1 -0
  113. package/dist/primitives/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js +88 -0
  114. package/dist/primitives/Dialog/Dialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  115. package/dist/primitives/DropdownMenu/DropdownMenu.js +7 -0
  116. package/dist/primitives/DropdownMenu/DropdownMenu.js.map +1 -0
  117. package/dist/primitives/DropdownMenu/DropdownMenu.vue.d.ts +55 -0
  118. package/dist/primitives/DropdownMenu/DropdownMenu.vue.d.ts.map +1 -0
  119. package/dist/primitives/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js +82 -0
  120. package/dist/primitives/DropdownMenu/DropdownMenu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  121. package/dist/primitives/Field/Field.js +7 -0
  122. package/dist/primitives/Field/Field.js.map +1 -0
  123. package/dist/primitives/Field/Field.vue.d.ts +53 -0
  124. package/dist/primitives/Field/Field.vue.d.ts.map +1 -0
  125. package/dist/primitives/Field/Field.vue_vue_type_script_setup_true_lang.js +84 -0
  126. package/dist/primitives/Field/Field.vue_vue_type_script_setup_true_lang.js.map +1 -0
  127. package/dist/primitives/InlineError/InlineError.js +7 -0
  128. package/dist/primitives/InlineError/InlineError.js.map +1 -0
  129. package/dist/primitives/InlineError/InlineError.vue.d.ts +32 -0
  130. package/dist/primitives/InlineError/InlineError.vue.d.ts.map +1 -0
  131. package/dist/primitives/InlineError/InlineError.vue_vue_type_script_setup_true_lang.js +44 -0
  132. package/dist/primitives/InlineError/InlineError.vue_vue_type_script_setup_true_lang.js.map +1 -0
  133. package/dist/primitives/Menubar/Menubar.js +7 -0
  134. package/dist/primitives/Menubar/Menubar.js.map +1 -0
  135. package/dist/primitives/Menubar/Menubar.vue.d.ts +41 -0
  136. package/dist/primitives/Menubar/Menubar.vue.d.ts.map +1 -0
  137. package/dist/primitives/Menubar/Menubar.vue_vue_type_script_setup_true_lang.js +184 -0
  138. package/dist/primitives/Menubar/Menubar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  139. package/dist/primitives/NumberField/NumberField.js +7 -0
  140. package/dist/primitives/NumberField/NumberField.js.map +1 -0
  141. package/dist/primitives/NumberField/NumberField.vue.d.ts +47 -0
  142. package/dist/primitives/NumberField/NumberField.vue.d.ts.map +1 -0
  143. package/dist/primitives/NumberField/NumberField.vue_vue_type_script_setup_true_lang.js +204 -0
  144. package/dist/primitives/NumberField/NumberField.vue_vue_type_script_setup_true_lang.js.map +1 -0
  145. package/dist/primitives/Popover/Popover.js +7 -0
  146. package/dist/primitives/Popover/Popover.js.map +1 -0
  147. package/dist/primitives/Popover/Popover.vue.d.ts +61 -0
  148. package/dist/primitives/Popover/Popover.vue.d.ts.map +1 -0
  149. package/dist/primitives/Popover/Popover.vue_vue_type_script_setup_true_lang.js +59 -0
  150. package/dist/primitives/Popover/Popover.vue_vue_type_script_setup_true_lang.js.map +1 -0
  151. package/dist/primitives/Progress/Progress.js +7 -0
  152. package/dist/primitives/Progress/Progress.js.map +1 -0
  153. package/dist/primitives/Progress/Progress.vue.d.ts +30 -0
  154. package/dist/primitives/Progress/Progress.vue.d.ts.map +1 -0
  155. package/dist/primitives/Progress/Progress.vue_vue_type_script_setup_true_lang.js +67 -0
  156. package/dist/primitives/Progress/Progress.vue_vue_type_script_setup_true_lang.js.map +1 -0
  157. package/dist/primitives/RadioGroup/RadioGroup.js +7 -0
  158. package/dist/primitives/RadioGroup/RadioGroup.js.map +1 -0
  159. package/dist/primitives/RadioGroup/RadioGroup.vue.d.ts +39 -0
  160. package/dist/primitives/RadioGroup/RadioGroup.vue.d.ts.map +1 -0
  161. package/dist/primitives/RadioGroup/RadioGroup.vue_vue_type_script_setup_true_lang.js +63 -0
  162. package/dist/primitives/RadioGroup/RadioGroup.vue_vue_type_script_setup_true_lang.js.map +1 -0
  163. package/dist/primitives/SegmentedControl/SegmentedControl.js +7 -0
  164. package/dist/primitives/SegmentedControl/SegmentedControl.js.map +1 -0
  165. package/dist/primitives/SegmentedControl/SegmentedControl.vue.d.ts +40 -0
  166. package/dist/primitives/SegmentedControl/SegmentedControl.vue.d.ts.map +1 -0
  167. package/dist/primitives/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js +89 -0
  168. package/dist/primitives/SegmentedControl/SegmentedControl.vue_vue_type_script_setup_true_lang.js.map +1 -0
  169. package/dist/primitives/Select/Select.js +7 -0
  170. package/dist/primitives/Select/Select.js.map +1 -0
  171. package/dist/primitives/Select/Select.vue.d.ts +56 -0
  172. package/dist/primitives/Select/Select.vue.d.ts.map +1 -0
  173. package/dist/primitives/Select/Select.vue_vue_type_script_setup_true_lang.js +122 -0
  174. package/dist/primitives/Select/Select.vue_vue_type_script_setup_true_lang.js.map +1 -0
  175. package/dist/primitives/Separator/Separator.js +7 -0
  176. package/dist/primitives/Separator/Separator.js.map +1 -0
  177. package/dist/primitives/Separator/Separator.vue.d.ts +19 -0
  178. package/dist/primitives/Separator/Separator.vue.d.ts.map +1 -0
  179. package/dist/primitives/Separator/Separator.vue_vue_type_script_setup_true_lang.js +31 -0
  180. package/dist/primitives/Separator/Separator.vue_vue_type_script_setup_true_lang.js.map +1 -0
  181. package/dist/primitives/Skeleton/Skeleton.js +7 -0
  182. package/dist/primitives/Skeleton/Skeleton.js.map +1 -0
  183. package/dist/primitives/Skeleton/Skeleton.vue.d.ts +16 -0
  184. package/dist/primitives/Skeleton/Skeleton.vue.d.ts.map +1 -0
  185. package/dist/primitives/Skeleton/Skeleton.vue_vue_type_script_setup_true_lang.js +37 -0
  186. package/dist/primitives/Skeleton/Skeleton.vue_vue_type_script_setup_true_lang.js.map +1 -0
  187. package/dist/primitives/Slider/Slider.js +7 -0
  188. package/dist/primitives/Slider/Slider.js.map +1 -0
  189. package/dist/primitives/Slider/Slider.vue.d.ts +58 -0
  190. package/dist/primitives/Slider/Slider.vue.d.ts.map +1 -0
  191. package/dist/primitives/Slider/Slider.vue_vue_type_script_setup_true_lang.js +137 -0
  192. package/dist/primitives/Slider/Slider.vue_vue_type_script_setup_true_lang.js.map +1 -0
  193. package/dist/primitives/Spinner/Spinner.js +7 -0
  194. package/dist/primitives/Spinner/Spinner.js.map +1 -0
  195. package/dist/primitives/Spinner/Spinner.vue.d.ts +21 -0
  196. package/dist/primitives/Spinner/Spinner.vue.d.ts.map +1 -0
  197. package/dist/primitives/Spinner/Spinner.vue_vue_type_script_setup_true_lang.js +63 -0
  198. package/dist/primitives/Spinner/Spinner.vue_vue_type_script_setup_true_lang.js.map +1 -0
  199. package/dist/primitives/Surface/Surface.js +7 -0
  200. package/dist/primitives/Surface/Surface.js.map +1 -0
  201. package/dist/primitives/Surface/Surface.vue.d.ts +42 -0
  202. package/dist/primitives/Surface/Surface.vue.d.ts.map +1 -0
  203. package/dist/primitives/Surface/Surface.vue_vue_type_script_setup_true_lang.js +48 -0
  204. package/dist/primitives/Surface/Surface.vue_vue_type_script_setup_true_lang.js.map +1 -0
  205. package/dist/primitives/Switch/Switch.js +7 -0
  206. package/dist/primitives/Switch/Switch.js.map +1 -0
  207. package/dist/primitives/Switch/Switch.vue.d.ts +24 -0
  208. package/dist/primitives/Switch/Switch.vue.d.ts.map +1 -0
  209. package/dist/primitives/Switch/Switch.vue_vue_type_script_setup_true_lang.js +44 -0
  210. package/dist/primitives/Switch/Switch.vue_vue_type_script_setup_true_lang.js.map +1 -0
  211. package/dist/primitives/Tabs/Tabs.js +7 -0
  212. package/dist/primitives/Tabs/Tabs.js.map +1 -0
  213. package/dist/primitives/Tabs/Tabs.vue.d.ts +33 -0
  214. package/dist/primitives/Tabs/Tabs.vue.d.ts.map +1 -0
  215. package/dist/primitives/Tabs/Tabs.vue_vue_type_script_setup_true_lang.js +54 -0
  216. package/dist/primitives/Tabs/Tabs.vue_vue_type_script_setup_true_lang.js.map +1 -0
  217. package/dist/primitives/TextField/TextField.js +7 -0
  218. package/dist/primitives/TextField/TextField.js.map +1 -0
  219. package/dist/primitives/TextField/TextField.vue.d.ts +58 -0
  220. package/dist/primitives/TextField/TextField.vue.d.ts.map +1 -0
  221. package/dist/primitives/TextField/TextField.vue_vue_type_script_setup_true_lang.js +71 -0
  222. package/dist/primitives/TextField/TextField.vue_vue_type_script_setup_true_lang.js.map +1 -0
  223. package/dist/primitives/Textarea/Textarea.js +7 -0
  224. package/dist/primitives/Textarea/Textarea.js.map +1 -0
  225. package/dist/primitives/Textarea/Textarea.vue.d.ts +48 -0
  226. package/dist/primitives/Textarea/Textarea.vue.d.ts.map +1 -0
  227. package/dist/primitives/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js +54 -0
  228. package/dist/primitives/Textarea/Textarea.vue_vue_type_script_setup_true_lang.js.map +1 -0
  229. package/dist/primitives/Toast/Toast.js +7 -0
  230. package/dist/primitives/Toast/Toast.js.map +1 -0
  231. package/dist/primitives/Toast/Toast.vue.d.ts +46 -0
  232. package/dist/primitives/Toast/Toast.vue.d.ts.map +1 -0
  233. package/dist/primitives/Toast/Toast.vue_vue_type_script_setup_true_lang.js +52 -0
  234. package/dist/primitives/Toast/Toast.vue_vue_type_script_setup_true_lang.js.map +1 -0
  235. package/dist/primitives/Toast/ToastItem.js +7 -0
  236. package/dist/primitives/Toast/ToastItem.js.map +1 -0
  237. package/dist/primitives/Toast/ToastItem.vue.d.ts +38 -0
  238. package/dist/primitives/Toast/ToastItem.vue.d.ts.map +1 -0
  239. package/dist/primitives/Toast/ToastItem.vue_vue_type_script_setup_true_lang.js +114 -0
  240. package/dist/primitives/Toast/ToastItem.vue_vue_type_script_setup_true_lang.js.map +1 -0
  241. package/dist/primitives/Tooltip/Tooltip.js +7 -0
  242. package/dist/primitives/Tooltip/Tooltip.js.map +1 -0
  243. package/dist/primitives/Tooltip/Tooltip.vue.d.ts +52 -0
  244. package/dist/primitives/Tooltip/Tooltip.vue.d.ts.map +1 -0
  245. package/dist/primitives/Tooltip/Tooltip.vue_vue_type_script_setup_true_lang.js +56 -0
  246. package/dist/primitives/Tooltip/Tooltip.vue_vue_type_script_setup_true_lang.js.map +1 -0
  247. package/dist/primitives/WindowControls/WindowControls.js +7 -0
  248. package/dist/primitives/WindowControls/WindowControls.js.map +1 -0
  249. package/dist/primitives/WindowControls/WindowControls.vue.d.ts +41 -0
  250. package/dist/primitives/WindowControls/WindowControls.vue.d.ts.map +1 -0
  251. package/dist/primitives/WindowControls/WindowControls.vue_vue_type_script_setup_true_lang.js +111 -0
  252. package/dist/primitives/WindowControls/WindowControls.vue_vue_type_script_setup_true_lang.js.map +1 -0
  253. package/dist/styles/fonts/Geist-Variable.woff2 +0 -0
  254. package/dist/styles/fonts/GeistMono-Variable.woff2 +0 -0
  255. package/dist/styles/fonts/OFL.txt +92 -0
  256. package/dist/styles/fonts.css +30 -0
  257. package/dist/styles/global.css +181 -0
  258. package/dist/styles/theme.css +212 -0
  259. package/package.json +123 -0
@@ -0,0 +1,56 @@
1
+ /** One row of the list. `value` is what the model carries; `label` is what a reader sees. */
2
+ export interface SelectOption {
3
+ /** The value bound to `v-model` when this row is chosen. Unique within the list. */
4
+ value: string;
5
+ /** The text shown on the row, and on the trigger once it is chosen. */
6
+ label: string;
7
+ /** Present but unchoosable — visible, skipped by the keyboard, unclickable. */
8
+ disabled?: boolean;
9
+ }
10
+ /**
11
+ * The trigger's height scale. It matches the text input scale exactly, so a
12
+ * form row mixing a Select beside a text field never comes out uneven — which
13
+ * is why reaching past `size` for an `h-*` class is always the wrong fix.
14
+ */
15
+ export type SelectSize = "sm" | "md" | "lg";
16
+ export declare const selectVariants: (props?: ({
17
+ size?: "sm" | "md" | "lg" | null | undefined;
18
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
19
+ declare const _default: typeof __VLS_export;
20
+ export default _default;
21
+ declare const __VLS_export: import("vue").DefineComponent<{
22
+ /** The chosen option's `value`. Leave it unset to show the placeholder. */
23
+ modelValue?: string;
24
+ /** The rows, in the order they are shown. */
25
+ options: SelectOption[];
26
+ /** Shown on the trigger while nothing is chosen. It is not an option. */
27
+ placeholder?: string;
28
+ /** Unavailable: dims the trigger and refuses to open. */
29
+ disabled?: boolean;
30
+ /** Error state: paints the destructive border and ring, and sets `aria-invalid`. */
31
+ invalid?: boolean;
32
+ /** Trigger height. It shares the text input scale so mixed form rows stay aligned. */
33
+ size?: SelectSize;
34
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
35
+ "update:modelValue": (value: string) => any;
36
+ }, string, import("vue").PublicProps, Readonly<{
37
+ /** The chosen option's `value`. Leave it unset to show the placeholder. */
38
+ modelValue?: string;
39
+ /** The rows, in the order they are shown. */
40
+ options: SelectOption[];
41
+ /** Shown on the trigger while nothing is chosen. It is not an option. */
42
+ placeholder?: string;
43
+ /** Unavailable: dims the trigger and refuses to open. */
44
+ disabled?: boolean;
45
+ /** Error state: paints the destructive border and ring, and sets `aria-invalid`. */
46
+ invalid?: boolean;
47
+ /** Trigger height. It shares the text input scale so mixed form rows stay aligned. */
48
+ size?: SelectSize;
49
+ }> & Readonly<{
50
+ "onUpdate:modelValue"?: (value: string) => any;
51
+ }>, {
52
+ size: SelectSize;
53
+ disabled: boolean;
54
+ invalid: boolean;
55
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
56
+ //# sourceMappingURL=Select.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Select.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Select/Select.vue"],"names":[],"mappings":"AAkNA,6FAA6F;AAC7F,MAAM,WAAW,YAAY;IAC3B,oFAAoF;IACpF,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C,eAAO,MAAM,cAAc;;8EAqB1B,CAAC;wBACmB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAkBd,2EAA2E;iBAC9D,MAAM;IACnB,6CAA6C;aACpC,YAAY,EAAE;IACvB,yEAAyE;kBAC3D,MAAM;IACpB,yDAAyD;eAC9C,OAAO;IAClB,oFAAoF;cAC1E,OAAO;IACjB,sFAAsF;WAC/E,UAAU;;;;IAXjB,2EAA2E;iBAC9D,MAAM;IACnB,6CAA6C;aACpC,YAAY,EAAE;IACvB,yEAAyE;kBAC3D,MAAM;IACpB,yDAAyD;eAC9C,OAAO;IAClB,oFAAoF;cAC1E,OAAO;IACjB,sFAAsF;WAC/E,UAAU;;;;UAAV,UAAU;cAJN,OAAO;aAER,OAAO;6EAyUjB,CAAC"}
@@ -0,0 +1,122 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { listStaggerDelay } from "../../lib/motion.js";
3
+ import { useSplitAttrs } from "../../lib/attrs.js";
4
+ import { Check, ChevronDown } from "@lucide/vue";
5
+ import { Fragment, createBlock, createElementBlock, createTextVNode, createVNode, defineComponent, mergeProps, normalizeClass, normalizeStyle, openBlock, renderList, toDisplayString, unref, withCtx } from "vue";
6
+ import { SelectContent, SelectIcon, SelectItem, SelectItemIndicator, SelectItemText, SelectPortal, SelectRoot, SelectTrigger, SelectValue, SelectViewport } from "reka-ui";
7
+ import { cva } from "class-variance-authority";
8
+ //#region src/primitives/Select/Select.vue?vue&type=script&setup=true&lang.ts
9
+ /**
10
+ * Select — pick one value out of a closed list, through a compact trigger and
11
+ * a popover listbox. It suits roughly three to fifteen rows where one value is
12
+ * always chosen: a language, a resolution, a quality preset.
13
+ *
14
+ * Below that, two to five options a reader should see all of at once are
15
+ * better shown than hidden. Above it, a list long enough to need searching
16
+ * wants a combobox, which is a different control rather than a longer version
17
+ * of this one.
18
+ *
19
+ * Built on Reka UI's Select, which supplies the listbox semantics: arrow-key
20
+ * navigation, first-character typeahead, Escape and outside-click to close, and
21
+ * the `role="combobox"` trigger wired to the listbox by `aria-expanded` and
22
+ * `aria-controls`. The active row is tracked by moving real focus onto it, not
23
+ * by `aria-activedescendant`.
24
+ */
25
+ var selectVariants = cva([
26
+ "group inline-flex w-full items-center justify-between gap-2 rounded-md border border-input bg-background text-foreground",
27
+ "transition-[color,background-color,box-shadow] duration-fast ease-out hover:bg-subtle",
28
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring",
29
+ "disabled:cursor-not-allowed disabled:opacity-50 data-[placeholder]:text-muted-foreground"
30
+ ], {
31
+ variants: { size: {
32
+ sm: "h-8 px-2.5 text-xs",
33
+ md: "h-9 px-3 text-sm",
34
+ lg: "h-11 px-4 text-base"
35
+ } },
36
+ defaultVariants: { size: "md" }
37
+ });
38
+ var Select_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
39
+ inheritAttrs: false,
40
+ __name: "Select",
41
+ props: {
42
+ modelValue: {},
43
+ options: {},
44
+ placeholder: {},
45
+ disabled: {
46
+ type: Boolean,
47
+ default: false
48
+ },
49
+ invalid: {
50
+ type: Boolean,
51
+ default: false
52
+ },
53
+ size: { default: "md" }
54
+ },
55
+ emits: ["update:modelValue"],
56
+ setup(__props) {
57
+ const { attrs, rest: triggerAttrs } = useSplitAttrs();
58
+ return (_ctx, _cache) => {
59
+ return openBlock(), createBlock(unref(SelectRoot), {
60
+ "model-value": __props.modelValue ?? "",
61
+ disabled: __props.disabled,
62
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => _ctx.$emit("update:modelValue", String($event)))
63
+ }, {
64
+ default: withCtx(() => [createVNode(unref(SelectTrigger), mergeProps(unref(triggerAttrs), {
65
+ "aria-invalid": __props.invalid || void 0,
66
+ "data-invalid": __props.invalid || void 0,
67
+ class: unref(cn)(unref(selectVariants)({ size: __props.size }), !__props.invalid && "focus-visible:shadow-halo", __props.invalid && "border-destructive focus-visible:outline-destructive", unref(attrs).class)
68
+ }), {
69
+ default: withCtx(() => [createVNode(unref(SelectValue), { placeholder: __props.placeholder ?? "" }, null, 8, ["placeholder"]), createVNode(unref(SelectIcon), { class: "shrink-0 text-muted-foreground" }, {
70
+ default: withCtx(() => [createVNode(unref(ChevronDown), { class: "h-4 w-4 transition-transform duration-fast ease-out group-data-[state=open]:rotate-180" })]),
71
+ _: 1
72
+ })]),
73
+ _: 1
74
+ }, 16, [
75
+ "aria-invalid",
76
+ "data-invalid",
77
+ "class"
78
+ ]), createVNode(unref(SelectPortal), null, {
79
+ default: withCtx(() => [createVNode(unref(SelectContent), {
80
+ position: "popper",
81
+ "side-offset": 6,
82
+ class: normalizeClass(unref(cn)("z-50 min-w-[var(--reka-select-trigger-width)] overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md", "data-[state=open]:animate-fade-rise"))
83
+ }, {
84
+ default: withCtx(() => [createVNode(unref(SelectViewport), { class: "p-1" }, {
85
+ default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.options, (option, index) => {
86
+ return openBlock(), createBlock(unref(SelectItem), {
87
+ key: option.value,
88
+ value: option.value,
89
+ disabled: option.disabled ?? false,
90
+ style: normalizeStyle({ animationDelay: unref(listStaggerDelay)(index) }),
91
+ class: normalizeClass(unref(cn)("relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-3 py-1.5 pr-8 text-sm text-foreground outline-none", "transition-colors duration-fast ease-out", "animate-fade-rise", "data-[highlighted]:bg-subtle", "data-[state=checked]:bg-primary-muted data-[state=checked]:text-primary", "data-[disabled]:pointer-events-none data-[disabled]:opacity-50"))
92
+ }, {
93
+ default: withCtx(() => [createVNode(unref(SelectItemText), null, {
94
+ default: withCtx(() => [createTextVNode(toDisplayString(option.label), 1)]),
95
+ _: 2
96
+ }, 1024), createVNode(unref(SelectItemIndicator), { class: "absolute right-2 inline-flex items-center" }, {
97
+ default: withCtx(() => [createVNode(unref(Check), { class: "h-4 w-4" })]),
98
+ _: 1
99
+ })]),
100
+ _: 2
101
+ }, 1032, [
102
+ "value",
103
+ "disabled",
104
+ "style",
105
+ "class"
106
+ ]);
107
+ }), 128))]),
108
+ _: 1
109
+ })]),
110
+ _: 1
111
+ }, 8, ["class"])]),
112
+ _: 1
113
+ })]),
114
+ _: 1
115
+ }, 8, ["model-value", "disabled"]);
116
+ };
117
+ }
118
+ });
119
+ //#endregion
120
+ export { Select_vue_vue_type_script_setup_true_lang_default as default, selectVariants };
121
+
122
+ //# sourceMappingURL=Select.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Select.vue_vue_type_script_setup_true_lang.js","names":["$emit"],"sources":["../../../src/primitives/Select/Select.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { cva } from \"class-variance-authority\";\n\n/** One row of the list. `value` is what the model carries; `label` is what a reader sees. */\nexport interface SelectOption {\n /** The value bound to `v-model` when this row is chosen. Unique within the list. */\n value: string;\n /** The text shown on the row, and on the trigger once it is chosen. */\n label: string;\n /** Present but unchoosable — visible, skipped by the keyboard, unclickable. */\n disabled?: boolean;\n}\n\n/**\n * The trigger's height scale. It matches the text input scale exactly, so a\n * form row mixing a Select beside a text field never comes out uneven — which\n * is why reaching past `size` for an `h-*` class is always the wrong fix.\n */\nexport type SelectSize = \"sm\" | \"md\" | \"lg\";\n\nexport const selectVariants = cva(\n [\n \"group inline-flex w-full items-center justify-between gap-2 rounded-md border border-input bg-background text-foreground\",\n \"transition-[color,background-color,box-shadow] duration-fast ease-out hover:bg-subtle\",\n // Rim-lit at rest; the ring blooms on focus.\n \"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\",\n \"disabled:cursor-not-allowed disabled:opacity-50 data-[placeholder]:text-muted-foreground\",\n ],\n {\n // `satisfies` keeps the two halves honest: the union above is the name a\n // consumer imports and the documentation prints, the map below is the\n // classes. Adding a member to one and not the other stops compiling.\n variants: {\n size: {\n sm: \"h-8 px-2.5 text-xs\",\n md: \"h-9 px-3 text-sm\",\n lg: \"h-11 px-4 text-base\",\n } satisfies Record<SelectSize, string>,\n },\n defaultVariants: { size: \"md\" },\n },\n);\n</script>\n\n<script setup lang=\"ts\">\nimport {\n SelectRoot,\n SelectTrigger,\n SelectValue,\n SelectIcon,\n SelectPortal,\n SelectContent,\n SelectViewport,\n SelectItem,\n SelectItemText,\n SelectItemIndicator,\n} from \"reka-ui\";\nimport { Check, ChevronDown } from \"@lucide/vue\";\nimport { cn } from \"../../lib/cn\";\nimport { listStaggerDelay } from \"../../lib/motion\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\n\n/**\n * Select — pick one value out of a closed list, through a compact trigger and\n * a popover listbox. It suits roughly three to fifteen rows where one value is\n * always chosen: a language, a resolution, a quality preset.\n *\n * Below that, two to five options a reader should see all of at once are\n * better shown than hidden. Above it, a list long enough to need searching\n * wants a combobox, which is a different control rather than a longer version\n * of this one.\n *\n * Built on Reka UI's Select, which supplies the listbox semantics: arrow-key\n * navigation, first-character typeahead, Escape and outside-click to close, and\n * the `role=\"combobox\"` trigger wired to the listbox by `aria-expanded` and\n * `aria-controls`. The active row is tracked by moving real focus onto it, not\n * by `aria-activedescendant`.\n */\nwithDefaults(\n defineProps<{\n /** The chosen option's `value`. Leave it unset to show the placeholder. */\n modelValue?: string;\n /** The rows, in the order they are shown. */\n options: SelectOption[];\n /** Shown on the trigger while nothing is chosen. It is not an option. */\n placeholder?: string;\n /** Unavailable: dims the trigger and refuses to open. */\n disabled?: boolean;\n /** Error state: paints the destructive border and ring, and sets `aria-invalid`. */\n invalid?: boolean;\n /** Trigger height. It shares the text input scale so mixed form rows stay aligned. */\n size?: SelectSize;\n }>(),\n { disabled: false, invalid: false, size: \"md\" },\n);\n\ndefineEmits<{\n /** The chosen option's `value`. Fires once per choice; the list closes with it. */\n \"update:modelValue\": [value: string];\n}>();\n\n// The root renders no DOM node at all, so fallthrough attributes would be\n// dropped on the floor rather than landing anywhere. They go to the trigger,\n// which is the interactive element they describe.\n//\n// `class` is pulled out of that spread and merged through `cn()` instead.\n// Spreading it alongside the trigger's own `:class` only concatenates the two\n// lists — Vue's merge is generic, not Tailwind-aware — so a caller's `w-28`\n// silently loses to the trigger's own `w-full` depending on which utility\n// Tailwind happened to emit last.\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: triggerAttrs } = useSplitAttrs();\n</script>\n\n<template>\n <SelectRoot\n :model-value=\"modelValue ?? ''\"\n :disabled=\"disabled\"\n @update:model-value=\"$emit('update:modelValue', String($event))\"\n >\n <SelectTrigger\n v-bind=\"triggerAttrs\"\n :aria-invalid=\"invalid || undefined\"\n :data-invalid=\"invalid || undefined\"\n :class=\"\n cn(\n selectVariants({ size }),\n !invalid && 'focus-visible:shadow-halo',\n invalid && 'border-destructive focus-visible:outline-destructive',\n attrs.class as string,\n )\n \"\n >\n <SelectValue :placeholder=\"placeholder ?? ''\" />\n <SelectIcon class=\"shrink-0 text-muted-foreground\">\n <ChevronDown\n class=\"h-4 w-4 transition-transform duration-fast ease-out group-data-[state=open]:rotate-180\"\n />\n </SelectIcon>\n </SelectTrigger>\n\n <SelectPortal>\n <SelectContent\n position=\"popper\"\n :side-offset=\"6\"\n :class=\"\n cn(\n 'z-50 min-w-[var(--reka-select-trigger-width)] overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md',\n // Scoped to the open state, never unconditional. Reka keeps the\n // closed content mounted while it waits for an animationend that a\n // mount-only animation never fires again — an invisible overlay\n // eating clicks. Scoping it makes the closed element compute\n // `animation-name: none`, which is the immediate-unmount branch.\n 'data-[state=open]:animate-fade-rise',\n )\n \"\n >\n <SelectViewport class=\"p-1\">\n <!-- The rows reveal one step after another, from the shared stagger\n vocabulary rather than a per-template delay of its own. -->\n <SelectItem\n v-for=\"(option, index) in options\"\n :key=\"option.value\"\n :value=\"option.value\"\n :disabled=\"option.disabled ?? false\"\n :style=\"{ animationDelay: listStaggerDelay(index) }\"\n :class=\"\n cn(\n 'relative flex cursor-pointer select-none items-center gap-2 rounded-sm px-3 py-1.5 pr-8 text-sm text-foreground outline-none',\n 'transition-colors duration-fast ease-out',\n 'animate-fade-rise',\n 'data-[highlighted]:bg-subtle',\n 'data-[state=checked]:bg-primary-muted data-[state=checked]:text-primary',\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n )\n \"\n >\n <SelectItemText>{{ option.label }}</SelectItemText>\n <SelectItemIndicator class=\"absolute right-2 inline-flex items-center\">\n <Check class=\"h-4 w-4\" />\n </SelectItemIndicator>\n </SelectItem>\n </SelectViewport>\n </SelectContent>\n </SelectPortal>\n </SelectRoot>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAoBA,IAAa,iBAAiB,IAC5B;CACE;CACA;CAEA;CACA;AACF,GACA;CAIE,UAAU,EACR,MAAM;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI;CACN,EACF;CACA,iBAAiB,EAAE,MAAM,KAAK;AAChC,CACF;;;;;;;;;;;;;;;;;;;;EAsEA,MAAM,EAAE,OAAO,MAAM,iBAAiB,cAAc;;GAIlD,OAAA,UAAA,GAAA,YAsEa,MAAA,UAAA,GAAA;IArEV,eAAa,QAAA,cAAU;IACvB,UAAU,QAAA;IACV,uBAAkB,OAAA,OAAA,OAAA,MAAA,WAAEA,KAAAA,MAAK,qBAAsB,OAAO,MAAM,CAAA;;IAE7D,SAAA,cAmBgB,CAnBhB,YAmBgB,MAAA,aAAA,GAnBhB,WACU,MAkBM,YAAA,GAlBM;KACnB,gBAAc,QAAA,WAAW,KAAA;KACzB,gBAAc,QAAA,WAAW,KAAA;KACzB,OAAgB,MAAA,EAAA,CAAE,CAAY,MAAA,cAAA,CAAc,CAAA,EAAA,MAAG,QAAA,KAAI,CAAA,GAAgB,CAAA,QAAA,WAAO,6BAA2C,QAAA,WAAO,wDAAsE,MAAA,KAAA,CAAK,CAAC,KAAA;;KASzM,SAAA,cAAgD,CAAhD,YAAgD,MAAA,WAAA,GAAA,EAAlC,aAAa,QAAA,eAAW,GAAA,GAAA,MAAA,GAAA,CAAA,aAAA,CAAA,GACtC,YAIa,MAAA,UAAA,GAAA,EAJD,OAAM,iCAAgC,GAAA;MAChD,SAAA,cAEE,CAFF,YAEE,MAAA,WAAA,GAAA,EADA,OAAM,yFAAwF,CAAA,CAAA,CAAA;;;;;;;;IAKpG,CAAA,GAAA,YA2Ce,MAAA,YAAA,GAAA,MAAA;KA1Cb,SAAA,cAyCgB,CAzChB,YAyCgB,MAAA,aAAA,GAAA;MAxCd,UAAS;MACR,eAAa;MACb,OAAK,eAAa,MAAA,EAAA,CAAE,CAAA,8IAAA,qCAAA,CAAA;;MAYrB,SAAA,cAyBiB,CAzBjB,YAyBiB,MAAA,cAAA,GAAA,EAzBD,OAAM,MAAK,GAAA;OAIvB,SAAA,cAAkC,EADpC,UAAA,IAAA,GAAA,mBAqBa,UAAA,MAAA,WApBe,QAAA,UAAlB,QAAQ,UAAK;QADvB,OAAA,UAAA,GAAA,YAqBa,MAAA,UAAA,GAAA;SAnBV,KAAK,OAAO;SACZ,OAAO,OAAO;SACd,UAAU,OAAO,YAAQ;SACzB,OAAK,eAAA,EAAA,gBAAoB,MAAA,gBAAA,CAAgB,CAAC,KAAK,EAAA,CAAA;SAC/C,OAAK,eAAiB,MAAA,EAAA,CAAE,CAAA,gIAAA,4CAAA,qBAAA,gCAAA,2EAAA,gEAAA,CAAA;;SAWzB,SAAA,cAAmD,CAAnD,YAAmD,MAAA,cAAA,GAAA,MAAA;UAAnC,SAAA,cAAkB,CAAf,gBAAA,gBAAA,OAAO,KAAK,GAAA,CAAA,CAAA,CAAA;;SAC/B,GAAA,IAAA,GAAA,YAEsB,MAAA,mBAAA,GAAA,EAFD,OAAM,4CAA2C,GAAA;UACpE,SAAA,cAAyB,CAAzB,YAAyB,MAAA,KAAA,GAAA,EAAlB,OAAM,UAAS,CAAA,CAAA,CAAA"}
@@ -0,0 +1,7 @@
1
+ import Separator_vue_vue_type_script_setup_true_lang_default from "./Separator.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/primitives/Separator/Separator.vue
3
+ var Separator_default = Separator_vue_vue_type_script_setup_true_lang_default;
4
+ //#endregion
5
+ export { Separator_default as default };
6
+
7
+ //# sourceMappingURL=Separator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Separator.js","names":[],"sources":["../../../src/primitives/Separator/Separator.vue"],"sourcesContent":["<script lang=\"ts\">\n/** Which axis the hairline draws along. */\nexport type SeparatorOrientation = \"horizontal\" | \"vertical\";\n</script>\n\n<script setup lang=\"ts\">\nimport { Separator as SeparatorRoot } from \"reka-ui\";\nimport { cn } from \"../../lib/cn\";\n\n/**\n * Separator — thin visual/semantic divider between content groups (a\n * settings section break, a toolbar group boundary). Built on Reka UI's\n * Separator: `role=\"separator\"` unless `decorative` (the common case —\n * visual dividers next to already-structured content don't need a second\n * landmark), matching `orientation` via `aria-orientation`.\n */\nwithDefaults(\n defineProps<{\n /** Which axis the hairline draws along. */\n orientation?: SeparatorOrientation;\n /** Purely visual, with no `role=\"separator\"` — the default, for a divider next to content that is already structured on its own. Set `false` only when the line is the sole semantic boundary between two regions. */\n decorative?: boolean;\n }>(),\n { orientation: \"horizontal\", decorative: true },\n);\n</script>\n\n<template>\n <SeparatorRoot\n :orientation=\"orientation\"\n :decorative=\"decorative\"\n :class=\"\n cn(\n 'shrink-0 bg-border',\n orientation === 'horizontal' ? 'h-px w-full' : 'h-full w-px self-stretch',\n )\n \"\n />\n</template>\n"],"mappings":""}
@@ -0,0 +1,19 @@
1
+ /** Which axis the hairline draws along. */
2
+ export type SeparatorOrientation = "horizontal" | "vertical";
3
+ declare const _default: typeof __VLS_export;
4
+ export default _default;
5
+ declare const __VLS_export: import("vue").DefineComponent<{
6
+ /** Which axis the hairline draws along. */
7
+ orientation?: SeparatorOrientation;
8
+ /** Purely visual, with no `role="separator"` — the default, for a divider next to content that is already structured on its own. Set `false` only when the line is the sole semantic boundary between two regions. */
9
+ decorative?: boolean;
10
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{
11
+ /** Which axis the hairline draws along. */
12
+ orientation?: SeparatorOrientation;
13
+ /** Purely visual, with no `role="separator"` — the default, for a divider next to content that is already structured on its own. Set `false` only when the line is the sole semantic boundary between two regions. */
14
+ decorative?: boolean;
15
+ }> & Readonly<{}>, {
16
+ orientation: SeparatorOrientation;
17
+ decorative: boolean;
18
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
19
+ //# sourceMappingURL=Separator.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Separator.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Separator/Separator.vue"],"names":[],"mappings":"AA8CA,2CAA2C;AAC3C,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,UAAU,CAAC;wBACxC,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IASd,2CAA2C;kBAC7B,oBAAoB;IAClC,sNAAsN;iBACzM,OAAO;;IAHpB,2CAA2C;kBAC7B,oBAAoB;IAClC,sNAAsN;iBACzM,OAAO;;iBAFN,oBAAoB;gBAErB,OAAO;6EA4DpB,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { createBlock, defineComponent, normalizeClass, openBlock, unref } from "vue";
3
+ import { Separator } from "reka-ui";
4
+ //#region src/primitives/Separator/Separator.vue?vue&type=script&setup=true&lang.ts
5
+ var Separator_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
6
+ __name: "Separator",
7
+ props: {
8
+ orientation: { default: "horizontal" },
9
+ decorative: {
10
+ type: Boolean,
11
+ default: true
12
+ }
13
+ },
14
+ setup(__props) {
15
+ return (_ctx, _cache) => {
16
+ return openBlock(), createBlock(unref(Separator), {
17
+ orientation: __props.orientation,
18
+ decorative: __props.decorative,
19
+ class: normalizeClass(unref(cn)("shrink-0 bg-border", __props.orientation === "horizontal" ? "h-px w-full" : "h-full w-px self-stretch"))
20
+ }, null, 8, [
21
+ "orientation",
22
+ "decorative",
23
+ "class"
24
+ ]);
25
+ };
26
+ }
27
+ });
28
+ //#endregion
29
+ export { Separator_vue_vue_type_script_setup_true_lang_default as default };
30
+
31
+ //# sourceMappingURL=Separator.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Separator.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/primitives/Separator/Separator.vue"],"sourcesContent":["<script lang=\"ts\">\n/** Which axis the hairline draws along. */\nexport type SeparatorOrientation = \"horizontal\" | \"vertical\";\n</script>\n\n<script setup lang=\"ts\">\nimport { Separator as SeparatorRoot } from \"reka-ui\";\nimport { cn } from \"../../lib/cn\";\n\n/**\n * Separator — thin visual/semantic divider between content groups (a\n * settings section break, a toolbar group boundary). Built on Reka UI's\n * Separator: `role=\"separator\"` unless `decorative` (the common case —\n * visual dividers next to already-structured content don't need a second\n * landmark), matching `orientation` via `aria-orientation`.\n */\nwithDefaults(\n defineProps<{\n /** Which axis the hairline draws along. */\n orientation?: SeparatorOrientation;\n /** Purely visual, with no `role=\"separator\"` — the default, for a divider next to content that is already structured on its own. Set `false` only when the line is the sole semantic boundary between two regions. */\n decorative?: boolean;\n }>(),\n { orientation: \"horizontal\", decorative: true },\n);\n</script>\n\n<template>\n <SeparatorRoot\n :orientation=\"orientation\"\n :decorative=\"decorative\"\n :class=\"\n cn(\n 'shrink-0 bg-border',\n orientation === 'horizontal' ? 'h-px w-full' : 'h-full w-px self-stretch',\n )\n \"\n />\n</template>\n"],"mappings":";;;;;;;;;;;;;;;GA4BE,OAAA,UAAA,GAAA,YASE,MAAA,SAAA,GAAA;IARC,aAAa,QAAA;IACb,YAAY,QAAA;IACZ,OAAK,eAAS,MAAA,EAAA,CAAE,CAAA,sBAAwC,QAAA,gBAAW,eAAA,gBAAA,0BAAA,CAAA"}
@@ -0,0 +1,7 @@
1
+ import Skeleton_vue_vue_type_script_setup_true_lang_default, { skeletonVariants } from "./Skeleton.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/primitives/Skeleton/Skeleton.vue
3
+ var Skeleton_default = Skeleton_vue_vue_type_script_setup_true_lang_default;
4
+ //#endregion
5
+ export { Skeleton_default as default, skeletonVariants };
6
+
7
+ //# sourceMappingURL=Skeleton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Skeleton.js","names":[],"sources":["../../../src/primitives/Skeleton/Skeleton.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { cva } from \"class-variance-authority\";\n\nexport type SkeletonVariant = \"text\" | \"circle\" | \"rect\";\n\n// A faint light band sweeps a muted base (background-color muted + a moving\n// transparent→light→transparent gradient image) — the shimmer language,\n// kept neutral and low-contrast so a loading page reads as \"coming\", not busy.\n// Under prefers-reduced-motion the sweep simply stops on a flat muted block.\n//\n// The band's colour goes through `--alpha()` rather than `hsl(var(…)/…)`.\n// Loom's tokens are whole colours (`--color-foreground: hsl(213 29% 15%)`),\n// not the bare channel triplets that idiom expects, so wrapping one in `hsl()`\n// produces a value the browser cannot compute — and a single invalid stop\n// takes the entire gradient with it, leaving a flat block that still animates\n// its own absence. `--alpha()` is Tailwind's own function for this and takes\n// the token as it is actually written.\nexport const skeletonVariants = cva(\n \"bg-muted bg-[linear-gradient(90deg,transparent_0%,--alpha(var(--color-foreground)/6%)_50%,transparent_100%)] bg-[length:200%_100%] animate-shimmer\",\n {\n variants: {\n variant: {\n text: \"h-4 rounded\",\n circle: \"rounded-full\",\n rect: \"rounded-md\",\n } satisfies Record<SkeletonVariant, string>,\n },\n defaultVariants: { variant: \"text\" },\n },\n);\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"../../lib/cn\";\n\n/**\n * Skeleton — content-loading placeholder for a KNOWN layout (a card, a list\n * row, an avatar) so the page's shape reads as \"coming\" instead of jumping\n * once real content lands. For an indeterminate wait with no layout shape\n * yet, use Spinner instead. Purely decorative (`aria-hidden`) — the loading\n * state itself is announced elsewhere (e.g. a Spinner or a live region), not\n * by the placeholder shapes. Width/height are the caller's concern via a\n * passthrough `class` (e.g. `class=\"h-10 w-10\"`).\n */\nwithDefaults(\n defineProps<{\n /** Which shape stands in for the real content: a text line, a round avatar, or a rectangular block. */\n variant?: SkeletonVariant;\n }>(),\n { variant: \"text\" },\n);\n</script>\n\n<template>\n <div aria-hidden=\"true\" :class=\"cn(skeletonVariants({ variant }))\" />\n</template>\n"],"mappings":""}
@@ -0,0 +1,16 @@
1
+ export type SkeletonVariant = "text" | "circle" | "rect";
2
+ export declare const skeletonVariants: (props?: ({
3
+ variant?: "circle" | "rect" | "text" | null | undefined;
4
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
5
+ declare const _default: typeof __VLS_export;
6
+ export default _default;
7
+ declare const __VLS_export: import("vue").DefineComponent<{
8
+ /** Which shape stands in for the real content: a text line, a round avatar, or a rectangular block. */
9
+ variant?: SkeletonVariant;
10
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{
11
+ /** Which shape stands in for the real content: a text line, a round avatar, or a rectangular block. */
12
+ variant?: SkeletonVariant;
13
+ }> & Readonly<{}>, {
14
+ variant: SkeletonVariant;
15
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
16
+ //# sourceMappingURL=Skeleton.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Skeleton.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Skeleton/Skeleton.vue"],"names":[],"mappings":"AAgEA,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAczD,eAAO,MAAM,gBAAgB;;8EAY5B,CAAC;wBACmB,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAWd,uGAAuG;cAC7F,eAAe;;IADzB,uGAAuG;cAC7F,eAAe;;aAAf,eAAe;6EAsCzB,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { createElementBlock, defineComponent, normalizeClass, openBlock, unref } from "vue";
3
+ import { cva } from "class-variance-authority";
4
+ //#region src/primitives/Skeleton/Skeleton.vue?vue&type=script&setup=true&lang.ts
5
+ /**
6
+ * Skeleton — content-loading placeholder for a KNOWN layout (a card, a list
7
+ * row, an avatar) so the page's shape reads as "coming" instead of jumping
8
+ * once real content lands. For an indeterminate wait with no layout shape
9
+ * yet, use Spinner instead. Purely decorative (`aria-hidden`) — the loading
10
+ * state itself is announced elsewhere (e.g. a Spinner or a live region), not
11
+ * by the placeholder shapes. Width/height are the caller's concern via a
12
+ * passthrough `class` (e.g. `class="h-10 w-10"`).
13
+ */
14
+ var skeletonVariants = cva("bg-muted bg-[linear-gradient(90deg,transparent_0%,--alpha(var(--color-foreground)/6%)_50%,transparent_100%)] bg-[length:200%_100%] animate-shimmer", {
15
+ variants: { variant: {
16
+ text: "h-4 rounded",
17
+ circle: "rounded-full",
18
+ rect: "rounded-md"
19
+ } },
20
+ defaultVariants: { variant: "text" }
21
+ });
22
+ var Skeleton_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
23
+ __name: "Skeleton",
24
+ props: { variant: { default: "text" } },
25
+ setup(__props) {
26
+ return (_ctx, _cache) => {
27
+ return openBlock(), createElementBlock("div", {
28
+ "aria-hidden": "true",
29
+ class: normalizeClass(unref(cn)(unref(skeletonVariants)({ variant: __props.variant })))
30
+ }, null, 2);
31
+ };
32
+ }
33
+ });
34
+ //#endregion
35
+ export { Skeleton_vue_vue_type_script_setup_true_lang_default as default, skeletonVariants };
36
+
37
+ //# sourceMappingURL=Skeleton.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Skeleton.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/primitives/Skeleton/Skeleton.vue"],"sourcesContent":["<script lang=\"ts\">\nimport { cva } from \"class-variance-authority\";\n\nexport type SkeletonVariant = \"text\" | \"circle\" | \"rect\";\n\n// A faint light band sweeps a muted base (background-color muted + a moving\n// transparent→light→transparent gradient image) — the shimmer language,\n// kept neutral and low-contrast so a loading page reads as \"coming\", not busy.\n// Under prefers-reduced-motion the sweep simply stops on a flat muted block.\n//\n// The band's colour goes through `--alpha()` rather than `hsl(var(…)/…)`.\n// Loom's tokens are whole colours (`--color-foreground: hsl(213 29% 15%)`),\n// not the bare channel triplets that idiom expects, so wrapping one in `hsl()`\n// produces a value the browser cannot compute — and a single invalid stop\n// takes the entire gradient with it, leaving a flat block that still animates\n// its own absence. `--alpha()` is Tailwind's own function for this and takes\n// the token as it is actually written.\nexport const skeletonVariants = cva(\n \"bg-muted bg-[linear-gradient(90deg,transparent_0%,--alpha(var(--color-foreground)/6%)_50%,transparent_100%)] bg-[length:200%_100%] animate-shimmer\",\n {\n variants: {\n variant: {\n text: \"h-4 rounded\",\n circle: \"rounded-full\",\n rect: \"rounded-md\",\n } satisfies Record<SkeletonVariant, string>,\n },\n defaultVariants: { variant: \"text\" },\n },\n);\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"../../lib/cn\";\n\n/**\n * Skeleton — content-loading placeholder for a KNOWN layout (a card, a list\n * row, an avatar) so the page's shape reads as \"coming\" instead of jumping\n * once real content lands. For an indeterminate wait with no layout shape\n * yet, use Spinner instead. Purely decorative (`aria-hidden`) — the loading\n * state itself is announced elsewhere (e.g. a Spinner or a live region), not\n * by the placeholder shapes. Width/height are the caller's concern via a\n * passthrough `class` (e.g. `class=\"h-10 w-10\"`).\n */\nwithDefaults(\n defineProps<{\n /** Which shape stands in for the real content: a text line, a round avatar, or a rectangular block. */\n variant?: SkeletonVariant;\n }>(),\n { variant: \"text\" },\n);\n</script>\n\n<template>\n <div aria-hidden=\"true\" :class=\"cn(skeletonVariants({ variant }))\" />\n</template>\n"],"mappings":";;;;;;;;;;;;;AAiBA,IAAa,mBAAmB,IAC9B,sJACA;CACE,UAAU,EACR,SAAS;EACP,MAAM;EACN,QAAQ;EACR,MAAM;CACR,EACF;CACA,iBAAiB,EAAE,SAAS,OAAO;AACrC,CACF;;;;;;GAyBE,OAAA,UAAA,GAAA,mBAAqE,OAAA;IAAhE,eAAY;IAAQ,OAAK,eAAE,MAAA,EAAA,CAAE,CAAC,MAAA,gBAAA,CAAgB,CAAA,EAAA,SAAG,QAAA,QAAO,CAAA,CAAA,CAAA"}
@@ -0,0 +1,7 @@
1
+ import Slider_vue_vue_type_script_setup_true_lang_default from "./Slider.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/primitives/Slider/Slider.vue
3
+ var Slider_default = Slider_vue_vue_type_script_setup_true_lang_default;
4
+ //#endregion
5
+ export { Slider_default as default };
6
+
7
+ //# sourceMappingURL=Slider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.js","names":[],"sources":["../../../src/primitives/Slider/Slider.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, watch } from \"vue\";\nimport { SliderRoot, SliderTrack, SliderRange, SliderThumb } from \"reka-ui\";\nimport { cn } from \"../../lib/cn\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\n\n/**\n * Slider — one continuous value inside a bounded range. Reach for it when the\n * range itself is the information: a volume, a ratio, a share of something\n * whole. A number that happens to be numeric but has no meaningful ceiling —\n * a coordinate, an angle — belongs in a NumberField instead.\n *\n * Built on Reka UI's Slider for the `role=\"slider\"` semantics, the pointer\n * drag and the arrow / Home / End stepping. Single-thumb only: Reka models the\n * value as an array, and this exposes a scalar.\n *\n * Two things are added here.\n *\n * The first is the drag buffer, and without it the component silently drops\n * changes. Given a defined model value Reka runs fully controlled, and its\n * release-time \"did this change?\" check compares against whatever it was last\n * fed — not against what it emitted. A host that correctly withholds transient\n * values until commit therefore leaves that check reading the pre-drag value\n * for the whole gesture, so it always answers no and the commit never fires.\n * `lastValue` below feeds Reka's own transient ticks back into its model, which\n * is exactly the fix NumberField applies for the same reason. Keyboard steps\n * need no buffer: Reka updates and commits inside one synchronous call, so it\n * compares against a value that is still old either way.\n *\n * The second is the abort path. Reka has no drag cancellation of its own — it\n * handles pointerdown, move and up, and commits whenever the release value\n * differs from the one it snapshotted — so Escape or a browser-issued\n * `pointercancel` mid-drag would still write one checkpoint on release. The\n * bail-out mirrors NumberField's: reset `lastValue` to the committed value, so\n * Reka's own comparison sees no change and never commits, and swallow the\n * still-captured pointer's remaining ticks until it releases.\n */\nconst props = withDefaults(\n defineProps<{\n /** The current value. Transient drag positions are reported before it changes. */\n modelValue?: number;\n /** The floor of the range, and where Home lands. */\n min?: number;\n /** The ceiling of the range, and where End lands. */\n max?: number;\n /** The granularity of one arrow-key step and of the drag's own snapping. */\n step?: number;\n /** Unavailable: dims the track and refuses both the pointer and the keyboard. */\n disabled?: boolean;\n }>(),\n { min: 0, max: 1, step: 0.01, disabled: false },\n);\n\nconst emit = defineEmits<{\n /** Transient: every position the thumb passes through during a drag. Not a checkpoint. */\n \"update:modelValue\": [value: number];\n /** Committed: once at the end of a gesture — drag release, or a keyboard step. */\n commit: [value: number];\n}>();\n\n// The root renders a real element, and it is the one a caller's `class` has to\n// land on — sizing and layout (`flex-1` to grow in a toolbar) are dead weight\n// on the thumb, which is a 16px absolutely-positioned circle no flex rule\n// reaches. Every other fallthrough attribute goes the other way, onto the\n// thumb: `aria-labelledby` describes the `role=\"slider\"` element, not the box\n// around it.\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: thumbAttrs } = useSplitAttrs();\n\n// What the Reka root is fed as its own model value: seeded from the prop, then\n// advanced on every tick Reka emits, so its release-time check sees the drag's\n// real end position rather than the frozen prop.\nconst lastValue = ref(props.modelValue);\nwatch(\n () => props.modelValue,\n (value) => {\n lastValue.value = value;\n },\n);\n\nconst values = computed(() => (lastValue.value === undefined ? [] : [lastValue.value]));\n\nfunction onUpdate(next: number[] | undefined) {\n const value = next?.[0];\n if (value === undefined || aborted) return;\n lastValue.value = value;\n emit(\"update:modelValue\", value);\n}\n\nfunction onCommit(next: number[]) {\n if (next[0] !== undefined && !aborted) emit(\"commit\", next[0]);\n}\n\n// The abort path. Its window listeners live for the duration of one pointer\n// gesture and no longer.\nlet aborted = false;\nlet teardownDrag: (() => void) | undefined;\n\nfunction resetToCommitted() {\n if (lastValue.value === props.modelValue) return;\n lastValue.value = props.modelValue;\n // One transient tick carrying the committed value, so the host can restore\n // its pre-drag preview. Still never a checkpoint.\n if (props.modelValue !== undefined) emit(\"update:modelValue\", props.modelValue);\n}\n\nfunction onRootPointerDown() {\n if (props.disabled) return;\n aborted = false;\n const onDragKeydown = (keyEvent: KeyboardEvent) => {\n if (keyEvent.key !== \"Escape\" || aborted) return;\n keyEvent.preventDefault();\n keyEvent.stopPropagation();\n // Reka keeps the pointer captured until release, so `aborted` is what\n // stops the remaining move ticks from resurrecting the gesture.\n aborted = true;\n resetToCommitted();\n };\n const onPointerUp = () => {\n // This runs after Reka's own element-level release handling, so a\n // swallowed gesture has already settled by the time the abort re-arms.\n teardownDrag?.();\n aborted = false;\n };\n const onPointerCancel = () => {\n teardownDrag?.();\n aborted = false; // a cancelled pointer emits no further ticks\n resetToCommitted();\n };\n window.addEventListener(\"pointerup\", onPointerUp);\n window.addEventListener(\"pointercancel\", onPointerCancel);\n window.addEventListener(\"keydown\", onDragKeydown, true);\n teardownDrag = () => {\n window.removeEventListener(\"pointerup\", onPointerUp);\n window.removeEventListener(\"pointercancel\", onPointerCancel);\n window.removeEventListener(\"keydown\", onDragKeydown, true);\n teardownDrag = undefined;\n };\n}\n\nonBeforeUnmount(() => teardownDrag?.());\n</script>\n\n<template>\n <SliderRoot\n :model-value=\"values\"\n :min=\"min\"\n :max=\"max\"\n :step=\"step\"\n :disabled=\"disabled\"\n :class=\"\n cn(\n 'relative flex w-full touch-none items-center py-2 data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',\n attrs.class as string,\n )\n \"\n @pointerdown=\"onRootPointerDown\"\n @update:model-value=\"onUpdate\"\n @value-commit=\"onCommit\"\n >\n <SliderTrack class=\"relative h-1.5 w-full grow rounded-full bg-muted\">\n <!-- The filled range is a value a person set, so it is painted flat in\n the human force's colour rather than in a gradient. -->\n <SliderRange class=\"absolute h-full rounded-full bg-primary\" />\n </SliderTrack>\n <SliderThumb\n v-bind=\"thumbAttrs\"\n class=\"block h-4 w-4 rounded-full border-2 border-primary bg-background shadow-sm transition-transform duration-fast ease-spring hover:scale-110 active:scale-95 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo data-[disabled]:pointer-events-none\"\n />\n </SliderRoot>\n</template>\n"],"mappings":""}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Slider — one continuous value inside a bounded range. Reach for it when the
3
+ * range itself is the information: a volume, a ratio, a share of something
4
+ * whole. A number that happens to be numeric but has no meaningful ceiling —
5
+ * a coordinate, an angle — belongs in a NumberField instead.
6
+ *
7
+ * Built on Reka UI's Slider for the `role="slider"` semantics, the pointer
8
+ * drag and the arrow / Home / End stepping. Single-thumb only: Reka models the
9
+ * value as an array, and this exposes a scalar.
10
+ *
11
+ * Two things are added here.
12
+ *
13
+ * The first is the drag buffer, and without it the component silently drops
14
+ * changes. Given a defined model value Reka runs fully controlled, and its
15
+ * release-time "did this change?" check compares against whatever it was last
16
+ * fed — not against what it emitted. A host that correctly withholds transient
17
+ * values until commit therefore leaves that check reading the pre-drag value
18
+ * for the whole gesture, so it always answers no and the commit never fires.
19
+ * `lastValue` below feeds Reka's own transient ticks back into its model, which
20
+ * is exactly the fix NumberField applies for the same reason. Keyboard steps
21
+ * need no buffer: Reka updates and commits inside one synchronous call, so it
22
+ * compares against a value that is still old either way.
23
+ *
24
+ * The second is the abort path. Reka has no drag cancellation of its own — it
25
+ * handles pointerdown, move and up, and commits whenever the release value
26
+ * differs from the one it snapshotted — so Escape or a browser-issued
27
+ * `pointercancel` mid-drag would still write one checkpoint on release. The
28
+ * bail-out mirrors NumberField's: reset `lastValue` to the committed value, so
29
+ * Reka's own comparison sees no change and never commits, and swallow the
30
+ * still-captured pointer's remaining ticks until it releases.
31
+ */
32
+ type __VLS_Props = {
33
+ /** The current value. Transient drag positions are reported before it changes. */
34
+ modelValue?: number;
35
+ /** The floor of the range, and where Home lands. */
36
+ min?: number;
37
+ /** The ceiling of the range, and where End lands. */
38
+ max?: number;
39
+ /** The granularity of one arrow-key step and of the drag's own snapping. */
40
+ step?: number;
41
+ /** Unavailable: dims the track and refuses both the pointer and the keyboard. */
42
+ disabled?: boolean;
43
+ };
44
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
45
+ "update:modelValue": (value: number) => any;
46
+ commit: (value: number) => any;
47
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
48
+ "onUpdate:modelValue"?: (value: number) => any;
49
+ onCommit?: (value: number) => any;
50
+ }>, {
51
+ disabled: boolean;
52
+ max: number;
53
+ min: number;
54
+ step: number;
55
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
56
+ declare const _default: typeof __VLS_export;
57
+ export default _default;
58
+ //# sourceMappingURL=Slider.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Slider/Slider.vue"],"names":[],"mappings":"AAmLA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,KAAK,WAAW,GAAG;IACf,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qDAAqD;IACrD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAyPJ,QAAA,MAAM,YAAY;;;;;;;cA1PH,OAAO;SAJZ,MAAM;SAFN,MAAM;UAIL,MAAM;6EAgQf,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -0,0 +1,137 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { useSplitAttrs } from "../../lib/attrs.js";
3
+ import { computed, createBlock, createVNode, defineComponent, mergeProps, normalizeClass, onBeforeUnmount, openBlock, ref, unref, watch, withCtx } from "vue";
4
+ import { SliderRange, SliderRoot, SliderThumb, SliderTrack } from "reka-ui";
5
+ //#region src/primitives/Slider/Slider.vue?vue&type=script&setup=true&lang.ts
6
+ /**
7
+ * Slider — one continuous value inside a bounded range. Reach for it when the
8
+ * range itself is the information: a volume, a ratio, a share of something
9
+ * whole. A number that happens to be numeric but has no meaningful ceiling —
10
+ * a coordinate, an angle — belongs in a NumberField instead.
11
+ *
12
+ * Built on Reka UI's Slider for the `role="slider"` semantics, the pointer
13
+ * drag and the arrow / Home / End stepping. Single-thumb only: Reka models the
14
+ * value as an array, and this exposes a scalar.
15
+ *
16
+ * Two things are added here.
17
+ *
18
+ * The first is the drag buffer, and without it the component silently drops
19
+ * changes. Given a defined model value Reka runs fully controlled, and its
20
+ * release-time "did this change?" check compares against whatever it was last
21
+ * fed — not against what it emitted. A host that correctly withholds transient
22
+ * values until commit therefore leaves that check reading the pre-drag value
23
+ * for the whole gesture, so it always answers no and the commit never fires.
24
+ * `lastValue` below feeds Reka's own transient ticks back into its model, which
25
+ * is exactly the fix NumberField applies for the same reason. Keyboard steps
26
+ * need no buffer: Reka updates and commits inside one synchronous call, so it
27
+ * compares against a value that is still old either way.
28
+ *
29
+ * The second is the abort path. Reka has no drag cancellation of its own — it
30
+ * handles pointerdown, move and up, and commits whenever the release value
31
+ * differs from the one it snapshotted — so Escape or a browser-issued
32
+ * `pointercancel` mid-drag would still write one checkpoint on release. The
33
+ * bail-out mirrors NumberField's: reset `lastValue` to the committed value, so
34
+ * Reka's own comparison sees no change and never commits, and swallow the
35
+ * still-captured pointer's remaining ticks until it releases.
36
+ */
37
+ var Slider_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
38
+ inheritAttrs: false,
39
+ __name: "Slider",
40
+ props: {
41
+ modelValue: {},
42
+ min: { default: 0 },
43
+ max: { default: 1 },
44
+ step: { default: .01 },
45
+ disabled: {
46
+ type: Boolean,
47
+ default: false
48
+ }
49
+ },
50
+ emits: ["update:modelValue", "commit"],
51
+ setup(__props, { emit: __emit }) {
52
+ const props = __props;
53
+ const emit = __emit;
54
+ const { attrs, rest: thumbAttrs } = useSplitAttrs();
55
+ const lastValue = ref(props.modelValue);
56
+ watch(() => props.modelValue, (value) => {
57
+ lastValue.value = value;
58
+ });
59
+ const values = computed(() => lastValue.value === void 0 ? [] : [lastValue.value]);
60
+ function onUpdate(next) {
61
+ const value = next?.[0];
62
+ if (value === void 0 || aborted) return;
63
+ lastValue.value = value;
64
+ emit("update:modelValue", value);
65
+ }
66
+ function onCommit(next) {
67
+ if (next[0] !== void 0 && !aborted) emit("commit", next[0]);
68
+ }
69
+ let aborted = false;
70
+ let teardownDrag;
71
+ function resetToCommitted() {
72
+ if (lastValue.value === props.modelValue) return;
73
+ lastValue.value = props.modelValue;
74
+ if (props.modelValue !== void 0) emit("update:modelValue", props.modelValue);
75
+ }
76
+ function onRootPointerDown() {
77
+ if (props.disabled) return;
78
+ aborted = false;
79
+ const onDragKeydown = (keyEvent) => {
80
+ if (keyEvent.key !== "Escape" || aborted) return;
81
+ keyEvent.preventDefault();
82
+ keyEvent.stopPropagation();
83
+ aborted = true;
84
+ resetToCommitted();
85
+ };
86
+ const onPointerUp = () => {
87
+ teardownDrag?.();
88
+ aborted = false;
89
+ };
90
+ const onPointerCancel = () => {
91
+ teardownDrag?.();
92
+ aborted = false;
93
+ resetToCommitted();
94
+ };
95
+ window.addEventListener("pointerup", onPointerUp);
96
+ window.addEventListener("pointercancel", onPointerCancel);
97
+ window.addEventListener("keydown", onDragKeydown, true);
98
+ teardownDrag = () => {
99
+ window.removeEventListener("pointerup", onPointerUp);
100
+ window.removeEventListener("pointercancel", onPointerCancel);
101
+ window.removeEventListener("keydown", onDragKeydown, true);
102
+ teardownDrag = void 0;
103
+ };
104
+ }
105
+ onBeforeUnmount(() => teardownDrag?.());
106
+ return (_ctx, _cache) => {
107
+ return openBlock(), createBlock(unref(SliderRoot), {
108
+ "model-value": values.value,
109
+ min: __props.min,
110
+ max: __props.max,
111
+ step: __props.step,
112
+ disabled: __props.disabled,
113
+ class: normalizeClass(unref(cn)("relative flex w-full touch-none items-center py-2 data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50", unref(attrs).class)),
114
+ onPointerdown: onRootPointerDown,
115
+ "onUpdate:modelValue": onUpdate,
116
+ onValueCommit: onCommit
117
+ }, {
118
+ default: withCtx(() => [createVNode(unref(SliderTrack), { class: "relative h-1.5 w-full grow rounded-full bg-muted" }, {
119
+ default: withCtx(() => [createVNode(unref(SliderRange), { class: "absolute h-full rounded-full bg-primary" })]),
120
+ _: 1
121
+ }), createVNode(unref(SliderThumb), mergeProps(unref(thumbAttrs), { class: "block h-4 w-4 rounded-full border-2 border-primary bg-background shadow-sm transition-transform duration-fast ease-spring hover:scale-110 active:scale-95 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo data-[disabled]:pointer-events-none" }), null, 16)]),
122
+ _: 1
123
+ }, 8, [
124
+ "model-value",
125
+ "min",
126
+ "max",
127
+ "step",
128
+ "disabled",
129
+ "class"
130
+ ]);
131
+ };
132
+ }
133
+ });
134
+ //#endregion
135
+ export { Slider_vue_vue_type_script_setup_true_lang_default as default };
136
+
137
+ //# sourceMappingURL=Slider.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slider.vue_vue_type_script_setup_true_lang.js","names":[],"sources":["../../../src/primitives/Slider/Slider.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, watch } from \"vue\";\nimport { SliderRoot, SliderTrack, SliderRange, SliderThumb } from \"reka-ui\";\nimport { cn } from \"../../lib/cn\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\n\n/**\n * Slider — one continuous value inside a bounded range. Reach for it when the\n * range itself is the information: a volume, a ratio, a share of something\n * whole. A number that happens to be numeric but has no meaningful ceiling —\n * a coordinate, an angle — belongs in a NumberField instead.\n *\n * Built on Reka UI's Slider for the `role=\"slider\"` semantics, the pointer\n * drag and the arrow / Home / End stepping. Single-thumb only: Reka models the\n * value as an array, and this exposes a scalar.\n *\n * Two things are added here.\n *\n * The first is the drag buffer, and without it the component silently drops\n * changes. Given a defined model value Reka runs fully controlled, and its\n * release-time \"did this change?\" check compares against whatever it was last\n * fed — not against what it emitted. A host that correctly withholds transient\n * values until commit therefore leaves that check reading the pre-drag value\n * for the whole gesture, so it always answers no and the commit never fires.\n * `lastValue` below feeds Reka's own transient ticks back into its model, which\n * is exactly the fix NumberField applies for the same reason. Keyboard steps\n * need no buffer: Reka updates and commits inside one synchronous call, so it\n * compares against a value that is still old either way.\n *\n * The second is the abort path. Reka has no drag cancellation of its own — it\n * handles pointerdown, move and up, and commits whenever the release value\n * differs from the one it snapshotted — so Escape or a browser-issued\n * `pointercancel` mid-drag would still write one checkpoint on release. The\n * bail-out mirrors NumberField's: reset `lastValue` to the committed value, so\n * Reka's own comparison sees no change and never commits, and swallow the\n * still-captured pointer's remaining ticks until it releases.\n */\nconst props = withDefaults(\n defineProps<{\n /** The current value. Transient drag positions are reported before it changes. */\n modelValue?: number;\n /** The floor of the range, and where Home lands. */\n min?: number;\n /** The ceiling of the range, and where End lands. */\n max?: number;\n /** The granularity of one arrow-key step and of the drag's own snapping. */\n step?: number;\n /** Unavailable: dims the track and refuses both the pointer and the keyboard. */\n disabled?: boolean;\n }>(),\n { min: 0, max: 1, step: 0.01, disabled: false },\n);\n\nconst emit = defineEmits<{\n /** Transient: every position the thumb passes through during a drag. Not a checkpoint. */\n \"update:modelValue\": [value: number];\n /** Committed: once at the end of a gesture — drag release, or a keyboard step. */\n commit: [value: number];\n}>();\n\n// The root renders a real element, and it is the one a caller's `class` has to\n// land on — sizing and layout (`flex-1` to grow in a toolbar) are dead weight\n// on the thumb, which is a 16px absolutely-positioned circle no flex rule\n// reaches. Every other fallthrough attribute goes the other way, onto the\n// thumb: `aria-labelledby` describes the `role=\"slider\"` element, not the box\n// around it.\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: thumbAttrs } = useSplitAttrs();\n\n// What the Reka root is fed as its own model value: seeded from the prop, then\n// advanced on every tick Reka emits, so its release-time check sees the drag's\n// real end position rather than the frozen prop.\nconst lastValue = ref(props.modelValue);\nwatch(\n () => props.modelValue,\n (value) => {\n lastValue.value = value;\n },\n);\n\nconst values = computed(() => (lastValue.value === undefined ? [] : [lastValue.value]));\n\nfunction onUpdate(next: number[] | undefined) {\n const value = next?.[0];\n if (value === undefined || aborted) return;\n lastValue.value = value;\n emit(\"update:modelValue\", value);\n}\n\nfunction onCommit(next: number[]) {\n if (next[0] !== undefined && !aborted) emit(\"commit\", next[0]);\n}\n\n// The abort path. Its window listeners live for the duration of one pointer\n// gesture and no longer.\nlet aborted = false;\nlet teardownDrag: (() => void) | undefined;\n\nfunction resetToCommitted() {\n if (lastValue.value === props.modelValue) return;\n lastValue.value = props.modelValue;\n // One transient tick carrying the committed value, so the host can restore\n // its pre-drag preview. Still never a checkpoint.\n if (props.modelValue !== undefined) emit(\"update:modelValue\", props.modelValue);\n}\n\nfunction onRootPointerDown() {\n if (props.disabled) return;\n aborted = false;\n const onDragKeydown = (keyEvent: KeyboardEvent) => {\n if (keyEvent.key !== \"Escape\" || aborted) return;\n keyEvent.preventDefault();\n keyEvent.stopPropagation();\n // Reka keeps the pointer captured until release, so `aborted` is what\n // stops the remaining move ticks from resurrecting the gesture.\n aborted = true;\n resetToCommitted();\n };\n const onPointerUp = () => {\n // This runs after Reka's own element-level release handling, so a\n // swallowed gesture has already settled by the time the abort re-arms.\n teardownDrag?.();\n aborted = false;\n };\n const onPointerCancel = () => {\n teardownDrag?.();\n aborted = false; // a cancelled pointer emits no further ticks\n resetToCommitted();\n };\n window.addEventListener(\"pointerup\", onPointerUp);\n window.addEventListener(\"pointercancel\", onPointerCancel);\n window.addEventListener(\"keydown\", onDragKeydown, true);\n teardownDrag = () => {\n window.removeEventListener(\"pointerup\", onPointerUp);\n window.removeEventListener(\"pointercancel\", onPointerCancel);\n window.removeEventListener(\"keydown\", onDragKeydown, true);\n teardownDrag = undefined;\n };\n}\n\nonBeforeUnmount(() => teardownDrag?.());\n</script>\n\n<template>\n <SliderRoot\n :model-value=\"values\"\n :min=\"min\"\n :max=\"max\"\n :step=\"step\"\n :disabled=\"disabled\"\n :class=\"\n cn(\n 'relative flex w-full touch-none items-center py-2 data-[disabled]:cursor-not-allowed data-[disabled]:opacity-50',\n attrs.class as string,\n )\n \"\n @pointerdown=\"onRootPointerDown\"\n @update:model-value=\"onUpdate\"\n @value-commit=\"onCommit\"\n >\n <SliderTrack class=\"relative h-1.5 w-full grow rounded-full bg-muted\">\n <!-- The filled range is a value a person set, so it is painted flat in\n the human force's colour rather than in a gradient. -->\n <SliderRange class=\"absolute h-full rounded-full bg-primary\" />\n </SliderTrack>\n <SliderThumb\n v-bind=\"thumbAttrs\"\n class=\"block h-4 w-4 rounded-full border-2 border-primary bg-background shadow-sm transition-transform duration-fast ease-spring hover:scale-110 active:scale-95 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring focus-visible:shadow-halo data-[disabled]:pointer-events-none\"\n />\n </SliderRoot>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqCA,MAAM,QAAQ;EAgBd,MAAM,OAAO;EAcb,MAAM,EAAE,OAAO,MAAM,eAAe,cAAc;EAKlD,MAAM,YAAY,IAAI,MAAM,UAAU;EACtC,YACQ,MAAM,aACX,UAAU;GACT,UAAU,QAAQ;EACpB,CACF;EAEA,MAAM,SAAS,eAAgB,UAAU,UAAU,KAAA,IAAY,CAAC,IAAI,CAAC,UAAU,KAAK,CAAE;EAEtF,SAAS,SAAS,MAA4B;GAC5C,MAAM,QAAQ,OAAO;GACrB,IAAI,UAAU,KAAA,KAAa,SAAS;GACpC,UAAU,QAAQ;GAClB,KAAK,qBAAqB,KAAK;EACjC;EAEA,SAAS,SAAS,MAAgB;GAChC,IAAI,KAAK,OAAO,KAAA,KAAa,CAAC,SAAS,KAAK,UAAU,KAAK,EAAE;EAC/D;EAIA,IAAI,UAAU;EACd,IAAI;EAEJ,SAAS,mBAAmB;GAC1B,IAAI,UAAU,UAAU,MAAM,YAAY;GAC1C,UAAU,QAAQ,MAAM;GAGxB,IAAI,MAAM,eAAe,KAAA,GAAW,KAAK,qBAAqB,MAAM,UAAU;EAChF;EAEA,SAAS,oBAAoB;GAC3B,IAAI,MAAM,UAAU;GACpB,UAAU;GACV,MAAM,iBAAiB,aAA4B;IACjD,IAAI,SAAS,QAAQ,YAAY,SAAS;IAC1C,SAAS,eAAe;IACxB,SAAS,gBAAgB;IAGzB,UAAU;IACV,iBAAiB;GACnB;GACA,MAAM,oBAAoB;IAGxB,eAAe;IACf,UAAU;GACZ;GACA,MAAM,wBAAwB;IAC5B,eAAe;IACf,UAAU;IACV,iBAAiB;GACnB;GACA,OAAO,iBAAiB,aAAa,WAAW;GAChD,OAAO,iBAAiB,iBAAiB,eAAe;GACxD,OAAO,iBAAiB,WAAW,eAAe,IAAI;GACtD,qBAAqB;IACnB,OAAO,oBAAoB,aAAa,WAAW;IACnD,OAAO,oBAAoB,iBAAiB,eAAe;IAC3D,OAAO,oBAAoB,WAAW,eAAe,IAAI;IACzD,eAAe,KAAA;GACjB;EACF;EAEA,sBAAsB,eAAe,CAAC;;GAIpC,OAAA,UAAA,GAAA,YAyBa,MAAA,UAAA,GAAA;IAxBV,eAAa,OAAA;IACb,KAAK,QAAA;IACL,KAAK,QAAA;IACL,MAAM,QAAA;IACN,UAAU,QAAA;IACV,OAAK,eAAS,MAAA,EAAA,CAAE,CAAA,mHAAqI,MAAA,KAAA,CAAK,CAAC,KAAA,CAAA;IAM3J,eAAa;IACb,uBAAoB;IACpB,eAAc;;IAEf,SAAA,cAIc,CAJd,YAIc,MAAA,WAAA,GAAA,EAJD,OAAM,mDAAkD,GAAA;KAGnE,SAAA,cAA+D,CAA/D,YAA+D,MAAA,WAAA,GAAA,EAAlD,OAAM,0CAAyC,CAAA,CAAA,CAAA;;IAE9D,CAAA,GAAA,YAGE,MAAA,WAAA,GAHF,WACU,MAER,UAAA,GAFkB,EAClB,OAAM,4SAA2S,CAAA,GAAA,MAAA,EAAA,CAAA,CAAA"}