@uisatin/ui 0.2.0 → 0.4.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 (359) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +10 -1
  3. package/{chunk-P4O6TGDR.js → chunk-3VVO5MY5.js} +28 -26
  4. package/chunk-47DDBME3.js +87 -0
  5. package/{chunk-SHDFUXYV.js → chunk-5663JVE5.js} +16 -18
  6. package/chunk-67CBFB6Y.js +99 -0
  7. package/chunk-6DWLTGRQ.js +130 -0
  8. package/chunk-6GNMUJQ4.js +45 -0
  9. package/chunk-6JTSZAGO.js +177 -0
  10. package/chunk-6RLSRMB5.js +14 -0
  11. package/chunk-6Y6CY2DP.js +55 -0
  12. package/{chunk-O7F3CIDV.js → chunk-7NV53EL5.js} +10 -12
  13. package/{chunk-BNZVTLHV.js → chunk-7SVMERPH.js} +25 -21
  14. package/chunk-A52HUWVM.js +24 -0
  15. package/chunk-AKEZCWNW.js +29 -0
  16. package/{chunk-SH6NG6VN.js → chunk-APRVUOD6.js} +6 -8
  17. package/{chunk-QUF2IPOZ.js → chunk-C435UD7V.js} +14 -15
  18. package/{chunk-B2K45IUR.js → chunk-C6WRJ7DG.js} +5 -7
  19. package/{chunk-PF3YBUKT.js → chunk-CQFAMWZI.js} +16 -15
  20. package/chunk-DAKVTPYZ.js +86 -0
  21. package/{chunk-VAGIAREV.js → chunk-DMZW4LGU.js} +29 -26
  22. package/chunk-EBZHGRM5.js +46 -0
  23. package/chunk-EHEXE2UV.js +44 -0
  24. package/{chunk-72OCFAPT.js → chunk-EQAFDIPE.js} +26 -23
  25. package/{chunk-LLHTVIM3.js → chunk-EXKSKYG3.js} +7 -9
  26. package/chunk-FB6DG3LR.js +35 -0
  27. package/chunk-GH2DEOGO.js +67 -0
  28. package/{chunk-YG7JOOLJ.js → chunk-GKDMCY2S.js} +5 -7
  29. package/chunk-GTFUAA6H.js +42 -0
  30. package/{chunk-TX3H3QMA.js → chunk-HI6QIG55.js} +71 -70
  31. package/{chunk-6QMSWITQ.js → chunk-HZV7EXGU.js} +24 -26
  32. package/{chunk-A5XEM3GF.js → chunk-IKJIR6VL.js} +34 -36
  33. package/{chunk-DO3TBNSC.js → chunk-INJWE2LD.js} +15 -17
  34. package/chunk-J5UQPROI.js +56 -0
  35. package/{chunk-6YXUBP27.js → chunk-JCR5TWTF.js} +72 -67
  36. package/chunk-JKOBDLP3.js +25 -0
  37. package/chunk-JR3VVDV6.js +37 -0
  38. package/chunk-JYGCZWET.js +112 -0
  39. package/{chunk-UGRSWP6U.js → chunk-K5G5OEV5.js} +10 -12
  40. package/{chunk-B6V4VSGH.js → chunk-KDU7AT2T.js} +14 -15
  41. package/chunk-KITXKIYW.js +104 -0
  42. package/{chunk-NN6PKJWS.js → chunk-KQNA22D3.js} +7 -9
  43. package/{chunk-YPNKBE5X.js → chunk-L5PPN42A.js} +14 -9
  44. package/chunk-LAOE6Y57.js +95 -0
  45. package/chunk-LI5VYDLN.js +195 -0
  46. package/{chunk-7TXHCRAG.js → chunk-LKSFTNPF.js} +8 -10
  47. package/chunk-LLW3X4ZJ.js +39 -0
  48. package/{chunk-RTJ76X5U.js → chunk-LWRB4DED.js} +2 -4
  49. package/{chunk-NSRTTYQ4.js → chunk-M7RILZVW.js} +42 -35
  50. package/{chunk-LW3TRU5W.js → chunk-MOGWOUCN.js} +28 -16
  51. package/chunk-NCIRJ5V2.js +108 -0
  52. package/chunk-NQL6SIIB.js +168 -0
  53. package/chunk-NTSU44FY.js +81 -0
  54. package/{chunk-3DINAQLL.js → chunk-P36KBUYD.js} +33 -29
  55. package/chunk-P6RHT2VM.js +147 -0
  56. package/{chunk-CL2II6BX.js → chunk-PD2KD5OR.js} +11 -13
  57. package/{chunk-XL75JRUA.js → chunk-PP46SY7M.js} +42 -22
  58. package/{chunk-L6NCCSIP.js → chunk-PTK4QAOQ.js} +36 -29
  59. package/{chunk-HL42K2NH.js → chunk-Q7KVC5B4.js} +17 -17
  60. package/{chunk-H4NU7NPO.js → chunk-R3DTMBDT.js} +62 -61
  61. package/{chunk-KNUWZNFV.js → chunk-R4KPFBMK.js} +4 -6
  62. package/chunk-R5TQ3HNB.js +71 -0
  63. package/chunk-RFSPJECL.js +84 -0
  64. package/chunk-RPL6FRVX.js +88 -0
  65. package/{chunk-AN2RNJLR.js → chunk-STYOBAC7.js} +16 -16
  66. package/{chunk-X3PQANZO.js → chunk-SVUWR3HD.js} +47 -46
  67. package/chunk-T7P3OEBP.js +128 -0
  68. package/{chunk-QS4N4MNP.js → chunk-TB3ZRV3Y.js} +18 -20
  69. package/{chunk-MYEZXZZC.js → chunk-TOY6YPTG.js} +23 -25
  70. package/{chunk-XILQ7GXE.js → chunk-U6X6ODDJ.js} +11 -13
  71. package/{chunk-XZNHT6MO.js → chunk-UAJ6M34K.js} +115 -61
  72. package/chunk-W2EH6RY5.js +42 -0
  73. package/{chunk-FDKIX4DC.js → chunk-W2QQQWNE.js} +7 -9
  74. package/{chunk-LZMKSFCF.js → chunk-WALANB3V.js} +10 -12
  75. package/chunk-WCUR44O6.js +88 -0
  76. package/{chunk-BNTPPZCK.js → chunk-WJYJMX5S.js} +37 -39
  77. package/chunk-WZSLDYUU.js +131 -0
  78. package/{chunk-J3NSDRVH.js → chunk-XETMIETJ.js} +0 -2
  79. package/chunk-XU6JJDMZ.js +117 -0
  80. package/{chunk-BKZBWPUH.js → chunk-XWPH7C2W.js} +9 -11
  81. package/{chunk-GICKPMJU.js → chunk-YXWXSRXG.js} +31 -31
  82. package/{chunk-2HKBZFIK.js → chunk-YY236ZSJ.js} +31 -31
  83. package/{chunk-YX5VNRJX.js → chunk-YYFAZQ25.js} +0 -2
  84. package/{chunk-Y5AYU7PK.js → chunk-ZHFIWDGF.js} +0 -2
  85. package/components/accordion.js +2 -4
  86. package/components/action-button.d.ts +37 -0
  87. package/components/action-button.js +5 -0
  88. package/components/agent-loading.d.ts +2 -0
  89. package/components/agent-loading.js +2 -4
  90. package/components/agent-picker.js +5 -5
  91. package/components/agent-suggestion.js +5 -6
  92. package/components/alert.d.ts +37 -0
  93. package/components/alert.js +5 -0
  94. package/components/announcement-bar.js +7 -7
  95. package/components/attachment.js +5 -5
  96. package/components/avatar.js +4 -6
  97. package/components/badge.js +2 -4
  98. package/components/banner-mesh.js +1 -3
  99. package/components/banner.js +6 -6
  100. package/components/bar-chart.js +10 -11
  101. package/components/breadcrumb.js +5 -6
  102. package/components/button-group.d.ts +26 -0
  103. package/components/button-group.js +5 -0
  104. package/components/button.d.ts +13 -1
  105. package/components/button.js +4 -4
  106. package/components/card.js +5 -5
  107. package/components/channel-chart.js +10 -11
  108. package/components/chart.js +9 -10
  109. package/components/checkbox.js +2 -4
  110. package/components/chip.js +2 -4
  111. package/components/citations.d.ts +6 -4
  112. package/components/citations.js +4 -5
  113. package/components/code-block.js +5 -5
  114. package/components/combobox.d.ts +12 -3
  115. package/components/combobox.js +10 -10
  116. package/components/command-menu.d.ts +6 -2
  117. package/components/command-menu.js +5 -6
  118. package/components/context-menu.d.ts +12 -5
  119. package/components/context-menu.js +5 -6
  120. package/components/cookie-consent.js +5 -5
  121. package/components/date-picker.d.ts +26 -14
  122. package/components/date-picker.js +9 -9
  123. package/components/decision-card.js +7 -7
  124. package/components/dialog.d.ts +6 -8
  125. package/components/dialog.js +6 -5
  126. package/components/donut-chart.js +10 -11
  127. package/components/dot.js +2 -4
  128. package/components/dropdown.d.ts +6 -1
  129. package/components/dropdown.js +4 -5
  130. package/components/empty-state.js +2 -4
  131. package/components/field-group.d.ts +27 -0
  132. package/components/field-group.js +3 -0
  133. package/components/file-upload.js +7 -7
  134. package/components/floating.js +1 -3
  135. package/components/form-field.d.ts +38 -1
  136. package/components/form-field.js +2 -4
  137. package/components/form.d.ts +47 -0
  138. package/components/form.js +3 -0
  139. package/components/hover-card.d.ts +5 -2
  140. package/components/hover-card.js +2 -4
  141. package/components/input-group.d.ts +21 -0
  142. package/components/input-group.js +6 -0
  143. package/components/input-otp.d.ts +4 -2
  144. package/components/input-otp.js +7 -8
  145. package/components/input.d.ts +5 -1
  146. package/components/input.js +3 -5
  147. package/components/kbd.js +2 -4
  148. package/components/labels.d.ts +86 -0
  149. package/components/labels.js +1 -0
  150. package/components/line-chart.js +11 -12
  151. package/components/link.d.ts +20 -0
  152. package/components/link.js +3 -0
  153. package/components/list.d.ts +46 -0
  154. package/components/list.js +2 -0
  155. package/components/message-actions.js +5 -5
  156. package/components/message.js +8 -8
  157. package/components/number-input.d.ts +4 -2
  158. package/components/number-input.js +7 -8
  159. package/components/pagination.js +6 -6
  160. package/components/password-input.d.ts +16 -0
  161. package/components/password-input.js +7 -0
  162. package/components/popover.d.ts +11 -5
  163. package/components/popover.js +3 -4
  164. package/components/progress.js +2 -4
  165. package/components/prompt-bar.js +6 -6
  166. package/components/radio.js +2 -4
  167. package/components/search-bar.js +3 -5
  168. package/components/segmented-control.d.ts +4 -2
  169. package/components/segmented-control.js +3 -5
  170. package/components/select.d.ts +11 -2
  171. package/components/select.js +6 -7
  172. package/components/selectable-card.d.ts +37 -0
  173. package/components/selectable-card.js +2 -0
  174. package/components/selectable-checkbox.d.ts +14 -0
  175. package/components/selectable-checkbox.js +4 -0
  176. package/components/selectable-radio.d.ts +16 -0
  177. package/components/selectable-radio.js +3 -0
  178. package/components/separator.d.ts +18 -0
  179. package/components/separator.js +2 -0
  180. package/components/sheet.d.ts +4 -2
  181. package/components/sheet.js +7 -6
  182. package/components/sidebar.js +2 -4
  183. package/components/skeleton.js +2 -4
  184. package/components/slider.d.ts +6 -2
  185. package/components/slider.js +7 -8
  186. package/components/sliding-indicator.js +1 -3
  187. package/components/spinner.d.ts +18 -0
  188. package/components/spinner.js +3 -0
  189. package/components/split-button.d.ts +24 -0
  190. package/components/split-button.js +8 -0
  191. package/components/streaming-text.js +2 -4
  192. package/components/switch.js +2 -4
  193. package/components/table.d.ts +16 -5
  194. package/components/table.js +4 -5
  195. package/components/tabs.d.ts +4 -2
  196. package/components/tabs.js +3 -5
  197. package/components/textarea.js +3 -5
  198. package/components/thinking.js +3 -5
  199. package/components/toast.js +5 -5
  200. package/components/toggle.js +2 -4
  201. package/components/tooltip.d.ts +5 -2
  202. package/components/tooltip.js +3 -5
  203. package/index.d.ts +17 -2
  204. package/index.js +82 -231
  205. package/lib/utils.d.ts +8 -1
  206. package/lib/utils.js +1 -3
  207. package/package.json +11 -1
  208. package/styles.css +1 -1
  209. package/theme/create-theme.d.ts +6 -2
  210. package/theme/index.js +1 -0
  211. package/chunk-2HKBZFIK.js.map +0 -1
  212. package/chunk-3DINAQLL.js.map +0 -1
  213. package/chunk-3ERGAHKA.js +0 -179
  214. package/chunk-3ERGAHKA.js.map +0 -1
  215. package/chunk-6C7CGJX2.js +0 -86
  216. package/chunk-6C7CGJX2.js.map +0 -1
  217. package/chunk-6QMSWITQ.js.map +0 -1
  218. package/chunk-6YXUBP27.js.map +0 -1
  219. package/chunk-72OCFAPT.js.map +0 -1
  220. package/chunk-7TXHCRAG.js.map +0 -1
  221. package/chunk-A5XEM3GF.js.map +0 -1
  222. package/chunk-AN2RNJLR.js.map +0 -1
  223. package/chunk-B2K45IUR.js.map +0 -1
  224. package/chunk-B6V4VSGH.js.map +0 -1
  225. package/chunk-BKZBWPUH.js.map +0 -1
  226. package/chunk-BNTPPZCK.js.map +0 -1
  227. package/chunk-BNZVTLHV.js.map +0 -1
  228. package/chunk-CL2II6BX.js.map +0 -1
  229. package/chunk-D7RZNTFC.js +0 -95
  230. package/chunk-D7RZNTFC.js.map +0 -1
  231. package/chunk-DETGJAIC.js +0 -147
  232. package/chunk-DETGJAIC.js.map +0 -1
  233. package/chunk-DO3TBNSC.js.map +0 -1
  234. package/chunk-ESC5JCVQ.js +0 -90
  235. package/chunk-ESC5JCVQ.js.map +0 -1
  236. package/chunk-FDKIX4DC.js.map +0 -1
  237. package/chunk-GICKPMJU.js.map +0 -1
  238. package/chunk-GQA24FYG.js +0 -57
  239. package/chunk-GQA24FYG.js.map +0 -1
  240. package/chunk-H4NU7NPO.js.map +0 -1
  241. package/chunk-H63FYCMY.js +0 -11
  242. package/chunk-H63FYCMY.js.map +0 -1
  243. package/chunk-HL42K2NH.js.map +0 -1
  244. package/chunk-HNQUX43Z.js +0 -109
  245. package/chunk-HNQUX43Z.js.map +0 -1
  246. package/chunk-HRKPV66B.js +0 -32
  247. package/chunk-HRKPV66B.js.map +0 -1
  248. package/chunk-J3NSDRVH.js.map +0 -1
  249. package/chunk-JPNWHWAQ.js +0 -151
  250. package/chunk-JPNWHWAQ.js.map +0 -1
  251. package/chunk-KNUWZNFV.js.map +0 -1
  252. package/chunk-L6NCCSIP.js.map +0 -1
  253. package/chunk-LLHTVIM3.js.map +0 -1
  254. package/chunk-LW3TRU5W.js.map +0 -1
  255. package/chunk-LZMKSFCF.js.map +0 -1
  256. package/chunk-MR3JDI7E.js +0 -122
  257. package/chunk-MR3JDI7E.js.map +0 -1
  258. package/chunk-MYEZXZZC.js.map +0 -1
  259. package/chunk-NN6PKJWS.js.map +0 -1
  260. package/chunk-NSRTTYQ4.js.map +0 -1
  261. package/chunk-O7F3CIDV.js.map +0 -1
  262. package/chunk-P4O6TGDR.js.map +0 -1
  263. package/chunk-PF3YBUKT.js.map +0 -1
  264. package/chunk-PVOLDO4G.js +0 -47
  265. package/chunk-PVOLDO4G.js.map +0 -1
  266. package/chunk-QS4N4MNP.js.map +0 -1
  267. package/chunk-QUF2IPOZ.js.map +0 -1
  268. package/chunk-RTJ76X5U.js.map +0 -1
  269. package/chunk-SH6NG6VN.js.map +0 -1
  270. package/chunk-SHDFUXYV.js.map +0 -1
  271. package/chunk-TKO44NDI.js +0 -84
  272. package/chunk-TKO44NDI.js.map +0 -1
  273. package/chunk-TX3H3QMA.js.map +0 -1
  274. package/chunk-UBNHSZSE.js +0 -88
  275. package/chunk-UBNHSZSE.js.map +0 -1
  276. package/chunk-UC3ZJWOD.js +0 -73
  277. package/chunk-UC3ZJWOD.js.map +0 -1
  278. package/chunk-UGRSWP6U.js.map +0 -1
  279. package/chunk-VAGIAREV.js.map +0 -1
  280. package/chunk-WTMZT3IT.js +0 -105
  281. package/chunk-WTMZT3IT.js.map +0 -1
  282. package/chunk-WX6BP5ZP.js +0 -39
  283. package/chunk-WX6BP5ZP.js.map +0 -1
  284. package/chunk-X3PQANZO.js.map +0 -1
  285. package/chunk-XILQ7GXE.js.map +0 -1
  286. package/chunk-XL75JRUA.js.map +0 -1
  287. package/chunk-XZNHT6MO.js.map +0 -1
  288. package/chunk-Y5AYU7PK.js.map +0 -1
  289. package/chunk-YG7JOOLJ.js.map +0 -1
  290. package/chunk-YPJYW624.js +0 -195
  291. package/chunk-YPJYW624.js.map +0 -1
  292. package/chunk-YPNKBE5X.js.map +0 -1
  293. package/chunk-YX5VNRJX.js.map +0 -1
  294. package/components/accordion.js.map +0 -1
  295. package/components/agent-loading.js.map +0 -1
  296. package/components/agent-picker.js.map +0 -1
  297. package/components/agent-suggestion.js.map +0 -1
  298. package/components/announcement-bar.js.map +0 -1
  299. package/components/attachment.js.map +0 -1
  300. package/components/avatar.js.map +0 -1
  301. package/components/badge.js.map +0 -1
  302. package/components/banner-mesh.js.map +0 -1
  303. package/components/banner.js.map +0 -1
  304. package/components/bar-chart.js.map +0 -1
  305. package/components/breadcrumb.js.map +0 -1
  306. package/components/button.js.map +0 -1
  307. package/components/card.js.map +0 -1
  308. package/components/channel-chart.js.map +0 -1
  309. package/components/chart.js.map +0 -1
  310. package/components/checkbox.js.map +0 -1
  311. package/components/chip.js.map +0 -1
  312. package/components/citations.js.map +0 -1
  313. package/components/code-block.js.map +0 -1
  314. package/components/combobox.js.map +0 -1
  315. package/components/command-menu.js.map +0 -1
  316. package/components/context-menu.js.map +0 -1
  317. package/components/cookie-consent.js.map +0 -1
  318. package/components/date-picker.js.map +0 -1
  319. package/components/decision-card.js.map +0 -1
  320. package/components/dialog.js.map +0 -1
  321. package/components/donut-chart.js.map +0 -1
  322. package/components/dot.js.map +0 -1
  323. package/components/dropdown.js.map +0 -1
  324. package/components/empty-state.js.map +0 -1
  325. package/components/file-upload.js.map +0 -1
  326. package/components/floating.js.map +0 -1
  327. package/components/form-field.js.map +0 -1
  328. package/components/hover-card.js.map +0 -1
  329. package/components/input-otp.js.map +0 -1
  330. package/components/input.js.map +0 -1
  331. package/components/kbd.js.map +0 -1
  332. package/components/line-chart.js.map +0 -1
  333. package/components/message-actions.js.map +0 -1
  334. package/components/message.js.map +0 -1
  335. package/components/number-input.js.map +0 -1
  336. package/components/pagination.js.map +0 -1
  337. package/components/popover.js.map +0 -1
  338. package/components/progress.js.map +0 -1
  339. package/components/prompt-bar.js.map +0 -1
  340. package/components/radio.js.map +0 -1
  341. package/components/search-bar.js.map +0 -1
  342. package/components/segmented-control.js.map +0 -1
  343. package/components/select.js.map +0 -1
  344. package/components/sheet.js.map +0 -1
  345. package/components/sidebar.js.map +0 -1
  346. package/components/skeleton.js.map +0 -1
  347. package/components/slider.js.map +0 -1
  348. package/components/sliding-indicator.js.map +0 -1
  349. package/components/streaming-text.js.map +0 -1
  350. package/components/switch.js.map +0 -1
  351. package/components/table.js.map +0 -1
  352. package/components/tabs.js.map +0 -1
  353. package/components/textarea.js.map +0 -1
  354. package/components/thinking.js.map +0 -1
  355. package/components/toast.js.map +0 -1
  356. package/components/toggle.js.map +0 -1
  357. package/components/tooltip.js.map +0 -1
  358. package/index.js.map +0 -1
  359. package/lib/utils.js.map +0 -1
