@ayasofyazilim/ui 0.0.0 → 0.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 (667) hide show
  1. package/dist/aria/index.js +2 -0
  2. package/dist/aria/index.js.map +1 -0
  3. package/dist/aria/number-field.js +46 -0
  4. package/dist/aria/number-field.js.map +1 -0
  5. package/dist/components/accordion.js +66 -0
  6. package/dist/components/accordion.js.map +1 -0
  7. package/dist/components/alert-dialog.js +148 -0
  8. package/dist/components/alert-dialog.js.map +1 -0
  9. package/dist/components/alert.js +69 -0
  10. package/dist/components/alert.js.map +1 -0
  11. package/dist/components/aspect-ratio.js +12 -0
  12. package/dist/components/aspect-ratio.js.map +1 -0
  13. package/dist/components/avatar.js +55 -0
  14. package/dist/components/avatar.js.map +1 -0
  15. package/dist/components/badge.js +62 -0
  16. package/dist/components/badge.js.map +1 -0
  17. package/dist/components/breadcrumb.js +104 -0
  18. package/dist/components/breadcrumb.js.map +1 -0
  19. package/dist/components/button-group.js +77 -0
  20. package/dist/components/button-group.js.map +1 -0
  21. package/dist/components/button.js +56 -0
  22. package/dist/components/button.js.map +1 -0
  23. package/dist/components/calendar.js +196 -0
  24. package/dist/components/calendar.js.map +1 -0
  25. package/dist/components/card.js +91 -0
  26. package/dist/components/card.js.map +1 -0
  27. package/dist/components/carousel.js +200 -0
  28. package/dist/components/carousel.js.map +1 -0
  29. package/dist/components/chart.js +250 -0
  30. package/dist/components/chart.js.map +1 -0
  31. package/dist/components/checkbox.js +33 -0
  32. package/dist/components/checkbox.js.map +1 -0
  33. package/dist/components/collapsible.js +36 -0
  34. package/dist/components/collapsible.js.map +1 -0
  35. package/dist/components/command.js +178 -0
  36. package/dist/components/command.js.map +1 -0
  37. package/dist/components/context-menu.js +225 -0
  38. package/dist/components/context-menu.js.map +1 -0
  39. package/dist/components/dialog.js +139 -0
  40. package/dist/components/dialog.js.map +1 -0
  41. package/dist/components/drawer.js +130 -0
  42. package/dist/components/drawer.js.map +1 -0
  43. package/dist/components/dropdown-menu.js +234 -0
  44. package/dist/components/dropdown-menu.js.map +1 -0
  45. package/dist/components/empty.js +100 -0
  46. package/dist/components/empty.js.map +1 -0
  47. package/dist/components/field.js +231 -0
  48. package/dist/components/field.js.map +1 -0
  49. package/dist/components/form.js +124 -0
  50. package/dist/components/form.js.map +1 -0
  51. package/dist/components/hover-card.js +40 -0
  52. package/dist/components/hover-card.js.map +1 -0
  53. package/dist/components/input-group.js +156 -0
  54. package/dist/components/input-group.js.map +1 -0
  55. package/dist/components/input-otp.js +68 -0
  56. package/dist/components/input-otp.js.map +1 -0
  57. package/dist/components/input.js +22 -0
  58. package/dist/components/input.js.map +1 -0
  59. package/dist/components/item.js +188 -0
  60. package/dist/components/item.js.map +1 -0
  61. package/dist/components/kbd.js +32 -0
  62. package/dist/components/kbd.js.map +1 -0
  63. package/dist/components/label.js +24 -0
  64. package/dist/components/label.js.map +1 -0
  65. package/dist/components/menubar.js +253 -0
  66. package/dist/components/menubar.js.map +1 -0
  67. package/dist/components/navigation-menu.js +171 -0
  68. package/dist/components/navigation-menu.js.map +1 -0
  69. package/dist/components/pagination.js +125 -0
  70. package/dist/components/pagination.js.map +1 -0
  71. package/dist/components/popover.js +82 -0
  72. package/dist/components/popover.js.map +1 -0
  73. package/dist/components/progress.js +33 -0
  74. package/dist/components/progress.js.map +1 -0
  75. package/dist/components/radio-group.js +47 -0
  76. package/dist/components/radio-group.js.map +1 -0
  77. package/dist/components/resizable.js +50 -0
  78. package/dist/components/resizable.js.map +1 -0
  79. package/dist/components/scroll-area.js +62 -0
  80. package/dist/components/scroll-area.js.map +1 -0
  81. package/dist/components/select.js +173 -0
  82. package/dist/components/select.js.map +1 -0
  83. package/dist/components/separator.js +28 -0
  84. package/dist/components/separator.js.map +1 -0
  85. package/dist/components/sheet.js +129 -0
  86. package/dist/components/sheet.js.map +1 -0
  87. package/dist/components/sidebar.js +759 -0
  88. package/dist/components/sidebar.js.map +1 -0
  89. package/dist/components/skeleton.js +16 -0
  90. package/dist/components/skeleton.js.map +1 -0
  91. package/dist/components/slider.js +65 -0
  92. package/dist/components/slider.js.map +1 -0
  93. package/dist/components/sonner.js +40 -0
  94. package/dist/components/sonner.js.map +1 -0
  95. package/dist/components/spinner.js +18 -0
  96. package/dist/components/spinner.js.map +1 -0
  97. package/dist/components/stepper.js +220 -0
  98. package/dist/components/stepper.js.map +1 -0
  99. package/dist/components/switch.js +33 -0
  100. package/dist/components/switch.js.map +1 -0
  101. package/dist/components/table.js +131 -0
  102. package/dist/components/table.js.map +1 -0
  103. package/dist/components/tabs.js +69 -0
  104. package/dist/components/tabs.js.map +1 -0
  105. package/dist/components/textarea.js +19 -0
  106. package/dist/components/textarea.js.map +1 -0
  107. package/dist/components/toggle-group.js +70 -0
  108. package/dist/components/toggle-group.js.map +1 -0
  109. package/dist/components/toggle.js +45 -0
  110. package/dist/components/toggle.js.map +1 -0
  111. package/dist/components/tooltip.js +65 -0
  112. package/dist/components/tooltip.js.map +1 -0
  113. package/dist/custom/action-button.js +38 -0
  114. package/dist/custom/action-button.js.map +1 -0
  115. package/dist/custom/async-select.js +249 -0
  116. package/dist/custom/async-select.js.map +1 -0
  117. package/dist/custom/awesome-not-found.js +113 -0
  118. package/dist/custom/awesome-not-found.js.map +1 -0
  119. package/dist/custom/charts/area-chart.js +125 -0
  120. package/dist/custom/charts/area-chart.js.map +1 -0
  121. package/dist/custom/charts/bar-chart.js +232 -0
  122. package/dist/custom/charts/bar-chart.js.map +1 -0
  123. package/dist/custom/charts/chart-card.js +71 -0
  124. package/dist/custom/charts/chart-card.js.map +1 -0
  125. package/dist/custom/charts/index.js +5 -0
  126. package/dist/custom/charts/index.js.map +1 -0
  127. package/dist/custom/charts/pie-chart.js +153 -0
  128. package/dist/custom/charts/pie-chart.js.map +1 -0
  129. package/dist/custom/charts/radar-chart.js +112 -0
  130. package/dist/custom/charts/radar-chart.js.map +1 -0
  131. package/dist/custom/checkbox-tree.js +70 -0
  132. package/dist/custom/checkbox-tree.js.map +1 -0
  133. package/dist/custom/combobox.js +233 -0
  134. package/dist/custom/combobox.js.map +1 -0
  135. package/dist/custom/confirm-dialog.js +90 -0
  136. package/dist/custom/confirm-dialog.js.map +1 -0
  137. package/dist/custom/country-selector.js +151 -0
  138. package/dist/custom/country-selector.js.map +1 -0
  139. package/dist/custom/date-picker/calendar-rac.js +91 -0
  140. package/dist/custom/date-picker/calendar-rac.js.map +1 -0
  141. package/dist/custom/date-picker/datefield-rac.js +77 -0
  142. package/dist/custom/date-picker/datefield-rac.js.map +1 -0
  143. package/dist/custom/date-picker/index.js +251 -0
  144. package/dist/custom/date-picker/index.js.map +1 -0
  145. package/dist/custom/date-picker/types/index.js +1 -0
  146. package/dist/custom/date-picker/types/index.js.map +1 -0
  147. package/dist/custom/date-picker/utils/index.js +30 -0
  148. package/dist/custom/date-picker/utils/index.js.map +1 -0
  149. package/dist/custom/date-picker-old.js +46 -0
  150. package/dist/custom/date-picker-old.js.map +1 -0
  151. package/dist/custom/date-tooltip.js +89 -0
  152. package/dist/custom/date-tooltip.js.map +1 -0
  153. package/dist/custom/document-scanner/consts.js +13 -0
  154. package/dist/custom/document-scanner/consts.js.map +1 -0
  155. package/dist/custom/document-scanner/corner-adjustment/action-buttons.js +24 -0
  156. package/dist/custom/document-scanner/corner-adjustment/action-buttons.js.map +1 -0
  157. package/dist/custom/document-scanner/corner-adjustment/corner-handle.js +44 -0
  158. package/dist/custom/document-scanner/corner-adjustment/corner-handle.js.map +1 -0
  159. package/dist/custom/document-scanner/corner-adjustment/hooks/use-corner-drag.js +60 -0
  160. package/dist/custom/document-scanner/corner-adjustment/hooks/use-corner-drag.js.map +1 -0
  161. package/dist/custom/document-scanner/corner-adjustment/index.js +124 -0
  162. package/dist/custom/document-scanner/corner-adjustment/index.js.map +1 -0
  163. package/dist/custom/document-scanner/corner-adjustment/types.js +1 -0
  164. package/dist/custom/document-scanner/corner-adjustment/types.js.map +1 -0
  165. package/dist/custom/document-scanner/corner-adjustment/utils/clip-path.js +16 -0
  166. package/dist/custom/document-scanner/corner-adjustment/utils/clip-path.js.map +1 -0
  167. package/dist/custom/document-scanner/corner-adjustment/zoom-magnifier.js +85 -0
  168. package/dist/custom/document-scanner/corner-adjustment/zoom-magnifier.js.map +1 -0
  169. package/dist/custom/document-scanner/hooks/use-document-capture.js +61 -0
  170. package/dist/custom/document-scanner/hooks/use-document-capture.js.map +1 -0
  171. package/dist/custom/document-scanner/hooks/use-document-scanner.js +59 -0
  172. package/dist/custom/document-scanner/hooks/use-document-scanner.js.map +1 -0
  173. package/dist/custom/document-scanner/hooks/use-perspective-crop.js +31 -0
  174. package/dist/custom/document-scanner/hooks/use-perspective-crop.js.map +1 -0
  175. package/dist/custom/document-scanner/index.js +229 -0
  176. package/dist/custom/document-scanner/index.js.map +1 -0
  177. package/dist/custom/document-scanner/lib.js +289 -0
  178. package/dist/custom/document-scanner/lib.js.map +1 -0
  179. package/dist/custom/document-scanner/types.js +1 -0
  180. package/dist/custom/document-scanner/types.js.map +1 -0
  181. package/dist/custom/document-scanner/utils/perspective-correction.js +100 -0
  182. package/dist/custom/document-scanner/utils/perspective-correction.js.map +1 -0
  183. package/dist/custom/document-viewer/controllers.js +76 -0
  184. package/dist/custom/document-viewer/controllers.js.map +1 -0
  185. package/dist/custom/document-viewer/index.js +36 -0
  186. package/dist/custom/document-viewer/index.js.map +1 -0
  187. package/dist/custom/document-viewer/renderers/image.js +40 -0
  188. package/dist/custom/document-viewer/renderers/image.js.map +1 -0
  189. package/dist/custom/document-viewer/renderers/index.js +3 -0
  190. package/dist/custom/document-viewer/renderers/index.js.map +1 -0
  191. package/dist/custom/document-viewer/renderers/pdf.js +95 -0
  192. package/dist/custom/document-viewer/renderers/pdf.js.map +1 -0
  193. package/dist/custom/email-input/email.js +184 -0
  194. package/dist/custom/email-input/email.js.map +1 -0
  195. package/dist/custom/email-input/index.js +8 -0
  196. package/dist/custom/email-input/index.js.map +1 -0
  197. package/dist/custom/email-input/types.js +13 -0
  198. package/dist/custom/email-input/types.js.map +1 -0
  199. package/dist/custom/file-uploader.js +389 -0
  200. package/dist/custom/file-uploader.js.map +1 -0
  201. package/dist/custom/filter-component/fields/async-select.js +31 -0
  202. package/dist/custom/filter-component/fields/async-select.js.map +1 -0
  203. package/dist/custom/filter-component/fields/date.js +56 -0
  204. package/dist/custom/filter-component/fields/date.js.map +1 -0
  205. package/dist/custom/filter-component/fields/multi-select.js +28 -0
  206. package/dist/custom/filter-component/fields/multi-select.js.map +1 -0
  207. package/dist/custom/filter-component/index.js +149 -0
  208. package/dist/custom/filter-component/index.js.map +1 -0
  209. package/dist/custom/image-canvas.js +193 -0
  210. package/dist/custom/image-canvas.js.map +1 -0
  211. package/dist/custom/json-editor.js +30 -0
  212. package/dist/custom/json-editor.js.map +1 -0
  213. package/dist/custom/master-data-grid/components/dialogs/column-settings-dialog.js +84 -0
  214. package/dist/custom/master-data-grid/components/dialogs/column-settings-dialog.js.map +1 -0
  215. package/dist/custom/master-data-grid/components/dialogs/index.js +5 -0
  216. package/dist/custom/master-data-grid/components/dialogs/index.js.map +1 -0
  217. package/dist/custom/master-data-grid/components/filters/client-filter.js +310 -0
  218. package/dist/custom/master-data-grid/components/filters/client-filter.js.map +1 -0
  219. package/dist/custom/master-data-grid/components/filters/filter-input.js +209 -0
  220. package/dist/custom/master-data-grid/components/filters/filter-input.js.map +1 -0
  221. package/dist/custom/master-data-grid/components/filters/index.js +9 -0
  222. package/dist/custom/master-data-grid/components/filters/index.js.map +1 -0
  223. package/dist/custom/master-data-grid/components/filters/inline-column-filter.js +188 -0
  224. package/dist/custom/master-data-grid/components/filters/inline-column-filter.js.map +1 -0
  225. package/dist/custom/master-data-grid/components/filters/multi-filter-dialog.js +65 -0
  226. package/dist/custom/master-data-grid/components/filters/multi-filter-dialog.js.map +1 -0
  227. package/dist/custom/master-data-grid/components/filters/server-filter.js +213 -0
  228. package/dist/custom/master-data-grid/components/filters/server-filter.js.map +1 -0
  229. package/dist/custom/master-data-grid/components/master-data-grid.js +421 -0
  230. package/dist/custom/master-data-grid/components/master-data-grid.js.map +1 -0
  231. package/dist/custom/master-data-grid/components/pagination/index.js +5 -0
  232. package/dist/custom/master-data-grid/components/pagination/index.js.map +1 -0
  233. package/dist/custom/master-data-grid/components/pagination/pagination.js +159 -0
  234. package/dist/custom/master-data-grid/components/pagination/pagination.js.map +1 -0
  235. package/dist/custom/master-data-grid/components/table/cell-renderer.js +442 -0
  236. package/dist/custom/master-data-grid/components/table/cell-renderer.js.map +1 -0
  237. package/dist/custom/master-data-grid/components/table/header-cell.js +116 -0
  238. package/dist/custom/master-data-grid/components/table/header-cell.js.map +1 -0
  239. package/dist/custom/master-data-grid/components/table/index.js +5 -0
  240. package/dist/custom/master-data-grid/components/table/index.js.map +1 -0
  241. package/dist/custom/master-data-grid/components/table/table-body-renderer.js +79 -0
  242. package/dist/custom/master-data-grid/components/table/table-body-renderer.js.map +1 -0
  243. package/dist/custom/master-data-grid/components/table/virtual-body.js +86 -0
  244. package/dist/custom/master-data-grid/components/table/virtual-body.js.map +1 -0
  245. package/dist/custom/master-data-grid/components/toolbar/index.js +5 -0
  246. package/dist/custom/master-data-grid/components/toolbar/index.js.map +1 -0
  247. package/dist/custom/master-data-grid/components/toolbar/toolbar.js +238 -0
  248. package/dist/custom/master-data-grid/components/toolbar/toolbar.js.map +1 -0
  249. package/dist/custom/master-data-grid/hooks/index.js +7 -0
  250. package/dist/custom/master-data-grid/hooks/index.js.map +1 -0
  251. package/dist/custom/master-data-grid/hooks/use-columns.js +278 -0
  252. package/dist/custom/master-data-grid/hooks/use-columns.js.map +1 -0
  253. package/dist/custom/master-data-grid/hooks/use-editing.js +75 -0
  254. package/dist/custom/master-data-grid/hooks/use-editing.js.map +1 -0
  255. package/dist/custom/master-data-grid/hooks/use-table-state-reducer.js +96 -0
  256. package/dist/custom/master-data-grid/hooks/use-table-state-reducer.js.map +1 -0
  257. package/dist/custom/master-data-grid/hooks/use-table-state.js +25 -0
  258. package/dist/custom/master-data-grid/hooks/use-table-state.js.map +1 -0
  259. package/dist/custom/master-data-grid/index.js +5 -0
  260. package/dist/custom/master-data-grid/index.js.map +1 -0
  261. package/dist/custom/master-data-grid/types.js +1 -0
  262. package/dist/custom/master-data-grid/types.js.map +1 -0
  263. package/dist/custom/master-data-grid/utils/column-generator.js +203 -0
  264. package/dist/custom/master-data-grid/utils/column-generator.js.map +1 -0
  265. package/dist/custom/master-data-grid/utils/export-utils.js +46 -0
  266. package/dist/custom/master-data-grid/utils/export-utils.js.map +1 -0
  267. package/dist/custom/master-data-grid/utils/filter-fns.js +218 -0
  268. package/dist/custom/master-data-grid/utils/filter-fns.js.map +1 -0
  269. package/dist/custom/master-data-grid/utils/index.js +16 -0
  270. package/dist/custom/master-data-grid/utils/index.js.map +1 -0
  271. package/dist/custom/master-data-grid/utils/pinning-utils.js +70 -0
  272. package/dist/custom/master-data-grid/utils/pinning-utils.js.map +1 -0
  273. package/dist/custom/master-data-grid/utils/translation-utils.js +33 -0
  274. package/dist/custom/master-data-grid/utils/translation-utils.js.map +1 -0
  275. package/dist/custom/multi-select.js +339 -0
  276. package/dist/custom/multi-select.js.map +1 -0
  277. package/dist/custom/password-input.js +158 -0
  278. package/dist/custom/password-input.js.map +1 -0
  279. package/dist/custom/phone-input.js +127 -0
  280. package/dist/custom/phone-input.js.map +1 -0
  281. package/dist/custom/schema-form/custom/index.js +2 -0
  282. package/dist/custom/schema-form/custom/index.js.map +1 -0
  283. package/dist/custom/schema-form/custom/label.js +39 -0
  284. package/dist/custom/schema-form/custom/label.js.map +1 -0
  285. package/dist/custom/schema-form/fields/base-input-field.js +73 -0
  286. package/dist/custom/schema-form/fields/base-input-field.js.map +1 -0
  287. package/dist/custom/schema-form/fields/field.js +72 -0
  288. package/dist/custom/schema-form/fields/field.js.map +1 -0
  289. package/dist/custom/schema-form/fields/index.js +6 -0
  290. package/dist/custom/schema-form/fields/index.js.map +1 -0
  291. package/dist/custom/schema-form/fields/object.js +9 -0
  292. package/dist/custom/schema-form/fields/object.js.map +1 -0
  293. package/dist/custom/schema-form/fields/table-array/array-field-item.js +58 -0
  294. package/dist/custom/schema-form/fields/table-array/array-field-item.js.map +1 -0
  295. package/dist/custom/schema-form/fields/table-array/array-field-template.js +104 -0
  296. package/dist/custom/schema-form/fields/table-array/array-field-template.js.map +1 -0
  297. package/dist/custom/schema-form/index.js +219 -0
  298. package/dist/custom/schema-form/index.js.map +1 -0
  299. package/dist/custom/schema-form/templates/description.js +19 -0
  300. package/dist/custom/schema-form/templates/description.js.map +1 -0
  301. package/dist/custom/schema-form/templates/index.js +3 -0
  302. package/dist/custom/schema-form/templates/index.js.map +1 -0
  303. package/dist/custom/schema-form/templates/submit.js +31 -0
  304. package/dist/custom/schema-form/templates/submit.js.map +1 -0
  305. package/dist/custom/schema-form/types.js +1 -0
  306. package/dist/custom/schema-form/types.js.map +1 -0
  307. package/dist/custom/schema-form/utils/index.js +10 -0
  308. package/dist/custom/schema-form/utils/index.js.map +1 -0
  309. package/dist/custom/schema-form/utils/schema-dependency.js +349 -0
  310. package/dist/custom/schema-form/utils/schema-dependency.js.map +1 -0
  311. package/dist/custom/schema-form/utils/schemas.js +190 -0
  312. package/dist/custom/schema-form/utils/schemas.js.map +1 -0
  313. package/dist/custom/schema-form/utils/validation.js +19 -0
  314. package/dist/custom/schema-form/utils/validation.js.map +1 -0
  315. package/dist/custom/schema-form/widgets/boolean.js +73 -0
  316. package/dist/custom/schema-form/widgets/boolean.js.map +1 -0
  317. package/dist/custom/schema-form/widgets/combobox.js +222 -0
  318. package/dist/custom/schema-form/widgets/combobox.js.map +1 -0
  319. package/dist/custom/schema-form/widgets/date.js +56 -0
  320. package/dist/custom/schema-form/widgets/date.js.map +1 -0
  321. package/dist/custom/schema-form/widgets/email.js +37 -0
  322. package/dist/custom/schema-form/widgets/email.js.map +1 -0
  323. package/dist/custom/schema-form/widgets/index.js +11 -0
  324. package/dist/custom/schema-form/widgets/index.js.map +1 -0
  325. package/dist/custom/schema-form/widgets/password.js +42 -0
  326. package/dist/custom/schema-form/widgets/password.js.map +1 -0
  327. package/dist/custom/schema-form/widgets/phone.js +39 -0
  328. package/dist/custom/schema-form/widgets/phone.js.map +1 -0
  329. package/dist/custom/schema-form/widgets/select.js +78 -0
  330. package/dist/custom/schema-form/widgets/select.js.map +1 -0
  331. package/dist/custom/schema-form/widgets/selectable.js +25 -0
  332. package/dist/custom/schema-form/widgets/selectable.js.map +1 -0
  333. package/dist/custom/schema-form/widgets/string-array.js +237 -0
  334. package/dist/custom/schema-form/widgets/string-array.js.map +1 -0
  335. package/dist/custom/schema-form/widgets/url.js +53 -0
  336. package/dist/custom/schema-form/widgets/url.js.map +1 -0
  337. package/dist/custom/section-layout-v2.js +150 -0
  338. package/dist/custom/section-layout-v2.js.map +1 -0
  339. package/dist/custom/select-tabs.js +66 -0
  340. package/dist/custom/select-tabs.js.map +1 -0
  341. package/dist/custom/selectable.js +231 -0
  342. package/dist/custom/selectable.js.map +1 -0
  343. package/dist/custom/stepper.js +166 -0
  344. package/dist/custom/stepper.js.map +1 -0
  345. package/dist/custom/tab-layout.js +182 -0
  346. package/dist/custom/tab-layout.js.map +1 -0
  347. package/dist/custom/tanstack-table/fields/index.js +13 -0
  348. package/dist/custom/tanstack-table/fields/index.js.map +1 -0
  349. package/dist/custom/tanstack-table/fields/tanstack-table-action-dialogs.js +76 -0
  350. package/dist/custom/tanstack-table/fields/tanstack-table-action-dialogs.js.map +1 -0
  351. package/dist/custom/tanstack-table/fields/tanstack-table-column-header.js +47 -0
  352. package/dist/custom/tanstack-table/fields/tanstack-table-column-header.js.map +1 -0
  353. package/dist/custom/tanstack-table/fields/tanstack-table-filter-date.js +132 -0
  354. package/dist/custom/tanstack-table/fields/tanstack-table-filter-date.js.map +1 -0
  355. package/dist/custom/tanstack-table/fields/tanstack-table-filter-faceted.js +131 -0
  356. package/dist/custom/tanstack-table/fields/tanstack-table-filter-faceted.js.map +1 -0
  357. package/dist/custom/tanstack-table/fields/tanstack-table-filter-text.js +64 -0
  358. package/dist/custom/tanstack-table/fields/tanstack-table-filter-text.js.map +1 -0
  359. package/dist/custom/tanstack-table/fields/tanstack-table-pagination.js +135 -0
  360. package/dist/custom/tanstack-table/fields/tanstack-table-pagination.js.map +1 -0
  361. package/dist/custom/tanstack-table/fields/tanstack-table-plain-table.js +111 -0
  362. package/dist/custom/tanstack-table/fields/tanstack-table-plain-table.js.map +1 -0
  363. package/dist/custom/tanstack-table/fields/tanstack-table-row-actions-confirmation.js +65 -0
  364. package/dist/custom/tanstack-table/fields/tanstack-table-row-actions-confirmation.js.map +1 -0
  365. package/dist/custom/tanstack-table/fields/tanstack-table-row-actions-custom-dialog.js +69 -0
  366. package/dist/custom/tanstack-table/fields/tanstack-table-row-actions-custom-dialog.js.map +1 -0
  367. package/dist/custom/tanstack-table/fields/tanstack-table-row-actions.js +119 -0
  368. package/dist/custom/tanstack-table/fields/tanstack-table-row-actions.js.map +1 -0
  369. package/dist/custom/tanstack-table/fields/tanstack-table-table-actions-custom-dialog.js +75 -0
  370. package/dist/custom/tanstack-table/fields/tanstack-table-table-actions-custom-dialog.js.map +1 -0
  371. package/dist/custom/tanstack-table/fields/tanstack-table-table-actions-schemaform-dialog.js +41 -0
  372. package/dist/custom/tanstack-table/fields/tanstack-table-table-actions-schemaform-dialog.js.map +1 -0
  373. package/dist/custom/tanstack-table/fields/tanstack-table-toolbar.js +106 -0
  374. package/dist/custom/tanstack-table/fields/tanstack-table-toolbar.js.map +1 -0
  375. package/dist/custom/tanstack-table/fields/tanstack-table-view-options.js +132 -0
  376. package/dist/custom/tanstack-table/fields/tanstack-table-view-options.js.map +1 -0
  377. package/dist/custom/tanstack-table/index.js +217 -0
  378. package/dist/custom/tanstack-table/index.js.map +1 -0
  379. package/dist/custom/tanstack-table/types/index.js +1 -0
  380. package/dist/custom/tanstack-table/types/index.js.map +1 -0
  381. package/dist/custom/tanstack-table/utils/cell-with-actions.js +16 -0
  382. package/dist/custom/tanstack-table/utils/cell-with-actions.js.map +1 -0
  383. package/dist/custom/tanstack-table/utils/column-names.js +15 -0
  384. package/dist/custom/tanstack-table/utils/column-names.js.map +1 -0
  385. package/dist/custom/tanstack-table/utils/columns-by-row-data.js +246 -0
  386. package/dist/custom/tanstack-table/utils/columns-by-row-data.js.map +1 -0
  387. package/dist/custom/tanstack-table/utils/editable-columns-by-row-data.js +187 -0
  388. package/dist/custom/tanstack-table/utils/editable-columns-by-row-data.js.map +1 -0
  389. package/dist/custom/tanstack-table/utils/faceted-boolean-options.js +25 -0
  390. package/dist/custom/tanstack-table/utils/faceted-boolean-options.js.map +1 -0
  391. package/dist/custom/tanstack-table/utils/index.js +10 -0
  392. package/dist/custom/tanstack-table/utils/index.js.map +1 -0
  393. package/dist/custom/tanstack-table/utils/pinning-styles.js +38 -0
  394. package/dist/custom/tanstack-table/utils/pinning-styles.js.map +1 -0
  395. package/dist/custom/tanstack-table/utils/table.js +66 -0
  396. package/dist/custom/tanstack-table/utils/table.js.map +1 -0
  397. package/dist/custom/tanstack-table/utils/test-conditions.js +10 -0
  398. package/dist/custom/tanstack-table/utils/test-conditions.js.map +1 -0
  399. package/dist/custom/timeline.js +165 -0
  400. package/dist/custom/timeline.js.map +1 -0
  401. package/dist/custom/tree.js +130 -0
  402. package/dist/custom/tree.js.map +1 -0
  403. package/dist/custom/tscanify/browser.js +36 -0
  404. package/dist/custom/tscanify/browser.js.map +1 -0
  405. package/dist/custom/tscanify/index.js +34 -0
  406. package/dist/custom/tscanify/index.js.map +1 -0
  407. package/dist/custom/tscanify/tscanify-browser.js +363 -0
  408. package/dist/custom/tscanify/tscanify-browser.js.map +1 -0
  409. package/dist/custom/tscanify/tscanify.js +197 -0
  410. package/dist/custom/tscanify/tscanify.js.map +1 -0
  411. package/dist/custom/tscanify/types.js +1 -0
  412. package/dist/custom/tscanify/types.js.map +1 -0
  413. package/dist/custom/webcam.js +519 -0
  414. package/dist/custom/webcam.js.map +1 -0
  415. package/dist/hooks/use-callback-ref.js +15 -0
  416. package/dist/hooks/use-callback-ref.js.map +1 -0
  417. package/dist/hooks/use-controllable-state.js +49 -0
  418. package/dist/hooks/use-controllable-state.js.map +1 -0
  419. package/dist/hooks/use-debounce.js +18 -0
  420. package/dist/hooks/use-debounce.js.map +1 -0
  421. package/dist/hooks/use-is-visible.js +22 -0
  422. package/dist/hooks/use-is-visible.js.map +1 -0
  423. package/dist/hooks/use-media-query.js +19 -0
  424. package/dist/hooks/use-media-query.js.map +1 -0
  425. package/dist/hooks/use-mobile.js +21 -0
  426. package/dist/hooks/use-mobile.js.map +1 -0
  427. package/dist/hooks/use-on-window-resize.js +15 -0
  428. package/dist/hooks/use-on-window-resize.js.map +1 -0
  429. package/dist/hooks/use-scroll.js +20 -0
  430. package/dist/hooks/use-scroll.js.map +1 -0
  431. package/dist/lib/utils.js +48 -0
  432. package/dist/lib/utils.js.map +1 -0
  433. package/dist/lib/zod.js +7 -0
  434. package/dist/lib/zod.js.map +1 -0
  435. package/package.json +34 -8
  436. package/src/aria/index.tsx +1 -1
  437. package/src/aria/number-field.tsx +41 -41
  438. package/src/components/accordion.tsx +66 -66
  439. package/src/components/alert-dialog.tsx +157 -157
  440. package/src/components/alert.tsx +70 -70
  441. package/src/components/aspect-ratio.tsx +11 -11
  442. package/src/components/avatar.tsx +53 -53
  443. package/src/components/badge.tsx +74 -67
  444. package/src/components/breadcrumb.tsx +109 -109
  445. package/src/components/button-group.tsx +83 -83
  446. package/src/components/button.tsx +69 -68
  447. package/src/components/calendar.tsx +216 -219
  448. package/src/components/card.tsx +92 -92
  449. package/src/components/carousel.tsx +241 -241
  450. package/src/components/chart.tsx +363 -363
  451. package/src/components/checkbox.tsx +32 -32
  452. package/src/components/collapsible.tsx +33 -33
  453. package/src/components/command.tsx +184 -184
  454. package/src/components/context-menu.tsx +252 -252
  455. package/src/components/dialog.tsx +144 -144
  456. package/src/components/drawer.tsx +135 -135
  457. package/src/components/dropdown-menu.tsx +258 -258
  458. package/src/components/empty.tsx +100 -100
  459. package/src/components/field.tsx +248 -248
  460. package/src/components/form.tsx +169 -169
  461. package/src/components/hover-card.tsx +44 -44
  462. package/src/components/input-group.tsx +170 -170
  463. package/src/components/input-otp.tsx +77 -77
  464. package/src/components/input.tsx +21 -21
  465. package/src/components/item.tsx +193 -193
  466. package/src/components/kbd.tsx +28 -28
  467. package/src/components/label.tsx +24 -24
  468. package/src/components/menubar.tsx +276 -276
  469. package/src/components/navigation-menu.tsx +168 -168
  470. package/src/components/pagination.tsx +127 -130
  471. package/src/components/popover.tsx +88 -88
  472. package/src/components/progress.tsx +31 -31
  473. package/src/components/radio-group.tsx +45 -45
  474. package/src/components/resizable.tsx +56 -56
  475. package/src/components/scroll-area.tsx +58 -58
  476. package/src/components/select.tsx +189 -189
  477. package/src/components/separator.tsx +28 -28
  478. package/src/components/sheet.tsx +140 -140
  479. package/src/components/sidebar.tsx +862 -862
  480. package/src/components/skeleton.tsx +13 -13
  481. package/src/components/slider.tsx +63 -63
  482. package/src/components/sonner.tsx +40 -40
  483. package/src/components/spinner.tsx +16 -16
  484. package/src/components/stepper.tsx +290 -291
  485. package/src/components/switch.tsx +31 -31
  486. package/src/components/table.tsx +133 -133
  487. package/src/components/tabs.tsx +66 -66
  488. package/src/components/textarea.tsx +18 -18
  489. package/src/components/toggle-group.tsx +83 -83
  490. package/src/components/toggle.tsx +47 -47
  491. package/src/components/tooltip.tsx +66 -66
  492. package/src/custom/action-button.tsx +45 -48
  493. package/src/custom/async-select.tsx +287 -287
  494. package/src/custom/awesome-not-found.tsx +116 -116
  495. package/src/custom/charts/area-chart.tsx +147 -147
  496. package/src/custom/charts/bar-chart.tsx +233 -233
  497. package/src/custom/charts/chart-card.tsx +103 -103
  498. package/src/custom/charts/index.tsx +16 -16
  499. package/src/custom/charts/pie-chart.tsx +168 -168
  500. package/src/custom/charts/radar-chart.tsx +126 -126
  501. package/src/custom/checkbox-tree.tsx +100 -100
  502. package/src/custom/combobox.tsx +296 -296
  503. package/src/custom/confirm-dialog.tsx +114 -102
  504. package/src/custom/country-selector.tsx +204 -204
  505. package/src/custom/date-picker/calendar-rac.tsx +109 -109
  506. package/src/custom/date-picker/datefield-rac.tsx +84 -84
  507. package/src/custom/date-picker/index.tsx +273 -273
  508. package/src/custom/date-picker/types/index.ts +4 -4
  509. package/src/custom/date-picker/utils/index.ts +42 -42
  510. package/src/custom/date-picker-old.tsx +50 -50
  511. package/src/custom/date-tooltip.tsx +98 -98
  512. package/src/custom/document-scanner/consts.ts +5 -5
  513. package/src/custom/document-scanner/corner-adjustment/action-buttons.tsx +33 -33
  514. package/src/custom/document-scanner/corner-adjustment/corner-handle.tsx +43 -43
  515. package/src/custom/document-scanner/corner-adjustment/hooks/use-corner-drag.ts +85 -85
  516. package/src/custom/document-scanner/corner-adjustment/index.tsx +125 -125
  517. package/src/custom/document-scanner/corner-adjustment/types.ts +53 -53
  518. package/src/custom/document-scanner/corner-adjustment/utils/clip-path.ts +22 -22
  519. package/src/custom/document-scanner/corner-adjustment/zoom-magnifier.tsx +115 -115
  520. package/src/custom/document-scanner/hooks/use-document-capture.ts +81 -81
  521. package/src/custom/document-scanner/hooks/use-document-scanner.ts +80 -80
  522. package/src/custom/document-scanner/hooks/use-perspective-crop.ts +38 -38
  523. package/src/custom/document-scanner/index.tsx +255 -255
  524. package/src/custom/document-scanner/lib.ts +407 -407
  525. package/src/custom/document-scanner/types.ts +205 -205
  526. package/src/custom/document-scanner/utils/perspective-correction.ts +139 -139
  527. package/src/custom/document-viewer/controllers.tsx +98 -98
  528. package/src/custom/document-viewer/index.tsx +43 -43
  529. package/src/custom/document-viewer/renderers/image.tsx +37 -37
  530. package/src/custom/document-viewer/renderers/index.tsx +2 -2
  531. package/src/custom/document-viewer/renderers/pdf.tsx +105 -105
  532. package/src/custom/email-input/domains.json +159 -159
  533. package/src/custom/email-input/email.tsx +231 -229
  534. package/src/custom/email-input/index.tsx +4 -4
  535. package/src/custom/email-input/types.ts +104 -104
  536. package/src/custom/file-uploader.tsx +541 -541
  537. package/src/custom/filter-component/fields/async-select.tsx +33 -33
  538. package/src/custom/filter-component/fields/date.tsx +60 -60
  539. package/src/custom/filter-component/fields/multi-select.tsx +30 -30
  540. package/src/custom/filter-component/index.tsx +217 -217
  541. package/src/custom/image-canvas.tsx +260 -260
  542. package/src/custom/json-editor.tsx +22 -22
  543. package/src/custom/master-data-grid/components/dialogs/column-settings-dialog.tsx +100 -100
  544. package/src/custom/master-data-grid/components/dialogs/index.ts +1 -1
  545. package/src/custom/master-data-grid/components/filters/client-filter.tsx +369 -368
  546. package/src/custom/master-data-grid/components/filters/filter-input.tsx +256 -256
  547. package/src/custom/master-data-grid/components/filters/index.ts +3 -3
  548. package/src/custom/master-data-grid/components/filters/inline-column-filter.tsx +233 -233
  549. package/src/custom/master-data-grid/components/filters/multi-filter-dialog.tsx +91 -90
  550. package/src/custom/master-data-grid/components/filters/server-filter.tsx +265 -255
  551. package/src/custom/master-data-grid/components/master-data-grid.tsx +472 -472
  552. package/src/custom/master-data-grid/components/pagination/index.ts +1 -1
  553. package/src/custom/master-data-grid/components/pagination/pagination.tsx +178 -178
  554. package/src/custom/master-data-grid/components/table/cell-renderer.tsx +621 -634
  555. package/src/custom/master-data-grid/components/table/header-cell.tsx +162 -162
  556. package/src/custom/master-data-grid/components/table/index.ts +4 -4
  557. package/src/custom/master-data-grid/components/table/table-body-renderer.tsx +113 -113
  558. package/src/custom/master-data-grid/components/table/virtual-body.tsx +138 -138
  559. package/src/custom/master-data-grid/components/toolbar/index.ts +1 -1
  560. package/src/custom/master-data-grid/components/toolbar/toolbar.tsx +314 -314
  561. package/src/custom/master-data-grid/hooks/index.ts +3 -3
  562. package/src/custom/master-data-grid/hooks/use-columns.tsx +353 -332
  563. package/src/custom/master-data-grid/hooks/use-editing.ts +106 -106
  564. package/src/custom/master-data-grid/hooks/use-table-state-reducer.ts +157 -157
  565. package/src/custom/master-data-grid/hooks/use-table-state.ts +31 -31
  566. package/src/custom/master-data-grid/index.ts +16 -16
  567. package/src/custom/master-data-grid/types.ts +487 -466
  568. package/src/custom/master-data-grid/utils/column-generator.tsx +324 -306
  569. package/src/custom/master-data-grid/utils/export-utils.ts +67 -67
  570. package/src/custom/master-data-grid/utils/filter-fns.ts +310 -290
  571. package/src/custom/master-data-grid/utils/index.ts +8 -8
  572. package/src/custom/master-data-grid/utils/pinning-utils.ts +88 -88
  573. package/src/custom/master-data-grid/utils/translation-utils.ts +42 -42
  574. package/src/custom/multi-select.tsx +434 -432
  575. package/src/custom/password-input.tsx +194 -194
  576. package/src/custom/phone-input.tsx +172 -172
  577. package/src/custom/schema-form/custom/index.tsx +1 -1
  578. package/src/custom/schema-form/custom/label.tsx +53 -53
  579. package/src/custom/schema-form/fields/base-input-field.tsx +82 -82
  580. package/src/custom/schema-form/fields/field.tsx +67 -67
  581. package/src/custom/schema-form/fields/index.tsx +5 -5
  582. package/src/custom/schema-form/fields/object.tsx +12 -12
  583. package/src/custom/schema-form/fields/table-array/array-field-item.tsx +90 -90
  584. package/src/custom/schema-form/fields/table-array/array-field-template.tsx +115 -115
  585. package/src/custom/schema-form/index.tsx +259 -259
  586. package/src/custom/schema-form/templates/description.tsx +20 -20
  587. package/src/custom/schema-form/templates/index.tsx +2 -2
  588. package/src/custom/schema-form/templates/submit.tsx +32 -32
  589. package/src/custom/schema-form/types.ts +64 -64
  590. package/src/custom/schema-form/utils/index.ts +4 -4
  591. package/src/custom/schema-form/utils/schema-dependency.ts +655 -655
  592. package/src/custom/schema-form/utils/schemas.ts +289 -289
  593. package/src/custom/schema-form/utils/validation.ts +23 -23
  594. package/src/custom/schema-form/widgets/boolean.tsx +77 -77
  595. package/src/custom/schema-form/widgets/combobox.tsx +274 -274
  596. package/src/custom/schema-form/widgets/date.tsx +59 -59
  597. package/src/custom/schema-form/widgets/email.tsx +34 -34
  598. package/src/custom/schema-form/widgets/index.tsx +10 -10
  599. package/src/custom/schema-form/widgets/password.tsx +40 -40
  600. package/src/custom/schema-form/widgets/phone.tsx +40 -40
  601. package/src/custom/schema-form/widgets/select.tsx +105 -105
  602. package/src/custom/schema-form/widgets/selectable.tsx +25 -25
  603. package/src/custom/schema-form/widgets/string-array.tsx +296 -296
  604. package/src/custom/schema-form/widgets/url.tsx +56 -56
  605. package/src/custom/section-layout-v2.tsx +212 -212
  606. package/src/custom/select-tabs.tsx +109 -109
  607. package/src/custom/selectable.tsx +316 -316
  608. package/src/custom/stepper.tsx +236 -236
  609. package/src/custom/tab-layout.tsx +213 -213
  610. package/src/custom/tanstack-table/fields/index.tsx +12 -12
  611. package/src/custom/tanstack-table/fields/tanstack-table-action-dialogs.tsx +89 -89
  612. package/src/custom/tanstack-table/fields/tanstack-table-column-header.tsx +68 -66
  613. package/src/custom/tanstack-table/fields/tanstack-table-filter-date.tsx +180 -180
  614. package/src/custom/tanstack-table/fields/tanstack-table-filter-faceted.tsx +158 -158
  615. package/src/custom/tanstack-table/fields/tanstack-table-filter-text.tsx +73 -76
  616. package/src/custom/tanstack-table/fields/tanstack-table-pagination.tsx +136 -136
  617. package/src/custom/tanstack-table/fields/tanstack-table-plain-table.tsx +142 -142
  618. package/src/custom/tanstack-table/fields/tanstack-table-row-actions-confirmation.tsx +77 -77
  619. package/src/custom/tanstack-table/fields/tanstack-table-row-actions-custom-dialog.tsx +87 -87
  620. package/src/custom/tanstack-table/fields/tanstack-table-row-actions.tsx +151 -151
  621. package/src/custom/tanstack-table/fields/tanstack-table-table-actions-custom-dialog.tsx +88 -88
  622. package/src/custom/tanstack-table/fields/tanstack-table-table-actions-schemaform-dialog.tsx +47 -47
  623. package/src/custom/tanstack-table/fields/tanstack-table-toolbar.tsx +143 -143
  624. package/src/custom/tanstack-table/fields/tanstack-table-view-options.tsx +171 -171
  625. package/src/custom/tanstack-table/index.tsx +244 -244
  626. package/src/custom/tanstack-table/types/index.ts +328 -328
  627. package/src/custom/tanstack-table/utils/cell-with-actions.tsx +21 -21
  628. package/src/custom/tanstack-table/utils/column-names.ts +26 -26
  629. package/src/custom/tanstack-table/utils/columns-by-row-data.tsx +312 -312
  630. package/src/custom/tanstack-table/utils/editable-columns-by-row-data.tsx +219 -219
  631. package/src/custom/tanstack-table/utils/faceted-boolean-options.tsx +22 -22
  632. package/src/custom/tanstack-table/utils/index.tsx +10 -10
  633. package/src/custom/tanstack-table/utils/pinning-styles.ts +57 -57
  634. package/src/custom/tanstack-table/utils/table.tsx +83 -83
  635. package/src/custom/tanstack-table/utils/test-conditions.ts +17 -17
  636. package/src/custom/timeline.tsx +208 -208
  637. package/src/custom/tree.tsx +202 -200
  638. package/src/custom/tscanify/browser.ts +66 -66
  639. package/src/custom/tscanify/index.ts +51 -51
  640. package/src/custom/tscanify/tscanify-browser.ts +522 -522
  641. package/src/custom/tscanify/tscanify.ts +262 -262
  642. package/src/custom/tscanify/types.ts +22 -22
  643. package/src/custom/webcam.tsx +737 -737
  644. package/src/hooks/use-callback-ref.ts +27 -27
  645. package/src/hooks/use-controllable-state.ts +67 -67
  646. package/src/hooks/use-debounce.ts +19 -19
  647. package/src/hooks/use-is-visible.ts +23 -23
  648. package/src/hooks/use-media-query.ts +21 -21
  649. package/src/hooks/use-mobile.ts +21 -21
  650. package/src/hooks/use-on-window-resize.ts +15 -15
  651. package/src/hooks/use-scroll.tsx +22 -22
  652. package/src/lib/utils.ts +61 -61
  653. package/src/lib/zod.ts +2 -2
  654. package/src/styles/core.css +57 -57
  655. package/src/test/email-input.test.tsx +217 -217
  656. package/src/test/password-input.test.tsx +92 -92
  657. package/src/test/select-tabs.test.tsx +302 -302
  658. package/src/test/selectable.test.tsx +1093 -1093
  659. package/__mocks__/canvas.ts +0 -8
  660. package/components.json +0 -21
  661. package/eslint.config.js +0 -4
  662. package/jest-environment.js +0 -37
  663. package/jest.config.ts +0 -47
  664. package/jest.setup.ts +0 -69
  665. package/postcss.config.mjs +0 -6
  666. package/tsconfig.json +0 -13
  667. package/tsconfig.lint.json +0 -8
