efficient-easel 0.99.1 → 0.99.2
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 +55 -26
- package/dist/autosave/index.d.ts +5 -5
- package/dist/blocks/index.d.ts +2 -2
- package/dist/canvas/index.d.ts +3 -3
- package/dist/chrome/index.d.ts +13 -9
- package/dist/chrome/index.js +9 -9
- package/dist/chunk-672FAEKU.js +1 -0
- package/dist/chunk-7JTL3P6P.js +1 -0
- package/dist/chunk-F2PIG3AA.js +10 -0
- package/dist/chunk-XUE5O62R.js +3 -0
- package/dist/copy/index.d.ts +5 -5
- package/dist/data/index.d.ts +4 -4
- package/dist/drag/index.d.ts +4 -4
- package/dist/{editor/editor.css → easel/easel.css} +1 -1
- package/dist/easel/index.d.ts +385 -0
- package/dist/easel/index.js +1 -0
- package/dist/edit-lock/index.d.ts +5 -3
- package/dist/edit-lock/index.js +1 -1
- package/dist/editor/index.d.ts +9 -360
- package/dist/editor/index.js +1 -9
- package/dist/fields/index.d.ts +4 -4
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/menu/index.d.ts +8 -6
- package/dist/menu/index.js +4 -4
- package/dist/node-ops/index.d.ts +9 -9
- package/dist/panel/index.d.ts +1 -1
- package/dist/pick/index.d.ts +3 -3
- package/dist/rail/index.d.ts +10 -6
- package/dist/rail/index.js +1 -1
- package/dist/rail/rail.css +1 -1
- package/dist/strings/catalogue.d.ts +23 -17
- package/dist/strings/catalogue.js +1 -1
- package/dist/strings/index.d.ts +28 -20
- package/dist/strings/index.js +2 -2
- package/dist/style-clipboard/index.d.ts +5 -5
- package/dist/tree/index.d.ts +2 -2
- package/dist/{types-Dy6oR6Z2.d.ts → types-BOSGNvil.d.ts} +26 -14
- package/dist/{types-DNrn_w4V.d.ts → types-Bs_gVkVI.d.ts} +18 -10
- package/dist/{types-pGBXevBU.d.ts → types-DO-b0LNj.d.ts} +13 -7
- package/dist/{types-CnRzp9oc.d.ts → types-p9j2Fac7.d.ts} +11 -9
- package/dist/{watch-DmasQA61.d.ts → watch-B5RTR-WX.d.ts} +1 -1
- package/dist/{wordFit-9B9nqyf3.d.ts → wordFit-D4S36PvB.d.ts} +1 -1
- package/dist/{words-D9ChvbNC.d.ts → words-BDignMl_.d.ts} +1 -1
- package/dist/{words-bOMsUJk9.d.ts → words-C74EUpFr.d.ts} +2 -2
- package/dist/{words-B2YLaKEr.d.ts → words-CnnHb9jo.d.ts} +1 -1
- package/dist/{words-DOhF-4D4.d.ts → words-DMG4dYq2.d.ts} +1 -1
- package/dist/{words-BK-npta-.d.ts → words-N4ebT88_.d.ts} +1 -1
- package/dist/{words-Cqmyey0s.d.ts → words-c-3h9xQQ.d.ts} +2 -2
- package/dist/{words-B87GIFWH.d.ts → words-is_Vy6hn.d.ts} +1 -1
- package/package.json +9 -3
- package/dist/chunk-IBOFSS56.js +0 -3
- package/dist/chunk-JE63JHKO.js +0 -1
- package/dist/chunk-TDA4HH54.js +0 -1
- /package/dist/{chunk-OWBO4WKA.js → chunk-2PHD4L6A.js} +0 -0
- /package/dist/{chunk-GGTPNGFJ.js → chunk-AELNNAFM.js} +0 -0
package/dist/editor/index.d.ts
CHANGED
|
@@ -1,361 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export { I as ItemSelector } from '../plan-DChbUXdS.js';
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import { b as NodeOpsHost, C as ClipboardEntry } from '../useNodeOps-BF0fQsif.js';
|
|
11
|
-
import { I as InspectorFields } from '../types-C7HFvdtk.js';
|
|
1
|
+
export { CanvasFrame, CanvasFrameProps, CanvasOverlay, CanvasSlotProps, DEFAULT_UI, Easel, EaselCanvas, EaselCanvasProps, EaselOptions, EaselProvider, EaselProviderProps, EditDocument, Editor, EditorCanvas, EditorCanvasProps, EditorOptions, EditorProvider, SelectedFields, bindUndoKeys, createEasel, createEditor, createUseEasel, createUseEditor, recordsByDefault, reduce, uiView, useEasel, useEaselApi, useEaselNodeOps, useEditor, useEditorApi, useEditorNodeOps, useSelectedFields, validSelection } from '../easel/index.js';
|
|
2
|
+
export { A as AppState, b as EaselAction, E as EaselConfig, c as EaselCore, e as EaselHistory, d as EaselUi, a as EaselView, f as EditorAction, g as EditorConfig, h as EditorCore, i as EditorHistory, j as EditorUi, k as EditorView, H as HistoryEntry, P as Permissions, S as SetDataPatch } from '../types-BOSGNvil.js';
|
|
3
|
+
export { I as ItemSelector, N as NodeSelection } from '../plan-DChbUXdS.js';
|
|
4
|
+
import '../data/index.js';
|
|
5
|
+
import '../types-41704JE4.js';
|
|
6
|
+
import '../resolve-D68pb3Bx.js';
|
|
7
|
+
import 'react';
|
|
8
|
+
import '../useNodeOps-BF0fQsif.js';
|
|
9
|
+
import '../types-C7HFvdtk.js';
|
|
12
10
|
import '../buckets-CuLM47h9.js';
|
|
13
|
-
|
|
14
|
-
interface EditorOptions<C extends EditorConfig = EditorConfig> {
|
|
15
|
-
config: C;
|
|
16
|
-
/** The document — Puck 0.20's shape, unchanged. */
|
|
17
|
-
data: DataInput | Data;
|
|
18
|
-
/** The host's own UI keys to start with (and an `itemSelector`, if any). */
|
|
19
|
-
ui?: Record<string, unknown>;
|
|
20
|
-
/** Called with the new document after every change that changed it — once
|
|
21
|
-
* per `batch`, once per undo / redo. Not called for `load`. */
|
|
22
|
-
onChange?: (data: Data) => void;
|
|
23
|
-
/** Editor-wide permissions, under each block's own (Puck's `permissions`). */
|
|
24
|
-
permissions?: Partial<Permissions>;
|
|
25
|
-
/**
|
|
26
|
-
* Changes recorded closer together than this collapse into ONE undo step —
|
|
27
|
-
* Puck's 250 ms history debounce, so a word typed into a field is undone as
|
|
28
|
-
* a word and not as letters. A `batch` is never collapsed into its
|
|
29
|
-
* neighbours. 0 records every change on its own.
|
|
30
|
-
*/
|
|
31
|
-
historyCoalesceMs?: number;
|
|
32
|
-
/** The clock, for tests. */
|
|
33
|
-
now?: () => number;
|
|
34
|
-
}
|
|
35
|
-
interface Editor<C extends EditorConfig = EditorConfig> {
|
|
36
|
-
/** What `useEditor` reads. The same object until the state changes. */
|
|
37
|
-
getState: () => EditorView<C>;
|
|
38
|
-
subscribe: (listener: () => void) => () => void;
|
|
39
|
-
/** One Puck action. Outside a `batch`, one undo step when it records. */
|
|
40
|
-
dispatch: (action: EditorAction) => void;
|
|
41
|
-
/**
|
|
42
|
-
* Run several changes as ONE: one undo step, one `onChange`, and one
|
|
43
|
-
* notification to subscribers. Each dispatch inside sees the ones before it.
|
|
44
|
-
* Throwing inside puts everything back. Batches nest; only the outer one
|
|
45
|
-
* records.
|
|
46
|
-
*/
|
|
47
|
-
batch: (fn: () => void) => void;
|
|
48
|
-
/** Select a node by id, or nothing. Selection is not an undo step. */
|
|
49
|
-
select: (id: string | null) => void;
|
|
50
|
-
/** Select a slot — a column — or nothing. */
|
|
51
|
-
selectSlot: (address: SlotAddress | null) => void;
|
|
52
|
-
/** Apply a node-ops plan (`{ data, select }`) as one change. */
|
|
53
|
-
run: (plan: {
|
|
54
|
-
data: Data;
|
|
55
|
-
select?: NodeSelection | undefined;
|
|
56
|
-
}) => void;
|
|
57
|
-
/**
|
|
58
|
-
* Put a different document in WITHOUT remounting anything — Puck needed a
|
|
59
|
-
* new `key` on `<Puck>` for that, which threw away every subscriber's state.
|
|
60
|
-
* The history starts again at this document unless `keepHistory`.
|
|
61
|
-
*/
|
|
62
|
-
load: (data: DataInput | Data, options?: {
|
|
63
|
-
keepHistory?: boolean;
|
|
64
|
-
selection?: NodeSelection;
|
|
65
|
-
}) => void;
|
|
66
|
-
undo: () => void;
|
|
67
|
-
redo: () => void;
|
|
68
|
-
setPermissions: (permissions: Partial<Permissions>) => void;
|
|
69
|
-
/**
|
|
70
|
-
* Run every block's `resolveData` over the document, as `<Puck>` did when it
|
|
71
|
-
* mounted (trigger `'load'`), and write what changed as ONE change folded
|
|
72
|
-
* into the step it happens in — a resolver bringing a stale document up to
|
|
73
|
-
* date is not an undo step (Puck made it one, which undid back to the stale
|
|
74
|
-
* document). `onChange` hears it, as Puck's did. `EditorProvider` runs this
|
|
75
|
-
* on mount; a node changed by hand while it ran is left as the hand left it.
|
|
76
|
-
*/
|
|
77
|
-
resolveAll: (options?: {
|
|
78
|
-
trigger?: ResolveTrigger;
|
|
79
|
-
metadata?: Record<string, unknown>;
|
|
80
|
-
}) => Promise<void>;
|
|
81
|
-
/** This editor's memory of the last change each node was resolved for —
|
|
82
|
-
* Puck kept one per editor, shared by every write that resolves. */
|
|
83
|
-
readonly resolveCache: ResolveCache;
|
|
84
|
-
/**
|
|
85
|
-
* Swap the config in place — `<Puck>` took a new `config` prop live. The
|
|
86
|
-
* website editor rebuilds a few blocks' fields when the site's gap moves; the
|
|
87
|
-
* document, the selection and the history are untouched.
|
|
88
|
-
*/
|
|
89
|
-
setConfig: (config: C) => void;
|
|
90
|
-
/** The config in force now. */
|
|
91
|
-
readonly config: C;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Puck 0.20's UI at mount (`defaultAppState.ui`), less the selection, which
|
|
95
|
-
* the store holds by id. A host's chrome reads these — the website editor
|
|
96
|
-
* opens its side panels from `leftSideBarVisible` / `rightSideBarVisible` — so
|
|
97
|
-
* a host moving off `<Puck>` finds them where they were.
|
|
98
|
-
*/
|
|
99
|
-
declare const DEFAULT_UI: Record<string, unknown>;
|
|
100
|
-
/**
|
|
101
|
-
* THE EDITOR STORE (blueprint step 5.1): the document, the selection by id and
|
|
102
|
-
* the host's UI keys, with Puck's actions, Puck's history and a `batch` Puck
|
|
103
|
-
* never had. Framework-free — `useEditor` (./react) is the React binding.
|
|
104
|
-
*/
|
|
105
|
-
declare function createEditor<C extends EditorConfig>(options: EditorOptions<C>): Editor<C>;
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Puck 0.20's reducer, on `efficient-easel/data` — blueprint step 5.1.
|
|
109
|
-
*
|
|
110
|
-
* Each action means what it meant to Puck, so the apps' `dispatch` calls move
|
|
111
|
-
* over unchanged (`reorder`'s and `move`'s indexes, `replaceRoot` MERGING
|
|
112
|
-
* props, `duplicate` selecting the copy, `insert` leaving the selection where
|
|
113
|
-
* it was). Two things differ, on purpose:
|
|
114
|
-
*
|
|
115
|
-
* - THE SELECTION IS BY ID. Puck held `itemSelector` — a place — so a node
|
|
116
|
-
* inserted or removed above the selected one silently moved the selection
|
|
117
|
-
* onto its neighbour, and both editors carried patches for exactly that.
|
|
118
|
-
* Here `itemSelector` is derived from the id on every read, and a
|
|
119
|
-
* selection whose node is gone becomes nothing rather than whatever now
|
|
120
|
-
* sits in its place.
|
|
121
|
-
* - A SLOT CAN BE SELECTED (a column): `ui.selectedSlot`, which Puck had no
|
|
122
|
-
* way to say.
|
|
123
|
-
*/
|
|
124
|
-
/** Whether Puck records an action in history when the action does not say:
|
|
125
|
-
* everything but the state-setters. */
|
|
126
|
-
declare function recordsByDefault(action: EditorAction): boolean;
|
|
127
|
-
/** The UI as Puck shows it: the host's keys, with the selection translated. */
|
|
128
|
-
declare function uiView(core: EditorCore, config: EditorConfig): EditorUi;
|
|
129
|
-
/** A selection that still points at something; otherwise nothing. */
|
|
130
|
-
declare function validSelection(data: Data, config: EditorConfig, selection: NodeSelection): NodeSelection;
|
|
131
|
-
/** One action, applied. Pure: the same core and action give the same core. */
|
|
132
|
-
declare function reduce(core: EditorCore, action: EditorAction, config: EditorConfig): EditorCore;
|
|
133
|
-
|
|
134
|
-
/** Puts one editor in reach of everything under it — `<Puck>`'s provider
|
|
135
|
-
* half — and, as `<Puck>` did, binds undo / redo to the page's keyboard
|
|
136
|
-
* (`hotkeys={false}` for a host that binds its own) and runs every block's
|
|
137
|
-
* `resolveData` once on mount (`resolveOnMount={false}` to skip). */
|
|
138
|
-
declare function EditorProvider({ editor, hotkeys, resolveOnMount, children, }: {
|
|
139
|
-
editor: Editor;
|
|
140
|
-
hotkeys?: boolean;
|
|
141
|
-
/** Run every block's `resolveData` once the editor mounts, as `<Puck>` did
|
|
142
|
-
* (`editor.resolveAll`). On by default. */
|
|
143
|
-
resolveOnMount?: boolean;
|
|
144
|
-
children?: ReactNode;
|
|
145
|
-
}): react.JSX.Element;
|
|
146
|
-
/** The editor itself, for handlers that read the state at the moment they run
|
|
147
|
-
* (`useGetPuck`'s job) and for `dispatch` / `batch` / `select`. */
|
|
148
|
-
declare function useEditorApi<C extends EditorConfig = EditorConfig>(): Editor<C>;
|
|
149
|
-
/**
|
|
150
|
-
* Read a slice of the editor and re-render when it changes — `usePuck` /
|
|
151
|
-
* `createUsePuck()`'s selector form, over the same state shape, so the apps'
|
|
152
|
-
* selectors move over by renaming the hook.
|
|
153
|
-
*
|
|
154
|
-
* A selector may return a fresh object; the snapshot is cached per state and
|
|
155
|
-
* per selector, so React sees the same value for the same state and does not
|
|
156
|
-
* loop. A primitive or an unchanged reference does not re-render.
|
|
157
|
-
*/
|
|
158
|
-
declare function useEditor<T, C extends EditorConfig = EditorConfig>(selector: (view: EditorView<C>) => T): T;
|
|
159
|
-
/**
|
|
160
|
-
* A typed `useEditor` for one config — `createUsePuck<Config>()`'s shape, so
|
|
161
|
-
* a file that made its own typed hook keeps the one line that made it.
|
|
162
|
-
*/
|
|
163
|
-
declare function createUseEditor<C extends EditorConfig = EditorConfig>(): <T>(selector: (view: EditorView<C>) => T) => T;
|
|
164
|
-
|
|
165
|
-
/** What a slot component accepts — Puck's. */
|
|
166
|
-
interface CanvasSlotProps {
|
|
167
|
-
className?: string;
|
|
168
|
-
style?: CSSProperties;
|
|
169
|
-
allow?: string[];
|
|
170
|
-
disallow?: string[];
|
|
171
|
-
minEmptyHeight?: number;
|
|
172
|
-
collisionAxis?: unknown;
|
|
173
|
-
}
|
|
174
|
-
interface CanvasFrameProps {
|
|
175
|
-
children?: ReactNode;
|
|
176
|
-
/** `preview-frame` by default — the id the apps' canvas watchers look for. */
|
|
177
|
-
id?: string;
|
|
178
|
-
/**
|
|
179
|
-
* The frame's accessible name. Default "Canvas", in the strings provider's
|
|
180
|
-
* language (`EditorStrings.canvas.frame`).
|
|
181
|
-
*/
|
|
182
|
-
title?: string;
|
|
183
|
-
className?: string;
|
|
184
|
-
style?: CSSProperties;
|
|
185
|
-
/** Copy the host page's stylesheets into the frame, and keep them in step.
|
|
186
|
-
* On by default: the blocks are styled by the app's own CSS. */
|
|
187
|
-
mirrorStyles?: boolean;
|
|
188
|
-
/** Called with the frame's document once it is ready, and null when it goes. */
|
|
189
|
-
onDocument?: (doc: Document | null) => void;
|
|
190
|
-
/**
|
|
191
|
-
* `'auto'` (the default, Puck's): the frame is as tall as its content, and
|
|
192
|
-
* the host's pane scrolls it — so the canvas reads like the page it is.
|
|
193
|
-
* `'fill'`: the frame fills its parent and scrolls itself.
|
|
194
|
-
*/
|
|
195
|
-
height?: 'auto' | 'fill';
|
|
196
|
-
/**
|
|
197
|
-
* The page's CSP nonce, for a host whose policy allows styles by nonce
|
|
198
|
-
* (`style-src 'nonce-…'`). The frame is the host page's own document, so the
|
|
199
|
-
* same policy applies in it, and a stylesheet without the nonce is refused.
|
|
200
|
-
* Given, it is set on every stylesheet the canvas puts in the frame: each
|
|
201
|
-
* `<style>` and `<link rel="stylesheet">` copied in from the host
|
|
202
|
-
* (`mirrorStyles`), and each sheet `useCanvasStyle` / `upsertCanvasStyle`
|
|
203
|
-
* (`efficient-easel/canvas`) creates there. Left out, nothing changes.
|
|
204
|
-
*
|
|
205
|
-
* Read when the frame is built, like `mirrorStyles`: a nonce is the page's
|
|
206
|
-
* for as long as the page lives.
|
|
207
|
-
*/
|
|
208
|
-
nonce?: string;
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* An iframe of the editor's own, with the content portalled in. No `src`: the
|
|
212
|
-
* frame's first document is used — there to write into at once, with no load
|
|
213
|
-
* to wait for and nothing fetched. The host's stylesheets are copied into its
|
|
214
|
-
* head and copied again whenever the host's head changes (a route's CSS
|
|
215
|
-
* arriving late, a dev reload).
|
|
216
|
-
*
|
|
217
|
-
* ⚠️ THAT FIRST DOCUMENT HAS NO DOCTYPE, SO IT RENDERS IN QUIRKS MODE, and it
|
|
218
|
-
* is rewritten with one before anything is drawn. Puck's frame was a
|
|
219
|
-
* `<!DOCTYPE html>` srcdoc, so every block was written against standards mode;
|
|
220
|
-
* in quirks mode a `height: 100%` resolves through auto-height ancestors (an
|
|
221
|
-
* empty slot grew to the frame's full height), tables stop inheriting the
|
|
222
|
-
* page's font, and an image's line box changes. (0.89.0–0.92.0 shipped the
|
|
223
|
-
* quirks-mode frame.)
|
|
224
|
-
*/
|
|
225
|
-
declare function CanvasFrame({ children, id, title, className, style, mirrorStyles, onDocument, height, nonce, }: CanvasFrameProps): react.JSX.Element;
|
|
226
|
-
/**
|
|
227
|
-
* The whole document, for editing. Works in a `CanvasFrame` or on its own.
|
|
228
|
-
*
|
|
229
|
-
* `metadata` is the editor-wide metadata: the root's `puck.metadata`, and —
|
|
230
|
-
* under each block's own — every block's (see the header).
|
|
231
|
-
*/
|
|
232
|
-
declare function EditDocument({ metadata }: {
|
|
233
|
-
metadata?: Record<string, unknown>;
|
|
234
|
-
}): react.JSX.Element;
|
|
235
|
-
/** What a host may wrap an outline in — Puck's `componentOverlay`: render
|
|
236
|
-
* `children` to draw it, or nothing to hide it (a text part open on the
|
|
237
|
-
* block, say). */
|
|
238
|
-
type CanvasOverlay = ComponentType<{
|
|
239
|
-
componentId: string;
|
|
240
|
-
kind: 'selected' | 'hover';
|
|
241
|
-
children: ReactNode;
|
|
242
|
-
}>;
|
|
243
|
-
interface EditorCanvasProps {
|
|
244
|
-
/** Draw in an iframe of the editor's own (default), or straight into the page. */
|
|
245
|
-
frame?: boolean;
|
|
246
|
-
className?: string;
|
|
247
|
-
style?: CSSProperties;
|
|
248
|
-
/**
|
|
249
|
-
* The editor-wide metadata — what the published page passes `Render` as
|
|
250
|
-
* `metadata`. Every block reads it as `puck.metadata` (its own `metadata`
|
|
251
|
-
* laid over it) and the root as it is. Change it whenever the host's data
|
|
252
|
-
* changes: the blocks redraw in place, nothing remounts, and it never enters
|
|
253
|
-
* the document or the undo history.
|
|
254
|
-
*/
|
|
255
|
-
metadata?: Record<string, unknown>;
|
|
256
|
-
/** Copy the host's stylesheets into the frame (default true). */
|
|
257
|
-
mirrorStyles?: boolean;
|
|
258
|
-
/** The frame's height: as tall as its content (default, Puck's), or filling its parent. */
|
|
259
|
-
height?: 'auto' | 'fill';
|
|
260
|
-
/**
|
|
261
|
-
* The frame's accessible name — an iframe with none is announced as "frame".
|
|
262
|
-
* Default "Canvas", in the strings provider's language. Unused with
|
|
263
|
-
* `frame={false}`, where there is no frame to name.
|
|
264
|
-
*/
|
|
265
|
-
title?: string;
|
|
266
|
-
/** The page's CSP nonce for the frame's stylesheets — see `CanvasFrameProps.nonce`. Unused with `frame={false}`. */
|
|
267
|
-
nonce?: string;
|
|
268
|
-
onDocument?: (doc: Document | null) => void;
|
|
269
|
-
/**
|
|
270
|
-
* Wraps everything drawn in the frame, and is handed the frame's document —
|
|
271
|
-
* Puck's `overrides.iframe`: where a host syncs its theme onto the frame's
|
|
272
|
-
* `<html>` or adds frame-only CSS.
|
|
273
|
-
*/
|
|
274
|
-
frameWrapper?: ComponentType<{
|
|
275
|
-
document?: Document;
|
|
276
|
-
children: ReactNode;
|
|
277
|
-
}>;
|
|
278
|
-
/** Wraps each outline — Puck's `componentOverlay`; see `CanvasOverlay`. */
|
|
279
|
-
overlay?: CanvasOverlay;
|
|
280
|
-
/** Drawn inside the frame, after the document — a host's canvas-only layer. */
|
|
281
|
-
children?: ReactNode;
|
|
282
|
-
}
|
|
283
|
-
/**
|
|
284
|
-
* `<Puck.Preview>`, ours: the document for editing, its outlines, and the
|
|
285
|
-
* clicks that select. Must sit under an `EditorProvider`.
|
|
286
|
-
*/
|
|
287
|
-
declare function EditorCanvas({ frame, className, style, metadata, mirrorStyles, onDocument, height, title, nonce, frameWrapper: FrameWrapper, overlay, children, }: EditorCanvasProps): ReactElement;
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* THE PARTS, ON THE STORE (blueprint step 5.2).
|
|
291
|
-
*
|
|
292
|
-
* Every part built in steps 2.1–4.9 takes a HOST — what to read, how to write
|
|
293
|
-
* — so it never knew Puck. Until now each app wrote that host twice, once per
|
|
294
|
-
* editor, against Puck's store: `EmailFields` and `SiteFields` for the settings
|
|
295
|
-
* panel, the node-ops host for the menus. These are the hosts, written ONCE,
|
|
296
|
-
* against the engine's store; the parts' own APIs do not change.
|
|
297
|
-
*/
|
|
298
|
-
/** `useNodeOps` with the store as its host: reads the document, and writes one
|
|
299
|
-
* `run` — one undo step, the selection travelling with it. */
|
|
300
|
-
declare function useEditorNodeOps(options?: Omit<NodeOpsHost, 'data' | 'config' | 'commit'>): {
|
|
301
|
-
held: ClipboardEntry | null;
|
|
302
|
-
remove: (id: string) => boolean;
|
|
303
|
-
duplicate: (id: string) => boolean;
|
|
304
|
-
move: (id: string, to: Place) => boolean;
|
|
305
|
-
step: (id: string, dir: -1 | 1) => boolean;
|
|
306
|
-
canStep: (id: string, dir: -1 | 1) => boolean;
|
|
307
|
-
setProps: (id: string, patch: Record<string, unknown>) => boolean;
|
|
308
|
-
copy: (id: string, label: string) => boolean;
|
|
309
|
-
cut: (id: string, label: string) => boolean;
|
|
310
|
-
paste: (at: Place) => boolean;
|
|
311
|
-
parentOf: (selection: NodeSelection) => NodeSelection;
|
|
312
|
-
};
|
|
313
|
-
interface SelectedFields {
|
|
314
|
-
/** The selected node's id, or `"root"` with nothing selected. */
|
|
315
|
-
id: string;
|
|
316
|
-
/** The node the fields are for — the selected one, or the root as `{ type: 'root', props }`. */
|
|
317
|
-
node: ResolvableItem;
|
|
318
|
-
/** Its fields, resolved as Puck resolved them (`resolveFields` with Puck's params, parent included). */
|
|
319
|
-
fields: InspectorFields;
|
|
320
|
-
/** What the fields show. */
|
|
321
|
-
values: Record<string, unknown>;
|
|
322
|
-
/** The block's (or the root's) `edit` permission is off. */
|
|
323
|
-
readOnly: boolean;
|
|
324
|
-
/** Write one field: `resolveData` as Puck ran it, then ONE replace — one undo step. */
|
|
325
|
-
onChange: (name: string, value: unknown) => void;
|
|
326
|
-
}
|
|
327
|
-
/**
|
|
328
|
-
* The settings panel's host: the selected node's fields and the write that
|
|
329
|
-
* changes one — what `EmailFields` and `SiteFields` each did against Puck,
|
|
330
|
-
* here once:
|
|
331
|
-
* - fields resolve through `useResolvedFields` (Puck's
|
|
332
|
-
* `useRegisterFieldsSlice`: `changed`, `lastFields`, `appState`, `parent`);
|
|
333
|
-
* - a change runs the block's `resolveData` (`resolveNodeData`, Puck's
|
|
334
|
-
* `resolveComponentData`, with this editor's own memory of the last
|
|
335
|
-
* change) and then writes ONE `replace` of the node, or ONE `replaceRoot`.
|
|
336
|
-
*
|
|
337
|
-
* The write reads the node AT THE MOMENT IT RUNS, by id: a field changed while
|
|
338
|
-
* a resolver is still running writes onto what is current, never onto what was
|
|
339
|
-
* selected when the change began.
|
|
340
|
-
*/
|
|
341
|
-
declare function useSelectedFields(): SelectedFields;
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
* UNDO AND REDO ON THE KEYBOARD — Puck's own six bindings, which both editors
|
|
345
|
-
* relied on without writing any: ⌘Z / Ctrl+Z undo; ⇧⌘Z, ⌘Y, Ctrl+Shift+Z and
|
|
346
|
-
* Ctrl+Y redo.
|
|
347
|
-
*
|
|
348
|
-
* Exact combinations, read off the physical key (`code`, as Puck read it), so
|
|
349
|
-
* a layout that moves Z still undoes and ⌥⌘Z does nothing.
|
|
350
|
-
*
|
|
351
|
-
* ⚠️ PUCK FIRED THESE IN A TEXT FIELD TOO, and so does this: ⌘Z while typing
|
|
352
|
-
* in a setting undoes the editor's last step — which, since a field writes as
|
|
353
|
-
* it is typed, is the typing — and the browser's own text undo is prevented,
|
|
354
|
-
* so there are never two undo histories answering one key.
|
|
355
|
-
*
|
|
356
|
-
* Bound per DOCUMENT: the host page (`EditorProvider`) and the canvas frame
|
|
357
|
-
* (`EditorCanvas`), because a key pressed in the frame never reaches the page.
|
|
358
|
-
*/
|
|
359
|
-
declare function bindUndoKeys(doc: Document, editor: Pick<Editor, 'undo' | 'redo'>): () => void;
|
|
360
|
-
|
|
361
|
-
export { CanvasFrame, type CanvasFrameProps, type CanvasOverlay, type CanvasSlotProps, DEFAULT_UI, EditDocument, type Editor, EditorAction, EditorCanvas, type EditorCanvasProps, EditorConfig, EditorCore, type EditorOptions, EditorProvider, EditorUi, EditorView, NodeSelection, Permissions, type SelectedFields, bindUndoKeys, createEditor, createUseEditor, recordsByDefault, reduce, uiView, useEditor, useEditorApi, useEditorNodeOps, useSelectedFields, validSelection };
|
package/dist/editor/index.js
CHANGED
|
@@ -1,9 +1 @@
|
|
|
1
|
-
import{DEFAULT_CANVAS_WORDS as e}from"../chunk-GGTPNGFJ.js";import{useResolvedFields as t}from"../chunk-YRLPFZW3.js";import{toItemSelector as n,fromItemSelector as o,useNodeOps as r}from"../chunk-D2BCHTQR.js";import{useWords as i}from"../chunk-MFIRYGHW.js";import{setCanvasNonce as a}from"../chunk-ZNCEOSXO.js";import{find as s,ROOT_ID as l,getList as d,remove as c,parseZoneKey as u,move as p,duplicate as h,replaceNode as f,createNode as m,insert as v,normalizeData as y,createResolveCache as g,resolveNodeData as k,ROOT_SLOT as b}from"../chunk-KRXQM65X.js";import{topLevelSlotKeys as w,fieldsFrom as S,defaultsFrom as I}from"../chunk-NKB3KVAB.js";import{createContext as C,useEffect as x,useContext as O,useRef as D,useSyncExternalStore as E,useState as A,useLayoutEffect as z,useMemo as M,useCallback as Z}from"react";import{jsx as $,jsxs as R}from"react/jsx-runtime";import{createPortal as N}from"react-dom";function B(e){return!["setData","setUi","set"].includes(e.type)}var P=(e,t,n,o)=>{const r=d(e,t,u(n));return r?.[o]??null},j=(e,t,n,o,r)=>{const i=P(e,t,n,o);if(!i)throw new Error(`${r}: nothing at ${n}[${o}]`);return i};function K(e,t){const{selection:o}=e;return{...e.ui,itemSelector:n(e.data,t,o),selectedSlot:o&&"slot"===o.kind?{parentId:o.parentId,slot:o.slot}:null}}function L(e,t,n){return n?"node"===n.kind?s(e,t,n.id)?n:null:n.parentId===l?d(e,t,n)?n:null:s(e,t,n.parentId)&&d(e,t,n)?n:null:null}function F(e,t,n,r=!1){const{itemSelector:i,selectedSlot:a,...s}=n;let l=e.selection;var d;return"itemSelector"in n&&(l=o(e.data,t,i??null)),"selectedSlot"in n&&(a?l=(d=a)?{kind:"slot",parentId:d.parentId,slot:d.slot}:null:"slot"===l?.kind&&(l=null)),{...e,selection:l,ui:r?s:{...e.ui,...s}}}function H(e,t,n){const o=V(e,t,n);if(o===e)return e;const r=L(o.data,n,o.selection);return r===o.selection?o:{...o,selection:r}}function V(e,t,n){const{data:o}=e;switch(t.type){case"setData":{const n="function"==typeof t.data?t.data(o):t.data;return{...e,data:{...o,...n}}}case"setUi":return F(e,n,"function"==typeof t.ui?t.ui(K(e,n)):t.ui);case"set":{const r={data:o,ui:K(e,n)},i="function"==typeof t.state?t.state(r):t.state;let a=i.data?{...e,data:i.data}:e;return i.ui&&(a=F(a,n,i.ui,!0)),a}case"insert":{const r={...u(t.destinationZone),index:t.destinationIndex},i=m(n,t.componentType,{},t.id?{id:t.id}:{});return{...e,data:v(o,n,r,i)}}case"replace":{const r=j(o,n,t.destinationZone,t.destinationIndex,"replace");if(r.props.id!==t.data.props.id)throw new Error("Can't change the id during a replace action. Use remove and insert for a new node.");return{...e,data:f(o,n,r.props.id,t.data)}}case"replaceRoot":{const n={...o.root,props:{...o.root.props,...t.root.props},readOnly:t.root.readOnly};return{...e,data:{...o,root:n}}}case"duplicate":{const r=j(o,n,t.sourceZone,t.sourceIndex,"duplicate"),i=h(o,n,r.props.id),a=P(i,n,t.sourceZone,t.sourceIndex+1);return{...e,data:i,selection:a?{kind:"node",id:a.props.id}:e.selection}}case"reorder":return V(e,{...t,type:"move",sourceZone:t.destinationZone},n);case"move":{if(t.sourceZone===t.destinationZone&&t.sourceIndex===t.destinationIndex)return e;const r=P(o,n,t.sourceZone,t.sourceIndex);if(!r)return e;const i={...u(t.destinationZone),index:t.destinationIndex};return{...e,data:p(o,n,r.props.id,i)}}case"remove":{const r=j(o,n,t.zone,t.index,"remove");return{...e,data:c(o,n,r.props.id)}}default:return e}}var T={drag:!0,duplicate:!0,delete:!0,edit:!0,insert:!0},q={leftSideBarVisible:!0,rightSideBarVisible:!0,arrayState:{},componentList:{},isDragging:!1,previewMode:"edit",viewports:{current:{width:360,height:"auto"},options:[],controlsVisible:!0},field:{focus:null}},G=0,Y=()=>`history-${G+=1}`;function U(e){let t=e.config;const r=e.now??(()=>Date.now()),i=e.historyCoalesceMs??250;let a=e.permissions??{};const l=y(e.data,t);let c={data:l,selection:null,ui:{...q}};if(e.ui){const{itemSelector:n,selectedSlot:r,...i}=e.ui;c={data:l,selection:r?{kind:"slot",...r}:o(l,t,n??null),ui:{...q,...i}}}let u=[{core:c,at:-1/0,sealed:!0,id:Y()}],p=0;const h=e=>{const t=u[p],n=r();!e&&p===u.length-1&&p>0&&!t.sealed&&n-t.at<i?u=[...u.slice(0,p),{...t,core:c,at:n}]:(u=[...u.slice(0,p+1),{core:c,at:n,sealed:e,id:Y()}],p=u.length-1)},m=/* @__PURE__ */new Set;let v=null,b=null,w=0,S=null,I=!1;const C=()=>{for(const e of[...m])e()},x=()=>{u=[...u.slice(0,p),{...u[p],core:c},...u.slice(p+1)]},O=(t,n)=>{w>0?I=I||n:(n?h(!1):c!==t&&x(),c.data!==t.data&&e.onChange?.(c.data),c!==t&&C())},D=e=>{const n=c;if(c=H(c,e,t),c===n)return;const o=e.recordHistory??B(e);O(n,o&&c.data!==n.data)},E=t=>{0===w&&(S=c,I=!1),w+=1;try{t()}catch(e){throw w-=1,0===w&&S&&(c=S,S=null),e}if(w-=1,w>0||!S)return;const n=S;S=null,I&&c.data!==n.data?h(!0):c!==n&&x(),c.data!==n.data&&e.onChange?.(c.data),c!==n&&C()},A=e=>{const n=c,o=L(c.data,t,e);var r,i;(r=o,i=c.selection,r===i||r&&i&&r.kind===i.kind&&("node"===r.kind&&"node"===i.kind?r.id===i.id:"slot"===r.kind&&"slot"===i.kind&&r.parentId===i.parentId&&r.slot===i.slot))||(c={...c,selection:o},O(n,!1))},z=t=>{const n=c;p=t,c=u[p].core,c.data!==n.data&&e.onChange?.(c.data),c!==n&&C()},M=(e={})=>{const n=e.root?t.root?.permissions:t.components[e.item?.type??e.type??""]?.permissions;return{...T,...a,...n}},Z=g(),$={resolveCache:Z,async resolveAll({trigger:e="load",metadata:n}={}){const o=c.data,r={type:"root",props:{...o.root.props??{}}},i=[...o.content,...Object.values(o.zones??{}).flat()],[a,...l]=await Promise.all([k(r,t,{cache:Z,trigger:e,metadata:n}),...i.map(o=>k(o,t,{cache:Z,trigger:e,metadata:n}))]);E(()=>{const e=c;let n=c.data;l.forEach((e,r)=>{if(!e.didChange)return;const a=i[r].props.id,l=s(n,t,a)?.node;l&&l===s(o,t,a)?.node&&(n=f(n,t,a,e.node))}),a.didChange&&n.root===o.root&&(n={...n,root:{...n.root,props:a.node.props,readOnly:a.node.readOnly??n.root.readOnly}}),n!==c.data&&(c={...c,data:n,selection:L(n,t,c.selection)},O(e,!1))})},get config(){return t},getState(){if(v&&b===c)return v;const e=c,o={data:e.data,ui:K(e,t)},r="node"===e.selection?.kind?s(e.data,t,e.selection.id)?.node??null:null;return v={appState:o,selection:e.selection,selectedItem:r,config:t,dispatch:D,history:{back:()=>$.undo(),forward:()=>$.redo(),hasPast:p>0,hasFuture:p<u.length-1,histories:u.map(e=>({id:e.id,state:{data:e.core.data,ui:K(e.core,t)}})),index:p,setHistoryIndex:e=>{e>=0&&e<u.length&&e!==p&&z(e)}},getPermissions:M,getItemById:n=>s(e.data,t,n)?.node,getItemBySelector:n=>function(e,t,n){const[o,r]=(n.zone??"root:default-zone").split(/:(.*)/s);return d(e,t,{parentId:o,slot:r})?.[n.index]}(e.data,t,n),getSelectorForId:o=>{const r=n(e.data,t,{kind:"node",id:o});return r?{index:r.index,zone:r.zone??"root:default-zone"}:void 0}},b=e,v},subscribe:e=>(m.add(e),()=>{m.delete(e)}),dispatch:D,batch:E,select:e=>A(e?{kind:"node",id:e}:null),selectSlot:e=>A(e?{kind:"slot",parentId:e.parentId,slot:e.slot}:null),run(e){E(()=>{const n=c,o=void 0===e.select?c.selection:e.select;c={...c,data:e.data,selection:L(e.data,t,o)},O(n,e.data!==n.data)})},load(e,n={}){const o=c,r=y(e,t);c={...c,data:r,selection:L(r,t,n.selection??c.selection)},n.keepHistory||(u=[{core:c,at:-1/0,sealed:!0,id:Y()}],p=0),c!==o&&C()},undo(){p>0&&z(p-1)},redo(){p<u.length-1&&z(p+1)},setPermissions(e){a=e,v=null,C()},setConfig(e){e!==t&&(t=e,v=null,C())}};return $}function W(e,t){const n=e=>{if(e.altKey)return;e.metaKey!==e.ctrlKey&&("KeyZ"===e.code?(e.preventDefault(),e.shiftKey?t.redo():t.undo()):"KeyY"!==e.code||e.shiftKey||(e.preventDefault(),t.redo()))};return e.addEventListener("keydown",n),()=>e.removeEventListener("keydown",n)}var X=C(null);function Q({editor:e,hotkeys:t=!0,resolveOnMount:n=!0,children:o}){return x(()=>{n&&e.resolveAll()},[e,n]),x(()=>{if(t&&"undefined"!=typeof document)return W(document,e)},[e,t]),/* @__PURE__ */$(X.Provider,{value:e,children:o})}function J(){const e=O(X);if(!e)throw new Error("useEditor: no <EditorProvider> above this component");return e}function _(e){const t=J(),n=D({view:null,selector:null,value:void 0,has:!1}),o=()=>{const o=t.getState(),r=n.current;if(r.has&&r.view===o&&r.selector===e)return r.value;const i=e(o);return r.has&&Object.is(r.value,i)?(n.current={view:o,selector:e,value:r.value,has:!0},r.value):(n.current={view:o,selector:e,value:i,has:!0},i)};return E(t.subscribe,o,o)}function ee(){return function(e){return _(e)}}var te="data-puck-component",ne="data-puck-dropzone",oe={},re="data-es-mirror";function ie(e,t,n){for(const e of Array.from(t.head.querySelectorAll(`[${re}]`)))e.remove();for(const o of Array.from(e.head.querySelectorAll('style, link[rel="stylesheet"]'))){const e=o.cloneNode(!0);e.setAttribute(re,""),n&&e.setAttribute("nonce",n),t.head.appendChild(e)}}function ae({children:t,id:n="preview-frame",title:o,className:r,style:s,mirrorStyles:l=!0,onDocument:d,height:c="auto",nonce:u}){const p=i("canvas",e),h=D(null),[f,m]=A(null);return z(()=>{const e=h.current,t=f?.ownerDocument.defaultView;if("auto"!==c||!e||!f||!t)return;const n=()=>{e.style.height=`${Math.ceil(f.getBoundingClientRect().height)}px`};n();const o=t.ResizeObserver,r=o?new o(n):null;return r?.observe(f),()=>r?.disconnect()},[f,c]),z(()=>{let e=h.current?.contentDocument;if(!e)return;"CSS1Compat"!==e.compatMode&&(e.open(),e.write("<!DOCTYPE html><html><head></head><body></body></html>"),e.close(),e=h.current?.contentDocument??e),e.body||e.documentElement.appendChild(e.createElement("body")),e.body.style.margin="0";const t=e.createElement("div");t.setAttribute("data-puck-entry",""),t.id="frame-root","fill"===c&&t.classList.add("es-frame-fill"),e.body.appendChild(t),a(e,u),m(t),d?.(e);let n=null;const o=h.current?.ownerDocument;if(l&&o){ie(o,e,u);const t=o.defaultView;t&&"MutationObserver"in t&&(n=new t.MutationObserver(()=>ie(o,e,u)),n.observe(o.head,{childList:!0,subtree:!0,characterData:!0}))}return()=>{n?.disconnect(),t.remove(),m(null),d?.(null)}},[]),/* @__PURE__ */$("iframe",{ref:h,id:n,title:o??p.frame,className:r,style:{border:0,width:"100%",display:"block",..."fill"===c?{height:"100%"}:null,...s},children:f?N(t,f):null})}var se=C(null),le=C(oe),de=[];function ce({parentId:e,slot:t,className:n,style:o,minEmptyHeight:r=128}){const i=J(),a=_(n=>d(n.appState.data,i.config,{parentId:e,slot:t})??de),s=_(t=>"node"===t.selection?.kind&&t.selection.id===e&&e!==l),c=_(n=>"slot"===n.selection?.kind&&n.selection.parentId===e&&n.selection.slot===t),u=O(se),p=["es-zone"];return a.length&&p.push("has-children"),e===l&&p.push("is-root"),(s||c)&&p.push("is-area-selected"),null!==u&&u===e&&e!==l&&p.push("is-hovering-area"),n&&p.push(n),/* @__PURE__ */$("div",{className:p.join(" "),[ne]:`${e}:${t}`,style:{...o,"--min-empty-height":`${r}px`},children:a.map(e=>/* @__PURE__ */$(he,{node:e},e.props.id))})}function ue(e,t,n,o){const r="root"===t?e.root:e.components[t],i={...o};for(const e of w(S(r)))i[e]=function(t={}){/* @__PURE__ */
|
|
2
|
-
return $(ce,{parentId:n,slot:e,...t})};return i}function pe(e){return function({zone:t,...n}){/* @__PURE__ */
|
|
3
|
-
return $(ce,{parentId:e,slot:t,...n})}}function he({node:e}){const t=J().config,n=t.components[e.type],o=e.props.id,r=function(e){const t=D(null);return M(()=>n=>{const o=t.current;o&&o!==n&&(o.removeAttribute(te),o.removeAttribute("data-puck-dnd")),t.current=n,n&&(n.setAttribute(te,e),n.setAttribute("data-puck-dnd",e),n.style.position="relative")},[e])}(o),i=O(le);if(!n?.render)return null;const a=n.render,s=ue(t,e.type,o,{...I(n),...e.props}),l={renderDropZone:pe(o),isEditing:!0,dragRef:n.inline?r:null,metadata:{...i,...n.metadata}};return n.inline?/* @__PURE__ */$(a,{...s,puck:l,editMode:!0}):/* @__PURE__ */$("div",{[te]:o,"data-puck-dnd":o,style:{position:"relative"},children:/* @__PURE__ */$(a,{...s,puck:l,editMode:!0})})}function fe({metadata:e}){const t=_(e=>e.config),n=_(e=>e.appState.data.root).props??{},o=t.root?.render,r=/* @__PURE__ */$(ce,{parentId:l,slot:b}),i=o?/* @__PURE__ */$(o,{id:"puck-root",...ue(t,"root",l,n),puck:{renderDropZone:pe(l),isEditing:!0,dragRef:null,metadata:e??{}},editMode:!0,children:r}):r;/* @__PURE__ */
|
|
4
|
-
return $(le.Provider,{value:e??oe,children:i})}function me({id:e,kind:t,overlay:n}){const o=D(null),[r,i]=A(null);z(()=>{const t=o.current?.ownerDocument,n=t?.defaultView;if(!t||!n||!e)return void i(null);let r=0;const a=()=>{r=0;const a=function(e,t){if(!e||!t)return null;const n=e.getBoundingClientRect(),o=t.getBoundingClientRect();return{top:n.top-o.top,left:n.left-o.left,width:n.width,height:n.height}}(t.querySelector(`[${te}="${n.CSS?.escape?n.CSS.escape(e):e}"]`),o.current?.parentElement??null);i(e=>{return(t=e)===(n=a)||t&&n&&t.top===n.top&&t.left===n.left&&t.width===n.width&&t.height===n.height?e:a;var t,n})},s=()=>{r||(r=(n.requestAnimationFrame??(e=>n.setTimeout(e,16)))(a))};a();const l="MutationObserver"in n?new n.MutationObserver(s):null;l?.observe(t.body,{childList:!0,subtree:!0,attributes:!0,characterData:!0});const d="ResizeObserver"in n?new n.ResizeObserver(s):null;return d?.observe(t.documentElement),n.addEventListener("resize",s),()=>{l?.disconnect(),d?.disconnect(),n.removeEventListener("resize",s),r&&(n.cancelAnimationFrame??n.clearTimeout)(r)}},[e]);const a=/* @__PURE__ */$("div",{ref:o,"aria-hidden":"true",className:`es-canvas-outline is-${t}`,style:r?{position:"absolute",top:r.top,left:r.left,width:r.width,height:r.height}:{display:"none"}});return n&&e?/* @__PURE__ */$(n,{componentId:e,kind:t,children:a}):a}function ve({frame:e=!0,className:t,style:n,metadata:o,mirrorStyles:r,onDocument:i,height:a,title:s,nonce:l,frameWrapper:d,overlay:c,children:u}){const p=J(),[h,f]=A(void 0),m=_(e=>"node"===e.selection?.kind?e.selection.id:null),[v,y]=A(null),g=/* @__PURE__ */R("div",{className:"es-canvas-content",style:{position:"relative"},onClick:e=>{const t=e.target;t.closest?.("a[href]")&&e.preventDefault();const n=t.closest?.(`[${te}]`);n?p.select(n.getAttribute(te)):t.hasAttribute?.(ne)||p.select(null)},onMouseOver:e=>{const t=e.target.closest?.(`[${te}]`),n=t?.getAttribute(te)??null;n!==v&&y(n)},onMouseLeave:()=>y(null),children:[
|
|
5
|
-
/* @__PURE__ */$(se.Provider,{value:v,children:/* @__PURE__ */$(fe,{metadata:o})}),
|
|
6
|
-
/* @__PURE__ */R("div",{className:"es-canvas-outlines",style:{position:"absolute",top:0,left:0,pointerEvents:"none"},children:[
|
|
7
|
-
/* @__PURE__ */$(me,{id:v&&v!==m?v:null,kind:"hover",overlay:c}),
|
|
8
|
-
/* @__PURE__ */$(me,{id:m,kind:"selected",overlay:c})]}),u]}),k=d?/* @__PURE__ */$(d,{document:h,children:g}):g,b=D(null);/* @__PURE__ */
|
|
9
|
-
return $("div",{className:"es-canvas"+(t?` ${t}`:""),style:n,"data-puck-preview":"",children:e?/* @__PURE__ */$(ae,{mirrorStyles:r,onDocument:e=>{b.current?.(),b.current=e?W(e,p):null,f(e??void 0),i?.(e)},height:a,title:s,nonce:l,children:k}):/* @__PURE__ */$("div",{id:"preview-frame","data-puck-entry":"",children:k})})}function ye(e={}){const t=J(),n=_(e=>e.appState.data);return r({...e,data:n,config:t.config,commit:(e,{select:n})=>t.run({data:e,select:n})})}function ge(){const e=J(),n=_(e=>e.config),o=e.resolveCache,r=_(e=>e.selectedItem),i=_(e=>e.appState.data.root),a=r?r.props.id:"root",l=i.props??{},d=M(()=>r||{type:"root",props:l},[r,l]),c=r?n.components[r.type]:n.root,u=e.getState(),p=r?s(u.appState.data,n,a):null,h=p&&"root"!==p.place.parentId?p.place.parentId:null,f=h?u.getItemById(h)??null:null,{fields:m}=t({id:a,node:d,block:c,parent:f,appState:u.appState}),v=u.getPermissions(r?{item:r}:{root:!0}),y=Z((t,r)=>{(async()=>{const i=e.getState();if("root"!==a){const s=i.getItemById(a),l=i.getSelectorForId(a);if(!s||!l)return;const d={...s,props:{...s.props,[t]:r}},{node:c}=await k(d,n,{cache:o,trigger:"replace"}),u=e.getState().getSelectorForId(a);if(!u)return;return void e.dispatch({type:"replace",destinationZone:u.zone??"root:default-zone",destinationIndex:u.index,data:c})}const s=i.appState.data.root.props??{},{node:l}=await k({type:"root",props:{...s,[t]:r}},n,{cache:o,trigger:"replace"});e.dispatch({type:"replaceRoot",root:{props:l.props,readOnly:l.readOnly},recordHistory:!0})})()},[e,n,o,a]);return{id:a,node:d,fields:m,values:d.props,readOnly:!1===v.edit,onChange:y}}export{ae as CanvasFrame,q as DEFAULT_UI,fe as EditDocument,ve as EditorCanvas,Q as EditorProvider,W as bindUndoKeys,U as createEditor,ee as createUseEditor,B as recordsByDefault,H as reduce,K as uiView,_ as useEditor,J as useEditorApi,ye as useEditorNodeOps,ge as useSelectedFields,L as validSelection};
|
|
1
|
+
export{CanvasFrame,DEFAULT_UI,EaselCanvas,EaselProvider,EditDocument,EditorCanvas,EditorProvider,bindUndoKeys,createEasel,createEditor,createUseEasel,createUseEditor,recordsByDefault,reduce,uiView,useEasel,useEaselApi,useEaselNodeOps,useEditor,useEditorApi,useEditorNodeOps,useSelectedFields,validSelection}from"../chunk-F2PIG3AA.js";import"../chunk-D2BCHTQR.js";import"../chunk-AELNNAFM.js";import"../chunk-YRLPFZW3.js";import"../chunk-MFIRYGHW.js";import"../chunk-ZNCEOSXO.js";import"../chunk-KRXQM65X.js";import"../chunk-NKB3KVAB.js";
|
package/dist/fields/index.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ interface InspectorProps {
|
|
|
28
28
|
renderers?: Partial<Record<InspectorFieldDef['type'], FieldRenderer>>;
|
|
29
29
|
/** Unique per panel, e.g. the selected node's id: every field id starts with it. */
|
|
30
30
|
idPrefix?: string;
|
|
31
|
-
/** The tab strip's name. Default "Settings" (`
|
|
31
|
+
/** The tab strip's name. Default "Settings" (`EaselStrings.panel.settings`). */
|
|
32
32
|
ariaLabel?: string;
|
|
33
33
|
/** Drawn after the rows, on every tab (an app's own trailing rows). */
|
|
34
34
|
children?: ReactNode;
|
|
@@ -49,7 +49,7 @@ interface InspectorProps {
|
|
|
49
49
|
* - THE SPACING IS THE PANEL'S (panel.css `--es-rhythm-*`): a row adds none of
|
|
50
50
|
* its own, so the rhythm is defined once for both editors.
|
|
51
51
|
* - A TAB'S KEY IS NOT ITS WORD. `bucket: 'Style'` names the tab; what the tab
|
|
52
|
-
* says is `
|
|
52
|
+
* says is `EaselStrings.panel.buckets.Style`, from the strings provider.
|
|
53
53
|
*/
|
|
54
54
|
declare function Inspector({ fields, values, onChange, readOnly, context, tab, onTab, tabs, tabIcons, renderers, idPrefix, ariaLabel, children, }: InspectorProps): react.JSX.Element;
|
|
55
55
|
|
|
@@ -187,14 +187,14 @@ declare function useResolvedFields({ id, node, block, parent, appState }: Resolv
|
|
|
187
187
|
* so an editor can keep the open item across a re-render of the panel.
|
|
188
188
|
*
|
|
189
189
|
* Its words ("Add slide", "2 of 5", the rows' drag hint) are the strings
|
|
190
|
-
* provider's — `
|
|
190
|
+
* provider's — `EaselStrings.fields.list` and `.tree` — English with none.
|
|
191
191
|
*/
|
|
192
192
|
interface ListFieldProps<T> {
|
|
193
193
|
/** The list's name, e.g. "Slides". Also the back button's word. */
|
|
194
194
|
label: string;
|
|
195
195
|
/** A glyph before the name, as a settings row wears one. */
|
|
196
196
|
icon?: ReactNode;
|
|
197
|
-
/** One item's word, lower case, e.g. "slide": "Add slide", "Delete slide". Default "item" (`
|
|
197
|
+
/** One item's word, lower case, e.g. "slide": "Add slide", "Delete slide". Default "item" (`EaselStrings.fields.list.item`). */
|
|
198
198
|
noun?: string;
|
|
199
199
|
items: readonly T[];
|
|
200
200
|
onChange: (next: T[]) => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { EditorRail, EditorRailButton, RailTokens, railCssVars, railTokens } from './rail/index.js';
|
|
1
|
+
export { EaselRail, EaselRailButton, EditorRail, EditorRailButton, RailTokens, railCssVars, railTokens } from './rail/index.js';
|
|
2
2
|
export { AddIcon, LayersIcon, MediaIcon, PageIcon as PagesIcon, IconProps as RailIconProps, SitemapIcon, StylesIcon } from './icons/index.js';
|
|
3
|
-
export { W as WordFit } from './wordFit-
|
|
4
|
-
export { E as
|
|
3
|
+
export { W as WordFit } from './wordFit-D4S36PvB.js';
|
|
4
|
+
export { E as EaselRailButtonProps, a as EaselRailItem, b as EaselRailOrientation, c as EaselRailProps, d as EditorRailButtonProps, e as EditorRailItem, f as EditorRailOrientation, g as EditorRailProps } from './types-Bs_gVkVI.js';
|
|
5
5
|
export { SPACING_SCALE, ShellTokens, shellCssVars, shellTokens } from './shell/index.js';
|
|
6
6
|
import 'react';
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./chunk-
|
|
1
|
+
import"./chunk-2PHD4L6A.js";export{SPACING_SCALE,shellCssVars,shellTokens}from"./chunk-2UX75JDP.js";export{EaselRail,EaselRailButton,EditorRail,EditorRailButton,railCssVars,railTokens}from"./chunk-XUE5O62R.js";import"./chunk-2OAZYSWJ.js";import"./chunk-BZ5ASXOL.js";export{AddIcon,LayersIcon,MediaIcon,PageIcon as PagesIcon,SitemapIcon,StylesIcon}from"./chunk-PI26YXYD.js";
|
package/dist/menu/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { a as
|
|
3
|
-
export { E as EditorContextMenuItem } from '../types-
|
|
2
|
+
import { a as EaselContextMenuProps, b as EaselContextMenuSkin } from '../types-DO-b0LNj.js';
|
|
3
|
+
export { E as EaselContextMenuItem, c as EditorContextMenuItem, d as EditorContextMenuProps, e as EditorContextMenuSkin } from '../types-DO-b0LNj.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* The right-click menu box, shared by both editors (card 66400.d).
|
|
@@ -17,7 +17,7 @@ export { E as EditorContextMenuItem } from '../types-pGBXevBU.js';
|
|
|
17
17
|
* the box no longer knows what it looks like. The admin version hard-coded ONE
|
|
18
18
|
* editor's surface — `glassStyle()` from efficient-shell, plus that portal's
|
|
19
19
|
* Tailwind palette — into the only box both editors were ever going to share.
|
|
20
|
-
* Here the look is a {@link
|
|
20
|
+
* Here the look is a {@link EaselContextMenuSkin}, the default is the
|
|
21
21
|
* storefront's approved one, and the admin passes its own strings in. So this
|
|
22
22
|
* module imports nothing but React (`tests/menu-leaf-safety.test.ts`), and the
|
|
23
23
|
* admin's rendered markup is byte-identical to what shipped
|
|
@@ -28,7 +28,9 @@ export { E as EditorContextMenuItem } from '../types-pGBXevBU.js';
|
|
|
28
28
|
* server component may import the module and must render it inside the host's
|
|
29
29
|
* client boundary.
|
|
30
30
|
*/
|
|
31
|
-
declare function
|
|
31
|
+
declare function EaselContextMenu({ x, y, items, onClose, maxHeight, skin, portalTo, }: EaselContextMenuProps): react.ReactPortal | null;
|
|
32
|
+
/** @deprecated The name before the Easel rename: `EaselContextMenu`. */
|
|
33
|
+
declare const EditorContextMenu: typeof EaselContextMenu;
|
|
32
34
|
|
|
33
35
|
/**
|
|
34
36
|
* The default skin — the storefront editor's approved look, in classes that
|
|
@@ -44,6 +46,6 @@ declare function EditorContextMenu({ x, y, items, onClose, maxHeight, skin, port
|
|
|
44
46
|
* present, answers every query a test can ask, and cannot be seen. Pinned by
|
|
45
47
|
* `tests/menu-layer.test.tsx` (f).
|
|
46
48
|
*/
|
|
47
|
-
declare const ES_MENU_SKIN:
|
|
49
|
+
declare const ES_MENU_SKIN: EaselContextMenuSkin;
|
|
48
50
|
|
|
49
|
-
export { ES_MENU_SKIN,
|
|
51
|
+
export { ES_MENU_SKIN, EaselContextMenu, EaselContextMenuProps, EaselContextMenuSkin, EditorContextMenu };
|
package/dist/menu/index.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import{useRef as e,useState as n,useLayoutEffect as t,useEffect as l}from"react";import{createPortal as r}from"react-dom";import{jsxs as i,Fragment as a,jsx as o}from"react/jsx-runtime";var c={menu:"es-editor es-menu",menuSub:"es-editor es-menu",item:"es-menu-item",itemDanger:"es-menu-item is-danger",divider:"es-menu-divider",header:"es-menu-header",icon:"es-menu-icon",shortcut:"es-menu-shortcut",label:"es-menu-label",labelSub:"es-menu-label es-menu-label-sub",chevron:"es-menu-chevron",tick:"es-menu-tick"};function u({x:u,y:s,items:d,onClose:m,maxHeight:h,skin:b,portalTo:y}){const p=e(null),g=e(null),[f,
|
|
1
|
+
import{useRef as e,useState as n,useLayoutEffect as t,useEffect as l}from"react";import{createPortal as r}from"react-dom";import{jsxs as i,Fragment as a,jsx as o}from"react/jsx-runtime";var c={menu:"es-editor es-menu",menuSub:"es-editor es-menu",item:"es-menu-item",itemDanger:"es-menu-item is-danger",divider:"es-menu-divider",header:"es-menu-header",icon:"es-menu-icon",shortcut:"es-menu-shortcut",label:"es-menu-label",labelSub:"es-menu-label es-menu-label-sub",chevron:"es-menu-chevron",tick:"es-menu-tick"};function u({x:u,y:s,items:d,onClose:m,maxHeight:h,skin:b,portalTo:y}){const p=e(null),g=e(null),[f,v]=n(null),[w,x]=n({x:u,y:s}),[N,k]=n({x:u,y:s});if(N.x===u&&N.y===s||(k({x:u,y:s}),x({x:u,y:s})),t(()=>{const e=p.current;if(!e)return;const{width:n,height:t}=e.getBoundingClientRect(),l=window.innerWidth,r=window.innerHeight;let i=s;s+t>r-8&&(i=s-t>=8?s-t:Math.max(8,r-t-8));let a=u;u+n>l-8&&(a=u-n>=8?u-n:Math.max(8,l-n-8)),a===w.x&&i===w.y||x({x:a,y:i})},[u,s,d,w.x,w.y]),l(()=>{const e=document.activeElement;return p.current?.querySelector('[role="menuitem"]')?.focus(),()=>e?.focus?.()},[]),l(()=>{const e=e=>{const n=e.target;g.current?.contains(n)||p.current&&!p.current.contains(n)&&m()},n=e=>{"Escape"===e.key&&m()},t=setTimeout(()=>{window.addEventListener("mousedown",e),window.addEventListener("contextmenu",e),window.addEventListener("keydown",n)},0);return()=>{clearTimeout(t),window.removeEventListener("mousedown",e),window.removeEventListener("contextmenu",e),window.removeEventListener("keydown",n)}},[m]),0===d.length)return null;const C=b??c,E=e=>e.danger?C.itemDanger:C.item,S=({on:e})=>/* @__PURE__ */o("span",{className:C.tick,"aria-hidden":"true",children:e?"✓":""}),L=({of:e})=>null==e.icon?null:/* @__PURE__ */o("span",{className:C.icon,"aria-hidden":"true",children:e.icon}),T=({of:e})=>null==e.shortcut?null:/* @__PURE__ */o("span",{className:C.shortcut,"aria-hidden":"true",children:e.shortcut}),B=e=>null!=e.icon||null!=e.shortcut,M=(e,n,t)=>{if(!e.children?.length)return void v(null);const l=t.getBoundingClientRect(),r=p.current,i=r?parseFloat(getComputedStyle(r).minWidth):NaN,a=Number.isFinite(i)&&i>0?i:r?.getBoundingClientRect().width??0,o=l.right+a>window.innerWidth-8?l.left-a:l.right;v({i:n,x:Math.max(8,o),y:l.top})},F=f?d[f.i]:null,H=e=>({...C.surface,...e});return r(
|
|
2
2
|
/* @__PURE__ */i(a,{children:[
|
|
3
|
-
/* @__PURE__ */o("div",{ref:p,"data-es-menu":"",role:"menu","aria-label":d.find(e=>e.header)?.label,className:C.menu,style:H({left:
|
|
3
|
+
/* @__PURE__ */o("div",{ref:p,"data-es-menu":"",role:"menu","aria-label":d.find(e=>e.header)?.label,className:C.menu,style:H({left:w.x,top:w.y,maxHeight:h||void 0}),children:d.map((e,n)=>"—"===e.label?
|
|
4
4
|
/* @__PURE__ */o("div",{role:"separator",className:C.divider},n):e.header?/* @__PURE__ */o("div",{className:C.header,children:e.label},n):e.children?.length?/* @__PURE__ */i("button",{type:"button",role:"menuitem","aria-haspopup":"menu","aria-expanded":f?.i===n,onMouseEnter:t=>M(e,n,t.currentTarget),onFocus:t=>M(e,n,t.currentTarget),onClick:t=>M(e,n,t.currentTarget),className:E(e),style:C.itemStyle,children:[
|
|
5
5
|
/* @__PURE__ */o(L,{of:e}),
|
|
6
6
|
/* @__PURE__ */o("span",{className:C.label,children:e.label}),
|
|
7
7
|
/* @__PURE__ */o(T,{of:e}),
|
|
8
|
-
/* @__PURE__ */o("span",{"aria-hidden":"true",className:C.chevron,children:"›"})]},n):/* @__PURE__ */o("button",{type:"button",role:"menuitem",onMouseEnter:()=>
|
|
8
|
+
/* @__PURE__ */o("span",{"aria-hidden":"true",className:C.chevron,children:"›"})]},n):/* @__PURE__ */o("button",{type:"button",role:"menuitem",onMouseEnter:()=>v(null),onClick:()=>{e.onClick(),m()},className:E(e),style:C.itemStyle,children:B(e)?/* @__PURE__ */i(a,{children:[
|
|
9
9
|
/* @__PURE__ */o(L,{of:e}),
|
|
10
10
|
/* @__PURE__ */o("span",{className:C.label,children:e.label}),
|
|
11
11
|
/* @__PURE__ */o(T,{of:e})]}):e.label},n))}),F?.children?.length&&f?/* @__PURE__ */o("div",{ref:g,"data-es-menu":"",role:"menu","aria-label":F.label,className:C.menuSub??C.menu,style:H({left:f.x,top:f.y}),children:F.children.map((e,n)=>/* @__PURE__ */i("button",{type:"button",role:"menuitemradio","aria-checked":Boolean(e.checked),onClick:()=>{e.onClick(),m()},className:E(e),style:C.itemStyle,children:[
|
|
12
12
|
/* @__PURE__ */o(S,{on:Boolean(e.checked)}),
|
|
13
13
|
/* @__PURE__ */o(L,{of:e}),
|
|
14
14
|
/* @__PURE__ */o("span",{className:C.labelSub??C.label,children:e.label}),
|
|
15
|
-
/* @__PURE__ */o(T,{of:e})]},n))}):null]}),y??document.body)}export{c as ES_MENU_SKIN,u as EditorContextMenu};
|
|
15
|
+
/* @__PURE__ */o(T,{of:e})]},n))}):null]}),y??document.body)}var s=u;export{c as ES_MENU_SKIN,u as EaselContextMenu,s as EditorContextMenu};
|
package/dist/node-ops/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { A as AfterRemove, I as ItemSelector, N as NodeSelection, P as Planned, S as StepBounds, c as canStep, f as fromItemSelector, p as parentStep, a as planDuplicate, b as planMove, d as planPaste, e as planRemove, g as planSetProps, h as planStep, t as toItemSelector } from '../plan-DChbUXdS.js';
|
|
2
2
|
export { C as ClipboardEntry, N as NodeClipboard, a as NodeOps, b as NodeOpsHost, c as createNodeClipboard, u as useNodeOps } from '../useNodeOps-BF0fQsif.js';
|
|
3
3
|
import { ReactNode } from 'react';
|
|
4
|
-
import { E as
|
|
5
|
-
import { N as NodeMenuWords } from '../words-
|
|
4
|
+
import { E as EaselContextMenuItem } from '../types-DO-b0LNj.js';
|
|
5
|
+
import { N as NodeMenuWords } from '../words-DMG4dYq2.js';
|
|
6
6
|
import '../types-41704JE4.js';
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -10,7 +10,7 @@ import '../types-41704JE4.js';
|
|
|
10
10
|
*
|
|
11
11
|
* The campaign designer (`blockMenuItems`) and the storefront editor
|
|
12
12
|
* (`nodeMenuItems`) each built their own, in the same row type and drawn by the
|
|
13
|
-
* same `
|
|
13
|
+
* same `EaselContextMenu`, and they had drifted: different group order, the
|
|
14
14
|
* layer flyout in a different group, Copy / Cut / Paste / Rename on one side
|
|
15
15
|
* only, and no pinned-block rule on the storefront. The ORDER and the GROUPS
|
|
16
16
|
* are decided here once:
|
|
@@ -34,7 +34,7 @@ import '../types-41704JE4.js';
|
|
|
34
34
|
*/
|
|
35
35
|
|
|
36
36
|
type NodeMenuRowId = 'layer' | 'addInside' | 'duplicate' | 'moveUp' | 'moveDown' | 'copy' | 'cut' | 'paste' | 'rename' | 'hide' | 'show' | 'upLevel' | 'delete';
|
|
37
|
-
type RowLook = Partial<Pick<
|
|
37
|
+
type RowLook = Partial<Pick<EaselContextMenuItem, 'label' | 'icon' | 'shortcut' | 'danger'>> & {
|
|
38
38
|
/** `null` draws the row with no glyph. */
|
|
39
39
|
icon?: ReactNode | null;
|
|
40
40
|
};
|
|
@@ -43,7 +43,7 @@ interface NodeMenuOptions {
|
|
|
43
43
|
title: string;
|
|
44
44
|
/** The layer flyout: its entries (built by the host from the ancestor chain) and which group it sits in. */
|
|
45
45
|
layer?: {
|
|
46
|
-
items:
|
|
46
|
+
items: EaselContextMenuItem[];
|
|
47
47
|
group?: 'pick' | 'change';
|
|
48
48
|
};
|
|
49
49
|
/** Each present action is offered; an absent one is not. */
|
|
@@ -69,7 +69,7 @@ interface NodeMenuOptions {
|
|
|
69
69
|
delete?: () => void;
|
|
70
70
|
};
|
|
71
71
|
/** The host's style rows (styleMenuItems). Offered on pinned blocks too. */
|
|
72
|
-
style?:
|
|
72
|
+
style?: EaselContextMenuItem[];
|
|
73
73
|
/**
|
|
74
74
|
* The block cannot move or be removed: show this line when nothing else is on
|
|
75
75
|
* offer. It is a CAPTION, like the title — it says why the menu is short, and
|
|
@@ -79,13 +79,13 @@ interface NodeMenuOptions {
|
|
|
79
79
|
/** Per-row look overrides: label, icon (`null` = none), shortcut, danger. */
|
|
80
80
|
rows?: Partial<Record<NodeMenuRowId, RowLook>>;
|
|
81
81
|
/** Host rows added to the end of a group. */
|
|
82
|
-
extras?: Partial<Record<'pick' | 'make' | 'change' | 'remove',
|
|
82
|
+
extras?: Partial<Record<'pick' | 'make' | 'change' | 'remove', EaselContextMenuItem[]>>;
|
|
83
83
|
/**
|
|
84
|
-
* The rows' own words in the host's language: `
|
|
84
|
+
* The rows' own words in the host's language: `useEaselStrings().menu`
|
|
85
85
|
* (0.95.0). Left out, English. A row's `rows` override still wins.
|
|
86
86
|
*/
|
|
87
87
|
words?: NodeMenuWords;
|
|
88
88
|
}
|
|
89
|
-
declare function nodeMenuItems(options: NodeMenuOptions):
|
|
89
|
+
declare function nodeMenuItems(options: NodeMenuOptions): EaselContextMenuItem[];
|
|
90
90
|
|
|
91
91
|
export { type NodeMenuOptions, type NodeMenuRowId, NodeMenuWords, nodeMenuItems };
|
package/dist/panel/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { W as WordFit } from '../wordFit-
|
|
3
|
+
import { W as WordFit } from '../wordFit-D4S36PvB.js';
|
|
4
4
|
export { a as SETTINGS_BUCKETS, S as SettingsBucket } from '../buckets-CuLM47h9.js';
|
|
5
5
|
|
|
6
6
|
/**
|