@@ -1,8 +1,9 @@
1
- import { Chip } from './chunk-3ERGAHKA.js';
2
- import { useFieldChrome, FieldChrome, SelectChevron } from './chunk-72OCFAPT.js';
3
- import { MenuItemContent, menuItemClass, menuSurfaceClass } from './chunk-3DINAQLL.js';
4
- import { Button } from './chunk-HNQUX43Z.js';
5
- import { cn } from './chunk-H63FYCMY.js';
1
+ import { Chip } from './chunk-6JTSZAGO.js';
2
+ import { useFieldChrome, FieldChrome, SelectChevron } from './chunk-EQAFDIPE.js';
3
+ import { MenuItemContent, menuItemClass, menuSurfaceClass } from './chunk-P36KBUYD.js';
4
+ import { Button } from './chunk-6DWLTGRQ.js';
5
+ import { useSatinLabels } from './chunk-NTSU44FY.js';
6
+ import { cn } from './chunk-EHEXE2UV.js';
6
7
  import * as React from 'react';
7
8
  import { Popover } from 'radix-ui';
8
9
  import { Search } from 'iconoir-react';
@@ -20,12 +21,12 @@ function Combobox({
20
21
  onValueChange,
21
22
  multiple = false,
22
23
  footer = false,
23
- placeholder = "Select\u2026",
24
- searchPlaceholder = "Search\u2026",
25
- emptyText = "No results",
26
- applyLabel = "Apply",
27
- cancelLabel = "Cancel",
28
- clearLabel = "Clear",
24
+ placeholder: placeholderProp,
25
+ searchPlaceholder: searchPlaceholderProp,
26
+ emptyText: emptyTextProp,
27
+ applyLabel: applyLabelProp,
28
+ cancelLabel: cancelLabelProp,
29
+ clearLabel: clearLabelProp,
29
30
  label,
30
31
  hint,
31
32
  error,
@@ -41,9 +42,17 @@ function Combobox({
41
42
  onInteractOutside,
42
43
  wrapperClassName,
43
44
  className,
45
+ "aria-describedby": describedBy,
44
46
  ...props
45
47
  }) {
46
48
  const chrome = useFieldChrome({ id, disabled, error, hint });
49
+ const labels = useSatinLabels();
50
+ const placeholder = placeholderProp ?? labels.select;
51
+ const searchPlaceholder = searchPlaceholderProp ?? labels.search;
52
+ const emptyText = emptyTextProp ?? labels.noResults;
53
+ const applyLabel = applyLabelProp ?? labels.apply;
54
+ const cancelLabel = cancelLabelProp ?? labels.cancel;
55
+ const clearLabel = clearLabelProp ?? labels.clear;
47
56
  const listId = `${chrome.controlId}-list`;
48
57
  const [uncontrolledValue, setUncontrolledValue] = React.useState(defaultValue);
49
58
  const applied = value ?? uncontrolledValue;
@@ -100,51 +109,51 @@ function Combobox({
100
109
  "data-invalid": chrome.invalid || void 0,
101
110
  "data-disabled": chrome.disabled || void 0,
102
111
  "data-state": open ? "open" : "closed",
103
- className: cn("satin-field satin-select satin-combobox relative", className),
112
+ className: cn("satin-field satin-select satin-combobox sa:relative", className),
104
113
  children: [
105
114
  /* @__PURE__ */ jsx(
106
115
  Popover.Trigger,
107
116
  {
117
+ ...props,
108
118
  id: chrome.controlId,
109
119
  "data-slot": "combobox-trigger",
110
120
  disabled: chrome.disabled,
111
121
  "aria-invalid": chrome.invalid || void 0,
112
- "aria-describedby": chrome.describedBy,
113
- "aria-label": props["aria-label"],
122
+ "aria-describedby": [describedBy, chrome.describedBy].filter(Boolean).join(" ") || void 0,
114
123
  "aria-haspopup": "listbox",
115
- className: "absolute inset-0 cursor-pointer rounded-[inherit] outline-none focus-visible:ring-0 disabled:cursor-not-allowed",
116
- children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: chosen.length ? chosen.map((o) => o.label).join(", ") : placeholder })
124
+ className: "sa:absolute sa:inset-0 sa:cursor-pointer sa:rounded-[inherit] sa:outline-none sa:focus-visible:ring-0 sa:disabled:cursor-not-allowed",
125
+ children: /* @__PURE__ */ jsx("span", { className: "sa:sr-only", children: chosen.length ? chosen.map((o) => o.label).join(", ") : placeholder })
117
126
  }
118
127
  ),
119
- lead && /* @__PURE__ */ jsx("span", { className: "satin-field-icon satin-combobox-icon pointer-events-none", "aria-hidden": true, children: lead }),
120
- /* @__PURE__ */ jsxs("div", { className: "pointer-events-none flex min-w-0 flex-1 flex-wrap items-center gap-1 *:pointer-events-auto", children: [
128
+ lead && /* @__PURE__ */ jsx("span", { className: "satin-field-icon satin-combobox-icon sa:pointer-events-none", "aria-hidden": true, children: lead }),
129
+ /* @__PURE__ */ jsxs("div", { className: "sa:pointer-events-none sa:flex sa:min-w-0 sa:flex-1 sa:flex-wrap sa:items-center sa:gap-1 sa:*:pointer-events-auto", children: [
121
130
  chips && chosen.map((o) => /* @__PURE__ */ jsx(
122
131
  Chip,
123
132
  {
124
133
  size: "sm",
125
134
  variant: "outline",
126
135
  disabled: chrome.disabled,
127
- removeLabel: `Remove ${o.label}`,
136
+ removeLabel: `${labels.remove} ${o.label}`,
128
137
  onRemove: () => commit(applied.filter((v) => v !== o.value)),
129
- className: "relative",
138
+ className: "sa:relative",
130
139
  children: o.label
131
140
  },
132
141
  o.value
133
142
  )),
134
- triggerText && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("pointer-events-none! min-w-0 flex-1 truncate", chosen.length ? "text-text-default" : "text-text-muted"), children: triggerText }),
143
+ triggerText && /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: cn("sa:pointer-events-none! sa:min-w-0 sa:flex-1 sa:truncate", chosen.length ? "sa:text-text-default" : "sa:text-text-muted"), children: triggerText }),
135
144
  !label && chips && chosen.length > 1 && /* @__PURE__ */ jsx(
136
145
  Button,
137
146
  {
138
147
  variant: "tertiary",
139
148
  size: "xs",
140
149
  disabled: chrome.disabled,
141
- className: "relative ml-auto",
150
+ className: "sa:relative sa:ml-auto",
142
151
  onClick: () => commit([]),
143
152
  children: clearLabel
144
153
  }
145
154
  )
146
155
  ] }),
147
- /* @__PURE__ */ jsx(SelectChevron, { className: "satin-combobox-icon pointer-events-none" })
156
+ /* @__PURE__ */ jsx(SelectChevron, { className: "satin-combobox-icon sa:pointer-events-none" })
148
157
  ]
149
158
  }
150
159
  ) }),
