@cascivo/mcp 0.2.0 → 0.3.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/LICENSE +1 -1
- package/README.md +53 -23
- package/dist/context/accordion.md +93 -0
- package/dist/context/action-sheet.md +117 -0
- package/dist/context/alert-dialog.md +122 -0
- package/dist/context/alert.md +110 -0
- package/dist/context/app-shell.md +98 -0
- package/dist/context/aspect-ratio.md +92 -0
- package/dist/context/avatar-group.md +111 -0
- package/dist/context/avatar.md +100 -0
- package/dist/context/badge.md +119 -0
- package/dist/context/block/console-app.md +66 -0
- package/dist/context/block/dashboard-charts.md +61 -0
- package/dist/context/block/empty-dashboard.md +60 -0
- package/dist/context/block/login-page.md +60 -0
- package/dist/context/block/notification-center.md +61 -0
- package/dist/context/block/page-with-breadcrumb.md +54 -0
- package/dist/context/block/settings-form-page.md +60 -0
- package/dist/context/block/sidebar-app.md +55 -0
- package/dist/context/block/stats-cards.md +61 -0
- package/dist/context/block/users-table-page.md +61 -0
- package/dist/context/blockquote.md +95 -0
- package/dist/context/bottom-sheet.md +112 -0
- package/dist/context/breadcrumb.md +106 -0
- package/dist/context/button-group.md +100 -0
- package/dist/context/button.md +117 -0
- package/dist/context/calendar.md +118 -0
- package/dist/context/card.md +90 -0
- package/dist/context/carousel.md +101 -0
- package/dist/context/chart/area-chart.md +99 -0
- package/dist/context/chart/bar-chart.md +114 -0
- package/dist/context/chart/boxplot.md +82 -0
- package/dist/context/chart/bubble-chart.md +80 -0
- package/dist/context/chart/bullet.md +75 -0
- package/dist/context/chart/calendar.md +79 -0
- package/dist/context/chart/candlestick.md +104 -0
- package/dist/context/chart/combo-chart.md +78 -0
- package/dist/context/chart/funnel.md +87 -0
- package/dist/context/chart/gauge.md +87 -0
- package/dist/context/chart/heatmap.md +77 -0
- package/dist/context/chart/histogram.md +74 -0
- package/dist/context/chart/kpi.md +70 -0
- package/dist/context/chart/line-chart.md +113 -0
- package/dist/context/chart/meter.md +71 -0
- package/dist/context/chart/pie-chart.md +126 -0
- package/dist/context/chart/polar.md +92 -0
- package/dist/context/chart/radar.md +81 -0
- package/dist/context/chart/radial-bar.md +96 -0
- package/dist/context/chart/sankey.md +89 -0
- package/dist/context/chart/scatter-chart.md +90 -0
- package/dist/context/chart/sparkline.md +69 -0
- package/dist/context/chart/stream.md +88 -0
- package/dist/context/chart/sunburst.md +93 -0
- package/dist/context/chart/treemap.md +84 -0
- package/dist/context/chat-bubble.md +116 -0
- package/dist/context/checkbox-card.md +104 -0
- package/dist/context/checkbox.md +104 -0
- package/dist/context/code-snippet.md +118 -0
- package/dist/context/code.md +103 -0
- package/dist/context/collapsible.md +104 -0
- package/dist/context/color-picker.md +101 -0
- package/dist/context/combobox.md +125 -0
- package/dist/context/command-menu.md +121 -0
- package/dist/context/comparison.md +117 -0
- package/dist/context/contained-list.md +103 -0
- package/dist/context/context-menu.md +103 -0
- package/dist/context/copy-button.md +106 -0
- package/dist/context/data-list.md +99 -0
- package/dist/context/data-table.md +149 -0
- package/dist/context/date-picker.md +116 -0
- package/dist/context/date-range-picker.md +113 -0
- package/dist/context/dock.md +117 -0
- package/dist/context/drawer.md +111 -0
- package/dist/context/dropdown.md +96 -0
- package/dist/context/editable.md +101 -0
- package/dist/context/editor/code-editor.md +146 -0
- package/dist/context/editor/highlight.md +74 -0
- package/dist/context/empty-state.md +101 -0
- package/dist/context/fab.md +128 -0
- package/dist/context/field.md +118 -0
- package/dist/context/file-uploader.md +121 -0
- package/dist/context/filter.md +129 -0
- package/dist/context/flow/flow-background.md +103 -0
- package/dist/context/flow/flow-canvas.md +82 -0
- package/dist/context/flow/flow-controls.md +84 -0
- package/dist/context/flow/flow-edge.md +128 -0
- package/dist/context/flow/flow-handle.md +83 -0
- package/dist/context/flow/flow-minimap.md +89 -0
- package/dist/context/flow/flow-node.md +97 -0
- package/dist/context/flow/flow-panel.md +75 -0
- package/dist/context/flow/flow-story.md +145 -0
- package/dist/context/flow/flow.md +139 -0
- package/dist/context/form.md +104 -0
- package/dist/context/header-panel.md +96 -0
- package/dist/context/header.md +104 -0
- package/dist/context/heading.md +107 -0
- package/dist/context/hover-card.md +108 -0
- package/dist/context/icon-button.md +115 -0
- package/dist/context/image.md +115 -0
- package/dist/context/indicator.md +95 -0
- package/dist/context/inline-loading.md +101 -0
- package/dist/context/input-group.md +122 -0
- package/dist/context/input.md +101 -0
- package/dist/context/item.md +109 -0
- package/dist/context/join.md +97 -0
- package/dist/context/kbd.md +100 -0
- package/dist/context/label.md +117 -0
- package/dist/context/layout/app-shell.md +85 -0
- package/dist/context/layout/auth-layout.md +74 -0
- package/dist/context/layout/auto-grid.md +69 -0
- package/dist/context/layout/center.md +67 -0
- package/dist/context/layout/columns.md +70 -0
- package/dist/context/layout/dashboard-layout.md +68 -0
- package/dist/context/layout/grid.md +70 -0
- package/dist/context/layout/masonry.md +70 -0
- package/dist/context/layout/page-header.md +75 -0
- package/dist/context/layout/section.md +69 -0
- package/dist/context/layout/settings-layout.md +68 -0
- package/dist/context/layout/spacer.md +64 -0
- package/dist/context/layout/split-view.md +71 -0
- package/dist/context/layout/stack.md +93 -0
- package/dist/context/link.md +112 -0
- package/dist/context/list.md +109 -0
- package/dist/context/log-viewer.md +124 -0
- package/dist/context/menu-button.md +137 -0
- package/dist/context/menu.md +108 -0
- package/dist/context/menubar.md +92 -0
- package/dist/context/modal.md +96 -0
- package/dist/context/multi-select.md +104 -0
- package/dist/context/native-select.md +118 -0
- package/dist/context/navigation-menu.md +95 -0
- package/dist/context/notification.md +116 -0
- package/dist/context/number-input.md +117 -0
- package/dist/context/otp-input.md +98 -0
- package/dist/context/overflow-menu.md +107 -0
- package/dist/context/pagination.md +123 -0
- package/dist/context/password-input.md +100 -0
- package/dist/context/popover.md +108 -0
- package/dist/context/progress-bar.md +107 -0
- package/dist/context/progress-circle.md +101 -0
- package/dist/context/progress-indicator.md +105 -0
- package/dist/context/progress.md +109 -0
- package/dist/context/prose.md +110 -0
- package/dist/context/pull-to-refresh.md +101 -0
- package/dist/context/qr-code.md +101 -0
- package/dist/context/radial-progress.md +117 -0
- package/dist/context/radio-card.md +95 -0
- package/dist/context/radio.md +94 -0
- package/dist/context/rating-group.md +97 -0
- package/dist/context/relative-time.md +90 -0
- package/dist/context/resizable.md +102 -0
- package/dist/context/scroll-area.md +101 -0
- package/dist/context/search.md +113 -0
- package/dist/context/section/cta.md +83 -0
- package/dist/context/section/feature-grid.md +98 -0
- package/dist/context/section/hero.md +101 -0
- package/dist/context/section/media-masonry.md +77 -0
- package/dist/context/section/page-footer.md +101 -0
- package/dist/context/section/stats-band.md +81 -0
- package/dist/context/segmented-control.md +101 -0
- package/dist/context/select.md +101 -0
- package/dist/context/separator.md +88 -0
- package/dist/context/sheet.md +100 -0
- package/dist/context/shell-header.md +105 -0
- package/dist/context/side-nav.md +134 -0
- package/dist/context/skeleton.md +101 -0
- package/dist/context/skip-nav.md +103 -0
- package/dist/context/slider.md +98 -0
- package/dist/context/spinner.md +89 -0
- package/dist/context/stack.md +96 -0
- package/dist/context/stat.md +101 -0
- package/dist/context/status.md +105 -0
- package/dist/context/steps.md +124 -0
- package/dist/context/structured-list.md +107 -0
- package/dist/context/swap.md +100 -0
- package/dist/context/swipe-item.md +110 -0
- package/dist/context/switcher.md +97 -0
- package/dist/context/tabs.md +93 -0
- package/dist/context/tag.md +110 -0
- package/dist/context/tags-input.md +94 -0
- package/dist/context/text.md +111 -0
- package/dist/context/textarea.md +98 -0
- package/dist/context/tile.md +116 -0
- package/dist/context/time-picker.md +102 -0
- package/dist/context/timeline.md +93 -0
- package/dist/context/toast.md +91 -0
- package/dist/context/toc.md +110 -0
- package/dist/context/toggle-group.md +118 -0
- package/dist/context/toggle.md +103 -0
- package/dist/context/toggletip.md +119 -0
- package/dist/context/tooltip.md +92 -0
- package/dist/context/tree-view.md +107 -0
- package/dist/context/user.md +100 -0
- package/dist/context/visually-hidden.md +90 -0
- package/dist/context.json +22456 -0
- package/dist/index.d.mts +3 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +73 -32
- package/dist/index.mjs.map +1 -1
- package/dist/marketplace.json +70 -0
- package/dist/registry.json +2832 -358
- package/dist/tokens.catalog.json +2375 -0
- package/dist/tokens.variants.json +3291 -0
- package/package.json +4 -3
- package/readme.body.md +53 -23
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Swap
|
|
2
|
+
|
|
3
|
+
**Category:** inputs
|
|
4
|
+
**Description:** Animated toggle between two icon/content states with rotate or flip transition
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Theme toggles where an icon animates between two states (sun/moon)
|
|
9
|
+
- Favorite or bookmark toggles that flip between outlined and filled icons
|
|
10
|
+
- Any scenario where exactly two icons swap places with a transition
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
|
|
14
|
+
- Form toggles with a visible label — use Toggle
|
|
15
|
+
- Checkbox-style inputs that are part of a submitted form — use Checkbox
|
|
16
|
+
- When a text label must always be visible alongside the control
|
|
17
|
+
|
|
18
|
+
## Anti-patterns
|
|
19
|
+
|
|
20
|
+
### Swap is designed for icon transitions; for labeled on/off controls use Toggle
|
|
21
|
+
|
|
22
|
+
**Bad:** `<Swap on="Enable" off="Disable" /> (text content)`
|
|
23
|
+
**Good:** `<Toggle label="Enable notifications" />`
|
|
24
|
+
**Why:** Swap is designed for icon transitions; for labeled on/off controls use Toggle
|
|
25
|
+
|
|
26
|
+
## Related components
|
|
27
|
+
|
|
28
|
+
- **Toggle** (alternative): Use when a visible text label is required alongside the switch control
|
|
29
|
+
- **Checkbox** (alternative): Use for form selections that are submitted rather than applied immediately
|
|
30
|
+
|
|
31
|
+
## Accessibility rationale
|
|
32
|
+
|
|
33
|
+
Renders a <button role="switch"> with aria-checked reflecting state. Both on/off slots are aria-hidden so screen readers announce the button state, not the icon content.
|
|
34
|
+
|
|
35
|
+
## Props
|
|
36
|
+
|
|
37
|
+
| Name | Type | Required | Default | Description |
|
|
38
|
+
| ------------ | ---------------------------- | -------- | ------- | -------------------------------------------------------- |
|
|
39
|
+
| `on` | `React.ReactNode` | Yes | — | Content shown in the active (on) state. |
|
|
40
|
+
| `off` | `React.ReactNode` | Yes | — | Content shown in the inactive (off) state. |
|
|
41
|
+
| `checked` | `boolean` | No | false | Whether the control is checked (controlled). |
|
|
42
|
+
| `onChange` | `(checked: boolean) => void` | No | — | Called when the value changes. |
|
|
43
|
+
| `mode` | `'rotate' \| 'flip'` | No | rotate | Transition between states ('rotate' \| 'flip'). |
|
|
44
|
+
| `aria-label` | `string` | No | — | Accessible label used when no visible label is present. |
|
|
45
|
+
| `className` | `string` | No | — | Additional CSS class names merged onto the root element. |
|
|
46
|
+
|
|
47
|
+
## Tokens
|
|
48
|
+
|
|
49
|
+
- `--cascivo-ring-width`
|
|
50
|
+
- `--cascivo-ring-color`
|
|
51
|
+
- `--cascivo-radius-control`
|
|
52
|
+
- `--cascivo-ease-out`
|
|
53
|
+
|
|
54
|
+
## Examples
|
|
55
|
+
|
|
56
|
+
### Theme toggle (rotate)
|
|
57
|
+
|
|
58
|
+
Sun/moon icon that rotates between two states
|
|
59
|
+
|
|
60
|
+
```jsx
|
|
61
|
+
<Swap on={<SunIcon />} off={<MoonIcon />} mode="rotate" aria-label="Toggle theme" />
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Flip mode
|
|
65
|
+
|
|
66
|
+
Heart icon that flips to filled on activation
|
|
67
|
+
|
|
68
|
+
```jsx
|
|
69
|
+
<Swap on={<HeartFilledIcon />} off={<HeartIcon />} mode="flip" aria-label="Favorite" />
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Boundaries
|
|
73
|
+
|
|
74
|
+
| Area | Level | Note |
|
|
75
|
+
| -------------- | -------- | --------------------------------------------------------------------------- |
|
|
76
|
+
| content | flexible | on/off slots accept any ReactNode — icons, text, images |
|
|
77
|
+
| animation mode | flexible | rotate (default) or flip — choose based on the visual metaphor of the icons |
|
|
78
|
+
|
|
79
|
+
## AI context prompt
|
|
80
|
+
|
|
81
|
+
Copy this into an LLM context bar before editing this component:
|
|
82
|
+
|
|
83
|
+
```text
|
|
84
|
+
I am modifying the cascivo Swap component (inputs). Animated toggle between two icon/content states with rotate or flip transition
|
|
85
|
+
|
|
86
|
+
Architecture constraints — follow exactly:
|
|
87
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
88
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
89
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
90
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
91
|
+
- CSS logical properties only (RTL-safe).
|
|
92
|
+
|
|
93
|
+
Swap is strictly bound to these tokens — use only these, do not invent token names:
|
|
94
|
+
--cascivo-ring-width, --cascivo-ring-color, --cascivo-radius-control, --cascivo-ease-out
|
|
95
|
+
|
|
96
|
+
Accessibility: role "switch", WCAG 2.2-AA, keyboard: Space/Enter. Keep it AA.
|
|
97
|
+
Flexible: content, animation mode.
|
|
98
|
+
|
|
99
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
100
|
+
```
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# SwipeItem
|
|
2
|
+
|
|
3
|
+
**Category:** display
|
|
4
|
+
**Description:** List row whose leading/trailing actions are revealed by a horizontal swipe, with keyboard parity
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- List rows on touch surfaces where secondary actions (archive, delete) should hide until swiped
|
|
9
|
+
- Mail/inbox-style rows that reveal contextual actions behind the content
|
|
10
|
+
- Compact lists where always-visible action buttons would crowd each row
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
|
|
14
|
+
- A single primary action per row — render it inline as a Button
|
|
15
|
+
- Destructive actions that need confirmation — pair with an AlertDialog instead of swipe-only
|
|
16
|
+
- Non-list, free-form content — swipe-to-reveal is a list-row affordance
|
|
17
|
+
|
|
18
|
+
## Anti-patterns
|
|
19
|
+
|
|
20
|
+
### Gesture-only actions are unreachable by keyboard and screen-reader users
|
|
21
|
+
|
|
22
|
+
**Bad:** `Relying on the swipe gesture as the only way to reach Delete`
|
|
23
|
+
**Good:** `Action buttons stay in the DOM and a11y tree; focusing one reveals its side`
|
|
24
|
+
**Why:** Gesture-only actions are unreachable by keyboard and screen-reader users
|
|
25
|
+
|
|
26
|
+
## Related components
|
|
27
|
+
|
|
28
|
+
- **ActionSheet** (alternative): Use an ActionSheet when a row tap should present a fuller list of actions
|
|
29
|
+
- **List** (contained-by): SwipeItem wraps individual rows within a list
|
|
30
|
+
|
|
31
|
+
## Accessibility rationale
|
|
32
|
+
|
|
33
|
+
The action buttons are always rendered in the DOM and the accessibility tree, never gesture-only. Focusing an action (via keyboard) reveals its side so it is visible, Enter/Space activate it, and Escape closes the row — giving full keyboard and screen-reader parity with the swipe gesture. The drag uses touch-action: pan-y so vertical scrolling is unaffected.
|
|
34
|
+
|
|
35
|
+
## Props
|
|
36
|
+
|
|
37
|
+
| Name | Type | Required | Default | Description |
|
|
38
|
+
| ----------------- | ----------------- | -------- | ------- | -------------------------------------------------------------------------- |
|
|
39
|
+
| `children` | `React.ReactNode` | Yes | — | The row content |
|
|
40
|
+
| `leadingActions` | `SwipeAction[]` | No | — | Actions revealed by dragging toward the end edge (shown on the start edge) |
|
|
41
|
+
| `trailingActions` | `SwipeAction[]` | No | — | Actions revealed by dragging toward the start edge (shown on the end edge) |
|
|
42
|
+
| `className` | `string` | No | — | Additional CSS class names merged onto the root element. |
|
|
43
|
+
|
|
44
|
+
## Tokens
|
|
45
|
+
|
|
46
|
+
- `--cascivo-color-surface`
|
|
47
|
+
- `--cascivo-color-accent`
|
|
48
|
+
- `--cascivo-color-accent-content`
|
|
49
|
+
- `--cascivo-color-destructive`
|
|
50
|
+
- `--cascivo-color-text-on-destructive`
|
|
51
|
+
- `--cascivo-target-min-coarse`
|
|
52
|
+
- `--cascivo-motion-enter`
|
|
53
|
+
|
|
54
|
+
## Examples
|
|
55
|
+
|
|
56
|
+
### Trailing actions
|
|
57
|
+
|
|
58
|
+
```jsx
|
|
59
|
+
<SwipeItem
|
|
60
|
+
trailingActions={[
|
|
61
|
+
{ label: 'Archive', onSelect: archive },
|
|
62
|
+
{ label: 'Delete', onSelect: remove, destructive: true },
|
|
63
|
+
]}
|
|
64
|
+
>
|
|
65
|
+
<MessageRow message={message} />
|
|
66
|
+
</SwipeItem>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Leading and trailing
|
|
70
|
+
|
|
71
|
+
```jsx
|
|
72
|
+
<SwipeItem
|
|
73
|
+
leadingActions={[{ label: 'Pin', icon: <PinIcon />, onSelect: pin }]}
|
|
74
|
+
trailingActions={[{ label: 'Delete', onSelect: remove, destructive: true }]}
|
|
75
|
+
>
|
|
76
|
+
<TaskRow task={task} />
|
|
77
|
+
</SwipeItem>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Boundaries
|
|
81
|
+
|
|
82
|
+
| Area | Level | Note |
|
|
83
|
+
| ---------------- | -------- | -------------------------------------------------------------------------------- |
|
|
84
|
+
| actions | flexible | Any number of leading and/or trailing actions; each may be destructive |
|
|
85
|
+
| reveal direction | strict | Leading reveals on the start edge, trailing on the end edge (physical-axis drag) |
|
|
86
|
+
|
|
87
|
+
## AI context prompt
|
|
88
|
+
|
|
89
|
+
Copy this into an LLM context bar before editing this component:
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
I am modifying the cascivo SwipeItem component (display). List row whose leading/trailing actions are revealed by a horizontal swipe, with keyboard parity
|
|
93
|
+
|
|
94
|
+
Architecture constraints — follow exactly:
|
|
95
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
96
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
97
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
98
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
99
|
+
- CSS logical properties only (RTL-safe).
|
|
100
|
+
|
|
101
|
+
SwipeItem is strictly bound to these tokens — use only these, do not invent token names:
|
|
102
|
+
--cascivo-color-surface, --cascivo-color-accent, --cascivo-color-accent-content, --cascivo-color-destructive, --cascivo-color-text-on-destructive, --cascivo-target-min-coarse, --cascivo-motion-enter
|
|
103
|
+
|
|
104
|
+
Accessibility: role "group", WCAG 2.2-AA, keyboard: Tab/Enter/Space/Escape. Keep it AA.
|
|
105
|
+
|
|
106
|
+
Do not change (strict): reveal direction — Leading reveals on the start edge, trailing on the end edge (physical-axis drag)
|
|
107
|
+
Flexible: actions.
|
|
108
|
+
|
|
109
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
110
|
+
```
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Switcher
|
|
2
|
+
|
|
3
|
+
**Category:** navigation
|
|
4
|
+
**Description:** App/product switcher list — lives inside HeaderPanel, renders links with active indicator and optional dividers
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Listing sibling apps/products the user can switch between
|
|
9
|
+
- Rendering switch destinations inside a HeaderPanel opened from the shell header
|
|
10
|
+
- Grouping switch targets with dividers and marking the active one
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
|
|
14
|
+
- Primary in-app navigation — use SideNav
|
|
15
|
+
- A small action menu attached to a control — use Dropdown
|
|
16
|
+
|
|
17
|
+
## Anti-patterns
|
|
18
|
+
|
|
19
|
+
### Switcher models cross-app jumps, not navigation within the current app
|
|
20
|
+
|
|
21
|
+
**Bad:** `Using Switcher as the main page navigation`
|
|
22
|
+
**Good:** `<SideNav> for primary navigation; Switcher only for app/product switching`
|
|
23
|
+
**Why:** Switcher models cross-app jumps, not navigation within the current app
|
|
24
|
+
|
|
25
|
+
## Related components
|
|
26
|
+
|
|
27
|
+
- **HeaderPanel** (contained-by): Switcher is placed inside a HeaderPanel opened by a ShellHeader action
|
|
28
|
+
|
|
29
|
+
## Accessibility rationale
|
|
30
|
+
|
|
31
|
+
role="list" structures the entries; each switch target is a real link with the active destination marked, so keyboard and screen-reader users can identify and reach the current app
|
|
32
|
+
|
|
33
|
+
## Props
|
|
34
|
+
|
|
35
|
+
| Name | Type | Required | Default | Description |
|
|
36
|
+
| ----------- | ----------------- | -------- | ------------------ | ----------------------------------------------------------------------------- |
|
|
37
|
+
| `items` | `SwitcherEntry[]` | Yes | — | SwitcherLink ({ label, href, active?, icon? }) or divider ({ divider: true }) |
|
|
38
|
+
| `label` | `string` | No | Switch application | Text label for the control. |
|
|
39
|
+
| `className` | `string` | No | — | Additional CSS class names merged onto the root element. |
|
|
40
|
+
|
|
41
|
+
## Tokens
|
|
42
|
+
|
|
43
|
+
- `--cascivo-color-text`
|
|
44
|
+
- `--cascivo-color-bg-subtle`
|
|
45
|
+
- `--cascivo-color-accent`
|
|
46
|
+
- `--cascivo-color-accent-subtle`
|
|
47
|
+
- `--cascivo-color-border`
|
|
48
|
+
- `--cascivo-focus-ring`
|
|
49
|
+
|
|
50
|
+
## Examples
|
|
51
|
+
|
|
52
|
+
### App switcher
|
|
53
|
+
|
|
54
|
+
Place inside a HeaderPanel opened by a Grid action in ShellHeader
|
|
55
|
+
|
|
56
|
+
```jsx
|
|
57
|
+
<Switcher
|
|
58
|
+
items={[
|
|
59
|
+
{ label: 'Console', href: '/console', active: true },
|
|
60
|
+
{ label: 'Billing', href: '/billing' },
|
|
61
|
+
{ divider: true },
|
|
62
|
+
{ label: 'Docs', href: 'https://docs.example.com' },
|
|
63
|
+
]}
|
|
64
|
+
/>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Boundaries
|
|
68
|
+
|
|
69
|
+
| Area | Level | Note |
|
|
70
|
+
| ----------- | -------- | ------------------------------------------------------------- |
|
|
71
|
+
| dividers | flexible | Dividers group entries as needed |
|
|
72
|
+
| token names | strict | Accent and surface colors must resolve to --cascivo-\* tokens |
|
|
73
|
+
|
|
74
|
+
## AI context prompt
|
|
75
|
+
|
|
76
|
+
Copy this into an LLM context bar before editing this component:
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
I am modifying the cascivo Switcher component (navigation). App/product switcher list — lives inside HeaderPanel, renders links with active indicator and optional dividers
|
|
80
|
+
|
|
81
|
+
Architecture constraints — follow exactly:
|
|
82
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
83
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
84
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
85
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
86
|
+
- CSS logical properties only (RTL-safe).
|
|
87
|
+
|
|
88
|
+
Switcher is strictly bound to these tokens — use only these, do not invent token names:
|
|
89
|
+
--cascivo-color-text, --cascivo-color-bg-subtle, --cascivo-color-accent, --cascivo-color-accent-subtle, --cascivo-color-border, --cascivo-focus-ring
|
|
90
|
+
|
|
91
|
+
Accessibility: role "list", WCAG 2.2-AA, keyboard: Tab/Enter. Keep it AA.
|
|
92
|
+
|
|
93
|
+
Do not change (strict): token names — Accent and surface colors must resolve to --cascivo-* tokens
|
|
94
|
+
Flexible: dividers.
|
|
95
|
+
|
|
96
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
97
|
+
```
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Tabs
|
|
2
|
+
|
|
3
|
+
**Category:** navigation
|
|
4
|
+
**Description:** Switch between related panels of content
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Switching between peer panels of related content in the same context
|
|
9
|
+
- Showing one section at a time when all sections are equally important
|
|
10
|
+
|
|
11
|
+
## When NOT to use
|
|
12
|
+
|
|
13
|
+
- Stacked sequential content the user reads top to bottom — use Accordion
|
|
14
|
+
- Changing a setting or view parameter — use a SegmentedControl
|
|
15
|
+
- Navigating between pages — use links
|
|
16
|
+
|
|
17
|
+
## Anti-patterns
|
|
18
|
+
|
|
19
|
+
### Tabs imply switching content panels; toggling a parameter is a control, not navigation
|
|
20
|
+
|
|
21
|
+
**Bad:** `Using Tabs to toggle a single display option (e.g. grid/list view)`
|
|
22
|
+
**Good:** `<SegmentedControl> for view/setting toggles`
|
|
23
|
+
**Why:** Tabs imply switching content panels; toggling a parameter is a control, not navigation
|
|
24
|
+
|
|
25
|
+
## Related components
|
|
26
|
+
|
|
27
|
+
- **Accordion** (alternative): Accordion stacks sequential sections; Tabs switch between peers
|
|
28
|
+
- **SegmentedControl** (alternative): SegmentedControl changes a setting/parameter rather than swapping panels
|
|
29
|
+
|
|
30
|
+
## Accessibility rationale
|
|
31
|
+
|
|
32
|
+
Implements the WAI-ARIA tabs pattern: tablist/tab/tabpanel roles with arrow-key navigation and Home/End, so the active tab and its panel are correctly associated for assistive tech
|
|
33
|
+
|
|
34
|
+
## Props
|
|
35
|
+
|
|
36
|
+
| Name | Type | Required | Default | Description |
|
|
37
|
+
| --------------- | ------------------------- | -------- | ------- | ------------------------------------------ |
|
|
38
|
+
| `defaultValue` | `string` | No | — | The initial value when uncontrolled. |
|
|
39
|
+
| `value` | `string` | No | — | The controlled value. |
|
|
40
|
+
| `onValueChange` | `(value: string) => void` | No | — | Called with the new value when it changes. |
|
|
41
|
+
|
|
42
|
+
## Tokens
|
|
43
|
+
|
|
44
|
+
- `--cascivo-color-accent`
|
|
45
|
+
- `--cascivo-color-text`
|
|
46
|
+
- `--cascivo-color-text-subtle`
|
|
47
|
+
- `--cascivo-color-border`
|
|
48
|
+
- `--cascivo-focus-ring`
|
|
49
|
+
|
|
50
|
+
## Examples
|
|
51
|
+
|
|
52
|
+
### Basic
|
|
53
|
+
|
|
54
|
+
```jsx
|
|
55
|
+
<Tabs defaultValue="account">
|
|
56
|
+
<TabsList>
|
|
57
|
+
<TabsTrigger value="account">Account</TabsTrigger>
|
|
58
|
+
</TabsList>
|
|
59
|
+
<TabsContent value="account">…</TabsContent>
|
|
60
|
+
</Tabs>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Boundaries
|
|
64
|
+
|
|
65
|
+
| Area | Level | Note |
|
|
66
|
+
| -------------------------- | -------- | ------------------------------------------------------------------- |
|
|
67
|
+
| controlled vs uncontrolled | flexible | Use value or defaultValue depending on control needs |
|
|
68
|
+
| token names | strict | Accent, borders, and focus ring must resolve to --cascivo-\* tokens |
|
|
69
|
+
|
|
70
|
+
## AI context prompt
|
|
71
|
+
|
|
72
|
+
Copy this into an LLM context bar before editing this component:
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
I am modifying the cascivo Tabs component (navigation). Switch between related panels of content
|
|
76
|
+
|
|
77
|
+
Architecture constraints — follow exactly:
|
|
78
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
79
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
80
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
81
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
82
|
+
- CSS logical properties only (RTL-safe).
|
|
83
|
+
|
|
84
|
+
Tabs is strictly bound to these tokens — use only these, do not invent token names:
|
|
85
|
+
--cascivo-color-accent, --cascivo-color-text, --cascivo-color-text-subtle, --cascivo-color-border, --cascivo-focus-ring
|
|
86
|
+
|
|
87
|
+
Accessibility: role "tablist", WCAG 2.2-AA, keyboard: ArrowLeft/ArrowRight/Home/End. Keep it AA.
|
|
88
|
+
|
|
89
|
+
Do not change (strict): token names — Accent, borders, and focus ring must resolve to --cascivo-* tokens
|
|
90
|
+
Flexible: controlled vs uncontrolled.
|
|
91
|
+
|
|
92
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
93
|
+
```
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Tag
|
|
2
|
+
|
|
3
|
+
**Category:** display
|
|
4
|
+
**Description:** Compact chip for labeling, categorizing, or filtering content
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Labeling, categorizing, or filtering content with a compact chip
|
|
9
|
+
- Representing a removable selection or active filter (onDismiss)
|
|
10
|
+
- Showing a set of keywords or attributes on an item
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
|
|
14
|
+
- A static, non-interactive status label — use Badge
|
|
15
|
+
- A live system state with a dot — use Status
|
|
16
|
+
|
|
17
|
+
## Anti-patterns
|
|
18
|
+
|
|
19
|
+
### Tag provides accessible dismiss semantics; bolting interactivity onto Badge skips that
|
|
20
|
+
|
|
21
|
+
**Bad:** `Using Badge with a custom close button to make it removable`
|
|
22
|
+
**Good:** `<Tag onDismiss={remove}> which renders a proper labeled remove button`
|
|
23
|
+
**Why:** Tag provides accessible dismiss semantics; bolting interactivity onto Badge skips that
|
|
24
|
+
|
|
25
|
+
## Related components
|
|
26
|
+
|
|
27
|
+
- **Badge** (alternative): Badge is the static, non-interactive counterpart
|
|
28
|
+
- **TagsInput** (contained-by): TagsInput renders Tags for each entered value
|
|
29
|
+
|
|
30
|
+
## Accessibility rationale
|
|
31
|
+
|
|
32
|
+
When dismissible, the remove control is a real button with a label (dismissLabel) so keyboard users can remove it via Enter/Space; color variants are reinforced by text, not hue alone
|
|
33
|
+
|
|
34
|
+
## Props
|
|
35
|
+
|
|
36
|
+
| Name | Type | Required | Default | Description |
|
|
37
|
+
| -------------- | ---------------------------------------------------------- | -------- | ------- | --------------------------------------------------------------- |
|
|
38
|
+
| `variant` | `'default' \| 'info' \| 'success' \| 'warning' \| 'error'` | No | default | Selects the visual style variant. |
|
|
39
|
+
| `size` | `'sm' \| 'md'` | No | md | Visual size of the component (e.g. 'sm', 'md', 'lg'). |
|
|
40
|
+
| `onDismiss` | `() => void` | No | — | When provided, renders a trailing remove button inside the chip |
|
|
41
|
+
| `dismissLabel` | `string` | No | Remove | Accessible label for the dismiss button. |
|
|
42
|
+
|
|
43
|
+
## Tokens
|
|
44
|
+
|
|
45
|
+
- `--cascivo-color-bg-subtle`
|
|
46
|
+
- `--cascivo-color-text-subtle`
|
|
47
|
+
- `--cascivo-color-info`
|
|
48
|
+
- `--cascivo-color-info-subtle`
|
|
49
|
+
- `--cascivo-color-success`
|
|
50
|
+
- `--cascivo-color-success-subtle`
|
|
51
|
+
- `--cascivo-color-warning`
|
|
52
|
+
- `--cascivo-color-warning-subtle`
|
|
53
|
+
- `--cascivo-color-destructive`
|
|
54
|
+
- `--cascivo-color-destructive-subtle`
|
|
55
|
+
- `--cascivo-radius-badge`
|
|
56
|
+
- `--cascivo-focus-ring`
|
|
57
|
+
|
|
58
|
+
## Examples
|
|
59
|
+
|
|
60
|
+
### Default
|
|
61
|
+
|
|
62
|
+
```jsx
|
|
63
|
+
<Tag>Design</Tag>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Success
|
|
67
|
+
|
|
68
|
+
```jsx
|
|
69
|
+
<Tag variant="success">Approved</Tag>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Dismissible
|
|
73
|
+
|
|
74
|
+
Renders a trailing remove button labeled by dismissLabel
|
|
75
|
+
|
|
76
|
+
```jsx
|
|
77
|
+
<Tag onDismiss={() => removeFilter()}>Filter: Active</Tag>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Boundaries
|
|
81
|
+
|
|
82
|
+
| Area | Level | Note |
|
|
83
|
+
| -------------------------- | -------- | --------------------------------------------------------------- |
|
|
84
|
+
| variant and dismissibility | flexible | onDismiss is optional; variant matches semantic meaning |
|
|
85
|
+
| token names | strict | Variant colors must resolve to --cascivo-color-\*-subtle tokens |
|
|
86
|
+
|
|
87
|
+
## AI context prompt
|
|
88
|
+
|
|
89
|
+
Copy this into an LLM context bar before editing this component:
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
I am modifying the cascivo Tag component (display). Compact chip for labeling, categorizing, or filtering content
|
|
93
|
+
|
|
94
|
+
Architecture constraints — follow exactly:
|
|
95
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
96
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
97
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
98
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
99
|
+
- CSS logical properties only (RTL-safe).
|
|
100
|
+
|
|
101
|
+
Tag is strictly bound to these tokens — use only these, do not invent token names:
|
|
102
|
+
--cascivo-color-bg-subtle, --cascivo-color-text-subtle, --cascivo-color-info, --cascivo-color-info-subtle, --cascivo-color-success, --cascivo-color-success-subtle, --cascivo-color-warning, --cascivo-color-warning-subtle, --cascivo-color-destructive, --cascivo-color-destructive-subtle, --cascivo-radius-badge, --cascivo-focus-ring
|
|
103
|
+
|
|
104
|
+
Accessibility: role "none", WCAG 2.2-AA, keyboard: Enter/Space. Keep it AA.
|
|
105
|
+
|
|
106
|
+
Do not change (strict): token names — Variant colors must resolve to --cascivo-color-*-subtle tokens
|
|
107
|
+
Flexible: variant and dismissibility.
|
|
108
|
+
|
|
109
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
110
|
+
```
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# TagsInput
|
|
2
|
+
|
|
3
|
+
**Category:** inputs
|
|
4
|
+
**Description:** Free-form multi-value chip input
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Collecting an open-ended set of free-text values the user types themselves (keywords, emails, labels)
|
|
9
|
+
- Each entry should appear as a removable chip and there is no fixed list to pick from
|
|
10
|
+
- You need per-tag validation or a cap on how many entries are allowed
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
|
|
14
|
+
- Values come from a fixed, known list — use MultiSelect
|
|
15
|
+
- Only a single line of free text is needed — use Input
|
|
16
|
+
|
|
17
|
+
## Anti-patterns
|
|
18
|
+
|
|
19
|
+
### Free-text entry invites typos and inconsistent values when the set is actually constrained; pick from options instead
|
|
20
|
+
|
|
21
|
+
**Bad:** `<TagsInput value={selectedRoles} ... /> // roles are a fixed enum`
|
|
22
|
+
**Good:** `<MultiSelect options={roleOptions} />`
|
|
23
|
+
**Why:** Free-text entry invites typos and inconsistent values when the set is actually constrained; pick from options instead
|
|
24
|
+
|
|
25
|
+
## Related components
|
|
26
|
+
|
|
27
|
+
- **MultiSelect** (alternative): Use when values come from a fixed list rather than free text
|
|
28
|
+
- **Input** (alternative): Use for a single free-text value with no chips
|
|
29
|
+
|
|
30
|
+
## Accessibility rationale
|
|
31
|
+
|
|
32
|
+
The typing surface is a real <input> and each tag exposes a dedicated remove button with an aria-label naming the tag, so screen-reader users can both add (Enter/comma) and delete (Backspace or the button) without ambiguity.
|
|
33
|
+
|
|
34
|
+
## Props
|
|
35
|
+
|
|
36
|
+
| Name | Type | Required | Default | Description |
|
|
37
|
+
| --------------- | -------------------------- | -------- | ------- | ------------------------------------------------------------------ |
|
|
38
|
+
| `value` | `string[]` | Yes | — | The controlled value. |
|
|
39
|
+
| `onValueChange` | `(v: string[]) => void` | Yes | — | Called with the new value when it changes. |
|
|
40
|
+
| `placeholder` | `string` | No | — | Placeholder text shown when the field is empty. |
|
|
41
|
+
| `validate` | `(tag: string) => boolean` | No | — | Returns whether a candidate tag is allowed. |
|
|
42
|
+
| `max` | `number` | No | — | Maximum allowed value. |
|
|
43
|
+
| `disabled` | `boolean` | No | false | When true, disables the control and removes it from the tab order. |
|
|
44
|
+
|
|
45
|
+
## Tokens
|
|
46
|
+
|
|
47
|
+
- `--cascivo-color-surface`
|
|
48
|
+
- `--cascivo-color-border`
|
|
49
|
+
- `--cascivo-color-accent`
|
|
50
|
+
- `--cascivo-color-destructive`
|
|
51
|
+
- `--cascivo-color-bg-subtle`
|
|
52
|
+
- `--cascivo-radius-input`
|
|
53
|
+
- `--cascivo-radius-full`
|
|
54
|
+
- `--cascivo-focus-ring`
|
|
55
|
+
|
|
56
|
+
## Examples
|
|
57
|
+
|
|
58
|
+
### Basic
|
|
59
|
+
|
|
60
|
+
```jsx
|
|
61
|
+
<TagsInput value={['react', 'vue']} onValueChange={() => {}} placeholder="Add tag…" />
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Boundaries
|
|
65
|
+
|
|
66
|
+
| Area | Level | Note |
|
|
67
|
+
| ----------- | -------- | ---------------------------------------------------------------------------------------------- |
|
|
68
|
+
| tag values | flexible | Free text, optionally constrained by the validate predicate and max count |
|
|
69
|
+
| commit keys | strict | Enter and comma commit a tag; Backspace on empty removes the last — fixed interaction contract |
|
|
70
|
+
|
|
71
|
+
## AI context prompt
|
|
72
|
+
|
|
73
|
+
Copy this into an LLM context bar before editing this component:
|
|
74
|
+
|
|
75
|
+
```text
|
|
76
|
+
I am modifying the cascivo TagsInput component (inputs). Free-form multi-value chip input
|
|
77
|
+
|
|
78
|
+
Architecture constraints — follow exactly:
|
|
79
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
80
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
81
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
82
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
83
|
+
- CSS logical properties only (RTL-safe).
|
|
84
|
+
|
|
85
|
+
TagsInput is strictly bound to these tokens — use only these, do not invent token names:
|
|
86
|
+
--cascivo-color-surface, --cascivo-color-border, --cascivo-color-accent, --cascivo-color-destructive, --cascivo-color-bg-subtle, --cascivo-radius-input, --cascivo-radius-full, --cascivo-focus-ring
|
|
87
|
+
|
|
88
|
+
Accessibility: role "textbox", WCAG 2.2-AA, keyboard: Enter/,/Backspace. Keep it AA.
|
|
89
|
+
|
|
90
|
+
Do not change (strict): commit keys — Enter and comma commit a tag; Backspace on empty removes the last — fixed interaction contract
|
|
91
|
+
Flexible: tag values.
|
|
92
|
+
|
|
93
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
94
|
+
```
|