@tribepad/themis 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (654) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +21 -0
  3. package/README.md +114 -0
  4. package/dist/Carousel-NTZX5TOW.js +16 -0
  5. package/dist/Carousel-NTZX5TOW.js.map +1 -0
  6. package/dist/Carousel-YH3DOQJU.mjs +7 -0
  7. package/dist/Carousel-YH3DOQJU.mjs.map +1 -0
  8. package/dist/chunk-2HIUTHMU.mjs +234 -0
  9. package/dist/chunk-2HIUTHMU.mjs.map +1 -0
  10. package/dist/chunk-34GTFTDO.js +431 -0
  11. package/dist/chunk-34GTFTDO.js.map +1 -0
  12. package/dist/chunk-3H7ASYR7.js +250 -0
  13. package/dist/chunk-3H7ASYR7.js.map +1 -0
  14. package/dist/chunk-3IEN7JOP.js +316 -0
  15. package/dist/chunk-3IEN7JOP.js.map +1 -0
  16. package/dist/chunk-3JHN4GAL.js +326 -0
  17. package/dist/chunk-3JHN4GAL.js.map +1 -0
  18. package/dist/chunk-3MJPASQU.js +232 -0
  19. package/dist/chunk-3MJPASQU.js.map +1 -0
  20. package/dist/chunk-3XD2JUL3.js +572 -0
  21. package/dist/chunk-3XD2JUL3.js.map +1 -0
  22. package/dist/chunk-3YOY2VJ6.js +189 -0
  23. package/dist/chunk-3YOY2VJ6.js.map +1 -0
  24. package/dist/chunk-4DU5JSXB.js +408 -0
  25. package/dist/chunk-4DU5JSXB.js.map +1 -0
  26. package/dist/chunk-4E4E2GSS.js +352 -0
  27. package/dist/chunk-4E4E2GSS.js.map +1 -0
  28. package/dist/chunk-4NHAP4AN.mjs +3 -0
  29. package/dist/chunk-4NHAP4AN.mjs.map +1 -0
  30. package/dist/chunk-4S33J5NY.mjs +415 -0
  31. package/dist/chunk-4S33J5NY.mjs.map +1 -0
  32. package/dist/chunk-5SMGRT3G.mjs +354 -0
  33. package/dist/chunk-5SMGRT3G.mjs.map +1 -0
  34. package/dist/chunk-5SVLJN2C.mjs +22 -0
  35. package/dist/chunk-5SVLJN2C.mjs.map +1 -0
  36. package/dist/chunk-66WTU4EB.mjs +299 -0
  37. package/dist/chunk-66WTU4EB.mjs.map +1 -0
  38. package/dist/chunk-6S25NMOT.mjs +335 -0
  39. package/dist/chunk-6S25NMOT.mjs.map +1 -0
  40. package/dist/chunk-6SP7UB3D.js +4 -0
  41. package/dist/chunk-6SP7UB3D.js.map +1 -0
  42. package/dist/chunk-6TYWWQHM.mjs +565 -0
  43. package/dist/chunk-6TYWWQHM.mjs.map +1 -0
  44. package/dist/chunk-A3YUJA6W.mjs +384 -0
  45. package/dist/chunk-A3YUJA6W.mjs.map +1 -0
  46. package/dist/chunk-A6KEDVUR.js +61 -0
  47. package/dist/chunk-A6KEDVUR.js.map +1 -0
  48. package/dist/chunk-A77RUEWL.js +730 -0
  49. package/dist/chunk-A77RUEWL.js.map +1 -0
  50. package/dist/chunk-AA4IKMPE.mjs +3 -0
  51. package/dist/chunk-AA4IKMPE.mjs.map +1 -0
  52. package/dist/chunk-AKIA6GW6.mjs +163 -0
  53. package/dist/chunk-AKIA6GW6.mjs.map +1 -0
  54. package/dist/chunk-AL6P275L.mjs +435 -0
  55. package/dist/chunk-AL6P275L.mjs.map +1 -0
  56. package/dist/chunk-AZ3RJYTB.js +37 -0
  57. package/dist/chunk-AZ3RJYTB.js.map +1 -0
  58. package/dist/chunk-B5Q4UPL6.js +32 -0
  59. package/dist/chunk-B5Q4UPL6.js.map +1 -0
  60. package/dist/chunk-B6DHPMDP.mjs +335 -0
  61. package/dist/chunk-B6DHPMDP.mjs.map +1 -0
  62. package/dist/chunk-BDXKKMBZ.mjs +184 -0
  63. package/dist/chunk-BDXKKMBZ.mjs.map +1 -0
  64. package/dist/chunk-BL6E2DLZ.mjs +52 -0
  65. package/dist/chunk-BL6E2DLZ.mjs.map +1 -0
  66. package/dist/chunk-CGFDS4XS.mjs +121 -0
  67. package/dist/chunk-CGFDS4XS.mjs.map +1 -0
  68. package/dist/chunk-CJIW5TKI.js +139 -0
  69. package/dist/chunk-CJIW5TKI.js.map +1 -0
  70. package/dist/chunk-CKNISJOQ.js +314 -0
  71. package/dist/chunk-CKNISJOQ.js.map +1 -0
  72. package/dist/chunk-D6CBOECS.mjs +1757 -0
  73. package/dist/chunk-D6CBOECS.mjs.map +1 -0
  74. package/dist/chunk-DDWEVC2S.js +166 -0
  75. package/dist/chunk-DDWEVC2S.js.map +1 -0
  76. package/dist/chunk-DZ556D2F.mjs +176 -0
  77. package/dist/chunk-DZ556D2F.mjs.map +1 -0
  78. package/dist/chunk-E2KQFV3O.mjs +10 -0
  79. package/dist/chunk-E2KQFV3O.mjs.map +1 -0
  80. package/dist/chunk-EMMLADSC.js +126 -0
  81. package/dist/chunk-EMMLADSC.js.map +1 -0
  82. package/dist/chunk-EP4WOI5D.mjs +926 -0
  83. package/dist/chunk-EP4WOI5D.mjs.map +1 -0
  84. package/dist/chunk-FJRXLJC2.mjs +160 -0
  85. package/dist/chunk-FJRXLJC2.mjs.map +1 -0
  86. package/dist/chunk-FKQI434R.js +345 -0
  87. package/dist/chunk-FKQI434R.js.map +1 -0
  88. package/dist/chunk-FPKEAJRZ.mjs +100 -0
  89. package/dist/chunk-FPKEAJRZ.mjs.map +1 -0
  90. package/dist/chunk-FWQYB22U.js +183 -0
  91. package/dist/chunk-FWQYB22U.js.map +1 -0
  92. package/dist/chunk-GD5GHTMA.js +189 -0
  93. package/dist/chunk-GD5GHTMA.js.map +1 -0
  94. package/dist/chunk-GE5XTSDZ.js +447 -0
  95. package/dist/chunk-GE5XTSDZ.js.map +1 -0
  96. package/dist/chunk-GVE47ZAX.mjs +32 -0
  97. package/dist/chunk-GVE47ZAX.mjs.map +1 -0
  98. package/dist/chunk-HK46BT5U.mjs +18 -0
  99. package/dist/chunk-HK46BT5U.mjs.map +1 -0
  100. package/dist/chunk-HQVRMR6N.js +365 -0
  101. package/dist/chunk-HQVRMR6N.js.map +1 -0
  102. package/dist/chunk-HSGBJPJO.mjs +398 -0
  103. package/dist/chunk-HSGBJPJO.mjs.map +1 -0
  104. package/dist/chunk-I3AUTOMZ.mjs +125 -0
  105. package/dist/chunk-I3AUTOMZ.mjs.map +1 -0
  106. package/dist/chunk-IEI5LD5C.mjs +1161 -0
  107. package/dist/chunk-IEI5LD5C.mjs.map +1 -0
  108. package/dist/chunk-IIPTC2X7.mjs +118 -0
  109. package/dist/chunk-IIPTC2X7.mjs.map +1 -0
  110. package/dist/chunk-J7TLHF2Q.js +4 -0
  111. package/dist/chunk-J7TLHF2Q.js.map +1 -0
  112. package/dist/chunk-JJOWXFXQ.mjs +765 -0
  113. package/dist/chunk-JJOWXFXQ.mjs.map +1 -0
  114. package/dist/chunk-JPTSS2OA.mjs +3 -0
  115. package/dist/chunk-JPTSS2OA.mjs.map +1 -0
  116. package/dist/chunk-KFXXRLTP.js +396 -0
  117. package/dist/chunk-KFXXRLTP.js.map +1 -0
  118. package/dist/chunk-KPRRBSG6.mjs +272 -0
  119. package/dist/chunk-KPRRBSG6.mjs.map +1 -0
  120. package/dist/chunk-NFSBGRDB.mjs +57 -0
  121. package/dist/chunk-NFSBGRDB.mjs.map +1 -0
  122. package/dist/chunk-NGJVCFTM.js +219 -0
  123. package/dist/chunk-NGJVCFTM.js.map +1 -0
  124. package/dist/chunk-NSQ6MZJ6.mjs +728 -0
  125. package/dist/chunk-NSQ6MZJ6.mjs.map +1 -0
  126. package/dist/chunk-NYQYHT76.mjs +296 -0
  127. package/dist/chunk-NYQYHT76.mjs.map +1 -0
  128. package/dist/chunk-OLJJGI5B.js +1193 -0
  129. package/dist/chunk-OLJJGI5B.js.map +1 -0
  130. package/dist/chunk-Q3572X2J.js +292 -0
  131. package/dist/chunk-Q3572X2J.js.map +1 -0
  132. package/dist/chunk-QH7N7D4I.mjs +210 -0
  133. package/dist/chunk-QH7N7D4I.mjs.map +1 -0
  134. package/dist/chunk-R7XUIV25.js +466 -0
  135. package/dist/chunk-R7XUIV25.js.map +1 -0
  136. package/dist/chunk-RFFO4KPM.js +135 -0
  137. package/dist/chunk-RFFO4KPM.js.map +1 -0
  138. package/dist/chunk-RFX7QKA7.mjs +180 -0
  139. package/dist/chunk-RFX7QKA7.mjs.map +1 -0
  140. package/dist/chunk-SN5LFAP3.js +940 -0
  141. package/dist/chunk-SN5LFAP3.js.map +1 -0
  142. package/dist/chunk-T4COXKQ3.js +24 -0
  143. package/dist/chunk-T4COXKQ3.js.map +1 -0
  144. package/dist/chunk-TS54QM27.js +125 -0
  145. package/dist/chunk-TS54QM27.js.map +1 -0
  146. package/dist/chunk-UE2S4PCX.mjs +220 -0
  147. package/dist/chunk-UE2S4PCX.mjs.map +1 -0
  148. package/dist/chunk-UTW3QX2A.mjs +282 -0
  149. package/dist/chunk-UTW3QX2A.mjs.map +1 -0
  150. package/dist/chunk-V74LGMAE.js +1767 -0
  151. package/dist/chunk-V74LGMAE.js.map +1 -0
  152. package/dist/chunk-VIREG536.js +12 -0
  153. package/dist/chunk-VIREG536.js.map +1 -0
  154. package/dist/chunk-VY7M7346.js +4 -0
  155. package/dist/chunk-VY7M7346.js.map +1 -0
  156. package/dist/chunk-W3TJOO7H.mjs +319 -0
  157. package/dist/chunk-W3TJOO7H.mjs.map +1 -0
  158. package/dist/chunk-WIUOB36M.js +54 -0
  159. package/dist/chunk-WIUOB36M.js.map +1 -0
  160. package/dist/chunk-WJGLM4CY.js +291 -0
  161. package/dist/chunk-WJGLM4CY.js.map +1 -0
  162. package/dist/chunk-WNURH5OO.mjs +453 -0
  163. package/dist/chunk-WNURH5OO.mjs.map +1 -0
  164. package/dist/chunk-X25TNRSD.mjs +364 -0
  165. package/dist/chunk-X25TNRSD.mjs.map +1 -0
  166. package/dist/chunk-Y3GT7ETK.js +108 -0
  167. package/dist/chunk-Y3GT7ETK.js.map +1 -0
  168. package/dist/chunk-Z4FRNOF6.mjs +115 -0
  169. package/dist/chunk-Z4FRNOF6.mjs.map +1 -0
  170. package/dist/chunk-ZMYLD3BN.js +166 -0
  171. package/dist/chunk-ZMYLD3BN.js.map +1 -0
  172. package/dist/chunk-ZP2KV6EX.js +815 -0
  173. package/dist/chunk-ZP2KV6EX.js.map +1 -0
  174. package/dist/chunk-ZVKXFELU.js +366 -0
  175. package/dist/chunk-ZVKXFELU.js.map +1 -0
  176. package/dist/elements/Accordion/Accordion.d.ts +139 -0
  177. package/dist/elements/Accordion/Accordion.d.ts.map +1 -0
  178. package/dist/elements/Accordion/Accordion.types.d.ts +143 -0
  179. package/dist/elements/Accordion/Accordion.types.d.ts.map +1 -0
  180. package/dist/elements/Accordion/index.d.ts +13 -0
  181. package/dist/elements/Accordion/index.d.ts.map +1 -0
  182. package/dist/elements/Accordion/index.js +78 -0
  183. package/dist/elements/Accordion/index.js.map +1 -0
  184. package/dist/elements/Accordion/index.mjs +5 -0
  185. package/dist/elements/Accordion/index.mjs.map +1 -0
  186. package/dist/elements/Avatar/Avatar.d.ts +51 -0
  187. package/dist/elements/Avatar/Avatar.d.ts.map +1 -0
  188. package/dist/elements/Avatar/Avatar.types.d.ts +145 -0
  189. package/dist/elements/Avatar/Avatar.types.d.ts.map +1 -0
  190. package/dist/elements/Avatar/AvatarGroup.d.ts +32 -0
  191. package/dist/elements/Avatar/AvatarGroup.d.ts.map +1 -0
  192. package/dist/elements/Avatar/index.d.ts +11 -0
  193. package/dist/elements/Avatar/index.d.ts.map +1 -0
  194. package/dist/elements/Avatar/index.js +54 -0
  195. package/dist/elements/Avatar/index.js.map +1 -0
  196. package/dist/elements/Avatar/index.mjs +5 -0
  197. package/dist/elements/Avatar/index.mjs.map +1 -0
  198. package/dist/elements/Badge/Badge.d.ts +39 -0
  199. package/dist/elements/Badge/Badge.d.ts.map +1 -0
  200. package/dist/elements/Badge/Badge.types.d.ts +76 -0
  201. package/dist/elements/Badge/Badge.types.d.ts.map +1 -0
  202. package/dist/elements/Badge/index.d.ts +18 -0
  203. package/dist/elements/Badge/index.d.ts.map +1 -0
  204. package/dist/elements/Badge/index.js +43 -0
  205. package/dist/elements/Badge/index.js.map +1 -0
  206. package/dist/elements/Badge/index.mjs +6 -0
  207. package/dist/elements/Badge/index.mjs.map +1 -0
  208. package/dist/elements/Breadcrumbs/Breadcrumbs.d.ts +91 -0
  209. package/dist/elements/Breadcrumbs/Breadcrumbs.d.ts.map +1 -0
  210. package/dist/elements/Breadcrumbs/Breadcrumbs.types.d.ts +114 -0
  211. package/dist/elements/Breadcrumbs/Breadcrumbs.types.d.ts.map +1 -0
  212. package/dist/elements/Breadcrumbs/index.d.ts +14 -0
  213. package/dist/elements/Breadcrumbs/index.d.ts.map +1 -0
  214. package/dist/elements/Breadcrumbs/index.js +54 -0
  215. package/dist/elements/Breadcrumbs/index.js.map +1 -0
  216. package/dist/elements/Breadcrumbs/index.mjs +9 -0
  217. package/dist/elements/Breadcrumbs/index.mjs.map +1 -0
  218. package/dist/elements/Button/Button.d.ts +92 -0
  219. package/dist/elements/Button/Button.d.ts.map +1 -0
  220. package/dist/elements/Button/Button.types.d.ts +54 -0
  221. package/dist/elements/Button/Button.types.d.ts.map +1 -0
  222. package/dist/elements/Button/index.d.ts +18 -0
  223. package/dist/elements/Button/index.d.ts.map +1 -0
  224. package/dist/elements/Button/index.js +27 -0
  225. package/dist/elements/Button/index.js.map +1 -0
  226. package/dist/elements/Button/index.mjs +6 -0
  227. package/dist/elements/Button/index.mjs.map +1 -0
  228. package/dist/elements/ButtonGroup/ButtonGroup.d.ts +53 -0
  229. package/dist/elements/ButtonGroup/ButtonGroup.d.ts.map +1 -0
  230. package/dist/elements/ButtonGroup/ButtonGroup.types.d.ts +98 -0
  231. package/dist/elements/ButtonGroup/ButtonGroup.types.d.ts.map +1 -0
  232. package/dist/elements/ButtonGroup/ButtonGroup.utils.d.ts +60 -0
  233. package/dist/elements/ButtonGroup/ButtonGroup.utils.d.ts.map +1 -0
  234. package/dist/elements/ButtonGroup/ButtonGroup.variants.d.ts +39 -0
  235. package/dist/elements/ButtonGroup/ButtonGroup.variants.d.ts.map +1 -0
  236. package/dist/elements/ButtonGroup/ButtonGroupContext.d.ts +42 -0
  237. package/dist/elements/ButtonGroup/ButtonGroupContext.d.ts.map +1 -0
  238. package/dist/elements/ButtonGroup/index.d.ts +35 -0
  239. package/dist/elements/ButtonGroup/index.d.ts.map +1 -0
  240. package/dist/elements/ButtonGroup/index.js +66 -0
  241. package/dist/elements/ButtonGroup/index.js.map +1 -0
  242. package/dist/elements/ButtonGroup/index.mjs +5 -0
  243. package/dist/elements/ButtonGroup/index.mjs.map +1 -0
  244. package/dist/elements/Card/Card.d.ts +104 -0
  245. package/dist/elements/Card/Card.d.ts.map +1 -0
  246. package/dist/elements/Card/Card.types.d.ts +227 -0
  247. package/dist/elements/Card/Card.types.d.ts.map +1 -0
  248. package/dist/elements/Card/index.d.ts +38 -0
  249. package/dist/elements/Card/index.d.ts.map +1 -0
  250. package/dist/elements/Card/index.js +85 -0
  251. package/dist/elements/Card/index.js.map +1 -0
  252. package/dist/elements/Card/index.mjs +8 -0
  253. package/dist/elements/Card/index.mjs.map +1 -0
  254. package/dist/elements/Carousel/Carousel.d.ts +13 -0
  255. package/dist/elements/Carousel/Carousel.d.ts.map +1 -0
  256. package/dist/elements/Carousel/Carousel.types.d.ts +65 -0
  257. package/dist/elements/Carousel/Carousel.types.d.ts.map +1 -0
  258. package/dist/elements/Carousel/LazyCarousel.d.ts +46 -0
  259. package/dist/elements/Carousel/LazyCarousel.d.ts.map +1 -0
  260. package/dist/elements/Carousel/index.d.ts +5 -0
  261. package/dist/elements/Carousel/index.d.ts.map +1 -0
  262. package/dist/elements/Carousel/index.js +23 -0
  263. package/dist/elements/Carousel/index.js.map +1 -0
  264. package/dist/elements/Carousel/index.mjs +10 -0
  265. package/dist/elements/Carousel/index.mjs.map +1 -0
  266. package/dist/elements/Chart/Chart.d.ts +44 -0
  267. package/dist/elements/Chart/Chart.d.ts.map +1 -0
  268. package/dist/elements/Chart/Chart.types.d.ts +254 -0
  269. package/dist/elements/Chart/Chart.types.d.ts.map +1 -0
  270. package/dist/elements/Chart/ChartAnnouncer.d.ts +24 -0
  271. package/dist/elements/Chart/ChartAnnouncer.d.ts.map +1 -0
  272. package/dist/elements/Chart/ChartAxis.d.ts +42 -0
  273. package/dist/elements/Chart/ChartAxis.d.ts.map +1 -0
  274. package/dist/elements/Chart/ChartBarSeries.d.ts +54 -0
  275. package/dist/elements/Chart/ChartBarSeries.d.ts.map +1 -0
  276. package/dist/elements/Chart/ChartContext.d.ts +46 -0
  277. package/dist/elements/Chart/ChartContext.d.ts.map +1 -0
  278. package/dist/elements/Chart/ChartDataPoint.d.ts +56 -0
  279. package/dist/elements/Chart/ChartDataPoint.d.ts.map +1 -0
  280. package/dist/elements/Chart/ChartDataTable.d.ts +35 -0
  281. package/dist/elements/Chart/ChartDataTable.d.ts.map +1 -0
  282. package/dist/elements/Chart/ChartGrid.d.ts +32 -0
  283. package/dist/elements/Chart/ChartGrid.d.ts.map +1 -0
  284. package/dist/elements/Chart/ChartLegend.d.ts +32 -0
  285. package/dist/elements/Chart/ChartLegend.d.ts.map +1 -0
  286. package/dist/elements/Chart/ChartLineSeries.d.ts +52 -0
  287. package/dist/elements/Chart/ChartLineSeries.d.ts.map +1 -0
  288. package/dist/elements/Chart/ChartSVG.d.ts +62 -0
  289. package/dist/elements/Chart/ChartSVG.d.ts.map +1 -0
  290. package/dist/elements/Chart/ChartTooltip.d.ts +45 -0
  291. package/dist/elements/Chart/ChartTooltip.d.ts.map +1 -0
  292. package/dist/elements/Chart/chart.constants.d.ts +108 -0
  293. package/dist/elements/Chart/chart.constants.d.ts.map +1 -0
  294. package/dist/elements/Chart/chart.variants.d.ts +45 -0
  295. package/dist/elements/Chart/chart.variants.d.ts.map +1 -0
  296. package/dist/elements/Chart/index.d.ts +12 -0
  297. package/dist/elements/Chart/index.d.ts.map +1 -0
  298. package/dist/elements/Chart/index.js +47 -0
  299. package/dist/elements/Chart/index.js.map +1 -0
  300. package/dist/elements/Chart/index.mjs +6 -0
  301. package/dist/elements/Chart/index.mjs.map +1 -0
  302. package/dist/elements/Chart/useChartDimensions.d.ts +18 -0
  303. package/dist/elements/Chart/useChartDimensions.d.ts.map +1 -0
  304. package/dist/elements/Chart/useChartKeyboard.d.ts +42 -0
  305. package/dist/elements/Chart/useChartKeyboard.d.ts.map +1 -0
  306. package/dist/elements/Chart/useRovingTabIndex.d.ts +46 -0
  307. package/dist/elements/Chart/useRovingTabIndex.d.ts.map +1 -0
  308. package/dist/elements/Checkbox/Checkbox.d.ts +94 -0
  309. package/dist/elements/Checkbox/Checkbox.d.ts.map +1 -0
  310. package/dist/elements/Checkbox/Checkbox.types.d.ts +82 -0
  311. package/dist/elements/Checkbox/Checkbox.types.d.ts.map +1 -0
  312. package/dist/elements/Checkbox/index.d.ts +7 -0
  313. package/dist/elements/Checkbox/index.d.ts.map +1 -0
  314. package/dist/elements/Checkbox/index.js +47 -0
  315. package/dist/elements/Checkbox/index.js.map +1 -0
  316. package/dist/elements/Checkbox/index.mjs +6 -0
  317. package/dist/elements/Checkbox/index.mjs.map +1 -0
  318. package/dist/elements/CheckboxGroup/CheckboxGroup.d.ts +130 -0
  319. package/dist/elements/CheckboxGroup/CheckboxGroup.d.ts.map +1 -0
  320. package/dist/elements/CheckboxGroup/CheckboxGroup.types.d.ts +142 -0
  321. package/dist/elements/CheckboxGroup/CheckboxGroup.types.d.ts.map +1 -0
  322. package/dist/elements/CheckboxGroup/index.d.ts +10 -0
  323. package/dist/elements/CheckboxGroup/index.d.ts.map +1 -0
  324. package/dist/elements/CheckboxGroup/index.js +71 -0
  325. package/dist/elements/CheckboxGroup/index.js.map +1 -0
  326. package/dist/elements/CheckboxGroup/index.mjs +6 -0
  327. package/dist/elements/CheckboxGroup/index.mjs.map +1 -0
  328. package/dist/elements/DatePicker/Calendar.d.ts +16 -0
  329. package/dist/elements/DatePicker/Calendar.d.ts.map +1 -0
  330. package/dist/elements/DatePicker/DateField.d.ts +13 -0
  331. package/dist/elements/DatePicker/DateField.d.ts.map +1 -0
  332. package/dist/elements/DatePicker/DatePicker.d.ts +16 -0
  333. package/dist/elements/DatePicker/DatePicker.d.ts.map +1 -0
  334. package/dist/elements/DatePicker/DatePicker.types.d.ts +390 -0
  335. package/dist/elements/DatePicker/DatePicker.types.d.ts.map +1 -0
  336. package/dist/elements/DatePicker/DatePicker.variants.d.ts +42 -0
  337. package/dist/elements/DatePicker/DatePicker.variants.d.ts.map +1 -0
  338. package/dist/elements/DatePicker/DateRangePicker.d.ts +13 -0
  339. package/dist/elements/DatePicker/DateRangePicker.d.ts.map +1 -0
  340. package/dist/elements/DatePicker/index.d.ts +14 -0
  341. package/dist/elements/DatePicker/index.d.ts.map +1 -0
  342. package/dist/elements/DatePicker/index.js +123 -0
  343. package/dist/elements/DatePicker/index.js.map +1 -0
  344. package/dist/elements/DatePicker/index.mjs +6 -0
  345. package/dist/elements/DatePicker/index.mjs.map +1 -0
  346. package/dist/elements/Dropdown/Dropdown.d.ts +197 -0
  347. package/dist/elements/Dropdown/Dropdown.d.ts.map +1 -0
  348. package/dist/elements/Dropdown/Dropdown.types.d.ts +175 -0
  349. package/dist/elements/Dropdown/Dropdown.types.d.ts.map +1 -0
  350. package/dist/elements/Dropdown/index.d.ts +12 -0
  351. package/dist/elements/Dropdown/index.d.ts.map +1 -0
  352. package/dist/elements/Dropdown/index.js +41 -0
  353. package/dist/elements/Dropdown/index.js.map +1 -0
  354. package/dist/elements/Dropdown/index.mjs +4 -0
  355. package/dist/elements/Dropdown/index.mjs.map +1 -0
  356. package/dist/elements/FileField/FileField.d.ts +46 -0
  357. package/dist/elements/FileField/FileField.d.ts.map +1 -0
  358. package/dist/elements/FileField/FileField.types.d.ts +99 -0
  359. package/dist/elements/FileField/FileField.types.d.ts.map +1 -0
  360. package/dist/elements/FileField/FileField.variants.d.ts +49 -0
  361. package/dist/elements/FileField/FileField.variants.d.ts.map +1 -0
  362. package/dist/elements/FileField/FilePreview.d.ts +27 -0
  363. package/dist/elements/FileField/FilePreview.d.ts.map +1 -0
  364. package/dist/elements/FileField/FileProgress.d.ts +35 -0
  365. package/dist/elements/FileField/FileProgress.d.ts.map +1 -0
  366. package/dist/elements/FileField/FileProgress.variants.d.ts +55 -0
  367. package/dist/elements/FileField/FileProgress.variants.d.ts.map +1 -0
  368. package/dist/elements/FileField/index.d.ts +41 -0
  369. package/dist/elements/FileField/index.d.ts.map +1 -0
  370. package/dist/elements/FileField/index.js +138 -0
  371. package/dist/elements/FileField/index.js.map +1 -0
  372. package/dist/elements/FileField/index.mjs +9 -0
  373. package/dist/elements/FileField/index.mjs.map +1 -0
  374. package/dist/elements/FileField/useFilePreview.d.ts +46 -0
  375. package/dist/elements/FileField/useFilePreview.d.ts.map +1 -0
  376. package/dist/elements/FileField/utils.d.ts +134 -0
  377. package/dist/elements/FileField/utils.d.ts.map +1 -0
  378. package/dist/elements/FormLayout/FormLayout.d.ts +51 -0
  379. package/dist/elements/FormLayout/FormLayout.d.ts.map +1 -0
  380. package/dist/elements/FormLayout/FormLayout.types.d.ts +66 -0
  381. package/dist/elements/FormLayout/FormLayout.types.d.ts.map +1 -0
  382. package/dist/elements/FormLayout/index.d.ts +3 -0
  383. package/dist/elements/FormLayout/index.d.ts.map +1 -0
  384. package/dist/elements/FormLayout/index.js +17 -0
  385. package/dist/elements/FormLayout/index.js.map +1 -0
  386. package/dist/elements/FormLayout/index.mjs +4 -0
  387. package/dist/elements/FormLayout/index.mjs.map +1 -0
  388. package/dist/elements/Modal/Modal.d.ts +168 -0
  389. package/dist/elements/Modal/Modal.d.ts.map +1 -0
  390. package/dist/elements/Modal/Modal.types.d.ts +265 -0
  391. package/dist/elements/Modal/Modal.types.d.ts.map +1 -0
  392. package/dist/elements/Modal/index.d.ts +14 -0
  393. package/dist/elements/Modal/index.d.ts.map +1 -0
  394. package/dist/elements/Modal/index.js +52 -0
  395. package/dist/elements/Modal/index.js.map +1 -0
  396. package/dist/elements/Modal/index.mjs +3 -0
  397. package/dist/elements/Modal/index.mjs.map +1 -0
  398. package/dist/elements/NumberField/NumberField.d.ts +43 -0
  399. package/dist/elements/NumberField/NumberField.d.ts.map +1 -0
  400. package/dist/elements/NumberField/NumberField.types.d.ts +112 -0
  401. package/dist/elements/NumberField/NumberField.types.d.ts.map +1 -0
  402. package/dist/elements/NumberField/NumberField.variants.d.ts +82 -0
  403. package/dist/elements/NumberField/NumberField.variants.d.ts.map +1 -0
  404. package/dist/elements/NumberField/index.d.ts +25 -0
  405. package/dist/elements/NumberField/index.d.ts.map +1 -0
  406. package/dist/elements/NumberField/index.js +57 -0
  407. package/dist/elements/NumberField/index.js.map +1 -0
  408. package/dist/elements/NumberField/index.mjs +8 -0
  409. package/dist/elements/NumberField/index.mjs.map +1 -0
  410. package/dist/elements/OTPInput/OTPInput.d.ts +105 -0
  411. package/dist/elements/OTPInput/OTPInput.d.ts.map +1 -0
  412. package/dist/elements/OTPInput/OTPInput.styles.d.ts +83 -0
  413. package/dist/elements/OTPInput/OTPInput.styles.d.ts.map +1 -0
  414. package/dist/elements/OTPInput/OTPInput.types.d.ts +189 -0
  415. package/dist/elements/OTPInput/OTPInput.types.d.ts.map +1 -0
  416. package/dist/elements/OTPInput/components/OTPDigit.d.ts +51 -0
  417. package/dist/elements/OTPInput/components/OTPDigit.d.ts.map +1 -0
  418. package/dist/elements/OTPInput/hooks/useOTPInput.d.ts +36 -0
  419. package/dist/elements/OTPInput/hooks/useOTPInput.d.ts.map +1 -0
  420. package/dist/elements/OTPInput/hooks/useOTPKeyboard.d.ts +59 -0
  421. package/dist/elements/OTPInput/hooks/useOTPKeyboard.d.ts.map +1 -0
  422. package/dist/elements/OTPInput/index.d.ts +27 -0
  423. package/dist/elements/OTPInput/index.d.ts.map +1 -0
  424. package/dist/elements/OTPInput/index.js +13 -0
  425. package/dist/elements/OTPInput/index.js.map +1 -0
  426. package/dist/elements/OTPInput/index.mjs +4 -0
  427. package/dist/elements/OTPInput/index.mjs.map +1 -0
  428. package/dist/elements/Panel/Panel.d.ts +111 -0
  429. package/dist/elements/Panel/Panel.d.ts.map +1 -0
  430. package/dist/elements/Panel/Panel.types.d.ts +243 -0
  431. package/dist/elements/Panel/Panel.types.d.ts.map +1 -0
  432. package/dist/elements/Panel/index.d.ts +4 -0
  433. package/dist/elements/Panel/index.d.ts.map +1 -0
  434. package/dist/elements/Panel/index.js +33 -0
  435. package/dist/elements/Panel/index.js.map +1 -0
  436. package/dist/elements/Panel/index.mjs +4 -0
  437. package/dist/elements/Panel/index.mjs.map +1 -0
  438. package/dist/elements/Progress/Progress.d.ts +44 -0
  439. package/dist/elements/Progress/Progress.d.ts.map +1 -0
  440. package/dist/elements/Progress/Progress.types.d.ts +64 -0
  441. package/dist/elements/Progress/Progress.types.d.ts.map +1 -0
  442. package/dist/elements/Progress/index.d.ts +11 -0
  443. package/dist/elements/Progress/index.d.ts.map +1 -0
  444. package/dist/elements/Progress/index.js +30 -0
  445. package/dist/elements/Progress/index.js.map +1 -0
  446. package/dist/elements/Progress/index.mjs +5 -0
  447. package/dist/elements/Progress/index.mjs.map +1 -0
  448. package/dist/elements/RadioGroup/RadioGroup.d.ts +110 -0
  449. package/dist/elements/RadioGroup/RadioGroup.d.ts.map +1 -0
  450. package/dist/elements/RadioGroup/RadioGroup.types.d.ts +143 -0
  451. package/dist/elements/RadioGroup/RadioGroup.types.d.ts.map +1 -0
  452. package/dist/elements/RadioGroup/index.d.ts +10 -0
  453. package/dist/elements/RadioGroup/index.d.ts.map +1 -0
  454. package/dist/elements/RadioGroup/index.js +47 -0
  455. package/dist/elements/RadioGroup/index.js.map +1 -0
  456. package/dist/elements/RadioGroup/index.mjs +6 -0
  457. package/dist/elements/RadioGroup/index.mjs.map +1 -0
  458. package/dist/elements/Resizable/Resizable.types.d.ts +188 -0
  459. package/dist/elements/Resizable/Resizable.types.d.ts.map +1 -0
  460. package/dist/elements/Resizable/components/ResizableHandle.d.ts +28 -0
  461. package/dist/elements/Resizable/components/ResizableHandle.d.ts.map +1 -0
  462. package/dist/elements/Resizable/components/ResizablePanel.d.ts +24 -0
  463. package/dist/elements/Resizable/components/ResizablePanel.d.ts.map +1 -0
  464. package/dist/elements/Resizable/components/ResizablePanelGroup.d.ts +26 -0
  465. package/dist/elements/Resizable/components/ResizablePanelGroup.d.ts.map +1 -0
  466. package/dist/elements/Resizable/components/ResizablePopover.d.ts +45 -0
  467. package/dist/elements/Resizable/components/ResizablePopover.d.ts.map +1 -0
  468. package/dist/elements/Resizable/hooks/useResizable.d.ts +50 -0
  469. package/dist/elements/Resizable/hooks/useResizable.d.ts.map +1 -0
  470. package/dist/elements/Resizable/hooks/useResizableContext.d.ts +36 -0
  471. package/dist/elements/Resizable/hooks/useResizableContext.d.ts.map +1 -0
  472. package/dist/elements/Resizable/index.d.ts +37 -0
  473. package/dist/elements/Resizable/index.d.ts.map +1 -0
  474. package/dist/elements/Resizable/index.js +65 -0
  475. package/dist/elements/Resizable/index.js.map +1 -0
  476. package/dist/elements/Resizable/index.mjs +8 -0
  477. package/dist/elements/Resizable/index.mjs.map +1 -0
  478. package/dist/elements/Select/Select.d.ts +184 -0
  479. package/dist/elements/Select/Select.d.ts.map +1 -0
  480. package/dist/elements/Select/Select.types.d.ts +166 -0
  481. package/dist/elements/Select/Select.types.d.ts.map +1 -0
  482. package/dist/elements/Select/index.d.ts +35 -0
  483. package/dist/elements/Select/index.d.ts.map +1 -0
  484. package/dist/elements/Select/index.js +33 -0
  485. package/dist/elements/Select/index.js.map +1 -0
  486. package/dist/elements/Select/index.mjs +4 -0
  487. package/dist/elements/Select/index.mjs.map +1 -0
  488. package/dist/elements/Skeleton/Skeleton.d.ts +31 -0
  489. package/dist/elements/Skeleton/Skeleton.d.ts.map +1 -0
  490. package/dist/elements/Skeleton/Skeleton.types.d.ts +36 -0
  491. package/dist/elements/Skeleton/Skeleton.types.d.ts.map +1 -0
  492. package/dist/elements/Skeleton/index.d.ts +11 -0
  493. package/dist/elements/Skeleton/index.d.ts.map +1 -0
  494. package/dist/elements/Skeleton/index.js +22 -0
  495. package/dist/elements/Skeleton/index.js.map +1 -0
  496. package/dist/elements/Skeleton/index.mjs +5 -0
  497. package/dist/elements/Skeleton/index.mjs.map +1 -0
  498. package/dist/elements/Switch/Switch.d.ts +39 -0
  499. package/dist/elements/Switch/Switch.d.ts.map +1 -0
  500. package/dist/elements/Switch/Switch.types.d.ts +53 -0
  501. package/dist/elements/Switch/Switch.types.d.ts.map +1 -0
  502. package/dist/elements/Switch/index.d.ts +8 -0
  503. package/dist/elements/Switch/index.d.ts.map +1 -0
  504. package/dist/elements/Switch/index.js +49 -0
  505. package/dist/elements/Switch/index.js.map +1 -0
  506. package/dist/elements/Switch/index.mjs +31 -0
  507. package/dist/elements/Switch/index.mjs.map +1 -0
  508. package/dist/elements/Table/Table.d.ts +123 -0
  509. package/dist/elements/Table/Table.d.ts.map +1 -0
  510. package/dist/elements/Table/Table.types.d.ts +356 -0
  511. package/dist/elements/Table/Table.types.d.ts.map +1 -0
  512. package/dist/elements/Table/index.d.ts +5 -0
  513. package/dist/elements/Table/index.d.ts.map +1 -0
  514. package/dist/elements/Table/index.js +76 -0
  515. package/dist/elements/Table/index.js.map +1 -0
  516. package/dist/elements/Table/index.mjs +7 -0
  517. package/dist/elements/Table/index.mjs.map +1 -0
  518. package/dist/elements/Tabs/Tabs.d.ts +129 -0
  519. package/dist/elements/Tabs/Tabs.d.ts.map +1 -0
  520. package/dist/elements/Tabs/Tabs.types.d.ts +179 -0
  521. package/dist/elements/Tabs/Tabs.types.d.ts.map +1 -0
  522. package/dist/elements/Tabs/index.d.ts +12 -0
  523. package/dist/elements/Tabs/index.d.ts.map +1 -0
  524. package/dist/elements/Tabs/index.js +74 -0
  525. package/dist/elements/Tabs/index.js.map +1 -0
  526. package/dist/elements/Tabs/index.mjs +5 -0
  527. package/dist/elements/Tabs/index.mjs.map +1 -0
  528. package/dist/elements/TextField/TextField.d.ts +155 -0
  529. package/dist/elements/TextField/TextField.d.ts.map +1 -0
  530. package/dist/elements/TextField/TextField.types.d.ts +258 -0
  531. package/dist/elements/TextField/TextField.types.d.ts.map +1 -0
  532. package/dist/elements/TextField/index.css +23 -0
  533. package/dist/elements/TextField/index.css.map +1 -0
  534. package/dist/elements/TextField/index.d.ts +13 -0
  535. package/dist/elements/TextField/index.d.ts.map +1 -0
  536. package/dist/elements/TextField/index.js +260 -0
  537. package/dist/elements/TextField/index.js.map +1 -0
  538. package/dist/elements/TextField/index.mjs +207 -0
  539. package/dist/elements/TextField/index.mjs.map +1 -0
  540. package/dist/elements/TimeField/TimeField.d.ts +34 -0
  541. package/dist/elements/TimeField/TimeField.d.ts.map +1 -0
  542. package/dist/elements/TimeField/TimeField.types.d.ts +151 -0
  543. package/dist/elements/TimeField/TimeField.types.d.ts.map +1 -0
  544. package/dist/elements/TimeField/index.d.ts +24 -0
  545. package/dist/elements/TimeField/index.d.ts.map +1 -0
  546. package/dist/elements/TimeField/index.js +45 -0
  547. package/dist/elements/TimeField/index.js.map +1 -0
  548. package/dist/elements/TimeField/index.mjs +4 -0
  549. package/dist/elements/TimeField/index.mjs.map +1 -0
  550. package/dist/elements/Toast/Toast.d.ts +105 -0
  551. package/dist/elements/Toast/Toast.d.ts.map +1 -0
  552. package/dist/elements/Toast/Toast.types.d.ts +209 -0
  553. package/dist/elements/Toast/Toast.types.d.ts.map +1 -0
  554. package/dist/elements/Toast/ToastProvider.d.ts +37 -0
  555. package/dist/elements/Toast/ToastProvider.d.ts.map +1 -0
  556. package/dist/elements/Toast/Toaster.d.ts +18 -0
  557. package/dist/elements/Toast/Toaster.d.ts.map +1 -0
  558. package/dist/elements/Toast/index.d.ts +27 -0
  559. package/dist/elements/Toast/index.d.ts.map +1 -0
  560. package/dist/elements/Toast/index.js +60 -0
  561. package/dist/elements/Toast/index.js.map +1 -0
  562. package/dist/elements/Toast/index.mjs +7 -0
  563. package/dist/elements/Toast/index.mjs.map +1 -0
  564. package/dist/elements/Tooltip/Tooltip.d.ts +108 -0
  565. package/dist/elements/Tooltip/Tooltip.d.ts.map +1 -0
  566. package/dist/elements/Tooltip/Tooltip.types.d.ts +135 -0
  567. package/dist/elements/Tooltip/Tooltip.types.d.ts.map +1 -0
  568. package/dist/elements/Tooltip/index.d.ts +11 -0
  569. package/dist/elements/Tooltip/index.d.ts.map +1 -0
  570. package/dist/elements/Tooltip/index.js +59 -0
  571. package/dist/elements/Tooltip/index.js.map +1 -0
  572. package/dist/elements/Tooltip/index.mjs +6 -0
  573. package/dist/elements/Tooltip/index.mjs.map +1 -0
  574. package/dist/elements/index.css +23 -0
  575. package/dist/elements/index.css.map +1 -0
  576. package/dist/elements/index.d.ts +42 -0
  577. package/dist/elements/index.d.ts.map +1 -0
  578. package/dist/elements/index.js +839 -0
  579. package/dist/elements/index.js.map +1 -0
  580. package/dist/elements/index.mjs +42 -0
  581. package/dist/elements/index.mjs.map +1 -0
  582. package/dist/index.css +23 -0
  583. package/dist/index.css.map +1 -0
  584. package/dist/index.d.ts +4 -0
  585. package/dist/index.d.ts.map +1 -0
  586. package/dist/index.js +865 -0
  587. package/dist/index.js.map +1 -0
  588. package/dist/index.mjs +44 -0
  589. package/dist/index.mjs.map +1 -0
  590. package/dist/schemas/BaseComponentProps.d.ts +25 -0
  591. package/dist/schemas/BaseComponentProps.d.ts.map +1 -0
  592. package/dist/schemas/RegistryItem.d.ts +55 -0
  593. package/dist/schemas/RegistryItem.d.ts.map +1 -0
  594. package/dist/schemas/index.d.ts +3 -0
  595. package/dist/schemas/index.d.ts.map +1 -0
  596. package/dist/schemas/index.js +29 -0
  597. package/dist/schemas/index.js.map +1 -0
  598. package/dist/schemas/index.mjs +4 -0
  599. package/dist/schemas/index.mjs.map +1 -0
  600. package/dist/styles/defaults.css +174 -0
  601. package/dist/styles/index.d.ts +7 -0
  602. package/dist/styles/index.d.ts.map +1 -0
  603. package/dist/styles/index.js +153 -0
  604. package/dist/styles/index.js.map +1 -0
  605. package/dist/styles/index.mjs +4 -0
  606. package/dist/styles/index.mjs.map +1 -0
  607. package/dist/styles/interaction-states.d.ts +96 -0
  608. package/dist/styles/interaction-states.d.ts.map +1 -0
  609. package/dist/styles/shared-variants.d.ts +120 -0
  610. package/dist/styles/shared-variants.d.ts.map +1 -0
  611. package/dist/styles/tokens.css +89 -0
  612. package/dist/utils/cn.d.ts +13 -0
  613. package/dist/utils/cn.d.ts.map +1 -0
  614. package/dist/utils/index.d.ts +2 -0
  615. package/dist/utils/index.d.ts.map +1 -0
  616. package/dist/utils/index.js +13 -0
  617. package/dist/utils/index.js.map +1 -0
  618. package/dist/utils/index.mjs +4 -0
  619. package/dist/utils/index.mjs.map +1 -0
  620. package/package.json +228 -0
  621. package/src/elements/Accordion/Accordion.stories.tsx +793 -0
  622. package/src/elements/Avatar/Avatar.stories.tsx +408 -0
  623. package/src/elements/Badge/Badge.stories.tsx +509 -0
  624. package/src/elements/Breadcrumbs/Breadcrumbs.stories.tsx +623 -0
  625. package/src/elements/Button/Button.stories.tsx +670 -0
  626. package/src/elements/ButtonGroup/ButtonGroup.stories.tsx +658 -0
  627. package/src/elements/Card/Card.stories.tsx +570 -0
  628. package/src/elements/Carousel/Carousel.stories.tsx +597 -0
  629. package/src/elements/Chart/Chart.stories.tsx +616 -0
  630. package/src/elements/Checkbox/Checkbox.stories.tsx +514 -0
  631. package/src/elements/CheckboxGroup/CheckboxGroup.stories.tsx +1514 -0
  632. package/src/elements/DatePicker/DatePicker.stories.tsx +341 -0
  633. package/src/elements/Dropdown/Dropdown.stories.tsx +397 -0
  634. package/src/elements/FileField/FileField.stories.tsx +1021 -0
  635. package/src/elements/FileField/FileProgress.stories.tsx +359 -0
  636. package/src/elements/FormLayout/FormLayout.stories.tsx +637 -0
  637. package/src/elements/Modal/Modal.stories.tsx +640 -0
  638. package/src/elements/NumberField/NumberField.stories.tsx +678 -0
  639. package/src/elements/OTPInput/OTPInput.stories.tsx +404 -0
  640. package/src/elements/Panel/Panel.stories.tsx +769 -0
  641. package/src/elements/Progress/Progress.stories.tsx +668 -0
  642. package/src/elements/RadioGroup/RadioGroup.stories.tsx +1153 -0
  643. package/src/elements/Resizable/Resizable.stories.tsx +374 -0
  644. package/src/elements/Select/Select.stories.tsx +362 -0
  645. package/src/elements/Skeleton/Skeleton.stories.tsx +284 -0
  646. package/src/elements/Switch/Switch.stories.tsx +441 -0
  647. package/src/elements/Table/Table.stories.tsx +790 -0
  648. package/src/elements/Tabs/Tabs.stories.tsx +661 -0
  649. package/src/elements/TextField/TextField.stories.tsx +1878 -0
  650. package/src/elements/TimeField/TimeField.stories.tsx +671 -0
  651. package/src/elements/Toast/Toast.stories.tsx +971 -0
  652. package/src/elements/Tooltip/Tooltip.stories.tsx +748 -0
  653. package/tailwind.config.js +10 -0
  654. package/tailwind.config.v3.js +10 -0
