@cascivo/mcp 0.2.0 → 0.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +53 -23
- package/dist/context/accordion.md +93 -0
- package/dist/context/action-sheet.md +117 -0
- package/dist/context/alert-dialog.md +122 -0
- package/dist/context/alert.md +110 -0
- package/dist/context/app-shell.md +98 -0
- package/dist/context/aspect-ratio.md +92 -0
- package/dist/context/avatar-group.md +111 -0
- package/dist/context/avatar.md +100 -0
- package/dist/context/badge.md +119 -0
- package/dist/context/block/console-app.md +66 -0
- package/dist/context/block/dashboard-charts.md +61 -0
- package/dist/context/block/empty-dashboard.md +60 -0
- package/dist/context/block/login-page.md +60 -0
- package/dist/context/block/notification-center.md +61 -0
- package/dist/context/block/page-with-breadcrumb.md +54 -0
- package/dist/context/block/settings-form-page.md +60 -0
- package/dist/context/block/sidebar-app.md +55 -0
- package/dist/context/block/stats-cards.md +61 -0
- package/dist/context/block/users-table-page.md +61 -0
- package/dist/context/blockquote.md +95 -0
- package/dist/context/bottom-sheet.md +112 -0
- package/dist/context/breadcrumb.md +106 -0
- package/dist/context/button-group.md +100 -0
- package/dist/context/button.md +117 -0
- package/dist/context/calendar.md +118 -0
- package/dist/context/card.md +90 -0
- package/dist/context/carousel.md +101 -0
- package/dist/context/chart/area-chart.md +99 -0
- package/dist/context/chart/bar-chart.md +114 -0
- package/dist/context/chart/boxplot.md +82 -0
- package/dist/context/chart/bubble-chart.md +80 -0
- package/dist/context/chart/bullet.md +75 -0
- package/dist/context/chart/calendar.md +79 -0
- package/dist/context/chart/candlestick.md +104 -0
- package/dist/context/chart/combo-chart.md +78 -0
- package/dist/context/chart/funnel.md +87 -0
- package/dist/context/chart/gauge.md +87 -0
- package/dist/context/chart/heatmap.md +77 -0
- package/dist/context/chart/histogram.md +74 -0
- package/dist/context/chart/kpi.md +70 -0
- package/dist/context/chart/line-chart.md +113 -0
- package/dist/context/chart/meter.md +71 -0
- package/dist/context/chart/pie-chart.md +126 -0
- package/dist/context/chart/polar.md +92 -0
- package/dist/context/chart/radar.md +81 -0
- package/dist/context/chart/radial-bar.md +96 -0
- package/dist/context/chart/sankey.md +89 -0
- package/dist/context/chart/scatter-chart.md +90 -0
- package/dist/context/chart/sparkline.md +69 -0
- package/dist/context/chart/stream.md +88 -0
- package/dist/context/chart/sunburst.md +93 -0
- package/dist/context/chart/treemap.md +84 -0
- package/dist/context/chat-bubble.md +116 -0
- package/dist/context/checkbox-card.md +104 -0
- package/dist/context/checkbox.md +104 -0
- package/dist/context/code-snippet.md +118 -0
- package/dist/context/code.md +103 -0
- package/dist/context/collapsible.md +104 -0
- package/dist/context/color-picker.md +101 -0
- package/dist/context/combobox.md +125 -0
- package/dist/context/command-menu.md +121 -0
- package/dist/context/comparison.md +117 -0
- package/dist/context/contained-list.md +103 -0
- package/dist/context/context-menu.md +103 -0
- package/dist/context/copy-button.md +106 -0
- package/dist/context/data-list.md +99 -0
- package/dist/context/data-table.md +149 -0
- package/dist/context/date-picker.md +116 -0
- package/dist/context/date-range-picker.md +113 -0
- package/dist/context/dock.md +117 -0
- package/dist/context/drawer.md +111 -0
- package/dist/context/dropdown.md +96 -0
- package/dist/context/editable.md +101 -0
- package/dist/context/editor/code-editor.md +146 -0
- package/dist/context/editor/highlight.md +74 -0
- package/dist/context/empty-state.md +101 -0
- package/dist/context/fab.md +128 -0
- package/dist/context/field.md +118 -0
- package/dist/context/file-uploader.md +121 -0
- package/dist/context/filter.md +129 -0
- package/dist/context/flow/flow-background.md +103 -0
- package/dist/context/flow/flow-canvas.md +82 -0
- package/dist/context/flow/flow-controls.md +84 -0
- package/dist/context/flow/flow-edge.md +128 -0
- package/dist/context/flow/flow-handle.md +83 -0
- package/dist/context/flow/flow-minimap.md +89 -0
- package/dist/context/flow/flow-node.md +97 -0
- package/dist/context/flow/flow-panel.md +75 -0
- package/dist/context/flow/flow-story.md +145 -0
- package/dist/context/flow/flow.md +139 -0
- package/dist/context/form.md +104 -0
- package/dist/context/header-panel.md +96 -0
- package/dist/context/header.md +104 -0
- package/dist/context/heading.md +107 -0
- package/dist/context/hover-card.md +108 -0
- package/dist/context/icon-button.md +115 -0
- package/dist/context/image.md +115 -0
- package/dist/context/indicator.md +95 -0
- package/dist/context/inline-loading.md +101 -0
- package/dist/context/input-group.md +122 -0
- package/dist/context/input.md +101 -0
- package/dist/context/item.md +109 -0
- package/dist/context/join.md +97 -0
- package/dist/context/kbd.md +100 -0
- package/dist/context/label.md +117 -0
- package/dist/context/layout/app-shell.md +85 -0
- package/dist/context/layout/auth-layout.md +74 -0
- package/dist/context/layout/auto-grid.md +69 -0
- package/dist/context/layout/center.md +67 -0
- package/dist/context/layout/columns.md +70 -0
- package/dist/context/layout/dashboard-layout.md +68 -0
- package/dist/context/layout/grid.md +70 -0
- package/dist/context/layout/masonry.md +70 -0
- package/dist/context/layout/page-header.md +75 -0
- package/dist/context/layout/section.md +69 -0
- package/dist/context/layout/settings-layout.md +68 -0
- package/dist/context/layout/spacer.md +64 -0
- package/dist/context/layout/split-view.md +71 -0
- package/dist/context/layout/stack.md +93 -0
- package/dist/context/link.md +112 -0
- package/dist/context/list.md +109 -0
- package/dist/context/log-viewer.md +124 -0
- package/dist/context/menu-button.md +137 -0
- package/dist/context/menu.md +108 -0
- package/dist/context/menubar.md +92 -0
- package/dist/context/modal.md +96 -0
- package/dist/context/multi-select.md +104 -0
- package/dist/context/native-select.md +118 -0
- package/dist/context/navigation-menu.md +95 -0
- package/dist/context/notification.md +116 -0
- package/dist/context/number-input.md +117 -0
- package/dist/context/otp-input.md +98 -0
- package/dist/context/overflow-menu.md +107 -0
- package/dist/context/pagination.md +123 -0
- package/dist/context/password-input.md +100 -0
- package/dist/context/popover.md +108 -0
- package/dist/context/progress-bar.md +107 -0
- package/dist/context/progress-circle.md +101 -0
- package/dist/context/progress-indicator.md +105 -0
- package/dist/context/progress.md +109 -0
- package/dist/context/prose.md +110 -0
- package/dist/context/pull-to-refresh.md +101 -0
- package/dist/context/qr-code.md +101 -0
- package/dist/context/radial-progress.md +117 -0
- package/dist/context/radio-card.md +95 -0
- package/dist/context/radio.md +94 -0
- package/dist/context/rating-group.md +97 -0
- package/dist/context/relative-time.md +90 -0
- package/dist/context/resizable.md +102 -0
- package/dist/context/scroll-area.md +101 -0
- package/dist/context/search.md +113 -0
- package/dist/context/section/cta.md +83 -0
- package/dist/context/section/feature-grid.md +98 -0
- package/dist/context/section/hero.md +101 -0
- package/dist/context/section/media-masonry.md +77 -0
- package/dist/context/section/page-footer.md +101 -0
- package/dist/context/section/stats-band.md +81 -0
- package/dist/context/segmented-control.md +101 -0
- package/dist/context/select.md +101 -0
- package/dist/context/separator.md +88 -0
- package/dist/context/sheet.md +100 -0
- package/dist/context/shell-header.md +105 -0
- package/dist/context/side-nav.md +134 -0
- package/dist/context/skeleton.md +101 -0
- package/dist/context/skip-nav.md +103 -0
- package/dist/context/slider.md +98 -0
- package/dist/context/spinner.md +89 -0
- package/dist/context/stack.md +96 -0
- package/dist/context/stat.md +101 -0
- package/dist/context/status.md +105 -0
- package/dist/context/steps.md +124 -0
- package/dist/context/structured-list.md +107 -0
- package/dist/context/swap.md +100 -0
- package/dist/context/swipe-item.md +110 -0
- package/dist/context/switcher.md +97 -0
- package/dist/context/tabs.md +93 -0
- package/dist/context/tag.md +110 -0
- package/dist/context/tags-input.md +94 -0
- package/dist/context/text.md +111 -0
- package/dist/context/textarea.md +98 -0
- package/dist/context/tile.md +116 -0
- package/dist/context/time-picker.md +102 -0
- package/dist/context/timeline.md +93 -0
- package/dist/context/toast.md +91 -0
- package/dist/context/toc.md +110 -0
- package/dist/context/toggle-group.md +118 -0
- package/dist/context/toggle.md +103 -0
- package/dist/context/toggletip.md +119 -0
- package/dist/context/tooltip.md +92 -0
- package/dist/context/tree-view.md +107 -0
- package/dist/context/user.md +100 -0
- package/dist/context/visually-hidden.md +90 -0
- package/dist/context.json +22456 -0
- package/dist/index.d.mts +3 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +73 -32
- package/dist/index.mjs.map +1 -1
- package/dist/marketplace.json +70 -0
- package/dist/registry.json +2832 -358
- package/dist/tokens.catalog.json +2375 -0
- package/dist/tokens.variants.json +3291 -0
- package/package.json +4 -3
- package/readme.body.md +53 -23
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Dropdown
|
|
2
|
+
|
|
3
|
+
**Category:** overlay
|
|
4
|
+
**Description:** Menu of actions revealed from a trigger
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Revealing a short menu of actions from a trigger button (row actions, "More" overflow, account menu)
|
|
9
|
+
- Grouping related commands behind one affordance with optional icons and separators
|
|
10
|
+
|
|
11
|
+
## When NOT to use
|
|
12
|
+
|
|
13
|
+
- Selecting a persistent value for a form — use Select or Combobox
|
|
14
|
+
- A global searchable command palette — use CommandMenu; right-click context actions — use ContextMenu
|
|
15
|
+
|
|
16
|
+
## Anti-patterns
|
|
17
|
+
|
|
18
|
+
### Dropdown items are role="menuitem" actions fired via onSelect — there is no selected-value semantics for assistive tech or forms
|
|
19
|
+
|
|
20
|
+
**Bad:** `Using Dropdown to choose a form value and reading the selection as field state`
|
|
21
|
+
**Good:** `Use Select/Combobox which expose role="combobox" and a controlled value`
|
|
22
|
+
**Why:** Dropdown items are role="menuitem" actions fired via onSelect — there is no selected-value semantics for assistive tech or forms
|
|
23
|
+
|
|
24
|
+
## Related components
|
|
25
|
+
|
|
26
|
+
- **Select** (alternative): Use for choosing and persisting a single form value
|
|
27
|
+
- **CommandMenu** (alternative): Use for a searchable global action palette
|
|
28
|
+
- **Button** (pairs-with): The trigger is typically a Button passed via the trigger prop
|
|
29
|
+
|
|
30
|
+
## Accessibility rationale
|
|
31
|
+
|
|
32
|
+
The menu is role="menu" with role="menuitem" buttons and roving tabindex; the trigger gets aria-haspopup="menu" and aria-expanded via cloneElement; arrow/Home/End/Enter/Escape are handled and focus returns to the trigger on select or close, and popover="auto" provides light-dismiss synced back to state via the toggle event
|
|
33
|
+
|
|
34
|
+
## Props
|
|
35
|
+
|
|
36
|
+
| Name | Type | Required | Default | Description |
|
|
37
|
+
| -------------- | ----------------------------------------------------------------------------------------------- | -------- | ------------ | --------------------------------------------------- |
|
|
38
|
+
| `trigger` | `ReactElement` | Yes | — | The element that opens the dropdown when activated. |
|
|
39
|
+
| `items` | `{ label: string; value: string; icon?: ReactNode; disabled?: boolean; separator?: boolean }[]` | Yes | — | The items to render. |
|
|
40
|
+
| `onSelect` | `(value: string) => void` | No | — | Called with the selected value. |
|
|
41
|
+
| `placement` | `'bottom-start' \| 'bottom-end'` | No | bottom-start | Placement relative to the trigger. |
|
|
42
|
+
| `open` | `boolean` | No | — | Whether the component is open (controlled). |
|
|
43
|
+
| `onOpenChange` | `(open: boolean) => void` | No | — | Called with the next open state when it changes. |
|
|
44
|
+
|
|
45
|
+
## Tokens
|
|
46
|
+
|
|
47
|
+
- `--cascivo-color-surface-overlay`
|
|
48
|
+
- `--cascivo-color-border`
|
|
49
|
+
- `--cascivo-color-bg-subtle`
|
|
50
|
+
- `--cascivo-radius-md`
|
|
51
|
+
- `--cascivo-z-dropdown`
|
|
52
|
+
|
|
53
|
+
## Examples
|
|
54
|
+
|
|
55
|
+
### Basic
|
|
56
|
+
|
|
57
|
+
```jsx
|
|
58
|
+
<Dropdown
|
|
59
|
+
trigger={<Button>Actions</Button>}
|
|
60
|
+
items={[{ label: 'Edit', value: 'edit' }]}
|
|
61
|
+
onSelect={handle}
|
|
62
|
+
/>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Boundaries
|
|
66
|
+
|
|
67
|
+
| Area | Level | Note |
|
|
68
|
+
| -------------------------- | -------- | ---------------------------------------------------------------------------------- |
|
|
69
|
+
| trigger element | flexible | Any ReactElement works as the trigger; ref and aria props are merged in |
|
|
70
|
+
| controlled vs uncontrolled | flexible | Supports open + onOpenChange or fully internal state |
|
|
71
|
+
| token names | strict | Menu styling resolves to semantic --cascivo-color-\* / --cascivo-z-dropdown tokens |
|
|
72
|
+
|
|
73
|
+
## AI context prompt
|
|
74
|
+
|
|
75
|
+
Copy this into an LLM context bar before editing this component:
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
I am modifying the cascivo Dropdown component (overlay). Menu of actions revealed from a trigger
|
|
79
|
+
|
|
80
|
+
Architecture constraints — follow exactly:
|
|
81
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
82
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
83
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
84
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
85
|
+
- CSS logical properties only (RTL-safe).
|
|
86
|
+
|
|
87
|
+
Dropdown is strictly bound to these tokens — use only these, do not invent token names:
|
|
88
|
+
--cascivo-color-surface-overlay, --cascivo-color-border, --cascivo-color-bg-subtle, --cascivo-radius-md, --cascivo-z-dropdown
|
|
89
|
+
|
|
90
|
+
Accessibility: role "menu", WCAG 2.2-AA, keyboard: ArrowDown/ArrowUp/Home/End/Enter/Space/Escape. Keep it AA.
|
|
91
|
+
|
|
92
|
+
Do not change (strict): token names — Menu styling resolves to semantic --cascivo-color-* / --cascivo-z-dropdown tokens
|
|
93
|
+
Flexible: trigger element, controlled vs uncontrolled.
|
|
94
|
+
|
|
95
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
96
|
+
```
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Editable
|
|
2
|
+
|
|
3
|
+
**Category:** inputs
|
|
4
|
+
**Description:** Inline click-to-edit text field
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Editing a single piece of text in place where the value is normally read-only — titles, names, labels
|
|
9
|
+
- Keeping the page layout stable: the preview and the edit input occupy the same spot
|
|
10
|
+
- Letting users opt into editing by clicking, without a separate edit mode or form
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
|
|
14
|
+
- A field that is always meant to be edited — use Input inside a Form instead
|
|
15
|
+
- Multi-line or rich text — this is a single-line input only
|
|
16
|
+
- Collecting several related values at once — use a Form with grouped fields
|
|
17
|
+
|
|
18
|
+
## Anti-patterns
|
|
19
|
+
|
|
20
|
+
### Inline edit hides the affordance behind a click; required form fields should be visibly editable from the start
|
|
21
|
+
|
|
22
|
+
**Bad:** `<Editable value={email} onValueChange={save} /> as a primary form control`
|
|
23
|
+
**Good:** `<Input label="Email" value={email} onChange={...} />`
|
|
24
|
+
**Why:** Inline edit hides the affordance behind a click; required form fields should be visibly editable from the start
|
|
25
|
+
|
|
26
|
+
## Related components
|
|
27
|
+
|
|
28
|
+
- **Input** (alternative): Use Input when the field is always editable rather than click-to-reveal
|
|
29
|
+
|
|
30
|
+
## Accessibility rationale
|
|
31
|
+
|
|
32
|
+
The preview renders as a real <button> so it is keyboard-focusable and announces as an actionable control; while editing, Enter confirms and Escape cancels, and focus is moved into the input and its text selected so keyboard users can immediately type.
|
|
33
|
+
|
|
34
|
+
## Props
|
|
35
|
+
|
|
36
|
+
| Name | Type | Required | Default | Description |
|
|
37
|
+
| --------------- | --------------------- | -------- | ------- | ------------------------------------------------------------------ |
|
|
38
|
+
| `value` | `string` | Yes | — | The controlled value. |
|
|
39
|
+
| `onValueChange` | `(v: string) => void` | Yes | — | Called with the new value when it changes. |
|
|
40
|
+
| `placeholder` | `string` | No | — | Placeholder text shown when the field is empty. |
|
|
41
|
+
| `disabled` | `boolean` | No | false | When true, disables the control and removes it from the tab order. |
|
|
42
|
+
| `submitOnBlur` | `boolean` | No | true | When true, commits the edit when the field loses focus. |
|
|
43
|
+
| `onCancel` | `() => void` | No | — | Called when the edit is cancelled. |
|
|
44
|
+
|
|
45
|
+
## Tokens
|
|
46
|
+
|
|
47
|
+
- `--cascivo-color-surface`
|
|
48
|
+
- `--cascivo-color-border`
|
|
49
|
+
- `--cascivo-color-accent`
|
|
50
|
+
- `--cascivo-color-text`
|
|
51
|
+
- `--cascivo-color-text-muted`
|
|
52
|
+
- `--cascivo-color-bg-subtle`
|
|
53
|
+
- `--cascivo-radius-sm`
|
|
54
|
+
- `--cascivo-focus-ring`
|
|
55
|
+
|
|
56
|
+
## Examples
|
|
57
|
+
|
|
58
|
+
### Basic
|
|
59
|
+
|
|
60
|
+
```jsx
|
|
61
|
+
<Editable value="Click to edit" onValueChange={() => {}} />
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### With placeholder
|
|
65
|
+
|
|
66
|
+
```jsx
|
|
67
|
+
<Editable value="" onValueChange={() => {}} placeholder="Enter text" />
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Boundaries
|
|
71
|
+
|
|
72
|
+
| Area | Level | Note |
|
|
73
|
+
| ----------------------- | -------- | ---------------------------------------------------------------------------------------- |
|
|
74
|
+
| token names | strict | Visual styling must resolve to the listed --cascivo-\* surface/border/accent/text tokens |
|
|
75
|
+
| placeholder copy | flexible | Free, within tone guidance |
|
|
76
|
+
| submit-on-blur behavior | flexible | submitOnBlur toggles whether blurring confirms or cancels the edit |
|
|
77
|
+
|
|
78
|
+
## AI context prompt
|
|
79
|
+
|
|
80
|
+
Copy this into an LLM context bar before editing this component:
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
I am modifying the cascivo Editable component (inputs). Inline click-to-edit text field
|
|
84
|
+
|
|
85
|
+
Architecture constraints — follow exactly:
|
|
86
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
87
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
88
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
89
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
90
|
+
- CSS logical properties only (RTL-safe).
|
|
91
|
+
|
|
92
|
+
Editable is strictly bound to these tokens — use only these, do not invent token names:
|
|
93
|
+
--cascivo-color-surface, --cascivo-color-border, --cascivo-color-accent, --cascivo-color-text, --cascivo-color-text-muted, --cascivo-color-bg-subtle, --cascivo-radius-sm, --cascivo-focus-ring
|
|
94
|
+
|
|
95
|
+
Accessibility: role "button", WCAG 2.2-AA, keyboard: Enter/Escape. Keep it AA.
|
|
96
|
+
|
|
97
|
+
Do not change (strict): token names — Visual styling must resolve to the listed --cascivo-* surface/border/accent/text tokens
|
|
98
|
+
Flexible: placeholder copy, submit-on-blur behavior.
|
|
99
|
+
|
|
100
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
101
|
+
```
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# CodeEditor
|
|
2
|
+
|
|
3
|
+
**Category:** inputs
|
|
4
|
+
**Description:** Lightweight code editor — a native textarea overlaid on a syntax-highlighted layer, with line numbers and Tab indent.
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Editing code or config inline — JSON, snippets, web languages — with line numbers and syntax colors
|
|
9
|
+
- A lightweight, themeable code field where a full IDE editor (Monaco/CodeMirror) would be overkill
|
|
10
|
+
- Editing Markdown notes — find/replace, real undo/redo, save, and selection-preserving external sync
|
|
11
|
+
- Editing long-form Markdown — generated docs, concatenated books, big notes — windowed (viewport-scoped) tokenization keeps scrolling/typing smooth well past ~5,000 lines
|
|
12
|
+
|
|
13
|
+
## When NOT to use
|
|
14
|
+
|
|
15
|
+
- You need IntelliSense/LSP, multi-cursor, folding, a minimap, or diff view — use a full editor framework
|
|
16
|
+
- Plain prose or a single-line value — use Textarea or Input
|
|
17
|
+
- Sustained editing of 100k+-line documents — use a full editor framework / dedicated worker pipeline (the windowed tokenizer keeps per-render work O(viewport), but a worker offload is intentionally out of scope)
|
|
18
|
+
- Soft-wrap (wrap) on a very large document — rendering is O(n) under wrap; disable wrap above ~10k lines for sustained editing
|
|
19
|
+
|
|
20
|
+
## Anti-patterns
|
|
21
|
+
|
|
22
|
+
### The overlay technique keeps the bundle tiny and themes via the cascivo token system
|
|
23
|
+
|
|
24
|
+
**Bad:** `Reaching for Monaco to show an editable snippet`
|
|
25
|
+
**Good:** `Use CodeEditor for the basic set (line numbers + highlighting) at a fraction of the weight`
|
|
26
|
+
**Why:** The overlay technique keeps the bundle tiny and themes via the cascivo token system
|
|
27
|
+
|
|
28
|
+
## Related components
|
|
29
|
+
|
|
30
|
+
- **Highlight** (pairs-with): The read-only renderer sharing the same tokenizer — for snippets and docs
|
|
31
|
+
- **Textarea** (alternative): Use for free-form prose without syntax highlighting
|
|
32
|
+
|
|
33
|
+
## Accessibility rationale
|
|
34
|
+
|
|
35
|
+
The native <textarea> is the editing surface, so caret, selection, IME, undo, and the a11y tree come from the browser; the highlight layer and gutter are aria-hidden.
|
|
36
|
+
|
|
37
|
+
## Props
|
|
38
|
+
|
|
39
|
+
| Name | Type | Required | Default | Description |
|
|
40
|
+
| ----------------- | --------------------------------------------------- | -------- | --------- | ---------------------------------------------------------------------------------------------- |
|
|
41
|
+
| `value` | `string` | No | — | Controlled value |
|
|
42
|
+
| `defaultValue` | `string` | No | — | Initial value for uncontrolled use |
|
|
43
|
+
| `onValueChange` | `(value: string) => void` | No | — | Called with the new text on every edit |
|
|
44
|
+
| `language` | `string` | No | plaintext | Grammar name (plaintext/json/javascript/typescript/css/html/markdown/bash) |
|
|
45
|
+
| `lineNumbers` | `boolean` | No | true | Show the line-number gutter |
|
|
46
|
+
| `tabSize` | `number` | No | 2 | Spaces per tab stop |
|
|
47
|
+
| `insertSpaces` | `boolean` | No | true | Insert spaces vs a literal tab on Tab |
|
|
48
|
+
| `wrap` | `boolean` | No | false | Soft-wrap long lines instead of scrolling horizontally |
|
|
49
|
+
| `readOnly` | `boolean` | No | false | When true, the value is shown but cannot be edited. |
|
|
50
|
+
| `disabled` | `boolean` | No | false | When true, disables the control and removes it from the tab order. |
|
|
51
|
+
| `placeholder` | `string` | No | — | Placeholder text shown when the field is empty. |
|
|
52
|
+
| `label` | `string` | No | — | Accessible label (defaults to the i18n "Code editor") |
|
|
53
|
+
| `onSave` | `(value: string) => void` | No | — | Called on Mod-S; the browser save dialog is suppressed |
|
|
54
|
+
| `bracketMatching` | `boolean` | No | false | Highlight the bracket matching the one adjacent to the caret |
|
|
55
|
+
| `theme` | `EditorTheme` | No | — | Per-instance --cascivo-editor-\* overrides; swapping it re-themes live |
|
|
56
|
+
| `keymap` | `KeyMap` | No | — | Extra key bindings merged over the built-ins (user wins on a chord) |
|
|
57
|
+
| `decorations` | `Decoration[] \| ((value: string) => Decoration[])` | No | — | Extra offset-range → CSS class decorations |
|
|
58
|
+
| `commands` | `SlashCommand[]` | No | — | Slash-command entries; typing "/" opens a filtered menu. Omit to disable. |
|
|
59
|
+
| `ref` | `Ref<CodeEditorHandle>` | No | — | Imperative handle: applyEdit / getSelection / focus / undo / redo / openFind / openCommandMenu |
|
|
60
|
+
| `className` | `string` | No | — | Additional CSS class names merged onto the root element. |
|
|
61
|
+
|
|
62
|
+
## Tokens
|
|
63
|
+
|
|
64
|
+
- `--cascivo-editor-bg`
|
|
65
|
+
- `--cascivo-editor-fg`
|
|
66
|
+
- `--cascivo-editor-gutter-bg`
|
|
67
|
+
- `--cascivo-editor-gutter-fg`
|
|
68
|
+
- `--cascivo-editor-gutter-active`
|
|
69
|
+
- `--cascivo-editor-current-line`
|
|
70
|
+
- `--cascivo-editor-selection`
|
|
71
|
+
- `--cascivo-editor-border`
|
|
72
|
+
- `--cascivo-editor-match`
|
|
73
|
+
- `--cascivo-editor-match-current`
|
|
74
|
+
- `--cascivo-editor-bracket`
|
|
75
|
+
|
|
76
|
+
## Examples
|
|
77
|
+
|
|
78
|
+
### Basic editor
|
|
79
|
+
|
|
80
|
+
```jsx
|
|
81
|
+
import { CodeEditor } from '@cascivo/editor'
|
|
82
|
+
import '@cascivo/editor/styles.css'
|
|
83
|
+
;<CodeEditor language="typescript" lineNumbers defaultValue={'const x = 1\n'} />
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Controlled
|
|
87
|
+
|
|
88
|
+
```jsx
|
|
89
|
+
<CodeEditor language="json" value={value} onValueChange={setValue} />
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Notes editing — find, save, brackets
|
|
93
|
+
|
|
94
|
+
```jsx
|
|
95
|
+
<CodeEditor
|
|
96
|
+
language="markdown"
|
|
97
|
+
value={doc}
|
|
98
|
+
onValueChange={setDoc}
|
|
99
|
+
onSave={save} // Mod-S
|
|
100
|
+
bracketMatching
|
|
101
|
+
/> // Mod-F to search
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Slash commands
|
|
105
|
+
|
|
106
|
+
Type "/" to open a filtered command menu; arrows + Enter insert.
|
|
107
|
+
|
|
108
|
+
```jsx
|
|
109
|
+
const commands = [
|
|
110
|
+
{ id: 'fence', label: 'Code block', keywords: ['code'], insert: '\u0060\u0060\u0060\n\n\u0060\u0060\u0060' },
|
|
111
|
+
{ id: 'todo', label: 'TODO', insert: '// TODO: ' },
|
|
112
|
+
{ id: 'date', label: 'Date', run: (e) => e.applyEdit(e.getSelection(), new Date().toISOString()) },
|
|
113
|
+
]
|
|
114
|
+
|
|
115
|
+
<CodeEditor language="markdown" commands={commands} />
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Boundaries
|
|
119
|
+
|
|
120
|
+
| Area | Level | Note |
|
|
121
|
+
| --------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
122
|
+
| languages | flexible | Ships a small grammar set; registerGrammar adds custom languages without bundle bloat |
|
|
123
|
+
| large documents | flexible | Windowed tokenization (tokenizeRange + LineStateIndex) makes per-render work O(viewport) and per-edit work O(changed suffix); long Markdown edits well past ~5,000 lines. Worker offload / 100k+-line sustained editing stay out of scope |
|
|
124
|
+
|
|
125
|
+
## AI context prompt
|
|
126
|
+
|
|
127
|
+
Copy this into an LLM context bar before editing this component:
|
|
128
|
+
|
|
129
|
+
```text
|
|
130
|
+
I am modifying the cascivo CodeEditor component (inputs). Lightweight code editor — a native textarea overlaid on a syntax-highlighted layer, with line numbers and Tab indent.
|
|
131
|
+
|
|
132
|
+
Architecture constraints — follow exactly:
|
|
133
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
134
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
135
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
136
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
137
|
+
- CSS logical properties only (RTL-safe).
|
|
138
|
+
|
|
139
|
+
CodeEditor is strictly bound to these tokens — use only these, do not invent token names:
|
|
140
|
+
--cascivo-editor-bg, --cascivo-editor-fg, --cascivo-editor-gutter-bg, --cascivo-editor-gutter-fg, --cascivo-editor-gutter-active, --cascivo-editor-current-line, --cascivo-editor-selection, --cascivo-editor-border, --cascivo-editor-match, --cascivo-editor-match-current, --cascivo-editor-bracket
|
|
141
|
+
|
|
142
|
+
Accessibility: role "textbox", WCAG 2.1-AA, keyboard: Tab (indent)/Shift+Tab (dedent)/Mod+Z / Mod+Shift+Z (undo / redo)/Mod+F (find)/Mod+Alt+F (replace)/Mod+S (save)// (open slash-command menu when commands are provided)/Up/Down + Enter/Tab (navigate + insert a command), Escape (dismiss)/Standard textarea editing. Keep it AA.
|
|
143
|
+
Flexible: languages, large documents.
|
|
144
|
+
|
|
145
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
146
|
+
```
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Highlight
|
|
2
|
+
|
|
3
|
+
**Category:** display
|
|
4
|
+
**Description:** Read-only syntax-highlighted code block — the same owned tokenizer as CodeEditor, without the textarea.
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Displaying non-editable code or config with syntax colors — docs, snippets, examples
|
|
9
|
+
- A lightweight highlighter that themes via the cascivo token system
|
|
10
|
+
|
|
11
|
+
## When NOT to use
|
|
12
|
+
|
|
13
|
+
- The code must be editable — use CodeEditor
|
|
14
|
+
- You need copy-to-clipboard chrome around a snippet — pair with a code-snippet surface
|
|
15
|
+
|
|
16
|
+
## Related components
|
|
17
|
+
|
|
18
|
+
- **CodeEditor** (pairs-with): The editable surface sharing the same tokenizer
|
|
19
|
+
|
|
20
|
+
## Accessibility rationale
|
|
21
|
+
|
|
22
|
+
Renders a read-only <pre><code>; the line-number gutter is aria-hidden and an optional label names the block.
|
|
23
|
+
|
|
24
|
+
## Props
|
|
25
|
+
|
|
26
|
+
| Name | Type | Required | Default | Description |
|
|
27
|
+
| ------------- | --------- | -------- | --------- | -------------------------------------------------------------------------- |
|
|
28
|
+
| `value` | `string` | Yes | — | Code to render |
|
|
29
|
+
| `language` | `string` | No | plaintext | Grammar name (plaintext/json/javascript/typescript/css/html/markdown/bash) |
|
|
30
|
+
| `lineNumbers` | `boolean` | No | false | Show the line-number gutter |
|
|
31
|
+
| `wrap` | `boolean` | No | false | Soft-wrap long lines |
|
|
32
|
+
| `tabSize` | `number` | No | 2 | Spaces per tab stop |
|
|
33
|
+
| `label` | `string` | No | — | Accessible label for the code block |
|
|
34
|
+
| `className` | `string` | No | — | Additional CSS class names merged onto the root element. |
|
|
35
|
+
|
|
36
|
+
## Tokens
|
|
37
|
+
|
|
38
|
+
- `--cascivo-editor-bg`
|
|
39
|
+
- `--cascivo-editor-fg`
|
|
40
|
+
- `--cascivo-editor-gutter-bg`
|
|
41
|
+
- `--cascivo-editor-gutter-fg`
|
|
42
|
+
- `--cascivo-editor-border`
|
|
43
|
+
|
|
44
|
+
## Examples
|
|
45
|
+
|
|
46
|
+
### Read-only snippet
|
|
47
|
+
|
|
48
|
+
```jsx
|
|
49
|
+
import { Highlight } from '@cascivo/editor'
|
|
50
|
+
import '@cascivo/editor/styles.css'
|
|
51
|
+
;<Highlight language="json" value={'{ "ok": true }'} />
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## AI context prompt
|
|
55
|
+
|
|
56
|
+
Copy this into an LLM context bar before editing this component:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
I am modifying the cascivo Highlight component (display). Read-only syntax-highlighted code block — the same owned tokenizer as CodeEditor, without the textarea.
|
|
60
|
+
|
|
61
|
+
Architecture constraints — follow exactly:
|
|
62
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
63
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
64
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
65
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
66
|
+
- CSS logical properties only (RTL-safe).
|
|
67
|
+
|
|
68
|
+
Highlight is strictly bound to these tokens — use only these, do not invent token names:
|
|
69
|
+
--cascivo-editor-bg, --cascivo-editor-fg, --cascivo-editor-gutter-bg, --cascivo-editor-gutter-fg, --cascivo-editor-border
|
|
70
|
+
|
|
71
|
+
Accessibility: role "group", WCAG 2.1-AA, keyboard: Scroll (no interactive controls). Keep it AA.
|
|
72
|
+
|
|
73
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
74
|
+
```
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# EmptyState
|
|
2
|
+
|
|
3
|
+
**Category:** display
|
|
4
|
+
**Description:** Placeholder for views that have no data to display
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- Filling a view that has no data with guidance and a primary next step
|
|
9
|
+
- Explaining why a list/table is empty (no results, nothing created yet)
|
|
10
|
+
- Offering an action that resolves the empty condition (action prop)
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
|
|
14
|
+
- Content is still loading — use Skeleton or Spinner
|
|
15
|
+
- An error occurred — use Alert to explain the failure
|
|
16
|
+
|
|
17
|
+
## Anti-patterns
|
|
18
|
+
|
|
19
|
+
### Conflating loading with empty tells the user there is no data when there may be
|
|
20
|
+
|
|
21
|
+
**Bad:** `Showing an EmptyState while data is still fetching`
|
|
22
|
+
**Good:** `A Skeleton during load, then EmptyState only if the result is empty`
|
|
23
|
+
**Why:** Conflating loading with empty tells the user there is no data when there may be
|
|
24
|
+
|
|
25
|
+
## Related components
|
|
26
|
+
|
|
27
|
+
- **Skeleton** (alternative): Skeleton covers the loading phase before data resolves
|
|
28
|
+
- **Alert** (alternative): Use Alert for error states rather than a generic empty state
|
|
29
|
+
|
|
30
|
+
## Accessibility rationale
|
|
31
|
+
|
|
32
|
+
Presentational by role; the title carries the meaning as text and the action is a real focusable control, so keyboard and screen-reader users can act on the next step
|
|
33
|
+
|
|
34
|
+
## Props
|
|
35
|
+
|
|
36
|
+
| Name | Type | Required | Default | Description |
|
|
37
|
+
| ------------- | -------------- | -------- | ------- | ----------------------------------------------------- |
|
|
38
|
+
| `icon` | `ReactNode` | No | — | Icon element rendered in the component. |
|
|
39
|
+
| `title` | `string` | Yes | — | Title text for the component. |
|
|
40
|
+
| `description` | `string` | No | — | Supporting description text. |
|
|
41
|
+
| `action` | `ReactNode` | No | — | Primary action shown in the component. |
|
|
42
|
+
| `size` | `'md' \| 'lg'` | No | md | Visual size of the component (e.g. 'sm', 'md', 'lg'). |
|
|
43
|
+
|
|
44
|
+
## Tokens
|
|
45
|
+
|
|
46
|
+
- `--cascivo-color-text`
|
|
47
|
+
- `--cascivo-color-text-subtle`
|
|
48
|
+
- `--cascivo-color-text-muted`
|
|
49
|
+
- `--cascivo-color-bg-subtle`
|
|
50
|
+
- `--cascivo-radius-full`
|
|
51
|
+
|
|
52
|
+
## Examples
|
|
53
|
+
|
|
54
|
+
### Basic
|
|
55
|
+
|
|
56
|
+
```jsx
|
|
57
|
+
<EmptyState title="No results" description="Try adjusting your filters." />
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### With action
|
|
61
|
+
|
|
62
|
+
```jsx
|
|
63
|
+
<EmptyState
|
|
64
|
+
icon="📄"
|
|
65
|
+
title="No documents yet"
|
|
66
|
+
description="Create your first document to get started."
|
|
67
|
+
action={<Button>New document</Button>}
|
|
68
|
+
/>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Boundaries
|
|
72
|
+
|
|
73
|
+
| Area | Level | Note |
|
|
74
|
+
| --------------- | -------- | ----------------------------------------------------------------------- |
|
|
75
|
+
| size and action | flexible | Action and icon are optional; size scales for full-page vs in-panel use |
|
|
76
|
+
| token names | strict | Text and background colors must resolve to --cascivo-\* tokens |
|
|
77
|
+
|
|
78
|
+
## AI context prompt
|
|
79
|
+
|
|
80
|
+
Copy this into an LLM context bar before editing this component:
|
|
81
|
+
|
|
82
|
+
```text
|
|
83
|
+
I am modifying the cascivo EmptyState component (display). Placeholder for views that have no data to display
|
|
84
|
+
|
|
85
|
+
Architecture constraints — follow exactly:
|
|
86
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
87
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
88
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
89
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
90
|
+
- CSS logical properties only (RTL-safe).
|
|
91
|
+
|
|
92
|
+
EmptyState is strictly bound to these tokens — use only these, do not invent token names:
|
|
93
|
+
--cascivo-color-text, --cascivo-color-text-subtle, --cascivo-color-text-muted, --cascivo-color-bg-subtle, --cascivo-radius-full
|
|
94
|
+
|
|
95
|
+
Accessibility: role "none", WCAG 2.2-AA. Keep it AA.
|
|
96
|
+
|
|
97
|
+
Do not change (strict): token names — Text and background colors must resolve to --cascivo-* tokens
|
|
98
|
+
Flexible: size and action.
|
|
99
|
+
|
|
100
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
101
|
+
```
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Fab
|
|
2
|
+
|
|
3
|
+
**Category:** inputs
|
|
4
|
+
**Description:** Floating action button anchored to a screen corner, with an optional speed-dial of secondary actions
|
|
5
|
+
|
|
6
|
+
## When to use
|
|
7
|
+
|
|
8
|
+
- A single, high-emphasis primary action that floats above scrolling content (e.g. Compose, Add)
|
|
9
|
+
- A small cluster of related create actions revealed from one corner via a speed-dial
|
|
10
|
+
- Touch-first screens where the primary action should stay reachable at the thumb
|
|
11
|
+
|
|
12
|
+
## When NOT to use
|
|
13
|
+
|
|
14
|
+
- Ordinary form or toolbar buttons — use Button or IconButton in the layout flow
|
|
15
|
+
- More than a handful of actions — use a Menu, Drawer, or full navigation
|
|
16
|
+
- Primary navigation between top-level destinations — use Dock
|
|
17
|
+
|
|
18
|
+
## Anti-patterns
|
|
19
|
+
|
|
20
|
+
### A floating button competes with the in-flow submit and hides the action off the form
|
|
21
|
+
|
|
22
|
+
**Bad:** `<Fab label="Save"><SaveIcon /></Fab> next to a form submit button`
|
|
23
|
+
**Good:** `<Button type="submit">Save</Button>`
|
|
24
|
+
**Why:** A floating button competes with the in-flow submit and hides the action off the form
|
|
25
|
+
|
|
26
|
+
## Related components
|
|
27
|
+
|
|
28
|
+
- **IconButton** (alternative): Use IconButton for an in-flow icon control; Fab floats and is high-emphasis
|
|
29
|
+
- **Dock** (alternative): Use Dock for bottom navigation between destinations rather than a single action
|
|
30
|
+
|
|
31
|
+
## Accessibility rationale
|
|
32
|
+
|
|
33
|
+
The main button is icon-only and requires a `label` that becomes its aria-label. With a speed-dial it exposes aria-haspopup="menu", aria-expanded, and aria-controls; the dial is a role="menu" of role="menuitem" buttons under vertical roving focus (Arrow keys, Home/End, wrapping). Opening moves focus to the first action and closing (Escape, outside press, or selection via DismissableLayer) returns focus to the button.
|
|
34
|
+
|
|
35
|
+
## Props
|
|
36
|
+
|
|
37
|
+
| Name | Type | Required | Default | Description |
|
|
38
|
+
| -------------- | -------------------------------- | -------- | ---------- | --------------------------------------------------------------------------- |
|
|
39
|
+
| `children` | `React.ReactNode` | Yes | — | The main icon |
|
|
40
|
+
| `label` | `string` | Yes | — | Accessible name for the button |
|
|
41
|
+
| `onClick` | `() => void` | No | — | Called when the element is clicked. |
|
|
42
|
+
| `actions` | `FabAction[]` | No | — | Speed-dial actions; each has a label, icon, onSelect, and optional disabled |
|
|
43
|
+
| `position` | `'bottom-end' \| 'bottom-start'` | No | bottom-end | Position of the component. |
|
|
44
|
+
| `open` | `boolean` | No | — | Whether the component is open (controlled). |
|
|
45
|
+
| `defaultOpen` | `boolean` | No | — | Whether the component is open on first render (uncontrolled). |
|
|
46
|
+
| `onOpenChange` | `(open: boolean) => void` | No | — | Called with the next open state when it changes. |
|
|
47
|
+
| `className` | `string` | No | — | Additional CSS class names merged onto the root element. |
|
|
48
|
+
|
|
49
|
+
## Tokens
|
|
50
|
+
|
|
51
|
+
- `--cascivo-color-accent`
|
|
52
|
+
- `--cascivo-color-accent-content`
|
|
53
|
+
- `--cascivo-color-accent-hover`
|
|
54
|
+
- `--cascivo-color-surface`
|
|
55
|
+
- `--cascivo-color-border`
|
|
56
|
+
- `--cascivo-radius-full`
|
|
57
|
+
- `--cascivo-shadow-overlay`
|
|
58
|
+
- `--cascivo-target-min-coarse`
|
|
59
|
+
- `--cascivo-motion-enter`
|
|
60
|
+
- `--cascivo-motion-exit`
|
|
61
|
+
- `--cascivo-z-dropdown`
|
|
62
|
+
|
|
63
|
+
## Examples
|
|
64
|
+
|
|
65
|
+
### Single action
|
|
66
|
+
|
|
67
|
+
```jsx
|
|
68
|
+
<Fab label="Compose" onClick={compose}>
|
|
69
|
+
<PlusIcon />
|
|
70
|
+
</Fab>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Speed dial
|
|
74
|
+
|
|
75
|
+
The main button toggles a menu of secondary actions.
|
|
76
|
+
|
|
77
|
+
```jsx
|
|
78
|
+
<Fab
|
|
79
|
+
label="Create"
|
|
80
|
+
actions={[
|
|
81
|
+
{ label: 'New note', icon: <NoteIcon />, onSelect: newNote },
|
|
82
|
+
{ label: 'New folder', icon: <FolderIcon />, onSelect: newFolder },
|
|
83
|
+
]}
|
|
84
|
+
>
|
|
85
|
+
<PlusIcon />
|
|
86
|
+
</Fab>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Start corner
|
|
90
|
+
|
|
91
|
+
```jsx
|
|
92
|
+
<Fab label="Help" position="bottom-start" onClick={openHelp}>
|
|
93
|
+
<HelpIcon />
|
|
94
|
+
</Fab>
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Boundaries
|
|
98
|
+
|
|
99
|
+
| Area | Level | Note |
|
|
100
|
+
| ---------- | -------- | ----------------------------------------------------------------------------- |
|
|
101
|
+
| actions | flexible | Omit for a single-action button, or provide a speed-dial of secondary actions |
|
|
102
|
+
| position | strict | Anchored to bottom-end or bottom-start; honours safe-area insets |
|
|
103
|
+
| open state | flexible | Speed-dial is controlled (open/onOpenChange) or uncontrolled (defaultOpen) |
|
|
104
|
+
|
|
105
|
+
## AI context prompt
|
|
106
|
+
|
|
107
|
+
Copy this into an LLM context bar before editing this component:
|
|
108
|
+
|
|
109
|
+
```text
|
|
110
|
+
I am modifying the cascivo Fab component (inputs). Floating action button anchored to a screen corner, with an optional speed-dial of secondary actions
|
|
111
|
+
|
|
112
|
+
Architecture constraints — follow exactly:
|
|
113
|
+
- Signals only (useSignal/useComputed/useSignalEffect from @cascivo/core). Never useState/useEffect/useContext/useReducer.
|
|
114
|
+
- Style only through --cascivo-* custom properties. No Tailwind, no inline styles, no CSS-in-JS.
|
|
115
|
+
- Responsive via @container queries on the canonical scale (30rem/40rem/64rem/80rem). Do not use global viewport @media breakpoints.
|
|
116
|
+
- Visual states (hover/focus/active/disabled) via CSS pseudo-classes, not JS.
|
|
117
|
+
- CSS logical properties only (RTL-safe).
|
|
118
|
+
|
|
119
|
+
Fab is strictly bound to these tokens — use only these, do not invent token names:
|
|
120
|
+
--cascivo-color-accent, --cascivo-color-accent-content, --cascivo-color-accent-hover, --cascivo-color-surface, --cascivo-color-border, --cascivo-radius-full, --cascivo-shadow-overlay, --cascivo-target-min-coarse, --cascivo-motion-enter, --cascivo-motion-exit, --cascivo-z-dropdown
|
|
121
|
+
|
|
122
|
+
Accessibility: role "button", WCAG 2.2-AA, keyboard: Enter/Space/ArrowUp/ArrowDown/Home/End/Escape. Keep it AA.
|
|
123
|
+
|
|
124
|
+
Do not change (strict): position — Anchored to bottom-end or bottom-start; honours safe-area insets
|
|
125
|
+
Flexible: actions, open state.
|
|
126
|
+
|
|
127
|
+
Do not invent props, tokens, or global viewport media queries.
|
|
128
|
+
```
|