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.
- package/README.md +4 -3
- package/dist/bin/index.js +9 -24
- package/dist/bin/index.js.map +1 -1
- package/dist/src/commands/add.d.ts +2 -2
- package/dist/src/commands/add.d.ts.map +1 -1
- package/dist/src/commands/add.js +4 -70
- package/dist/src/commands/add.js.map +1 -1
- package/dist/src/commands/hook.d.ts +5 -4
- package/dist/src/commands/hook.d.ts.map +1 -1
- package/dist/src/commands/hook.js +7 -75
- package/dist/src/commands/hook.js.map +1 -1
- package/dist/src/commands/init.js +1 -1
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/layout.d.ts +5 -4
- package/dist/src/commands/layout.d.ts.map +1 -1
- package/dist/src/commands/layout.js +7 -75
- package/dist/src/commands/layout.js.map +1 -1
- package/dist/src/commands/provider.d.ts +5 -4
- package/dist/src/commands/provider.d.ts.map +1 -1
- package/dist/src/commands/provider.js +7 -75
- package/dist/src/commands/provider.js.map +1 -1
- package/dist/src/commands/update.d.ts.map +1 -1
- package/dist/src/commands/update.js +78 -43
- package/dist/src/commands/update.js.map +1 -1
- package/dist/src/commands/utils.d.ts +5 -4
- package/dist/src/commands/utils.d.ts.map +1 -1
- package/dist/src/commands/utils.js +7 -80
- package/dist/src/commands/utils.js.map +1 -1
- package/dist/src/shared/addFromRegistry.d.ts +16 -0
- package/dist/src/shared/addFromRegistry.d.ts.map +1 -0
- package/dist/src/shared/addFromRegistry.js +88 -0
- package/dist/src/shared/addFromRegistry.js.map +1 -0
- package/dist/src/shared/getInstallCommand.d.ts.map +1 -1
- package/dist/src/shared/getInstallCommand.js +5 -0
- package/dist/src/shared/getInstallCommand.js.map +1 -1
- package/dist/src/shared/installDependencies.d.ts +0 -10
- package/dist/src/shared/installDependencies.d.ts.map +1 -1
- package/dist/src/shared/installDependencies.js +0 -17
- package/dist/src/shared/installDependencies.js.map +1 -1
- package/dist/src/shared/installFromPlan.d.ts +7 -5
- package/dist/src/shared/installFromPlan.d.ts.map +1 -1
- package/dist/src/shared/installFromPlan.js +103 -36
- package/dist/src/shared/installFromPlan.js.map +1 -1
- package/dist/src/shared/loadRegistry.d.ts +12 -3
- package/dist/src/shared/loadRegistry.d.ts.map +1 -1
- package/dist/src/shared/loadRegistry.js +19 -20
- package/dist/src/shared/loadRegistry.js.map +1 -1
- package/dist/src/shared/registryClient.d.ts +19 -0
- package/dist/src/shared/registryClient.d.ts.map +1 -0
- package/dist/src/shared/registryClient.js +128 -0
- package/dist/src/shared/registryClient.js.map +1 -0
- package/dist/src/shared/resolveEntry.d.ts +10 -7
- package/dist/src/shared/resolveEntry.d.ts.map +1 -1
- package/dist/src/shared/resolveEntry.js +18 -13
- package/dist/src/shared/resolveEntry.js.map +1 -1
- package/dist/src/shared/suggestOtherCommand.d.ts +7 -1
- package/dist/src/shared/suggestOtherCommand.d.ts.map +1 -1
- package/dist/src/shared/suggestOtherCommand.js +29 -23
- package/dist/src/shared/suggestOtherCommand.js.map +1 -1
- package/dist/src/types/main.d.ts +31 -2
- package/dist/src/types/main.d.ts.map +1 -1
- package/package.json +6 -11
- package/apps/lib/components/ActionButton.tsx +0 -93
- package/apps/lib/components/ActionsGroup.tsx +0 -27
- package/apps/lib/components/AlertDialog.tsx +0 -204
- package/apps/lib/components/Avatar.tsx +0 -46
- package/apps/lib/components/Badge.tsx +0 -250
- package/apps/lib/components/BadgeField.tsx +0 -403
- package/apps/lib/components/Breadcrumb.tsx +0 -280
- package/apps/lib/components/Button.tsx +0 -325
- package/apps/lib/components/ButtonGroup.tsx +0 -190
- package/apps/lib/components/Calendar.tsx +0 -115
- package/apps/lib/components/Card.tsx +0 -95
- package/apps/lib/components/Checkbox.tsx +0 -42
- package/apps/lib/components/ColorPicker.tsx +0 -441
- package/apps/lib/components/ConclusionHeader.tsx +0 -148
- package/apps/lib/components/ContextMenu.tsx +0 -571
- package/apps/lib/components/CountBadge.tsx +0 -52
- package/apps/lib/components/DataTable.tsx +0 -213
- package/apps/lib/components/DataViews/badge.ts +0 -49
- package/apps/lib/components/DataViews/cell.tsx +0 -324
- package/apps/lib/components/DataViews/context.ts +0 -144
- package/apps/lib/components/DataViews/data-views.tsx +0 -395
- package/apps/lib/components/DataViews/filters/children.tsx +0 -98
- package/apps/lib/components/DataViews/filters/custom.tsx +0 -34
- package/apps/lib/components/DataViews/filters/filters.tsx +0 -157
- package/apps/lib/components/DataViews/filters/index.ts +0 -4
- package/apps/lib/components/DataViews/filters/labelled.tsx +0 -20
- package/apps/lib/components/DataViews/filters/presets.tsx +0 -65
- package/apps/lib/components/DataViews/filters/sync.tsx +0 -35
- package/apps/lib/components/DataViews/filters/values.ts +0 -173
- package/apps/lib/components/DataViews/header.tsx +0 -220
- package/apps/lib/components/DataViews/hooks/index.ts +0 -5
- package/apps/lib/components/DataViews/hooks/useActiveRow.ts +0 -22
- package/apps/lib/components/DataViews/hooks/useControllable.ts +0 -52
- package/apps/lib/components/DataViews/index.ts +0 -88
- package/apps/lib/components/DataViews/panel/columns.tsx +0 -153
- package/apps/lib/components/DataViews/panel/controls.tsx +0 -106
- package/apps/lib/components/DataViews/panel/index.ts +0 -3
- package/apps/lib/components/DataViews/panel/panel.tsx +0 -164
- package/apps/lib/components/DataViews/panel/saved-views.tsx +0 -67
- package/apps/lib/components/DataViews/panel/section.tsx +0 -81
- package/apps/lib/components/DataViews/panel/sort.tsx +0 -42
- package/apps/lib/components/DataViews/panel/tab.tsx +0 -31
- package/apps/lib/components/DataViews/slots.ts +0 -72
- package/apps/lib/components/DataViews/states.tsx +0 -73
- package/apps/lib/components/DataViews/types.ts +0 -510
- package/apps/lib/components/DataViews/views/board-view.tsx +0 -381
- package/apps/lib/components/DataViews/views/card-rows.tsx +0 -36
- package/apps/lib/components/DataViews/views/inbox-view.tsx +0 -260
- package/apps/lib/components/DataViews/views/pane-views.tsx +0 -196
- package/apps/lib/components/DataViews/views/table-view.tsx +0 -493
- package/apps/lib/components/DataViews/views/tree-view.tsx +0 -367
- package/apps/lib/components/DatePicker.tsx +0 -232
- package/apps/lib/components/Dialog.tsx +0 -116
- package/apps/lib/components/Divider.tsx +0 -28
- package/apps/lib/components/Drawer.tsx +0 -451
- package/apps/lib/components/DropdownMenu.tsx +0 -554
- package/apps/lib/components/FieldHint.tsx +0 -69
- package/apps/lib/components/Form.tsx +0 -182
- package/apps/lib/components/FormBuilder/context.ts +0 -85
- package/apps/lib/components/FormBuilder/field-kind.ts +0 -28
- package/apps/lib/components/FormBuilder/fields/ChoiceFields.tsx +0 -60
- package/apps/lib/components/FormBuilder/fields/ColorField.tsx +0 -59
- package/apps/lib/components/FormBuilder/fields/CustomField.tsx +0 -11
- package/apps/lib/components/FormBuilder/fields/DateField.tsx +0 -32
- package/apps/lib/components/FormBuilder/fields/FieldArray.tsx +0 -74
- package/apps/lib/components/FormBuilder/fields/FieldShell.tsx +0 -168
- package/apps/lib/components/FormBuilder/fields/FileField.tsx +0 -39
- package/apps/lib/components/FormBuilder/fields/OptionListFields.tsx +0 -132
- package/apps/lib/components/FormBuilder/fields/OtpField.tsx +0 -31
- package/apps/lib/components/FormBuilder/fields/PhoneField.tsx +0 -109
- package/apps/lib/components/FormBuilder/fields/RichTextEditorField.tsx +0 -31
- package/apps/lib/components/FormBuilder/fields/SelectField.tsx +0 -114
- package/apps/lib/components/FormBuilder/fields/SignatureField.tsx +0 -157
- package/apps/lib/components/FormBuilder/fields/SliderField.tsx +0 -67
- package/apps/lib/components/FormBuilder/fields/SwitchBoxField.tsx +0 -41
- package/apps/lib/components/FormBuilder/fields/TableField.tsx +0 -336
- package/apps/lib/components/FormBuilder/fields/TextField.tsx +0 -213
- package/apps/lib/components/FormBuilder/fields/TreeSelectField.tsx +0 -43
- package/apps/lib/components/FormBuilder/fields/countries.ts +0 -303
- package/apps/lib/components/FormBuilder/fields/index.ts +0 -25
- package/apps/lib/components/FormBuilder/form-builder.tsx +0 -198
- package/apps/lib/components/FormBuilder/index.ts +0 -31
- package/apps/lib/components/FormBuilder/numberFormat.ts +0 -16
- package/apps/lib/components/FormBuilder/submit.tsx +0 -67
- package/apps/lib/components/FormBuilder/types.ts +0 -316
- package/apps/lib/components/FormRenderer/FormDrawer.tsx +0 -250
- package/apps/lib/components/FormRenderer/detail.tsx +0 -256
- package/apps/lib/components/FormRenderer/form-renderer.tsx +0 -358
- package/apps/lib/components/FormRenderer/header.tsx +0 -88
- package/apps/lib/components/FormRenderer/index.ts +0 -17
- package/apps/lib/components/FormRenderer/notch-action.tsx +0 -64
- package/apps/lib/components/FormRenderer/section.tsx +0 -39
- package/apps/lib/components/FormRenderer/stepper.tsx +0 -393
- package/apps/lib/components/FormRenderer/types.ts +0 -115
- package/apps/lib/components/FormSummary.tsx +0 -282
- package/apps/lib/components/HeaderBar.tsx +0 -117
- package/apps/lib/components/ImageAttachment.tsx +0 -209
- package/apps/lib/components/InnerLabelField.tsx +0 -154
- package/apps/lib/components/Input.tsx +0 -224
- package/apps/lib/components/InputField.tsx +0 -147
- package/apps/lib/components/InputOTP.tsx +0 -84
- package/apps/lib/components/Label.tsx +0 -129
- package/apps/lib/components/LabelField.tsx +0 -76
- package/apps/lib/components/LabeledCheckBox.tsx +0 -51
- package/apps/lib/components/LabeledRadio.tsx +0 -51
- package/apps/lib/components/LinkButton.tsx +0 -94
- package/apps/lib/components/LoginButton.tsx +0 -51
- package/apps/lib/components/PasswordLevel.tsx +0 -58
- package/apps/lib/components/Popover.tsx +0 -312
- package/apps/lib/components/ProfileMenu.tsx +0 -85
- package/apps/lib/components/Radio.tsx +0 -59
- package/apps/lib/components/RadioCard.tsx +0 -50
- package/apps/lib/components/ScrollArea.tsx +0 -54
- package/apps/lib/components/SearchField.tsx +0 -62
- package/apps/lib/components/SearchableSelect.tsx +0 -318
- package/apps/lib/components/SearchableTable.tsx +0 -344
- package/apps/lib/components/SearchableTree.tsx +0 -485
- package/apps/lib/components/SearchableTreeDialog.tsx +0 -502
- package/apps/lib/components/SectionBlock.tsx +0 -168
- package/apps/lib/components/Select.tsx +0 -347
- package/apps/lib/components/SimpleSelect.tsx +0 -225
- package/apps/lib/components/Skeleton.tsx +0 -12
- package/apps/lib/components/SlideDatePicker.tsx +0 -255
- package/apps/lib/components/SpinLoading.tsx +0 -174
- package/apps/lib/components/Stepper.tsx +0 -480
- package/apps/lib/components/Switch.tsx +0 -82
- package/apps/lib/components/TabFormItem.tsx +0 -153
- package/apps/lib/components/TabSwitch.tsx +0 -172
- package/apps/lib/components/Table.tsx +0 -597
- package/apps/lib/components/TextEditor/ChartBlockTool.ts +0 -676
- package/apps/lib/components/TextEditor/RichTextField.tsx +0 -46
- package/apps/lib/components/TextEditor/TableDnDWrapper.ts +0 -462
- package/apps/lib/components/TextEditor/TextEditor.tsx +0 -1164
- package/apps/lib/components/TextEditor/TextEditorToolbar.tsx +0 -429
- package/apps/lib/components/TextEditor/editor-tools/AlignmentTune.ts +0 -70
- package/apps/lib/components/TextEditor/editor-tools/ColorInlineTool.ts +0 -50
- package/apps/lib/components/TextEditor/editor-tools/StrikethroughInlineTool.ts +0 -48
- package/apps/lib/components/TextEditor/editor-tools/inlineFormat.ts +0 -98
- package/apps/lib/components/TextEditor/editorjs.d.ts +0 -60
- package/apps/lib/components/TextEditor/index.ts +0 -7
- package/apps/lib/components/TextEditor/markdownParser.ts +0 -346
- package/apps/lib/components/Textarea.tsx +0 -117
- package/apps/lib/components/Timeline.tsx +0 -263
- package/apps/lib/components/Toast.tsx +0 -87
- package/apps/lib/components/Toggle.tsx +0 -125
- package/apps/lib/components/ToggleButton.tsx +0 -140
- package/apps/lib/components/Tooltip.tsx +0 -116
- package/apps/lib/components/TransparentLabel.tsx +0 -71
- package/apps/lib/components/TreeDropDown.tsx +0 -115
- package/apps/lib/components/TreeFolder/TreeFolder.tsx +0 -380
- package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +0 -75
- package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +0 -354
- package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +0 -60
- package/apps/lib/components/TreeFolder/icons.tsx +0 -60
- package/apps/lib/components/TreeFolder/index.ts +0 -24
- package/apps/lib/components/TreeFolder/treeFolderUtils.ts +0 -109
- package/apps/lib/components/TreeFolder/types.ts +0 -77
- package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +0 -118
- package/apps/lib/hooks/useActiveTreeItem.ts +0 -61
- package/apps/lib/hooks/useClickOutside.ts +0 -27
- package/apps/lib/hooks/useDragDrop.tsx +0 -365
- package/apps/lib/hooks/useHtmlDir.ts +0 -31
- package/apps/lib/hooks/useInfiniteScroll.ts +0 -108
- package/apps/lib/hooks/useIsMobile.ts +0 -21
- package/apps/lib/hooks/useResize.ts +0 -67
- package/apps/lib/hooks/useTagSelection.ts +0 -300
- package/apps/lib/layouts/CNLayout.tsx +0 -372
- package/apps/lib/layouts/DataViewCard.tsx +0 -62
- package/apps/lib/layouts/FieldSection.tsx +0 -91
- package/apps/lib/layouts/TreeSubLayout.tsx +0 -173
- package/apps/lib/providers/ThemeProvider.tsx +0 -84
- package/apps/lib/registry.json +0 -1217
- package/apps/lib/tsconfig.json +0 -9
- package/apps/lib/tsconfig.tsbuildinfo +0 -1
- package/apps/lib/utils/cn.ts +0 -6
- package/apps/lib/utils/color.ts +0 -175
- package/apps/lib/utils/dataViews/path.ts +0 -67
- package/apps/lib/utils/dataViews/query.ts +0 -73
- package/apps/lib/utils/dataViews/types.ts +0 -187
- package/apps/lib/utils/dateFormat.ts +0 -108
- package/apps/lib/utils/resize.ts +0 -31
- package/apps/lib/utils/scroller.ts +0 -26
- package/apps/lib/utils/types.ts +0 -16
- package/docs/BLOCKS.md +0 -129
- package/docs/CHANGELOG-1.1.16.md +0 -108
- package/docs/Cover.png +0 -0
- package/docs/README.md +0 -215
- package/docs/components/action-button.md +0 -638
- package/docs/components/actions-group.md +0 -708
- package/docs/components/alert-dialog.md +0 -920
- package/docs/components/avatar.md +0 -709
- package/docs/components/badge-field.md +0 -738
- package/docs/components/badge.md +0 -301
- package/docs/components/breadcrumb.md +0 -930
- package/docs/components/button-group.md +0 -650
- package/docs/components/button.md +0 -639
- package/docs/components/calendar.md +0 -555
- package/docs/components/card.md +0 -622
- package/docs/components/chart-block-tool.md +0 -129
- package/docs/components/checkbox.md +0 -699
- package/docs/components/cn-layout.md +0 -854
- package/docs/components/color-picker.md +0 -101
- package/docs/components/conclusion-header.md +0 -80
- package/docs/components/context-menu.md +0 -483
- package/docs/components/count-badge.md +0 -560
- package/docs/components/data-table.md +0 -854
- package/docs/components/data-views/backend-response.md +0 -324
- package/docs/components/data-views/examples/a11y-rtl.md +0 -250
- package/docs/components/data-views/examples/api-orders-route.md +0 -130
- package/docs/components/data-views/examples/fields.md +0 -362
- package/docs/components/data-views/examples/filters.md +0 -307
- package/docs/components/data-views/examples/inbox-routing.md +0 -218
- package/docs/components/data-views/examples/index.md +0 -29
- package/docs/components/data-views/examples/overview.md +0 -244
- package/docs/components/data-views/examples/panel.md +0 -212
- package/docs/components/data-views/examples/scale.md +0 -231
- package/docs/components/data-views/examples/server-side.md +0 -210
- package/docs/components/data-views/examples/state.md +0 -250
- package/docs/components/data-views/examples/tree-custom.md +0 -388
- package/docs/components/data-views/examples/view-registry.md +0 -313
- package/docs/components/data-views/examples/views.md +0 -534
- package/docs/components/data-views/guide.md +0 -405
- package/docs/components/data-views/index.md +0 -1521
- package/docs/components/data-views/migration.md +0 -81
- package/docs/components/date-picker.md +0 -857
- package/docs/components/dialog.md +0 -929
- package/docs/components/divider.md +0 -766
- package/docs/components/drawer.md +0 -654
- package/docs/components/dropdown-menu.md +0 -668
- package/docs/components/field-hint.md +0 -898
- package/docs/components/field-section.md +0 -781
- package/docs/components/form-builder.md +0 -284
- package/docs/components/form-renderer.md +0 -396
- package/docs/components/form-summary.md +0 -138
- package/docs/components/form.md +0 -785
- package/docs/components/header-bar.md +0 -188
- package/docs/components/image-attachment.md +0 -906
- package/docs/components/inner-label-field.md +0 -819
- package/docs/components/input-field.md +0 -623
- package/docs/components/input-otp.md +0 -756
- package/docs/components/input.md +0 -634
- package/docs/components/label-field.md +0 -770
- package/docs/components/label.md +0 -761
- package/docs/components/labeled-check-box.md +0 -642
- package/docs/components/labeled-radio.md +0 -796
- package/docs/components/link-button.md +0 -685
- package/docs/components/login-button.md +0 -872
- package/docs/components/password-level.md +0 -803
- package/docs/components/popover.md +0 -649
- package/docs/components/profile-menu.md +0 -656
- package/docs/components/radio-card.md +0 -801
- package/docs/components/radio.md +0 -735
- package/docs/components/scroll-area.md +0 -691
- package/docs/components/search-field.md +0 -702
- package/docs/components/searchable-select.md +0 -368
- package/docs/components/searchable-table.md +0 -438
- package/docs/components/searchable-tree-dialog.md +0 -190
- package/docs/components/searchable-tree.md +0 -200
- package/docs/components/section-block.md +0 -483
- package/docs/components/select.md +0 -709
- package/docs/components/simple-select.md +0 -741
- package/docs/components/skeleton.md +0 -706
- package/docs/components/slide-date-picker.md +0 -837
- package/docs/components/spin-loading.md +0 -696
- package/docs/components/stepper.md +0 -316
- package/docs/components/switch.md +0 -770
- package/docs/components/tab-form-item.md +0 -773
- package/docs/components/tab-switch.md +0 -170
- package/docs/components/table-dnd-wrapper.md +0 -107
- package/docs/components/table.md +0 -1088
- package/docs/components/text-editor.md +0 -735
- package/docs/components/textarea.md +0 -681
- package/docs/components/timeline.md +0 -254
- package/docs/components/toast.md +0 -773
- package/docs/components/toggle-button.md +0 -643
- package/docs/components/toggle.md +0 -882
- package/docs/components/tooltip.md +0 -513
- package/docs/components/transparent-label.md +0 -721
- package/docs/components/tree-drop-down.md +0 -740
- package/docs/components/tree-folder.md +0 -110
- package/docs/components/tree-sub-layout.md +0 -707
- package/docs/explanation/architecture.md +0 -54
- package/docs/explanation/design-system.md +0 -52
- package/docs/how-to/form-and-list-recipes.md +0 -386
- package/docs/how-to/forms-with-form-builder.md +0 -472
- package/docs/how-to/guides.md +0 -1027
- package/docs/migration/changelog.md +0 -60
- package/docs/migration/form-builder-2.5.2.md +0 -113
- package/docs/reference/cli.md +0 -112
- package/docs/reference/components.md +0 -572
- package/docs/reference/hooks.md +0 -1523
- package/docs/reference/providers.md +0 -866
- package/docs/reference/tailwind-plugins.md +0 -942
- package/docs/reference/theme.md +0 -85
- package/docs/reference/types.md +0 -1016
- package/docs/reference/utilities.md +0 -726
- package/docs/tutorials/building-first-form.md +0 -846
- package/docs/tutorials/component-composition.md +0 -882
- package/docs/tutorials/getting-started.md +0 -302
- package/docs/tutorials/theming-basics.md +0 -785
|
@@ -1,726 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Utilities Reference
|
|
3
|
-
description: Helper functions and utility modules in TORCH Glare Components Library.
|
|
4
|
-
category: Reference
|
|
5
|
-
tags: [utilities, helpers, functions, date, styles, resize]
|
|
6
|
-
related:
|
|
7
|
-
- Types Reference
|
|
8
|
-
- Hooks Reference
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Utilities Reference
|
|
12
|
-
|
|
13
|
-
Complete reference of helper functions and utility modules available in TORCH Glare.
|
|
14
|
-
|
|
15
|
-
## Table of Contents
|
|
16
|
-
|
|
17
|
-
- [Class Name Utilities](#class-name-utilities)
|
|
18
|
-
- [Date & Time Utilities](#date--time-utilities)
|
|
19
|
-
- [Resize Utilities](#resize-utilities)
|
|
20
|
-
- [Type Utilities](#type-utilities)
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## Class Name Utilities
|
|
25
|
-
|
|
26
|
-
### cn
|
|
27
|
-
|
|
28
|
-
Utility function to merge and deduplicate Tailwind CSS classes.
|
|
29
|
-
|
|
30
|
-
**Import:**
|
|
31
|
-
```typescript
|
|
32
|
-
import { cn } from "@/utils/cn";
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
**Signature:**
|
|
36
|
-
```typescript
|
|
37
|
-
function cn(...inputs: ClassValue[]): string
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
**Parameters:**
|
|
41
|
-
- `...inputs`: `ClassValue[]` - Any number of class values to merge
|
|
42
|
-
|
|
43
|
-
**Returns:**
|
|
44
|
-
- `string` - Merged and deduplicated class names
|
|
45
|
-
|
|
46
|
-
**Examples:**
|
|
47
|
-
|
|
48
|
-
#### Basic Usage
|
|
49
|
-
|
|
50
|
-
```typescript
|
|
51
|
-
import { cn } from "@/utils/cn";
|
|
52
|
-
|
|
53
|
-
// Merge multiple classes
|
|
54
|
-
cn('px-4 py-2', 'bg-blue-500', 'text-white')
|
|
55
|
-
// Returns: "px-4 py-2 bg-blue-500 text-white"
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
#### Conditional Classes
|
|
59
|
-
|
|
60
|
-
```typescript
|
|
61
|
-
const isActive = true;
|
|
62
|
-
const isDisabled = false;
|
|
63
|
-
|
|
64
|
-
cn(
|
|
65
|
-
'base-class',
|
|
66
|
-
isActive && 'active-class',
|
|
67
|
-
isDisabled && 'disabled-class'
|
|
68
|
-
)
|
|
69
|
-
// Returns: "base-class active-class"
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
#### Object Syntax
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
cn({
|
|
76
|
-
'text-white': true,
|
|
77
|
-
'bg-blue-500': true,
|
|
78
|
-
'hover:bg-blue-600': true,
|
|
79
|
-
'opacity-50': false
|
|
80
|
-
})
|
|
81
|
-
// Returns: "text-white bg-blue-500 hover:bg-blue-600"
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
#### Array Syntax
|
|
85
|
-
|
|
86
|
-
```typescript
|
|
87
|
-
cn([
|
|
88
|
-
'px-4',
|
|
89
|
-
'py-2',
|
|
90
|
-
['rounded', 'shadow'],
|
|
91
|
-
{ 'bg-blue-500': true }
|
|
92
|
-
])
|
|
93
|
-
// Returns: "px-4 py-2 rounded shadow bg-blue-500"
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
#### Deduplicating Conflicts
|
|
97
|
-
|
|
98
|
-
```typescript
|
|
99
|
-
// Later classes override earlier ones
|
|
100
|
-
cn('px-2 py-1', 'px-4 py-2')
|
|
101
|
-
// Returns: "px-4 py-2"
|
|
102
|
-
|
|
103
|
-
// Works with Tailwind modifiers
|
|
104
|
-
cn('hover:text-blue-500', 'hover:text-red-500')
|
|
105
|
-
// Returns: "hover:text-red-500"
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
#### Component Usage
|
|
109
|
-
|
|
110
|
-
```typescript
|
|
111
|
-
interface ButtonProps {
|
|
112
|
-
variant?: 'primary' | 'secondary';
|
|
113
|
-
size?: 'S' | 'M' | 'L';
|
|
114
|
-
className?: string;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function Button({ variant = 'primary', size = 'M', className }: ButtonProps) {
|
|
118
|
-
return (
|
|
119
|
-
<button
|
|
120
|
-
className={cn(
|
|
121
|
-
// Base classes
|
|
122
|
-
'rounded font-medium',
|
|
123
|
-
|
|
124
|
-
// Variant classes
|
|
125
|
-
{
|
|
126
|
-
'bg-blue-500 text-white': variant === 'primary',
|
|
127
|
-
'bg-gray-200 text-gray-800': variant === 'secondary',
|
|
128
|
-
},
|
|
129
|
-
|
|
130
|
-
// Size classes
|
|
131
|
-
{
|
|
132
|
-
'px-2 py-1 text-sm': size === 'S',
|
|
133
|
-
'px-4 py-2 text-base': size === 'M',
|
|
134
|
-
'px-6 py-3 text-lg': size === 'L',
|
|
135
|
-
},
|
|
136
|
-
|
|
137
|
-
// Custom classes (overrides defaults)
|
|
138
|
-
className
|
|
139
|
-
)}
|
|
140
|
-
>
|
|
141
|
-
Click me
|
|
142
|
-
</button>
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
**Use Cases:**
|
|
148
|
-
- Merging component class names
|
|
149
|
-
- Handling conditional styling
|
|
150
|
-
- Deduplicating Tailwind classes
|
|
151
|
-
- Combining base and custom styles
|
|
152
|
-
|
|
153
|
-
**Related:**
|
|
154
|
-
- Uses [clsx](https://github.com/lukeed/clsx) internally
|
|
155
|
-
- Uses [tailwind-merge](https://github.com/dcastil/tailwind-merge) for deduplication
|
|
156
|
-
|
|
157
|
-
---
|
|
158
|
-
|
|
159
|
-
## Date & Time Utilities
|
|
160
|
-
|
|
161
|
-
Utilities for working with dates, times, and date pickers.
|
|
162
|
-
|
|
163
|
-
### applyTimeToDate
|
|
164
|
-
|
|
165
|
-
Applies time from a picker to a date object.
|
|
166
|
-
|
|
167
|
-
**Import:**
|
|
168
|
-
```typescript
|
|
169
|
-
import { applyTimeToDate } from "@/utils/dateFormat";
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
**Signature:**
|
|
173
|
-
```typescript
|
|
174
|
-
function applyTimeToDate(
|
|
175
|
-
date: Date,
|
|
176
|
-
timePickerValue: TimePickerValue
|
|
177
|
-
): Date
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
**Parameters:**
|
|
181
|
-
- `date`: `Date` - The base date to apply time to
|
|
182
|
-
- `timePickerValue`: `TimePickerValue` - Object with hour, minute, and AM/PM
|
|
183
|
-
|
|
184
|
-
**Returns:**
|
|
185
|
-
- `Date` - New Date object with applied time
|
|
186
|
-
|
|
187
|
-
**Example:**
|
|
188
|
-
|
|
189
|
-
```typescript
|
|
190
|
-
const date = new Date('2024-01-15');
|
|
191
|
-
const time = {
|
|
192
|
-
hour: '02',
|
|
193
|
-
minute: '30',
|
|
194
|
-
time: 'PM'
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
const result = applyTimeToDate(date, time);
|
|
198
|
-
// Result: Date object with time set to 14:30 (2:30 PM)
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
---
|
|
202
|
-
|
|
203
|
-
### isValidDateObject
|
|
204
|
-
|
|
205
|
-
Validates if a value is a valid Date object.
|
|
206
|
-
|
|
207
|
-
**Import:**
|
|
208
|
-
```typescript
|
|
209
|
-
import { isValidDateObject } from "@/utils/dateFormat";
|
|
210
|
-
```
|
|
211
|
-
|
|
212
|
-
**Signature:**
|
|
213
|
-
```typescript
|
|
214
|
-
function isValidDateObject(date: Date): boolean
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
**Parameters:**
|
|
218
|
-
- `date`: `Date` - The date to validate
|
|
219
|
-
|
|
220
|
-
**Returns:**
|
|
221
|
-
- `boolean` - True if valid Date, false otherwise
|
|
222
|
-
|
|
223
|
-
**Examples:**
|
|
224
|
-
|
|
225
|
-
```typescript
|
|
226
|
-
import { isValidDateObject } from "@/utils/dateFormat";
|
|
227
|
-
|
|
228
|
-
isValidDateObject(new Date())
|
|
229
|
-
// Returns: true
|
|
230
|
-
|
|
231
|
-
isValidDateObject(new Date('2024-01-15'))
|
|
232
|
-
// Returns: true
|
|
233
|
-
|
|
234
|
-
isValidDateObject(new Date('invalid'))
|
|
235
|
-
// Returns: false
|
|
236
|
-
|
|
237
|
-
isValidDateObject(null)
|
|
238
|
-
// Returns: false
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
---
|
|
242
|
-
|
|
243
|
-
### applyTimeToDateValue
|
|
244
|
-
|
|
245
|
-
Applies time to various date value types (single, array, or range).
|
|
246
|
-
|
|
247
|
-
**Import:**
|
|
248
|
-
```typescript
|
|
249
|
-
import { applyTimeToDateValue } from "@/utils/dateFormat";
|
|
250
|
-
```
|
|
251
|
-
|
|
252
|
-
**Signature:**
|
|
253
|
-
```typescript
|
|
254
|
-
function applyTimeToDateValue(
|
|
255
|
-
dateValue: Date | Date[] | DateRange | undefined,
|
|
256
|
-
timePickerValue: TimePickerValue
|
|
257
|
-
): Date | Date[] | DateRange | undefined
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
**Parameters:**
|
|
261
|
-
- `dateValue`: `Date | Date[] | DateRange | undefined` - Date value to process
|
|
262
|
-
- `timePickerValue`: `TimePickerValue` - Time to apply
|
|
263
|
-
|
|
264
|
-
**Returns:**
|
|
265
|
-
- Same type as input with time applied
|
|
266
|
-
|
|
267
|
-
**Examples:**
|
|
268
|
-
|
|
269
|
-
#### Single Date
|
|
270
|
-
|
|
271
|
-
```typescript
|
|
272
|
-
const date = new Date('2024-01-15');
|
|
273
|
-
const time = { hour: '02', minute: '30', time: 'PM' };
|
|
274
|
-
|
|
275
|
-
applyTimeToDateValue(date, time)
|
|
276
|
-
// Returns: Date with time 14:30
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
#### Date Array
|
|
280
|
-
|
|
281
|
-
```typescript
|
|
282
|
-
const dates = [
|
|
283
|
-
new Date('2024-01-15'),
|
|
284
|
-
new Date('2024-01-16')
|
|
285
|
-
];
|
|
286
|
-
const time = { hour: '09', minute: '00', time: 'AM' };
|
|
287
|
-
|
|
288
|
-
applyTimeToDateValue(dates, time)
|
|
289
|
-
// Returns: Array of dates, each with time 09:00
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
#### Date Range
|
|
293
|
-
|
|
294
|
-
```typescript
|
|
295
|
-
const range = {
|
|
296
|
-
from: new Date('2024-01-15'),
|
|
297
|
-
to: new Date('2024-01-20')
|
|
298
|
-
};
|
|
299
|
-
const time = { hour: '11', minute: '30', time: 'AM' };
|
|
300
|
-
|
|
301
|
-
applyTimeToDateValue(range, time)
|
|
302
|
-
// Returns: { from: Date(11:30), to: Date(11:30) }
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
---
|
|
306
|
-
|
|
307
|
-
### formatDateValueToString
|
|
308
|
-
|
|
309
|
-
Formats date values to strings with time applied.
|
|
310
|
-
|
|
311
|
-
**Import:**
|
|
312
|
-
```typescript
|
|
313
|
-
import { formatDateValueToString } from "@/utils/dateFormat";
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
**Signature:**
|
|
317
|
-
```typescript
|
|
318
|
-
function formatDateValueToString(
|
|
319
|
-
date: Date | Date[] | DateRange | undefined,
|
|
320
|
-
timePickerValue: TimePickerValue,
|
|
321
|
-
dateFormat: string
|
|
322
|
-
): string
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
**Parameters:**
|
|
326
|
-
- `date`: `Date | Date[] | DateRange | undefined` - Date to format
|
|
327
|
-
- `timePickerValue`: `TimePickerValue` - Time to apply
|
|
328
|
-
- `dateFormat`: `string` - Format string (e.g., 'MM/dd/yyyy')
|
|
329
|
-
|
|
330
|
-
**Returns:**
|
|
331
|
-
- `string` - Formatted date string
|
|
332
|
-
|
|
333
|
-
**Examples:**
|
|
334
|
-
|
|
335
|
-
#### Single Date
|
|
336
|
-
|
|
337
|
-
```typescript
|
|
338
|
-
const date = new Date('2024-01-15');
|
|
339
|
-
const time = { hour: '02', minute: '30', time: 'PM' };
|
|
340
|
-
|
|
341
|
-
formatDateValueToString(date, time, 'MM/dd/yyyy hh:mm a')
|
|
342
|
-
// Returns: "01/15/2024 02:30 PM"
|
|
343
|
-
|
|
344
|
-
formatDateValueToString(date, time, 'yyyy-MM-dd HH:mm')
|
|
345
|
-
// Returns: "2024-01-15 14:30"
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
#### Date Array
|
|
349
|
-
|
|
350
|
-
```typescript
|
|
351
|
-
const dates = [
|
|
352
|
-
new Date('2024-01-15'),
|
|
353
|
-
new Date('2024-01-16')
|
|
354
|
-
];
|
|
355
|
-
const time = { hour: '09', minute: '00', time: 'AM' };
|
|
356
|
-
|
|
357
|
-
formatDateValueToString(dates, time, 'MM/dd/yyyy')
|
|
358
|
-
// Returns: "01/15/2024, 01/16/2024"
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
#### Date Range
|
|
362
|
-
|
|
363
|
-
```typescript
|
|
364
|
-
const range = {
|
|
365
|
-
from: new Date('2024-01-15'),
|
|
366
|
-
to: new Date('2024-01-20')
|
|
367
|
-
};
|
|
368
|
-
const time = { hour: '11', minute: '30', time: 'AM' };
|
|
369
|
-
|
|
370
|
-
formatDateValueToString(range, time, 'MMM dd, yyyy')
|
|
371
|
-
// Returns: "Jan 15, 2024 - Jan 20, 2024"
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
#### Format Patterns
|
|
375
|
-
|
|
376
|
-
Common format patterns (using [date-fns](https://date-fns.org/)):
|
|
377
|
-
|
|
378
|
-
| Pattern | Output | Description |
|
|
379
|
-
|---------|--------|-------------|
|
|
380
|
-
| `yyyy-MM-dd` | 2024-01-15 | ISO date format |
|
|
381
|
-
| `MM/dd/yyyy` | 01/15/2024 | US date format |
|
|
382
|
-
| `dd/MM/yyyy` | 15/01/2024 | European format |
|
|
383
|
-
| `MMM dd, yyyy` | Jan 15, 2024 | Long date |
|
|
384
|
-
| `MMMM dd, yyyy` | January 15, 2024 | Full month name |
|
|
385
|
-
| `hh:mm a` | 02:30 PM | 12-hour time |
|
|
386
|
-
| `HH:mm` | 14:30 | 24-hour time |
|
|
387
|
-
| `yyyy-MM-dd HH:mm:ss` | 2024-01-15 14:30:00 | Full timestamp |
|
|
388
|
-
|
|
389
|
-
---
|
|
390
|
-
|
|
391
|
-
## Resize Utilities
|
|
392
|
-
|
|
393
|
-
Utilities for calculating element dimensions during resize operations.
|
|
394
|
-
|
|
395
|
-
### calculateNewWidthFromMouse
|
|
396
|
-
|
|
397
|
-
Calculates new width based on mouse position with RTL support.
|
|
398
|
-
|
|
399
|
-
**Import:**
|
|
400
|
-
```typescript
|
|
401
|
-
import { calculateNewWidthFromMouse } from "@/utils/resize";
|
|
402
|
-
```
|
|
403
|
-
|
|
404
|
-
**Signature:**
|
|
405
|
-
```typescript
|
|
406
|
-
function calculateNewWidthFromMouse(
|
|
407
|
-
event: MouseEvent,
|
|
408
|
-
resizableRef: MutableRefObject<HTMLElement | null> | RefObject<HTMLElement | null>,
|
|
409
|
-
isRtl: boolean
|
|
410
|
-
): number
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
**Parameters:**
|
|
414
|
-
- `event`: `MouseEvent` - Mouse event from resize
|
|
415
|
-
- `resizableRef`: `Ref<HTMLElement>` - Ref to element being resized
|
|
416
|
-
- `isRtl`: `boolean` - Whether layout is RTL
|
|
417
|
-
|
|
418
|
-
**Returns:**
|
|
419
|
-
- `number` - Calculated width in pixels
|
|
420
|
-
|
|
421
|
-
**Example:**
|
|
422
|
-
|
|
423
|
-
```typescript
|
|
424
|
-
import { useRef, useState } from 'react';
|
|
425
|
-
import { calculateNewWidthFromMouse } from "@/utils/resize";
|
|
426
|
-
|
|
427
|
-
function ResizablePanel() {
|
|
428
|
-
const panelRef = useRef<HTMLDivElement>(null);
|
|
429
|
-
const [width, setWidth] = useState(300);
|
|
430
|
-
const isRtl = document.dir === 'rtl';
|
|
431
|
-
|
|
432
|
-
const handleMouseMove = (e: MouseEvent) => {
|
|
433
|
-
const newWidth = calculateNewWidthFromMouse(e, panelRef, isRtl);
|
|
434
|
-
setWidth(newWidth);
|
|
435
|
-
};
|
|
436
|
-
|
|
437
|
-
return (
|
|
438
|
-
<div
|
|
439
|
-
ref={panelRef}
|
|
440
|
-
style={{ width: `${width}px` }}
|
|
441
|
-
onMouseDown={() => {
|
|
442
|
-
document.addEventListener('mousemove', handleMouseMove);
|
|
443
|
-
}}
|
|
444
|
-
>
|
|
445
|
-
Resizable content
|
|
446
|
-
</div>
|
|
447
|
-
);
|
|
448
|
-
}
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
---
|
|
452
|
-
|
|
453
|
-
### calculateNewWidthFromTouch
|
|
454
|
-
|
|
455
|
-
Calculates new width based on touch position with RTL support.
|
|
456
|
-
|
|
457
|
-
**Import:**
|
|
458
|
-
```typescript
|
|
459
|
-
import { calculateNewWidthFromTouch } from "@/utils/resize";
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
**Signature:**
|
|
463
|
-
```typescript
|
|
464
|
-
function calculateNewWidthFromTouch(
|
|
465
|
-
event: TouchEvent,
|
|
466
|
-
resizableRef: MutableRefObject<HTMLElement | null> | RefObject<HTMLElement | null>,
|
|
467
|
-
isRtl: boolean
|
|
468
|
-
): number
|
|
469
|
-
```
|
|
470
|
-
|
|
471
|
-
**Parameters:**
|
|
472
|
-
- `event`: `TouchEvent` - Touch event from resize
|
|
473
|
-
- `resizableRef`: `Ref<HTMLElement>` - Ref to element being resized
|
|
474
|
-
- `isRtl`: `boolean` - Whether layout is RTL
|
|
475
|
-
|
|
476
|
-
**Returns:**
|
|
477
|
-
- `number` - Calculated width in pixels
|
|
478
|
-
|
|
479
|
-
**Example:**
|
|
480
|
-
|
|
481
|
-
```typescript
|
|
482
|
-
import { useRef, useState } from 'react';
|
|
483
|
-
import { calculateNewWidthFromTouch } from "@/utils/resize";
|
|
484
|
-
|
|
485
|
-
function TouchResizablePanel() {
|
|
486
|
-
const panelRef = useRef<HTMLDivElement>(null);
|
|
487
|
-
const [width, setWidth] = useState(300);
|
|
488
|
-
const isRtl = document.dir === 'rtl';
|
|
489
|
-
|
|
490
|
-
const handleTouchMove = (e: TouchEvent) => {
|
|
491
|
-
const newWidth = calculateNewWidthFromTouch(e, panelRef, isRtl);
|
|
492
|
-
setWidth(newWidth);
|
|
493
|
-
};
|
|
494
|
-
|
|
495
|
-
return (
|
|
496
|
-
<div
|
|
497
|
-
ref={panelRef}
|
|
498
|
-
style={{ width: `${width}px` }}
|
|
499
|
-
onTouchStart={() => {
|
|
500
|
-
document.addEventListener('touchmove', handleTouchMove);
|
|
501
|
-
}}
|
|
502
|
-
>
|
|
503
|
-
Touch resizable content
|
|
504
|
-
</div>
|
|
505
|
-
);
|
|
506
|
-
}
|
|
507
|
-
```
|
|
508
|
-
|
|
509
|
-
---
|
|
510
|
-
|
|
511
|
-
## Type Utilities
|
|
512
|
-
|
|
513
|
-
### TimePickerValue
|
|
514
|
-
|
|
515
|
-
Type for time picker values.
|
|
516
|
-
|
|
517
|
-
```typescript
|
|
518
|
-
export type TimePickerValue = {
|
|
519
|
-
hour: string; // "01" to "12"
|
|
520
|
-
minute: string; // "00" to "59"
|
|
521
|
-
time: string; // "AM" or "PM"
|
|
522
|
-
}
|
|
523
|
-
```
|
|
524
|
-
|
|
525
|
-
**Example:**
|
|
526
|
-
|
|
527
|
-
```typescript
|
|
528
|
-
const time: TimePickerValue = {
|
|
529
|
-
hour: '02',
|
|
530
|
-
minute: '30',
|
|
531
|
-
time: 'PM'
|
|
532
|
-
};
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
---
|
|
536
|
-
|
|
537
|
-
## Common Patterns
|
|
538
|
-
|
|
539
|
-
### Combining Utilities
|
|
540
|
-
|
|
541
|
-
#### Date Formatting with Time
|
|
542
|
-
|
|
543
|
-
```typescript
|
|
544
|
-
import { applyTimeToDate, formatDateValueToString, isValidDateObject } from "@/utils/dateFormat";
|
|
545
|
-
|
|
546
|
-
function formatUserSelectedDate(
|
|
547
|
-
date: Date,
|
|
548
|
-
time: TimePickerValue,
|
|
549
|
-
format: string
|
|
550
|
-
): string | null {
|
|
551
|
-
if (!isValidDateObject(date)) {
|
|
552
|
-
return null;
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
return formatDateValueToString(date, time, format);
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
// Usage
|
|
559
|
-
const date = new Date('2024-01-15');
|
|
560
|
-
const time = { hour: '02', minute: '30', time: 'PM' };
|
|
561
|
-
const formatted = formatUserSelectedDate(date, time, 'MM/dd/yyyy hh:mm a');
|
|
562
|
-
// Returns: "01/15/2024 02:30 PM"
|
|
563
|
-
```
|
|
564
|
-
|
|
565
|
-
#### Class Name Merging with Variants
|
|
566
|
-
|
|
567
|
-
```typescript
|
|
568
|
-
import { cn } from "@/utils/cn";
|
|
569
|
-
import { cva, type VariantProps } from 'class-variance-authority';
|
|
570
|
-
|
|
571
|
-
const buttonVariants = cva(
|
|
572
|
-
'rounded font-medium transition-colors',
|
|
573
|
-
{
|
|
574
|
-
variants: {
|
|
575
|
-
variant: {
|
|
576
|
-
primary: 'bg-blue-500 text-white hover:bg-blue-600',
|
|
577
|
-
secondary: 'bg-gray-200 text-gray-800 hover:bg-gray-300',
|
|
578
|
-
},
|
|
579
|
-
size: {
|
|
580
|
-
sm: 'px-2 py-1 text-sm',
|
|
581
|
-
md: 'px-4 py-2 text-base',
|
|
582
|
-
lg: 'px-6 py-3 text-lg',
|
|
583
|
-
},
|
|
584
|
-
},
|
|
585
|
-
defaultVariants: {
|
|
586
|
-
variant: 'primary',
|
|
587
|
-
size: 'md',
|
|
588
|
-
},
|
|
589
|
-
}
|
|
590
|
-
);
|
|
591
|
-
|
|
592
|
-
interface ButtonProps extends VariantProps<typeof buttonVariants> {
|
|
593
|
-
className?: string;
|
|
594
|
-
}
|
|
595
|
-
|
|
596
|
-
function Button({ variant, size, className }: ButtonProps) {
|
|
597
|
-
return (
|
|
598
|
-
<button className={cn(buttonVariants({ variant, size }), className)}>
|
|
599
|
-
Click me
|
|
600
|
-
</button>
|
|
601
|
-
);
|
|
602
|
-
}
|
|
603
|
-
```
|
|
604
|
-
|
|
605
|
-
#### Resize with Constraints
|
|
606
|
-
|
|
607
|
-
```typescript
|
|
608
|
-
import { calculateNewWidthFromMouse, calculateNewWidthFromTouch } from "@/utils/resize";
|
|
609
|
-
|
|
610
|
-
function ConstrainedResize() {
|
|
611
|
-
const MIN_WIDTH = 200;
|
|
612
|
-
const MAX_WIDTH = 600;
|
|
613
|
-
|
|
614
|
-
const handleResize = (
|
|
615
|
-
event: MouseEvent | TouchEvent,
|
|
616
|
-
ref: RefObject<HTMLElement>,
|
|
617
|
-
isRtl: boolean
|
|
618
|
-
) => {
|
|
619
|
-
const newWidth = event instanceof MouseEvent
|
|
620
|
-
? calculateNewWidthFromMouse(event, ref, isRtl)
|
|
621
|
-
: calculateNewWidthFromTouch(event, ref, isRtl);
|
|
622
|
-
|
|
623
|
-
// Apply constraints
|
|
624
|
-
return Math.max(MIN_WIDTH, Math.min(MAX_WIDTH, newWidth));
|
|
625
|
-
};
|
|
626
|
-
|
|
627
|
-
return { handleResize, MIN_WIDTH, MAX_WIDTH };
|
|
628
|
-
}
|
|
629
|
-
```
|
|
630
|
-
|
|
631
|
-
---
|
|
632
|
-
|
|
633
|
-
## Best Practices
|
|
634
|
-
|
|
635
|
-
### 1. Always Use cn for Class Merging
|
|
636
|
-
|
|
637
|
-
```typescript
|
|
638
|
-
// ✓ Good - Uses cn utility
|
|
639
|
-
<div className={cn('base-class', props.className)} />
|
|
640
|
-
|
|
641
|
-
// ✗ Bad - Manual string concatenation
|
|
642
|
-
<div className={`base-class ${props.className}`} />
|
|
643
|
-
```
|
|
644
|
-
|
|
645
|
-
### 2. Validate Dates Before Operations
|
|
646
|
-
|
|
647
|
-
```typescript
|
|
648
|
-
// ✓ Good - Validates first
|
|
649
|
-
if (isValidDateObject(date)) {
|
|
650
|
-
const result = applyTimeToDate(date, time);
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
// ✗ Bad - No validation
|
|
654
|
-
const result = applyTimeToDate(date, time); // May throw error
|
|
655
|
-
```
|
|
656
|
-
|
|
657
|
-
### 3. Handle Both Mouse and Touch Events
|
|
658
|
-
|
|
659
|
-
```typescript
|
|
660
|
-
// ✓ Good - Handles both
|
|
661
|
-
const width = isTouchEvent
|
|
662
|
-
? calculateNewWidthFromTouch(event, ref, isRtl)
|
|
663
|
-
: calculateNewWidthFromMouse(event, ref, isRtl);
|
|
664
|
-
|
|
665
|
-
// ✗ Bad - Only handles mouse
|
|
666
|
-
const width = calculateNewWidthFromMouse(event, ref, isRtl);
|
|
667
|
-
```
|
|
668
|
-
|
|
669
|
-
### 4. Use Descriptive Format Strings
|
|
670
|
-
|
|
671
|
-
```typescript
|
|
672
|
-
// ✓ Good - Clear intent
|
|
673
|
-
formatDateValueToString(date, time, 'MMM dd, yyyy hh:mm a')
|
|
674
|
-
|
|
675
|
-
// ✗ Bad - Unclear format
|
|
676
|
-
formatDateValueToString(date, time, 'M/d/yy h:m')
|
|
677
|
-
```
|
|
678
|
-
|
|
679
|
-
---
|
|
680
|
-
|
|
681
|
-
## Related Documentation
|
|
682
|
-
|
|
683
|
-
- [Hooks Reference](./hooks.md) - Custom React hooks
|
|
684
|
-
- [Types Reference](./types.md) - TypeScript types
|
|
685
|
-
- [Component API Index](./components.md) - Component references
|
|
686
|
-
|
|
687
|
-
---
|
|
688
|
-
|
|
689
|
-
## External Dependencies
|
|
690
|
-
|
|
691
|
-
These utilities depend on the following external libraries:
|
|
692
|
-
|
|
693
|
-
- [clsx](https://github.com/lukeed/clsx) - Conditional class names
|
|
694
|
-
- [tailwind-merge](https://github.com/dcastil/tailwind-merge) - Tailwind class deduplication
|
|
695
|
-
- [date-fns](https://date-fns.org/) - Date formatting
|
|
696
|
-
- [react-day-picker](https://react-day-picker.js.org/) - Date picker types
|
|
697
|
-
|
|
698
|
-
---
|
|
699
|
-
|
|
700
|
-
## Additional Resources
|
|
701
|
-
|
|
702
|
-
- [Tailwind CSS Documentation](https://tailwindcss.com)
|
|
703
|
-
- [date-fns Format Reference](https://date-fns.org/docs/format)
|
|
704
|
-
- [TypeScript Utility Types](https://www.typescriptlang.org/docs/handbook/utility-types.html)
|
|
705
|
-
|
|
706
|
-
---
|
|
707
|
-
|
|
708
|
-
## Scroller Utilities
|
|
709
|
-
|
|
710
|
-
### horizontalScrollerStyles
|
|
711
|
-
|
|
712
|
-
The design's 14px horizontal scroller as a class string: a thin track that thickens and turns blue
|
|
713
|
-
on hover. Shared by `TableScroller` and `SectionBlock`'s body so the two cannot drift.
|
|
714
|
-
|
|
715
|
-
```tsx
|
|
716
|
-
import { horizontalScrollerStyles } from "@/utils/scroller";
|
|
717
|
-
import { cn } from "@/utils/cn";
|
|
718
|
-
|
|
719
|
-
<div className={cn(horizontalScrollerStyles, "rounded-lg")}>
|
|
720
|
-
<table className="w-max">…</table>
|
|
721
|
-
</div>
|
|
722
|
-
```
|
|
723
|
-
|
|
724
|
-
It includes `overflow-x-auto overflow-y-hidden`, so the element it lands on becomes the scrollport —
|
|
725
|
-
you do not add an overflow class yourself.
|
|
726
|
-
|