@zyncat/ui 0.8.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 (334) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +133 -0
  3. package/dist/alert.css +132 -0
  4. package/dist/alert.d.ts +46 -0
  5. package/dist/alert.js +80 -0
  6. package/dist/alert.js.map +1 -0
  7. package/dist/avatar-group.d.ts +24 -0
  8. package/dist/avatar-group.js +23 -0
  9. package/dist/avatar-group.js.map +1 -0
  10. package/dist/avatar.css +200 -0
  11. package/dist/avatar.d.ts +35 -0
  12. package/dist/avatar.js +67 -0
  13. package/dist/avatar.js.map +1 -0
  14. package/dist/badge.css +182 -0
  15. package/dist/badge.d.ts +34 -0
  16. package/dist/badge.js +4 -0
  17. package/dist/badge.js.map +1 -0
  18. package/dist/button.css +269 -0
  19. package/dist/button.d.ts +44 -0
  20. package/dist/button.js +4 -0
  21. package/dist/button.js.map +1 -0
  22. package/dist/checkbox.css +177 -0
  23. package/dist/checkbox.d.ts +35 -0
  24. package/dist/checkbox.js +5 -0
  25. package/dist/checkbox.js.map +1 -0
  26. package/dist/chunk-2ERBBFZS.js +12 -0
  27. package/dist/chunk-2ERBBFZS.js.map +1 -0
  28. package/dist/chunk-2HORSLXJ.js +191 -0
  29. package/dist/chunk-2HORSLXJ.js.map +1 -0
  30. package/dist/chunk-36WVAQKL.js +40 -0
  31. package/dist/chunk-36WVAQKL.js.map +1 -0
  32. package/dist/chunk-3SBCBYB7.js +575 -0
  33. package/dist/chunk-3SBCBYB7.js.map +1 -0
  34. package/dist/chunk-4R2GQO43.js +125 -0
  35. package/dist/chunk-4R2GQO43.js.map +1 -0
  36. package/dist/chunk-64UU4LGU.js +258 -0
  37. package/dist/chunk-64UU4LGU.js.map +1 -0
  38. package/dist/chunk-7SZCJ7WI.js +35 -0
  39. package/dist/chunk-7SZCJ7WI.js.map +1 -0
  40. package/dist/chunk-BIDVNLJO.js +38 -0
  41. package/dist/chunk-BIDVNLJO.js.map +1 -0
  42. package/dist/chunk-CONSWNIV.js +17 -0
  43. package/dist/chunk-CONSWNIV.js.map +1 -0
  44. package/dist/chunk-EQ32F2QJ.js +75 -0
  45. package/dist/chunk-EQ32F2QJ.js.map +1 -0
  46. package/dist/chunk-GY7JOPUQ.js +111 -0
  47. package/dist/chunk-GY7JOPUQ.js.map +1 -0
  48. package/dist/chunk-I4XQ4PV2.js +30 -0
  49. package/dist/chunk-I4XQ4PV2.js.map +1 -0
  50. package/dist/chunk-JSKXZMLH.js +67 -0
  51. package/dist/chunk-JSKXZMLH.js.map +1 -0
  52. package/dist/chunk-L3Q3VDIW.js +295 -0
  53. package/dist/chunk-L3Q3VDIW.js.map +1 -0
  54. package/dist/chunk-LDC3RIYA.js +62 -0
  55. package/dist/chunk-LDC3RIYA.js.map +1 -0
  56. package/dist/chunk-MKIQFK7S.js +43 -0
  57. package/dist/chunk-MKIQFK7S.js.map +1 -0
  58. package/dist/chunk-MMRIQNEN.js +20 -0
  59. package/dist/chunk-MMRIQNEN.js.map +1 -0
  60. package/dist/chunk-MXOPCFWR.js +59 -0
  61. package/dist/chunk-MXOPCFWR.js.map +1 -0
  62. package/dist/chunk-NEF5XAHG.js +17 -0
  63. package/dist/chunk-NEF5XAHG.js.map +1 -0
  64. package/dist/chunk-NNXJCLTV.js +22 -0
  65. package/dist/chunk-NNXJCLTV.js.map +1 -0
  66. package/dist/chunk-O4N2OBTR.js +94 -0
  67. package/dist/chunk-O4N2OBTR.js.map +1 -0
  68. package/dist/chunk-PMECHR3A.js +38 -0
  69. package/dist/chunk-PMECHR3A.js.map +1 -0
  70. package/dist/chunk-QDK66S4G.js +44 -0
  71. package/dist/chunk-QDK66S4G.js.map +1 -0
  72. package/dist/chunk-QGNC7LH5.js +8 -0
  73. package/dist/chunk-QGNC7LH5.js.map +1 -0
  74. package/dist/chunk-QMSJZCK3.js +398 -0
  75. package/dist/chunk-QMSJZCK3.js.map +1 -0
  76. package/dist/chunk-S5ZTZANS.js +57 -0
  77. package/dist/chunk-S5ZTZANS.js.map +1 -0
  78. package/dist/chunk-S7B34VGN.js +14 -0
  79. package/dist/chunk-S7B34VGN.js.map +1 -0
  80. package/dist/chunk-TCUCYFT7.js +25 -0
  81. package/dist/chunk-TCUCYFT7.js.map +1 -0
  82. package/dist/chunk-TYHR4VNM.js +193 -0
  83. package/dist/chunk-TYHR4VNM.js.map +1 -0
  84. package/dist/chunk-U5QQZC3U.js +56 -0
  85. package/dist/chunk-U5QQZC3U.js.map +1 -0
  86. package/dist/chunk-UE63OOVG.js +13 -0
  87. package/dist/chunk-UE63OOVG.js.map +1 -0
  88. package/dist/chunk-VTJTGVZZ.js +22 -0
  89. package/dist/chunk-VTJTGVZZ.js.map +1 -0
  90. package/dist/chunk-W3SHPKSB.js +49 -0
  91. package/dist/chunk-W3SHPKSB.js.map +1 -0
  92. package/dist/chunk-XZAEIQDR.js +188 -0
  93. package/dist/chunk-XZAEIQDR.js.map +1 -0
  94. package/dist/chunk-YGGCQNNU.js +92 -0
  95. package/dist/chunk-YGGCQNNU.js.map +1 -0
  96. package/dist/collapse.css +88 -0
  97. package/dist/collapse.d.ts +46 -0
  98. package/dist/collapse.js +5 -0
  99. package/dist/collapse.js.map +1 -0
  100. package/dist/count-badge.d.ts +13 -0
  101. package/dist/count-badge.js +13 -0
  102. package/dist/count-badge.js.map +1 -0
  103. package/dist/date-field.d.ts +25 -0
  104. package/dist/date-field.js +87 -0
  105. package/dist/date-field.js.map +1 -0
  106. package/dist/date-picker.css +595 -0
  107. package/dist/date-range-field.d.ts +33 -0
  108. package/dist/date-range-field.js +404 -0
  109. package/dist/date-range-field.js.map +1 -0
  110. package/dist/datetime-field.d.ts +29 -0
  111. package/dist/datetime-field.js +155 -0
  112. package/dist/datetime-field.js.map +1 -0
  113. package/dist/dialog.css +180 -0
  114. package/dist/dialog.d.ts +42 -0
  115. package/dist/dialog.js +128 -0
  116. package/dist/dialog.js.map +1 -0
  117. package/dist/dom-props-C0jrllBw.d.ts +5 -0
  118. package/dist/field-chrome-CMPOQSLs.d.ts +28 -0
  119. package/dist/field-shell-Cuda-feL.d.ts +24 -0
  120. package/dist/glide.d.ts +15 -0
  121. package/dist/glide.js +5 -0
  122. package/dist/glide.js.map +1 -0
  123. package/dist/icon.css +33 -0
  124. package/dist/input.css +333 -0
  125. package/dist/mcp.js +359 -0
  126. package/dist/motion-devtools.css +265 -0
  127. package/dist/motion-devtools.d.ts +51 -0
  128. package/dist/motion-devtools.js +354 -0
  129. package/dist/motion-devtools.js.map +1 -0
  130. package/dist/motion-scale-Canq4stZ.d.ts +18 -0
  131. package/dist/motion-tokens.d.ts +28 -0
  132. package/dist/motion-tokens.js +3 -0
  133. package/dist/motion-tokens.js.map +1 -0
  134. package/dist/multi-select.d.ts +44 -0
  135. package/dist/multi-select.js +109 -0
  136. package/dist/multi-select.js.map +1 -0
  137. package/dist/number-field.d.ts +36 -0
  138. package/dist/number-field.js +112 -0
  139. package/dist/number-field.js.map +1 -0
  140. package/dist/odometer.css +62 -0
  141. package/dist/otp-field.d.ts +31 -0
  142. package/dist/otp-field.js +98 -0
  143. package/dist/otp-field.js.map +1 -0
  144. package/dist/overlay.css +23 -0
  145. package/dist/pagination.css +43 -0
  146. package/dist/pagination.d.ts +29 -0
  147. package/dist/pagination.js +107 -0
  148. package/dist/pagination.js.map +1 -0
  149. package/dist/popover.css +69 -0
  150. package/dist/popover.d.ts +35 -0
  151. package/dist/popover.js +15 -0
  152. package/dist/popover.js.map +1 -0
  153. package/dist/radio-group.css +300 -0
  154. package/dist/radio-group.d.ts +52 -0
  155. package/dist/radio-group.js +115 -0
  156. package/dist/radio-group.js.map +1 -0
  157. package/dist/select.css +416 -0
  158. package/dist/select.d.ts +49 -0
  159. package/dist/select.js +99 -0
  160. package/dist/select.js.map +1 -0
  161. package/dist/sheet.css +26 -0
  162. package/dist/sheet.d.ts +31 -0
  163. package/dist/sheet.js +14 -0
  164. package/dist/sheet.js.map +1 -0
  165. package/dist/status-badge.d.ts +19 -0
  166. package/dist/status-badge.js +72 -0
  167. package/dist/status-badge.js.map +1 -0
  168. package/dist/table.css +348 -0
  169. package/dist/table.d.ts +75 -0
  170. package/dist/table.js +262 -0
  171. package/dist/table.js.map +1 -0
  172. package/dist/tabs.css +208 -0
  173. package/dist/tabs.d.ts +71 -0
  174. package/dist/tabs.js +181 -0
  175. package/dist/tabs.js.map +1 -0
  176. package/dist/tag.css +248 -0
  177. package/dist/tag.d.ts +52 -0
  178. package/dist/tag.js +72 -0
  179. package/dist/tag.js.map +1 -0
  180. package/dist/text-field.d.ts +28 -0
  181. package/dist/text-field.js +69 -0
  182. package/dist/text-field.js.map +1 -0
  183. package/dist/textarea.css +219 -0
  184. package/dist/textarea.d.ts +38 -0
  185. package/dist/textarea.js +144 -0
  186. package/dist/textarea.js.map +1 -0
  187. package/dist/time-field.d.ts +28 -0
  188. package/dist/time-field.js +66 -0
  189. package/dist/time-field.js.map +1 -0
  190. package/dist/timing-7JA_zQHP.d.ts +27 -0
  191. package/dist/toast-store.d.ts +86 -0
  192. package/dist/toast-store.js +3 -0
  193. package/dist/toast-store.js.map +1 -0
  194. package/dist/toast.css +257 -0
  195. package/dist/toast.d.ts +12 -0
  196. package/dist/toast.js +310 -0
  197. package/dist/toast.js.map +1 -0
  198. package/dist/toggle-tag.d.ts +34 -0
  199. package/dist/toggle-tag.js +57 -0
  200. package/dist/toggle-tag.js.map +1 -0
  201. package/dist/toggle.css +152 -0
  202. package/dist/toggle.d.ts +31 -0
  203. package/dist/toggle.js +75 -0
  204. package/dist/toggle.js.map +1 -0
  205. package/dist/tooltip.css +86 -0
  206. package/dist/tooltip.d.ts +30 -0
  207. package/dist/tooltip.js +268 -0
  208. package/dist/tooltip.js.map +1 -0
  209. package/dist/types-SGMShK7R.d.ts +22 -0
  210. package/llms.txt +196 -0
  211. package/next.d.mts +7 -0
  212. package/next.mjs +59 -0
  213. package/package.json +257 -0
  214. package/src/components/composites/alert/Alert.tsx +141 -0
  215. package/src/components/composites/alert/alert.css +132 -0
  216. package/src/components/composites/date-picker/DateField.tsx +80 -0
  217. package/src/components/composites/date-picker/DateRangeField.tsx +110 -0
  218. package/src/components/composites/date-picker/DateTimeField.tsx +162 -0
  219. package/src/components/composites/date-picker/TimeField.tsx +78 -0
  220. package/src/components/composites/date-picker/calendar-panel.tsx +216 -0
  221. package/src/components/composites/date-picker/date-picker.css +595 -0
  222. package/src/components/composites/date-picker/date-utils.ts +56 -0
  223. package/src/components/composites/date-picker/field-shell.tsx +85 -0
  224. package/src/components/composites/date-picker/range-panel.tsx +363 -0
  225. package/src/components/composites/date-picker/time-core.tsx +290 -0
  226. package/src/components/composites/date-picker/use-day-focus.ts +35 -0
  227. package/src/components/composites/dialog/Dialog.tsx +198 -0
  228. package/src/components/composites/dialog/dialog.css +180 -0
  229. package/src/components/composites/pagination/Pagination.tsx +131 -0
  230. package/src/components/composites/pagination/pagination.css +43 -0
  231. package/src/components/composites/popover/Popover.tsx +141 -0
  232. package/src/components/composites/popover/popover.css +69 -0
  233. package/src/components/composites/select/MultiSelect.tsx +133 -0
  234. package/src/components/composites/select/Select.tsx +122 -0
  235. package/src/components/composites/select/core/index.ts +4 -0
  236. package/src/components/composites/select/core/menu.tsx +100 -0
  237. package/src/components/composites/select/core/panel.tsx +154 -0
  238. package/src/components/composites/select/core/trigger.tsx +74 -0
  239. package/src/components/composites/select/core/types.ts +39 -0
  240. package/src/components/composites/select/core/use-listbox.ts +182 -0
  241. package/src/components/composites/select/select.css +416 -0
  242. package/src/components/composites/sheet/Sheet.tsx +135 -0
  243. package/src/components/composites/sheet/sheet.css +26 -0
  244. package/src/components/composites/sheet/use-sheet-drag.ts +126 -0
  245. package/src/components/composites/table/Table.tsx +377 -0
  246. package/src/components/composites/table/table.css +348 -0
  247. package/src/components/composites/tabs/Tabs.tsx +278 -0
  248. package/src/components/composites/tabs/tabs.css +208 -0
  249. package/src/components/composites/toast/Toast.tsx +380 -0
  250. package/src/components/composites/toast/toast-store.ts +295 -0
  251. package/src/components/composites/toast/toast.css +257 -0
  252. package/src/components/composites/tooltip/Tooltip.tsx +110 -0
  253. package/src/components/composites/tooltip/tooltip-host.tsx +184 -0
  254. package/src/components/composites/tooltip/tooltip-store.ts +81 -0
  255. package/src/components/composites/tooltip/tooltip.css +86 -0
  256. package/src/components/dev/MotionDevtools.tsx +200 -0
  257. package/src/components/dev/motion-devtools.css +265 -0
  258. package/src/components/dev/slowmo-engine.ts +230 -0
  259. package/src/components/internal/glass/glass.css +100 -0
  260. package/src/components/internal/glass/glint.ts +9 -0
  261. package/src/components/internal/hooks/use-controllable.ts +21 -0
  262. package/src/components/internal/hooks/use-scroll-edges.ts +46 -0
  263. package/src/components/internal/icon/Icon.tsx +66 -0
  264. package/src/components/internal/icon/IconSlot.tsx +10 -0
  265. package/src/components/internal/icon/icon.css +33 -0
  266. package/src/components/internal/overlay/focus.ts +68 -0
  267. package/src/components/internal/overlay/layer.tsx +149 -0
  268. package/src/components/internal/overlay/modal.tsx +141 -0
  269. package/src/components/internal/overlay/overlay.css +23 -0
  270. package/src/components/internal/overlay/position.ts +103 -0
  271. package/src/components/internal/utils/cx.ts +3 -0
  272. package/src/components/internal/utils/token-px.ts +8 -0
  273. package/src/components/primitives/avatar/Avatar.tsx +120 -0
  274. package/src/components/primitives/avatar/AvatarGroup.tsx +56 -0
  275. package/src/components/primitives/avatar/avatar.css +200 -0
  276. package/src/components/primitives/badge/Badge.tsx +75 -0
  277. package/src/components/primitives/badge/CountBadge.tsx +20 -0
  278. package/src/components/primitives/badge/StatusBadge.tsx +111 -0
  279. package/src/components/primitives/badge/badge.css +182 -0
  280. package/src/components/primitives/badge/odometer.css +62 -0
  281. package/src/components/primitives/badge/odometer.tsx +36 -0
  282. package/src/components/primitives/button/Button.tsx +102 -0
  283. package/src/components/primitives/button/button.css +269 -0
  284. package/src/components/primitives/checkbox/Checkbox.tsx +76 -0
  285. package/src/components/primitives/checkbox/check-glyph.tsx +28 -0
  286. package/src/components/primitives/checkbox/checkbox.css +177 -0
  287. package/src/components/primitives/collapse/Collapse.tsx +86 -0
  288. package/src/components/primitives/collapse/collapse.css +88 -0
  289. package/src/components/primitives/collapse/collapse.typecheck.tsx +29 -0
  290. package/src/components/primitives/input/NumberField.tsx +139 -0
  291. package/src/components/primitives/input/OtpField.tsx +134 -0
  292. package/src/components/primitives/input/TextField.tsx +110 -0
  293. package/src/components/primitives/input/field-chrome.tsx +83 -0
  294. package/src/components/primitives/input/input.css +333 -0
  295. package/src/components/primitives/radio-group/RadioGroup.tsx +183 -0
  296. package/src/components/primitives/radio-group/radio-group.css +300 -0
  297. package/src/components/primitives/tag/Tag.tsx +143 -0
  298. package/src/components/primitives/tag/ToggleTag.tsx +97 -0
  299. package/src/components/primitives/tag/tag.css +248 -0
  300. package/src/components/primitives/textarea/Textarea.tsx +190 -0
  301. package/src/components/primitives/textarea/textarea.css +219 -0
  302. package/src/components/primitives/toggle/Toggle.tsx +105 -0
  303. package/src/components/primitives/toggle/toggle.css +152 -0
  304. package/src/css.d.ts +1 -0
  305. package/src/dom-props.ts +1 -0
  306. package/src/engine/animate.ts +141 -0
  307. package/src/engine/drag.ts +53 -0
  308. package/src/engine/ease.ts +155 -0
  309. package/src/engine/flip.ts +59 -0
  310. package/src/engine/index.ts +13 -0
  311. package/src/mcp/server.ts +420 -0
  312. package/src/motion/element.tsx +53 -0
  313. package/src/motion/flip.tsx +87 -0
  314. package/src/motion/glide.tsx +47 -0
  315. package/src/motion/motion-timing.ts +33 -0
  316. package/src/motion/presence-context.ts +18 -0
  317. package/src/motion/presence.tsx +91 -0
  318. package/src/motion/timing.ts +49 -0
  319. package/src/motion/use-motion.ts +64 -0
  320. package/src/styles.css +26 -0
  321. package/src/tokens/avatar.css +20 -0
  322. package/src/tokens/color.css +58 -0
  323. package/src/tokens/elevation.css +22 -0
  324. package/src/tokens/fonts.css +3 -0
  325. package/src/tokens/glass.css +20 -0
  326. package/src/tokens/icons.css +7 -0
  327. package/src/tokens/layers.css +6 -0
  328. package/src/tokens/motion-scale.ts +17 -0
  329. package/src/tokens/motion-tokens.ts +92 -0
  330. package/src/tokens/motion.css +49 -0
  331. package/src/tokens/radius.css +11 -0
  332. package/src/tokens/semantic.css +65 -0
  333. package/src/tokens/spacing.css +26 -0
  334. package/src/tokens/typography.css +52 -0
