@flesler/cursor-canvas-web 0.0.0-stage → 1.0.0
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 +21 -0
- package/README.md +211 -2
- package/dist/cursor-canvas.cjs +1 -0
- package/dist/cursor-canvas.js +1406 -0
- package/dist/runtime/index.d.ts +24 -0
- package/dist/runtime.cjs +1 -0
- package/dist/runtime.js +23 -0
- package/dist/shim/charts.d.ts +62 -0
- package/dist/shim/cursor-canvas.d.ts +278 -0
- package/dist/shim/dag.d.ts +55 -0
- package/dist/shim/diff.d.ts +23 -0
- package/dist/shim/theme.d.ts +319 -0
- package/dist/shim/todo.d.ts +22 -0
- package/dist/shim/use-tokens.d.ts +6 -0
- package/package.json +86 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 thisismydesign
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,212 @@
|
|
|
1
|
-
#
|
|
1
|
+
# cursor-canvas-web
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **Fork** of [`@thisismydesign/cursor-canvas-web`](https://github.com/thisismydesign/cursor-canvas-web) ([npm](https://www.npmjs.com/package/@thisismydesign/cursor-canvas-web)), published as **`@flesler/cursor-canvas-web`**. We keep the shim aligned with the Cursor IDE `cursor/canvas` SDK (see [`COMPAT.md`](./COMPAT.md), `pnpm test:contract`) and track current stack versions — **Mantine 8** and **Recharts 2 or 3** — instead of the upstream Mantine 7 line.
|
|
4
|
+
|
|
5
|
+
Deploy **Cursor canvases** to the web.
|
|
6
|
+
|
|
7
|
+
A Cursor canvas is a `.tsx` that imports only from `cursor/canvas`. That module isn't an installable package; it's provided by the Cursor IDE at compile time, so a canvas can't build or render anywhere outside the IDE. This project is an open, **Mantine-backed shim** of `cursor/canvas`. A build-time Vite alias swaps the module for the shim, so the same `.tsx` renders in the Cursor IDE and on the web. No converter, no fork of your source.
|
|
8
|
+
|
|
9
|
+
**Upstream demo:** <https://thisismydesign.github.io/cursor-canvas-web/> (this fork uses the same demo canvas; deploy your own `dist/` from `pnpm build`)
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
## How it works: a module shim, not a converter
|
|
14
|
+
|
|
15
|
+
Your canvas stays a normal `.tsx` React component that imports only from
|
|
16
|
+
`cursor/canvas`. The only bridge is one module that re-exports that API
|
|
17
|
+
implemented with Mantine. A Vite alias (plus a matching tsconfig path) resolves
|
|
18
|
+
`cursor/canvas` to the shim at build time. There is no parser, AST, or registry,
|
|
19
|
+
and your canvas source never changes.
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
your.canvas.tsx Vite alias + @flesler/cursor-canvas-web
|
|
23
|
+
imports "cursor/canvas" -> tsconfig paths -> Mantine core + @mantine/charts
|
|
24
|
+
-> Vite build -> any static host
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Because the shim mirrors the real SDK API, a canvas that builds here also
|
|
28
|
+
compiles and renders unchanged in the Cursor IDE.
|
|
29
|
+
|
|
30
|
+
## Install
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm add @flesler/cursor-canvas-web
|
|
34
|
+
# peer deps your app must supply (Mantine 8 + matching charts styles):
|
|
35
|
+
pnpm add react react-dom @mantine/core@^8 @mantine/charts@^8 recharts@^2
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The package ships two entry points:
|
|
39
|
+
|
|
40
|
+
| Import | Provides |
|
|
41
|
+
| ------------------------------------------- | --------------------------------------------- |
|
|
42
|
+
| `@flesler/cursor-canvas-web` | The `cursor/canvas` shim (components, hooks). |
|
|
43
|
+
| `@flesler/cursor-canvas-web/runtime` | `CanvasRoot` + `mountCanvas` web host glue. |
|
|
44
|
+
|
|
45
|
+
## Use it in your project
|
|
46
|
+
|
|
47
|
+
### 1. Point `cursor/canvas` at the package
|
|
48
|
+
|
|
49
|
+
Two coordinated settings — runtime (Vite) and types (tsconfig) — keep your
|
|
50
|
+
canvas sources pure while resolving the bare specifier to the shim:
|
|
51
|
+
|
|
52
|
+
```ts
|
|
53
|
+
// vite.config.ts — runtime
|
|
54
|
+
resolve: {
|
|
55
|
+
alias: {
|
|
56
|
+
'cursor/canvas': '@flesler/cursor-canvas-web',
|
|
57
|
+
},
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```jsonc
|
|
62
|
+
// tsconfig.json — types
|
|
63
|
+
"paths": {
|
|
64
|
+
"cursor/canvas": ["./node_modules/@flesler/cursor-canvas-web"]
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### 2. Mount your canvas
|
|
69
|
+
|
|
70
|
+
Use the `mountCanvas` helper (it wraps `MantineProvider` for you):
|
|
71
|
+
|
|
72
|
+
```tsx
|
|
73
|
+
// src/main.tsx
|
|
74
|
+
import { mountCanvas } from '@flesler/cursor-canvas-web/runtime';
|
|
75
|
+
import '@mantine/core/styles.css';
|
|
76
|
+
import '@mantine/charts/styles.css';
|
|
77
|
+
import MyCanvas from '../.cursor/canvases/my.canvas';
|
|
78
|
+
|
|
79
|
+
mountCanvas('root', <MyCanvas />);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Or, if you manage your own React root, wrap the tree with `CanvasRoot`:
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
import { CanvasRoot } from '@flesler/cursor-canvas-web/runtime';
|
|
86
|
+
import '@mantine/core/styles.css';
|
|
87
|
+
import '@mantine/charts/styles.css';
|
|
88
|
+
|
|
89
|
+
createRoot(el).render(
|
|
90
|
+
<CanvasRoot defaultColorScheme="auto">
|
|
91
|
+
<MyCanvas />
|
|
92
|
+
</CanvasRoot>,
|
|
93
|
+
);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The canvas file itself never changes — it still imports only from
|
|
97
|
+
`cursor/canvas`, so it renders identically in the Cursor IDE.
|
|
98
|
+
|
|
99
|
+
### 3. Deploy
|
|
100
|
+
|
|
101
|
+
The result is a plain Vite app, so `pnpm build` produces a static `dist/` you
|
|
102
|
+
can host anywhere (GitHub Pages, Netlify, Vercel, S3, …). This repo deploys its
|
|
103
|
+
example canvas to GitHub Pages — see [Example deployment](#example-deployment).
|
|
104
|
+
|
|
105
|
+
## Supported canvas API
|
|
106
|
+
|
|
107
|
+
The shim implements the **full public `cursor/canvas` surface**:
|
|
108
|
+
|
|
109
|
+
- Typography: `H1`, `H2`, `H3`, `Text`, `Code`, `Link`
|
|
110
|
+
- Layout: `Stack`, `Row`, `Spacer`, `Grid`, `Divider`, `mergeStyle`
|
|
111
|
+
- Surfaces: `Card`/`CardHeader`/`CardBody` (incl. `collapsible`)
|
|
112
|
+
- Display & feedback: `Stat`, `Pill`, `Callout`, `Table`
|
|
113
|
+
- Actions: `Button`, `IconButton`
|
|
114
|
+
- Forms: `Select`, `Checkbox`, `Toggle`, `TextInput`, `TextArea`
|
|
115
|
+
- Charts: `LineChart`, `BarChart`, `PieChart`
|
|
116
|
+
- Rich: `Swatch`, `UsageBar`, `CollapsibleSection`, `TodoList`/`TodoListCard`,
|
|
117
|
+
`DiffView`/`DiffStats`, `computeDAGLayout`
|
|
118
|
+
- Hooks: `useCanvasState`, `useHostTheme`, `useCanvasAction` (+ React
|
|
119
|
+
`useState` / `useEffect` / `useRef` / `useMemo` re-exported from the barrel)
|
|
120
|
+
- Tokens: `categoryPalette(Dark|Light)`, `colorPalette`, `usageColorSequence`,
|
|
121
|
+
`canvasTokens(Light)`, `canvasPalette(Dark|Light)`; `useHostTheme()` also
|
|
122
|
+
exposes `category`, `chart.palette` / `chart.sequence`, `radius`, `typography`,
|
|
123
|
+
and `spacing` (see `COMPAT.md` for IDE vs web)
|
|
124
|
+
|
|
125
|
+
Known fidelity gaps (behavior is reproduced, not the exact renderer):
|
|
126
|
+
`DiffView` skips Shiki syntax highlighting (plain-text fallback), and
|
|
127
|
+
`useCanvasAction` is a no-op on the web (IDE-only). Styling approximates the
|
|
128
|
+
Cursor theme rather than matching it pixel-for-pixel.
|
|
129
|
+
|
|
130
|
+
If your canvas needs an export the shim doesn't yet provide, see
|
|
131
|
+
[Extending the shim](#extending-the-shim).
|
|
132
|
+
|
|
133
|
+
## Example deployment
|
|
134
|
+
|
|
135
|
+
This repo is itself a working example. The canvas at
|
|
136
|
+
[`.cursor/canvases/demo.canvas.tsx`](./.cursor/canvases/demo.canvas.tsx) is the
|
|
137
|
+
single source of truth: the web app imports it directly, and the same file is
|
|
138
|
+
copied into Cursor's managed canvases folder so it renders in the IDE too.
|
|
139
|
+
|
|
140
|
+
The deployed result lives at
|
|
141
|
+
<https://thisismydesign.github.io/cursor-canvas-web/>.
|
|
142
|
+
|
|
143
|
+
`deploy.yml` builds and publishes to GitHub Pages on push to `main` via
|
|
144
|
+
`configure-pages` / `upload-pages-artifact` / `deploy-pages`. The Vite `base`
|
|
145
|
+
defaults to `/cursor-canvas-web/` (project Page); override it with the
|
|
146
|
+
`BASE_PATH` env var if you deploy elsewhere.
|
|
147
|
+
|
|
148
|
+
## Develop this repo
|
|
149
|
+
|
|
150
|
+
Tool versions (Node, pnpm) are pinned in [`.tool-versions`](./.tool-versions)
|
|
151
|
+
and managed with [mise](https://mise.jdx.dev/).
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
mise install # install Node + pnpm from .tool-versions
|
|
155
|
+
pnpm install
|
|
156
|
+
pnpm dev # start the dev server
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Validation gate:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
pnpm typecheck # tsc --noEmit, strict
|
|
163
|
+
pnpm lint # eslint
|
|
164
|
+
pnpm test # vitest run
|
|
165
|
+
pnpm test:contract # IDE SDK snapshot + export parity + consumer tsc
|
|
166
|
+
pnpm sync:sdk # refresh test/contract/cursor-sdk from ~/.cursor/skills-cursor/canvas/sdk
|
|
167
|
+
pnpm build # typecheck + vite build -> dist/
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Layout
|
|
171
|
+
|
|
172
|
+
| Path | Role |
|
|
173
|
+
| ---------------------------------- | ----------------------------------------------------- |
|
|
174
|
+
| `.cursor/canvases/demo.canvas.tsx` | The example canvas; imports **only** `cursor/canvas`. |
|
|
175
|
+
| `src/shim/cursor-canvas.tsx` | Mantine implementation matching the real SDK API. |
|
|
176
|
+
| `src/shim/theme.ts` | Tone→color map + host-theme tokens. |
|
|
177
|
+
| `src/runtime/index.tsx` | Web host glue (`CanvasRoot`, `mountCanvas`). |
|
|
178
|
+
| `src/main.tsx` | Mounts React inside `MantineProvider`. |
|
|
179
|
+
| `vite.config.ts` | `resolve.alias` for `cursor/canvas` + Pages base. |
|
|
180
|
+
| `vite.lib.config.ts` | Library build (shim + runtime) for publishing. |
|
|
181
|
+
| `tsconfig.json` | `paths` maps `cursor/canvas` to the shim. |
|
|
182
|
+
|
|
183
|
+
### Extending the shim
|
|
184
|
+
|
|
185
|
+
To support more of the canvas API:
|
|
186
|
+
|
|
187
|
+
1. Add the export to `src/shim/cursor-canvas.tsx`, implemented with Mantine.
|
|
188
|
+
2. Keep prop shapes stable — they are the contract canvases rely on, and they
|
|
189
|
+
must match the official SDK declarations so canvases render unchanged in the
|
|
190
|
+
IDE.
|
|
191
|
+
3. If it carries semantic color, map `tone` via `toneColor` in
|
|
192
|
+
`src/shim/theme.ts`, using the SDK's tone vocabulary for that primitive
|
|
193
|
+
(`StatTone`, `PillTone`, `CalloutTone`, `ChartTone`).
|
|
194
|
+
4. Add a test under `src/shim/__tests__/`.
|
|
195
|
+
|
|
196
|
+
The only non-trivial adapter so far is `LineChart`, which reshapes parallel
|
|
197
|
+
`categories` + `series[]` arrays into Mantine's array-of-row-objects `data` and
|
|
198
|
+
maps each series `tone` to a color (`reshapeLineChartData`).
|
|
199
|
+
|
|
200
|
+
### Publishing
|
|
201
|
+
|
|
202
|
+
`prepublishOnly` runs `typecheck`, `test`, and `build:lib` automatically, so a
|
|
203
|
+
publish only needs:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
npm login
|
|
207
|
+
npm publish --access public --tag latest
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
`--access public` is required for the scoped package. Publishing needs 2FA
|
|
211
|
+
(WebAuthn/passkey) on your npm account; `npm publish` opens a browser to
|
|
212
|
+
complete the passkey prompt.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react/jsx-runtime"),u=require("@mantine/core"),y=require("react"),B=require("@mantine/charts"),O={foreground:"#E4E4E4EB",foregroundSecondary:"#E4E4E48D",foregroundTertiary:"#E4E4E45E",foregroundQuaternary:"#E4E4E442",editor:"#181818",chrome:"#141414",sidebar:"#141414",elevated:"#181818",fillPrimary:"#E4E4E430",fillSecondary:"#E4E4E41E",fillTertiary:"#E4E4E411",fillQuaternary:"#E4E4E40A",strokePrimary:"#E4E4E433",strokeSecondary:"#E4E4E41F",strokeTertiary:"#E4E4E414",strokeFocused:"#599CE7",accent:"#599CE7",buttonBackground:"#599CE7",buttonForeground:"#191c22",buttonHoverBackground:"#6AABE9",link:"#87c3ff",diffInsertedLine:"#3FA26633",diffRemovedLine:"#B8004933",diffStripAdded:"#3FA2668F",diffStripRemoved:"#FC6B838F"},G={foreground:"#141414F0",foregroundSecondary:"#141414BD",foregroundTertiary:"#1414148A",foregroundQuaternary:"#1414145C",editor:"#FCFCFC",chrome:"#F8F8F8",sidebar:"#F3F3F3",elevated:"#FCFCFC",fillPrimary:"#14141433",fillSecondary:"#14141424",fillTertiary:"#14141414",fillQuaternary:"#1414140F",strokePrimary:"#14141433",strokeSecondary:"#1414141F",strokeTertiary:"#14141414",strokeFocused:"#3685BF",accent:"#3685BF",buttonBackground:"#3685BF",buttonForeground:"#FCFCFC",buttonHoverBackground:"#2E76AB",link:"#3685BF",diffInsertedLine:"#1F8A651F",diffRemovedLine:"#CF2D5614",diffStripAdded:"#1F8A65CC",diffStripRemoved:"#CF2D56CC"},M={gray:"#8888A8E0",purple:"#7B64B8F0",green:"#1F8A65E8",yellow:"#E8C030E0",cyan:"#2A9A8AE0",pink:"#C85898E0",blue:"#2E79B5E0",orange:"#F0A040E0",red:"#C04848E0"},$={gray:"#8888A8E0",purple:"#7B64B8F0",green:"#1F8A65E8",yellow:"#E8C030E0",cyan:"#2A9A8AE0",pink:"#C85898E0",blue:"#2E79B5E0",orange:"#F0A088E0",red:"#CF2D56E0"};function oe(e,t){return{bg:{editor:e.editor,chrome:e.chrome,elevated:e.elevated},text:{primary:e.foreground,secondary:e.foregroundSecondary,tertiary:e.foregroundTertiary,quaternary:e.foregroundQuaternary,link:e.link,onAccent:e.buttonForeground},stroke:{primary:e.strokePrimary,secondary:e.strokeSecondary,tertiary:e.strokeTertiary,focused:e.strokeFocused},fill:{primary:e.fillPrimary,secondary:e.fillSecondary,tertiary:e.fillTertiary,quaternary:e.fillQuaternary},accent:{primary:e.accent,control:e.buttonBackground,controlHover:e.buttonHoverBackground},diff:{insertedLine:e.diffInsertedLine,removedLine:e.diffRemovedLine,stripAdded:e.diffStripAdded,stripRemoved:e.diffStripRemoved},category:t}}const ae=oe(O,M),se=oe(G,$),ye=M,I=["blue","purple","green","yellow","cyan","pink","orange","red","gray"],me={green:"#1F8A65E8",darkGreen:"#0D855AE0",lightGreen:"#52B896E0",mintGreen:"#7DCAB0E0",blue:"#2E79B5E0",lightBlue:"#70B0D8E0",indigo:"#5A6CC0F0",lightIndigo:"#9AAADCE0",purple:"#7B64B8F0",lightPurple:"#AA98D8E0",warmPink:"#C85898E0",lightPink:"#E8A0C4E0",brightOrange:"#F0A040E0",deepOrange:"#C06028E0",goldenYellow:"#E8C030E0",darkAmber:"#C04848E0",warmPeach:"#F0A088E0",vibrantTeal:"#2A9A8AE0",muted:"#8888A8E0",neutralLine:"#888899D0"},ve={h1:{fontSize:"24px",lineHeight:"30px",fontWeight:590},h2:{fontSize:"18px",lineHeight:"24px",fontWeight:590},h3:{fontSize:"16px",lineHeight:"22px",fontWeight:590},body:{fontSize:"14px",lineHeight:"20px",fontWeight:400},small:{fontSize:"12px",lineHeight:"16px",fontWeight:400}},be={"0.5":2,1:4,"1.5":6,2:8,"2.5":10,3:12,"3.5":14,4:16,"4.5":18,5:20,6:24,7:28,8:32,9:36,10:40},Ee={none:0,xs:2,sm:4,md:6,lg:8,xl:12,full:9999},W=["#1F8A65E8","#70B0D8E0","#5A6CC0F0","#F0A040E0","#C06028E0","#E8C030E0","#C85898E0","#F0A088E0","#7B64B8F0","#7DCAB0E0","#8888A8E0","#2A9A8AE0"],E={success:"#1F8A65",danger:"#CF2D56",warning:"#E8A33D",info:"#2E79B5",neutral:"#8888A8",added:"#1F8A65",deleted:"#CF2D56",renamed:"#5A6CC0"},q={success:"green",danger:"red",warning:"orange",info:"blue",neutral:"gray",added:"green",deleted:"red",renamed:"indigo"};function je(e){const t=e==="dark"?ae:se;return{...t,kind:e,tokens:t,palette:e==="dark"?O:G,category:e==="dark"?M:$,chart:{palette:me,sequence:W},radius:Ee,typography:ve,spacing:be}}function j(){const e=u.useComputedColorScheme("light");return je(e==="dark"?"dark":"light")}function ie(e,t){return e?E[e]:W[t%W.length]}function N(e,t){return e.map((r,s)=>{const i={category:r};for(const o of t)i[o.name]=o.data[s]??0;return i})}function ce(e){return e.map((t,r)=>({name:t.name,color:ie(t.tone,r)}))}function le(e,t){if(!(!e&&!t))return r=>`${t??""}${r}${e??""}`}function ke(e,t){if(e!=null&&e.length)return e.map(r=>({...t?{x:r.value}:{y:r.value},label:r.label,color:r.tone?E[r.tone]:E.neutral}))}function de(e){const t=ke(e.referenceLines,!!e.horizontal);if(e.stacked||e.normalized)return{referenceLines:t};const r=e.beginAtZero!==!1,s=[e.yMin??(r?0:"auto"),e.yMax??"auto"];return e.horizontal?{xAxisProps:{domain:s},referenceLines:t}:{yAxisProps:{domain:s},referenceLines:t}}function Se(e,t,r){return e!==void 0?e:t.length===1&&r.length<=8}function Ce({categories:e,series:t,height:r=240,fill:s,valueSuffix:i,valuePrefix:o,showValues:l,showHoverGuide:f=!0,beginAtZero:d,yMin:c,yMax:h,referenceLines:x,style:v}){const b=N(e,t),F=ce(t),k=de({beginAtZero:d,yMin:c,yMax:h,referenceLines:x,horizontal:!1}),S={h:r,data:b,dataKey:"category",series:F,curveType:"monotone",withLegend:t.length>1,valueFormatter:le(i,o),withPointLabels:l??e.length<=20,tooltipProps:f?void 0:{cursor:!1},...k,style:v};return s?n.jsx(B.AreaChart,{...S}):n.jsx(B.LineChart,{...S})}function Ae({categories:e,series:t,height:r=240,stacked:s,horizontal:i,normalized:o,valueSuffix:l,valuePrefix:f,showValues:d,beginAtZero:c,yMin:h,yMax:x,referenceLines:v,style:b}){const F=N(e,t),k=o?"percent":s?"stacked":"default",S=de({beginAtZero:c,yMin:h,yMax:x,referenceLines:v,horizontal:i,stacked:s,normalized:o}),T=!s&&!o&&Se(d,t,e);return n.jsx(B.BarChart,{h:r,data:F,dataKey:"category",series:ce(t),type:k,orientation:i?"vertical":"horizontal",withLegend:t.length>1,valueFormatter:le(l,f),withBarValueLabel:T,...S,style:b})}function Fe({data:e,size:t=200,donut:r,style:s}){const o={data:e.map((l,f)=>({name:l.label,value:l.value,color:ie(l.tone,f)})),size:t,withTooltip:!0,style:s};return r?n.jsx(B.DonutChart,{...o}):n.jsx(B.PieChart,{...o,withLabelsLine:!1})}function Te(e){const{nodes:t,edges:r,direction:s="vertical",nodeWidth:i=160,nodeHeight:o=40,rankGap:l=64,nodeGap:f=48,padding:d=24}=e,c=t.map(a=>a.id),h=new Set(c),x=new Map;for(const a of c)x.set(a,[]);for(const a of r)h.has(a.from)&&h.has(a.to)&&x.get(a.from).push(a.to);const v=0,b=1,F=2,k=new Map(c.map(a=>[a,v])),S=new Set,T=(a,g)=>`${a}\0${g}`,Q=a=>{k.set(a,b);for(const g of x.get(a)??[]){const p=k.get(g);p===b?S.add(T(a,g)):p===v&&Q(g)}k.set(a,F)};for(const a of c)k.get(a)===v&&Q(a);const he=r.filter(a=>h.has(a.from)&&h.has(a.to)&&!S.has(T(a.from,a.to))),C=new Map(c.map(a=>[a,0])),K=new Map(c.map(a=>[a,[]]));for(const a of he)K.get(a.from).push(a.to),C.set(a.to,(C.get(a.to)??0)+1);const w=new Map(c.map(a=>[a,0])),z=c.filter(a=>(C.get(a)??0)===0);for(;z.length>0;){const a=z.shift(),g=w.get(a);for(const p of K.get(a))w.set(p,Math.max(w.get(p),g+1)),C.set(p,C.get(p)-1),C.get(p)===0&&z.push(p)}const A=new Map;for(const a of c){const g=w.get(a);A.has(g)||A.set(g,[]),A.get(g).push(a)}const L=[...A.keys()].sort((a,g)=>a-g),m=s==="vertical",X=a=>a*(m?i:o)+Math.max(0,a-1)*f,V=Math.max(0,...L.map(a=>X(A.get(a).length))),D=new Map,Y=[];L.forEach((a,g)=>{const p=A.get(a),H=X(p.length),R=d+(V-H)/2,P=d+g*((m?o:i)+l);p.forEach((ee,te)=>{const re=R+te*((m?i:o)+f),pe=m?re:P,xe=m?P:re;D.set(ee,{id:ee,x:pe,y:xe,rank:a,order:te})}),Y.push({rank:a,x:m?R:P,y:m?P:R,width:m?H:i,height:m?o:H,nodeIds:p})});const U=(a,g)=>a?m?{x:a.x+i/2,y:g==="source"?a.y+o:a.y}:{x:g==="source"?a.x+i:a.x,y:a.y+o/2}:{x:0,y:0},ge=r.filter(a=>h.has(a.from)&&h.has(a.to)).map(a=>{const g=U(D.get(a.from),"source"),p=U(D.get(a.to),"target");return{from:a.from,to:a.to,sourceX:g.x,sourceY:g.y,targetX:p.x,targetY:p.y,isBackEdge:S.has(T(a.from,a.to))}}),J=d*2+L.length*(m?o:i)+Math.max(0,L.length-1)*l,Z=d*2+V;return{nodes:[...D.values()],edges:ge,ranks:Y,direction:s,width:m?Z:J,height:m?J:Z}}function Be({additions:e=0,deletions:t=0,style:r}){return e===0&&t===0?null:n.jsxs("span",{style:{display:"inline-flex",gap:8,fontVariantNumeric:"tabular-nums",fontSize:12,fontWeight:600,...r},children:[e>0&&n.jsxs("span",{style:{color:E.added},children:["+",e]}),t>0&&n.jsxs("span",{style:{color:E.deleted},children:["-",t]})]})}const we={added:"+",removed:"-",unchanged:" "};function Le({lines:e,showLineNumbers:t=!0,coloredLineNumbers:r=!0,showAccentStrip:s=!0,style:i}){const o=j(),l=c=>c==="added"?o.diff.insertedLine:c==="removed"?o.diff.removedLine:"transparent",f=c=>c==="added"?o.diff.stripAdded:c==="removed"?o.diff.stripRemoved:"transparent",d=c=>r&&c==="added"?E.added:r&&c==="removed"?E.deleted:o.text.tertiary;return n.jsx("div",{style:{fontFamily:'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Code", monospace',fontSize:12.5,lineHeight:"18px",color:o.text.primary,overflowX:"auto",...i},children:e.map((c,h)=>n.jsxs("div",{style:{display:"flex",alignItems:"stretch",background:l(c.type),borderLeft:s?`3px solid ${f(c.type)}`:void 0},children:[t&&n.jsx("span",{style:{flex:"0 0 auto",width:40,textAlign:"right",paddingRight:10,userSelect:"none",color:d(c.type)},children:c.lineNumber??""}),n.jsx("span",{style:{flex:"0 0 auto",width:14,textAlign:"center",userSelect:"none",color:d(c.type)},children:we[c.type]}),n.jsx("pre",{style:{margin:0,padding:"0 8px",whiteSpace:"pre",fontFamily:"inherit"},children:c.content})]},h))})}function De({status:e}){const t=j(),r=e==="completed"?E.success:e==="in_progress"?t.accent.primary:e==="cancelled"?E.danger:t.text.tertiary;return n.jsxs("svg",{width:14,height:14,viewBox:"0 0 14 14",fill:"none",style:{flex:"0 0 auto",marginTop:3},"aria-hidden":!0,children:[n.jsx("circle",{cx:7,cy:7,r:6,stroke:r,strokeWidth:1.4}),e==="completed"&&n.jsx("path",{d:"M4 7.2l2 2 4-4.4",stroke:r,strokeWidth:1.4,strokeLinecap:"round",strokeLinejoin:"round"}),e==="in_progress"&&n.jsx("circle",{cx:7,cy:7,r:3,fill:r}),e==="cancelled"&&n.jsx("path",{d:"M4.8 4.8l4.4 4.4M9.2 4.8l-4.4 4.4",stroke:r,strokeWidth:1.4,strokeLinecap:"round"})]})}function ue({todos:e,dimmedTodoIds:t,onTodoClick:r,style:s}){const i=j();return e.length===0?null:n.jsx("div",{style:{display:"flex",flexDirection:"column",...s},children:e.map(o=>{const l=t==null?void 0:t.has(o.id);return n.jsxs("button",{type:"button",onClick:()=>r==null?void 0:r(o),style:{display:"flex",gap:8,alignItems:"flex-start",width:"100%",textAlign:"left",padding:"4px 6px",background:"transparent",border:"none",cursor:r?"pointer":"default",color:i.text.primary,fontSize:14,lineHeight:"20px",opacity:l?.45:1},children:[n.jsx(De,{status:o.status}),n.jsx("span",{style:{textDecoration:o.status==="cancelled"?"line-through":void 0,color:o.status==="cancelled"?i.text.tertiary:void 0},children:o.content})]},o.id)})})}function Pe({todos:e,dimmedTodoIds:t,defaultExpanded:r=!1,onTodoClick:s,style:i}){const o=j(),[l,f]=y.useState(r);if(e.length===0)return null;const d=e.filter(c=>c.status==="completed").length;return n.jsxs("div",{style:{border:`1px solid ${o.stroke.primary}`,borderRadius:6,overflow:"hidden",...i},children:[n.jsxs("button",{type:"button",onClick:()=>f(c=>!c),style:{display:"flex",alignItems:"center",gap:8,width:"100%",padding:"6px 10px",background:"transparent",border:"none",cursor:"pointer",color:o.text.secondary,fontSize:12,fontWeight:600},children:[n.jsx("svg",{width:12,height:12,viewBox:"0 0 12 12",fill:"none",style:{transform:l?"rotate(90deg)":"none",transition:"transform 120ms"},"aria-hidden":!0,children:n.jsx("path",{d:"M4 2.5L8 6l-4 3.5",stroke:"currentColor",strokeWidth:1.4,strokeLinecap:"round",strokeLinejoin:"round"})}),n.jsx("span",{children:"Todos"}),n.jsx("span",{style:{flex:1}}),n.jsxs("span",{children:[d," of ",e.length," Done"]})]}),l&&n.jsx("div",{style:{padding:6},children:n.jsx(ue,{todos:e,dimmedTodoIds:t,onTodoClick:s})})]})}function Me(e,t){const r=`canvas:${e}`,[s,i]=y.useState(()=>{if(typeof localStorage>"u")return t;try{const l=localStorage.getItem(r);return l===null?t:JSON.parse(l)}catch{return t}}),o=y.useCallback(l=>{i(f=>{const d=typeof l=="function"?l(f):l;try{localStorage==null||localStorage.setItem(r,JSON.stringify(d))}catch{}return d})},[r]);return[s,o]}function ze(){return y.useCallback(e=>{},[])}function He(e,t){return{...e,...t}}function Re({children:e,style:t}){return n.jsx(u.Title,{order:1,fz:24,lh:"30px",style:t,children:e})}function Ie({children:e,style:t}){return n.jsx(u.Title,{order:2,fz:18,lh:"24px",style:t,children:e})}function We({children:e,style:t}){return n.jsx(u.Title,{order:3,fz:16,lh:"22px",style:t,children:e})}const Oe={normal:400,medium:500,semibold:600,bold:700};function Ge({children:e,tone:t="primary",size:r="body",as:s="p",weight:i="normal",italic:o,truncate:l,style:f}){const d=j();return n.jsx(u.Text,{component:s,size:r==="small"?"xs":"sm",fw:Oe[i],c:t==="primary"?void 0:d.text[t],truncate:l,style:{fontStyle:o?"italic":void 0,...f},children:e})}function $e({children:e,style:t}){return n.jsx("code",{style:{fontFamily:'ui-monospace, SFMono-Regular, Menlo, Monaco, "Cascadia Code", monospace',fontSize:"0.92em",background:"var(--mantine-color-default-hover)",borderRadius:4,padding:"1px 4px",...t},children:e})}function qe({children:e,href:t,style:r}){return n.jsx("a",{href:t,target:"_blank",rel:"noreferrer",style:{color:"var(--mantine-color-anchor)",...r},children:e})}function Ne({children:e,gap:t,style:r}){return n.jsx(u.Stack,{gap:t,style:r,children:e})}const ne={start:"flex-start",center:"center",end:"flex-end",stretch:"stretch","space-between":"space-between"};function _e({children:e,gap:t,align:r="center",justify:s="start",wrap:i=!1,style:o}){return n.jsx(u.Group,{gap:t,align:ne[r],justify:ne[s],wrap:i?"wrap":"nowrap",style:o,children:e})}function Qe(){return n.jsx("div",{style:{flex:1}})}function Ke({children:e,columns:t,gap:r=16,align:s,style:i}){const o=typeof t=="number"?`repeat(${t}, minmax(0, 1fr))`:t;return n.jsx("div",{style:{display:"grid",gridTemplateColumns:o,gap:r,alignItems:s,...i},children:e})}function Xe({style:e}){return n.jsx(u.Divider,{style:e})}const _=y.createContext({collapsible:!1,open:!0,toggle:()=>{}});function Ve({children:e,variant:t="default",collapsible:r=!1,defaultOpen:s=!0,open:i,onOpenChange:o,style:l}){const[f,d]=y.useState(s),c=i??f,h=y.useCallback(()=>{const x=!c;i===void 0&&d(x),o==null||o(x)},[c,i,o]);return n.jsx(u.Card,{withBorder:t!=="borderless",radius:"md",padding:0,style:l,children:n.jsx(_.Provider,{value:{collapsible:r,open:c,toggle:h},children:e})})}function Ye({children:e,trailing:t,style:r}){const{collapsible:s,open:i,toggle:o}=y.useContext(_);return n.jsxs("div",{onClick:s?o:void 0,style:{display:"flex",alignItems:"center",justifyContent:"space-between",gap:8,padding:"8px 14px",borderBottom:"1px solid var(--mantine-color-default-border)",fontSize:12,fontWeight:600,color:"var(--mantine-color-dimmed)",cursor:s?"pointer":void 0,userSelect:s?"none":void 0,...r},children:[n.jsxs("span",{style:{display:"inline-flex",alignItems:"center",gap:6},children:[s&&n.jsx(fe,{expanded:i}),e]}),t!=null&&n.jsx("span",{children:t})]})}function Ue({children:e,style:t}){const{collapsible:r,open:s}=y.useContext(_);return r&&!s?null:n.jsx("div",{style:{padding:14,...t},children:e})}function fe({expanded:e}){return n.jsx("svg",{width:12,height:12,viewBox:"0 0 12 12",fill:"none",style:{transform:e?"rotate(90deg)":"none",transition:"transform 120ms"},"aria-hidden":!0,children:n.jsx("path",{d:"M4 2.5L8 6l-4 3.5",stroke:"currentColor",strokeWidth:1.4,strokeLinecap:"round",strokeLinejoin:"round"})})}function Je({value:e,label:t,tone:r,style:s}){return n.jsxs("div",{style:s,children:[n.jsx(u.Text,{fz:22,fw:700,lh:1.2,c:r?`${q[r]}.6`:void 0,children:e}),n.jsx(u.Text,{fz:12,c:"dimmed",children:t})]})}function Ze({children:e,active:t,tone:r="neutral",size:s="md",leadingContent:i,keyboardHint:o,title:l,style:f,onClick:d}){return n.jsx(u.Badge,{color:q[r],variant:t?"filled":"light",size:s==="sm"?"sm":"md",leftSection:i,rightSection:o,title:l,onClick:d,style:{cursor:d?"pointer":void 0,textTransform:"none",...f},children:e})}function et({children:e,tone:t="neutral",title:r,icon:s,style:i}){return n.jsx(u.Alert,{color:q[t],title:r,icon:s,variant:"light",style:i,children:e})}const tt={success:"rgba(31,138,101,0.12)",danger:"rgba(207,45,86,0.12)",warning:"rgba(232,163,61,0.14)",info:"rgba(46,121,181,0.12)",neutral:"rgba(136,136,168,0.12)"};function rt({headers:e,rows:t,columnAlign:r,rowTone:s,framed:i=!0,striped:o,stickyHeader:l,style:f,emptyMessage:d}){return n.jsxs(u.Table,{withTableBorder:i,withColumnBorders:!1,striped:o,stickyHeader:l,highlightOnHover:!0,style:f,children:[n.jsx(u.Table.Thead,{children:n.jsx(u.Table.Tr,{children:e.map((c,h)=>n.jsx(u.Table.Th,{ta:(r==null?void 0:r[h])??"left",children:c},h))})}),n.jsx(u.Table.Tbody,{children:t.length===0?n.jsx(u.Table.Tr,{children:n.jsx(u.Table.Td,{colSpan:e.length,ta:"center",c:"dimmed",children:d??"No data"})}):t.map((c,h)=>{const x=s==null?void 0:s[h];return n.jsx(u.Table.Tr,{style:x?{background:tt[x]}:void 0,children:e.map((v,b)=>n.jsx(u.Table.Td,{ta:(r==null?void 0:r[b])??"left",children:c[b]},b))},h)})})]})}const nt={primary:"filled",secondary:"default",ghost:"subtle"};function ot({children:e,variant:t="secondary",disabled:r,type:s="button",style:i,onClick:o}){return n.jsx(u.Button,{variant:nt[t],size:"xs",disabled:r,type:s,onClick:o,style:i,children:e})}function at({children:e,onClick:t,disabled:r,title:s,variant:i="default",size:o="md",style:l}){return n.jsx(u.ActionIcon,{variant:i==="circle"?"light":"subtle",radius:i==="circle"?"xl":"sm",size:o==="sm"?"sm":"md",color:"gray",disabled:r,title:s,"aria-label":s,onClick:t,style:l,children:e})}function st({value:e,onChange:t,options:r,placeholder:s,disabled:i,style:o}){return n.jsx(u.Select,{value:e,data:r,placeholder:s,disabled:i,allowDeselect:!1,onChange:l=>{l!==null&&(t==null||t(l))},style:o})}function it({checked:e,onChange:t,disabled:r,label:s,style:i}){return n.jsx(u.Checkbox,{checked:e,disabled:r,label:s,onChange:o=>t==null?void 0:t(o.currentTarget.checked),style:i})}function ct({checked:e,onChange:t,disabled:r,size:s="sm",style:i}){return n.jsx(u.Switch,{checked:e,disabled:r,size:s==="sm"?"sm":"md",onChange:o=>t==null?void 0:t(o.currentTarget.checked),style:i})}function lt({value:e,onChange:t,placeholder:r,disabled:s,type:i,style:o}){return n.jsx(u.TextInput,{value:e,placeholder:r,disabled:s,type:i,onChange:l=>t==null?void 0:t(l.currentTarget.value),style:o})}function dt({value:e,onChange:t,placeholder:r,disabled:s,rows:i=3,style:o}){return n.jsx(u.Textarea,{value:e,placeholder:r,disabled:s,autosize:!0,minRows:i,onChange:l=>t==null?void 0:t(l.currentTarget.value),style:o})}function ut({color:e,style:t}){const r=j();return n.jsx("span",{style:{display:"inline-block",width:14,height:14,borderRadius:4,background:r.category[e],flex:"0 0 auto",...t}})}function ft({segments:e,total:t,topLeftLabel:r,topRightLabel:s,style:i}){const o=j(),l=t>0?t:1,f=e.reduce((c,h)=>c+(Number.isFinite(h.value)&&h.value>0?h.value:0),0),d=Math.max(0,l-f);return n.jsxs("div",{style:i,children:[(r!=null||s!=null)&&n.jsxs("div",{style:{display:"flex",justifyContent:"space-between",fontSize:12,color:o.text.secondary,marginBottom:6},children:[n.jsx("span",{children:r}),n.jsx("span",{children:s})]}),n.jsxs("div",{style:{display:"flex",gap:2,height:8},children:[e.map((c,h)=>{const x=Number.isFinite(c.value)&&c.value>0?c.value:0,v=o.category[c.color??I[h%I.length]];return n.jsx("div",{style:{width:`${x/l*100}%`,background:v,borderRadius:3}},c.id)}),d>0&&n.jsx("div",{style:{width:`${d/l*100}%`,background:o.fill.tertiary,borderRadius:3}})]})]})}function ht({title:e,leading:t,count:r,trailing:s,children:i,defaultOpen:o=!1,style:l}){const f=j(),[d,c]=y.useState(o);return n.jsxs("div",{style:l,children:[n.jsxs("div",{onClick:()=>c(h=>!h),style:{display:"flex",alignItems:"center",gap:6,padding:"4px 0",cursor:"pointer",userSelect:"none",color:f.text.primary,fontSize:14},children:[n.jsx(fe,{expanded:d}),t,n.jsx("span",{style:{fontWeight:500},children:e}),r!=null&&n.jsx("span",{style:{color:f.text.tertiary,fontSize:12},children:r}),n.jsx("span",{style:{flex:1}}),s!=null&&n.jsx("span",{style:{color:f.text.tertiary},children:s})]}),d&&n.jsx("div",{style:{paddingLeft:18,paddingBottom:4},children:i})]})}Object.defineProperty(exports,"useEffect",{enumerable:!0,get:()=>y.useEffect});Object.defineProperty(exports,"useMemo",{enumerable:!0,get:()=>y.useMemo});Object.defineProperty(exports,"useRef",{enumerable:!0,get:()=>y.useRef});Object.defineProperty(exports,"useState",{enumerable:!0,get:()=>y.useState});exports.BarChart=Ae;exports.Button=ot;exports.Callout=et;exports.Card=Ve;exports.CardBody=Ue;exports.CardHeader=Ye;exports.Checkbox=it;exports.Code=$e;exports.CollapsibleSection=ht;exports.DiffStats=Be;exports.DiffView=Le;exports.Divider=Xe;exports.Grid=Ke;exports.H1=Re;exports.H2=Ie;exports.H3=We;exports.IconButton=at;exports.LineChart=Ce;exports.Link=qe;exports.PieChart=Fe;exports.Pill=Ze;exports.Row=_e;exports.Select=st;exports.Spacer=Qe;exports.Stack=Ne;exports.Stat=Je;exports.Swatch=ut;exports.Table=rt;exports.Text=Ge;exports.TextArea=dt;exports.TextInput=lt;exports.TodoList=ue;exports.TodoListCard=Pe;exports.Toggle=ct;exports.UsageBar=ft;exports.canvasPaletteDark=O;exports.canvasPaletteLight=G;exports.canvasTokens=ae;exports.canvasTokensLight=se;exports.categoryPaletteDark=M;exports.categoryPaletteLight=$;exports.colorPalette=ye;exports.computeDAGLayout=Te;exports.mergeStyle=He;exports.reshapeLineChartData=N;exports.usageColorSequence=I;exports.useCanvasAction=ze;exports.useCanvasState=Me;exports.useHostTheme=j;
|