@cascivo/mcp 0.1.8 → 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 -22
- 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 +5 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +374 -64
- package/dist/index.mjs.map +1 -1
- package/dist/marketplace.json +70 -0
- package/dist/registry.json +5622 -786
- package/dist/tokens.catalog.json +2375 -0
- package/dist/tokens.variants.json +3291 -0
- package/package.json +4 -3
- package/readme.body.md +53 -22
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
# Comparison
|
|
2
|
+
|
|
3
|
+
**Category:** display
|
|
4
|
+
**Description:** Reveals the difference between two layers with a draggable divider
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Showing the difference between two versions of similar content (before/after edits, original vs processed)
|
|
9
|
+
- Letting users interactively reveal one image or panel over another
|
|
10
|
+
- Side-by-side visual demos where a draggable divider is clearer than two static images
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
|
|
14
|
+
- Comparing more than two items — use a layout or table instead
|
|
15
|
+
- Non-visual data comparison — use a table or chart
|
|
16
|
+
- Static side-by-side images with no need for an interactive reveal
|
|
17
|
+
|
|
18
|
+
## Anti-patterns
|
|
19
|
+
|
|
20
|
+
### The divider is a slider; without a label assistive tech announces an unnamed control
|
|
21
|
+
|
|
22
|
+
**Bad:** `<Comparison before={<Before />} after={<After />} /> with no label`
|
|
23
|
+
**Good:** `<Comparison label="Reveal edited photo" before={<Before />} after={<After />} />`
|
|
24
|
+
**Why:** The divider is a slider; without a label assistive tech announces an unnamed control
|
|
25
|
+
|
|
26
|
+
## Related components
|
|
27
|
+
|
|
28
|
+
- **Slider** (alternative): Use Slider for selecting a numeric value rather than revealing layered content
|
|
29
|
+
- **Carousel** (alternative): Use Carousel to step through more than two pieces of content
|
|
30
|
+
|
|
31
|
+
## Accessibility rationale
|
|
32
|
+
|
|
33
|
+
The divider is a role="slider" with aria-valuemin/max/now and full keyboard support (Arrow/Home/End/PageUp/PageDown); aria-orientation reflects the axis so the value and direction are conveyed without sight
|
|
34
|
+
|
|
35
|
+
## Props
|
|
36
|
+
|
|
37
|
+
| Name | Type | Required | Default | Description |
|
|
38
|
+
| ------------------ | ---------------------------- | -------- | ---------- | ------------------------------------------------------- |
|
|
39
|
+
| `after` | `ReactNode` | Yes | — | Base layer shown underneath |
|
|
40
|
+
| `before` | `ReactNode` | Yes | — | Top layer revealed up to the divider |
|
|
41
|
+
| `position` | `number` | No | — | Divider position 0–100 (controlled) |
|
|
42
|
+
| `defaultPosition` | `number` | No | 50 | The initial divider position (0–100) when uncontrolled. |
|
|
43
|
+
| `onPositionChange` | `(position: number) => void` | No | — | Called with the new divider position when it changes. |
|
|
44
|
+
| `orientation` | `'horizontal' \| 'vertical'` | No | horizontal | Layout orientation of the component. |
|
|
45
|
+
| `keyboardStep` | `number` | No | 5 | How far the divider moves per arrow-key press. |
|
|
46
|
+
| `label` | `string` | No | — | Text label for the control. |
|
|
47
|
+
|
|
48
|
+
## Tokens
|
|
49
|
+
|
|
50
|
+
- `--cascivo-radius-md`
|
|
51
|
+
- `--cascivo-radius-full`
|
|
52
|
+
- `--cascivo-color-surface`
|
|
53
|
+
- `--cascivo-color-border`
|
|
54
|
+
- `--cascivo-color-focus-ring`
|
|
55
|
+
- `--cascivo-shadow-sm`
|
|
56
|
+
- `--cascivo-target-min-coarse`
|
|
57
|
+
|
|
58
|
+
## Examples
|
|
59
|
+
|
|
60
|
+
### Image before/after
|
|
61
|
+
|
|
62
|
+
```jsx
|
|
63
|
+
<Comparison
|
|
64
|
+
before={<img src="/edited.jpg" alt="" />}
|
|
65
|
+
after={<img src="/original.jpg" alt="Original" />}
|
|
66
|
+
label="Reveal edited image"
|
|
67
|
+
/>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Vertical
|
|
71
|
+
|
|
72
|
+
```jsx
|
|
73
|
+
<Comparison orientation="vertical" before={<Before />} after={<After />} />
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Controlled
|
|
77
|
+
|
|
78
|
+
```jsx
|
|
79
|
+
<Comparison
|
|
80
|
+
position={position}
|
|
81
|
+
onPositionChange={setPosition}
|
|
82
|
+
before={<Before />}
|
|
83
|
+
after={<After />}
|
|
84
|
+
/>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Boundaries
|
|
88
|
+
|
|
89
|
+
| Area | Level | Note |
|
|
90
|
+
| ----------- | -------- | -------------------------------------------------------------------- |
|
|
91
|
+
| orientation | flexible | Horizontal or vertical depending on the content |
|
|
92
|
+
| label | strict | Provide a label (or rely on the i18n default) so the slider is named |
|
|
93
|
+
|
|
94
|
+
## AI context prompt
|
|
95
|
+
|
|
96
|
+
Copy this into an LLM context bar before editing this component:
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
I am modifying the cascivo Comparison component (display). Reveals the difference between two layers with a draggable divider
|
|
100
|
+
|
|
101
|
+
Architecture constraints — follow exactly:
|
|
102
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
103
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
104
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
105
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
106
|
+
- CSS logical properties only (RTL-safe).
|
|
107
|
+
|
|
108
|
+
Comparison is strictly bound to these tokens — use only these, do not invent token names:
|
|
109
|
+
--cascivo-radius-md, --cascivo-radius-full, --cascivo-color-surface, --cascivo-color-border, --cascivo-color-focus-ring, --cascivo-shadow-sm, --cascivo-target-min-coarse
|
|
110
|
+
|
|
111
|
+
Accessibility: role "slider", WCAG 2.2-AA, keyboard: ArrowLeft/ArrowRight/ArrowUp/ArrowDown/Home/End/PageUp/PageDown. Keep it AA.
|
|
112
|
+
|
|
113
|
+
Do not change (strict): label — Provide a label (or rely on the i18n default) so the slider is named
|
|
114
|
+
Flexible: orientation.
|
|
115
|
+
|
|
116
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
117
|
+
```
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# ContainedList
|
|
2
|
+
|
|
3
|
+
**Category:** display
|
|
4
|
+
**Description:** Labelled list of rows inside a bordered container
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Grouping a short set of related rows under a visible heading in a bordered surface
|
|
9
|
+
- Presenting selectable or navigable rows (settings groups, member lists)
|
|
10
|
+
- Separating a labelled cluster of items from surrounding page content
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
|
|
14
|
+
- A long, virtualised data set — use a Table or DataList instead
|
|
15
|
+
- Plain bulleted prose where the container border adds no meaning — use List
|
|
16
|
+
|
|
17
|
+
## Anti-patterns
|
|
18
|
+
|
|
19
|
+
### A non-interactive div gives no focus or role semantics to assistive tech
|
|
20
|
+
|
|
21
|
+
**Bad:** `Putting interactive controls on a plain ContainedListItem div`
|
|
22
|
+
**Good:** `Use ContainedListItem asChild with a <button> or <a> so the row is keyboard-focusable`
|
|
23
|
+
**Why:** A non-interactive div gives no focus or role semantics to assistive tech
|
|
24
|
+
|
|
25
|
+
## Related components
|
|
26
|
+
|
|
27
|
+
- **List** (alternative): List is for unbordered prose lists; ContainedList adds a labelled surface
|
|
28
|
+
- **ContainedListItem** (contains): Each row is a ContainedListItem
|
|
29
|
+
|
|
30
|
+
## Accessibility rationale
|
|
31
|
+
|
|
32
|
+
The container heading labels the ul/li structure; interactive rows must slot a real button or link via asChild so role and focus are native, not faked on a div
|
|
33
|
+
|
|
34
|
+
## Props
|
|
35
|
+
|
|
36
|
+
| Name | Type | Required | Default | Description |
|
|
37
|
+
| -------- | -------------------------- | -------- | ------- | -------------------------------------------- |
|
|
38
|
+
| `label` | `ReactNode` | Yes | — | Text label for the control. |
|
|
39
|
+
| `kind` | `'on-page' \| 'disclosed'` | No | on-page | Visual treatment — 'on-page' or 'disclosed'. |
|
|
40
|
+
| `action` | `ReactNode` | No | — | Primary action shown in the component. |
|
|
41
|
+
|
|
42
|
+
## Tokens
|
|
43
|
+
|
|
44
|
+
- `--cascivo-color-surface`
|
|
45
|
+
- `--cascivo-color-border`
|
|
46
|
+
- `--cascivo-color-bg-subtle`
|
|
47
|
+
- `--cascivo-radius-surface`
|
|
48
|
+
- `--cascivo-focus-ring`
|
|
49
|
+
|
|
50
|
+
## Examples
|
|
51
|
+
|
|
52
|
+
### Basic contained list
|
|
53
|
+
|
|
54
|
+
```jsx
|
|
55
|
+
<ContainedList label="Members">
|
|
56
|
+
<ContainedListItem>Ada Lovelace</ContainedListItem>
|
|
57
|
+
<ContainedListItem>Alan Turing</ContainedListItem>
|
|
58
|
+
</ContainedList>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Interactive rows
|
|
62
|
+
|
|
63
|
+
```jsx
|
|
64
|
+
<ContainedList label="Settings" kind="disclosed">
|
|
65
|
+
<ContainedListItem asChild>
|
|
66
|
+
<button type="button" onClick={open}>
|
|
67
|
+
Profile
|
|
68
|
+
</button>
|
|
69
|
+
</ContainedListItem>
|
|
70
|
+
</ContainedList>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Boundaries
|
|
74
|
+
|
|
75
|
+
| Area | Level | Note |
|
|
76
|
+
| -------------- | -------- | ------------------------------------------------------------------------ |
|
|
77
|
+
| kind | flexible | on-page sits inline; disclosed adds a header band for menus and popovers |
|
|
78
|
+
| list semantics | strict | Rows are always ul/li; do not replace with generic divs |
|
|
79
|
+
|
|
80
|
+
## AI context prompt
|
|
81
|
+
|
|
82
|
+
Copy this into an LLM context bar before editing this component:
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
I am modifying the cascivo ContainedList component (display). Labelled list of rows inside a bordered container
|
|
86
|
+
|
|
87
|
+
Architecture constraints — follow exactly:
|
|
88
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
89
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
90
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
91
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
92
|
+
- CSS logical properties only (RTL-safe).
|
|
93
|
+
|
|
94
|
+
ContainedList is strictly bound to these tokens — use only these, do not invent token names:
|
|
95
|
+
--cascivo-color-surface, --cascivo-color-border, --cascivo-color-bg-subtle, --cascivo-radius-surface, --cascivo-focus-ring
|
|
96
|
+
|
|
97
|
+
Accessibility: role "list", WCAG 2.2-AA, keyboard: Tab/Enter/Space. Keep it AA.
|
|
98
|
+
|
|
99
|
+
Do not change (strict): list semantics — Rows are always ul/li; do not replace with generic divs
|
|
100
|
+
Flexible: kind.
|
|
101
|
+
|
|
102
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
103
|
+
```
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# ContextMenu
|
|
2
|
+
|
|
3
|
+
**Category:** overlay
|
|
4
|
+
**Description:** Right-click context menu anchored at pointer coordinates via CSS custom properties
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Offering actions contextual to an element via right-click (rename, delete, copy on a row or canvas item)
|
|
9
|
+
- Power-user surfaces where the desktop right-click affordance is expected
|
|
10
|
+
|
|
11
|
+
## When NOT to use
|
|
12
|
+
|
|
13
|
+
- Primary actions that must be discoverable by all users — right-click is hidden; use a visible Button or Dropdown
|
|
14
|
+
- Selecting a value or filtering a list — use Combobox/Select
|
|
15
|
+
|
|
16
|
+
## Anti-patterns
|
|
17
|
+
|
|
18
|
+
### Right-click is undiscoverable and unavailable on touch, so critical actions become unreachable for many users
|
|
19
|
+
|
|
20
|
+
**Bad:** `Putting the only path to an action behind a right-click ContextMenu`
|
|
21
|
+
**Good:** `Also expose it via a visible Dropdown or Button; treat the context menu as a shortcut`
|
|
22
|
+
**Why:** Right-click is undiscoverable and unavailable on touch, so critical actions become unreachable for many users
|
|
23
|
+
|
|
24
|
+
## Related components
|
|
25
|
+
|
|
26
|
+
- **Dropdown** (alternative): Use a button-triggered menu when actions must be visible and touch-accessible
|
|
27
|
+
- **Menu** (alternative): Use a general menu when the trigger is not a right-click gesture
|
|
28
|
+
|
|
29
|
+
## Accessibility rationale
|
|
30
|
+
|
|
31
|
+
The menu container is role="menu" and items are role="menuitem" with tabIndex management and aria-disabled, and it uses popover="auto" so it light-dismisses on Escape or outside click; the toggle event syncs that dismissal back into state so focus and open state stay consistent
|
|
32
|
+
|
|
33
|
+
## Props
|
|
34
|
+
|
|
35
|
+
| Name | Type | Required | Default | Description |
|
|
36
|
+
| ---------- | ----------------- | -------- | ------- | ------------------------------------------------------------------- |
|
|
37
|
+
| `children` | `React.ReactNode` | Yes | — | The right-click target first, followed by ContextMenuItem children. |
|
|
38
|
+
|
|
39
|
+
## Tokens
|
|
40
|
+
|
|
41
|
+
- `--cascivo-color-surface`
|
|
42
|
+
- `--cascivo-color-border`
|
|
43
|
+
- `--cascivo-radius-md`
|
|
44
|
+
- `--cascivo-shadow-md`
|
|
45
|
+
- `--cascivo-motion-enter`
|
|
46
|
+
- `--cascivo-motion-exit`
|
|
47
|
+
- `--cascivo-color-bg-subtle`
|
|
48
|
+
|
|
49
|
+
## Examples
|
|
50
|
+
|
|
51
|
+
### Basic
|
|
52
|
+
|
|
53
|
+
```jsx
|
|
54
|
+
<ContextMenu>
|
|
55
|
+
<div>Right-click me</div>
|
|
56
|
+
<ContextMenuItem onSelect={rename}>Rename</ContextMenuItem>
|
|
57
|
+
<ContextMenuItem onSelect={remove}>Delete</ContextMenuItem>
|
|
58
|
+
</ContextMenu>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Disabled item
|
|
62
|
+
|
|
63
|
+
```jsx
|
|
64
|
+
<ContextMenu>
|
|
65
|
+
<FileRow file={file} />
|
|
66
|
+
<ContextMenuItem onSelect={copy}>Copy</ContextMenuItem>
|
|
67
|
+
<ContextMenuItem onSelect={paste} disabled>
|
|
68
|
+
Paste
|
|
69
|
+
</ContextMenuItem>
|
|
70
|
+
</ContextMenu>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Boundaries
|
|
74
|
+
|
|
75
|
+
| Area | Level | Note |
|
|
76
|
+
| --------------- | -------- | ---------------------------------------------------------------------------------------------- |
|
|
77
|
+
| menu contents | flexible | Accepts arbitrary ContextMenuItem children after the trigger child |
|
|
78
|
+
| anchor position | strict | Anchored at pointer coordinates via --cascivo-context-x/y custom properties set on right-click |
|
|
79
|
+
|
|
80
|
+
## AI context prompt
|
|
81
|
+
|
|
82
|
+
Copy this into an LLM context bar before editing this component:
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
I am modifying the cascivo ContextMenu component (overlay). Right-click context menu anchored at pointer coordinates via CSS custom properties
|
|
86
|
+
|
|
87
|
+
Architecture constraints — follow exactly:
|
|
88
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
89
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
90
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
91
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
92
|
+
- CSS logical properties only (RTL-safe).
|
|
93
|
+
|
|
94
|
+
ContextMenu is strictly bound to these tokens — use only these, do not invent token names:
|
|
95
|
+
--cascivo-color-surface, --cascivo-color-border, --cascivo-radius-md, --cascivo-shadow-md, --cascivo-motion-enter, --cascivo-motion-exit, --cascivo-color-bg-subtle
|
|
96
|
+
|
|
97
|
+
Accessibility: role "menu", WCAG 2.2-AA, keyboard: ArrowDown/ArrowUp/Enter/Space/Escape. Keep it AA.
|
|
98
|
+
|
|
99
|
+
Do not change (strict): anchor position — Anchored at pointer coordinates via --cascivo-context-x/y custom properties set on right-click
|
|
100
|
+
Flexible: menu contents.
|
|
101
|
+
|
|
102
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
103
|
+
```
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# CopyButton
|
|
2
|
+
|
|
3
|
+
**Category:** inputs
|
|
4
|
+
**Description:** Icon button that copies a value to the clipboard with copied feedback
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Letting users copy a short value to the clipboard — install commands, API keys, tokens, share links
|
|
9
|
+
- Inline next to code snippets or read-only fields where copying is the primary affordance
|
|
10
|
+
|
|
11
|
+
## When NOT to use
|
|
12
|
+
|
|
13
|
+
- Triggering a general action — use Button
|
|
14
|
+
- Copying content the user can already select and edit freely where a copy affordance adds nothing
|
|
15
|
+
|
|
16
|
+
## Anti-patterns
|
|
17
|
+
|
|
18
|
+
### Its click handler is fixed to navigator.clipboard.writeText(value) plus copied feedback — overloading it breaks user expectation
|
|
19
|
+
|
|
20
|
+
**Bad:** `Wiring CopyButton to perform a non-clipboard action via onClick`
|
|
21
|
+
**Good:** `Use Button for arbitrary actions; CopyButton always writes value to the clipboard`
|
|
22
|
+
**Why:** Its click handler is fixed to navigator.clipboard.writeText(value) plus copied feedback — overloading it breaks user expectation
|
|
23
|
+
|
|
24
|
+
## Related components
|
|
25
|
+
|
|
26
|
+
- **Button** (alternative): Use for actions other than copying to clipboard
|
|
27
|
+
- **Input** (pairs-with): Often placed alongside a read-only field whose value it copies
|
|
28
|
+
|
|
29
|
+
## Accessibility rationale
|
|
30
|
+
|
|
31
|
+
Renders a native <button> so Enter/Space, focus, and role come from the platform; the aria-label swaps between copy and copied labels to announce the state change to screen readers since the icon swap alone is silent, and the SVG icons are aria-hidden
|
|
32
|
+
|
|
33
|
+
## Props
|
|
34
|
+
|
|
35
|
+
| Name | Type | Required | Default | Description |
|
|
36
|
+
| -------- | ------------------------------------ | -------- | ------- | ----------------------------------------------------- |
|
|
37
|
+
| `value` | `string` | Yes | — | The text written to the clipboard on click |
|
|
38
|
+
| `size` | `'sm' \| 'md'` | No | md | Visual size of the component (e.g. 'sm', 'md', 'lg'). |
|
|
39
|
+
| `labels` | `{ copy?: string; copied?: string }` | No | — | Overrides the built-in i18n labels per instance |
|
|
40
|
+
|
|
41
|
+
## Tokens
|
|
42
|
+
|
|
43
|
+
- `--cascivo-color-surface`
|
|
44
|
+
- `--cascivo-color-text-subtle`
|
|
45
|
+
- `--cascivo-color-text`
|
|
46
|
+
- `--cascivo-color-border`
|
|
47
|
+
- `--cascivo-color-bg-subtle`
|
|
48
|
+
- `--cascivo-color-success`
|
|
49
|
+
- `--cascivo-radius-control`
|
|
50
|
+
- `--cascivo-focus-ring`
|
|
51
|
+
- `--cascivo-control-height-sm`
|
|
52
|
+
- `--cascivo-control-height-md`
|
|
53
|
+
|
|
54
|
+
## Examples
|
|
55
|
+
|
|
56
|
+
### Default
|
|
57
|
+
|
|
58
|
+
```jsx
|
|
59
|
+
<CopyButton value="npx cascivo add button" />
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Small
|
|
63
|
+
|
|
64
|
+
```jsx
|
|
65
|
+
<CopyButton value="pnpm install" size="sm" />
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Custom labels
|
|
69
|
+
|
|
70
|
+
Override the built-in copy/copied strings per instance
|
|
71
|
+
|
|
72
|
+
```jsx
|
|
73
|
+
<CopyButton value="token" labels={{ copy: 'Copy token', copied: 'Token copied' }} />
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Boundaries
|
|
77
|
+
|
|
78
|
+
| Area | Level | Note |
|
|
79
|
+
| ----------- | -------- | ------------------------------------------------------------------------------------------------- |
|
|
80
|
+
| labels | flexible | copy/copied strings overridable via labels; default from i18n catalog |
|
|
81
|
+
| token names | strict | Styling resolves to semantic --cascivo-color-\* tokens; copied state uses --cascivo-color-success |
|
|
82
|
+
|
|
83
|
+
## AI context prompt
|
|
84
|
+
|
|
85
|
+
Copy this into an LLM context bar before editing this component:
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
I am modifying the cascivo CopyButton component (inputs). Icon button that copies a value to the clipboard with copied feedback
|
|
89
|
+
|
|
90
|
+
Architecture constraints — follow exactly:
|
|
91
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
92
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
93
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
94
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
95
|
+
- CSS logical properties only (RTL-safe).
|
|
96
|
+
|
|
97
|
+
CopyButton is strictly bound to these tokens — use only these, do not invent token names:
|
|
98
|
+
--cascivo-color-surface, --cascivo-color-text-subtle, --cascivo-color-text, --cascivo-color-border, --cascivo-color-bg-subtle, --cascivo-color-success, --cascivo-radius-control, --cascivo-focus-ring, --cascivo-control-height-sm, --cascivo-control-height-md
|
|
99
|
+
|
|
100
|
+
Accessibility: role "button", WCAG 2.2-AA, keyboard: Enter/Space. Keep it AA.
|
|
101
|
+
|
|
102
|
+
Do not change (strict): token names — Styling resolves to semantic --cascivo-color-* tokens; copied state uses --cascivo-color-success
|
|
103
|
+
Flexible: labels.
|
|
104
|
+
|
|
105
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
106
|
+
```
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# DataList
|
|
2
|
+
|
|
3
|
+
**Category:** display
|
|
4
|
+
**Description:** Key-value pairs rendered as a description list
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Displaying read-only key-value metadata (profile fields, record summaries)
|
|
9
|
+
- Presenting structured attributes where each value maps to a single label
|
|
10
|
+
- Compact detail panels next to or below a primary subject
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
|
|
14
|
+
- Editable fields — use form Inputs, not a DataList
|
|
15
|
+
- Tabular data with many rows and columns — use a Table
|
|
16
|
+
|
|
17
|
+
## Anti-patterns
|
|
18
|
+
|
|
19
|
+
### dl/dt/dd conveys the term-to-description relationship to assistive tech for free
|
|
20
|
+
|
|
21
|
+
**Bad:** `Faking a description list with stacked divs and manual labels`
|
|
22
|
+
**Good:** `Use the native dl/dt/dd structure DataList emits`
|
|
23
|
+
**Why:** dl/dt/dd conveys the term-to-description relationship to assistive tech for free
|
|
24
|
+
|
|
25
|
+
## Related components
|
|
26
|
+
|
|
27
|
+
- **ContainedList** (alternative): ContainedList shows single-value rows; DataList shows labelled pairs
|
|
28
|
+
|
|
29
|
+
## Accessibility rationale
|
|
30
|
+
|
|
31
|
+
Rendered as semantic dl with dt/dd pairs so the label-to-value association is native; no extra ARIA role is added
|
|
32
|
+
|
|
33
|
+
## Props
|
|
34
|
+
|
|
35
|
+
| Name | Type | Required | Default | Description |
|
|
36
|
+
| ------------- | ------------------------------------------------------- | -------- | ---------- | ----------------------------------------------------- |
|
|
37
|
+
| `items` | `{ id?: string; label: ReactNode; value: ReactNode }[]` | Yes | — | The items to render. |
|
|
38
|
+
| `orientation` | `'horizontal' \| 'vertical'` | No | horizontal | Layout orientation of the component. |
|
|
39
|
+
| `dividers` | `boolean` | No | false | When true, shows dividers between items. |
|
|
40
|
+
| `size` | `'sm' \| 'md'` | No | md | Visual size of the component (e.g. 'sm', 'md', 'lg'). |
|
|
41
|
+
|
|
42
|
+
## Tokens
|
|
43
|
+
|
|
44
|
+
- `--cascivo-color-text`
|
|
45
|
+
- `--cascivo-color-text-subtle`
|
|
46
|
+
- `--cascivo-color-border`
|
|
47
|
+
- `--cascivo-space-3`
|
|
48
|
+
- `--cascivo-space-4`
|
|
49
|
+
|
|
50
|
+
## Examples
|
|
51
|
+
|
|
52
|
+
### Horizontal data list
|
|
53
|
+
|
|
54
|
+
```jsx
|
|
55
|
+
<DataList
|
|
56
|
+
items={[
|
|
57
|
+
{ label: 'Name', value: 'Ada Lovelace' },
|
|
58
|
+
{ label: 'Role', value: 'Mathematician' },
|
|
59
|
+
]}
|
|
60
|
+
/>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Vertical with dividers
|
|
64
|
+
|
|
65
|
+
```jsx
|
|
66
|
+
<DataList orientation="vertical" dividers items={[{ label: 'Email', value: 'ada@example.com' }]} />
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Boundaries
|
|
70
|
+
|
|
71
|
+
| Area | Level | Note |
|
|
72
|
+
| -------------------- | -------- | --------------------------------------------------------------------------- |
|
|
73
|
+
| orientation and size | flexible | horizontal for wide panels, vertical for narrow columns; size tunes density |
|
|
74
|
+
| dl semantics | strict | Always renders dl/dt/dd; do not substitute generic elements |
|
|
75
|
+
|
|
76
|
+
## AI context prompt
|
|
77
|
+
|
|
78
|
+
Copy this into an LLM context bar before editing this component:
|
|
79
|
+
|
|
80
|
+
```text
|
|
81
|
+
I am modifying the cascivo DataList component (display). Key-value pairs rendered as a description list
|
|
82
|
+
|
|
83
|
+
Architecture constraints — follow exactly:
|
|
84
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
85
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
86
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
87
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
88
|
+
- CSS logical properties only (RTL-safe).
|
|
89
|
+
|
|
90
|
+
DataList is strictly bound to these tokens — use only these, do not invent token names:
|
|
91
|
+
--cascivo-color-text, --cascivo-color-text-subtle, --cascivo-color-border, --cascivo-space-3, --cascivo-space-4
|
|
92
|
+
|
|
93
|
+
Accessibility: role "none", WCAG 2.2-AA. Keep it AA.
|
|
94
|
+
|
|
95
|
+
Do not change (strict): dl semantics — Always renders dl/dt/dd; do not substitute generic elements
|
|
96
|
+
Flexible: orientation and size.
|
|
97
|
+
|
|
98
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
99
|
+
```
|