@tribepad/themis 1.0.1 → 1.0.2

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 (301) hide show
  1. package/dist/elements/Accordion/index.js +1 -335
  2. package/dist/elements/Accordion/index.js.map +1 -1
  3. package/dist/elements/Accordion/index.mjs +1 -317
  4. package/dist/elements/Accordion/index.mjs.map +1 -1
  5. package/dist/elements/AlertDialog/AlertDialog.d.ts +43 -0
  6. package/dist/elements/AlertDialog/AlertDialog.d.ts.map +1 -0
  7. package/dist/elements/AlertDialog/AlertDialog.styles.d.ts +15 -0
  8. package/dist/elements/AlertDialog/AlertDialog.styles.d.ts.map +1 -0
  9. package/dist/elements/AlertDialog/AlertDialog.types.d.ts +72 -0
  10. package/dist/elements/AlertDialog/AlertDialog.types.d.ts.map +1 -0
  11. package/dist/elements/AlertDialog/index.d.ts +25 -0
  12. package/dist/elements/AlertDialog/index.d.ts.map +1 -0
  13. package/dist/elements/AlertDialog/index.js +3 -0
  14. package/dist/elements/AlertDialog/index.js.map +1 -0
  15. package/dist/elements/AlertDialog/index.mjs +3 -0
  16. package/dist/elements/AlertDialog/index.mjs.map +1 -0
  17. package/dist/elements/Avatar/index.js +1 -468
  18. package/dist/elements/Avatar/index.js.map +1 -1
  19. package/dist/elements/Avatar/index.mjs +1 -456
  20. package/dist/elements/Avatar/index.mjs.map +1 -1
  21. package/dist/elements/Badge/index.js +1 -243
  22. package/dist/elements/Badge/index.js.map +1 -1
  23. package/dist/elements/Badge/index.mjs +1 -234
  24. package/dist/elements/Badge/index.mjs.map +1 -1
  25. package/dist/elements/Breadcrumbs/index.js +1 -821
  26. package/dist/elements/Breadcrumbs/index.js.map +1 -1
  27. package/dist/elements/Breadcrumbs/index.mjs +1 -810
  28. package/dist/elements/Breadcrumbs/index.mjs.map +1 -1
  29. package/dist/elements/Button/Button.d.ts +26 -81
  30. package/dist/elements/Button/Button.d.ts.map +1 -1
  31. package/dist/elements/Button/Button.styles.d.ts +35 -0
  32. package/dist/elements/Button/Button.styles.d.ts.map +1 -0
  33. package/dist/elements/Button/Button.types.d.ts +20 -8
  34. package/dist/elements/Button/Button.types.d.ts.map +1 -1
  35. package/dist/elements/Button/index.js +1 -288
  36. package/dist/elements/Button/index.js.map +1 -1
  37. package/dist/elements/Button/index.mjs +1 -283
  38. package/dist/elements/Button/index.mjs.map +1 -1
  39. package/dist/elements/ButtonGroup/index.js +1 -237
  40. package/dist/elements/ButtonGroup/index.js.map +1 -1
  41. package/dist/elements/ButtonGroup/index.mjs +1 -222
  42. package/dist/elements/ButtonGroup/index.mjs.map +1 -1
  43. package/dist/elements/Card/index.js +1 -579
  44. package/dist/elements/Card/index.js.map +1 -1
  45. package/dist/elements/Card/index.mjs +1 -560
  46. package/dist/elements/Card/index.mjs.map +1 -1
  47. package/dist/elements/Carousel/Carousel.d.ts +1 -11
  48. package/dist/elements/Carousel/Carousel.d.ts.map +1 -1
  49. package/dist/elements/Carousel/LazyCarousel.d.ts +1 -1
  50. package/dist/elements/Carousel/LazyCarousel.d.ts.map +1 -1
  51. package/dist/elements/Carousel/index.js +1 -789
  52. package/dist/elements/Carousel/index.js.map +1 -1
  53. package/dist/elements/Carousel/index.mjs +1 -786
  54. package/dist/elements/Carousel/index.mjs.map +1 -1
  55. package/dist/elements/Chart/ChartContext.d.ts.map +1 -1
  56. package/dist/elements/Chart/index.js +1 -1842
  57. package/dist/elements/Chart/index.js.map +1 -1
  58. package/dist/elements/Chart/index.mjs +1 -1832
  59. package/dist/elements/Chart/index.mjs.map +1 -1
  60. package/dist/elements/Checkbox/index.js +1 -316
  61. package/dist/elements/Checkbox/index.js.map +1 -1
  62. package/dist/elements/Checkbox/index.mjs +1 -306
  63. package/dist/elements/Checkbox/index.mjs.map +1 -1
  64. package/dist/elements/CheckboxGroup/index.js +1 -455
  65. package/dist/elements/CheckboxGroup/index.js.map +1 -1
  66. package/dist/elements/CheckboxGroup/index.mjs +1 -439
  67. package/dist/elements/CheckboxGroup/index.mjs.map +1 -1
  68. package/dist/elements/Combobox/Combobox.d.ts +56 -0
  69. package/dist/elements/Combobox/Combobox.d.ts.map +1 -0
  70. package/dist/elements/Combobox/Combobox.styles.d.ts +29 -0
  71. package/dist/elements/Combobox/Combobox.styles.d.ts.map +1 -0
  72. package/dist/elements/Combobox/Combobox.types.d.ts +67 -0
  73. package/dist/elements/Combobox/Combobox.types.d.ts.map +1 -0
  74. package/dist/elements/Combobox/index.d.ts +20 -0
  75. package/dist/elements/Combobox/index.d.ts.map +1 -0
  76. package/dist/elements/Combobox/index.js +3 -0
  77. package/dist/elements/Combobox/index.js.map +1 -0
  78. package/dist/elements/Combobox/index.mjs +3 -0
  79. package/dist/elements/Combobox/index.mjs.map +1 -0
  80. package/dist/elements/DatePicker/DatePicker.d.ts +1 -1
  81. package/dist/elements/DatePicker/DatePicker.d.ts.map +1 -1
  82. package/dist/elements/DatePicker/index.js +1 -903
  83. package/dist/elements/DatePicker/index.js.map +1 -1
  84. package/dist/elements/DatePicker/index.mjs +1 -853
  85. package/dist/elements/DatePicker/index.mjs.map +1 -1
  86. package/dist/elements/Dropdown/Dropdown.d.ts +7 -15
  87. package/dist/elements/Dropdown/Dropdown.d.ts.map +1 -1
  88. package/dist/elements/Dropdown/Dropdown.styles.d.ts +22 -0
  89. package/dist/elements/Dropdown/Dropdown.styles.d.ts.map +1 -0
  90. package/dist/elements/Dropdown/index.d.ts +1 -0
  91. package/dist/elements/Dropdown/index.d.ts.map +1 -1
  92. package/dist/elements/Dropdown/index.js +1 -193
  93. package/dist/elements/Dropdown/index.js.map +1 -1
  94. package/dist/elements/Dropdown/index.mjs +1 -184
  95. package/dist/elements/Dropdown/index.mjs.map +1 -1
  96. package/dist/elements/FileField/index.js +1 -1539
  97. package/dist/elements/FileField/index.js.map +1 -1
  98. package/dist/elements/FileField/index.mjs +1 -1507
  99. package/dist/elements/FileField/index.mjs.map +1 -1
  100. package/dist/elements/FormLayout/index.js +1 -170
  101. package/dist/elements/FormLayout/index.js.map +1 -1
  102. package/dist/elements/FormLayout/index.mjs +1 -167
  103. package/dist/elements/FormLayout/index.mjs.map +1 -1
  104. package/dist/elements/Modal/Modal.d.ts +9 -14
  105. package/dist/elements/Modal/Modal.d.ts.map +1 -1
  106. package/dist/elements/Modal/Modal.styles.d.ts +29 -0
  107. package/dist/elements/Modal/Modal.styles.d.ts.map +1 -0
  108. package/dist/elements/Modal/index.d.ts +1 -0
  109. package/dist/elements/Modal/index.d.ts.map +1 -1
  110. package/dist/elements/Modal/index.js +1 -232
  111. package/dist/elements/Modal/index.js.map +1 -1
  112. package/dist/elements/Modal/index.mjs +1 -220
  113. package/dist/elements/Modal/index.mjs.map +1 -1
  114. package/dist/elements/NumberField/index.js +1 -666
  115. package/dist/elements/NumberField/index.js.map +1 -1
  116. package/dist/elements/NumberField/index.mjs +1 -654
  117. package/dist/elements/NumberField/index.mjs.map +1 -1
  118. package/dist/elements/OTPInput/OTPInput.d.ts.map +1 -1
  119. package/dist/elements/OTPInput/index.js +1 -734
  120. package/dist/elements/OTPInput/index.js.map +1 -1
  121. package/dist/elements/OTPInput/index.mjs +1 -732
  122. package/dist/elements/OTPInput/index.mjs.map +1 -1
  123. package/dist/elements/Pagination/Pagination.d.ts +45 -0
  124. package/dist/elements/Pagination/Pagination.d.ts.map +1 -0
  125. package/dist/elements/Pagination/Pagination.styles.d.ts +10 -0
  126. package/dist/elements/Pagination/Pagination.styles.d.ts.map +1 -0
  127. package/dist/elements/Pagination/Pagination.types.d.ts +55 -0
  128. package/dist/elements/Pagination/Pagination.types.d.ts.map +1 -0
  129. package/dist/elements/Pagination/index.d.ts +21 -0
  130. package/dist/elements/Pagination/index.d.ts.map +1 -0
  131. package/dist/elements/Pagination/index.js +3 -0
  132. package/dist/elements/Pagination/index.js.map +1 -0
  133. package/dist/elements/Pagination/index.mjs +3 -0
  134. package/dist/elements/Pagination/index.mjs.map +1 -0
  135. package/dist/elements/Panel/index.js +1 -330
  136. package/dist/elements/Panel/index.js.map +1 -1
  137. package/dist/elements/Panel/index.mjs +1 -323
  138. package/dist/elements/Panel/index.mjs.map +1 -1
  139. package/dist/elements/PasswordField/PasswordField.d.ts +27 -0
  140. package/dist/elements/PasswordField/PasswordField.d.ts.map +1 -0
  141. package/dist/elements/PasswordField/PasswordField.styles.d.ts +32 -0
  142. package/dist/elements/PasswordField/PasswordField.styles.d.ts.map +1 -0
  143. package/dist/elements/PasswordField/PasswordField.types.d.ts +100 -0
  144. package/dist/elements/PasswordField/PasswordField.types.d.ts.map +1 -0
  145. package/dist/elements/PasswordField/index.css +2 -0
  146. package/dist/elements/PasswordField/index.css.map +1 -0
  147. package/dist/elements/PasswordField/index.d.ts +20 -0
  148. package/dist/elements/PasswordField/index.d.ts.map +1 -0
  149. package/dist/elements/PasswordField/index.js +3 -0
  150. package/dist/elements/PasswordField/index.js.map +1 -0
  151. package/dist/elements/PasswordField/index.mjs +3 -0
  152. package/dist/elements/PasswordField/index.mjs.map +1 -0
  153. package/dist/elements/Progress/index.js +1 -187
  154. package/dist/elements/Progress/index.js.map +1 -1
  155. package/dist/elements/Progress/index.mjs +1 -181
  156. package/dist/elements/Progress/index.mjs.map +1 -1
  157. package/dist/elements/RadioGroup/index.js +1 -369
  158. package/dist/elements/RadioGroup/index.js.map +1 -1
  159. package/dist/elements/RadioGroup/index.mjs +1 -359
  160. package/dist/elements/RadioGroup/index.mjs.map +1 -1
  161. package/dist/elements/Resizable/index.js +1 -1580
  162. package/dist/elements/Resizable/index.js.map +1 -1
  163. package/dist/elements/Resizable/index.mjs +1 -1566
  164. package/dist/elements/Resizable/index.mjs.map +1 -1
  165. package/dist/elements/SearchField/SearchField.d.ts +27 -0
  166. package/dist/elements/SearchField/SearchField.d.ts.map +1 -0
  167. package/dist/elements/SearchField/SearchField.styles.d.ts +32 -0
  168. package/dist/elements/SearchField/SearchField.styles.d.ts.map +1 -0
  169. package/dist/elements/SearchField/SearchField.types.d.ts +45 -0
  170. package/dist/elements/SearchField/SearchField.types.d.ts.map +1 -0
  171. package/dist/elements/SearchField/index.css +2 -0
  172. package/dist/elements/SearchField/index.css.map +1 -0
  173. package/dist/elements/SearchField/index.d.ts +21 -0
  174. package/dist/elements/SearchField/index.d.ts.map +1 -0
  175. package/dist/elements/SearchField/index.js +3 -0
  176. package/dist/elements/SearchField/index.js.map +1 -0
  177. package/dist/elements/SearchField/index.mjs +3 -0
  178. package/dist/elements/SearchField/index.mjs.map +1 -0
  179. package/dist/elements/Select/Select.d.ts +19 -48
  180. package/dist/elements/Select/Select.d.ts.map +1 -1
  181. package/dist/elements/Select/Select.styles.d.ts +55 -0
  182. package/dist/elements/Select/Select.styles.d.ts.map +1 -0
  183. package/dist/elements/Select/index.js +1 -589
  184. package/dist/elements/Select/index.js.map +1 -1
  185. package/dist/elements/Select/index.mjs +1 -582
  186. package/dist/elements/Select/index.mjs.map +1 -1
  187. package/dist/elements/Skeleton/index.js +1 -82
  188. package/dist/elements/Skeleton/index.js.map +1 -1
  189. package/dist/elements/Skeleton/index.mjs +1 -78
  190. package/dist/elements/Skeleton/index.mjs.map +1 -1
  191. package/dist/elements/Switch/index.js +1 -179
  192. package/dist/elements/Switch/index.js.map +1 -1
  193. package/dist/elements/Switch/index.mjs +1 -173
  194. package/dist/elements/Switch/index.mjs.map +1 -1
  195. package/dist/elements/Table/Table.d.ts +3 -24
  196. package/dist/elements/Table/Table.d.ts.map +1 -1
  197. package/dist/elements/Table/Table.styles.d.ts +24 -0
  198. package/dist/elements/Table/Table.styles.d.ts.map +1 -0
  199. package/dist/elements/Table/index.js +1 -595
  200. package/dist/elements/Table/index.js.map +1 -1
  201. package/dist/elements/Table/index.mjs +1 -578
  202. package/dist/elements/Table/index.mjs.map +1 -1
  203. package/dist/elements/Tabs/index.js +1 -337
  204. package/dist/elements/Tabs/index.js.map +1 -1
  205. package/dist/elements/Tabs/index.mjs +1 -320
  206. package/dist/elements/Tabs/index.mjs.map +1 -1
  207. package/dist/elements/TextField/TextField.d.ts +6 -42
  208. package/dist/elements/TextField/TextField.d.ts.map +1 -1
  209. package/dist/elements/TextField/TextField.hooks.d.ts +63 -0
  210. package/dist/elements/TextField/TextField.hooks.d.ts.map +1 -0
  211. package/dist/elements/TextField/TextField.icons.d.ts +19 -0
  212. package/dist/elements/TextField/TextField.icons.d.ts.map +1 -0
  213. package/dist/elements/TextField/TextField.styles.d.ts +37 -0
  214. package/dist/elements/TextField/TextField.styles.d.ts.map +1 -0
  215. package/dist/elements/TextField/TextField.types.d.ts +3 -0
  216. package/dist/elements/TextField/TextField.types.d.ts.map +1 -1
  217. package/dist/elements/TextField/index.css +1 -22
  218. package/dist/elements/TextField/index.css.map +1 -1
  219. package/dist/elements/TextField/index.js +1 -902
  220. package/dist/elements/TextField/index.js.map +1 -1
  221. package/dist/elements/TextField/index.mjs +1 -882
  222. package/dist/elements/TextField/index.mjs.map +1 -1
  223. package/dist/elements/TimeField/index.js +1 -254
  224. package/dist/elements/TimeField/index.js.map +1 -1
  225. package/dist/elements/TimeField/index.mjs +1 -238
  226. package/dist/elements/TimeField/index.mjs.map +1 -1
  227. package/dist/elements/Toast/Toast.d.ts +0 -22
  228. package/dist/elements/Toast/Toast.d.ts.map +1 -1
  229. package/dist/elements/Toast/index.js +1 -737
  230. package/dist/elements/Toast/index.js.map +1 -1
  231. package/dist/elements/Toast/index.mjs +1 -724
  232. package/dist/elements/Toast/index.mjs.map +1 -1
  233. package/dist/elements/Tooltip/index.js +1 -323
  234. package/dist/elements/Tooltip/index.js.map +1 -1
  235. package/dist/elements/Tooltip/index.mjs +1 -310
  236. package/dist/elements/Tooltip/index.mjs.map +1 -1
  237. package/dist/elements/index.css +1 -22
  238. package/dist/elements/index.css.map +1 -1
  239. package/dist/elements/index.d.ts +13 -1
  240. package/dist/elements/index.d.ts.map +1 -1
  241. package/dist/elements/index.js +1 -12455
  242. package/dist/elements/index.js.map +1 -1
  243. package/dist/elements/index.mjs +1 -12233
  244. package/dist/elements/index.mjs.map +1 -1
  245. package/dist/index.css +1 -22
  246. package/dist/index.css.map +1 -1
  247. package/dist/index.js +2 -12490
  248. package/dist/index.js.map +1 -1
  249. package/dist/index.mjs +2 -12262
  250. package/dist/index.mjs.map +1 -1
  251. package/dist/schemas/index.js +2 -54
  252. package/dist/schemas/index.js.map +1 -1
  253. package/dist/schemas/index.mjs +2 -48
  254. package/dist/schemas/index.mjs.map +1 -1
  255. package/dist/styles/defaults.css +151 -0
  256. package/dist/styles/index.js +1 -166
  257. package/dist/styles/index.js.map +1 -1
  258. package/dist/styles/index.mjs +1 -129
  259. package/dist/styles/index.mjs.map +1 -1
  260. package/dist/utils/index.js +1 -12
  261. package/dist/utils/index.js.map +1 -1
  262. package/dist/utils/index.mjs +1 -10
  263. package/dist/utils/index.mjs.map +1 -1
  264. package/package.json +9 -7
  265. package/src/elements/Accordion/Accordion.stories.tsx +1 -1
  266. package/src/elements/AlertDialog/AlertDialog.stories.tsx +124 -0
  267. package/src/elements/Avatar/Avatar.stories.tsx +1 -1
  268. package/src/elements/Badge/Badge.stories.tsx +1 -1
  269. package/src/elements/Breadcrumbs/Breadcrumbs.stories.tsx +1 -1
  270. package/src/elements/Button/Button.stories.tsx +1 -1
  271. package/src/elements/ButtonGroup/ButtonGroup.stories.tsx +1 -1
  272. package/src/elements/Card/Card.stories.tsx +1 -1
  273. package/src/elements/Carousel/Carousel.stories.tsx +1 -1
  274. package/src/elements/Chart/Chart.stories.tsx +1 -1
  275. package/src/elements/Checkbox/Checkbox.stories.tsx +1 -1
  276. package/src/elements/CheckboxGroup/CheckboxGroup.stories.tsx +1 -1
  277. package/src/elements/Combobox/Combobox.stories.tsx +133 -0
  278. package/src/elements/DatePicker/DatePicker.stories.tsx +1 -1
  279. package/src/elements/Dropdown/Dropdown.stories.tsx +1 -1
  280. package/src/elements/FileField/FileField.stories.tsx +1 -1
  281. package/src/elements/FileField/FileProgress.stories.tsx +1 -1
  282. package/src/elements/FormLayout/FormLayout.stories.tsx +1 -1
  283. package/src/elements/Modal/Modal.stories.tsx +1 -1
  284. package/src/elements/NumberField/NumberField.stories.tsx +1 -1
  285. package/src/elements/OTPInput/OTPInput.stories.tsx +1 -1
  286. package/src/elements/Pagination/Pagination.stories.tsx +203 -0
  287. package/src/elements/Panel/Panel.stories.tsx +1 -1
  288. package/src/elements/PasswordField/PasswordField.stories.tsx +167 -0
  289. package/src/elements/Progress/Progress.stories.tsx +1 -1
  290. package/src/elements/RadioGroup/RadioGroup.stories.tsx +1 -1
  291. package/src/elements/Resizable/Resizable.stories.tsx +1 -1
  292. package/src/elements/SearchField/SearchField.stories.tsx +146 -0
  293. package/src/elements/Select/Select.stories.tsx +1 -1
  294. package/src/elements/Skeleton/Skeleton.stories.tsx +1 -1
  295. package/src/elements/Switch/Switch.stories.tsx +1 -1
  296. package/src/elements/Table/Table.stories.tsx +1 -1
  297. package/src/elements/Tabs/Tabs.stories.tsx +1 -1
  298. package/src/elements/TextField/TextField.stories.tsx +1 -1
  299. package/src/elements/TimeField/TimeField.stories.tsx +1 -1
  300. package/src/elements/Toast/Toast.stories.tsx +1 -1
  301. package/src/elements/Tooltip/Tooltip.stories.tsx +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/cn.ts","../../../src/elements/Tabs/Tabs.tsx","../../../src/schemas/BaseComponentProps.ts","../../../src/elements/Tabs/Tabs.types.ts"],"names":["twMerge","clsx","ReactActivity","jsx","cva","AriaTabs","AriaTabList","composeRenderProps","className","AriaTab","AriaTabPanel","z"],"mappings":";;;;;;;;;;;AAcO,SAAS,MAAM,MAAA,EAA8B;AAClD,EAAA,OAAOA,qBAAA,CAAQC,SAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACgBA,IAAM,QAAA,GAAWC,cAAA,IAAiB,SAAS,gBAAA,CAAiB;AAAA,EAC1D,QAAA;AAAA,EACA;AACF,CAAA,EAGiB;AAGf,EAAA,uBAAOC,cAAA,CAAC,KAAA,EAAA,EAAI,oBAAA,EAAoB,IAAA,EAAO,QAAA,EAAS,CAAA;AAClD,CAAA;AA4BO,IAAM,eAAA,GAAkBC,0BAAA;AAAA;AAAA,EAE7B;AAAA,IACE,wDAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,WAAA,EAAa;AAAA,QACX,UAAA,EAAY,qBAAA;AAAA,QACZ,QAAA,EAAU;AAAA;AACZ,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,WAAA,EAAa;AAAA;AACf;AAEJ;AASO,IAAM,WAAA,GAAcA,0BAAA;AAAA;AAAA,EAEzB;AAAA,IACE,4EAAA;AAAA,IACA,iCAAA;AAAA,IACA,wDAAA;AAAA,IACA,iDAAA;AAAA,IACA,8DAAA;AAAA;AAAA,IAEA,gEAAA;AAAA,IACA,iGAAA;AAAA,IACA,2BAAA;AAAA;AAAA,IAEA;AAAA,GACF;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,WAAA,EAAa;AAAA,QACX,UAAA,EAAY,EAAA;AAAA,QACZ,QAAA,EAAU;AAAA;AACZ,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,WAAA,EAAa;AAAA;AACf;AAEJ;AAOO,IAAM,gBAAA,GAAmBA,0BAAA;AAAA,EAC9B;AAAA,IACE,8CAAA;AAAA,IACA,iDAAA;AAAA,IACA;AAAA,GACF;AAAA,EACA;AAAA,IACE,UAAU,EAAC;AAAA,IACX,iBAAiB;AAAC;AAEtB;AAiCA,SAAS,QAAA,CAAS;AAAA,EAChB,QAAA;AAAA,EACA,WAAA;AAAA,EACA,kBAAA;AAAA,EACA,iBAAA;AAAA,EACA,WAAA,GAAc,YAAA;AAAA,EACd,kBAAA,GAAqB,WAAA;AAAA,EACrB,UAAA,GAAa,KAAA;AAAA,EACb,YAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAc;AACZ,EAAA,uBACED,cAAA;AAAA,IAACE,wBAAA;AAAA,IAAA;AAAA,MACC,WAAA;AAAA,MACA,kBAAA;AAAA,MACA,iBAAA;AAAA,MACA,WAAA;AAAA,MACA,kBAAA;AAAA,MACA,UAAA;AAAA,MACA,YAAA;AAAA,MACA,SAAA,EAAW,GAAG,SAAS,CAAA;AAAA,MACtB,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ;AAEA,QAAA,CAAS,WAAA,GAAc,MAAA;AAWvB,SAAS,gBAAA,CAAiB;AAAA,EACxB,QAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAiB;AACf,EAAA,uBACEF,cAAA;AAAA,IAACG,2BAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAWC,sCAAA;AAAA,QAAmB,SAAA;AAAA,QAAW,CAACC,YAAW,WAAA,KACnD,EAAA;AAAA,UACE,eAAA,CAAgB,EAAE,WAAA,EAAa,WAAA,CAAY,aAAa,CAAA;AAAA,UACxDA;AAAA;AACF,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ;AAEA,gBAAA,CAAiB,WAAA,GAAc,SAAA;AAa/B,SAAS,YAAA,CAAa;AAAA,EACpB,QAAA;AAAA,EACA,EAAA;AAAA,EACA,UAAA,GAAa,KAAA;AAAA,EACb,IAAA;AAAA,EACA,MAAA;AAAA,EACA,GAAA;AAAA,EACA,QAAA;AAAA,EACA,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAa;AAEX,EAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,YAAA,EAAc;AACzC,IAAA,MAAM,cAAA,GACJ,OAAO,QAAA,KAAa,QAAA,IACnB,MAAM,OAAA,CAAQ,QAAQ,CAAA,IACrB,QAAA,CAAS,IAAA,CAAK,CAAC,KAAA,KAAU,OAAO,UAAU,QAAQ,CAAA;AAEtD,IAAA,IAAI,CAAC,cAAA,IAAkB,CAAC,KAAA,CAAM,YAAY,CAAA,EAAG;AAC3C,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN;AAAA,OACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,uBACEL,cAAA;AAAA,IAACM,uBAAA;AAAA,IAAA;AAAA,MACC,EAAA;AAAA,MACA,UAAA;AAAA,MACA,IAAA;AAAA,MACA,MAAA;AAAA,MACA,GAAA;AAAA,MACA,QAAA;AAAA,MACA,SAAA,EAAWF,sCAAA;AAAA,QAAmB,SAAA;AAAA,QAAW,CAACC,UAAAA,KACxC,EAAA,CAAG,WAAA,IAAeA,UAAS;AAAA,OAC7B;AAAA,MACC,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ;AAEA,YAAA,CAAa,WAAA,GAAc,KAAA;AA0B3B,SAAS,iBAAA,CAAkB;AAAA,EACzB,QAAA;AAAA,EACA,EAAA;AAAA,EACA,gBAAA,GAAmB,KAAA;AAAA,EACnB,aAAA,GAAgB,KAAA;AAAA,EAChB,SAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAkB;AAEhB,EAAA,MAAM,aAAa,aAAA,IAAiB,gBAAA;AAIpC,EAAA,IAAI,OAAO,aAAa,UAAA,EAAY;AAClC,IAAA,uBACEL,cAAA;AAAA,MAACO,4BAAA;AAAA,MAAA;AAAA,QACC,EAAA;AAAA,QACA,gBAAA,EAAkB,UAAA;AAAA,QAClB,SAAA,EAAWH,sCAAA;AAAA,UAAmB,SAAA;AAAA,UAAW,CAACC,UAAAA,KACxC,EAAA,CAAG,gBAAA,IAAoBA,UAAS;AAAA,SAClC;AAAA,QACC,GAAG,KAAA;AAAA,QAEH,WAAC,WAAA,KAAgB;AAGhB,UAAA,MAAM,UAAA,GAAa,CAAC,WAAA,CAAY,OAAA;AAChC,UAAA,MAAM,OAAA,GACJ,QAAA,CACA,EAAE,UAAA,EAAY,CAAA;AAEhB,UAAA,IAAI,aAAA,EAAe;AACjB,YAAA,sCACG,QAAA,EAAA,EAAS,IAAA,EAAM,UAAA,GAAa,SAAA,GAAY,UACtC,QAAA,EAAA,OAAA,EACH,CAAA;AAAA,UAEJ;AAEA,UAAA,OAAO,OAAA;AAAA,QACT;AAAA;AAAA,KACF;AAAA,EAEJ;AAIA,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,uBACEL,cAAA;AAAA,MAACO,4BAAA;AAAA,MAAA;AAAA,QACC,EAAA;AAAA,QACA,gBAAA,EAAkB,UAAA;AAAA,QAClB,SAAA,EAAWH,sCAAA;AAAA,UAAmB,SAAA;AAAA,UAAW,CAACC,UAAAA,KACxC,EAAA,CAAG,gBAAA,IAAoBA,UAAS;AAAA,SAClC;AAAA,QACC,GAAG,KAAA;AAAA,QAEH,WAAC,WAAA,KAAgB;AAChB,UAAA,MAAM,UAAA,GAAa,CAAC,WAAA,CAAY,OAAA;AAChC,UAAA,sCACG,QAAA,EAAA,EAAS,IAAA,EAAM,UAAA,GAAa,SAAA,GAAY,UACtC,QAAA,EACH,CAAA;AAAA,QAEJ;AAAA;AAAA,KACF;AAAA,EAEJ;AAGA,EAAA,uBACEL,cAAA;AAAA,IAACO,4BAAA;AAAA,IAAA;AAAA,MACC,EAAA;AAAA,MACA,gBAAA,EAAkB,UAAA;AAAA,MAClB,SAAA,EAAWH,sCAAA;AAAA,QAAmB,SAAA;AAAA,QAAW,CAACC,UAAAA,KACxC,EAAA,CAAG,gBAAA,IAAoBA,UAAS;AAAA,OAClC;AAAA,MACC,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ;AAEA,iBAAA,CAAkB,WAAA,GAAc,UAAA;AAgBzB,IAAM,IAAA,GAAO;AACb,IAAM,OAAA,GAAU;AAChB,IAAM,GAAA,GAAM;AACZ,IAAM,QAAA,GAAW;ACxZjB,IAAM,wBAAA,GAA2BG,MAAE,MAAA,CAAO;AAAA;AAAA,EAE/C,SAAA,EAAWA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAG/B,QAAA,EAAUA,KAAA,CAAE,GAAA,EAAI,CAAE,QAAA,EAAS;AAAA;AAAA,EAC3B,EAAA,EAAIA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAGxB,YAAA,EAAcA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EAClC,iBAAA,EAAmBA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EACvC,kBAAA,EAAoBA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA,EACxC,WAAA,EAAaA,MAAE,IAAA,CAAK,CAAC,OAAO,QAAA,EAAU,WAAW,CAAC,CAAA,CAAE,QAAA,EAAS;AAAA,EAC7D,aAAA,EAAeA,KAAA,CAAE,OAAA,EAAQ,CAAE,QAAA,EAAS;AAAA;AAAA,EAGpC,aAAA,EAAeA,KAAA,CAAE,MAAA,EAAO,CAAE,QAAA;AAC5B,CAAC,CAAA;;;ACjBM,IAAM,wBAAwBA,KAAAA,CAAE,IAAA,CAAK,CAAC,YAAA,EAAc,UAAU,CAAC;AAQ/D,IAAM,+BAA+BA,KAAAA,CAAE,IAAA,CAAK,CAAC,WAAA,EAAa,QAAQ,CAAC;AAOnE,IAAM,SAAA,GAAYA,KAAAA,CAAE,KAAA,CAAM,CAACA,KAAAA,CAAE,QAAO,EAAGA,KAAAA,CAAE,MAAA,EAAQ,CAAC;AASlD,IAAM,eAAA,GAAkB,yBAAyB,MAAA,CAAO;AAAA;AAAA,EAE7D,WAAA,EAAa,UAAU,QAAA,EAAS;AAAA;AAAA,EAGhC,kBAAA,EAAoB,UAAU,QAAA,EAAS;AAAA;AAAA,EAGvC,iBAAA,EAAmBA,KAAAA,CAAE,MAAA,EAA2B,CAAE,QAAA,EAAS;AAAA;AAAA,EAG3D,WAAA,EAAa,qBAAA,CAAsB,QAAA,EAAS,CAAE,QAAQ,YAAY,CAAA;AAAA;AAAA,EAGlE,kBAAA,EAAoB,4BAAA,CAA6B,QAAA,EAAS,CAAE,QAAQ,WAAW,CAAA;AAAA;AAAA,EAG/E,YAAYA,KAAAA,CAAE,OAAA,GAAU,QAAA,EAAS,CAAE,QAAQ,KAAK,CAAA;AAAA;AAAA,EAGhD,YAAA,EAAcA,KAAAA,CAAE,KAAA,CAAM,SAAS,EAAE,QAAA,EAAS;AAAA;AAAA,EAG1C,QAAA,EAAUA,MAAE,MAAA;AACd,CAAC;AAUM,IAAM,kBAAA,GAAqB,yBAAyB,MAAA,CAAO;AAAA;AAAA,EAEhE,YAAA,EAAcA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAGlC,iBAAA,EAAmBA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAGvC,QAAA,EAAUA,MAAE,MAAA;AACd,CAAC;AAWM,IAAM,cAAA,GAAiB,yBAAyB,MAAA,CAAO;AAAA;AAAA,EAE5D,EAAA,EAAI,SAAA;AAAA;AAAA,EAGJ,YAAYA,KAAAA,CAAE,OAAA,GAAU,QAAA,EAAS,CAAE,QAAQ,KAAK,CAAA;AAAA;AAAA,EAGhD,IAAA,EAAMA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAG1B,MAAA,EAAQA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAG5B,GAAA,EAAKA,KAAAA,CAAE,MAAA,EAAO,CAAE,QAAA,EAAS;AAAA;AAAA,EAGzB,QAAA,EAAUA,KAAAA,CAAE,KAAA,CAAM,CAACA,KAAAA,CAAE,MAAA,EAAO,EAAGA,KAAAA,CAAE,OAAA,EAAS,CAAC,CAAA,CAAE,QAAA,EAAS;AAAA;AAAA,EAGtD,QAAA,EAAUA,MAAE,MAAA;AACd,CAAC;AAWM,IAAM,mBAAA,GAAsB,yBAAyB,MAAA,CAAO;AAAA;AAAA,EAEjE,EAAA,EAAI,SAAA;AAAA;AAAA;AAAA,EAIJ,kBAAkBA,KAAAA,CAAE,OAAA,GAAU,QAAA,EAAS,CAAE,QAAQ,KAAK,CAAA;AAAA;AAAA;AAAA;AAAA,EAKtD,eAAeA,KAAAA,CAAE,OAAA,GAAU,QAAA,EAAS,CAAE,QAAQ,KAAK,CAAA;AAAA;AAAA,EAGnD,QAAA,EAAUA,MAAE,MAAA;AACd,CAAC;AASM,IAAM,0BAAA,GAA6BA,MAAE,IAAA,CAAK,CAAC,QAAQ,OAAA,EAAS,IAAA,EAAM,MAAM,CAAC;AAOzE,IAAM,sBAAA,GAAyB,yBAAyB,MAAA,CAAO;AAAA;AAAA,EAEpE,SAAA,EAAW,0BAAA;AAAA;AAAA,EAGX,YAAYA,KAAAA,CAAE,OAAA,GAAU,QAAA,EAAS,CAAE,QAAQ,KAAK,CAAA;AAAA;AAAA,EAGhD,OAAA,EAASA,MAAE,MAAA,EAAmB;AAAA;AAAA,EAG9B,YAAA,EAAcA,MAAE,MAAA;AAClB,CAAC","file":"index.js","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","'use client';\n\n/**\n * Tabs Component - Implementation\n *\n * Accessible tabbed interface component combining React Aria primitives with ShadCN styling.\n * Follows Themis library patterns with compound component structure and direct named exports.\n *\n * Key Features:\n * - React Aria Tabs for full accessibility (WCAG 2.2 AAA)\n * - CVA variants for orientation styling\n * - React 19.2 Activity API for state preservation (preserveState prop)\n * - Dual keyboard activation modes (automatic/manual)\n * - Support for icons, badges, and link-based tabs\n *\n * @see tabs-prd.md (Full requirements)\n * @see Tabs.types.ts (Zod schemas)\n * @see plan.md (Implementation approach)\n */\n\n// React 19.2 Activity API - may not be available in all builds\n// Import conditionally to support environments where Activity is unavailable\nimport {\n Activity as ReactActivity,\n type ReactNode,\n type Key,\n type ReactElement,\n} from 'react';\n\n// Activity component with fallback for environments where it's not available\n// The fallback simply renders children directly - no state preservation when Activity unavailable\n// Note: ActivityFallback doesn't actually preserve state; it's just a pass-through\nconst Activity = ReactActivity ?? function ActivityFallback({\n children,\n mode,\n}: {\n children: ReactNode;\n mode: 'visible' | 'hidden';\n}): ReactElement {\n // When Activity is not available, just render children directly\n // mode is ignored in the fallback\n return <div data-activity-mode={mode}>{children}</div>;\n};\nimport {\n Tabs as AriaTabs,\n TabList as AriaTabList,\n Tab as AriaTab,\n TabPanel as AriaTabPanel,\n composeRenderProps,\n type Key as AriaKey,\n} from 'react-aria-components';\nimport { cva } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport type {\n TabsProps,\n TabListProps,\n TabProps,\n TabPanelProps,\n} from './Tabs.types';\n\n// ============================================================================\n// CVA Variants\n// ============================================================================\n\n/**\n * TabList CVA variants\n *\n * @see PRD.md FR-002 (TabList Requirements)\n * @see PRD.md DS-001 (Design System - Layout)\n */\nexport const tabListVariants = cva(\n // Base styles\n [\n 'inline-flex items-center justify-center rounded-md p-1',\n 'bg-[var(--accent-background)] text-[var(--menu-muted)]',\n ],\n {\n variants: {\n orientation: {\n horizontal: 'h-10 flex-row gap-0',\n vertical: 'h-auto flex-col w-full gap-1',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n }\n);\n\n/**\n * Tab CVA variants\n *\n * @see PRD.md FR-003 (Tab Requirements)\n * @see PRD.md DS-002 (Design System - Tab Styling)\n * @see PRD.md AR-001 (Accessibility - 44×44px touch targets)\n */\nexport const tabVariants = cva(\n // Base styles\n [\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-sm',\n 'px-3 py-1.5 text-sm font-medium',\n 'ring-offset-[var(--content-background)] transition-all',\n 'focus-visible:outline-none focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2',\n // States via data attributes\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n 'data-[selected]:bg-[var(--content-background)] data-[selected]:text-[var(--content-foreground)]',\n 'data-[selected]:shadow-sm',\n // WCAG 2.2 AAA: 44×44px minimum touch target\n 'min-h-[44px]',\n ],\n {\n variants: {\n orientation: {\n horizontal: '',\n vertical: 'w-full justify-start',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n }\n);\n\n/**\n * TabPanel CVA variants\n *\n * @see PRD.md FR-004 (TabPanel Requirements)\n */\nexport const tabPanelVariants = cva(\n [\n 'mt-2 ring-offset-[var(--content-background)]',\n 'focus-visible:outline-none focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2',\n ],\n {\n variants: {},\n defaultVariants: {},\n }\n);\n\n// ============================================================================\n// Components\n// ============================================================================\n\n/**\n * Tabs Root Component\n *\n * Container for tabbed interface. Manages selection state and provides\n * context to child components.\n *\n * @see PRD.md FR-001 (Compound Component Pattern)\n * @see PRD.md FR-012 (Controlled Mode)\n * @see PRD.md FR-013 (Uncontrolled Mode)\n *\n * @example\n * // Uncontrolled\n * <Tabs defaultSelectedKey=\"tab1\">\n * <TabList aria-label=\"Navigation\">\n * <Tab id=\"tab1\">Tab 1</Tab>\n * <Tab id=\"tab2\">Tab 2</Tab>\n * </TabList>\n * <TabPanel id=\"tab1\">Content 1</TabPanel>\n * <TabPanel id=\"tab2\">Content 2</TabPanel>\n * </Tabs>\n *\n * @example\n * // Controlled\n * <Tabs selectedKey={selected} onSelectionChange={setSelected}>\n * ...\n * </Tabs>\n */\nfunction TabsRoot({\n children,\n selectedKey,\n defaultSelectedKey,\n onSelectionChange,\n orientation = 'horizontal',\n keyboardActivation = 'automatic',\n isDisabled = false,\n disabledKeys,\n className,\n ...props\n}: TabsProps) {\n return (\n <AriaTabs\n selectedKey={selectedKey}\n defaultSelectedKey={defaultSelectedKey}\n onSelectionChange={onSelectionChange as (key: Key) => void}\n orientation={orientation}\n keyboardActivation={keyboardActivation}\n isDisabled={isDisabled}\n disabledKeys={disabledKeys as Iterable<AriaKey> | undefined}\n className={cn(className)}\n {...props}\n >\n {children}\n </AriaTabs>\n );\n}\n\nTabsRoot.displayName = 'Tabs';\n\n/**\n * TabList Component\n *\n * Container for tab buttons. Uses roving tabindex for keyboard navigation.\n * Receives orientation from parent Tabs via React Aria context.\n *\n * @see PRD.md FR-002 (TabList Requirements)\n * @see PRD.md AR-001 (ARIA Requirements)\n */\nfunction TabListComponent({\n children,\n className,\n ...props\n}: TabListProps) {\n return (\n <AriaTabList\n className={composeRenderProps(className, (className, renderProps) =>\n cn(\n tabListVariants({ orientation: renderProps.orientation }),\n className\n )\n )}\n {...props}\n >\n {children}\n </AriaTabList>\n );\n}\n\nTabListComponent.displayName = 'TabList';\n\n/**\n * Tab Component\n *\n * Individual tab button. Can render as button or anchor (when href provided).\n * Supports icons and badges as children.\n *\n * @see PRD.md FR-003 (Tab Requirements)\n * @see PRD.md FR-007 (Disabled States)\n * @see PRD.md FR-013 (Icon Support)\n * @see PRD.md FR-014 (Link-based Tabs)\n */\nfunction TabComponent({\n children,\n id,\n isDisabled = false,\n href,\n target,\n rel,\n download,\n className,\n ...props\n}: TabProps) {\n // Warn if icon-only tab without aria-label\n if (process.env.NODE_ENV !== 'production') {\n const hasTextContent =\n typeof children === 'string' ||\n (Array.isArray(children) &&\n children.some((child) => typeof child === 'string'));\n\n if (!hasTextContent && !props['aria-label']) {\n console.warn(\n 'Tabs: Icon-only tabs should have an aria-label for accessibility.'\n );\n }\n }\n\n return (\n <AriaTab\n id={id}\n isDisabled={isDisabled}\n href={href}\n target={target}\n rel={rel}\n download={download}\n className={composeRenderProps(className, (className) =>\n cn(tabVariants(), className)\n )}\n {...props}\n >\n {children}\n </AriaTab>\n );\n}\n\nTabComponent.displayName = 'Tab';\n\n/**\n * TabPanel Component\n *\n * Content panel associated with a tab. Only the selected panel is visible.\n * Supports preserveState for React Activity state preservation.\n *\n * @see PRD.md FR-004 (TabPanel Requirements)\n * @see PRD.md FR-015 (Force Mount Panels)\n * @see PRD.md FR-016 (React Activity State Preservation)\n *\n * @example\n * // Default behavior - content unmounts when hidden\n * <TabPanel id=\"tab1\">Content</TabPanel>\n *\n * @example\n * // Legacy force mount - keeps content in DOM\n * <TabPanel id=\"tab1\" shouldForceMount>Form with state</TabPanel>\n *\n * @example\n * // React Activity - preserves state with proper effect cleanup\n * <TabPanel id=\"tab1\" preserveState>\n * <FormWithDraft />\n * </TabPanel>\n */\nfunction TabPanelComponent({\n children,\n id,\n shouldForceMount = false,\n preserveState = false,\n className,\n ...props\n}: TabPanelProps) {\n // preserveState takes precedence - both enable force mounting\n const forceMount = preserveState || shouldForceMount;\n\n // If children is a render function (for dynamic content based on selection state),\n // we need to use the render props pattern\n if (typeof children === 'function') {\n return (\n <AriaTabPanel\n id={id}\n shouldForceMount={forceMount}\n className={composeRenderProps(className, (className) =>\n cn(tabPanelVariants(), className)\n )}\n {...props}\n >\n {(renderProps) => {\n // React Aria TabPanelRenderProps includes: state, isInert\n // We derive isSelected from state - if state is undefined, panel is selected\n const isSelected = !renderProps.isInert;\n const content = (\n children as (renderProps: { isSelected: boolean }) => ReactNode\n )({ isSelected });\n\n if (preserveState) {\n return (\n <Activity mode={isSelected ? 'visible' : 'hidden'}>\n {content}\n </Activity>\n );\n }\n\n return content;\n }}\n </AriaTabPanel>\n );\n }\n\n // For static children (not a function), render directly\n // If preserveState is enabled, wrap in Activity\n if (preserveState) {\n return (\n <AriaTabPanel\n id={id}\n shouldForceMount={forceMount}\n className={composeRenderProps(className, (className) =>\n cn(tabPanelVariants(), className)\n )}\n {...props}\n >\n {(renderProps) => {\n const isSelected = !renderProps.isInert;\n return (\n <Activity mode={isSelected ? 'visible' : 'hidden'}>\n {children}\n </Activity>\n );\n }}\n </AriaTabPanel>\n );\n }\n\n // Default: render static children directly\n return (\n <AriaTabPanel\n id={id}\n shouldForceMount={forceMount}\n className={composeRenderProps(className, (className) =>\n cn(tabPanelVariants(), className)\n )}\n {...props}\n >\n {children}\n </AriaTabPanel>\n );\n}\n\nTabPanelComponent.displayName = 'TabPanel';\n\n// ============================================================================\n// Exports\n// ============================================================================\n\n/**\n * Direct named exports (not Object.assign compound pattern)\n *\n * Tabs follows React Aria's direct export pattern because:\n * - Simpler structure (only 4 components vs Dialog's 9)\n * - Better tree-shaking with named exports\n * - Clearer imports: import { Tabs, TabList, Tab, TabPanel } from '...'\n *\n * @see plan.md \"Why Direct Named Exports (Not Object.assign)?\"\n */\nexport const Tabs = TabsRoot;\nexport const TabList = TabListComponent;\nexport const Tab = TabComponent;\nexport const TabPanel = TabPanelComponent;\n\n// Re-export types for convenience\nexport type { TabsProps, TabListProps, TabProps, TabPanelProps };\n","import { z } from 'zod';\n\n/**\n * Base props schema for all Themis components\n * Ensures consistent accessibility and styling APIs across the library\n *\n * @see spec.md FR-009 to FR-014 (Accessibility Requirements)\n * @see constitution.md Principle IV (Accessibility First - WCAG 2.2 AA minimum)\n */\nexport const BaseComponentPropsSchema = z.object({\n // Styling\n className: z.string().optional(),\n\n // React\n children: z.any().optional(), // ReactNode not directly supported by Zod\n id: z.string().optional(),\n\n // Accessibility (WCAG 2.2 AA requirements)\n 'aria-label': z.string().optional(),\n 'aria-labelledby': z.string().optional(),\n 'aria-describedby': z.string().optional(),\n 'aria-live': z.enum(['off', 'polite', 'assertive']).optional(),\n 'aria-hidden': z.boolean().optional(),\n\n // Testing & Development\n 'data-testid': z.string().optional(),\n});\n\nexport type BaseComponentProps = z.infer<typeof BaseComponentPropsSchema>;\n","import { z } from 'zod';\nimport { BaseComponentPropsSchema } from '../../schemas/BaseComponentProps';\nimport type { ReactNode, Key } from 'react';\n\n/**\n * Tab orientation schema\n *\n * @see PRD.md FR-005 (Orientation Support)\n */\nexport const TabsOrientationSchema = z.enum(['horizontal', 'vertical']);\nexport type TabsOrientation = z.infer<typeof TabsOrientationSchema>;\n\n/**\n * Keyboard activation mode schema\n *\n * @see PRD.md FR-006 (Keyboard Activation Modes)\n */\nexport const TabsKeyboardActivationSchema = z.enum(['automatic', 'manual']);\nexport type TabsKeyboardActivation = z.infer<typeof TabsKeyboardActivationSchema>;\n\n/**\n * Key schema for tab identification\n * Supports both string and number keys per React Aria convention\n */\nexport const KeySchema = z.union([z.string(), z.number()]);\n\n/**\n * Tabs root component props schema\n *\n * @see PRD.md FR-001 (Compound Component Pattern)\n * @see PRD.md FR-012 (Controlled Mode)\n * @see PRD.md FR-013 (Uncontrolled Mode)\n */\nexport const TabsPropsSchema = BaseComponentPropsSchema.extend({\n // Controlled mode: selected tab key\n selectedKey: KeySchema.optional(),\n\n // Uncontrolled mode: default selected tab key\n defaultSelectedKey: KeySchema.optional(),\n\n // Selection change handler\n onSelectionChange: z.custom<(key: Key) => void>().optional(),\n\n // Orientation: horizontal or vertical layout\n orientation: TabsOrientationSchema.optional().default('horizontal'),\n\n // Keyboard activation: automatic (arrows select) or manual (arrows focus, Enter selects)\n keyboardActivation: TabsKeyboardActivationSchema.optional().default('automatic'),\n\n // Disable all tabs\n isDisabled: z.boolean().optional().default(false),\n\n // Keys of tabs to disable individually\n disabledKeys: z.array(KeySchema).optional(),\n\n // Children: TabList and TabPanel components\n children: z.custom<ReactNode>(),\n});\n\nexport type TabsProps = z.infer<typeof TabsPropsSchema>;\n\n/**\n * TabList component props schema\n *\n * @see PRD.md FR-002 (TabList Requirements)\n * @see PRD.md AR-001 (ARIA Requirements)\n */\nexport const TabListPropsSchema = BaseComponentPropsSchema.extend({\n // Accessible label (required for accessibility if no aria-labelledby)\n 'aria-label': z.string().optional(),\n\n // Reference to labelling element\n 'aria-labelledby': z.string().optional(),\n\n // Children: Tab components\n children: z.custom<ReactNode>(),\n});\n\nexport type TabListProps = z.infer<typeof TabListPropsSchema>;\n\n/**\n * Tab component props schema\n *\n * @see PRD.md FR-003 (Tab Requirements)\n * @see PRD.md FR-007 (Disabled States)\n * @see PRD.md FR-014 (Link-based Tabs)\n */\nexport const TabPropsSchema = BaseComponentPropsSchema.extend({\n // Unique identifier for the tab (required)\n id: KeySchema,\n\n // Disable this specific tab\n isDisabled: z.boolean().optional().default(false),\n\n // Link tab: URL for navigation-style tabs\n href: z.string().optional(),\n\n // Link tab: target attribute\n target: z.string().optional(),\n\n // Link tab: rel attribute\n rel: z.string().optional(),\n\n // Link tab: download attribute\n download: z.union([z.string(), z.boolean()]).optional(),\n\n // Tab content (text, icons, badges)\n children: z.custom<ReactNode>(),\n});\n\nexport type TabProps = z.infer<typeof TabPropsSchema>;\n\n/**\n * TabPanel component props schema\n *\n * @see PRD.md FR-004 (TabPanel Requirements)\n * @see PRD.md FR-015 (Force Mount Panels)\n * @see PRD.md FR-016 (React Activity State Preservation)\n */\nexport const TabPanelPropsSchema = BaseComponentPropsSchema.extend({\n // Unique identifier matching a Tab id (required)\n id: KeySchema,\n\n // Legacy: Force panel to stay in DOM when hidden\n // Use preserveState instead for proper effect cleanup\n shouldForceMount: z.boolean().optional().default(false),\n\n // React 19.2 Activity: Preserve state with proper effect cleanup\n // When true, wraps content in <Activity> component\n // Effects are cleaned up when hidden, restored when visible\n preserveState: z.boolean().optional().default(false),\n\n // Panel content\n children: z.custom<ReactNode>(),\n});\n\nexport type TabPanelProps = z.infer<typeof TabPanelPropsSchema>;\n\n/**\n * Scroll arrow direction for overflow handling\n *\n * @see PRD.md FR-010 (Overflow Handling)\n */\nexport const ScrollArrowDirectionSchema = z.enum(['left', 'right', 'up', 'down']);\nexport type ScrollArrowDirection = z.infer<typeof ScrollArrowDirectionSchema>;\n\n/**\n * Internal props for scroll arrow buttons\n * Used by overflow handling implementation\n */\nexport const ScrollArrowPropsSchema = BaseComponentPropsSchema.extend({\n // Scroll direction\n direction: ScrollArrowDirectionSchema,\n\n // Disable when can't scroll further\n isDisabled: z.boolean().optional().default(false),\n\n // Click handler for scrolling\n onPress: z.custom<() => void>(),\n\n // Accessible label\n 'aria-label': z.string(),\n});\n\nexport type ScrollArrowProps = z.infer<typeof ScrollArrowPropsSchema>;\n"]}
