@mocanvas/editor 4.0.2 → 4.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/ARCHITECTURE.md +8 -2
- package/MIGRATION.md +48 -22
- package/README.md +5 -0
- package/UI.md +24 -2
- package/dist/index.d.ts +322 -41
- package/dist/index.js +449 -153
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/ARCHITECTURE.md
CHANGED
|
@@ -18,9 +18,15 @@ document model, tools, and UI live in TypeScript.
|
|
|
18
18
|
|
|
19
19
|
## Non-goals (v1)
|
|
20
20
|
|
|
21
|
-
- Wire compatibility with tldraw's sync protocol.
|
|
22
|
-
|
|
21
|
+
- Wire compatibility with tldraw's sync protocol. `@mocanvas/sync` is a
|
|
22
|
+
transport of its own; it does not speak tldraw's wire format.
|
|
23
23
|
- Pixel-identical rendering of every built-in shape.
|
|
24
|
+
- Shipping message catalogues. The translation seam exists
|
|
25
|
+
(`TLUiOverrides.translations`); the strings are the host's.
|
|
26
|
+
|
|
27
|
+
Slot-compatible UI components were a non-goal here and are no longer: the
|
|
28
|
+
`TLComponents` and `TLUiOverrides` surfaces are implemented. See
|
|
29
|
+
[MIGRATION.md §7](MIGRATION.md).
|
|
24
30
|
|
|
25
31
|
## Clean-room rule
|
|
26
32
|
|
package/MIGRATION.md
CHANGED
|
@@ -10,7 +10,8 @@ The short version: your **documents, records, ids and `.tldr` files carry over
|
|
|
10
10
|
untouched**, most of your **`Editor` calls carry over untouched**, your
|
|
11
11
|
**`ShapeUtil` / `StateNode` / `BindingUtil` subclasses keep their shape**, and
|
|
12
12
|
the real work is (a) imports, (b) teaching custom shapes about the GPU
|
|
13
|
-
renderer, and (c)
|
|
13
|
+
renderer, and (c) UI, where the slots are compatible but the message
|
|
14
|
+
catalogues are yours to supply (§7).
|
|
14
15
|
|
|
15
16
|
---
|
|
16
17
|
|
|
@@ -237,6 +238,21 @@ the `export * from "@mocanvas/mocanvas"` at the top of the package.
|
|
|
237
238
|
Everything `@mocanvas/editor` exports is re-exported by `@mocanvas/mocanvas`, so in app
|
|
238
239
|
code you can import from `@mocanvas/mocanvas` alone.
|
|
239
240
|
|
|
241
|
+
### Step 1b — the stylesheet
|
|
242
|
+
|
|
243
|
+
| Old import | New import |
|
|
244
|
+
| ------------------------ | --------------------------------- |
|
|
245
|
+
| `"tldraw/tldraw.css"` | `"@mocanvas/mocanvas/mocanvas.css"` |
|
|
246
|
+
|
|
247
|
+
Same arrangement, same one line, wherever you had it. The default UI is
|
|
248
|
+
unstyled without it.
|
|
249
|
+
|
|
250
|
+
`@mocanvas/compat` does not re-export the stylesheet — a package can only
|
|
251
|
+
export files it contains — so this import names `@mocanvas/mocanvas` even
|
|
252
|
+
during the zero-rename step. Under pnpm's strict `node_modules` that means
|
|
253
|
+
adding `@mocanvas/mocanvas` to your own dependencies alongside
|
|
254
|
+
`@mocanvas/compat`.
|
|
255
|
+
|
|
240
256
|
### Step 2 — drop the prefixes
|
|
241
257
|
|
|
242
258
|
Once the app builds and runs against `@mocanvas/compat`, rename `TLFoo` →
|
|
@@ -499,26 +515,35 @@ returns both and `putContentOntoCurrentPage` accepts both.
|
|
|
499
515
|
|
|
500
516
|
## 7. UI
|
|
501
517
|
|
|
502
|
-
**
|
|
503
|
-
|
|
518
|
+
**Slot compatibility exists.** This section used to say it did not and that it
|
|
519
|
+
was a v1 non-goal; both stopped being true before 4.0. Your existing overrides
|
|
520
|
+
of tldraw's UI components are the shape mocanvas expects.
|
|
504
521
|
|
|
505
522
|
What you have:
|
|
506
523
|
|
|
507
|
-
- `
|
|
508
|
-
|
|
509
|
-
- `
|
|
510
|
-
|
|
524
|
+
- `components` — the `TLComponents` map, at both the canvas level and the
|
|
525
|
+
chrome level. Pass a component to replace a slot, `null` to remove it.
|
|
526
|
+
- `overrides` — `TLUiOverrides`, with `tools`, `actions` and `translations`.
|
|
527
|
+
The tool and action lists are what the toolbar, the menus and the keyboard
|
|
528
|
+
bindings are all built from, so rewriting an entry changes all three
|
|
529
|
+
together rather than only what is drawn.
|
|
530
|
+
- The default chrome as named exports — `TldrawUi`, `DefaultUi`,
|
|
531
|
+
`DefaultToolbar`, `DefaultMainMenu` and the rest — so you can render one
|
|
532
|
+
piece of it inside chrome of your own.
|
|
533
|
+
- `useTools()` and `useActions()` return those lists after overrides, which is
|
|
534
|
+
what a toolbar of your own should render from.
|
|
535
|
+
- `hideUi` on `<Mocanvas />` still turns the chrome off entirely, leaving you
|
|
536
|
+
the canvas and your `children`.
|
|
511
537
|
- `useEditor()` inside any descendant of `<Canvas>` / `<EditorProvider>`
|
|
512
538
|
returns the `Editor` (`useMaybeEditor()` returns `Editor | null`).
|
|
513
539
|
- `track(Component)` and `useValue` from `@mocanvas/state/react` — re-exported
|
|
514
|
-
from `@mocanvas/editor` and `@mocanvas/mocanvas` — make a component re-render
|
|
515
|
-
signals it reads change.
|
|
540
|
+
from `@mocanvas/editor` and `@mocanvas/mocanvas` — make a component re-render
|
|
541
|
+
when the signals it reads change.
|
|
516
542
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
components.
|
|
543
|
+
One real difference remains: mocanvas ships **no message catalogues**, so
|
|
544
|
+
`overrides.translations` is where UI strings come from. The language menu lists
|
|
545
|
+
only the locales you supply a non-empty dictionary for, and renders nothing at
|
|
546
|
+
all if you supply none — see the note in `UI.md`.
|
|
522
547
|
|
|
523
548
|
---
|
|
524
549
|
|
|
@@ -626,19 +651,20 @@ before.
|
|
|
626
651
|
|
|
627
652
|
## 10. Known gaps
|
|
628
653
|
|
|
629
|
-
|
|
630
|
-
the
|
|
654
|
+
Every row below was re-checked against the built package rather than carried
|
|
655
|
+
forward from the roadmap. Rows that used to sit here and no longer belong —
|
|
656
|
+
`editor.resizeShape` and `stretchShapes`, `editor.getSvgString` and `toImage`,
|
|
657
|
+
`editor.textMeasure`/`user`/`menus`, presence records, and slot-compatible UI —
|
|
658
|
+
are all present, and the entries claiming otherwise were stale rather than
|
|
659
|
+
aspirational.
|
|
631
660
|
|
|
632
661
|
| Gap | Status |
|
|
633
662
|
| --- | ------ |
|
|
634
|
-
| `editor.resizeShape`, `editor.stretchShapes` | phase 3. Interactive resize lives in the select tool; `ShapeUtil.onResize` and `BaseBoxShapeUtil` work, but there is no imperative resize entry point on `Editor`. |
|
|
635
|
-
| `editor.getSvgString`, `editor.toImage` | Not `Editor` methods. Export is a set of free functions in `@mocanvas/mocanvas`: `getSvgString(editor, ids?, opts?)`, `exportToBlob(editor, opts)`, `downloadBlob(blob, filename)`, `copyBlobToClipboard(blob)`. |
|
|
636
663
|
| `ShapeUtil.toSvg`, `ShapeUtil.toBackgroundSvg` | Not `ShapeUtil` members. Custom shapes contribute to SVG export through `registerShapeSvgRenderer(type, renderer)`; without one they fall back to `geometryFallbackSvg`. |
|
|
637
|
-
|
|
|
638
|
-
| Sync protocol | Explicit v1 non-goal. Wire compatibility with tldraw's sync protocol is not planned for v1. |
|
|
639
|
-
| Slot-compatible UI | Explicit v1 non-goal. See §7. |
|
|
664
|
+
| Sync protocol | Wire compatibility with tldraw's own sync protocol is not planned. `@mocanvas/sync` is a working transport of its own — presence records, `store.mergeRemoteChanges`, and a relay — but it does not speak tldraw's wire format. |
|
|
640
665
|
| `image` shape on the GPU | The texture path exists in the engine (`StyleWords.texture` + `uploadTexture`) but the `image` shape still draws an `<img>` in the DOM overlay. |
|
|
641
|
-
| `
|
|
666
|
+
| `FrameShapeUtil` default size | mocanvas creates a frame at **160×90**; tldraw creates one at 320×180. Same aspect, half the size. It only bites code that creates a frame *programmatically* without passing `w`/`h` — drawing one with the tool sizes it from the drag either way. Pass explicit dimensions if the size matters to you. Aligning the default is a behaviour change and is not being made in a patch release. |
|
|
667
|
+
| An unregistered shape type in `store.put()` | Accepted, deliberately, and confirmed rather than fixed. A `.tldr` written by a build that knows a shape type this one does not must survive a load/save round trip instead of being dropped on the next save, so an unknown `type` passes its props through untouched. Its *other* fields are still validated — `x` must be a number whatever the type is — and a type you did register is validated in full. See `COMPAT.md`. |
|
|
642
668
|
| Text rendering | DOM overlay. Glyph-atlas text in WASM is phase 3. |
|
|
643
669
|
| GPU frame clipping | The `CLIP` flag and `isClipShape` hook are wired end to end, but no built-in shape enables it yet (phase 3). |
|
|
644
670
|
| WebGPU backend | Phase 3. WebGL2 is the only backend today, behind `RenderBackend`. |
|
package/README.md
CHANGED
|
@@ -16,6 +16,11 @@ npm install @mocanvas/editor react react-dom
|
|
|
16
16
|
|
|
17
17
|
`react` and `react-dom` (>= 18) are peer dependencies.
|
|
18
18
|
|
|
19
|
+
This package ships no stylesheet: `<Canvas />` carries its own fallbacks for
|
|
20
|
+
the theme custom properties, so it renders correctly on its own. The default
|
|
21
|
+
UI theme is `@mocanvas/mocanvas/mocanvas.css`, and you import it only if you
|
|
22
|
+
also render that package's UI.
|
|
23
|
+
|
|
19
24
|
## Use
|
|
20
25
|
|
|
21
26
|
```tsx
|
package/UI.md
CHANGED
|
@@ -4,6 +4,27 @@
|
|
|
4
4
|
style panel, an optional statistics chip, and the chrome the editor draws on the
|
|
5
5
|
canvas itself. All of it is optional and all of it is themeable from CSS.
|
|
6
6
|
|
|
7
|
+
## Loading the stylesheet
|
|
8
|
+
|
|
9
|
+
The theme is published as `@mocanvas/mocanvas/mocanvas.css` and your app
|
|
10
|
+
imports it:
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import "@mocanvas/mocanvas/mocanvas.css"
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The package's JavaScript entry does not import it. That is deliberate: Node has
|
|
17
|
+
no loader for `.css`, so a CSS import inside `dist/index.js` makes
|
|
18
|
+
`import "@mocanvas/mocanvas"` throw `ERR_UNKNOWN_FILE_EXTENSION` anywhere there
|
|
19
|
+
is no bundler — vitest, SSR, a plain script. Up to and including 4.0.2 it did,
|
|
20
|
+
and the emitted file was content-hashed (`dist/ui-4C5V5GYT.css`) so there was no
|
|
21
|
+
stable name to import instead. Both are fixed; the cost is this one line in your
|
|
22
|
+
app.
|
|
23
|
+
|
|
24
|
+
`<Canvas />` from `@mocanvas/editor` carries fallback values for the canvas
|
|
25
|
+
chrome tokens, so an editor mounted without the stylesheet still renders
|
|
26
|
+
legibly — but the toolbar, panels, menus and dialogs need it.
|
|
27
|
+
|
|
7
28
|
Source lives in `packages/mocanvas/src/ui/`:
|
|
8
29
|
|
|
9
30
|
| File | What it holds |
|
|
@@ -122,8 +143,9 @@ so inline marks like the "mixed" badge keep the size they ask for.
|
|
|
122
143
|
<Mocanvas hideUi />
|
|
123
144
|
```
|
|
124
145
|
|
|
125
|
-
This drops the toolbar, zoom bar, style panel and stats chip.
|
|
126
|
-
|
|
146
|
+
This drops the toolbar, zoom bar, style panel and stats chip. The stylesheet is
|
|
147
|
+
imported by your app, not by the component, so the canvas chrome tokens above
|
|
148
|
+
keep working. Default keyboard
|
|
127
149
|
shortcuts are wired by `<Mocanvas />` itself and are unaffected; call
|
|
128
150
|
`useKeyboardShortcuts(editor)` yourself if you build on `<Canvas />` directly.
|
|
129
151
|
|