@k3-universe/react-kit 0.0.40 → 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 (704) 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 +40 -15
  9. package/dist/kit/builder/auth/hooks/core-hooks.d.ts.map +1 -1
  10. package/dist/kit/builder/form/components/FormBuilder.d.ts.map +1 -1
  11. package/dist/kit/builder/form/components/fields/AutocompleteField.d.ts.map +1 -1
  12. package/dist/kit/builder/form/components/fields/DatePickerField.d.ts.map +1 -1
  13. package/dist/kit/builder/form/components/fields/DateRangePickerField.d.ts.map +1 -1
  14. package/dist/kit/builder/form/components/sectionNodes.d.ts +1 -0
  15. package/dist/kit/builder/form/components/sectionNodes.d.ts.map +1 -1
  16. package/dist/kit/builder/form/types.d.ts +3 -1
  17. package/dist/kit/builder/form/types.d.ts.map +1 -1
  18. package/dist/kit/components/autocomplete/Autocomplete.d.ts +2 -1
  19. package/dist/kit/components/autocomplete/Autocomplete.d.ts.map +1 -1
  20. package/dist/kit/layouts/admin/hooks/menu.d.ts.map +1 -1
  21. package/dist/kit/themes/clean-slate.css +4 -8
  22. package/dist/kit/themes/default.css +5 -9
  23. package/dist/kit/themes/minimal-modern.css +4 -8
  24. package/dist/kit/themes/spotify.css +4 -8
  25. package/package.json +1 -1
  26. package/src/index.ts +99 -99
  27. package/src/kit/builder/auth/components/Can.tsx +27 -27
  28. package/src/kit/builder/auth/components/RequireAuth.tsx +78 -78
  29. package/src/kit/builder/auth/components/ShowWhenAuthenticated.tsx +10 -10
  30. package/src/kit/builder/auth/components/ShowWhenError.tsx +10 -10
  31. package/src/kit/builder/auth/components/ShowWhenLoading.tsx +10 -10
  32. package/src/kit/builder/auth/components/ShowWhenUnauthenticated.tsx +10 -10
  33. package/src/kit/builder/auth/components/withPermission.tsx +23 -23
  34. package/src/kit/builder/auth/hooks/action-hooks.ts +34 -34
  35. package/src/kit/builder/auth/hooks/core-hooks.ts +65 -65
  36. package/src/kit/builder/auth/hooks/index.ts +4 -4
  37. package/src/kit/builder/auth/hooks/permission-hooks.ts +43 -43
  38. package/src/kit/builder/auth/hooks/token-hooks.ts +25 -25
  39. package/src/kit/builder/auth/index.ts +132 -132
  40. package/src/kit/builder/auth/providers/AuthProvider.tsx +131 -131
  41. package/src/kit/builder/auth/types/adapter-config.ts +44 -44
  42. package/src/kit/builder/auth/types/adapter.ts +132 -132
  43. package/src/kit/builder/auth/types/core.ts +27 -27
  44. package/src/kit/builder/auth/types/index.ts +9 -9
  45. package/src/kit/builder/auth/types/middleware.ts +20 -20
  46. package/src/kit/builder/auth/types/permissions.ts +23 -23
  47. package/src/kit/builder/auth/types/state.ts +16 -16
  48. package/src/kit/builder/auth/types/storage.ts +21 -21
  49. package/src/kit/builder/auth/types/token-manager.ts +9 -9
  50. package/src/kit/builder/auth/types/utils.ts +55 -55
  51. package/src/kit/builder/auth/utils/auth-adapter.ts +437 -437
  52. package/src/kit/builder/auth/utils/client-adapters/apollo-link.ts +30 -30
  53. package/src/kit/builder/auth/utils/client-adapters/axios.ts +61 -61
  54. package/src/kit/builder/auth/utils/client-adapters/fetch.ts +48 -48
  55. package/src/kit/builder/auth/utils/client-adapters/graphql.ts +60 -60
  56. package/src/kit/builder/auth/utils/client-adapters/index.ts +6 -6
  57. package/src/kit/builder/auth/utils/client-adapters/rest.ts +60 -60
  58. package/src/kit/builder/auth/utils/client-adapters/urql-exchange.ts +76 -76
  59. package/src/kit/builder/auth/utils/permission-checker.ts +150 -150
  60. package/src/kit/builder/auth/utils/storage/browser.ts +99 -99
  61. package/src/kit/builder/auth/utils/storage/cookie.ts +116 -116
  62. package/src/kit/builder/auth/utils/storage/encryption.ts +80 -80
  63. package/src/kit/builder/auth/utils/storage/env.ts +2 -2
  64. package/src/kit/builder/auth/utils/storage/factory.ts +37 -37
  65. package/src/kit/builder/auth/utils/storage/index.ts +6 -6
  66. package/src/kit/builder/auth/utils/storage/memory.ts +15 -15
  67. package/src/kit/builder/auth/utils/token-manager.ts +55 -55
  68. package/src/kit/builder/data-table/components/DataTable.tsx +547 -547
  69. package/src/kit/builder/data-table/components/DataTableColumnHeader.tsx +67 -67
  70. package/src/kit/builder/data-table/components/DataTablePagination.tsx +112 -112
  71. package/src/kit/builder/data-table/components/DataTableViewOptions.tsx +51 -51
  72. package/src/kit/builder/data-table/index.ts +6 -6
  73. package/src/kit/builder/data-table/types.ts +44 -44
  74. package/src/kit/builder/data-table/utils/dotAccessor.ts +6 -6
  75. package/src/kit/builder/dialog/index.ts +6 -6
  76. package/src/kit/builder/dialog/provider.tsx +170 -170
  77. package/src/kit/builder/form/components/FormBuilder.tsx +295 -289
  78. package/src/kit/builder/form/components/FormBuilderActions.tsx +78 -78
  79. package/src/kit/builder/form/components/FormBuilderContext.tsx +52 -52
  80. package/src/kit/builder/form/components/FormBuilderField.tsx +456 -456
  81. package/src/kit/builder/form/components/fields/ArrayField.tsx +311 -311
  82. package/src/kit/builder/form/components/fields/AutocompleteField.tsx +89 -88
  83. package/src/kit/builder/form/components/fields/CheckboxField.tsx +65 -65
  84. package/src/kit/builder/form/components/fields/DateField.tsx +26 -26
  85. package/src/kit/builder/form/components/fields/DatePickerField.tsx +31 -29
  86. package/src/kit/builder/form/components/fields/DateRangePickerField.tsx +55 -46
  87. package/src/kit/builder/form/components/fields/DateTimePickerField.tsx +38 -38
  88. package/src/kit/builder/form/components/fields/DateTimeRangePickerField.tsx +48 -48
  89. package/src/kit/builder/form/components/fields/FileField.tsx +31 -31
  90. package/src/kit/builder/form/components/fields/MonthPickerField.tsx +33 -33
  91. package/src/kit/builder/form/components/fields/MonthRangePickerField.tsx +41 -41
  92. package/src/kit/builder/form/components/fields/NumberField.tsx +20 -20
  93. package/src/kit/builder/form/components/fields/ObjectField.tsx +35 -35
  94. package/src/kit/builder/form/components/fields/RadioField.tsx +47 -47
  95. package/src/kit/builder/form/components/fields/SelectField.tsx +46 -46
  96. package/src/kit/builder/form/components/fields/SwitchField.tsx +65 -65
  97. package/src/kit/builder/form/components/fields/TextField.tsx +25 -25
  98. package/src/kit/builder/form/components/fields/TextareaField.tsx +20 -20
  99. package/src/kit/builder/form/components/fields/TimePickerField.tsx +35 -35
  100. package/src/kit/builder/form/components/fields/TimeRangePickerField.tsx +43 -43
  101. package/src/kit/builder/form/components/fields/index.ts +21 -21
  102. package/src/kit/builder/form/components/fields/types.ts +18 -18
  103. package/src/kit/builder/form/components/index.ts +3 -3
  104. package/src/kit/builder/form/components/sectionNodes.tsx +147 -144
  105. package/src/kit/builder/form/hooks/useFormBuilder.ts +451 -451
  106. package/src/kit/builder/form/index.ts +4 -4
  107. package/src/kit/builder/form/types.ts +245 -243
  108. package/src/kit/builder/form/utils/common-forms.ts +68 -68
  109. package/src/kit/builder/form/utils/dependencies.ts +56 -56
  110. package/src/kit/builder/form/utils/field-factories.ts +177 -177
  111. package/src/kit/builder/form/utils/index.ts +17 -17
  112. package/src/kit/builder/form/utils/section-factories.ts +38 -38
  113. package/src/kit/builder/form/utils/transformers.ts +100 -100
  114. package/src/kit/builder/form/utils/validations.ts +22 -22
  115. package/src/kit/builder/form/utils/validators.ts +20 -20
  116. package/src/kit/builder/page/Page.tsx +202 -202
  117. package/src/kit/builder/page/index.ts +1 -1
  118. package/src/kit/builder/section/SectionBuilder.tsx +435 -435
  119. package/src/kit/builder/section/SectionContainer.tsx +85 -85
  120. package/src/kit/builder/section/index.ts +2 -2
  121. package/src/kit/builder/section/types.ts +80 -80
  122. package/src/kit/builder/stack-dialog/context.ts +15 -15
  123. package/src/kit/builder/stack-dialog/hooks.ts +13 -13
  124. package/src/kit/builder/stack-dialog/index.ts +12 -12
  125. package/src/kit/builder/stack-dialog/provider.tsx +51 -51
  126. package/src/kit/builder/stack-dialog/renderer.tsx +36 -36
  127. package/src/kit/builder/stack-dialog/types.ts +34 -34
  128. package/src/kit/components/autocomplete/Autocomplete.tsx +671 -664
  129. package/src/kit/components/autocomplete/index.ts +3 -3
  130. package/src/kit/components/autocomplete/types.ts +27 -27
  131. package/src/kit/components/datepicker/DatePicker.tsx +173 -173
  132. package/src/kit/components/datepicker/DateRangePicker.tsx +526 -526
  133. package/src/kit/components/datepicker/index.ts +2 -2
  134. package/src/kit/components/datetimepicker/DateTimePicker.tsx +420 -420
  135. package/src/kit/components/datetimepicker/DateTimeRangePicker.tsx +676 -676
  136. package/src/kit/components/datetimepicker/index.ts +2 -2
  137. package/src/kit/components/fileuploader/FileUploader.tsx +626 -626
  138. package/src/kit/components/fileuploader/index.ts +3 -3
  139. package/src/kit/components/fileuploader/types.ts +76 -76
  140. package/src/kit/components/forminfo/FormInfoError.tsx +135 -135
  141. package/src/kit/components/forminfo/index.ts +1 -1
  142. package/src/kit/components/keyboard/Keyboard.tsx +916 -916
  143. package/src/kit/components/keyboard/index.ts +4 -4
  144. package/src/kit/components/login/Login.tsx +141 -141
  145. package/src/kit/components/login/index.ts +1 -1
  146. package/src/kit/components/monthpicker/MonthInput.tsx +131 -131
  147. package/src/kit/components/monthpicker/MonthPicker.tsx +224 -224
  148. package/src/kit/components/monthpicker/MonthRangeInput.tsx +153 -153
  149. package/src/kit/components/monthpicker/MonthRangePicker.tsx +409 -409
  150. package/src/kit/components/numpad/Numpad.tsx +377 -377
  151. package/src/kit/components/numpad/index.ts +4 -4
  152. package/src/kit/components/timepicker/TimePicker.tsx +319 -319
  153. package/src/kit/components/timepicker/TimeRangePicker.tsx +368 -368
  154. package/src/kit/components/timepicker/index.ts +2 -2
  155. package/src/kit/layouts/admin/components/AdminLayout.tsx +286 -286
  156. package/src/kit/layouts/admin/components/ThemeToggle.tsx +54 -54
  157. package/src/kit/layouts/admin/hooks/menu.ts +32 -32
  158. package/src/kit/layouts/admin/providers/AdminMenuProvider.tsx +78 -78
  159. package/src/kit/layouts/admin/types/index.ts +26 -26
  160. package/src/kit/providers/ThemeProvider.tsx +90 -90
  161. package/src/kit/themes/base.css +11 -11
  162. package/src/kit/themes/clean-slate.css +155 -155
  163. package/src/kit/themes/default.css +192 -192
  164. package/src/kit/themes/minimal-modern.css +155 -155
  165. package/src/kit/themes/spotify.css +164 -164
  166. package/src/shadcn/hooks/use-mobile.ts +21 -21
  167. package/src/shadcn/lib/utils.ts +6 -6
  168. package/src/shadcn/ui/accordion.tsx +66 -66
  169. package/src/shadcn/ui/alert-dialog.tsx +157 -157
  170. package/src/shadcn/ui/alert.tsx +66 -66
  171. package/src/shadcn/ui/aspect-ratio.tsx +11 -11
  172. package/src/shadcn/ui/avatar.tsx +53 -53
  173. package/src/shadcn/ui/badge.tsx +46 -46
  174. package/src/shadcn/ui/breadcrumb.tsx +108 -108
  175. package/src/shadcn/ui/button.tsx +59 -59
  176. package/src/shadcn/ui/calendar.tsx +217 -217
  177. package/src/shadcn/ui/card.tsx +92 -92
  178. package/src/shadcn/ui/carousel.tsx +240 -240
  179. package/src/shadcn/ui/chart.tsx +353 -353
  180. package/src/shadcn/ui/checkbox.tsx +32 -32
  181. package/src/shadcn/ui/collapsible.tsx +33 -33
  182. package/src/shadcn/ui/command.tsx +184 -184
  183. package/src/shadcn/ui/context-menu.tsx +252 -252
  184. package/src/shadcn/ui/dialog.tsx +143 -143
  185. package/src/shadcn/ui/drawer.tsx +135 -135
  186. package/src/shadcn/ui/dropdown-menu.tsx +257 -257
  187. package/src/shadcn/ui/form.tsx +168 -168
  188. package/src/shadcn/ui/hover-card.tsx +44 -44
  189. package/src/shadcn/ui/input-otp.tsx +77 -77
  190. package/src/shadcn/ui/input.tsx +21 -21
  191. package/src/shadcn/ui/label.tsx +24 -24
  192. package/src/shadcn/ui/menubar.tsx +276 -276
  193. package/src/shadcn/ui/navigation-menu.tsx +168 -168
  194. package/src/shadcn/ui/pagination.tsx +127 -127
  195. package/src/shadcn/ui/popover.tsx +48 -48
  196. package/src/shadcn/ui/progress.tsx +31 -31
  197. package/src/shadcn/ui/radio-group.tsx +45 -45
  198. package/src/shadcn/ui/resizable.tsx +56 -56
  199. package/src/shadcn/ui/scroll-area.tsx +58 -58
  200. package/src/shadcn/ui/select.tsx +185 -185
  201. package/src/shadcn/ui/separator.tsx +28 -28
  202. package/src/shadcn/ui/sheet.tsx +139 -139
  203. package/src/shadcn/ui/sidebar.tsx +726 -726
  204. package/src/shadcn/ui/skeleton.tsx +13 -13
  205. package/src/shadcn/ui/slider.tsx +63 -63
  206. package/src/shadcn/ui/sonner.tsx +25 -25
  207. package/src/shadcn/ui/switch.tsx +31 -31
  208. package/src/shadcn/ui/table.tsx +116 -116
  209. package/src/shadcn/ui/tabs.tsx +66 -66
  210. package/src/shadcn/ui/textarea.tsx +18 -18
  211. package/src/shadcn/ui/toggle-group.tsx +73 -73
  212. package/src/shadcn/ui/toggle.tsx +47 -47
  213. package/src/shadcn/ui/tooltip.tsx +61 -61
  214. package/src/stories/FileUploader.stories.tsx +185 -185
  215. package/src/stories/kit/builder/DataTable.Basic.stories.tsx +71 -71
  216. package/src/stories/kit/builder/DataTable.Filters.stories.tsx +98 -98
  217. package/src/stories/kit/builder/DataTable.Pagination.stories.tsx +73 -73
  218. package/src/stories/kit/builder/DataTable.SelectionAndActions.stories.tsx +77 -77
  219. package/src/stories/kit/builder/DataTable.Sorting.stories.tsx +67 -67
  220. package/src/stories/kit/builder/Dialog.stories.tsx +90 -90
  221. package/src/stories/kit/builder/Form.ArrayLayouts.stories.tsx +177 -177
  222. package/src/stories/kit/builder/Form.Autocomplete.stories.tsx +220 -220
  223. package/src/stories/kit/builder/Form.Basic.stories.tsx +79 -79
  224. package/src/stories/kit/builder/Form.Complex.stories.tsx +569 -569
  225. package/src/stories/kit/builder/Form.DateTime.stories.tsx +70 -70
  226. package/src/stories/kit/builder/Form.Dynamic.stories.tsx +926 -926
  227. package/src/stories/kit/builder/Form.Files.stories.tsx +136 -136
  228. package/src/stories/kit/builder/Form.MultipleFormBuilder.stories.tsx +377 -377
  229. package/src/stories/kit/builder/Form.Pickers.stories.tsx +75 -75
  230. package/src/stories/kit/builder/Form.Simple.stories.tsx +91 -91
  231. package/src/stories/kit/builder/Form.Time.stories.tsx +68 -68
  232. package/src/stories/kit/builder/Page.stories.tsx +115 -115
  233. package/src/stories/kit/builder/Section.stories.tsx +282 -282
  234. package/src/stories/kit/components/Autocomplete.stories.tsx +313 -313
  235. package/src/stories/kit/components/DatePicker.stories.tsx +195 -195
  236. package/src/stories/kit/components/DateRangePicker.stories.tsx +195 -195
  237. package/src/stories/kit/components/Keyboard.stories.tsx +263 -263
  238. package/src/stories/kit/components/Login.stories.tsx +167 -167
  239. package/src/stories/kit/components/MonthPicker.stories.tsx +100 -100
  240. package/src/stories/kit/components/MonthRangePicker.stories.tsx +117 -117
  241. package/src/stories/kit/components/Numpad.stories.tsx +195 -195
  242. package/src/stories/kit/components/TimePicker.stories.tsx +71 -71
  243. package/src/stories/kit/components/TimeRangePicker.stories.tsx +43 -43
  244. package/src/stories/kit/layouts/admin/AdminLayout.Basic.stories.tsx +118 -118
  245. package/src/stories/kit/layouts/admin/AdminLayout.Collapsible.stories.tsx +81 -81
  246. package/src/stories/kit/layouts/admin/AdminLayout.Complex.stories.tsx +251 -251
  247. package/src/stories/kit/layouts/admin/AdminLayout.CustomSidebarHeaderComponent.stories.tsx +80 -80
  248. package/src/stories/kit/layouts/admin/AdminLayout.CustomSidebarTitleAndIcon.stories.tsx +70 -70
  249. package/src/stories/kit/layouts/admin/AdminLayout.HeaderSlots.stories.tsx +87 -87
  250. package/src/stories/shadcn/ui/Accordion.stories.tsx +117 -117
  251. package/src/stories/shadcn/ui/Alert.stories.tsx +36 -36
  252. package/src/stories/shadcn/ui/AlertDialog.stories.tsx +73 -73
  253. package/src/stories/shadcn/ui/AspectRatio.stories.tsx +58 -58
  254. package/src/stories/shadcn/ui/Avatar.stories.tsx +26 -26
  255. package/src/stories/shadcn/ui/Badge.stories.tsx +28 -28
  256. package/src/stories/shadcn/ui/Breadcrumb.stories.tsx +47 -47
  257. package/src/stories/shadcn/ui/Button.stories.tsx +51 -51
  258. package/src/stories/shadcn/ui/Calendar.stories.tsx +33 -33
  259. package/src/stories/shadcn/ui/Card.stories.tsx +39 -39
  260. package/src/stories/shadcn/ui/Carousel.stories.tsx +37 -37
  261. package/src/stories/shadcn/ui/Chart.stories.tsx +72 -72
  262. package/src/stories/shadcn/ui/Checkbox.stories.tsx +64 -64
  263. package/src/stories/shadcn/ui/Collapsible.stories.tsx +40 -40
  264. package/src/stories/shadcn/ui/Command.stories.tsx +53 -53
  265. package/src/stories/shadcn/ui/ContextMenu.stories.tsx +67 -67
  266. package/src/stories/shadcn/ui/Dialog.stories.tsx +45 -45
  267. package/src/stories/shadcn/ui/Drawer.stories.tsx +49 -49
  268. package/src/stories/shadcn/ui/DropdownMenu.stories.tsx +75 -75
  269. package/src/stories/shadcn/ui/Form.stories.tsx +93 -93
  270. package/src/stories/shadcn/ui/HoverCard.stories.tsx +43 -43
  271. package/src/stories/shadcn/ui/Input.stories.tsx +41 -41
  272. package/src/stories/shadcn/ui/InputOtp.stories.tsx +39 -39
  273. package/src/stories/shadcn/ui/Label.stories.tsx +29 -29
  274. package/src/stories/shadcn/ui/Menubar.stories.tsx +87 -87
  275. package/src/stories/shadcn/ui/NavigationMenu.stories.tsx +78 -78
  276. package/src/stories/shadcn/ui/Pagination.stories.tsx +51 -51
  277. package/src/stories/shadcn/ui/Popover.stories.tsx +53 -53
  278. package/src/stories/shadcn/ui/Progress.stories.tsx +30 -30
  279. package/src/stories/shadcn/ui/RadioGroup.stories.tsx +31 -31
  280. package/src/stories/shadcn/ui/Resizable.stories.tsx +55 -55
  281. package/src/stories/shadcn/ui/ScrollArea.stories.tsx +84 -84
  282. package/src/stories/shadcn/ui/Select.stories.tsx +61 -61
  283. package/src/stories/shadcn/ui/Separator.stories.tsx +35 -35
  284. package/src/stories/shadcn/ui/Sheet.stories.tsx +48 -48
  285. package/src/stories/shadcn/ui/Sidebar.stories.tsx +131 -131
  286. package/src/stories/shadcn/ui/Skeleton.stories.tsx +23 -23
  287. package/src/stories/shadcn/ui/Slider.stories.tsx +21 -21
  288. package/src/stories/shadcn/ui/Sonner.stories.tsx +49 -49
  289. package/src/stories/shadcn/ui/Switch.stories.tsx +28 -28
  290. package/src/stories/shadcn/ui/Table.stories.tsx +374 -374
  291. package/src/stories/shadcn/ui/Tabs.stories.tsx +31 -31
  292. package/src/stories/shadcn/ui/Textarea.stories.tsx +42 -42
  293. package/src/stories/shadcn/ui/Toggle.stories.tsx +44 -44
  294. package/src/stories/shadcn/ui/ToggleGroup.stories.tsx +28 -28
  295. package/src/stories/shadcn/ui/Tooltip.stories.tsx +30 -30
  296. package/tsconfig.json +20 -20
  297. package/tsconfig.lib.json +52 -52
  298. package/tsconfig.spec.json +38 -38
  299. package/vite.config.ts +93 -93
  300. package/storybook-static/assets/Accordion.stories-KU4JBR8U.js +0 -52
  301. package/storybook-static/assets/AdminLayout-CPvVCwfY.js +0 -53
  302. package/storybook-static/assets/AdminLayout.Basic.stories-DkP2UVXe.js +0 -4
  303. package/storybook-static/assets/AdminLayout.Collapsible.stories-BuuVjtpW.js +0 -4
  304. package/storybook-static/assets/AdminLayout.Complex.stories-D-k4H0hJ.js +0 -29
  305. package/storybook-static/assets/AdminLayout.CustomSidebarHeaderComponent.stories-B_0IEDd4.js +0 -9
  306. package/storybook-static/assets/AdminLayout.CustomSidebarTitleAndIcon.stories-CvAeXUyA.js +0 -4
  307. package/storybook-static/assets/AdminLayout.HeaderSlots.stories-RBFHoSZK.js +0 -7
  308. package/storybook-static/assets/Alert.stories-DKxKtIc0.js +0 -27
  309. package/storybook-static/assets/AlertDialog.stories-BqTpZ_nG.js +0 -43
  310. package/storybook-static/assets/AspectRatio.stories-DPO9QQ5F.js +0 -22
  311. package/storybook-static/assets/Autocomplete-Cpg4CaJe.js +0 -56
  312. package/storybook-static/assets/Autocomplete.stories-CWj4G5fh.js +0 -56
  313. package/storybook-static/assets/Avatar.stories-DPhov_2g.js +0 -12
  314. package/storybook-static/assets/Badge.stories-DFKrRdXq.js +0 -12
  315. package/storybook-static/assets/Breadcrumb.stories-CTE6CZUC.js +0 -25
  316. package/storybook-static/assets/Button.stories-cbt2InL-.js +0 -26
  317. package/storybook-static/assets/Calendar.stories-DRhTw_43.js +0 -3
  318. package/storybook-static/assets/Card.stories-Isf6n_K3.js +0 -15
  319. package/storybook-static/assets/Carousel.stories-Cmg0I3fR.js +0 -15
  320. package/storybook-static/assets/Chart.stories-aQ-fNijT.js +0 -126
  321. package/storybook-static/assets/Checkbox.stories-B7YMXPDc.js +0 -12
  322. package/storybook-static/assets/Collapsible.stories-BUzl17ZZ.js +0 -18
  323. package/storybook-static/assets/Combination-BdQWAuko.js +0 -41
  324. package/storybook-static/assets/Command.stories-DzBlWQs0.js +0 -30
  325. package/storybook-static/assets/ContextMenu.stories-CJlBQyXc.js +0 -31
  326. package/storybook-static/assets/DataTable.Basic.stories-BWYKFDmK.js +0 -6
  327. package/storybook-static/assets/DataTable.Filters.stories-uZdtJk8t.js +0 -21
  328. package/storybook-static/assets/DataTable.Pagination.stories-C5N1khkp.js +0 -24
  329. package/storybook-static/assets/DataTable.SelectionAndActions.stories-FhCqZKvO.js +0 -26
  330. package/storybook-static/assets/DataTable.Sorting.stories-D-k7EtRj.js +0 -6
  331. package/storybook-static/assets/Dialog.stories-C62AF-Gx.js +0 -54
  332. package/storybook-static/assets/Dialog.stories-lrjRwOus.js +0 -18
  333. package/storybook-static/assets/Drawer.stories-CGjkdJeV.js +0 -24
  334. package/storybook-static/assets/DropdownMenu.stories-DkGClRAA.js +0 -35
  335. package/storybook-static/assets/Form.ArrayLayouts.stories-C5d_062d.js +0 -130
  336. package/storybook-static/assets/Form.Autocomplete.stories-CPZPkk4o.js +0 -142
  337. package/storybook-static/assets/Form.Basic.stories-Bhcu3-3n.js +0 -58
  338. package/storybook-static/assets/Form.Complex.stories-QnXh5a7Q.js +0 -361
  339. package/storybook-static/assets/Form.Dynamic.stories-DFW6wIuT.js +0 -502
  340. package/storybook-static/assets/Form.Simple.stories-BhJcyhbE.js +0 -53
  341. package/storybook-static/assets/Form.stories-PFNsMYxO.js +0 -3
  342. package/storybook-static/assets/FormBuilder-BQBBxo_k.js +0 -5
  343. package/storybook-static/assets/HoverCard.stories-CAlQEVn8.js +0 -21
  344. package/storybook-static/assets/Input.stories-CEhODt0V.js +0 -16
  345. package/storybook-static/assets/InputOtp.stories-DSvNP4dS.js +0 -42
  346. package/storybook-static/assets/Label.stories-B3pa8ZLY.js +0 -14
  347. package/storybook-static/assets/Login.stories-C7KQkmR_.js +0 -37
  348. package/storybook-static/assets/Menubar.stories-CHXhSHxc.js +0 -44
  349. package/storybook-static/assets/MonthPicker.stories-BnrOc4fm.js +0 -99
  350. package/storybook-static/assets/MonthRangePicker.stories-55Gk1t-7.js +0 -134
  351. package/storybook-static/assets/NavigationMenu.stories-CXoS080P.js +0 -30
  352. package/storybook-static/assets/Page.stories-GdSJgZ6-.js +0 -91
  353. package/storybook-static/assets/Pagination.stories-BEBwqH4N.js +0 -29
  354. package/storybook-static/assets/Popover.stories-BICy98Cw.js +0 -15
  355. package/storybook-static/assets/Progress.stories-DECHNOME.js +0 -8
  356. package/storybook-static/assets/RadioGroup.stories-DA7-uKfV.js +0 -16
  357. package/storybook-static/assets/Resizable.stories-B99kWkH7.js +0 -25
  358. package/storybook-static/assets/ScrollArea.stories-BqvUAXqU.js +0 -12
  359. package/storybook-static/assets/Section.stories-lFMlFBQn.js +0 -277
  360. package/storybook-static/assets/SectionBuilder-BQW705x0.js +0 -1
  361. package/storybook-static/assets/Select.stories-BsKyZ6Io.js +0 -17
  362. package/storybook-static/assets/Separator.stories-BTDOaOM2.js +0 -17
  363. package/storybook-static/assets/Sheet.stories-Cam1gR6G.js +0 -24
  364. package/storybook-static/assets/Sidebar.stories-DnOa6G7y.js +0 -106
  365. package/storybook-static/assets/Skeleton.stories-BQNIuIe5.js +0 -9
  366. package/storybook-static/assets/Slider.stories-Bslq7hjq.js +0 -6
  367. package/storybook-static/assets/Sonner.stories-D34pBBtI.js +0 -18
  368. package/storybook-static/assets/Switch.stories-Puyb1-Bx.js +0 -3
  369. package/storybook-static/assets/Table.stories-ClZxAhut.js +0 -35
  370. package/storybook-static/assets/Tabs.stories-CURNTETB.js +0 -10
  371. package/storybook-static/assets/Textarea.stories-Cf1ZBrWw.js +0 -17
  372. package/storybook-static/assets/Toggle.stories-CdMHY_bi.js +0 -3
  373. package/storybook-static/assets/ToggleGroup.stories-BM68m1dX.js +0 -13
  374. package/storybook-static/assets/Tooltip.stories-DiQv64dM.js +0 -10
  375. package/storybook-static/assets/accordion-DVgwQcnw.js +0 -1
  376. package/storybook-static/assets/alert-dialog-DCUEwpqm.js +0 -7
  377. package/storybook-static/assets/avatar-BzwOE-mi.js +0 -1
  378. package/storybook-static/assets/axe-HmUsR1st.js +0 -30
  379. package/storybook-static/assets/badge-BnQWua6u.js +0 -1
  380. package/storybook-static/assets/button-0oMkiryo.js +0 -1
  381. package/storybook-static/assets/card-BJpPOzP8.js +0 -1
  382. package/storybook-static/assets/chart-column-DZGb4ZZS.js +0 -6
  383. package/storybook-static/assets/check-B9hBGj6o.js +0 -6
  384. package/storybook-static/assets/checkbox-CyIeaWHX.js +0 -1
  385. package/storybook-static/assets/chevron-down-D_37S6il.js +0 -6
  386. package/storybook-static/assets/chevron-left-BBoN0vbI.js +0 -6
  387. package/storybook-static/assets/chevron-right-B5vIMLxK.js +0 -6
  388. package/storybook-static/assets/circle-C5Lzx6Nx.js +0 -6
  389. package/storybook-static/assets/clean-slate-D1HmMFJM.css +0 -1
  390. package/storybook-static/assets/command-Csa9p8_a.js +0 -6
  391. package/storybook-static/assets/createLucideIcon-BrHXro7t.js +0 -21
  392. package/storybook-static/assets/default-CN_Fo1GY.css +0 -1
  393. package/storybook-static/assets/dependencies-ctrV69dx.js +0 -1
  394. package/storybook-static/assets/dialog-CsnqITTn.js +0 -1
  395. package/storybook-static/assets/dropdown-menu-BWxxwPHL.js +0 -1
  396. package/storybook-static/assets/ellipsis-BRS038RR.js +0 -6
  397. package/storybook-static/assets/grip-vertical-BxXG8KNA.js +0 -6
  398. package/storybook-static/assets/iframe-C9bogcIc.css +0 -1
  399. package/storybook-static/assets/iframe-v7iAhKit.js +0 -1555
  400. package/storybook-static/assets/index-0-qMRXou.js +0 -1
  401. package/storybook-static/assets/index-AvwFFKJc.js +0 -1
  402. package/storybook-static/assets/index-BVDb4dFc.js +0 -1
  403. package/storybook-static/assets/index-B_qx7A5T.js +0 -1
  404. package/storybook-static/assets/index-BdQq_4o_.js +0 -1
  405. package/storybook-static/assets/index-BfiCOk42.js +0 -1
  406. package/storybook-static/assets/index-Bv9yk470.js +0 -1
  407. package/storybook-static/assets/index-Bw1A27Kp.js +0 -1
  408. package/storybook-static/assets/index-ByqivBWx.js +0 -1
  409. package/storybook-static/assets/index-C9Ta0ZTH.js +0 -1
  410. package/storybook-static/assets/index-CDY5kTx5.js +0 -1
  411. package/storybook-static/assets/index-CGnyVRgB.js +0 -1
  412. package/storybook-static/assets/index-CGrAONsN.js +0 -1
  413. package/storybook-static/assets/index-CWjrGFAQ.js +0 -1
  414. package/storybook-static/assets/index-CwBdPBFz.js +0 -9
  415. package/storybook-static/assets/index-D8RXF03I.js +0 -1
  416. package/storybook-static/assets/index-DLIxT4Z7.js +0 -1
  417. package/storybook-static/assets/index-DW48STyt.js +0 -1
  418. package/storybook-static/assets/index-DbaA6-o1.js +0 -1
  419. package/storybook-static/assets/index-Dph_5COR.js +0 -1
  420. package/storybook-static/assets/index-DrN5n71E.js +0 -1
  421. package/storybook-static/assets/index-Tp9IdbR8.js +0 -1
  422. package/storybook-static/assets/index-WyF3-wTE.js +0 -9
  423. package/storybook-static/assets/index-XSmPROEP.js +0 -1
  424. package/storybook-static/assets/index-Z6wF44KX.js +0 -5
  425. package/storybook-static/assets/index-_RPqOjlQ.js +0 -1
  426. package/storybook-static/assets/index-jrimW4QO.js +0 -1
  427. package/storybook-static/assets/index-nqc17SX4.js +0 -1
  428. package/storybook-static/assets/input-11YRd9gD.js +0 -1
  429. package/storybook-static/assets/jsx-runtime-D_zvdyIk.js +0 -9
  430. package/storybook-static/assets/label-Do8ODIVk.js +0 -1
  431. package/storybook-static/assets/lodash-DDwpuhPG.js +0 -73
  432. package/storybook-static/assets/matchers-7Z3WT2CE-T3xScrR7.js +0 -14
  433. package/storybook-static/assets/minimal-modern-BlYVzfQU.css +0 -1
  434. package/storybook-static/assets/popover-CcciSWAw.js +0 -1
  435. package/storybook-static/assets/preload-helper-Dp1pzeXC.js +0 -1
  436. package/storybook-static/assets/radio-group-DiJ0Y_KQ.js +0 -1
  437. package/storybook-static/assets/react-18-Cr9fq_Ip.js +0 -25
  438. package/storybook-static/assets/react-icons.esm-B_ULMmNU.js +0 -1
  439. package/storybook-static/assets/refresh-cw-BmRDhIV_.js +0 -6
  440. package/storybook-static/assets/schemas-CGNYCiJ6.js +0 -18
  441. package/storybook-static/assets/section-factories-DCCY9R35.js +0 -1
  442. package/storybook-static/assets/select-DDrkxaOg.js +0 -6
  443. package/storybook-static/assets/separator-o5SAUnaJ.js +0 -1
  444. package/storybook-static/assets/settings-2-xWGvvbG6.js +0 -6
  445. package/storybook-static/assets/sheet-C7jhU3XE.js +0 -1
  446. package/storybook-static/assets/shopping-cart-BFlrufvo.js +0 -11
  447. package/storybook-static/assets/sidebar-C8hU1Mxy.js +0 -6
  448. package/storybook-static/assets/skeleton-CjDnQs43.js +0 -1
  449. package/storybook-static/assets/spotify-CUDj7g8m.css +0 -1
  450. package/storybook-static/assets/switch-CKGRuk3u.js +0 -1
  451. package/storybook-static/assets/table-CP3vMqFn.js +0 -1
  452. package/storybook-static/assets/tabs-CopK2m3j.js +0 -1
  453. package/storybook-static/assets/textarea-Dw2vruMl.js +0 -1
  454. package/storybook-static/assets/toggle-DmHbWetf.js +0 -16
  455. package/storybook-static/assets/tooltip-_LqYEYFw.js +0 -1
  456. package/storybook-static/assets/trash-2-xdbApPby.js +0 -11
  457. package/storybook-static/assets/utils-D-KgF5mV.js +0 -1
  458. package/storybook-static/assets/x-B1a4fyWM.js +0 -6
  459. package/storybook-static/favicon-wrapper.svg +0 -46
  460. package/storybook-static/favicon.svg +0 -1
  461. package/storybook-static/iframe.html +0 -687
  462. package/storybook-static/index.d.ts +0 -64
  463. package/storybook-static/index.d.ts.map +0 -1
  464. package/storybook-static/index.html +0 -166
  465. package/storybook-static/index.json +0 -1
  466. package/storybook-static/kit/builder/data-table/components/DataTable.d.ts +0 -37
  467. package/storybook-static/kit/builder/data-table/components/DataTable.d.ts.map +0 -1
  468. package/storybook-static/kit/builder/data-table/components/DataTableColumnHeader.d.ts +0 -8
  469. package/storybook-static/kit/builder/data-table/components/DataTableColumnHeader.d.ts.map +0 -1
  470. package/storybook-static/kit/builder/data-table/components/DataTablePagination.d.ts +0 -6
  471. package/storybook-static/kit/builder/data-table/components/DataTablePagination.d.ts.map +0 -1
  472. package/storybook-static/kit/builder/data-table/components/DataTableViewOptions.d.ts +0 -5
  473. package/storybook-static/kit/builder/data-table/components/DataTableViewOptions.d.ts.map +0 -1
  474. package/storybook-static/kit/builder/data-table/index.d.ts +0 -7
  475. package/storybook-static/kit/builder/data-table/index.d.ts.map +0 -1
  476. package/storybook-static/kit/builder/data-table/types.d.ts +0 -27
  477. package/storybook-static/kit/builder/data-table/types.d.ts.map +0 -1
  478. package/storybook-static/kit/builder/data-table/utils/dotAccessor.d.ts +0 -2
  479. package/storybook-static/kit/builder/data-table/utils/dotAccessor.d.ts.map +0 -1
  480. package/storybook-static/kit/builder/dialog/index.d.ts +0 -3
  481. package/storybook-static/kit/builder/dialog/index.d.ts.map +0 -1
  482. package/storybook-static/kit/builder/dialog/provider.d.ts +0 -26
  483. package/storybook-static/kit/builder/dialog/provider.d.ts.map +0 -1
  484. package/storybook-static/kit/builder/form/components/FormBuilder.d.ts +0 -137
  485. package/storybook-static/kit/builder/form/components/FormBuilder.d.ts.map +0 -1
  486. package/storybook-static/kit/builder/form/components/FormBuilderActions.d.ts +0 -20
  487. package/storybook-static/kit/builder/form/components/FormBuilderActions.d.ts.map +0 -1
  488. package/storybook-static/kit/builder/form/components/FormBuilderField.d.ts +0 -12
  489. package/storybook-static/kit/builder/form/components/FormBuilderField.d.ts.map +0 -1
  490. package/storybook-static/kit/builder/form/components/fields/ArrayField.d.ts +0 -3
  491. package/storybook-static/kit/builder/form/components/fields/ArrayField.d.ts.map +0 -1
  492. package/storybook-static/kit/builder/form/components/fields/AutocompleteField.d.ts +0 -3
  493. package/storybook-static/kit/builder/form/components/fields/AutocompleteField.d.ts.map +0 -1
  494. package/storybook-static/kit/builder/form/components/fields/CheckboxField.d.ts +0 -3
  495. package/storybook-static/kit/builder/form/components/fields/CheckboxField.d.ts.map +0 -1
  496. package/storybook-static/kit/builder/form/components/fields/DateField.d.ts +0 -3
  497. package/storybook-static/kit/builder/form/components/fields/DateField.d.ts.map +0 -1
  498. package/storybook-static/kit/builder/form/components/fields/FileField.d.ts +0 -3
  499. package/storybook-static/kit/builder/form/components/fields/FileField.d.ts.map +0 -1
  500. package/storybook-static/kit/builder/form/components/fields/NumberField.d.ts +0 -3
  501. package/storybook-static/kit/builder/form/components/fields/NumberField.d.ts.map +0 -1
  502. package/storybook-static/kit/builder/form/components/fields/ObjectField.d.ts +0 -3
  503. package/storybook-static/kit/builder/form/components/fields/ObjectField.d.ts.map +0 -1
  504. package/storybook-static/kit/builder/form/components/fields/RadioField.d.ts +0 -3
  505. package/storybook-static/kit/builder/form/components/fields/RadioField.d.ts.map +0 -1
  506. package/storybook-static/kit/builder/form/components/fields/SelectField.d.ts +0 -3
  507. package/storybook-static/kit/builder/form/components/fields/SelectField.d.ts.map +0 -1
  508. package/storybook-static/kit/builder/form/components/fields/SwitchField.d.ts +0 -3
  509. package/storybook-static/kit/builder/form/components/fields/SwitchField.d.ts.map +0 -1
  510. package/storybook-static/kit/builder/form/components/fields/TextField.d.ts +0 -3
  511. package/storybook-static/kit/builder/form/components/fields/TextField.d.ts.map +0 -1
  512. package/storybook-static/kit/builder/form/components/fields/TextareaField.d.ts +0 -3
  513. package/storybook-static/kit/builder/form/components/fields/TextareaField.d.ts.map +0 -1
  514. package/storybook-static/kit/builder/form/components/fields/index.d.ts +0 -14
  515. package/storybook-static/kit/builder/form/components/fields/index.d.ts.map +0 -1
  516. package/storybook-static/kit/builder/form/components/fields/types.d.ts +0 -14
  517. package/storybook-static/kit/builder/form/components/fields/types.d.ts.map +0 -1
  518. package/storybook-static/kit/builder/form/components/index.d.ts +0 -4
  519. package/storybook-static/kit/builder/form/components/index.d.ts.map +0 -1
  520. package/storybook-static/kit/builder/form/index.d.ts +0 -3
  521. package/storybook-static/kit/builder/form/index.d.ts.map +0 -1
  522. package/storybook-static/kit/builder/form/utils/common-forms.d.ts +0 -7
  523. package/storybook-static/kit/builder/form/utils/common-forms.d.ts.map +0 -1
  524. package/storybook-static/kit/builder/form/utils/dependencies.d.ts +0 -41
  525. package/storybook-static/kit/builder/form/utils/dependencies.d.ts.map +0 -1
  526. package/storybook-static/kit/builder/form/utils/field-factories.d.ts +0 -23
  527. package/storybook-static/kit/builder/form/utils/field-factories.d.ts.map +0 -1
  528. package/storybook-static/kit/builder/form/utils/index.d.ts +0 -15
  529. package/storybook-static/kit/builder/form/utils/index.d.ts.map +0 -1
  530. package/storybook-static/kit/builder/form/utils/section-factories.d.ts +0 -7
  531. package/storybook-static/kit/builder/form/utils/section-factories.d.ts.map +0 -1
  532. package/storybook-static/kit/builder/form/utils/transformers.d.ts +0 -6
  533. package/storybook-static/kit/builder/form/utils/transformers.d.ts.map +0 -1
  534. package/storybook-static/kit/builder/form/utils/validations.d.ts +0 -13
  535. package/storybook-static/kit/builder/form/utils/validations.d.ts.map +0 -1
  536. package/storybook-static/kit/builder/form/utils/validators.d.ts +0 -8
  537. package/storybook-static/kit/builder/form/utils/validators.d.ts.map +0 -1
  538. package/storybook-static/kit/builder/page/Page.d.ts +0 -48
  539. package/storybook-static/kit/builder/page/Page.d.ts.map +0 -1
  540. package/storybook-static/kit/builder/page/index.d.ts +0 -2
  541. package/storybook-static/kit/builder/page/index.d.ts.map +0 -1
  542. package/storybook-static/kit/builder/section/SectionBuilder.d.ts +0 -3
  543. package/storybook-static/kit/builder/section/SectionBuilder.d.ts.map +0 -1
  544. package/storybook-static/kit/builder/section/index.d.ts +0 -3
  545. package/storybook-static/kit/builder/section/index.d.ts.map +0 -1
  546. package/storybook-static/kit/builder/section/types.d.ts +0 -70
  547. package/storybook-static/kit/builder/section/types.d.ts.map +0 -1
  548. package/storybook-static/kit/builder/stack-dialog/context.d.ts +0 -3
  549. package/storybook-static/kit/builder/stack-dialog/context.d.ts.map +0 -1
  550. package/storybook-static/kit/builder/stack-dialog/hooks.d.ts +0 -6
  551. package/storybook-static/kit/builder/stack-dialog/hooks.d.ts.map +0 -1
  552. package/storybook-static/kit/builder/stack-dialog/index.d.ts +0 -5
  553. package/storybook-static/kit/builder/stack-dialog/index.d.ts.map +0 -1
  554. package/storybook-static/kit/builder/stack-dialog/provider.d.ts +0 -3
  555. package/storybook-static/kit/builder/stack-dialog/provider.d.ts.map +0 -1
  556. package/storybook-static/kit/builder/stack-dialog/renderer.d.ts +0 -6
  557. package/storybook-static/kit/builder/stack-dialog/renderer.d.ts.map +0 -1
  558. package/storybook-static/kit/builder/stack-dialog/types.d.ts +0 -20
  559. package/storybook-static/kit/builder/stack-dialog/types.d.ts.map +0 -1
  560. package/storybook-static/kit/components/autocomplete/Autocomplete.d.ts +0 -53
  561. package/storybook-static/kit/components/autocomplete/Autocomplete.d.ts.map +0 -1
  562. package/storybook-static/kit/components/autocomplete/index.d.ts +0 -4
  563. package/storybook-static/kit/components/autocomplete/index.d.ts.map +0 -1
  564. package/storybook-static/kit/components/autocomplete/types.d.ts +0 -19
  565. package/storybook-static/kit/components/autocomplete/types.d.ts.map +0 -1
  566. package/storybook-static/kit/components/login/Login.d.ts +0 -29
  567. package/storybook-static/kit/components/login/Login.d.ts.map +0 -1
  568. package/storybook-static/kit/components/login/index.d.ts +0 -2
  569. package/storybook-static/kit/components/login/index.d.ts.map +0 -1
  570. package/storybook-static/kit/components/monthpicker/MonthPicker.d.ts +0 -32
  571. package/storybook-static/kit/components/monthpicker/MonthPicker.d.ts.map +0 -1
  572. package/storybook-static/kit/components/monthpicker/MonthRangePicker.d.ts +0 -48
  573. package/storybook-static/kit/components/monthpicker/MonthRangePicker.d.ts.map +0 -1
  574. package/storybook-static/kit/layouts/admin/components/AdminLayout.d.ts +0 -17
  575. package/storybook-static/kit/layouts/admin/components/AdminLayout.d.ts.map +0 -1
  576. package/storybook-static/kit/layouts/admin/components/ThemeToggle.d.ts +0 -5
  577. package/storybook-static/kit/layouts/admin/components/ThemeToggle.d.ts.map +0 -1
  578. package/storybook-static/kit/layouts/admin/hooks/menu.d.ts +0 -13
  579. package/storybook-static/kit/layouts/admin/hooks/menu.d.ts.map +0 -1
  580. package/storybook-static/kit/layouts/admin/providers/AdminMenuProvider.d.ts +0 -7
  581. package/storybook-static/kit/layouts/admin/providers/AdminMenuProvider.d.ts.map +0 -1
  582. package/storybook-static/kit/layouts/admin/types/index.d.ts +0 -27
  583. package/storybook-static/kit/layouts/admin/types/index.d.ts.map +0 -1
  584. package/storybook-static/kit/providers/ThemeProvider.d.ts +0 -14
  585. package/storybook-static/kit/providers/ThemeProvider.d.ts.map +0 -1
  586. package/storybook-static/nunito-sans-bold-italic.woff2 +0 -0
  587. package/storybook-static/nunito-sans-bold.woff2 +0 -0
  588. package/storybook-static/nunito-sans-italic.woff2 +0 -0
  589. package/storybook-static/nunito-sans-regular.woff2 +0 -0
  590. package/storybook-static/project.json +0 -1
  591. package/storybook-static/sb-addons/a11y-5/manager-bundle.js +0 -5
  592. package/storybook-static/sb-addons/essentials-backgrounds-1/manager-bundle.js +0 -3
  593. package/storybook-static/sb-addons/essentials-measure-2/manager-bundle.js +0 -3
  594. package/storybook-static/sb-addons/essentials-outline-3/manager-bundle.js +0 -3
  595. package/storybook-static/sb-addons/interactions-4/manager-bundle.js +0 -57
  596. package/storybook-static/sb-addons/storybook-core-server-presets-0/common-manager-bundle.js +0 -971
  597. package/storybook-static/sb-addons/storysource-6/manager-bundle.js +0 -3
  598. package/storybook-static/sb-common-assets/favicon-wrapper.svg +0 -46
  599. package/storybook-static/sb-common-assets/favicon.svg +0 -1
  600. package/storybook-static/sb-common-assets/nunito-sans-bold-italic.woff2 +0 -0
  601. package/storybook-static/sb-common-assets/nunito-sans-bold.woff2 +0 -0
  602. package/storybook-static/sb-common-assets/nunito-sans-italic.woff2 +0 -0
  603. package/storybook-static/sb-common-assets/nunito-sans-regular.woff2 +0 -0
  604. package/storybook-static/sb-manager/globals-module-info.js +0 -797
  605. package/storybook-static/sb-manager/globals-runtime.js +0 -69653
  606. package/storybook-static/sb-manager/globals.js +0 -34
  607. package/storybook-static/sb-manager/runtime.js +0 -13181
  608. package/storybook-static/shadcn/hooks/use-mobile.d.ts +0 -2
  609. package/storybook-static/shadcn/hooks/use-mobile.d.ts.map +0 -1
  610. package/storybook-static/shadcn/lib/utils.d.ts +0 -3
  611. package/storybook-static/shadcn/lib/utils.d.ts.map +0 -1
  612. package/storybook-static/shadcn/ui/accordion.d.ts +0 -8
  613. package/storybook-static/shadcn/ui/accordion.d.ts.map +0 -1
  614. package/storybook-static/shadcn/ui/alert-dialog.d.ts +0 -15
  615. package/storybook-static/shadcn/ui/alert-dialog.d.ts.map +0 -1
  616. package/storybook-static/shadcn/ui/alert.d.ts +0 -10
  617. package/storybook-static/shadcn/ui/alert.d.ts.map +0 -1
  618. package/storybook-static/shadcn/ui/aspect-ratio.d.ts +0 -4
  619. package/storybook-static/shadcn/ui/aspect-ratio.d.ts.map +0 -1
  620. package/storybook-static/shadcn/ui/avatar.d.ts +0 -7
  621. package/storybook-static/shadcn/ui/avatar.d.ts.map +0 -1
  622. package/storybook-static/shadcn/ui/badge.d.ts +0 -10
  623. package/storybook-static/shadcn/ui/badge.d.ts.map +0 -1
  624. package/storybook-static/shadcn/ui/breadcrumb.d.ts +0 -12
  625. package/storybook-static/shadcn/ui/breadcrumb.d.ts.map +0 -1
  626. package/storybook-static/shadcn/ui/button.d.ts +0 -11
  627. package/storybook-static/shadcn/ui/button.d.ts.map +0 -1
  628. package/storybook-static/shadcn/ui/calendar.d.ts +0 -9
  629. package/storybook-static/shadcn/ui/calendar.d.ts.map +0 -1
  630. package/storybook-static/shadcn/ui/card.d.ts +0 -10
  631. package/storybook-static/shadcn/ui/card.d.ts.map +0 -1
  632. package/storybook-static/shadcn/ui/carousel.d.ts +0 -20
  633. package/storybook-static/shadcn/ui/carousel.d.ts.map +0 -1
  634. package/storybook-static/shadcn/ui/chart.d.ts +0 -41
  635. package/storybook-static/shadcn/ui/chart.d.ts.map +0 -1
  636. package/storybook-static/shadcn/ui/checkbox.d.ts +0 -5
  637. package/storybook-static/shadcn/ui/checkbox.d.ts.map +0 -1
  638. package/storybook-static/shadcn/ui/collapsible.d.ts +0 -6
  639. package/storybook-static/shadcn/ui/collapsible.d.ts.map +0 -1
  640. package/storybook-static/shadcn/ui/command.d.ts +0 -19
  641. package/storybook-static/shadcn/ui/command.d.ts.map +0 -1
  642. package/storybook-static/shadcn/ui/context-menu.d.ts +0 -26
  643. package/storybook-static/shadcn/ui/context-menu.d.ts.map +0 -1
  644. package/storybook-static/shadcn/ui/dialog.d.ts +0 -16
  645. package/storybook-static/shadcn/ui/dialog.d.ts.map +0 -1
  646. package/storybook-static/shadcn/ui/drawer.d.ts +0 -14
  647. package/storybook-static/shadcn/ui/drawer.d.ts.map +0 -1
  648. package/storybook-static/shadcn/ui/dropdown-menu.d.ts +0 -26
  649. package/storybook-static/shadcn/ui/dropdown-menu.d.ts.map +0 -1
  650. package/storybook-static/shadcn/ui/form.d.ts +0 -25
  651. package/storybook-static/shadcn/ui/form.d.ts.map +0 -1
  652. package/storybook-static/shadcn/ui/hover-card.d.ts +0 -7
  653. package/storybook-static/shadcn/ui/hover-card.d.ts.map +0 -1
  654. package/storybook-static/shadcn/ui/input-otp.d.ts +0 -12
  655. package/storybook-static/shadcn/ui/input-otp.d.ts.map +0 -1
  656. package/storybook-static/shadcn/ui/input.d.ts +0 -4
  657. package/storybook-static/shadcn/ui/input.d.ts.map +0 -1
  658. package/storybook-static/shadcn/ui/label.d.ts +0 -5
  659. package/storybook-static/shadcn/ui/label.d.ts.map +0 -1
  660. package/storybook-static/shadcn/ui/menubar.d.ts +0 -27
  661. package/storybook-static/shadcn/ui/menubar.d.ts.map +0 -1
  662. package/storybook-static/shadcn/ui/navigation-menu.d.ts +0 -15
  663. package/storybook-static/shadcn/ui/navigation-menu.d.ts.map +0 -1
  664. package/storybook-static/shadcn/ui/pagination.d.ts +0 -14
  665. package/storybook-static/shadcn/ui/pagination.d.ts.map +0 -1
  666. package/storybook-static/shadcn/ui/popover.d.ts +0 -8
  667. package/storybook-static/shadcn/ui/popover.d.ts.map +0 -1
  668. package/storybook-static/shadcn/ui/progress.d.ts +0 -5
  669. package/storybook-static/shadcn/ui/progress.d.ts.map +0 -1
  670. package/storybook-static/shadcn/ui/radio-group.d.ts +0 -6
  671. package/storybook-static/shadcn/ui/radio-group.d.ts.map +0 -1
  672. package/storybook-static/shadcn/ui/resizable.d.ts +0 -9
  673. package/storybook-static/shadcn/ui/resizable.d.ts.map +0 -1
  674. package/storybook-static/shadcn/ui/scroll-area.d.ts +0 -6
  675. package/storybook-static/shadcn/ui/scroll-area.d.ts.map +0 -1
  676. package/storybook-static/shadcn/ui/select.d.ts +0 -16
  677. package/storybook-static/shadcn/ui/select.d.ts.map +0 -1
  678. package/storybook-static/shadcn/ui/separator.d.ts +0 -5
  679. package/storybook-static/shadcn/ui/separator.d.ts.map +0 -1
  680. package/storybook-static/shadcn/ui/sheet.d.ts +0 -14
  681. package/storybook-static/shadcn/ui/sheet.d.ts.map +0 -1
  682. package/storybook-static/shadcn/ui/sidebar.d.ts +0 -70
  683. package/storybook-static/shadcn/ui/sidebar.d.ts.map +0 -1
  684. package/storybook-static/shadcn/ui/skeleton.d.ts +0 -3
  685. package/storybook-static/shadcn/ui/skeleton.d.ts.map +0 -1
  686. package/storybook-static/shadcn/ui/slider.d.ts +0 -5
  687. package/storybook-static/shadcn/ui/slider.d.ts.map +0 -1
  688. package/storybook-static/shadcn/ui/sonner.d.ts +0 -4
  689. package/storybook-static/shadcn/ui/sonner.d.ts.map +0 -1
  690. package/storybook-static/shadcn/ui/switch.d.ts +0 -5
  691. package/storybook-static/shadcn/ui/switch.d.ts.map +0 -1
  692. package/storybook-static/shadcn/ui/table.d.ts +0 -11
  693. package/storybook-static/shadcn/ui/table.d.ts.map +0 -1
  694. package/storybook-static/shadcn/ui/tabs.d.ts +0 -8
  695. package/storybook-static/shadcn/ui/tabs.d.ts.map +0 -1
  696. package/storybook-static/shadcn/ui/textarea.d.ts +0 -4
  697. package/storybook-static/shadcn/ui/textarea.d.ts.map +0 -1
  698. package/storybook-static/shadcn/ui/toggle-group.d.ts +0 -8
  699. package/storybook-static/shadcn/ui/toggle-group.d.ts.map +0 -1
  700. package/storybook-static/shadcn/ui/toggle.d.ts +0 -10
  701. package/storybook-static/shadcn/ui/toggle.d.ts.map +0 -1
  702. package/storybook-static/shadcn/ui/tooltip.d.ts +0 -8
  703. package/storybook-static/shadcn/ui/tooltip.d.ts.map +0 -1
  704. 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;