torch-glare 2.3.0 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/apps/lib/components/ActionButton.tsx +7 -12
- package/apps/lib/components/ActionsGroup.tsx +4 -15
- package/apps/lib/components/AlertDialog.tsx +173 -191
- package/apps/lib/components/Avatar.tsx +13 -16
- package/apps/lib/components/Badge.tsx +7 -3
- package/apps/lib/components/BadgeField.tsx +76 -71
- package/apps/lib/components/Breadcrumb.tsx +49 -85
- package/apps/lib/components/Button.tsx +20 -19
- package/apps/lib/components/ButtonGroup.tsx +31 -41
- package/apps/lib/components/Calendar.tsx +51 -29
- package/apps/lib/components/Card.tsx +2 -13
- package/apps/lib/components/ChartBlockTool.ts +17 -52
- package/apps/lib/components/Checkbox.tsx +9 -16
- package/apps/lib/components/ContextMenu.tsx +110 -106
- package/apps/lib/components/CountBadge.tsx +4 -6
- package/apps/lib/components/DataTable.tsx +196 -216
- package/apps/lib/components/DataViews/DataViewRadio.tsx +10 -8
- package/apps/lib/components/DataViews/DataViewsConfigPanel.tsx +21 -55
- package/apps/lib/components/DataViews/DataViewsHeader.tsx +1 -3
- package/apps/lib/components/DataViews/DataViewsLayout.tsx +5 -12
- package/apps/lib/components/DataViews/FilterPanel.tsx +173 -150
- package/apps/lib/components/DataViews/HeaderSearch.tsx +1 -5
- package/apps/lib/components/DataViews/InboxView.tsx +22 -68
- package/apps/lib/components/DataViews/InboxViewCard.tsx +68 -77
- package/apps/lib/components/DataViews/KanbanView.tsx +8 -25
- package/apps/lib/components/DataViews/PanelControls.tsx +3 -13
- package/apps/lib/components/DataViews/SettingsPanel.tsx +83 -89
- package/apps/lib/components/DataViews/TableView.tsx +8 -28
- package/apps/lib/components/DataViews/TreeView.tsx +12 -40
- package/apps/lib/components/DataViews/badgeAdapter.ts +32 -28
- package/apps/lib/components/DataViews/fieldRenderers.tsx +106 -141
- package/apps/lib/components/DataViews/filters/DatePickerRangeFilter.tsx +87 -0
- package/apps/lib/components/DataViews/filters/DateRangePopover.tsx +39 -32
- package/apps/lib/components/DataViews/filters/PresetChips.tsx +15 -15
- package/apps/lib/components/DataViews/filters/RangeSliderWithInputs.tsx +69 -58
- package/apps/lib/components/DataViews/index.ts +26 -26
- package/apps/lib/components/DataViews/tree/TreeDrawer.tsx +12 -16
- package/apps/lib/components/DataViews/tree/TreeSidebar.tsx +28 -31
- package/apps/lib/components/DataViews/types.ts +111 -114
- package/apps/lib/components/DatePicker.tsx +198 -191
- package/apps/lib/components/Dialog.tsx +92 -105
- package/apps/lib/components/Divider.tsx +21 -24
- package/apps/lib/components/Drawer.tsx +79 -139
- package/apps/lib/components/DropdownMenu.tsx +144 -181
- package/apps/lib/components/FieldHint.tsx +4 -11
- package/apps/lib/components/Form.tsx +146 -155
- package/apps/lib/components/FormStepper.tsx +9 -39
- package/apps/lib/components/HeaderBar.tsx +119 -0
- package/apps/lib/components/ImageAttachment.tsx +111 -73
- package/apps/lib/components/InnerLabelField.tsx +20 -16
- package/apps/lib/components/Input.tsx +171 -172
- package/apps/lib/components/InputField.tsx +44 -45
- package/apps/lib/components/InputOTP.tsx +68 -69
- package/apps/lib/components/Label.tsx +31 -35
- package/apps/lib/components/LabelField.tsx +4 -5
- package/apps/lib/components/LabeledCheckBox.tsx +8 -12
- package/apps/lib/components/LabeledRadio.tsx +7 -5
- package/apps/lib/components/LinkButton.tsx +2 -9
- package/apps/lib/components/LoginButton.tsx +4 -9
- package/apps/lib/components/PasswordLevel.tsx +5 -5
- package/apps/lib/components/Popover.tsx +15 -33
- package/apps/lib/components/ProfileMenu.tsx +67 -72
- package/apps/lib/components/Radio.tsx +1 -5
- package/apps/lib/components/RadioCard.tsx +9 -28
- package/apps/lib/components/ScrollArea.tsx +45 -43
- package/apps/lib/components/SearchField.tsx +49 -39
- package/apps/lib/components/SearchableSelect.tsx +46 -52
- package/apps/lib/components/SearchableTable.tsx +199 -219
- package/apps/lib/components/SearchableTree.tsx +469 -0
- package/apps/lib/components/SearchableTreeDialog.tsx +493 -0
- package/apps/lib/components/SectionBlock.tsx +4 -16
- package/apps/lib/components/Select.tsx +53 -80
- package/apps/lib/components/SimpleSelect.tsx +196 -187
- package/apps/lib/components/Skeleton.tsx +9 -12
- package/apps/lib/components/SlideDatePicker.tsx +215 -166
- package/apps/lib/components/SpinLoading.tsx +33 -49
- package/apps/lib/components/Stepper.tsx +13 -56
- package/apps/lib/components/Switch.tsx +8 -10
- package/apps/lib/components/TabFormItem.tsx +3 -12
- package/apps/lib/components/TabSwitch.tsx +7 -34
- package/apps/lib/components/Table.tsx +60 -75
- package/apps/lib/components/TableDnDWrapper.ts +15 -48
- package/apps/lib/components/TextEditor.tsx +93 -104
- package/apps/lib/components/Textarea.tsx +8 -12
- package/apps/lib/components/Timeline.tsx +21 -41
- package/apps/lib/components/Toast.tsx +83 -83
- package/apps/lib/components/Toggle.tsx +112 -114
- package/apps/lib/components/ToggleButton.tsx +1 -1
- package/apps/lib/components/Tooltip.tsx +24 -19
- package/apps/lib/components/TransparentLabel.tsx +61 -62
- package/apps/lib/components/TreeDropDown.tsx +86 -52
- package/apps/lib/components/TreeFolder/TreeFolder.tsx +15 -48
- package/apps/lib/components/TreeFolder/TreeFolderBreadcrumb.tsx +16 -21
- package/apps/lib/components/TreeFolder/TreeFolderRow.tsx +9 -20
- package/apps/lib/components/TreeFolder/TreeFolderStyles.tsx +3 -3
- package/apps/lib/components/TreeFolder/icons.tsx +14 -17
- package/apps/lib/components/TreeFolder/index.ts +15 -8
- package/apps/lib/components/TreeFolder/treeFolderUtils.ts +47 -52
- package/apps/lib/components/TreeFolder/types.ts +32 -32
- package/apps/lib/components/TreeFolder/useTreeFolderDnD.ts +117 -123
- package/apps/lib/hooks/useActiveTreeItem.ts +52 -55
- package/apps/lib/hooks/useClickOutside.ts +21 -20
- package/apps/lib/hooks/useDataViewsState.ts +86 -80
- package/apps/lib/hooks/useIsMobile.ts +12 -12
- package/apps/lib/hooks/useResize.ts +54 -65
- package/apps/lib/hooks/useTagSelection.ts +201 -201
- package/apps/lib/layouts/CNLayout.tsx +181 -140
- package/apps/lib/layouts/DataViewCard.tsx +4 -18
- package/apps/lib/layouts/FieldSection.tsx +2 -6
- package/apps/lib/layouts/TreeSubLayout.tsx +24 -38
- package/apps/lib/providers/ThemeProvider.tsx +8 -23
- package/apps/lib/registry.json +1004 -0
- package/apps/lib/tsconfig.json +9 -0
- package/apps/lib/utils/cn.ts +1 -1
- package/apps/lib/utils/dataViews/columnUtils.ts +46 -44
- package/apps/lib/utils/dataViews/fieldUtils.ts +70 -71
- package/apps/lib/utils/dataViews/nestedDataUtils.tsx +129 -122
- package/apps/lib/utils/dataViews/pathUtils.ts +74 -67
- package/apps/lib/utils/dataViews/rangeUtils.ts +121 -112
- package/apps/lib/utils/dataViews/treeUtils.ts +204 -211
- package/apps/lib/utils/dateFormat.ts +64 -54
- package/apps/lib/utils/markdownParser.ts +2 -7
- package/apps/lib/utils/resize.ts +21 -25
- package/apps/lib/utils/types.ts +13 -13
- package/dist/bin/index.js +8 -2
- package/dist/bin/index.js.map +1 -1
- package/dist/src/shared/getAvailableFiles.d.ts.map +1 -1
- package/dist/src/shared/getAvailableFiles.js +6 -1
- package/dist/src/shared/getAvailableFiles.js.map +1 -1
- package/dist/src/shared/loadRegistry.d.ts +7 -0
- package/dist/src/shared/loadRegistry.d.ts.map +1 -0
- package/dist/src/shared/loadRegistry.js +31 -0
- package/dist/src/shared/loadRegistry.js.map +1 -0
- package/dist/src/shared/resolveInstallPlan.d.ts +12 -0
- package/dist/src/shared/resolveInstallPlan.d.ts.map +1 -0
- package/dist/src/shared/resolveInstallPlan.js +39 -0
- package/dist/src/shared/resolveInstallPlan.js.map +1 -0
- package/dist/src/types/main.d.ts +24 -0
- package/dist/src/types/main.d.ts.map +1 -1
- package/docs/README.md +10 -2
- package/docs/components/action-button.md +30 -24
- package/docs/components/actions-group.md +26 -20
- package/docs/components/alert-dialog.md +45 -45
- package/docs/components/avatar.md +6 -2
- package/docs/components/badge-field.md +6 -2
- package/docs/components/badge.md +7 -1
- package/docs/components/breadcrumb.md +15 -40
- package/docs/components/button-group.md +13 -10
- package/docs/components/button.md +58 -33
- package/docs/components/calendar.md +26 -19
- package/docs/components/card.md +19 -16
- package/docs/components/chart-block-tool.md +128 -0
- package/docs/components/checkbox.md +16 -8
- package/docs/components/cn-layout.md +7 -1
- package/docs/components/context-menu.md +47 -24
- package/docs/components/count-badge.md +7 -1
- package/docs/components/data-table.md +45 -33
- package/docs/components/data-views-config-panel.md +18 -14
- package/docs/components/data-views-layout.md +20 -17
- package/docs/components/date-picker.md +30 -23
- package/docs/components/dialog.md +43 -42
- package/docs/components/divider.md +10 -4
- package/docs/components/drawer.md +8 -33
- package/docs/components/dropdown-menu.md +51 -32
- package/docs/components/field-hint.md +37 -25
- package/docs/components/field-section.md +9 -3
- package/docs/components/form-stepper.md +6 -0
- package/docs/components/form.md +17 -20
- package/docs/components/header-bar.md +187 -0
- package/docs/components/image-attachment.md +33 -41
- package/docs/components/inbox-view.md +16 -5
- package/docs/components/inner-label-field.md +34 -24
- package/docs/components/input-field.md +18 -10
- package/docs/components/input-otp.md +14 -11
- package/docs/components/input.md +22 -16
- package/docs/components/kanban-view.md +15 -5
- package/docs/components/label-field.md +32 -22
- package/docs/components/label.md +43 -32
- package/docs/components/labeled-check-box.md +16 -8
- package/docs/components/labeled-radio.md +18 -11
- package/docs/components/link-button.md +7 -1
- package/docs/components/login-button.md +8 -2
- package/docs/components/password-level.md +37 -24
- package/docs/components/popover.md +26 -23
- package/docs/components/profile-menu.md +38 -27
- package/docs/components/radio-card.md +16 -9
- package/docs/components/radio.md +16 -8
- package/docs/components/scroll-area.md +6 -2
- package/docs/components/search-field.md +14 -6
- package/docs/components/searchable-select.md +19 -14
- package/docs/components/searchable-table.md +60 -41
- package/docs/components/searchable-tree-dialog.md +190 -0
- package/docs/components/searchable-tree.md +200 -0
- package/docs/components/section-block.md +130 -4
- package/docs/components/select.md +23 -18
- package/docs/components/simple-select.md +14 -10
- package/docs/components/skeleton.md +43 -33
- package/docs/components/slide-date-picker.md +37 -29
- package/docs/components/spin-loading.md +32 -23
- package/docs/components/stepper.md +6 -0
- package/docs/components/switch.md +14 -6
- package/docs/components/tab-form-item.md +7 -1
- package/docs/components/tab-switch.md +13 -6
- package/docs/components/table-dnd-wrapper.md +105 -0
- package/docs/components/table-view.md +15 -5
- package/docs/components/table.md +28 -28
- package/docs/components/text-editor.md +19 -13
- package/docs/components/textarea.md +15 -7
- package/docs/components/timeline.md +6 -0
- package/docs/components/toast.md +35 -26
- package/docs/components/toggle-button.md +24 -21
- package/docs/components/toggle.md +23 -15
- package/docs/components/tooltip.md +42 -30
- package/docs/components/transparent-label.md +29 -20
- package/docs/components/tree-drop-down.md +31 -23
- package/docs/components/tree-sub-layout.md +6 -2
- package/docs/components/tree-view.md +16 -5
- package/docs/explanation/architecture.md +54 -0
- package/docs/explanation/design-system.md +52 -0
- package/docs/how-to/data-views-from-backend-response.md +7 -4
- package/docs/how-to/guides.md +24 -18
- package/docs/migration/changelog.md +38 -0
- package/docs/reference/cli.md +87 -0
- package/docs/reference/components.md +11 -12
- package/docs/reference/hooks.md +8 -8
- package/docs/reference/providers.md +22 -22
- package/docs/reference/tailwind-plugins.md +2 -2
- package/docs/reference/theme.md +85 -0
- package/docs/reference/types.md +4 -4
- package/docs/reference/utilities.md +19 -26
- package/docs/tutorials/building-first-form.md +20 -13
- package/docs/tutorials/component-composition.md +34 -50
- package/docs/tutorials/getting-started.md +2 -2
- package/docs/tutorials/theming-basics.md +13 -10
- package/package.json +31 -3
- package/dist/src/commands/block.d.ts +0 -5
- package/dist/src/commands/block.d.ts.map +0 -1
- package/dist/src/commands/block.js +0 -255
- package/dist/src/commands/block.js.map +0 -1
- package/dist/src/shared/configureFonts.d.ts +0 -6
- package/dist/src/shared/configureFonts.d.ts.map +0 -1
- package/dist/src/shared/configureFonts.js +0 -106
- package/dist/src/shared/configureFonts.js.map +0 -1
- package/dist/src/shared/configureGlobalCss.d.ts +0 -6
- package/dist/src/shared/configureGlobalCss.d.ts.map +0 -1
- package/dist/src/shared/configureGlobalCss.js +0 -154
- package/dist/src/shared/configureGlobalCss.js.map +0 -1
- package/dist/src/shared/configureTailwind.d.ts +0 -7
- package/dist/src/shared/configureTailwind.d.ts.map +0 -1
- package/dist/src/shared/configureTailwind.js +0 -163
- package/dist/src/shared/configureTailwind.js.map +0 -1
- package/dist/src/shared/detectFramework.d.ts +0 -23
- package/dist/src/shared/detectFramework.d.ts.map +0 -1
- package/dist/src/shared/detectFramework.js +0 -119
- package/dist/src/shared/detectFramework.js.map +0 -1
- package/dist/src/shared/installBaseUtils.d.ts +0 -5
- package/dist/src/shared/installBaseUtils.d.ts.map +0 -1
- package/dist/src/shared/installBaseUtils.js +0 -79
- package/dist/src/shared/installBaseUtils.js.map +0 -1
- package/dist/src/shared/resolveAliases.d.ts +0 -24
- package/dist/src/shared/resolveAliases.d.ts.map +0 -1
- package/dist/src/shared/resolveAliases.js +0 -98
- package/dist/src/shared/resolveAliases.js.map +0 -1
|
@@ -11,40 +11,31 @@ keywords: [dropdown-menu, menu, radix-ui, submenu, checkbox, radio, auto-group]
|
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
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
|
+
|
|
14
17
|
```bash
|
|
15
|
-
|
|
18
|
+
npx torch-glare@latest init
|
|
19
|
+
npx torch-glare@latest add DropdownMenu
|
|
16
20
|
```
|
|
17
21
|
|
|
22
|
+
`add` also copies any components, hooks, and utilities that `DropdownMenu` depends on.
|
|
23
|
+
|
|
18
24
|
## Import
|
|
19
25
|
|
|
20
|
-
|
|
21
|
-
import {
|
|
22
|
-
DropdownMenu,
|
|
23
|
-
DropdownMenuTrigger,
|
|
24
|
-
DropdownMenuContent,
|
|
25
|
-
DropdownMenuItem,
|
|
26
|
-
DropdownMenuCheckboxItem,
|
|
27
|
-
DropdownMenuRadioGroup,
|
|
28
|
-
DropdownMenuRadioItem,
|
|
29
|
-
DropdownMenuLabel,
|
|
30
|
-
DropdownMenuShortcut,
|
|
31
|
-
DropdownMenuSub,
|
|
32
|
-
DropdownMenuSubTrigger,
|
|
33
|
-
DropdownMenuSubContent,
|
|
34
|
-
DropdownMenuGroup,
|
|
35
|
-
DropdownMenuPortal,
|
|
36
|
-
} from '@torch-ui/components'
|
|
37
|
-
```
|
|
26
|
+
Import from your project's local path — the alias configured in `glare.json` (e.g. `@/*`):
|
|
38
27
|
|
|
39
|
-
|
|
28
|
+
```tsx
|
|
29
|
+
import { DropdownMenu } from "@/components/DropdownMenu";
|
|
30
|
+
```
|
|
40
31
|
|
|
41
32
|
## Quick Examples
|
|
42
33
|
|
|
43
34
|
### Basic Menu
|
|
44
35
|
|
|
45
36
|
```typescript
|
|
46
|
-
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from
|
|
47
|
-
import { Button } from
|
|
37
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from "@/components/DropdownMenu";
|
|
38
|
+
import { Button } from "@/components/Button";
|
|
48
39
|
|
|
49
40
|
function Example() {
|
|
50
41
|
return (
|
|
@@ -65,7 +56,7 @@ function Example() {
|
|
|
65
56
|
### With Icons
|
|
66
57
|
|
|
67
58
|
```typescript
|
|
68
|
-
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from
|
|
59
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from "@/components/DropdownMenu";
|
|
69
60
|
|
|
70
61
|
function IconMenu() {
|
|
71
62
|
return (
|
|
@@ -97,7 +88,7 @@ function IconMenu() {
|
|
|
97
88
|
### With Keyboard Shortcuts
|
|
98
89
|
|
|
99
90
|
```typescript
|
|
100
|
-
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuShortcut } from
|
|
91
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuShortcut } from "@/components/DropdownMenu";
|
|
101
92
|
|
|
102
93
|
function ShortcutMenu() {
|
|
103
94
|
return (
|
|
@@ -129,7 +120,7 @@ function ShortcutMenu() {
|
|
|
129
120
|
Labels act as section boundaries. The loose items between labels are automatically wrapped in boxed groups — no separator component needed.
|
|
130
121
|
|
|
131
122
|
```typescript
|
|
132
|
-
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel } from
|
|
123
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel } from "@/components/DropdownMenu";
|
|
133
124
|
|
|
134
125
|
function OrganizedMenu() {
|
|
135
126
|
return (
|
|
@@ -158,7 +149,7 @@ function OrganizedMenu() {
|
|
|
158
149
|
Checkbox and radio items keep the menu **open** when toggled (the built-in `onSelect` calls `preventDefault`), so users can change several options without the menu closing each time.
|
|
159
150
|
|
|
160
151
|
```typescript
|
|
161
|
-
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuCheckboxItem } from
|
|
152
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuCheckboxItem } from "@/components/DropdownMenu";
|
|
162
153
|
import { useState } from 'react'
|
|
163
154
|
|
|
164
155
|
function CheckboxMenu() {
|
|
@@ -199,7 +190,7 @@ function CheckboxMenu() {
|
|
|
199
190
|
### With Radio Group
|
|
200
191
|
|
|
201
192
|
```typescript
|
|
202
|
-
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuRadioItem } from
|
|
193
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuRadioGroup, DropdownMenuRadioItem } from "@/components/DropdownMenu";
|
|
203
194
|
import { useState } from 'react'
|
|
204
195
|
|
|
205
196
|
function RadioMenu() {
|
|
@@ -225,7 +216,7 @@ function RadioMenu() {
|
|
|
225
216
|
### With Submenu
|
|
226
217
|
|
|
227
218
|
```typescript
|
|
228
|
-
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent } from
|
|
219
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent } from "@/components/DropdownMenu";
|
|
229
220
|
|
|
230
221
|
function SubmenuExample() {
|
|
231
222
|
return (
|
|
@@ -258,7 +249,7 @@ function SubmenuExample() {
|
|
|
258
249
|
### Disabled Items
|
|
259
250
|
|
|
260
251
|
```typescript
|
|
261
|
-
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from
|
|
252
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from "@/components/DropdownMenu";
|
|
262
253
|
|
|
263
254
|
function DisabledMenu() {
|
|
264
255
|
return (
|
|
@@ -281,7 +272,7 @@ function DisabledMenu() {
|
|
|
281
272
|
For a true right-click (context) menu, use the dedicated [ContextMenu](./context-menu.md) component instead of DropdownMenu — it opens at the pointer on right-click / long-press.
|
|
282
273
|
|
|
283
274
|
```typescript
|
|
284
|
-
import { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem } from
|
|
275
|
+
import { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem } from "@/components/ContextMenu";
|
|
285
276
|
|
|
286
277
|
function Example() {
|
|
287
278
|
return (
|
|
@@ -299,6 +290,32 @@ function Example() {
|
|
|
299
290
|
}
|
|
300
291
|
```
|
|
301
292
|
|
|
293
|
+
### Long Menu (max height + scroll)
|
|
294
|
+
|
|
295
|
+
Tall menus scroll instead of overflowing off-screen. The surface caps at `maxHeight` (default `320`px) and never exceeds the space available after collision handling. Pass `maxHeight` to change the cap.
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel } from "@/components/DropdownMenu";
|
|
299
|
+
import { Button } from "@/components/Button";
|
|
300
|
+
|
|
301
|
+
function LongMenu() {
|
|
302
|
+
return (
|
|
303
|
+
<DropdownMenu>
|
|
304
|
+
<DropdownMenuTrigger asChild>
|
|
305
|
+
<Button variant="BorderStyle">Jump to section</Button>
|
|
306
|
+
</DropdownMenuTrigger>
|
|
307
|
+
{/* Cap the surface at 240px — the rest scrolls. */}
|
|
308
|
+
<DropdownMenuContent align="start" maxHeight={240}>
|
|
309
|
+
<DropdownMenuLabel>Sections</DropdownMenuLabel>
|
|
310
|
+
{Array.from({ length: 20 }, (_, i) => (
|
|
311
|
+
<DropdownMenuItem key={i}>Section {i + 1}</DropdownMenuItem>
|
|
312
|
+
))}
|
|
313
|
+
</DropdownMenuContent>
|
|
314
|
+
</DropdownMenu>
|
|
315
|
+
)
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
302
319
|
## API Reference
|
|
303
320
|
|
|
304
321
|
### DropdownMenu (Root)
|
|
@@ -326,6 +343,7 @@ function Example() {
|
|
|
326
343
|
| `sideOffset` | `number` | `4` | Distance from trigger |
|
|
327
344
|
| `collisionPadding` | `number` | `8` | Gap kept from viewport edges when flipping/shifting |
|
|
328
345
|
| `align` | `'start' \| 'center' \| 'end'` | `'center'` | Alignment (inherited from Radix) |
|
|
346
|
+
| `maxHeight` | `number` | `320` | Max height (px) of the surface before it scrolls. Capped at `min(maxHeight, available-height)` so the menu never overflows off-screen |
|
|
329
347
|
| `autoGroup` | `boolean` | `true` | Auto-wrap loose items in boxed groups |
|
|
330
348
|
|
|
331
349
|
### DropdownMenuItem
|
|
@@ -426,6 +444,7 @@ interface DropdownMenuContentProps {
|
|
|
426
444
|
sideOffset?: number
|
|
427
445
|
collisionPadding?: number
|
|
428
446
|
align?: 'start' | 'center' | 'end'
|
|
447
|
+
maxHeight?: number // default 320 — surface scrolls past this
|
|
429
448
|
autoGroup?: boolean
|
|
430
449
|
}
|
|
431
450
|
|
|
@@ -469,7 +488,7 @@ export const DropdownMenuRadioItem: React.ForwardRefExoticComponent<DropdownMenu
|
|
|
469
488
|
### With State Management
|
|
470
489
|
|
|
471
490
|
```typescript
|
|
472
|
-
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from
|
|
491
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from "@/components/DropdownMenu";
|
|
473
492
|
import { useState } from 'react'
|
|
474
493
|
|
|
475
494
|
function useDropdownMenu() {
|
|
@@ -508,7 +527,7 @@ function StatefulMenu() {
|
|
|
508
527
|
|
|
509
528
|
```typescript
|
|
510
529
|
import { render, screen, fireEvent } from '@testing-library/react'
|
|
511
|
-
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from
|
|
530
|
+
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem } from "@/components/DropdownMenu";
|
|
512
531
|
|
|
513
532
|
describe('DropdownMenu', () => {
|
|
514
533
|
it('opens on trigger click', () => {
|
|
@@ -11,13 +11,22 @@ keywords: [field-hint, alert, validation, message, form, feedback, inline]
|
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
14
|
-
|
|
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 FieldHint
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`add` also copies any components, hooks, and utilities that `FieldHint` depends on.
|
|
15
23
|
|
|
16
24
|
## Import
|
|
17
25
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
Import from your project's local path — the alias configured in `glare.json` (e.g. `@/*`):
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
21
30
|
```
|
|
22
31
|
|
|
23
32
|
## Quick Examples
|
|
@@ -25,7 +34,7 @@ import type { FieldHintProps } from '@torch-ui/components'
|
|
|
25
34
|
### Basic Usage
|
|
26
35
|
|
|
27
36
|
```typescript
|
|
28
|
-
import { FieldHint } from
|
|
37
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
29
38
|
|
|
30
39
|
function Example() {
|
|
31
40
|
return (
|
|
@@ -40,7 +49,7 @@ function Example() {
|
|
|
40
49
|
### All States
|
|
41
50
|
|
|
42
51
|
```typescript
|
|
43
|
-
import { FieldHint } from
|
|
52
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
44
53
|
|
|
45
54
|
function AllStates() {
|
|
46
55
|
return (
|
|
@@ -72,8 +81,8 @@ function AllStates() {
|
|
|
72
81
|
### With Form Field
|
|
73
82
|
|
|
74
83
|
```typescript
|
|
75
|
-
import { FieldHint } from
|
|
76
|
-
import { InputField } from
|
|
84
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
85
|
+
import { InputField } from "@/components/InputField";
|
|
77
86
|
import { useState } from 'react'
|
|
78
87
|
|
|
79
88
|
function WithFormField() {
|
|
@@ -115,7 +124,7 @@ function WithFormField() {
|
|
|
115
124
|
### Custom Icon
|
|
116
125
|
|
|
117
126
|
```typescript
|
|
118
|
-
import { FieldHint } from
|
|
127
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
119
128
|
|
|
120
129
|
function CustomIcon() {
|
|
121
130
|
return (
|
|
@@ -145,8 +154,9 @@ function CustomIcon() {
|
|
|
145
154
|
### Password Validation
|
|
146
155
|
|
|
147
156
|
```typescript
|
|
148
|
-
import { FieldHint } from
|
|
149
|
-
import { InputField
|
|
157
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
158
|
+
import { InputField } from "@/components/InputField";
|
|
159
|
+
import { PasswordLevel } from "@/components/PasswordLevel";
|
|
150
160
|
import { useState } from 'react'
|
|
151
161
|
|
|
152
162
|
function PasswordValidation() {
|
|
@@ -199,8 +209,9 @@ function PasswordValidation() {
|
|
|
199
209
|
### Form Validation
|
|
200
210
|
|
|
201
211
|
```typescript
|
|
202
|
-
import { FieldHint } from
|
|
203
|
-
import {
|
|
212
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
213
|
+
import { Button } from "@/components/Button";
|
|
214
|
+
import { InputField } from "@/components/InputField";
|
|
204
215
|
import { useState } from 'react'
|
|
205
216
|
|
|
206
217
|
function FormValidation() {
|
|
@@ -289,8 +300,9 @@ function FormValidation() {
|
|
|
289
300
|
### API Response Feedback
|
|
290
301
|
|
|
291
302
|
```typescript
|
|
292
|
-
import { FieldHint } from
|
|
293
|
-
import {
|
|
303
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
304
|
+
import { Button } from "@/components/Button";
|
|
305
|
+
import { InputField } from "@/components/InputField";
|
|
294
306
|
import { useState } from 'react'
|
|
295
307
|
|
|
296
308
|
function APIFeedback() {
|
|
@@ -360,7 +372,7 @@ function APIFeedback() {
|
|
|
360
372
|
### File Upload Feedback
|
|
361
373
|
|
|
362
374
|
```typescript
|
|
363
|
-
import { FieldHint } from
|
|
375
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
364
376
|
import { useState } from 'react'
|
|
365
377
|
|
|
366
378
|
function FileUploadFeedback() {
|
|
@@ -429,7 +441,7 @@ function FileUploadFeedback() {
|
|
|
429
441
|
### Multi-line Message
|
|
430
442
|
|
|
431
443
|
```typescript
|
|
432
|
-
import { FieldHint } from
|
|
444
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
433
445
|
|
|
434
446
|
function MultilineMessage() {
|
|
435
447
|
return (
|
|
@@ -456,7 +468,7 @@ Please save your work before continuing.`}
|
|
|
456
468
|
### Dynamic Theme
|
|
457
469
|
|
|
458
470
|
```typescript
|
|
459
|
-
import { FieldHint } from
|
|
471
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
460
472
|
import { useState } from 'react'
|
|
461
473
|
|
|
462
474
|
function DynamicTheme() {
|
|
@@ -488,8 +500,8 @@ function DynamicTheme() {
|
|
|
488
500
|
### Conditional Rendering
|
|
489
501
|
|
|
490
502
|
```typescript
|
|
491
|
-
import { FieldHint } from
|
|
492
|
-
import { InputField } from
|
|
503
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
504
|
+
import { InputField } from "@/components/InputField";
|
|
493
505
|
import { useState } from 'react'
|
|
494
506
|
|
|
495
507
|
function ConditionalHints() {
|
|
@@ -579,7 +591,7 @@ export const FieldHint: React.FC<FieldHintProps>
|
|
|
579
591
|
### Usage with Types
|
|
580
592
|
|
|
581
593
|
```typescript
|
|
582
|
-
import { FieldHint } from
|
|
594
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
583
595
|
import { useState } from 'react'
|
|
584
596
|
|
|
585
597
|
type ValidationState = {
|
|
@@ -607,7 +619,7 @@ function TypedExample() {
|
|
|
607
619
|
### Validation Hook
|
|
608
620
|
|
|
609
621
|
```typescript
|
|
610
|
-
import { FieldHint } from
|
|
622
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
611
623
|
import { useState, useCallback } from 'react'
|
|
612
624
|
|
|
613
625
|
function useFieldValidation<T>(
|
|
@@ -665,8 +677,8 @@ function ValidatedField() {
|
|
|
665
677
|
### Form Field Wrapper
|
|
666
678
|
|
|
667
679
|
```typescript
|
|
668
|
-
import { FieldHint } from
|
|
669
|
-
import { InputField } from
|
|
680
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
681
|
+
import { InputField } from "@/components/InputField";
|
|
670
682
|
import { ReactNode } from 'react'
|
|
671
683
|
|
|
672
684
|
interface FieldWrapperProps {
|
|
@@ -711,7 +723,7 @@ function FieldWrapper({
|
|
|
711
723
|
|
|
712
724
|
```typescript
|
|
713
725
|
import { render, screen } from '@testing-library/react'
|
|
714
|
-
import { FieldHint } from
|
|
726
|
+
import { FieldHint } from "@/components/FieldHint";
|
|
715
727
|
|
|
716
728
|
describe('FieldHint', () => {
|
|
717
729
|
it('renders label text', () => {
|
|
@@ -12,10 +12,16 @@ A structured form section component that provides consistent layout for form fie
|
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
14
14
|
|
|
15
|
+
TORCH Glare is a copy-in library: the CLI copies this component's source into your project
|
|
16
|
+
(you do **not** install it from the npm package). Run `init` once, then `add`:
|
|
17
|
+
|
|
15
18
|
```bash
|
|
16
|
-
npx torch-
|
|
19
|
+
npx torch-glare@latest init
|
|
20
|
+
npx torch-glare@latest add FieldSection
|
|
17
21
|
```
|
|
18
22
|
|
|
23
|
+
`add` also copies any components, hooks, and utilities that `FieldSection` depends on.
|
|
24
|
+
|
|
19
25
|
## Imports
|
|
20
26
|
|
|
21
27
|
```typescript
|
|
@@ -346,7 +352,7 @@ export function ProfileSettingsForm() {
|
|
|
346
352
|
>
|
|
347
353
|
<div className="w-full flex items-center gap-4">
|
|
348
354
|
<Avatar size="L" src="/default-avatar.jpg" />
|
|
349
|
-
<Button variant="
|
|
355
|
+
<Button variant="BluSecStyle" size="M">
|
|
350
356
|
Upload New Photo
|
|
351
357
|
</Button>
|
|
352
358
|
</div>
|
|
@@ -490,7 +496,7 @@ export function AccountSettings() {
|
|
|
490
496
|
}
|
|
491
497
|
>
|
|
492
498
|
<div className="w-full space-y-2">
|
|
493
|
-
<Button variant="
|
|
499
|
+
<Button variant="RedSecStyle" size="M">
|
|
494
500
|
Delete Account
|
|
495
501
|
</Button>
|
|
496
502
|
</div>
|
|
@@ -14,10 +14,16 @@ The component is composed of `FormStepper`, `FormStep`, `FormStepIndicator`, and
|
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
|
17
|
+
TORCH Glare is a copy-in library: the CLI copies this component's source into your project
|
|
18
|
+
(you do **not** install it from the npm package). Run `init` once, then `add`:
|
|
19
|
+
|
|
17
20
|
```bash
|
|
21
|
+
npx torch-glare@latest init
|
|
18
22
|
npx torch-glare@latest add FormStepper
|
|
19
23
|
```
|
|
20
24
|
|
|
25
|
+
`add` also copies any components, hooks, and utilities that `FormStepper` depends on.
|
|
26
|
+
|
|
21
27
|
## Imports
|
|
22
28
|
|
|
23
29
|
```typescript
|
package/docs/components/form.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: Form
|
|
3
|
-
version:
|
|
3
|
+
version: 2.4.0
|
|
4
4
|
status: stable
|
|
5
5
|
category: components/forms
|
|
6
6
|
tags: [form, validation, react-hook-form, accessible, compound]
|
|
@@ -18,25 +18,22 @@ dependencies:
|
|
|
18
18
|
|
|
19
19
|
## Installation
|
|
20
20
|
|
|
21
|
+
TORCH Glare is a copy-in library: the CLI copies this component's source into your project
|
|
22
|
+
(you do **not** install it from the npm package). Run `init` once, then `add`:
|
|
23
|
+
|
|
21
24
|
```bash
|
|
22
|
-
|
|
25
|
+
npx torch-glare@latest init
|
|
26
|
+
npx torch-glare@latest add Form
|
|
23
27
|
```
|
|
24
28
|
|
|
29
|
+
`add` also copies any components, hooks, and utilities that `Form` depends on.
|
|
30
|
+
|
|
25
31
|
## Import
|
|
26
32
|
|
|
27
|
-
|
|
28
|
-
import {
|
|
29
|
-
Form,
|
|
30
|
-
FormField,
|
|
31
|
-
FormItem,
|
|
32
|
-
FormLabel,
|
|
33
|
-
FormControl,
|
|
34
|
-
FormDescription,
|
|
35
|
-
FormMessage
|
|
36
|
-
} from 'torch-glare/lib/components/Form'
|
|
33
|
+
Import from your project's local path — the alias configured in `glare.json` (e.g. `@/*`):
|
|
37
34
|
|
|
38
|
-
|
|
39
|
-
import {
|
|
35
|
+
```tsx
|
|
36
|
+
import { Form } from "@/components/Form";
|
|
40
37
|
```
|
|
41
38
|
|
|
42
39
|
## Quick Examples
|
|
@@ -52,9 +49,9 @@ import {
|
|
|
52
49
|
FormLabel,
|
|
53
50
|
FormControl,
|
|
54
51
|
FormMessage
|
|
55
|
-
} from '
|
|
56
|
-
import { Input } from '
|
|
57
|
-
import { Button } from '
|
|
52
|
+
} from '@/components/Form'
|
|
53
|
+
import { Input } from '@/components/Input'
|
|
54
|
+
import { Button } from '@/components/Button'
|
|
58
55
|
|
|
59
56
|
function BasicForm() {
|
|
60
57
|
const form = useForm({
|
|
@@ -213,9 +210,9 @@ function ValidatedForm() {
|
|
|
213
210
|
### With Multiple Field Types
|
|
214
211
|
|
|
215
212
|
```typescript
|
|
216
|
-
import { Select, SelectTrigger, SelectContent, SelectItem, SelectValue } from '
|
|
217
|
-
import { Checkbox } from '
|
|
218
|
-
import { RadioGroup, RadioGroupItem } from '
|
|
213
|
+
import { Select, SelectTrigger, SelectContent, SelectItem, SelectValue } from '@/components/Select'
|
|
214
|
+
import { Checkbox } from '@/components/Checkbox'
|
|
215
|
+
import { RadioGroup, RadioGroupItem } from '@/components/Radio'
|
|
219
216
|
|
|
220
217
|
function MultiFieldForm() {
|
|
221
218
|
const form = useForm({
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: HeaderBar
|
|
3
|
+
description: Variant-driven page/form header chip pairing a colored emphasis pill with a plain title.
|
|
4
|
+
component: true
|
|
5
|
+
group: Layout
|
|
6
|
+
keywords: [header, headerbar, page-header, form-header, title, badge, label, layout]
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# HeaderBar
|
|
10
|
+
|
|
11
|
+
A presentational header chip used at the top of a form, page, or drawer to communicate the current record context — for example "NEW sales invoice", "EDIT sales invoice", or "ORDER de-344". It pairs a colored emphasis pill (the `label`) with a plain `title`, and the `variant` controls both the pill color and which side the pill sits on. The surface is always a fixed dark container, and the component is non-interactive.
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
TORCH Glare is a copy-in library: the CLI copies this component's source into your project
|
|
16
|
+
(you do **not** install it from the npm package). Run `init` once, then `add`:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx torch-glare@latest init
|
|
20
|
+
npx torch-glare@latest add HeaderBar
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`add` also copies any components, hooks, and utilities that `HeaderBar` depends on.
|
|
24
|
+
|
|
25
|
+
## Imports
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import HeaderBar from '@/components/HeaderBar'
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { HeaderBar } from '@/components/HeaderBar'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Both the default export and the named export resolve to the same component. The website convention is the default import.
|
|
36
|
+
|
|
37
|
+
## Basic Usage
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import HeaderBar from '@/components/HeaderBar'
|
|
41
|
+
|
|
42
|
+
export function BasicHeaderBar() {
|
|
43
|
+
return (
|
|
44
|
+
<HeaderBar
|
|
45
|
+
variant="new"
|
|
46
|
+
label="New"
|
|
47
|
+
title="sales iNVOICE"
|
|
48
|
+
/>
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Examples
|
|
54
|
+
|
|
55
|
+
### New Invoice Header
|
|
56
|
+
|
|
57
|
+
The `new` variant renders a blue emphasis pill on the left followed by the plain title on the right. Use it on create screens.
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import HeaderBar from '@/components/HeaderBar'
|
|
61
|
+
|
|
62
|
+
export function NewInvoiceHeader() {
|
|
63
|
+
return (
|
|
64
|
+
<HeaderBar
|
|
65
|
+
variant="new"
|
|
66
|
+
label="New"
|
|
67
|
+
title="sales iNVOICE"
|
|
68
|
+
/>
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Edit Header
|
|
74
|
+
|
|
75
|
+
The `edit` variant shares the exact same layout as `new` (pill left, title right) but uses an orange emphasis pill. Use it on edit screens.
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import HeaderBar from '@/components/HeaderBar'
|
|
79
|
+
|
|
80
|
+
export function EditInvoiceHeader() {
|
|
81
|
+
return (
|
|
82
|
+
<HeaderBar
|
|
83
|
+
variant="edit"
|
|
84
|
+
label="edit"
|
|
85
|
+
title="sales iNVOICE"
|
|
86
|
+
/>
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Detail Header
|
|
92
|
+
|
|
93
|
+
The `detail` variant swaps the positions: the plain title renders on the left and the colored (white-alpha) pill renders on the right. Use it for read-only record context such as an order reference.
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import HeaderBar from '@/components/HeaderBar'
|
|
97
|
+
|
|
98
|
+
export function OrderDetailHeader() {
|
|
99
|
+
// Renders as: SALES INVOICE [ de-344 ]
|
|
100
|
+
// plain title on the LEFT, badge on the RIGHT
|
|
101
|
+
return (
|
|
102
|
+
<HeaderBar
|
|
103
|
+
variant="detail"
|
|
104
|
+
label="de-344"
|
|
105
|
+
title="sales iNVOICE"
|
|
106
|
+
/>
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Themed
|
|
112
|
+
|
|
113
|
+
HeaderBar accepts a `theme` prop applied via `data-theme`. The surface is always a dark chip, so theming is most useful for keeping the component consistent with the surrounding `data-theme` scope.
|
|
114
|
+
|
|
115
|
+
```tsx
|
|
116
|
+
import HeaderBar from '@/components/HeaderBar'
|
|
117
|
+
|
|
118
|
+
export function ThemedHeaderBars() {
|
|
119
|
+
return (
|
|
120
|
+
<div className="flex flex-col gap-4">
|
|
121
|
+
<HeaderBar variant="new" label="New" title="sales iNVOICE" theme="dark" />
|
|
122
|
+
<HeaderBar variant="edit" label="edit" title="sales iNVOICE" theme="light" />
|
|
123
|
+
<HeaderBar variant="detail" label="de-344" title="sales iNVOICE" theme="default" />
|
|
124
|
+
</div>
|
|
125
|
+
)
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## API Reference
|
|
130
|
+
|
|
131
|
+
### HeaderBar Props
|
|
132
|
+
|
|
133
|
+
| Prop | Type | Default | Description |
|
|
134
|
+
|------|------|---------|-------------|
|
|
135
|
+
| variant | `'new' \| 'edit' \| 'detail'` | `'new'` | Controls both the pill color and which side the pill sits on |
|
|
136
|
+
| label | `string` | — (required) | Text rendered inside the colored emphasis pill |
|
|
137
|
+
| title | `string` | — (required) | Plain text rendered alongside the pill |
|
|
138
|
+
| theme | `Themes` | — | Theme variant applied via `data-theme` (`'dark' \| 'light' \| 'default'`) |
|
|
139
|
+
| className | `string` | — | Additional CSS classes merged onto the root element |
|
|
140
|
+
|
|
141
|
+
All standard `HTMLAttributes<HTMLDivElement>` (for example `id`, `aria-*`, `data-*`, `style`, `onClick`) pass through to the root `div`.
|
|
142
|
+
|
|
143
|
+
## Variants
|
|
144
|
+
|
|
145
|
+
| Variant | Pill color | Pill text | Layout (left → right) |
|
|
146
|
+
|---------|-----------|-----------|------------------------|
|
|
147
|
+
| `new` | `bg-blue-sparkle-alpha-50` | `text-blue-sparkle-200` | pill (`label`) → title |
|
|
148
|
+
| `edit` | `bg-orange-alpha-50` | `text-orange-200` | pill (`label`) → title |
|
|
149
|
+
| `detail` | `bg-white-alpha-30` | `text-white-00` | title → pill (`label`) — positions swapped |
|
|
150
|
+
|
|
151
|
+
## Styling
|
|
152
|
+
|
|
153
|
+
- **Fixed dark container**: `rounded-[14px]`, `border-black-600`, `bg-black-1000`, `p-1.5`, with a double soft shadow. The surface is always dark regardless of theme.
|
|
154
|
+
- **Layout**: the root is `inline-flex`, so the chip hugs its content rather than stretching to fill its parent.
|
|
155
|
+
- **Typography**: 28px, weight 510, uppercase, SF Pro with the `cv05` stylistic set. Both `label` and `title` render uppercase.
|
|
156
|
+
- **Emphasis pill**: the colored badge background and text color are driven entirely by `variant` (see the Variants table). For `detail`, the pill also moves to the right side.
|
|
157
|
+
|
|
158
|
+
## TypeScript Types
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
import { HTMLAttributes } from 'react'
|
|
162
|
+
import { Themes } from '@/utils/types'
|
|
163
|
+
|
|
164
|
+
interface HeaderBarProps extends HTMLAttributes<HTMLDivElement> {
|
|
165
|
+
variant?: 'new' | 'edit' | 'detail'
|
|
166
|
+
label: string
|
|
167
|
+
title: string
|
|
168
|
+
theme?: Themes
|
|
169
|
+
className?: string
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Accessibility
|
|
174
|
+
|
|
175
|
+
- HeaderBar is purely presentational — it has no interactive behavior and is intended to label the surrounding content visually.
|
|
176
|
+
- Because the text is rendered uppercase via styling (not the source string), screen readers receive the original casing of `label` and `title`.
|
|
177
|
+
- Pass any `aria-*` attributes through the standard prop spread when the chip needs an explicit accessible role or label in its context.
|
|
178
|
+
- HeaderBar does not render an HTML heading element. When this chip represents the page or section heading, ensure proper heading semantics exist in the surrounding layout (for example an `<h1>` / `<h2>` for the page) so document structure remains navigable.
|
|
179
|
+
|
|
180
|
+
## Best Practices
|
|
181
|
+
|
|
182
|
+
1. **Match the variant to the screen mode**: use `new` for create screens, `edit` for edit screens, and `detail` for read-only record context.
|
|
183
|
+
2. **Keep `label` short**: it is the emphasis pill, so a concise token (a mode word like "New" / "edit" or a record reference like "de-344") reads best — text renders UPPERCASE automatically.
|
|
184
|
+
3. **Use `title` for the record type**: the plain side should name the entity (for example "sales invoice", "Order"), not duplicate the label.
|
|
185
|
+
4. **Expect the detail swap**: for `variant="detail"` the pill moves to the right and the title to the left — author content with that ordering in mind.
|
|
186
|
+
5. **Don't rely on it for interactivity**: HeaderBar is a label, not a control; place buttons or actions in a separate toolbar.
|
|
187
|
+
6. **Let it hug its content**: the chip is `inline-flex`; avoid forcing it to full width and keep it at the top of the form, page, or drawer it describes.
|