@k3-universe/react-kit 0.0.41 → 0.0.42

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 (701) hide show
  1. package/.babelrc +12 -12
  2. package/.storybook/main.ts +22 -22
  3. package/.storybook/preview.ts +198 -198
  4. package/Dockerfile.storybook +43 -43
  5. package/README.md +9 -9
  6. package/biome.json +10 -10
  7. package/components.json +20 -20
  8. package/dist/index.js +32 -14
  9. package/dist/kit/builder/auth/hooks/core-hooks.d.ts.map +1 -1
  10. package/dist/kit/builder/form/components/fields/AutocompleteField.d.ts.map +1 -1
  11. package/dist/kit/builder/form/components/fields/DatePickerField.d.ts.map +1 -1
  12. package/dist/kit/builder/form/components/fields/DateRangePickerField.d.ts.map +1 -1
  13. package/dist/kit/builder/form/types.d.ts +2 -0
  14. package/dist/kit/builder/form/types.d.ts.map +1 -1
  15. package/dist/kit/components/autocomplete/Autocomplete.d.ts +2 -1
  16. package/dist/kit/components/autocomplete/Autocomplete.d.ts.map +1 -1
  17. package/dist/kit/layouts/admin/hooks/menu.d.ts.map +1 -1
  18. package/dist/kit/themes/clean-slate.css +4 -8
  19. package/dist/kit/themes/default.css +5 -9
  20. package/dist/kit/themes/minimal-modern.css +4 -8
  21. package/dist/kit/themes/spotify.css +4 -8
  22. package/package.json +1 -1
  23. package/src/index.ts +99 -99
  24. package/src/kit/builder/auth/components/Can.tsx +27 -27
  25. package/src/kit/builder/auth/components/RequireAuth.tsx +78 -78
  26. package/src/kit/builder/auth/components/ShowWhenAuthenticated.tsx +10 -10
  27. package/src/kit/builder/auth/components/ShowWhenError.tsx +10 -10
  28. package/src/kit/builder/auth/components/ShowWhenLoading.tsx +10 -10
  29. package/src/kit/builder/auth/components/ShowWhenUnauthenticated.tsx +10 -10
  30. package/src/kit/builder/auth/components/withPermission.tsx +23 -23
  31. package/src/kit/builder/auth/hooks/action-hooks.ts +34 -34
  32. package/src/kit/builder/auth/hooks/core-hooks.ts +65 -65
  33. package/src/kit/builder/auth/hooks/index.ts +4 -4
  34. package/src/kit/builder/auth/hooks/permission-hooks.ts +43 -43
  35. package/src/kit/builder/auth/hooks/token-hooks.ts +25 -25
  36. package/src/kit/builder/auth/index.ts +132 -132
  37. package/src/kit/builder/auth/providers/AuthProvider.tsx +131 -131
  38. package/src/kit/builder/auth/types/adapter-config.ts +44 -44
  39. package/src/kit/builder/auth/types/adapter.ts +132 -132
  40. package/src/kit/builder/auth/types/core.ts +27 -27
  41. package/src/kit/builder/auth/types/index.ts +9 -9
  42. package/src/kit/builder/auth/types/middleware.ts +20 -20
  43. package/src/kit/builder/auth/types/permissions.ts +23 -23
  44. package/src/kit/builder/auth/types/state.ts +16 -16
  45. package/src/kit/builder/auth/types/storage.ts +21 -21
  46. package/src/kit/builder/auth/types/token-manager.ts +9 -9
  47. package/src/kit/builder/auth/types/utils.ts +55 -55
  48. package/src/kit/builder/auth/utils/auth-adapter.ts +437 -437
  49. package/src/kit/builder/auth/utils/client-adapters/apollo-link.ts +30 -30
  50. package/src/kit/builder/auth/utils/client-adapters/axios.ts +61 -61
  51. package/src/kit/builder/auth/utils/client-adapters/fetch.ts +48 -48
  52. package/src/kit/builder/auth/utils/client-adapters/graphql.ts +60 -60
  53. package/src/kit/builder/auth/utils/client-adapters/index.ts +6 -6
  54. package/src/kit/builder/auth/utils/client-adapters/rest.ts +60 -60
  55. package/src/kit/builder/auth/utils/client-adapters/urql-exchange.ts +76 -76
  56. package/src/kit/builder/auth/utils/permission-checker.ts +150 -150
  57. package/src/kit/builder/auth/utils/storage/browser.ts +99 -99
  58. package/src/kit/builder/auth/utils/storage/cookie.ts +116 -116
  59. package/src/kit/builder/auth/utils/storage/encryption.ts +80 -80
  60. package/src/kit/builder/auth/utils/storage/env.ts +2 -2
  61. package/src/kit/builder/auth/utils/storage/factory.ts +37 -37
  62. package/src/kit/builder/auth/utils/storage/index.ts +6 -6
  63. package/src/kit/builder/auth/utils/storage/memory.ts +15 -15
  64. package/src/kit/builder/auth/utils/token-manager.ts +55 -55
  65. package/src/kit/builder/data-table/components/DataTable.tsx +547 -547
  66. package/src/kit/builder/data-table/components/DataTableColumnHeader.tsx +67 -67
  67. package/src/kit/builder/data-table/components/DataTablePagination.tsx +112 -112
  68. package/src/kit/builder/data-table/components/DataTableViewOptions.tsx +51 -51
  69. package/src/kit/builder/data-table/index.ts +6 -6
  70. package/src/kit/builder/data-table/types.ts +44 -44
  71. package/src/kit/builder/data-table/utils/dotAccessor.ts +6 -6
  72. package/src/kit/builder/dialog/index.ts +6 -6
  73. package/src/kit/builder/dialog/provider.tsx +170 -170
  74. package/src/kit/builder/form/components/FormBuilder.tsx +295 -295
  75. package/src/kit/builder/form/components/FormBuilderActions.tsx +78 -78
  76. package/src/kit/builder/form/components/FormBuilderContext.tsx +52 -52
  77. package/src/kit/builder/form/components/FormBuilderField.tsx +456 -456
  78. package/src/kit/builder/form/components/fields/ArrayField.tsx +311 -311
  79. package/src/kit/builder/form/components/fields/AutocompleteField.tsx +89 -88
  80. package/src/kit/builder/form/components/fields/CheckboxField.tsx +65 -65
  81. package/src/kit/builder/form/components/fields/DateField.tsx +26 -26
  82. package/src/kit/builder/form/components/fields/DatePickerField.tsx +31 -29
  83. package/src/kit/builder/form/components/fields/DateRangePickerField.tsx +55 -46
  84. package/src/kit/builder/form/components/fields/DateTimePickerField.tsx +38 -38
  85. package/src/kit/builder/form/components/fields/DateTimeRangePickerField.tsx +48 -48
  86. package/src/kit/builder/form/components/fields/FileField.tsx +31 -31
  87. package/src/kit/builder/form/components/fields/MonthPickerField.tsx +33 -33
  88. package/src/kit/builder/form/components/fields/MonthRangePickerField.tsx +41 -41
  89. package/src/kit/builder/form/components/fields/NumberField.tsx +20 -20
  90. package/src/kit/builder/form/components/fields/ObjectField.tsx +35 -35
  91. package/src/kit/builder/form/components/fields/RadioField.tsx +47 -47
  92. package/src/kit/builder/form/components/fields/SelectField.tsx +46 -46
  93. package/src/kit/builder/form/components/fields/SwitchField.tsx +65 -65
  94. package/src/kit/builder/form/components/fields/TextField.tsx +25 -25
  95. package/src/kit/builder/form/components/fields/TextareaField.tsx +20 -20
  96. package/src/kit/builder/form/components/fields/TimePickerField.tsx +35 -35
  97. package/src/kit/builder/form/components/fields/TimeRangePickerField.tsx +43 -43
  98. package/src/kit/builder/form/components/fields/index.ts +21 -21
  99. package/src/kit/builder/form/components/fields/types.ts +18 -18
  100. package/src/kit/builder/form/components/index.ts +3 -3
  101. package/src/kit/builder/form/components/sectionNodes.tsx +147 -147
  102. package/src/kit/builder/form/hooks/useFormBuilder.ts +451 -451
  103. package/src/kit/builder/form/index.ts +4 -4
  104. package/src/kit/builder/form/types.ts +245 -243
  105. package/src/kit/builder/form/utils/common-forms.ts +68 -68
  106. package/src/kit/builder/form/utils/dependencies.ts +56 -56
  107. package/src/kit/builder/form/utils/field-factories.ts +177 -177
  108. package/src/kit/builder/form/utils/index.ts +17 -17
  109. package/src/kit/builder/form/utils/section-factories.ts +38 -38
  110. package/src/kit/builder/form/utils/transformers.ts +100 -100
  111. package/src/kit/builder/form/utils/validations.ts +22 -22
  112. package/src/kit/builder/form/utils/validators.ts +20 -20
  113. package/src/kit/builder/page/Page.tsx +202 -202
  114. package/src/kit/builder/page/index.ts +1 -1
  115. package/src/kit/builder/section/SectionBuilder.tsx +435 -435
  116. package/src/kit/builder/section/SectionContainer.tsx +85 -85
  117. package/src/kit/builder/section/index.ts +2 -2
  118. package/src/kit/builder/section/types.ts +80 -80
  119. package/src/kit/builder/stack-dialog/context.ts +15 -15
  120. package/src/kit/builder/stack-dialog/hooks.ts +13 -13
  121. package/src/kit/builder/stack-dialog/index.ts +12 -12
  122. package/src/kit/builder/stack-dialog/provider.tsx +51 -51
  123. package/src/kit/builder/stack-dialog/renderer.tsx +36 -36
  124. package/src/kit/builder/stack-dialog/types.ts +34 -34
  125. package/src/kit/components/autocomplete/Autocomplete.tsx +671 -664
  126. package/src/kit/components/autocomplete/index.ts +3 -3
  127. package/src/kit/components/autocomplete/types.ts +27 -27
  128. package/src/kit/components/datepicker/DatePicker.tsx +173 -173
  129. package/src/kit/components/datepicker/DateRangePicker.tsx +526 -526
  130. package/src/kit/components/datepicker/index.ts +2 -2
  131. package/src/kit/components/datetimepicker/DateTimePicker.tsx +420 -420
  132. package/src/kit/components/datetimepicker/DateTimeRangePicker.tsx +676 -676
  133. package/src/kit/components/datetimepicker/index.ts +2 -2
  134. package/src/kit/components/fileuploader/FileUploader.tsx +626 -626
  135. package/src/kit/components/fileuploader/index.ts +3 -3
  136. package/src/kit/components/fileuploader/types.ts +76 -76
  137. package/src/kit/components/forminfo/FormInfoError.tsx +135 -135
  138. package/src/kit/components/forminfo/index.ts +1 -1
  139. package/src/kit/components/keyboard/Keyboard.tsx +916 -916
  140. package/src/kit/components/keyboard/index.ts +4 -4
  141. package/src/kit/components/login/Login.tsx +141 -141
  142. package/src/kit/components/login/index.ts +1 -1
  143. package/src/kit/components/monthpicker/MonthInput.tsx +131 -131
  144. package/src/kit/components/monthpicker/MonthPicker.tsx +224 -224
  145. package/src/kit/components/monthpicker/MonthRangeInput.tsx +153 -153
  146. package/src/kit/components/monthpicker/MonthRangePicker.tsx +409 -409
  147. package/src/kit/components/numpad/Numpad.tsx +377 -377
  148. package/src/kit/components/numpad/index.ts +4 -4
  149. package/src/kit/components/timepicker/TimePicker.tsx +319 -319
  150. package/src/kit/components/timepicker/TimeRangePicker.tsx +368 -368
  151. package/src/kit/components/timepicker/index.ts +2 -2
  152. package/src/kit/layouts/admin/components/AdminLayout.tsx +286 -286
  153. package/src/kit/layouts/admin/components/ThemeToggle.tsx +54 -54
  154. package/src/kit/layouts/admin/hooks/menu.ts +32 -32
  155. package/src/kit/layouts/admin/providers/AdminMenuProvider.tsx +78 -78
  156. package/src/kit/layouts/admin/types/index.ts +26 -26
  157. package/src/kit/providers/ThemeProvider.tsx +90 -90
  158. package/src/kit/themes/base.css +11 -11
  159. package/src/kit/themes/clean-slate.css +155 -155
  160. package/src/kit/themes/default.css +192 -192
  161. package/src/kit/themes/minimal-modern.css +155 -155
  162. package/src/kit/themes/spotify.css +164 -164
  163. package/src/shadcn/hooks/use-mobile.ts +21 -21
  164. package/src/shadcn/lib/utils.ts +6 -6
  165. package/src/shadcn/ui/accordion.tsx +66 -66
  166. package/src/shadcn/ui/alert-dialog.tsx +157 -157
  167. package/src/shadcn/ui/alert.tsx +66 -66
  168. package/src/shadcn/ui/aspect-ratio.tsx +11 -11
  169. package/src/shadcn/ui/avatar.tsx +53 -53
  170. package/src/shadcn/ui/badge.tsx +46 -46
  171. package/src/shadcn/ui/breadcrumb.tsx +108 -108
  172. package/src/shadcn/ui/button.tsx +59 -59
  173. package/src/shadcn/ui/calendar.tsx +217 -217
  174. package/src/shadcn/ui/card.tsx +92 -92
  175. package/src/shadcn/ui/carousel.tsx +240 -240
  176. package/src/shadcn/ui/chart.tsx +353 -353
  177. package/src/shadcn/ui/checkbox.tsx +32 -32
  178. package/src/shadcn/ui/collapsible.tsx +33 -33
  179. package/src/shadcn/ui/command.tsx +184 -184
  180. package/src/shadcn/ui/context-menu.tsx +252 -252
  181. package/src/shadcn/ui/dialog.tsx +143 -143
  182. package/src/shadcn/ui/drawer.tsx +135 -135
  183. package/src/shadcn/ui/dropdown-menu.tsx +257 -257
  184. package/src/shadcn/ui/form.tsx +168 -168
  185. package/src/shadcn/ui/hover-card.tsx +44 -44
  186. package/src/shadcn/ui/input-otp.tsx +77 -77
  187. package/src/shadcn/ui/input.tsx +21 -21
  188. package/src/shadcn/ui/label.tsx +24 -24
  189. package/src/shadcn/ui/menubar.tsx +276 -276
  190. package/src/shadcn/ui/navigation-menu.tsx +168 -168
  191. package/src/shadcn/ui/pagination.tsx +127 -127
  192. package/src/shadcn/ui/popover.tsx +48 -48
  193. package/src/shadcn/ui/progress.tsx +31 -31
  194. package/src/shadcn/ui/radio-group.tsx +45 -45
  195. package/src/shadcn/ui/resizable.tsx +56 -56
  196. package/src/shadcn/ui/scroll-area.tsx +58 -58
  197. package/src/shadcn/ui/select.tsx +185 -185
  198. package/src/shadcn/ui/separator.tsx +28 -28
  199. package/src/shadcn/ui/sheet.tsx +139 -139
  200. package/src/shadcn/ui/sidebar.tsx +726 -726
  201. package/src/shadcn/ui/skeleton.tsx +13 -13
  202. package/src/shadcn/ui/slider.tsx +63 -63
  203. package/src/shadcn/ui/sonner.tsx +25 -25
  204. package/src/shadcn/ui/switch.tsx +31 -31
  205. package/src/shadcn/ui/table.tsx +116 -116
  206. package/src/shadcn/ui/tabs.tsx +66 -66
  207. package/src/shadcn/ui/textarea.tsx +18 -18
  208. package/src/shadcn/ui/toggle-group.tsx +73 -73
  209. package/src/shadcn/ui/toggle.tsx +47 -47
  210. package/src/shadcn/ui/tooltip.tsx +61 -61
  211. package/src/stories/FileUploader.stories.tsx +185 -185
  212. package/src/stories/kit/builder/DataTable.Basic.stories.tsx +71 -71
  213. package/src/stories/kit/builder/DataTable.Filters.stories.tsx +98 -98
  214. package/src/stories/kit/builder/DataTable.Pagination.stories.tsx +73 -73
  215. package/src/stories/kit/builder/DataTable.SelectionAndActions.stories.tsx +77 -77
  216. package/src/stories/kit/builder/DataTable.Sorting.stories.tsx +67 -67
  217. package/src/stories/kit/builder/Dialog.stories.tsx +90 -90
  218. package/src/stories/kit/builder/Form.ArrayLayouts.stories.tsx +177 -177
  219. package/src/stories/kit/builder/Form.Autocomplete.stories.tsx +220 -220
  220. package/src/stories/kit/builder/Form.Basic.stories.tsx +79 -79
  221. package/src/stories/kit/builder/Form.Complex.stories.tsx +569 -569
  222. package/src/stories/kit/builder/Form.DateTime.stories.tsx +70 -70
  223. package/src/stories/kit/builder/Form.Dynamic.stories.tsx +926 -926
  224. package/src/stories/kit/builder/Form.Files.stories.tsx +136 -136
  225. package/src/stories/kit/builder/Form.MultipleFormBuilder.stories.tsx +377 -377
  226. package/src/stories/kit/builder/Form.Pickers.stories.tsx +75 -75
  227. package/src/stories/kit/builder/Form.Simple.stories.tsx +91 -91
  228. package/src/stories/kit/builder/Form.Time.stories.tsx +68 -68
  229. package/src/stories/kit/builder/Page.stories.tsx +115 -115
  230. package/src/stories/kit/builder/Section.stories.tsx +282 -282
  231. package/src/stories/kit/components/Autocomplete.stories.tsx +313 -313
  232. package/src/stories/kit/components/DatePicker.stories.tsx +195 -195
  233. package/src/stories/kit/components/DateRangePicker.stories.tsx +195 -195
  234. package/src/stories/kit/components/Keyboard.stories.tsx +263 -263
  235. package/src/stories/kit/components/Login.stories.tsx +167 -167
  236. package/src/stories/kit/components/MonthPicker.stories.tsx +100 -100
  237. package/src/stories/kit/components/MonthRangePicker.stories.tsx +117 -117
  238. package/src/stories/kit/components/Numpad.stories.tsx +195 -195
  239. package/src/stories/kit/components/TimePicker.stories.tsx +71 -71
  240. package/src/stories/kit/components/TimeRangePicker.stories.tsx +43 -43
  241. package/src/stories/kit/layouts/admin/AdminLayout.Basic.stories.tsx +118 -118
  242. package/src/stories/kit/layouts/admin/AdminLayout.Collapsible.stories.tsx +81 -81
  243. package/src/stories/kit/layouts/admin/AdminLayout.Complex.stories.tsx +251 -251
  244. package/src/stories/kit/layouts/admin/AdminLayout.CustomSidebarHeaderComponent.stories.tsx +80 -80
  245. package/src/stories/kit/layouts/admin/AdminLayout.CustomSidebarTitleAndIcon.stories.tsx +70 -70
  246. package/src/stories/kit/layouts/admin/AdminLayout.HeaderSlots.stories.tsx +87 -87
  247. package/src/stories/shadcn/ui/Accordion.stories.tsx +117 -117
  248. package/src/stories/shadcn/ui/Alert.stories.tsx +36 -36
  249. package/src/stories/shadcn/ui/AlertDialog.stories.tsx +73 -73
  250. package/src/stories/shadcn/ui/AspectRatio.stories.tsx +58 -58
  251. package/src/stories/shadcn/ui/Avatar.stories.tsx +26 -26
  252. package/src/stories/shadcn/ui/Badge.stories.tsx +28 -28
  253. package/src/stories/shadcn/ui/Breadcrumb.stories.tsx +47 -47
  254. package/src/stories/shadcn/ui/Button.stories.tsx +51 -51
  255. package/src/stories/shadcn/ui/Calendar.stories.tsx +33 -33
  256. package/src/stories/shadcn/ui/Card.stories.tsx +39 -39
  257. package/src/stories/shadcn/ui/Carousel.stories.tsx +37 -37
  258. package/src/stories/shadcn/ui/Chart.stories.tsx +72 -72
  259. package/src/stories/shadcn/ui/Checkbox.stories.tsx +64 -64
  260. package/src/stories/shadcn/ui/Collapsible.stories.tsx +40 -40
  261. package/src/stories/shadcn/ui/Command.stories.tsx +53 -53
  262. package/src/stories/shadcn/ui/ContextMenu.stories.tsx +67 -67
  263. package/src/stories/shadcn/ui/Dialog.stories.tsx +45 -45
  264. package/src/stories/shadcn/ui/Drawer.stories.tsx +49 -49
  265. package/src/stories/shadcn/ui/DropdownMenu.stories.tsx +75 -75
  266. package/src/stories/shadcn/ui/Form.stories.tsx +93 -93
  267. package/src/stories/shadcn/ui/HoverCard.stories.tsx +43 -43
  268. package/src/stories/shadcn/ui/Input.stories.tsx +41 -41
  269. package/src/stories/shadcn/ui/InputOtp.stories.tsx +39 -39
  270. package/src/stories/shadcn/ui/Label.stories.tsx +29 -29
  271. package/src/stories/shadcn/ui/Menubar.stories.tsx +87 -87
  272. package/src/stories/shadcn/ui/NavigationMenu.stories.tsx +78 -78
  273. package/src/stories/shadcn/ui/Pagination.stories.tsx +51 -51
  274. package/src/stories/shadcn/ui/Popover.stories.tsx +53 -53
  275. package/src/stories/shadcn/ui/Progress.stories.tsx +30 -30
  276. package/src/stories/shadcn/ui/RadioGroup.stories.tsx +31 -31
  277. package/src/stories/shadcn/ui/Resizable.stories.tsx +55 -55
  278. package/src/stories/shadcn/ui/ScrollArea.stories.tsx +84 -84
  279. package/src/stories/shadcn/ui/Select.stories.tsx +61 -61
  280. package/src/stories/shadcn/ui/Separator.stories.tsx +35 -35
  281. package/src/stories/shadcn/ui/Sheet.stories.tsx +48 -48
  282. package/src/stories/shadcn/ui/Sidebar.stories.tsx +131 -131
  283. package/src/stories/shadcn/ui/Skeleton.stories.tsx +23 -23
  284. package/src/stories/shadcn/ui/Slider.stories.tsx +21 -21
  285. package/src/stories/shadcn/ui/Sonner.stories.tsx +49 -49
  286. package/src/stories/shadcn/ui/Switch.stories.tsx +28 -28
  287. package/src/stories/shadcn/ui/Table.stories.tsx +374 -374
  288. package/src/stories/shadcn/ui/Tabs.stories.tsx +31 -31
  289. package/src/stories/shadcn/ui/Textarea.stories.tsx +42 -42
  290. package/src/stories/shadcn/ui/Toggle.stories.tsx +44 -44
  291. package/src/stories/shadcn/ui/ToggleGroup.stories.tsx +28 -28
  292. package/src/stories/shadcn/ui/Tooltip.stories.tsx +30 -30
  293. package/tsconfig.json +20 -20
  294. package/tsconfig.lib.json +52 -52
  295. package/tsconfig.spec.json +38 -38
  296. package/vite.config.ts +93 -93
  297. package/storybook-static/assets/Accordion.stories-KU4JBR8U.js +0 -52
  298. package/storybook-static/assets/AdminLayout-CPvVCwfY.js +0 -53
  299. package/storybook-static/assets/AdminLayout.Basic.stories-DkP2UVXe.js +0 -4
  300. package/storybook-static/assets/AdminLayout.Collapsible.stories-BuuVjtpW.js +0 -4
  301. package/storybook-static/assets/AdminLayout.Complex.stories-D-k4H0hJ.js +0 -29
  302. package/storybook-static/assets/AdminLayout.CustomSidebarHeaderComponent.stories-B_0IEDd4.js +0 -9
  303. package/storybook-static/assets/AdminLayout.CustomSidebarTitleAndIcon.stories-CvAeXUyA.js +0 -4
  304. package/storybook-static/assets/AdminLayout.HeaderSlots.stories-RBFHoSZK.js +0 -7
  305. package/storybook-static/assets/Alert.stories-DKxKtIc0.js +0 -27
  306. package/storybook-static/assets/AlertDialog.stories-BqTpZ_nG.js +0 -43
  307. package/storybook-static/assets/AspectRatio.stories-DPO9QQ5F.js +0 -22
  308. package/storybook-static/assets/Autocomplete-Cpg4CaJe.js +0 -56
  309. package/storybook-static/assets/Autocomplete.stories-CWj4G5fh.js +0 -56
  310. package/storybook-static/assets/Avatar.stories-DPhov_2g.js +0 -12
  311. package/storybook-static/assets/Badge.stories-DFKrRdXq.js +0 -12
  312. package/storybook-static/assets/Breadcrumb.stories-CTE6CZUC.js +0 -25
  313. package/storybook-static/assets/Button.stories-cbt2InL-.js +0 -26
  314. package/storybook-static/assets/Calendar.stories-DRhTw_43.js +0 -3
  315. package/storybook-static/assets/Card.stories-Isf6n_K3.js +0 -15
  316. package/storybook-static/assets/Carousel.stories-Cmg0I3fR.js +0 -15
  317. package/storybook-static/assets/Chart.stories-aQ-fNijT.js +0 -126
  318. package/storybook-static/assets/Checkbox.stories-B7YMXPDc.js +0 -12
  319. package/storybook-static/assets/Collapsible.stories-BUzl17ZZ.js +0 -18
  320. package/storybook-static/assets/Combination-BdQWAuko.js +0 -41
  321. package/storybook-static/assets/Command.stories-DzBlWQs0.js +0 -30
  322. package/storybook-static/assets/ContextMenu.stories-CJlBQyXc.js +0 -31
  323. package/storybook-static/assets/DataTable.Basic.stories-BWYKFDmK.js +0 -6
  324. package/storybook-static/assets/DataTable.Filters.stories-uZdtJk8t.js +0 -21
  325. package/storybook-static/assets/DataTable.Pagination.stories-C5N1khkp.js +0 -24
  326. package/storybook-static/assets/DataTable.SelectionAndActions.stories-FhCqZKvO.js +0 -26
  327. package/storybook-static/assets/DataTable.Sorting.stories-D-k7EtRj.js +0 -6
  328. package/storybook-static/assets/Dialog.stories-C62AF-Gx.js +0 -54
  329. package/storybook-static/assets/Dialog.stories-lrjRwOus.js +0 -18
  330. package/storybook-static/assets/Drawer.stories-CGjkdJeV.js +0 -24
  331. package/storybook-static/assets/DropdownMenu.stories-DkGClRAA.js +0 -35
  332. package/storybook-static/assets/Form.ArrayLayouts.stories-C5d_062d.js +0 -130
  333. package/storybook-static/assets/Form.Autocomplete.stories-CPZPkk4o.js +0 -142
  334. package/storybook-static/assets/Form.Basic.stories-Bhcu3-3n.js +0 -58
  335. package/storybook-static/assets/Form.Complex.stories-QnXh5a7Q.js +0 -361
  336. package/storybook-static/assets/Form.Dynamic.stories-DFW6wIuT.js +0 -502
  337. package/storybook-static/assets/Form.Simple.stories-BhJcyhbE.js +0 -53
  338. package/storybook-static/assets/Form.stories-PFNsMYxO.js +0 -3
  339. package/storybook-static/assets/FormBuilder-BQBBxo_k.js +0 -5
  340. package/storybook-static/assets/HoverCard.stories-CAlQEVn8.js +0 -21
  341. package/storybook-static/assets/Input.stories-CEhODt0V.js +0 -16
  342. package/storybook-static/assets/InputOtp.stories-DSvNP4dS.js +0 -42
  343. package/storybook-static/assets/Label.stories-B3pa8ZLY.js +0 -14
  344. package/storybook-static/assets/Login.stories-C7KQkmR_.js +0 -37
  345. package/storybook-static/assets/Menubar.stories-CHXhSHxc.js +0 -44
  346. package/storybook-static/assets/MonthPicker.stories-BnrOc4fm.js +0 -99
  347. package/storybook-static/assets/MonthRangePicker.stories-55Gk1t-7.js +0 -134
  348. package/storybook-static/assets/NavigationMenu.stories-CXoS080P.js +0 -30
  349. package/storybook-static/assets/Page.stories-GdSJgZ6-.js +0 -91
  350. package/storybook-static/assets/Pagination.stories-BEBwqH4N.js +0 -29
  351. package/storybook-static/assets/Popover.stories-BICy98Cw.js +0 -15
  352. package/storybook-static/assets/Progress.stories-DECHNOME.js +0 -8
  353. package/storybook-static/assets/RadioGroup.stories-DA7-uKfV.js +0 -16
  354. package/storybook-static/assets/Resizable.stories-B99kWkH7.js +0 -25
  355. package/storybook-static/assets/ScrollArea.stories-BqvUAXqU.js +0 -12
  356. package/storybook-static/assets/Section.stories-lFMlFBQn.js +0 -277
  357. package/storybook-static/assets/SectionBuilder-BQW705x0.js +0 -1
  358. package/storybook-static/assets/Select.stories-BsKyZ6Io.js +0 -17
  359. package/storybook-static/assets/Separator.stories-BTDOaOM2.js +0 -17
  360. package/storybook-static/assets/Sheet.stories-Cam1gR6G.js +0 -24
  361. package/storybook-static/assets/Sidebar.stories-DnOa6G7y.js +0 -106
  362. package/storybook-static/assets/Skeleton.stories-BQNIuIe5.js +0 -9
  363. package/storybook-static/assets/Slider.stories-Bslq7hjq.js +0 -6
  364. package/storybook-static/assets/Sonner.stories-D34pBBtI.js +0 -18
  365. package/storybook-static/assets/Switch.stories-Puyb1-Bx.js +0 -3
  366. package/storybook-static/assets/Table.stories-ClZxAhut.js +0 -35
  367. package/storybook-static/assets/Tabs.stories-CURNTETB.js +0 -10
  368. package/storybook-static/assets/Textarea.stories-Cf1ZBrWw.js +0 -17
  369. package/storybook-static/assets/Toggle.stories-CdMHY_bi.js +0 -3
  370. package/storybook-static/assets/ToggleGroup.stories-BM68m1dX.js +0 -13
  371. package/storybook-static/assets/Tooltip.stories-DiQv64dM.js +0 -10
  372. package/storybook-static/assets/accordion-DVgwQcnw.js +0 -1
  373. package/storybook-static/assets/alert-dialog-DCUEwpqm.js +0 -7
  374. package/storybook-static/assets/avatar-BzwOE-mi.js +0 -1
  375. package/storybook-static/assets/axe-HmUsR1st.js +0 -30
  376. package/storybook-static/assets/badge-BnQWua6u.js +0 -1
  377. package/storybook-static/assets/button-0oMkiryo.js +0 -1
  378. package/storybook-static/assets/card-BJpPOzP8.js +0 -1
  379. package/storybook-static/assets/chart-column-DZGb4ZZS.js +0 -6
  380. package/storybook-static/assets/check-B9hBGj6o.js +0 -6
  381. package/storybook-static/assets/checkbox-CyIeaWHX.js +0 -1
  382. package/storybook-static/assets/chevron-down-D_37S6il.js +0 -6
  383. package/storybook-static/assets/chevron-left-BBoN0vbI.js +0 -6
  384. package/storybook-static/assets/chevron-right-B5vIMLxK.js +0 -6
  385. package/storybook-static/assets/circle-C5Lzx6Nx.js +0 -6
  386. package/storybook-static/assets/clean-slate-D1HmMFJM.css +0 -1
  387. package/storybook-static/assets/command-Csa9p8_a.js +0 -6
  388. package/storybook-static/assets/createLucideIcon-BrHXro7t.js +0 -21
  389. package/storybook-static/assets/default-CN_Fo1GY.css +0 -1
  390. package/storybook-static/assets/dependencies-ctrV69dx.js +0 -1
  391. package/storybook-static/assets/dialog-CsnqITTn.js +0 -1
  392. package/storybook-static/assets/dropdown-menu-BWxxwPHL.js +0 -1
  393. package/storybook-static/assets/ellipsis-BRS038RR.js +0 -6
  394. package/storybook-static/assets/grip-vertical-BxXG8KNA.js +0 -6
  395. package/storybook-static/assets/iframe-C9bogcIc.css +0 -1
  396. package/storybook-static/assets/iframe-v7iAhKit.js +0 -1555
  397. package/storybook-static/assets/index-0-qMRXou.js +0 -1
  398. package/storybook-static/assets/index-AvwFFKJc.js +0 -1
  399. package/storybook-static/assets/index-BVDb4dFc.js +0 -1
  400. package/storybook-static/assets/index-B_qx7A5T.js +0 -1
  401. package/storybook-static/assets/index-BdQq_4o_.js +0 -1
  402. package/storybook-static/assets/index-BfiCOk42.js +0 -1
  403. package/storybook-static/assets/index-Bv9yk470.js +0 -1
  404. package/storybook-static/assets/index-Bw1A27Kp.js +0 -1
  405. package/storybook-static/assets/index-ByqivBWx.js +0 -1
  406. package/storybook-static/assets/index-C9Ta0ZTH.js +0 -1
  407. package/storybook-static/assets/index-CDY5kTx5.js +0 -1
  408. package/storybook-static/assets/index-CGnyVRgB.js +0 -1
  409. package/storybook-static/assets/index-CGrAONsN.js +0 -1
  410. package/storybook-static/assets/index-CWjrGFAQ.js +0 -1
  411. package/storybook-static/assets/index-CwBdPBFz.js +0 -9
  412. package/storybook-static/assets/index-D8RXF03I.js +0 -1
  413. package/storybook-static/assets/index-DLIxT4Z7.js +0 -1
  414. package/storybook-static/assets/index-DW48STyt.js +0 -1
  415. package/storybook-static/assets/index-DbaA6-o1.js +0 -1
  416. package/storybook-static/assets/index-Dph_5COR.js +0 -1
  417. package/storybook-static/assets/index-DrN5n71E.js +0 -1
  418. package/storybook-static/assets/index-Tp9IdbR8.js +0 -1
  419. package/storybook-static/assets/index-WyF3-wTE.js +0 -9
  420. package/storybook-static/assets/index-XSmPROEP.js +0 -1
  421. package/storybook-static/assets/index-Z6wF44KX.js +0 -5
  422. package/storybook-static/assets/index-_RPqOjlQ.js +0 -1
  423. package/storybook-static/assets/index-jrimW4QO.js +0 -1
  424. package/storybook-static/assets/index-nqc17SX4.js +0 -1
  425. package/storybook-static/assets/input-11YRd9gD.js +0 -1
  426. package/storybook-static/assets/jsx-runtime-D_zvdyIk.js +0 -9
  427. package/storybook-static/assets/label-Do8ODIVk.js +0 -1
  428. package/storybook-static/assets/lodash-DDwpuhPG.js +0 -73
  429. package/storybook-static/assets/matchers-7Z3WT2CE-T3xScrR7.js +0 -14
  430. package/storybook-static/assets/minimal-modern-BlYVzfQU.css +0 -1
  431. package/storybook-static/assets/popover-CcciSWAw.js +0 -1
  432. package/storybook-static/assets/preload-helper-Dp1pzeXC.js +0 -1
  433. package/storybook-static/assets/radio-group-DiJ0Y_KQ.js +0 -1
  434. package/storybook-static/assets/react-18-Cr9fq_Ip.js +0 -25
  435. package/storybook-static/assets/react-icons.esm-B_ULMmNU.js +0 -1
  436. package/storybook-static/assets/refresh-cw-BmRDhIV_.js +0 -6
  437. package/storybook-static/assets/schemas-CGNYCiJ6.js +0 -18
  438. package/storybook-static/assets/section-factories-DCCY9R35.js +0 -1
  439. package/storybook-static/assets/select-DDrkxaOg.js +0 -6
  440. package/storybook-static/assets/separator-o5SAUnaJ.js +0 -1
  441. package/storybook-static/assets/settings-2-xWGvvbG6.js +0 -6
  442. package/storybook-static/assets/sheet-C7jhU3XE.js +0 -1
  443. package/storybook-static/assets/shopping-cart-BFlrufvo.js +0 -11
  444. package/storybook-static/assets/sidebar-C8hU1Mxy.js +0 -6
  445. package/storybook-static/assets/skeleton-CjDnQs43.js +0 -1
  446. package/storybook-static/assets/spotify-CUDj7g8m.css +0 -1
  447. package/storybook-static/assets/switch-CKGRuk3u.js +0 -1
  448. package/storybook-static/assets/table-CP3vMqFn.js +0 -1
  449. package/storybook-static/assets/tabs-CopK2m3j.js +0 -1
  450. package/storybook-static/assets/textarea-Dw2vruMl.js +0 -1
  451. package/storybook-static/assets/toggle-DmHbWetf.js +0 -16
  452. package/storybook-static/assets/tooltip-_LqYEYFw.js +0 -1
  453. package/storybook-static/assets/trash-2-xdbApPby.js +0 -11
  454. package/storybook-static/assets/utils-D-KgF5mV.js +0 -1
  455. package/storybook-static/assets/x-B1a4fyWM.js +0 -6
  456. package/storybook-static/favicon-wrapper.svg +0 -46
  457. package/storybook-static/favicon.svg +0 -1
  458. package/storybook-static/iframe.html +0 -687
  459. package/storybook-static/index.d.ts +0 -64
  460. package/storybook-static/index.d.ts.map +0 -1
  461. package/storybook-static/index.html +0 -166
  462. package/storybook-static/index.json +0 -1
  463. package/storybook-static/kit/builder/data-table/components/DataTable.d.ts +0 -37
  464. package/storybook-static/kit/builder/data-table/components/DataTable.d.ts.map +0 -1
  465. package/storybook-static/kit/builder/data-table/components/DataTableColumnHeader.d.ts +0 -8
  466. package/storybook-static/kit/builder/data-table/components/DataTableColumnHeader.d.ts.map +0 -1
  467. package/storybook-static/kit/builder/data-table/components/DataTablePagination.d.ts +0 -6
  468. package/storybook-static/kit/builder/data-table/components/DataTablePagination.d.ts.map +0 -1
  469. package/storybook-static/kit/builder/data-table/components/DataTableViewOptions.d.ts +0 -5
  470. package/storybook-static/kit/builder/data-table/components/DataTableViewOptions.d.ts.map +0 -1
  471. package/storybook-static/kit/builder/data-table/index.d.ts +0 -7
  472. package/storybook-static/kit/builder/data-table/index.d.ts.map +0 -1
  473. package/storybook-static/kit/builder/data-table/types.d.ts +0 -27
  474. package/storybook-static/kit/builder/data-table/types.d.ts.map +0 -1
  475. package/storybook-static/kit/builder/data-table/utils/dotAccessor.d.ts +0 -2
  476. package/storybook-static/kit/builder/data-table/utils/dotAccessor.d.ts.map +0 -1
  477. package/storybook-static/kit/builder/dialog/index.d.ts +0 -3
  478. package/storybook-static/kit/builder/dialog/index.d.ts.map +0 -1
  479. package/storybook-static/kit/builder/dialog/provider.d.ts +0 -26
  480. package/storybook-static/kit/builder/dialog/provider.d.ts.map +0 -1
  481. package/storybook-static/kit/builder/form/components/FormBuilder.d.ts +0 -137
  482. package/storybook-static/kit/builder/form/components/FormBuilder.d.ts.map +0 -1
  483. package/storybook-static/kit/builder/form/components/FormBuilderActions.d.ts +0 -20
  484. package/storybook-static/kit/builder/form/components/FormBuilderActions.d.ts.map +0 -1
  485. package/storybook-static/kit/builder/form/components/FormBuilderField.d.ts +0 -12
  486. package/storybook-static/kit/builder/form/components/FormBuilderField.d.ts.map +0 -1
  487. package/storybook-static/kit/builder/form/components/fields/ArrayField.d.ts +0 -3
  488. package/storybook-static/kit/builder/form/components/fields/ArrayField.d.ts.map +0 -1
  489. package/storybook-static/kit/builder/form/components/fields/AutocompleteField.d.ts +0 -3
  490. package/storybook-static/kit/builder/form/components/fields/AutocompleteField.d.ts.map +0 -1
  491. package/storybook-static/kit/builder/form/components/fields/CheckboxField.d.ts +0 -3
  492. package/storybook-static/kit/builder/form/components/fields/CheckboxField.d.ts.map +0 -1
  493. package/storybook-static/kit/builder/form/components/fields/DateField.d.ts +0 -3
  494. package/storybook-static/kit/builder/form/components/fields/DateField.d.ts.map +0 -1
  495. package/storybook-static/kit/builder/form/components/fields/FileField.d.ts +0 -3
  496. package/storybook-static/kit/builder/form/components/fields/FileField.d.ts.map +0 -1
  497. package/storybook-static/kit/builder/form/components/fields/NumberField.d.ts +0 -3
  498. package/storybook-static/kit/builder/form/components/fields/NumberField.d.ts.map +0 -1
  499. package/storybook-static/kit/builder/form/components/fields/ObjectField.d.ts +0 -3
  500. package/storybook-static/kit/builder/form/components/fields/ObjectField.d.ts.map +0 -1
  501. package/storybook-static/kit/builder/form/components/fields/RadioField.d.ts +0 -3
  502. package/storybook-static/kit/builder/form/components/fields/RadioField.d.ts.map +0 -1
  503. package/storybook-static/kit/builder/form/components/fields/SelectField.d.ts +0 -3
  504. package/storybook-static/kit/builder/form/components/fields/SelectField.d.ts.map +0 -1
  505. package/storybook-static/kit/builder/form/components/fields/SwitchField.d.ts +0 -3
  506. package/storybook-static/kit/builder/form/components/fields/SwitchField.d.ts.map +0 -1
  507. package/storybook-static/kit/builder/form/components/fields/TextField.d.ts +0 -3
  508. package/storybook-static/kit/builder/form/components/fields/TextField.d.ts.map +0 -1
  509. package/storybook-static/kit/builder/form/components/fields/TextareaField.d.ts +0 -3
  510. package/storybook-static/kit/builder/form/components/fields/TextareaField.d.ts.map +0 -1
  511. package/storybook-static/kit/builder/form/components/fields/index.d.ts +0 -14
  512. package/storybook-static/kit/builder/form/components/fields/index.d.ts.map +0 -1
  513. package/storybook-static/kit/builder/form/components/fields/types.d.ts +0 -14
  514. package/storybook-static/kit/builder/form/components/fields/types.d.ts.map +0 -1
  515. package/storybook-static/kit/builder/form/components/index.d.ts +0 -4
  516. package/storybook-static/kit/builder/form/components/index.d.ts.map +0 -1
  517. package/storybook-static/kit/builder/form/index.d.ts +0 -3
  518. package/storybook-static/kit/builder/form/index.d.ts.map +0 -1
  519. package/storybook-static/kit/builder/form/utils/common-forms.d.ts +0 -7
  520. package/storybook-static/kit/builder/form/utils/common-forms.d.ts.map +0 -1
  521. package/storybook-static/kit/builder/form/utils/dependencies.d.ts +0 -41
  522. package/storybook-static/kit/builder/form/utils/dependencies.d.ts.map +0 -1
  523. package/storybook-static/kit/builder/form/utils/field-factories.d.ts +0 -23
  524. package/storybook-static/kit/builder/form/utils/field-factories.d.ts.map +0 -1
  525. package/storybook-static/kit/builder/form/utils/index.d.ts +0 -15
  526. package/storybook-static/kit/builder/form/utils/index.d.ts.map +0 -1
  527. package/storybook-static/kit/builder/form/utils/section-factories.d.ts +0 -7
  528. package/storybook-static/kit/builder/form/utils/section-factories.d.ts.map +0 -1
  529. package/storybook-static/kit/builder/form/utils/transformers.d.ts +0 -6
  530. package/storybook-static/kit/builder/form/utils/transformers.d.ts.map +0 -1
  531. package/storybook-static/kit/builder/form/utils/validations.d.ts +0 -13
  532. package/storybook-static/kit/builder/form/utils/validations.d.ts.map +0 -1
  533. package/storybook-static/kit/builder/form/utils/validators.d.ts +0 -8
  534. package/storybook-static/kit/builder/form/utils/validators.d.ts.map +0 -1
  535. package/storybook-static/kit/builder/page/Page.d.ts +0 -48
  536. package/storybook-static/kit/builder/page/Page.d.ts.map +0 -1
  537. package/storybook-static/kit/builder/page/index.d.ts +0 -2
  538. package/storybook-static/kit/builder/page/index.d.ts.map +0 -1
  539. package/storybook-static/kit/builder/section/SectionBuilder.d.ts +0 -3
  540. package/storybook-static/kit/builder/section/SectionBuilder.d.ts.map +0 -1
  541. package/storybook-static/kit/builder/section/index.d.ts +0 -3
  542. package/storybook-static/kit/builder/section/index.d.ts.map +0 -1
  543. package/storybook-static/kit/builder/section/types.d.ts +0 -70
  544. package/storybook-static/kit/builder/section/types.d.ts.map +0 -1
  545. package/storybook-static/kit/builder/stack-dialog/context.d.ts +0 -3
  546. package/storybook-static/kit/builder/stack-dialog/context.d.ts.map +0 -1
  547. package/storybook-static/kit/builder/stack-dialog/hooks.d.ts +0 -6
  548. package/storybook-static/kit/builder/stack-dialog/hooks.d.ts.map +0 -1
  549. package/storybook-static/kit/builder/stack-dialog/index.d.ts +0 -5
  550. package/storybook-static/kit/builder/stack-dialog/index.d.ts.map +0 -1
  551. package/storybook-static/kit/builder/stack-dialog/provider.d.ts +0 -3
  552. package/storybook-static/kit/builder/stack-dialog/provider.d.ts.map +0 -1
  553. package/storybook-static/kit/builder/stack-dialog/renderer.d.ts +0 -6
  554. package/storybook-static/kit/builder/stack-dialog/renderer.d.ts.map +0 -1
  555. package/storybook-static/kit/builder/stack-dialog/types.d.ts +0 -20
  556. package/storybook-static/kit/builder/stack-dialog/types.d.ts.map +0 -1
  557. package/storybook-static/kit/components/autocomplete/Autocomplete.d.ts +0 -53
  558. package/storybook-static/kit/components/autocomplete/Autocomplete.d.ts.map +0 -1
  559. package/storybook-static/kit/components/autocomplete/index.d.ts +0 -4
  560. package/storybook-static/kit/components/autocomplete/index.d.ts.map +0 -1
  561. package/storybook-static/kit/components/autocomplete/types.d.ts +0 -19
  562. package/storybook-static/kit/components/autocomplete/types.d.ts.map +0 -1
  563. package/storybook-static/kit/components/login/Login.d.ts +0 -29
  564. package/storybook-static/kit/components/login/Login.d.ts.map +0 -1
  565. package/storybook-static/kit/components/login/index.d.ts +0 -2
  566. package/storybook-static/kit/components/login/index.d.ts.map +0 -1
  567. package/storybook-static/kit/components/monthpicker/MonthPicker.d.ts +0 -32
  568. package/storybook-static/kit/components/monthpicker/MonthPicker.d.ts.map +0 -1
  569. package/storybook-static/kit/components/monthpicker/MonthRangePicker.d.ts +0 -48
  570. package/storybook-static/kit/components/monthpicker/MonthRangePicker.d.ts.map +0 -1
  571. package/storybook-static/kit/layouts/admin/components/AdminLayout.d.ts +0 -17
  572. package/storybook-static/kit/layouts/admin/components/AdminLayout.d.ts.map +0 -1
  573. package/storybook-static/kit/layouts/admin/components/ThemeToggle.d.ts +0 -5
  574. package/storybook-static/kit/layouts/admin/components/ThemeToggle.d.ts.map +0 -1
  575. package/storybook-static/kit/layouts/admin/hooks/menu.d.ts +0 -13
  576. package/storybook-static/kit/layouts/admin/hooks/menu.d.ts.map +0 -1
  577. package/storybook-static/kit/layouts/admin/providers/AdminMenuProvider.d.ts +0 -7
  578. package/storybook-static/kit/layouts/admin/providers/AdminMenuProvider.d.ts.map +0 -1
  579. package/storybook-static/kit/layouts/admin/types/index.d.ts +0 -27
  580. package/storybook-static/kit/layouts/admin/types/index.d.ts.map +0 -1
  581. package/storybook-static/kit/providers/ThemeProvider.d.ts +0 -14
  582. package/storybook-static/kit/providers/ThemeProvider.d.ts.map +0 -1
  583. package/storybook-static/nunito-sans-bold-italic.woff2 +0 -0
  584. package/storybook-static/nunito-sans-bold.woff2 +0 -0
  585. package/storybook-static/nunito-sans-italic.woff2 +0 -0
  586. package/storybook-static/nunito-sans-regular.woff2 +0 -0
  587. package/storybook-static/project.json +0 -1
  588. package/storybook-static/sb-addons/a11y-5/manager-bundle.js +0 -5
  589. package/storybook-static/sb-addons/essentials-backgrounds-1/manager-bundle.js +0 -3
  590. package/storybook-static/sb-addons/essentials-measure-2/manager-bundle.js +0 -3
  591. package/storybook-static/sb-addons/essentials-outline-3/manager-bundle.js +0 -3
  592. package/storybook-static/sb-addons/interactions-4/manager-bundle.js +0 -57
  593. package/storybook-static/sb-addons/storybook-core-server-presets-0/common-manager-bundle.js +0 -971
  594. package/storybook-static/sb-addons/storysource-6/manager-bundle.js +0 -3
  595. package/storybook-static/sb-common-assets/favicon-wrapper.svg +0 -46
  596. package/storybook-static/sb-common-assets/favicon.svg +0 -1
  597. package/storybook-static/sb-common-assets/nunito-sans-bold-italic.woff2 +0 -0
  598. package/storybook-static/sb-common-assets/nunito-sans-bold.woff2 +0 -0
  599. package/storybook-static/sb-common-assets/nunito-sans-italic.woff2 +0 -0
  600. package/storybook-static/sb-common-assets/nunito-sans-regular.woff2 +0 -0
  601. package/storybook-static/sb-manager/globals-module-info.js +0 -797
  602. package/storybook-static/sb-manager/globals-runtime.js +0 -69653
  603. package/storybook-static/sb-manager/globals.js +0 -34
  604. package/storybook-static/sb-manager/runtime.js +0 -13181
  605. package/storybook-static/shadcn/hooks/use-mobile.d.ts +0 -2
  606. package/storybook-static/shadcn/hooks/use-mobile.d.ts.map +0 -1
  607. package/storybook-static/shadcn/lib/utils.d.ts +0 -3
  608. package/storybook-static/shadcn/lib/utils.d.ts.map +0 -1
  609. package/storybook-static/shadcn/ui/accordion.d.ts +0 -8
  610. package/storybook-static/shadcn/ui/accordion.d.ts.map +0 -1
  611. package/storybook-static/shadcn/ui/alert-dialog.d.ts +0 -15
  612. package/storybook-static/shadcn/ui/alert-dialog.d.ts.map +0 -1
  613. package/storybook-static/shadcn/ui/alert.d.ts +0 -10
  614. package/storybook-static/shadcn/ui/alert.d.ts.map +0 -1
  615. package/storybook-static/shadcn/ui/aspect-ratio.d.ts +0 -4
  616. package/storybook-static/shadcn/ui/aspect-ratio.d.ts.map +0 -1
  617. package/storybook-static/shadcn/ui/avatar.d.ts +0 -7
  618. package/storybook-static/shadcn/ui/avatar.d.ts.map +0 -1
  619. package/storybook-static/shadcn/ui/badge.d.ts +0 -10
  620. package/storybook-static/shadcn/ui/badge.d.ts.map +0 -1
  621. package/storybook-static/shadcn/ui/breadcrumb.d.ts +0 -12
  622. package/storybook-static/shadcn/ui/breadcrumb.d.ts.map +0 -1
  623. package/storybook-static/shadcn/ui/button.d.ts +0 -11
  624. package/storybook-static/shadcn/ui/button.d.ts.map +0 -1
  625. package/storybook-static/shadcn/ui/calendar.d.ts +0 -9
  626. package/storybook-static/shadcn/ui/calendar.d.ts.map +0 -1
  627. package/storybook-static/shadcn/ui/card.d.ts +0 -10
  628. package/storybook-static/shadcn/ui/card.d.ts.map +0 -1
  629. package/storybook-static/shadcn/ui/carousel.d.ts +0 -20
  630. package/storybook-static/shadcn/ui/carousel.d.ts.map +0 -1
  631. package/storybook-static/shadcn/ui/chart.d.ts +0 -41
  632. package/storybook-static/shadcn/ui/chart.d.ts.map +0 -1
  633. package/storybook-static/shadcn/ui/checkbox.d.ts +0 -5
  634. package/storybook-static/shadcn/ui/checkbox.d.ts.map +0 -1
  635. package/storybook-static/shadcn/ui/collapsible.d.ts +0 -6
  636. package/storybook-static/shadcn/ui/collapsible.d.ts.map +0 -1
  637. package/storybook-static/shadcn/ui/command.d.ts +0 -19
  638. package/storybook-static/shadcn/ui/command.d.ts.map +0 -1
  639. package/storybook-static/shadcn/ui/context-menu.d.ts +0 -26
  640. package/storybook-static/shadcn/ui/context-menu.d.ts.map +0 -1
  641. package/storybook-static/shadcn/ui/dialog.d.ts +0 -16
  642. package/storybook-static/shadcn/ui/dialog.d.ts.map +0 -1
  643. package/storybook-static/shadcn/ui/drawer.d.ts +0 -14
  644. package/storybook-static/shadcn/ui/drawer.d.ts.map +0 -1
  645. package/storybook-static/shadcn/ui/dropdown-menu.d.ts +0 -26
  646. package/storybook-static/shadcn/ui/dropdown-menu.d.ts.map +0 -1
  647. package/storybook-static/shadcn/ui/form.d.ts +0 -25
  648. package/storybook-static/shadcn/ui/form.d.ts.map +0 -1
  649. package/storybook-static/shadcn/ui/hover-card.d.ts +0 -7
  650. package/storybook-static/shadcn/ui/hover-card.d.ts.map +0 -1
  651. package/storybook-static/shadcn/ui/input-otp.d.ts +0 -12
  652. package/storybook-static/shadcn/ui/input-otp.d.ts.map +0 -1
  653. package/storybook-static/shadcn/ui/input.d.ts +0 -4
  654. package/storybook-static/shadcn/ui/input.d.ts.map +0 -1
  655. package/storybook-static/shadcn/ui/label.d.ts +0 -5
  656. package/storybook-static/shadcn/ui/label.d.ts.map +0 -1
  657. package/storybook-static/shadcn/ui/menubar.d.ts +0 -27
  658. package/storybook-static/shadcn/ui/menubar.d.ts.map +0 -1
  659. package/storybook-static/shadcn/ui/navigation-menu.d.ts +0 -15
  660. package/storybook-static/shadcn/ui/navigation-menu.d.ts.map +0 -1
  661. package/storybook-static/shadcn/ui/pagination.d.ts +0 -14
  662. package/storybook-static/shadcn/ui/pagination.d.ts.map +0 -1
  663. package/storybook-static/shadcn/ui/popover.d.ts +0 -8
  664. package/storybook-static/shadcn/ui/popover.d.ts.map +0 -1
  665. package/storybook-static/shadcn/ui/progress.d.ts +0 -5
  666. package/storybook-static/shadcn/ui/progress.d.ts.map +0 -1
  667. package/storybook-static/shadcn/ui/radio-group.d.ts +0 -6
  668. package/storybook-static/shadcn/ui/radio-group.d.ts.map +0 -1
  669. package/storybook-static/shadcn/ui/resizable.d.ts +0 -9
  670. package/storybook-static/shadcn/ui/resizable.d.ts.map +0 -1
  671. package/storybook-static/shadcn/ui/scroll-area.d.ts +0 -6
  672. package/storybook-static/shadcn/ui/scroll-area.d.ts.map +0 -1
  673. package/storybook-static/shadcn/ui/select.d.ts +0 -16
  674. package/storybook-static/shadcn/ui/select.d.ts.map +0 -1
  675. package/storybook-static/shadcn/ui/separator.d.ts +0 -5
  676. package/storybook-static/shadcn/ui/separator.d.ts.map +0 -1
  677. package/storybook-static/shadcn/ui/sheet.d.ts +0 -14
  678. package/storybook-static/shadcn/ui/sheet.d.ts.map +0 -1
  679. package/storybook-static/shadcn/ui/sidebar.d.ts +0 -70
  680. package/storybook-static/shadcn/ui/sidebar.d.ts.map +0 -1
  681. package/storybook-static/shadcn/ui/skeleton.d.ts +0 -3
  682. package/storybook-static/shadcn/ui/skeleton.d.ts.map +0 -1
  683. package/storybook-static/shadcn/ui/slider.d.ts +0 -5
  684. package/storybook-static/shadcn/ui/slider.d.ts.map +0 -1
  685. package/storybook-static/shadcn/ui/sonner.d.ts +0 -4
  686. package/storybook-static/shadcn/ui/sonner.d.ts.map +0 -1
  687. package/storybook-static/shadcn/ui/switch.d.ts +0 -5
  688. package/storybook-static/shadcn/ui/switch.d.ts.map +0 -1
  689. package/storybook-static/shadcn/ui/table.d.ts +0 -11
  690. package/storybook-static/shadcn/ui/table.d.ts.map +0 -1
  691. package/storybook-static/shadcn/ui/tabs.d.ts +0 -8
  692. package/storybook-static/shadcn/ui/tabs.d.ts.map +0 -1
  693. package/storybook-static/shadcn/ui/textarea.d.ts +0 -4
  694. package/storybook-static/shadcn/ui/textarea.d.ts.map +0 -1
  695. package/storybook-static/shadcn/ui/toggle-group.d.ts +0 -8
  696. package/storybook-static/shadcn/ui/toggle-group.d.ts.map +0 -1
  697. package/storybook-static/shadcn/ui/toggle.d.ts +0 -10
  698. package/storybook-static/shadcn/ui/toggle.d.ts.map +0 -1
  699. package/storybook-static/shadcn/ui/tooltip.d.ts +0 -8
  700. package/storybook-static/shadcn/ui/tooltip.d.ts.map +0 -1
  701. package/storybook-static/vite-inject-mocker-entry.js +0 -18