1
+ {"version":3,"sources":["../../../src/utils/cn.ts","../../../src/elements/Tabs/Tabs.tsx","../../../src/schemas/BaseComponentProps.ts","../../../src/elements/Tabs/Tabs.types.ts"],"names":["cn","inputs","twMerge","clsx","Activity","ReactActivity","children","mode","jsx","tabListVariants","cva","tabVariants","tabPanelVariants","TabsRoot","selectedKey","defaultSelectedKey","onSelectionChange","orientation","keyboardActivation","isDisabled","disabledKeys","className","props","AriaTabs","TabListComponent","AriaTabList","composeRenderProps","renderProps","TabComponent","id","href","target","rel","download","child","AriaTab","TabPanelComponent","shouldForceMount","preserveState","forceMount","AriaTabPanel","isSelected","content","Tabs","TabList","Tab","TabPanel","BaseComponentPropsSchema","z","TabsOrientationSchema","TabsKeyboardActivationSchema","KeySchema","TabsPropsSchema","TabListPropsSchema","TabPropsSchema","TabPanelPropsSchema","ScrollArrowDirectionSchema","ScrollArrowPropsSchema"],"mappings":"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","file":"index.js","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","'use client';\n\n/**\n * Tabs Component - Implementation\n *\n * Accessible tabbed interface component combining React Aria primitives with ShadCN styling.\n * Follows Themis library patterns with compound component structure and direct named exports.\n *\n * Key Features:\n * - React Aria Tabs for full accessibility (WCAG 2.2 AAA)\n * - CVA variants for orientation styling\n * - React 19.2 Activity API for state preservation (preserveState prop)\n * - Dual keyboard activation modes (automatic/manual)\n * - Support for icons, badges, and link-based tabs\n *\n * @see tabs-prd.md (Full requirements)\n * @see Tabs.types.ts (Zod schemas)\n * @see plan.md (Implementation approach)\n */\n\n// React 19.2 Activity API - may not be available in all builds\n// Import conditionally to support environments where Activity is unavailable\nimport {\n Activity as ReactActivity,\n type ReactNode,\n type Key,\n type ReactElement,\n} from 'react';\n\n// Activity component with fallback for environments where it's not available\n// The fallback simply renders children directly - no state preservation when Activity unavailable\n// Note: ActivityFallback doesn't actually preserve state; it's just a pass-through\nconst Activity = ReactActivity ?? function ActivityFallback({\n children,\n mode,\n}: {\n children: ReactNode;\n mode: 'visible' | 'hidden';\n}): ReactElement {\n // When Activity is not available, just render children directly\n // mode is ignored in the fallback\n return <div data-activity-mode={mode}>{children}</div>;\n};\nimport {\n Tabs as AriaTabs,\n TabList as AriaTabList,\n Tab as AriaTab,\n TabPanel as AriaTabPanel,\n composeRenderProps,\n type Key as AriaKey,\n} from 'react-aria-components';\nimport { cva } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport type {\n TabsProps,\n TabListProps,\n TabProps,\n TabPanelProps,\n} from './Tabs.types';\n\n// ============================================================================\n// CVA Variants\n// ============================================================================\n\n/**\n * TabList CVA variants\n *\n * @see PRD.md FR-002 (TabList Requirements)\n * @see PRD.md DS-001 (Design System - Layout)\n */\nexport const tabListVariants = cva(\n // Base styles\n [\n 'inline-flex items-center justify-center rounded-md p-1',\n 'bg-[var(--accent-background)] text-[var(--menu-muted)]',\n ],\n {\n variants: {\n orientation: {\n horizontal: 'h-10 flex-row gap-0',\n vertical: 'h-auto flex-col w-full gap-1',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n }\n);\n\n/**\n * Tab CVA variants\n *\n * @see PRD.md FR-003 (Tab Requirements)\n * @see PRD.md DS-002 (Design System - Tab Styling)\n * @see PRD.md AR-001 (Accessibility - 44×44px touch targets)\n */\nexport const tabVariants = cva(\n // Base styles\n [\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-sm',\n 'px-3 py-1.5 text-sm font-medium',\n 'ring-offset-[var(--content-background)] transition-all',\n 'focus-visible:outline-none focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2',\n // States via data attributes\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n 'data-[selected]:bg-[var(--content-background)] data-[selected]:text-[var(--content-foreground)]',\n 'data-[selected]:shadow-sm',\n // WCAG 2.2 AAA: 44×44px minimum touch target\n 'min-h-[44px]',\n ],\n {\n variants: {\n orientation: {\n horizontal: '',\n vertical: 'w-full justify-start',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n }\n);\n\n/**\n * TabPanel CVA variants\n *\n * @see PRD.md FR-004 (TabPanel Requirements)\n */\nexport const tabPanelVariants = cva(\n [\n 'mt-2 ring-offset-[var(--content-background)]',\n 'focus-visible:outline-none focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2',\n ],\n {\n variants: {},\n defaultVariants: {},\n }\n);\n\n// ============================================================================\n// Components\n// ============================================================================\n\n/**\n * Tabs Root Component\n *\n * Container for tabbed interface. Manages selection state and provides\n * context to child components.\n *\n * @see PRD.md FR-001 (Compound Component Pattern)\n * @see PRD.md FR-012 (Controlled Mode)\n * @see PRD.md FR-013 (Uncontrolled Mode)\n *\n * @example\n * // Uncontrolled\n * <Tabs defaultSelectedKey=\"tab1\">\n * <TabList aria-label=\"Navigation\">\n * <Tab id=\"tab1\">Tab 1</Tab>\n * <Tab id=\"tab2\">Tab 2</Tab>\n * </TabList>\n * <TabPanel id=\"tab1\">Content 1</TabPanel>\n * <TabPanel id=\"tab2\">Content 2</TabPanel>\n * </Tabs>\n *\n * @example\n * // Controlled\n * <Tabs selectedKey={selected} onSelectionChange={setSelected}>\n * ...\n * </Tabs>\n */\nfunction TabsRoot({\n children,\n selectedKey,\n defaultSelectedKey,\n onSelectionChange,\n orientation = 'horizontal',\n keyboardActivation = 'automatic',\n isDisabled = false,\n disabledKeys,\n className,\n ...props\n}: TabsProps) {\n return (\n <AriaTabs\n selectedKey={selectedKey}\n defaultSelectedKey={defaultSelectedKey}\n onSelectionChange={onSelectionChange as (key: Key) => void}\n orientation={orientation}\n keyboardActivation={keyboardActivation}\n isDisabled={isDisabled}\n disabledKeys={disabledKeys as Iterable<AriaKey> | undefined}\n className={cn(className)}\n {...props}\n >\n {children}\n </AriaTabs>\n );\n}\n\nTabsRoot.displayName = 'Tabs';\n\n/**\n * TabList Component\n *\n * Container for tab buttons. Uses roving tabindex for keyboard navigation.\n * Receives orientation from parent Tabs via React Aria context.\n *\n * @see PRD.md FR-002 (TabList Requirements)\n * @see PRD.md AR-001 (ARIA Requirements)\n */\nfunction TabListComponent({\n children,\n className,\n ...props\n}: TabListProps) {\n return (\n <AriaTabList\n className={composeRenderProps(className, (className, renderProps) =>\n cn(\n tabListVariants({ orientation: renderProps.orientation }),\n className\n )\n )}\n {...props}\n >\n {children}\n </AriaTabList>\n );\n}\n\nTabListComponent.displayName = 'TabList';\n\n/**\n * Tab Component\n *\n * Individual tab button. Can render as button or anchor (when href provided).\n * Supports icons and badges as children.\n *\n * @see PRD.md FR-003 (Tab Requirements)\n * @see PRD.md FR-007 (Disabled States)\n * @see PRD.md FR-013 (Icon Support)\n * @see PRD.md FR-014 (Link-based Tabs)\n */\nfunction TabComponent({\n children,\n id,\n isDisabled = false,\n href,\n target,\n rel,\n download,\n className,\n ...props\n}: TabProps) {\n // Warn if icon-only tab without aria-label\n if (process.env.NODE_ENV !== 'production') {\n const hasTextContent =\n typeof children === 'string' ||\n (Array.isArray(children) &&\n children.some((child) => typeof child === 'string'));\n\n if (!hasTextContent && !props['aria-label']) {\n console.warn(\n 'Tabs: Icon-only tabs should have an aria-label for accessibility.'\n );\n }\n }\n\n return (\n <AriaTab\n id={id}\n isDisabled={isDisabled}\n href={href}\n target={target}\n rel={rel}\n download={download}\n className={composeRenderProps(className, (className) =>\n cn(tabVariants(), className)\n )}\n {...props}\n >\n {children}\n </AriaTab>\n );\n}\n\nTabComponent.displayName = 'Tab';\n\n/**\n * TabPanel Component\n *\n * Content panel associated with a tab. Only the selected panel is visible.\n * Supports preserveState for React Activity state preservation.\n *\n * @see PRD.md FR-004 (TabPanel Requirements)\n * @see PRD.md FR-015 (Force Mount Panels)\n * @see PRD.md FR-016 (React Activity State Preservation)\n *\n * @example\n * // Default behavior - content unmounts when hidden\n * <TabPanel id=\"tab1\">Content</TabPanel>\n *\n * @example\n * // Legacy force mount - keeps content in DOM\n * <TabPanel id=\"tab1\" shouldForceMount>Form with state</TabPanel>\n *\n * @example\n * // React Activity - preserves state with proper effect cleanup\n * <TabPanel id=\"tab1\" preserveState>\n * <FormWithDraft />\n * </TabPanel>\n */\nfunction TabPanelComponent({\n children,\n id,\n shouldForceMount = false,\n preserveState = false,\n className,\n ...props\n}: TabPanelProps) {\n // preserveState takes precedence - both enable force mounting\n const forceMount = preserveState || shouldForceMount;\n\n // If children is a render function (for dynamic content based on selection state),\n // we need to use the render props pattern\n if (typeof children === 'function') {\n return (\n <AriaTabPanel\n id={id}\n shouldForceMount={forceMount}\n className={composeRenderProps(className, (className) =>\n cn(tabPanelVariants(), className)\n )}\n {...props}\n >\n {(renderProps) => {\n // React Aria TabPanelRenderProps includes: state, isInert\n // We derive isSelected from state - if state is undefined, panel is selected\n const isSelected = !renderProps.isInert;\n const content = (\n children as (renderProps: { isSelected: boolean }) => ReactNode\n )({ isSelected });\n\n if (preserveState) {\n return (\n <Activity mode={isSelected ? 'visible' : 'hidden'}>\n {content}\n </Activity>\n );\n }\n\n return content;\n }}\n </AriaTabPanel>\n );\n }\n\n // For static children (not a function), render directly\n // If preserveState is enabled, wrap in Activity\n if (preserveState) {\n return (\n <AriaTabPanel\n id={id}\n shouldForceMount={forceMount}\n className={composeRenderProps(className, (className) =>\n cn(tabPanelVariants(), className)\n )}\n {...props}\n >\n {(renderProps) => {\n const isSelected = !renderProps.isInert;\n return (\n <Activity mode={isSelected ? 'visible' : 'hidden'}>\n {children}\n </Activity>\n );\n }}\n </AriaTabPanel>\n );\n }\n\n // Default: render static children directly\n return (\n <AriaTabPanel\n id={id}\n shouldForceMount={forceMount}\n className={composeRenderProps(className, (className) =>\n cn(tabPanelVariants(), className)\n )}\n {...props}\n >\n {children}\n </AriaTabPanel>\n );\n}\n\nTabPanelComponent.displayName = 'TabPanel';\n\n// ============================================================================\n// Exports\n// ============================================================================\n\n/**\n * Direct named exports (not Object.assign compound pattern)\n *\n * Tabs follows React Aria's direct export pattern because:\n * - Simpler structure (only 4 components vs Dialog's 9)\n * - Better tree-shaking with named exports\n * - Clearer imports: import { Tabs, TabList, Tab, TabPanel } from '...'\n *\n * @see plan.md \"Why Direct Named Exports (Not Object.assign)?\"\n */\nexport const Tabs = TabsRoot;\nexport const TabList = TabListComponent;\nexport const Tab = TabComponent;\nexport const TabPanel = TabPanelComponent;\n\n// Re-export types for convenience\nexport type { TabsProps, TabListProps, TabProps, TabPanelProps };\n","import { z } from 'zod';\n\n/**\n * Base props schema for all Themis components\n * Ensures consistent accessibility and styling APIs across the library\n *\n * @see spec.md FR-009 to FR-014 (Accessibility Requirements)\n * @see constitution.md Principle IV (Accessibility First - WCAG 2.2 AA minimum)\n */\nexport const BaseComponentPropsSchema = z.object({\n // Styling\n className: z.string().optional(),\n\n // React\n children: z.any().optional(), // ReactNode not directly supported by Zod\n id: z.string().optional(),\n\n // Accessibility (WCAG 2.2 AA requirements)\n 'aria-label': z.string().optional(),\n 'aria-labelledby': z.string().optional(),\n 'aria-describedby': z.string().optional(),\n 'aria-live': z.enum(['off', 'polite', 'assertive']).optional(),\n 'aria-hidden': z.boolean().optional(),\n\n // Testing & Development\n 'data-testid': z.string().optional(),\n});\n\nexport type BaseComponentProps = z.infer<typeof BaseComponentPropsSchema>;\n","import { z } from 'zod';\nimport { BaseComponentPropsSchema } from '../../schemas/BaseComponentProps';\nimport type { ReactNode, Key } from 'react';\n\n/**\n * Tab orientation schema\n *\n * @see PRD.md FR-005 (Orientation Support)\n */\nexport const TabsOrientationSchema = z.enum(['horizontal', 'vertical']);\nexport type TabsOrientation = z.infer<typeof TabsOrientationSchema>;\n\n/**\n * Keyboard activation mode schema\n *\n * @see PRD.md FR-006 (Keyboard Activation Modes)\n */\nexport const TabsKeyboardActivationSchema = z.enum(['automatic', 'manual']);\nexport type TabsKeyboardActivation = z.infer<typeof TabsKeyboardActivationSchema>;\n\n/**\n * Key schema for tab identification\n * Supports both string and number keys per React Aria convention\n */\nexport const KeySchema = z.union([z.string(), z.number()]);\n\n/**\n * Tabs root component props schema\n *\n * @see PRD.md FR-001 (Compound Component Pattern)\n * @see PRD.md FR-012 (Controlled Mode)\n * @see PRD.md FR-013 (Uncontrolled Mode)\n */\nexport const TabsPropsSchema = BaseComponentPropsSchema.extend({\n // Controlled mode: selected tab key\n selectedKey: KeySchema.optional(),\n\n // Uncontrolled mode: default selected tab key\n defaultSelectedKey: KeySchema.optional(),\n\n // Selection change handler\n onSelectionChange: z.custom<(key: Key) => void>().optional(),\n\n // Orientation: horizontal or vertical layout\n orientation: TabsOrientationSchema.optional().default('horizontal'),\n\n // Keyboard activation: automatic (arrows select) or manual (arrows focus, Enter selects)\n keyboardActivation: TabsKeyboardActivationSchema.optional().default('automatic'),\n\n // Disable all tabs\n isDisabled: z.boolean().optional().default(false),\n\n // Keys of tabs to disable individually\n disabledKeys: z.array(KeySchema).optional(),\n\n // Children: TabList and TabPanel components\n children: z.custom<ReactNode>(),\n});\n\nexport type TabsProps = z.infer<typeof TabsPropsSchema>;\n\n/**\n * TabList component props schema\n *\n * @see PRD.md FR-002 (TabList Requirements)\n * @see PRD.md AR-001 (ARIA Requirements)\n */\nexport const TabListPropsSchema = BaseComponentPropsSchema.extend({\n // Accessible label (required for accessibility if no aria-labelledby)\n 'aria-label': z.string().optional(),\n\n // Reference to labelling element\n 'aria-labelledby': z.string().optional(),\n\n // Children: Tab components\n children: z.custom<ReactNode>(),\n});\n\nexport type TabListProps = z.infer<typeof TabListPropsSchema>;\n\n/**\n * Tab component props schema\n *\n * @see PRD.md FR-003 (Tab Requirements)\n * @see PRD.md FR-007 (Disabled States)\n * @see PRD.md FR-014 (Link-based Tabs)\n */\nexport const TabPropsSchema = BaseComponentPropsSchema.extend({\n // Unique identifier for the tab (required)\n id: KeySchema,\n\n // Disable this specific tab\n isDisabled: z.boolean().optional().default(false),\n\n // Link tab: URL for navigation-style tabs\n href: z.string().optional(),\n\n // Link tab: target attribute\n target: z.string().optional(),\n\n // Link tab: rel attribute\n rel: z.string().optional(),\n\n // Link tab: download attribute\n download: z.union([z.string(), z.boolean()]).optional(),\n\n // Tab content (text, icons, badges)\n children: z.custom<ReactNode>(),\n});\n\nexport type TabProps = z.infer<typeof TabPropsSchema>;\n\n/**\n * TabPanel component props schema\n *\n * @see PRD.md FR-004 (TabPanel Requirements)\n * @see PRD.md FR-015 (Force Mount Panels)\n * @see PRD.md FR-016 (React Activity State Preservation)\n */\nexport const TabPanelPropsSchema = BaseComponentPropsSchema.extend({\n // Unique identifier matching a Tab id (required)\n id: KeySchema,\n\n // Legacy: Force panel to stay in DOM when hidden\n // Use preserveState instead for proper effect cleanup\n shouldForceMount: z.boolean().optional().default(false),\n\n // React 19.2 Activity: Preserve state with proper effect cleanup\n // When true, wraps content in <Activity> component\n // Effects are cleaned up when hidden, restored when visible\n preserveState: z.boolean().optional().default(false),\n\n // Panel content\n children: z.custom<ReactNode>(),\n});\n\nexport type TabPanelProps = z.infer<typeof TabPanelPropsSchema>;\n\n/**\n * Scroll arrow direction for overflow handling\n *\n * @see PRD.md FR-010 (Overflow Handling)\n */\nexport const ScrollArrowDirectionSchema = z.enum(['left', 'right', 'up', 'down']);\nexport type ScrollArrowDirection = z.infer<typeof ScrollArrowDirectionSchema>;\n\n/**\n * Internal props for scroll arrow buttons\n * Used by overflow handling implementation\n */\nexport const ScrollArrowPropsSchema = BaseComponentPropsSchema.extend({\n // Scroll direction\n direction: ScrollArrowDirectionSchema,\n\n // Disable when can't scroll further\n isDisabled: z.boolean().optional().default(false),\n\n // Click handler for scrolling\n onPress: z.custom<() => void>(),\n\n // Accessible label\n 'aria-label': z.string(),\n});\n\nexport type ScrollArrowProps = z.infer<typeof ScrollArrowPropsSchema>;\n"]}
@@ -1,322 +1,3 @@
1
1
  "use client";
