@tribepad/themis 1.0.0 → 1.0.1

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 (326) hide show
  1. package/dist/elements/Accordion/index.js +325 -66
  2. package/dist/elements/Accordion/index.js.map +1 -1
  3. package/dist/elements/Accordion/index.mjs +317 -3
  4. package/dist/elements/Accordion/index.mjs.map +1 -1
  5. package/dist/elements/Avatar/index.js +461 -45
  6. package/dist/elements/Avatar/index.js.map +1 -1
  7. package/dist/elements/Avatar/index.mjs +456 -3
  8. package/dist/elements/Avatar/index.mjs.map +1 -1
  9. package/dist/elements/Badge/index.js +238 -36
  10. package/dist/elements/Badge/index.js.map +1 -1
  11. package/dist/elements/Badge/index.mjs +234 -4
  12. package/dist/elements/Badge/index.mjs.map +1 -1
  13. package/dist/elements/Breadcrumbs/index.js +808 -39
  14. package/dist/elements/Breadcrumbs/index.js.map +1 -1
  15. package/dist/elements/Breadcrumbs/index.mjs +810 -7
  16. package/dist/elements/Breadcrumbs/index.mjs.map +1 -1
  17. package/dist/elements/Button/index.js +282 -19
  18. package/dist/elements/Button/index.js.map +1 -1
  19. package/dist/elements/Button/index.mjs +283 -4
  20. package/dist/elements/Button/index.mjs.map +1 -1
  21. package/dist/elements/ButtonGroup/index.js +229 -56
  22. package/dist/elements/ButtonGroup/index.js.map +1 -1
  23. package/dist/elements/ButtonGroup/index.mjs +222 -3
  24. package/dist/elements/ButtonGroup/index.mjs.map +1 -1
  25. package/dist/elements/Card/Card.d.ts.map +1 -1
  26. package/dist/elements/Card/index.js +563 -67
  27. package/dist/elements/Card/index.js.map +1 -1
  28. package/dist/elements/Card/index.mjs +560 -6
  29. package/dist/elements/Card/index.mjs.map +1 -1
  30. package/dist/elements/Carousel/index.js +782 -14
  31. package/dist/elements/Carousel/index.js.map +1 -1
  32. package/dist/elements/Carousel/index.mjs +786 -8
  33. package/dist/elements/Carousel/index.mjs.map +1 -1
  34. package/dist/elements/Chart/index.js +1833 -36
  35. package/dist/elements/Chart/index.js.map +1 -1
  36. package/dist/elements/Chart/index.mjs +1832 -4
  37. package/dist/elements/Chart/index.mjs.map +1 -1
  38. package/dist/elements/Checkbox/index.js +310 -39
  39. package/dist/elements/Checkbox/index.js.map +1 -1
  40. package/dist/elements/Checkbox/index.mjs +306 -4
  41. package/dist/elements/Checkbox/index.mjs.map +1 -1
  42. package/dist/elements/CheckboxGroup/index.js +445 -59
  43. package/dist/elements/CheckboxGroup/index.js.map +1 -1
  44. package/dist/elements/CheckboxGroup/index.mjs +439 -4
  45. package/dist/elements/CheckboxGroup/index.mjs.map +1 -1
  46. package/dist/elements/DatePicker/index.js +871 -89
  47. package/dist/elements/DatePicker/index.js.map +1 -1
  48. package/dist/elements/DatePicker/index.mjs +853 -4
  49. package/dist/elements/DatePicker/index.mjs.map +1 -1
  50. package/dist/elements/Dropdown/index.js +189 -35
  51. package/dist/elements/Dropdown/index.js.map +1 -1
  52. package/dist/elements/Dropdown/index.mjs +184 -2
  53. package/dist/elements/Dropdown/index.mjs.map +1 -1
  54. package/dist/elements/FileField/index.js +1532 -129
  55. package/dist/elements/FileField/index.js.map +1 -1
  56. package/dist/elements/FileField/index.mjs +1507 -7
  57. package/dist/elements/FileField/index.mjs.map +1 -1
  58. package/dist/elements/FormLayout/index.js +166 -11
  59. package/dist/elements/FormLayout/index.js.map +1 -1
  60. package/dist/elements/FormLayout/index.mjs +167 -2
  61. package/dist/elements/FormLayout/index.mjs.map +1 -1
  62. package/dist/elements/Modal/index.js +228 -46
  63. package/dist/elements/Modal/index.js.map +1 -1
  64. package/dist/elements/Modal/index.mjs +220 -1
  65. package/dist/elements/Modal/index.mjs.map +1 -1
  66. package/dist/elements/NumberField/index.js +659 -48
  67. package/dist/elements/NumberField/index.js.map +1 -1
  68. package/dist/elements/NumberField/index.mjs +654 -6
  69. package/dist/elements/NumberField/index.mjs.map +1 -1
  70. package/dist/elements/OTPInput/index.js +729 -6
  71. package/dist/elements/OTPInput/index.js.map +1 -1
  72. package/dist/elements/OTPInput/index.mjs +732 -2
  73. package/dist/elements/OTPInput/index.mjs.map +1 -1
  74. package/dist/elements/Panel/index.js +326 -27
  75. package/dist/elements/Panel/index.js.map +1 -1
  76. package/dist/elements/Panel/index.mjs +323 -2
  77. package/dist/elements/Panel/index.mjs.map +1 -1
  78. package/dist/elements/Progress/index.js +181 -22
  79. package/dist/elements/Progress/index.js.map +1 -1
  80. package/dist/elements/Progress/index.mjs +181 -3
  81. package/dist/elements/Progress/index.mjs.map +1 -1
  82. package/dist/elements/RadioGroup/index.js +358 -34
  83. package/dist/elements/RadioGroup/index.js.map +1 -1
  84. package/dist/elements/RadioGroup/index.mjs +359 -4
  85. package/dist/elements/RadioGroup/index.mjs.map +1 -1
  86. package/dist/elements/Resizable/components/ResizableHandle.d.ts +0 -8
  87. package/dist/elements/Resizable/components/ResizableHandle.d.ts.map +1 -1
  88. package/dist/elements/Resizable/components/ResizablePanel.d.ts +0 -8
  89. package/dist/elements/Resizable/components/ResizablePanel.d.ts.map +1 -1
  90. package/dist/elements/Resizable/components/ResizablePanelGroup.d.ts +0 -8
  91. package/dist/elements/Resizable/components/ResizablePanelGroup.d.ts.map +1 -1
  92. package/dist/elements/Resizable/components/ResizablePopover.d.ts +0 -8
  93. package/dist/elements/Resizable/components/ResizablePopover.d.ts.map +1 -1
  94. package/dist/elements/Resizable/index.js +1568 -51
  95. package/dist/elements/Resizable/index.js.map +1 -1
  96. package/dist/elements/Resizable/index.mjs +1566 -6
  97. package/dist/elements/Resizable/index.mjs.map +1 -1
  98. package/dist/elements/Select/index.js +580 -22
  99. package/dist/elements/Select/index.js.map +1 -1
  100. package/dist/elements/Select/index.mjs +582 -2
  101. package/dist/elements/Select/index.mjs.map +1 -1
  102. package/dist/elements/Skeleton/index.js +77 -15
  103. package/dist/elements/Skeleton/index.js.map +1 -1
  104. package/dist/elements/Skeleton/index.mjs +78 -3
  105. package/dist/elements/Skeleton/index.mjs.map +1 -1
  106. package/dist/elements/Switch/index.js +153 -21
  107. package/dist/elements/Switch/index.js.map +1 -1
  108. package/dist/elements/Switch/index.mjs +149 -5
  109. package/dist/elements/Switch/index.mjs.map +1 -1
  110. package/dist/elements/Table/index.js +589 -68
  111. package/dist/elements/Table/index.js.map +1 -1
  112. package/dist/elements/Table/index.mjs +578 -5
  113. package/dist/elements/Table/index.mjs.map +1 -1
  114. package/dist/elements/Tabs/index.js +328 -63
  115. package/dist/elements/Tabs/index.js.map +1 -1
  116. package/dist/elements/Tabs/index.mjs +320 -3
  117. package/dist/elements/Tabs/index.mjs.map +1 -1
  118. package/dist/elements/TextField/index.js +695 -51
  119. package/dist/elements/TextField/index.js.map +1 -1
  120. package/dist/elements/TextField/index.mjs +684 -7
  121. package/dist/elements/TextField/index.mjs.map +1 -1
  122. package/dist/elements/TimeField/index.js +244 -33
  123. package/dist/elements/TimeField/index.js.map +1 -1
  124. package/dist/elements/TimeField/index.mjs +238 -2
  125. package/dist/elements/TimeField/index.mjs.map +1 -1
  126. package/dist/elements/Toast/index.js +727 -48
  127. package/dist/elements/Toast/index.js.map +1 -1
  128. package/dist/elements/Toast/index.mjs +724 -5
  129. package/dist/elements/Toast/index.mjs.map +1 -1
  130. package/dist/elements/Tooltip/index.js +315 -49
  131. package/dist/elements/Tooltip/index.js.map +1 -1
  132. package/dist/elements/Tooltip/index.mjs +310 -4
  133. package/dist/elements/Tooltip/index.mjs.map +1 -1
  134. package/dist/elements/index.js +12417 -799
  135. package/dist/elements/index.js.map +1 -1
  136. package/dist/elements/index.mjs +12233 -40
  137. package/dist/elements/index.mjs.map +1 -1
  138. package/dist/index.js +12452 -825
  139. package/dist/index.js.map +1 -1
  140. package/dist/index.mjs +12262 -42
  141. package/dist/index.mjs.map +1 -1
  142. package/dist/schemas/index.js +47 -21
  143. package/dist/schemas/index.js.map +1 -1
  144. package/dist/schemas/index.mjs +47 -2
  145. package/dist/schemas/index.mjs.map +1 -1
  146. package/dist/styles/index.js +161 -147
  147. package/dist/styles/index.js.map +1 -1
  148. package/dist/styles/index.mjs +128 -2
  149. package/dist/styles/index.mjs.map +1 -1
  150. package/dist/utils/index.js +7 -7
  151. package/dist/utils/index.js.map +1 -1
  152. package/dist/utils/index.mjs +9 -2
  153. package/dist/utils/index.mjs.map +1 -1
  154. package/package.json +1 -1
  155. package/dist/Carousel-NTZX5TOW.js +0 -16
  156. package/dist/Carousel-NTZX5TOW.js.map +0 -1
  157. package/dist/Carousel-YH3DOQJU.mjs +0 -7
  158. package/dist/Carousel-YH3DOQJU.mjs.map +0 -1
  159. package/dist/chunk-2HIUTHMU.mjs +0 -234
  160. package/dist/chunk-2HIUTHMU.mjs.map +0 -1
  161. package/dist/chunk-34GTFTDO.js +0 -431
  162. package/dist/chunk-34GTFTDO.js.map +0 -1
  163. package/dist/chunk-3H7ASYR7.js +0 -250
  164. package/dist/chunk-3H7ASYR7.js.map +0 -1
  165. package/dist/chunk-3IEN7JOP.js +0 -316
  166. package/dist/chunk-3IEN7JOP.js.map +0 -1
  167. package/dist/chunk-3JHN4GAL.js +0 -326
  168. package/dist/chunk-3JHN4GAL.js.map +0 -1
  169. package/dist/chunk-3MJPASQU.js +0 -232
  170. package/dist/chunk-3MJPASQU.js.map +0 -1
  171. package/dist/chunk-3XD2JUL3.js +0 -572
  172. package/dist/chunk-3XD2JUL3.js.map +0 -1
  173. package/dist/chunk-3YOY2VJ6.js +0 -189
  174. package/dist/chunk-3YOY2VJ6.js.map +0 -1
  175. package/dist/chunk-4DU5JSXB.js +0 -408
  176. package/dist/chunk-4DU5JSXB.js.map +0 -1
  177. package/dist/chunk-4E4E2GSS.js +0 -352
  178. package/dist/chunk-4E4E2GSS.js.map +0 -1
  179. package/dist/chunk-4NHAP4AN.mjs +0 -3
  180. package/dist/chunk-4NHAP4AN.mjs.map +0 -1
  181. package/dist/chunk-4S33J5NY.mjs +0 -415
  182. package/dist/chunk-4S33J5NY.mjs.map +0 -1
  183. package/dist/chunk-5SMGRT3G.mjs +0 -354
  184. package/dist/chunk-5SMGRT3G.mjs.map +0 -1
  185. package/dist/chunk-5SVLJN2C.mjs +0 -22
  186. package/dist/chunk-5SVLJN2C.mjs.map +0 -1
  187. package/dist/chunk-66WTU4EB.mjs +0 -299
  188. package/dist/chunk-66WTU4EB.mjs.map +0 -1
  189. package/dist/chunk-6S25NMOT.mjs +0 -335
  190. package/dist/chunk-6S25NMOT.mjs.map +0 -1
  191. package/dist/chunk-6SP7UB3D.js +0 -4
  192. package/dist/chunk-6SP7UB3D.js.map +0 -1
  193. package/dist/chunk-6TYWWQHM.mjs +0 -565
  194. package/dist/chunk-6TYWWQHM.mjs.map +0 -1
  195. package/dist/chunk-A3YUJA6W.mjs +0 -384
  196. package/dist/chunk-A3YUJA6W.mjs.map +0 -1
  197. package/dist/chunk-A6KEDVUR.js +0 -61
  198. package/dist/chunk-A6KEDVUR.js.map +0 -1
  199. package/dist/chunk-A77RUEWL.js +0 -730
  200. package/dist/chunk-A77RUEWL.js.map +0 -1
  201. package/dist/chunk-AA4IKMPE.mjs +0 -3
  202. package/dist/chunk-AA4IKMPE.mjs.map +0 -1
  203. package/dist/chunk-AKIA6GW6.mjs +0 -163
  204. package/dist/chunk-AKIA6GW6.mjs.map +0 -1
  205. package/dist/chunk-AL6P275L.mjs +0 -435
  206. package/dist/chunk-AL6P275L.mjs.map +0 -1
  207. package/dist/chunk-AZ3RJYTB.js +0 -37
  208. package/dist/chunk-AZ3RJYTB.js.map +0 -1
  209. package/dist/chunk-B5Q4UPL6.js +0 -32
  210. package/dist/chunk-B5Q4UPL6.js.map +0 -1
  211. package/dist/chunk-B6DHPMDP.mjs +0 -335
  212. package/dist/chunk-B6DHPMDP.mjs.map +0 -1
  213. package/dist/chunk-BDXKKMBZ.mjs +0 -184
  214. package/dist/chunk-BDXKKMBZ.mjs.map +0 -1
  215. package/dist/chunk-BL6E2DLZ.mjs +0 -52
  216. package/dist/chunk-BL6E2DLZ.mjs.map +0 -1
  217. package/dist/chunk-CGFDS4XS.mjs +0 -121
  218. package/dist/chunk-CGFDS4XS.mjs.map +0 -1
  219. package/dist/chunk-CJIW5TKI.js +0 -139
  220. package/dist/chunk-CJIW5TKI.js.map +0 -1
  221. package/dist/chunk-CKNISJOQ.js +0 -314
  222. package/dist/chunk-CKNISJOQ.js.map +0 -1
  223. package/dist/chunk-D6CBOECS.mjs +0 -1757
  224. package/dist/chunk-D6CBOECS.mjs.map +0 -1
  225. package/dist/chunk-DDWEVC2S.js +0 -166
  226. package/dist/chunk-DDWEVC2S.js.map +0 -1
  227. package/dist/chunk-DZ556D2F.mjs +0 -176
  228. package/dist/chunk-DZ556D2F.mjs.map +0 -1
  229. package/dist/chunk-E2KQFV3O.mjs +0 -10
  230. package/dist/chunk-E2KQFV3O.mjs.map +0 -1
  231. package/dist/chunk-EMMLADSC.js +0 -126
  232. package/dist/chunk-EMMLADSC.js.map +0 -1
  233. package/dist/chunk-EP4WOI5D.mjs +0 -926
  234. package/dist/chunk-EP4WOI5D.mjs.map +0 -1
  235. package/dist/chunk-FJRXLJC2.mjs +0 -160
  236. package/dist/chunk-FJRXLJC2.mjs.map +0 -1
  237. package/dist/chunk-FKQI434R.js +0 -345
  238. package/dist/chunk-FKQI434R.js.map +0 -1
  239. package/dist/chunk-FPKEAJRZ.mjs +0 -100
  240. package/dist/chunk-FPKEAJRZ.mjs.map +0 -1
  241. package/dist/chunk-FWQYB22U.js +0 -183
  242. package/dist/chunk-FWQYB22U.js.map +0 -1
  243. package/dist/chunk-GD5GHTMA.js +0 -189
  244. package/dist/chunk-GD5GHTMA.js.map +0 -1
  245. package/dist/chunk-GE5XTSDZ.js +0 -447
  246. package/dist/chunk-GE5XTSDZ.js.map +0 -1
  247. package/dist/chunk-GVE47ZAX.mjs +0 -32
  248. package/dist/chunk-GVE47ZAX.mjs.map +0 -1
  249. package/dist/chunk-HK46BT5U.mjs +0 -18
  250. package/dist/chunk-HK46BT5U.mjs.map +0 -1
  251. package/dist/chunk-HQVRMR6N.js +0 -365
  252. package/dist/chunk-HQVRMR6N.js.map +0 -1
  253. package/dist/chunk-HSGBJPJO.mjs +0 -398
  254. package/dist/chunk-HSGBJPJO.mjs.map +0 -1
  255. package/dist/chunk-I3AUTOMZ.mjs +0 -125
  256. package/dist/chunk-I3AUTOMZ.mjs.map +0 -1
  257. package/dist/chunk-IEI5LD5C.mjs +0 -1161
  258. package/dist/chunk-IEI5LD5C.mjs.map +0 -1
  259. package/dist/chunk-IIPTC2X7.mjs +0 -118
  260. package/dist/chunk-IIPTC2X7.mjs.map +0 -1
  261. package/dist/chunk-J7TLHF2Q.js +0 -4
  262. package/dist/chunk-J7TLHF2Q.js.map +0 -1
  263. package/dist/chunk-JJOWXFXQ.mjs +0 -765
  264. package/dist/chunk-JJOWXFXQ.mjs.map +0 -1
  265. package/dist/chunk-JPTSS2OA.mjs +0 -3
  266. package/dist/chunk-JPTSS2OA.mjs.map +0 -1
  267. package/dist/chunk-KFXXRLTP.js +0 -396
  268. package/dist/chunk-KFXXRLTP.js.map +0 -1
  269. package/dist/chunk-KPRRBSG6.mjs +0 -272
  270. package/dist/chunk-KPRRBSG6.mjs.map +0 -1
  271. package/dist/chunk-NFSBGRDB.mjs +0 -57
  272. package/dist/chunk-NFSBGRDB.mjs.map +0 -1
  273. package/dist/chunk-NGJVCFTM.js +0 -219
  274. package/dist/chunk-NGJVCFTM.js.map +0 -1
  275. package/dist/chunk-NSQ6MZJ6.mjs +0 -728
  276. package/dist/chunk-NSQ6MZJ6.mjs.map +0 -1
  277. package/dist/chunk-NYQYHT76.mjs +0 -296
  278. package/dist/chunk-NYQYHT76.mjs.map +0 -1
  279. package/dist/chunk-OLJJGI5B.js +0 -1193
  280. package/dist/chunk-OLJJGI5B.js.map +0 -1
  281. package/dist/chunk-Q3572X2J.js +0 -292
  282. package/dist/chunk-Q3572X2J.js.map +0 -1
  283. package/dist/chunk-QH7N7D4I.mjs +0 -210
  284. package/dist/chunk-QH7N7D4I.mjs.map +0 -1
  285. package/dist/chunk-R7XUIV25.js +0 -466
  286. package/dist/chunk-R7XUIV25.js.map +0 -1
  287. package/dist/chunk-RFFO4KPM.js +0 -135
  288. package/dist/chunk-RFFO4KPM.js.map +0 -1
  289. package/dist/chunk-RFX7QKA7.mjs +0 -180
  290. package/dist/chunk-RFX7QKA7.mjs.map +0 -1
  291. package/dist/chunk-SN5LFAP3.js +0 -940
  292. package/dist/chunk-SN5LFAP3.js.map +0 -1
  293. package/dist/chunk-T4COXKQ3.js +0 -24
  294. package/dist/chunk-T4COXKQ3.js.map +0 -1
  295. package/dist/chunk-TS54QM27.js +0 -125
  296. package/dist/chunk-TS54QM27.js.map +0 -1
  297. package/dist/chunk-UE2S4PCX.mjs +0 -220
  298. package/dist/chunk-UE2S4PCX.mjs.map +0 -1
  299. package/dist/chunk-UTW3QX2A.mjs +0 -282
  300. package/dist/chunk-UTW3QX2A.mjs.map +0 -1
  301. package/dist/chunk-V74LGMAE.js +0 -1767
  302. package/dist/chunk-V74LGMAE.js.map +0 -1
  303. package/dist/chunk-VIREG536.js +0 -12
  304. package/dist/chunk-VIREG536.js.map +0 -1
  305. package/dist/chunk-VY7M7346.js +0 -4
  306. package/dist/chunk-VY7M7346.js.map +0 -1
  307. package/dist/chunk-W3TJOO7H.mjs +0 -319
  308. package/dist/chunk-W3TJOO7H.mjs.map +0 -1
  309. package/dist/chunk-WIUOB36M.js +0 -54
  310. package/dist/chunk-WIUOB36M.js.map +0 -1
  311. package/dist/chunk-WJGLM4CY.js +0 -291
  312. package/dist/chunk-WJGLM4CY.js.map +0 -1
  313. package/dist/chunk-WNURH5OO.mjs +0 -453
  314. package/dist/chunk-WNURH5OO.mjs.map +0 -1
  315. package/dist/chunk-X25TNRSD.mjs +0 -364
  316. package/dist/chunk-X25TNRSD.mjs.map +0 -1
  317. package/dist/chunk-Y3GT7ETK.js +0 -108
  318. package/dist/chunk-Y3GT7ETK.js.map +0 -1
  319. package/dist/chunk-Z4FRNOF6.mjs +0 -115
  320. package/dist/chunk-Z4FRNOF6.mjs.map +0 -1
  321. package/dist/chunk-ZMYLD3BN.js +0 -166
  322. package/dist/chunk-ZMYLD3BN.js.map +0 -1
  323. package/dist/chunk-ZP2KV6EX.js +0 -815
  324. package/dist/chunk-ZP2KV6EX.js.map +0 -1
  325. package/dist/chunk-ZVKXFELU.js +0 -366
  326. package/dist/chunk-ZVKXFELU.js.map +0 -1