@@ -0,0 +1,416 @@
1
+ /* Select family - <Select> (single) + <MultiSelect>, one .select__* vocabulary (no native <select>). */
2
+
3
+ .select {
4
+ position: relative;
5
+ display: inline-block;
6
+ width: 100%;
7
+ font-family: var(--font-sans);
8
+ }
9
+
10
+ .select__trigger {
11
+ appearance: none;
12
+ margin: 0;
13
+ font-family: inherit;
14
+ cursor: pointer;
15
+ text-align: left;
16
+ display: flex;
17
+ align-items: center;
18
+ gap: var(--space-2);
19
+ width: 100%;
20
+ height: var(--control-height);
21
+ padding: 0 var(--space-3);
22
+ background: var(--bg-inset);
23
+ border: var(--border-hairline) solid var(--border-default);
24
+ border-radius: var(--radius-md);
25
+ color: var(--text-body);
26
+ font-size: var(--size-body);
27
+ line-height: var(--leading-body);
28
+ font-weight: var(--weight-regular);
29
+ transition:
30
+ color var(--duration-base) var(--ease-standard),
31
+ background-color var(--duration-base) var(--ease-standard),
32
+ border-color var(--duration-base) var(--ease-standard),
33
+ box-shadow var(--duration-base) var(--ease-standard);
34
+ }
35
+ .select__trigger:hover {
36
+ border-color: var(--border-strong);
37
+ background-color: var(--gray-wash-strong);
38
+ }
39
+ .select__trigger:focus-visible {
40
+ outline: none;
41
+ border-color: var(--accent);
42
+ background: var(--bg-surface);
43
+ box-shadow: var(--ring-accent);
44
+ }
45
+ .select[data-open='true'] .select__trigger {
46
+ border-color: var(--accent);
47
+ background: var(--bg-surface);
48
+ box-shadow: var(--ring-accent);
49
+ }
50
+
51
+ .select[data-size='sm'] .select__trigger {
52
+ height: var(--control-height-sm);
53
+ padding: 0 var(--space-2);
54
+ font-size: var(--size-caption);
55
+ line-height: var(--leading-caption);
56
+ gap: var(--space-1);
57
+ }
58
+ .select[data-size='lg'] .select__trigger {
59
+ height: var(--control-height-lg);
60
+ padding: 0 var(--space-4);
61
+ }
62
+
63
+ .select[data-invalid='true'] .select__trigger {
64
+ border-color: var(--danger);
65
+ }
66
+ .select[data-invalid='true'] .select__trigger:focus-visible,
67
+ .select[data-invalid='true'][data-open='true'] .select__trigger {
68
+ border-color: var(--danger);
69
+ box-shadow: var(--ring-danger);
70
+ }
71
+
72
+ .select[data-disabled='true'] .select__trigger {
73
+ cursor: not-allowed;
74
+ background: var(--bg-muted);
75
+ border-color: var(--border-subtle);
76
+ color: var(--text-disabled);
77
+ box-shadow: none;
78
+ }
79
+ .select[data-disabled='true'] .select__value,
80
+ .select[data-disabled='true'] .select__leading,
81
+ .select[data-disabled='true'] .select__caret {
82
+ color: var(--text-disabled);
83
+ }
84
+
85
+ .select[data-loading='true'] .select__value {
86
+ color: var(--text-muted);
87
+ }
88
+
89
+ .select__leading {
90
+ display: inline-flex;
91
+ flex: 0 0 auto;
92
+ font-size: var(--icon-sm);
93
+ color: var(--text-muted);
94
+ }
95
+ .select__value {
96
+ flex: 1 1 auto;
97
+ min-width: 0;
98
+ color: var(--text-body);
99
+ }
100
+ .select__value[data-placeholder='true'] {
101
+ color: var(--text-disabled);
102
+ }
103
+ .select__caret {
104
+ display: inline-flex;
105
+ flex: 0 0 auto;
106
+ font-size: var(--icon-sm);
107
+ color: var(--text-subtle);
108
+ transition:
109
+ transform var(--duration-base) var(--ease-entrance),
110
+ color var(--duration-fast) var(--ease-standard);
111
+ }
112
+ .select[data-open='true'] .select__caret {
113
+ transform: rotate(180deg);
114
+ color: var(--text-muted);
115
+ }
116
+ .select__count {
117
+ flex: 0 0 auto;
118
+ font-family: var(--font-mono);
119
+ font-size: var(--size-micro);
120
+ line-height: 1;
121
+ font-variant-numeric: tabular-nums;
122
+ color: var(--text-accent);
123
+ background: var(--accent-wash);
124
+ padding: var(--space-px) var(--space-1);
125
+ border-radius: var(--radius-sm);
126
+ }
127
+
128
+ .select__value,
129
+ .select__option-label,
130
+ .select__option-desc {
131
+ overflow: hidden;
132
+ text-overflow: ellipsis;
133
+ white-space: nowrap;
134
+ }
135
+
136
+ /* Menu enter/exit are Motion-owned inline styles (selectMenuVariants); this sheet only sets the look + transform-origin. */
137
+ .select__menu {
138
+ position: fixed;
139
+ margin: 0;
140
+ inset: auto; /* JS sets top/left/min-width - anchor() needs the top layer, which we don't use */
141
+ z-index: var(
142
+ --layer-overlay
143
+ ); /* base of the overlay band (tokens/layers.css) - plain React-owned node, not the top layer */
144
+ width: max-content;
145
+ max-width: min(22rem, 92vw);
146
+ background: var(--bg-surface-raised);
147
+ border: var(--border-hairline) solid var(--border-default);
148
+ border-radius: var(--radius-lg);
149
+ box-shadow: var(--shadow-lg);
150
+ padding: var(--space-1);
151
+ transform-origin: top left;
152
+ }
153
+ /* flipped above the trigger (data-side from useAnchorPosition) - scale from the anchored edge */
154
+ .select__menu[data-side='top'] {
155
+ transform-origin: bottom left;
156
+ }
157
+
158
+ .select__search {
159
+ display: flex;
160
+ align-items: center;
161
+ gap: var(--space-2);
162
+ padding: var(--space-2);
163
+ margin: 0 0 var(--space-1);
164
+ border-bottom: var(--border-hairline) solid var(--border-subtle);
165
+ font-size: var(--icon-sm);
166
+ color: var(--text-subtle);
167
+ }
168
+ .select__search-input {
169
+ appearance: none;
170
+ border: none;
171
+ outline: none;
172
+ background: transparent;
173
+ width: 100%;
174
+ padding: 0;
175
+ font-family: var(--font-sans);
176
+ font-size: var(--size-body);
177
+ line-height: var(--leading-body);
178
+ color: var(--text-body);
179
+ }
180
+ .select__search-input::placeholder {
181
+ color: var(--text-disabled);
182
+ }
183
+
184
+ /* Row-height motion is the Collapse primitive, not this scroll container.
185
+ position: relative anchors the glide pill (a single absolute child) to the scrolled content. */
186
+ .select__list {
187
+ position: relative;
188
+ max-height: 16.5rem;
189
+ overflow-y: auto;
190
+ overscroll-behavior: contain;
191
+ scroll-behavior: smooth;
192
+ scrollbar-width: none;
193
+ }
194
+ .select__list::-webkit-scrollbar {
195
+ width: 0;
196
+ height: 0;
197
+ display: none;
198
+ }
199
+
200
+ .select__group-label {
201
+ position: sticky;
202
+ top: 0;
203
+ z-index: 1;
204
+ background: var(--bg-surface-raised);
205
+ padding: var(--space-2) var(--space-2) var(--space-1);
206
+ font: var(--type-micro);
207
+ text-transform: uppercase;
208
+ letter-spacing: var(--tracking-caps);
209
+ color: var(--text-subtle);
210
+ }
211
+ .select__group + .select__group .select__group-label {
212
+ border-top: var(--border-hairline) solid var(--border-subtle);
213
+ margin-top: var(--space-1);
214
+ }
215
+
216
+ .select__option {
217
+ padding: var(--option-padding);
218
+ position: relative;
219
+ display: flex;
220
+ align-items: center;
221
+ gap: var(--space-2);
222
+ border-radius: var(--radius-md);
223
+ cursor: pointer;
224
+ color: var(--text-body);
225
+ user-select: none;
226
+ transition:
227
+ background-color var(--duration-base) var(--ease-standard),
228
+ color var(--duration-base) var(--ease-standard);
229
+ }
230
+
231
+ .select__option[data-size='sm'] {
232
+ --option-padding: var(--space-1);
233
+ }
234
+
235
+ .select__option[data-size='md'] {
236
+ --option-padding: var(--space-2);
237
+ }
238
+
239
+ .select__option[data-size='lg'] {
240
+ --option-padding: var(--space-4);
241
+ }
242
+
243
+ .select__option-icon {
244
+ display: inline-flex;
245
+ flex: 0 0 auto;
246
+ font-size: var(--icon-sm);
247
+ color: var(--text-muted);
248
+ }
249
+ .select__option-text {
250
+ display: flex;
251
+ flex-direction: column;
252
+ gap: var(--space-px);
253
+ min-width: 0;
254
+ flex: 1 1 auto;
255
+ }
256
+ .select__option-label {
257
+ font-size: var(--size-body);
258
+ line-height: var(--leading-body);
259
+ }
260
+ .select__option-desc {
261
+ font: var(--type-caption);
262
+ color: var(--text-subtle);
263
+ }
264
+ .select__option-check {
265
+ display: inline-flex;
266
+ align-items: center;
267
+ justify-content: center;
268
+ flex: 0 0 auto;
269
+ min-width: var(--icon-sm);
270
+ font-size: var(--icon-sm);
271
+ color: var(--accent);
272
+ opacity: 0;
273
+ transition: var(--transition-opacity);
274
+ }
275
+
276
+ /* Hover pill - one persistent fill in the list (../motion/glide) that travels to the active row and
277
+ animates its real size, so it's never clipped by the searchable rows' collapse and never scales.
278
+ GlidePill sets x/y/width/height inline; the option (position: relative) paints above it. */
279
+ .select__glide {
280
+ position: absolute;
281
+ top: 0;
282
+ left: 0;
283
+ z-index: 0;
284
+ border-radius: var(--radius-md);
285
+ background: var(--neutral-wash);
286
+ pointer-events: none;
287
+ }
288
+
289
+ /* Active row: the pill carries the fill; here we only lift the text. Selected rules follow, so source order wins. */
290
+ .select__option[data-active='true'] {
291
+ color: var(--text-strong);
292
+ }
293
+ .select__option[data-active='true'] .select__option-icon {
294
+ color: var(--text-body);
295
+ }
296
+ .select__option[data-selected='true'] {
297
+ background-color: var(--accent-wash);
298
+ }
299
+ .select__option[data-selected='true'] .select__option-label {
300
+ color: var(--text-accent);
301
+ font-weight: var(--weight-medium);
302
+ }
303
+ .select__option[data-selected='true'] .select__option-icon {
304
+ color: var(--text-accent);
305
+ }
306
+ .select__option[data-selected='true'] .select__option-check {
307
+ opacity: 1;
308
+ }
309
+ .select__option[data-disabled='true'] {
310
+ cursor: not-allowed;
311
+ color: var(--text-disabled);
312
+ }
313
+ .select__option[data-disabled='true'] .select__option-icon {
314
+ color: var(--text-disabled);
315
+ }
316
+
317
+ /* check lands with a spring when a row becomes selected (remounts via React key) */
318
+ .select__option[data-selected='true'] .select__option-check :is(i, svg) {
319
+ animation: select-check-in var(--duration-base) var(--ease-spring);
320
+ }
321
+ @keyframes select-check-in {
322
+ from {
323
+ opacity: 0;
324
+ transform: scale(0.5);
325
+ }
326
+ to {
327
+ opacity: 1;
328
+ transform: scale(1);
329
+ }
330
+ }
331
+
332
+ /* Multi-select: the reused Checkbox box IS the indicator - no row fill (avoid double-encoding); strip the .cbx standalone chrome. */
333
+ .select__menu[data-multiple='true'] .select__option-check {
334
+ opacity: 1;
335
+ }
336
+ .select__menu[data-multiple='true'] .select__option .cbx {
337
+ padding: 0;
338
+ gap: 0;
339
+ pointer-events: none;
340
+ }
341
+ .select__menu[data-multiple='true'] .select__option .cbx__box {
342
+ margin-top: 0;
343
+ }
344
+
345
+ /* Row owns the press (.cbx is pointer-events:none): dip the box on press - explicit transform,
346
+ so a checked box (whose resting scale would otherwise dilute --press) still scales from center. */
347
+ .select__menu[data-multiple='true'] .select__option:active:not([data-disabled='true']) .cbx__box {
348
+ transform: scale(0.86);
349
+ }
350
+ .select__menu[data-multiple='true'] .select__option[data-selected='true'] {
351
+ background-color: transparent;
352
+ }
353
+
354
+ .select__empty {
355
+ padding: var(--space-4) var(--space-3);
356
+ text-align: center;
357
+ font: var(--type-caption);
358
+ color: var(--text-subtle);
359
+ }
360
+
361
+ .select__loading {
362
+ display: flex;
363
+ flex-direction: column;
364
+ gap: var(--space-1);
365
+ padding: var(--space-1);
366
+ }
367
+ .select__skeleton {
368
+ display: flex;
369
+ align-items: center;
370
+ gap: var(--space-2);
371
+ padding: var(--space-2);
372
+ }
373
+ .select__skeleton-dot {
374
+ width: var(--icon-sm);
375
+ height: var(--icon-sm);
376
+ border-radius: var(--radius-full);
377
+ background: var(--bg-muted);
378
+ flex: 0 0 auto;
379
+ }
380
+ .select__skeleton-bar {
381
+ height: 0.5rem;
382
+ border-radius: var(--radius-full);
383
+ background: var(--bg-muted);
384
+ flex: 1 1 auto;
385
+ max-width: 11rem;
386
+ }
387
+ .select__skeleton:nth-child(2) .select__skeleton-bar {
388
+ max-width: 7rem;
389
+ }
390
+ .select__skeleton:nth-child(3) .select__skeleton-bar {
391
+ max-width: 9rem;
392
+ }
393
+ .select__loading [data-pulse] {
394
+ animation: select-pulse var(--duration-spin) var(--ease-standard) infinite alternate;
395
+ }
396
+ @keyframes select-pulse {
397
+ from {
398
+ opacity: 0.55;
399
+ }
400
+ to {
401
+ opacity: 1;
402
+ }
403
+ }
404
+
405
+ @media (prefers-reduced-motion: reduce) {
406
+ .select__list {
407
+ scroll-behavior: auto;
408
+ }
409
+ .select__option-check :is(i, svg),
410
+ .select__loading [data-pulse] {
411
+ animation: none;
412
+ }
413
+ .select__loading [data-pulse] {
414
+ opacity: 0.7;
415
+ }
416
+ }
@@ -0,0 +1,49 @@
1
+ import * as react from 'react';
2
+ import { ReactNode, HTMLAttributes } from 'react';
3
+ import { S as SelectOption, a as SelectGroup } from './types-SGMShK7R.js';
4
+ import { ButtonProps } from './button.js';
5
+ import { D as DisableableAnimation } from './timing-7JA_zQHP.js';
6
+ import { D as DataAttributes } from './dom-props-C0jrllBw.js';
7
+ import './motion-scale-Canq4stZ.js';
8
+
9
+ interface SelectProps {
10
+ /** The choices - a flat `SelectOption[]`, or `SelectGroup[]` to render labeled sections. @default [] */
11
+ options: SelectOption[] | SelectGroup[];
12
+ /** Controlled value - matches an option's `value`, or `null` for none. Omit for uncontrolled (use `defaultValue`). */
13
+ value?: string | null;
14
+ /** Initial value when uncontrolled. @default null */
15
+ defaultValue?: string | null;
16
+ /** Fires on commit - gets the new `value` and its full `SelectOption`. Committing closes the menu. */
17
+ onChange?: (value: string, option: SelectOption) => void;
18
+ /** Trigger text when nothing is selected. @default 'Select an option' */
19
+ placeholder?: string;
20
+ /** Control height. @default 'md' */
21
+ size?: 'sm' | 'md' | 'lg';
22
+ /** Disabled - trigger is inert and the menu cannot open. @default false */
23
+ disabled?: boolean;
24
+ /** Danger ring + border. @default false */
25
+ invalid?: boolean;
26
+ /** Skeleton rows in the menu; trigger reads "Loading...". @default false */
27
+ loading?: boolean;
28
+ /** Type-to-filter field pinned above the list. @default false */
29
+ searchable?: boolean;
30
+ /** Placeholder for the `searchable` filter input. @default 'Filter options' */
31
+ searchPlaceholder?: string;
32
+ /** Your own icon node pinned before the trigger label; else the selected option's icon. */
33
+ leadingIcon?: ReactNode;
34
+ /** Base id for the trigger/menu/list ids and a11y wiring; auto-generated if omitted. */
35
+ id?: string;
36
+ /** Accessible name for the trigger and listbox - supply when there is no visible label. */
37
+ ariaLabel?: string;
38
+ /** Standard <div> attributes (className, style, data-*, ...) forwarded to the select root. */
39
+ htmlProps?: HTMLAttributes<HTMLDivElement> & DataAttributes;
40
+ /** Menu open/close timing - motion tokens only, or `null` to disable. @default duration 'base' + ease 'entrance'/'exit' */
41
+ animation?: DisableableAnimation;
42
+ /** Trigger props */
43
+ triggerProps?: ButtonProps;
44
+ /** Show check icon on selected value */
45
+ showCheck?: boolean;
46
+ }
47
+ declare function Select({ options, value: controlledValue, defaultValue, onChange, placeholder, size, disabled, invalid, loading, searchable, searchPlaceholder, leadingIcon, id, ariaLabel, htmlProps, animation, triggerProps, showCheck, }: SelectProps): react.JSX.Element;
48
+
49
+ export { Select, SelectGroup, SelectOption, type SelectProps };
package/dist/select.js ADDED
@@ -0,0 +1,99 @@
1
+ 'use client';import { useListbox, SelectTrigger, ListboxPanel } from './chunk-QMSJZCK3.js';
2
+ import './chunk-EQ32F2QJ.js';
3
+ import './chunk-GY7JOPUQ.js';
4
+ import './chunk-UE63OOVG.js';
5
+ import './chunk-MKIQFK7S.js';
6
+ import './chunk-NEF5XAHG.js';
7
+ import './chunk-MXOPCFWR.js';
8
+ import './chunk-W3SHPKSB.js';
9
+ import './chunk-L3Q3VDIW.js';
10
+ import './chunk-2ERBBFZS.js';
11
+ import './chunk-3SBCBYB7.js';
12
+ import { useControllable } from './chunk-MMRIQNEN.js';
13
+ import './chunk-S5ZTZANS.js';
14
+ import './chunk-U5QQZC3U.js';
15
+ import './chunk-7SZCJ7WI.js';
16
+ import './chunk-VTJTGVZZ.js';
17
+ import { cx } from './chunk-QGNC7LH5.js';
18
+ import './select.css';
19
+ import { jsxs, jsx } from 'react/jsx-runtime';
20
+
21
+ function Select({
22
+ options = [],
23
+ value: controlledValue,
24
+ defaultValue = null,
25
+ onChange,
26
+ placeholder = "Select an option",
27
+ size = "md",
28
+ disabled = false,
29
+ invalid = false,
30
+ loading = false,
31
+ searchable = false,
32
+ searchPlaceholder = "Filter options",
33
+ leadingIcon = null,
34
+ id,
35
+ ariaLabel,
36
+ htmlProps,
37
+ animation,
38
+ triggerProps,
39
+ showCheck = true
40
+ }) {
41
+ const [value, setValue] = useControllable(controlledValue, defaultValue, onChange);
42
+ const lb = useListbox({
43
+ options,
44
+ disabled,
45
+ loading,
46
+ searchable,
47
+ id,
48
+ idPrefix: "select-",
49
+ isSelected: (v) => v === value && value != null,
50
+ onCommit: (opt) => setValue(opt.value, opt),
51
+ closeOnCommit: true
52
+ });
53
+ const selected = lb.flat.find((o) => o.value === value) || null;
54
+ const isPlaceholder = !loading && !selected;
55
+ return /* @__PURE__ */ jsxs(
56
+ "div",
57
+ {
58
+ ...htmlProps,
59
+ className: cx("select", htmlProps?.className),
60
+ "data-size": size,
61
+ "data-open": lb.open ? "true" : void 0,
62
+ "data-disabled": disabled ? "true" : void 0,
63
+ "data-invalid": invalid ? "true" : void 0,
64
+ "data-loading": loading ? "true" : void 0,
65
+ children: [
66
+ /* @__PURE__ */ jsx(
67
+ SelectTrigger,
68
+ {
69
+ lb,
70
+ disabled,
71
+ invalid,
72
+ ariaLabel,
73
+ leading: leadingIcon || selected && selected.icon || null,
74
+ text: loading ? "Loading..." : isPlaceholder ? placeholder : selected.label,
75
+ isPlaceholder,
76
+ ...triggerProps
77
+ }
78
+ ),
79
+ /* @__PURE__ */ jsx(
80
+ ListboxPanel,
81
+ {
82
+ lb,
83
+ loading,
84
+ searchable,
85
+ searchPlaceholder,
86
+ ariaLabel,
87
+ animation,
88
+ size,
89
+ ...!showCheck && { check: () => null }
90
+ }
91
+ )
92
+ ]
93
+ }
94
+ );
95
+ }
96
+
97
+ export { Select };
98
+ //# sourceMappingURL=select.js.map
99
+ //# sourceMappingURL=select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/composites/select/Select.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;AAoDO,SAAS,MAAA,CAAO;AAAA,EACrB,UAAU,EAAC;AAAA,EACX,KAAA,EAAO,eAAA;AAAA,EACP,YAAA,GAAe,IAAA;AAAA,EACf,QAAA;AAAA,EACA,WAAA,GAAc,kBAAA;AAAA,EACd,IAAA,GAAO,IAAA;AAAA,EACP,QAAA,GAAW,KAAA;AAAA,EACX,OAAA,GAAU,KAAA;AAAA,EACV,OAAA,GAAU,KAAA;AAAA,EACV,UAAA,GAAa,KAAA;AAAA,EACb,iBAAA,GAAoB,gBAAA;AAAA,EACpB,WAAA,GAAc,IAAA;AAAA,EACd,EAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,SAAA;AAAA,EACA,YAAA;AAAA,EACA,SAAA,GAAY;AACd,CAAA,EAAgB;AACd,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,IAAI,eAAA,CAA6C,eAAA,EAAiB,cAAc,QAAQ,CAAA;AAE9G,EAAA,MAAM,KAAK,UAAA,CAAW;AAAA,IACpB,OAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA,EAAA;AAAA,IACA,QAAA,EAAU,SAAA;AAAA,IACV,UAAA,EAAY,CAAC,CAAA,KAAM,CAAA,KAAM,SAAS,KAAA,IAAS,IAAA;AAAA,IAC3C,UAAU,CAAC,GAAA,KAAQ,QAAA,CAAS,GAAA,CAAI,OAAO,GAAG,CAAA;AAAA,IAC1C,aAAA,EAAe;AAAA,GAChB,CAAA;AAED,EAAA,MAAM,QAAA,GAAW,GAAG,IAAA,CAAK,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,KAAA,KAAU,KAAK,CAAA,IAAK,IAAA;AAC3D,EAAA,MAAM,aAAA,GAAgB,CAAC,OAAA,IAAW,CAAC,QAAA;AAEnC,EAAA,uBACE,IAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACE,GAAG,SAAA;AAAA,MACJ,SAAA,EAAW,EAAA,CAAG,QAAA,EAAU,SAAA,EAAW,SAAS,CAAA;AAAA,MAC5C,WAAA,EAAW,IAAA;AAAA,MACX,WAAA,EAAW,EAAA,CAAG,IAAA,GAAO,MAAA,GAAS,MAAA;AAAA,MAC9B,eAAA,EAAe,WAAW,MAAA,GAAS,MAAA;AAAA,MACnC,cAAA,EAAc,UAAU,MAAA,GAAS,MAAA;AAAA,MACjC,cAAA,EAAc,UAAU,MAAA,GAAS,MAAA;AAAA,MAEjC,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACC,EAAA;AAAA,YACA,QAAA;AAAA,YACA,OAAA;AAAA,YACA,SAAA;AAAA,YACA,OAAA,EAAS,WAAA,IAAgB,QAAA,IAAY,QAAA,CAAS,IAAA,IAAS,IAAA;AAAA,YACvD,IAAA,EAAM,OAAA,GAAU,YAAA,GAAe,aAAA,GAAgB,cAAc,QAAA,CAAS,KAAA;AAAA,YACtE,aAAA;AAAA,YACC,GAAG;AAAA;AAAA,SACN;AAAA,wBACA,GAAA;AAAA,UAAC,YAAA;AAAA,UAAA;AAAA,YACC,EAAA;AAAA,YACA,OAAA;AAAA,YACA,UAAA;AAAA,YACA,iBAAA;AAAA,YACA,SAAA;AAAA,YACA,SAAA;AAAA,YACA,IAAA;AAAA,YACC,GAAI,CAAC,SAAA,IAAa,EAAE,KAAA,EAAO,MAAM,IAAA;AAAK;AAAA;AACzC;AAAA;AAAA,GACF;AAEJ","file":"select.js","sourcesContent":["'use client';\n\nimport './select.css';\nimport type { HTMLAttributes, ReactNode } from 'react';\nimport { useControllable } from '../../internal/hooks/use-controllable';\nimport { useListbox, ListboxPanel, SelectTrigger, type SelectOption, type SelectGroup } from './core';\nimport type { DisableableAnimation } from '../../../motion/timing';\nimport type { DataAttributes } from '../../../dom-props';\nimport { ButtonProps } from '../../primitives/button/Button';\nimport { cx } from '../../internal/utils/cx';\n\nexport type { SelectOption, SelectGroup } from './core';\n\nexport interface SelectProps {\n /** The choices - a flat `SelectOption[]`, or `SelectGroup[]` to render labeled sections. @default [] */\n options: SelectOption[] | SelectGroup[];\n /** Controlled value - matches an option's `value`, or `null` for none. Omit for uncontrolled (use `defaultValue`). */\n value?: string | null;\n /** Initial value when uncontrolled. @default null */\n defaultValue?: string | null;\n /** Fires on commit - gets the new `value` and its full `SelectOption`. Committing closes the menu. */\n onChange?: (value: string, option: SelectOption) => void;\n /** Trigger text when nothing is selected. @default 'Select an option' */\n placeholder?: string;\n /** Control height. @default 'md' */\n size?: 'sm' | 'md' | 'lg';\n /** Disabled - trigger is inert and the menu cannot open. @default false */\n disabled?: boolean;\n /** Danger ring + border. @default false */\n invalid?: boolean;\n /** Skeleton rows in the menu; trigger reads \"Loading...\". @default false */\n loading?: boolean;\n /** Type-to-filter field pinned above the list. @default false */\n searchable?: boolean;\n /** Placeholder for the `searchable` filter input. @default 'Filter options' */\n searchPlaceholder?: string;\n /** Your own icon node pinned before the trigger label; else the selected option's icon. */\n leadingIcon?: ReactNode;\n /** Base id for the trigger/menu/list ids and a11y wiring; auto-generated if omitted. */\n id?: string;\n /** Accessible name for the trigger and listbox - supply when there is no visible label. */\n ariaLabel?: string;\n /** Standard <div> attributes (className, style, data-*, ...) forwarded to the select root. */\n htmlProps?: HTMLAttributes<HTMLDivElement> & DataAttributes;\n /** Menu open/close timing - motion tokens only, or `null` to disable. @default duration 'base' + ease 'entrance'/'exit' */\n animation?: DisableableAnimation;\n /** Trigger props */\n triggerProps?: ButtonProps;\n /** Show check icon on selected value */\n showCheck?: boolean;\n}\n\nexport function Select({\n options = [],\n value: controlledValue,\n defaultValue = null,\n onChange,\n placeholder = 'Select an option',\n size = 'md',\n disabled = false,\n invalid = false,\n loading = false,\n searchable = false,\n searchPlaceholder = 'Filter options',\n leadingIcon = null,\n id,\n ariaLabel,\n htmlProps,\n animation,\n triggerProps,\n showCheck = true,\n}: SelectProps) {\n const [value, setValue] = useControllable<string | null, SelectOption>(controlledValue, defaultValue, onChange);\n\n const lb = useListbox({\n options,\n disabled,\n loading,\n searchable,\n id,\n idPrefix: 'select-',\n isSelected: (v) => v === value && value != null,\n onCommit: (opt) => setValue(opt.value, opt),\n closeOnCommit: true,\n });\n\n const selected = lb.flat.find((o) => o.value === value) || null;\n const isPlaceholder = !loading && !selected;\n\n return (\n <div\n {...htmlProps}\n className={cx('select', htmlProps?.className)}\n data-size={size}\n data-open={lb.open ? 'true' : undefined}\n data-disabled={disabled ? 'true' : undefined}\n data-invalid={invalid ? 'true' : undefined}\n data-loading={loading ? 'true' : undefined}\n >\n <SelectTrigger\n lb={lb}\n disabled={disabled}\n invalid={invalid}\n ariaLabel={ariaLabel}\n leading={leadingIcon || (selected && selected.icon) || null}\n text={loading ? 'Loading...' : isPlaceholder ? placeholder : selected.label}\n isPlaceholder={isPlaceholder}\n {...triggerProps}\n />\n <ListboxPanel\n lb={lb}\n loading={loading}\n searchable={searchable}\n searchPlaceholder={searchPlaceholder}\n ariaLabel={ariaLabel}\n animation={animation}\n size={size}\n {...(!showCheck && { check: () => null })}\n />\n </div>\n );\n}\n"]}
package/dist/sheet.css ADDED
@@ -0,0 +1,26 @@
1
+ /* sheet.css - edge-docked placement on the modal shell: sheets dock flush (no layer padding); the panel spans the docked edge. */
2
+ .overlay-layer--sheet-right {
3
+ align-items: stretch;
4
+ justify-items: end;
5
+ }
6
+ .overlay-panel--sheet-right {
7
+ height: 100%;
8
+ max-width: 100%;
9
+ }
10
+
11
+ .overlay-layer--sheet-bottom {
12
+ align-items: end;
13
+ justify-items: stretch;
14
+ }
15
+ .overlay-panel--sheet-bottom {
16
+ width: 100%;
17
+ max-height: 100%;
18
+ }
19
+
20
+ /* Drag stretch scales the panel away from the edge it is docked to. */
21
+ .overlay-panel--sheet-right {
22
+ transform-origin: 100% 50%;
23
+ }
24
+ .overlay-panel--sheet-bottom {
25
+ transform-origin: 50% 100%;
26
+ }
@@ -0,0 +1,31 @@
1
+ import * as react from 'react';
2
+ import { ReactElement, HTMLAttributes, ReactNode } from 'react';
3
+ import { D as DisableableAnimation } from './timing-7JA_zQHP.js';
4
+ import { D as DataAttributes } from './dom-props-C0jrllBw.js';
5
+ import './motion-scale-Canq4stZ.js';
6
+
7
+ interface SheetProps {
8
+ /** Controlled open state. Omit to stay uncontrolled. */
9
+ open?: boolean;
10
+ /** Initial state when uncontrolled. Default false. */
11
+ defaultOpen?: boolean;
12
+ /** Fires whenever the open state changes. Pair with `open` for controlled use. */
13
+ onOpenChange?: (open: boolean) => void;
14
+ /** Cloned to open the sheet on click. */
15
+ trigger?: ReactElement | null;
16
+ /** Edge the sheet slides in from. Default 'right'. */
17
+ side?: 'right' | 'bottom';
18
+ /** Scrim/Esc dismissal + drag-to-edge. Default true. */
19
+ dismissible?: boolean;
20
+ /** Base id for the panel; drives the trigger's `aria-controls`. Auto-generated when omitted. */
21
+ id?: string;
22
+ /** Standard attributes (className, style, data-*, ...) forwarded to the sheet panel. */
23
+ htmlProps?: HTMLAttributes<HTMLDivElement> & DataAttributes;
24
+ /** Open/close timing - motion tokens only, or `null` to disable. @default open 'slow'/'entrance', close 'base'/'exit' */
25
+ animation?: DisableableAnimation;
26
+ /** The ENTIRE surface - paint AND semantics. Drive dismissal with `open`/`onOpenChange`. */
27
+ children: ReactNode;
28
+ }
29
+ declare function Sheet({ open: controlledOpen, defaultOpen, onOpenChange, trigger, side, dismissible, id, htmlProps, animation, children, }: SheetProps): react.JSX.Element;
30
+
31
+ export { Sheet, type SheetProps };
package/dist/sheet.js ADDED
@@ -0,0 +1,14 @@
1
+ 'use client';export { Sheet } from './chunk-XZAEIQDR.js';
2
+ import './chunk-4R2GQO43.js';
3
+ import './chunk-LDC3RIYA.js';
4
+ import './chunk-GY7JOPUQ.js';
5
+ import './chunk-NEF5XAHG.js';
6
+ import './chunk-MXOPCFWR.js';
7
+ import './chunk-W3SHPKSB.js';
8
+ import './chunk-L3Q3VDIW.js';
9
+ import './chunk-MMRIQNEN.js';
10
+ import './chunk-S5ZTZANS.js';
11
+ import './chunk-VTJTGVZZ.js';
12
+ import './chunk-QGNC7LH5.js';
13
+ //# sourceMappingURL=sheet.js.map
14
+ //# sourceMappingURL=sheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"sheet.js"}
@@ -0,0 +1,19 @@
1
+ import * as react from 'react';
2
+ import { BadgeProps } from './badge.js';
3
+ import './dom-props-C0jrllBw.js';
4
+
5
+ type PostStatus = 'draft' | 'scheduled' | 'processing' | 'published' | 'failed';
6
+ declare const POST_STATUS: Record<PostStatus, {
7
+ tone: BadgeProps['tone'];
8
+ label: string;
9
+ live?: boolean;
10
+ }>;
11
+ interface StatusBadgeProps extends Omit<BadgeProps, 'children' | 'tone'> {
12
+ /** Lifecycle state - maps to a canonical `tone` + label (`processing` also pulses live). Unknown falls back to `draft`. */
13
+ status: PostStatus;
14
+ /** Morph in place as `status` changes instead of swapping. */
15
+ morph?: boolean;
16
+ }
17
+ declare function StatusBadge({ status, morph, ...rest }: StatusBadgeProps): react.JSX.Element;
18
+
19
+ export { POST_STATUS, type PostStatus, StatusBadge, type StatusBadgeProps };