@cascivo/mcp 0.2.0 → 0.3.4
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
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -31,26 +31,56 @@ Add it to your MCP client configuration:
|
|
|
31
31
|
}
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
The server speaks the MCP stdio transport.
|
|
34
|
+
The server speaks the MCP stdio transport. It is **self-contained**: the registry, token catalog, variant matrix, component context, and marketplace catalog are all bundled with the package, so discovery, token, and validation tools work offline — hosted data is only fetched as a fallback. Override the registry with the `CASCIVO_REGISTRY_PATH` environment variable; add extra registries via `CASCADE_REGISTRIES`.
|
|
35
35
|
|
|
36
36
|
## Tools
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
| `
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
38
|
+
### Discovery
|
|
39
|
+
|
|
40
|
+
| Tool | Input | Returns |
|
|
41
|
+
| ------------------- | ---------------------- | -------------------------------------------------------------------------------------------------- |
|
|
42
|
+
| `list_registries` | `{}` | Available registries: the cascivo directory plus any configured via `CASCADE_REGISTRIES` |
|
|
43
|
+
| `list_components` | `{ category?, type? }` | All component manifests, filterable by category and entry type (`component`, `layout`, `block`, …) |
|
|
44
|
+
| `get_component` | `{ name, registry? }` | The full manifest (props, states, tokens, a11y, examples) — optionally from an external registry |
|
|
45
|
+
| `search_components` | `{ query, registry? }` | Fuzzy search by name, tags, or description |
|
|
46
|
+
| `get_context` | `{ name }` | Intent, whenToUse/whenNotToUse, and authoring guidance for one component |
|
|
47
|
+
| `select_component` | `{ need }` | Heuristic ranking of components for a natural-language need, with scores and reasons |
|
|
48
|
+
|
|
49
|
+
`category` is one of `inputs`, `display`, `overlay`, `navigation`, `feedback`, `chart`.
|
|
50
|
+
|
|
51
|
+
### Tokens & theming
|
|
52
|
+
|
|
53
|
+
| Tool | Input | Returns |
|
|
54
|
+
| -------------------- | ------------------------------------- | -------------------------------------------------------------------------------------------- |
|
|
55
|
+
| `get_tokens` | `{ group?, layer?, includeAliases? }` | The closed token catalog — canonical names only by default, so agents never hard-code values |
|
|
56
|
+
| `get_variant_matrix` | `{ role?, theme? }` | Deterministic intent→token map (colour role + state slot) + every token resolved per theme |
|
|
57
|
+
| `create_theme` | `{ primary, neutral, accent, name? }` | A custom theme as CSS (semantic token layer) generated from three colors |
|
|
58
|
+
|
|
59
|
+
### Scaffold & validate
|
|
60
|
+
|
|
61
|
+
| Tool | Input | Returns |
|
|
62
|
+
| -------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
|
63
|
+
| `scaffold_view` | `{ description, components? }` | A validated starter `ViewConfig` + the bound-vocabulary `grammar` for its components |
|
|
64
|
+
| `validate_view` | `{ config }` | Validation errors (component, prop type/enum, refs) with exact paths |
|
|
65
|
+
| `get_view_grammar` | `{ components? }` | Bound-vocabulary grammar + generation prompt for valid `ViewConfig` JSON |
|
|
66
|
+
| `validate_component` | `{ tsx?, css?, name? }` | Static structural-invariant check of generated source (banned hooks, off-scale breakpoints, missing CSS fallbacks, hallucinated tokens) |
|
|
67
|
+
| `scaffold_flow` | `{ description, steps?, layout? }` | Starter nodes/edges + ready-to-paste `<Flow />` JSX (from `@cascivo/flow`) for a diagram |
|
|
68
|
+
| `scaffold_page` | `{ description, components? }` | **Deprecated** — use `scaffold_view`; still returns a JSX scaffold plus the `scaffold_view` output |
|
|
69
|
+
|
|
70
|
+
### Templates
|
|
71
|
+
|
|
72
|
+
| Tool | Input | Returns |
|
|
73
|
+
| ---------------- | ------------------------------------------------ | -------------------------------------------------------------------------------- |
|
|
74
|
+
| `list_templates` | `{ category?, tag?, framework?, verifiedOnly? }` | Marketplace templates (whole-page compositions) from the catalog |
|
|
75
|
+
| `get_template` | `{ name }` | One template: its components, install command, demo link, and screenshots |
|
|
76
|
+
| `add_template` | `{ name, cwd? }` | Installs a template (components + page/fixture files) by running the cascivo CLI |
|
|
77
|
+
|
|
78
|
+
### Project
|
|
79
|
+
|
|
80
|
+
| Tool | Input | Returns |
|
|
81
|
+
| ---------------- | ----------------------------------- | --------------------------------------------------------------------------------- |
|
|
82
|
+
| `add_to_project` | `{ name, outputDir? }` | Runs `cascivo add <name>` as a child process |
|
|
83
|
+
| `create_app` | `{ name, theme?, sections?, cwd? }` | Scaffolds a full Vite + React app (shell + side nav + theme) via `cascivo create` |
|
|
54
84
|
|
|
55
85
|
### Bound-vocabulary generation (anti-hallucination)
|
|
56
86
|
|
|
@@ -59,11 +89,11 @@ prompt** plus a compact **allowed-vocabulary grammar** (each component → its
|
|
|
59
89
|
props → enum/size/variant values) for emitting valid `ViewConfig` JSON rendered
|
|
60
90
|
by `@cascivo/render` `<CascadeView />`. This is [OpenUI](https://openui.com)'s
|
|
61
91
|
"generate the system prompt from the component library" mechanism (see
|
|
62
|
-
[`
|
|
63
|
-
**derived**, not authored, an LLM is structurally
|
|
64
|
-
components, props, or enum values, and the grammar can
|
|
65
|
-
components. Pair it with `validate_view` (which
|
|
66
|
-
as the enforcement backstop.
|
|
92
|
+
[`ROADMAP-V40.md`](https://github.com/cascivo/cascivo/blob/main/docs/internal/ROADMAP-V40.md)):
|
|
93
|
+
because the grammar is **derived**, not authored, an LLM is structurally
|
|
94
|
+
prevented from inventing components, props, or enum values, and the grammar can
|
|
95
|
+
never drift from the components. Pair it with `validate_view` (which also checks
|
|
96
|
+
prop types/enums) as the enforcement backstop.
|
|
67
97
|
|
|
68
98
|
```ts
|
|
69
99
|
import { buildGenerationPrompt, loadRegistry } from '@cascivo/mcp'
|
|
@@ -82,7 +112,7 @@ const server = createServer({ registryPath: './registry.json' })
|
|
|
82
112
|
await server.connect(new StdioServerTransport())
|
|
83
113
|
```
|
|
84
114
|
|
|
85
|
-
The pure helpers (`listComponents`, `getComponent`, `searchComponents`, `generateThemeCss`, `scaffoldPage`) are exported too, so the registry can be queried without spinning up the protocol.
|
|
115
|
+
The pure helpers (`listComponents`, `getComponent`, `searchComponents`, `generateThemeCss`, `scaffoldPage`, `buildGrammar`, `buildGenerationPrompt`, `loadRegistry`) are exported too, so the registry can be queried without spinning up the protocol.
|
|
86
116
|
|
|
87
117
|
## Install
|
|
88
118
|
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Accordion
|
|
2
|
+
|
|
3
|
+
**Category:** navigation
|
|
4
|
+
**Description:** Vertically stacked, collapsible content sections
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Progressively disclosing sections of related content the user reads top to bottom
|
|
9
|
+
- Reducing vertical scroll when most sections stay collapsed (FAQs, settings groups)
|
|
10
|
+
- Allowing multiple sections open at once (type="multiple")
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
|
|
14
|
+
- Switching between mutually exclusive, equally important views — use Tabs
|
|
15
|
+
- A single show/hide region — a plain disclosure is enough
|
|
16
|
+
|
|
17
|
+
## Anti-patterns
|
|
18
|
+
|
|
19
|
+
### A single permanently-open section adds chrome and indirection for no gain
|
|
20
|
+
|
|
21
|
+
**Bad:** `<Accordion> with one item that is always open`
|
|
22
|
+
**Good:** `Render the content directly, or use a collapsible disclosure`
|
|
23
|
+
**Why:** A single permanently-open section adds chrome and indirection for no gain
|
|
24
|
+
|
|
25
|
+
## Related components
|
|
26
|
+
|
|
27
|
+
- **Tabs** (alternative): Tabs switch between peer views; Accordion stacks sequential sections vertically
|
|
28
|
+
|
|
29
|
+
## Accessibility rationale
|
|
30
|
+
|
|
31
|
+
Each trigger is a native <button> exposing aria-expanded and controlling its panel via aria-controls, so screen readers announce open/closed state and Enter/Space toggle from the platform
|
|
32
|
+
|
|
33
|
+
## Props
|
|
34
|
+
|
|
35
|
+
| Name | Type | Required | Default | Description |
|
|
36
|
+
| --------------- | ------------------------------------- | -------- | ------- | ------------------------------------------------------------------------------ |
|
|
37
|
+
| `type` | `'single' \| 'multiple'` | No | single | Whether one or multiple sections can be open at once ('single' \| 'multiple'). |
|
|
38
|
+
| `defaultValue` | `string \| string[]` | No | — | The initial value when uncontrolled. |
|
|
39
|
+
| `value` | `string \| string[]` | No | — | The controlled value. |
|
|
40
|
+
| `onValueChange` | `(value: string \| string[]) => void` | No | — | Called with the new value when it changes. |
|
|
41
|
+
|
|
42
|
+
## Tokens
|
|
43
|
+
|
|
44
|
+
- `--cascivo-color-border`
|
|
45
|
+
- `--cascivo-color-bg-subtle`
|
|
46
|
+
- `--cascivo-color-text`
|
|
47
|
+
- `--cascivo-radius-md`
|
|
48
|
+
- `--cascivo-focus-ring`
|
|
49
|
+
|
|
50
|
+
## Examples
|
|
51
|
+
|
|
52
|
+
### Single
|
|
53
|
+
|
|
54
|
+
```jsx
|
|
55
|
+
<Accordion type="single" defaultValue="a">
|
|
56
|
+
<AccordionItem value="a">
|
|
57
|
+
<AccordionTrigger>Section</AccordionTrigger>
|
|
58
|
+
<AccordionContent>…</AccordionContent>
|
|
59
|
+
</AccordionItem>
|
|
60
|
+
</Accordion>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Boundaries
|
|
64
|
+
|
|
65
|
+
| Area | Level | Note |
|
|
66
|
+
| ------------------ | -------- | ------------------------------------------------------------------------- |
|
|
67
|
+
| single vs multiple | flexible | type prop is free to choose based on whether sections are exclusive |
|
|
68
|
+
| token names | strict | Borders, surfaces, and radii must resolve to --cascivo-\* semantic 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 Accordion component (navigation). Vertically stacked, collapsible content sections
|
|
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
|
+
Accordion is strictly bound to these tokens — use only these, do not invent token names:
|
|
85
|
+
--cascivo-color-border, --cascivo-color-bg-subtle, --cascivo-color-text, --cascivo-radius-md, --cascivo-focus-ring
|
|
86
|
+
|
|
87
|
+
Accessibility: role "button", WCAG 2.2-AA, keyboard: Enter/Space. Keep it AA.
|
|
88
|
+
|
|
89
|
+
Do not change (strict): token names — Borders, surfaces, and radii must resolve to --cascivo-* semantic tokens
|
|
90
|
+
Flexible: single vs multiple.
|
|
91
|
+
|
|
92
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
93
|
+
```
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# ActionSheet
|
|
2
|
+
|
|
3
|
+
**Category:** overlay
|
|
4
|
+
**Description:** Bottom-rising sheet of discrete actions (iOS action-sheet pattern) with a Cancel button
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- A short list of discrete actions on a touch surface, rising from the bottom
|
|
9
|
+
- Confirming or choosing among a few operations (e.g. Share, Edit, Delete) on mobile
|
|
10
|
+
- A mobile-first alternative to an anchored dropdown menu when there is no trigger anchor
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
|
|
14
|
+
- A single yes/no confirmation — use AlertDialog
|
|
15
|
+
- A form or scrollable content — use BottomSheet or Sheet
|
|
16
|
+
- A menu anchored to a trigger on desktop — use Menu or Dropdown
|
|
17
|
+
|
|
18
|
+
## Anti-patterns
|
|
19
|
+
|
|
20
|
+
### A one-action sheet is a confirmation; AlertDialog states the decision clearly
|
|
21
|
+
|
|
22
|
+
**Bad:** `<ActionSheet actions={[{ label: "OK", onSelect }]} />`
|
|
23
|
+
**Good:** `<AlertDialog title="Delete item?" />`
|
|
24
|
+
**Why:** A one-action sheet is a confirmation; AlertDialog states the decision clearly
|
|
25
|
+
|
|
26
|
+
## Related components
|
|
27
|
+
|
|
28
|
+
- **BottomSheet** (alternative): Use BottomSheet for rich/resizable content; ActionSheet is a fixed list of actions
|
|
29
|
+
- **Menu** (alternative): Use Menu for a trigger-anchored dropdown on pointer-first surfaces
|
|
30
|
+
|
|
31
|
+
## Accessibility rationale
|
|
32
|
+
|
|
33
|
+
Renders role="menu" with role="menuitem" buttons under vertical roving focus (Arrow keys, Home/End, wrapping). The title labels the menu via aria-labelledby (or a built-in label otherwise) and the description via aria-describedby. FocusScope traps and restores focus; DismissableLayer handles Escape and outside-pointer dismissal; a separate Cancel button provides an explicit non-destructive exit.
|
|
34
|
+
|
|
35
|
+
## Props
|
|
36
|
+
|
|
37
|
+
| Name | Type | Required | Default | Description |
|
|
38
|
+
| -------------- | ------------------------------------- | -------- | ------- | ----------------------------------------------------------------------------- |
|
|
39
|
+
| `open` | `boolean` | No | — | Whether the component is open (controlled). |
|
|
40
|
+
| `defaultOpen` | `boolean` | No | — | Whether the component is open on first render (uncontrolled). |
|
|
41
|
+
| `onOpenChange` | `(open: boolean) => void` | No | — | Called with the next open state when it changes. |
|
|
42
|
+
| `actions` | `ActionSheetAction[]` | Yes | — | Choices, each with a label, onSelect, and optional destructive/disabled flags |
|
|
43
|
+
| `title` | `React.ReactNode` | No | — | Title text for the component. |
|
|
44
|
+
| `description` | `React.ReactNode` | No | — | Supporting description text. |
|
|
45
|
+
| `showCancel` | `boolean` | No | true | When true, shows a cancel button below the actions. |
|
|
46
|
+
| `labels` | `{ cancel?: string; label?: string }` | No | — | Overrides for the component’s user-visible strings (i18n). |
|
|
47
|
+
| `className` | `string` | No | — | Additional CSS class names merged onto the root element. |
|
|
48
|
+
|
|
49
|
+
## Tokens
|
|
50
|
+
|
|
51
|
+
- `--cascivo-color-surface`
|
|
52
|
+
- `--cascivo-color-border`
|
|
53
|
+
- `--cascivo-color-accent`
|
|
54
|
+
- `--cascivo-color-destructive`
|
|
55
|
+
- `--cascivo-color-text`
|
|
56
|
+
- `--cascivo-color-text-subtle`
|
|
57
|
+
- `--cascivo-color-text-muted`
|
|
58
|
+
- `--cascivo-radius-overlay`
|
|
59
|
+
- `--cascivo-shadow-overlay`
|
|
60
|
+
- `--cascivo-motion-enter`
|
|
61
|
+
- `--cascivo-motion-exit`
|
|
62
|
+
- `--cascivo-z-overlay`
|
|
63
|
+
|
|
64
|
+
## Examples
|
|
65
|
+
|
|
66
|
+
### Basic
|
|
67
|
+
|
|
68
|
+
```jsx
|
|
69
|
+
<ActionSheet
|
|
70
|
+
open={isOpen}
|
|
71
|
+
onOpenChange={setIsOpen}
|
|
72
|
+
title="Share photo"
|
|
73
|
+
actions={[
|
|
74
|
+
{ label: 'Copy link', onSelect: copyLink },
|
|
75
|
+
{ label: 'Delete', onSelect: remove, destructive: true },
|
|
76
|
+
]}
|
|
77
|
+
/>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Without cancel button
|
|
81
|
+
|
|
82
|
+
Escape and outside press still dismiss the sheet.
|
|
83
|
+
|
|
84
|
+
```jsx
|
|
85
|
+
<ActionSheet defaultOpen showCancel={false} actions={[{ label: 'Archive', onSelect: archive }]} />
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Boundaries
|
|
89
|
+
|
|
90
|
+
| Area | Level | Note |
|
|
91
|
+
| ---------- | -------- | ---------------------------------------------------------------------------------- |
|
|
92
|
+
| actions | flexible | Any number of actions; each may be destructive or disabled |
|
|
93
|
+
| open state | flexible | Controlled (open/onOpenChange) or uncontrolled (defaultOpen) |
|
|
94
|
+
| cancel | flexible | showCancel toggles the separate Cancel button (Escape/outside press still dismiss) |
|
|
95
|
+
|
|
96
|
+
## AI context prompt
|
|
97
|
+
|
|
98
|
+
Copy this into an LLM context bar before editing this component:
|
|
99
|
+
|
|
100
|
+
```text
|
|
101
|
+
I am modifying the cascivo ActionSheet component (overlay). Bottom-rising sheet of discrete actions (iOS action-sheet pattern) with a Cancel button
|
|
102
|
+
|
|
103
|
+
Architecture constraints — follow exactly:
|
|
104
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
105
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
106
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
107
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
108
|
+
- CSS logical properties only (RTL-safe).
|
|
109
|
+
|
|
110
|
+
ActionSheet is strictly bound to these tokens — use only these, do not invent token names:
|
|
111
|
+
--cascivo-color-surface, --cascivo-color-border, --cascivo-color-accent, --cascivo-color-destructive, --cascivo-color-text, --cascivo-color-text-subtle, --cascivo-color-text-muted, --cascivo-radius-overlay, --cascivo-shadow-overlay, --cascivo-motion-enter, --cascivo-motion-exit, --cascivo-z-overlay
|
|
112
|
+
|
|
113
|
+
Accessibility: role "menu", WCAG 2.2-AA, keyboard: ArrowUp/ArrowDown/Home/End/Enter/Space/Escape. Keep it AA.
|
|
114
|
+
Flexible: actions, open state, cancel.
|
|
115
|
+
|
|
116
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
117
|
+
```
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# AlertDialog
|
|
2
|
+
|
|
3
|
+
**Category:** overlay
|
|
4
|
+
**Description:** Confirmation dialog requiring explicit user action; no light-dismiss
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Confirming a destructive or irreversible action (delete, overwrite, sign out) before it happens
|
|
9
|
+
- Interrupting a flow to force an explicit decision the user must acknowledge
|
|
10
|
+
|
|
11
|
+
## When NOT to use
|
|
12
|
+
|
|
13
|
+
- Showing non-critical information or forms — use Modal, which supports light-dismiss and arbitrary content
|
|
14
|
+
- Confirming a low-stakes action where an undoable Toast is friendlier and less interruptive
|
|
15
|
+
|
|
16
|
+
## Anti-patterns
|
|
17
|
+
|
|
18
|
+
### AlertDialog only renders a title, description, and two action buttons, and is role="alertdialog" with no light-dismiss — it is built to demand a yes/no answer, not host content
|
|
19
|
+
|
|
20
|
+
**Bad:** `Using AlertDialog for a multi-field form or rich content`
|
|
21
|
+
**Good:** `Use Modal for content; reserve AlertDialog for a title + description + confirm/cancel decision`
|
|
22
|
+
**Why:** AlertDialog only renders a title, description, and two action buttons, and is role="alertdialog" with no light-dismiss — it is built to demand a yes/no answer, not host content
|
|
23
|
+
|
|
24
|
+
### It uses popover="manual" so it cannot be light-dismissed by design — closing must go through onConfirm/onCancel so the decision is always explicit
|
|
25
|
+
|
|
26
|
+
**Bad:** `Adding a backdrop/Escape close to dismiss the dialog without choosing`
|
|
27
|
+
**Good:** `undefined`
|
|
28
|
+
**Why:** It uses popover="manual" so it cannot be light-dismissed by design — closing must go through onConfirm/onCancel so the decision is always explicit
|
|
29
|
+
|
|
30
|
+
## Related components
|
|
31
|
+
|
|
32
|
+
- **Modal** (alternative): Use for general dialogs with content and light-dismiss; AlertDialog is the must-acknowledge confirm
|
|
33
|
+
- **Toast** (alternative): Prefer an undoable Toast for reversible low-stakes actions instead of a blocking confirm
|
|
34
|
+
- **Button** (pairs-with): A Button typically triggers the action that opens the AlertDialog
|
|
35
|
+
|
|
36
|
+
## Accessibility rationale
|
|
37
|
+
|
|
38
|
+
Uses role="alertdialog" with aria-modal and labelled/described-by wiring so assistive tech announces it as an interruptive decision; focus moves to the cancel button on open so the safe default is selected, and popover="manual" prevents accidental dismissal that would skip the decision
|
|
39
|
+
|
|
40
|
+
## Props
|
|
41
|
+
|
|
42
|
+
| Name | Type | Required | Default | Description |
|
|
43
|
+
| ------------- | ---------------------------- | -------- | ------- | ---------------------------------------------------------- |
|
|
44
|
+
| `open` | `boolean` | Yes | — | Whether the component is open (controlled). |
|
|
45
|
+
| `title` | `string` | Yes | — | Title text for the component. |
|
|
46
|
+
| `description` | `string` | Yes | — | Supporting description text. |
|
|
47
|
+
| `onConfirm` | `() => void` | Yes | — | Called when the confirm button is activated. |
|
|
48
|
+
| `onCancel` | `() => void` | Yes | — | Called when the cancel button is activated. |
|
|
49
|
+
| `labels` | `AlertDialogLabels` | No | — | Overrides for the component’s user-visible strings (i18n). |
|
|
50
|
+
| `variant` | `'destructive' \| 'default'` | No | default | Selects the visual style variant. |
|
|
51
|
+
|
|
52
|
+
## Tokens
|
|
53
|
+
|
|
54
|
+
- `--cascivo-color-surface`
|
|
55
|
+
- `--cascivo-color-border`
|
|
56
|
+
- `--cascivo-radius-lg`
|
|
57
|
+
- `--cascivo-shadow-xl`
|
|
58
|
+
- `--cascivo-motion-enter`
|
|
59
|
+
- `--cascivo-motion-exit`
|
|
60
|
+
- `--cascivo-color-accent`
|
|
61
|
+
- `--cascivo-color-destructive`
|
|
62
|
+
|
|
63
|
+
## Examples
|
|
64
|
+
|
|
65
|
+
### Destructive confirm
|
|
66
|
+
|
|
67
|
+
```jsx
|
|
68
|
+
<AlertDialog
|
|
69
|
+
open={isOpen}
|
|
70
|
+
variant="destructive"
|
|
71
|
+
title="Delete project?"
|
|
72
|
+
description="This permanently removes the project and cannot be undone."
|
|
73
|
+
onConfirm={remove}
|
|
74
|
+
onCancel={() => setIsOpen(false)}
|
|
75
|
+
/>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Custom action labels
|
|
79
|
+
|
|
80
|
+
```jsx
|
|
81
|
+
<AlertDialog
|
|
82
|
+
open={isOpen}
|
|
83
|
+
title="Sign out?"
|
|
84
|
+
description="Unsaved changes will be lost."
|
|
85
|
+
labels={{ confirm: 'Sign out', cancel: 'Stay' }}
|
|
86
|
+
onConfirm={signOut}
|
|
87
|
+
onCancel={() => setIsOpen(false)}
|
|
88
|
+
/>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Boundaries
|
|
92
|
+
|
|
93
|
+
| Area | Level | Note |
|
|
94
|
+
| ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
95
|
+
| dismiss behavior | strict | No light-dismiss — closing must go through onConfirm/onCancel |
|
|
96
|
+
| action labels | flexible | confirm/cancel copy overridable via labels; defaults come from the i18n catalog |
|
|
97
|
+
| token names | strict | Visual styling resolves to semantic --cascivo-color-\* tokens; destructive variant uses --cascivo-color-destructive |
|
|
98
|
+
|
|
99
|
+
## AI context prompt
|
|
100
|
+
|
|
101
|
+
Copy this into an LLM context bar before editing this component:
|
|
102
|
+
|
|
103
|
+
```text
|
|
104
|
+
I am modifying the cascivo AlertDialog component (overlay). Confirmation dialog requiring explicit user action; no light-dismiss
|
|
105
|
+
|
|
106
|
+
Architecture constraints — follow exactly:
|
|
107
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
108
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
109
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
110
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
111
|
+
- CSS logical properties only (RTL-safe).
|
|
112
|
+
|
|
113
|
+
AlertDialog is strictly bound to these tokens — use only these, do not invent token names:
|
|
114
|
+
--cascivo-color-surface, --cascivo-color-border, --cascivo-radius-lg, --cascivo-shadow-xl, --cascivo-motion-enter, --cascivo-motion-exit, --cascivo-color-accent, --cascivo-color-destructive
|
|
115
|
+
|
|
116
|
+
Accessibility: role "alertdialog", WCAG 2.2-AA, keyboard: Tab/Shift+Tab/Enter/Space. Keep it AA.
|
|
117
|
+
|
|
118
|
+
Do not change (strict): dismiss behavior — No light-dismiss — closing must go through onConfirm/onCancel; token names — Visual styling resolves to semantic --cascivo-color-* tokens; destructive variant uses --cascivo-color-destructive
|
|
119
|
+
Flexible: action labels.
|
|
120
|
+
|
|
121
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
122
|
+
```
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Alert
|
|
2
|
+
|
|
3
|
+
**Category:** display
|
|
4
|
+
**Description:** Highlights a short, important message inline
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Surfacing a persistent, contextual message inline within a view (warning, error, info, success)
|
|
9
|
+
- Communicating status that should stay visible until read or resolved
|
|
10
|
+
- Offering an inline recovery action tied to the message (action prop)
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
|
|
14
|
+
- Transient confirmation that should auto-dismiss — use Toast
|
|
15
|
+
- Blocking the user for a decision — use Modal or AlertDialog
|
|
16
|
+
|
|
17
|
+
## Anti-patterns
|
|
18
|
+
|
|
19
|
+
### Alerts persist by design; auto-hiding important inline context risks the user missing it
|
|
20
|
+
|
|
21
|
+
**Bad:** `Auto-dismissing an Alert on a timer to mimic a notification`
|
|
22
|
+
**Good:** `<Toast> for ephemeral feedback`
|
|
23
|
+
**Why:** Alerts persist by design; auto-hiding important inline context risks the user missing it
|
|
24
|
+
|
|
25
|
+
## Related components
|
|
26
|
+
|
|
27
|
+
- **Toast** (alternative): Toast auto-dismisses and floats; Alert persists inline in the layout
|
|
28
|
+
- **AlertDialog** (alternative): Use AlertDialog when the message must block and demand a choice
|
|
29
|
+
|
|
30
|
+
## Accessibility rationale
|
|
31
|
+
|
|
32
|
+
role="alert" makes assistive tech announce the message when it appears; the dismiss control is a real button so it is reachable and labeled, and color is paired with an icon/title so meaning is not conveyed by hue alone
|
|
33
|
+
|
|
34
|
+
## Props
|
|
35
|
+
|
|
36
|
+
| Name | Type | Required | Default | Description |
|
|
37
|
+
| ------------- | ---------------------------------------------------------------- | -------- | ------- | ---------------------------------------------------- |
|
|
38
|
+
| `variant` | `'default' \| 'info' \| 'success' \| 'warning' \| 'destructive'` | No | default | Selects the visual style variant. |
|
|
39
|
+
| `title` | `string` | No | — | Title text for the component. |
|
|
40
|
+
| `icon` | `ReactNode` | No | — | Icon element rendered in the component. |
|
|
41
|
+
| `dismissible` | `boolean` | No | false | When true, shows a control to dismiss the component. |
|
|
42
|
+
| `onDismiss` | `() => void` | No | — | Called when the component is dismissed. |
|
|
43
|
+
| `action` | `{ label: string; onClick: () => void }` | No | — | Primary action shown in the component. |
|
|
44
|
+
|
|
45
|
+
## Tokens
|
|
46
|
+
|
|
47
|
+
- `--cascivo-color-info`
|
|
48
|
+
- `--cascivo-color-success`
|
|
49
|
+
- `--cascivo-color-warning`
|
|
50
|
+
- `--cascivo-color-destructive`
|
|
51
|
+
- `--cascivo-color-border`
|
|
52
|
+
- `--cascivo-radius-md`
|
|
53
|
+
|
|
54
|
+
## Examples
|
|
55
|
+
|
|
56
|
+
### Info
|
|
57
|
+
|
|
58
|
+
```jsx
|
|
59
|
+
<Alert variant="info" title="Heads up">
|
|
60
|
+
Your trial ends soon.
|
|
61
|
+
</Alert>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Dismissible
|
|
65
|
+
|
|
66
|
+
```jsx
|
|
67
|
+
<Alert variant="success" dismissible title="Saved">
|
|
68
|
+
Changes saved.
|
|
69
|
+
</Alert>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Actionable
|
|
73
|
+
|
|
74
|
+
```jsx
|
|
75
|
+
<Alert variant="warning" title="Update available" action={{ label: 'Update now', onClick: update }}>
|
|
76
|
+
A new version is ready.
|
|
77
|
+
</Alert>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Boundaries
|
|
81
|
+
|
|
82
|
+
| Area | Level | Note |
|
|
83
|
+
| ----------- | -------- | -------------------------------------------------------------------------------- |
|
|
84
|
+
| variant | flexible | Choose the severity variant that matches the message; default is neutral |
|
|
85
|
+
| token names | strict | Severity colors must resolve to --cascivo-color-info/success/warning/destructive |
|
|
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 Alert component (display). Highlights a short, important message inline
|
|
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
|
+
Alert is strictly bound to these tokens — use only these, do not invent token names:
|
|
102
|
+
--cascivo-color-info, --cascivo-color-success, --cascivo-color-warning, --cascivo-color-destructive, --cascivo-color-border, --cascivo-radius-md
|
|
103
|
+
|
|
104
|
+
Accessibility: role "alert", WCAG 2.2-AA. Keep it AA.
|
|
105
|
+
|
|
106
|
+
Do not change (strict): token names — Severity colors must resolve to --cascivo-color-info/success/warning/destructive
|
|
107
|
+
Flexible: variant.
|
|
108
|
+
|
|
109
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
110
|
+
```
|