torch-glare 2.5.6 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (362) hide show
  1. package/README.md +4 -3
  2. package/dist/bin/index.js +9 -24
  3. package/dist/bin/index.js.map +1 -1
  4. package/dist/src/commands/add.d.ts +2 -2
  5. package/dist/src/commands/add.d.ts.map +1 -1
  6. package/dist/src/commands/add.js +4 -70
  7. package/dist/src/commands/add.js.map +1 -1
  8. package/dist/src/commands/hook.d.ts +5 -4
  9. package/dist/src/commands/hook.d.ts.map +1 -1
  10. package/dist/src/commands/hook.js +7 -75
  11. package/dist/src/commands/hook.js.map +1 -1
  12. package/dist/src/commands/init.js +1 -1
  13. package/dist/src/commands/init.js.map +1 -1
  14. package/dist/src/commands/layout.d.ts +5 -4
  15. package/dist/src/commands/layout.d.ts.map +1 -1
  16. package/dist/src/commands/layout.js +7 -75
  17. package/dist/src/commands/layout.js.map +1 -1
  18. package/dist/src/commands/provider.d.ts +5 -4
  19. package/dist/src/commands/provider.d.ts.map +1 -1
  20. package/dist/src/commands/provider.js +7 -75
  21. package/dist/src/commands/provider.js.map +1 -1
  22. package/dist/src/commands/update.d.ts.map +1 -1
  23. package/dist/src/commands/update.js +78 -43
  24. package/dist/src/commands/update.js.map +1 -1
  25. package/dist/src/commands/utils.d.ts +5 -4
  26. package/dist/src/commands/utils.d.ts.map +1 -1
  27. package/dist/src/commands/utils.js +7 -80
  28. package/dist/src/commands/utils.js.map +1 -1
  29. package/dist/src/shared/addFromRegistry.d.ts +16 -0
  30. package/dist/src/shared/addFromRegistry.d.ts.map +1 -0
  31. package/dist/src/shared/addFromRegistry.js +88 -0
  32. package/dist/src/shared/addFromRegistry.js.map +1 -0
  33. package/dist/src/shared/getInstallCommand.d.ts.map +1 -1
  34. package/dist/src/shared/getInstallCommand.js +5 -0
  35. package/dist/src/shared/getInstallCommand.js.map +1 -1
  36. package/dist/src/shared/installDependencies.d.ts +0 -10
  37. package/dist/src/shared/installDependencies.d.ts.map +1 -1
  38. package/dist/src/shared/installDependencies.js +0 -17
  39. package/dist/src/shared/installDependencies.js.map +1 -1
  40. package/dist/src/shared/installFromPlan.d.ts +7 -5
  41. package/dist/src/shared/installFromPlan.d.ts.map +1 -1
  42. package/dist/src/shared/installFromPlan.js +103 -36
  43. package/dist/src/shared/installFromPlan.js.map +1 -1
  44. package/dist/src/shared/loadRegistry.d.ts +12 -3
  45. package/dist/src/shared/loadRegistry.d.ts.map +1 -1
  46. package/dist/src/shared/loadRegistry.js +19 -20
  47. package/dist/src/shared/loadRegistry.js.map +1 -1
  48. package/dist/src/shared/registryClient.d.ts +19 -0
  49. package/dist/src/shared/registryClient.d.ts.map +1 -0
  50. package/dist/src/shared/registryClient.js +128 -0
  51. package/dist/src/shared/registryClient.js.map +1 -0
  52. package/dist/src/shared/resolveEntry.d.ts +10 -7
  53. package/dist/src/shared/resolveEntry.d.ts.map +1 -1
  54. package/dist/src/shared/resolveEntry.js +18 -13
  55. package/dist/src/shared/resolveEntry.js.map +1 -1
  56. package/dist/src/shared/suggestOtherCommand.d.ts +7 -1
  57. package/dist/src/shared/suggestOtherCommand.d.ts.map +1 -1
  58. package/dist/src/shared/suggestOtherCommand.js +29 -23
  59. package/dist/src/shared/suggestOtherCommand.js.map +1 -1
  60. package/dist/src/types/main.d.ts +31 -2
  61. package/dist/src/types/main.d.ts.map +1 -1
  62. package/package.json +6 -11
  63. package/apps/lib/components/ActionButton.tsx +0 -93
  64. package/apps/lib/components/ActionsGroup.tsx +0 -27
  65. package/apps/lib/components/AlertDialog.tsx +0 -204
  66. package/apps/lib/components/Avatar.tsx +0 -46
  67. package/apps/lib/components/Badge.tsx +0 -250
  68. package/apps/lib/components/BadgeField.tsx +0 -403
  69. package/apps/lib/components/Breadcrumb.tsx +0 -280
  70. package/apps/lib/components/Button.tsx +0 -325
  71. package/apps/lib/components/ButtonGroup.tsx +0 -190
  72. package/apps/lib/components/Calendar.tsx +0 -115
  73. package/apps/lib/components/Card.tsx +0 -95
  74. package/apps/lib/components/Checkbox.tsx +0 -42
  75. package/apps/lib/components/ColorPicker.tsx +0 -441
  76. package/apps/lib/components/ConclusionHeader.tsx +0 -148
  77. package/apps/lib/components/ContextMenu.tsx +0 -571
  78. package/apps/lib/components/CountBadge.tsx +0 -52
  79. package/apps/lib/components/DataTable.tsx +0 -213
  80. package/apps/lib/components/DataViews/badge.ts +0 -49
  81. package/apps/lib/components/DataViews/cell.tsx +0 -324
  82. package/apps/lib/components/DataViews/context.ts +0 -144
  83. package/apps/lib/components/DataViews/data-views.tsx +0 -395
  84. package/apps/lib/components/DataViews/filters/children.tsx +0 -98
  85. package/apps/lib/components/DataViews/filters/custom.tsx +0 -34
  86. package/apps/lib/components/DataViews/filters/filters.tsx +0 -157
  87. package/apps/lib/components/DataViews/filters/index.ts +0 -4
  88. package/apps/lib/components/DataViews/filters/labelled.tsx +0 -20
  89. package/apps/lib/components/DataViews/filters/presets.tsx +0 -65
  90. package/apps/lib/components/DataViews/filters/sync.tsx +0 -35
  91. package/apps/lib/components/DataViews/filters/values.ts +0 -173
  92. package/apps/lib/components/DataViews/header.tsx +0 -220
  93. package/apps/lib/components/DataViews/hooks/index.ts +0 -5
  94. package/apps/lib/components/DataViews/hooks/useActiveRow.ts +0 -22
  95. package/apps/lib/components/DataViews/hooks/useControllable.ts +0 -52
  96. package/apps/lib/components/DataViews/index.ts +0 -88
  97. package/apps/lib/components/DataViews/panel/columns.tsx +0 -153
  98. package/apps/lib/components/DataViews/panel/controls.tsx +0 -106
  99. package/apps/lib/components/DataViews/panel/index.ts +0 -3
  100. package/apps/lib/components/DataViews/panel/panel.tsx +0 -164
  101. package/apps/lib/components/DataViews/panel/saved-views.tsx +0 -67
  102. package/apps/lib/components/DataViews/panel/section.tsx +0 -81
  103. package/apps/lib/components/DataViews/panel/sort.tsx +0 -42
  104. package/apps/lib/components/DataViews/panel/tab.tsx +0 -31
  105. package/apps/lib/components/DataViews/slots.ts +0 -72
  106. package/apps/lib/components/DataViews/states.tsx +0 -73
  107. package/apps/lib/components/DataViews/types.ts +0 -510
  108. package/apps/lib/components/DataViews/views/board-view.tsx +0 -381
  109. package/apps/lib/components/DataViews/views/card-rows.tsx +0 -36
  110. package/apps/lib/components/DataViews/views/inbox-view.tsx +0 -260
  111. package/apps/lib/components/DataViews/views/pane-views.tsx +0 -196
  112. package/apps/lib/components/DataViews/views/table-view.tsx +0 -493
  113. package/apps/lib/components/DataViews/views/tree-view.tsx +0 -367
  114. package/apps/lib/components/DatePicker.tsx +0 -232
  115. package/apps/lib/components/Dialog.tsx +0 -116
  116. package/apps/lib/components/Divider.tsx +0 -28
  117. package/apps/lib/components/Drawer.tsx +0 -451
  118. package/apps/lib/components/DropdownMenu.tsx +0 -554
  119. package/apps/lib/components/FieldHint.tsx +0 -69
  120. package/apps/lib/components/Form.tsx +0 -182
  121. package/apps/lib/components/FormBuilder/context.ts +0 -85
  122. package/apps/lib/components/FormBuilder/field-kind.ts +0 -28
  123. package/apps/lib/components/FormBuilder/fields/ChoiceFields.tsx +0 -60
  124. package/apps/lib/components/FormBuilder/fields/ColorField.tsx +0 -59
  125. package/apps/lib/components/FormBuilder/fields/CustomField.tsx +0 -11
  126. package/apps/lib/components/FormBuilder/fields/DateField.tsx +0 -32
  127. package/apps/lib/components/FormBuilder/fields/FieldArray.tsx +0 -74
  128. package/apps/lib/components/FormBuilder/fields/FieldShell.tsx +0 -168
  129. package/apps/lib/components/FormBuilder/fields/FileField.tsx +0 -39
  130. package/apps/lib/components/FormBuilder/fields/OptionListFields.tsx +0 -132
  131. package/apps/lib/components/FormBuilder/fields/OtpField.tsx +0 -31
  132. package/apps/lib/components/FormBuilder/fields/PhoneField.tsx +0 -109
  133. package/apps/lib/components/FormBuilder/fields/RichTextEditorField.tsx +0 -31
  134. package/apps/lib/components/FormBuilder/fields/SelectField.tsx +0 -114
  135. package/apps/lib/components/FormBuilder/fields/SignatureField.tsx +0 -157
  136. package/apps/lib/components/FormBuilder/fields/SliderField.tsx +0 -67
  137. package/apps/lib/components/FormBuilder/fields/SwitchBoxField.tsx +0 -41
  138. package/apps/lib/components/FormBuilder/fields/TableField.tsx +0 -336
  139. package/apps/lib/components/FormBuilder/fields/TextField.tsx +0 -213
  140. package/apps/lib/components/FormBuilder/fields/TreeSelectField.tsx +0 -43
  141. package/apps/lib/components/FormBuilder/fields/countries.ts +0 -303
  142. package/apps/lib/components/FormBuilder/fields/index.ts +0 -25
  143. package/apps/lib/components/FormBuilder/form-builder.tsx +0 -198
  144. package/apps/lib/components/FormBuilder/index.ts +0 -31
  145. package/apps/lib/components/FormBuilder/numberFormat.ts +0 -16
  146. package/apps/lib/components/FormBuilder/submit.tsx +0 -67
  147. package/apps/lib/components/FormBuilder/types.ts +0 -316
  148. package/apps/lib/components/FormRenderer/FormDrawer.tsx +0 -250
  149. package/apps/lib/components/FormRenderer/detail.tsx +0 -256
  150. package/apps/lib/components/FormRenderer/form-renderer.tsx +0 -358
  151. package/apps/lib/components/FormRenderer/header.tsx +0 -88
  152. package/apps/lib/components/FormRenderer/index.ts +0 -17
  153. package/apps/lib/components/FormRenderer/notch-action.tsx +0 -64
  154. package/apps/lib/components/FormRenderer/section.tsx +0 -39
  155. package/apps/lib/components/FormRenderer/stepper.tsx +0 -393
  156. package/apps/lib/components/FormRenderer/types.ts +0 -115
  157. package/apps/lib/components/FormSummary.tsx +0 -282
  158. package/apps/lib/components/HeaderBar.tsx +0 -117
  159. package/apps/lib/components/ImageAttachment.tsx +0 -209
  160. package/apps/lib/components/InnerLabelField.tsx +0 -154
  161. package/apps/lib/components/Input.tsx +0 -224
  162. package/apps/lib/components/InputField.tsx +0 -147
  163. package/apps/lib/components/InputOTP.tsx +0 -84
  164. package/apps/lib/components/Label.tsx +0 -129
  165. package/apps/lib/components/LabelField.tsx +0 -76
  166. package/apps/lib/components/LabeledCheckBox.tsx +0 -51
  167. package/apps/lib/components/LabeledRadio.tsx +0 -51
  168. package/apps/lib/components/LinkButton.tsx +0 -94
  169. package/apps/lib/components/LoginButton.tsx +0 -51
  170. package/apps/lib/components/PasswordLevel.tsx +0 -58
  171. package/apps/lib/components/Popover.tsx +0 -312
  172. package/apps/lib/components/ProfileMenu.tsx +0 -85
  173. package/apps/lib/components/Radio.tsx +0 -59
  174. package/apps/lib/components/RadioCard.tsx +0 -50
  175. package/apps/lib/components/ScrollArea.tsx +0 -54
  176. package/apps/lib/components/SearchField.tsx +0 -62
  177. package/apps/lib/components/SearchableSelect.tsx +0 -318
  178. package/apps/lib/components/SearchableTable.tsx +0 -344
  179. package/apps/lib/components/SearchableTree.tsx +0 -485
  180. package/apps/lib/components/SearchableTreeDialog.tsx +0 -502
  181. package/apps/lib/components/SectionBlock.tsx +0 -168
  182. package/apps/lib/components/Select.tsx +0 -347
  183. package/apps/lib/components/SimpleSelect.tsx +0 -225
  184. package/apps/lib/components/Skeleton.tsx +0 -12
  185. package/apps/lib/components/SlideDatePicker.tsx +0 -255
  186. package/apps/lib/components/SpinLoading.tsx +0 -174
  187. package/apps/lib/components/Stepper.tsx +0 -480
  188. package/apps/lib/components/Switch.tsx +0 -82
  189. package/apps/lib/components/TabFormItem.tsx +0 -153
  190. package/apps/lib/components/TabSwitch.tsx +0 -172
  191. package/apps/lib/components/Table.tsx +0 -597
  192. package/apps/lib/components/TextEditor/ChartBlockTool.ts +0 -676
  193. package/apps/lib/components/TextEditor/RichTextField.tsx +0 -46
  194. package/apps/lib/components/TextEditor/TableDnDWrapper.ts +0 -462
  195. package/apps/lib/components/TextEditor/TextEditor.tsx +0 -1164
  196. package/apps/lib/components/TextEditor/TextEditorToolbar.tsx +0 -429
  197. package/apps/lib/components/TextEditor/editor-tools/AlignmentTune.ts +0 -70
  198. package/apps/lib/components/TextEditor/editor-tools/ColorInlineTool.ts +0 -50
  199. package/apps/lib/components/TextEditor/editor-tools/StrikethroughInlineTool.ts +0 -48
  200. package/apps/lib/components/TextEditor/editor-tools/inlineFormat.ts +0 -98
  201. package/apps/lib/components/TextEditor/editorjs.d.ts +0 -60
  202. package/apps/lib/components/TextEditor/index.ts +0 -7
  203. package/apps/lib/components/TextEditor/markdownParser.ts +0 -346
  204. package/apps/lib/components/Textarea.tsx +0 -117
  205. package/apps/lib/components/Timeline.tsx +0 -263
  206. package/apps/lib/components/Toast.tsx +0 -87
  207. package/apps/lib/components/Toggle.tsx +0 -125
  208. package/apps/lib/components/ToggleButton.tsx +0 -140
  209. package/apps/lib/components/Tooltip.tsx +0 -116
  210. package/apps/lib/components/TransparentLabel.tsx +0 -71
  211. package/apps/lib/components/TreeDropDown.tsx +0 -115
  212. package/apps/lib/components/TreeFolder/TreeFolder.tsx +0 -380
  213. package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +0 -75
  214. package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +0 -354
  215. package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +0 -60
  216. package/apps/lib/components/TreeFolder/icons.tsx +0 -60
  217. package/apps/lib/components/TreeFolder/index.ts +0 -24
  218. package/apps/lib/components/TreeFolder/treeFolderUtils.ts +0 -109
  219. package/apps/lib/components/TreeFolder/types.ts +0 -77
  220. package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +0 -118
  221. package/apps/lib/hooks/useActiveTreeItem.ts +0 -61
  222. package/apps/lib/hooks/useClickOutside.ts +0 -27
  223. package/apps/lib/hooks/useDragDrop.tsx +0 -365
  224. package/apps/lib/hooks/useHtmlDir.ts +0 -31
  225. package/apps/lib/hooks/useInfiniteScroll.ts +0 -108
  226. package/apps/lib/hooks/useIsMobile.ts +0 -21
  227. package/apps/lib/hooks/useResize.ts +0 -67
  228. package/apps/lib/hooks/useTagSelection.ts +0 -300
  229. package/apps/lib/layouts/CNLayout.tsx +0 -372
  230. package/apps/lib/layouts/DataViewCard.tsx +0 -62
  231. package/apps/lib/layouts/FieldSection.tsx +0 -91
  232. package/apps/lib/layouts/TreeSubLayout.tsx +0 -173
  233. package/apps/lib/providers/ThemeProvider.tsx +0 -84
  234. package/apps/lib/registry.json +0 -1217
  235. package/apps/lib/tsconfig.json +0 -9
  236. package/apps/lib/tsconfig.tsbuildinfo +0 -1
  237. package/apps/lib/utils/cn.ts +0 -6
  238. package/apps/lib/utils/color.ts +0 -175
  239. package/apps/lib/utils/dataViews/path.ts +0 -67
  240. package/apps/lib/utils/dataViews/query.ts +0 -73
  241. package/apps/lib/utils/dataViews/types.ts +0 -187
  242. package/apps/lib/utils/dateFormat.ts +0 -108
  243. package/apps/lib/utils/resize.ts +0 -31
  244. package/apps/lib/utils/scroller.ts +0 -26
  245. package/apps/lib/utils/types.ts +0 -16
  246. package/docs/BLOCKS.md +0 -129
  247. package/docs/CHANGELOG-1.1.16.md +0 -108
  248. package/docs/Cover.png +0 -0
  249. package/docs/README.md +0 -215
  250. package/docs/components/action-button.md +0 -638
  251. package/docs/components/actions-group.md +0 -708
  252. package/docs/components/alert-dialog.md +0 -920
  253. package/docs/components/avatar.md +0 -709
  254. package/docs/components/badge-field.md +0 -738
  255. package/docs/components/badge.md +0 -301
  256. package/docs/components/breadcrumb.md +0 -930
  257. package/docs/components/button-group.md +0 -650
  258. package/docs/components/button.md +0 -639
  259. package/docs/components/calendar.md +0 -555
  260. package/docs/components/card.md +0 -622
  261. package/docs/components/chart-block-tool.md +0 -129
  262. package/docs/components/checkbox.md +0 -699
  263. package/docs/components/cn-layout.md +0 -854
  264. package/docs/components/color-picker.md +0 -101
  265. package/docs/components/conclusion-header.md +0 -80
  266. package/docs/components/context-menu.md +0 -483
  267. package/docs/components/count-badge.md +0 -560
  268. package/docs/components/data-table.md +0 -854
  269. package/docs/components/data-views/backend-response.md +0 -324
  270. package/docs/components/data-views/examples/a11y-rtl.md +0 -250
  271. package/docs/components/data-views/examples/api-orders-route.md +0 -130
  272. package/docs/components/data-views/examples/fields.md +0 -362
  273. package/docs/components/data-views/examples/filters.md +0 -307
  274. package/docs/components/data-views/examples/inbox-routing.md +0 -218
  275. package/docs/components/data-views/examples/index.md +0 -29
  276. package/docs/components/data-views/examples/overview.md +0 -244
  277. package/docs/components/data-views/examples/panel.md +0 -212
  278. package/docs/components/data-views/examples/scale.md +0 -231
  279. package/docs/components/data-views/examples/server-side.md +0 -210
  280. package/docs/components/data-views/examples/state.md +0 -250
  281. package/docs/components/data-views/examples/tree-custom.md +0 -388
  282. package/docs/components/data-views/examples/view-registry.md +0 -313
  283. package/docs/components/data-views/examples/views.md +0 -534
  284. package/docs/components/data-views/guide.md +0 -405
  285. package/docs/components/data-views/index.md +0 -1521
  286. package/docs/components/data-views/migration.md +0 -81
  287. package/docs/components/date-picker.md +0 -857
  288. package/docs/components/dialog.md +0 -929
  289. package/docs/components/divider.md +0 -766
  290. package/docs/components/drawer.md +0 -654
  291. package/docs/components/dropdown-menu.md +0 -668
  292. package/docs/components/field-hint.md +0 -898
  293. package/docs/components/field-section.md +0 -781
  294. package/docs/components/form-builder.md +0 -284
  295. package/docs/components/form-renderer.md +0 -396
  296. package/docs/components/form-summary.md +0 -138
  297. package/docs/components/form.md +0 -785
  298. package/docs/components/header-bar.md +0 -188
  299. package/docs/components/image-attachment.md +0 -906
  300. package/docs/components/inner-label-field.md +0 -819
  301. package/docs/components/input-field.md +0 -623
  302. package/docs/components/input-otp.md +0 -756
  303. package/docs/components/input.md +0 -634
  304. package/docs/components/label-field.md +0 -770
  305. package/docs/components/label.md +0 -761
  306. package/docs/components/labeled-check-box.md +0 -642
  307. package/docs/components/labeled-radio.md +0 -796
  308. package/docs/components/link-button.md +0 -685
  309. package/docs/components/login-button.md +0 -872
  310. package/docs/components/password-level.md +0 -803
  311. package/docs/components/popover.md +0 -649
  312. package/docs/components/profile-menu.md +0 -656
  313. package/docs/components/radio-card.md +0 -801
  314. package/docs/components/radio.md +0 -735
  315. package/docs/components/scroll-area.md +0 -691
  316. package/docs/components/search-field.md +0 -702
  317. package/docs/components/searchable-select.md +0 -368
  318. package/docs/components/searchable-table.md +0 -438
  319. package/docs/components/searchable-tree-dialog.md +0 -190
  320. package/docs/components/searchable-tree.md +0 -200
  321. package/docs/components/section-block.md +0 -483
  322. package/docs/components/select.md +0 -709
  323. package/docs/components/simple-select.md +0 -741
  324. package/docs/components/skeleton.md +0 -706
  325. package/docs/components/slide-date-picker.md +0 -837
  326. package/docs/components/spin-loading.md +0 -696
  327. package/docs/components/stepper.md +0 -316
  328. package/docs/components/switch.md +0 -770
  329. package/docs/components/tab-form-item.md +0 -773
  330. package/docs/components/tab-switch.md +0 -170
  331. package/docs/components/table-dnd-wrapper.md +0 -107
  332. package/docs/components/table.md +0 -1088
  333. package/docs/components/text-editor.md +0 -735
  334. package/docs/components/textarea.md +0 -681
  335. package/docs/components/timeline.md +0 -254
  336. package/docs/components/toast.md +0 -773
  337. package/docs/components/toggle-button.md +0 -643
  338. package/docs/components/toggle.md +0 -882
  339. package/docs/components/tooltip.md +0 -513
  340. package/docs/components/transparent-label.md +0 -721
  341. package/docs/components/tree-drop-down.md +0 -740
  342. package/docs/components/tree-folder.md +0 -110
  343. package/docs/components/tree-sub-layout.md +0 -707
  344. package/docs/explanation/architecture.md +0 -54
  345. package/docs/explanation/design-system.md +0 -52
  346. package/docs/how-to/form-and-list-recipes.md +0 -386
  347. package/docs/how-to/forms-with-form-builder.md +0 -472
  348. package/docs/how-to/guides.md +0 -1027
  349. package/docs/migration/changelog.md +0 -60
  350. package/docs/migration/form-builder-2.5.2.md +0 -113
  351. package/docs/reference/cli.md +0 -112
  352. package/docs/reference/components.md +0 -572
  353. package/docs/reference/hooks.md +0 -1523
  354. package/docs/reference/providers.md +0 -866
  355. package/docs/reference/tailwind-plugins.md +0 -942
  356. package/docs/reference/theme.md +0 -85
  357. package/docs/reference/types.md +0 -1016
  358. package/docs/reference/utilities.md +0 -726
  359. package/docs/tutorials/building-first-form.md +0 -846
  360. package/docs/tutorials/component-composition.md +0 -882
  361. package/docs/tutorials/getting-started.md +0 -302
  362. package/docs/tutorials/theming-basics.md +0 -785