2
- import { Activity as Activity$1 } from 'react';
3
- import { Tabs as Tabs$1, TabList as TabList$1, composeRenderProps, Tab as Tab$1, TabPanel as TabPanel$1 } from 'react-aria-components';
4
- import { cva } from 'class-variance-authority';
5
- import { clsx } from 'clsx';
6
- import { twMerge } from 'tailwind-merge';
7
- import { jsx } from 'react/jsx-runtime';
8
- import { z } from 'zod';
9
-
10
- // src/elements/Tabs/Tabs.tsx
11
- function cn(...inputs) {
12
- return twMerge(clsx(inputs));
13
- }
14
- var Activity = Activity$1 ?? function ActivityFallback({
15
- children,
16
- mode
17
- }) {
18
- return /* @__PURE__ */ jsx("div", { "data-activity-mode": mode, children });
19
- };
20
- var tabListVariants = cva(
21
- // Base styles
22
- [
23
- "inline-flex items-center justify-center rounded-md p-1",
24
- "bg-[var(--accent-background)] text-[var(--menu-muted)]"
25
- ],
26
- {
27
- variants: {
28
- orientation: {
29
- horizontal: "h-10 flex-row gap-0",
30
- vertical: "h-auto flex-col w-full gap-1"
31
- }
32
- },
33
- defaultVariants: {
34
- orientation: "horizontal"
35
- }
36
- }
37
- );
38
- var tabVariants = cva(
39
- // Base styles
40
- [
41
- "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-sm",
42
- "px-3 py-1.5 text-sm font-medium",
43
- "ring-offset-[var(--content-background)] transition-all",
44
- "focus-visible:outline-none focus-visible:ring-2",
45
- "focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2",
46
- // States via data attributes
47
- "data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
48
- "data-[selected]:bg-[var(--content-background)] data-[selected]:text-[var(--content-foreground)]",
49
- "data-[selected]:shadow-sm",
50
- // WCAG 2.2 AAA: 44×44px minimum touch target
51
- "min-h-[44px]"
52
- ],
53
- {
54
- variants: {
55
- orientation: {
56
- horizontal: "",
57
- vertical: "w-full justify-start"
58
- }
59
- },
60
- defaultVariants: {
61
- orientation: "horizontal"
62
- }
63
- }
64
- );
65
- var tabPanelVariants = cva(
66
- [
67
- "mt-2 ring-offset-[var(--content-background)]",
68
- "focus-visible:outline-none focus-visible:ring-2",
69
- "focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2"
70
- ],
71
- {
72
- variants: {},
73
- defaultVariants: {}
74
- }
75
- );
76
- function TabsRoot({
77
- children,
78
- selectedKey,
79
- defaultSelectedKey,
80
- onSelectionChange,
81
- orientation = "horizontal",
82
- keyboardActivation = "automatic",
83
- isDisabled = false,
84
- disabledKeys,
85
- className,
86
- ...props
87
- }) {
88
- return /* @__PURE__ */ jsx(
89
- Tabs$1,
90
- {
91
- selectedKey,
92
- defaultSelectedKey,
93
- onSelectionChange,
94
- orientation,
95
- keyboardActivation,
96
- isDisabled,
97
- disabledKeys,
98
- className: cn(className),
99
- ...props,
100
- children
101
- }
102
- );
103
- }
104
- TabsRoot.displayName = "Tabs";
105
- function TabListComponent({
106
- children,
107
- className,
108
- ...props
109
- }) {
110
- return /* @__PURE__ */ jsx(
111
- TabList$1,
112
- {
113
- className: composeRenderProps(
114
- className,
115
- (className2, renderProps) => cn(
116
- tabListVariants({ orientation: renderProps.orientation }),
117
- className2
118
- )
119
- ),
120
- ...props,
121
- children
122
- }
123
- );
124
- }
125
- TabListComponent.displayName = "TabList";
126
- function TabComponent({
127
- children,
128
- id,
129
- isDisabled = false,
130
- href,
131
- target,
132
- rel,
133
- download,
134
- className,
135
- ...props
136
- }) {
137
- if (process.env.NODE_ENV !== "production") {
138
- const hasTextContent = typeof children === "string" || Array.isArray(children) && children.some((child) => typeof child === "string");
139
- if (!hasTextContent && !props["aria-label"]) {
140
- console.warn(
141
- "Tabs: Icon-only tabs should have an aria-label for accessibility."
142
- );
143
- }
144
- }
145
- return /* @__PURE__ */ jsx(
146
- Tab$1,
147
- {
148
- id,
149
- isDisabled,
150
- href,
151
- target,
152
- rel,
153
- download,
154
- className: composeRenderProps(
155
- className,
156
- (className2) => cn(tabVariants(), className2)
157
- ),
158
- ...props,
159
- children
160
- }
161
- );
162
- }
163
- TabComponent.displayName = "Tab";
164
- function TabPanelComponent({
165
- children,
166
- id,
167
- shouldForceMount = false,
168
- preserveState = false,
169
- className,
170
- ...props
171
- }) {
172
- const forceMount = preserveState || shouldForceMount;
173
- if (typeof children === "function") {
174
- return /* @__PURE__ */ jsx(
175
- TabPanel$1,
176
- {
177
- id,
178
- shouldForceMount: forceMount,
179
- className: composeRenderProps(
180
- className,
181
- (className2) => cn(tabPanelVariants(), className2)
182
- ),
183
- ...props,
184
- children: (renderProps) => {
185
- const isSelected = !renderProps.isInert;
186
- const content = children({ isSelected });
187
- if (preserveState) {
188
- return /* @__PURE__ */ jsx(Activity, { mode: isSelected ? "visible" : "hidden", children: content });
189
- }
190
- return content;
191
- }
192
- }
193
- );
194
- }
195
- if (preserveState) {
196
- return /* @__PURE__ */ jsx(
197
- TabPanel$1,
198
- {
199
- id,
200
- shouldForceMount: forceMount,
201
- className: composeRenderProps(
202
- className,
203
- (className2) => cn(tabPanelVariants(), className2)
204
- ),
205
- ...props,
206
- children: (renderProps) => {
207
- const isSelected = !renderProps.isInert;
208
- return /* @__PURE__ */ jsx(Activity, { mode: isSelected ? "visible" : "hidden", children });
209
- }
210
- }
211
- );
212
- }
213
- return /* @__PURE__ */ jsx(
214
- TabPanel$1,
215
- {
216
- id,
217
- shouldForceMount: forceMount,
218
- className: composeRenderProps(
219
- className,
220
- (className2) => cn(tabPanelVariants(), className2)
221
- ),
222
- ...props,
223
- children
224
- }
225
- );
226
- }
227
- TabPanelComponent.displayName = "TabPanel";
228
- var Tabs = TabsRoot;
229
- var TabList = TabListComponent;
230
- var Tab = TabComponent;
231
- var TabPanel = TabPanelComponent;
232
- var BaseComponentPropsSchema = z.object({
233
- // Styling
234
- className: z.string().optional(),
235
- // React
236
- children: z.any().optional(),
237
- // ReactNode not directly supported by Zod
238
- id: z.string().optional(),
239
- // Accessibility (WCAG 2.2 AA requirements)
240
- "aria-label": z.string().optional(),
241
- "aria-labelledby": z.string().optional(),
242
- "aria-describedby": z.string().optional(),
243
- "aria-live": z.enum(["off", "polite", "assertive"]).optional(),
244
- "aria-hidden": z.boolean().optional(),
245
- // Testing & Development
246
- "data-testid": z.string().optional()
247
- });
248
-
249
- // src/elements/Tabs/Tabs.types.ts
250
- var TabsOrientationSchema = z.enum(["horizontal", "vertical"]);
251
- var TabsKeyboardActivationSchema = z.enum(["automatic", "manual"]);
252
- var KeySchema = z.union([z.string(), z.number()]);
253
- var TabsPropsSchema = BaseComponentPropsSchema.extend({
254
- // Controlled mode: selected tab key
255
- selectedKey: KeySchema.optional(),
256
- // Uncontrolled mode: default selected tab key
257
- defaultSelectedKey: KeySchema.optional(),
258
- // Selection change handler
259
- onSelectionChange: z.custom().optional(),
260
- // Orientation: horizontal or vertical layout
261
- orientation: TabsOrientationSchema.optional().default("horizontal"),
262
- // Keyboard activation: automatic (arrows select) or manual (arrows focus, Enter selects)
263
- keyboardActivation: TabsKeyboardActivationSchema.optional().default("automatic"),
264
- // Disable all tabs
265
- isDisabled: z.boolean().optional().default(false),
266
- // Keys of tabs to disable individually
267
- disabledKeys: z.array(KeySchema).optional(),
268
- // Children: TabList and TabPanel components
269
- children: z.custom()
270
- });
271
- var TabListPropsSchema = BaseComponentPropsSchema.extend({
272
- // Accessible label (required for accessibility if no aria-labelledby)
273
- "aria-label": z.string().optional(),
274
- // Reference to labelling element
275
- "aria-labelledby": z.string().optional(),
276
- // Children: Tab components
277
- children: z.custom()
278
- });
279
- var TabPropsSchema = BaseComponentPropsSchema.extend({
280
- // Unique identifier for the tab (required)
281
- id: KeySchema,
282
- // Disable this specific tab
283
- isDisabled: z.boolean().optional().default(false),
284
- // Link tab: URL for navigation-style tabs
285
- href: z.string().optional(),
286
- // Link tab: target attribute
287
- target: z.string().optional(),
288
- // Link tab: rel attribute
289
- rel: z.string().optional(),
290
- // Link tab: download attribute
291
- download: z.union([z.string(), z.boolean()]).optional(),
292
- // Tab content (text, icons, badges)
293
- children: z.custom()
294
- });
295
- var TabPanelPropsSchema = BaseComponentPropsSchema.extend({
296
- // Unique identifier matching a Tab id (required)
297
- id: KeySchema,
298
- // Legacy: Force panel to stay in DOM when hidden
299
- // Use preserveState instead for proper effect cleanup
300
- shouldForceMount: z.boolean().optional().default(false),
301
- // React 19.2 Activity: Preserve state with proper effect cleanup
302
- // When true, wraps content in <Activity> component
303
- // Effects are cleaned up when hidden, restored when visible
304
- preserveState: z.boolean().optional().default(false),
305
- // Panel content
306
- children: z.custom()
307
- });
308
- var ScrollArrowDirectionSchema = z.enum(["left", "right", "up", "down"]);
309
- var ScrollArrowPropsSchema = BaseComponentPropsSchema.extend({
310
- // Scroll direction
311
- direction: ScrollArrowDirectionSchema,
312
- // Disable when can't scroll further
313
- isDisabled: z.boolean().optional().default(false),
314
- // Click handler for scrolling
315
- onPress: z.custom(),
316
- // Accessible label
317
- "aria-label": z.string()
318
- });
319
-
320
- export { KeySchema, ScrollArrowDirectionSchema, ScrollArrowPropsSchema, Tab, TabList, TabListPropsSchema, TabPanel, TabPanelPropsSchema, TabPropsSchema, Tabs, TabsKeyboardActivationSchema, TabsOrientationSchema, TabsPropsSchema, tabListVariants, tabPanelVariants, tabVariants };
321
- //# sourceMappingURL=index.mjs.map
2
+ import {Activity}from'react';import {Tabs,TabList,composeRenderProps,Tab,TabPanel}from'react-aria-components';import {cva}from'class-variance-authority';import {clsx}from'clsx';import {twMerge}from'tailwind-merge';import {jsx}from'react/jsx-runtime';import {z as z$1}from'zod';function m(...a){return twMerge(clsx(a))}var v=Activity??function({children:t,mode:i}){return jsx("div",{"data-activity-mode":i,children:t})},x=cva(["inline-flex items-center justify-center rounded-md p-1","bg-[var(--accent-background)] text-[var(--menu-muted)]"],{variants:{orientation:{horizontal:"h-10 flex-row gap-0",vertical:"h-auto flex-col w-full gap-1"}},defaultVariants:{orientation:"horizontal"}}),S=cva(["inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-sm","px-3 py-1.5 text-sm font-medium","ring-offset-[var(--content-background)] transition-all","focus-visible:outline-none focus-visible:ring-2","focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2","data-[disabled]:pointer-events-none data-[disabled]:opacity-50","data-[selected]:bg-[var(--content-background)] data-[selected]:text-[var(--content-foreground)]","data-[selected]:shadow-sm","min-h-[44px]"],{variants:{orientation:{horizontal:"",vertical:"w-full justify-start"}},defaultVariants:{orientation:"horizontal"}}),T=cva(["mt-2 ring-offset-[var(--content-background)]","focus-visible:outline-none focus-visible:ring-2","focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2"],{variants:{},defaultVariants:{}});function g({children:a,selectedKey:t,defaultSelectedKey:i,onSelectionChange:n,orientation:s="horizontal",keyboardActivation:p="automatic",isDisabled:b=false,disabledKeys:o,className:l,...d}){return jsx(Tabs,{selectedKey:t,defaultSelectedKey:i,onSelectionChange:n,orientation:s,keyboardActivation:p,isDisabled:b,disabledKeys:o,className:m(l),...d,children:a})}g.displayName="Tabs";function A({children:a,className:t,...i}){return jsx(TabList,{className:composeRenderProps(t,(n,s)=>m(x({orientation:s.orientation}),n)),...i,children:a})}A.displayName="TabList";function w({children:a,id:t,isDisabled:i=false,href:n,target:s,rel:p,download:b,className:o,...l}){return process.env.NODE_ENV!=="production"&&!(typeof a=="string"||Array.isArray(a)&&a.some(C=>typeof C=="string"))&&!l["aria-label"]&&console.warn("Tabs: Icon-only tabs should have an aria-label for accessibility."),jsx(Tab,{id:t,isDisabled:i,href:n,target:s,rel:p,download:b,className:composeRenderProps(o,d=>m(S(),d)),...l,children:a})}w.displayName="Tab";function K({children:a,id:t,shouldForceMount:i=false,preserveState:n=false,className:s,...p}){let b=n||i;return typeof a=="function"?jsx(TabPanel,{id:t,shouldForceMount:b,className:composeRenderProps(s,o=>m(T(),o)),...p,children:o=>{let l=!o.isInert,d=a({isSelected:l});return n?jsx(v,{mode:l?"visible":"hidden",children:d}):d}}):n?jsx(TabPanel,{id:t,shouldForceMount:b,className:composeRenderProps(s,o=>m(T(),o)),...p,children:o=>{let l=!o.isInert;return jsx(v,{mode:l?"visible":"hidden",children:a})}}):jsx(TabPanel,{id:t,shouldForceMount:b,className:composeRenderProps(s,o=>m(T(),o)),...p,children:a})}K.displayName="TabPanel";var F=g,B=A,E=w,I=K;var f=z$1.object({className:z$1.string().optional(),children:z$1.any().optional(),id:z$1.string().optional(),"aria-label":z$1.string().optional(),"aria-labelledby":z$1.string().optional(),"aria-describedby":z$1.string().optional(),"aria-live":z$1.enum(["off","polite","assertive"]).optional(),"aria-hidden":z$1.boolean().optional(),"data-testid":z$1.string().optional()});var N=z$1.enum(["horizontal","vertical"]),z=z$1.enum(["automatic","manual"]),u=z$1.union([z$1.string(),z$1.number()]),j=f.extend({selectedKey:u.optional(),defaultSelectedKey:u.optional(),onSelectionChange:z$1.custom().optional(),orientation:N.optional().default("horizontal"),keyboardActivation:z.optional().default("automatic"),isDisabled:z$1.boolean().optional().default(false),disabledKeys:z$1.array(u).optional(),children:z$1.custom()}),_=f.extend({"aria-label":z$1.string().optional(),"aria-labelledby":z$1.string().optional(),children:z$1.custom()}),q=f.extend({id:u,isDisabled:z$1.boolean().optional().default(false),href:z$1.string().optional(),target:z$1.string().optional(),rel:z$1.string().optional(),download:z$1.union([z$1.string(),z$1.boolean()]).optional(),children:z$1.custom()}),G=f.extend({id:u,shouldForceMount:z$1.boolean().optional().default(false),preserveState:z$1.boolean().optional().default(false),children:z$1.custom()}),L=z$1.enum(["left","right","up","down"]),H=f.extend({direction:L,isDisabled:z$1.boolean().optional().default(false),onPress:z$1.custom(),"aria-label":z$1.string()});export{u as KeySchema,L as ScrollArrowDirectionSchema,H as ScrollArrowPropsSchema,E as Tab,B as TabList,_ as TabListPropsSchema,I as TabPanel,G as TabPanelPropsSchema,q as TabPropsSchema,F as Tabs,z as TabsKeyboardActivationSchema,N as TabsOrientationSchema,j as TabsPropsSchema,x as tabListVariants,T as tabPanelVariants,S as tabVariants};//# sourceMappingURL=index.mjs.map
322
3
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/cn.ts","../../../src/elements/Tabs/Tabs.tsx","../../../src/schemas/BaseComponentProps.ts","../../../src/elements/Tabs/Tabs.types.ts"],"names":["ReactActivity","AriaTabs","AriaTabList","className","AriaTab","AriaTabPanel","z"],"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","'use client';\n\n/**\n * Tabs Component - Implementation\n *\n * Accessible tabbed interface component combining React Aria primitives with ShadCN styling.\n * Follows Themis library patterns with compound component structure and direct named exports.\n *\n * Key Features:\n * - React Aria Tabs for full accessibility (WCAG 2.2 AAA)\n * - CVA variants for orientation styling\n * - React 19.2 Activity API for state preservation (preserveState prop)\n * - Dual keyboard activation modes (automatic/manual)\n * - Support for icons, badges, and link-based tabs\n *\n * @see tabs-prd.md (Full requirements)\n * @see Tabs.types.ts (Zod schemas)\n * @see plan.md (Implementation approach)\n */\n\n// React 19.2 Activity API - may not be available in all builds\n// Import conditionally to support environments where Activity is unavailable\nimport {\n Activity as ReactActivity,\n type ReactNode,\n type Key,\n type ReactElement,\n} from 'react';\n\n// Activity component with fallback for environments where it's not available\n// The fallback simply renders children directly - no state preservation when Activity unavailable\n// Note: ActivityFallback doesn't actually preserve state; it's just a pass-through\nconst Activity = ReactActivity ?? function ActivityFallback({\n children,\n mode,\n}: {\n children: ReactNode;\n mode: 'visible' | 'hidden';\n}): ReactElement {\n // When Activity is not available, just render children directly\n // mode is ignored in the fallback\n return <div data-activity-mode={mode}>{children}</div>;\n};\nimport {\n Tabs as AriaTabs,\n TabList as AriaTabList,\n Tab as AriaTab,\n TabPanel as AriaTabPanel,\n composeRenderProps,\n type Key as AriaKey,\n} from 'react-aria-components';\nimport { cva } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport type {\n TabsProps,\n TabListProps,\n TabProps,\n TabPanelProps,\n} from './Tabs.types';\n\n// ============================================================================\n// CVA Variants\n// ============================================================================\n\n/**\n * TabList CVA variants\n *\n * @see PRD.md FR-002 (TabList Requirements)\n * @see PRD.md DS-001 (Design System - Layout)\n */\nexport const tabListVariants = cva(\n // Base styles\n [\n 'inline-flex items-center justify-center rounded-md p-1',\n 'bg-[var(--accent-background)] text-[var(--menu-muted)]',\n ],\n {\n variants: {\n orientation: {\n horizontal: 'h-10 flex-row gap-0',\n vertical: 'h-auto flex-col w-full gap-1',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n }\n);\n\n/**\n * Tab CVA variants\n *\n * @see PRD.md FR-003 (Tab Requirements)\n * @see PRD.md DS-002 (Design System - Tab Styling)\n * @see PRD.md AR-001 (Accessibility - 44×44px touch targets)\n */\nexport const tabVariants = cva(\n // Base styles\n [\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-sm',\n 'px-3 py-1.5 text-sm font-medium',\n 'ring-offset-[var(--content-background)] transition-all',\n 'focus-visible:outline-none focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2',\n // States via data attributes\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n 'data-[selected]:bg-[var(--content-background)] data-[selected]:text-[var(--content-foreground)]',\n 'data-[selected]:shadow-sm',\n // WCAG 2.2 AAA: 44×44px minimum touch target\n 'min-h-[44px]',\n ],\n {\n variants: {\n orientation: {\n horizontal: '',\n vertical: 'w-full justify-start',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n }\n);\n\n/**\n * TabPanel CVA variants\n *\n * @see PRD.md FR-004 (TabPanel Requirements)\n */\nexport const tabPanelVariants = cva(\n [\n 'mt-2 ring-offset-[var(--content-background)]',\n 'focus-visible:outline-none focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2',\n ],\n {\n variants: {},\n defaultVariants: {},\n }\n);\n\n// ============================================================================\n// Components\n// ============================================================================\n\n/**\n * Tabs Root Component\n *\n * Container for tabbed interface. Manages selection state and provides\n * context to child components.\n *\n * @see PRD.md FR-001 (Compound Component Pattern)\n * @see PRD.md FR-012 (Controlled Mode)\n * @see PRD.md FR-013 (Uncontrolled Mode)\n *\n * @example\n * // Uncontrolled\n * <Tabs defaultSelectedKey=\"tab1\">\n * <TabList aria-label=\"Navigation\">\n * <Tab id=\"tab1\">Tab 1</Tab>\n * <Tab id=\"tab2\">Tab 2</Tab>\n * </TabList>\n * <TabPanel id=\"tab1\">Content 1</TabPanel>\n * <TabPanel id=\"tab2\">Content 2</TabPanel>\n * </Tabs>\n *\n * @example\n * // Controlled\n * <Tabs selectedKey={selected} onSelectionChange={setSelected}>\n * ...\n * </Tabs>\n */\nfunction TabsRoot({\n children,\n selectedKey,\n defaultSelectedKey,\n onSelectionChange,\n orientation = 'horizontal',\n keyboardActivation = 'automatic',\n isDisabled = false,\n disabledKeys,\n className,\n ...props\n}: TabsProps) {\n return (\n <AriaTabs\n selectedKey={selectedKey}\n defaultSelectedKey={defaultSelectedKey}\n onSelectionChange={onSelectionChange as (key: Key) => void}\n orientation={orientation}\n keyboardActivation={keyboardActivation}\n isDisabled={isDisabled}\n disabledKeys={disabledKeys as Iterable<AriaKey> | undefined}\n className={cn(className)}\n {...props}\n >\n {children}\n </AriaTabs>\n );\n}\n\nTabsRoot.displayName = 'Tabs';\n\n/**\n * TabList Component\n *\n * Container for tab buttons. Uses roving tabindex for keyboard navigation.\n * Receives orientation from parent Tabs via React Aria context.\n *\n * @see PRD.md FR-002 (TabList Requirements)\n * @see PRD.md AR-001 (ARIA Requirements)\n */\nfunction TabListComponent({\n children,\n className,\n ...props\n}: TabListProps) {\n return (\n <AriaTabList\n className={composeRenderProps(className, (className, renderProps) =>\n cn(\n tabListVariants({ orientation: renderProps.orientation }),\n className\n )\n )}\n {...props}\n >\n {children}\n </AriaTabList>\n );\n}\n\nTabListComponent.displayName = 'TabList';\n\n/**\n * Tab Component\n *\n * Individual tab button. Can render as button or anchor (when href provided).\n * Supports icons and badges as children.\n *\n * @see PRD.md FR-003 (Tab Requirements)\n * @see PRD.md FR-007 (Disabled States)\n * @see PRD.md FR-013 (Icon Support)\n * @see PRD.md FR-014 (Link-based Tabs)\n */\nfunction TabComponent({\n children,\n id,\n isDisabled = false,\n href,\n target,\n rel,\n download,\n className,\n ...props\n}: TabProps) {\n // Warn if icon-only tab without aria-label\n if (process.env.NODE_ENV !== 'production') {\n const hasTextContent =\n typeof children === 'string' ||\n (Array.isArray(children) &&\n children.some((child) => typeof child === 'string'));\n\n if (!hasTextContent && !props['aria-label']) {\n console.warn(\n 'Tabs: Icon-only tabs should have an aria-label for accessibility.'\n );\n }\n }\n\n return (\n <AriaTab\n id={id}\n isDisabled={isDisabled}\n href={href}\n target={target}\n rel={rel}\n download={download}\n className={composeRenderProps(className, (className) =>\n cn(tabVariants(), className)\n )}\n {...props}\n >\n {children}\n </AriaTab>\n );\n}\n\nTabComponent.displayName = 'Tab';\n\n/**\n * TabPanel Component\n *\n * Content panel associated with a tab. Only the selected panel is visible.\n * Supports preserveState for React Activity state preservation.\n *\n * @see PRD.md FR-004 (TabPanel Requirements)\n * @see PRD.md FR-015 (Force Mount Panels)\n * @see PRD.md FR-016 (React Activity State Preservation)\n *\n * @example\n * // Default behavior - content unmounts when hidden\n * <TabPanel id=\"tab1\">Content</TabPanel>\n *\n * @example\n * // Legacy force mount - keeps content in DOM\n * <TabPanel id=\"tab1\" shouldForceMount>Form with state</TabPanel>\n *\n * @example\n * // React Activity - preserves state with proper effect cleanup\n * <TabPanel id=\"tab1\" preserveState>\n * <FormWithDraft />\n * </TabPanel>\n */\nfunction TabPanelComponent({\n children,\n id,\n shouldForceMount = false,\n preserveState = false,\n className,\n ...props\n}: TabPanelProps) {\n // preserveState takes precedence - both enable force mounting\n const forceMount = preserveState || shouldForceMount;\n\n // If children is a render function (for dynamic content based on selection state),\n // we need to use the render props pattern\n if (typeof children === 'function') {\n return (\n <AriaTabPanel\n id={id}\n shouldForceMount={forceMount}\n className={composeRenderProps(className, (className) =>\n cn(tabPanelVariants(), className)\n )}\n {...props}\n >\n {(renderProps) => {\n // React Aria TabPanelRenderProps includes: state, isInert\n // We derive isSelected from state - if state is undefined, panel is selected\n const isSelected = !renderProps.isInert;\n const content = (\n children as (renderProps: { isSelected: boolean }) => ReactNode\n )({ isSelected });\n\n if (preserveState) {\n return (\n <Activity mode={isSelected ? 'visible' : 'hidden'}>\n {content}\n </Activity>\n );\n }\n\n return content;\n }}\n </AriaTabPanel>\n );\n }\n\n // For static children (not a function), render directly\n // If preserveState is enabled, wrap in Activity\n if (preserveState) {\n return (\n <AriaTabPanel\n id={id}\n shouldForceMount={forceMount}\n className={composeRenderProps(className, (className) =>\n cn(tabPanelVariants(), className)\n )}\n {...props}\n >\n {(renderProps) => {\n const isSelected = !renderProps.isInert;\n return (\n <Activity mode={isSelected ? 'visible' : 'hidden'}>\n {children}\n </Activity>\n );\n }}\n </AriaTabPanel>\n );\n }\n\n // Default: render static children directly\n return (\n <AriaTabPanel\n id={id}\n shouldForceMount={forceMount}\n className={composeRenderProps(className, (className) =>\n cn(tabPanelVariants(), className)\n )}\n {...props}\n >\n {children}\n </AriaTabPanel>\n );\n}\n\nTabPanelComponent.displayName = 'TabPanel';\n\n// ============================================================================\n// Exports\n// ============================================================================\n\n/**\n * Direct named exports (not Object.assign compound pattern)\n *\n * Tabs follows React Aria's direct export pattern because:\n * - Simpler structure (only 4 components vs Dialog's 9)\n * - Better tree-shaking with named exports\n * - Clearer imports: import { Tabs, TabList, Tab, TabPanel } from '...'\n *\n * @see plan.md \"Why Direct Named Exports (Not Object.assign)?\"\n */\nexport const Tabs = TabsRoot;\nexport const TabList = TabListComponent;\nexport const Tab = TabComponent;\nexport const TabPanel = TabPanelComponent;\n\n// Re-export types for convenience\nexport type { TabsProps, TabListProps, TabProps, TabPanelProps };\n","import { z } from 'zod';\n\n/**\n * Base props schema for all Themis components\n * Ensures consistent accessibility and styling APIs across the library\n *\n * @see spec.md FR-009 to FR-014 (Accessibility Requirements)\n * @see constitution.md Principle IV (Accessibility First - WCAG 2.2 AA minimum)\n */\nexport const BaseComponentPropsSchema = z.object({\n // Styling\n className: z.string().optional(),\n\n // React\n children: z.any().optional(), // ReactNode not directly supported by Zod\n id: z.string().optional(),\n\n // Accessibility (WCAG 2.2 AA requirements)\n 'aria-label': z.string().optional(),\n 'aria-labelledby': z.string().optional(),\n 'aria-describedby': z.string().optional(),\n 'aria-live': z.enum(['off', 'polite', 'assertive']).optional(),\n 'aria-hidden': z.boolean().optional(),\n\n // Testing & Development\n 'data-testid': z.string().optional(),\n});\n\nexport type BaseComponentProps = z.infer<typeof BaseComponentPropsSchema>;\n","import { z } from 'zod';\nimport { BaseComponentPropsSchema } from '../../schemas/BaseComponentProps';\nimport type { ReactNode, Key } from 'react';\n\n/**\n * Tab orientation schema\n *\n * @see PRD.md FR-005 (Orientation Support)\n */\nexport const TabsOrientationSchema = z.enum(['horizontal', 'vertical']);\nexport type TabsOrientation = z.infer<typeof TabsOrientationSchema>;\n\n/**\n * Keyboard activation mode schema\n *\n * @see PRD.md FR-006 (Keyboard Activation Modes)\n */\nexport const TabsKeyboardActivationSchema = z.enum(['automatic', 'manual']);\nexport type TabsKeyboardActivation = z.infer<typeof TabsKeyboardActivationSchema>;\n\n/**\n * Key schema for tab identification\n * Supports both string and number keys per React Aria convention\n */\nexport const KeySchema = z.union([z.string(), z.number()]);\n\n/**\n * Tabs root component props schema\n *\n * @see PRD.md FR-001 (Compound Component Pattern)\n * @see PRD.md FR-012 (Controlled Mode)\n * @see PRD.md FR-013 (Uncontrolled Mode)\n */\nexport const TabsPropsSchema = BaseComponentPropsSchema.extend({\n // Controlled mode: selected tab key\n selectedKey: KeySchema.optional(),\n\n // Uncontrolled mode: default selected tab key\n defaultSelectedKey: KeySchema.optional(),\n\n // Selection change handler\n onSelectionChange: z.custom<(key: Key) => void>().optional(),\n\n // Orientation: horizontal or vertical layout\n orientation: TabsOrientationSchema.optional().default('horizontal'),\n\n // Keyboard activation: automatic (arrows select) or manual (arrows focus, Enter selects)\n keyboardActivation: TabsKeyboardActivationSchema.optional().default('automatic'),\n\n // Disable all tabs\n isDisabled: z.boolean().optional().default(false),\n\n // Keys of tabs to disable individually\n disabledKeys: z.array(KeySchema).optional(),\n\n // Children: TabList and TabPanel components\n children: z.custom<ReactNode>(),\n});\n\nexport type TabsProps = z.infer<typeof TabsPropsSchema>;\n\n/**\n * TabList component props schema\n *\n * @see PRD.md FR-002 (TabList Requirements)\n * @see PRD.md AR-001 (ARIA Requirements)\n */\nexport const TabListPropsSchema = BaseComponentPropsSchema.extend({\n // Accessible label (required for accessibility if no aria-labelledby)\n 'aria-label': z.string().optional(),\n\n // Reference to labelling element\n 'aria-labelledby': z.string().optional(),\n\n // Children: Tab components\n children: z.custom<ReactNode>(),\n});\n\nexport type TabListProps = z.infer<typeof TabListPropsSchema>;\n\n/**\n * Tab component props schema\n *\n * @see PRD.md FR-003 (Tab Requirements)\n * @see PRD.md FR-007 (Disabled States)\n * @see PRD.md FR-014 (Link-based Tabs)\n */\nexport const TabPropsSchema = BaseComponentPropsSchema.extend({\n // Unique identifier for the tab (required)\n id: KeySchema,\n\n // Disable this specific tab\n isDisabled: z.boolean().optional().default(false),\n\n // Link tab: URL for navigation-style tabs\n href: z.string().optional(),\n\n // Link tab: target attribute\n target: z.string().optional(),\n\n // Link tab: rel attribute\n rel: z.string().optional(),\n\n // Link tab: download attribute\n download: z.union([z.string(), z.boolean()]).optional(),\n\n // Tab content (text, icons, badges)\n children: z.custom<ReactNode>(),\n});\n\nexport type TabProps = z.infer<typeof TabPropsSchema>;\n\n/**\n * TabPanel component props schema\n *\n * @see PRD.md FR-004 (TabPanel Requirements)\n * @see PRD.md FR-015 (Force Mount Panels)\n * @see PRD.md FR-016 (React Activity State Preservation)\n */\nexport const TabPanelPropsSchema = BaseComponentPropsSchema.extend({\n // Unique identifier matching a Tab id (required)\n id: KeySchema,\n\n // Legacy: Force panel to stay in DOM when hidden\n // Use preserveState instead for proper effect cleanup\n shouldForceMount: z.boolean().optional().default(false),\n\n // React 19.2 Activity: Preserve state with proper effect cleanup\n // When true, wraps content in <Activity> component\n // Effects are cleaned up when hidden, restored when visible\n preserveState: z.boolean().optional().default(false),\n\n // Panel content\n children: z.custom<ReactNode>(),\n});\n\nexport type TabPanelProps = z.infer<typeof TabPanelPropsSchema>;\n\n/**\n * Scroll arrow direction for overflow handling\n *\n * @see PRD.md FR-010 (Overflow Handling)\n */\nexport const ScrollArrowDirectionSchema = z.enum(['left', 'right', 'up', 'down']);\nexport type ScrollArrowDirection = z.infer<typeof ScrollArrowDirectionSchema>;\n\n/**\n * Internal props for scroll arrow buttons\n * Used by overflow handling implementation\n */\nexport const ScrollArrowPropsSchema = BaseComponentPropsSchema.extend({\n // Scroll direction\n direction: ScrollArrowDirectionSchema,\n\n // Disable when can't scroll further\n isDisabled: z.boolean().optional().default(false),\n\n // Click handler for scrolling\n onPress: z.custom<() => void>(),\n\n // Accessible label\n 'aria-label': z.string(),\n});\n\nexport type ScrollArrowProps = z.infer<typeof ScrollArrowPropsSchema>;\n"]}
1
+ {"version":3,"sources":["../../../src/utils/cn.ts","../../../src/elements/Tabs/Tabs.tsx","../../../src/schemas/BaseComponentProps.ts","../../../src/elements/Tabs/Tabs.types.ts"],"names":["cn","inputs","twMerge","clsx","Activity","ReactActivity","children","mode","jsx","tabListVariants","cva","tabVariants","tabPanelVariants","TabsRoot","selectedKey","defaultSelectedKey","onSelectionChange","orientation","keyboardActivation","isDisabled","disabledKeys","className","props","AriaTabs","TabListComponent","AriaTabList","composeRenderProps","renderProps","TabComponent","id","href","target","rel","download","child","AriaTab","TabPanelComponent","shouldForceMount","preserveState","forceMount","AriaTabPanel","isSelected","content","Tabs","TabList","Tab","TabPanel","BaseComponentPropsSchema","z","TabsOrientationSchema","TabsKeyboardActivationSchema","KeySchema","TabsPropsSchema","TabListPropsSchema","TabPropsSchema","TabPanelPropsSchema","ScrollArrowDirectionSchema","ScrollArrowPropsSchema"],"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","'use client';\n\n/**\n * Tabs Component - Implementation\n *\n * Accessible tabbed interface component combining React Aria primitives with ShadCN styling.\n * Follows Themis library patterns with compound component structure and direct named exports.\n *\n * Key Features:\n * - React Aria Tabs for full accessibility (WCAG 2.2 AAA)\n * - CVA variants for orientation styling\n * - React 19.2 Activity API for state preservation (preserveState prop)\n * - Dual keyboard activation modes (automatic/manual)\n * - Support for icons, badges, and link-based tabs\n *\n * @see tabs-prd.md (Full requirements)\n * @see Tabs.types.ts (Zod schemas)\n * @see plan.md (Implementation approach)\n */\n\n// React 19.2 Activity API - may not be available in all builds\n// Import conditionally to support environments where Activity is unavailable\nimport {\n Activity as ReactActivity,\n type ReactNode,\n type Key,\n type ReactElement,\n} from 'react';\n\n// Activity component with fallback for environments where it's not available\n// The fallback simply renders children directly - no state preservation when Activity unavailable\n// Note: ActivityFallback doesn't actually preserve state; it's just a pass-through\nconst Activity = ReactActivity ?? function ActivityFallback({\n children,\n mode,\n}: {\n children: ReactNode;\n mode: 'visible' | 'hidden';\n}): ReactElement {\n // When Activity is not available, just render children directly\n // mode is ignored in the fallback\n return <div data-activity-mode={mode}>{children}</div>;\n};\nimport {\n Tabs as AriaTabs,\n TabList as AriaTabList,\n Tab as AriaTab,\n TabPanel as AriaTabPanel,\n composeRenderProps,\n type Key as AriaKey,\n} from 'react-aria-components';\nimport { cva } from 'class-variance-authority';\nimport { cn } from '../../utils/cn';\nimport type {\n TabsProps,\n TabListProps,\n TabProps,\n TabPanelProps,\n} from './Tabs.types';\n\n// ============================================================================\n// CVA Variants\n// ============================================================================\n\n/**\n * TabList CVA variants\n *\n * @see PRD.md FR-002 (TabList Requirements)\n * @see PRD.md DS-001 (Design System - Layout)\n */\nexport const tabListVariants = cva(\n // Base styles\n [\n 'inline-flex items-center justify-center rounded-md p-1',\n 'bg-[var(--accent-background)] text-[var(--menu-muted)]',\n ],\n {\n variants: {\n orientation: {\n horizontal: 'h-10 flex-row gap-0',\n vertical: 'h-auto flex-col w-full gap-1',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n }\n);\n\n/**\n * Tab CVA variants\n *\n * @see PRD.md FR-003 (Tab Requirements)\n * @see PRD.md DS-002 (Design System - Tab Styling)\n * @see PRD.md AR-001 (Accessibility - 44×44px touch targets)\n */\nexport const tabVariants = cva(\n // Base styles\n [\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-sm',\n 'px-3 py-1.5 text-sm font-medium',\n 'ring-offset-[var(--content-background)] transition-all',\n 'focus-visible:outline-none focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2',\n // States via data attributes\n 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50',\n 'data-[selected]:bg-[var(--content-background)] data-[selected]:text-[var(--content-foreground)]',\n 'data-[selected]:shadow-sm',\n // WCAG 2.2 AAA: 44×44px minimum touch target\n 'min-h-[44px]',\n ],\n {\n variants: {\n orientation: {\n horizontal: '',\n vertical: 'w-full justify-start',\n },\n },\n defaultVariants: {\n orientation: 'horizontal',\n },\n }\n);\n\n/**\n * TabPanel CVA variants\n *\n * @see PRD.md FR-004 (TabPanel Requirements)\n */\nexport const tabPanelVariants = cva(\n [\n 'mt-2 ring-offset-[var(--content-background)]',\n 'focus-visible:outline-none focus-visible:ring-2',\n 'focus-visible:ring-[var(--ring)] focus-visible:ring-offset-2',\n ],\n {\n variants: {},\n defaultVariants: {},\n }\n);\n\n// ============================================================================\n// Components\n// ============================================================================\n\n/**\n * Tabs Root Component\n *\n * Container for tabbed interface. Manages selection state and provides\n * context to child components.\n *\n * @see PRD.md FR-001 (Compound Component Pattern)\n * @see PRD.md FR-012 (Controlled Mode)\n * @see PRD.md FR-013 (Uncontrolled Mode)\n *\n * @example\n * // Uncontrolled\n * <Tabs defaultSelectedKey=\"tab1\">\n * <TabList aria-label=\"Navigation\">\n * <Tab id=\"tab1\">Tab 1</Tab>\n * <Tab id=\"tab2\">Tab 2</Tab>\n * </TabList>\n * <TabPanel id=\"tab1\">Content 1</TabPanel>\n * <TabPanel id=\"tab2\">Content 2</TabPanel>\n * </Tabs>\n *\n * @example\n * // Controlled\n * <Tabs selectedKey={selected} onSelectionChange={setSelected}>\n * ...\n * </Tabs>\n */\nfunction TabsRoot({\n children,\n selectedKey,\n defaultSelectedKey,\n onSelectionChange,\n orientation = 'horizontal',\n keyboardActivation = 'automatic',\n isDisabled = false,\n disabledKeys,\n className,\n ...props\n}: TabsProps) {\n return (\n <AriaTabs\n selectedKey={selectedKey}\n defaultSelectedKey={defaultSelectedKey}\n onSelectionChange={onSelectionChange as (key: Key) => void}\n orientation={orientation}\n keyboardActivation={keyboardActivation}\n isDisabled={isDisabled}\n disabledKeys={disabledKeys as Iterable<AriaKey> | undefined}\n className={cn(className)}\n {...props}\n >\n {children}\n </AriaTabs>\n );\n}\n\nTabsRoot.displayName = 'Tabs';\n\n/**\n * TabList Component\n *\n * Container for tab buttons. Uses roving tabindex for keyboard navigation.\n * Receives orientation from parent Tabs via React Aria context.\n *\n * @see PRD.md FR-002 (TabList Requirements)\n * @see PRD.md AR-001 (ARIA Requirements)\n */\nfunction TabListComponent({\n children,\n className,\n ...props\n}: TabListProps) {\n return (\n <AriaTabList\n className={composeRenderProps(className, (className, renderProps) =>\n cn(\n tabListVariants({ orientation: renderProps.orientation }),\n className\n )\n )}\n {...props}\n >\n {children}\n </AriaTabList>\n );\n}\n\nTabListComponent.displayName = 'TabList';\n\n/**\n * Tab Component\n *\n * Individual tab button. Can render as button or anchor (when href provided).\n * Supports icons and badges as children.\n *\n * @see PRD.md FR-003 (Tab Requirements)\n * @see PRD.md FR-007 (Disabled States)\n * @see PRD.md FR-013 (Icon Support)\n * @see PRD.md FR-014 (Link-based Tabs)\n */\nfunction TabComponent({\n children,\n id,\n isDisabled = false,\n href,\n target,\n rel,\n download,\n className,\n ...props\n}: TabProps) {\n // Warn if icon-only tab without aria-label\n if (process.env.NODE_ENV !== 'production') {\n const hasTextContent =\n typeof children === 'string' ||\n (Array.isArray(children) &&\n children.some((child) => typeof child === 'string'));\n\n if (!hasTextContent && !props['aria-label']) {\n console.warn(\n 'Tabs: Icon-only tabs should have an aria-label for accessibility.'\n );\n }\n }\n\n return (\n <AriaTab\n id={id}\n isDisabled={isDisabled}\n href={href}\n target={target}\n rel={rel}\n download={download}\n className={composeRenderProps(className, (className) =>\n cn(tabVariants(), className)\n )}\n {...props}\n >\n {children}\n </AriaTab>\n );\n}\n\nTabComponent.displayName = 'Tab';\n\n/**\n * TabPanel Component\n *\n * Content panel associated with a tab. Only the selected panel is visible.\n * Supports preserveState for React Activity state preservation.\n *\n * @see PRD.md FR-004 (TabPanel Requirements)\n * @see PRD.md FR-015 (Force Mount Panels)\n * @see PRD.md FR-016 (React Activity State Preservation)\n *\n * @example\n * // Default behavior - content unmounts when hidden\n * <TabPanel id=\"tab1\">Content</TabPanel>\n *\n * @example\n * // Legacy force mount - keeps content in DOM\n * <TabPanel id=\"tab1\" shouldForceMount>Form with state</TabPanel>\n *\n * @example\n * // React Activity - preserves state with proper effect cleanup\n * <TabPanel id=\"tab1\" preserveState>\n * <FormWithDraft />\n * </TabPanel>\n */\nfunction TabPanelComponent({\n children,\n id,\n shouldForceMount = false,\n preserveState = false,\n className,\n ...props\n}: TabPanelProps) {\n // preserveState takes precedence - both enable force mounting\n const forceMount = preserveState || shouldForceMount;\n\n // If children is a render function (for dynamic content based on selection state),\n // we need to use the render props pattern\n if (typeof children === 'function') {\n return (\n <AriaTabPanel\n id={id}\n shouldForceMount={forceMount}\n className={composeRenderProps(className, (className) =>\n cn(tabPanelVariants(), className)\n )}\n {...props}\n >\n {(renderProps) => {\n // React Aria TabPanelRenderProps includes: state, isInert\n // We derive isSelected from state - if state is undefined, panel is selected\n const isSelected = !renderProps.isInert;\n const content = (\n children as (renderProps: { isSelected: boolean }) => ReactNode\n )({ isSelected });\n\n if (preserveState) {\n return (\n <Activity mode={isSelected ? 'visible' : 'hidden'}>\n {content}\n </Activity>\n );\n }\n\n return content;\n }}\n </AriaTabPanel>\n );\n }\n\n // For static children (not a function), render directly\n // If preserveState is enabled, wrap in Activity\n if (preserveState) {\n return (\n <AriaTabPanel\n id={id}\n shouldForceMount={forceMount}\n className={composeRenderProps(className, (className) =>\n cn(tabPanelVariants(), className)\n )}\n {...props}\n >\n {(renderProps) => {\n const isSelected = !renderProps.isInert;\n return (\n <Activity mode={isSelected ? 'visible' : 'hidden'}>\n {children}\n </Activity>\n );\n }}\n </AriaTabPanel>\n );\n }\n\n // Default: render static children directly\n return (\n <AriaTabPanel\n id={id}\n shouldForceMount={forceMount}\n className={composeRenderProps(className, (className) =>\n cn(tabPanelVariants(), className)\n )}\n {...props}\n >\n {children}\n </AriaTabPanel>\n );\n}\n\nTabPanelComponent.displayName = 'TabPanel';\n\n// ============================================================================\n// Exports\n// ============================================================================\n\n/**\n * Direct named exports (not Object.assign compound pattern)\n *\n * Tabs follows React Aria's direct export pattern because:\n * - Simpler structure (only 4 components vs Dialog's 9)\n * - Better tree-shaking with named exports\n * - Clearer imports: import { Tabs, TabList, Tab, TabPanel } from '...'\n *\n * @see plan.md \"Why Direct Named Exports (Not Object.assign)?\"\n */\nexport const Tabs = TabsRoot;\nexport const TabList = TabListComponent;\nexport const Tab = TabComponent;\nexport const TabPanel = TabPanelComponent;\n\n// Re-export types for convenience\nexport type { TabsProps, TabListProps, TabProps, TabPanelProps };\n","import { z } from 'zod';\n\n/**\n * Base props schema for all Themis components\n * Ensures consistent accessibility and styling APIs across the library\n *\n * @see spec.md FR-009 to FR-014 (Accessibility Requirements)\n * @see constitution.md Principle IV (Accessibility First - WCAG 2.2 AA minimum)\n */\nexport const BaseComponentPropsSchema = z.object({\n // Styling\n className: z.string().optional(),\n\n // React\n children: z.any().optional(), // ReactNode not directly supported by Zod\n id: z.string().optional(),\n\n // Accessibility (WCAG 2.2 AA requirements)\n 'aria-label': z.string().optional(),\n 'aria-labelledby': z.string().optional(),\n 'aria-describedby': z.string().optional(),\n 'aria-live': z.enum(['off', 'polite', 'assertive']).optional(),\n 'aria-hidden': z.boolean().optional(),\n\n // Testing & Development\n 'data-testid': z.string().optional(),\n});\n\nexport type BaseComponentProps = z.infer<typeof BaseComponentPropsSchema>;\n","import { z } from 'zod';\nimport { BaseComponentPropsSchema } from '../../schemas/BaseComponentProps';\nimport type { ReactNode, Key } from 'react';\n\n/**\n * Tab orientation schema\n *\n * @see PRD.md FR-005 (Orientation Support)\n */\nexport const TabsOrientationSchema = z.enum(['horizontal', 'vertical']);\nexport type TabsOrientation = z.infer<typeof TabsOrientationSchema>;\n\n/**\n * Keyboard activation mode schema\n *\n * @see PRD.md FR-006 (Keyboard Activation Modes)\n */\nexport const TabsKeyboardActivationSchema = z.enum(['automatic', 'manual']);\nexport type TabsKeyboardActivation = z.infer<typeof TabsKeyboardActivationSchema>;\n\n/**\n * Key schema for tab identification\n * Supports both string and number keys per React Aria convention\n */\nexport const KeySchema = z.union([z.string(), z.number()]);\n\n/**\n * Tabs root component props schema\n *\n * @see PRD.md FR-001 (Compound Component Pattern)\n * @see PRD.md FR-012 (Controlled Mode)\n * @see PRD.md FR-013 (Uncontrolled Mode)\n */\nexport const TabsPropsSchema = BaseComponentPropsSchema.extend({\n // Controlled mode: selected tab key\n selectedKey: KeySchema.optional(),\n\n // Uncontrolled mode: default selected tab key\n defaultSelectedKey: KeySchema.optional(),\n\n // Selection change handler\n onSelectionChange: z.custom<(key: Key) => void>().optional(),\n\n // Orientation: horizontal or vertical layout\n orientation: TabsOrientationSchema.optional().default('horizontal'),\n\n // Keyboard activation: automatic (arrows select) or manual (arrows focus, Enter selects)\n keyboardActivation: TabsKeyboardActivationSchema.optional().default('automatic'),\n\n // Disable all tabs\n isDisabled: z.boolean().optional().default(false),\n\n // Keys of tabs to disable individually\n disabledKeys: z.array(KeySchema).optional(),\n\n // Children: TabList and TabPanel components\n children: z.custom<ReactNode>(),\n});\n\nexport type TabsProps = z.infer<typeof TabsPropsSchema>;\n\n/**\n * TabList component props schema\n *\n * @see PRD.md FR-002 (TabList Requirements)\n * @see PRD.md AR-001 (ARIA Requirements)\n */\nexport const TabListPropsSchema = BaseComponentPropsSchema.extend({\n // Accessible label (required for accessibility if no aria-labelledby)\n 'aria-label': z.string().optional(),\n\n // Reference to labelling element\n 'aria-labelledby': z.string().optional(),\n\n // Children: Tab components\n children: z.custom<ReactNode>(),\n});\n\nexport type TabListProps = z.infer<typeof TabListPropsSchema>;\n\n/**\n * Tab component props schema\n *\n * @see PRD.md FR-003 (Tab Requirements)\n * @see PRD.md FR-007 (Disabled States)\n * @see PRD.md FR-014 (Link-based Tabs)\n */\nexport const TabPropsSchema = BaseComponentPropsSchema.extend({\n // Unique identifier for the tab (required)\n id: KeySchema,\n\n // Disable this specific tab\n isDisabled: z.boolean().optional().default(false),\n\n // Link tab: URL for navigation-style tabs\n href: z.string().optional(),\n\n // Link tab: target attribute\n target: z.string().optional(),\n\n // Link tab: rel attribute\n rel: z.string().optional(),\n\n // Link tab: download attribute\n download: z.union([z.string(), z.boolean()]).optional(),\n\n // Tab content (text, icons, badges)\n children: z.custom<ReactNode>(),\n});\n\nexport type TabProps = z.infer<typeof TabPropsSchema>;\n\n/**\n * TabPanel component props schema\n *\n * @see PRD.md FR-004 (TabPanel Requirements)\n * @see PRD.md FR-015 (Force Mount Panels)\n * @see PRD.md FR-016 (React Activity State Preservation)\n */\nexport const TabPanelPropsSchema = BaseComponentPropsSchema.extend({\n // Unique identifier matching a Tab id (required)\n id: KeySchema,\n\n // Legacy: Force panel to stay in DOM when hidden\n // Use preserveState instead for proper effect cleanup\n shouldForceMount: z.boolean().optional().default(false),\n\n // React 19.2 Activity: Preserve state with proper effect cleanup\n // When true, wraps content in <Activity> component\n // Effects are cleaned up when hidden, restored when visible\n preserveState: z.boolean().optional().default(false),\n\n // Panel content\n children: z.custom<ReactNode>(),\n});\n\nexport type TabPanelProps = z.infer<typeof TabPanelPropsSchema>;\n\n/**\n * Scroll arrow direction for overflow handling\n *\n * @see PRD.md FR-010 (Overflow Handling)\n */\nexport const ScrollArrowDirectionSchema = z.enum(['left', 'right', 'up', 'down']);\nexport type ScrollArrowDirection = z.infer<typeof ScrollArrowDirectionSchema>;\n\n/**\n * Internal props for scroll arrow buttons\n * Used by overflow handling implementation\n */\nexport const ScrollArrowPropsSchema = BaseComponentPropsSchema.extend({\n // Scroll direction\n direction: ScrollArrowDirectionSchema,\n\n // Disable when can't scroll further\n isDisabled: z.boolean().optional().default(false),\n\n // Click handler for scrolling\n onPress: z.custom<() => void>(),\n\n // Accessible label\n 'aria-label': z.string(),\n});\n\nexport type ScrollArrowProps = z.infer<typeof ScrollArrowPropsSchema>;\n"]}