@@ -159,14 +168,14 @@ function Combobox({
159
168
  onOpenAutoFocus,
160
169
  onInteractOutside,
161
170
  className: cn(
162
- "pointer-events-auto z-50 flex w-(--radix-popover-trigger-width) min-w-60 max-w-[520px] flex-col overflow-hidden",
171
+ "sa:pointer-events-auto sa:z-50 sa:flex sa:w-(--radix-popover-trigger-width) sa:min-w-60 sa:max-w-[520px] sa:flex-col sa:overflow-hidden",
163
172
  menuSurfaceClass,
164
- "origin-(--radix-popover-content-transform-origin) outline-none",
165
- "data-[state=open]:animate-[satin-enter_var(--duration-base)_var(--ease-out)]"
173
+ "sa:origin-(--radix-popover-content-transform-origin) sa:outline-none",
174
+ "sa:data-[state=open]:animate-[satin-enter_var(--sa-duration-base)_var(--sa-ease-out)]"
166
175
  ),
167
176
  children: [
168
- /* @__PURE__ */ jsxs("label", { className: "flex h-9 shrink-0 items-center gap-2 border-b border-border-subtle px-3 text-text-muted", children: [
169
- /* @__PURE__ */ jsx(Search, { "aria-hidden": true, className: "size-4 shrink-0 [stroke-width:1.875]" }),
177
+ /* @__PURE__ */ jsxs("label", { className: "sa:flex sa:h-9 sa:shrink-0 sa:items-center sa:gap-2 sa:border-b sa:border-border-subtle sa:px-3 sa:text-text-muted", children: [
178
+ /* @__PURE__ */ jsx(Search, { "aria-hidden": true, className: "sa:size-4 sa:shrink-0 sa:[stroke-width:1.875]" }),
170
179
  /* @__PURE__ */ jsx(
171
180
  "input",
172
181
  {
@@ -192,7 +201,7 @@ function Combobox({
192
201
  if (!shown[active].disabled) pick(shown[active].value);
193
202
  }
194
203
  },
195
- className: "min-w-0 flex-1 bg-transparent text-base leading-[21px] text-text-default outline-none placeholder:text-text-muted focus-visible:ring-0"
204
+ className: "sa:min-w-0 sa:flex-1 sa:bg-transparent sa:text-base sa:leading-[21px] sa:text-text-default sa:outline-none sa:placeholder:text-text-muted sa:focus-visible:ring-0"
196
205
  }
197
206
  )
198
207
  ] }),
@@ -202,8 +211,8 @@ function Combobox({
202
211
  id: listId,
203
212
  role: "listbox",
204
213
  "aria-multiselectable": multiple || void 0,
205
- className: "flex max-h-60 flex-col gap-0.5 overflow-y-auto p-1",
206
- children: shown.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-6 text-center text-sm text-text-muted", children: emptyText }) : shown.map((o, i) => {
214
+ className: "sa:flex sa:max-h-60 sa:flex-col sa:gap-0.5 sa:overflow-y-auto sa:p-1",
215
+ children: shown.length === 0 ? /* @__PURE__ */ jsx("p", { className: "sa:px-3 sa:py-6 sa:text-center sa:text-sm sa:text-text-muted", children: emptyText }) : shown.map((o, i) => {
207
216
  const picked = picks.includes(o.value);
208
217
  return /* @__PURE__ */ jsx(
209
218
  "div",
@@ -217,7 +226,7 @@ function Combobox({
217
226
  onPointerMove: () => setActive(i),
218
227
  onMouseDown: (e) => e.preventDefault(),
219
228
  onClick: () => !o.disabled && pick(o.value),
220
- className: cn(menuItemClass, picked && "bg-bg-selected"),
229
+ className: cn(menuItemClass, picked && "sa:bg-bg-selected"),
221
230
  children: /* @__PURE__ */ jsx(
222
231
  MenuItemContent,
223
232
  {
@@ -235,7 +244,7 @@ function Combobox({
235
244
  })
236
245
  }
237
246
  ),
238
- footer && /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center justify-end gap-2 border-t border-border-subtle p-2", children: [
247
+ footer && /* @__PURE__ */ jsxs("div", { className: "sa:flex sa:shrink-0 sa:items-center sa:justify-end sa:gap-2 sa:border-t sa:border-border-subtle sa:p-2", children: [
239
248
  /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => setOpen(false), children: cancelLabel }),
240
249
  /* @__PURE__ */ jsx(Button, { disabled: pending.length === 0, onClick: apply, children: applyLabel })
241
250
  ] })
@@ -248,5 +257,3 @@ function Combobox({
248
257
  }
249
258
 
250
259
  export { Combobox };
251
- //# sourceMappingURL=chunk-NSRTTYQ4.js.map
252
- //# sourceMappingURL=chunk-NSRTTYQ4.js.map
@@ -1,5 +1,6 @@
1
- import { useFieldChrome, FieldChrome } from './chunk-72OCFAPT.js';
2
- import { cn } from './chunk-H63FYCMY.js';
1
+ import { useFieldChrome, FieldChrome } from './chunk-EQAFDIPE.js';
2
+ import { useSatinLabels } from './chunk-NTSU44FY.js';
3
+ import { cn } from './chunk-EHEXE2UV.js';
3
4
  import * as React from 'react';
4
5
  import { Minus, Plus } from 'iconoir-react';
5
6
  import { jsx, jsxs } from 'react/jsx-runtime';
@@ -22,9 +23,14 @@ function NumberInput({
22
23
  name,
23
24
  wrapperClassName,
24
25
  className,
26
+ "aria-describedby": describedBy,
27
+ onChange,
28
+ onBlur,
29
+ onKeyDown,
25
30
  ...props
26
31
  }) {
27
32
  const chrome = useFieldChrome({ id, disabled, error, hint });
33
+ const labels = useSatinLabels();
28
34
  const [inner, setInner] = React.useState(defaultValue);
29
35
  const value = valueProp ?? inner;
30
36
  const [draft, setDraft] = React.useState(null);
@@ -43,10 +49,10 @@ function NumberInput({
43
49
  const atMin = value <= min;
44
50
  const atMax = value >= max;
45
51
  const btn = cn(
46
- "grid size-6 shrink-0 place-items-center rounded-md text-text-muted outline-none",
47
- "transition-[background-color,color,opacity] duration-(--duration-fast) ease-(--ease-out)",
48
- "hover:bg-bg-hover hover:text-text-default focus-visible:[box-shadow:0_0_0_2px_var(--action-focus-ring)]",
49
- "disabled:pointer-events-none disabled:opacity-40 [&_svg]:size-4 [&_svg]:[stroke-width:1.875]"
52
+ "sa:grid sa:size-6 sa:shrink-0 sa:place-items-center sa:rounded-md sa:text-text-muted sa:outline-none",
53
+ "sa:transition-[background-color,color,opacity] sa:duration-(--sa-duration-fast) sa:ease-(--sa-ease-out)",
54
+ "sa:hover:bg-bg-hover sa:hover:text-text-default sa:focus-visible:[box-shadow:0_0_0_2px_var(--action-focus-ring)]",
55
+ "sa:disabled:pointer-events-none sa:disabled:opacity-40 sa:[&_svg]:size-4 sa:[&_svg]:[stroke-width:1.875]"
50
56
  );
51
57
  return /* @__PURE__ */ jsx(FieldChrome, { label, chrome, className: wrapperClassName, children: /* @__PURE__ */ jsxs(
52
58
  "div",
@@ -56,14 +62,14 @@ function NumberInput({
56
62
  "data-filled": true,
57
63
  "data-invalid": chrome.invalid || void 0,
58
64
  "data-disabled": chrome.disabled || void 0,
59
- className: cn("satin-field gap-1 px-1", className),
65
+ className: cn("satin-field sa:gap-1 sa:px-1", className),
60
66
  children: [
61
67
  /* @__PURE__ */ jsx(
62
68
  "button",
63
69
  {
64
70
  type: "button",
65
71
  tabIndex: -1,
66
- "aria-label": "Decrease",
72
+ "aria-label": labels.decrease,
67
73
  "aria-controls": chrome.controlId,
68
74
  disabled: chrome.disabled || atMin,
69
75
  onClick: () => by(-1),
@@ -74,6 +80,7 @@ function NumberInput({
74
80
  /* @__PURE__ */ jsx(
75
81
  "input",
76
82
  {
83
+ ...props,
77
84
  id: chrome.controlId,
78
85
  name,
79
86
  role: "spinbutton",
@@ -83,13 +90,20 @@ function NumberInput({
83
90
  "aria-valuemax": Number.isFinite(max) ? max : void 0,
84
91
  "aria-valuetext": formatValue(value),
85
92
  "aria-invalid": chrome.invalid || void 0,
86
- "aria-describedby": chrome.describedBy,
87
- "aria-label": props["aria-label"],
93
+ "aria-describedby": [describedBy, chrome.describedBy].filter(Boolean).join(" ") || void 0,
88
94
  disabled: chrome.disabled,
89
95
  value: draft ?? formatValue(value),
90
- onChange: (e) => setDraft(e.target.value),
91
- onBlur: () => draft != null && commit(Number(draft.replace(",", ".").replace(/[^\d.-]/g, "")) || 0),
96
+ onChange: (e) => {
97
+ onChange?.(e);
98
+ setDraft(e.target.value);
99
+ },
100
+ onBlur: (e) => {
101
+ onBlur?.(e);
102
+ if (draft != null) commit(Number(draft.replace(",", ".").replace(/[^\d.-]/g, "")) || 0);
103
+ },
92
104
  onKeyDown: (e) => {
105
+ onKeyDown?.(e);
106
+ if (e.defaultPrevented) return;
93
107
  const keys = {
94
108
  ArrowUp: () => by(1),
95
109
  ArrowDown: () => by(-1),
@@ -105,7 +119,7 @@ function NumberInput({
105
119
  keys[e.key]();
106
120
  }
107
121
  },
108
- className: "satin-field-input text-center tabular-nums"
122
+ className: "satin-field-input sa:text-center sa:tabular-nums"
109
123
  }
110
124
  ),
111
125
  /* @__PURE__ */ jsx(
@@ -113,7 +127,7 @@ function NumberInput({
113
127
  {
114
128
  type: "button",
115
129
  tabIndex: -1,
116
- "aria-label": "Increase",
130
+ "aria-label": labels.increase,
117
131
  "aria-controls": chrome.controlId,
118
132
  disabled: chrome.disabled || atMax,
119
133
  onClick: () => by(1),
@@ -127,5 +141,3 @@ function NumberInput({
127
141
  }
128
142
 
129
143
  export { NumberInput };
130
- //# sourceMappingURL=chunk-LW3TRU5W.js.map
131
- //# sourceMappingURL=chunk-LW3TRU5W.js.map
@@ -0,0 +1,108 @@
1
+ import { FormContext, FieldDescription, useFormContext } from './chunk-KITXKIYW.js';
2
+ import { cn } from './chunk-EHEXE2UV.js';
3
+ import * as React from 'react';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+
6
+ function formValues(form) {
7
+ const values = {};
8
+ for (const [key, value] of new FormData(form)) {
9
+ const prev = values[key];
10
+ values[key] = prev === void 0 ? value : Array.isArray(prev) ? [...prev, value] : [prev, value];
11
+ }
12
+ return values;
13
+ }
14
+ var hasErrors = (errors) => !!errors && Object.values(errors).some(Boolean);
15
+ function Form({
16
+ layout = "vertical",
17
+ errors,
18
+ disabled,
19
+ onSubmit,
20
+ onSubmitValues,
21
+ noValidate = true,
22
+ className,
23
+ children,
24
+ ref,
25
+ ...props
26
+ }) {
27
+ const formRef = React.useRef(null);
28
+ const [submits, setSubmits] = React.useState(0);
29
+ const context = React.useMemo(() => ({ layout, disabled, errors }), [layout, disabled, errors]);
30
+ const hadErrors = React.useRef(false);
31
+ const lastSubmit = React.useRef(0);
32
+ React.useEffect(() => {
33
+ const now = hasErrors(errors);
34
+ const submitted = submits !== lastSubmit.current;
35
+ if (now && (submitted || !hadErrors.current)) {
36
+ const first = formRef.current?.querySelector('[aria-invalid="true"]');
37
+ if (submits > 0) first?.focus();
38
+ }
39
+ hadErrors.current = now;
40
+ lastSubmit.current = submits;
41
+ }, [errors, submits]);
42
+ const setRefs = (node) => {
43
+ formRef.current = node;
44
+ if (typeof ref === "function") ref(node);
45
+ else if (ref) ref.current = node;
46
+ };
47
+ return /* @__PURE__ */ jsx(FormContext.Provider, { value: context, children: /* @__PURE__ */ jsx(
48
+ "form",
49
+ {
50
+ ref: setRefs,
51
+ "data-slot": "form",
52
+ "data-layout": layout,
53
+ noValidate,
54
+ onSubmit: (event) => {
55
+ setSubmits((n) => n + 1);
56
+ if (onSubmitValues) {
57
+ event.preventDefault();
58
+ onSubmitValues(formValues(event.currentTarget), event);
59
+ }
60
+ onSubmit?.(event);
61
+ },
62
+ className: cn("sa:w-full", className),
63
+ ...props,
64
+ children: /* @__PURE__ */ jsx("fieldset", { disabled, className: "sa:m-0 sa:grid sa:min-w-0 sa:gap-6 sa:border-0 sa:p-0", children })
65
+ }
66
+ ) });
67
+ }
68
+ function FormSection({ title, description, className, children, ...props }) {
69
+ const id = React.useId();
70
+ return /* @__PURE__ */ jsxs(
71
+ "section",
72
+ {
73
+ "aria-labelledby": `${id}-title`,
74
+ "data-slot": "form-section",
75
+ className: cn(
76
+ "sa:grid sa:gap-5 sa:not-first:border-t sa:not-first:border-border-default sa:not-first:pt-6",
77
+ className
78
+ ),
79
+ ...props,
80
+ children: [
81
+ /* @__PURE__ */ jsxs("header", { className: "sa:grid sa:gap-1", children: [
82
+ /* @__PURE__ */ jsx("h3", { id: `${id}-title`, className: "sa:text-base sa:font-medium sa:text-text-default", children: title }),
83
+ description && /* @__PURE__ */ jsx(FieldDescription, { children: description })
84
+ ] }),
85
+ /* @__PURE__ */ jsx("div", { className: "sa:grid sa:gap-5", children })
86
+ ]
87
+ }
88
+ );
89
+ }
90
+ function FormActions({ align = "end", className, ...props }) {
91
+ const form = useFormContext();
92
+ return /* @__PURE__ */ jsx(
93
+ "div",
94
+ {
95
+ "data-slot": "form-actions",
96
+ className: cn(
97
+ "sa:flex sa:flex-wrap sa:items-center sa:gap-2",
98
+ align === "end" && "sa:justify-end",
99
+ align === "between" && "sa:justify-end sa:[&>:first-child]:mr-auto",
100
+ align === "start" && form?.layout === "horizontal" && "sa:pl-46",
101
+ className
102
+ ),
103
+ ...props
104
+ }
105
+ );
106
+ }
107
+
108
+ export { Form, FormActions, FormSection, formValues };
@@ -0,0 +1,168 @@
1
+ // src/theme/create-theme.ts
2
+ var defaultTheme = { brand: "#4633D7", radius: 1 };
3
+ var toLinear = (c) => c <= 0.04045 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4;
4
+ var toGamma = (c) => c <= 31308e-7 ? 12.92 * c : 1.055 * c ** (1 / 2.4) - 0.055;
5
+ function hexToRgb(hex) {
6
+ const h = hex.replace("#", "");
7
+ const full = h.length === 3 ? [...h].map((c) => c + c).join("") : h.slice(0, 6);
8
+ return [0, 2, 4].map((i) => parseInt(full.slice(i, i + 2), 16) / 255);
9
+ }
10
+ function rgbToOklch([r, g, b]) {
11
+ const [lr, lg, lb] = [r, g, b].map(toLinear);
12
+ const l = Math.cbrt(0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb);
13
+ const m = Math.cbrt(0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb);
14
+ const s = Math.cbrt(0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb);
15
+ const L = 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s;
16
+ const A = 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s;
17
+ const B = 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s;
18
+ return [L, Math.hypot(A, B), (Math.atan2(B, A) * 180 / Math.PI + 360) % 360];
19
+ }
20
+ function oklchToRgb([L, C, H]) {
21
+ const a = C * Math.cos(H * Math.PI / 180);
22
+ const b = C * Math.sin(H * Math.PI / 180);
23
+ const l = (L + 0.3963377774 * a + 0.2158037573 * b) ** 3;
24
+ const m = (L - 0.1055613458 * a - 0.0638541728 * b) ** 3;
25
+ const s = (L - 0.0894841775 * a - 1.291485548 * b) ** 3;
26
+ return [
27
+ 4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
28
+ -1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
29
+ -0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
30
+ ];
31
+ }
32
+ var inGamut = (rgb) => rgb.every((c) => c >= -5e-4 && c <= 1.0005);
33
+ function oklchToHex([L, C, H]) {
34
+ let c = C;
35
+ let rgb = oklchToRgb([L, c, H]);
36
+ while (!inGamut(rgb) && c > 0) {
37
+ c = Math.max(0, c - 5e-3);
38
+ rgb = oklchToRgb([L, c, H]);
39
+ }
40
+ return "#" + rgb.map((v) => Math.round(Math.min(1, Math.max(0, toGamma(v))) * 255).toString(16).padStart(2, "0")).join("").toUpperCase();
41
+ }
42
+ var luminance = (hex) => {
43
+ const [r, g, b] = hexToRgb(hex).map(toLinear);
44
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
45
+ };
46
+ var contrast = (a, b) => {
47
+ const [x, y] = [luminance(a), luminance(b)].sort((p, q) => q - p);
48
+ return (x + 0.05) / (y + 0.05);
49
+ };
50
+ var RAMP = {
51
+ "blue-50": "#F2F4FF",
52
+ "blue-200": "#CFD6FF",
53
+ "blue-300": "#B1BBFE",
54
+ "blue-500": "#5146E9",
55
+ "blue-600": "#4633D7",
56
+ "blue-700": "#3923B9",
57
+ "blue-900": "#1D1168",
58
+ "blue-950": "#110A47",
59
+ "blue-soft-50": "#F3F5FF",
60
+ "blue-soft-200": "#D9DEFB",
61
+ "blue-soft-300": "#BEC7FC",
62
+ "blue-soft-700": "#5158A0",
63
+ "blue-soft-900": "#30344F",
64
+ "blue-soft-950": "#1F2132",
65
+ "primary-dark": "#493DD6",
66
+ "primary-hover-dark": "#554FE7",
67
+ "primary-pressed-dark": "#3E2AC5",
68
+ "primary-border-light": "#9085E7",
69
+ "primary-border-dark": "#928BE6"
70
+ };
71
+ var SOLID = /* @__PURE__ */ new Set(["blue-500", "blue-600", "blue-700", "primary-dark", "primary-hover-dark", "primary-pressed-dark"]);
72
+ function solidLightness(c, h, base, hoverStep) {
73
+ const passes = (L) => contrast(oklchToHex([L, c, h]), "#FFFFFF") >= 4.7 && contrast(oklchToHex([L + hoverStep, c, h]), "#FFFFFF") >= 4.7;
74
+ if (passes(base)) return base;
75
+ let lo = 0.2;
76
+ let hi = base;
77
+ for (let i = 0; i < 20; i++) {
78
+ const mid = (lo + hi) / 2;
79
+ if (passes(mid)) lo = mid;
80
+ else hi = mid;
81
+ }
82
+ return lo;
83
+ }
84
+ function brandVars(brand) {
85
+ const [bl, bc, bh] = rgbToOklch(hexToRgb(brand));
86
+ const lch = (step) => rgbToOklch(hexToRgb(RAMP[step]));
87
+ const [rl, rc, rh] = lch("blue-600");
88
+ const chroma = bc / rc;
89
+ const light = solidLightness(bc, bh, bl, lch("blue-500")[0] - rl);
90
+ const darkRest = lch("primary-dark")[0];
91
+ const dark = solidLightness(bc, bh, light + (darkRest - rl), lch("primary-hover-dark")[0] - darkRest);
92
+ const root = {};
93
+ for (const [step, hex] of Object.entries(RAMP)) {
94
+ const [l, c, h] = rgbToOklch(hexToRgb(hex));
95
+ const isDark = step.endsWith("-dark") && step !== "primary-border-dark";
96
+ const L = SOLID.has(step) ? isDark ? dark + (l - darkRest) : light + (l - rl) : l;
97
+ root[`--color-${step}`] = step === "blue-600" && light === bl ? brand.toUpperCase() : oklchToHex([Math.min(0.97, Math.max(0.15, L)), c * chroma, bh + (h - rh)]);
98
+ }
99
+ root["--sa-color-blue-600-a20"] = `${root["--sa-color-blue-600"]}33`;
100
+ root["--sa-color-blue-500-a20"] = `${root["--sa-color-blue-500"]}33`;
101
+ root["--sa-color-primary-focus-dark"] = `${root["--sa-color-primary-dark"]}33`;
102
+ return root;
103
+ }
104
+ var RADII = { xs: 4, sm: 6, md: 8, xl: 12, "2xl": 16, "3xl": 20 };
105
+ function radiusVars(scale) {
106
+ const v = {};
107
+ for (const [k, px] of Object.entries(RADII)) v[`--radius-${k}`] = `${Math.round(px * scale * 2) / 2}px`;
108
+ v["--sa-radius"] = `${Math.round(10 * scale * 2) / 2}px`;
109
+ v["--sa-radius-pill"] = scale >= 1 ? "9999px" : `${Math.round(16 * scale)}px`;
110
+ return v;
111
+ }
112
+ var VAR_PREFIX = "sa-";
113
+ var prefixed = (text, prefix) => prefix ? text.replace(/--(?=color-|radius)/g, `--${prefix}`) : text;
114
+ var prefixVars = (vars, prefix) => Object.fromEntries(Object.entries(vars).map(([k, v]) => [prefixed(k, prefix), prefixed(v, prefix)]));
115
+ function themeVars(theme, options = {}) {
116
+ const prefix = options.prefix ?? VAR_PREFIX;
117
+ return { root: prefixVars({ ...brandVars(theme.brand), ...radiusVars(theme.radius) }, prefix), dark: {} };
118
+ }
119
+ var SCOPED_LIGHT = {
120
+ "--border-focus": "var(--sa-color-blue-600)",
121
+ "--action-primary-bg": "var(--sa-color-blue-600)",
122
+ "--action-primary-bg-hover": "var(--sa-color-blue-500)",
123
+ "--action-primary-bg-pressed": "var(--sa-color-blue-700)",
124
+ "--action-primary-border": "var(--sa-color-primary-border-light)",
125
+ "--action-focus-ring": "var(--sa-color-blue-600-a20)",
126
+ "--status-brand-bg": "var(--sa-color-blue-soft-50)",
127
+ "--status-brand-border": "var(--sa-color-blue-soft-200)",
128
+ "--status-brand-fg": "var(--sa-color-blue-soft-700)",
129
+ "--sa-radius-lg": "var(--sa-radius)"
130
+ };
131
+ var SCOPED_DARK = {
132
+ "--border-focus": "var(--sa-color-primary-hover-dark)",
133
+ "--action-primary-bg": "var(--sa-color-primary-dark)",
134
+ "--action-primary-bg-hover": "var(--sa-color-primary-hover-dark)",
135
+ "--action-primary-bg-pressed": "var(--sa-color-primary-pressed-dark)",
136
+ "--action-primary-border": "var(--sa-color-primary-border-dark)",
137
+ "--action-focus-ring": "var(--sa-color-primary-focus-dark)",
138
+ "--status-brand-bg": "var(--sa-color-blue-soft-950)",
139
+ "--status-brand-border": "var(--sa-color-blue-soft-900)",
140
+ "--status-brand-fg": "var(--sa-color-blue-soft-300)"
141
+ };
142
+ function themeCss(theme, scope, options = {}) {
143
+ const prefix = options.prefix ?? VAR_PREFIX;
144
+ const vars = themeVars(theme, { prefix });
145
+ const root = scope ? { ...vars.root, ...prefixVars(SCOPED_LIGHT, prefix) } : vars.root;
146
+ const dark = scope ? { ...vars.dark, ...prefixVars(SCOPED_DARK, prefix) } : vars.dark;
147
+ const block = (sel, vars2) => `${sel} {
148
+ ${Object.entries(vars2).map(([k, v]) => ` ${k}: ${v};`).join("\n")}
149
+ }`;
150
+ return [
151
+ `/* Satin theme: brand ${theme.brand.toUpperCase()}, radius ${theme.radius}. */`,
152
+ // :root:root outranks Satin's own :root, so the theme wins wherever the file is loaded.
153
+ block(scope ?? ":root:root", root),
154
+ ...Object.keys(dark).length ? [block(scope ? `.dark ${scope}` : ":root.dark", dark)] : [],
155
+ ""
156
+ ].join("\n\n");
157
+ }
158
+ function randomTheme(current) {
159
+ const [, , currentHue] = current ? rgbToOklch(hexToRgb(current.brand)) : [0, 0, -360];
160
+ const hue = (currentHue + 60 + Math.random() * 240) % 360;
161
+ const l = 0.5 + Math.random() * 0.25;
162
+ const brand = oklchToHex([l, 0.12 + Math.random() * 0.08, hue]);
163
+ const radii = [0, 0.5, 1, 1.5].filter((r) => r !== current?.radius);
164
+ const radius = radii[Math.floor(Math.random() * radii.length)];
165
+ return { brand, radius };
166
+ }
167
+
168
+ export { contrast, defaultTheme, randomTheme, themeCss, themeVars };
@@ -0,0 +1,81 @@
1
+ import * as React from 'react';
2
+ import { jsx } from 'react/jsx-runtime';
3
+
4
+ // src/components/labels.tsx
5
+ var defaultLabels = {
6
+ close: "Close",
7
+ dismiss: "Dismiss",
8
+ announcement: "Announcement",
9
+ increase: "Increase",
10
+ decrease: "Decrease",
11
+ previous: "Previous",
12
+ next: "Next",
13
+ previousSection: "Previous section",
14
+ nextSection: "Next section",
15
+ previousQuestion: "Previous question",
16
+ nextQuestion: "Next question",
17
+ previousMonth: "Previous month",
18
+ nextMonth: "Next month",
19
+ year: "Year",
20
+ month: "Month",
21
+ sheets: "Sheets",
22
+ hiddenPages: "Hidden pages",
23
+ period: "Period",
24
+ commandMenu: "Command menu",
25
+ searchCommands: "Search commands",
26
+ commands: "Commands",
27
+ draft: "Draft",
28
+ files: "Files",
29
+ attachedFiles: "Attached files",
30
+ goodResponse: "Good response",
31
+ badResponse: "Bad response",
32
+ copy: "Copy",
33
+ attachments: "Attachments",
34
+ addToConversation: "Add to conversation",
35
+ message: "Message",
36
+ send: "Send",
37
+ stop: "Stop",
38
+ searchAgentsAndTools: "Search agents and tools",
39
+ addAgent: "Add an agent",
40
+ agentsAndTools: "Agents and tools",
41
+ model: "Model",
42
+ agent: "Agent",
43
+ remove: "Remove",
44
+ add: "Add",
45
+ selectAllRows: "Select all rows",
46
+ selectRow: "Select row",
47
+ select: "Select\u2026",
48
+ search: "Search\u2026",
49
+ noResults: "No results",
50
+ clear: "Clear",
51
+ apply: "Apply",
52
+ cancel: "Cancel",
53
+ pickDate: "Pick a date",
54
+ pickDates: "Pick dates",
55
+ from: "From",
56
+ to: "To",
57
+ value: "Value",
58
+ selected: "selected",
59
+ commandPlaceholder: "Type a command or search\u2026",
60
+ navigate: "Navigate",
61
+ openItem: "Open",
62
+ source: "Source",
63
+ moreOptions: "More options",
64
+ loading: "Loading",
65
+ submit: "Submit",
66
+ done: "Done",
67
+ opensInNewTab: "(opens in a new tab)",
68
+ showPassword: "Show password",
69
+ hidePassword: "Hide password"
70
+ };
71
+ var LabelsContext = React.createContext(defaultLabels);
72
+ function SatinLabels({ labels, children }) {
73
+ const parent = React.useContext(LabelsContext);
74
+ const value = React.useMemo(() => ({ ...parent, ...labels }), [parent, labels]);
75
+ return /* @__PURE__ */ jsx(LabelsContext.Provider, { value, children });
76
+ }
77
+ function useSatinLabels() {
78
+ return React.useContext(LabelsContext);
79
+ }
80
+
81
+ export { SatinLabels, defaultLabels, useSatinLabels };