@@ -1,6 +1,285 @@
1
- export { Button, buttonOuterVariants, buttonVariants, buttonVisualVariants } from '../../chunk-BDXKKMBZ.mjs';
2
- import '../../chunk-FPKEAJRZ.mjs';
3
- import '../../chunk-HK46BT5U.mjs';
4
- import '../../chunk-E2KQFV3O.mjs';
1
+ "use client";
2
+ import { createContext, memo, forwardRef, useId, useContext } from 'react';
3
+ import { Button as Button$1 } from 'react-aria-components';
4
+ import { cva } from 'class-variance-authority';
5
+ import { Loader2, Zap } from 'lucide-react';
6
+ import { clsx } from 'clsx';
7
+ import { twMerge } from 'tailwind-merge';
8
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
+
10
+ // src/elements/Button/Button.tsx
11
+ function cn(...inputs) {
12
+ return twMerge(clsx(inputs));
13
+ }
14
+ var PRESSED_STYLES = "data-[pressed]:scale-[0.97]";
15
+ var HOVER_STYLES = "data-[hovered]:shadow-md";
16
+ var HIGH_CONTRAST_HOVER = "hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground";
17
+ var HIGH_CONTRAST_PRESSED = "hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground";
18
+ var ButtonGroupContext = createContext(null);
19
+ ButtonGroupContext.displayName = "ButtonGroupContext";
20
+ function useButtonGroupContext() {
21
+ return useContext(ButtonGroupContext);
22
+ }
23
+ var ButtonGroupItemContext = createContext(null);
24
+ ButtonGroupItemContext.displayName = "ButtonGroupItemContext";
25
+ function useButtonGroupItemContext() {
26
+ return useContext(ButtonGroupItemContext);
27
+ }
28
+ cva("inline-flex items-center gap-0", {
29
+ variants: {
30
+ orientation: {
31
+ horizontal: "flex-row",
32
+ vertical: "flex-col w-full"
33
+ }
34
+ },
35
+ defaultVariants: {
36
+ orientation: "horizontal"
37
+ }
38
+ });
39
+ var buttonGroupItemVariants = cva("", {
40
+ variants: {
41
+ orientation: {
42
+ // min-w-[44px] ensures visual layer fills touch target width (for icon buttons)
43
+ horizontal: "min-w-[44px]",
44
+ // flex (overrides inline-flex) + min-h-[44px] makes visual layer fill touch target,
45
+ // eliminating gaps between stacked buttons in vertical orientation
46
+ vertical: "flex min-h-[44px]"
47
+ },
48
+ position: {
49
+ first: "",
50
+ middle: "",
51
+ last: "",
52
+ only: ""
53
+ // Single button - no modifications needed
54
+ }
55
+ },
56
+ compoundVariants: [
57
+ // ==========================================================================
58
+ // Horizontal Orientation
59
+ // ==========================================================================
60
+ {
61
+ orientation: "horizontal",
62
+ position: "first",
63
+ className: "rounded-r-none border-r-0"
64
+ },
65
+ {
66
+ orientation: "horizontal",
67
+ position: "middle",
68
+ className: "rounded-none border-r-0"
69
+ },
70
+ {
71
+ orientation: "horizontal",
72
+ position: "last",
73
+ className: "rounded-l-none"
74
+ },
75
+ // ==========================================================================
76
+ // Vertical Orientation
77
+ // Note: w-full is handled by Button's effectiveFullWidth for both layers
78
+ // ==========================================================================
79
+ {
80
+ orientation: "vertical",
81
+ position: "first",
82
+ className: "rounded-b-none border-b-0"
83
+ },
84
+ {
85
+ orientation: "vertical",
86
+ position: "middle",
87
+ className: "rounded-none border-b-0"
88
+ },
89
+ {
90
+ orientation: "vertical",
91
+ position: "last",
92
+ className: "rounded-t-none"
93
+ }
94
+ ],
95
+ defaultVariants: {
96
+ orientation: "horizontal",
97
+ position: "only"
98
+ }
99
+ });
100
+ cva("bg-[var(--border)]", {
101
+ variants: {
102
+ orientation: {
103
+ horizontal: "w-px h-6 mx-1",
104
+ vertical: "h-px w-full my-1"
105
+ }
106
+ },
107
+ defaultVariants: {
108
+ orientation: "horizontal"
109
+ }
110
+ });
111
+ var buttonOuterVariants = cva(
112
+ "inline-flex justify-center min-h-[44px] min-w-[44px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50",
113
+ {
114
+ variants: {
115
+ fullWidth: {
116
+ true: "w-full",
117
+ false: ""
118
+ },
119
+ inVerticalGroup: {
120
+ true: "items-stretch",
121
+ false: "items-center"
122
+ }
123
+ },
124
+ defaultVariants: {
125
+ fullWidth: false,
126
+ inVerticalGroup: false
127
+ }
128
+ }
129
+ );
130
+ var buttonVisualVariants = cva(
131
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 relative cursor-pointer",
132
+ {
133
+ variants: {
134
+ variant: {
135
+ default: "bg-[var(--primary-action)] text-[var(--primary-action-foreground)] shadow-md hover:bg-[var(--primary-action-hover)] data-[pressed]:bg-[var(--primary-action)]/80",
136
+ destructive: "bg-[var(--destructive-background)] text-[var(--destructive-foreground)] shadow-md hover:bg-[var(--destructive-background)]/90 data-[pressed]:bg-[var(--destructive-background)]/80",
137
+ outline: "border border-[var(--input-border)] bg-[var(--page-background)] hover:bg-[var(--input-border)] data-[pressed]:bg-[var(--input-border)]",
138
+ secondary: "bg-[var(--secondary)] text-[var(--secondary-foreground)] shadow-md hover:bg-[var(--secondary)]/80 data-[pressed]:bg-[var(--secondary)]/70",
139
+ ghost: "hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)] data-[pressed]:bg-[var(--accent)]",
140
+ link: "text-[var(--text-link)] underline-offset-4 hover:underline data-[pressed]:text-[var(--text-link-hover)]"
141
+ },
142
+ fullWidth: {
143
+ true: "w-full",
144
+ false: ""
145
+ },
146
+ visualSize: {
147
+ default: "h-10 px-4 py-2",
148
+ sm: "h-9 rounded-md px-3 text-xs",
149
+ lg: "h-11 rounded-md px-8",
150
+ icon: "h-10 w-10",
151
+ dot: "h-5 w-5 rounded-full p-0 min-h-0 min-w-0"
152
+ },
153
+ paywall: {
154
+ true: "!bg-[var(--paywall)] !text-[var(--paywall-foreground)] !shadow-md hover:!bg-[var(--paywall)]/90 !cursor-not-allowed !border-transparent",
155
+ false: ""
156
+ }
157
+ },
158
+ defaultVariants: {
159
+ variant: "default",
160
+ visualSize: "default",
161
+ paywall: false
162
+ }
163
+ }
164
+ );
165
+ var buttonVariants = buttonVisualVariants;
166
+ var Button = memo(forwardRef(
167
+ ({
168
+ className,
169
+ buttonVisualClassName,
170
+ variant,
171
+ size,
172
+ visualSize,
173
+ fullWidth,
174
+ loading = false,
175
+ loadingText = "Loading...",
176
+ shortcut,
177
+ children,
178
+ isDisabled,
179
+ paywall = false,
180
+ paywallRedirect,
181
+ paywallDescription,
182
+ onPress,
183
+ ...props
184
+ }, ref) => {
185
+ const paywallDescriptionId = useId();
186
+ const groupContext = useButtonGroupContext();
187
+ const itemContext = useButtonGroupItemContext();
188
+ const effectiveVariant = variant ?? groupContext?.variant ?? "default";
189
+ const effectiveSize = size ?? groupContext?.size;
190
+ const effectiveIsDisabled = isDisabled ?? groupContext?.isDisabled ?? false;
191
+ const isInVerticalGroup = groupContext?.orientation === "vertical";
192
+ const effectiveFullWidth = fullWidth || isInVerticalGroup;
193
+ const positionClassName = itemContext ? buttonGroupItemVariants({
194
+ orientation: groupContext?.orientation ?? "horizontal",
195
+ position: itemContext.position
196
+ }) : "";
197
+ const effectiveVisualSize = visualSize ?? effectiveSize ?? "default";
198
+ if (process.env.NODE_ENV !== "production") {
199
+ if ((effectiveVisualSize === "dot" || effectiveVisualSize === "icon") && !props["aria-label"] && !children) {
200
+ console.warn(
201
+ '[Button] visualSize="dot" or "icon" requires aria-label when no visible text is provided (WCAG 1.1.1)'
202
+ );
203
+ }
204
+ }
205
+ const handlePress = (e) => {
206
+ if (paywall) {
207
+ if (paywallRedirect) {
208
+ window.open(paywallRedirect, "_blank", "noopener,noreferrer");
209
+ }
210
+ return;
211
+ }
212
+ onPress?.(e);
213
+ };
214
+ const computedIsDisabled = effectiveIsDisabled || loading || void 0;
215
+ return /* @__PURE__ */ jsx(
216
+ Button$1,
217
+ {
218
+ ref,
219
+ isDisabled: computedIsDisabled,
220
+ "aria-disabled": paywall ? true : void 0,
221
+ "aria-describedby": paywall ? paywallDescriptionId : void 0,
222
+ onPress: handlePress,
223
+ className: cn(buttonOuterVariants({ fullWidth: effectiveFullWidth, inVerticalGroup: isInVerticalGroup }), className),
224
+ ...props,
225
+ children: (renderProps) => (
226
+ /* Layer 2: Visual Button */
227
+ /* @__PURE__ */ jsxs(
228
+ "span",
229
+ {
230
+ className: cn(
231
+ buttonVisualVariants({
232
+ variant: effectiveVariant,
233
+ visualSize: effectiveVisualSize,
234
+ paywall,
235
+ fullWidth: effectiveFullWidth
236
+ }),
237
+ // Position styling from ButtonGroup context (border-radius adjustments)
238
+ positionClassName,
239
+ buttonVisualClassName,
240
+ // Layer 2 interaction styles (no focus - focus ring is on Layer 1)
241
+ PRESSED_STYLES,
242
+ HOVER_STYLES,
243
+ HIGH_CONTRAST_HOVER,
244
+ HIGH_CONTRAST_PRESSED
245
+ ),
246
+ "data-pressed": renderProps.isPressed || void 0,
247
+ children: [
248
+ loading && /* @__PURE__ */ jsxs(Fragment, { children: [
249
+ /* @__PURE__ */ jsx(Loader2, { className: "motion-safe:animate-spin", "aria-hidden": "true" }),
250
+ /* @__PURE__ */ jsx("span", { className: "sr-only", "aria-live": "polite", children: loadingText })
251
+ ] }),
252
+ !loading && children,
253
+ paywall && /* @__PURE__ */ jsx(
254
+ Zap,
255
+ {
256
+ "data-testid": "zap-icon",
257
+ "aria-hidden": "true",
258
+ className: "ml-1"
259
+ }
260
+ ),
261
+ paywall && /* @__PURE__ */ jsxs("span", { id: paywallDescriptionId, className: "sr-only", children: [
262
+ "Premium feature: ",
263
+ paywallDescription || "Upgrade required to access this feature"
264
+ ] }),
265
+ renderProps.isFocusVisible && shortcut && /* @__PURE__ */ jsx("kbd", { className: "ml-auto hidden text-xs opacity-60 lg:inline", children: shortcut }),
266
+ renderProps.isPressed && /* @__PURE__ */ jsx(
267
+ "span",
268
+ {
269
+ className: "absolute inset-0 rounded-[inherit] bg-current opacity-10 motion-safe:animate-in motion-safe:zoom-in-95",
270
+ "aria-hidden": "true"
271
+ }
272
+ )
273
+ ]
274
+ }
275
+ )
276
+ )
277
+ }
278
+ );
279
+ }
280
+ ));
281
+ Button.displayName = "Button";
282
+
283
+ export { Button, buttonOuterVariants, buttonVariants, buttonVisualVariants };
5
284
  //# sourceMappingURL=index.mjs.map
