@flesler/cursor-canvas-web 1.0.2 → 1.1.1
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/README.md +9 -8
- package/dist/cursor-canvas.cjs +1 -1
- package/dist/cursor-canvas.js +702 -746
- package/dist/host-tokens-Cjzmp0z_.cjs +1 -0
- package/dist/host-tokens-Dh2BFFjv.js +412 -0
- package/dist/runtime/index.d.ts +5 -7
- package/dist/runtime.cjs +5 -1
- package/dist/runtime.js +109 -14
- package/package.json +22 -13
- package/src/vendor/canvas/SKILL.md +113 -0
- package/src/vendor/canvas-sdk/callout-tone-icons.d.ts +10 -0
- package/src/vendor/canvas-sdk/canvas-tokens.d.ts +259 -0
- package/src/vendor/canvas-sdk/chart-primitives.d.ts +272 -0
- package/src/vendor/canvas-sdk/collapsible-section.d.ts +66 -0
- package/src/vendor/canvas-sdk/dag-layout.d.ts +101 -0
- package/src/vendor/canvas-sdk/diff-view.d.ts +129 -0
- package/src/vendor/canvas-sdk/form-primitives.d.ts +194 -0
- package/src/vendor/canvas-sdk/hooks.d.ts +173 -0
- package/src/vendor/canvas-sdk/index.d.ts +65 -0
- package/src/vendor/canvas-sdk/internal/canvas-action-dispatch.d.ts +17 -0
- package/src/vendor/canvas-sdk/manifest.json +5 -0
- package/src/vendor/canvas-sdk/swatch.d.ts +39 -0
- package/src/vendor/canvas-sdk/theme.d.ts +107 -0
- package/src/vendor/canvas-sdk/todo-list.d.ts +48 -0
- package/src/vendor/canvas-sdk/ui-primitives.d.ts +569 -0
- package/src/vendor/canvas-sdk/usage-bar.d.ts +55 -0
- package/dist/shim/charts.d.ts +0 -66
- package/dist/shim/cursor-canvas.d.ts +0 -278
- package/dist/shim/dag.d.ts +0 -55
- package/dist/shim/diff.d.ts +0 -23
- package/dist/shim/theme.d.ts +0 -323
- package/dist/shim/todo.d.ts +0 -22
- package/dist/shim/use-tokens.d.ts +0 -6
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Form primitives for `cursor/canvas`. Provides themed, controlled form controls
|
|
3
|
+
* for interactive canvas apps with persistent state. All `onChange` callbacks
|
|
4
|
+
* receive the **value directly** (not a DOM event), so they pair naturally
|
|
5
|
+
* with `useCanvasState`:
|
|
6
|
+
*
|
|
7
|
+
* ```tsx
|
|
8
|
+
* const [name, setName] = useCanvasState("name", "");
|
|
9
|
+
* <TextInput value={name} onChange={setName} placeholder="Enter name…" />
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
import { type CSSProperties, type JSX, type ReactNode } from "react";
|
|
13
|
+
export type TextInputProps = {
|
|
14
|
+
value?: string;
|
|
15
|
+
/** Called with the new string value on every keystroke. */
|
|
16
|
+
onChange?: (value: string) => void;
|
|
17
|
+
placeholder?: string;
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
type?: "text" | "email" | "password" | "number" | "url" | "search";
|
|
20
|
+
style?: CSSProperties;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Single-line text input (28px height). Use for names, titles, search
|
|
24
|
+
* queries, and short text fields.
|
|
25
|
+
*
|
|
26
|
+
* `onChange` receives the **string value**, not a DOM event — this pairs
|
|
27
|
+
* directly with `useCanvasState` setters.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* const [name, setName] = useCanvasState("name", "");
|
|
32
|
+
*
|
|
33
|
+
* <TextInput value={name} onChange={setName} placeholder="Task title…" />
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function TextInput({ value, onChange, placeholder, disabled, type, style, }: TextInputProps): JSX.Element;
|
|
37
|
+
export type TextAreaProps = {
|
|
38
|
+
value?: string;
|
|
39
|
+
/** Called with the new string value on every keystroke. */
|
|
40
|
+
onChange?: (value: string) => void;
|
|
41
|
+
placeholder?: string;
|
|
42
|
+
disabled?: boolean;
|
|
43
|
+
/** Minimum visible rows. Defaults to 3. */
|
|
44
|
+
rows?: number;
|
|
45
|
+
style?: CSSProperties;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Multi-line text input that auto-resizes to fit its content.
|
|
49
|
+
* Use for notes, descriptions, comments, and multi-line text fields.
|
|
50
|
+
*
|
|
51
|
+
* The textarea grows as the user types. Set `rows` for the minimum visible
|
|
52
|
+
* height (defaults to 3). Override with `style={{ height: "100px" }}` for a
|
|
53
|
+
* fixed size.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```tsx
|
|
57
|
+
* const [notes, setNotes] = useCanvasState("notes", "");
|
|
58
|
+
*
|
|
59
|
+
* <TextArea value={notes} onChange={setNotes} placeholder="Add notes…" rows={4} />
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
export declare function TextArea({ value, onChange, placeholder, disabled, rows, style, }: TextAreaProps): JSX.Element;
|
|
63
|
+
export type CheckboxProps = {
|
|
64
|
+
checked?: boolean;
|
|
65
|
+
/** Called with the new boolean value when toggled. */
|
|
66
|
+
onChange?: (checked: boolean) => void;
|
|
67
|
+
disabled?: boolean;
|
|
68
|
+
/** Optional label rendered beside the checkbox. Clicking the label toggles the checkbox. */
|
|
69
|
+
label?: ReactNode;
|
|
70
|
+
style?: CSSProperties;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Checkbox with optional label (accent blue when checked).
|
|
74
|
+
*
|
|
75
|
+
* Pass `label` to render a clickable text label beside the checkbox. Without a
|
|
76
|
+
* label, provide `title` or wrap in your own `<label>` for accessibility.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```tsx
|
|
80
|
+
* const [agreed, setAgreed] = useCanvasState("agreed", false);
|
|
81
|
+
*
|
|
82
|
+
* <Checkbox checked={agreed} onChange={setAgreed} label="I agree to the terms" />
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```tsx
|
|
87
|
+
* // Checkbox in a list — no label, parent handles layout
|
|
88
|
+
* <Checkbox checked={item.done} onChange={(v) => toggleItem(item.id, v)} />
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
export declare function Checkbox({ checked, onChange, disabled, label, style, }: CheckboxProps): JSX.Element;
|
|
92
|
+
export type ToggleProps = {
|
|
93
|
+
checked?: boolean;
|
|
94
|
+
/** Called with the new boolean value when toggled. */
|
|
95
|
+
onChange?: (checked: boolean) => void;
|
|
96
|
+
disabled?: boolean;
|
|
97
|
+
/** `sm` = 16px track, `md` = 20px track (default `sm`). */
|
|
98
|
+
size?: "sm" | "md";
|
|
99
|
+
style?: CSSProperties;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Boolean toggle switch. Uses the accent color for the "on" state and a
|
|
103
|
+
* neutral fill for "off".
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```tsx
|
|
107
|
+
* const [enabled, setEnabled] = useCanvasState("enabled", false);
|
|
108
|
+
*
|
|
109
|
+
* <Row gap={8} align="center">
|
|
110
|
+
* <Text>Notifications</Text>
|
|
111
|
+
* <Spacer />
|
|
112
|
+
* <Toggle checked={enabled} onChange={setEnabled} />
|
|
113
|
+
* </Row>
|
|
114
|
+
* ```
|
|
115
|
+
*/
|
|
116
|
+
export declare function Toggle({ checked, onChange, disabled, size, style, }: ToggleProps): JSX.Element;
|
|
117
|
+
export type SelectOption = {
|
|
118
|
+
value: string;
|
|
119
|
+
label: string;
|
|
120
|
+
disabled?: boolean;
|
|
121
|
+
};
|
|
122
|
+
export type SelectProps = {
|
|
123
|
+
value?: string;
|
|
124
|
+
/** Called with the new selected value. */
|
|
125
|
+
onChange?: (value: string) => void;
|
|
126
|
+
/** List of options. Each must have a unique `value`. */
|
|
127
|
+
options: SelectOption[];
|
|
128
|
+
/** Placeholder shown when no value is selected. */
|
|
129
|
+
placeholder?: string;
|
|
130
|
+
disabled?: boolean;
|
|
131
|
+
style?: CSSProperties;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Dropdown select (native `<select>` with themed styling).
|
|
135
|
+
*
|
|
136
|
+
* Uses a native `<select>` under the hood for reliable keyboard, screen-reader,
|
|
137
|
+
* and mobile support. The OS-rendered option list is themed for dark mode via
|
|
138
|
+
* `color-scheme` and per-option colors.
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```tsx
|
|
142
|
+
* const [priority, setPriority] = useCanvasState("priority", "medium");
|
|
143
|
+
*
|
|
144
|
+
* <Select
|
|
145
|
+
* value={priority}
|
|
146
|
+
* onChange={setPriority}
|
|
147
|
+
* options={[
|
|
148
|
+
* { value: "low", label: "Low" },
|
|
149
|
+
* { value: "medium", label: "Medium" },
|
|
150
|
+
* { value: "high", label: "High" },
|
|
151
|
+
* ]}
|
|
152
|
+
* />
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
export declare function Select({ value, onChange, options, placeholder, disabled, style, }: SelectProps): JSX.Element;
|
|
156
|
+
export type IconButtonProps = {
|
|
157
|
+
/** Icon content: an SVG element, emoji, or unicode character. */
|
|
158
|
+
children: ReactNode;
|
|
159
|
+
onClick?: () => void;
|
|
160
|
+
disabled?: boolean;
|
|
161
|
+
/** Tooltip text. Always provide for accessibility since there is no text label. */
|
|
162
|
+
title?: string;
|
|
163
|
+
/**
|
|
164
|
+
* `"default"` is transparent until hovered; `"circle"` has a permanent
|
|
165
|
+
* background fill.
|
|
166
|
+
*/
|
|
167
|
+
variant?: "default" | "circle";
|
|
168
|
+
/** `sm` = 16px, `md` = 20px (default `md`). */
|
|
169
|
+
size?: "sm" | "md";
|
|
170
|
+
style?: CSSProperties;
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* Compact icon-only button for inline actions on list items (delete, edit,
|
|
174
|
+
* expand, etc.). Accepts **any** `children` as the icon — use an inline SVG,
|
|
175
|
+
* an emoji, or a unicode character.
|
|
176
|
+
*
|
|
177
|
+
* Always provide `title` for accessibility (screen-reader label + tooltip).
|
|
178
|
+
*
|
|
179
|
+
* Canvas has no icon font, so pass icon content directly.
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* ```tsx
|
|
183
|
+
* // Delete button on a card
|
|
184
|
+
* <IconButton title="Delete" onClick={() => remove(id)}>✕</IconButton>
|
|
185
|
+
*
|
|
186
|
+
* // Edit button with an SVG icon
|
|
187
|
+
* <IconButton title="Edit" variant="circle" size="sm" onClick={edit}>
|
|
188
|
+
* <svg width={12} height={12} viewBox="0 0 12 12" fill="none">
|
|
189
|
+
* <path d="M8.5 1.5l2 2L4 10H2V8z" stroke="currentColor" strokeWidth={1.2} />
|
|
190
|
+
* </svg>
|
|
191
|
+
* </IconButton>
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
export declare function IconButton({ children, onClick, disabled, title, variant, size, style, }: IconButtonProps): JSX.Element;
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import type { CanvasHostThemeBrand, CanvasPalette, CanvasTokens, ChartPalette } from "./canvas-tokens.js";
|
|
2
|
+
import { type CanvasAction } from "./internal/canvas-action-dispatch.js";
|
|
3
|
+
import { type CanvasRadius, type CanvasTypography } from "./theme.js";
|
|
4
|
+
/**
|
|
5
|
+
* Host theme for the current canvas. Semantic color groups (`text`, `bg`,
|
|
6
|
+
* `fill`, `stroke`, `accent`, `diff`) live at the top level for ergonomic
|
|
7
|
+
* inline-style access; `tokens` is also present as a self-reference for
|
|
8
|
+
* callers that prefer a namespaced form. There is no `colors` bag —
|
|
9
|
+
* `theme.colors.bg.primary` is not a path.
|
|
10
|
+
*/
|
|
11
|
+
export interface CanvasHostTheme extends CanvasTokens {
|
|
12
|
+
readonly kind: string;
|
|
13
|
+
readonly brand: CanvasHostThemeBrand;
|
|
14
|
+
readonly tokens: CanvasTokens;
|
|
15
|
+
readonly palette: CanvasPalette;
|
|
16
|
+
readonly radius: CanvasRadius;
|
|
17
|
+
readonly typography: CanvasTypography;
|
|
18
|
+
readonly chart: {
|
|
19
|
+
readonly palette: ChartPalette;
|
|
20
|
+
readonly sequence: readonly string[];
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Raw theme payload read from the host `theme` channel. Every field is typed
|
|
25
|
+
* `unknown` on purpose: the value crosses an untrusted JSON/SSE boundary
|
|
26
|
+
* (`window.__cursorCanvas.state`), so it is validated per-field at read time
|
|
27
|
+
* rather than trusted from the wire. Mirrors `CanvasHostThemeState` from
|
|
28
|
+
* `@anysphere/constants` (the producer side); kept local so this bundled SDK
|
|
29
|
+
* stays dependency-free.
|
|
30
|
+
*/
|
|
31
|
+
interface RawHostThemeState {
|
|
32
|
+
readonly kind?: unknown;
|
|
33
|
+
readonly brand?: unknown;
|
|
34
|
+
readonly primary?: unknown;
|
|
35
|
+
readonly editorBackground?: unknown;
|
|
36
|
+
readonly editorForeground?: unknown;
|
|
37
|
+
}
|
|
38
|
+
/** Exported for unit tests only; not part of the SDK surface (see index.ts). */
|
|
39
|
+
export declare function resolveTheme(raw: RawHostThemeState | undefined): CanvasHostTheme;
|
|
40
|
+
/**
|
|
41
|
+
* Returns the current host theme. When no host state is available (first
|
|
42
|
+
* paint, or a dead state bridge) it falls back to the page's
|
|
43
|
+
* `prefers-color-scheme` polarity instead of assuming dark.
|
|
44
|
+
*
|
|
45
|
+
* Semantic color groups are available directly on the returned object —
|
|
46
|
+
* `accent`, `text`, `bg`, `fill`, `stroke`, `diff` — as well as `kind`
|
|
47
|
+
* (`"dark"` | `"light"` | …), `brand` (`"cursor"` | `"grok"`, default
|
|
48
|
+
* `"cursor"` when the host omits it), and `palette` (the flat color
|
|
49
|
+
* palette). There is no `theme.colors` group.
|
|
50
|
+
*
|
|
51
|
+
* Call `useHostTheme()` inside each component that needs theme access —
|
|
52
|
+
* the returned object is scoped to that component, not shared across
|
|
53
|
+
* function boundaries.
|
|
54
|
+
*
|
|
55
|
+
* Stable paths for `style={{ ... }}` usage:
|
|
56
|
+
* - `text.primary / secondary / tertiary / quaternary` — text hierarchy
|
|
57
|
+
* - `bg.editor / chrome / elevated` — surface backgrounds
|
|
58
|
+
* - `fill.primary / secondary / tertiary / quaternary` — tinted fills
|
|
59
|
+
* - `stroke.primary / secondary / tertiary` — borders and dividers
|
|
60
|
+
* - `accent.primary / control` — accent blue and button background
|
|
61
|
+
* - `text.link` — link color
|
|
62
|
+
* - `text.onAccent` — text on accent-colored surfaces
|
|
63
|
+
*
|
|
64
|
+
* Prefer built-in components (`Card`, `Button`, `Text`, etc.) over raw
|
|
65
|
+
* token usage. Reach for tokens only when no component covers the case,
|
|
66
|
+
* and stick to flat solid colors — no gradients, no box-shadows.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```tsx
|
|
70
|
+
* function Overview() {
|
|
71
|
+
* const theme = useHostTheme();
|
|
72
|
+
* return (
|
|
73
|
+
* <div style={{ background: theme.fill.tertiary, color: theme.text.secondary, padding: 8 }}>
|
|
74
|
+
* <span style={{ color: theme.accent.primary }}>Accent text</span>
|
|
75
|
+
* </div>
|
|
76
|
+
* );
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export declare function useHostTheme(): CanvasHostTheme;
|
|
81
|
+
/**
|
|
82
|
+
* Setter for `useCanvasState`. Accepts either a new value or an updater
|
|
83
|
+
* function that receives the previous value.
|
|
84
|
+
*/
|
|
85
|
+
export type SetCanvasState<T> = (action: T | ((prev: T) => T)) => void;
|
|
86
|
+
/**
|
|
87
|
+
* Persistent state hook for canvas applications. Works like `React.useState`
|
|
88
|
+
* but the value survives rebuilds, reloads, and IDE restarts — it is stored
|
|
89
|
+
* in a `.canvas.data.json` sidecar file next to the canvas source.
|
|
90
|
+
*
|
|
91
|
+
* Each key is a unique string chosen by the canvas author. Keys are stable
|
|
92
|
+
* regardless of hook call order or component tree structure.
|
|
93
|
+
*
|
|
94
|
+
* @param key - Unique string identifier for this piece of state.
|
|
95
|
+
* @param defaultValue - Value returned when no persisted value exists for `key`.
|
|
96
|
+
* @returns A `[value, setValue]` tuple, same shape as `React.useState`.
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* ```tsx
|
|
100
|
+
* function Counter() {
|
|
101
|
+
* const [count, setCount] = useCanvasState("count", 0);
|
|
102
|
+
* return <Button onClick={() => setCount(c => c + 1)}>{count}</Button>;
|
|
103
|
+
* }
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```tsx
|
|
108
|
+
* interface Column { id: string; title: string; cardIds: string[] }
|
|
109
|
+
* function KanbanBoard() {
|
|
110
|
+
* const [columns, setColumns] = useCanvasState<Column[]>("columns", [
|
|
111
|
+
* { id: "todo", title: "To Do", cardIds: [] },
|
|
112
|
+
* { id: "doing", title: "In Progress", cardIds: [] },
|
|
113
|
+
* { id: "done", title: "Done", cardIds: [] },
|
|
114
|
+
* ]);
|
|
115
|
+
* // ...
|
|
116
|
+
* }
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
export declare function useCanvasState<T>(key: string, defaultValue: T): [T, SetCanvasState<T>];
|
|
120
|
+
export type { CanvasAction };
|
|
121
|
+
/**
|
|
122
|
+
* Returns a stable `dispatch` function for triggering IDE actions from
|
|
123
|
+
* canvas buttons. Actions are fire-and-forget — the canvas does not
|
|
124
|
+
* receive a response.
|
|
125
|
+
*
|
|
126
|
+
* ## Available actions
|
|
127
|
+
*
|
|
128
|
+
* **`openAgent`** — Navigate the IDE to an agent conversation.
|
|
129
|
+
* `agentId` is the conversation UUID (the filename stem from the
|
|
130
|
+
* `agent-transcripts/` directory). Works for both local and
|
|
131
|
+
* cloud/background agents in Glass and classic IDE modes.
|
|
132
|
+
*
|
|
133
|
+
* **`newComposerChat`** — Open a new local agent chat with the
|
|
134
|
+
* dispatching canvas file as an @mention. Optional `userPrompt` is
|
|
135
|
+
* appended after the mention. The canvas file is resolved from the
|
|
136
|
+
* action route's `canvasId`; do not pass the path from canvas UI.
|
|
137
|
+
*
|
|
138
|
+
* **`openFile`** — Open an existing workspace file in the host IDE.
|
|
139
|
+
* `path` may be workspace-relative or absolute. Optional `selection`
|
|
140
|
+
* follows VS Code editor line/column fields.
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```tsx
|
|
144
|
+
* function AgentLink({ agentId, title }: { agentId: string; title: string }) {
|
|
145
|
+
* const dispatch = useCanvasAction();
|
|
146
|
+
* return (
|
|
147
|
+
* <Button onClick={() => dispatch({ type: "openAgent", agentId })}>
|
|
148
|
+
* {title}
|
|
149
|
+
* </Button>
|
|
150
|
+
* );
|
|
151
|
+
* }
|
|
152
|
+
* ```
|
|
153
|
+
*
|
|
154
|
+
* @example
|
|
155
|
+
* ```tsx
|
|
156
|
+
* function AskAboutCanvas() {
|
|
157
|
+
* const dispatch = useCanvasAction();
|
|
158
|
+
* return (
|
|
159
|
+
* <Button
|
|
160
|
+
* onClick={() =>
|
|
161
|
+
* dispatch({
|
|
162
|
+
* type: "newComposerChat",
|
|
163
|
+
* userPrompt: "please explain what is using the most context",
|
|
164
|
+
* })
|
|
165
|
+
* }
|
|
166
|
+
* >
|
|
167
|
+
* Ask in chat
|
|
168
|
+
* </Button>
|
|
169
|
+
* );
|
|
170
|
+
* }
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
173
|
+
export declare function useCanvasAction(): (action: CanvasAction) => void;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public API for authoring `.canvas.tsx` files via `cursor/canvas`.
|
|
3
|
+
*
|
|
4
|
+
* Be creative with layout — use Grid, Row, cards, charts, tables, and raw SVG
|
|
5
|
+
* in whatever combination serves the content. Read
|
|
6
|
+
* `~/.cursor/skills-cursor/canvas/SKILL.md` for full design guidance. Key
|
|
7
|
+
* constraints:
|
|
8
|
+
*
|
|
9
|
+
* - Colors from `useHostTheme()` tokens (`theme.bg.editor`, not
|
|
10
|
+
* `theme.colors.bg.primary`). No hardcoded hex.
|
|
11
|
+
* - Literal props are component-specific: `Pill.tone` has no `"danger"`
|
|
12
|
+
* and is ignored; `Card.variant` is only `"default"` | `"borderless"`.
|
|
13
|
+
* - No gradients, no box-shadows, no emojis as decoration.
|
|
14
|
+
* - Don't wrap every section in Card — mix open sections with cards.
|
|
15
|
+
* - Run that skill's Pre-delivery self-check before returning code.
|
|
16
|
+
*/
|
|
17
|
+
/** React authoring utilities re-exported so canvases need one public import. */
|
|
18
|
+
export type { CSSProperties, RefObject } from "react";
|
|
19
|
+
export { useEffect, useMemo, useRef, useState } from "react";
|
|
20
|
+
/** Shared category color palette used by `Swatch`, `UsageBar`, etc. */
|
|
21
|
+
export type { CanvasHostThemeBrand, CategoryPalette, ChartPalette, Color, } from "./canvas-tokens.js";
|
|
22
|
+
export { categoryPaletteDark, categoryPaletteLight, colorPalette, usageColorSequence, } from "./canvas-tokens.js";
|
|
23
|
+
/** Charts. */
|
|
24
|
+
export type { BarChartProps, ChartDataPoint, ChartReferenceLine, ChartSeries, ChartTone, LineChartProps, PieChartProps, } from "./chart-primitives.js";
|
|
25
|
+
export { BarChart, LineChart, PieChart } from "./chart-primitives.js";
|
|
26
|
+
/** Borderless collapsible disclosure row with a structured header. */
|
|
27
|
+
export type { CollapsibleSectionProps } from "./collapsible-section.js";
|
|
28
|
+
export { CollapsibleSection } from "./collapsible-section.js";
|
|
29
|
+
/** DAG layout. */
|
|
30
|
+
export type { DAGLayoutEdge, DAGLayoutNode, DAGLayoutOptions, DAGLayoutRank, DAGLayoutResult, } from "./dag-layout.js";
|
|
31
|
+
export { computeDAGLayout } from "./dag-layout.js";
|
|
32
|
+
/**
|
|
33
|
+
* Diff rendering. Compose with the generic `Card` family for file-level
|
|
34
|
+
* chrome: use `DiffView` inside a `CardBody` (with `padding: 0`) and put
|
|
35
|
+
* `DiffStats` in the enclosing `CardHeader`'s `trailing` slot.
|
|
36
|
+
*/
|
|
37
|
+
export type { DiffLineData, DiffLineType, DiffStatsProps, DiffViewProps } from "./diff-view.js";
|
|
38
|
+
export { DiffStats, DiffView } from "./diff-view.js";
|
|
39
|
+
/** Form controls. */
|
|
40
|
+
export type { CheckboxProps, IconButtonProps, SelectOption, SelectProps, TextAreaProps, TextInputProps, ToggleProps, } from "./form-primitives.js";
|
|
41
|
+
export { Checkbox, IconButton, Select, TextArea, TextInput, Toggle } from "./form-primitives.js";
|
|
42
|
+
/** Host state hooks. */
|
|
43
|
+
export type { CanvasAction, CanvasHostTheme, SetCanvasState } from "./hooks.js";
|
|
44
|
+
export { useCanvasAction, useCanvasState, useHostTheme } from "./hooks.js";
|
|
45
|
+
/** Colored category swatch (uses the shared `Color` palette). */
|
|
46
|
+
export type { SwatchProps } from "./swatch.js";
|
|
47
|
+
export { Swatch } from "./swatch.js";
|
|
48
|
+
/** Semantic design tokens for custom styling. */
|
|
49
|
+
export type { CanvasPalette, CanvasTokens } from "./theme.js";
|
|
50
|
+
export { canvasPaletteDark, canvasPaletteGrokDark, canvasPaletteGrokLight, canvasPaletteLight, canvasTokens, canvasTokensLight, } from "./theme.js";
|
|
51
|
+
export type { TodoItem, TodoListCardProps, TodoListProps, TodoStatus } from "./todo-list.js";
|
|
52
|
+
export { TodoList, TodoListCard } from "./todo-list.js";
|
|
53
|
+
/** Component props types. */
|
|
54
|
+
export type { ButtonProps, CalloutProps, CalloutTone, CardBodyProps, CardHeaderProps, CardProps, CardSize, CardVariant, CodeProps, DividerProps, GridProps, H1Props, H2Props, H3Props, LinkProps, PillProps, PillSize, PillTone, RowProps, StackProps, StatProps, StatTone, TableColumnAlign, TableProps, TableRowTone, TextProps, TextWeight, } from "./ui-primitives.js";
|
|
55
|
+
/** Layout. */
|
|
56
|
+
/** Typography. */
|
|
57
|
+
/** Surfaces. */
|
|
58
|
+
/** Actions. */
|
|
59
|
+
/** Feedback. */
|
|
60
|
+
export { Button, Callout, Card, CardBody, CardHeader, Code, Divider, Grid, H1, H2, H3, Link,
|
|
61
|
+
/** Shallow-merge two style objects. Useful for combining tokens with overrides. */
|
|
62
|
+
mergeStyle, Pill, Row, Spacer, Stack, Stat, Table, Text, } from "./ui-primitives.js";
|
|
63
|
+
/** Usage bar — segmented progress meter with optional labels above. */
|
|
64
|
+
export type { UsageBarProps, UsageBarSegment } from "./usage-bar.js";
|
|
65
|
+
export { UsageBar } from "./usage-bar.js";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stub for IDE `hooks.d.ts` — the skills-cursor SDK snapshot omits `internal/`.
|
|
3
|
+
* Keep in sync with Cursor's dispatch action union when syncing the SDK.
|
|
4
|
+
*/
|
|
5
|
+
export type CanvasAction =
|
|
6
|
+
| { type: 'openAgent'; agentId: string }
|
|
7
|
+
| { type: 'newComposerChat'; userPrompt?: string }
|
|
8
|
+
| {
|
|
9
|
+
type: 'openFile';
|
|
10
|
+
path: string;
|
|
11
|
+
selection?: {
|
|
12
|
+
startLineNumber: number;
|
|
13
|
+
startColumn: number;
|
|
14
|
+
endLineNumber?: number;
|
|
15
|
+
endColumn?: number;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colored category swatch — a small filled rounded box. Intended for inline
|
|
3
|
+
* list/row decoration (category badges, the leading slot of
|
|
4
|
+
* `CollapsibleSection`, etc.).
|
|
5
|
+
*
|
|
6
|
+
* Pulls colors from `useHostTheme().category` so a category's swatch and its
|
|
7
|
+
* `UsageBar` segment for the same `color` stay visually coherent.
|
|
8
|
+
*/
|
|
9
|
+
import type { CSSProperties, JSX } from "react";
|
|
10
|
+
import type { Color } from "./canvas-tokens.js";
|
|
11
|
+
export type SwatchProps = {
|
|
12
|
+
/** One of the shared category hues. Matches `UsageBar` segment colors. */
|
|
13
|
+
color: Color;
|
|
14
|
+
style?: CSSProperties;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Filled, rounded category swatch (24px). Use as the leading visual on
|
|
18
|
+
* category rows, list items, or as the `leading` slot of a
|
|
19
|
+
* `CollapsibleSection`.
|
|
20
|
+
*
|
|
21
|
+
* Colors come from the shared `Color` palette, so a category's swatch
|
|
22
|
+
* matches its `UsageBar` segment for the same `color`.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```tsx
|
|
26
|
+
* // Standalone — purple "tools" swatch
|
|
27
|
+
* <Swatch color="purple" />
|
|
28
|
+
*
|
|
29
|
+
* // As the `leading` slot on a CollapsibleSection
|
|
30
|
+
* <CollapsibleSection
|
|
31
|
+
* title="Tools"
|
|
32
|
+
* count={4}
|
|
33
|
+
* leading={<Swatch color="purple" />}
|
|
34
|
+
* >
|
|
35
|
+
* <Text>Tool calls go here.</Text>
|
|
36
|
+
* </CollapsibleSection>
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export declare function Swatch({ color, style }: SwatchProps): JSX.Element;
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { CanvasHostThemeBrand } from "./canvas-tokens.js";
|
|
2
|
+
export type { CanvasHostThemeBrand, CanvasPalette, CanvasTokens, ChartPalette, } from "./canvas-tokens.js";
|
|
3
|
+
export { canvasPaletteDark, canvasPaletteGrokDark, canvasPaletteGrokLight, canvasPaletteLight, canvasTokens, canvasTokensLight, chartThemeForBrand, parseCanvasHostThemeBrand, } from "./canvas-tokens.js";
|
|
4
|
+
/** Typography presets used by the built-in `cursor/canvas` components. */
|
|
5
|
+
export declare const canvasTypography: {
|
|
6
|
+
readonly fontFamily: "inherit";
|
|
7
|
+
readonly h1: {
|
|
8
|
+
readonly fontSize: "24px";
|
|
9
|
+
readonly lineHeight: "30px";
|
|
10
|
+
readonly fontWeight: 590;
|
|
11
|
+
};
|
|
12
|
+
readonly h2: {
|
|
13
|
+
readonly fontSize: "18px";
|
|
14
|
+
readonly lineHeight: "24px";
|
|
15
|
+
readonly fontWeight: 590;
|
|
16
|
+
};
|
|
17
|
+
readonly h3: {
|
|
18
|
+
readonly fontSize: "16px";
|
|
19
|
+
readonly lineHeight: "22px";
|
|
20
|
+
readonly fontWeight: 590;
|
|
21
|
+
};
|
|
22
|
+
readonly body: {
|
|
23
|
+
readonly fontSize: "14px";
|
|
24
|
+
readonly lineHeight: "20px";
|
|
25
|
+
readonly fontWeight: 400;
|
|
26
|
+
};
|
|
27
|
+
readonly small: {
|
|
28
|
+
readonly fontSize: "12px";
|
|
29
|
+
readonly lineHeight: "16px";
|
|
30
|
+
readonly fontWeight: 400;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Cursor canvases inherit the host frame's face (Geist in IDE / Inter on
|
|
35
|
+
* portal). Do not force Geist into the SDK — hosts already load it.
|
|
36
|
+
*/
|
|
37
|
+
export declare const canvasFontFamilyCursor: "inherit";
|
|
38
|
+
/**
|
|
39
|
+
* Sand's current `--sand-font-sans` stack. Hosts apply this same stack on
|
|
40
|
+
* the frame document so `inherit` matches the token. System faces only.
|
|
41
|
+
*/
|
|
42
|
+
export declare const canvasFontFamilyGrok: string;
|
|
43
|
+
/** Spacing scale (px). */
|
|
44
|
+
export declare const canvasSpacing: {
|
|
45
|
+
readonly "0.5": 2;
|
|
46
|
+
readonly "1": 4;
|
|
47
|
+
readonly "1.5": 6;
|
|
48
|
+
readonly "2": 8;
|
|
49
|
+
readonly "2.5": 10;
|
|
50
|
+
readonly "3": 12;
|
|
51
|
+
readonly "3.5": 14;
|
|
52
|
+
readonly "4": 16;
|
|
53
|
+
readonly "4.5": 18;
|
|
54
|
+
readonly "5": 20;
|
|
55
|
+
readonly "6": 24;
|
|
56
|
+
readonly "7": 28;
|
|
57
|
+
readonly "8": 32;
|
|
58
|
+
readonly "9": 36;
|
|
59
|
+
readonly "10": 40;
|
|
60
|
+
};
|
|
61
|
+
export type CanvasSpacing = typeof canvasSpacing;
|
|
62
|
+
/** Border radius (px). */
|
|
63
|
+
export declare const canvasRadius: {
|
|
64
|
+
readonly none: 0;
|
|
65
|
+
readonly xs: 2;
|
|
66
|
+
readonly sm: 4;
|
|
67
|
+
readonly md: 6;
|
|
68
|
+
readonly lg: 8;
|
|
69
|
+
readonly xl: 12;
|
|
70
|
+
readonly full: 9999;
|
|
71
|
+
};
|
|
72
|
+
export type CanvasRadius = {
|
|
73
|
+
readonly [K in keyof typeof canvasRadius]: number;
|
|
74
|
+
};
|
|
75
|
+
export type CanvasTypography = {
|
|
76
|
+
readonly fontFamily: string;
|
|
77
|
+
readonly h1: {
|
|
78
|
+
readonly fontSize: string;
|
|
79
|
+
readonly lineHeight: string;
|
|
80
|
+
readonly fontWeight: number;
|
|
81
|
+
};
|
|
82
|
+
readonly h2: {
|
|
83
|
+
readonly fontSize: string;
|
|
84
|
+
readonly lineHeight: string;
|
|
85
|
+
readonly fontWeight: number;
|
|
86
|
+
};
|
|
87
|
+
readonly h3: {
|
|
88
|
+
readonly fontSize: string;
|
|
89
|
+
readonly lineHeight: string;
|
|
90
|
+
readonly fontWeight: number;
|
|
91
|
+
};
|
|
92
|
+
readonly body: {
|
|
93
|
+
readonly fontSize: string;
|
|
94
|
+
readonly lineHeight: string;
|
|
95
|
+
readonly fontWeight: number;
|
|
96
|
+
};
|
|
97
|
+
readonly small: {
|
|
98
|
+
readonly fontSize: string;
|
|
99
|
+
readonly lineHeight: string;
|
|
100
|
+
readonly fontWeight: number;
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
/** Sand-grounded radii: 8 / 10 / 14 on the md / lg / xl steps. */
|
|
104
|
+
export declare const canvasRadiusGrok: CanvasRadius;
|
|
105
|
+
export declare const canvasTypographyGrok: CanvasTypography;
|
|
106
|
+
export declare function canvasRadiusForBrand(brand: CanvasHostThemeBrand): CanvasRadius;
|
|
107
|
+
export declare function canvasTypographyForBrand(brand: CanvasHostThemeBrand): CanvasTypography;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { CSSProperties, JSX } from "react";
|
|
2
|
+
export type TodoStatus = "pending" | "in_progress" | "completed" | "cancelled";
|
|
3
|
+
export interface TodoItem {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly content: string;
|
|
6
|
+
readonly status: TodoStatus;
|
|
7
|
+
}
|
|
8
|
+
export type TodoListProps = {
|
|
9
|
+
todos: readonly TodoItem[];
|
|
10
|
+
dimmedTodoIds?: ReadonlySet<string>;
|
|
11
|
+
/** Called when a todo row is clicked (entire row is a button). */
|
|
12
|
+
onTodoClick?: (todo: TodoItem) => void;
|
|
13
|
+
style?: CSSProperties;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Task list with status icons and wrapping text. Each row is a **clickable**
|
|
17
|
+
* button; use `onTodoClick` to handle selection or navigation.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* <TodoList
|
|
22
|
+
* todos={items}
|
|
23
|
+
* onTodoClick={(todo) => setActiveId(todo.id)}
|
|
24
|
+
* />
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function TodoList({ todos, dimmedTodoIds, onTodoClick, style, }: TodoListProps): JSX.Element | null;
|
|
28
|
+
export type TodoListCardProps = {
|
|
29
|
+
todos: readonly TodoItem[];
|
|
30
|
+
dimmedTodoIds?: ReadonlySet<string>;
|
|
31
|
+
defaultExpanded?: boolean;
|
|
32
|
+
onTodoClick?: (todo: TodoItem) => void;
|
|
33
|
+
style?: CSSProperties;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Bordered, collapsible todo list with summary header (N of M Done). Compose
|
|
37
|
+
* with `onTodoClick` for row actions.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```tsx
|
|
41
|
+
* <TodoListCard
|
|
42
|
+
* todos={items}
|
|
43
|
+
* defaultExpanded
|
|
44
|
+
* onTodoClick={(todo) => console.log(todo.id)}
|
|
45
|
+
* />
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare function TodoListCard({ todos, dimmedTodoIds, defaultExpanded, onTodoClick, style, }: TodoListCardProps): JSX.Element | null;
|