@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 @@
1
+ {"version":3,"file":"TextField.vue_vue_type_script_setup_true_lang.js","names":["$slots","$emit"],"sources":["../../../src/primitives/TextField/TextField.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type TextFieldType = \"text\" | \"email\" | \"password\" | \"search\" | \"url\" | \"tel\";\n\nexport type TextFieldSize = \"sm\" | \"md\" | \"lg\";\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"../../lib/cn\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\n\n/**\n * TextField — single-line text entry (text · email · password · search · url ·\n * tel). The border, focus ring and invalid state live on the wrapper so\n * optional `#leading`/`#trailing` adornments (a search icon, a unit suffix)\n * sit *inside* the field and share its focus bloom, instead of every caller\n * re-inventing an icon-inside-input layout. For numeric entry reach for a\n * number field; for a bounded continuous value, a slider.\n *\n * Wrapping a rendered structure means the fallthrough `class` must land on\n * the wrapper (so a caller's `w-64`/`flex-1` sizes the whole field) while the\n * rest of the attrs (`id`, `name`, `data-testid`, `aria-describedby`,\n * `autocomplete`) belong on the real `<input>` — the split-attrs convention\n * shared with the other bare controls. The accessible name is a first-class\n * prop pair (`aria-label`/`aria-labelledby`, camelized by Vue) rather than a\n * loose fallthrough attr, so it is bound onto the input explicitly and shows\n * up in the props table — a bare input primitive can only be named by its\n * host.\n */\nwithDefaults(\n defineProps<{\n /** The current value. Pair with `@update:modelValue` for `v-model`. */\n modelValue?: string;\n /** The native input type — also the on-screen keyboard hint on mobile. */\n type?: TextFieldType;\n /** Text shown in the empty field. */\n placeholder?: string;\n /** Disables the field and blocks pointer and keyboard input. */\n disabled?: boolean;\n /** Error state: paints the destructive border/ring and sets aria-invalid. */\n invalid?: boolean;\n /** Control height. */\n size?: TextFieldSize;\n /** The accessible name, when no visible element already labels the field. */\n ariaLabel?: string;\n /** The id of the visible element that labels the field (e.g. a Field wrapper's label). */\n ariaLabelledby?: string;\n }>(),\n {\n type: \"text\",\n disabled: false,\n invalid: false,\n size: \"md\",\n },\n);\n\ndefineEmits<{ \"update:modelValue\": [value: string] }>();\n\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: inputAttrs } = useSplitAttrs();\n</script>\n\n<template>\n <div\n :data-disabled=\"disabled || undefined\"\n :data-invalid=\"invalid || undefined\"\n :class=\"\n cn(\n 'group flex items-center gap-2 rounded-md border border-input bg-background text-foreground',\n 'transition-[color,background-color,border-color,box-shadow] duration-fast ease-out',\n // Rim-lit at rest, the weave blooms on focus (Signature law): the field\n // catches light instead of casting a shadow, and focus draws it tight.\n 'focus-within:outline-2 focus-within:outline-offset-2 focus-within:outline-ring',\n !invalid && 'focus-within:shadow-halo',\n size === 'sm' && 'h-8 px-2.5 text-xs',\n size === 'md' && 'h-9 px-3 text-sm',\n size === 'lg' && 'h-11 px-4 text-base',\n invalid && 'border-destructive focus-within:outline-destructive',\n disabled && 'cursor-not-allowed opacity-50',\n attrs.class as string,\n )\n \"\n >\n <span\n v-if=\"$slots.leading\"\n class=\"inline-flex shrink-0 text-muted-foreground transition-colors duration-fast ease-out group-focus-within:text-foreground\"\n >\n <slot name=\"leading\" />\n </span>\n <input\n v-bind=\"inputAttrs\"\n :aria-label=\"ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :type=\"type\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :aria-invalid=\"invalid || undefined\"\n class=\"min-w-0 flex-1 bg-transparent outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed\"\n @input=\"$emit('update:modelValue', ($event.target as HTMLInputElement).value)\"\n />\n <span\n v-if=\"$slots.trailing\"\n class=\"inline-flex shrink-0 text-muted-foreground transition-colors duration-fast ease-out group-focus-within:text-foreground\"\n >\n <slot name=\"trailing\" />\n </span>\n </div>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0DA,MAAM,EAAE,OAAO,MAAM,eAAe,cAAc;;GAIhD,OAAA,UAAA,GAAA,mBA4CM,OAAA;IA3CH,iBAAe,QAAA,YAAY,KAAA;IAC3B,gBAAc,QAAA,WAAW,KAAA;IACzB,OAAK,eAAS,MAAA,EAAA,CAAE,CAAA,8FAAA,sFAAA,kFAA0c,CAAA,QAAA,WAAO,4BAAwC,QAAA,SAAI,QAAA,sBAA2C,QAAA,SAAI,QAAA,oBAAyC,QAAA,SAAI,QAAA,uBAA4C,QAAA,WAAO,uDAAmE,QAAA,YAAQ,iCAA6C,MAAA,KAAA,CAAK,CAAC,KAAA,CAAA;;IAkBnxBA,KAAAA,OAAO,WADf,UAAA,GAAA,mBAKO,QALP,YAKO,CADL,WAAuB,KAAA,QAAA,SAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA;IAEzB,mBAWE,SAXF,WACU,MAUR,UAAA,GAVkB;KACjB,cAAY,QAAA;KACZ,mBAAiB,QAAA;KACjB,MAAM,QAAA;KACN,OAAO,QAAA;KACP,aAAa,QAAA;KACb,UAAU,QAAA;KACV,gBAAc,QAAA,WAAW,KAAA;KAC1B,OAAM;KACL,SAAK,OAAA,OAAA,OAAA,MAAA,WAAEC,KAAAA,MAAK,qBAAuB,OAAO,OAA4B,KAAK;;IAGtED,KAAAA,OAAO,YADf,UAAA,GAAA,mBAKO,QALP,YAKO,CADL,WAAwB,KAAA,QAAA,UAAA,CAAA,CAAA,KAAA,mBAAA,IAAA,IAAA"}
@@ -0,0 +1,7 @@
1
+ import Textarea_vue_vue_type_script_setup_true_lang_default from "./Textarea.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/primitives/Textarea/Textarea.vue
3
+ var Textarea_default = Textarea_vue_vue_type_script_setup_true_lang_default;
4
+ //#endregion
5
+ export { Textarea_default as default };
6
+
7
+ //# sourceMappingURL=Textarea.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Textarea.js","names":[],"sources":["../../../src/primitives/Textarea/Textarea.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type TextareaResize = \"none\" | \"vertical\";\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"../../lib/cn\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\n\n/**\n * Textarea — multi-line text entry. A native `<textarea>`, single node (no\n * wrapper — unlike TextField there are no `#leading`/`#trailing` adornments to\n * frame), so `class` and the rest of the fallthrough attrs both target the\n * same element; still routed through `useSplitAttrs()` for the same reason as\n * every other primitive — a caller's `class` needs a Tailwind-aware `cn()`\n * merge, not a raw `v-bind` clobbering it. The accessible name is a\n * first-class prop pair (`aria-label`/`aria-labelledby`, camelized by Vue)\n * bound onto the textarea explicitly, the same contract as TextField.\n */\nwithDefaults(\n defineProps<{\n /** The current value. Pair with `@update:modelValue` for `v-model`. */\n modelValue?: string;\n /** Text shown in the empty field. */\n placeholder?: string;\n /** Disables the field and blocks pointer and keyboard input. */\n disabled?: boolean;\n /** Error state: paints the destructive border/ring and sets aria-invalid. */\n invalid?: boolean;\n /** Initial height in text rows. */\n rows?: number;\n /** Whether a person can drag-resize the field; `none` locks it to `rows`. */\n resize?: TextareaResize;\n /** The accessible name, when no visible element already labels the field. */\n ariaLabel?: string;\n /** The id of the visible element that labels the field (e.g. a Field wrapper's label). */\n ariaLabelledby?: string;\n }>(),\n {\n disabled: false,\n invalid: false,\n rows: 3,\n resize: \"vertical\",\n },\n);\n\ndefineEmits<{ \"update:modelValue\": [value: string] }>();\n\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: textareaAttrs } = useSplitAttrs();\n</script>\n\n<template>\n <textarea\n v-bind=\"textareaAttrs\"\n :aria-label=\"ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :rows=\"rows\"\n :aria-invalid=\"invalid || undefined\"\n :class=\"\n cn(\n 'rounded-md border border-input bg-background text-foreground px-3 py-2 text-sm',\n 'transition-[color,background-color,border-color,box-shadow] duration-fast ease-out',\n // Rim-lit at rest, the weave blooms on focus (Signature law).\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n !invalid && 'focus-visible:shadow-halo',\n 'placeholder:text-muted-foreground',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n invalid && 'border-destructive focus-visible:outline-destructive',\n resize === 'none' ? 'resize-none' : 'resize-y',\n attrs.class as string,\n )\n \"\n @input=\"$emit('update:modelValue', ($event.target as HTMLTextAreaElement).value)\"\n />\n</template>\n"],"mappings":""}
@@ -0,0 +1,48 @@
1
+ export type TextareaResize = "none" | "vertical";
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
4
+ declare const __VLS_export: import("vue").DefineComponent<{
5
+ /** The current value. Pair with `@update:modelValue` for `v-model`. */
6
+ modelValue?: string;
7
+ /** Text shown in the empty field. */
8
+ placeholder?: string;
9
+ /** Disables the field and blocks pointer and keyboard input. */
10
+ disabled?: boolean;
11
+ /** Error state: paints the destructive border/ring and sets aria-invalid. */
12
+ invalid?: boolean;
13
+ /** Initial height in text rows. */
14
+ rows?: number;
15
+ /** Whether a person can drag-resize the field; `none` locks it to `rows`. */
16
+ resize?: TextareaResize;
17
+ /** The accessible name, when no visible element already labels the field. */
18
+ ariaLabel?: string;
19
+ /** The id of the visible element that labels the field (e.g. a Field wrapper's label). */
20
+ ariaLabelledby?: string;
21
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
22
+ "update:modelValue": (value: string) => any;
23
+ }, string, import("vue").PublicProps, Readonly<{
24
+ /** The current value. Pair with `@update:modelValue` for `v-model`. */
25
+ modelValue?: string;
26
+ /** Text shown in the empty field. */
27
+ placeholder?: string;
28
+ /** Disables the field and blocks pointer and keyboard input. */
29
+ disabled?: boolean;
30
+ /** Error state: paints the destructive border/ring and sets aria-invalid. */
31
+ invalid?: boolean;
32
+ /** Initial height in text rows. */
33
+ rows?: number;
34
+ /** Whether a person can drag-resize the field; `none` locks it to `rows`. */
35
+ resize?: TextareaResize;
36
+ /** The accessible name, when no visible element already labels the field. */
37
+ ariaLabel?: string;
38
+ /** The id of the visible element that labels the field (e.g. a Field wrapper's label). */
39
+ ariaLabelledby?: string;
40
+ }> & Readonly<{
41
+ "onUpdate:modelValue"?: (value: string) => any;
42
+ }>, {
43
+ disabled: boolean;
44
+ invalid: boolean;
45
+ resize: TextareaResize;
46
+ rows: number;
47
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
48
+ //# sourceMappingURL=Textarea.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Textarea.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Textarea/Textarea.vue"],"names":[],"mappings":"AAqFA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,CAAC;wBAC5B,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAYd,uEAAuE;iBAC1D,MAAM;IACnB,qCAAqC;kBACvB,MAAM;IACpB,gEAAgE;eACrD,OAAO;IAClB,6EAA6E;cACnE,OAAO;IACjB,mCAAmC;WAC5B,MAAM;IACb,6EAA6E;aACpE,cAAc;IACvB,6EAA6E;gBACjE,MAAM;IAClB,0FAA0F;qBACzE,MAAM;;;;IAfvB,uEAAuE;iBAC1D,MAAM;IACnB,qCAAqC;kBACvB,MAAM;IACpB,gEAAgE;eACrD,OAAO;IAClB,6EAA6E;cACnE,OAAO;IACjB,mCAAmC;WAC5B,MAAM;IACb,6EAA6E;aACpE,cAAc;IACvB,6EAA6E;gBACjE,MAAM;IAClB,0FAA0F;qBACzE,MAAM;;;;cAVZ,OAAO;aAER,OAAO;YAIR,cAAc;UAFhB,MAAM;6EAyFb,CAAC"}
@@ -0,0 +1,54 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { useSplitAttrs } from "../../lib/attrs.js";
3
+ import { createElementBlock, defineComponent, mergeProps, openBlock, unref } from "vue";
4
+ //#region src/primitives/Textarea/Textarea.vue?vue&type=script&setup=true&lang.ts
5
+ var _hoisted_1 = [
6
+ "aria-label",
7
+ "aria-labelledby",
8
+ "value",
9
+ "placeholder",
10
+ "disabled",
11
+ "rows",
12
+ "aria-invalid"
13
+ ];
14
+ var Textarea_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
15
+ inheritAttrs: false,
16
+ __name: "Textarea",
17
+ props: {
18
+ modelValue: {},
19
+ placeholder: {},
20
+ disabled: {
21
+ type: Boolean,
22
+ default: false
23
+ },
24
+ invalid: {
25
+ type: Boolean,
26
+ default: false
27
+ },
28
+ rows: { default: 3 },
29
+ resize: { default: "vertical" },
30
+ ariaLabel: {},
31
+ ariaLabelledby: {}
32
+ },
33
+ emits: ["update:modelValue"],
34
+ setup(__props) {
35
+ const { attrs, rest: textareaAttrs } = useSplitAttrs();
36
+ return (_ctx, _cache) => {
37
+ return openBlock(), createElementBlock("textarea", mergeProps(unref(textareaAttrs), {
38
+ "aria-label": __props.ariaLabel,
39
+ "aria-labelledby": __props.ariaLabelledby,
40
+ value: __props.modelValue,
41
+ placeholder: __props.placeholder,
42
+ disabled: __props.disabled,
43
+ rows: __props.rows,
44
+ "aria-invalid": __props.invalid || void 0,
45
+ class: unref(cn)("rounded-md border border-input bg-background text-foreground px-3 py-2 text-sm", "transition-[color,background-color,border-color,box-shadow] duration-fast ease-out", "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring", !__props.invalid && "focus-visible:shadow-halo", "placeholder:text-muted-foreground", "disabled:cursor-not-allowed disabled:opacity-50", __props.invalid && "border-destructive focus-visible:outline-destructive", __props.resize === "none" ? "resize-none" : "resize-y", unref(attrs).class),
46
+ onInput: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("update:modelValue", $event.target.value))
47
+ }), null, 16, _hoisted_1);
48
+ };
49
+ }
50
+ });
51
+ //#endregion
52
+ export { Textarea_vue_vue_type_script_setup_true_lang_default as default };
53
+
54
+ //# sourceMappingURL=Textarea.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Textarea.vue_vue_type_script_setup_true_lang.js","names":["$emit"],"sources":["../../../src/primitives/Textarea/Textarea.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type TextareaResize = \"none\" | \"vertical\";\n</script>\n\n<script setup lang=\"ts\">\nimport { cn } from \"../../lib/cn\";\nimport { useSplitAttrs } from \"../../lib/attrs\";\n\n/**\n * Textarea — multi-line text entry. A native `<textarea>`, single node (no\n * wrapper — unlike TextField there are no `#leading`/`#trailing` adornments to\n * frame), so `class` and the rest of the fallthrough attrs both target the\n * same element; still routed through `useSplitAttrs()` for the same reason as\n * every other primitive — a caller's `class` needs a Tailwind-aware `cn()`\n * merge, not a raw `v-bind` clobbering it. The accessible name is a\n * first-class prop pair (`aria-label`/`aria-labelledby`, camelized by Vue)\n * bound onto the textarea explicitly, the same contract as TextField.\n */\nwithDefaults(\n defineProps<{\n /** The current value. Pair with `@update:modelValue` for `v-model`. */\n modelValue?: string;\n /** Text shown in the empty field. */\n placeholder?: string;\n /** Disables the field and blocks pointer and keyboard input. */\n disabled?: boolean;\n /** Error state: paints the destructive border/ring and sets aria-invalid. */\n invalid?: boolean;\n /** Initial height in text rows. */\n rows?: number;\n /** Whether a person can drag-resize the field; `none` locks it to `rows`. */\n resize?: TextareaResize;\n /** The accessible name, when no visible element already labels the field. */\n ariaLabel?: string;\n /** The id of the visible element that labels the field (e.g. a Field wrapper's label). */\n ariaLabelledby?: string;\n }>(),\n {\n disabled: false,\n invalid: false,\n rows: 3,\n resize: \"vertical\",\n },\n);\n\ndefineEmits<{ \"update:modelValue\": [value: string] }>();\n\ndefineOptions({ inheritAttrs: false });\nconst { attrs, rest: textareaAttrs } = useSplitAttrs();\n</script>\n\n<template>\n <textarea\n v-bind=\"textareaAttrs\"\n :aria-label=\"ariaLabel\"\n :aria-labelledby=\"ariaLabelledby\"\n :value=\"modelValue\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :rows=\"rows\"\n :aria-invalid=\"invalid || undefined\"\n :class=\"\n cn(\n 'rounded-md border border-input bg-background text-foreground px-3 py-2 text-sm',\n 'transition-[color,background-color,border-color,box-shadow] duration-fast ease-out',\n // Rim-lit at rest, the weave blooms on focus (Signature law).\n 'focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring',\n !invalid && 'focus-visible:shadow-halo',\n 'placeholder:text-muted-foreground',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n invalid && 'border-destructive focus-visible:outline-destructive',\n resize === 'none' ? 'resize-none' : 'resize-y',\n attrs.class as string,\n )\n \"\n @input=\"$emit('update:modelValue', ($event.target as HTMLTextAreaElement).value)\"\n />\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgDA,MAAM,EAAE,OAAO,MAAM,kBAAkB,cAAc;;GAInD,OAAA,UAAA,GAAA,mBAwBE,YAxBF,WACU,MAuBR,aAAA,GAvBqB;IACpB,cAAY,QAAA;IACZ,mBAAiB,QAAA;IACjB,OAAO,QAAA;IACP,aAAa,QAAA;IACb,UAAU,QAAA;IACV,MAAM,QAAA;IACN,gBAAc,QAAA,WAAW,KAAA;IACzB,OAAc,MAAA,EAAA,CAAE,CAAA,kFAAA,sFAAA,qFAAuW,CAAA,QAAA,WAAO,6BAAA,qCAAA,mDAAiJ,QAAA,WAAO,wDAAoE,QAAA,WAAM,SAAA,gBAAA,YAAkD,MAAA,KAAA,CAAK,CAAC,KAAA;IAcxpB,SAAK,OAAA,OAAA,OAAA,MAAA,WAAEA,KAAAA,MAAK,qBAAuB,OAAO,OAA+B,KAAK"}
@@ -0,0 +1,7 @@
1
+ import Toast_vue_vue_type_script_setup_true_lang_default from "./Toast.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/primitives/Toast/Toast.vue
3
+ var Toast_default = Toast_vue_vue_type_script_setup_true_lang_default;
4
+ //#endregion
5
+ export { Toast_default as default };
6
+
7
+ //# sourceMappingURL=Toast.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toast.js","names":[],"sources":["../../../src/primitives/Toast/Toast.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type ToastVariant = \"info\" | \"success\" | \"warning\" | \"destructive\" | \"ai\";\n</script>\n\n<script setup lang=\"ts\">\nimport { ToastProvider, ToastViewport } from \"reka-ui\";\nimport { optional } from \"../../lib/props\";\nimport ToastItem from \"./ToastItem.vue\";\n\n/**\n * Toast — a transient, self-dismissing notification the user need not act on\n * (a save confirmed, an export finished, a recoverable error). Built on Reka\n * UI's Toast: it announces to assistive tech (`role`/`aria-live`), pauses on\n * hover/focus, and is swipe/Esc dismissible.\n *\n * Presentational and self-contained — the provider + viewport are bundled so a\n * single Toast works standalone (the card itself lives in the internal\n * `ToastItem`), and it stays free of any queue logic: the host owns *when*\n * toasts open (this primitive renders one). An app that shows several at once\n * has to keep its own queue and its own provider/viewport pair — several\n * standalone `Toast`s each bundling their own viewport would stack at the\n * same screen coordinates rather than list one below the next.\n *\n * For a blocking confirmation use `Dialog`; for a persistent field/section error\n * that must stay until resolved use `InlineError`.\n */\nwithDefaults(\n defineProps<{\n /** Controls visibility; pair with `v-model:open`. Omit to let the toast own its own open state. */\n open?: boolean | undefined;\n /** The toast's headline — always shown. */\n title: string;\n /** An optional second line of detail below the title. */\n description?: string;\n /** Selects the accent icon and colour. */\n variant?: ToastVariant;\n /** ms before auto-dismiss; the Reka default pauses on hover/focus. */\n duration?: number;\n /** Shows the ✕ close button. */\n closable?: boolean;\n /** Renders a single inline action button; emits `action` when pressed. */\n actionLabel?: string;\n }>(),\n {\n // `open` is tri-state and its third state is the default: `undefined`\n // means the toast has not been handed an owner and manages itself. Vue\n // would otherwise cast an absent Boolean prop to `false`, which reads as\n // \"the host says closed\" and leaves `<Toast title=\"…\" />` rendering\n // nothing at all. Declaring the default explicitly is what keeps\n // `undefined` reachable.\n open: undefined,\n variant: \"info\",\n duration: 5000,\n closable: true,\n },\n);\n\ndefineEmits<{ \"update:open\": [value: boolean]; action: [] }>();\n</script>\n\n<template>\n <ToastProvider>\n <ToastItem\n v-bind=\"optional({ open, description, actionLabel })\"\n :title=\"title\"\n :variant=\"variant\"\n :duration=\"duration\"\n :closable=\"closable\"\n @update:open=\"$emit('update:open', $event)\"\n @action=\"$emit('action')\"\n />\n\n <ToastViewport\n class=\"fixed bottom-0 right-0 z-[100] flex w-[min(92vw,24rem)] flex-col gap-2 p-4 outline-none\"\n />\n </ToastProvider>\n</template>\n"],"mappings":""}
@@ -0,0 +1,46 @@
1
+ export type ToastVariant = "info" | "success" | "warning" | "destructive" | "ai";
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
4
+ declare const __VLS_export: import("vue").DefineComponent<{
5
+ /** Controls visibility; pair with `v-model:open`. Omit to let the toast own its own open state. */
6
+ open?: boolean | undefined;
7
+ /** The toast's headline — always shown. */
8
+ title: string;
9
+ /** An optional second line of detail below the title. */
10
+ description?: string;
11
+ /** Selects the accent icon and colour. */
12
+ variant?: ToastVariant;
13
+ /** ms before auto-dismiss; the Reka default pauses on hover/focus. */
14
+ duration?: number;
15
+ /** Shows the ✕ close button. */
16
+ closable?: boolean;
17
+ /** Renders a single inline action button; emits `action` when pressed. */
18
+ actionLabel?: string;
19
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
20
+ "update:open": (value: boolean) => any;
21
+ action: () => any;
22
+ }, string, import("vue").PublicProps, Readonly<{
23
+ /** Controls visibility; pair with `v-model:open`. Omit to let the toast own its own open state. */
24
+ open?: boolean | undefined;
25
+ /** The toast's headline — always shown. */
26
+ title: string;
27
+ /** An optional second line of detail below the title. */
28
+ description?: string;
29
+ /** Selects the accent icon and colour. */
30
+ variant?: ToastVariant;
31
+ /** ms before auto-dismiss; the Reka default pauses on hover/focus. */
32
+ duration?: number;
33
+ /** Shows the ✕ close button. */
34
+ closable?: boolean;
35
+ /** Renders a single inline action button; emits `action` when pressed. */
36
+ actionLabel?: string;
37
+ }> & Readonly<{
38
+ "onUpdate:open"?: (value: boolean) => any;
39
+ onAction?: () => any;
40
+ }>, {
41
+ variant: ToastVariant;
42
+ open: boolean | undefined;
43
+ closable: boolean;
44
+ duration: number;
45
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
46
+ //# sourceMappingURL=Toast.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toast.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Toast/Toast.vue"],"names":[],"mappings":"AAqFA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,GAAG,IAAI,CAAC;wBAC5D,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAmBd,mGAAmG;WAC5F,OAAO,GAAG,SAAS;IAC1B,2CAA2C;WACpC,MAAM;IACb,yDAAyD;kBAC3C,MAAM;IACpB,0CAA0C;cAChC,YAAY;IACtB,sEAAsE;eAC3D,MAAM;IACjB,gCAAgC;eACrB,OAAO;IAClB,0EAA0E;kBAC5D,MAAM;;;;;IAbpB,mGAAmG;WAC5F,OAAO,GAAG,SAAS;IAC1B,2CAA2C;WACpC,MAAM;IACb,yDAAyD;kBAC3C,MAAM;IACpB,0CAA0C;cAChC,YAAY;IACtB,sEAAsE;eAC3D,MAAM;IACjB,gCAAgC;eACrB,OAAO;IAClB,0EAA0E;kBAC5D,MAAM;;;;;aANV,YAAY;UANf,OAAO,GAAG,SAAS;cAUf,OAAO;cAFP,MAAM;6EA2IjB,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { optional } from "../../lib/props.js";
2
+ import ToastItem_default from "./ToastItem.js";
3
+ import { createBlock, createVNode, defineComponent, mergeProps, openBlock, unref, withCtx } from "vue";
4
+ import { ToastProvider, ToastViewport } from "reka-ui";
5
+ //#region src/primitives/Toast/Toast.vue?vue&type=script&setup=true&lang.ts
6
+ var Toast_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
7
+ __name: "Toast",
8
+ props: {
9
+ open: {
10
+ type: Boolean,
11
+ default: void 0
12
+ },
13
+ title: {},
14
+ description: {},
15
+ variant: { default: "info" },
16
+ duration: { default: 5e3 },
17
+ closable: {
18
+ type: Boolean,
19
+ default: true
20
+ },
21
+ actionLabel: {}
22
+ },
23
+ emits: ["update:open", "action"],
24
+ setup(__props) {
25
+ return (_ctx, _cache) => {
26
+ return openBlock(), createBlock(unref(ToastProvider), null, {
27
+ default: withCtx(() => [createVNode(ToastItem_default, mergeProps(unref(optional)({
28
+ open: __props.open,
29
+ description: __props.description,
30
+ actionLabel: __props.actionLabel
31
+ }), {
32
+ title: __props.title,
33
+ variant: __props.variant,
34
+ duration: __props.duration,
35
+ closable: __props.closable,
36
+ "onUpdate:open": _cache[0] || (_cache[0] = ($event) => _ctx.$emit("update:open", $event)),
37
+ onAction: _cache[1] || (_cache[1] = ($event) => _ctx.$emit("action"))
38
+ }), null, 16, [
39
+ "title",
40
+ "variant",
41
+ "duration",
42
+ "closable"
43
+ ]), createVNode(unref(ToastViewport), { class: "fixed bottom-0 right-0 z-[100] flex w-[min(92vw,24rem)] flex-col gap-2 p-4 outline-none" })]),
44
+ _: 1
45
+ });
46
+ };
47
+ }
48
+ });
49
+ //#endregion
50
+ export { Toast_vue_vue_type_script_setup_true_lang_default as default };
51
+
52
+ //# sourceMappingURL=Toast.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Toast.vue_vue_type_script_setup_true_lang.js","names":["$emit"],"sources":["../../../src/primitives/Toast/Toast.vue"],"sourcesContent":["<script lang=\"ts\">\nexport type ToastVariant = \"info\" | \"success\" | \"warning\" | \"destructive\" | \"ai\";\n</script>\n\n<script setup lang=\"ts\">\nimport { ToastProvider, ToastViewport } from \"reka-ui\";\nimport { optional } from \"../../lib/props\";\nimport ToastItem from \"./ToastItem.vue\";\n\n/**\n * Toast — a transient, self-dismissing notification the user need not act on\n * (a save confirmed, an export finished, a recoverable error). Built on Reka\n * UI's Toast: it announces to assistive tech (`role`/`aria-live`), pauses on\n * hover/focus, and is swipe/Esc dismissible.\n *\n * Presentational and self-contained — the provider + viewport are bundled so a\n * single Toast works standalone (the card itself lives in the internal\n * `ToastItem`), and it stays free of any queue logic: the host owns *when*\n * toasts open (this primitive renders one). An app that shows several at once\n * has to keep its own queue and its own provider/viewport pair — several\n * standalone `Toast`s each bundling their own viewport would stack at the\n * same screen coordinates rather than list one below the next.\n *\n * For a blocking confirmation use `Dialog`; for a persistent field/section error\n * that must stay until resolved use `InlineError`.\n */\nwithDefaults(\n defineProps<{\n /** Controls visibility; pair with `v-model:open`. Omit to let the toast own its own open state. */\n open?: boolean | undefined;\n /** The toast's headline — always shown. */\n title: string;\n /** An optional second line of detail below the title. */\n description?: string;\n /** Selects the accent icon and colour. */\n variant?: ToastVariant;\n /** ms before auto-dismiss; the Reka default pauses on hover/focus. */\n duration?: number;\n /** Shows the ✕ close button. */\n closable?: boolean;\n /** Renders a single inline action button; emits `action` when pressed. */\n actionLabel?: string;\n }>(),\n {\n // `open` is tri-state and its third state is the default: `undefined`\n // means the toast has not been handed an owner and manages itself. Vue\n // would otherwise cast an absent Boolean prop to `false`, which reads as\n // \"the host says closed\" and leaves `<Toast title=\"…\" />` rendering\n // nothing at all. Declaring the default explicitly is what keeps\n // `undefined` reachable.\n open: undefined,\n variant: \"info\",\n duration: 5000,\n closable: true,\n },\n);\n\ndefineEmits<{ \"update:open\": [value: boolean]; action: [] }>();\n</script>\n\n<template>\n <ToastProvider>\n <ToastItem\n v-bind=\"optional({ open, description, actionLabel })\"\n :title=\"title\"\n :variant=\"variant\"\n :duration=\"duration\"\n :closable=\"closable\"\n @update:open=\"$emit('update:open', $event)\"\n @action=\"$emit('action')\"\n />\n\n <ToastViewport\n class=\"fixed bottom-0 right-0 z-[100] flex w-[min(92vw,24rem)] flex-col gap-2 p-4 outline-none\"\n />\n </ToastProvider>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;GA6DE,OAAA,UAAA,GAAA,YAcgB,MAAA,aAAA,GAAA,MAAA;IAbd,SAAA,cAQE,CARF,YAQE,mBARF,WACU,MAOR,QAAA,CAPgB,CAAA;KAAA,MAAG,QAAA;KAAI,aAAE,QAAA;KAAW,aAAE,QAAA;IAAW,CAAA,GAAA;KAChD,OAAO,QAAA;KACP,SAAS,QAAA;KACT,UAAU,QAAA;KACV,UAAU,QAAA;KACV,iBAAW,OAAA,OAAA,OAAA,MAAA,WAAEA,KAAAA,MAAK,eAAgB,MAAM;KACxC,UAAM,OAAA,OAAA,OAAA,MAAA,WAAEA,KAAAA,MAAK,QAAA;;;;;;IAGhB,CAAA,GAAA,YAEE,MAAA,aAAA,GAAA,EADA,OAAM,0FAAyF,CAAA,CAAA,CAAA"}
@@ -0,0 +1,7 @@
1
+ import ToastItem_vue_vue_type_script_setup_true_lang_default from "./ToastItem.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/primitives/Toast/ToastItem.vue
3
+ var ToastItem_default = ToastItem_vue_vue_type_script_setup_true_lang_default;
4
+ //#endregion
5
+ export { ToastItem_default as default };
6
+
7
+ //# sourceMappingURL=ToastItem.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToastItem.js","names":[],"sources":["../../../src/primitives/Toast/ToastItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { ToastRoot, ToastTitle, ToastDescription, ToastAction, ToastClose } from \"reka-ui\";\nimport { Info, CircleCheck, TriangleAlert, CircleX, Sparkles, X } from \"@lucide/vue\";\nimport { cn } from \"../../lib/cn\";\nimport { optional } from \"../../lib/props\";\nimport type { ToastVariant } from \"./Toast.vue\";\n\n/**\n * ToastItem — one toast card (ToastRoot + Loom treatment), INTERNAL to\n * the design system. It must live inside a `ToastProvider` whose\n * `ToastViewport` it teleports into: `Toast` bundles that pair for the\n * standalone case. Not exported from the barrel — hosts use `Toast`.\n */\nconst props = withDefaults(\n defineProps<{\n /** Controls visibility; pair with `v-model:open`. Omit to let the toast own its own open state. */\n open?: boolean | undefined;\n /** The toast's headline — always shown. */\n title: string;\n /** An optional second line of detail below the title. */\n description?: string;\n /** Selects the accent icon and colour. */\n variant?: ToastVariant;\n /** ms before auto-dismiss; the Reka default pauses on hover/focus. */\n duration?: number;\n /** Shows the ✕ close button. */\n closable?: boolean;\n /** Renders a single inline action button; emits `action` when pressed. */\n actionLabel?: string;\n }>(),\n {\n // See Toast.vue: `undefined` is the uncontrolled state, and only an\n // explicit default keeps it reachable past Vue's Boolean casting.\n open: undefined,\n variant: \"info\",\n duration: 5000,\n closable: true,\n },\n);\n\ndefineEmits<{ \"update:open\": [value: boolean]; action: [] }>();\n\n// `satisfies` binds this map to ToastVariant so a variant added to the type\n// without a matching entry here fails at compile time (Button's own idiom).\nconst toastAccents = {\n info: { icon: Info, color: \"text-info\" },\n success: { icon: CircleCheck, color: \"text-success\" },\n warning: { icon: TriangleAlert, color: \"text-warning\" },\n destructive: { icon: CircleX, color: \"text-destructive\" },\n ai: { icon: Sparkles, color: \"text-primary\" },\n} satisfies Record<ToastVariant, { icon: typeof Info; color: string }>;\n\nconst accent = computed(() => toastAccents[props.variant]);\n</script>\n\n<template>\n <!-- The slide-in animation rides this inner card, never ToastRoot: Reka\n drives ToastRoot's own transform for the swipe-to-dismiss gesture, so a\n filled entrance transform there would freeze the swipe. ToastRoot itself\n carries no animation, so Reka Presence unmounts it immediately on close. -->\n <ToastRoot\n v-bind=\"optional({ open })\"\n :duration=\"duration\"\n class=\"outline-none\"\n @update:open=\"$emit('update:open', $event)\"\n >\n <div\n :class=\"\n cn(\n 'relative flex animate-toast-in items-start gap-3 rounded-md border border-border bg-popover p-3 pr-8 text-popover-foreground shadow-lg',\n // Agent emission (Signature law): an AI-authored toast breathes a\n // Conduct pulse — the one variant driven by an agent, made visible.\n variant === 'ai' && 'border-primary/40',\n )\n \"\n >\n <span\n v-if=\"variant === 'ai'\"\n aria-hidden=\"true\"\n class=\"pointer-events-none absolute inset-0 rounded-md animate-conduct\"\n />\n <component\n :is=\"accent.icon\"\n :class=\"cn('mt-0.5 h-4 w-4 shrink-0', accent.color)\"\n aria-hidden=\"true\"\n />\n <div class=\"min-w-0 flex-1\">\n <ToastTitle class=\"text-sm font-medium\">{{ title }}</ToastTitle>\n <ToastDescription v-if=\"description\" class=\"mt-0.5 text-xs text-muted-foreground\">\n {{ description }}\n </ToastDescription>\n </div>\n\n <ToastAction v-if=\"actionLabel\" :alt-text=\"actionLabel\" as-child @click=\"$emit('action')\">\n <button\n type=\"button\"\n class=\"shrink-0 rounded-sm px-2 py-1 text-xs font-medium text-primary transition-colors duration-fast ease-out hover:bg-subtle focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n >\n {{ actionLabel }}\n </button>\n </ToastAction>\n\n <ToastClose\n v-if=\"closable\"\n aria-label=\"Close\"\n class=\"absolute right-2 top-2 inline-flex h-6 w-6 items-center justify-center rounded-sm text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n >\n <X class=\"h-3.5 w-3.5\" />\n </ToastClose>\n </div>\n </ToastRoot>\n</template>\n"],"mappings":""}
@@ -0,0 +1,38 @@
1
+ import type { ToastVariant } from "./Toast.vue";
2
+ /**
3
+ * ToastItem — one toast card (ToastRoot + Loom treatment), INTERNAL to
4
+ * the design system. It must live inside a `ToastProvider` whose
5
+ * `ToastViewport` it teleports into: `Toast` bundles that pair for the
6
+ * standalone case. Not exported from the barrel — hosts use `Toast`.
7
+ */
8
+ type __VLS_Props = {
9
+ /** Controls visibility; pair with `v-model:open`. Omit to let the toast own its own open state. */
10
+ open?: boolean | undefined;
11
+ /** The toast's headline — always shown. */
12
+ title: string;
13
+ /** An optional second line of detail below the title. */
14
+ description?: string;
15
+ /** Selects the accent icon and colour. */
16
+ variant?: ToastVariant;
17
+ /** ms before auto-dismiss; the Reka default pauses on hover/focus. */
18
+ duration?: number;
19
+ /** Shows the ✕ close button. */
20
+ closable?: boolean;
21
+ /** Renders a single inline action button; emits `action` when pressed. */
22
+ actionLabel?: string;
23
+ };
24
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
25
+ "update:open": (value: boolean) => any;
26
+ action: () => any;
27
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
28
+ "onUpdate:open"?: (value: boolean) => any;
29
+ onAction?: () => any;
30
+ }>, {
31
+ variant: ToastVariant;
32
+ open: boolean | undefined;
33
+ closable: boolean;
34
+ duration: number;
35
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
36
+ declare const _default: typeof __VLS_export;
37
+ export default _default;
38
+ //# sourceMappingURL=ToastItem.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToastItem.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Toast/ToastItem.vue"],"names":[],"mappings":"AAyHA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;;;GAKG;AACH,KAAK,WAAW,GAAG;IACf,mGAAmG;IACnG,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0EAA0E;IAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AA8QJ,QAAA,MAAM,YAAY;;;;;;;aArRJ,YAAY;UANf,OAAO,GAAG,SAAS;cAUf,OAAO;cAFP,MAAM;6EAuRnB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -0,0 +1,114 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { optional } from "../../lib/props.js";
3
+ import { CircleCheck, CircleX, Info, Sparkles, TriangleAlert, X } from "@lucide/vue";
4
+ import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeProps, normalizeClass, openBlock, resolveDynamicComponent, toDisplayString, unref, withCtx } from "vue";
5
+ import { ToastAction, ToastClose, ToastDescription, ToastRoot, ToastTitle } from "reka-ui";
6
+ //#region src/primitives/Toast/ToastItem.vue?vue&type=script&setup=true&lang.ts
7
+ var _hoisted_1 = {
8
+ key: 0,
9
+ "aria-hidden": "true",
10
+ class: "pointer-events-none absolute inset-0 rounded-md animate-conduct"
11
+ };
12
+ var _hoisted_2 = { class: "min-w-0 flex-1" };
13
+ var _hoisted_3 = {
14
+ type: "button",
15
+ class: "shrink-0 rounded-sm px-2 py-1 text-xs font-medium text-primary transition-colors duration-fast ease-out hover:bg-subtle focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring"
16
+ };
17
+ /**
18
+ * ToastItem — one toast card (ToastRoot + Loom treatment), INTERNAL to
19
+ * the design system. It must live inside a `ToastProvider` whose
20
+ * `ToastViewport` it teleports into: `Toast` bundles that pair for the
21
+ * standalone case. Not exported from the barrel — hosts use `Toast`.
22
+ */
23
+ var ToastItem_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
24
+ __name: "ToastItem",
25
+ props: {
26
+ open: {
27
+ type: Boolean,
28
+ default: void 0
29
+ },
30
+ title: {},
31
+ description: {},
32
+ variant: { default: "info" },
33
+ duration: { default: 5e3 },
34
+ closable: {
35
+ type: Boolean,
36
+ default: true
37
+ },
38
+ actionLabel: {}
39
+ },
40
+ emits: ["update:open", "action"],
41
+ setup(__props) {
42
+ const props = __props;
43
+ const toastAccents = {
44
+ info: {
45
+ icon: Info,
46
+ color: "text-info"
47
+ },
48
+ success: {
49
+ icon: CircleCheck,
50
+ color: "text-success"
51
+ },
52
+ warning: {
53
+ icon: TriangleAlert,
54
+ color: "text-warning"
55
+ },
56
+ destructive: {
57
+ icon: CircleX,
58
+ color: "text-destructive"
59
+ },
60
+ ai: {
61
+ icon: Sparkles,
62
+ color: "text-primary"
63
+ }
64
+ };
65
+ const accent = computed(() => toastAccents[props.variant]);
66
+ return (_ctx, _cache) => {
67
+ return openBlock(), createBlock(unref(ToastRoot), mergeProps(unref(optional)({ open: __props.open }), {
68
+ duration: __props.duration,
69
+ class: "outline-none",
70
+ "onUpdate:open": _cache[1] || (_cache[1] = ($event) => _ctx.$emit("update:open", $event))
71
+ }), {
72
+ default: withCtx(() => [createElementVNode("div", { class: normalizeClass(unref(cn)("relative flex animate-toast-in items-start gap-3 rounded-md border border-border bg-popover p-3 pr-8 text-popover-foreground shadow-lg", __props.variant === "ai" && "border-primary/40")) }, [
73
+ __props.variant === "ai" ? (openBlock(), createElementBlock("span", _hoisted_1)) : createCommentVNode("", true),
74
+ (openBlock(), createBlock(resolveDynamicComponent(accent.value.icon), {
75
+ class: normalizeClass(unref(cn)("mt-0.5 h-4 w-4 shrink-0", accent.value.color)),
76
+ "aria-hidden": "true"
77
+ }, null, 8, ["class"])),
78
+ createElementVNode("div", _hoisted_2, [createVNode(unref(ToastTitle), { class: "text-sm font-medium" }, {
79
+ default: withCtx(() => [createTextVNode(toDisplayString(__props.title), 1)]),
80
+ _: 1
81
+ }), __props.description ? (openBlock(), createBlock(unref(ToastDescription), {
82
+ key: 0,
83
+ class: "mt-0.5 text-xs text-muted-foreground"
84
+ }, {
85
+ default: withCtx(() => [createTextVNode(toDisplayString(__props.description), 1)]),
86
+ _: 1
87
+ })) : createCommentVNode("", true)]),
88
+ __props.actionLabel ? (openBlock(), createBlock(unref(ToastAction), {
89
+ key: 1,
90
+ "alt-text": __props.actionLabel,
91
+ "as-child": "",
92
+ onClick: _cache[0] || (_cache[0] = ($event) => _ctx.$emit("action"))
93
+ }, {
94
+ default: withCtx(() => [createElementVNode("button", _hoisted_3, toDisplayString(__props.actionLabel), 1)]),
95
+ _: 1
96
+ }, 8, ["alt-text"])) : createCommentVNode("", true),
97
+ __props.closable ? (openBlock(), createBlock(unref(ToastClose), {
98
+ key: 2,
99
+ "aria-label": "Close",
100
+ class: "absolute right-2 top-2 inline-flex h-6 w-6 items-center justify-center rounded-sm text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring"
101
+ }, {
102
+ default: withCtx(() => [createVNode(unref(X), { class: "h-3.5 w-3.5" })]),
103
+ _: 1
104
+ })) : createCommentVNode("", true)
105
+ ], 2)]),
106
+ _: 1
107
+ }, 16, ["duration"]);
108
+ };
109
+ }
110
+ });
111
+ //#endregion
112
+ export { ToastItem_vue_vue_type_script_setup_true_lang_default as default };
113
+
114
+ //# sourceMappingURL=ToastItem.vue_vue_type_script_setup_true_lang.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ToastItem.vue_vue_type_script_setup_true_lang.js","names":["$emit"],"sources":["../../../src/primitives/Toast/ToastItem.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { ToastRoot, ToastTitle, ToastDescription, ToastAction, ToastClose } from \"reka-ui\";\nimport { Info, CircleCheck, TriangleAlert, CircleX, Sparkles, X } from \"@lucide/vue\";\nimport { cn } from \"../../lib/cn\";\nimport { optional } from \"../../lib/props\";\nimport type { ToastVariant } from \"./Toast.vue\";\n\n/**\n * ToastItem — one toast card (ToastRoot + Loom treatment), INTERNAL to\n * the design system. It must live inside a `ToastProvider` whose\n * `ToastViewport` it teleports into: `Toast` bundles that pair for the\n * standalone case. Not exported from the barrel — hosts use `Toast`.\n */\nconst props = withDefaults(\n defineProps<{\n /** Controls visibility; pair with `v-model:open`. Omit to let the toast own its own open state. */\n open?: boolean | undefined;\n /** The toast's headline — always shown. */\n title: string;\n /** An optional second line of detail below the title. */\n description?: string;\n /** Selects the accent icon and colour. */\n variant?: ToastVariant;\n /** ms before auto-dismiss; the Reka default pauses on hover/focus. */\n duration?: number;\n /** Shows the ✕ close button. */\n closable?: boolean;\n /** Renders a single inline action button; emits `action` when pressed. */\n actionLabel?: string;\n }>(),\n {\n // See Toast.vue: `undefined` is the uncontrolled state, and only an\n // explicit default keeps it reachable past Vue's Boolean casting.\n open: undefined,\n variant: \"info\",\n duration: 5000,\n closable: true,\n },\n);\n\ndefineEmits<{ \"update:open\": [value: boolean]; action: [] }>();\n\n// `satisfies` binds this map to ToastVariant so a variant added to the type\n// without a matching entry here fails at compile time (Button's own idiom).\nconst toastAccents = {\n info: { icon: Info, color: \"text-info\" },\n success: { icon: CircleCheck, color: \"text-success\" },\n warning: { icon: TriangleAlert, color: \"text-warning\" },\n destructive: { icon: CircleX, color: \"text-destructive\" },\n ai: { icon: Sparkles, color: \"text-primary\" },\n} satisfies Record<ToastVariant, { icon: typeof Info; color: string }>;\n\nconst accent = computed(() => toastAccents[props.variant]);\n</script>\n\n<template>\n <!-- The slide-in animation rides this inner card, never ToastRoot: Reka\n drives ToastRoot's own transform for the swipe-to-dismiss gesture, so a\n filled entrance transform there would freeze the swipe. ToastRoot itself\n carries no animation, so Reka Presence unmounts it immediately on close. -->\n <ToastRoot\n v-bind=\"optional({ open })\"\n :duration=\"duration\"\n class=\"outline-none\"\n @update:open=\"$emit('update:open', $event)\"\n >\n <div\n :class=\"\n cn(\n 'relative flex animate-toast-in items-start gap-3 rounded-md border border-border bg-popover p-3 pr-8 text-popover-foreground shadow-lg',\n // Agent emission (Signature law): an AI-authored toast breathes a\n // Conduct pulse — the one variant driven by an agent, made visible.\n variant === 'ai' && 'border-primary/40',\n )\n \"\n >\n <span\n v-if=\"variant === 'ai'\"\n aria-hidden=\"true\"\n class=\"pointer-events-none absolute inset-0 rounded-md animate-conduct\"\n />\n <component\n :is=\"accent.icon\"\n :class=\"cn('mt-0.5 h-4 w-4 shrink-0', accent.color)\"\n aria-hidden=\"true\"\n />\n <div class=\"min-w-0 flex-1\">\n <ToastTitle class=\"text-sm font-medium\">{{ title }}</ToastTitle>\n <ToastDescription v-if=\"description\" class=\"mt-0.5 text-xs text-muted-foreground\">\n {{ description }}\n </ToastDescription>\n </div>\n\n <ToastAction v-if=\"actionLabel\" :alt-text=\"actionLabel\" as-child @click=\"$emit('action')\">\n <button\n type=\"button\"\n class=\"shrink-0 rounded-sm px-2 py-1 text-xs font-medium text-primary transition-colors duration-fast ease-out hover:bg-subtle focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n >\n {{ actionLabel }}\n </button>\n </ToastAction>\n\n <ToastClose\n v-if=\"closable\"\n aria-label=\"Close\"\n class=\"absolute right-2 top-2 inline-flex h-6 w-6 items-center justify-center rounded-sm text-muted-foreground transition-colors duration-fast ease-out hover:bg-subtle hover:text-foreground focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring\"\n >\n <X class=\"h-3.5 w-3.5\" />\n </ToastClose>\n </div>\n </ToastRoot>\n</template>\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAcA,MAAM,QAAQ;EA+Bd,MAAM,eAAe;GACnB,MAAM;IAAE,MAAM;IAAM,OAAO;GAAY;GACvC,SAAS;IAAE,MAAM;IAAa,OAAO;GAAe;GACpD,SAAS;IAAE,MAAM;IAAe,OAAO;GAAe;GACtD,aAAa;IAAE,MAAM;IAAS,OAAO;GAAmB;GACxD,IAAI;IAAE,MAAM;IAAU,OAAO;GAAe;EAC9C;EAEA,MAAM,SAAS,eAAe,aAAa,MAAM,QAAQ;;GAQvD,OAAA,UAAA,GAAA,YAkDY,MAAA,SAAA,GAlDZ,WACU,MAiDE,QAAA,CAjDM,CAAA,EAAA,MAAG,QAAA,KAAI,CAAA,GAAA;IACtB,UAAU,QAAA;IACX,OAAM;IACL,iBAAW,OAAA,OAAA,OAAA,MAAA,WAAEA,KAAAA,MAAK,eAAgB,MAAM;;IAEzC,SAAA,cA2CM,CA3CN,mBA2CM,OAAA,EA1CH,OAAK,eAAW,MAAA,EAAA,CAAE,CAAA,0IAA4T,QAAA,YAAO,QAAA,mBAAA,CAAA,EAAA,GAAA;KAU9U,QAAA,YAAO,QADf,UAAA,GAAA,mBAIE,QAJF,UAIE,KAAA,mBAAA,IAAA,IAAA;MACF,UAAA,GAAA,YAIE,wBAHK,OAAA,MAAO,IAAI,GAAA;MACf,OAAK,eAAE,MAAA,EAAA,CAAE,CAAA,2BAA4B,OAAA,MAAO,KAAK,CAAA;MAClD,eAAY;;KAEd,mBAKM,OALN,YAKM,CAJJ,YAAgE,MAAA,UAAA,GAAA,EAApD,OAAM,sBAAqB,GAAA;MAAC,SAAA,cAAW,CAAR,gBAAA,gBAAA,QAAA,KAAK,GAAA,CAAA,CAAA,CAAA;;KACxB,CAAA,GAAA,QAAA,eAAxB,UAAA,GAAA,YAEmB,MAAA,gBAAA,GAAA;;MAFkB,OAAM;;MACzC,SAAA,cAAiB,CAAd,gBAAA,gBAAA,QAAA,WAAW,GAAA,CAAA,CAAA,CAAA;;;KAIC,QAAA,eAAnB,UAAA,GAAA,YAOc,MAAA,WAAA,GAAA;;MAPmB,YAAU,QAAA;MAAa,YAAA;MAAU,SAAK,OAAA,OAAA,OAAA,MAAA,WAAEA,KAAAA,MAAK,QAAA;;MAC5E,SAAA,cAKS,CALT,mBAKS,UALT,YAKS,gBADJ,QAAA,WAAW,GAAA,CAAA,CAAA,CAAA;;;KAKV,QAAA,YADR,UAAA,GAAA,YAMa,MAAA,UAAA,GAAA;;MAJX,cAAW;MACX,OAAM;;MAEN,SAAA,cAAyB,CAAzB,YAAyB,MAAA,CAAA,GAAA,EAAtB,OAAM,cAAa,CAAA,CAAA,CAAA"}
@@ -0,0 +1,7 @@
1
+ import Tooltip_vue_vue_type_script_setup_true_lang_default from "./Tooltip.vue_vue_type_script_setup_true_lang.js";
2
+ //#region src/primitives/Tooltip/Tooltip.vue
3
+ var Tooltip_default = Tooltip_vue_vue_type_script_setup_true_lang_default;
4
+ //#endregion
5
+ export { Tooltip_default as default };
6
+
7
+ //# sourceMappingURL=Tooltip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tooltip.js","names":[],"sources":["../../../src/primitives/Tooltip/Tooltip.vue"],"sourcesContent":["<script lang=\"ts\">\n/**\n * Which edge of the trigger the tip prefers, before collision flipping. The\n * members mirror Reka's own `Side`, and the template binding is what enforces\n * that: a member Reka does not accept stops `:side=\"side\"` type-checking.\n * Declared here rather than aliased so the generated props table prints the\n * four values instead of a name that tells the reader nothing.\n */\nexport type TooltipSide = \"top\" | \"right\" | \"bottom\" | \"left\";\n</script>\n\n<script setup lang=\"ts\">\nimport {\n TooltipProvider,\n TooltipRoot,\n TooltipTrigger,\n TooltipPortal,\n TooltipContent,\n TooltipArrow,\n} from \"reka-ui\";\nimport { cn } from \"../../lib/cn\";\nimport { optional } from \"../../lib/props\";\n\n/**\n * Tooltip — a short, non-interactive hint on hover or keyboard focus of its\n * trigger: the label for an icon-only button, or one terse explanation.\n *\n * A tooltip is not a small dialog, and the difference is the whole contract.\n * It never takes focus — focus stays on the trigger the entire time it is\n * shown, which is what lets a keyboard user read it and keep going. Hovering\n * the trigger or focusing it opens the tip; Esc, blur and moving the pointer\n * away close it; the page behind never stops scrolling. Nothing inside it can\n * be reached, so nothing interactive belongs inside it. The moment a hint\n * needs a link or a button, it is a `Popover`.\n *\n * It is wired as `aria-describedby`, never `aria-labelledby`: it *supplements*\n * an accessible name and must never be the only source of one. An icon-only\n * button still carries its own `aria-label` — a screen reader user who never\n * hovers would otherwise meet an unnamed button.\n *\n * The provider is bundled in so a single tooltip works with no setup. An\n * application with many can hoist one Reka `TooltipProvider` higher later,\n * which is what shares the hover delay across them.\n */\nwithDefaults(\n defineProps<{\n /** The hint text. The default slot overrides it where the hint needs markup. */\n content?: string;\n /** The edge of the trigger to anchor against, before collision flipping. */\n side?: TooltipSide;\n /** Gap in pixels between the trigger and the tip. */\n sideOffset?: number;\n /** Milliseconds of hover before the tip appears. Keyboard focus is always immediate. */\n delay?: number;\n /** Drive the tip from the host with `v-model:open` — an onboarding hint, say. Omit it for hover and focus alone. */\n open?: boolean | undefined;\n }>(),\n // `open: undefined` is load-bearing, not a redundant default — it is what\n // keeps the uncontrolled third state reachable past Vue's absent-Boolean\n // casting. `optional()` in the template is the other half; its docblock\n // carries the reasoning for both. `content` needs no such entry: a string\n // prop is already `undefined` when absent.\n { open: undefined, side: \"top\", sideOffset: 6, delay: 300 },\n);\n\ndefineEmits<{ \"update:open\": [value: boolean] }>();\n</script>\n\n<template>\n <TooltipProvider :delay-duration=\"delay\">\n <TooltipRoot v-bind=\"optional({ open })\" @update:open=\"$emit('update:open', $event)\">\n <!-- @slot The element the hint describes. Rendered `as-child`, so the\n caller's own element *is* the trigger and keeps its own accessible\n name. -->\n <TooltipTrigger as-child>\n <slot name=\"trigger\" />\n </TooltipTrigger>\n\n <TooltipPortal>\n <TooltipContent\n :side=\"side\"\n :side-offset=\"sideOffset\"\n :class=\"\n cn(\n 'z-50 max-w-[16rem] rounded-md bg-foreground px-2 py-1 text-xs font-medium text-background shadow-md',\n // Scoped to the open state, never unconditional. Reka's Presence\n // keeps closed content mounted until an animationend arrives, and\n // a mount-only animation never fires a second one — so an\n // unconditional animation class leaves a stray tip in the page.\n // Scoped, the closed element computes `animation-name: none` and\n // Presence unmounts it at once.\n //\n // `delayed-open` rather than `open`: the animation belongs to the\n // hover path, which the user waited for. A tip opened by keyboard\n // focus appears instantly, because a keyboard user asked for it\n // deliberately and has nothing to wait through.\n 'data-[state=delayed-open]:animate-scale-in',\n )\n \"\n style=\"transform-origin: var(--reka-popper-transform-origin)\"\n >\n <!-- @slot The hint, where markup is needed. Takes precedence over\n `content`. Nothing interactive belongs here — a tooltip cannot be\n reached by keyboard or pointer. -->\n <slot>{{ content }}</slot>\n <TooltipArrow class=\"fill-foreground\" :width=\"10\" :height=\"5\" />\n </TooltipContent>\n </TooltipPortal>\n </TooltipRoot>\n </TooltipProvider>\n</template>\n"],"mappings":""}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Which edge of the trigger the tip prefers, before collision flipping. The
3
+ * members mirror Reka's own `Side`, and the template binding is what enforces
4
+ * that: a member Reka does not accept stops `:side="side"` type-checking.
5
+ * Declared here rather than aliased so the generated props table prints the
6
+ * four values instead of a name that tells the reader nothing.
7
+ */
8
+ export type TooltipSide = "top" | "right" | "bottom" | "left";
9
+ declare const _default: typeof __VLS_export;
10
+ export default _default;
11
+ declare const __VLS_export: __VLS_WithSlots<import("vue").DefineComponent<{
12
+ /** The hint text. The default slot overrides it where the hint needs markup. */
13
+ content?: string;
14
+ /** The edge of the trigger to anchor against, before collision flipping. */
15
+ side?: TooltipSide;
16
+ /** Gap in pixels between the trigger and the tip. */
17
+ sideOffset?: number;
18
+ /** Milliseconds of hover before the tip appears. Keyboard focus is always immediate. */
19
+ delay?: number;
20
+ /** Drive the tip from the host with `v-model:open` — an onboarding hint, say. Omit it for hover and focus alone. */
21
+ open?: boolean | undefined;
22
+ }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
23
+ "update:open": (value: boolean) => any;
24
+ }, string, import("vue").PublicProps, Readonly<{
25
+ /** The hint text. The default slot overrides it where the hint needs markup. */
26
+ content?: string;
27
+ /** The edge of the trigger to anchor against, before collision flipping. */
28
+ side?: TooltipSide;
29
+ /** Gap in pixels between the trigger and the tip. */
30
+ sideOffset?: number;
31
+ /** Milliseconds of hover before the tip appears. Keyboard focus is always immediate. */
32
+ delay?: number;
33
+ /** Drive the tip from the host with `v-model:open` — an onboarding hint, say. Omit it for hover and focus alone. */
34
+ open?: boolean | undefined;
35
+ }> & Readonly<{
36
+ "onUpdate:open"?: (value: boolean) => any;
37
+ }>, {
38
+ open: boolean | undefined;
39
+ side: TooltipSide;
40
+ sideOffset: number;
41
+ delay: number;
42
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>, {
43
+ trigger?: (props: {}) => any;
44
+ } & {
45
+ default?: (props: {}) => any;
46
+ }>;
47
+ type __VLS_WithSlots<T, S> = T & {
48
+ new (): {
49
+ $slots: S;
50
+ };
51
+ };
52
+ //# sourceMappingURL=Tooltip.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tooltip.vue.d.ts","sourceRoot":"","sources":["../../../src/primitives/Tooltip/Tooltip.vue"],"names":[],"mappings":"AA8HA;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;wBACzC,OAAO,YAAY;AAAxC,wBAAyC;AACzC,QAAA,MAAM,YAAY;IAuBd,gFAAgF;cACtE,MAAM;IAChB,4EAA4E;WACrE,WAAW;IAClB,qDAAqD;iBACxC,MAAM;IACnB,wFAAwF;YAChF,MAAM;IACd,oHAAoH;WAC7G,OAAO,GAAG,SAAS;;;;IAT1B,gFAAgF;cACtE,MAAM;IAChB,4EAA4E;WACrE,WAAW;IAClB,qDAAqD;iBACxC,MAAM;IACnB,wFAAwF;YAChF,MAAM;IACd,oHAAoH;WAC7G,OAAO,GAAG,SAAS;;;;UAAnB,OAAO,GAAG,SAAS;UANnB,WAAW;gBAEL,MAAM;WAEX,MAAM;;cA0LJ,CAAC,KAAK,IAAiB,KAAK,GAAG;;cAC/B,CAAC,KAAK,IAAiB,KAAK,GAAG;EAWzC,CAAC;AAWL,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { cn } from "../../lib/cn.js";
2
+ import { optional } from "../../lib/props.js";
3
+ import { createBlock, createTextVNode, createVNode, defineComponent, mergeProps, normalizeClass, openBlock, renderSlot, toDisplayString, unref, withCtx } from "vue";
4
+ import { TooltipArrow, TooltipContent, TooltipPortal, TooltipProvider, TooltipRoot, TooltipTrigger } from "reka-ui";
5
+ //#region src/primitives/Tooltip/Tooltip.vue?vue&type=script&setup=true&lang.ts
6
+ var Tooltip_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
7
+ __name: "Tooltip",
8
+ props: {
9
+ content: {},
10
+ side: { default: "top" },
11
+ sideOffset: { default: 6 },
12
+ delay: { default: 300 },
13
+ open: {
14
+ type: Boolean,
15
+ default: void 0
16
+ }
17
+ },
18
+ emits: ["update:open"],
19
+ setup(__props) {
20
+ return (_ctx, _cache) => {
21
+ return openBlock(), createBlock(unref(TooltipProvider), { "delay-duration": __props.delay }, {
22
+ default: withCtx(() => [createVNode(unref(TooltipRoot), mergeProps(unref(optional)({ open: __props.open }), { "onUpdate:open": _cache[0] || (_cache[0] = ($event) => _ctx.$emit("update:open", $event)) }), {
23
+ default: withCtx(() => [createVNode(unref(TooltipTrigger), { "as-child": "" }, {
24
+ default: withCtx(() => [renderSlot(_ctx.$slots, "trigger")]),
25
+ _: 3
26
+ }), createVNode(unref(TooltipPortal), null, {
27
+ default: withCtx(() => [createVNode(unref(TooltipContent), {
28
+ side: __props.side,
29
+ "side-offset": __props.sideOffset,
30
+ class: normalizeClass(unref(cn)("z-50 max-w-[16rem] rounded-md bg-foreground px-2 py-1 text-xs font-medium text-background shadow-md", "data-[state=delayed-open]:animate-scale-in")),
31
+ style: { "transform-origin": "var(--reka-popper-transform-origin)" }
32
+ }, {
33
+ default: withCtx(() => [renderSlot(_ctx.$slots, "default", {}, () => [createTextVNode(toDisplayString(__props.content), 1)]), createVNode(unref(TooltipArrow), {
34
+ class: "fill-foreground",
35
+ width: 10,
36
+ height: 5
37
+ })]),
38
+ _: 3
39
+ }, 8, [
40
+ "side",
41
+ "side-offset",
42
+ "class"
43
+ ])]),
44
+ _: 3
45
+ })]),
46
+ _: 3
47
+ }, 16)]),
48
+ _: 3
49
+ }, 8, ["delay-duration"]);
50
+ };
51
+ }
52
+ });
53
+ //#endregion
54
+ export { Tooltip_vue_vue_type_script_setup_true_lang_default as default };
55
+
56
+ //# sourceMappingURL=Tooltip.vue_vue_type_script_setup_true_lang.js.map