@grampro/kit 0.0.0-stage → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (505) hide show
  1. package/.gbs/skills/gbs-components/SKILL.md +190 -0
  2. package/.gbs/skills/gbs-components/references/accessibility.md +102 -0
  3. package/.gbs/skills/gbs-components/references/data-display.md +185 -0
  4. package/.gbs/skills/gbs-components/references/data-grid.md +116 -0
  5. package/.gbs/skills/gbs-components/references/forms.md +202 -0
  6. package/.gbs/skills/gbs-components/references/install.md +211 -0
  7. package/.gbs/skills/gbs-components/references/overlays.md +206 -0
  8. package/.gbs/skills/gbs-components/references/pickers.md +83 -0
  9. package/.gbs/skills/gbs-components/references/styling.md +246 -0
  10. package/.gbs/skills/gbs-components/references/toaster.md +57 -0
  11. package/CHANGELOG.md +173 -0
  12. package/LICENSE +15 -0
  13. package/README.md +193 -2
  14. package/index.cjs +1410 -0
  15. package/package.json +77 -6
  16. package/schema/passport-v1.schema.json +204 -0
  17. package/source/components/accordion/README.md +45 -0
  18. package/source/components/accordion/core/index.ts +2 -0
  19. package/source/components/accordion/core/open.ts +56 -0
  20. package/source/components/accordion/core/types.ts +17 -0
  21. package/source/components/accordion/index.ts +8 -0
  22. package/source/components/accordion/passport.json +259 -0
  23. package/source/components/accordion/react/Accordion.tsx +133 -0
  24. package/source/components/accordion/react/AccordionItem.tsx +120 -0
  25. package/source/components/accordion/react/context.ts +20 -0
  26. package/source/components/accordion/react/props.ts +13 -0
  27. package/source/components/accordion/styles.css +207 -0
  28. package/source/components/alert/README.md +39 -0
  29. package/source/components/alert/core/index.ts +2 -0
  30. package/source/components/alert/core/live.ts +25 -0
  31. package/source/components/alert/core/types.ts +7 -0
  32. package/source/components/alert/index.ts +5 -0
  33. package/source/components/alert/passport.json +250 -0
  34. package/source/components/alert/react/Alert.tsx +113 -0
  35. package/source/components/alert/react/icons.tsx +21 -0
  36. package/source/components/alert/react/locale.ts +5 -0
  37. package/source/components/alert/react/props.ts +11 -0
  38. package/source/components/alert/styles.css +154 -0
  39. package/source/components/avatar/core/identity.ts +103 -0
  40. package/source/components/avatar/core/index.ts +2 -0
  41. package/source/components/avatar/core/types.ts +12 -0
  42. package/source/components/avatar/index.ts +7 -0
  43. package/source/components/avatar/passport.json +294 -0
  44. package/source/components/avatar/react/Avatar.tsx +118 -0
  45. package/source/components/avatar/react/AvatarGroup.tsx +74 -0
  46. package/source/components/avatar/react/locale.ts +11 -0
  47. package/source/components/avatar/react/props.ts +6 -0
  48. package/source/components/avatar/styles.css +225 -0
  49. package/source/components/badge/README.md +37 -0
  50. package/source/components/badge/core/count.ts +37 -0
  51. package/source/components/badge/core/index.ts +2 -0
  52. package/source/components/badge/core/types.ts +11 -0
  53. package/source/components/badge/index.ts +7 -0
  54. package/source/components/badge/passport.json +332 -0
  55. package/source/components/badge/react/Badge.tsx +89 -0
  56. package/source/components/badge/react/Tag.tsx +82 -0
  57. package/source/components/badge/react/locale.ts +5 -0
  58. package/source/components/badge/react/props.ts +6 -0
  59. package/source/components/badge/styles.css +203 -0
  60. package/source/components/breadcrumb/README.md +34 -0
  61. package/source/components/breadcrumb/core/index.ts +4 -0
  62. package/source/components/breadcrumb/core/trail.ts +42 -0
  63. package/source/components/breadcrumb/core/types.ts +20 -0
  64. package/source/components/breadcrumb/index.ts +5 -0
  65. package/source/components/breadcrumb/passport.json +243 -0
  66. package/source/components/breadcrumb/react/Breadcrumb.tsx +177 -0
  67. package/source/components/breadcrumb/react/locale.ts +6 -0
  68. package/source/components/breadcrumb/react/props.ts +14 -0
  69. package/source/components/breadcrumb/styles.css +138 -0
  70. package/source/components/button/README.md +32 -0
  71. package/source/components/button/core/index.ts +3 -0
  72. package/source/components/button/core/state.ts +16 -0
  73. package/source/components/button/core/types.ts +28 -0
  74. package/source/components/button/index.ts +5 -0
  75. package/source/components/button/passport.json +402 -0
  76. package/source/components/button/passport.manual.json +31 -0
  77. package/source/components/button/react/Button.tsx +173 -0
  78. package/source/components/button/react/locale.ts +5 -0
  79. package/source/components/button/react/props.ts +23 -0
  80. package/source/components/button/styles.css +232 -0
  81. package/source/components/card/README.md +60 -0
  82. package/source/components/card/core/index.ts +4 -0
  83. package/source/components/card/core/trend.ts +32 -0
  84. package/source/components/card/core/types.ts +5 -0
  85. package/source/components/card/index.ts +5 -0
  86. package/source/components/card/passport.json +337 -0
  87. package/source/components/card/react/Card.tsx +133 -0
  88. package/source/components/card/react/Stat.tsx +127 -0
  89. package/source/components/card/react/props.ts +4 -0
  90. package/source/components/card/styles.css +230 -0
  91. package/source/components/checkbox/README.md +36 -0
  92. package/source/components/checkbox/core/group.ts +30 -0
  93. package/source/components/checkbox/core/index.ts +3 -0
  94. package/source/components/checkbox/core/types.ts +17 -0
  95. package/source/components/checkbox/index.ts +9 -0
  96. package/source/components/checkbox/passport.json +456 -0
  97. package/source/components/checkbox/react/Checkbox.tsx +147 -0
  98. package/source/components/checkbox/react/CheckboxGroup.tsx +149 -0
  99. package/source/components/checkbox/react/context.ts +16 -0
  100. package/source/components/checkbox/react/locale.ts +5 -0
  101. package/source/components/checkbox/react/props.ts +6 -0
  102. package/source/components/checkbox/styles.css +211 -0
  103. package/source/components/combobox/README.md +170 -0
  104. package/source/components/combobox/core/filter.ts +155 -0
  105. package/source/components/combobox/core/index.ts +16 -0
  106. package/source/components/combobox/core/types.ts +48 -0
  107. package/source/components/combobox/core/virtual.ts +67 -0
  108. package/source/components/combobox/index.ts +13 -0
  109. package/source/components/combobox/passport.json +456 -0
  110. package/source/components/combobox/react/Listbox.tsx +310 -0
  111. package/source/components/combobox/react/MultiSelect.tsx +265 -0
  112. package/source/components/combobox/react/Popover.tsx +38 -0
  113. package/source/components/combobox/react/Select.tsx +200 -0
  114. package/source/components/combobox/react/icons.tsx +11 -0
  115. package/source/components/combobox/react/locale.ts +16 -0
  116. package/source/components/combobox/react/props.ts +88 -0
  117. package/source/components/combobox/react/useCombobox.ts +409 -0
  118. package/source/components/combobox/styles.css +419 -0
  119. package/source/components/data-grid/README.md +233 -0
  120. package/source/components/data-grid/agent/coerce.ts +368 -0
  121. package/source/components/data-grid/agent/contract.ts +410 -0
  122. package/source/components/data-grid/agent/dataset.ts +92 -0
  123. package/source/components/data-grid/agent/engine.ts +470 -0
  124. package/source/components/data-grid/agent/executors.ts +155 -0
  125. package/source/components/data-grid/agent/index.ts +79 -0
  126. package/source/components/data-grid/agent/intent.ts +324 -0
  127. package/source/components/data-grid/agent/operations.ts +335 -0
  128. package/source/components/data-grid/agent/validate.ts +630 -0
  129. package/source/components/data-grid/agent/webmcp.ts +107 -0
  130. package/source/components/data-grid/core/columnHelper.ts +21 -0
  131. package/source/components/data-grid/core/columns.ts +288 -0
  132. package/source/components/data-grid/core/filtering.ts +237 -0
  133. package/source/components/data-grid/core/grid.ts +638 -0
  134. package/source/components/data-grid/core/index.ts +14 -0
  135. package/source/components/data-grid/core/rows.ts +64 -0
  136. package/source/components/data-grid/core/sorting.ts +133 -0
  137. package/source/components/data-grid/core/state.ts +82 -0
  138. package/source/components/data-grid/core/store.ts +52 -0
  139. package/source/components/data-grid/core/types.ts +302 -0
  140. package/source/components/data-grid/core/values.ts +98 -0
  141. package/source/components/data-grid/core/virtual.ts +85 -0
  142. package/source/components/data-grid/export/csv.ts +32 -0
  143. package/source/components/data-grid/export/download.ts +12 -0
  144. package/source/components/data-grid/export/pdf-font.ts +139 -0
  145. package/source/components/data-grid/export/pdf-writer.ts +113 -0
  146. package/source/components/data-grid/export/pdf.ts +379 -0
  147. package/source/components/data-grid/export/table.ts +73 -0
  148. package/source/components/data-grid/export/xlsx.ts +145 -0
  149. package/source/components/data-grid/export/zip.ts +87 -0
  150. package/source/components/data-grid/index.ts +14 -0
  151. package/source/components/data-grid/passport.json +1051 -0
  152. package/source/components/data-grid/passport.manual.json +255 -0
  153. package/source/components/data-grid/react/AskGrid.tsx +164 -0
  154. package/source/components/data-grid/react/Cell.tsx +282 -0
  155. package/source/components/data-grid/react/ColumnMenu.tsx +135 -0
  156. package/source/components/data-grid/react/DataGrid.tsx +335 -0
  157. package/source/components/data-grid/react/FilterForm.tsx +142 -0
  158. package/source/components/data-grid/react/HeaderRow.tsx +332 -0
  159. package/source/components/data-grid/react/Pagination.tsx +107 -0
  160. package/source/components/data-grid/react/Popover.tsx +35 -0
  161. package/source/components/data-grid/react/Row.tsx +85 -0
  162. package/source/components/data-grid/react/Toolbar.tsx +267 -0
  163. package/source/components/data-grid/react/Viewport.tsx +167 -0
  164. package/source/components/data-grid/react/context.ts +57 -0
  165. package/source/components/data-grid/react/hooks.ts +83 -0
  166. package/source/components/data-grid/react/icons.tsx +45 -0
  167. package/source/components/data-grid/react/keyboard.ts +110 -0
  168. package/source/components/data-grid/react/locale.ts +130 -0
  169. package/source/components/data-grid/styles.css +874 -0
  170. package/source/components/date-picker/README.md +141 -0
  171. package/source/components/date-picker/core/calendar.ts +266 -0
  172. package/source/components/date-picker/core/format.ts +170 -0
  173. package/source/components/date-picker/core/index.ts +41 -0
  174. package/source/components/date-picker/core/today.ts +72 -0
  175. package/source/components/date-picker/core/types.ts +68 -0
  176. package/source/components/date-picker/index.ts +16 -0
  177. package/source/components/date-picker/passport.json +407 -0
  178. package/source/components/date-picker/react/Calendar.tsx +160 -0
  179. package/source/components/date-picker/react/CalendarPanel.tsx +170 -0
  180. package/source/components/date-picker/react/DatePicker.tsx +249 -0
  181. package/source/components/date-picker/react/DateRangePicker.tsx +291 -0
  182. package/source/components/date-picker/react/MonthYearPanels.tsx +123 -0
  183. package/source/components/date-picker/react/Popover.tsx +45 -0
  184. package/source/components/date-picker/react/icons.tsx +15 -0
  185. package/source/components/date-picker/react/locale.ts +23 -0
  186. package/source/components/date-picker/react/props.ts +76 -0
  187. package/source/components/date-picker/react/useDatePicker.ts +557 -0
  188. package/source/components/date-picker/styles.css +445 -0
  189. package/source/components/dialog/README.md +39 -0
  190. package/source/components/dialog/core/api.ts +34 -0
  191. package/source/components/dialog/core/dialog.ts +11 -0
  192. package/source/components/dialog/core/index.ts +7 -0
  193. package/source/components/dialog/core/store.ts +81 -0
  194. package/source/components/dialog/core/types.ts +59 -0
  195. package/source/components/dialog/index.ts +7 -0
  196. package/source/components/dialog/passport.json +344 -0
  197. package/source/components/dialog/react/Dialog.tsx +279 -0
  198. package/source/components/dialog/react/DialogHost.tsx +45 -0
  199. package/source/components/dialog/react/icons.tsx +20 -0
  200. package/source/components/dialog/react/locale.ts +8 -0
  201. package/source/components/dialog/react/props.ts +13 -0
  202. package/source/components/dialog/styles.css +280 -0
  203. package/source/components/file-uploader/README.md +99 -0
  204. package/source/components/file-uploader/core/format.ts +79 -0
  205. package/source/components/file-uploader/core/index.ts +26 -0
  206. package/source/components/file-uploader/core/store.ts +432 -0
  207. package/source/components/file-uploader/core/transport.ts +154 -0
  208. package/source/components/file-uploader/core/types.ts +126 -0
  209. package/source/components/file-uploader/core/validate.ts +83 -0
  210. package/source/components/file-uploader/index.ts +7 -0
  211. package/source/components/file-uploader/passport.json +518 -0
  212. package/source/components/file-uploader/react/FileRow.tsx +268 -0
  213. package/source/components/file-uploader/react/FileUploader.tsx +511 -0
  214. package/source/components/file-uploader/react/icons.tsx +60 -0
  215. package/source/components/file-uploader/react/locale.ts +33 -0
  216. package/source/components/file-uploader/react/props.ts +31 -0
  217. package/source/components/file-uploader/react/useFileUploader.ts +32 -0
  218. package/source/components/file-uploader/styles.css +394 -0
  219. package/source/components/input/README.md +44 -0
  220. package/source/components/input/core/count.ts +5 -0
  221. package/source/components/input/core/index.ts +11 -0
  222. package/source/components/input/core/otp.ts +64 -0
  223. package/source/components/input/core/types.ts +14 -0
  224. package/source/components/input/index.ts +8 -0
  225. package/source/components/input/passport.json +536 -0
  226. package/source/components/input/react/Input.tsx +219 -0
  227. package/source/components/input/react/OtpInput.tsx +256 -0
  228. package/source/components/input/react/dom.ts +10 -0
  229. package/source/components/input/react/icons.tsx +17 -0
  230. package/source/components/input/react/locale.ts +9 -0
  231. package/source/components/input/react/props.ts +6 -0
  232. package/source/components/input/styles.css +295 -0
  233. package/source/components/menu/README.md +68 -0
  234. package/source/components/menu/core/index.ts +11 -0
  235. package/source/components/menu/core/navigation.ts +84 -0
  236. package/source/components/menu/core/types.ts +32 -0
  237. package/source/components/menu/index.ts +19 -0
  238. package/source/components/menu/passport.json +322 -0
  239. package/source/components/menu/react/Menu.tsx +371 -0
  240. package/source/components/menu/react/context.ts +31 -0
  241. package/source/components/menu/react/items.tsx +268 -0
  242. package/source/components/menu/react/locale.ts +6 -0
  243. package/source/components/menu/react/props.ts +4 -0
  244. package/source/components/menu/react/useMenuKeys.ts +124 -0
  245. package/source/components/menu/styles.css +224 -0
  246. package/source/components/modal/README.md +51 -0
  247. package/source/components/modal/core/dismiss.ts +29 -0
  248. package/source/components/modal/core/index.ts +3 -0
  249. package/source/components/modal/core/types.ts +27 -0
  250. package/source/components/modal/index.ts +5 -0
  251. package/source/components/modal/passport.json +289 -0
  252. package/source/components/modal/react/Modal.tsx +242 -0
  253. package/source/components/modal/react/icons.tsx +1 -0
  254. package/source/components/modal/react/locale.ts +5 -0
  255. package/source/components/modal/react/props.ts +17 -0
  256. package/source/components/modal/styles.css +241 -0
  257. package/source/components/number-input/README.md +53 -0
  258. package/source/components/number-input/core/format.ts +37 -0
  259. package/source/components/number-input/core/index.ts +4 -0
  260. package/source/components/number-input/core/parse.ts +118 -0
  261. package/source/components/number-input/core/step.ts +73 -0
  262. package/source/components/number-input/core/types.ts +32 -0
  263. package/source/components/number-input/index.ts +5 -0
  264. package/source/components/number-input/passport.json +541 -0
  265. package/source/components/number-input/react/NumberInput.tsx +465 -0
  266. package/source/components/number-input/react/icons.tsx +17 -0
  267. package/source/components/number-input/react/locale.ts +7 -0
  268. package/source/components/number-input/react/props.ts +11 -0
  269. package/source/components/number-input/styles.css +230 -0
  270. package/source/components/popover/README.md +44 -0
  271. package/source/components/popover/core/index.ts +2 -0
  272. package/source/components/popover/core/types.ts +12 -0
  273. package/source/components/popover/index.ts +4 -0
  274. package/source/components/popover/passport.json +238 -0
  275. package/source/components/popover/react/Popover.tsx +202 -0
  276. package/source/components/popover/react/locale.ts +5 -0
  277. package/source/components/popover/react/props.ts +4 -0
  278. package/source/components/popover/styles.css +148 -0
  279. package/source/components/progress/README.md +38 -0
  280. package/source/components/progress/core/index.ts +2 -0
  281. package/source/components/progress/core/progress.ts +40 -0
  282. package/source/components/progress/core/types.ts +23 -0
  283. package/source/components/progress/index.ts +7 -0
  284. package/source/components/progress/passport.json +270 -0
  285. package/source/components/progress/react/CircularProgress.tsx +106 -0
  286. package/source/components/progress/react/Progress.tsx +113 -0
  287. package/source/components/progress/react/locale.ts +7 -0
  288. package/source/components/progress/react/props.ts +6 -0
  289. package/source/components/progress/styles.css +200 -0
  290. package/source/components/radio-group/README.md +58 -0
  291. package/source/components/radio-group/core/group.ts +36 -0
  292. package/source/components/radio-group/core/index.ts +2 -0
  293. package/source/components/radio-group/core/types.ts +20 -0
  294. package/source/components/radio-group/index.ts +9 -0
  295. package/source/components/radio-group/passport.json +477 -0
  296. package/source/components/radio-group/react/Radio.tsx +144 -0
  297. package/source/components/radio-group/react/RadioGroup.tsx +179 -0
  298. package/source/components/radio-group/react/context.ts +18 -0
  299. package/source/components/radio-group/react/locale.ts +5 -0
  300. package/source/components/radio-group/react/props.ts +12 -0
  301. package/source/components/radio-group/styles.css +269 -0
  302. package/source/components/shared/README.md +54 -0
  303. package/source/components/shared/core/agent/adapter.ts +65 -0
  304. package/source/components/shared/core/agent/history.ts +120 -0
  305. package/source/components/shared/core/agent/index.ts +46 -0
  306. package/source/components/shared/core/agent/numbers.ts +217 -0
  307. package/source/components/shared/core/agent/schema.ts +180 -0
  308. package/source/components/shared/core/agent/types.ts +169 -0
  309. package/source/components/shared/core/agent/webmcp.ts +328 -0
  310. package/source/components/shared/core/cx.ts +9 -0
  311. package/source/components/shared/core/field.ts +35 -0
  312. package/source/components/shared/core/position.ts +124 -0
  313. package/source/components/shared/core/text.ts +14 -0
  314. package/source/components/shared/index.ts +17 -0
  315. package/source/components/shared/react/GramproAIProvider.tsx +50 -0
  316. package/source/components/shared/react/Popover.tsx +189 -0
  317. package/source/components/shared/react/icons.tsx +74 -0
  318. package/source/components/shared/react/useAskAgent.ts +217 -0
  319. package/source/components/shared/react/useControllableState.ts +42 -0
  320. package/source/components/shared/styles.css +79 -0
  321. package/source/components/shared/version.json +4 -0
  322. package/source/components/shared/version.ts +6 -0
  323. package/source/components/skeleton/README.md +58 -0
  324. package/source/components/skeleton/core/index.ts +3 -0
  325. package/source/components/skeleton/core/lines.ts +25 -0
  326. package/source/components/skeleton/core/types.ts +5 -0
  327. package/source/components/skeleton/index.ts +5 -0
  328. package/source/components/skeleton/passport.json +251 -0
  329. package/source/components/skeleton/react/Empty.tsx +51 -0
  330. package/source/components/skeleton/react/Skeleton.tsx +92 -0
  331. package/source/components/skeleton/react/props.ts +4 -0
  332. package/source/components/skeleton/styles.css +185 -0
  333. package/source/components/spinner/README.md +29 -0
  334. package/source/components/spinner/core/index.ts +3 -0
  335. package/source/components/spinner/core/types.ts +28 -0
  336. package/source/components/spinner/core/visibility.ts +34 -0
  337. package/source/components/spinner/index.ts +6 -0
  338. package/source/components/spinner/passport.json +245 -0
  339. package/source/components/spinner/react/Spinner.tsx +96 -0
  340. package/source/components/spinner/react/locale.ts +5 -0
  341. package/source/components/spinner/react/props.ts +4 -0
  342. package/source/components/spinner/react/useDelayedLoading.ts +39 -0
  343. package/source/components/spinner/styles.css +173 -0
  344. package/source/components/switch/README.md +46 -0
  345. package/source/components/switch/core/index.ts +2 -0
  346. package/source/components/switch/core/toggle.ts +54 -0
  347. package/source/components/switch/core/types.ts +9 -0
  348. package/source/components/switch/index.ts +5 -0
  349. package/source/components/switch/passport.json +421 -0
  350. package/source/components/switch/react/Switch.tsx +219 -0
  351. package/source/components/switch/react/locale.ts +5 -0
  352. package/source/components/switch/react/props.ts +12 -0
  353. package/source/components/switch/styles.css +227 -0
  354. package/source/components/tabs/README.md +32 -0
  355. package/source/components/tabs/core/index.ts +3 -0
  356. package/source/components/tabs/core/navigation.ts +54 -0
  357. package/source/components/tabs/core/types.ts +16 -0
  358. package/source/components/tabs/index.ts +5 -0
  359. package/source/components/tabs/passport.json +315 -0
  360. package/source/components/tabs/react/Tabs.tsx +306 -0
  361. package/source/components/tabs/react/context.ts +21 -0
  362. package/source/components/tabs/styles.css +263 -0
  363. package/source/components/textarea/README.md +39 -0
  364. package/source/components/textarea/core/count.ts +5 -0
  365. package/source/components/textarea/core/index.ts +4 -0
  366. package/source/components/textarea/core/size.ts +23 -0
  367. package/source/components/textarea/core/types.ts +17 -0
  368. package/source/components/textarea/index.ts +5 -0
  369. package/source/components/textarea/passport.json +382 -0
  370. package/source/components/textarea/react/Textarea.tsx +208 -0
  371. package/source/components/textarea/react/locale.ts +5 -0
  372. package/source/components/textarea/react/props.ts +4 -0
  373. package/source/components/textarea/styles.css +158 -0
  374. package/source/components/toaster/README.md +128 -0
  375. package/source/components/toaster/core/api.ts +87 -0
  376. package/source/components/toaster/core/index.ts +14 -0
  377. package/source/components/toaster/core/store.ts +211 -0
  378. package/source/components/toaster/core/toast.ts +12 -0
  379. package/source/components/toaster/core/types.ts +78 -0
  380. package/source/components/toaster/index.ts +6 -0
  381. package/source/components/toaster/passport.json +221 -0
  382. package/source/components/toaster/react/ToastItem.tsx +164 -0
  383. package/source/components/toaster/react/Toaster.tsx +187 -0
  384. package/source/components/toaster/react/icons.tsx +23 -0
  385. package/source/components/toaster/react/locale.ts +6 -0
  386. package/source/components/toaster/react/props.ts +15 -0
  387. package/source/components/toaster/react/useToasts.ts +11 -0
  388. package/source/components/toaster/styles.css +282 -0
  389. package/source/components/tooltip/README.md +43 -0
  390. package/source/components/tooltip/core/index.ts +4 -0
  391. package/source/components/tooltip/core/types.ts +4 -0
  392. package/source/components/tooltip/core/visibility.ts +34 -0
  393. package/source/components/tooltip/index.ts +3 -0
  394. package/source/components/tooltip/passport.json +170 -0
  395. package/source/components/tooltip/react/Tooltip.tsx +196 -0
  396. package/source/components/tooltip/react/props.ts +4 -0
  397. package/source/components/tooltip/styles.css +71 -0
  398. package/source/fallback/index.tsx +11 -0
  399. package/source/globalStyle.ts +74 -0
  400. package/source/hooks/SelectionHooks/type.ts +4 -0
  401. package/source/hooks/SelectionHooks/useClickOutside.ts +22 -0
  402. package/source/hooks/SelectionHooks/useMultiSelectState.ts +64 -0
  403. package/source/hooks/SelectionHooks/useSelectData.ts +58 -0
  404. package/source/hooks/SelectionHooks/useSelectState.ts +36 -0
  405. package/source/icon/Icon.tsx +102 -0
  406. package/source/icon/iconPaths.ts +206 -0
  407. package/source/legacy-components/bargraph/index.tsx +95 -0
  408. package/source/legacy-components/bargraph/type.ts +12 -0
  409. package/source/legacy-components/breadcrumb/index.tsx +66 -0
  410. package/source/legacy-components/breadcrumb/types.ts +10 -0
  411. package/source/legacy-components/button/index.tsx +42 -0
  412. package/source/legacy-components/card/index.tsx +31 -0
  413. package/source/legacy-components/checkbox/index.tsx +25 -0
  414. package/source/legacy-components/contextmenu/ContextMenu.tsx +87 -0
  415. package/source/legacy-components/contextmenu/ContextMenuItem.tsx +30 -0
  416. package/source/legacy-components/contextmenu/index.ts +2 -0
  417. package/source/legacy-components/contextmenu/types.ts +19 -0
  418. package/source/legacy-components/darkmode/index.tsx +55 -0
  419. package/source/legacy-components/datagrid/context/GridContext.tsx +215 -0
  420. package/source/legacy-components/datagrid/createTemplate.tsx +82 -0
  421. package/source/legacy-components/datagrid/hooks/index.ts +6 -0
  422. package/source/legacy-components/datagrid/hooks/useColumns.ts +33 -0
  423. package/source/legacy-components/datagrid/hooks/useDataSource.ts +54 -0
  424. package/source/legacy-components/datagrid/hooks/useFiltering.ts +169 -0
  425. package/source/legacy-components/datagrid/hooks/usePagination.ts +112 -0
  426. package/source/legacy-components/datagrid/hooks/useRowSelection.ts +48 -0
  427. package/source/legacy-components/datagrid/hooks/useSearch.ts +90 -0
  428. package/source/legacy-components/datagrid/index.tsx +28 -0
  429. package/source/legacy-components/datagrid/layout/FilterPopup.tsx +92 -0
  430. package/source/legacy-components/datagrid/layout/GridBody.tsx +184 -0
  431. package/source/legacy-components/datagrid/layout/GridPagination.tsx +119 -0
  432. package/source/legacy-components/datagrid/layout/GridToolbar.tsx +109 -0
  433. package/source/legacy-components/datagrid/layout/index.tsx +68 -0
  434. package/source/legacy-components/datagrid/type.ts +198 -0
  435. package/source/legacy-components/datepicker/index.tsx +365 -0
  436. package/source/legacy-components/datepicker/types.ts +12 -0
  437. package/source/legacy-components/dialog/index.tsx +44 -0
  438. package/source/legacy-components/dialog/types.ts +12 -0
  439. package/source/legacy-components/formrenderer/componentHandles/CheckBoxHandles.tsx +80 -0
  440. package/source/legacy-components/formrenderer/componentHandles/DatePickerHandles.tsx +93 -0
  441. package/source/legacy-components/formrenderer/componentHandles/InputHandles.tsx +106 -0
  442. package/source/legacy-components/formrenderer/componentHandles/MultiHandles.tsx +93 -0
  443. package/source/legacy-components/formrenderer/componentHandles/SelectHandles.tsx +95 -0
  444. package/source/legacy-components/formrenderer/helperFunctions.ts +72 -0
  445. package/source/legacy-components/formrenderer/index.tsx +93 -0
  446. package/source/legacy-components/formrenderer/types.ts +127 -0
  447. package/source/legacy-components/input/index.tsx +142 -0
  448. package/source/legacy-components/input/types.ts +10 -0
  449. package/source/legacy-components/materialInput/index.tsx +138 -0
  450. package/source/legacy-components/materialInput/types.ts +16 -0
  451. package/source/legacy-components/modal/index.tsx +152 -0
  452. package/source/legacy-components/modal/types.ts +19 -0
  453. package/source/legacy-components/multiselect/PortalDropDown.tsx +44 -0
  454. package/source/legacy-components/multiselect/index.tsx +269 -0
  455. package/source/legacy-components/multiselect/types.ts +26 -0
  456. package/source/legacy-components/navbar/AuthSection.tsx +98 -0
  457. package/source/legacy-components/navbar/MobileToggle.tsx +31 -0
  458. package/source/legacy-components/navbar/NavItemComponent.tsx +119 -0
  459. package/source/legacy-components/navbar/SearchBar.tsx +55 -0
  460. package/source/legacy-components/navbar/helperFunctions.ts +27 -0
  461. package/source/legacy-components/navbar/index.tsx +156 -0
  462. package/source/legacy-components/navbar/types.ts +69 -0
  463. package/source/legacy-components/select/PortalDropDown.tsx +59 -0
  464. package/source/legacy-components/select/index.tsx +249 -0
  465. package/source/legacy-components/select/types.ts +29 -0
  466. package/source/legacy-components/sidebar/components/MenuItem.tsx +101 -0
  467. package/source/legacy-components/sidebar/components/MenuSection.tsx +34 -0
  468. package/source/legacy-components/sidebar/components/SidebarFooter.tsx +50 -0
  469. package/source/legacy-components/sidebar/components/SidebarLogo.tsx +24 -0
  470. package/source/legacy-components/sidebar/components/SidebarMenu.tsx +29 -0
  471. package/source/legacy-components/sidebar/components/UserProfile.tsx +31 -0
  472. package/source/legacy-components/sidebar/hooks/useSidebarState.ts +41 -0
  473. package/source/legacy-components/sidebar/index.tsx +77 -0
  474. package/source/legacy-components/sidebar/type.ts +42 -0
  475. package/source/legacy-components/spinner/Stroke.tsx +89 -0
  476. package/source/legacy-components/spinner/index.tsx +54 -0
  477. package/source/legacy-components/spinner/types.ts +9 -0
  478. package/source/legacy-components/tabs/index.tsx +71 -0
  479. package/source/legacy-components/tabs/types.ts +16 -0
  480. package/source/legacy-components/textarea/index.tsx +123 -0
  481. package/source/legacy-components/textarea/types.ts +15 -0
  482. package/source/legacy-components/toast/ToastComponent.tsx +101 -0
  483. package/source/legacy-components/toast/ToastIcon.tsx +61 -0
  484. package/source/legacy-components/toast/index.tsx +42 -0
  485. package/source/legacy-components/toast/toastStore.ts +42 -0
  486. package/source/legacy-components/toast/types.ts +18 -0
  487. package/source/legacy-components/toast/useToast.ts +12 -0
  488. package/source/legacy-components/uploader/ProgressAnimation.tsx +50 -0
  489. package/source/legacy-components/uploader/UploadedFilePreview.tsx +130 -0
  490. package/source/legacy-components/uploader/index.tsx +311 -0
  491. package/source/legacy-components/uploader/types.ts +30 -0
  492. package/source/legacy-components/uploader/uploaderIcon.tsx +72 -0
  493. package/source/legacy-components/uploader/uploaderService.ts +134 -0
  494. package/source/legacy-components/useUploader/useUploader.tsx +310 -0
  495. package/source/legacy-components/usepaginateddata/usePaginatedData.ts +174 -0
  496. package/source/theme.ts +40 -0
  497. package/source/utils.ts +10 -0
  498. package/tools/env.cjs +61 -0
  499. package/tools/passport/cli.cjs +79 -0
  500. package/tools/passport/extract.cjs +493 -0
  501. package/tools/passport/index.cjs +185 -0
  502. package/tools/passport/merge.cjs +131 -0
  503. package/tools/passport/policy.cjs +65 -0
  504. package/tools/passport/validate.cjs +277 -0
  505. package/tools/ts-require.cjs +79 -0