@@ -1,857 +0,0 @@
1
- ---
2
- title: DatePicker
3
- description: Complete date and time picker with calendar dropdown, optional time selection, and input field integration
4
- group: Date & Time
5
- keywords: [date-picker, calendar, time, datetime, input, popover]
6
- ---
7
-
8
- # DatePicker
9
-
10
- > A comprehensive date picker component that combines a calendar dropdown with optional time selection and seamless input field integration. Built on top of the Calendar component with Popover for elegant date and time selection.
11
-
12
- ## Installation
13
-
14
- TORCH Glare is a copy-in library: the CLI copies this component's source into your project
15
- (you do **not** install it from the npm package). Run `init` once, then `add`:
16
-
17
- ```bash
18
- npx torch-glare@latest init
19
- npx torch-glare@latest add DatePicker
20
- ```
21
-
22
- `add` also copies any components, hooks, and utilities that `DatePicker` depends on.
23
-
24
- ## Import
25
-
26
- Import from your project's local path — the alias configured in `glare.json` (e.g. `@/*`):
27
-
28
- ```tsx
29
- import { DatePicker } from "@/components/DatePicker";
30
- ```
31
-
32
- ## Quick Examples
33
-
34
- ### Basic Usage
35
-
36
- ```typescript
37
- import { DatePicker } from "@/components/DatePicker";
38
- import { useState } from 'react'
39
-
40
- function Example() {
41
- const [date, setDate] = useState<Date>(new Date())
42
-
43
- return (
44
- <DatePicker
45
- mode="single"
46
- value={date}
47
- onChange={(e) => setDate(e.target.value)}
48
- />
49
- )
50
- }
51
- ```
52
-
53
- ### With Time Picker
54
-
55
- ```typescript
56
- import { DatePicker } from "@/components/DatePicker";
57
- import { useState } from 'react'
58
-
59
- function DateTimePicker() {
60
- const [datetime, setDatetime] = useState<Date>(new Date())
61
-
62
- return (
63
- <DatePicker
64
- mode="single"
65
- value={datetime}
66
- onChange={(e) => setDatetime(e.target.value)}
67
- timePicker
68
- />
69
- )
70
- }
71
- ```
72
-
73
- ### Range Selection
74
-
75
- ```typescript
76
- import { DatePicker } from "@/components/DatePicker";
77
- import { useState } from 'react'
78
- import { DateRange } from 'react-day-picker'
79
-
80
- function RangePicker() {
81
- const [range, setRange] = useState<DateRange>({
82
- from: new Date(),
83
- to: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
84
- })
85
-
86
- return (
87
- <DatePicker
88
- mode="range"
89
- selected={range}
90
- onChange={(e) => setRange(e.target.value)}
91
- min={1}
92
- max={30}
93
- />
94
- )
95
- }
96
- ```
97
-
98
- ### Multiple Date Selection
99
-
100
- ```typescript
101
- import { DatePicker } from "@/components/DatePicker";
102
- import { useState } from 'react'
103
-
104
- function MultipleDates() {
105
- const [dates, setDates] = useState<Date[]>([])
106
-
107
- return (
108
- <DatePicker
109
- mode="multiple"
110
- selected={dates}
111
- onChange={(e) => setDates(e.target.value)}
112
- max={5}
113
- />
114
- )
115
- }
116
- ```
117
-
118
- ### Custom Date Format
119
-
120
- ```typescript
121
- import { DatePicker } from "@/components/DatePicker";
122
-
123
- function CustomFormat() {
124
- const [date, setDate] = useState<Date>(new Date())
125
-
126
- return (
127
- <DatePicker
128
- value={date}
129
- onChange={(e) => setDate(e.target.value)}
130
- dateFormat="MMM dd, yyyy" // "Jan 15, 2024"
131
- />
132
- )
133
- }
134
- ```
135
-
136
- ### Custom Trigger Element
137
-
138
- ```typescript
139
- import { DatePicker } from "@/components/DatePicker";
140
- import { Button } from "@/components/Button";
141
-
142
- function CustomTrigger() {
143
- const [date, setDate] = useState<Date>(new Date())
144
-
145
- return (
146
- <DatePicker
147
- value={date}
148
- onChange={(e) => setDate(e.target.value)}
149
- >
150
- <Button variant="BluSecStyle">
151
- <i className="ri-calendar-line" />
152
- Select Date
153
- </Button>
154
- </DatePicker>
155
- )
156
- }
157
- ```
158
-
159
- ### With Controlled Input
160
-
161
- ```typescript
162
- import { DatePicker } from "@/components/DatePicker";
163
- import { InputField } from "@/components/InputField";
164
- import { useState } from 'react'
165
-
166
- function ControlledInput() {
167
- const [date, setDate] = useState<Date>(new Date())
168
-
169
- return (
170
- <DatePicker
171
- value={date}
172
- onChange={(e) => setDate(e.target.value)}
173
- >
174
- <InputField
175
- label="Appointment Date"
176
- placeholder="Select a date"
177
- />
178
- </DatePicker>
179
- )
180
- }
181
- ```
182
-
183
- ### Date Restrictions
184
-
185
- ```typescript
186
- import { DatePicker } from "@/components/DatePicker";
187
-
188
- function RestrictedDates() {
189
- const [date, setDate] = useState<Date>()
190
-
191
- return (
192
- <DatePicker
193
- value={date}
194
- onChange={(e) => setDate(e.target.value)}
195
- calendarProps={{
196
- disabled: [
197
- { before: new Date() }, // No past dates
198
- { dayOfWeek: [0, 6] }, // No weekends
199
- ],
200
- fromDate: new Date(),
201
- toDate: new Date(2025, 11, 31),
202
- }}
203
- />
204
- )
205
- }
206
- ```
207
-
208
- ### Booking System
209
-
210
- ```typescript
211
- import { DatePicker } from "@/components/DatePicker";
212
- import { useState } from 'react'
213
- import { DateRange } from 'react-day-picker'
214
-
215
- function BookingPicker() {
216
- const [range, setRange] = useState<DateRange>()
217
-
218
- const bookedDates = [
219
- new Date(2024, 0, 15),
220
- new Date(2024, 0, 16),
221
- { from: new Date(2024, 0, 20), to: new Date(2024, 0, 22) },
222
- ]
223
-
224
- const nightsCount = range?.from && range?.to
225
- ? Math.ceil((range.to.getTime() - range.from.getTime()) / (1000 * 60 * 60 * 24))
226
- : 0
227
-
228
- return (
229
- <div>
230
- <DatePicker
231
- mode="range"
232
- selected={range}
233
- onChange={(e) => setRange(e.target.value)}
234
- min={1}
235
- max={30}
236
- calendarProps={{
237
- disabled: bookedDates,
238
- }}
239
- />
240
- {nightsCount > 0 && (
241
- <p className="mt-2 text-sm">
242
- {nightsCount} night{nightsCount > 1 ? 's' : ''} selected
243
- </p>
244
- )}
245
- </div>
246
- )
247
- }
248
- ```
249
-
250
- ### Deadline Picker with Time
251
-
252
- ```typescript
253
- import { DatePicker } from "@/components/DatePicker";
254
- import { useState } from 'react'
255
-
256
- function DeadlinePicker() {
257
- const [deadline, setDeadline] = useState<Date>()
258
-
259
- return (
260
- <DatePicker
261
- value={deadline}
262
- onChange={(e) => setDeadline(e.target.value)}
263
- timePicker
264
- calendarProps={{
265
- disabled: { before: new Date() },
266
- }}
267
- dateFormat="MMM dd, yyyy 'at' hh:mm a"
268
- >
269
- <InputField
270
- label="Project Deadline"
271
- placeholder="Select deadline with time"
272
- childrenSide={<i className="ri-time-line" />}
273
- />
274
- </DatePicker>
275
- )
276
- }
277
- ```
278
-
279
- ## API Reference
280
-
281
- ### DatePicker Props
282
-
283
- Extends all standard input attributes (`HTMLAttributes<HTMLInputElement>`).
284
-
285
- | Prop | Type | Default | Description |
286
- |------|------|---------|-------------|
287
- | `mode` | `'single' \| 'multiple' \| 'range'` | `'single'` | Selection mode |
288
- | `selected` | `Date \| Date[] \| DateRange` | - | Selected date(s) for Calendar |
289
- | `value` | `Date \| Date[] \| DateRange` | - | Input field value |
290
- | `onChange` | `(e: Event) => void` | - | Change handler (event with target.value) |
291
- | `timePicker` | `boolean` | `false` | Show time picker |
292
- | `dateFormat` | `string` | `'yyyy/MM/dd'` | Date display format |
293
- | `size` | `'M' \| 'S'` | `'M'` | Input field size |
294
- | `min` | `number` | - | Minimum range length (range mode) |
295
- | `max` | `number` | - | Maximum range/multiple count |
296
- | `showWeekNumber` | `boolean` | `false` | Show week numbers in calendar |
297
- | `captionLayout` | `'dropdown' \| 'label' \| 'dropdown-months' \| 'dropdown-years'` | `'dropdown'` | Caption style |
298
- | `calendarProps` | `CalendarProps` | - | Additional Calendar props |
299
- | `children` | `ReactElement` | - | Custom trigger element |
300
- | `className` | `string` | - | Additional CSS classes |
301
-
302
- ### TimePickerValue Interface
303
-
304
- ```typescript
305
- interface TimePickerValue {
306
- hour: number // 1-12
307
- minute: number // 0-59
308
- time: 'AM' | 'PM'
309
- }
310
- ```
311
-
312
- ## TypeScript
313
-
314
- ### Full Type Definitions
315
-
316
- ```typescript
317
- import { DateRange } from 'react-day-picker'
318
-
319
- interface DatePickerProps extends HTMLAttributes<HTMLInputElement> {
320
- mode?: "single" | "multiple" | "range"
321
- selected?: Date | Date[] | DateRange | undefined
322
- min?: number
323
- max?: number
324
- size?: "M" | "S"
325
- showWeekNumber?: boolean
326
- captionLayout?: "dropdown" | "label" | "dropdown-months" | "dropdown-years"
327
- dateFormat?: string
328
- calendarProps?: CalendarProps
329
- timePicker?: boolean
330
- value?: Date | Date[] | DateRange
331
- onChange?: (e: { target: { value: Date | Date[] | DateRange } }) => void
332
- children?: ReactElement
333
- }
334
-
335
- // Usage with different modes
336
- type SingleDatePicker = DatePickerProps & {
337
- mode: 'single'
338
- value?: Date
339
- selected?: Date
340
- onChange?: (e: { target: { value: Date | undefined } }) => void
341
- }
342
-
343
- type MultipleDatePicker = DatePickerProps & {
344
- mode: 'multiple'
345
- value?: Date[]
346
- selected?: Date[]
347
- onChange?: (e: { target: { value: Date[] | undefined } }) => void
348
- max?: number
349
- }
350
-
351
- type RangeDatePicker = DatePickerProps & {
352
- mode: 'range'
353
- value?: DateRange
354
- selected?: DateRange
355
- onChange?: (e: { target: { value: DateRange | undefined } }) => void
356
- min?: number
357
- max?: number
358
- }
359
- ```
360
-
361
- ## Common Patterns
362
-
363
- ### Event Scheduler
364
-
365
- ```typescript
366
- import { DatePicker } from "@/components/DatePicker";
367
- import { useState } from 'react'
368
-
369
- function EventScheduler() {
370
- const [startDate, setStartDate] = useState<Date>(new Date())
371
- const [endDate, setEndDate] = useState<Date>()
372
-
373
- return (
374
- <div className="space-y-4">
375
- <DatePicker
376
- value={startDate}
377
- onChange={(e) => {
378
- setStartDate(e.target.value)
379
- // Ensure end date is after start date
380
- if (endDate && endDate < e.target.value) {
381
- setEndDate(e.target.value)
382
- }
383
- }}
384
- timePicker
385
- dateFormat="MMM dd, yyyy hh:mm a"
386
- >
387
- <InputField label="Event Start" />
388
- </DatePicker>
389
-
390
- <DatePicker
391
- value={endDate}
392
- onChange={(e) => setEndDate(e.target.value)}
393
- timePicker
394
- dateFormat="MMM dd, yyyy hh:mm a"
395
- calendarProps={{
396
- disabled: { before: startDate },
397
- }}
398
- >
399
- <InputField label="Event End" />
400
- </DatePicker>
401
- </div>
402
- )
403
- }
404
- ```
405
-
406
- ### Birthday Picker
407
-
408
- ```typescript
409
- import { DatePicker } from "@/components/DatePicker";
410
- import { useState } from 'react'
411
-
412
- function BirthdayPicker() {
413
- const [birthday, setBirthday] = useState<Date>()
414
-
415
- const maxDate = new Date()
416
- maxDate.setFullYear(maxDate.getFullYear() - 13) // Minimum age 13
417
-
418
- return (
419
- <DatePicker
420
- value={birthday}
421
- onChange={(e) => setBirthday(e.target.value)}
422
- dateFormat="MMMM dd, yyyy"
423
- calendarProps={{
424
- captionLayout: 'dropdown',
425
- toDate: maxDate,
426
- fromDate: new Date(1900, 0, 1),
427
- }}
428
- >
429
- <InputField
430
- label="Date of Birth"
431
- placeholder="Select your birthday"
432
- />
433
- </DatePicker>
434
- )
435
- }
436
- ```
437
-
438
- ### Work Schedule Picker
439
-
440
- ```typescript
441
- import { DatePicker } from "@/components/DatePicker";
442
- import { useState } from 'react'
443
-
444
- function WorkSchedule() {
445
- const [workDays, setWorkDays] = useState<Date[]>([])
446
-
447
- return (
448
- <DatePicker
449
- mode="multiple"
450
- selected={workDays}
451
- onChange={(e) => setWorkDays(e.target.value)}
452
- max={5} // Max 5 work days
453
- calendarProps={{
454
- disabled: { dayOfWeek: [0, 6] }, // Disable weekends
455
- }}
456
- >
457
- <InputField
458
- label="Select Work Days"
459
- placeholder={`${workDays.length} day${workDays.length !== 1 ? 's' : ''} selected`}
460
- />
461
- </DatePicker>
462
- )
463
- }
464
- ```
465
-
466
- ## Testing
467
-
468
- ### Unit Test Examples
469
-
470
- ```typescript
471
- import { render, screen, fireEvent, waitFor } from '@testing-library/react'
472
- import { DatePicker } from "@/components/DatePicker";
473
- import userEvent from '@testing-library/user-event'
474
-
475
- describe('DatePicker', () => {
476
- it('renders with default input', () => {
477
- render(<DatePicker mode="single" />)
478
-
479
- const input = screen.getByRole('textbox')
480
- expect(input).toBeInTheDocument()
481
- expect(input).toHaveAttribute('readonly')
482
- })
483
-
484
- it('opens calendar on input click', async () => {
485
- render(<DatePicker mode="single" />)
486
-
487
- const input = screen.getByRole('textbox')
488
- await userEvent.click(input)
489
-
490
- await waitFor(() => {
491
- expect(screen.getByRole('grid')).toBeInTheDocument() // Calendar grid
492
- })
493
- })
494
-
495
- it('selects a date', async () => {
496
- const handleChange = jest.fn()
497
-
498
- render(
499
- <DatePicker
500
- mode="single"
501
- onChange={handleChange}
502
- />
503
- )
504
-
505
- const input = screen.getByRole('textbox')
506
- await userEvent.click(input)
507
-
508
- const day15 = await screen.findByRole('button', { name: /15/ })
509
- await userEvent.click(day15)
510
-
511
- expect(handleChange).toHaveBeenCalled()
512
- const selectedDate = handleChange.mock.calls[0][0].target.value
513
- expect(selectedDate.getDate()).toBe(15)
514
- })
515
-
516
- it('displays time picker when enabled', async () => {
517
- render(
518
- <DatePicker
519
- mode="single"
520
- timePicker
521
- />
522
- )
523
-
524
- const input = screen.getByRole('textbox')
525
- await userEvent.click(input)
526
-
527
- await waitFor(() => {
528
- expect(screen.getByText(/AM/i)).toBeInTheDocument()
529
- expect(screen.getByText(/PM/i)).toBeInTheDocument()
530
- })
531
- })
532
-
533
- it('formats date according to dateFormat prop', () => {
534
- const date = new Date(2024, 0, 15)
535
-
536
- render(
537
- <DatePicker
538
- mode="single"
539
- value={date}
540
- dateFormat="MMM dd, yyyy"
541
- />
542
- )
543
-
544
- const input = screen.getByRole('textbox')
545
- expect(input).toHaveValue('Jan 15, 2024')
546
- })
547
-
548
- it('renders custom trigger element', () => {
549
- const CustomButton = <button>Pick Date</button>
550
-
551
- render(
552
- <DatePicker mode="single">
553
- {CustomButton}
554
- </DatePicker>
555
- )
556
-
557
- expect(screen.getByText('Pick Date')).toBeInTheDocument()
558
- })
559
-
560
- it('disables body scroll when open', async () => {
561
- render(<DatePicker mode="single" />)
562
-
563
- const input = screen.getByRole('textbox')
564
- await userEvent.click(input)
565
-
566
- await waitFor(() => {
567
- expect(document.body.style.overflow).toBe('hidden')
568
- })
569
- })
570
-
571
- it('respects min/max range constraints', async () => {
572
- const handleChange = jest.fn()
573
-
574
- render(
575
- <DatePicker
576
- mode="range"
577
- onChange={handleChange}
578
- min={2}
579
- max={7}
580
- />
581
- )
582
-
583
- // Test that constraints are applied
584
- // This would require more complex interaction testing
585
- })
586
- })
587
- ```
588
-
589
- ## Known Limitations & Frontend Patterns
590
-
591
- ### `onChange` payload type does not match what TypeScript thinks
592
-
593
- `DatePicker` props extend `HTMLAttributes<HTMLInputElement>`, which makes `onChange` look like `(e: ChangeEvent<HTMLInputElement>) => void` where `e.target.value: string`. **At runtime the value is a `Date | Date[] | DateRange`**, not a string — the component dispatches a hand-rolled pseudo-event with the typed payload behind a `string` type assertion.
594
-
595
- **Workaround — cast through `unknown` on every call site:**
596
-
597
- ```tsx
598
- <DatePicker
599
- mode="single"
600
- value={startDate}
601
- onChange={(e) =>
602
- setStartDate(e.target.value as unknown as Date | undefined)
603
- }
604
- />
605
- ```
606
-
607
- For `mode="multiple"`:
608
-
609
- ```tsx
610
- onChange={(e) => setDates(e.target.value as unknown as Date[] | undefined)}
611
- ```
612
-
613
- For `mode="range"`:
614
-
615
- ```tsx
616
- onChange={(e) => setRange(e.target.value as unknown as DateRange | undefined)}
617
- ```
618
-
619
- The `as unknown as Date` shape is required — TypeScript will reject `as Date` directly because `string` and `Date` don't overlap.
620
-
621
- ### `TimePickerValue` interface — `hour`/`minute` are strings, not numbers
622
-
623
- The shipped runtime uses `string` for `hour`, `minute`, and `time` (`"AM" | "PM"`). If you derive your own state from `TimePickerValue`, type those fields as `string`, not `number`, regardless of what older docs claim.
624
-
625
- ### Internal `<Picker>` value/onChange types are incompatible with `TimePickerValue` — `tsc` fails out of the box
626
-
627
- `DatePicker.tsx` wraps `torch-react-mobile-picker`'s `<Picker>` and passes a concrete `TimePickerValue` (`{ hour, minute, time }`) where the picker's generic `PickerValue` (`Record<string, string>`) is expected. Strict TypeScript builds fail immediately:
628
-
629
- ```
630
- DatePicker.tsx: Type 'TimePickerValue' is not assignable to type 'PickerValue'.
631
- Index signature for type 'string' is missing in type 'TimePickerValue'.
632
- DatePicker.tsx: Type '(e: TimePickerValue) => void' is not assignable to type
633
- '(value: PickerValue, key: string) => void'.
634
- ```
635
-
636
- **Workaround — add `as any` casts at the `<Picker>` boundary** (and only there, so consumer types stay honest):
637
-
638
- ```tsx
639
- <Picker
640
- value={value as any}
641
- onChange={((e: TimePickerValue) => {
642
- onChange(e);
643
- }) as any}
644
- wheelMode="normal"
645
- >
646
- ```
647
-
648
- Patch this manually after `npx torch-glare add DatePicker` — otherwise `pnpm build` (which runs `tsc -b`) will fail. The same `Ref` import in the file is also unused and trips `noUnusedLocals`; remove it while you're in there.
649
-
650
- ### `npx torch-glare add DatePicker` does not install `utils/dateFormat.ts`
651
-
652
- The CLI ships `DatePicker.tsx` without copying the `dateFormat.ts` utility it imports, so the component fails to build immediately after install:
653
-
654
- ```
655
- [plugin:vite:import-analysis] Failed to resolve import "../utils/dateFormat"
656
- from "DatePicker.tsx".
657
- ```
658
-
659
- **Workaround until the CLI is fixed:** create `utils/dateFormat.ts` manually with the three exports the component needs:
660
-
661
- - `TimePickerValue` (`{ hour: string; minute: string; time: "AM" | "PM" }`)
662
- - `applyTimeToDateValue(value, timePickerValue)` — applies the time picker value to the date value
663
- - `formatDateValueToString(value, timePickerValue, dateFormat)` — formats the date value to a display string
664
-
665
- Reverse-engineer the implementation from the call sites in `DatePicker.tsx` until the CLI copies it automatically.
666
-
667
- ## Accessibility
668
-
669
- - **Keyboard Navigation**:
670
- - Tab: Focus input field
671
- - Enter/Space: Open calendar dropdown
672
- - Arrow keys: Navigate calendar (when open)
673
- - Escape: Close dropdown
674
- - **ARIA Attributes**: Inherited from Calendar and Popover
675
- - **Screen Readers**: Date announced on selection
676
- - **Focus Management**: Focus returns to trigger after selection
677
- - **Body Scroll Lock**: Prevents background scroll when picker open
678
-
679
- ### Accessibility Best Practices
680
-
681
- ```typescript
682
- // Provide labels for inputs
683
- <DatePicker>
684
- <InputField
685
- label="Appointment Date"
686
- aria-describedby="date-hint"
687
- />
688
- </DatePicker>
689
- <p id="date-hint">Select a date for your appointment</p>
690
-
691
- // Describe restrictions
692
- <DatePicker
693
- calendarProps={{
694
- disabled: { before: new Date() },
695
- 'aria-label': 'Select a future date',
696
- }}
697
- />
698
- ```
699
-
700
- ## Performance
701
-
702
- | Metric | Value |
703
- |--------|-------|
704
- | Bundle size (minified) | ~45kb |
705
- | Bundle size (gzipped) | ~12kb |
706
- | Dependencies | react-day-picker, torch-react-mobile-picker |
707
- | Initial render | <25ms |
708
- | Dropdown open | <15ms |
709
- | Tree-shakeable | ✅ |
710
-
711
- ### Performance Tips
712
-
713
- 1. **Memoize callbacks**:
714
- ```typescript
715
- const handleChange = useCallback((e) => {
716
- setDate(e.target.value)
717
- }, [])
718
- ```
719
-
720
- 2. **Use value prop sparingly**: Only use when you need controlled state
721
-
722
- 3. **Lazy load time picker**: Only enable when needed
723
-
724
- 4. **Limit calendarProps modifiers**: Complex modifiers can slow rendering
725
-
726
- ## Styling
727
-
728
- ### Custom Styles
729
-
730
- ```typescript
731
- // Style the input field
732
- <DatePicker
733
- className="custom-date-input"
734
- size="M"
735
- >
736
- <InputField className="custom-field" />
737
- </DatePicker>
738
-
739
- // Style the calendar
740
- <DatePicker
741
- calendarProps={{
742
- className: "custom-calendar",
743
- classNames: {
744
- day: "custom-day",
745
- selected: "custom-selected",
746
- },
747
- }}
748
- />
749
- ```
750
-
751
- ### Default Styling
752
-
753
- - Input: Read-only field with calendar icon
754
- - Popover: Dropdown with calendar and optional time picker
755
- - Calendar: Themed calendar with dropdown navigation
756
- - Time Picker: Wheel interface with hour/minute/AM-PM columns
757
-
758
- ## Integration Examples
759
-
760
- ### With Form Libraries
761
-
762
- ```typescript
763
- import { DatePicker } from "@/components/DatePicker";
764
- import { useForm, Controller } from 'react-hook-form'
765
-
766
- function FormExample() {
767
- const { control, handleSubmit } = useForm()
768
-
769
- return (
770
- <form onSubmit={handleSubmit(console.log)}>
771
- <Controller
772
- name="appointmentDate"
773
- control={control}
774
- rules={{ required: 'Date is required' }}
775
- render={({ field, fieldState: { error } }) => (
776
- <div>
777
- <DatePicker
778
- value={field.value}
779
- onChange={(e) => field.onChange(e.target.value)}
780
- timePicker
781
- >
782
- <InputField
783
- label="Appointment Date & Time"
784
- error={error?.message}
785
- />
786
- </DatePicker>
787
- </div>
788
- )}
789
- />
790
- </form>
791
- )
792
- }
793
- ```
794
-
795
- ### With State Management
796
-
797
- ```typescript
798
- import { DatePicker } from "@/components/DatePicker";
799
- import { useStore } from './store'
800
-
801
- function DatePickerWithStore() {
802
- const { selectedDate, setSelectedDate } = useStore()
803
-
804
- return (
805
- <DatePicker
806
- value={selectedDate}
807
- onChange={(e) => setSelectedDate(e.target.value)}
808
- mode="single"
809
- />
810
- )
811
- }
812
- ```
813
-
814
- ## Best Practices
815
-
816
- 1. **Always specify mode**: Be explicit about selection type
817
- ```typescript
818
- <DatePicker mode="single" />
819
- ```
820
-
821
- 2. **Use controlled components**: Manage state explicitly
822
- ```typescript
823
- const [date, setDate] = useState<Date>()
824
- <DatePicker value={date} onChange={(e) => setDate(e.target.value)} />
825
- ```
826
-
827
- 3. **Provide clear labels**: Help users understand the input
828
- ```typescript
829
- <DatePicker>
830
- <InputField label="Select Date" />
831
- </DatePicker>
832
- ```
833
-
834
- 4. **Handle undefined values**: User can clear selection
835
- ```typescript
836
- onChange={(e) => {
837
- setDate(e.target.value || new Date())
838
- }}
839
- ```
840
-
841
- 5. **Use timePicker selectively**: Only when time is necessary
842
-
843
- 6. **Disable invalid dates**: Use calendarProps.disabled
844
-
845
- 7. **Format dates appropriately**: Match user's locale and context
846
- ```typescript
847
- <DatePicker dateFormat="MMM dd, yyyy" />
848
- ```
849
-
850
- 8. **Test keyboard navigation**: Ensure accessibility
851
-
852
- ## Related Components
853
-
854
- - [Calendar](./calendar.md) - Base calendar component
855
- - [SlideDatePicker](./slide-date-picker.md) - Mobile-optimized slide picker
856
- - [InputField](./input-field.md) - Input field used as default trigger
857
- - [Popover](./popover.md) - Dropdown container