banhaten 0.3.0 → 0.5.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/CHANGELOG.md +139 -73
- package/CONTRIBUTING.md +46 -44
- package/README.md +192 -190
- package/SECURITY.md +15 -15
- package/banhaten.config.example.json +11 -11
- package/docs/design-spacing.md +13 -0
- package/docs/design-system/README.md +22 -20
- package/docs/design-system/adoption-quality-remediation.md +87 -87
- package/docs/design-system/agent-usage.md +13 -13
- package/docs/design-system/appearance-presets.md +189 -189
- package/docs/design-system/appearances/default.md +94 -94
- package/docs/design-system/appearances/rounded.md +95 -95
- package/docs/design-system/appearances/sharp.md +95 -95
- package/docs/design-system/component-docs-pattern.md +81 -81
- package/docs/design-system/component-implementation-ownership-audit.md +245 -244
- package/docs/design-system/component-quality-audit-2026-08-20.md +225 -223
- package/docs/design-system/component-showcase-consistency-report.md +219 -219
- package/docs/design-system/component-token-consistency-audit.md +173 -173
- package/docs/design-system/components/README.md +90 -76
- package/docs/design-system/components/accordion.md +53 -53
- package/docs/design-system/components/activity-feed.md +94 -94
- package/docs/design-system/components/activity-heatmap.md +57 -57
- package/docs/design-system/components/agent-input.md +85 -0
- package/docs/design-system/components/alert-dialog.md +72 -72
- package/docs/design-system/components/alert.md +98 -98
- package/docs/design-system/components/approval-card.md +134 -0
- package/docs/design-system/components/aspect-ratio.md +45 -45
- package/docs/design-system/components/attribute.md +89 -89
- package/docs/design-system/components/autocomplete.md +75 -75
- package/docs/design-system/components/avatar.md +54 -54
- package/docs/design-system/components/badge.md +54 -54
- package/docs/design-system/components/banner.md +87 -87
- package/docs/design-system/components/breadcrumbs.md +177 -176
- package/docs/design-system/components/button-group.md +98 -98
- package/docs/design-system/components/button.md +83 -80
- package/docs/design-system/components/card.md +88 -88
- package/docs/design-system/components/carousel.md +46 -46
- package/docs/design-system/components/catalog-components.md +47 -47
- package/docs/design-system/components/chart.md +95 -24
- package/docs/design-system/components/checkbox.md +54 -54
- package/docs/design-system/components/collapsible.md +67 -53
- package/docs/design-system/components/command.md +62 -62
- package/docs/design-system/components/context-menu.md +46 -46
- package/docs/design-system/components/date-picker.md +81 -79
- package/docs/design-system/components/divider.md +102 -102
- package/docs/design-system/components/empty-state.md +56 -56
- package/docs/design-system/components/field.md +70 -70
- package/docs/design-system/components/file-upload.md +187 -187
- package/docs/design-system/components/hover-card.md +48 -48
- package/docs/design-system/components/icons.md +48 -48
- package/docs/design-system/components/inline-citations.md +93 -0
- package/docs/design-system/components/input-group.md +58 -58
- package/docs/design-system/components/input-otp.md +56 -56
- package/docs/design-system/components/input.md +117 -61
- package/docs/design-system/components/item.md +59 -57
- package/docs/design-system/components/kbd.md +54 -49
- package/docs/design-system/components/label.md +49 -49
- package/docs/design-system/components/menu.md +71 -61
- package/docs/design-system/components/menubar.md +47 -47
- package/docs/design-system/components/modal.md +105 -105
- package/docs/design-system/components/native-select.md +54 -54
- package/docs/design-system/components/navigation-menu.md +50 -50
- package/docs/design-system/components/onboarding-step-list-item.md +82 -82
- package/docs/design-system/components/page-header.md +93 -86
- package/docs/design-system/components/pagination.md +57 -57
- package/docs/design-system/components/popover.md +60 -60
- package/docs/design-system/components/progress-slider.md +50 -50
- package/docs/design-system/components/progress.md +76 -76
- package/docs/design-system/components/radio-card.md +51 -51
- package/docs/design-system/components/radio-group.md +57 -57
- package/docs/design-system/components/resizable.md +44 -44
- package/docs/design-system/components/rolling-count.md +61 -0
- package/docs/design-system/components/scroll-area.md +51 -51
- package/docs/design-system/components/segmented-control.md +54 -54
- package/docs/design-system/components/select.md +68 -62
- package/docs/design-system/components/sheet.md +67 -67
- package/docs/design-system/components/shimmer-text.md +67 -0
- package/docs/design-system/components/sidebar.md +127 -76
- package/docs/design-system/components/skeleton.md +75 -75
- package/docs/design-system/components/slideout.md +65 -65
- package/docs/design-system/components/slider.md +63 -63
- package/docs/design-system/components/social-button.md +50 -50
- package/docs/design-system/components/spinner.md +62 -62
- package/docs/design-system/components/steps.md +65 -65
- package/docs/design-system/components/streaming-text.md +82 -0
- package/docs/design-system/components/table.md +419 -414
- package/docs/design-system/components/tabs.md +59 -55
- package/docs/design-system/components/tag.md +80 -80
- package/docs/design-system/components/task-list.md +95 -0
- package/docs/design-system/components/textarea.md +50 -50
- package/docs/design-system/components/thinking-reasoning.md +72 -0
- package/docs/design-system/components/thinking-state.md +67 -0
- package/docs/design-system/components/timeline.md +83 -83
- package/docs/design-system/components/toast.md +58 -58
- package/docs/design-system/components/toggle.md +81 -81
- package/docs/design-system/components/toolbar.md +92 -87
- package/docs/design-system/components/tooltip.md +94 -92
- package/docs/design-system/components/typography.md +18 -18
- package/docs/design-system/density-and-elevation.md +65 -61
- package/docs/design-system/design-system-test-missing-items.md +368 -368
- package/docs/design-system/direction-and-localization.md +23 -23
- package/docs/design-system/form-recipes.md +73 -73
- package/docs/design-system/gap-promotion-policy.md +21 -21
- package/docs/design-system/icons.md +74 -69
- package/docs/design-system/installation.md +70 -68
- package/docs/design-system/launch-comparison-shadcn.md +98 -98
- package/docs/design-system/registry-and-cli.md +64 -64
- package/docs/design-system/release-policy.md +30 -30
- package/docs/design-system/roadmap.md +14 -14
- package/docs/design-system/support-matrix.md +23 -23
- package/docs/design-system/tabs.md +54 -53
- package/docs/design-system/template-gap-audit.md +32 -0
- package/docs/design-system/templates.md +59 -0
- package/docs/design-system/token-governance.md +72 -60
- package/package.json +98 -98
- package/registry/component-contract.json +40 -40
- package/registry/components/accordion.tsx +155 -155
- package/registry/components/agent-input-parts.tsx +552 -0
- package/registry/components/agent-input-state.ts +156 -0
- package/registry/components/agent-input.css +307 -0
- package/registry/components/agent-input.tsx +382 -0
- package/registry/components/alert-dialog.tsx +297 -297
- package/registry/components/alert.tsx +293 -293
- package/registry/components/approval-card.css +409 -0
- package/registry/components/approval-card.tsx +401 -0
- package/registry/components/approval-frame.tsx +108 -0
- package/registry/components/approval-questions.tsx +559 -0
- package/registry/components/aspect-ratio.tsx +30 -30
- package/registry/components/attribute.tsx +454 -448
- package/registry/components/autocomplete.tsx +598 -651
- package/registry/components/avatar.tsx +385 -381
- package/registry/components/badge.tsx +629 -629
- package/registry/components/button-group.tsx +565 -565
- package/registry/components/button.tsx +127 -123
- package/registry/components/card.tsx +638 -638
- package/registry/components/carousel.tsx +296 -296
- package/registry/components/chart-block-data.ts +177 -0
- package/registry/components/chart-block.css +171 -0
- package/registry/components/chart-block.tsx +260 -0
- package/registry/components/chart-interactions.ts +123 -0
- package/registry/components/chart-options.cartesian.ts +162 -0
- package/registry/components/chart-options.paint.ts +99 -0
- package/registry/components/chart-options.parts.ts +72 -0
- package/registry/components/chart-options.radial.ts +109 -0
- package/registry/components/chart-options.ts +44 -0
- package/registry/components/chart-options.types.ts +67 -0
- package/registry/components/chart.tsx +203 -203
- package/registry/components/checkbox.tsx +247 -247
- package/registry/components/collapsible.tsx +109 -69
- package/registry/components/command.tsx +208 -208
- package/registry/components/context-menu.tsx +236 -236
- package/registry/components/data-chart.tsx +40 -0
- package/registry/components/date-picker.tsx +1289 -1277
- package/registry/components/echart-theme.ts +246 -0
- package/registry/components/echart.css +49 -0
- package/registry/components/echart.tsx +178 -0
- package/registry/components/expanded/ActivityFeed.tsx +227 -227
- package/registry/components/expanded/ActivityHeatmap.tsx +64 -64
- package/registry/components/expanded/Banner.tsx +179 -179
- package/registry/components/expanded/Breadcrumbs.tsx +131 -131
- package/registry/components/expanded/CatalogComponentsShowcase.tsx +205 -205
- package/registry/components/expanded/CatalogDivider.tsx +49 -49
- package/registry/components/expanded/EmptyState.tsx +155 -155
- package/registry/components/expanded/FileUpload.tsx +543 -543
- package/registry/components/expanded/OnboardingStepListItem.tsx +60 -59
- package/registry/components/expanded/PageHeader.tsx +179 -166
- package/registry/components/expanded/Slideout.tsx +108 -108
- package/registry/components/expanded/Steps.tsx +402 -402
- package/registry/components/expanded/Table.tsx +1092 -1071
- package/registry/components/expanded/Timeline.tsx +203 -203
- package/registry/components/expanded/activityFeed.css +248 -248
- package/registry/components/expanded/activityHeatmap.css +66 -66
- package/registry/components/expanded/banner.css +260 -255
- package/registry/components/expanded/breadcrumbs.css +140 -140
- package/registry/components/expanded/catalogComponentsShowcase.css +87 -87
- package/registry/components/expanded/divider.css +75 -75
- package/registry/components/expanded/emptyState.css +111 -111
- package/registry/components/expanded/fileUpload.css +457 -457
- package/registry/components/expanded/onboardingStepListItem.css +135 -126
- package/registry/components/expanded/pageHeader.css +248 -290
- package/registry/components/expanded/slideout.css +276 -276
- package/registry/components/expanded/steps.css +356 -356
- package/registry/components/expanded/table.css +606 -603
- package/registry/components/expanded/timeline.css +286 -286
- package/registry/components/field.tsx +283 -283
- package/registry/components/hover-card.tsx +48 -48
- package/registry/components/inline-citations.css +126 -0
- package/registry/components/inline-citations.tsx +292 -0
- package/registry/components/input-content.ts +107 -107
- package/registry/components/input-group.tsx +130 -130
- package/registry/components/input-otp.tsx +584 -584
- package/registry/components/input.tsx +990 -972
- package/registry/components/item.tsx +189 -189
- package/registry/components/kbd.tsx +246 -151
- package/registry/components/label.tsx +78 -78
- package/registry/components/menu.tsx +978 -986
- package/registry/components/menubar.tsx +226 -226
- package/registry/components/modal.tsx +872 -872
- package/registry/components/native-select.tsx +205 -205
- package/registry/components/navigation-menu.tsx +171 -171
- package/registry/components/pagination.css +36 -36
- package/registry/components/pagination.tsx +560 -555
- package/registry/components/popover.tsx +338 -338
- package/registry/components/progress-slider.tsx +216 -216
- package/registry/components/radio-card.tsx +676 -677
- package/registry/components/radio-group.tsx +570 -570
- package/registry/components/resizable.tsx +108 -108
- package/registry/components/rolling-count.css +37 -0
- package/registry/components/rolling-count.tsx +110 -0
- package/registry/components/scroll-area.tsx +91 -91
- package/registry/components/segmented-control.tsx +87 -87
- package/registry/components/select-content.tsx +218 -218
- package/registry/components/select.tsx +937 -932
- package/registry/components/sheet.tsx +305 -305
- package/registry/components/shimmer-text.css +69 -0
- package/registry/components/shimmer-text.tsx +43 -0
- package/registry/components/sidebar.tsx +1433 -358
- package/registry/components/skeleton.css +54 -54
- package/registry/components/skeleton.tsx +482 -482
- package/registry/components/slider.tsx +380 -380
- package/registry/components/social-button.tsx +387 -387
- package/registry/components/spinner.tsx +78 -78
- package/registry/components/streaming-text.css +45 -0
- package/registry/components/streaming-text.tsx +165 -0
- package/registry/components/table-elements.tsx +128 -128
- package/registry/components/tabs.css +222 -218
- package/registry/components/tabs.tsx +241 -241
- package/registry/components/tag.tsx +423 -423
- package/registry/components/task-list.css +328 -0
- package/registry/components/task-list.tsx +429 -0
- package/registry/components/textarea.tsx +610 -610
- package/registry/components/thinking-reasoning.css +178 -0
- package/registry/components/thinking-reasoning.tsx +253 -0
- package/registry/components/thinking-state.css +8 -0
- package/registry/components/thinking-state.tsx +46 -0
- package/registry/components/toast.tsx +136 -136
- package/registry/components/toggle.tsx +256 -256
- package/registry/components/toolbar.tsx +539 -539
- package/registry/components/tooltip.tsx +433 -431
- package/registry/examples/agent-input-demo.tsx +90 -0
- package/registry/examples/alert-demo.tsx +34 -34
- package/registry/examples/alert-dialog-demo.tsx +42 -42
- package/registry/examples/approval-card-demo.tsx +83 -0
- package/registry/examples/aspect-ratio-demo.tsx +11 -11
- package/registry/examples/attribute-demo.tsx +65 -65
- package/registry/examples/autocomplete-demo.tsx +109 -109
- package/registry/examples/avatar-demo.tsx +132 -132
- package/registry/examples/badge-demo.tsx +69 -69
- package/registry/examples/button-demo.tsx +86 -83
- package/registry/examples/button-group-demo.tsx +63 -63
- package/registry/examples/card-demo.tsx +86 -86
- package/registry/examples/carousel-demo.tsx +43 -43
- package/registry/examples/chart-block-demo.tsx +5 -0
- package/registry/examples/chart-demo.tsx +18 -33
- package/registry/examples/checkbox-demo.tsx +62 -62
- package/registry/examples/collapsible-demo.tsx +16 -16
- package/registry/examples/collection-filter-bar-demo.tsx +135 -135
- package/registry/examples/command-demo.tsx +42 -42
- package/registry/examples/command-palette-demo.tsx +235 -236
- package/registry/examples/context-menu-demo.tsx +29 -29
- package/registry/examples/control-density-contract-demo.tsx +65 -61
- package/registry/examples/date-picker-demo.tsx +127 -127
- package/registry/examples/divider-demo.tsx +17 -17
- package/registry/examples/expanded/activity-heatmap-demo.tsx +29 -29
- package/registry/examples/expanded/banner-demo.tsx +48 -48
- package/registry/examples/expanded/breadcrumbs-demo.tsx +59 -59
- package/registry/examples/expanded/empty-state-demo.tsx +39 -39
- package/registry/examples/expanded/file-upload-demo.tsx +60 -60
- package/registry/examples/expanded/onboarding-step-demo.tsx +11 -11
- package/registry/examples/expanded/slideout-demo.tsx +15 -15
- package/registry/examples/expanded/steps-demo.tsx +29 -29
- package/registry/examples/expanded/tabs-demo.tsx +13 -13
- package/registry/examples/expanded/timeline-demo.tsx +18 -18
- package/registry/examples/field-demo.tsx +51 -51
- package/registry/examples/hover-card-demo.tsx +23 -23
- package/registry/examples/inline-citations-demo.tsx +31 -0
- package/registry/examples/input-actions-demo.tsx +36 -0
- package/registry/examples/input-demo.tsx +87 -87
- package/registry/examples/input-group-demo.tsx +16 -16
- package/registry/examples/input-otp-demo.tsx +72 -72
- package/registry/examples/item-demo.tsx +46 -46
- package/registry/examples/kbd-demo.tsx +12 -11
- package/registry/examples/label-demo.tsx +20 -20
- package/registry/examples/menu-demo.tsx +122 -122
- package/registry/examples/menubar-demo.tsx +34 -34
- package/registry/examples/modal-demo.tsx +74 -74
- package/registry/examples/native-select-demo.tsx +16 -16
- package/registry/examples/navigation-menu-demo.tsx +29 -29
- package/registry/examples/pagination-demo.tsx +20 -20
- package/registry/examples/popover-demo.tsx +547 -546
- package/registry/examples/progress-demo.tsx +37 -37
- package/registry/examples/progress-slider-demo.tsx +29 -29
- package/registry/examples/radio-card-demo.tsx +51 -51
- package/registry/examples/radio-group-demo.tsx +62 -62
- package/registry/examples/resizable-demo.tsx +22 -22
- package/registry/examples/results-toolbar-demo.tsx +44 -44
- package/registry/examples/rolling-count-demo.tsx +39 -0
- package/registry/examples/scroll-area-demo.tsx +15 -15
- package/registry/examples/segmented-control-demo.tsx +39 -39
- package/registry/examples/select-demo.tsx +87 -87
- package/registry/examples/sheet-demo.tsx +47 -47
- package/registry/examples/shimmer-text-demo.tsx +20 -0
- package/registry/examples/sidebar-demo.tsx +101 -57
- package/registry/examples/slider-demo.tsx +31 -31
- package/registry/examples/social-button-demo.tsx +61 -61
- package/registry/examples/spinner-demo.tsx +59 -59
- package/registry/examples/streaming-text-demo.tsx +28 -0
- package/registry/examples/tabs-demo.tsx +13 -13
- package/registry/examples/tag-demo.tsx +29 -29
- package/registry/examples/task-list-demo.tsx +74 -0
- package/registry/examples/textarea-demo.tsx +79 -79
- package/registry/examples/thinking-reasoning-demo.tsx +74 -0
- package/registry/examples/thinking-state-demo.tsx +13 -0
- package/registry/examples/toast-demo.tsx +35 -35
- package/registry/examples/toggle-demo.tsx +59 -59
- package/registry/examples/tooltip-demo.tsx +115 -115
- package/registry/guidance/USAGE.md +27 -27
- package/registry/guidance/charts.LICENSE.txt +24 -0
- package/registry/hooks/use-controllable-state.ts +33 -0
- package/registry/hooks/use-direction.ts +207 -207
- package/registry/hooks/use-listbox-navigation.ts +73 -0
- package/registry/hooks/use-motion-end.ts +55 -0
- package/registry/hooks/use-reduced-motion.ts +28 -0
- package/registry/index.json +1634 -184
- package/registry/styles/globals.css +1462 -1570
- package/registry.json +364 -10
- package/schema/config.schema.json +51 -51
- package/schema/registry.schema.json +194 -190
- package/schema/tokens.schema.json +167 -163
- package/src/cli/command-line.js +194 -194
- package/src/cli/config-editors.js +9 -9
- package/src/cli/doctor.js +399 -399
- package/src/cli/file-transaction.js +302 -295
- package/src/cli/global-css.js +153 -153
- package/src/cli/index.js +1002 -1009
- package/src/cli/install-plan.js +592 -592
- package/src/cli/install-receipt.js +171 -171
- package/src/cli/jsonc.js +203 -203
- package/src/cli/package-install-state.js +254 -254
- package/src/cli/package-manager.js +238 -238
- package/src/cli/package-plan.js +185 -185
- package/src/cli/package-version.js +97 -97
- package/src/cli/registry-query.js +207 -207
- package/src/cli/reporting.js +55 -55
- package/src/cli/schema-validation.js +19 -19
- package/src/cli/source-scanner.js +686 -686
- package/src/cli/vite-config.js +478 -478
- package/tokens/banhaten.tokens.json +458 -224
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
# Direction and Localization
|
|
2
|
-
|
|
3
|
-
Banhaten is Arabic and English-first, but text direction and language are separate contracts. Components resolve direction from an explicit `dir`, `DirectionProvider`, the nearest valid `[dir]` ancestor, or the document root—in that order. Direction changes layout, icon mirroring, and keyboard geometry; it never selects translated UI or accessibility copy.
|
|
4
|
-
|
|
5
|
-
Use a request-known direction provider for server rendering so the server markup, hydration snapshot, and first paint agree:
|
|
6
|
-
|
|
7
|
-
```tsx
|
|
8
|
-
import { DirectionProvider } from "@/hooks/use-direction"
|
|
9
|
-
import {
|
|
10
|
-
arabicPaginationMessages,
|
|
11
|
-
Pagination,
|
|
12
|
-
} from "@/components/ui/pagination"
|
|
13
|
-
|
|
14
|
-
<DirectionProvider dir="rtl">
|
|
15
|
-
<Pagination messages={arabicPaginationMessages} />
|
|
16
|
-
</DirectionProvider>
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
`DirectionProvider dir="rtl"` works equally well with English, Arabic, Hebrew, Persian, or Urdu. Choose a component's `messages` catalog from the product locale, or pass its direct label props. The exported Arabic catalogs are conveniences, not RTL defaults.
|
|
20
|
-
|
|
21
|
-
Without an explicit prop or provider, server output uses a stable LTR snapshot. After hydration, one shared subscription per document synchronizes consumers with the nearest nested boundary or document root. This avoids hydration mismatches and per-component document observers. For an RTL first paint, provide the request-known direction during SSR.
|
|
22
|
-
|
|
23
|
-
Use logical CSS properties (`start`, `end`, `margin-inline`, `padding-inline`) and `dir="auto"` for user-authored copy. Test mixed-language content, punctuation, numbers, icon mirroring, arrow-key behavior, focus order, portal content, and screen-reader names in every supported direction and locale combination.
|
|
1
|
+
# Direction and Localization
|
|
2
|
+
|
|
3
|
+
Banhaten is Arabic and English-first, but text direction and language are separate contracts. Components resolve direction from an explicit `dir`, `DirectionProvider`, the nearest valid `[dir]` ancestor, or the document root—in that order. Direction changes layout, icon mirroring, and keyboard geometry; it never selects translated UI or accessibility copy.
|
|
4
|
+
|
|
5
|
+
Use a request-known direction provider for server rendering so the server markup, hydration snapshot, and first paint agree:
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
import { DirectionProvider } from "@/hooks/use-direction"
|
|
9
|
+
import {
|
|
10
|
+
arabicPaginationMessages,
|
|
11
|
+
Pagination,
|
|
12
|
+
} from "@/components/ui/pagination"
|
|
13
|
+
|
|
14
|
+
<DirectionProvider dir="rtl">
|
|
15
|
+
<Pagination messages={arabicPaginationMessages} />
|
|
16
|
+
</DirectionProvider>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`DirectionProvider dir="rtl"` works equally well with English, Arabic, Hebrew, Persian, or Urdu. Choose a component's `messages` catalog from the product locale, or pass its direct label props. The exported Arabic catalogs are conveniences, not RTL defaults.
|
|
20
|
+
|
|
21
|
+
Without an explicit prop or provider, server output uses a stable LTR snapshot. After hydration, one shared subscription per document synchronizes consumers with the nearest nested boundary or document root. This avoids hydration mismatches and per-component document observers. For an RTL first paint, provide the request-known direction during SSR.
|
|
22
|
+
|
|
23
|
+
Use logical CSS properties (`start`, `end`, `margin-inline`, `padding-inline`) and `dir="auto"` for user-authored copy. Test mixed-language content, punctuation, numbers, icon mirroring, arrow-key behavior, focus order, portal content, and screen-reader names in every supported direction and locale combination.
|
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
# Form Recipes
|
|
2
|
-
|
|
3
|
-
## Labeled field with validation
|
|
4
|
-
|
|
5
|
-
Compose `Field`, `FieldLabel`, `FieldControl`, `FieldDescription`, and `FieldError`. Associate the input with its label, keep help text stable, and announce errors only when validation has run.
|
|
6
|
-
|
|
7
|
-
```tsx
|
|
8
|
-
<Field invalid={Boolean(error)}>
|
|
9
|
-
<FieldLabel htmlFor="email">Email</FieldLabel>
|
|
10
|
-
<FieldControl>
|
|
11
|
-
<Input id="email" state={error ? "error" : "default"} />
|
|
12
|
-
</FieldControl>
|
|
13
|
-
<FieldDescription>Use your work email.</FieldDescription>
|
|
14
|
-
{error ? <FieldError>{error}</FieldError> : null}
|
|
15
|
-
</Field>
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## Selection and dates
|
|
19
|
-
|
|
20
|
-
Use `Select` for a bounded option set, `Autocomplete` for searchable options, and `DatePicker`/`DateRangePicker` for calendar input. Controlled values are preferred when validation, persistence, or URL state owns the result.
|
|
21
|
-
|
|
22
|
-
Do not emulate a date field with `Input`, a typed `@`, or a generic trailing icon. The Date Picker owns the calendar affordance, keyboard behavior, formatted value, and the same semantic density contract as the surrounding controls.
|
|
23
|
-
|
|
24
|
-
## Golden recipe: collection filter bar
|
|
25
|
-
|
|
26
|
-
Use the complete [`CollectionFilterBarDemo`](../../registry/examples/collection-filter-bar-demo.tsx) recipe for collection and search screens. It establishes the approved composition:
|
|
27
|
-
|
|
28
|
-
- `ToolbarSearch` is full width and uses `shortcutKeys={["Mod", "F"]}` so Command and Control resolve by platform.
|
|
29
|
-
- `DatePicker` owns the From and To fields.
|
|
30
|
-
- `Select` owns Type and Order; `ToolbarSelect` is only a trigger-shaped primitive and is not a complete menu.
|
|
31
|
-
- Every control declares `density="default"`; responsive width classes do not replace component height, padding, radius, or typography.
|
|
32
|
-
- The Reset action uses the same density and resets all composed controls.
|
|
33
|
-
|
|
34
|
-
```tsx
|
|
35
|
-
<form aria-label="Collection filters" data-recipe="collection-filter-bar">
|
|
36
|
-
<ToolbarSearch
|
|
37
|
-
aria-label="Search bookmarks"
|
|
38
|
-
density="default"
|
|
39
|
-
shortcutKeys={["Mod", "F"]}
|
|
40
|
-
width="full"
|
|
41
|
-
/>
|
|
42
|
-
<div className="flex flex-wrap items-end gap-3">
|
|
43
|
-
<DatePicker density="default" triggerProps={{ "aria-label": "From" }} />
|
|
44
|
-
<DatePicker density="default" triggerProps={{ "aria-label": "To" }} />
|
|
45
|
-
<Select density="default" value="Everything">{/* items */}</Select>
|
|
46
|
-
<Select density="default" value="Recently bookmarked">{/* items */}</Select>
|
|
47
|
-
<ToolbarButton density="default" type="reset" variant="link">Reset</ToolbarButton>
|
|
48
|
-
</div>
|
|
49
|
-
</form>
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Golden recipe: results toolbar
|
|
53
|
-
|
|
54
|
-
Use the complete [`ResultsToolbarDemo`](../../registry/examples/results-toolbar-demo.tsx) recipe for result counts, layout selection, and batch actions. `SegmentedControl` is the approved content-width primitive for small mutually exclusive values such as cards per row.
|
|
55
|
-
|
|
56
|
-
```tsx
|
|
57
|
-
<Toolbar aria-label="Bookmark results" layout="split" wrap>
|
|
58
|
-
<ToolbarText density="default"><strong>5,371</strong> bookmarks</ToolbarText>
|
|
59
|
-
<ToolbarSection align="end" wrap>
|
|
60
|
-
<SegmentedControl aria-label="Cards per row" defaultValue="4" density="default">
|
|
61
|
-
<SegmentedControlLabel>Cards / row</SegmentedControlLabel>
|
|
62
|
-
{[3, 4, 5, 6].map((count) => (
|
|
63
|
-
<SegmentedControlItem key={count} value={String(count)}>{count}</SegmentedControlItem>
|
|
64
|
-
))}
|
|
65
|
-
</SegmentedControl>
|
|
66
|
-
<ToolbarButton density="default" variant="outline">Select</ToolbarButton>
|
|
67
|
-
</ToolbarSection>
|
|
68
|
-
</Toolbar>
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## RTL forms
|
|
72
|
-
|
|
73
|
-
Set direction at the form or application boundary. Labels and helper text use logical alignment; OTP, calendar, pagination, and selection keyboard movement resolve the inherited direction. Localize labels, placeholders, validation messages, date formatting, and number formatting in the product layer.
|
|
1
|
+
# Form Recipes
|
|
2
|
+
|
|
3
|
+
## Labeled field with validation
|
|
4
|
+
|
|
5
|
+
Compose `Field`, `FieldLabel`, `FieldControl`, `FieldDescription`, and `FieldError`. Associate the input with its label, keep help text stable, and announce errors only when validation has run.
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
<Field invalid={Boolean(error)}>
|
|
9
|
+
<FieldLabel htmlFor="email">Email</FieldLabel>
|
|
10
|
+
<FieldControl>
|
|
11
|
+
<Input id="email" state={error ? "error" : "default"} />
|
|
12
|
+
</FieldControl>
|
|
13
|
+
<FieldDescription>Use your work email.</FieldDescription>
|
|
14
|
+
{error ? <FieldError>{error}</FieldError> : null}
|
|
15
|
+
</Field>
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Selection and dates
|
|
19
|
+
|
|
20
|
+
Use `Select` for a bounded option set, `Autocomplete` for searchable options, and `DatePicker`/`DateRangePicker` for calendar input. Controlled values are preferred when validation, persistence, or URL state owns the result.
|
|
21
|
+
|
|
22
|
+
Do not emulate a date field with `Input`, a typed `@`, or a generic trailing icon. The Date Picker owns the calendar affordance, keyboard behavior, formatted value, and the same semantic density contract as the surrounding controls.
|
|
23
|
+
|
|
24
|
+
## Golden recipe: collection filter bar
|
|
25
|
+
|
|
26
|
+
Use the complete [`CollectionFilterBarDemo`](../../registry/examples/collection-filter-bar-demo.tsx) recipe for collection and search screens. It establishes the approved composition:
|
|
27
|
+
|
|
28
|
+
- `ToolbarSearch` is full width and uses `shortcutKeys={["Mod", "F"]}` so Command and Control resolve by platform.
|
|
29
|
+
- `DatePicker` owns the From and To fields.
|
|
30
|
+
- `Select` owns Type and Order; `ToolbarSelect` is only a trigger-shaped primitive and is not a complete menu.
|
|
31
|
+
- Every control declares `density="default"`; responsive width classes do not replace component height, padding, radius, or typography.
|
|
32
|
+
- The Reset action uses the same density and resets all composed controls.
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
<form aria-label="Collection filters" data-recipe="collection-filter-bar">
|
|
36
|
+
<ToolbarSearch
|
|
37
|
+
aria-label="Search bookmarks"
|
|
38
|
+
density="default"
|
|
39
|
+
shortcutKeys={["Mod", "F"]}
|
|
40
|
+
width="full"
|
|
41
|
+
/>
|
|
42
|
+
<div className="flex flex-wrap items-end gap-3">
|
|
43
|
+
<DatePicker density="default" triggerProps={{ "aria-label": "From" }} />
|
|
44
|
+
<DatePicker density="default" triggerProps={{ "aria-label": "To" }} />
|
|
45
|
+
<Select density="default" value="Everything">{/* items */}</Select>
|
|
46
|
+
<Select density="default" value="Recently bookmarked">{/* items */}</Select>
|
|
47
|
+
<ToolbarButton density="default" type="reset" variant="link">Reset</ToolbarButton>
|
|
48
|
+
</div>
|
|
49
|
+
</form>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Golden recipe: results toolbar
|
|
53
|
+
|
|
54
|
+
Use the complete [`ResultsToolbarDemo`](../../registry/examples/results-toolbar-demo.tsx) recipe for result counts, layout selection, and batch actions. `SegmentedControl` is the approved content-width primitive for small mutually exclusive values such as cards per row.
|
|
55
|
+
|
|
56
|
+
```tsx
|
|
57
|
+
<Toolbar aria-label="Bookmark results" layout="split" wrap>
|
|
58
|
+
<ToolbarText density="default"><strong>5,371</strong> bookmarks</ToolbarText>
|
|
59
|
+
<ToolbarSection align="end" wrap>
|
|
60
|
+
<SegmentedControl aria-label="Cards per row" defaultValue="4" density="default">
|
|
61
|
+
<SegmentedControlLabel>Cards / row</SegmentedControlLabel>
|
|
62
|
+
{[3, 4, 5, 6].map((count) => (
|
|
63
|
+
<SegmentedControlItem key={count} value={String(count)}>{count}</SegmentedControlItem>
|
|
64
|
+
))}
|
|
65
|
+
</SegmentedControl>
|
|
66
|
+
<ToolbarButton density="default" variant="outline">Select</ToolbarButton>
|
|
67
|
+
</ToolbarSection>
|
|
68
|
+
</Toolbar>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## RTL forms
|
|
72
|
+
|
|
73
|
+
Set direction at the form or application boundary. Labels and helper text use logical alignment; OTP, calendar, pagination, and selection keyboard movement resolve the inherited direction. Localize labels, placeholders, validation messages, date formatting, and number formatting in the product layer.
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
# Gap promotion policy
|
|
2
|
-
|
|
3
|
-
Every visual-QA background records missing components, assets, composition patterns, and tokens as structured gap metadata. The promotion report groups recurring needs across backgrounds and flags any normalized need seen in three or more distinct scenarios.
|
|
4
|
-
|
|
5
|
-
Run:
|
|
6
|
-
|
|
7
|
-
```sh
|
|
8
|
-
npm --prefix playground run report:gap-promotions
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
The generated [Gap Promotion Report](./gap-promotion-report.md) is checked during background tests. Common needs are classified automatically; add `promotionKey` to a gap when two differently worded gaps represent the same reusable need or when a heuristic would group unrelated needs.
|
|
12
|
-
|
|
13
|
-
A candidate does not automatically become a component. Promotion requires:
|
|
14
|
-
|
|
15
|
-
1. Evidence from at least three backgrounds.
|
|
16
|
-
2. A smallest-stable API and explicit fit/avoid guidance.
|
|
17
|
-
3. Semantic density, state, accessibility, and RTL contracts where applicable.
|
|
18
|
-
4. Migration of at least one real background away from its local fallback.
|
|
19
|
-
5. Behavior and visual tests before resolved gap metadata is removed.
|
|
20
|
-
|
|
21
|
-
The first application of this policy produced `SegmentedControl`, migrated the CRM Intelligence background to the shared primitive, and removed its former local segmented-control gap.
|
|
1
|
+
# Gap promotion policy
|
|
2
|
+
|
|
3
|
+
Every visual-QA background records missing components, assets, composition patterns, and tokens as structured gap metadata. The promotion report groups recurring needs across backgrounds and flags any normalized need seen in three or more distinct scenarios.
|
|
4
|
+
|
|
5
|
+
Run:
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
npm --prefix playground run report:gap-promotions
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The generated [Gap Promotion Report](./gap-promotion-report.md) is checked during background tests. Common needs are classified automatically; add `promotionKey` to a gap when two differently worded gaps represent the same reusable need or when a heuristic would group unrelated needs.
|
|
12
|
+
|
|
13
|
+
A candidate does not automatically become a component. Promotion requires:
|
|
14
|
+
|
|
15
|
+
1. Evidence from at least three backgrounds.
|
|
16
|
+
2. A smallest-stable API and explicit fit/avoid guidance.
|
|
17
|
+
3. Semantic density, state, accessibility, and RTL contracts where applicable.
|
|
18
|
+
4. Migration of at least one real background away from its local fallback.
|
|
19
|
+
5. Behavior and visual tests before resolved gap metadata is removed.
|
|
20
|
+
|
|
21
|
+
The first application of this policy produced `SegmentedControl`, migrated the CRM Intelligence background to the shared primitive, and removed its former local segmented-control gap.
|
|
@@ -1,69 +1,74 @@
|
|
|
1
|
-
# Icons
|
|
2
|
-
|
|
3
|
-
The interactive icon explorer is available in the app under the `Icons` section.
|
|
4
|
-
|
|
5
|
-
## Recommendation Posture
|
|
6
|
-
|
|
7
|
-
Start the decision with five serious candidates:
|
|
8
|
-
|
|
9
|
-
- `Lucide`: best default for modern product UI, especially if we want light, consistent, stroke-based icons.
|
|
10
|
-
- `Tabler Icons`: best coverage-first option. It has a huge set, outline/fill coverage, and a familiar 24px grid.
|
|
11
|
-
- `Material Symbols`: best if we want Google-style recognizability and many built-in style axes.
|
|
12
|
-
- `Radix Icons`: best for very dense component UI where 15px icons need to stay crisp.
|
|
13
|
-
- `Phosphor`: best if we want expressive weight control, including thin, bold, fill, and duotone variants.
|
|
14
|
-
|
|
15
|
-
Keep `Simple Icons` as a separate brand-logo source. It should not be the primary UI icon family.
|
|
16
|
-
|
|
17
|
-
## Packs To Review
|
|
18
|
-
|
|
19
|
-
| Pack | Prefix | License | Best for | Variants to compare |
|
|
20
|
-
| --- | --- | --- | --- | --- |
|
|
21
|
-
| Google Material Symbols | `material-symbols` | Apache-2.0 | Google-style UI, broad coverage | Regular, Rounded, Sharp, Outline, Outline Rounded, Outline Sharp |
|
|
22
|
-
| Google Material Icons Classic | `ic` | Apache-2.0 | Existing Material Icons familiarity | Filled/Baseline, Outlined, Rounded, Sharp, Two tone |
|
|
23
|
-
| Material Design Icons by Pictogrammers | `mdi` | Apache-2.0 | Maximum utility coverage | Single broad style |
|
|
24
|
-
| Radix Icons | `radix-icons` | MIT | Dense controls, primitives, menus | Single 15px style |
|
|
25
|
-
| Lucide | `lucide` | ISC | Clean SaaS/product UI | Single outline style |
|
|
26
|
-
| Heroicons | `heroicons` | MIT | Tailwind-friendly apps | Outline 24, Solid 24, Solid 20, Solid 16 |
|
|
27
|
-
| Tabler Icons | `tabler` | MIT | Broad app coverage | Outline, filled where available |
|
|
28
|
-
| Phosphor | `ph` | MIT | Adjustable visual tone | Thin, Light, Regular, Bold, Fill, Duotone |
|
|
29
|
-
| Remix Icon | `ri` | Apache-2.0 | Neutral line/fill system icons | Line, Fill |
|
|
30
|
-
| Bootstrap Icons | `bi` | MIT | Bootstrap-adjacent apps | Mixed outline/fill names |
|
|
31
|
-
| Fluent UI System Icons | `fluent` | MIT | Microsoft-like UI language | Regular, Filled |
|
|
32
|
-
| Carbon Icons | `carbon` | Apache-2.0 | Enterprise/data tools | Fixed source sizes in packages |
|
|
33
|
-
| Ant Design Icons | `ant-design` | MIT | Enterprise React products | Outlined, Filled, TwoTone |
|
|
34
|
-
| Octicons | `octicon` | MIT | Developer tools, GitHub-like UI | 16px and 24px source sizes |
|
|
35
|
-
| Feather Icons | `feather` | MIT | Minimal legacy outline style | Single outline style |
|
|
36
|
-
| Iconoir | `iconoir` | MIT | Broad modern outline set | Single outline style |
|
|
37
|
-
| Flowbite Icons | `flowbite` | MIT | Tailwind/Flowbite apps | Outline, Solid |
|
|
38
|
-
| Ionicons | `ion` | MIT | Mobile/app UI | Outline, Filled, Sharp |
|
|
39
|
-
| Simple Icons | `simple-icons` | CC0-1.0 | Brand logos only | Single-color brand marks |
|
|
40
|
-
|
|
41
|
-
## Decision Criteria
|
|
42
|
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
66
|
-
-
|
|
67
|
-
-
|
|
68
|
-
-
|
|
69
|
-
-
|
|
1
|
+
# Icons
|
|
2
|
+
|
|
3
|
+
The interactive icon explorer is available in the app under the `Icons` section.
|
|
4
|
+
|
|
5
|
+
## Recommendation Posture
|
|
6
|
+
|
|
7
|
+
Start the decision with five serious candidates:
|
|
8
|
+
|
|
9
|
+
- `Lucide`: best default for modern product UI, especially if we want light, consistent, stroke-based icons.
|
|
10
|
+
- `Tabler Icons`: best coverage-first option. It has a huge set, outline/fill coverage, and a familiar 24px grid.
|
|
11
|
+
- `Material Symbols`: best if we want Google-style recognizability and many built-in style axes.
|
|
12
|
+
- `Radix Icons`: best for very dense component UI where 15px icons need to stay crisp.
|
|
13
|
+
- `Phosphor`: best if we want expressive weight control, including thin, bold, fill, and duotone variants.
|
|
14
|
+
|
|
15
|
+
Keep `Simple Icons` as a separate brand-logo source. It should not be the primary UI icon family.
|
|
16
|
+
|
|
17
|
+
## Packs To Review
|
|
18
|
+
|
|
19
|
+
| Pack | Prefix | License | Best for | Variants to compare |
|
|
20
|
+
| --- | --- | --- | --- | --- |
|
|
21
|
+
| Google Material Symbols | `material-symbols` | Apache-2.0 | Google-style UI, broad coverage | Regular, Rounded, Sharp, Outline, Outline Rounded, Outline Sharp |
|
|
22
|
+
| Google Material Icons Classic | `ic` | Apache-2.0 | Existing Material Icons familiarity | Filled/Baseline, Outlined, Rounded, Sharp, Two tone |
|
|
23
|
+
| Material Design Icons by Pictogrammers | `mdi` | Apache-2.0 | Maximum utility coverage | Single broad style |
|
|
24
|
+
| Radix Icons | `radix-icons` | MIT | Dense controls, primitives, menus | Single 15px style |
|
|
25
|
+
| Lucide | `lucide` | ISC | Clean SaaS/product UI | Single outline style |
|
|
26
|
+
| Heroicons | `heroicons` | MIT | Tailwind-friendly apps | Outline 24, Solid 24, Solid 20, Solid 16 |
|
|
27
|
+
| Tabler Icons | `tabler` | MIT | Broad app coverage | Outline, filled where available |
|
|
28
|
+
| Phosphor | `ph` | MIT | Adjustable visual tone | Thin, Light, Regular, Bold, Fill, Duotone |
|
|
29
|
+
| Remix Icon | `ri` | Apache-2.0 | Neutral line/fill system icons | Line, Fill |
|
|
30
|
+
| Bootstrap Icons | `bi` | MIT | Bootstrap-adjacent apps | Mixed outline/fill names |
|
|
31
|
+
| Fluent UI System Icons | `fluent` | MIT | Microsoft-like UI language | Regular, Filled |
|
|
32
|
+
| Carbon Icons | `carbon` | Apache-2.0 | Enterprise/data tools | Fixed source sizes in packages |
|
|
33
|
+
| Ant Design Icons | `ant-design` | MIT | Enterprise React products | Outlined, Filled, TwoTone |
|
|
34
|
+
| Octicons | `octicon` | MIT | Developer tools, GitHub-like UI | 16px and 24px source sizes |
|
|
35
|
+
| Feather Icons | `feather` | MIT | Minimal legacy outline style | Single outline style |
|
|
36
|
+
| Iconoir | `iconoir` | MIT | Broad modern outline set | Single outline style |
|
|
37
|
+
| Flowbite Icons | `flowbite` | MIT | Tailwind/Flowbite apps | Outline, Solid |
|
|
38
|
+
| Ionicons | `ion` | MIT | Mobile/app UI | Outline, Filled, Sharp |
|
|
39
|
+
| Simple Icons | `simple-icons` | CC0-1.0 | Brand logos only | Single-color brand marks |
|
|
40
|
+
|
|
41
|
+
## Decision Criteria
|
|
42
|
+
|
|
43
|
+
- Default UI glyph clarity at 18px, with the glyph centered in a 20px layout slot.
|
|
44
|
+
- Small-control icon clarity at 16px without promoting those intentionally compact glyphs to the default size.
|
|
45
|
+
- Menu, dropdown, and table icon legibility in dense rows.
|
|
46
|
+
- Visual match with `default`, `rounded`, and `sharp` appearances.
|
|
47
|
+
- Variant usefulness: filled states, two-tone states, sharp geometry, or rounded geometry.
|
|
48
|
+
- Coverage for navigation, data, files, users, settings, alerts, billing, integrations, and brand logos.
|
|
49
|
+
- Licensing and attribution obligations. Keep source license notices in the project when redistributing SVG/source files.
|
|
50
|
+
|
|
51
|
+
## Default Geometry Contract
|
|
52
|
+
|
|
53
|
+
Default UI icons use `--bh-icon-size-default` (`18px`) inside `--bh-icon-slot-size-default` (`20px`). The resulting `--bh-icon-slot-inset-default` is `1px` on each side. Components must preserve that slot so switching from the former 20px glyph does not change alignment, gaps, or control dimensions. Intentional 12px, 16px, 24px, brand-logo, avatar, spinner, and control-indicator sizes remain component-specific.
|
|
54
|
+
|
|
55
|
+
## Sources
|
|
56
|
+
|
|
57
|
+
- Google Material Icons repository: https://github.com/google/material-design-icons
|
|
58
|
+
- Iconify collection API: https://iconify.design/docs/api/collection.html
|
|
59
|
+
- Radix Icons: https://github.com/radix-ui/icons
|
|
60
|
+
- Lucide: https://github.com/lucide-icons/lucide
|
|
61
|
+
- Heroicons: https://heroicons.com
|
|
62
|
+
- Tabler Icons: https://github.com/tabler/tabler-icons
|
|
63
|
+
- Phosphor Icons: https://github.com/phosphor-icons/core
|
|
64
|
+
- Remix Icon: https://www.remixicon.com
|
|
65
|
+
- Bootstrap Icons: https://icons.getbootstrap.com
|
|
66
|
+
- Fluent UI System Icons: https://github.com/microsoft/fluentui-system-icons
|
|
67
|
+
- Carbon Icons: https://carbondesignsystem.com/elements/icons/code
|
|
68
|
+
- Ant Design Icons: https://www.npmjs.com/package/@ant-design/icons
|
|
69
|
+
- Octicons: https://primer.github.io/design/components/icon
|
|
70
|
+
- Feather Icons: https://github.com/feathericons/feather
|
|
71
|
+
- Iconoir: https://github.com/iconoir-icons/iconoir
|
|
72
|
+
- Flowbite Icons: https://flowbite.com/icons
|
|
73
|
+
- Ionicons: https://github.com/ionic-team/ionicons
|
|
74
|
+
- Simple Icons: https://github.com/simple-icons/simple-icons
|
|
@@ -1,68 +1,70 @@
|
|
|
1
|
-
# Installation
|
|
2
|
-
|
|
3
|
-
## Requirements
|
|
4
|
-
|
|
5
|
-
Banhaten installs source into a React 18.2/19 project using Tailwind CSS 4. Use Node 18.18 or newer.
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npx banhaten init
|
|
9
|
-
npx banhaten add button input select
|
|
10
|
-
```
|
|
11
|
-
|
|
12
|
-
Run the package-manager command printed by the CLI. It detects npm, pnpm, Yarn, and Bun from `packageManager` or lockfiles.
|
|
13
|
-
|
|
14
|
-
Dependency declarations are validated with npm-compatible semantic-version
|
|
15
|
-
ranges. A consumer range is kept only when every version it allows satisfies the
|
|
16
|
-
Banhaten requirement. If the Banhaten range is wholly contained by a broader
|
|
17
|
-
consumer range, the CLI safely narrows the declaration in its existing package
|
|
18
|
-
section, updates `package.json`, and prints an install command so the package
|
|
19
|
-
manager can reconcile its lockfile. Partial overlaps, disjoint ranges, mutable
|
|
20
|
-
tags, workspace protocols, aliases, Git URLs, and local file specs fail without
|
|
21
|
-
writing. Banhaten deliberately does not treat a current lockfile resolution as a
|
|
22
|
-
durable compatibility guarantee. When the manifest is already safe, the CLI also
|
|
23
|
-
checks package versions inside the target project or declared workspace boundary.
|
|
24
|
-
For npm lockfiles v2 and v3 it verifies the importer declarations and exact locked
|
|
25
|
-
resolutions; stale, missing, incompatible, or opaque lock state keeps the install
|
|
26
|
-
action visible. Machine-readable output exposes the same
|
|
27
|
-
`{ required, command, cwd }` state, including the project or workspace directory
|
|
28
|
-
where the command must run.
|
|
29
|
-
|
|
30
|
-
## Vite
|
|
31
|
-
|
|
32
|
-
Before writing, the CLI resolves a canonical install plan from
|
|
33
|
-
`banhaten.config.json`, the TypeScript `@/*` path, and the Vite `@` alias. If
|
|
34
|
-
TypeScript and Vite agree, that root is used even when another `src` directory
|
|
35
|
-
exists. If only one side declares the alias, the CLI mirrors it to the other.
|
|
36
|
-
Conflicting roots, multi-target TypeScript paths, destination-overlapping aliases,
|
|
37
|
-
inherited TypeScript aliases without local `baseUrl`/`paths`, and Vite aliases
|
|
38
|
-
that cannot be inspected statically fail without changing the project. When a
|
|
39
|
-
supported Vite config exists, `init` also adds the Tailwind Vite plugin while
|
|
40
|
-
preserving its existing structure.
|
|
41
|
-
|
|
42
|
-
CLI commands use strict schemas. Unknown or duplicate flags, missing values, and
|
|
43
|
-
unexpected positional arguments are rejected before project discovery. The
|
|
44
|
-
install receipt pins the resolved destinations; changing roots later requires
|
|
45
|
-
moving or removing the old generated files and receipt first.
|
|
46
|
-
|
|
47
|
-
## Next.js and other frameworks
|
|
48
|
-
|
|
49
|
-
Without Vite, the CLI installs Tailwind and writes the configured global stylesheet, aliases, `cn` utility, and direction hook. Import the generated global stylesheet from the framework root layout and ensure the `@/*` TypeScript alias resolves to the source directory.
|
|
50
|
-
|
|
51
|
-
## Fonts and direction
|
|
52
|
-
|
|
53
|
-
The generated stylesheet imports Inter weights 400–700 and IBM Plex Sans Arabic weights 400–700. Set document language and direction at the application boundary:
|
|
54
|
-
|
|
55
|
-
```tsx
|
|
56
|
-
<html lang="ar" dir="rtl" data-theme="
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
Wrap server-rendered component trees in `DirectionProvider` when request data already determines the direction; this keeps the first server and client snapshots identical. It is also the boundary for nested surfaces that differ from the document. Without it, components hydrate from a stable LTR snapshot and then synchronize from the document through one shared observer.
|
|
60
|
-
|
|
61
|
-
## Updating safely
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
npx banhaten diff
|
|
65
|
-
npx banhaten update
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
The receipt records generated hashes. Unmodified files update automatically. Locally modified files and token blocks stop without writing; pass `--force` only after reviewing the unified diff. Put product overrides outside the marked token block and product composition in wrapper components.
|
|
1
|
+
# Installation
|
|
2
|
+
|
|
3
|
+
## Requirements
|
|
4
|
+
|
|
5
|
+
Banhaten installs source into a React 18.2/19 project using Tailwind CSS 4. Use Node 18.18 or newer.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx banhaten init
|
|
9
|
+
npx banhaten add button input select
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Run the package-manager command printed by the CLI. It detects npm, pnpm, Yarn, and Bun from `packageManager` or lockfiles.
|
|
13
|
+
|
|
14
|
+
Dependency declarations are validated with npm-compatible semantic-version
|
|
15
|
+
ranges. A consumer range is kept only when every version it allows satisfies the
|
|
16
|
+
Banhaten requirement. If the Banhaten range is wholly contained by a broader
|
|
17
|
+
consumer range, the CLI safely narrows the declaration in its existing package
|
|
18
|
+
section, updates `package.json`, and prints an install command so the package
|
|
19
|
+
manager can reconcile its lockfile. Partial overlaps, disjoint ranges, mutable
|
|
20
|
+
tags, workspace protocols, aliases, Git URLs, and local file specs fail without
|
|
21
|
+
writing. Banhaten deliberately does not treat a current lockfile resolution as a
|
|
22
|
+
durable compatibility guarantee. When the manifest is already safe, the CLI also
|
|
23
|
+
checks package versions inside the target project or declared workspace boundary.
|
|
24
|
+
For npm lockfiles v2 and v3 it verifies the importer declarations and exact locked
|
|
25
|
+
resolutions; stale, missing, incompatible, or opaque lock state keeps the install
|
|
26
|
+
action visible. Machine-readable output exposes the same
|
|
27
|
+
`{ required, command, cwd }` state, including the project or workspace directory
|
|
28
|
+
where the command must run.
|
|
29
|
+
|
|
30
|
+
## Vite
|
|
31
|
+
|
|
32
|
+
Before writing, the CLI resolves a canonical install plan from
|
|
33
|
+
`banhaten.config.json`, the TypeScript `@/*` path, and the Vite `@` alias. If
|
|
34
|
+
TypeScript and Vite agree, that root is used even when another `src` directory
|
|
35
|
+
exists. If only one side declares the alias, the CLI mirrors it to the other.
|
|
36
|
+
Conflicting roots, multi-target TypeScript paths, destination-overlapping aliases,
|
|
37
|
+
inherited TypeScript aliases without local `baseUrl`/`paths`, and Vite aliases
|
|
38
|
+
that cannot be inspected statically fail without changing the project. When a
|
|
39
|
+
supported Vite config exists, `init` also adds the Tailwind Vite plugin while
|
|
40
|
+
preserving its existing structure.
|
|
41
|
+
|
|
42
|
+
CLI commands use strict schemas. Unknown or duplicate flags, missing values, and
|
|
43
|
+
unexpected positional arguments are rejected before project discovery. The
|
|
44
|
+
install receipt pins the resolved destinations; changing roots later requires
|
|
45
|
+
moving or removing the old generated files and receipt first.
|
|
46
|
+
|
|
47
|
+
## Next.js and other frameworks
|
|
48
|
+
|
|
49
|
+
Without Vite, the CLI installs Tailwind and writes the configured global stylesheet, aliases, `cn` utility, and direction hook. Import the generated global stylesheet from the framework root layout and ensure the `@/*` TypeScript alias resolves to the source directory.
|
|
50
|
+
|
|
51
|
+
## Fonts and direction
|
|
52
|
+
|
|
53
|
+
The generated stylesheet imports Inter weights 400–700 and IBM Plex Sans Arabic weights 400–700. Set document language and direction at the application boundary:
|
|
54
|
+
|
|
55
|
+
```tsx
|
|
56
|
+
<html lang="ar" dir="rtl" data-theme="gray" data-radius="default">
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Wrap server-rendered component trees in `DirectionProvider` when request data already determines the direction; this keeps the first server and client snapshots identical. It is also the boundary for nested surfaces that differ from the document. Without it, components hydrate from a stable LTR snapshot and then synchronize from the document through one shared observer.
|
|
60
|
+
|
|
61
|
+
## Updating safely
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
npx banhaten diff
|
|
65
|
+
npx banhaten update
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The receipt records generated hashes. Unmodified files update automatically. Locally modified files and token blocks stop without writing; pass `--force` only after reviewing the unified diff. Put product overrides outside the marked token block and product composition in wrapper components.
|
|
69
|
+
|
|
70
|
+
The CLI also checks the original contents of every write target and the files used for ownership checks and merges before and after staging. An intervening edit, creation, or deletion aborts the plan, even with `--force`. Re-run the command after concurrent edits have finished.
|