@@ -0,0 +1,50 @@
1
+ import type { MenuItem, IconComponent } from "../type";
2
+
3
+ type SidebarFooterProps = {
4
+ footerItems?: MenuItem[];
5
+ iconMap: Record<string, IconComponent>;
6
+ };
7
+
8
+ export const SidebarFooter = ({ footerItems, iconMap }: SidebarFooterProps) => {
9
+ if (!footerItems) return null;
10
+ if (!iconMap) return null;
11
+
12
+ return (
13
+ <div className="border-t border-gray-200">
14
+ <ul className="px-4 py-2 space-y-1">
15
+ {footerItems?.map((item) => {
16
+ const IconComponent = iconMap[item.icon] || (() => null);
17
+
18
+ if (item.type === "custom" && item.component) {
19
+ const CustomComponent = item.component;
20
+ return (
21
+ <li
22
+ key={item.id}
23
+ className="py-2 px-3 flex items-center text-sm text-gray-700"
24
+ >
25
+ <span className="mr-3">
26
+ <IconComponent />
27
+ </span>
28
+ <CustomComponent />
29
+ </li>
30
+ );
31
+ }
32
+
33
+ return (
34
+ <li key={item.id}>
35
+ <a
36
+ href={item.path}
37
+ className="flex items-center py-2 px-3 rounded-md text-sm text-gray-700 hover:bg-gray-50"
38
+ >
39
+ <span className="mr-3">
40
+ <IconComponent />
41
+ </span>
42
+ <span>{item?.name}</span>
43
+ </a>
44
+ </li>
45
+ );
46
+ })}
47
+ </ul>
48
+ </div>
49
+ );
50
+ };
@@ -0,0 +1,24 @@
1
+ import type { MenuData } from "../type";
2
+
3
+ type SidebarLogoProps = {
4
+ logo: MenuData["logo"];
5
+ };
6
+
7
+ export const SidebarLogo = ({ logo }: SidebarLogoProps) => {
8
+ if (!logo) return null;
9
+
10
+ return (
11
+ <div className="p-4 flex items-center">
12
+ <div className="flex-shrink-0 mr-2">
13
+ <div className="h-6 w-6 bg-black text-white rounded flex items-center justify-center">
14
+ <img
15
+ src={logo?.logoUrl}
16
+ alt={logo?.name}
17
+ className="h-4 w-4 text-white"
18
+ />
19
+ </div>
20
+ </div>
21
+ <span className="text-gray-800 font-semibold text-lg">{logo?.name}</span>
22
+ </div>
23
+ );
24
+ };
@@ -0,0 +1,29 @@
1
+ import type { IconComponent, MenuSection } from "../type";
2
+ import { MenuSection as MenuSectionComponent } from "./MenuSection";
3
+
4
+ type SidebarMenuProps = {
5
+ sections?: MenuSection[];
6
+ iconMap: Record<string, IconComponent>;
7
+ toggleItem: (sectionIndex: number, itemId: number | string) => void;
8
+ };
9
+
10
+ export const SidebarMenu = ({
11
+ sections,
12
+ iconMap,
13
+ toggleItem,
14
+
15
+ }: SidebarMenuProps) => {
16
+ return (
17
+ <div className="flex-grow overflow-y-auto px-4 py-2">
18
+ {sections?.map((section, sectionIndex) => (
19
+ <MenuSectionComponent
20
+ key={section.title}
21
+ section={section}
22
+ sectionIndex={sectionIndex}
23
+ iconMap={iconMap}
24
+ toggleItem={toggleItem}
25
+ />
26
+ ))}
27
+ </div>
28
+ );
29
+ };
@@ -0,0 +1,31 @@
1
+ import type { MenuData } from "../type";
2
+
3
+ type UserProfileProps = {
4
+ profile: MenuData["profile"];
5
+ };
6
+
7
+ export const UserProfile = ({ profile }: UserProfileProps) => {
8
+ if (!profile) return null;
9
+
10
+ return (
11
+ <div className="border-t border-gray-200 px-4 py-3 flex flex-col gap-2">
12
+ <div className="flex">
13
+ <div className="w-8 h-8 rounded-full bg-orange-100 text-orange-700 flex items-center justify-center mr-3">
14
+ <span className="text-xs font-medium">
15
+ {profile?.name
16
+ .split(" ")
17
+ .map((n) => n[0])
18
+ .join("")}
19
+ </span>
20
+ </div>
21
+ <div className="flex-grow">
22
+ <div className="text-sm font-medium text-gray-700">
23
+ {profile?.name}
24
+ </div>
25
+ <div className="text-xs text-gray-400">{profile?.email}</div>
26
+ </div>
27
+ </div>
28
+ <div className="text-xs text-gray-400">© 2024 Sequence Inc.</div>
29
+ </div>
30
+ );
31
+ };
@@ -0,0 +1,41 @@
1
+ import { useState } from "react";
2
+ import type { MenuData } from "../type";
3
+
4
+ export const useSidebarState = (menuData: MenuData) => {
5
+ const [sidebarData, setSidebarData] = useState<MenuData>(menuData);
6
+
7
+ const toggleItem = (sectionIndex: number, itemId: number | string): void => {
8
+ const newData = { ...sidebarData };
9
+
10
+ const section = newData.sections?.[sectionIndex];
11
+ if (!section) return;
12
+
13
+ const itemIndex = section.items.findIndex((item) => item.id === itemId);
14
+ if (itemIndex === -1) return;
15
+
16
+ if (section.items[itemIndex].expandable) {
17
+ section.items[itemIndex].expanded = !section.items[itemIndex].expanded;
18
+ setSidebarData({ ...newData });
19
+ }
20
+ };
21
+
22
+ const toggleMode = (): void => {
23
+ const newData = { ...sidebarData };
24
+ if (!newData.footer) return;
25
+
26
+ const toggleModeIndex = newData.footer.findIndex(
27
+ (item) => item.type === "toggle"
28
+ );
29
+ if (toggleModeIndex === -1) return;
30
+
31
+ newData.footer[toggleModeIndex].active =
32
+ !newData.footer[toggleModeIndex].active;
33
+ setSidebarData({ ...newData });
34
+ };
35
+
36
+ return {
37
+ sidebarData,
38
+ toggleItem,
39
+ toggleMode,
40
+ };
41
+ };
@@ -0,0 +1,77 @@
1
+ import type { SidebarProps } from "./type";
2
+ import { useSidebarState } from "./hooks/useSidebarState";
3
+ import { SidebarLogo } from "./components/SidebarLogo";
4
+ import { SidebarMenu } from "./components/SidebarMenu";
5
+ import { SidebarFooter } from "./components/SidebarFooter";
6
+ import { UserProfile } from "./components/UserProfile";
7
+ import Icon from "../icon/Icon";
8
+ import { menuIcon, x } from "../icon/iconPaths";
9
+ import { useState } from "react";
10
+
11
+ export function Sidebar({ menuData, iconMap }: SidebarProps) {
12
+ const { sidebarData, toggleItem } = useSidebarState(menuData);
13
+ const [showSideBarMobile, setShowSideBarMobile] = useState(false);
14
+
15
+ return (
16
+ <div>
17
+ {/* Mobile menu button - only show when sidebar is closed */}
18
+ {!showSideBarMobile && (
19
+ <button
20
+ className="md:hidden flex items-center justify-between absolute p-4 border z-50 bg-white rounded-xl top-3 left-3"
21
+ onClick={() => setShowSideBarMobile(true)}
22
+ >
23
+ <Icon
24
+ elements={menuIcon}
25
+ svgClass={"stroke-black fill-none"}
26
+ dimensions={{ width: "18", height: "18" }}
27
+ />
28
+ </button>
29
+ )}
30
+
31
+ {/* Mobile sidebar overlay */}
32
+ {showSideBarMobile && (
33
+ <div
34
+ className="md:hidden fixed inset-0 z-40"
35
+ onClick={() => setShowSideBarMobile(false)}
36
+ />
37
+ )}
38
+
39
+ {/* Mobile sidebar */}
40
+ <div
41
+ className={`md:hidden fixed left-0 top-0 h-screen bg-white w-64 border-r border-gray-200 z-40 transform transition-transform duration-300 ease-in-out ${
42
+ showSideBarMobile ? "translate-x-0" : "-translate-x-full"
43
+ }`}
44
+ >
45
+ <div className="flex items-center justify-between pr-4">
46
+ <SidebarLogo logo={sidebarData.logo} />
47
+ <button onClick={() => setShowSideBarMobile(false)}>
48
+ <Icon
49
+ elements={x}
50
+ svgClass={"stroke-black fill-none"}
51
+ dimensions={{ width: "18", height: "18" }}
52
+ />
53
+ </button>
54
+ </div>
55
+ <SidebarMenu
56
+ sections={sidebarData.sections}
57
+ iconMap={iconMap}
58
+ toggleItem={toggleItem}
59
+ />
60
+ <SidebarFooter footerItems={sidebarData.footer} iconMap={iconMap} />
61
+ <UserProfile profile={sidebarData.profile} />
62
+ </div>
63
+
64
+ {/* Desktop sidebar */}
65
+ <div className="hidden md:flex flex-col h-screen bg-white w-64 border-r border-gray-200 sticky left-0 top-0">
66
+ <SidebarLogo logo={sidebarData.logo} />
67
+ <SidebarMenu
68
+ sections={sidebarData.sections}
69
+ iconMap={iconMap}
70
+ toggleItem={toggleItem}
71
+ />
72
+ <SidebarFooter footerItems={sidebarData.footer} iconMap={iconMap} />
73
+ <UserProfile profile={sidebarData.profile} />
74
+ </div>
75
+ </div>
76
+ );
77
+ }
@@ -0,0 +1,42 @@
1
+ export type IconComponent = React.FC;
2
+
3
+ export type MenuItem = {
4
+ id: number | string;
5
+ name: string;
6
+ icon: string;
7
+ path?: string;
8
+ active?: boolean;
9
+ expandable?: boolean;
10
+ expanded?: boolean;
11
+ badge?: string;
12
+ toggle?: boolean;
13
+ type?: string;
14
+ component?: React.FC;
15
+ };
16
+
17
+ export type MenuSection = {
18
+ id?: number | string;
19
+ title: string;
20
+ items: MenuItem[];
21
+ component?: React.FC;
22
+ type?: string;
23
+ };
24
+
25
+ export type MenuData = {
26
+ logo?: {
27
+ name: string;
28
+ logoUrl: string;
29
+ };
30
+ sections?: MenuSection[];
31
+ footer?: MenuItem[];
32
+ profile?: {
33
+ name: string;
34
+ email: string;
35
+ avatarUrl: string;
36
+ };
37
+ };
38
+
39
+ export type SidebarProps = {
40
+ menuData: MenuData;
41
+ iconMap: Record<string, IconComponent>;
42
+ };
@@ -0,0 +1,89 @@
1
+ import React from "react";
2
+
3
+ interface StrokeProps {
4
+ size?: string;
5
+ strokeColor?: string;
6
+ }
7
+
8
+ export default function Stroke(props: StrokeProps) {
9
+ const { size, strokeColor } = props;
10
+ return (
11
+ <svg
12
+ className={`${size} animate-spin ${strokeColor}`}
13
+ viewBox="0 0 256 256"
14
+ >
15
+ <line
16
+ x1="128"
17
+ y1="32"
18
+ x2="128"
19
+ y2="64"
20
+ strokeLinecap="round"
21
+ strokeLinejoin="round"
22
+ strokeWidth="24"
23
+ ></line>
24
+ <line
25
+ x1="195.9"
26
+ y1="60.1"
27
+ x2="173.3"
28
+ y2="82.7"
29
+ strokeLinecap="round"
30
+ strokeLinejoin="round"
31
+ strokeWidth="24"
32
+ ></line>
33
+ <line
34
+ x1="224"
35
+ y1="128"
36
+ x2="192"
37
+ y2="128"
38
+ strokeLinecap="round"
39
+ strokeLinejoin="round"
40
+ strokeWidth="24"
41
+ ></line>
42
+ <line
43
+ x1="195.9"
44
+ y1="195.9"
45
+ x2="173.3"
46
+ y2="173.3"
47
+ strokeLinecap="round"
48
+ strokeLinejoin="round"
49
+ strokeWidth="24"
50
+ ></line>
51
+ <line
52
+ x1="128"
53
+ y1="224"
54
+ x2="128"
55
+ y2="192"
56
+ strokeLinecap="round"
57
+ strokeLinejoin="round"
58
+ strokeWidth="24"
59
+ ></line>
60
+ <line
61
+ x1="60.1"
62
+ y1="195.9"
63
+ x2="82.7"
64
+ y2="173.3"
65
+ strokeLinecap="round"
66
+ strokeLinejoin="round"
67
+ strokeWidth="24"
68
+ ></line>
69
+ <line
70
+ x1="32"
71
+ y1="128"
72
+ x2="64"
73
+ y2="128"
74
+ strokeLinecap="round"
75
+ strokeLinejoin="round"
76
+ strokeWidth="24"
77
+ ></line>
78
+ <line
79
+ x1="60.1"
80
+ y1="60.1"
81
+ x2="82.7"
82
+ y2="82.7"
83
+ strokeLinecap="round"
84
+ strokeLinejoin="round"
85
+ strokeWidth="24"
86
+ ></line>
87
+ </svg>
88
+ );
89
+ }
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Copyright (c) Grampro Business Services and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import React from "react";
9
+ import Stroke from "./Stroke";
10
+ import type { SpinnerProps } from "./types";
11
+
12
+ export const Spinner: React.FC<SpinnerProps> = ({
13
+ size = "h-10 w-10",
14
+ color = "border-blue-500",
15
+ fullCircleColor = "border-t-blue-400",
16
+ dotColor = "bg-blue-500",
17
+ duration = "duration-500",
18
+ type = "circle",
19
+ strokeColor = "stroke-blue-500",
20
+ }) => {
21
+ if (type === "circle") {
22
+ return (
23
+ <div
24
+ className={`loader ease-linear rounded-full border-4 border-t-4 ${color} ${size} ${duration} border-t-transparent animate-spin`}
25
+ ></div>
26
+ );
27
+ } else if (type === "circle-bg") {
28
+ return (
29
+ <div
30
+ className={`${size} animate-spin rounded-full border-4 ${fullCircleColor}`}
31
+ ></div>
32
+ );
33
+ } else if (type === "dot") {
34
+ return (
35
+ <div className="flex space-x-2 dark:invert">
36
+ <div
37
+ className={`${size} ${dotColor} rounded-full animate-bounce`}
38
+ style={{ animationDelay: "-0.3s" }}
39
+ ></div>
40
+ <div
41
+ className={`${size} ${dotColor} rounded-full animate-bounce`}
42
+ style={{ animationDelay: "-0.15s" }}
43
+ ></div>
44
+ <div
45
+ className={`${size} ${dotColor} rounded-full animate-bounce`}
46
+ ></div>
47
+ </div>
48
+ );
49
+ } else if (type === "stroke") {
50
+ return <Stroke size={size} strokeColor={strokeColor} />;
51
+ } else {
52
+ return null;
53
+ }
54
+ };
@@ -0,0 +1,9 @@
1
+ export type SpinnerProps = {
2
+ size?: string;
3
+ color?: string;
4
+ fullCircleColor?: string;
5
+ dotColor?: string;
6
+ duration?: string;
7
+ type?: "circle" | "circle-bg" | "dot" | "stroke";
8
+ strokeColor?: string;
9
+ };
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Copyright (c) Grampro Business Services and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ import { useState } from "react";
9
+ import { twMerge } from "tailwind-merge";
10
+ import type { TabsProps } from "./types";
11
+
12
+ export function Tabs({
13
+ tabs,
14
+ defaultTabId,
15
+ renderContent,
16
+ onChange,
17
+ className = "",
18
+ variant = "line",
19
+ }: TabsProps) {
20
+ const [activeTabId, setActiveTabId] = useState<string>(
21
+ defaultTabId || (tabs.length > 0 ? tabs[0].id : "")
22
+ );
23
+
24
+ const handleTabChange = (tabId: string) => {
25
+ setActiveTabId(tabId);
26
+ if (onChange) {
27
+ onChange(tabId);
28
+ }
29
+ };
30
+
31
+ const isPills = variant === "pills";
32
+
33
+ return (
34
+ <div className={twMerge("w-full", className)}>
35
+ <nav
36
+ className={twMerge(
37
+ "flex gap-1",
38
+ isPills
39
+ ? "rounded-lg bg-zinc-100 p-1 dark:bg-zinc-900"
40
+ : "border-b border-zinc-200 dark:border-zinc-800"
41
+ )}
42
+ >
43
+ {tabs.map((tab) => {
44
+ const isActive = activeTabId === tab.id;
45
+
46
+ return (
47
+ <button
48
+ key={tab.id}
49
+ type="button"
50
+ disabled={tab.disabled}
51
+ className={twMerge(
52
+ "min-h-9 px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-black dark:focus-visible:ring-white disabled:cursor-not-allowed disabled:text-zinc-400",
53
+ isPills ? "rounded-md" : "-mb-px border-b-2 border-transparent",
54
+ isActive && isPills
55
+ ? "bg-white text-zinc-950 shadow-sm dark:bg-zinc-800 dark:text-white"
56
+ : "",
57
+ isActive && !isPills
58
+ ? "border-black text-black dark:border-white dark:text-white"
59
+ : "text-zinc-500 hover:text-zinc-800 dark:text-zinc-400 dark:hover:text-zinc-100"
60
+ )}
61
+ onClick={() => !tab.disabled && handleTabChange(tab.id)}
62
+ >
63
+ {tab.label}
64
+ </button>
65
+ );
66
+ })}
67
+ </nav>
68
+ <div className="pt-4">{renderContent(activeTabId)}</div>
69
+ </div>
70
+ );
71
+ }
@@ -0,0 +1,16 @@
1
+ import type { ReactNode } from "react";
2
+
3
+ export interface TabItem {
4
+ id: string;
5
+ label: string;
6
+ disabled?: boolean;
7
+ }
8
+
9
+ export interface TabsProps {
10
+ tabs: TabItem[];
11
+ defaultTabId?: string;
12
+ renderContent: (activeTabId: string) => ReactNode;
13
+ onChange?: (tabId: string) => void;
14
+ className?: string;
15
+ variant?: "line" | "pills";
16
+ }
@@ -0,0 +1,123 @@
1
+ import React, { useState, useRef, useEffect } from "react";
2
+ import { twMerge } from "tailwind-merge";
3
+ import type { TextAreaProps } from "./types";
4
+
5
+ export const TextArea = ({
6
+ label,
7
+ placeholder = "Enter your text here...",
8
+ value,
9
+ onChange,
10
+ error,
11
+ helperText,
12
+ rows = 4,
13
+ maxLength,
14
+ required = false,
15
+ disabled = false,
16
+ variant = "default",
17
+ className = "",
18
+ ...props
19
+ }: TextAreaProps) => {
20
+ const [isFocused, setIsFocused] = useState(false);
21
+ const [charCount, setCharCount] = useState(0);
22
+ const textareaRef = useRef<HTMLTextAreaElement>(null);
23
+
24
+ useEffect(() => {
25
+ if (typeof value === "string") {
26
+ setCharCount(value.length);
27
+ }
28
+ }, [value]);
29
+
30
+ const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
31
+ setCharCount(e.target.value.length);
32
+ if (onChange) {
33
+ onChange(e);
34
+ }
35
+ };
36
+
37
+ const isFloating = variant === "minimal" && (isFocused || Boolean(value));
38
+
39
+ const variantClasses = {
40
+ default: {
41
+ textarea:
42
+ "border border-zinc-300 bg-white text-zinc-900 shadow-sm hover:border-zinc-400 focus:border-black focus:ring-black/20 dark:border-zinc-800 dark:bg-zinc-950 dark:text-zinc-100 dark:focus:border-white dark:focus:ring-white/20",
43
+ label: "mb-2 block text-sm font-medium text-zinc-700 dark:text-zinc-300",
44
+ },
45
+ minimal: {
46
+ textarea:
47
+ "border-0 border-b-2 border-zinc-200 bg-transparent px-0 shadow-none focus:border-black dark:border-zinc-800 dark:text-zinc-100 dark:focus:border-white",
48
+ label: twMerge(
49
+ "absolute left-0 pointer-events-none transition-all duration-200",
50
+ isFloating ? "-top-5 text-xs text-black dark:text-white font-semibold" : "top-3 text-sm text-zinc-400"
51
+ ),
52
+ },
53
+ glass: {
54
+ textarea:
55
+ "border border-white/40 bg-white/70 text-zinc-900 shadow-sm backdrop-blur hover:border-white/70 focus:border-black focus:ring-black/20 dark:border-white/10 dark:bg-zinc-950/70 dark:text-zinc-100 dark:focus:border-white dark:focus:ring-white/20",
56
+ label: "mb-2 block text-sm font-medium text-zinc-700 dark:text-zinc-300",
57
+ },
58
+ }[variant];
59
+
60
+ return (
61
+ <div className={twMerge("relative w-full", className)}>
62
+ {label && variant !== "minimal" && (
63
+ <label className={variantClasses.label}>
64
+ {label}
65
+ {required && <span className="ml-1 text-rose-500">*</span>}
66
+ </label>
67
+ )}
68
+
69
+ <div className="relative">
70
+ <textarea
71
+ ref={textareaRef}
72
+ value={value}
73
+ onChange={handleChange}
74
+ onFocus={() => setIsFocused(true)}
75
+ onBlur={() => setIsFocused(false)}
76
+ placeholder={variant === "minimal" ? (isFocused ? placeholder : "") : placeholder}
77
+ rows={rows}
78
+ maxLength={maxLength}
79
+ required={required}
80
+ disabled={disabled}
81
+ className={twMerge(
82
+ "w-full resize-none rounded-lg px-3 py-3 text-sm outline-none transition-all duration-200 focus:ring-2 disabled:cursor-not-allowed disabled:bg-zinc-50 dark:disabled:bg-zinc-900 disabled:opacity-60",
83
+ variantClasses.textarea,
84
+ error ? "border-rose-500 focus:border-rose-500 focus:ring-rose-500/20" : ""
85
+ )}
86
+ {...props}
87
+ />
88
+
89
+ {variant === "minimal" && label && (
90
+ <label
91
+ className={variantClasses.label}
92
+ onClick={() => textareaRef.current?.focus()}
93
+ >
94
+ {label}
95
+ {required && <span className="ml-1 text-rose-500">*</span>}
96
+ </label>
97
+ )}
98
+ </div>
99
+
100
+ <div className="mt-2 flex items-start justify-between gap-3">
101
+ <div className="min-w-0 flex-1">
102
+ {error ? (
103
+ <p className="text-xs font-medium text-rose-600">{error}</p>
104
+ ) : helperText ? (
105
+ <p className="text-xs text-zinc-500">{helperText}</p>
106
+ ) : null}
107
+ </div>
108
+
109
+ {maxLength && (
110
+ <span
111
+ className={twMerge(
112
+ "shrink-0 text-xs text-zinc-400",
113
+ charCount > maxLength * 0.9 ? "text-amber-600" : "",
114
+ charCount === maxLength ? "text-rose-600" : ""
115
+ )}
116
+ >
117
+ {charCount}/{maxLength}
118
+ </span>
119
+ )}
120
+ </div>
121
+ </div>
122
+ );
123
+ };
@@ -0,0 +1,15 @@
1
+ export interface TextAreaProps
2
+ extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
3
+ label?: string;
4
+ placeholder?: string;
5
+ value?: string;
6
+ onChange?: (e: React.ChangeEvent<HTMLTextAreaElement>) => void;
7
+ error?: string;
8
+ helperText?: string;
9
+ rows?: number;
10
+ maxLength?: number;
11
+ required?: boolean;
12
+ disabled?: boolean;
13
+ variant?: "default" | "minimal" | "glass";
14
+ className?: string;
15
+ }