banhaten 0.1.2 → 0.1.3
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 +93 -328
- package/banhaten.config.example.json +1 -1
- package/docs/design-system/README.md +11 -0
- package/docs/design-system/appearance-presets.md +184 -0
- package/docs/design-system/appearances/default.md +94 -0
- package/docs/design-system/appearances/rounded.md +95 -0
- package/docs/design-system/appearances/sharp.md +95 -0
- package/docs/design-system/component-showcase-consistency-report.md +217 -0
- package/docs/design-system/component-token-consistency-audit.md +163 -0
- package/docs/design-system/components/README.md +74 -0
- package/docs/design-system/components/accordion.md +51 -0
- package/docs/design-system/components/activity-feed.md +92 -0
- package/docs/design-system/components/alert-dialog.md +70 -0
- package/docs/design-system/components/alert.md +79 -0
- package/docs/design-system/components/aspect-ratio.md +44 -0
- package/docs/design-system/components/attribute.md +87 -0
- package/docs/design-system/components/autocomplete.md +74 -0
- package/docs/design-system/components/avatar.md +52 -0
- package/docs/design-system/components/badge.md +53 -0
- package/docs/design-system/components/banner.md +85 -0
- package/docs/design-system/components/breadcrumbs.md +174 -0
- package/docs/design-system/components/button-group.md +83 -0
- package/docs/design-system/components/button.md +77 -0
- package/docs/design-system/components/card.md +78 -0
- package/docs/design-system/components/carousel.md +44 -0
- package/docs/design-system/components/catalog-components.md +45 -0
- package/docs/design-system/components/chart.md +43 -0
- package/docs/design-system/components/checkbox.md +52 -0
- package/docs/design-system/components/collapsible.md +48 -0
- package/docs/design-system/components/command-bar.md +57 -0
- package/docs/design-system/components/command.md +60 -0
- package/docs/design-system/components/context-menu.md +44 -0
- package/docs/design-system/components/date-picker.md +77 -0
- package/docs/design-system/components/divider.md +101 -0
- package/docs/design-system/components/empty-state.md +55 -0
- package/docs/design-system/components/field.md +69 -0
- package/docs/design-system/components/file-upload.md +185 -0
- package/docs/design-system/components/hover-card.md +46 -0
- package/docs/design-system/components/icons.md +48 -0
- package/docs/design-system/components/input-group.md +56 -0
- package/docs/design-system/components/input-otp.md +55 -0
- package/docs/design-system/components/input.md +48 -0
- package/docs/design-system/components/kbd.md +44 -0
- package/docs/design-system/components/label.md +48 -0
- package/docs/design-system/components/menu.md +59 -0
- package/docs/design-system/components/menubar.md +45 -0
- package/docs/design-system/components/modal.md +98 -0
- package/docs/design-system/components/native-select.md +52 -0
- package/docs/design-system/components/navigation-menu.md +48 -0
- package/docs/design-system/components/onboarding-step-list-item.md +80 -0
- package/docs/design-system/components/page-header.md +84 -0
- package/docs/design-system/components/pagination.md +49 -0
- package/docs/design-system/components/popover.md +58 -0
- package/docs/design-system/components/progress-slider.md +48 -0
- package/docs/design-system/components/progress.md +75 -0
- package/docs/design-system/components/radio-card.md +49 -0
- package/docs/design-system/components/radio-group.md +55 -0
- package/docs/design-system/components/resizable.md +42 -0
- package/docs/design-system/components/scroll-area.md +45 -0
- package/docs/design-system/components/select.md +50 -0
- package/docs/design-system/components/sheet.md +65 -0
- package/docs/design-system/components/sidebar.md +68 -0
- package/docs/design-system/components/skeleton.md +73 -0
- package/docs/design-system/components/slideout.md +63 -0
- package/docs/design-system/components/slider.md +61 -0
- package/docs/design-system/components/social-button.md +47 -0
- package/docs/design-system/components/spinner.md +61 -0
- package/docs/design-system/components/steps.md +63 -0
- package/docs/design-system/components/table.md +397 -0
- package/docs/design-system/components/tabs.md +52 -0
- package/docs/design-system/components/tag.md +78 -0
- package/docs/design-system/components/textarea.md +48 -0
- package/docs/design-system/components/timeline.md +81 -0
- package/docs/design-system/components/toast.md +56 -0
- package/docs/design-system/components/toggle.md +79 -0
- package/docs/design-system/components/toolbar.md +85 -0
- package/docs/design-system/components/tooltip.md +90 -0
- package/docs/design-system/components/typography.md +18 -0
- package/docs/design-system/design-system-test-missing-items.md +368 -0
- package/docs/design-system/icons.md +69 -0
- package/docs/design-system/registry-and-cli.md +41 -0
- package/docs/design-system/tabs.md +53 -0
- package/docs/design-system/token-governance.md +38 -0
- package/package.json +83 -65
- package/registry/components/alert-dialog.tsx +297 -0
- package/registry/components/aspect-ratio.tsx +30 -0
- package/registry/components/carousel.tsx +234 -0
- package/registry/components/chart.tsx +170 -0
- package/registry/components/collapsible.tsx +69 -0
- package/registry/components/command.tsx +174 -0
- package/registry/components/context-menu.tsx +236 -0
- package/registry/components/date-picker.tsx +1 -1
- package/registry/components/expanded/PageHeader.tsx +1 -1
- package/registry/components/expanded/breadcrumbs.css +139 -139
- package/registry/components/expanded/catalogComponentsShowcase.css +83 -83
- package/registry/components/expanded/steps.css +274 -274
- package/registry/components/expanded/timeline.css +264 -264
- package/registry/components/field.tsx +230 -0
- package/registry/components/hover-card.tsx +48 -0
- package/registry/components/input-group.tsx +130 -0
- package/registry/components/input.tsx +2 -2
- package/registry/components/kbd.tsx +44 -0
- package/registry/components/label.tsx +78 -0
- package/registry/components/menu.tsx +3 -1
- package/registry/components/menubar.tsx +226 -0
- package/registry/components/modal.tsx +109 -76
- package/registry/components/native-select.tsx +205 -0
- package/registry/components/navigation-menu.tsx +171 -0
- package/registry/components/radio-group.tsx +1 -1
- package/registry/components/resizable.tsx +74 -0
- package/registry/components/scroll-area.tsx +67 -0
- package/registry/components/select.tsx +2 -4
- package/registry/components/sheet.tsx +305 -0
- package/registry/components/sidebar.tsx +352 -0
- package/registry/components/social-button.tsx +74 -10
- package/registry/components/{expanded/tabs.css → tabs.css} +127 -106
- package/registry/components/tabs.tsx +242 -0
- package/registry/components/textarea.tsx +1 -1
- package/registry/components/toast.tsx +131 -0
- package/registry/examples/alert-dialog-demo.tsx +42 -0
- package/registry/examples/aspect-ratio-demo.tsx +11 -0
- package/registry/examples/carousel-demo.tsx +25 -0
- package/registry/examples/chart-demo.tsx +33 -0
- package/registry/examples/collapsible-demo.tsx +16 -0
- package/registry/examples/command-demo.tsx +42 -0
- package/registry/examples/context-menu-demo.tsx +29 -0
- package/registry/examples/expanded/tabs-demo.tsx +1 -1
- package/registry/examples/field-demo.tsx +51 -0
- package/registry/examples/hover-card-demo.tsx +23 -0
- package/registry/examples/input-group-demo.tsx +16 -0
- package/registry/examples/kbd-demo.tsx +11 -0
- package/registry/examples/label-demo.tsx +20 -0
- package/registry/examples/menubar-demo.tsx +34 -0
- package/registry/examples/native-select-demo.tsx +16 -0
- package/registry/examples/navigation-menu-demo.tsx +29 -0
- package/registry/examples/resizable-demo.tsx +22 -0
- package/registry/examples/scroll-area-demo.tsx +15 -0
- package/registry/examples/sheet-demo.tsx +47 -0
- package/registry/examples/sidebar-demo.tsx +55 -0
- package/registry/examples/tabs-demo.tsx +13 -0
- package/registry/examples/toast-demo.tsx +35 -0
- package/registry/index.json +655 -11
- package/registry/styles/globals.css +4733 -4690
- package/registry.json +1612 -0
- package/schema/config.schema.json +48 -0
- package/schema/registry.schema.json +85 -0
- package/schema/tokens.schema.json +63 -0
- package/src/cli/index.js +312 -18
- package/tokens/banhaten.tokens.json +1 -1
- package/registry/assets/avatars/avatar-02.jpg +0 -0
- package/registry/assets/avatars/avatar-03.jpg +0 -0
- package/registry/assets/avatars/avatar-04.jpg +0 -0
- package/registry/assets/avatars/avatar-05.jpg +0 -0
- package/registry/assets/avatars/avatar-06.jpg +0 -0
- package/registry/assets/avatars/avatar-07.jpg +0 -0
- package/registry/assets/avatars/avatar-08.jpg +0 -0
- package/registry/assets/avatars/avatar-09.jpg +0 -0
- package/registry/assets/avatars/avatar-10.jpg +0 -0
- package/registry/assets/avatars/avatar-11.jpg +0 -0
- package/registry/assets/avatars/avatar-12.jpg +0 -0
- package/registry/assets/avatars/avatar-13.jpg +0 -0
- package/registry/assets/avatars/avatar-14.jpg +0 -0
- package/registry/assets/avatars/avatar-15.jpg +0 -0
- package/registry/assets/avatars/avatar-16.jpg +0 -0
- package/registry/assets/avatars/avatar-17.jpg +0 -0
- package/registry/assets/avatars/avatar-18.jpg +0 -0
- package/registry/assets/avatars/avatar-19.jpg +0 -0
- package/registry/assets/avatars/avatar-20.jpg +0 -0
- package/registry/assets/avatars/avatar-21.jpg +0 -0
- package/registry/assets/avatars/avatar-22.jpg +0 -0
- package/registry/assets/avatars/avatar-23.jpg +0 -0
- package/registry/assets/avatars/avatar-24.jpg +0 -0
- package/registry/assets/avatars/avatar-25.jpg +0 -0
- package/registry/assets/avatars/avatar-26.jpg +0 -0
- package/registry/assets/avatars/avatar-27.jpg +0 -0
- package/registry/assets/avatars/avatar-28.jpg +0 -0
- package/registry/assets/avatars/avatar-29.jpg +0 -0
- package/registry/assets/avatars/avatar-30.jpg +0 -0
- package/registry/assets/avatars/avatar-31.jpg +0 -0
- package/registry/assets/avatars/avatar-32.jpg +0 -0
- package/registry/assets/avatars/avatar-33.jpg +0 -0
- package/registry/assets/avatars/avatar-34.jpg +0 -0
- package/registry/assets/avatars/avatar-35.jpg +0 -0
- package/registry/assets/image-assets.json +0 -744
- package/registry/assets/images/art-02.jpg +0 -0
- package/registry/assets/images/art-03.jpg +0 -0
- package/registry/assets/images/art-04.jpg +0 -0
- package/registry/assets/images/art-05.jpg +0 -0
- package/registry/assets/images/art-06.jpg +0 -0
- package/registry/assets/images/art-07.jpg +0 -0
- package/registry/assets/images/art-08.jpg +0 -0
- package/registry/assets/images/art-09.jpg +0 -0
- package/registry/assets/images/art-10.jpg +0 -0
- package/registry/assets/images/art-11.jpg +0 -0
- package/registry/assets/images/art-12.jpg +0 -0
- package/registry/assets/images/art-13.jpg +0 -0
- package/registry/assets/images/art-14.jpg +0 -0
- package/registry/assets/images/art-15.jpg +0 -0
- package/registry/assets/images/art-16.jpg +0 -0
- package/registry/assets/images/art-17.jpg +0 -0
- package/registry/assets/images/art-18.jpg +0 -0
- package/registry/assets/images/art-19.jpg +0 -0
- package/registry/assets/images/art-20.jpg +0 -0
- package/registry/assets/images/art-21.jpg +0 -0
- package/registry/assets/images/art-22.jpg +0 -0
- package/registry/assets/images/art-23.jpg +0 -0
- package/registry/assets/images/art-24.jpg +0 -0
- package/registry/assets/images/art-25.jpg +0 -0
- package/registry/assets/images/art-26.jpg +0 -0
- package/registry/assets/images/art-27.jpg +0 -0
- package/registry/assets/images/nature-01.jpg +0 -0
- package/registry/assets/images/nature-02.jpg +0 -0
- package/registry/assets/images/nature-03.jpg +0 -0
- package/registry/assets/images/nature-04.jpg +0 -0
- package/registry/assets/images/nature-05.jpg +0 -0
- package/registry/assets/images/nature-06.jpg +0 -0
- package/registry/assets/images/nature-07.jpg +0 -0
- package/registry/assets/images/nature-08.jpg +0 -0
- package/registry/assets/images/nature-09.jpg +0 -0
- package/registry/assets/images/nature-10.jpg +0 -0
- package/registry/assets/images/nature-11.jpg +0 -0
- package/registry/assets/images/nature-12.jpg +0 -0
- package/registry/assets/images/nature-13.jpg +0 -0
- package/registry/assets/images/nature-14.jpg +0 -0
- package/registry/assets/images/nature-15.jpg +0 -0
- package/registry/assets/images/nature-16.jpg +0 -0
- package/registry/assets/images/nature-17.jpg +0 -0
- package/registry/assets/images/nature-18.jpg +0 -0
- package/registry/assets/images/nature-19.jpg +0 -0
- package/registry/assets/images/nature-20.jpg +0 -0
- package/registry/components/expanded/Tabs.tsx +0 -86
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Autocomplete
|
|
2
|
+
|
|
3
|
+
Autocomplete is a searchable combobox field for choosing one or many known options.
|
|
4
|
+
|
|
5
|
+
The implementation is intentionally composed from existing Banhaten primitives: `Input` owns the field surface, `SelectMenu` and `SelectMenuItem` own the result list, and `Tag` owns selected multi-value chips. The component adds filtering, selected-value state, keyboard navigation, ARIA combobox wiring, and controlled or uncontrolled APIs.
|
|
6
|
+
|
|
7
|
+
## API
|
|
8
|
+
|
|
9
|
+
```tsx
|
|
10
|
+
<Autocomplete
|
|
11
|
+
label="Owner"
|
|
12
|
+
placeholder="Search people"
|
|
13
|
+
options={[
|
|
14
|
+
{ value: "ahmed", label: "Ahmed Galal", addonText: "Design system" },
|
|
15
|
+
{ value: "nora", label: "Nora Ali", addonText: "Product" },
|
|
16
|
+
]}
|
|
17
|
+
/>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
| Prop | Values | Default |
|
|
21
|
+
| --- | --- | --- |
|
|
22
|
+
| `options` | `{ value, label, addonText, itemType, media, keywords, disabled }[]` | required |
|
|
23
|
+
| `selectionMode` | `single`, `multiple` | `single` |
|
|
24
|
+
| `value` / `defaultValue` | `string` or `string[]` | none |
|
|
25
|
+
| `inputValue` / `defaultInputValue` | `string` | inferred from selected single value |
|
|
26
|
+
| `open` / `defaultOpen` | `boolean` | `false` |
|
|
27
|
+
| `filterOptions` | custom filtering function | label, value, and keywords filter |
|
|
28
|
+
| `size` | `md`, `lg` | `lg` |
|
|
29
|
+
| `variant` | `default`, `soft` | `default` |
|
|
30
|
+
| `state` | `default`, `filled`, `error`, `disabled` | inferred |
|
|
31
|
+
| `dir` | `ltr`, `rtl`, `auto` | inherited |
|
|
32
|
+
|
|
33
|
+
## Composition Rules
|
|
34
|
+
|
|
35
|
+
- Use autocomplete for known option sets that benefit from search.
|
|
36
|
+
- Use `Select` when the option set is short and browsing is faster than typing.
|
|
37
|
+
- Use `selectionMode="multiple"` when selected options need removable chips; chips render with `Tag`.
|
|
38
|
+
- Keep async fetching, debouncing, and remote loading in product code by controlling `inputValue`, `open`, and `options`.
|
|
39
|
+
- Keep option labels concise. Use `addonText` for secondary metadata.
|
|
40
|
+
|
|
41
|
+
## Accessibility
|
|
42
|
+
|
|
43
|
+
- The input uses `role="combobox"`, `aria-autocomplete="list"`, `aria-expanded`, `aria-controls`, and `aria-activedescendant`.
|
|
44
|
+
- Results render as a `listbox` using Select menu rows.
|
|
45
|
+
- Arrow keys move the active option, `Enter` selects, `Escape` closes, and `Backspace` removes the last selected tag in multiple mode when the search field is empty.
|
|
46
|
+
- Labels and helper text are associated with the input, and error state maps to `aria-invalid`.
|
|
47
|
+
|
|
48
|
+
## Token Contract
|
|
49
|
+
|
|
50
|
+
Autocomplete consumes tokens through the primitives it composes:
|
|
51
|
+
|
|
52
|
+
- Field surface, typography, icon sizing, focus ring, and disabled/error states from `Input`.
|
|
53
|
+
- Menu surface, item rows, hover state, selected check, and item media slots from `Select`.
|
|
54
|
+
- Removable selected chips from `Tag`.
|
|
55
|
+
- Additional layout uses spacing, content, and z-index tokens only.
|
|
56
|
+
|
|
57
|
+
## Install
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx banhaten add autocomplete
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Examples
|
|
64
|
+
|
|
65
|
+
Primary registry example: `examples/autocomplete-demo.tsx`.
|
|
66
|
+
|
|
67
|
+
Open the live component page or run `npx banhaten docs autocomplete` to inspect source files, install command, and examples.
|
|
68
|
+
|
|
69
|
+
## RTL Rules
|
|
70
|
+
|
|
71
|
+
- `inheritsDirection`: true
|
|
72
|
+
- `composition`: Uses the existing Input field, Select menu and menu item rows, and Tag chips instead of introducing new visual primitives.
|
|
73
|
+
- `spacing`: Uses logical positioning, logical gaps, and inherited direction so the input, menu rows, checks, helper text, and selected tags mirror naturally.
|
|
74
|
+
- `textDirection`: Labels, option text, helper text, and tag labels use dir="auto" through the composed primitives.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Avatar
|
|
2
|
+
|
|
3
|
+
Avatar represents people, accounts, teams, and system actors. It supports images, initials, icon fallback, circular or rounded forms, status dots, action overlays, stacked groups, group counts, size scale, and RTL-safe overlap.
|
|
4
|
+
|
|
5
|
+
## API
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
<Avatar name="Ahmed Galal" src="/avatars/avatar-01.jpg" status="available" />
|
|
9
|
+
|
|
10
|
+
<AvatarGroup>
|
|
11
|
+
<Avatar name="Nora" />
|
|
12
|
+
<Avatar name="Omar" />
|
|
13
|
+
<AvatarGroupCount>+4</AvatarGroupCount>
|
|
14
|
+
</AvatarGroup>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
| Prop | Values |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `size` | `2xs`, `xs`, `sm`, `md`, `lg`, `xl`, `2xl`, `3xl`, `4xl` |
|
|
20
|
+
| `form` | `circular`, `rounded` |
|
|
21
|
+
| `status` | `offline`, `busy`, `blocked`, `available`, `away` |
|
|
22
|
+
| `action` | `custom`, `edit`, `verified`, `remove` |
|
|
23
|
+
|
|
24
|
+
## Token Contract
|
|
25
|
+
|
|
26
|
+
Avatar consumes Banhaten radius, sizing, border, shadow, status, background, and content tokens. Status and action markers should stay token-bound so themes and dark mode remain consistent.
|
|
27
|
+
|
|
28
|
+
## RTL
|
|
29
|
+
|
|
30
|
+
Avatar groups use logical negative margin so overlap reverses naturally in RTL. Status and action affordances use logical end placement.
|
|
31
|
+
|
|
32
|
+
## Accessibility
|
|
33
|
+
|
|
34
|
+
Use `name` or accessible image alt text for user avatars. Decorative grouped avatars can be hidden from assistive tech when the surrounding row already names the people.
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npx banhaten add avatar
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Examples
|
|
43
|
+
|
|
44
|
+
Primary registry example: `examples/avatar-demo.tsx`.
|
|
45
|
+
|
|
46
|
+
Open the live component page or run `npx banhaten docs avatar` to inspect source files, install command, and examples.
|
|
47
|
+
|
|
48
|
+
## RTL Rules
|
|
49
|
+
|
|
50
|
+
- `inheritsDirection`: true
|
|
51
|
+
- `groupOverlap`: Uses logical -ms spacing so overlap reverses naturally in RTL.
|
|
52
|
+
- `badgePlacement`: Status dots use logical end/bottom positioning; avatar actions use logical end/top positioning.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Badge
|
|
2
|
+
|
|
3
|
+
Badge is a compact status, count, classification, or metadata primitive. It supports light, outline, and solid styles; semantic color families; dot, flag, leading icon, trailing icon, numeric, and split-action compositions; and RTL-safe layout.
|
|
4
|
+
|
|
5
|
+
## API
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
<Badge color="green">Active</Badge>
|
|
9
|
+
<Badge color="blue" type="dot">New</Badge>
|
|
10
|
+
<Badge color="neutral" type="trailing-icon" splitAction>
|
|
11
|
+
Filter
|
|
12
|
+
</Badge>
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
| Prop | Values | Default |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| `style` | `light`, `outline`, `solid` | `light` |
|
|
18
|
+
| `color` | `neutral`, `blue`, `green`, `amber`, `danger`, `purple`, `fuchsia`, `rose`, `sky`, `golden` | `neutral` |
|
|
19
|
+
| `type` | `default`, `leading-icon`, `trailing-icon`, `dot`, `flag` | `default` |
|
|
20
|
+
| `size` | `sm`, `lg` | `sm` |
|
|
21
|
+
| `splitAction` | `boolean` | `false` |
|
|
22
|
+
|
|
23
|
+
## Token Contract
|
|
24
|
+
|
|
25
|
+
Badge uses semantic content, background, border, radius, typography, icon, opacity, and focus tokens. Provider or brand colors should be added through semantic aliases, not raw literals.
|
|
26
|
+
|
|
27
|
+
## RTL
|
|
28
|
+
|
|
29
|
+
Use `data-icon="inline-start"` or `data-icon="inline-end"` on icons. Directional arrows should also set `data-rtl-flip="true"`.
|
|
30
|
+
|
|
31
|
+
## Accessibility
|
|
32
|
+
|
|
33
|
+
Badges are usually descriptive text. Do not use color alone for critical status; include a readable label such as `Failed`, `Warning`, or `Active`.
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx banhaten add badge
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Examples
|
|
42
|
+
|
|
43
|
+
Primary registry example: `examples/badge-demo.tsx`.
|
|
44
|
+
|
|
45
|
+
Open the live component page or run `npx banhaten docs badge` to inspect source files, install command, and examples.
|
|
46
|
+
|
|
47
|
+
## RTL Rules
|
|
48
|
+
|
|
49
|
+
- `inheritsDirection`: true
|
|
50
|
+
- `iconPlacement`: Set type="leading-icon" or type="trailing-icon" and use data-icon="inline-start" or data-icon="inline-end". Add splitAction to give a trailing icon its own token-sized compartment.
|
|
51
|
+
- `directionalIconFlip`: Use data-rtl-flip="true" on arrows that should mirror.
|
|
52
|
+
- `textDirection`: Uses dir="auto" by default for short Arabic and English labels.
|
|
53
|
+
- `legacyVariants`: The previous variant prop is still accepted as a compatibility shim.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
# Banner
|
|
2
|
+
|
|
3
|
+
`Banner` presents short product announcements, notices, or lightweight calls to action.
|
|
4
|
+
|
|
5
|
+
Figma reference: `Design system 3.0 Copy / Banner`, node `237:39513`.
|
|
6
|
+
|
|
7
|
+
## Variants
|
|
8
|
+
|
|
9
|
+
The implementation covers the Banner matrix from Figma:
|
|
10
|
+
|
|
11
|
+
| Prop | Values |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| `type` | `slim`, `single-action-inline`, `single-action`, `input` |
|
|
14
|
+
| `size` | `floating`, `full-width` |
|
|
15
|
+
| `content` | `title`, `title-description` |
|
|
16
|
+
| `color` | `brand`, `grey`, `brand-light` |
|
|
17
|
+
| `dir` | `ltr`, `rtl` |
|
|
18
|
+
|
|
19
|
+
## API
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
<Banner
|
|
23
|
+
type="single-action"
|
|
24
|
+
size="floating"
|
|
25
|
+
content="title"
|
|
26
|
+
color="brand"
|
|
27
|
+
dir="ltr"
|
|
28
|
+
/>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
| Prop | Default |
|
|
32
|
+
| --- | --- |
|
|
33
|
+
| `title` | localized demo title |
|
|
34
|
+
| `description` | localized demo description |
|
|
35
|
+
| `linkLabel` | `Link button` |
|
|
36
|
+
| `actionLabel` | `Button` |
|
|
37
|
+
| `inputPlaceholder` | `Placeholder` |
|
|
38
|
+
| `showIcon` | `true` |
|
|
39
|
+
| `showInlineAction` | `true` |
|
|
40
|
+
| `onAction` | none |
|
|
41
|
+
| `onClose` | none |
|
|
42
|
+
|
|
43
|
+
## Pixel Rules
|
|
44
|
+
|
|
45
|
+
- Root padding is `12px 16px`.
|
|
46
|
+
- Slim title rows are `48px`; slim title-description rows are `52px`.
|
|
47
|
+
- Single-action, inline-action, and input rows are `60px`.
|
|
48
|
+
- Floating rows use `10px` radius; full-width rows have square edges.
|
|
49
|
+
- Leading icon is `20px`; close icon is `16px`.
|
|
50
|
+
- Action controls and text inputs are `36px` tall with `8px` radius.
|
|
51
|
+
- LTR body text uses `15px / 24px`. RTL title-only body text uses `12px / 16px`.
|
|
52
|
+
- Title-description content uses a semibold title, a `17px / 28px` separator dot, and regular description text.
|
|
53
|
+
|
|
54
|
+
## Token Contract
|
|
55
|
+
|
|
56
|
+
The component consumes Banhaten semantic tokens and component aliases. Do not hard-code Figma fallback literals in component source; promote any Figma value into `registry/styles/globals.css` as a `--bh-*` token or alias first.
|
|
57
|
+
|
|
58
|
+
- Backgrounds: `--bh-bg-brand-default`, `--bh-bg-brand-soft`, `--bh-bg-muted`, `--bh-bg-always-white`
|
|
59
|
+
- Content: `--bh-content-default`, `--bh-content-inverse`, `--bh-content-link`, `--bh-content-muted`, `--bh-content-subtle`
|
|
60
|
+
- Borders: `--bh-border-subtle`, `--bh-border-input`
|
|
61
|
+
- Shape: `--bh-control-default`, `--bh-radius-lg-8`, `--bh-radius-xl-10`
|
|
62
|
+
- Space: `--bh-space-xs-4`, `--bh-space-md-8`, `--bh-space-lg-10`, `--bh-space-xl-12`, `--bh-space-3xl-16`
|
|
63
|
+
|
|
64
|
+
## Accessibility
|
|
65
|
+
|
|
66
|
+
- The banner root exposes an `aria-label`.
|
|
67
|
+
- Link, action, and close affordances are real buttons.
|
|
68
|
+
- The input variant uses a real text input with an `aria-label`.
|
|
69
|
+
- RTL is controlled through `dir="rtl"` so icon, text, action, input, and close placement mirror logically.
|
|
70
|
+
|
|
71
|
+
## Install
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
npx banhaten add banner
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Examples
|
|
78
|
+
|
|
79
|
+
Primary registry example: `examples/expanded/banner-demo.tsx`.
|
|
80
|
+
|
|
81
|
+
Open the live component page or run `npx banhaten docs banner` to inspect source files, install command, and examples.
|
|
82
|
+
|
|
83
|
+
## RTL Rules
|
|
84
|
+
|
|
85
|
+
This component has no special RTL contract beyond inherited document direction and logical spacing.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Breadcrumbs
|
|
2
|
+
|
|
3
|
+
Breadcrumbs show a user's location in a hierarchy and provide a quick path back to parent pages. Use `Breadcrumbs` for page-level navigation, not for step progress, tabs, or filters.
|
|
4
|
+
|
|
5
|
+
Figma reference: `Breadcrumbs`, node `238:7987`.
|
|
6
|
+
|
|
7
|
+
## Variants
|
|
8
|
+
|
|
9
|
+
The Figma component defines these variants:
|
|
10
|
+
|
|
11
|
+
| Type | Style | Separator type | Direction |
|
|
12
|
+
| --- | --- | --- | --- |
|
|
13
|
+
| `Default` | `Default` | `Slash` | LTR and RTL |
|
|
14
|
+
| `Default` | `Default` | `Chevron` | LTR and RTL |
|
|
15
|
+
| `Default` | `Raised` | `Slash` | LTR and RTL |
|
|
16
|
+
| `Default` | `Raised` | `Chevron` | LTR and RTL |
|
|
17
|
+
| `Only Icon` | `Default` | `Slash` | LTR and RTL |
|
|
18
|
+
| `Only Icon` | `Default` | `Chevron` | LTR and RTL |
|
|
19
|
+
| `Only Icon` | `Raised` | `Slash` | LTR and RTL |
|
|
20
|
+
| `Only Icon` | `Raised` | `Chevron` | LTR and RTL |
|
|
21
|
+
|
|
22
|
+
The Figma source supports up to six visible breadcrumb items. Code should model this as an `items` collection instead of positional booleans such as `showBreadcrumb01`.
|
|
23
|
+
|
|
24
|
+
## API
|
|
25
|
+
|
|
26
|
+
Use semantic names in code even if the Figma variant labels are title-cased.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
type BreadcrumbSeparator = "slash" | "chevron";
|
|
30
|
+
type BreadcrumbStyle = "default" | "raised";
|
|
31
|
+
|
|
32
|
+
type BreadcrumbItem = {
|
|
33
|
+
label: string;
|
|
34
|
+
href?: string;
|
|
35
|
+
icon?: React.ReactNode;
|
|
36
|
+
current?: boolean;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
type BreadcrumbsProps = {
|
|
40
|
+
items: BreadcrumbItem[];
|
|
41
|
+
separator?: BreadcrumbSeparator;
|
|
42
|
+
style?: BreadcrumbStyle;
|
|
43
|
+
iconOnly?: boolean;
|
|
44
|
+
dir?: "ltr" | "rtl" | "auto";
|
|
45
|
+
maxItems?: number;
|
|
46
|
+
"aria-label"?: string;
|
|
47
|
+
};
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`items` should be ordered from root to current page in logical reading order. RTL rendering should mirror the visual order through layout direction, not by reversing the source data.
|
|
51
|
+
|
|
52
|
+
## Layout
|
|
53
|
+
|
|
54
|
+
- The root is a horizontal flex row with centered alignment.
|
|
55
|
+
- The default style has no container background and uses a compact inline gap.
|
|
56
|
+
- The raised style adds a surface fill, a 1px border, 12px padding, and an 8px radius in the Figma source.
|
|
57
|
+
- Text items use `Body/body-md (base)/medium` with a 15px size and 24px line height.
|
|
58
|
+
- Item icons are 20px square.
|
|
59
|
+
- Slash and chevron separators are 16px square and should be decorative.
|
|
60
|
+
- LTR chevrons point right; RTL chevrons point left.
|
|
61
|
+
- The icon-only type keeps the same item and separator rhythm but hides visible labels.
|
|
62
|
+
- Do not allow wrapping inside individual breadcrumb labels unless the component has a deliberate collapsed or overflow mode.
|
|
63
|
+
|
|
64
|
+
## Tokens
|
|
65
|
+
|
|
66
|
+
Breadcrumbs should consume existing semantic tokens:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
export const breadcrumbsTokens = {
|
|
70
|
+
itemColor: "content.subtle",
|
|
71
|
+
currentItemColor: "content.default",
|
|
72
|
+
iconColor: "content.subtle",
|
|
73
|
+
separatorColor: "content.subtle",
|
|
74
|
+
raisedBackground: "background.card",
|
|
75
|
+
raisedBorder: "border.subtle",
|
|
76
|
+
raisedRadius: "shape.control",
|
|
77
|
+
inlineGap: "space.xs-4",
|
|
78
|
+
raisedGap: "space.md-8",
|
|
79
|
+
raisedPadding: "space.xl-12",
|
|
80
|
+
};
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Do not hard-code Figma fallback values in component code. The current Figma fallbacks include `content/subtle` as `#4e596e`, `bg/raised` as white, `border/subtle` as `rgba(55, 83, 122, 0.13)`, and `radius/lg-8` as 8px. Implementations should resolve those through semantic tokens.
|
|
84
|
+
|
|
85
|
+
If the design system later adds a dedicated `background.raised` token, the raised style can map to it. Until then, use the closest raised surface token such as `background.card`.
|
|
86
|
+
|
|
87
|
+
## Accessibility
|
|
88
|
+
|
|
89
|
+
- Render the component as navigation, usually `<nav aria-label="Breadcrumb">`.
|
|
90
|
+
- Use an ordered list so the hierarchy is exposed to assistive technology.
|
|
91
|
+
- Render linked ancestors as anchors.
|
|
92
|
+
- Mark the current page with `aria-current="page"` and do not require it to be a link.
|
|
93
|
+
- Hide separators from assistive technology with `aria-hidden="true"`.
|
|
94
|
+
- Icon-only breadcrumbs must provide an accessible label for every item, even when visible text is hidden.
|
|
95
|
+
- Preserve logical item order for screen readers in RTL contexts.
|
|
96
|
+
- Provide keyboard focus treatment through the link or action primitive, not on decorative separators.
|
|
97
|
+
|
|
98
|
+
## Usage
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
<Breadcrumbs
|
|
102
|
+
items={[
|
|
103
|
+
{ label: "Home", href: "/", icon: <HomeIcon /> },
|
|
104
|
+
{ label: "Products", href: "/products" },
|
|
105
|
+
{ label: "Analytics", current: true },
|
|
106
|
+
]}
|
|
107
|
+
/>
|
|
108
|
+
|
|
109
|
+
<Breadcrumbs
|
|
110
|
+
separator="chevron"
|
|
111
|
+
style="raised"
|
|
112
|
+
items={[
|
|
113
|
+
{ label: "Home", href: "/", icon: <HomeIcon /> },
|
|
114
|
+
{ label: "Reports", href: "/reports" },
|
|
115
|
+
{ label: "Monthly", current: true },
|
|
116
|
+
]}
|
|
117
|
+
/>
|
|
118
|
+
|
|
119
|
+
<Breadcrumbs
|
|
120
|
+
iconOnly
|
|
121
|
+
aria-label="Breadcrumb"
|
|
122
|
+
items={[
|
|
123
|
+
{ label: "Home", href: "/", icon: <HomeIcon /> },
|
|
124
|
+
{ label: "Settings", href: "/settings", icon: <SettingsIcon /> },
|
|
125
|
+
{ label: "Profile", current: true, icon: <UserIcon /> },
|
|
126
|
+
]}
|
|
127
|
+
/>
|
|
128
|
+
|
|
129
|
+
<Breadcrumbs
|
|
130
|
+
dir="rtl"
|
|
131
|
+
separator="chevron"
|
|
132
|
+
items={[
|
|
133
|
+
{ label: "Home", href: "/", icon: <HomeIcon /> },
|
|
134
|
+
{ label: "Account", href: "/account" },
|
|
135
|
+
{ label: "Security", current: true },
|
|
136
|
+
]}
|
|
137
|
+
/>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Preset Impact
|
|
141
|
+
|
|
142
|
+
- `default`: inline breadcrumbs remain quiet, and raised breadcrumbs use a modest surface radius with subtle border separation.
|
|
143
|
+
- `rounded`: raised breadcrumbs can use the softer control radius and slightly more relaxed spacing.
|
|
144
|
+
- `sharp`: raised breadcrumbs should use square or near-square corners and tighter horizontal rhythm.
|
|
145
|
+
|
|
146
|
+
## Implementation Notes
|
|
147
|
+
|
|
148
|
+
- Use the design system's icon primitive for home and chevron icons. The Figma source uses Remix Icon `home-5-line`, `arrow-right-s-line`, and `arrow-left-s-line`.
|
|
149
|
+
- Generate separators between items instead of requiring callers to include separator items.
|
|
150
|
+
- Keep overflow behavior explicit. If the trail is too long, collapse middle items behind an overflow control instead of silently hiding the current page.
|
|
151
|
+
- Prefer `dir` or logical CSS properties for RTL behavior rather than maintaining separate RTL item arrays.
|
|
152
|
+
- The raised style is a navigation surface, not a card. Keep elevation at `elevation.none` unless a consuming product places it inside an overlay.
|
|
153
|
+
|
|
154
|
+
## Install
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
npx banhaten add breadcrumbs
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Examples
|
|
161
|
+
|
|
162
|
+
Primary registry example: `examples/expanded/breadcrumbs-demo.tsx`.
|
|
163
|
+
|
|
164
|
+
Open the live component page or run `npx banhaten docs breadcrumbs` to inspect source files, install command, and examples.
|
|
165
|
+
|
|
166
|
+
## Token Contract
|
|
167
|
+
|
|
168
|
+
Component styles must resolve through Banhaten semantic tokens, component aliases, or documented exception-ledger values.
|
|
169
|
+
Do not add raw colors, pixel values, opacity utilities, z-index values, durations, or shadow literals directly to component source.
|
|
170
|
+
Covered source files: `components/expanded/breadcrumbs.css`, `components/expanded/Breadcrumbs.tsx`.
|
|
171
|
+
|
|
172
|
+
## RTL Rules
|
|
173
|
+
|
|
174
|
+
This component has no special RTL contract beyond inherited document direction and logical spacing.
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# Button Group
|
|
2
|
+
|
|
3
|
+
Button Group is a connected set of related button actions. It supports text buttons and icon-only buttons, three sizes, inherited LTR/RTL direction, logical dividers, and tokenized interaction states.
|
|
4
|
+
|
|
5
|
+
The implementation follows the Figma component at `Design system 3.0 Copy / Button Group Item 1.2` (`390:12399`).
|
|
6
|
+
|
|
7
|
+
## API
|
|
8
|
+
|
|
9
|
+
Use `ButtonGroup` as the connected container and `ButtonGroupItem` for each action.
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
<ButtonGroup aria-label="View options" size="md">
|
|
13
|
+
<ButtonGroupItem>
|
|
14
|
+
<PlusIcon data-icon="inline-start" />
|
|
15
|
+
Button
|
|
16
|
+
<PlusIcon data-icon="inline-end" />
|
|
17
|
+
</ButtonGroupItem>
|
|
18
|
+
<ButtonGroupItem aria-pressed>
|
|
19
|
+
<PlusIcon data-icon="inline-start" />
|
|
20
|
+
Active
|
|
21
|
+
<PlusIcon data-icon="inline-end" />
|
|
22
|
+
</ButtonGroupItem>
|
|
23
|
+
</ButtonGroup>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Variants
|
|
27
|
+
|
|
28
|
+
| Prop | Values |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| `size` | `md`, `sm`, `xs` |
|
|
31
|
+
| `mode` | `default`, `iconOnly` |
|
|
32
|
+
| `ButtonGroupItem aria-pressed` | `true`, `false` |
|
|
33
|
+
| `ButtonGroupItem disabled` | `boolean` |
|
|
34
|
+
|
|
35
|
+
Interaction styling is applied through native CSS pseudo states: `:hover`, `:active`, `:focus-visible`, `:disabled`, and `aria-pressed="true"`.
|
|
36
|
+
|
|
37
|
+
## States
|
|
38
|
+
|
|
39
|
+
| State | Background | Content |
|
|
40
|
+
| --- | --- | --- |
|
|
41
|
+
| Default | `--bh-button-group-item-bg` | `--bh-button-group-content-default` |
|
|
42
|
+
| Hover | `--bh-button-group-item-hover-bg` | `--bh-button-group-content-default` |
|
|
43
|
+
| Pressed | `--bh-button-group-item-pressed-bg` | `--bh-button-group-content-default` |
|
|
44
|
+
| Active | `--bh-button-group-item-active-bg` | `--bh-button-group-content-active` |
|
|
45
|
+
| Disabled | `--bh-button-group-item-disabled-bg` | `--bh-button-group-content-disabled` |
|
|
46
|
+
|
|
47
|
+
## Dimensions
|
|
48
|
+
|
|
49
|
+
| Size | Height | LTR text item | RTL text item | Icon-only item |
|
|
50
|
+
| --- | ---: | ---: | ---: | ---: |
|
|
51
|
+
| `md` | 40px | 128px | 124px | 40px |
|
|
52
|
+
| `sm` | 36px | 120px | 116px | 36px |
|
|
53
|
+
| `xs` | 32px | 112px | 108px | 32px |
|
|
54
|
+
|
|
55
|
+
Text buttons use the design-system button typography tokens. Icon-only buttons require an accessible label.
|
|
56
|
+
|
|
57
|
+
## Install
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx banhaten add button-group
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Examples
|
|
64
|
+
|
|
65
|
+
Primary registry example: `examples/button-group-demo.tsx`.
|
|
66
|
+
|
|
67
|
+
Open the live component page or run `npx banhaten docs button-group` to inspect source files, install command, and examples.
|
|
68
|
+
|
|
69
|
+
## Token Contract
|
|
70
|
+
|
|
71
|
+
Component styles must resolve through Banhaten semantic tokens, component aliases, or documented exception-ledger values.
|
|
72
|
+
Do not add raw colors, pixel values, opacity utilities, z-index values, durations, or shadow literals directly to component source.
|
|
73
|
+
Covered source files: `components/button-group.tsx`.
|
|
74
|
+
|
|
75
|
+
## RTL Rules
|
|
76
|
+
|
|
77
|
+
- `inheritsDirection`: true
|
|
78
|
+
- `itemSizing`: LTR and RTL default items keep their fixed Figma matrix widths. Icon-only groups keep the same square dimensions.
|
|
79
|
+
- `spacing`: Uses logical dividers and inherited flex direction so item order, icon order, padding, and separators follow LTR or RTL.
|
|
80
|
+
|
|
81
|
+
## Accessibility
|
|
82
|
+
|
|
83
|
+
This component relies on `@radix-ui/react-slot` for its base accessibility behavior. Keep required labels, titles, descriptions, and focusable trigger/content relationships intact when composing it.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Button
|
|
2
|
+
|
|
3
|
+
Button is the primary action primitive for forms, workflows, navigation actions, and destructive confirmations. It supports semantic variants, text and icon sizes, loading composition, link composition through `asChild`, and RTL-safe icon behavior.
|
|
4
|
+
|
|
5
|
+
## API
|
|
6
|
+
|
|
7
|
+
```tsx
|
|
8
|
+
<Button variant="default" size="default">
|
|
9
|
+
Save changes
|
|
10
|
+
</Button>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
| Prop | Values | Default |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| `variant` | `default`, `secondary`, `soft`, `outline`, `ghost`, `ghost-primary`, `danger`, `soft-danger`, `white` | `default` |
|
|
16
|
+
| `size` | `xs`, `sm`, `default`, `lg`, `xl`, `icon-xs`, `icon-sm`, `icon`, `icon-lg`, `icon-xl` | `default` |
|
|
17
|
+
| `asChild` | `boolean` | `false` |
|
|
18
|
+
| `disabled` | `boolean` | `false` |
|
|
19
|
+
| `aria-busy` | `boolean` | none |
|
|
20
|
+
|
|
21
|
+
## Examples
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
<Button>
|
|
25
|
+
<PlusIcon data-icon="inline-start" />
|
|
26
|
+
New item
|
|
27
|
+
</Button>
|
|
28
|
+
|
|
29
|
+
<Button variant="outline">
|
|
30
|
+
Continue
|
|
31
|
+
<ArrowRightIcon data-icon="inline-end" data-rtl-flip="true" />
|
|
32
|
+
</Button>
|
|
33
|
+
|
|
34
|
+
<Button disabled aria-busy="true">
|
|
35
|
+
<Spinner data-icon="inline-start" />
|
|
36
|
+
Loading
|
|
37
|
+
</Button>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
<div dir="rtl">
|
|
42
|
+
<Button>إرسال</Button>
|
|
43
|
+
<Button variant="outline">
|
|
44
|
+
متابعة
|
|
45
|
+
<ArrowRightIcon data-icon="inline-end" data-rtl-flip="true" />
|
|
46
|
+
</Button>
|
|
47
|
+
</div>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Token Contract
|
|
51
|
+
|
|
52
|
+
Button consumes semantic interaction, content, border, radius, typography, spacing, opacity, and shadow tokens. Component source should not hard-code Figma color, spacing, radius, or shadow literals.
|
|
53
|
+
|
|
54
|
+
- Typography: `--bh-text-button-font-size`, `--bh-text-button-line-height`, `--bh-text-button-font-weight`, `--bh-text-button-letter-spacing`
|
|
55
|
+
- Shape: `--bh-control-default`
|
|
56
|
+
- Heights and padding: `--bh-button-*-height`, `--bh-button-*-padding-x`, `--bh-button-*-padding-y`
|
|
57
|
+
- Icon rhythm: `--bh-button-icon-size`, `--bh-button-icon-offset`, `--bh-button-label-padding-x`
|
|
58
|
+
- Effects: `--shadow-button-raised`, `--shadow-button-secondary`, `--shadow-button-soft`, `--shadow-button-focus`, `--shadow-button-danger-focus`
|
|
59
|
+
|
|
60
|
+
## RTL Rules
|
|
61
|
+
|
|
62
|
+
- Button inherits `dir` from the nearest parent.
|
|
63
|
+
- Text labels render with `dir="auto"` so Arabic and English labels resolve naturally.
|
|
64
|
+
- Use `data-icon="inline-start"` and `data-icon="inline-end"` for optical icon offsets.
|
|
65
|
+
- Use `data-rtl-flip="true"` only for directional icons that should mirror, such as arrows and chevrons.
|
|
66
|
+
|
|
67
|
+
## Accessibility
|
|
68
|
+
|
|
69
|
+
- Use native `type`, `disabled`, and `aria-busy` attributes for behavior.
|
|
70
|
+
- Icon-only buttons must have an accessible name through `aria-label`.
|
|
71
|
+
- Use `asChild` for anchors or router links instead of nesting interactive elements.
|
|
72
|
+
|
|
73
|
+
## Install
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
npx banhaten add button
|
|
77
|
+
```
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Card
|
|
2
|
+
|
|
3
|
+
Card is a token-built surface primitive for product summaries, media tiles, and action panels. It supports vertical and horizontal layouts, leading and trailing image treatments, full-image cards, desktop/mobile spacing, footer actions, and RTL-safe text.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx banhaten add card
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Anatomy
|
|
12
|
+
|
|
13
|
+
- `Card`: root surface with title, subtitle, description, media, and optional footer composition.
|
|
14
|
+
- `CardMedia`: image/media slot with leading, trailing, or full-image treatment.
|
|
15
|
+
- `CardFooter`: supporting metadata or action area.
|
|
16
|
+
- `CardActions`: Button-composed primary and secondary actions.
|
|
17
|
+
|
|
18
|
+
## Example
|
|
19
|
+
|
|
20
|
+
```tsx
|
|
21
|
+
import { Card } from "@/components/ui/card"
|
|
22
|
+
|
|
23
|
+
export function Example() {
|
|
24
|
+
return (
|
|
25
|
+
<Card
|
|
26
|
+
title="Project activity"
|
|
27
|
+
subtitle="Updated 2 minutes ago"
|
|
28
|
+
description="A compact summary of the latest workspace changes."
|
|
29
|
+
orientation="horizontal"
|
|
30
|
+
type="leading-image"
|
|
31
|
+
/>
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Variants
|
|
37
|
+
|
|
38
|
+
| Prop | Values |
|
|
39
|
+
| --- | --- |
|
|
40
|
+
| `orientation` | `vertical`, `horizontal` |
|
|
41
|
+
| `type` | `leading-image`, `trailing-image`, `full-image` |
|
|
42
|
+
| `breakpoint` | `desktop`, `mobile` |
|
|
43
|
+
| `dir` | inherited, `ltr`, `rtl` |
|
|
44
|
+
|
|
45
|
+
## RTL
|
|
46
|
+
|
|
47
|
+
Card uses logical spacing, inherited direction, and `dir="auto"` copy wrappers so title, subtitle, description, footer actions, and menu affordances mirror naturally.
|
|
48
|
+
|
|
49
|
+
## API
|
|
50
|
+
|
|
51
|
+
Public exports: `Card`, `CardMedia`, `CardFooter`, `CardActions`.
|
|
52
|
+
|
|
53
|
+
| Contract | Values |
|
|
54
|
+
| --- | --- |
|
|
55
|
+
| `types` | `leading-image`, `trailing-image`, `full-image` |
|
|
56
|
+
| `orientations` | `vertical`, `horizontal` |
|
|
57
|
+
|
|
58
|
+
## Examples
|
|
59
|
+
|
|
60
|
+
Primary registry example: `examples/card-demo.tsx`.
|
|
61
|
+
|
|
62
|
+
Open the live component page or run `npx banhaten docs card` to inspect source files, install command, and examples.
|
|
63
|
+
|
|
64
|
+
## Token Contract
|
|
65
|
+
|
|
66
|
+
Component styles must resolve through Banhaten semantic tokens, component aliases, or documented exception-ledger values.
|
|
67
|
+
Do not add raw colors, pixel values, opacity utilities, z-index values, durations, or shadow literals directly to component source.
|
|
68
|
+
Covered source files: `components/card.tsx`, `assets/images/art-01.jpg`.
|
|
69
|
+
|
|
70
|
+
## RTL Rules
|
|
71
|
+
|
|
72
|
+
- `inheritsDirection`: true
|
|
73
|
+
- `spacing`: Uses logical direction, text-start behavior, and dir="auto" copy so title, subtitle, description, footer actions, and menu affordance mirror naturally.
|
|
74
|
+
- `actions`: The default footer composes the existing Button primitive and keeps action order logical in LTR and RTL.
|
|
75
|
+
|
|
76
|
+
## Accessibility
|
|
77
|
+
|
|
78
|
+
Keep native semantics, accessible names, keyboard reachability, focus-visible treatment, and status/error announcements intact when composing this component.
|