@@ -1,541 +1,541 @@
1
- "use client";
2
-
3
- import { FileText, Folder, FolderOpen, Upload, X } from "lucide-react";
4
- import * as React from "react";
5
- import Dropzone, {
6
- FileWithPath as DefaultFileWithPath,
7
- DropzoneState,
8
- type DropzoneProps,
9
- type FileRejection,
10
- } from "react-dropzone";
11
- import {
12
- Avatar,
13
- AvatarFallback,
14
- AvatarImage,
15
- } from "@repo/ayasofyazilim-ui/components/avatar";
16
- import { Button } from "@repo/ayasofyazilim-ui/components/button";
17
- import {
18
- Collapsible,
19
- CollapsibleContent,
20
- CollapsibleTrigger,
21
- } from "@repo/ayasofyazilim-ui/components/collapsible";
22
- import { Progress } from "@repo/ayasofyazilim-ui/components/progress";
23
- import { ScrollArea } from "@repo/ayasofyazilim-ui/components/scroll-area";
24
- import { toast } from "@repo/ayasofyazilim-ui/components/sonner";
25
- import { cn, formatBytes } from "@repo/ayasofyazilim-ui/lib/utils";
26
- import { useControllableState } from "../hooks/use-controllable-state";
27
-
28
- export type FileWithPath = DefaultFileWithPath;
29
- export type BaseFileUploaderProps = React.HTMLAttributes<HTMLDivElement> & {
30
- /**
31
- * Value of the uploader.
32
- * @type File[]
33
- * @default undefined
34
- * @example value={files}
35
- */
36
- value?: DefaultFileWithPath[];
37
-
38
- /**
39
- * Function to be called when the value changes.
40
- * @type (files: File[]) => void
41
- * @default undefined
42
- * @example onValueChange={(files) => setFiles(files)}
43
- */
44
- onValueChange?: (files: DefaultFileWithPath[]) => void;
45
-
46
- /**
47
- * Function to be called when files are uploaded.
48
- * @type (files: File[]) => Promise<void>
49
- * @default undefined
50
- * @example onUpload={(files) => uploadFiles(files)}
51
- */
52
- onUpload?: (files: File[]) => Promise<void>;
53
-
54
- /**
55
- * Progress of the uploaded files.
56
- * @type Record<string, number> | undefined
57
- * @default undefined
58
- * @example progresses={{ "file1.png": 50 }}
59
- */
60
- progresses?: Record<string, number>;
61
-
62
- /**
63
- * Accepted file types for the uploader.
64
- * @type { [key: string]: string[]}
65
- * @default
66
- * ```ts
67
- * { "image/*": [] }
68
- * ```
69
- * @example accept={["image/png", "image/jpeg"]}
70
- */
71
- accept?: DropzoneProps["accept"];
72
-
73
- /**
74
- * Maximum file size for the uploader.
75
- * @type number | undefined
76
- * @default 1024 * 1024 * 2 // 2MB
77
- * @example maxSize={1024 * 1024 * 2} // 2MB
78
- */
79
- maxSize?: DropzoneProps["maxSize"];
80
-
81
- /**
82
- * Maximum number of files for the uploader.
83
- * @type number | undefined
84
- * @default 1
85
- * @example maxFileCount={4}
86
- */
87
- maxFileCount?: DropzoneProps["maxFiles"];
88
-
89
- /**
90
- * Whether the uploader should accept multiple files.
91
- * @type boolean
92
- * @default false
93
- * @example multiple
94
- */
95
- multiple?: boolean;
96
-
97
- /**
98
- * Whether the uploader is disabled.
99
- * @type boolean
100
- * @default false
101
- * @example disabled
102
- */
103
- disabled?: boolean;
104
-
105
- /**
106
- * Whether the uploader has drag and drop functionality.
107
- * @type boolean
108
- * @default false
109
- * @example noDrag
110
- */
111
- label?: string | React.ReactNode;
112
- description?: string | React.ReactNode;
113
- classNames?: {
114
- container?: string;
115
- collapsible?: string;
116
- dropzoneContainer?: string;
117
- dropzone?: string;
118
- fileList?: string;
119
- header?: string;
120
- collapsibleContent?: string;
121
- };
122
- showFileList?: boolean;
123
- fileCardRenderer?: (props: FileCardProps) => React.ReactNode;
124
- } & (ButtonFileUploaderProps | DropzoneFileUploaderProps);
125
-
126
- type ButtonFileUploaderProps = {
127
- variant: "button";
128
- children?: React.ReactNode;
129
- headerChildren?: React.ReactNode;
130
- };
131
- type DropzoneFileUploaderProps = {
132
- variant: "dropzone";
133
- };
134
- export function FileUploader(props: BaseFileUploaderProps) {
135
- const {
136
- value: valueProp,
137
- onValueChange,
138
- onUpload,
139
- progresses,
140
- accept = {
141
- "image/*": [],
142
- },
143
- maxSize = 1024 * 1024 * 2,
144
- maxFileCount = 1,
145
- multiple = false,
146
- disabled = false,
147
- classNames,
148
- showFileList = true,
149
- label,
150
- description,
151
- fileCardRenderer,
152
- } = props;
153
-
154
- const [files, setFiles] = useControllableState({
155
- prop: valueProp,
156
- onChange: onValueChange,
157
- });
158
-
159
- const onDrop = React.useCallback(
160
- (acceptedFiles: File[], rejectedFiles: FileRejection[]) => {
161
- if (!multiple && maxFileCount === 1 && acceptedFiles.length > 1) {
162
- toast.error("Cannot upload more than 1 file at a time");
163
- return;
164
- }
165
-
166
- if ((files?.length ?? 0) + acceptedFiles.length > maxFileCount) {
167
- toast.error(`Cannot upload more than ${maxFileCount} files`);
168
- return;
169
- }
170
-
171
- const newFiles = acceptedFiles.map((file) =>
172
- Object.assign(file, {
173
- preview: URL.createObjectURL(file),
174
- })
175
- );
176
- if (newFiles.length > 0 && !isOpen) setIsOpen(true);
177
- const updatedFiles = files ? [...files, ...newFiles] : newFiles;
178
-
179
- setFiles(updatedFiles);
180
-
181
- if (rejectedFiles.length > 0) {
182
- rejectedFiles.forEach(({ file, errors }) => {
183
- toast.error(
184
- `File ${file.name} was rejected because of ${errors.map((error) => error.message).join(", ")}`
185
- );
186
- });
187
- }
188
-
189
- if (
190
- onUpload &&
191
- updatedFiles.length > 0 &&
192
- updatedFiles.length <= maxFileCount
193
- ) {
194
- const target =
195
- updatedFiles.length > 0 ? `${updatedFiles.length} files` : `file`;
196
-
197
- toast.promise(onUpload(updatedFiles), {
198
- loading: `Uploading ${target}...`,
199
- success: () => {
200
- setFiles([]);
201
- return `${target} uploaded`;
202
- },
203
- error: `Failed to upload ${target}`,
204
- });
205
- }
206
- },
207
-
208
- [files, maxFileCount, multiple, onUpload, setFiles]
209
- );
210
-
211
- function onRemove(index: number) {
212
- if (!files) return;
213
- const newFiles = files.filter((_, i) => i !== index);
214
- setFiles(newFiles);
215
- if (newFiles.length === 0) setIsOpen(false);
216
- onValueChange?.(newFiles);
217
- }
218
-
219
- // Revoke preview url when component unmounts
220
- React.useEffect(
221
- () => () => {
222
- if (!files) return;
223
- files.forEach((file) => {
224
- if (isFileWithPreview(file)) {
225
- URL.revokeObjectURL(file.preview);
226
- }
227
- });
228
- },
229
- []
230
- );
231
-
232
- const isDisabled = disabled || (files?.length ?? 0) >= maxFileCount;
233
- const [isOpen, setIsOpen] = React.useState(false);
234
- return (
235
- <Collapsible
236
- onOpenChange={setIsOpen}
237
- open={isOpen}
238
- className={cn(
239
- "transition-all flex flex-col w-full border rounded-lg [&>h3]:w-full",
240
- classNames?.collapsible
241
- )}
242
- >
243
- <div
244
- className={cn(
245
- " gap-4 p-4",
246
- props.variant === "button"
247
- ? "flex flex-col sm:flex-row"
248
- : "grid grid-cols-12",
249
- classNames?.container
250
- )}
251
- >
252
- <CollapsibleTrigger
253
- className={cn(
254
- "gap-4 group/trigger hover:no-underline",
255
- !files?.length && "opacity-50"
256
- )}
257
- asChild
258
- >
259
- <Button
260
- variant="outline"
261
- className="gap-2"
262
- disabled={isDisabled || !files?.length}
263
- >
264
- <FolderOpen className="w-4 group-data-[state=open]/trigger:hidden" />
265
- <Folder className="w-4 group-data-[state=closed]/trigger:hidden" />
266
- Files
267
- </Button>
268
- </CollapsibleTrigger>
269
- <Dropzone
270
- onDrop={onDrop}
271
- accept={accept}
272
- maxSize={maxSize}
273
- maxFiles={maxFileCount}
274
- multiple={maxFileCount > 1 || multiple}
275
- disabled={isDisabled}
276
- noDrag={props.variant === "button"}
277
- >
278
- {(dropzone) => (
279
- <DropzoneTrigger {...dropzone} {...props} isDisabled={isDisabled} />
280
- )}
281
- </Dropzone>
282
- <div className={cn("flex w-full", classNames?.header)}>
283
- <div className="flex flex-col w-full text-nowrap justify-center">
284
- {label && (
285
- <span className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
286
- {label}
287
- </span>
288
- )}
289
- {description && (
290
- <span className="text-muted-foreground text-sm">
291
- {description}
292
- </span>
293
- )}
294
- </div>
295
- {props.variant === "button" &&
296
- props.headerChildren &&
297
- props.headerChildren}
298
- </div>
299
- </div>
300
- {props.children && props.children}
301
- <CollapsibleContent
302
- className={cn("w-full p-0 h-max", classNames?.collapsibleContent)}
303
- >
304
- <div
305
- className={cn(
306
- "group relative flex flex-col gap-4 overflow-hidden",
307
- files?.length && props.variant === "button" && "",
308
- files?.length && files?.length > 0 && "p-4 border-t",
309
- classNames?.container
310
- )}
311
- >
312
- {files?.length && showFileList !== false ? (
313
- <ScrollArea className="h-fit w-full">
314
- <div
315
- className={cn(
316
- "grid max-h-48 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 flex-col gap-4",
317
- files.length === 1 && "grid-cols-1!",
318
- files.length === 2 && "sm:grid-cols-2!",
319
- files.length === 3 && "lg:grid-cols-3!",
320
- files.length === 4 && "2xl:grid-cols-4!",
321
- classNames?.fileList
322
- )}
323
- >
324
- {files?.map((file, index) => (
325
- <React.Fragment
326
- key={file.name + file.lastModified + file.path}
327
- >
328
- {fileCardRenderer ? (
329
- fileCardRenderer({
330
- file,
331
- index,
332
- onRemove: () => onRemove(index),
333
- })
334
- ) : (
335
- <FileCard
336
- file={file}
337
- onRemove={() => onRemove(index)}
338
- progress={progresses?.[file.name]}
339
- />
340
- )}
341
- </React.Fragment>
342
- ))}
343
- </div>
344
- </ScrollArea>
345
- ) : null}
346
- </div>
347
- </CollapsibleContent>
348
- </Collapsible>
349
- );
350
- }
351
-
352
- export interface FileCardProps {
353
- index: number;
354
- file: DefaultFileWithPath;
355
- onRemove?: () => void;
356
- disabled?: boolean;
357
- progress?: number;
358
- classNames?: {
359
- container?: string;
360
- removeButton?: string;
361
- };
362
- }
363
-
364
- export function FileCard({
365
- file,
366
- progress,
367
- onRemove,
368
- disabled,
369
- classNames,
370
- }: Omit<FileCardProps, "index">) {
371
- return (
372
- <div
373
- className={cn(
374
- "bg-muted relative flex items-center gap-2.5 overflow-hidden rounded-md p-2",
375
- classNames?.container
376
- )}
377
- >
378
- <div className="flex flex-1 gap-2.5">
379
- {isFileWithPreview(file) ? <FilePreview file={file} /> : null}
380
- <div className="flex w-full flex-col gap-2">
381
- <div className="flex flex-col gap-px overflow-hidden">
382
- <p className="text-foreground/80 line-clamp-1 text-sm font-medium max-w-60 text-ellipsis">
383
- {file.name}
384
- </p>
385
- <p className="text-muted-foreground text-xs">
386
- {formatBytes(file.size)}
387
- </p>
388
- </div>
389
- {progress ? (
390
- <Progress value={progress} className="duration-1000" />
391
- ) : null}
392
- </div>
393
- </div>
394
- {onRemove && (
395
- <div className="flex items-center gap-2">
396
- <Button
397
- type="button"
398
- variant="outline"
399
- size="icon"
400
- className={cn("size-7", classNames?.removeButton)}
401
- disabled={!!progress || disabled}
402
- onClick={onRemove}
403
- >
404
- <X className="size-4" aria-hidden="true" />
405
- <span className="sr-only">Remove file</span>
406
- </Button>
407
- </div>
408
- )}
409
- </div>
410
- );
411
- }
412
-
413
- export function isFileWithPreview(
414
- file: FileWithPath
415
- ): file is FileWithPath & { preview: string } {
416
- return "preview" in file && typeof file.preview === "string";
417
- }
418
-
419
- export interface FilePreviewProps {
420
- file: FileWithPath & { preview: string };
421
- }
422
-
423
- export function FilePreview({ file }: FilePreviewProps) {
424
- if (file.type.startsWith("image/")) {
425
- return (
426
- <Avatar className="rounded-md border">
427
- <AvatarImage
428
- className="rounded-md"
429
- src={file.preview}
430
- alt={file.name}
431
- loading="lazy"
432
- />
433
- <AvatarFallback className="bg-white rounded-md text-xs">
434
- {`.${file.name.split(".")[1]}`}
435
- </AvatarFallback>
436
- </Avatar>
437
- );
438
- }
439
-
440
- return (
441
- <FileText className="text-muted-foreground size-10" aria-hidden="true" />
442
- );
443
- }
444
-
445
- type DropzoneTriggerProps = DropzoneState &
446
- BaseFileUploaderProps & {
447
- isDisabled?: boolean;
448
- };
449
- function DropzoneTrigger(props: DropzoneTriggerProps) {
450
- const {
451
- classNames,
452
- variant,
453
- getRootProps,
454
- getInputProps,
455
- isDragActive = true,
456
- maxFileCount = 1,
457
- maxSize = 1024 * 1024 * 2,
458
- isDisabled,
459
- // ...dropzoneProps
460
- } = props;
461
- if (variant === "button") {
462
- return (
463
- <div
464
- className={cn(
465
- "flex flex-col sm:flex-row gap-4",
466
- classNames?.dropzoneContainer
467
- )}
468
- >
469
- <div
470
- {...getRootProps()}
471
- // {...dropzoneProps}
472
- className={cn(
473
- "relative flex items-center gap-4 rounded-lg",
474
- classNames?.dropzone
475
- )}
476
- >
477
- <input {...getInputProps()} />
478
- <Button
479
- type="button"
480
- variant="outline"
481
- className="min-h-9 gap-2 w-full sm:max-w-max"
482
- disabled={isDisabled}
483
- >
484
- <Upload className="size-4" aria-hidden="true" />
485
- Select
486
- </Button>
487
- </div>
488
- </div>
489
- );
490
- }
491
- return (
492
- <div
493
- {...getRootProps()}
494
- // {...dropzoneProps}
495
- className={cn(
496
- "border-muted-foreground/25 hover:bg-muted/25 group relative grid h-52 w-full cursor-pointer place-items-center rounded-lg border-2 border-dashed px-5 py-2.5 text-center transition",
497
- "ring-offset-background focus-visible:ring-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
498
- isDragActive && "border-muted-foreground/50",
499
- isDisabled && "pointer-events-none opacity-60",
500
- variant === "dropzone" && "col-span-full row-start-2",
501
- classNames?.dropzone
502
- )}
503
- >
504
- <input {...getInputProps()} />
505
- {isDragActive ? (
506
- <div className="flex flex-col items-center justify-center gap-4 sm:px-5">
507
- <div className="rounded-full border border-dashed p-3">
508
- <Upload
509
- className="text-muted-foreground size-7"
510
- aria-hidden="true"
511
- />
512
- </div>
513
- <p className="text-muted-foreground font-medium">
514
- Drop the files here
515
- </p>
516
- </div>
517
- ) : (
518
- <div className="flex flex-col items-center justify-center gap-4 sm:px-5">
519
- <div className="rounded-full border border-dashed p-3">
520
- <Upload
521
- className="text-muted-foreground size-7"
522
- aria-hidden="true"
523
- />
524
- </div>
525
- <div className="flex flex-col gap-px">
526
- <p className="text-muted-foreground font-medium">
527
- Drag{`'n'`} drop files here, or click to select files
528
- </p>
529
- <p className="text-muted-foreground/70 text-sm">
530
- You can upload
531
- {maxFileCount > 1
532
- ? ` ${maxFileCount === Infinity ? "multiple" : maxFileCount}
533
- files (up to ${formatBytes(maxSize)} each)`
534
- : ` a file with ${formatBytes(maxSize)}`}
535
- </p>
536
- </div>
537
- </div>
538
- )}
539
- </div>
540
- );
541
- }
1
+ "use client";
2
+
3
+ import { FileText, Folder, FolderOpen, Upload, X } from "lucide-react";
4
+ import * as React from "react";
5
+ import Dropzone, {
6
+ FileWithPath as DefaultFileWithPath,
7
+ DropzoneState,
8
+ type DropzoneProps,
9
+ type FileRejection,
10
+ } from "react-dropzone";
11
+ import {
12
+ Avatar,
13
+ AvatarFallback,
14
+ AvatarImage,
15
+ } from "@ayasofyazilim/ui/components/avatar";
16
+ import { Button } from "@ayasofyazilim/ui/components/button";
17
+ import {
18
+ Collapsible,
19
+ CollapsibleContent,
20
+ CollapsibleTrigger,
21
+ } from "@ayasofyazilim/ui/components/collapsible";
22
+ import { Progress } from "@ayasofyazilim/ui/components/progress";
23
+ import { ScrollArea } from "@ayasofyazilim/ui/components/scroll-area";
24
+ import { cn, formatBytes } from "@ayasofyazilim/ui/lib/utils";
25
+ import { useControllableState } from "../hooks/use-controllable-state";
26
+ import { toast } from "sonner";
27
+
28
+ export type FileWithPath = DefaultFileWithPath;
29
+ export type BaseFileUploaderProps = React.HTMLAttributes<HTMLDivElement> & {
30
+ /**
31
+ * Value of the uploader.
32
+ * @type File[]
33
+ * @default undefined
34
+ * @example value={files}
35
+ */
36
+ value?: DefaultFileWithPath[];
37
+
38
+ /**
39
+ * Function to be called when the value changes.
40
+ * @type (files: File[]) => void
41
+ * @default undefined
42
+ * @example onValueChange={(files) => setFiles(files)}
43
+ */
44
+ onValueChange?: (files: DefaultFileWithPath[]) => void;
45
+
46
+ /**
47
+ * Function to be called when files are uploaded.
48
+ * @type (files: File[]) => Promise<void>
49
+ * @default undefined
50
+ * @example onUpload={(files) => uploadFiles(files)}
51
+ */
52
+ onUpload?: (files: File[]) => Promise<void>;
53
+
54
+ /**
55
+ * Progress of the uploaded files.
56
+ * @type Record<string, number> | undefined
57
+ * @default undefined
58
+ * @example progresses={{ "file1.png": 50 }}
59
+ */
60
+ progresses?: Record<string, number>;
61
+
62
+ /**
63
+ * Accepted file types for the uploader.
64
+ * @type { [key: string]: string[]}
65
+ * @default
66
+ * ```ts
67
+ * { "image/*": [] }
68
+ * ```
69
+ * @example accept={["image/png", "image/jpeg"]}
70
+ */
71
+ accept?: DropzoneProps["accept"];
72
+
73
+ /**
74
+ * Maximum file size for the uploader.
75
+ * @type number | undefined
76
+ * @default 1024 * 1024 * 2 // 2MB
77
+ * @example maxSize={1024 * 1024 * 2} // 2MB
78
+ */
79
+ maxSize?: DropzoneProps["maxSize"];
80
+
81
+ /**
82
+ * Maximum number of files for the uploader.
83
+ * @type number | undefined
84
+ * @default 1
85
+ * @example maxFileCount={4}
86
+ */
87
+ maxFileCount?: DropzoneProps["maxFiles"];
88
+
89
+ /**
90
+ * Whether the uploader should accept multiple files.
91
+ * @type boolean
92
+ * @default false
93
+ * @example multiple
94
+ */
95
+ multiple?: boolean;
96
+
97
+ /**
98
+ * Whether the uploader is disabled.
99
+ * @type boolean
100
+ * @default false
101
+ * @example disabled
102
+ */
103
+ disabled?: boolean;
104
+
105
+ /**
106
+ * Whether the uploader has drag and drop functionality.
107
+ * @type boolean
108
+ * @default false
109
+ * @example noDrag
110
+ */
111
+ label?: string | React.ReactNode;
112
+ description?: string | React.ReactNode;
113
+ classNames?: {
114
+ container?: string;
115
+ collapsible?: string;
116
+ dropzoneContainer?: string;
117
+ dropzone?: string;
118
+ fileList?: string;
119
+ header?: string;
120
+ collapsibleContent?: string;
121
+ };
122
+ showFileList?: boolean;
123
+ fileCardRenderer?: (props: FileCardProps) => React.ReactNode;
124
+ } & (ButtonFileUploaderProps | DropzoneFileUploaderProps);
125
+
126
+ type ButtonFileUploaderProps = {
127
+ variant: "button";
128
+ children?: React.ReactNode;
129
+ headerChildren?: React.ReactNode;
130
+ };
131
+ type DropzoneFileUploaderProps = {
132
+ variant: "dropzone";
133
+ };
134
+ export function FileUploader(props: BaseFileUploaderProps) {
135
+ const {
136
+ value: valueProp,
137
+ onValueChange,
138
+ onUpload,
139
+ progresses,
140
+ accept = {
141
+ "image/*": [],
142
+ },
143
+ maxSize = 1024 * 1024 * 2,
144
+ maxFileCount = 1,
145
+ multiple = false,
146
+ disabled = false,
147
+ classNames,
148
+ showFileList = true,
149
+ label,
150
+ description,
151
+ fileCardRenderer,
152
+ } = props;
153
+
154
+ const [files, setFiles] = useControllableState({
155
+ prop: valueProp,
156
+ onChange: onValueChange,
157
+ });
158
+
159
+ const onDrop = React.useCallback(
160
+ (acceptedFiles: File[], rejectedFiles: FileRejection[]) => {
161
+ if (!multiple && maxFileCount === 1 && acceptedFiles.length > 1) {
162
+ toast.error("Cannot upload more than 1 file at a time");
163
+ return;
164
+ }
165
+
166
+ if ((files?.length ?? 0) + acceptedFiles.length > maxFileCount) {
167
+ toast.error(`Cannot upload more than ${maxFileCount} files`);
168
+ return;
169
+ }
170
+
171
+ const newFiles = acceptedFiles.map((file) =>
172
+ Object.assign(file, {
173
+ preview: URL.createObjectURL(file),
174
+ }),
175
+ );
176
+ if (newFiles.length > 0 && !isOpen) setIsOpen(true);
177
+ const updatedFiles = files ? [...files, ...newFiles] : newFiles;
178
+
179
+ setFiles(updatedFiles);
180
+
181
+ if (rejectedFiles.length > 0) {
182
+ rejectedFiles.forEach(({ file, errors }) => {
183
+ toast.error(
184
+ `File ${file.name} was rejected because of ${errors.map((error) => error.message).join(", ")}`,
185
+ );
186
+ });
187
+ }
188
+
189
+ if (
190
+ onUpload &&
191
+ updatedFiles.length > 0 &&
192
+ updatedFiles.length <= maxFileCount
193
+ ) {
194
+ const target =
195
+ updatedFiles.length > 0 ? `${updatedFiles.length} files` : `file`;
196
+
197
+ toast.promise(onUpload(updatedFiles), {
198
+ loading: `Uploading ${target}...`,
199
+ success: () => {
200
+ setFiles([]);
201
+ return `${target} uploaded`;
202
+ },
203
+ error: `Failed to upload ${target}`,
204
+ });
205
+ }
206
+ },
207
+
208
+ [files, maxFileCount, multiple, onUpload, setFiles],
209
+ );
210
+
211
+ function onRemove(index: number) {
212
+ if (!files) return;
213
+ const newFiles = files.filter((_, i) => i !== index);
214
+ setFiles(newFiles);
215
+ if (newFiles.length === 0) setIsOpen(false);
216
+ onValueChange?.(newFiles);
217
+ }
218
+
219
+ // Revoke preview url when component unmounts
220
+ React.useEffect(
221
+ () => () => {
222
+ if (!files) return;
223
+ files.forEach((file) => {
224
+ if (isFileWithPreview(file)) {
225
+ URL.revokeObjectURL(file.preview);
226
+ }
227
+ });
228
+ },
229
+ [],
230
+ );
231
+
232
+ const isDisabled = disabled || (files?.length ?? 0) >= maxFileCount;
233
+ const [isOpen, setIsOpen] = React.useState(false);
234
+ return (
235
+ <Collapsible
236
+ onOpenChange={setIsOpen}
237
+ open={isOpen}
238
+ className={cn(
239
+ "transition-all flex flex-col w-full border rounded-lg [&>h3]:w-full",
240
+ classNames?.collapsible,
241
+ )}
242
+ >
243
+ <div
244
+ className={cn(
245
+ " gap-4 p-4",
246
+ props.variant === "button"
247
+ ? "flex flex-col sm:flex-row"
248
+ : "grid grid-cols-12",
249
+ classNames?.container,
250
+ )}
251
+ >
252
+ <CollapsibleTrigger
253
+ className={cn(
254
+ "gap-4 group/trigger hover:no-underline",
255
+ !files?.length && "opacity-50",
256
+ )}
257
+ asChild
258
+ >
259
+ <Button
260
+ variant="outline"
261
+ className="gap-2"
262
+ disabled={isDisabled || !files?.length}
263
+ >
264
+ <FolderOpen className="w-4 group-data-[state=open]/trigger:hidden" />
265
+ <Folder className="w-4 group-data-[state=closed]/trigger:hidden" />
266
+ Files
267
+ </Button>
268
+ </CollapsibleTrigger>
269
+ <Dropzone
270
+ onDrop={onDrop}
271
+ accept={accept}
272
+ maxSize={maxSize}
273
+ maxFiles={maxFileCount}
274
+ multiple={maxFileCount > 1 || multiple}
275
+ disabled={isDisabled}
276
+ noDrag={props.variant === "button"}
277
+ >
278
+ {(dropzone) => (
279
+ <DropzoneTrigger {...dropzone} {...props} isDisabled={isDisabled} />
280
+ )}
281
+ </Dropzone>
282
+ <div className={cn("flex w-full", classNames?.header)}>
283
+ <div className="flex flex-col w-full text-nowrap justify-center">
284
+ {label && (
285
+ <span className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70">
286
+ {label}
287
+ </span>
288
+ )}
289
+ {description && (
290
+ <span className="text-muted-foreground text-sm">
291
+ {description}
292
+ </span>
293
+ )}
294
+ </div>
295
+ {props.variant === "button" &&
296
+ props.headerChildren &&
297
+ props.headerChildren}
298
+ </div>
299
+ </div>
300
+ {props.children && props.children}
301
+ <CollapsibleContent
302
+ className={cn("w-full p-0 h-max", classNames?.collapsibleContent)}
303
+ >
304
+ <div
305
+ className={cn(
306
+ "group relative flex flex-col gap-4 overflow-hidden",
307
+ files?.length && props.variant === "button" && "",
308
+ files?.length && files?.length > 0 && "p-4 border-t",
309
+ classNames?.container,
310
+ )}
311
+ >
312
+ {files?.length && showFileList !== false ? (
313
+ <ScrollArea className="h-fit w-full">
314
+ <div
315
+ className={cn(
316
+ "grid max-h-48 sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 flex-col gap-4",
317
+ files.length === 1 && "grid-cols-1!",
318
+ files.length === 2 && "sm:grid-cols-2!",
319
+ files.length === 3 && "lg:grid-cols-3!",
320
+ files.length === 4 && "2xl:grid-cols-4!",
321
+ classNames?.fileList,
322
+ )}
323
+ >
324
+ {files?.map((file, index) => (
325
+ <React.Fragment
326
+ key={file.name + file.lastModified + file.path}
327
+ >
328
+ {fileCardRenderer ? (
329
+ fileCardRenderer({
330
+ file,
331
+ index,
332
+ onRemove: () => onRemove(index),
333
+ })
334
+ ) : (
335
+ <FileCard
336
+ file={file}
337
+ onRemove={() => onRemove(index)}
338
+ progress={progresses?.[file.name]}
339
+ />
340
+ )}
341
+ </React.Fragment>
342
+ ))}
343
+ </div>
344
+ </ScrollArea>
345
+ ) : null}
346
+ </div>
347
+ </CollapsibleContent>
348
+ </Collapsible>
349
+ );
350
+ }
351
+
352
+ export interface FileCardProps {
353
+ index: number;
354
+ file: DefaultFileWithPath;
355
+ onRemove?: () => void;
356
+ disabled?: boolean;
357
+ progress?: number;
358
+ classNames?: {
359
+ container?: string;
360
+ removeButton?: string;
361
+ };
362
+ }
363
+
364
+ export function FileCard({
365
+ file,
366
+ progress,
367
+ onRemove,
368
+ disabled,
369
+ classNames,
370
+ }: Omit<FileCardProps, "index">) {
371
+ return (
372
+ <div
373
+ className={cn(
374
+ "bg-muted relative flex items-center gap-2.5 overflow-hidden rounded-md p-2",
375
+ classNames?.container,
376
+ )}
377
+ >
378
+ <div className="flex flex-1 gap-2.5">
379
+ {isFileWithPreview(file) ? <FilePreview file={file} /> : null}
380
+ <div className="flex w-full flex-col gap-2">
381
+ <div className="flex flex-col gap-px overflow-hidden">
382
+ <p className="text-foreground/80 line-clamp-1 text-sm font-medium max-w-60 text-ellipsis">
383
+ {file.name}
384
+ </p>
385
+ <p className="text-muted-foreground text-xs">
386
+ {formatBytes(file.size)}
387
+ </p>
388
+ </div>
389
+ {progress ? (
390
+ <Progress value={progress} className="duration-1000" />
391
+ ) : null}
392
+ </div>
393
+ </div>
394
+ {onRemove && (
395
+ <div className="flex items-center gap-2">
396
+ <Button
397
+ type="button"
398
+ variant="outline"
399
+ size="icon"
400
+ className={cn("size-7", classNames?.removeButton)}
401
+ disabled={!!progress || disabled}
402
+ onClick={onRemove}
403
+ >
404
+ <X className="size-4" aria-hidden="true" />
405
+ <span className="sr-only">Remove file</span>
406
+ </Button>
407
+ </div>
408
+ )}
409
+ </div>
410
+ );
411
+ }
412
+
413
+ export function isFileWithPreview(
414
+ file: FileWithPath,
415
+ ): file is FileWithPath & { preview: string } {
416
+ return "preview" in file && typeof file.preview === "string";
417
+ }
418
+
419
+ export interface FilePreviewProps {
420
+ file: FileWithPath & { preview: string };
421
+ }
422
+
423
+ export function FilePreview({ file }: FilePreviewProps) {
424
+ if (file.type.startsWith("image/")) {
425
+ return (
426
+ <Avatar className="rounded-md border">
427
+ <AvatarImage
428
+ className="rounded-md"
429
+ src={file.preview}
430
+ alt={file.name}
431
+ loading="lazy"
432
+ />
433
+ <AvatarFallback className="bg-white rounded-md text-xs">
434
+ {`.${file.name.split(".")[1]}`}
435
+ </AvatarFallback>
436
+ </Avatar>
437
+ );
438
+ }
439
+
440
+ return (
441
+ <FileText className="text-muted-foreground size-10" aria-hidden="true" />
442
+ );
443
+ }
444
+
445
+ type DropzoneTriggerProps = DropzoneState &
446
+ BaseFileUploaderProps & {
447
+ isDisabled?: boolean;
448
+ };
449
+ function DropzoneTrigger(props: DropzoneTriggerProps) {
450
+ const {
451
+ classNames,
452
+ variant,
453
+ getRootProps,
454
+ getInputProps,
455
+ isDragActive = true,
456
+ maxFileCount = 1,
457
+ maxSize = 1024 * 1024 * 2,
458
+ isDisabled,
459
+ // ...dropzoneProps
460
+ } = props;
461
+ if (variant === "button") {
462
+ return (
463
+ <div
464
+ className={cn(
465
+ "flex flex-col sm:flex-row gap-4",
466
+ classNames?.dropzoneContainer,
467
+ )}
468
+ >
469
+ <div
470
+ {...getRootProps()}
471
+ // {...dropzoneProps}
472
+ className={cn(
473
+ "relative flex items-center gap-4 rounded-lg",
474
+ classNames?.dropzone,
475
+ )}
476
+ >
477
+ <input {...getInputProps()} />
478
+ <Button
479
+ type="button"
480
+ variant="outline"
481
+ className="min-h-9 gap-2 w-full sm:max-w-max"
482
+ disabled={isDisabled}
483
+ >
484
+ <Upload className="size-4" aria-hidden="true" />
485
+ Select
486
+ </Button>
487
+ </div>
488
+ </div>
489
+ );
490
+ }
491
+ return (
492
+ <div
493
+ {...getRootProps()}
494
+ // {...dropzoneProps}
495
+ className={cn(
496
+ "border-muted-foreground/25 hover:bg-muted/25 group relative grid h-52 w-full cursor-pointer place-items-center rounded-lg border-2 border-dashed px-5 py-2.5 text-center transition",
497
+ "ring-offset-background focus-visible:ring-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
498
+ isDragActive && "border-muted-foreground/50",
499
+ isDisabled && "pointer-events-none opacity-60",
500
+ variant === "dropzone" && "col-span-full row-start-2",
501
+ classNames?.dropzone,
502
+ )}
503
+ >
504
+ <input {...getInputProps()} />
505
+ {isDragActive ? (
506
+ <div className="flex flex-col items-center justify-center gap-4 sm:px-5">
507
+ <div className="rounded-full border border-dashed p-3">
508
+ <Upload
509
+ className="text-muted-foreground size-7"
510
+ aria-hidden="true"
511
+ />
512
+ </div>
513
+ <p className="text-muted-foreground font-medium">
514
+ Drop the files here
515
+ </p>
516
+ </div>
517
+ ) : (
518
+ <div className="flex flex-col items-center justify-center gap-4 sm:px-5">
519
+ <div className="rounded-full border border-dashed p-3">
520
+ <Upload
521
+ className="text-muted-foreground size-7"
522
+ aria-hidden="true"
523
+ />
524
+ </div>
525
+ <div className="flex flex-col gap-px">
526
+ <p className="text-muted-foreground font-medium">
527
+ Drag{`'n'`} drop files here, or click to select files
528
+ </p>
529
+ <p className="text-muted-foreground/70 text-sm">
530
+ You can upload
531
+ {maxFileCount > 1
532
+ ? ` ${maxFileCount === Infinity ? "multiple" : maxFileCount}
533
+ files (up to ${formatBytes(maxSize)} each)`
534
+ : ` a file with ${formatBytes(maxSize)}`}
535
+ </p>
536
+ </div>
537
+ </div>
538
+ )}
539
+ </div>
540
+ );
541
+ }