@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
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Field
|
|
2
|
+
|
|
3
|
+
**Category:** inputs
|
|
4
|
+
**Description:** Form-field wrapper composing label, control, description, and error
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Pairing a single control with its label, helper text, and validation message
|
|
9
|
+
- Wiring aria-describedby / aria-invalid automatically instead of by hand
|
|
10
|
+
|
|
11
|
+
## When NOT to use
|
|
12
|
+
|
|
13
|
+
- A standalone control that needs no label, description, or error
|
|
14
|
+
- Grouping multiple related controls — use a <fieldset> with a <legend>
|
|
15
|
+
|
|
16
|
+
## Anti-patterns
|
|
17
|
+
|
|
18
|
+
### Field clones exactly one child control to inject its id and aria wiring; multiple children break the association
|
|
19
|
+
|
|
20
|
+
**Bad:** `<Field label="Email"><Input /><Input /></Field>`
|
|
21
|
+
**Good:** `<Field label="Email"><Input /></Field>`
|
|
22
|
+
**Why:** Field clones exactly one child control to inject its id and aria wiring; multiple children break the association
|
|
23
|
+
|
|
24
|
+
### Hand-wired markup easily drifts: missing ids, no role="alert", mismatched aria-describedby — Field keeps them in sync
|
|
25
|
+
|
|
26
|
+
**Bad:** `<div><label>Email</label><input aria-invalid /><span>Error</span></div>`
|
|
27
|
+
**Good:** `<Field label="Email" error="Error"><Input /></Field>`
|
|
28
|
+
**Why:** Hand-wired markup easily drifts: missing ids, no role="alert", mismatched aria-describedby — Field keeps them in sync
|
|
29
|
+
|
|
30
|
+
## Related components
|
|
31
|
+
|
|
32
|
+
- **Label** (contains): Field renders a Label and links it to the control via htmlFor
|
|
33
|
+
- **Input** (contains): The control passed as children receives the generated id and aria attributes
|
|
34
|
+
|
|
35
|
+
## Accessibility rationale
|
|
36
|
+
|
|
37
|
+
Generates stable ids with useId and links them through htmlFor and aria-describedby; the error carries role="alert" so it is announced on appearance, and aria-invalid marks the control invalid for assistive tech
|
|
38
|
+
|
|
39
|
+
## Props
|
|
40
|
+
|
|
41
|
+
| Name | Type | Required | Default | Description |
|
|
42
|
+
| ------------- | -------------- | -------- | ------- | ------------------------------------------------------------------ |
|
|
43
|
+
| `label` | `ReactNode` | No | — | Text label for the control. |
|
|
44
|
+
| `description` | `ReactNode` | No | — | Supporting description text. |
|
|
45
|
+
| `error` | `ReactNode` | No | — | Error message shown when the value is invalid. |
|
|
46
|
+
| `required` | `boolean` | No | false | When true, marks the field as required. |
|
|
47
|
+
| `disabled` | `boolean` | No | false | When true, disables the control and removes it from the tab order. |
|
|
48
|
+
| `id` | `string` | No | — | Id applied to the root element (auto-generated when omitted). |
|
|
49
|
+
| `children` | `ReactElement` | Yes | — | Content rendered inside the component. |
|
|
50
|
+
|
|
51
|
+
## Tokens
|
|
52
|
+
|
|
53
|
+
- `--cascivo-space-2`
|
|
54
|
+
- `--cascivo-font-sans`
|
|
55
|
+
- `--cascivo-text-sm`
|
|
56
|
+
- `--cascivo-leading-snug`
|
|
57
|
+
- `--cascivo-color-text-muted`
|
|
58
|
+
- `--cascivo-color-destructive`
|
|
59
|
+
|
|
60
|
+
## Examples
|
|
61
|
+
|
|
62
|
+
### Basic
|
|
63
|
+
|
|
64
|
+
```jsx
|
|
65
|
+
<Field label="Email">
|
|
66
|
+
<Input type="email" />
|
|
67
|
+
</Field>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### With description
|
|
71
|
+
|
|
72
|
+
```jsx
|
|
73
|
+
<Field label="Email" description="We never share it.">
|
|
74
|
+
<Input />
|
|
75
|
+
</Field>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### With error
|
|
79
|
+
|
|
80
|
+
Sets aria-invalid on the control and announces the error via role="alert".
|
|
81
|
+
|
|
82
|
+
```jsx
|
|
83
|
+
<Field label="Email" error="Email is required" required>
|
|
84
|
+
<Input />
|
|
85
|
+
</Field>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Boundaries
|
|
89
|
+
|
|
90
|
+
| Area | Level | Note |
|
|
91
|
+
| --------------- | -------- | ---------------------------------------------------------------------- |
|
|
92
|
+
| token names | strict | Spacing and color must resolve to --cascivo-\* semantic tokens |
|
|
93
|
+
| control element | flexible | Any single element accepting id/aria-\* props can be the child control |
|
|
94
|
+
|
|
95
|
+
## AI context prompt
|
|
96
|
+
|
|
97
|
+
Copy this into an LLM context bar before editing this component:
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
I am modifying the cascivo Field component (inputs). Form-field wrapper composing label, control, description, and error
|
|
101
|
+
|
|
102
|
+
Architecture constraints — follow exactly:
|
|
103
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
104
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
105
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
106
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
107
|
+
- CSS logical properties only (RTL-safe).
|
|
108
|
+
|
|
109
|
+
Field is strictly bound to these tokens — use only these, do not invent token names:
|
|
110
|
+
--cascivo-space-2, --cascivo-font-sans, --cascivo-text-sm, --cascivo-leading-snug, --cascivo-color-text-muted, --cascivo-color-destructive
|
|
111
|
+
|
|
112
|
+
Accessibility: role "group", WCAG 2.2-AA. Keep it AA.
|
|
113
|
+
|
|
114
|
+
Do not change (strict): token names — Spacing and color must resolve to --cascivo-* semantic tokens
|
|
115
|
+
Flexible: control element.
|
|
116
|
+
|
|
117
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
118
|
+
```
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# FileUploader
|
|
2
|
+
|
|
3
|
+
**Category:** inputs
|
|
4
|
+
**Description:** Drag-and-drop file upload zone with file list and status indicators.
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Letting users attach one or more files via click-to-browse or drag-and-drop
|
|
9
|
+
- Showing per-file upload progress and status (uploading, complete, error) in a list
|
|
10
|
+
- Enforcing client-side accept/maxSize constraints with a callback for rejected files
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
|
|
14
|
+
- A single short text value — use Input
|
|
15
|
+
- Choosing from a fixed set of options rather than supplying a file — use Select or MultiSelect
|
|
16
|
+
|
|
17
|
+
## Anti-patterns
|
|
18
|
+
|
|
19
|
+
### The file list is controlled — without wiring files/onFilesAdded/onRemove nothing renders in the list and status cannot update
|
|
20
|
+
|
|
21
|
+
**Bad:** `Treating the component as uncontrolled and ignoring onFilesAdded`
|
|
22
|
+
**Good:** `Track accepted files in state and pass them back via the files prop`
|
|
23
|
+
**Why:** The file list is controlled — without wiring files/onFilesAdded/onRemove nothing renders in the list and status cannot update
|
|
24
|
+
|
|
25
|
+
### Client-side accept/maxSize are UX filters, not enforcement; a determined user can bypass them
|
|
26
|
+
|
|
27
|
+
**Bad:** `Relying only on accept/maxSize for security`
|
|
28
|
+
**Good:** `Re-validate type and size on the server after upload`
|
|
29
|
+
**Why:** Client-side accept/maxSize are UX filters, not enforcement; a determined user can bypass them
|
|
30
|
+
|
|
31
|
+
## Related components
|
|
32
|
+
|
|
33
|
+
- **Form** (pairs-with): Place the uploader inside a Form when files are part of a larger submission
|
|
34
|
+
- **Input** (alternative): Use a plain text Input when capturing a value rather than a file
|
|
35
|
+
|
|
36
|
+
## Accessibility rationale
|
|
37
|
+
|
|
38
|
+
The drop zone is a real <button> so it is keyboard-operable (Enter/Space open the native file picker), the hidden file input is removed from the tab order and labelled via aria-describedby, and the file list uses aria-live="polite" so status changes are announced; each remove control carries an aria-label naming its file.
|
|
39
|
+
|
|
40
|
+
## Props
|
|
41
|
+
|
|
42
|
+
| Name | Type | Required | Default | Description |
|
|
43
|
+
| -------------- | --------------------------------------------------- | -------- | ------- | --------------------------------------- |
|
|
44
|
+
| `files` | `UploaderFile[]` | No | — | Controlled file list |
|
|
45
|
+
| `onFilesAdded` | `(files: File[]) => void` | No | — | Called with accepted files |
|
|
46
|
+
| `onRemove` | `(id: string) => void` | No | — | Called when a file is removed |
|
|
47
|
+
| `multiple` | `boolean` | No | — | Allow multiple files |
|
|
48
|
+
| `accept` | `string` | No | — | Accepted file types (MIME or extension) |
|
|
49
|
+
| `maxSize` | `number` | No | — | Maximum file size in bytes |
|
|
50
|
+
| `onRejected` | `(files: File[], reason: 'size' \| 'type') => void` | No | — | Called with rejected files |
|
|
51
|
+
| `label` | `string` | No | — | Field label |
|
|
52
|
+
| `hint` | `string` | No | — | Hint text below the drop zone |
|
|
53
|
+
| `labels` | `FileUploaderLabels` | No | — | i18n label overrides |
|
|
54
|
+
| `disabled` | `boolean` | No | — | Disables the upload zone |
|
|
55
|
+
|
|
56
|
+
## Tokens
|
|
57
|
+
|
|
58
|
+
- `--cascivo-color-accent`
|
|
59
|
+
- `--cascivo-color-accent-subtle`
|
|
60
|
+
- `--cascivo-color-success`
|
|
61
|
+
- `--cascivo-color-danger`
|
|
62
|
+
- `--cascivo-color-danger-subtle`
|
|
63
|
+
|
|
64
|
+
## Examples
|
|
65
|
+
|
|
66
|
+
### Basic
|
|
67
|
+
|
|
68
|
+
Single file upload zone
|
|
69
|
+
|
|
70
|
+
```jsx
|
|
71
|
+
<FileUploader onFilesAdded={console.log} />
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Multiple
|
|
75
|
+
|
|
76
|
+
Accept multiple files
|
|
77
|
+
|
|
78
|
+
```jsx
|
|
79
|
+
<FileUploader multiple onFilesAdded={console.log} />
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### With files
|
|
83
|
+
|
|
84
|
+
Shows file list
|
|
85
|
+
|
|
86
|
+
```jsx
|
|
87
|
+
<FileUploader files={[{ id: '1', name: 'report.pdf', size: 102400, status: 'complete' }]} />
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Boundaries
|
|
91
|
+
|
|
92
|
+
| Area | Level | Note |
|
|
93
|
+
| ---------------------------- | -------- | -------------------------------------------------------------------------- |
|
|
94
|
+
| token names | strict | Status colors must resolve to --cascivo-color-accent/success/danger tokens |
|
|
95
|
+
| label and hint copy | flexible | Overridable via label/hint props or the labels object |
|
|
96
|
+
| accept / maxSize constraints | flexible | Configure freely; rejected files surface through onRejected |
|
|
97
|
+
|
|
98
|
+
## AI context prompt
|
|
99
|
+
|
|
100
|
+
Copy this into an LLM context bar before editing this component:
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
I am modifying the cascivo FileUploader component (inputs). Drag-and-drop file upload zone with file list and status indicators.
|
|
104
|
+
|
|
105
|
+
Architecture constraints — follow exactly:
|
|
106
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
107
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
108
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
109
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
110
|
+
- CSS logical properties only (RTL-safe).
|
|
111
|
+
|
|
112
|
+
FileUploader is strictly bound to these tokens — use only these, do not invent token names:
|
|
113
|
+
--cascivo-color-accent, --cascivo-color-accent-subtle, --cascivo-color-success, --cascivo-color-danger, --cascivo-color-danger-subtle
|
|
114
|
+
|
|
115
|
+
Accessibility: role "button", WCAG 2.2-AA, keyboard: Enter/Space. Keep it AA.
|
|
116
|
+
|
|
117
|
+
Do not change (strict): token names — Status colors must resolve to --cascivo-color-accent/success/danger tokens
|
|
118
|
+
Flexible: label and hint copy, accept / maxSize constraints.
|
|
119
|
+
|
|
120
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
121
|
+
```
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Filter
|
|
2
|
+
|
|
3
|
+
**Category:** inputs
|
|
4
|
+
**Description:** A group of toggleable pill or outline buttons for filtering content by category
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Tag or category filtering on listing pages where the active filters must remain visible
|
|
9
|
+
- Facet chips that toggle content visibility (e.g. product categories, team labels)
|
|
10
|
+
|
|
11
|
+
## When NOT to use
|
|
12
|
+
|
|
13
|
+
- Navigation between distinct views — use Tabs
|
|
14
|
+
- A binary on/off switch — use Toggle
|
|
15
|
+
- Form field for selecting a value — use Select or Checkbox
|
|
16
|
+
|
|
17
|
+
## Anti-patterns
|
|
18
|
+
|
|
19
|
+
### Filter is for narrowing visible content, not routing between views
|
|
20
|
+
|
|
21
|
+
**Bad:** `<Filter options={statusOptions} onChange={navigate} />`
|
|
22
|
+
**Good:** `<Tabs items={statusTabs} />`
|
|
23
|
+
**Why:** Filter is for narrowing visible content, not routing between views
|
|
24
|
+
|
|
25
|
+
## Related components
|
|
26
|
+
|
|
27
|
+
- **Tabs** (alternative): Tabs navigate between views; Filter narrows displayed content
|
|
28
|
+
- **Toggle** (alternative): Toggle is the binary on/off primitive; Filter handles multi-option sets
|
|
29
|
+
- **Tag** (pairs-with): Tag displays the currently active filters as dismissible chips
|
|
30
|
+
|
|
31
|
+
## Accessibility rationale
|
|
32
|
+
|
|
33
|
+
Wraps buttons in a role="group" so screen readers announce the group label; each button uses aria-pressed to communicate selected state without relying on color alone
|
|
34
|
+
|
|
35
|
+
## Props
|
|
36
|
+
|
|
37
|
+
| Name | Type | Required | Default | Description |
|
|
38
|
+
| -------------- | ------------------------------ | -------- | ------- | ------------------------------------------------------------- |
|
|
39
|
+
| `options` | `FilterOption[]` | Yes | — | Array of { label, value } objects to render as filter buttons |
|
|
40
|
+
| `value` | `string[]` | No | — | Controlled selected values |
|
|
41
|
+
| `defaultValue` | `string[]` | No | [] | Initial selected values for uncontrolled use |
|
|
42
|
+
| `onChange` | `(selected: string[]) => void` | No | — | Called when the value changes. |
|
|
43
|
+
| `multi` | `boolean` | No | false | Allow multiple items to be selected simultaneously |
|
|
44
|
+
| `variant` | `'pill' \| 'outline'` | No | pill | Selects the visual style variant. |
|
|
45
|
+
|
|
46
|
+
## Tokens
|
|
47
|
+
|
|
48
|
+
- `--cascivo-radius-full`
|
|
49
|
+
- `--cascivo-border-default`
|
|
50
|
+
- `--cascivo-color-text-subtle`
|
|
51
|
+
- `--cascivo-color-text`
|
|
52
|
+
- `--cascivo-color-active-bg`
|
|
53
|
+
- `--cascivo-color-accent`
|
|
54
|
+
- `--cascivo-color-accent-content`
|
|
55
|
+
- `--cascivo-ring-width`
|
|
56
|
+
- `--cascivo-ring-color`
|
|
57
|
+
- `--cascivo-ease-out`
|
|
58
|
+
|
|
59
|
+
## Examples
|
|
60
|
+
|
|
61
|
+
### Single-select
|
|
62
|
+
|
|
63
|
+
```jsx
|
|
64
|
+
<Filter
|
|
65
|
+
options={[
|
|
66
|
+
{ label: 'All', value: 'all' },
|
|
67
|
+
{ label: 'Active', value: 'active' },
|
|
68
|
+
{ label: 'Archived', value: 'archived' },
|
|
69
|
+
]}
|
|
70
|
+
aria-label="Filter by status"
|
|
71
|
+
/>
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Multi-select
|
|
75
|
+
|
|
76
|
+
```jsx
|
|
77
|
+
<Filter
|
|
78
|
+
multi
|
|
79
|
+
options={[
|
|
80
|
+
{ label: 'Design', value: 'design' },
|
|
81
|
+
{ label: 'Engineering', value: 'engineering' },
|
|
82
|
+
{ label: 'Marketing', value: 'marketing' },
|
|
83
|
+
]}
|
|
84
|
+
aria-label="Filter by team"
|
|
85
|
+
/>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Outline variant
|
|
89
|
+
|
|
90
|
+
```jsx
|
|
91
|
+
<Filter
|
|
92
|
+
variant="outline"
|
|
93
|
+
options={[
|
|
94
|
+
{ label: 'React', value: 'react' },
|
|
95
|
+
{ label: 'Vue', value: 'vue' },
|
|
96
|
+
]}
|
|
97
|
+
aria-label="Filter by framework"
|
|
98
|
+
/>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Boundaries
|
|
102
|
+
|
|
103
|
+
| Area | Level | Note |
|
|
104
|
+
| ------- | -------- | ----------------------------------------------------------------------------------------------- |
|
|
105
|
+
| variant | flexible | pill suits floating filter bars; outline suits embedded filter rows within a bordered container |
|
|
106
|
+
| multi | flexible | single-select for mutually exclusive categories; multi for additive facets |
|
|
107
|
+
|
|
108
|
+
## AI context prompt
|
|
109
|
+
|
|
110
|
+
Copy this into an LLM context bar before editing this component:
|
|
111
|
+
|
|
112
|
+
```text
|
|
113
|
+
I am modifying the cascivo Filter component (inputs). A group of toggleable pill or outline buttons for filtering content by category
|
|
114
|
+
|
|
115
|
+
Architecture constraints — follow exactly:
|
|
116
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
117
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
118
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
119
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
120
|
+
- CSS logical properties only (RTL-safe).
|
|
121
|
+
|
|
122
|
+
Filter is strictly bound to these tokens — use only these, do not invent token names:
|
|
123
|
+
--cascivo-radius-full, --cascivo-border-default, --cascivo-color-text-subtle, --cascivo-color-text, --cascivo-color-active-bg, --cascivo-color-accent, --cascivo-color-accent-content, --cascivo-ring-width, --cascivo-ring-color, --cascivo-ease-out
|
|
124
|
+
|
|
125
|
+
Accessibility: role "group", WCAG 2.2-AA, keyboard: Tab/Enter/Space. Keep it AA.
|
|
126
|
+
Flexible: variant, multi.
|
|
127
|
+
|
|
128
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
129
|
+
```
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# FlowBackground
|
|
2
|
+
|
|
3
|
+
**Category:** display
|
|
4
|
+
**Description:** Decorative dots / grid / cross canvas background, drawn purely in CSS gradients.
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Giving a flow canvas a sense of space and scale with a dotted or grid backdrop
|
|
9
|
+
- Reinforcing pan/zoom by letting the pattern move and scale with the viewport
|
|
10
|
+
|
|
11
|
+
## When NOT to use
|
|
12
|
+
|
|
13
|
+
- As a page background — this is a flow-canvas decoration, not a general surface
|
|
14
|
+
|
|
15
|
+
## Anti-patterns
|
|
16
|
+
|
|
17
|
+
### Per-cell DOM is needlessly expensive; one repeating gradient costs nothing.
|
|
18
|
+
|
|
19
|
+
**Bad:** `Rendering a DOM node per grid cell`
|
|
20
|
+
**Good:** `A single CSS gradient layer`
|
|
21
|
+
**Why:** Per-cell DOM is needlessly expensive; one repeating gradient costs nothing.
|
|
22
|
+
|
|
23
|
+
## Related components
|
|
24
|
+
|
|
25
|
+
- **FlowCanvas** (contained-by): Lives inside the canvas pane.
|
|
26
|
+
|
|
27
|
+
## Accessibility rationale
|
|
28
|
+
|
|
29
|
+
Purely decorative — marked aria-hidden and presentation, never in the a11y tree.
|
|
30
|
+
|
|
31
|
+
## Props
|
|
32
|
+
|
|
33
|
+
| Name | Type | Required | Default | Description |
|
|
34
|
+
| ----------- | ----------------------------- | -------- | ------- | -------------------------------------------------------- |
|
|
35
|
+
| `variant` | `'dots' \| 'grid' \| 'cross'` | No | dots | Pattern style. |
|
|
36
|
+
| `gap` | `number` | No | 20 | Cell spacing (px). |
|
|
37
|
+
| `size` | `number` | No | 1 | Dot radius / line thickness (px). |
|
|
38
|
+
| `color` | `string` | No | — | Pattern color (defaults to the border token). |
|
|
39
|
+
| `className` | `string` | No | — | Additional CSS class names merged onto the root element. |
|
|
40
|
+
|
|
41
|
+
## Tokens
|
|
42
|
+
|
|
43
|
+
- `--cascivo-color-border`
|
|
44
|
+
|
|
45
|
+
## Examples
|
|
46
|
+
|
|
47
|
+
### Dotted background
|
|
48
|
+
|
|
49
|
+
A dotted grid behind a flow canvas.
|
|
50
|
+
|
|
51
|
+
```jsx
|
|
52
|
+
;() => (
|
|
53
|
+
<div style={{ position: 'relative', height: 220, overflow: 'hidden' }}>
|
|
54
|
+
<FlowBackground variant="dots" gap={24} />
|
|
55
|
+
</div>
|
|
56
|
+
)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Grid and cross
|
|
60
|
+
|
|
61
|
+
The grid and cross variants.
|
|
62
|
+
|
|
63
|
+
```jsx
|
|
64
|
+
;() => (
|
|
65
|
+
<div style={{ display: 'grid', gap: 16, gridTemplateColumns: '1fr 1fr' }}>
|
|
66
|
+
<div style={{ position: 'relative', height: 180, overflow: 'hidden' }}>
|
|
67
|
+
<FlowBackground variant="grid" gap={28} />
|
|
68
|
+
</div>
|
|
69
|
+
<div style={{ position: 'relative', height: 180, overflow: 'hidden' }}>
|
|
70
|
+
<FlowBackground variant="cross" gap={28} size={4} />
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Boundaries
|
|
77
|
+
|
|
78
|
+
| Area | Level | Note |
|
|
79
|
+
| ------- | -------- | ------------------------------------------------- |
|
|
80
|
+
| pattern | flexible | dots \| grid \| cross with configurable gap/size. |
|
|
81
|
+
|
|
82
|
+
## AI context prompt
|
|
83
|
+
|
|
84
|
+
Copy this into an LLM context bar before editing this component:
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
I am modifying the cascivo FlowBackground component (display). Decorative dots / grid / cross canvas background, drawn purely in CSS gradients.
|
|
88
|
+
|
|
89
|
+
Architecture constraints — follow exactly:
|
|
90
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
91
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
92
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
93
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
94
|
+
- CSS logical properties only (RTL-safe).
|
|
95
|
+
|
|
96
|
+
FlowBackground is strictly bound to these tokens — use only these, do not invent token names:
|
|
97
|
+
--cascivo-color-border
|
|
98
|
+
|
|
99
|
+
Accessibility: role "presentation", WCAG 2.1-AA. Keep it AA.
|
|
100
|
+
Flexible: pattern.
|
|
101
|
+
|
|
102
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
103
|
+
```
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# FlowCanvas
|
|
2
|
+
|
|
3
|
+
**Category:** display
|
|
4
|
+
**Description:** The pan/zoom canvas pane — a single CSS-transformed layer driven by the viewport signal.
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Hosting a hand-composed flow from low-level FlowNode/FlowEdge primitives
|
|
9
|
+
- When you need direct control of the viewport, pan, and zoom
|
|
10
|
+
|
|
11
|
+
## When NOT to use
|
|
12
|
+
|
|
13
|
+
- For the common case — prefer the declarative <Flow nodes edges /> instead
|
|
14
|
+
|
|
15
|
+
## Related components
|
|
16
|
+
|
|
17
|
+
- **Flow** (alternative): The declarative data-driven wrapper.
|
|
18
|
+
- **FlowBackground** (contains): A common child.
|
|
19
|
+
|
|
20
|
+
## Accessibility rationale
|
|
21
|
+
|
|
22
|
+
role="application" — the pane is an interactive canvas with pointer gestures.
|
|
23
|
+
|
|
24
|
+
## Props
|
|
25
|
+
|
|
26
|
+
| Name | Type | Required | Default | Description |
|
|
27
|
+
| ------------------ | ---------------------------------------- | -------- | ------- | -------------------------------------------------------- |
|
|
28
|
+
| `children` | `ReactNode` | No | — | Background, nodes, edges. |
|
|
29
|
+
| `viewport` | `{ x: number; y: number; zoom: number }` | No | — | Controlled viewport. |
|
|
30
|
+
| `onViewportChange` | `(viewport: Viewport) => void` | No | — | Viewport change callback. |
|
|
31
|
+
| `minZoom` | `number` | No | 0.2 | Lower bound for the viewport zoom level. |
|
|
32
|
+
| `maxZoom` | `number` | No | 2 | Upper bound for the viewport zoom level. |
|
|
33
|
+
| `panOnDrag` | `boolean` | No | true | Drag the empty pane to pan the viewport. |
|
|
34
|
+
| `zoomOnScroll` | `boolean` | No | true | Wheel or pinch to zoom the viewport. |
|
|
35
|
+
| `fitView` | `boolean` | No | false | Frame the whole graph once on mount. |
|
|
36
|
+
| `className` | `string` | No | — | Additional CSS class names merged onto the root element. |
|
|
37
|
+
|
|
38
|
+
## Tokens
|
|
39
|
+
|
|
40
|
+
- `--cascivo-color-bg`
|
|
41
|
+
- `--cascivo-radius-surface`
|
|
42
|
+
|
|
43
|
+
## Examples
|
|
44
|
+
|
|
45
|
+
### Empty canvas with a background
|
|
46
|
+
|
|
47
|
+
```jsx
|
|
48
|
+
;() => (
|
|
49
|
+
<FlowCanvas style={{ height: 240 }}>
|
|
50
|
+
<FlowBackground />
|
|
51
|
+
</FlowCanvas>
|
|
52
|
+
)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Boundaries
|
|
56
|
+
|
|
57
|
+
| Area | Level | Note |
|
|
58
|
+
| -------- | -------- | ---------------------------------- |
|
|
59
|
+
| viewport | flexible | Controllable; pan/zoom toggleable. |
|
|
60
|
+
|
|
61
|
+
## AI context prompt
|
|
62
|
+
|
|
63
|
+
Copy this into an LLM context bar before editing this component:
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
I am modifying the cascivo FlowCanvas component (display). The pan/zoom canvas pane — a single CSS-transformed layer driven by the viewport signal.
|
|
67
|
+
|
|
68
|
+
Architecture constraints — follow exactly:
|
|
69
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
70
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
71
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
72
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
73
|
+
- CSS logical properties only (RTL-safe).
|
|
74
|
+
|
|
75
|
+
FlowCanvas is strictly bound to these tokens — use only these, do not invent token names:
|
|
76
|
+
--cascivo-color-bg, --cascivo-radius-surface
|
|
77
|
+
|
|
78
|
+
Accessibility: role "application", WCAG 2.1-AA, keyboard: Tab (focus)/Drag (pan)/Wheel (zoom). Keep it AA.
|
|
79
|
+
Flexible: viewport.
|
|
80
|
+
|
|
81
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
82
|
+
```
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# FlowControls
|
|
2
|
+
|
|
3
|
+
**Category:** display
|
|
4
|
+
**Description:** Zoom in / out / fit-view controls for a flow canvas — real, i18n-labeled buttons.
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Giving users explicit zoom/fit controls on a flow canvas
|
|
9
|
+
|
|
10
|
+
## When NOT to use
|
|
11
|
+
|
|
12
|
+
- When the canvas is static/non-interactive
|
|
13
|
+
|
|
14
|
+
## Related components
|
|
15
|
+
|
|
16
|
+
- **FlowCanvas** (pairs-with): Calls its viewport actions.
|
|
17
|
+
- **FlowMiniMap** (pairs-with): Complementary navigation chrome.
|
|
18
|
+
|
|
19
|
+
## Accessibility rationale
|
|
20
|
+
|
|
21
|
+
Real <button>s with i18n-defaulted aria-labels; ≥44px coarse targets.
|
|
22
|
+
|
|
23
|
+
## Props
|
|
24
|
+
|
|
25
|
+
| Name | Type | Required | Default | Description |
|
|
26
|
+
| ------------- | -------------------------------------------------------------- | -------- | ----------- | ---------------------------------------------------------- |
|
|
27
|
+
| `position` | `'top-left' \| 'top-right' \| 'bottom-left' \| 'bottom-right'` | No | bottom-left | Position of the component. |
|
|
28
|
+
| `showZoom` | `boolean` | No | true | When true, shows the zoom-in/zoom-out buttons. |
|
|
29
|
+
| `showFitView` | `boolean` | No | true | When true, shows the fit-to-view button. |
|
|
30
|
+
| `onZoomIn` | `() => void` | No | — | Called when the zoom-in control is activated. |
|
|
31
|
+
| `onZoomOut` | `() => void` | No | — | Called when the zoom-out control is activated. |
|
|
32
|
+
| `onFitView` | `() => void` | No | — | Called when the fit-to-view control is activated. |
|
|
33
|
+
| `labels` | `FlowControlsLabels` | No | — | Overrides for the component’s user-visible strings (i18n). |
|
|
34
|
+
| `className` | `string` | No | — | Additional CSS class names merged onto the root element. |
|
|
35
|
+
|
|
36
|
+
## Tokens
|
|
37
|
+
|
|
38
|
+
- `--cascivo-color-surface`
|
|
39
|
+
- `--cascivo-color-border`
|
|
40
|
+
- `--cascivo-target-min-coarse`
|
|
41
|
+
|
|
42
|
+
## Examples
|
|
43
|
+
|
|
44
|
+
### Canvas controls
|
|
45
|
+
|
|
46
|
+
```jsx
|
|
47
|
+
;() => (
|
|
48
|
+
<div
|
|
49
|
+
style={{ position: 'relative', height: 200, border: '1px solid var(--cascivo-color-border)' }}
|
|
50
|
+
>
|
|
51
|
+
<FlowControls onZoomIn={() => {}} onZoomOut={() => {}} onFitView={() => {}} />
|
|
52
|
+
</div>
|
|
53
|
+
)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Boundaries
|
|
57
|
+
|
|
58
|
+
| Area | Level | Note |
|
|
59
|
+
| -------- | -------- | ---------------------- |
|
|
60
|
+
| position | flexible | Four corners. |
|
|
61
|
+
| buttons | flexible | Zoom / fit toggleable. |
|
|
62
|
+
|
|
63
|
+
## AI context prompt
|
|
64
|
+
|
|
65
|
+
Copy this into an LLM context bar before editing this component:
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
I am modifying the cascivo FlowControls component (display). Zoom in / out / fit-view controls for a flow canvas — real, i18n-labeled buttons.
|
|
69
|
+
|
|
70
|
+
Architecture constraints — follow exactly:
|
|
71
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
72
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
73
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
74
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
75
|
+
- CSS logical properties only (RTL-safe).
|
|
76
|
+
|
|
77
|
+
FlowControls is strictly bound to these tokens — use only these, do not invent token names:
|
|
78
|
+
--cascivo-color-surface, --cascivo-color-border, --cascivo-target-min-coarse
|
|
79
|
+
|
|
80
|
+
Accessibility: role "group", WCAG 2.1-AA, keyboard: Tab (focus)/Enter/Space (activate). Keep it AA.
|
|
81
|
+
Flexible: position, buttons.
|
|
82
|
+
|
|
83
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
84
|
+
```
|