@@ -0,0 +1,1021 @@
1
+ /**
2
+ * FileField Component Stories
3
+ * Storybook stories for FileField component demonstrating all variants, states, and features
4
+ *
5
+ * @see plan.md for architecture details
6
+ * @see filefield-prd.md for requirements
7
+ */
8
+
9
+ import { useState, type FormEvent } from 'react';
10
+ import type { Meta, StoryObj } from '@storybook/nextjs';
11
+ import { FileField } from './FileField';
12
+ import { formatFileSize, formatAcceptedTypes } from './utils';
13
+
14
+ const meta = {
15
+ title: 'Elements/FileField',
16
+ component: FileField,
17
+ parameters: {
18
+ layout: 'centered',
19
+ docs: {
20
+ description: {
21
+ component:
22
+ 'Accessible file selection input with drag-and-drop support. Built with React Aria FileTrigger primitive and WCAG 2.2 AAA compliance (7:1 contrast ratio, 44x44px touch targets).',
23
+ },
24
+ },
25
+ },
26
+ tags: ['autodocs'],
27
+ argTypes: {
28
+ label: {
29
+ control: 'text',
30
+ description: 'Label for the file field',
31
+ },
32
+ description: {
33
+ control: 'text',
34
+ description: 'Helper text below the drop zone',
35
+ },
36
+ size: {
37
+ control: 'select',
38
+ options: ['sm', 'default', 'lg'],
39
+ description: 'Size variant',
40
+ table: {
41
+ defaultValue: { summary: 'default' },
42
+ },
43
+ },
44
+ allowsMultiple: {
45
+ control: 'boolean',
46
+ description: 'Allow multiple file selection',
47
+ table: {
48
+ defaultValue: { summary: 'false' },
49
+ },
50
+ },
51
+ acceptedFileTypes: {
52
+ control: 'object',
53
+ description: 'Array of accepted MIME types or extensions',
54
+ },
55
+ maxFileSize: {
56
+ control: 'number',
57
+ description: 'Maximum file size in bytes',
58
+ },
59
+ maxFiles: {
60
+ control: 'number',
61
+ description: 'Maximum number of files (for multiple mode)',
62
+ },
63
+ isRequired: {
64
+ control: 'boolean',
65
+ description: 'Mark field as required',
66
+ table: {
67
+ defaultValue: { summary: 'false' },
68
+ },
69
+ },
70
+ isDisabled: {
71
+ control: 'boolean',
72
+ description: 'Disable the field',
73
+ table: {
74
+ defaultValue: { summary: 'false' },
75
+ },
76
+ },
77
+ isInvalid: {
78
+ control: 'boolean',
79
+ description: 'Show error state',
80
+ table: {
81
+ defaultValue: { summary: 'false' },
82
+ },
83
+ },
84
+ isValid: {
85
+ control: 'boolean',
86
+ description: 'Show success state',
87
+ table: {
88
+ defaultValue: { summary: 'false' },
89
+ },
90
+ },
91
+ errorMessage: {
92
+ control: 'text',
93
+ description: 'Error message to display',
94
+ },
95
+ successMessage: {
96
+ control: 'text',
97
+ description: 'Success message to display',
98
+ },
99
+ triggerText: {
100
+ control: 'text',
101
+ description: 'Custom text for the trigger button',
102
+ },
103
+ },
104
+ } satisfies Meta<typeof FileField>;
105
+
106
+ export default meta;
107
+ type Story = StoryObj<typeof meta>;
108
+
109
+ // Default story
110
+ export const Default: Story = {
111
+ args: {
112
+ label: 'Upload File',
113
+ description: 'Select a file to upload',
114
+ },
115
+ };
116
+
117
+ // ============================================================================
118
+ // Size Variants
119
+ // ============================================================================
120
+
121
+ export const Small: Story = {
122
+ args: {
123
+ label: 'Upload File',
124
+ size: 'sm',
125
+ description: 'Small size variant',
126
+ },
127
+ };
128
+
129
+ export const Large: Story = {
130
+ args: {
131
+ label: 'Upload File',
132
+ size: 'lg',
133
+ description: 'Large size variant',
134
+ },
135
+ };
136
+
137
+ export const AllSizes: Story = {
138
+ render: () => (
139
+ <div className="flex flex-col gap-6 w-[400px]">
140
+ <FileField label="Small" size="sm" description="Size: sm" />
141
+ <FileField label="Default" size="default" description="Size: default" />
142
+ <FileField label="Large" size="lg" description="Size: lg" />
143
+ </div>
144
+ ),
145
+ parameters: {
146
+ docs: {
147
+ description: {
148
+ story: 'All 3 size variants for comparison.',
149
+ },
150
+ },
151
+ },
152
+ };
153
+
154
+ // ============================================================================
155
+ // Multiple File Selection
156
+ // ============================================================================
157
+
158
+ export const MultipleFiles: Story = {
159
+ args: {
160
+ label: 'Upload Documents',
161
+ allowsMultiple: true,
162
+ description: 'Select multiple files',
163
+ },
164
+ parameters: {
165
+ docs: {
166
+ description: {
167
+ story: 'Allows selecting multiple files at once.',
168
+ },
169
+ },
170
+ },
171
+ };
172
+
173
+ export const MultipleWithLimit: Story = {
174
+ args: {
175
+ label: 'Upload Photos',
176
+ allowsMultiple: true,
177
+ maxFiles: 5,
178
+ description: 'Maximum 5 files allowed',
179
+ },
180
+ parameters: {
181
+ docs: {
182
+ description: {
183
+ story: 'Multiple file selection with a maximum count limit.',
184
+ },
185
+ },
186
+ },
187
+ };
188
+
189
+ // Interactive story with state
190
+ export const InteractiveMultiple: Story = {
191
+ render: function InteractiveMultipleStory() {
192
+ const [files, setFiles] = useState<File[]>([]);
193
+ return (
194
+ <div className="w-[400px]">
195
+ <FileField
196
+ label="Upload Documents"
197
+ allowsMultiple
198
+ maxFiles={5}
199
+ description={`${files.length}/5 files selected`}
200
+ value={files}
201
+ onChange={setFiles}
202
+ />
203
+ </div>
204
+ );
205
+ },
206
+ parameters: {
207
+ docs: {
208
+ description: {
209
+ story: 'Interactive example with file state management.',
210
+ },
211
+ },
212
+ },
213
+ };
214
+
215
+ // ============================================================================
216
+ // File Type Restrictions
217
+ // ============================================================================
218
+
219
+ export const ImageOnly: Story = {
220
+ args: {
221
+ label: 'Upload Image',
222
+ acceptedFileTypes: ['image/*'],
223
+ description: 'Accepts: images only',
224
+ },
225
+ };
226
+
227
+ export const PDFOnly: Story = {
228
+ args: {
229
+ label: 'Upload PDF',
230
+ acceptedFileTypes: ['application/pdf'],
231
+ description: 'Accepts: PDF files only',
232
+ },
233
+ };
234
+
235
+ export const DocumentTypes: Story = {
236
+ args: {
237
+ label: 'Upload Document',
238
+ acceptedFileTypes: ['application/pdf', '.doc', '.docx', '.txt'],
239
+ description: 'Accepts: PDF, DOC, DOCX, TXT',
240
+ },
241
+ };
242
+
243
+ export const MultipleTypes: Story = {
244
+ args: {
245
+ label: 'Upload Media',
246
+ acceptedFileTypes: ['image/*', 'video/*', 'audio/*'],
247
+ description: 'Accepts: images, videos, audio files',
248
+ },
249
+ };
250
+
251
+ // ============================================================================
252
+ // Size Limits
253
+ // ============================================================================
254
+
255
+ export const WithSizeLimit: Story = {
256
+ args: {
257
+ label: 'Upload Resume',
258
+ acceptedFileTypes: ['application/pdf'],
259
+ maxFileSize: 5 * 1024 * 1024, // 5MB
260
+ description: `Maximum size: ${formatFileSize(5 * 1024 * 1024)}`,
261
+ },
262
+ parameters: {
263
+ docs: {
264
+ description: {
265
+ story: 'File field with maximum file size validation.',
266
+ },
267
+ },
268
+ },
269
+ };
270
+
271
+ export const SmallSizeLimit: Story = {
272
+ args: {
273
+ label: 'Upload Avatar',
274
+ acceptedFileTypes: ['image/*'],
275
+ maxFileSize: 1024 * 1024, // 1MB
276
+ description: `Maximum size: ${formatFileSize(1024 * 1024)}`,
277
+ },
278
+ };
279
+
280
+ // ============================================================================
281
+ // Validation States
282
+ // ============================================================================
283
+
284
+ export const Required: Story = {
285
+ args: {
286
+ label: 'Upload Resume',
287
+ isRequired: true,
288
+ description: 'This field is required',
289
+ },
290
+ };
291
+
292
+ export const Invalid: Story = {
293
+ args: {
294
+ label: 'Upload File',
295
+ isInvalid: true,
296
+ errorMessage: 'Please upload a valid file',
297
+ },
298
+ };
299
+
300
+ export const Valid: Story = {
301
+ args: {
302
+ label: 'Upload File',
303
+ isValid: true,
304
+ successMessage: 'File is ready for upload',
305
+ },
306
+ };
307
+
308
+ export const CustomValidation: Story = {
309
+ render: function CustomValidationStory() {
310
+ const [files, setFiles] = useState<File[]>([]);
311
+ const [error, setError] = useState<string | undefined>();
312
+
313
+ const handleChange = (newFiles: File[]) => {
314
+ setFiles(newFiles);
315
+ setError(undefined);
316
+ };
317
+
318
+ const validate = (filesToValidate: File[]) => {
319
+ const file = filesToValidate[0];
320
+ if (file && !file.name.toLowerCase().includes('resume')) {
321
+ return 'File name must contain "resume"';
322
+ }
323
+ return undefined;
324
+ };
325
+
326
+ return (
327
+ <div className="w-[400px]">
328
+ <FileField
329
+ label="Upload Resume"
330
+ description='File name must contain "resume"'
331
+ acceptedFileTypes={['application/pdf']}
332
+ value={files}
333
+ onChange={handleChange}
334
+ validate={validate}
335
+ errorMessage={error}
336
+ isInvalid={!!error}
337
+ />
338
+ </div>
339
+ );
340
+ },
341
+ parameters: {
342
+ docs: {
343
+ description: {
344
+ story: 'Custom validation function to check file names.',
345
+ },
346
+ },
347
+ },
348
+ };
349
+
350
+ // ============================================================================
351
+ // Disabled State
352
+ // ============================================================================
353
+
354
+ export const Disabled: Story = {
355
+ args: {
356
+ label: 'Upload File',
357
+ isDisabled: true,
358
+ description: 'This field is disabled',
359
+ },
360
+ };
361
+
362
+ export const DisabledWithFiles: Story = {
363
+ render: function DisabledWithFilesStory() {
364
+ const mockFile = new File(['content'], 'existing-file.pdf', {
365
+ type: 'application/pdf',
366
+ });
367
+ Object.defineProperty(mockFile, 'size', { value: 1024 * 100 }); // 100KB
368
+
369
+ return (
370
+ <div className="w-[400px]">
371
+ <FileField
372
+ label="Upload File"
373
+ isDisabled
374
+ value={[mockFile]}
375
+ description="Field is disabled but shows existing files"
376
+ />
377
+ </div>
378
+ );
379
+ },
380
+ parameters: {
381
+ docs: {
382
+ description: {
383
+ story: 'Disabled state with pre-selected files visible.',
384
+ },
385
+ },
386
+ },
387
+ };
388
+
389
+ // ============================================================================
390
+ // Custom Trigger Text
391
+ // ============================================================================
392
+
393
+ export const CustomTriggerText: Story = {
394
+ args: {
395
+ label: 'Upload Photo',
396
+ triggerText: 'Select photo from device',
397
+ acceptedFileTypes: ['image/*'],
398
+ },
399
+ };
400
+
401
+ export const DragDropHint: Story = {
402
+ args: {
403
+ label: 'Upload Documents',
404
+ triggerText: 'Click to browse or drag files here',
405
+ allowsMultiple: true,
406
+ },
407
+ };
408
+
409
+ // ============================================================================
410
+ // Real-World Examples
411
+ // ============================================================================
412
+
413
+ export const ResumeUpload: Story = {
414
+ render: function ResumeUploadStory() {
415
+ const [files, setFiles] = useState<File[]>([]);
416
+
417
+ return (
418
+ <div className="w-[400px] rounded-lg border border-[var(--border)] p-6">
419
+ <h3 className="mb-4 text-lg font-semibold">Job Application</h3>
420
+ <FileField
421
+ label="Resume"
422
+ description="PDF format, max 5MB"
423
+ acceptedFileTypes={['application/pdf']}
424
+ maxFileSize={5 * 1024 * 1024}
425
+ isRequired
426
+ value={files}
427
+ onChange={setFiles}
428
+ />
429
+ </div>
430
+ );
431
+ },
432
+ parameters: {
433
+ docs: {
434
+ description: {
435
+ story: 'Real-world example: Resume upload for job applications.',
436
+ },
437
+ },
438
+ },
439
+ };
440
+
441
+ export const ProfilePictureUpload: Story = {
442
+ render: function ProfilePictureUploadStory() {
443
+ const [files, setFiles] = useState<File[]>([]);
444
+
445
+ return (
446
+ <div className="w-[400px] rounded-lg border border-[var(--border)] p-6">
447
+ <h3 className="mb-4 text-lg font-semibold">Profile Settings</h3>
448
+ <FileField
449
+ label="Profile Picture"
450
+ description="JPG, PNG or GIF, max 2MB"
451
+ acceptedFileTypes={['image/jpeg', 'image/png', 'image/gif']}
452
+ maxFileSize={2 * 1024 * 1024}
453
+ size="sm"
454
+ value={files}
455
+ onChange={setFiles}
456
+ />
457
+ </div>
458
+ );
459
+ },
460
+ parameters: {
461
+ docs: {
462
+ description: {
463
+ story: 'Real-world example: Profile picture upload.',
464
+ },
465
+ },
466
+ },
467
+ };
468
+
469
+ export const DocumentPortfolio: Story = {
470
+ render: function DocumentPortfolioStory() {
471
+ const [files, setFiles] = useState<File[]>([]);
472
+
473
+ return (
474
+ <div className="w-[500px] rounded-lg border border-[var(--border)] p-6">
475
+ <h3 className="mb-4 text-lg font-semibold">Portfolio Submission</h3>
476
+ <FileField
477
+ label="Portfolio Documents"
478
+ description="Upload up to 10 documents (PDF, DOC, images)"
479
+ acceptedFileTypes={['application/pdf', '.doc', '.docx', 'image/*']}
480
+ maxFileSize={10 * 1024 * 1024}
481
+ maxFiles={10}
482
+ allowsMultiple
483
+ size="lg"
484
+ value={files}
485
+ onChange={setFiles}
486
+ />
487
+ {files.length > 0 && (
488
+ <p className="mt-4 text-sm text-[var(--muted-foreground)]">
489
+ {files.length} file{files.length > 1 ? 's' : ''} selected,{' '}
490
+ {formatFileSize(files.reduce((acc, f) => acc + f.size, 0))} total
491
+ </p>
492
+ )}
493
+ </div>
494
+ );
495
+ },
496
+ parameters: {
497
+ docs: {
498
+ description: {
499
+ story: 'Real-world example: Portfolio document upload with multiple files.',
500
+ },
501
+ },
502
+ },
503
+ };
504
+
505
+ // ============================================================================
506
+ // Accessibility Stories
507
+ // ============================================================================
508
+
509
+ export const FocusVisible: Story = {
510
+ args: {
511
+ label: 'Upload File',
512
+ description: 'Tab to see focus ring',
513
+ },
514
+ parameters: {
515
+ docs: {
516
+ description: {
517
+ story:
518
+ 'Press Tab to see the focus ring. Meets WCAG 2.2 AAA standards with visible focus indicator.',
519
+ },
520
+ },
521
+ },
522
+ };
523
+
524
+ export const TouchTarget: Story = {
525
+ args: {
526
+ label: 'Upload File',
527
+ size: 'sm',
528
+ description: 'Trigger button has 44x44px minimum touch target',
529
+ },
530
+ parameters: {
531
+ docs: {
532
+ description: {
533
+ story:
534
+ 'Even with small size, the trigger button maintains 44x44px minimum touch targets (WCAG 2.2 AAA).',
535
+ },
536
+ },
537
+ },
538
+ };
539
+
540
+ export const ScreenReaderFriendly: Story = {
541
+ args: {
542
+ label: 'Upload Resume',
543
+ description: 'PDF format only, maximum 5MB',
544
+ isRequired: true,
545
+ acceptedFileTypes: ['application/pdf'],
546
+ maxFileSize: 5 * 1024 * 1024,
547
+ },
548
+ parameters: {
549
+ docs: {
550
+ description: {
551
+ story:
552
+ 'All elements have proper ARIA attributes. Label, description, and error messages are associated with the input for screen readers.',
553
+ },
554
+ },
555
+ },
556
+ };
557
+
558
+ // ============================================================================
559
+ // Theme Integration
560
+ // ============================================================================
561
+
562
+ export const LightTheme: Story = {
563
+ args: {
564
+ label: 'Upload File',
565
+ description: 'Light theme',
566
+ },
567
+ parameters: {
568
+ backgrounds: { default: 'light' },
569
+ },
570
+ };
571
+
572
+ export const DarkTheme: Story = {
573
+ args: {
574
+ label: 'Upload File',
575
+ description: 'Dark theme',
576
+ },
577
+ parameters: {
578
+ backgrounds: { default: 'dark' },
579
+ docs: {
580
+ description: {
581
+ story: 'FileField adapts to dark theme via semantic tokens.',
582
+ },
583
+ },
584
+ },
585
+ };
586
+
587
+ // ============================================================================
588
+ // Form Integration
589
+ // ============================================================================
590
+
591
+ export const FormWithFileField: Story = {
592
+ render: function FormWithFileFieldStory() {
593
+ const [files, setFiles] = useState<File[]>([]);
594
+ const [submitted, setSubmitted] = useState(false);
595
+
596
+ const handleSubmit = (e: FormEvent) => {
597
+ e.preventDefault();
598
+ if (files.length > 0) {
599
+ setSubmitted(true);
600
+ setTimeout(() => setSubmitted(false), 2000);
601
+ }
602
+ };
603
+
604
+ return (
605
+ <form onSubmit={handleSubmit} className="w-[400px] space-y-4">
606
+ <div className="rounded-lg border border-[var(--border)] p-6">
607
+ <h3 className="mb-4 text-lg font-semibold">Contact Form</h3>
608
+ <div className="space-y-4">
609
+ <div>
610
+ <label className="block text-sm font-medium mb-1">Name</label>
611
+ <input
612
+ type="text"
613
+ className="w-full rounded-md border border-[var(--input)] px-3 py-2"
614
+ placeholder="Your name"
615
+ />
616
+ </div>
617
+ <FileField
618
+ label="Attachment"
619
+ name="attachment"
620
+ description="Optional file attachment"
621
+ value={files}
622
+ onChange={setFiles}
623
+ />
624
+ <button
625
+ type="submit"
626
+ className="w-full rounded-md bg-[var(--primary)] px-4 py-2 text-[var(--primary-foreground)] hover:bg-[var(--primary)]/90"
627
+ >
628
+ {submitted ? 'Submitted!' : 'Submit'}
629
+ </button>
630
+ </div>
631
+ </div>
632
+ </form>
633
+ );
634
+ },
635
+ parameters: {
636
+ docs: {
637
+ description: {
638
+ story: 'FileField integrated into a form with name prop for form data.',
639
+ },
640
+ },
641
+ },
642
+ };
643
+
644
+ // ============================================================================
645
+ // Phase 1: Image Previews
646
+ // ============================================================================
647
+
648
+ export const WithImagePreviews: Story = {
649
+ render: function WithImagePreviewsStory() {
650
+ const [files, setFiles] = useState<File[]>([]);
651
+
652
+ return (
653
+ <div className="w-[400px]">
654
+ <FileField
655
+ label="Upload Images"
656
+ description="Select images to see thumbnails"
657
+ acceptedFileTypes={['image/*']}
658
+ allowsMultiple
659
+ showPreviews
660
+ previewSize={64}
661
+ value={files}
662
+ onChange={setFiles}
663
+ />
664
+ </div>
665
+ );
666
+ },
667
+ parameters: {
668
+ docs: {
669
+ description: {
670
+ story:
671
+ 'Enable `showPreviews` to display thumbnail previews for image files. Memory-efficient with automatic cleanup.',
672
+ },
673
+ },
674
+ },
675
+ };
676
+
677
+ export const LargeImagePreviews: Story = {
678
+ render: function LargeImagePreviewsStory() {
679
+ const [files, setFiles] = useState<File[]>([]);
680
+
681
+ return (
682
+ <div className="w-[500px]">
683
+ <FileField
684
+ label="Upload Photos"
685
+ description="Large preview thumbnails (80px)"
686
+ acceptedFileTypes={['image/*']}
687
+ allowsMultiple
688
+ showPreviews
689
+ previewSize={80}
690
+ size="lg"
691
+ value={files}
692
+ onChange={setFiles}
693
+ />
694
+ </div>
695
+ );
696
+ },
697
+ parameters: {
698
+ docs: {
699
+ description: {
700
+ story: 'Larger preview thumbnails with `previewSize={80}` and large field size.',
701
+ },
702
+ },
703
+ },
704
+ };
705
+
706
+ export const SmallImagePreviews: Story = {
707
+ render: function SmallImagePreviewsStory() {
708
+ const [files, setFiles] = useState<File[]>([]);
709
+
710
+ return (
711
+ <div className="w-[350px]">
712
+ <FileField
713
+ label="Upload Icons"
714
+ description="Small preview thumbnails"
715
+ acceptedFileTypes={['image/*']}
716
+ allowsMultiple
717
+ showPreviews
718
+ previewSize={40}
719
+ size="sm"
720
+ value={files}
721
+ onChange={setFiles}
722
+ />
723
+ </div>
724
+ );
725
+ },
726
+ parameters: {
727
+ docs: {
728
+ description: {
729
+ story: 'Small preview thumbnails with `previewSize={40}` and small field size.',
730
+ },
731
+ },
732
+ },
733
+ };
734
+
735
+ export const MixedFilesWithPreviews: Story = {
736
+ render: function MixedFilesWithPreviewsStory() {
737
+ const [files, setFiles] = useState<File[]>([]);
738
+
739
+ return (
740
+ <div className="w-[400px]">
741
+ <FileField
742
+ label="Upload Documents & Images"
743
+ description="Images show previews, other files show icons"
744
+ acceptedFileTypes={['image/*', 'application/pdf', '.doc', '.docx']}
745
+ allowsMultiple
746
+ showPreviews
747
+ value={files}
748
+ onChange={setFiles}
749
+ />
750
+ </div>
751
+ );
752
+ },
753
+ parameters: {
754
+ docs: {
755
+ description: {
756
+ story:
757
+ 'When `showPreviews` is enabled with mixed file types, images get thumbnails while other files show type-appropriate icons.',
758
+ },
759
+ },
760
+ },
761
+ };
762
+
763
+ // ============================================================================
764
+ // Phase 1: Upload Progress
765
+ // ============================================================================
766
+
767
+ export const UploadProgressPending: Story = {
768
+ render: function UploadProgressPendingStory() {
769
+ // Create mock files
770
+ const mockFiles = [
771
+ new File(['content1'], 'document.pdf', { type: 'application/pdf' }),
772
+ new File(['content2'], 'image.jpg', { type: 'image/jpeg' }),
773
+ new File(['content3'], 'report.docx', { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }),
774
+ ];
775
+
776
+ return (
777
+ <div className="w-[400px]">
778
+ <FileField
779
+ label="Upload Files"
780
+ description="Files waiting to upload (shimmer animation)"
781
+ allowsMultiple
782
+ showProgress
783
+ value={mockFiles}
784
+ uploadStatus={['pending', 'pending', 'pending']}
785
+ uploadProgress={[0, 0, 0]}
786
+ />
787
+ </div>
788
+ );
789
+ },
790
+ parameters: {
791
+ docs: {
792
+ description: {
793
+ story:
794
+ 'Pending upload state shows shimmer animation indicating files are queued for upload.',
795
+ },
796
+ },
797
+ },
798
+ };
799
+
800
+ export const UploadProgressUploading: Story = {
801
+ render: function UploadProgressUploadingStory() {
802
+ const mockFiles = [
803
+ new File(['content1'], 'document.pdf', { type: 'application/pdf' }),
804
+ new File(['content2'], 'image.jpg', { type: 'image/jpeg' }),
805
+ new File(['content3'], 'report.docx', { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }),
806
+ ];
807
+
808
+ return (
809
+ <div className="w-[400px]">
810
+ <FileField
811
+ label="Upload Files"
812
+ description="Files currently uploading"
813
+ allowsMultiple
814
+ showProgress
815
+ value={mockFiles}
816
+ uploadStatus={['uploading', 'uploading', 'pending']}
817
+ uploadProgress={[75, 30, 0]}
818
+ />
819
+ </div>
820
+ );
821
+ },
822
+ parameters: {
823
+ docs: {
824
+ description: {
825
+ story:
826
+ 'Uploading state shows progress percentage with primary color fill.',
827
+ },
828
+ },
829
+ },
830
+ };
831
+
832
+ export const UploadProgressComplete: Story = {
833
+ render: function UploadProgressCompleteStory() {
834
+ const mockFiles = [
835
+ new File(['content1'], 'document.pdf', { type: 'application/pdf' }),
836
+ new File(['content2'], 'image.jpg', { type: 'image/jpeg' }),
837
+ ];
838
+
839
+ return (
840
+ <div className="w-[400px]">
841
+ <FileField
842
+ label="Upload Files"
843
+ description="Files successfully uploaded"
844
+ allowsMultiple
845
+ showProgress
846
+ value={mockFiles}
847
+ uploadStatus={['complete', 'complete']}
848
+ uploadProgress={[100, 100]}
849
+ />
850
+ </div>
851
+ );
852
+ },
853
+ parameters: {
854
+ docs: {
855
+ description: {
856
+ story:
857
+ 'Complete state shows success color (green) with 100% progress. Screen readers announce completion.',
858
+ },
859
+ },
860
+ },
861
+ };
862
+
863
+ export const UploadProgressError: Story = {
864
+ render: function UploadProgressErrorStory() {
865
+ const mockFiles = [
866
+ new File(['content1'], 'document.pdf', { type: 'application/pdf' }),
867
+ new File(['content2'], 'large-file.zip', { type: 'application/zip' }),
868
+ ];
869
+
870
+ const errors = new Map<number, string>();
871
+ errors.set(1, 'Network timeout - please try again');
872
+
873
+ const handleRetry = (index: number) => {
874
+ alert(`Retrying upload for file at index ${index}`);
875
+ };
876
+
877
+ return (
878
+ <div className="w-[400px]">
879
+ <FileField
880
+ label="Upload Files"
881
+ description="One file failed to upload"
882
+ allowsMultiple
883
+ showProgress
884
+ value={mockFiles}
885
+ uploadStatus={['complete', 'error']}
886
+ uploadProgress={[100, 45]}
887
+ uploadErrors={errors}
888
+ onRetry={handleRetry}
889
+ />
890
+ </div>
891
+ );
892
+ },
893
+ parameters: {
894
+ docs: {
895
+ description: {
896
+ story:
897
+ 'Error state shows destructive color (red) with error message and retry button. Screen readers announce failure.',
898
+ },
899
+ },
900
+ },
901
+ };
902
+
903
+ export const UploadProgressMixed: Story = {
904
+ render: function UploadProgressMixedStory() {
905
+ const mockFiles = [
906
+ new File(['content1'], 'document.pdf', { type: 'application/pdf' }),
907
+ new File(['content2'], 'image.jpg', { type: 'image/jpeg' }),
908
+ new File(['content3'], 'video.mp4', { type: 'video/mp4' }),
909
+ new File(['content4'], 'report.docx', { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }),
910
+ ];
911
+
912
+ const errors = new Map<number, string>();
913
+ errors.set(2, 'File too large');
914
+
915
+ return (
916
+ <div className="w-[400px]">
917
+ <FileField
918
+ label="Upload Files"
919
+ description="Mixed upload states"
920
+ allowsMultiple
921
+ showProgress
922
+ value={mockFiles}
923
+ uploadStatus={['complete', 'uploading', 'error', 'pending']}
924
+ uploadProgress={[100, 60, 30, 0]}
925
+ uploadErrors={errors}
926
+ onRetry={(index) => alert(`Retry file ${index}`)}
927
+ />
928
+ </div>
929
+ );
930
+ },
931
+ parameters: {
932
+ docs: {
933
+ description: {
934
+ story:
935
+ 'Real-world scenario showing multiple files in different upload states simultaneously.',
936
+ },
937
+ },
938
+ },
939
+ };
940
+
941
+ export const SimulatedUpload: Story = {
942
+ render: function SimulatedUploadStory() {
943
+ const [files, setFiles] = useState<File[]>([]);
944
+ const [progress, setProgress] = useState<number[]>([]);
945
+ const [status, setStatus] = useState<Array<'pending' | 'uploading' | 'complete' | 'error'>>([]);
946
+ const [isUploading, setIsUploading] = useState(false);
947
+
948
+ const simulateUpload = async () => {
949
+ if (files.length === 0) return;
950
+
951
+ setIsUploading(true);
952
+ // Initialize all files as pending
953
+ setStatus(files.map(() => 'pending'));
954
+ setProgress(files.map(() => 0));
955
+
956
+ // Simulate uploading each file
957
+ for (let i = 0; i < files.length; i++) {
958
+ // Set current file to uploading
959
+ setStatus(prev => {
960
+ const next = [...prev];
961
+ next[i] = 'uploading';
962
+ return next;
963
+ });
964
+
965
+ // Simulate progress
966
+ for (let p = 0; p <= 100; p += 10) {
967
+ await new Promise(resolve => setTimeout(resolve, 100));
968
+ setProgress(prev => {
969
+ const next = [...prev];
970
+ next[i] = p;
971
+ return next;
972
+ });
973
+ }
974
+
975
+ // Mark as complete
976
+ setStatus(prev => {
977
+ const next = [...prev];
978
+ next[i] = 'complete';
979
+ return next;
980
+ });
981
+ }
982
+
983
+ setIsUploading(false);
984
+ };
985
+
986
+ return (
987
+ <div className="w-[400px] space-y-4">
988
+ <FileField
989
+ label="Upload Files"
990
+ description="Select files and click Upload to simulate"
991
+ allowsMultiple
992
+ showProgress={status.length > 0}
993
+ value={files}
994
+ onChange={(newFiles) => {
995
+ setFiles(newFiles);
996
+ setStatus([]);
997
+ setProgress([]);
998
+ }}
999
+ uploadStatus={status}
1000
+ uploadProgress={progress}
1001
+ />
1002
+ <button
1003
+ type="button"
1004
+ onClick={simulateUpload}
1005
+ disabled={files.length === 0 || isUploading}
1006
+ className="w-full rounded-md bg-[var(--primary)] px-4 py-2 text-[var(--primary-foreground)] hover:bg-[var(--primary)]/90 disabled:opacity-50"
1007
+ >
1008
+ {isUploading ? 'Uploading...' : 'Simulate Upload'}
1009
+ </button>
1010
+ </div>
1011
+ );
1012
+ },
1013
+ parameters: {
1014
+ docs: {
1015
+ description: {
1016
+ story:
1017
+ 'Interactive demo: Select files and click "Simulate Upload" to see progress animation in action.',
1018
+ },
1019
+ },
1020
+ },
1021
+ };