@@ -1,916 +1,916 @@
1
- "use client";
2
-
3
- import * as React from "react";
4
- import { Delete, ArrowLeft, CornerDownLeft } from "lucide-react";
5
- import { cn } from "../../../shadcn/lib/utils";
6
- import { Button } from "../../../shadcn/ui/button";
7
-
8
- // Constants
9
- const KEY_BUTTON_BASE_CLASSES =
10
- "rounded-xl border-2 border-teal-200 bg-white text-teal-600 transition-all duration-150 hover:bg-teal-50 h-16 min-w-[80px] max-w-[88px] text-lg font-semibold";
11
- const KEY_BUTTON_COMPACT_CLASSES =
12
- "rounded-xl border-2 border-teal-200 bg-white text-teal-600 transition-all duration-150 hover:bg-teal-50 h-16 min-w-[80px] max-w-[80px] text-lg font-semibold";
13
- const BACKSPACE_BUTTON_CLASSES =
14
- "rounded-xl bg-red-600 text-white transition-all duration-150 hover:bg-red-700 h-16 min-w-[80px] max-w-[80px]";
15
- const SPACE_BUTTON_CLASSES =
16
- "rounded-xl border-2 border-teal-200 bg-white text-teal-600 transition-all duration-150 hover:bg-teal-50 h-16 min-w-[630px] max-w-[630px] flex-1 text-lg font-semibold";
17
- const ENTER_BUTTON_CLASSES =
18
- "rounded-xl border-2 border-teal-200 bg-green-500 text-white transition-all duration-150 hover:bg-green-600 h-16 min-w-[80px] max-w-[80px] text-lg font-semibold";
19
- const PRESSED_KEY_CLASSES = "bg-teal-100 border-teal-400 scale-95";
20
- const ACTIVE_TOGGLE_CLASSES =
21
- "bg-teal-600 text-white border-teal-600 hover:bg-teal-700";
22
-
23
- export type KeyboardLayout = "qwerty" | "qwertz" | "azerty";
24
-
25
- export interface KeyboardProps
26
- extends Omit<
27
- React.HTMLAttributes<HTMLDivElement>,
28
- "onChange" | "onKeyPress"
29
- > {
30
- value?: string;
31
- onChange?: (value: string) => void;
32
- onKeyPress?: (key: string) => void;
33
- disabled?: boolean;
34
- layout?: KeyboardLayout;
35
- showNumbers?: boolean;
36
- showSymbols?: boolean;
37
- showShift?: boolean;
38
- showSpace?: boolean;
39
- showBackspace?: boolean;
40
- showEnter?: boolean;
41
- className?: string;
42
- buttonClassName?: string;
43
- customKeyStyle?: React.CSSProperties;
44
- customKeyClassName?: string;
45
- capsLock?: boolean;
46
- onCapsLockChange?: (capsLock: boolean) => void;
47
- inputRef?: React.RefObject<HTMLInputElement | HTMLTextAreaElement | null>;
48
- }
49
-
50
- const QWERTY_LAYOUT = {
51
- row1: ["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"],
52
- row2: ["a", "s", "d", "f", "g", "h", "j", "k", "l"],
53
- row3: ["z", "x", "c", "v", "b", "n", "m"],
54
- };
55
-
56
- const QWERTZ_LAYOUT = {
57
- row1: ["q", "w", "e", "r", "t", "z", "u", "i", "o", "p"],
58
- row2: ["a", "s", "d", "f", "g", "h", "j", "k", "l"],
59
- row3: ["y", "x", "c", "v", "b", "n", "m"],
60
- };
61
-
62
- const AZERTY_LAYOUT = {
63
- row1: ["a", "z", "e", "r", "t", "y", "u", "i", "o", "p"],
64
- row2: ["q", "s", "d", "f", "g", "h", "j", "k", "l", "m"],
65
- row3: ["w", "x", "c", "v", "b", "n"],
66
- };
67
-
68
- const NUMBER_ROW = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"];
69
-
70
- const getLayout = (layout: KeyboardLayout) => {
71
- switch (layout) {
72
- case "qwertz":
73
- return QWERTZ_LAYOUT;
74
- case "azerty":
75
- return AZERTY_LAYOUT;
76
- default:
77
- return QWERTY_LAYOUT;
78
- }
79
- };
80
-
81
- export function Keyboard({
82
- value: controlledValue,
83
- onChange,
84
- onKeyPress,
85
- disabled = false,
86
- layout = "qwerty",
87
- showNumbers = true,
88
- showSymbols = true,
89
- showShift = true,
90
- showSpace = true,
91
- showBackspace = true,
92
- showEnter = false,
93
- className,
94
- buttonClassName,
95
- customKeyStyle,
96
- customKeyClassName,
97
- capsLock: controlledCapsLock,
98
- onCapsLockChange,
99
- inputRef,
100
- ...props
101
- }: KeyboardProps) {
102
- const [internalValue, setInternalValue] = React.useState("");
103
- const [internalCapsLock, setInternalCapsLock] = React.useState(false);
104
- const [shiftPressed, setShiftPressed] = React.useState(false);
105
- const [symbolMode, setSymbolMode] = React.useState(false);
106
- const [pressedKey, setPressedKey] = React.useState<string | null>(null);
107
- const [inputValue, setInputValue] = React.useState("");
108
- const pendingCursorPos = React.useRef<number | null>(null);
109
-
110
- // Use a ref to track if virtual Caps Lock was just clicked (to prevent sync override)
111
- const virtualCapsLockJustToggled = React.useRef(false);
112
- // Track the last known Caps Lock state to detect changes
113
- const lastKnownCapsLockState = React.useRef(false);
114
-
115
- const isControlled = controlledValue !== undefined;
116
- const value = isControlled ? controlledValue : internalValue;
117
-
118
- // Sync inputValue with actual input value when inputRef is provided
119
- React.useEffect(() => {
120
- if (inputRef?.current) {
121
- const updateInputValue = () => {
122
- setInputValue(inputRef.current?.value ?? "");
123
- };
124
-
125
- // Initial sync
126
- updateInputValue();
127
-
128
- // Listen to input events to keep in sync
129
- const input = inputRef.current;
130
- input.addEventListener("input", updateInputValue);
131
- input.addEventListener("change", updateInputValue);
132
-
133
- return () => {
134
- input.removeEventListener("input", updateInputValue);
135
- input.removeEventListener("change", updateInputValue);
136
- };
137
- }
138
- setInputValue(value);
139
- return undefined;
140
- }, [inputRef, value]);
141
-
142
- // Restore cursor position after React re-renders
143
- React.useEffect(() => {
144
- if (inputRef?.current && pendingCursorPos.current !== null) {
145
- const pos = pendingCursorPos.current;
146
- pendingCursorPos.current = null;
147
- // Use setTimeout to ensure React has finished rendering
148
- setTimeout(() => {
149
- if (inputRef?.current) {
150
- inputRef.current.setSelectionRange(pos, pos);
151
- }
152
- }, 0);
153
- }
154
- }, [value, inputRef]);
155
-
156
- // Get the actual input value for disabled checks
157
- const actualInputValue = inputRef?.current ? inputValue : value;
158
-
159
- const isCapsLockControlled = controlledCapsLock !== undefined;
160
- const capsLock = isCapsLockControlled ? controlledCapsLock : internalCapsLock;
161
-
162
- // Update ref when capsLock changes
163
- React.useEffect(() => {
164
- lastKnownCapsLockState.current = capsLock;
165
- }, [capsLock]);
166
-
167
- const keyboardLayout = React.useMemo(() => getLayout(layout), [layout]);
168
-
169
- const isShiftActive = capsLock || shiftPressed;
170
-
171
- // Map real keyboard keys to virtual keyboard keys
172
- const mapRealKeyToVirtual = React.useCallback(
173
- (key: string, event: KeyboardEvent): string | null => {
174
- const keyLower = key.toLowerCase();
175
-
176
- // Handle special keys
177
- if (key === "Backspace" || key === "Delete") return "Backspace";
178
- if (key === "Enter") return "Enter";
179
- if (key === " ") return "Space";
180
- if (key === "Tab") return "Tab";
181
- if (key === "Shift" || key === "ShiftLeft" || key === "ShiftRight")
182
- return "Shift";
183
- if (key === "CapsLock") return "CapsLock";
184
- if (key === "#" || key === "+" || key === "=") return "#+=";
185
-
186
- // Handle numbers
187
- if (/^[0-9]$/.test(key)) {
188
- return symbolMode ? null : key;
189
- }
190
-
191
- // Handle letters
192
- if (/^[a-z]$/i.test(key)) {
193
- if (symbolMode) {
194
- // In symbol mode, letters map to symbols
195
- return null; // Symbols are shown in dedicated rows
196
- }
197
- return keyLower;
198
- }
199
-
200
- // Handle symbols when shift is pressed
201
- if (event.shiftKey) {
202
- const shiftSymbolMap: Record<string, string> = {
203
- "1": ".",
204
- "2": "@",
205
- "3": "#",
206
- "4": "_",
207
- "5": "%",
208
- "6": "^",
209
- "7": "&",
210
- "8": "*",
211
- "9": "(",
212
- "0": ")",
213
- "-": ",",
214
- "=": "+",
215
- "[": "{",
216
- "]": "}",
217
- "\\": "|",
218
- ";": ":",
219
- "'": '"',
220
- ",": "<",
221
- ".": ">",
222
- "/": "?",
223
- "`": "~",
224
- };
225
- return shiftSymbolMap[key] || null;
226
- }
227
-
228
- // Handle regular symbols
229
- const symbolMap: Record<string, string> = {
230
- "-": "-",
231
- "=": "=",
232
- "[": "[",
233
- "]": "]",
234
- "\\": "\\",
235
- ";": ";",
236
- "'": "'",
237
- ",": ",",
238
- ".": ".",
239
- "/": "/",
240
- "`": "`",
241
- };
242
- return symbolMap[key] || null;
243
- },
244
- [symbolMode],
245
- );
246
-
247
- const handleKeyPress = React.useCallback(
248
- (key: string) => {
249
- if (disabled) return;
250
-
251
- // If inputRef is provided, manipulate the input directly to handle selection
252
- if (inputRef?.current) {
253
- const input = inputRef.current;
254
- const start = input.selectionStart ?? 0;
255
- const end = input.selectionEnd ?? 0;
256
- const currentValue = input.value;
257
-
258
- // Replace selected text with the new key
259
- const newValue =
260
- currentValue.slice(0, start) + key + currentValue.slice(end);
261
- const newCursorPos = start + key.length;
262
-
263
- // Update our internal state first
264
- setInputValue(newValue);
265
-
266
- // Store cursor position to restore after React re-renders
267
- pendingCursorPos.current = newCursorPos;
268
-
269
- // Call onChange to update parent state - React will handle the re-render
270
- onChange?.(newValue);
271
- if (!isControlled) {
272
- setInternalValue(newValue);
273
- }
274
-
275
- onKeyPress?.(key);
276
- return;
277
- }
278
-
279
- // Fallback to old behavior if no inputRef
280
- const newValue = value + key;
281
- if (isControlled) {
282
- onChange?.(newValue);
283
- } else {
284
- setInternalValue(newValue);
285
- onChange?.(newValue);
286
- }
287
- onKeyPress?.(key);
288
- },
289
- [disabled, value, isControlled, onChange, onKeyPress, inputRef],
290
- );
291
-
292
- const handleBackspace = React.useCallback(() => {
293
- if (disabled) return;
294
-
295
- // If inputRef is provided, check the actual input value
296
- if (inputRef?.current) {
297
- const input = inputRef.current;
298
- const start = input.selectionStart ?? 0;
299
- const end = input.selectionEnd ?? 0;
300
- const currentValue = input.value;
301
-
302
- if (start === end && start === 0) return; // Nothing to delete
303
-
304
- // Set pressed key for animation
305
- setPressedKey("Backspace");
306
- setTimeout(() => {
307
- setPressedKey(null);
308
- }, 150);
309
-
310
- // If text is selected, delete the selection
311
- // Otherwise, delete the character before the cursor
312
- let newValue: string;
313
- let newCursorPos: number;
314
-
315
- if (start !== end) {
316
- // Delete selected text
317
- newValue = currentValue.slice(0, start) + currentValue.slice(end);
318
- newCursorPos = start;
319
- } else {
320
- // Delete character before cursor
321
- newValue = currentValue.slice(0, start - 1) + currentValue.slice(start);
322
- newCursorPos = Math.max(0, start - 1);
323
- }
324
-
325
- // Update our internal state first
326
- setInputValue(newValue);
327
-
328
- // Store cursor position to restore after React re-renders
329
- pendingCursorPos.current = newCursorPos;
330
-
331
- // Call onChange to update parent state - React will handle the re-render
332
- onChange?.(newValue);
333
- if (!isControlled) {
334
- setInternalValue(newValue);
335
- }
336
-
337
- onKeyPress?.("Backspace");
338
- return;
339
- }
340
-
341
- // Fallback to old behavior if no inputRef
342
- if (value.length === 0) return;
343
-
344
- // Set pressed key for animation
345
- setPressedKey("Backspace");
346
- setTimeout(() => {
347
- setPressedKey(null);
348
- }, 150);
349
-
350
- const newValue = value.slice(0, -1);
351
- if (isControlled) {
352
- onChange?.(newValue);
353
- } else {
354
- setInternalValue(newValue);
355
- onChange?.(newValue);
356
- }
357
- onKeyPress?.("Backspace");
358
- }, [disabled, value, isControlled, onChange, onKeyPress, inputRef]);
359
-
360
- const handleSpace = React.useCallback(() => {
361
- // Set pressed key for animation
362
- setPressedKey("Space");
363
- setTimeout(() => {
364
- setPressedKey(null);
365
- }, 150);
366
- handleKeyPress(" ");
367
- }, [handleKeyPress]);
368
-
369
- const handleEnter = React.useCallback(() => {
370
- if (disabled) return;
371
-
372
- // Set pressed key for animation
373
- setPressedKey("Enter");
374
- setTimeout(() => {
375
- setPressedKey(null);
376
- }, 150);
377
-
378
- // If inputRef is provided, handle Enter like a real keyboard
379
- if (inputRef?.current) {
380
- const input = inputRef?.current;
381
- const isTextarea = input.tagName === "TEXTAREA";
382
- const isInput = input.tagName === "INPUT";
383
-
384
- if (isTextarea) {
385
- // For textarea: insert newline like real keyboard
386
- const start = input.selectionStart ?? 0;
387
- const end = input.selectionEnd ?? 0;
388
- const currentValue = input.value;
389
-
390
- // Replace selected text with newline, or insert newline at cursor
391
- const newValue =
392
- currentValue.slice(0, start) + "\n" + currentValue.slice(end);
393
- const newCursorPos = start + 1;
394
-
395
- // Update input value
396
- input.value = newValue;
397
-
398
- // Set cursor position
399
- input.setSelectionRange(newCursorPos, newCursorPos);
400
-
401
- // Trigger input event for React
402
- const inputEvent = new Event("input", { bubbles: true });
403
- input.dispatchEvent(inputEvent);
404
-
405
- // Update controlled/uncontrolled state
406
- if (isControlled) {
407
- onChange?.(newValue);
408
- } else {
409
- setInternalValue(newValue);
410
- onChange?.(newValue);
411
- }
412
- } else if (isInput) {
413
- // For input: trigger Enter key events like real keyboard
414
- // This will trigger form submission if inside a form
415
-
416
- // Create and dispatch keydown event
417
- const keyDownEvent = new KeyboardEvent("keydown", {
418
- key: "Enter",
419
- code: "Enter",
420
- keyCode: 13,
421
- which: 13,
422
- bubbles: true,
423
- cancelable: true,
424
- });
425
- input.dispatchEvent(keyDownEvent);
426
-
427
- // Only trigger keypress and keyup if keydown wasn't prevented
428
- if (!keyDownEvent.defaultPrevented) {
429
- // Create and dispatch keypress event
430
- const keyPressEvent = new KeyboardEvent("keypress", {
431
- key: "Enter",
432
- code: "Enter",
433
- keyCode: 13,
434
- which: 13,
435
- bubbles: true,
436
- cancelable: true,
437
- });
438
- input.dispatchEvent(keyPressEvent);
439
-
440
- // Create and dispatch keyup event
441
- const keyUpEvent = new KeyboardEvent("keyup", {
442
- key: "Enter",
443
- code: "Enter",
444
- keyCode: 13,
445
- which: 13,
446
- bubbles: true,
447
- cancelable: true,
448
- });
449
- input.dispatchEvent(keyUpEvent);
450
-
451
- // If input is inside a form, trigger form submit
452
- const form = input.closest("form");
453
- if (form && !keyPressEvent.defaultPrevented) {
454
- // Trigger form submit event
455
- const submitEvent = new Event("submit", {
456
- bubbles: true,
457
- cancelable: true,
458
- });
459
- form.dispatchEvent(submitEvent);
460
-
461
- // If submit wasn't prevented, actually submit the form
462
- if (!submitEvent.defaultPrevented) {
463
- form.requestSubmit();
464
- }
465
- }
466
- }
467
- }
468
-
469
- // Call onKeyPress callback
470
- onKeyPress?.("Enter");
471
- return;
472
- }
473
-
474
- // Fallback: if no inputRef, just add newline to value
475
- const newValue = value + "\n";
476
- if (isControlled) {
477
- onChange?.(newValue);
478
- } else {
479
- setInternalValue(newValue);
480
- onChange?.(newValue);
481
- }
482
- onKeyPress?.("Enter");
483
- }, [disabled, value, isControlled, onChange, onKeyPress, inputRef]);
484
-
485
- const toggleCapsLock = React.useCallback(() => {
486
- // Set pressed key for animation
487
- setPressedKey("CapsLock");
488
- setTimeout(() => {
489
- setPressedKey(null);
490
- }, 150);
491
-
492
- // Set flag to prevent sync from overriding our toggle for a short period
493
- virtualCapsLockJustToggled.current = true;
494
-
495
- // Always use functional update to get the latest state
496
- if (isCapsLockControlled) {
497
- // For controlled components, use the current prop value
498
- const currentCapsLock = controlledCapsLock ?? false;
499
- const newCapsLock = !currentCapsLock;
500
- lastKnownCapsLockState.current = newCapsLock;
501
- onCapsLockChange?.(newCapsLock);
502
- } else {
503
- // For uncontrolled components, use functional update to avoid stale closures
504
- setInternalCapsLock((prev) => {
505
- const newCapsLock = !prev;
506
- lastKnownCapsLockState.current = newCapsLock;
507
- onCapsLockChange?.(newCapsLock);
508
- return newCapsLock;
509
- });
510
- }
511
-
512
- // Reset flag after a delay to allow sync again
513
- setTimeout(() => {
514
- virtualCapsLockJustToggled.current = false;
515
- }, 200);
516
- }, [isCapsLockControlled, onCapsLockChange, controlledCapsLock]);
517
-
518
- const toggleSymbolMode = React.useCallback(() => {
519
- // Set pressed key for animation
520
- setPressedKey("#+=");
521
- setTimeout(() => {
522
- setPressedKey(null);
523
- }, 150);
524
- setSymbolMode((prev) => !prev);
525
- }, []);
526
-
527
- // Listen to real keyboard events and sync Caps Lock state
528
- React.useEffect(() => {
529
- if (disabled) return;
530
-
531
- const handleKeyDown = (event: KeyboardEvent) => {
532
- // Handle Caps Lock key press on physical keyboard
533
- if (event.key === "CapsLock" || event.key === "Caps") {
534
- setPressedKey("CapsLock");
535
- virtualCapsLockJustToggled.current = false; // Reset flag - physical keyboard takes priority
536
-
537
- // When Caps Lock is pressed, the state changes AFTER this event
538
- // So we toggle based on the last known state
539
- const newCapsLock = !lastKnownCapsLockState.current;
540
- lastKnownCapsLockState.current = newCapsLock;
541
-
542
- if (!isCapsLockControlled) {
543
- setInternalCapsLock(newCapsLock);
544
- onCapsLockChange?.(newCapsLock);
545
- } else {
546
- onCapsLockChange?.(newCapsLock);
547
- }
548
- return;
549
- }
550
-
551
- // Sync with browser's actual caps lock state on any key press
552
- // This ensures we stay in sync with physical keyboard
553
- // But skip if virtual Caps Lock was just toggled (to prevent override)
554
- if (!virtualCapsLockJustToggled.current) {
555
- const browserCapsLock = event.getModifierState("CapsLock");
556
-
557
- // Only update if state has actually changed
558
- if (browserCapsLock !== lastKnownCapsLockState.current) {
559
- lastKnownCapsLockState.current = browserCapsLock;
560
-
561
- if (!isCapsLockControlled) {
562
- setInternalCapsLock(browserCapsLock);
563
- onCapsLockChange?.(browserCapsLock);
564
- } else {
565
- onCapsLockChange?.(browserCapsLock);
566
- }
567
- }
568
- }
569
-
570
- const virtualKey = mapRealKeyToVirtual(event.key, event);
571
- if (virtualKey) {
572
- setPressedKey(virtualKey);
573
- }
574
- };
575
-
576
- const handleKeyUp = (event: KeyboardEvent) => {
577
- setPressedKey(null);
578
-
579
- // Also check Caps Lock state on keyup to catch any changes
580
- if (!virtualCapsLockJustToggled.current) {
581
- const browserCapsLock = event.getModifierState("CapsLock");
582
- if (browserCapsLock !== lastKnownCapsLockState.current) {
583
- lastKnownCapsLockState.current = browserCapsLock;
584
-
585
- if (!isCapsLockControlled) {
586
- setInternalCapsLock(browserCapsLock);
587
- onCapsLockChange?.(browserCapsLock);
588
- } else {
589
- onCapsLockChange?.(browserCapsLock);
590
- }
591
- }
592
- }
593
- };
594
-
595
- window.addEventListener("keydown", handleKeyDown);
596
- window.addEventListener("keyup", handleKeyUp);
597
-
598
- return () => {
599
- window.removeEventListener("keydown", handleKeyDown);
600
- window.removeEventListener("keyup", handleKeyUp);
601
- };
602
- }, [disabled, mapRealKeyToVirtual, isCapsLockControlled, onCapsLockChange]);
603
-
604
- // Helper to animate key press
605
- const animateKeyPress = React.useCallback((key: string) => {
606
- setPressedKey(key);
607
- setTimeout(() => setPressedKey(null), 150);
608
- }, []);
609
-
610
- const formatKey = (key: string): string => {
611
- if (symbolMode) {
612
- const symbolMap: Record<string, string> = {
613
- q: "[",
614
- w: "]",
615
- e: "\\",
616
- r: ";",
617
- t: "'",
618
- y: ",",
619
- u: ".",
620
- i: "/",
621
- o: "=",
622
- p: "-",
623
- a: "{",
624
- s: "}",
625
- d: ":",
626
- f: '"',
627
- g: "<",
628
- h: ">",
629
- j: "?",
630
- k: "+",
631
- l: "_",
632
- z: "|",
633
- x: "~",
634
- c: "`",
635
- v: "|",
636
- b: "~",
637
- n: "`",
638
- m: "|",
639
- };
640
- return symbolMap[key.toLowerCase()] || key;
641
- }
642
- return isShiftActive ? key.toUpperCase() : key.toLowerCase();
643
- };
644
-
645
- const getNumberSymbol = (num: string, shift: boolean): string => {
646
- if (!shift) return num;
647
- const symbols: Record<string, string> = {
648
- "1": ".",
649
- "2": "@",
650
- "3": "#",
651
- "4": "_",
652
- "5": "%",
653
- "6": "^",
654
- "7": "&",
655
- "8": "*",
656
- "9": "(",
657
- "0": ")",
658
- };
659
- return symbols[num] || num;
660
- };
661
-
662
- // Helper component for key buttons
663
- const KeyButton = React.useCallback(
664
- ({
665
- children,
666
- onClick,
667
- isPressed = false,
668
- className = "",
669
- compact = false,
670
- }: {
671
- children: React.ReactNode;
672
- onClick: () => void;
673
- isPressed?: boolean;
674
- className?: string;
675
- compact?: boolean;
676
- }) => (
677
- <Button
678
- type="button"
679
- disabled={disabled}
680
- onClick={onClick}
681
- style={customKeyStyle}
682
- className={cn(
683
- compact ? KEY_BUTTON_COMPACT_CLASSES : KEY_BUTTON_BASE_CLASSES,
684
- isPressed && PRESSED_KEY_CLASSES,
685
- buttonClassName,
686
- customKeyClassName,
687
- className
688
- )}
689
- >
690
- {children}
691
- </Button>
692
- ),
693
- [disabled, customKeyStyle, buttonClassName, customKeyClassName]
694
- );
695
-
696
- // Helper component for symbol buttons
697
- const SymbolButton = React.useCallback(
698
- ({ sym }: { sym: string }) => {
699
- const isPressed = pressedKey === sym;
700
- return (
701
- <KeyButton
702
- isPressed={isPressed}
703
- onClick={() => {
704
- animateKeyPress(sym);
705
- handleKeyPress(sym);
706
- }}
707
- >
708
- {sym}
709
- </KeyButton>
710
- );
711
- },
712
- [pressedKey, animateKeyPress, handleKeyPress, KeyButton]
713
- );
714
-
715
- // Helper component for letter buttons
716
- const LetterButton = React.useCallback(
717
- ({ keyChar }: { keyChar: string }) => {
718
- const displayChar = formatKey(keyChar);
719
- const isPressed = pressedKey === keyChar.toLowerCase();
720
- return (
721
- <KeyButton
722
- isPressed={isPressed}
723
- onClick={() => {
724
- animateKeyPress(keyChar.toLowerCase());
725
- handleKeyPress(displayChar);
726
- if (shiftPressed) setShiftPressed(false);
727
- }}
728
- >
729
- {displayChar}
730
- </KeyButton>
731
- );
732
- },
733
- [
734
- pressedKey,
735
- shiftPressed,
736
- animateKeyPress,
737
- handleKeyPress,
738
- formatKey,
739
- KeyButton,
740
- ]
741
- );
742
-
743
- return (
744
- <div
745
- className={cn(
746
- "flex flex-col gap-3 p-6 bg-background border border-border rounded-lg shadow-sm",
747
- className,
748
- )}
749
- {...props}
750
- >
751
- {/* Number row - hidden when symbol mode is active */}
752
- {showNumbers && (
753
- <div className="flex gap-3 justify-center">
754
- {NUMBER_ROW.map((num) => {
755
- const displayChar = shiftPressed ? getNumberSymbol(num, true) : num;
756
- const isPressed = pressedKey === num;
757
- return (
758
- <KeyButton
759
- key={num}
760
- isPressed={isPressed}
761
- onClick={() => {
762
- animateKeyPress(num);
763
- handleKeyPress(displayChar);
764
- if (shiftPressed) setShiftPressed(false);
765
- }}
766
- >
767
- {displayChar}
768
- </KeyButton>
769
- );
770
- })}
771
- </div>
772
- )}
773
-
774
- {/* Symbol rows - shows when symbol mode is active */}
775
- {symbolMode && (
776
- <>
777
- {/* Row 1: Special symbols - 10 keys balanced */}
778
- <div className="flex gap-3 justify-center">
779
- {["!", "@", "#", "$", "%", "^", "&", "*", "(", ")"].map((sym) => (
780
- <SymbolButton key={sym} sym={sym} />
781
- ))}
782
- </div>
783
- {/* Row 2: Brackets and quotes - 10 keys balanced */}
784
- <div className="flex gap-3 justify-center">
785
- {["[", "]", "{", "}", "|", "\\", ";", ":", "'", '"'].map((sym) => (
786
- <SymbolButton key={sym} sym={sym} />
787
- ))}
788
- </div>
789
- {/* Row 3: Punctuation and operators - 9 keys */}
790
- <div className="flex gap-3 justify-center">
791
- {[",", ".", "/", "?", "+", "-", "=", "_", "~"].map((sym) => (
792
- <SymbolButton key={sym} sym={sym} />
793
- ))}
794
- {showBackspace && (
795
- <button
796
- type="button"
797
- disabled={disabled || actualInputValue.length === 0}
798
- onClick={handleBackspace}
799
- style={customKeyStyle}
800
- className={cn(
801
- BACKSPACE_BUTTON_CLASSES,
802
- buttonClassName,
803
- customKeyClassName
804
- )}
805
- >
806
- <Delete className="mx-auto h-6 w-6" />
807
- </button>
808
- )}
809
- </div>
810
- </>
811
- )}
812
-
813
- {/* Letter rows - hidden when symbol mode is active */}
814
- {!symbolMode && (
815
- <>
816
- {/* Row 1 - Letter row Q-P */}
817
- <div className="flex gap-3 justify-center">
818
- {keyboardLayout.row1.map((keyChar) => (
819
- <LetterButton key={keyChar} keyChar={keyChar} />
820
- ))}
821
- </div>
822
-
823
- {/* Row 2 */}
824
- <div className="flex gap-3 justify-center">
825
- {keyboardLayout.row2.map((keyChar) => (
826
- <LetterButton key={keyChar} keyChar={keyChar} />
827
- ))}
828
- </div>
829
- </>
830
- )}
831
-
832
- {/* Row 3 - Bottom letter row with controls */}
833
- <div className="flex gap-3 justify-center">
834
- {!symbolMode && (
835
- <>
836
- {showShift && (
837
- <KeyButton
838
- compact
839
- isPressed={pressedKey === "CapsLock" && !capsLock}
840
- onClick={toggleCapsLock}
841
- className={capsLock ? ACTIVE_TOGGLE_CLASSES : ""}
842
- >
843
- <ArrowLeft className="h-6 w-6 rotate-90" />
844
- </KeyButton>
845
- )}
846
- {keyboardLayout.row3.map((keyChar) => (
847
- <LetterButton key={keyChar} keyChar={keyChar} />
848
- ))}
849
- {showBackspace && (
850
- <button
851
- type="button"
852
- disabled={disabled || actualInputValue.length === 0}
853
- onClick={handleBackspace}
854
- style={customKeyStyle}
855
- className={cn(
856
- BACKSPACE_BUTTON_CLASSES,
857
- buttonClassName,
858
- customKeyClassName
859
- )}
860
- >
861
- <Delete className="mx-auto h-6 w-6" />
862
- </button>
863
- )}
864
- </>
865
- )}
866
- </div>
867
-
868
- {/* Bottom row */}
869
- <div className="flex gap-3 justify-center">
870
- <KeyButton
871
- compact
872
- isPressed={pressedKey === "#+=" && !symbolMode}
873
- onClick={toggleSymbolMode}
874
- className={symbolMode ? ACTIVE_TOGGLE_CLASSES : ""}
875
- >
876
- #+=
877
- </KeyButton>
878
- {showSpace && (
879
- <Button
880
- type="button"
881
- disabled={disabled}
882
- onClick={handleSpace}
883
- style={customKeyStyle}
884
- className={cn(
885
- SPACE_BUTTON_CLASSES,
886
- pressedKey === "Space" && PRESSED_KEY_CLASSES,
887
- buttonClassName,
888
- customKeyClassName
889
- )}
890
- >
891
- Space
892
- </Button>
893
- )}
894
- {showEnter && (
895
- <Button
896
- type="button"
897
- disabled={disabled}
898
- onClick={handleEnter}
899
- style={customKeyStyle}
900
- className={cn(
901
- ENTER_BUTTON_CLASSES,
902
- buttonClassName,
903
- customKeyClassName
904
- )}
905
- >
906
- <CornerDownLeft className="mx-auto h-6 w-6" />
907
- </Button>
908
- )}
909
- </div>
910
- </div>
911
- );
912
- }
913
-
914
- Keyboard.displayName = "Keyboard";
915
-
916
- export default Keyboard;
1
+ "use client";
2
+
3
+ import * as React from "react";
4
+ import { Delete, ArrowLeft, CornerDownLeft } from "lucide-react";
5
+ import { cn } from "../../../shadcn/lib/utils";
6
+ import { Button } from "../../../shadcn/ui/button";
7
+
8
+ // Constants
9
+ const KEY_BUTTON_BASE_CLASSES =
10
+ "rounded-xl border-2 border-teal-200 bg-white text-teal-600 transition-all duration-150 hover:bg-teal-50 h-16 min-w-[80px] max-w-[88px] text-lg font-semibold";
11
+ const KEY_BUTTON_COMPACT_CLASSES =
12
+ "rounded-xl border-2 border-teal-200 bg-white text-teal-600 transition-all duration-150 hover:bg-teal-50 h-16 min-w-[80px] max-w-[80px] text-lg font-semibold";
13
+ const BACKSPACE_BUTTON_CLASSES =
14
+ "rounded-xl bg-red-600 text-white transition-all duration-150 hover:bg-red-700 h-16 min-w-[80px] max-w-[80px]";
15
+ const SPACE_BUTTON_CLASSES =
16
+ "rounded-xl border-2 border-teal-200 bg-white text-teal-600 transition-all duration-150 hover:bg-teal-50 h-16 min-w-[630px] max-w-[630px] flex-1 text-lg font-semibold";
17
+ const ENTER_BUTTON_CLASSES =
18
+ "rounded-xl border-2 border-teal-200 bg-green-500 text-white transition-all duration-150 hover:bg-green-600 h-16 min-w-[80px] max-w-[80px] text-lg font-semibold";
19
+ const PRESSED_KEY_CLASSES = "bg-teal-100 border-teal-400 scale-95";
20
+ const ACTIVE_TOGGLE_CLASSES =
21
+ "bg-teal-600 text-white border-teal-600 hover:bg-teal-700";
22
+
23
+ export type KeyboardLayout = "qwerty" | "qwertz" | "azerty";
24
+
25
+ export interface KeyboardProps
26
+ extends Omit<
27
+ React.HTMLAttributes<HTMLDivElement>,
28
+ "onChange" | "onKeyPress"
29
+ > {
30
+ value?: string;
31
+ onChange?: (value: string) => void;
32
+ onKeyPress?: (key: string) => void;
33
+ disabled?: boolean;
34
+ layout?: KeyboardLayout;
35
+ showNumbers?: boolean;
36
+ showSymbols?: boolean;
37
+ showShift?: boolean;
38
+ showSpace?: boolean;
39
+ showBackspace?: boolean;
40
+ showEnter?: boolean;
41
+ className?: string;
42
+ buttonClassName?: string;
43
+ customKeyStyle?: React.CSSProperties;
44
+ customKeyClassName?: string;
45
+ capsLock?: boolean;
46
+ onCapsLockChange?: (capsLock: boolean) => void;
47
+ inputRef?: React.RefObject<HTMLInputElement | HTMLTextAreaElement | null>;
48
+ }
49
+
50
+ const QWERTY_LAYOUT = {
51
+ row1: ["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"],
52
+ row2: ["a", "s", "d", "f", "g", "h", "j", "k", "l"],
53
+ row3: ["z", "x", "c", "v", "b", "n", "m"],
54
+ };
55
+
56
+ const QWERTZ_LAYOUT = {
57
+ row1: ["q", "w", "e", "r", "t", "z", "u", "i", "o", "p"],
58
+ row2: ["a", "s", "d", "f", "g", "h", "j", "k", "l"],
59
+ row3: ["y", "x", "c", "v", "b", "n", "m"],
60
+ };
61
+
62
+ const AZERTY_LAYOUT = {
63
+ row1: ["a", "z", "e", "r", "t", "y", "u", "i", "o", "p"],
64
+ row2: ["q", "s", "d", "f", "g", "h", "j", "k", "l", "m"],
65
+ row3: ["w", "x", "c", "v", "b", "n"],
66
+ };
67
+
68
+ const NUMBER_ROW = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0"];
69
+
70
+ const getLayout = (layout: KeyboardLayout) => {
71
+ switch (layout) {
72
+ case "qwertz":
73
+ return QWERTZ_LAYOUT;
74
+ case "azerty":
75
+ return AZERTY_LAYOUT;
76
+ default:
77
+ return QWERTY_LAYOUT;
78
+ }
79
+ };
80
+
81
+ export function Keyboard({
82
+ value: controlledValue,
83
+ onChange,
84
+ onKeyPress,
85
+ disabled = false,
86
+ layout = "qwerty",
87
+ showNumbers = true,
88
+ showSymbols = true,
89
+ showShift = true,
90
+ showSpace = true,
91
+ showBackspace = true,
92
+ showEnter = false,
93
+ className,
94
+ buttonClassName,
95
+ customKeyStyle,
96
+ customKeyClassName,
97
+ capsLock: controlledCapsLock,
98
+ onCapsLockChange,
99
+ inputRef,
100
+ ...props
101
+ }: KeyboardProps) {
102
+ const [internalValue, setInternalValue] = React.useState("");
103
+ const [internalCapsLock, setInternalCapsLock] = React.useState(false);
104
+ const [shiftPressed, setShiftPressed] = React.useState(false);
105
+ const [symbolMode, setSymbolMode] = React.useState(false);
106
+ const [pressedKey, setPressedKey] = React.useState<string | null>(null);
107
+ const [inputValue, setInputValue] = React.useState("");
108
+ const pendingCursorPos = React.useRef<number | null>(null);
109
+
110
+ // Use a ref to track if virtual Caps Lock was just clicked (to prevent sync override)
111
+ const virtualCapsLockJustToggled = React.useRef(false);
112
+ // Track the last known Caps Lock state to detect changes
113
+ const lastKnownCapsLockState = React.useRef(false);
114
+
115
+ const isControlled = controlledValue !== undefined;
116
+ const value = isControlled ? controlledValue : internalValue;
117
+
118
+ // Sync inputValue with actual input value when inputRef is provided
119
+ React.useEffect(() => {
120
+ if (inputRef?.current) {
121
+ const updateInputValue = () => {
122
+ setInputValue(inputRef.current?.value ?? "");
123
+ };
124
+
125
+ // Initial sync
126
+ updateInputValue();
127
+
128
+ // Listen to input events to keep in sync
129
+ const input = inputRef.current;
130
+ input.addEventListener("input", updateInputValue);
131
+ input.addEventListener("change", updateInputValue);
132
+
133
+ return () => {
134
+ input.removeEventListener("input", updateInputValue);
135
+ input.removeEventListener("change", updateInputValue);
136
+ };
137
+ }
138
+ setInputValue(value);
139
+ return undefined;
140
+ }, [inputRef, value]);
141
+
142
+ // Restore cursor position after React re-renders
143
+ React.useEffect(() => {
144
+ if (inputRef?.current && pendingCursorPos.current !== null) {
145
+ const pos = pendingCursorPos.current;
146
+ pendingCursorPos.current = null;
147
+ // Use setTimeout to ensure React has finished rendering
148
+ setTimeout(() => {
149
+ if (inputRef?.current) {
150
+ inputRef.current.setSelectionRange(pos, pos);
151
+ }
152
+ }, 0);
153
+ }
154
+ }, [value, inputRef]);
155
+
156
+ // Get the actual input value for disabled checks
157
+ const actualInputValue = inputRef?.current ? inputValue : value;
158
+
159
+ const isCapsLockControlled = controlledCapsLock !== undefined;
160
+ const capsLock = isCapsLockControlled ? controlledCapsLock : internalCapsLock;
161
+
162
+ // Update ref when capsLock changes
163
+ React.useEffect(() => {
164
+ lastKnownCapsLockState.current = capsLock;
165
+ }, [capsLock]);
166
+
167
+ const keyboardLayout = React.useMemo(() => getLayout(layout), [layout]);
168
+
169
+ const isShiftActive = capsLock || shiftPressed;
170
+
171
+ // Map real keyboard keys to virtual keyboard keys
172
+ const mapRealKeyToVirtual = React.useCallback(
173
+ (key: string, event: KeyboardEvent): string | null => {
174
+ const keyLower = key.toLowerCase();
175
+
176
+ // Handle special keys
177
+ if (key === "Backspace" || key === "Delete") return "Backspace";
178
+ if (key === "Enter") return "Enter";
179
+ if (key === " ") return "Space";
180
+ if (key === "Tab") return "Tab";
181
+ if (key === "Shift" || key === "ShiftLeft" || key === "ShiftRight")
182
+ return "Shift";
183
+ if (key === "CapsLock") return "CapsLock";
184
+ if (key === "#" || key === "+" || key === "=") return "#+=";
185
+
186
+ // Handle numbers
187
+ if (/^[0-9]$/.test(key)) {
188
+ return symbolMode ? null : key;
189
+ }
190
+
191
+ // Handle letters
192
+ if (/^[a-z]$/i.test(key)) {
193
+ if (symbolMode) {
194
+ // In symbol mode, letters map to symbols
195
+ return null; // Symbols are shown in dedicated rows
196
+ }
197
+ return keyLower;
198
+ }
199
+
200
+ // Handle symbols when shift is pressed
201
+ if (event.shiftKey) {
202
+ const shiftSymbolMap: Record<string, string> = {
203
+ "1": ".",
204
+ "2": "@",
205
+ "3": "#",
206
+ "4": "_",
207
+ "5": "%",
208
+ "6": "^",
209
+ "7": "&",
210
+ "8": "*",
211
+ "9": "(",
212
+ "0": ")",
213
+ "-": ",",
214
+ "=": "+",
215
+ "[": "{",
216
+ "]": "}",
217
+ "\\": "|",
218
+ ";": ":",
219
+ "'": '"',
220
+ ",": "<",
221
+ ".": ">",
222
+ "/": "?",
223
+ "`": "~",
224
+ };
225
+ return shiftSymbolMap[key] || null;
226
+ }
227
+
228
+ // Handle regular symbols
229
+ const symbolMap: Record<string, string> = {
230
+ "-": "-",
231
+ "=": "=",
232
+ "[": "[",
233
+ "]": "]",
234
+ "\\": "\\",
235
+ ";": ";",
236
+ "'": "'",
237
+ ",": ",",
238
+ ".": ".",
239
+ "/": "/",
240
+ "`": "`",
241
+ };
242
+ return symbolMap[key] || null;
243
+ },
244
+ [symbolMode],
245
+ );
246
+
247
+ const handleKeyPress = React.useCallback(
248
+ (key: string) => {
249
+ if (disabled) return;
250
+
251
+ // If inputRef is provided, manipulate the input directly to handle selection
252
+ if (inputRef?.current) {
253
+ const input = inputRef.current;
254
+ const start = input.selectionStart ?? 0;
255
+ const end = input.selectionEnd ?? 0;
256
+ const currentValue = input.value;
257
+
258
+ // Replace selected text with the new key
259
+ const newValue =
260
+ currentValue.slice(0, start) + key + currentValue.slice(end);
261
+ const newCursorPos = start + key.length;
262
+
263
+ // Update our internal state first
264
+ setInputValue(newValue);
265
+
266
+ // Store cursor position to restore after React re-renders
267
+ pendingCursorPos.current = newCursorPos;
268
+
269
+ // Call onChange to update parent state - React will handle the re-render
270
+ onChange?.(newValue);
271
+ if (!isControlled) {
272
+ setInternalValue(newValue);
273
+ }
274
+
275
+ onKeyPress?.(key);
276
+ return;
277
+ }
278
+
279
+ // Fallback to old behavior if no inputRef
280
+ const newValue = value + key;
281
+ if (isControlled) {
282
+ onChange?.(newValue);
283
+ } else {
284
+ setInternalValue(newValue);
285
+ onChange?.(newValue);
286
+ }
287
+ onKeyPress?.(key);
288
+ },
289
+ [disabled, value, isControlled, onChange, onKeyPress, inputRef],
290
+ );
291
+
292
+ const handleBackspace = React.useCallback(() => {
293
+ if (disabled) return;
294
+
295
+ // If inputRef is provided, check the actual input value
296
+ if (inputRef?.current) {
297
+ const input = inputRef.current;
298
+ const start = input.selectionStart ?? 0;
299
+ const end = input.selectionEnd ?? 0;
300
+ const currentValue = input.value;
301
+
302
+ if (start === end && start === 0) return; // Nothing to delete
303
+
304
+ // Set pressed key for animation
305
+ setPressedKey("Backspace");
306
+ setTimeout(() => {
307
+ setPressedKey(null);
308
+ }, 150);
309
+
310
+ // If text is selected, delete the selection
311
+ // Otherwise, delete the character before the cursor
312
+ let newValue: string;
313
+ let newCursorPos: number;
314
+
315
+ if (start !== end) {
316
+ // Delete selected text
317
+ newValue = currentValue.slice(0, start) + currentValue.slice(end);
318
+ newCursorPos = start;
319
+ } else {
320
+ // Delete character before cursor
321
+ newValue = currentValue.slice(0, start - 1) + currentValue.slice(start);
322
+ newCursorPos = Math.max(0, start - 1);
323
+ }
324
+
325
+ // Update our internal state first
326
+ setInputValue(newValue);
327
+
328
+ // Store cursor position to restore after React re-renders
329
+ pendingCursorPos.current = newCursorPos;
330
+
331
+ // Call onChange to update parent state - React will handle the re-render
332
+ onChange?.(newValue);
333
+ if (!isControlled) {
334
+ setInternalValue(newValue);
335
+ }
336
+
337
+ onKeyPress?.("Backspace");
338
+ return;
339
+ }
340
+
341
+ // Fallback to old behavior if no inputRef
342
+ if (value.length === 0) return;
343
+
344
+ // Set pressed key for animation
345
+ setPressedKey("Backspace");
346
+ setTimeout(() => {
347
+ setPressedKey(null);
348
+ }, 150);
349
+
350
+ const newValue = value.slice(0, -1);
351
+ if (isControlled) {
352
+ onChange?.(newValue);
353
+ } else {
354
+ setInternalValue(newValue);
355
+ onChange?.(newValue);
356
+ }
357
+ onKeyPress?.("Backspace");
358
+ }, [disabled, value, isControlled, onChange, onKeyPress, inputRef]);
359
+
360
+ const handleSpace = React.useCallback(() => {
361
+ // Set pressed key for animation
362
+ setPressedKey("Space");
363
+ setTimeout(() => {
364
+ setPressedKey(null);
365
+ }, 150);
366
+ handleKeyPress(" ");
367
+ }, [handleKeyPress]);
368
+
369
+ const handleEnter = React.useCallback(() => {
370
+ if (disabled) return;
371
+
372
+ // Set pressed key for animation
373
+ setPressedKey("Enter");
374
+ setTimeout(() => {
375
+ setPressedKey(null);
376
+ }, 150);
377
+
378
+ // If inputRef is provided, handle Enter like a real keyboard
379
+ if (inputRef?.current) {
380
+ const input = inputRef?.current;
381
+ const isTextarea = input.tagName === "TEXTAREA";
382
+ const isInput = input.tagName === "INPUT";
383
+
384
+ if (isTextarea) {
385
+ // For textarea: insert newline like real keyboard
386
+ const start = input.selectionStart ?? 0;
387
+ const end = input.selectionEnd ?? 0;
388
+ const currentValue = input.value;
389
+
390
+ // Replace selected text with newline, or insert newline at cursor
391
+ const newValue =
392
+ currentValue.slice(0, start) + "\n" + currentValue.slice(end);
393
+ const newCursorPos = start + 1;
394
+
395
+ // Update input value
396
+ input.value = newValue;
397
+
398
+ // Set cursor position
399
+ input.setSelectionRange(newCursorPos, newCursorPos);
400
+
401
+ // Trigger input event for React
402
+ const inputEvent = new Event("input", { bubbles: true });
403
+ input.dispatchEvent(inputEvent);
404
+
405
+ // Update controlled/uncontrolled state
406
+ if (isControlled) {
407
+ onChange?.(newValue);
408
+ } else {
409
+ setInternalValue(newValue);
410
+ onChange?.(newValue);
411
+ }
412
+ } else if (isInput) {
413
+ // For input: trigger Enter key events like real keyboard
414
+ // This will trigger form submission if inside a form
415
+
416
+ // Create and dispatch keydown event
417
+ const keyDownEvent = new KeyboardEvent("keydown", {
418
+ key: "Enter",
419
+ code: "Enter",
420
+ keyCode: 13,
421
+ which: 13,
422
+ bubbles: true,
423
+ cancelable: true,
424
+ });
425
+ input.dispatchEvent(keyDownEvent);
426
+
427
+ // Only trigger keypress and keyup if keydown wasn't prevented
428
+ if (!keyDownEvent.defaultPrevented) {
429
+ // Create and dispatch keypress event
430
+ const keyPressEvent = new KeyboardEvent("keypress", {
431
+ key: "Enter",
432
+ code: "Enter",
433
+ keyCode: 13,
434
+ which: 13,
435
+ bubbles: true,
436
+ cancelable: true,
437
+ });
438
+ input.dispatchEvent(keyPressEvent);
439
+
440
+ // Create and dispatch keyup event
441
+ const keyUpEvent = new KeyboardEvent("keyup", {
442
+ key: "Enter",
443
+ code: "Enter",
444
+ keyCode: 13,
445
+ which: 13,
446
+ bubbles: true,
447
+ cancelable: true,
448
+ });
449
+ input.dispatchEvent(keyUpEvent);
450
+
451
+ // If input is inside a form, trigger form submit
452
+ const form = input.closest("form");
453
+ if (form && !keyPressEvent.defaultPrevented) {
454
+ // Trigger form submit event
455
+ const submitEvent = new Event("submit", {
456
+ bubbles: true,
457
+ cancelable: true,
458
+ });
459
+ form.dispatchEvent(submitEvent);
460
+
461
+ // If submit wasn't prevented, actually submit the form
462
+ if (!submitEvent.defaultPrevented) {
463
+ form.requestSubmit();
464
+ }
465
+ }
466
+ }
467
+ }
468
+
469
+ // Call onKeyPress callback
470
+ onKeyPress?.("Enter");
471
+ return;
472
+ }
473
+
474
+ // Fallback: if no inputRef, just add newline to value
475
+ const newValue = value + "\n";
476
+ if (isControlled) {
477
+ onChange?.(newValue);
478
+ } else {
479
+ setInternalValue(newValue);
480
+ onChange?.(newValue);
481
+ }
482
+ onKeyPress?.("Enter");
483
+ }, [disabled, value, isControlled, onChange, onKeyPress, inputRef]);
484
+
485
+ const toggleCapsLock = React.useCallback(() => {
486
+ // Set pressed key for animation
487
+ setPressedKey("CapsLock");
488
+ setTimeout(() => {
489
+ setPressedKey(null);
490
+ }, 150);
491
+
492
+ // Set flag to prevent sync from overriding our toggle for a short period
493
+ virtualCapsLockJustToggled.current = true;
494
+
495
+ // Always use functional update to get the latest state
496
+ if (isCapsLockControlled) {
497
+ // For controlled components, use the current prop value
498
+ const currentCapsLock = controlledCapsLock ?? false;
499
+ const newCapsLock = !currentCapsLock;
500
+ lastKnownCapsLockState.current = newCapsLock;
501
+ onCapsLockChange?.(newCapsLock);
502
+ } else {
503
+ // For uncontrolled components, use functional update to avoid stale closures
504
+ setInternalCapsLock((prev) => {
505
+ const newCapsLock = !prev;
506
+ lastKnownCapsLockState.current = newCapsLock;
507
+ onCapsLockChange?.(newCapsLock);
508
+ return newCapsLock;
509
+ });
510
+ }
511
+
512
+ // Reset flag after a delay to allow sync again
513
+ setTimeout(() => {
514
+ virtualCapsLockJustToggled.current = false;
515
+ }, 200);
516
+ }, [isCapsLockControlled, onCapsLockChange, controlledCapsLock]);
517
+
518
+ const toggleSymbolMode = React.useCallback(() => {
519
+ // Set pressed key for animation
520
+ setPressedKey("#+=");
521
+ setTimeout(() => {
522
+ setPressedKey(null);
523
+ }, 150);
524
+ setSymbolMode((prev) => !prev);
525
+ }, []);
526
+
527
+ // Listen to real keyboard events and sync Caps Lock state
528
+ React.useEffect(() => {
529
+ if (disabled) return;
530
+
531
+ const handleKeyDown = (event: KeyboardEvent) => {
532
+ // Handle Caps Lock key press on physical keyboard
533
+ if (event.key === "CapsLock" || event.key === "Caps") {
534
+ setPressedKey("CapsLock");
535
+ virtualCapsLockJustToggled.current = false; // Reset flag - physical keyboard takes priority
536
+
537
+ // When Caps Lock is pressed, the state changes AFTER this event
538
+ // So we toggle based on the last known state
539
+ const newCapsLock = !lastKnownCapsLockState.current;
540
+ lastKnownCapsLockState.current = newCapsLock;
541
+
542
+ if (!isCapsLockControlled) {
543
+ setInternalCapsLock(newCapsLock);
544
+ onCapsLockChange?.(newCapsLock);
545
+ } else {
546
+ onCapsLockChange?.(newCapsLock);
547
+ }
548
+ return;
549
+ }
550
+
551
+ // Sync with browser's actual caps lock state on any key press
552
+ // This ensures we stay in sync with physical keyboard
553
+ // But skip if virtual Caps Lock was just toggled (to prevent override)
554
+ if (!virtualCapsLockJustToggled.current) {
555
+ const browserCapsLock = event.getModifierState("CapsLock");
556
+
557
+ // Only update if state has actually changed
558
+ if (browserCapsLock !== lastKnownCapsLockState.current) {
559
+ lastKnownCapsLockState.current = browserCapsLock;
560
+
561
+ if (!isCapsLockControlled) {
562
+ setInternalCapsLock(browserCapsLock);
563
+ onCapsLockChange?.(browserCapsLock);
564
+ } else {
565
+ onCapsLockChange?.(browserCapsLock);
566
+ }
567
+ }
568
+ }
569
+
570
+ const virtualKey = mapRealKeyToVirtual(event.key, event);
571
+ if (virtualKey) {
572
+ setPressedKey(virtualKey);
573
+ }
574
+ };
575
+
576
+ const handleKeyUp = (event: KeyboardEvent) => {
577
+ setPressedKey(null);
578
+
579
+ // Also check Caps Lock state on keyup to catch any changes
580
+ if (!virtualCapsLockJustToggled.current) {
581
+ const browserCapsLock = event.getModifierState("CapsLock");
582
+ if (browserCapsLock !== lastKnownCapsLockState.current) {
583
+ lastKnownCapsLockState.current = browserCapsLock;
584
+
585
+ if (!isCapsLockControlled) {
586
+ setInternalCapsLock(browserCapsLock);
587
+ onCapsLockChange?.(browserCapsLock);
588
+ } else {
589
+ onCapsLockChange?.(browserCapsLock);
590
+ }
591
+ }
592
+ }
593
+ };
594
+
595
+ window.addEventListener("keydown", handleKeyDown);
596
+ window.addEventListener("keyup", handleKeyUp);
597
+
598
+ return () => {
599
+ window.removeEventListener("keydown", handleKeyDown);
600
+ window.removeEventListener("keyup", handleKeyUp);
601
+ };
602
+ }, [disabled, mapRealKeyToVirtual, isCapsLockControlled, onCapsLockChange]);
603
+
604
+ // Helper to animate key press
605
+ const animateKeyPress = React.useCallback((key: string) => {
606
+ setPressedKey(key);
607
+ setTimeout(() => setPressedKey(null), 150);
608
+ }, []);
609
+
610
+ const formatKey = (key: string): string => {
611
+ if (symbolMode) {
612
+ const symbolMap: Record<string, string> = {
613
+ q: "[",
614
+ w: "]",
615
+ e: "\\",
616
+ r: ";",
617
+ t: "'",
618
+ y: ",",
619
+ u: ".",
620
+ i: "/",
621
+ o: "=",
622
+ p: "-",
623
+ a: "{",
624
+ s: "}",
625
+ d: ":",
626
+ f: '"',
627
+ g: "<",
628
+ h: ">",
629
+ j: "?",
630
+ k: "+",
631
+ l: "_",
632
+ z: "|",
633
+ x: "~",
634
+ c: "`",
635
+ v: "|",
636
+ b: "~",
637
+ n: "`",
638
+ m: "|",
639
+ };
640
+ return symbolMap[key.toLowerCase()] || key;
641
+ }
642
+ return isShiftActive ? key.toUpperCase() : key.toLowerCase();
643
+ };
644
+
645
+ const getNumberSymbol = (num: string, shift: boolean): string => {
646
+ if (!shift) return num;
647
+ const symbols: Record<string, string> = {
648
+ "1": ".",
649
+ "2": "@",
650
+ "3": "#",
651
+ "4": "_",
652
+ "5": "%",
653
+ "6": "^",
654
+ "7": "&",
655
+ "8": "*",
656
+ "9": "(",
657
+ "0": ")",
658
+ };
659
+ return symbols[num] || num;
660
+ };
661
+
662
+ // Helper component for key buttons
663
+ const KeyButton = React.useCallback(
664
+ ({
665
+ children,
666
+ onClick,
667
+ isPressed = false,
668
+ className = "",
669
+ compact = false,
670
+ }: {
671
+ children: React.ReactNode;
672
+ onClick: () => void;
673
+ isPressed?: boolean;
674
+ className?: string;
675
+ compact?: boolean;
676
+ }) => (
677
+ <Button
678
+ type="button"
679
+ disabled={disabled}
680
+ onClick={onClick}
681
+ style={customKeyStyle}
682
+ className={cn(
683
+ compact ? KEY_BUTTON_COMPACT_CLASSES : KEY_BUTTON_BASE_CLASSES,
684
+ isPressed && PRESSED_KEY_CLASSES,
685
+ buttonClassName,
686
+ customKeyClassName,
687
+ className
688
+ )}
689
+ >
690
+ {children}
691
+ </Button>
692
+ ),
693
+ [disabled, customKeyStyle, buttonClassName, customKeyClassName]
694
+ );
695
+
696
+ // Helper component for symbol buttons
697
+ const SymbolButton = React.useCallback(
698
+ ({ sym }: { sym: string }) => {
699
+ const isPressed = pressedKey === sym;
700
+ return (
701
+ <KeyButton
702
+ isPressed={isPressed}
703
+ onClick={() => {
704
+ animateKeyPress(sym);
705
+ handleKeyPress(sym);
706
+ }}
707
+ >
708
+ {sym}
709
+ </KeyButton>
710
+ );
711
+ },
712
+ [pressedKey, animateKeyPress, handleKeyPress, KeyButton]
713
+ );
714
+
715
+ // Helper component for letter buttons
716
+ const LetterButton = React.useCallback(
717
+ ({ keyChar }: { keyChar: string }) => {
718
+ const displayChar = formatKey(keyChar);
719
+ const isPressed = pressedKey === keyChar.toLowerCase();
720
+ return (
721
+ <KeyButton
722
+ isPressed={isPressed}
723
+ onClick={() => {
724
+ animateKeyPress(keyChar.toLowerCase());
725
+ handleKeyPress(displayChar);
726
+ if (shiftPressed) setShiftPressed(false);
727
+ }}
728
+ >
729
+ {displayChar}
730
+ </KeyButton>
731
+ );
732
+ },
733
+ [
734
+ pressedKey,
735
+ shiftPressed,
736
+ animateKeyPress,
737
+ handleKeyPress,
738
+ formatKey,
739
+ KeyButton,
740
+ ]
741
+ );
742
+
743
+ return (
744
+ <div
745
+ className={cn(
746
+ "flex flex-col gap-3 p-6 bg-background border border-border rounded-lg shadow-sm",
747
+ className,
748
+ )}
749
+ {...props}
750
+ >
751
+ {/* Number row - hidden when symbol mode is active */}
752
+ {showNumbers && (
753
+ <div className="flex gap-3 justify-center">
754
+ {NUMBER_ROW.map((num) => {
755
+ const displayChar = shiftPressed ? getNumberSymbol(num, true) : num;
756
+ const isPressed = pressedKey === num;
757
+ return (
758
+ <KeyButton
759
+ key={num}
760
+ isPressed={isPressed}
761
+ onClick={() => {
762
+ animateKeyPress(num);
763
+ handleKeyPress(displayChar);
764
+ if (shiftPressed) setShiftPressed(false);
765
+ }}
766
+ >
767
+ {displayChar}
768
+ </KeyButton>
769
+ );
770
+ })}
771
+ </div>
772
+ )}
773
+
774
+ {/* Symbol rows - shows when symbol mode is active */}
775
+ {symbolMode && (
776
+ <>
777
+ {/* Row 1: Special symbols - 10 keys balanced */}
778
+ <div className="flex gap-3 justify-center">
779
+ {["!", "@", "#", "$", "%", "^", "&", "*", "(", ")"].map((sym) => (
780
+ <SymbolButton key={sym} sym={sym} />
781
+ ))}
782
+ </div>
783
+ {/* Row 2: Brackets and quotes - 10 keys balanced */}
784
+ <div className="flex gap-3 justify-center">
785
+ {["[", "]", "{", "}", "|", "\\", ";", ":", "'", '"'].map((sym) => (
786
+ <SymbolButton key={sym} sym={sym} />
787
+ ))}
788
+ </div>
789
+ {/* Row 3: Punctuation and operators - 9 keys */}
790
+ <div className="flex gap-3 justify-center">
791
+ {[",", ".", "/", "?", "+", "-", "=", "_", "~"].map((sym) => (
792
+ <SymbolButton key={sym} sym={sym} />
793
+ ))}
794
+ {showBackspace && (
795
+ <button
796
+ type="button"
797
+ disabled={disabled || actualInputValue.length === 0}
798
+ onClick={handleBackspace}
799
+ style={customKeyStyle}
800
+ className={cn(
801
+ BACKSPACE_BUTTON_CLASSES,
802
+ buttonClassName,
803
+ customKeyClassName
804
+ )}
805
+ >
806
+ <Delete className="mx-auto h-6 w-6" />
807
+ </button>
808
+ )}
809
+ </div>
810
+ </>
811
+ )}
812
+
813
+ {/* Letter rows - hidden when symbol mode is active */}
814
+ {!symbolMode && (
815
+ <>
816
+ {/* Row 1 - Letter row Q-P */}
817
+ <div className="flex gap-3 justify-center">
818
+ {keyboardLayout.row1.map((keyChar) => (
819
+ <LetterButton key={keyChar} keyChar={keyChar} />
820
+ ))}
821
+ </div>
822
+
823
+ {/* Row 2 */}
824
+ <div className="flex gap-3 justify-center">
825
+ {keyboardLayout.row2.map((keyChar) => (
826
+ <LetterButton key={keyChar} keyChar={keyChar} />
827
+ ))}
828
+ </div>
829
+ </>
830
+ )}
831
+
832
+ {/* Row 3 - Bottom letter row with controls */}
833
+ <div className="flex gap-3 justify-center">
834
+ {!symbolMode && (
835
+ <>
836
+ {showShift && (
837
+ <KeyButton
838
+ compact
839
+ isPressed={pressedKey === "CapsLock" && !capsLock}
840
+ onClick={toggleCapsLock}
841
+ className={capsLock ? ACTIVE_TOGGLE_CLASSES : ""}
842
+ >
843
+ <ArrowLeft className="h-6 w-6 rotate-90" />
844
+ </KeyButton>
845
+ )}
846
+ {keyboardLayout.row3.map((keyChar) => (
847
+ <LetterButton key={keyChar} keyChar={keyChar} />
848
+ ))}
849
+ {showBackspace && (
850
+ <button
851
+ type="button"
852
+ disabled={disabled || actualInputValue.length === 0}
853
+ onClick={handleBackspace}
854
+ style={customKeyStyle}
855
+ className={cn(
856
+ BACKSPACE_BUTTON_CLASSES,
857
+ buttonClassName,
858
+ customKeyClassName
859
+ )}
860
+ >
861
+ <Delete className="mx-auto h-6 w-6" />
862
+ </button>
863
+ )}
864
+ </>
865
+ )}
866
+ </div>
867
+
868
+ {/* Bottom row */}
869
+ <div className="flex gap-3 justify-center">
870
+ <KeyButton
871
+ compact
872
+ isPressed={pressedKey === "#+=" && !symbolMode}
873
+ onClick={toggleSymbolMode}
874
+ className={symbolMode ? ACTIVE_TOGGLE_CLASSES : ""}
875
+ >
876
+ #+=
877
+ </KeyButton>
878
+ {showSpace && (
879
+ <Button
880
+ type="button"
881
+ disabled={disabled}
882
+ onClick={handleSpace}
883
+ style={customKeyStyle}
884
+ className={cn(
885
+ SPACE_BUTTON_CLASSES,
886
+ pressedKey === "Space" && PRESSED_KEY_CLASSES,
887
+ buttonClassName,
888
+ customKeyClassName
889
+ )}
890
+ >
891
+ Space
892
+ </Button>
893
+ )}
894
+ {showEnter && (
895
+ <Button
896
+ type="button"
897
+ disabled={disabled}
898
+ onClick={handleEnter}
899
+ style={customKeyStyle}
900
+ className={cn(
901
+ ENTER_BUTTON_CLASSES,
902
+ buttonClassName,
903
+ customKeyClassName
904
+ )}
905
+ >
906
+ <CornerDownLeft className="mx-auto h-6 w-6" />
907
+ </Button>
908
+ )}
909
+ </div>
910
+ </div>
911
+ );
912
+ }
913
+
914
+ Keyboard.displayName = "Keyboard";
915
+
916
+ export default Keyboard;