6
285
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"index.mjs"}
1
+ {"version":3,"sources":["../../../src/utils/cn.ts","../../../src/styles/interaction-states.ts","../../../src/elements/ButtonGroup/ButtonGroupContext.tsx","../../../src/elements/ButtonGroup/ButtonGroup.variants.ts","../../../src/elements/Button/Button.tsx"],"names":["cva","AriaButton"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Class Name Utility\n * Merges Tailwind CSS classes with conflict resolution\n *\n * Combines clsx for conditional classes and tailwind-merge for deduplication\n *\n * @example\n * cn('px-2 py-1', 'px-4') // => 'py-1 px-4' (px-4 overrides px-2)\n * cn('text-red-500', condition && 'text-blue-500') // => conditional application\n */\n\nimport { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n","/**\n * Global Interaction State Styles\n *\n * Consistent interaction patterns across all Themis components.\n * These styles ensure WCAG 2.2 AAA compliance and predictable UX.\n *\n * @see spec.md FR-010 (Visible focus ring for keyboard navigation)\n * @see spec.md FR-031 (Pressed state feedback)\n * @see spec.md FR-012 (High contrast mode support)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\n/**\n * Focus state styles (FR-010)\n * Visible focus ring for keyboard navigation - WCAG 2.2 Level AAA\n *\n * Components can override by extending these styles:\n * @example\n * cn(FOCUS_STYLES, \"ring-4\") // Increases ring width to 4px\n */\nexport const FOCUS_STYLES = \"data-[focus-visible]:ring-2 data-[focus-visible]:ring-[var(--themis-ring)] data-[focus-visible]:ring-offset-2\";\n\n/**\n * Pressed/Active state styles (FR-031)\n * Visual feedback for press interactions\n *\n * Components can override the scale amount:\n * @example\n * cn(PRESSED_STYLES_BASE, \"data-[pressed]:scale-[0.95]\") // More pronounced scale\n */\nexport const PRESSED_STYLES = \"data-[pressed]:scale-[0.97]\";\n\n/**\n * Base pressed styles without scale (for components that need different feedback)\n */\nexport const PRESSED_STYLES_BASE = \"data-[pressed]:transition-transform data-[pressed]:duration-100\";\n\n/**\n * Hover state styles\n * Elevation change on hover for better affordance\n *\n * Components can override shadow depth:\n * @example\n * cn(HOVER_STYLES_BASE, \"data-[hovered]:shadow-lg\") // Larger shadow\n */\nexport const HOVER_STYLES = \"data-[hovered]:shadow-md\";\n\n/**\n * Base hover styles without shadow (for components that use different hover effects)\n */\nexport const HOVER_STYLES_BASE = \"data-[hovered]:transition-shadow data-[hovered]:duration-200\";\n\n/**\n * High contrast mode focus (FR-012)\n * Enhanced outlines for users requiring high contrast\n *\n * Uses 'hc:' prefix for prefers-contrast: more media query\n */\nexport const HIGH_CONTRAST_FOCUS = \"hc:data-[focus-visible]:outline hc:data-[focus-visible]:outline-4 hc:data-[focus-visible]:outline-offset-2 hc:data-[focus-visible]:outline-foreground\";\n\n/**\n * High contrast mode hover (FR-012)\n * Enhanced outlines for hover in high contrast mode\n */\nexport const HIGH_CONTRAST_HOVER = \"hc:data-[hovered]:outline hc:data-[hovered]:outline-2 hc:data-[hovered]:outline-foreground\";\n\n/**\n * High contrast mode pressed state\n * Enhanced outlines for pressed state in high contrast mode\n */\nexport const HIGH_CONTRAST_PRESSED = \"hc:data-[pressed]:outline hc:data-[pressed]:outline-2 hc:data-[pressed]:outline-offset-1 hc:data-[pressed]:outline-foreground\";\n\n/**\n * Combined high contrast styles\n * Use this for components that need all high contrast interaction states\n */\nexport const HIGH_CONTRAST_INTERACTIONS = `${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Disabled state styles\n * Consistent disabled appearance across all components\n */\nexport const DISABLED_STYLES = \"disabled:pointer-events-none disabled:opacity-50\";\n\n/**\n * Default interaction bundle\n * Most common combination for interactive components\n *\n * Includes: focus ring, pressed scale, hover shadow, high contrast enhancements\n *\n * @example\n * <button className={cn(DEFAULT_INTERACTIONS, \"bg-primary\")}>Click</button>\n */\nexport const DEFAULT_INTERACTIONS = `${FOCUS_STYLES} ${PRESSED_STYLES} ${HOVER_STYLES} ${HIGH_CONTRAST_FOCUS} ${HIGH_CONTRAST_HOVER} ${HIGH_CONTRAST_PRESSED}`;\n\n/**\n * Subtle interaction bundle\n * For components that need less pronounced feedback\n *\n * Includes: focus ring and high contrast, but no hover shadow or pressed scale\n */\nexport const SUBTLE_INTERACTIONS = `${FOCUS_STYLES} ${HIGH_CONTRAST_FOCUS}`;\n\n/**\n * Non-interactive element styles\n * For elements that should indicate they are not interactive\n */\nexport const NON_INTERACTIVE = \"cursor-default select-none\";\n","\"use client\";\n\nimport { createContext, useContext } from 'react';\nimport type {\n ButtonGroupContextValue,\n ButtonGroupItemContextValue,\n} from './ButtonGroup.types';\n\n/**\n * ButtonGroup Context System (Two-Level)\n *\n * Provides a two-level context pattern for ButtonGroup:\n *\n * 1. ButtonGroupContext (group-level):\n * - Provides: orientation, variant, size, isDisabled\n * - Consumed by: Button (for prop inheritance), Separator (for orientation)\n *\n * 2. ButtonGroupItemContext (item-level):\n * - Provides: position ('first' | 'middle' | 'last' | 'only')\n * - Consumed by: Button (for border-radius styling)\n *\n * Both contexts return null when not in a provider, allowing Button\n * to work standalone without any group context.\n *\n * @see plan.md for architecture details\n * @see ButtonGroup.tsx for Provider implementation\n */\n\n// =============================================================================\n// Group-Level Context\n// =============================================================================\n\n/**\n * Context for group-level props (orientation, variant, size, isDisabled)\n * Default value is null to indicate \"not in a group\"\n */\nconst ButtonGroupContext = createContext<ButtonGroupContextValue | null>(null);\n\nButtonGroupContext.displayName = 'ButtonGroupContext';\n\n/**\n * Hook to access group-level context\n * @returns ButtonGroupContextValue if inside a ButtonGroup, null otherwise\n */\nexport function useButtonGroupContext(): ButtonGroupContextValue | null {\n return useContext(ButtonGroupContext);\n}\n\n// =============================================================================\n// Item-Level Context\n// =============================================================================\n\n/**\n * Context for per-button position information\n * Default value is null to indicate \"not wrapped with position context\"\n */\nconst ButtonGroupItemContext =\n createContext<ButtonGroupItemContextValue | null>(null);\n\nButtonGroupItemContext.displayName = 'ButtonGroupItemContext';\n\n/**\n * Hook to access item-level context (position)\n * @returns ButtonGroupItemContextValue if wrapped with position context, null otherwise\n */\nexport function useButtonGroupItemContext(): ButtonGroupItemContextValue | null {\n return useContext(ButtonGroupItemContext);\n}\n\n// =============================================================================\n// Exports\n// =============================================================================\n\nexport { ButtonGroupContext, ButtonGroupItemContext };\n","import { cva } from 'class-variance-authority';\n\n/**\n * ButtonGroup CVA Variants\n *\n * Defines Class Variance Authority (CVA) variants for:\n * - ButtonGroup container (orientation-based layout)\n * - ButtonGroupItem (position-based border-radius)\n * - ButtonGroupSeparator (orientation-based styling)\n *\n * @see plan.md Phase 1: Design & Contracts - CVA Variants\n * @see constitution.md Principle V (Component Quality Standards)\n */\n\n// =============================================================================\n// Container Variants\n// =============================================================================\n\n/**\n * ButtonGroup container variants\n * Controls the layout direction based on orientation\n * Uses gap-0 to ensure buttons are connected (share borders)\n */\nexport const buttonGroupVariants = cva('inline-flex items-center gap-0', {\n variants: {\n orientation: {\n horizontal: 'flex-row',\n vertical: 'flex-col w-full',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n});\n\n// =============================================================================\n// Item Position Variants\n// =============================================================================\n\n/**\n * ButtonGroupItem position variants\n * Applied to Button's visual layer (Layer 2) for position-aware border-radius\n *\n * Compound variants handle both orientation and position combinations:\n * - Horizontal: left/right borders and radii\n * - Vertical: top/bottom borders and radii\n */\nexport const buttonGroupItemVariants = cva('', {\n variants: {\n orientation: {\n // min-w-[44px] ensures visual layer fills touch target width (for icon buttons)\n horizontal: 'min-w-[44px]',\n // flex (overrides inline-flex) + min-h-[44px] makes visual layer fill touch target,\n // eliminating gaps between stacked buttons in vertical orientation\n vertical: 'flex min-h-[44px]',\n },\n position: {\n first: '',\n middle: '',\n last: '',\n only: '', // Single button - no modifications needed\n },\n },\n compoundVariants: [\n // ==========================================================================\n // Horizontal Orientation\n // ==========================================================================\n {\n orientation: 'horizontal',\n position: 'first',\n className: 'rounded-r-none border-r-0',\n },\n {\n orientation: 'horizontal',\n position: 'middle',\n className: 'rounded-none border-r-0',\n },\n {\n orientation: 'horizontal',\n position: 'last',\n className: 'rounded-l-none',\n },\n // ==========================================================================\n // Vertical Orientation\n // Note: w-full is handled by Button's effectiveFullWidth for both layers\n // ==========================================================================\n {\n orientation: 'vertical',\n position: 'first',\n className: 'rounded-b-none border-b-0',\n },\n {\n orientation: 'vertical',\n position: 'middle',\n className: 'rounded-none border-b-0',\n },\n {\n orientation: 'vertical',\n position: 'last',\n className: 'rounded-t-none',\n },\n ],\n defaultVariants: {\n orientation: 'horizontal',\n position: 'only',\n },\n});\n\n// =============================================================================\n// Separator Variants\n// =============================================================================\n\n/**\n * ButtonGroupSeparator variants\n * Orientation-aware visual divider between button groups\n */\nexport const buttonGroupSeparatorVariants = cva('bg-[var(--border)]', {\n variants: {\n orientation: {\n horizontal: 'w-px h-6 mx-1',\n vertical: 'h-px w-full my-1',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n});\n","\"use client\";\n\n/**\n * Button Component - 3-Layer Architecture\n * Accessible button with React Aria primitives and CVA styling\n *\n * Architecture:\n * - Layer 1: Touch Target (44x44px WCAG AAA compliant, transparent)\n * - Layer 2: Visual Button (configurable size, colors, borders)\n * - Layer 3: Content & Effects (text, icons, ripple, loading spinner)\n *\n * @see 3layer-plan.md for architecture details\n * @see spec.md FR-029 to FR-037 (Button Component Requirements)\n * @see spec.md FR-009 (WCAG 2.2 AAA - 7:1 contrast ratio)\n * @see spec.md FR-014 (44x44px minimum touch targets)\n * @see constitution.md Principle IV (Accessibility First)\n */\n\nimport { forwardRef, memo, useId, type ReactNode } from 'react';\nimport {\n Button as AriaButton,\n type ButtonProps as AriaButtonProps,\n} from 'react-aria-components';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Loader2, Zap } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { PRESSED_STYLES, HOVER_STYLES, HIGH_CONTRAST_HOVER, HIGH_CONTRAST_PRESSED } from '../../styles/interaction-states';\nimport {\n useButtonGroupContext,\n useButtonGroupItemContext,\n} from '../ButtonGroup/ButtonGroupContext';\nimport { buttonGroupItemVariants } from '../ButtonGroup/ButtonGroup.variants';\n\n/**\n * Layer 1: Transparent outer touch target (44x44px minimum)\n * Handles WCAG 2.2 AAA touch target requirement\n * Always transparent, centers the visual button inside\n * IMPORTANT: Focus ring stays on Layer 1 for AAA compliance (2.4.13)\n *\n * In vertical ButtonGroups, uses items-stretch so the visual layer (Layer 2)\n * can fill the full touch target height, eliminating gaps between buttons.\n */\nconst buttonOuterVariants = cva(\n \"inline-flex justify-center min-h-[44px] min-w-[44px] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:pointer-events-none disabled:opacity-50\",\n {\n variants: {\n fullWidth: {\n true: \"w-full\",\n false: \"\",\n },\n inVerticalGroup: {\n true: \"items-stretch\",\n false: \"items-center\",\n },\n },\n defaultVariants: {\n fullWidth: false,\n inVerticalGroup: false,\n },\n }\n);\n\n/**\n * Layer 2: Visual button appearance (adjustable size)\n * Provides the visual appearance with configurable size\n * Can be smaller than touch target for use cases like carousel dots\n * NOTE: NO focus-visible styles here - focus ring is on Layer 1\n */\nconst buttonVisualVariants = cva(\n \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0 relative cursor-pointer\",\n {\n variants: {\n variant: {\n default:\n \"bg-[var(--primary-action)] text-[var(--primary-action-foreground)] shadow-md hover:bg-[var(--primary-action-hover)] data-[pressed]:bg-[var(--primary-action)]/80\",\n destructive:\n \"bg-[var(--destructive-background)] text-[var(--destructive-foreground)] shadow-md hover:bg-[var(--destructive-background)]/90 data-[pressed]:bg-[var(--destructive-background)]/80\",\n outline:\n \"border border-[var(--input-border)] bg-[var(--page-background)] hover:bg-[var(--input-border)] data-[pressed]:bg-[var(--input-border)]\",\n secondary:\n \"bg-[var(--secondary)] text-[var(--secondary-foreground)] shadow-md hover:bg-[var(--secondary)]/80 data-[pressed]:bg-[var(--secondary)]/70\",\n ghost:\n \"hover:bg-[var(--accent)] hover:text-[var(--accent-foreground)] data-[pressed]:bg-[var(--accent)]\",\n link: \"text-[var(--text-link)] underline-offset-4 hover:underline data-[pressed]:text-[var(--text-link-hover)]\",\n },\n fullWidth: {\n true: \"w-full\",\n false: \"\",\n },\n visualSize: {\n default: \"h-10 px-4 py-2\",\n sm: \"h-9 rounded-md px-3 text-xs\",\n lg: \"h-11 rounded-md px-8\",\n icon: \"h-10 w-10\",\n dot: \"h-5 w-5 rounded-full p-0 min-h-0 min-w-0\",\n },\n paywall: {\n true: \"!bg-[var(--paywall)] !text-[var(--paywall-foreground)] !shadow-md hover:!bg-[var(--paywall)]/90 !cursor-not-allowed !border-transparent\",\n false: \"\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n visualSize: \"default\",\n paywall: false,\n },\n }\n);\n\n/**\n * @deprecated Use buttonVisualVariants instead. This alias is kept for backward compatibility.\n */\nconst buttonVariants = buttonVisualVariants;\n\nexport interface ButtonProps\n extends Omit<AriaButtonProps, 'className'>,\n VariantProps<typeof buttonVisualVariants> {\n as?: 'button' | 'a';\n loading?: boolean;\n loadingText?: string;\n shortcut?: string;\n className?: string;\n buttonVisualClassName?: string;\n children?: ReactNode;\n /** Enables paywall state - overrides variant styling and prevents normal action */\n paywall?: boolean;\n /** URL to open in new tab when paywalled button is clicked */\n paywallRedirect?: string;\n /** Description of the premium feature for tooltips and screen readers (max 200 chars) */\n paywallDescription?: string;\n /** Full width button */\n fullWidth?: boolean;\n /**\n * Visual size of the button (Layer 2)\n * Defaults to `size` for backward compatibility\n * Use independently for small visual buttons with large touch targets\n * @example <Button size=\"default\" visualSize=\"dot\" /> // 44px touch, 12px visual\n */\n visualSize?: 'sm' | 'default' | 'lg' | 'icon' | 'dot';\n /**\n * Size of the button - controls both touch target awareness and visual size\n * @deprecated For independent visual sizing, use visualSize prop instead\n */\n size?: 'sm' | 'default' | 'lg' | 'icon';\n}\n\n/**\n * Button Component - 3-Layer Architecture\n * Fully accessible button with React Aria and themed styling\n *\n * Layer 1: Touch Target (AriaButton) - 44x44px WCAG AAA compliant\n * Layer 2: Visual Button (span) - configurable appearance\n * Layer 3: Content (children) - text, icons, effects\n */\nconst Button = memo(forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n className,\n buttonVisualClassName,\n variant,\n size,\n visualSize,\n fullWidth,\n loading = false,\n loadingText = \"Loading...\",\n shortcut,\n children,\n isDisabled,\n paywall = false,\n paywallRedirect,\n paywallDescription,\n onPress,\n ...props\n },\n ref\n ) => {\n const paywallDescriptionId = useId();\n\n // ==========================================================================\n // ButtonGroup Context Integration\n // ==========================================================================\n\n // Consume group-level context (variant, size, isDisabled, orientation)\n const groupContext = useButtonGroupContext();\n\n // Consume item-level context (position for border-radius styling)\n const itemContext = useButtonGroupItemContext();\n\n // Merge context values with props (props take precedence)\n const effectiveVariant = variant ?? groupContext?.variant ?? 'default';\n const effectiveSize = size ?? groupContext?.size;\n const effectiveIsDisabled = isDisabled ?? groupContext?.isDisabled ?? false;\n\n // In vertical groups, buttons should be full width automatically\n const isInVerticalGroup = groupContext?.orientation === 'vertical';\n const effectiveFullWidth = fullWidth || isInVerticalGroup;\n\n // Position styling for ButtonGroup (only applied when in a group)\n const positionClassName = itemContext\n ? buttonGroupItemVariants({\n orientation: groupContext?.orientation ?? 'horizontal',\n position: itemContext.position,\n })\n : '';\n\n // Default visualSize to size for backward compatibility\n const effectiveVisualSize = visualSize ?? effectiveSize ?? 'default';\n\n // AAA Accessibility: Warn in dev/test if icon/dot variant lacks accessible name\n if (process.env.NODE_ENV !== 'production') {\n if (\n (effectiveVisualSize === 'dot' || effectiveVisualSize === 'icon') &&\n !props['aria-label'] &&\n !children\n ) {\n console.warn(\n '[Button] visualSize=\"dot\" or \"icon\" requires aria-label when no visible text is provided (WCAG 1.1.1)'\n );\n }\n }\n\n /**\n * Handle button press - intercepts action when paywalled\n * If paywalled with redirect URL, opens in new tab\n * Otherwise, calls the normal onPress handler\n */\n const handlePress = (e: Parameters<NonNullable<AriaButtonProps['onPress']>>[0]): void => {\n if (paywall) {\n if (paywallRedirect) {\n window.open(paywallRedirect, '_blank', 'noopener,noreferrer');\n }\n // Don't call onPress when paywalled\n return;\n }\n onPress?.(e);\n };\n\n // Only set isDisabled when we have a reason to disable\n // Otherwise, let slot system control disabled state (e.g., in NumberField)\n const computedIsDisabled = effectiveIsDisabled || loading || undefined;\n\n return (\n <AriaButton\n ref={ref}\n isDisabled={computedIsDisabled}\n aria-disabled={paywall ? true : undefined}\n aria-describedby={paywall ? paywallDescriptionId : undefined}\n onPress={handlePress}\n className={cn(buttonOuterVariants({ fullWidth: effectiveFullWidth, inVerticalGroup: isInVerticalGroup }), className)}\n {...props}\n >\n {(renderProps) => (\n /* Layer 2: Visual Button */\n <span\n className={cn(\n buttonVisualVariants({\n variant: effectiveVariant,\n visualSize: effectiveVisualSize,\n paywall,\n fullWidth: effectiveFullWidth,\n }),\n // Position styling from ButtonGroup context (border-radius adjustments)\n positionClassName,\n buttonVisualClassName,\n // Layer 2 interaction styles (no focus - focus ring is on Layer 1)\n PRESSED_STYLES,\n HOVER_STYLES,\n HIGH_CONTRAST_HOVER,\n HIGH_CONTRAST_PRESSED\n )}\n data-pressed={renderProps.isPressed || undefined}\n >\n {/* Layer 3: Content & Effects */}\n\n {/* FR-033: Loading spinner with screen reader announcement */}\n {/* Uses motion-safe: for WCAG 2.3.3 AAA (Animation from Interactions) */}\n {loading && (\n <>\n <Loader2 className=\"motion-safe:animate-spin\" aria-hidden=\"true\" />\n <span className=\"sr-only\" aria-live=\"polite\">\n {loadingText}\n </span>\n </>\n )}\n\n {/* Hide children during loading */}\n {!loading && children}\n\n {/* Paywall: Lightning bolt icon */}\n {paywall && (\n <Zap\n data-testid=\"zap-icon\"\n aria-hidden=\"true\"\n className=\"ml-1\"\n />\n )}\n\n {/* Paywall: Screen reader description */}\n {paywall && (\n <span id={paywallDescriptionId} className=\"sr-only\">\n Premium feature: {paywallDescription || \"Upgrade required to access this feature\"}\n </span>\n )}\n\n {/* FR-034: Keyboard shortcut display on focus */}\n {renderProps.isFocusVisible && shortcut && (\n <kbd className=\"ml-auto hidden text-xs opacity-60 lg:inline\">\n {shortcut}\n </kbd>\n )}\n\n {/* Touch/press ripple effect - FR-031: Pressed state feedback */}\n {/* Uses motion-safe: for WCAG 2.3.3 AAA (Animation from Interactions) */}\n {renderProps.isPressed && (\n <span\n className=\"absolute inset-0 rounded-[inherit] bg-current opacity-10 motion-safe:animate-in motion-safe:zoom-in-95\"\n aria-hidden=\"true\"\n />\n )}\n </span>\n )}\n </AriaButton>\n );\n }\n));\n\nButton.displayName = \"Button\";\n\nexport { Button, buttonVariants, buttonOuterVariants, buttonVisualVariants };\n"]}
@@ -1,66 +1,239 @@
1
+ "use client";
1
2
  'use strict';
2
3
 
3
- var chunkRFFO4KPM_js = require('../../chunk-RFFO4KPM.js');
4
- var chunkY3GT7ETK_js = require('../../chunk-Y3GT7ETK.js');
5
- require('../../chunk-VIREG536.js');
4
+ var react = require('react');
5
+ var reactAriaComponents = require('react-aria-components');
6
+ var clsx = require('clsx');
7
+ var tailwindMerge = require('tailwind-merge');
8
+ var classVarianceAuthority = require('class-variance-authority');
9
+ var jsxRuntime = require('react/jsx-runtime');
10
+ var zod = require('zod');
6
11
 
7
-
8
-
9
- Object.defineProperty(exports, "ButtonGroup", {
10
- enumerable: true,
11
- get: function () { return chunkRFFO4KPM_js.ButtonGroup; }
12
- });
13
- Object.defineProperty(exports, "ButtonGroupPropsSchema", {
14
- enumerable: true,
15
- get: function () { return chunkRFFO4KPM_js.ButtonGroupPropsSchema; }
16
- });
17
- Object.defineProperty(exports, "ButtonGroupSeparator", {
18
- enumerable: true,
19
- get: function () { return chunkRFFO4KPM_js.ButtonGroupSeparator; }
20
- });
21
- Object.defineProperty(exports, "ButtonGroupSeparatorPropsSchema", {
22
- enumerable: true,
23
- get: function () { return chunkRFFO4KPM_js.ButtonGroupSeparatorPropsSchema; }
24
- });
25
- Object.defineProperty(exports, "filterButtonChildren", {
26
- enumerable: true,
27
- get: function () { return chunkRFFO4KPM_js.filterButtonChildren; }
12
+ // src/elements/ButtonGroup/ButtonGroup.tsx
13
+ function cn(...inputs) {
14
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
15
+ }
16
+ var ButtonGroupContext = react.createContext(null);
17
+ ButtonGroupContext.displayName = "ButtonGroupContext";
18
+ function useButtonGroupContext() {
19
+ return react.useContext(ButtonGroupContext);
20
+ }
21
+ var ButtonGroupItemContext = react.createContext(null);
22
+ ButtonGroupItemContext.displayName = "ButtonGroupItemContext";
23
+ function useButtonGroupItemContext() {
24
+ return react.useContext(ButtonGroupItemContext);
25
+ }
26
+ var buttonGroupVariants = classVarianceAuthority.cva("inline-flex items-center gap-0", {
27
+ variants: {
28
+ orientation: {
29
+ horizontal: "flex-row",
30
+ vertical: "flex-col w-full"
31
+ }
32
+ },
33
+ defaultVariants: {
34
+ orientation: "horizontal"
35
+ }
28
36
  });
29
- Object.defineProperty(exports, "getButtonIndex", {
30
- enumerable: true,
31
- get: function () { return chunkRFFO4KPM_js.getButtonIndex; }
37
+ var buttonGroupItemVariants = classVarianceAuthority.cva("", {
38
+ variants: {
39
+ orientation: {
40
+ // min-w-[44px] ensures visual layer fills touch target width (for icon buttons)
41
+ horizontal: "min-w-[44px]",
42
+ // flex (overrides inline-flex) + min-h-[44px] makes visual layer fill touch target,
43
+ // eliminating gaps between stacked buttons in vertical orientation
44
+ vertical: "flex min-h-[44px]"
45
+ },
46
+ position: {
47
+ first: "",
48
+ middle: "",
49
+ last: "",
50
+ only: ""
51
+ // Single button - no modifications needed
52
+ }
53
+ },
54
+ compoundVariants: [
55
+ // ==========================================================================
56
+ // Horizontal Orientation
57
+ // ==========================================================================
58
+ {
59
+ orientation: "horizontal",
60
+ position: "first",
61
+ className: "rounded-r-none border-r-0"
62
+ },
63
+ {
64
+ orientation: "horizontal",
65
+ position: "middle",
66
+ className: "rounded-none border-r-0"
67
+ },
68
+ {
69
+ orientation: "horizontal",
70
+ position: "last",
71
+ className: "rounded-l-none"
72
+ },
73
+ // ==========================================================================
74
+ // Vertical Orientation
75
+ // Note: w-full is handled by Button's effectiveFullWidth for both layers
76
+ // ==========================================================================
77
+ {
78
+ orientation: "vertical",
79
+ position: "first",
80
+ className: "rounded-b-none border-b-0"
81
+ },
82
+ {
83
+ orientation: "vertical",
84
+ position: "middle",
85
+ className: "rounded-none border-b-0"
86
+ },
87
+ {
88
+ orientation: "vertical",
89
+ position: "last",
90
+ className: "rounded-t-none"
91
+ }
92
+ ],
93
+ defaultVariants: {
94
+ orientation: "horizontal",
95
+ position: "only"
96
+ }
32
97
  });
33
- Object.defineProperty(exports, "getPosition", {
34
- enumerable: true,
35
- get: function () { return chunkRFFO4KPM_js.getPosition; }
98
+ var buttonGroupSeparatorVariants = classVarianceAuthority.cva("bg-[var(--border)]", {
99
+ variants: {
100
+ orientation: {
101
+ horizontal: "w-px h-6 mx-1",
102
+ vertical: "h-px w-full my-1"
103
+ }
104
+ },
105
+ defaultVariants: {
106
+ orientation: "horizontal"
107
+ }
36
108
  });
37
- Object.defineProperty(exports, "isButtonElement", {
38
- enumerable: true,
39
- get: function () { return chunkRFFO4KPM_js.isButtonElement; }
109
+ var isButtonElement = (child) => {
110
+ if (!react.isValidElement(child)) return false;
111
+ const componentType = child.type;
112
+ return componentType?.displayName === "Button";
113
+ };
114
+ var isSeparatorElement = (child) => {
115
+ if (!react.isValidElement(child)) return false;
116
+ const componentType = child.type;
117
+ return componentType?.displayName === "ButtonGroupSeparator";
118
+ };
119
+ var getPosition = (index, total) => {
120
+ if (total === 1) return "only";
121
+ if (index === 0) return "first";
122
+ if (index === total - 1) return "last";
123
+ return "middle";
124
+ };
125
+ var filterButtonChildren = (children) => {
126
+ return children.filter(isButtonElement);
127
+ };
128
+ var getButtonIndex = (child, buttonChildren) => {
129
+ return buttonChildren.indexOf(child);
130
+ };
131
+ var ButtonGroup = react.forwardRef(
132
+ ({
133
+ orientation = "horizontal",
134
+ variant,
135
+ size,
136
+ isDisabled,
137
+ className,
138
+ children,
139
+ ...props
140
+ }, ref) => {
141
+ const childArray = react.Children.toArray(children);
142
+ const buttonChildren = childArray.filter(isButtonElement);
143
+ const totalButtons = buttonChildren.length;
144
+ const groupContextValue = {
145
+ orientation,
146
+ variant,
147
+ size,
148
+ isDisabled
149
+ };
150
+ const wrappedChildren = childArray.map((child, index) => {
151
+ if (isButtonElement(child)) {
152
+ const buttonIndex = buttonChildren.indexOf(child);
153
+ const position = getPosition(buttonIndex, totalButtons);
154
+ return /* @__PURE__ */ jsxRuntime.jsx(
155
+ ButtonGroupItemContext.Provider,
156
+ {
157
+ value: { position },
158
+ children: child
159
+ },
160
+ index
161
+ );
162
+ }
163
+ return child;
164
+ });
165
+ return /* @__PURE__ */ jsxRuntime.jsx(
166
+ reactAriaComponents.Toolbar,
167
+ {
168
+ ref,
169
+ orientation,
170
+ "aria-label": props["aria-label"],
171
+ "aria-labelledby": props["aria-labelledby"],
172
+ className: cn(buttonGroupVariants({ orientation }), className),
173
+ children: /* @__PURE__ */ jsxRuntime.jsx(ButtonGroupContext.Provider, { value: groupContextValue, children: wrappedChildren })
174
+ }
175
+ );
176
+ }
177
+ );
178
+ ButtonGroup.displayName = "ButtonGroup";
179
+ var ButtonGroupSeparator = react.forwardRef(
180
+ ({ className, ...props }, ref) => {
181
+ const groupContext = useButtonGroupContext();
182
+ const orientation = groupContext?.orientation ?? "horizontal";
183
+ return /* @__PURE__ */ jsxRuntime.jsx(
184
+ "div",
185
+ {
186
+ ref,
187
+ role: "separator",
188
+ "aria-hidden": "true",
189
+ className: cn(
190
+ buttonGroupSeparatorVariants({ orientation }),
191
+ className
192
+ ),
193
+ ...props
194
+ }
195
+ );
196
+ }
197
+ );
198
+ ButtonGroupSeparator.displayName = "ButtonGroupSeparator";
199
+ var ButtonGroupPropsSchema = zod.z.object({
200
+ /** Orientation of the button group layout */
201
+ orientation: zod.z.enum(["horizontal", "vertical"]).optional().default("horizontal"),
202
+ /** Default variant for all child buttons (can be overridden per-button) */
203
+ variant: zod.z.enum(["default", "destructive", "outline", "secondary", "ghost"]).optional(),
204
+ /** Default size for all child buttons (can be overridden per-button) */
205
+ size: zod.z.enum(["sm", "default", "lg", "icon"]).optional(),
206
+ /** Disable all buttons in the group */
207
+ isDisabled: zod.z.boolean().optional(),
208
+ /** Accessible label for the toolbar (recommended) */
209
+ "aria-label": zod.z.string().optional(),
210
+ /** ID of element that labels the toolbar */
211
+ "aria-labelledby": zod.z.string().optional(),
212
+ /** Additional CSS classes */
213
+ className: zod.z.string().optional(),
214
+ /** Child elements (Buttons, Separators, etc.) */
215
+ children: zod.z.custom()
40
216
  });
41
- Object.defineProperty(exports, "isSeparatorElement", {
42
- enumerable: true,
43
- get: function () { return chunkRFFO4KPM_js.isSeparatorElement; }
44
- });
45
- Object.defineProperty(exports, "buttonGroupItemVariants", {
46
- enumerable: true,
47
- get: function () { return chunkY3GT7ETK_js.buttonGroupItemVariants; }
48
- });
49
- Object.defineProperty(exports, "buttonGroupSeparatorVariants", {
50
- enumerable: true,
51
- get: function () { return chunkY3GT7ETK_js.buttonGroupSeparatorVariants; }
52
- });
53
- Object.defineProperty(exports, "buttonGroupVariants", {
54
- enumerable: true,
55
- get: function () { return chunkY3GT7ETK_js.buttonGroupVariants; }
56
- });
57
- Object.defineProperty(exports, "useButtonGroupContext", {
58
- enumerable: true,
59
- get: function () { return chunkY3GT7ETK_js.useButtonGroupContext; }
60
- });
61
- Object.defineProperty(exports, "useButtonGroupItemContext", {
62
- enumerable: true,
63
- get: function () { return chunkY3GT7ETK_js.useButtonGroupItemContext; }
217
+ var ButtonGroupSeparatorPropsSchema = zod.z.object({
218
+ /** Additional CSS classes */
219
+ className: zod.z.string().optional(),
220
+ /** Test ID for testing */
221
+ "data-testid": zod.z.string().optional()
64
222
  });
223
+
224
+ exports.ButtonGroup = ButtonGroup;
225
+ exports.ButtonGroupPropsSchema = ButtonGroupPropsSchema;
226
+ exports.ButtonGroupSeparator = ButtonGroupSeparator;
227
+ exports.ButtonGroupSeparatorPropsSchema = ButtonGroupSeparatorPropsSchema;
228
+ exports.buttonGroupItemVariants = buttonGroupItemVariants;
229
+ exports.buttonGroupSeparatorVariants = buttonGroupSeparatorVariants;
230
+ exports.buttonGroupVariants = buttonGroupVariants;
231
+ exports.filterButtonChildren = filterButtonChildren;
232
+ exports.getButtonIndex = getButtonIndex;
233
+ exports.getPosition = getPosition;
234
+ exports.isButtonElement = isButtonElement;
235
+ exports.isSeparatorElement = isSeparatorElement;
236
+ exports.useButtonGroupContext = useButtonGroupContext;
237
+ exports.useButtonGroupItemContext = useButtonGroupItemContext;
65
238
  //# sourceMappingURL=index.js.map
66
239
  //# sourceMappingURL=index.js.map