efficient-easel 0.99.1 → 0.100.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/README.md +281 -36
- package/dist/autosave/index.d.ts +12 -6
- package/dist/blocks/index.d.ts +2 -2
- package/dist/canvas/index.d.ts +3 -3
- package/dist/canvas/index.js +1 -1
- package/dist/chrome/chrome.css +96 -29
- package/dist/chrome/index.d.ts +72 -19
- package/dist/chrome/index.js +17 -21
- package/dist/chunk-3EDSDPIP.js +1 -0
- package/dist/chunk-67GNT6PF.js +1 -0
- package/dist/{chunk-PI26YXYD.js → chunk-6EIVTKZZ.js} +21 -14
- package/dist/chunk-A5UK76FC.js +6 -0
- package/dist/chunk-AZT7V4UM.js +10 -0
- package/dist/chunk-DICUMYMG.js +12 -0
- package/dist/chunk-HDVD27VB.js +1 -0
- package/dist/chunk-JQM3V7XQ.js +1 -0
- package/dist/{chunk-TDA4HH54.js → chunk-JUQ6YJCG.js} +1 -1
- package/dist/chunk-LA54QLP5.js +1 -0
- package/dist/chunk-LGKQXSKO.js +16 -0
- package/dist/chunk-M6F6LS3H.js +1 -0
- package/dist/chunk-MH5GUZFQ.js +9 -0
- package/dist/chunk-P6O363EE.js +6 -0
- package/dist/chunk-PAELDYYS.js +1 -0
- package/dist/{chunk-JYPOOHII.js → chunk-QKVR3K73.js} +3 -3
- package/dist/chunk-SAJUCHOX.js +1 -0
- package/dist/chunk-TRVZ7C23.js +1 -0
- package/dist/chunk-V7GIIXFB.js +16 -0
- package/dist/{chunk-IBOFSS56.js → chunk-WZ7TGAAT.js} +1 -1
- package/dist/chunk-ZJEBF4NB.js +1 -0
- package/dist/copy/copy.css +388 -5
- package/dist/copy/index.d.ts +271 -8
- package/dist/copy/index.js +31 -10
- package/dist/data/index.d.ts +4 -4
- package/dist/drag/drag.css +10 -1
- package/dist/drag/index.d.ts +102 -11
- package/dist/drag/index.js +18 -17
- package/dist/{editor/editor.css → easel/easel.css} +16 -1
- package/dist/{editor → easel}/index.d.ts +146 -51
- package/dist/easel/index.js +9 -0
- package/dist/edit-lock/index.d.ts +3 -3
- package/dist/edit-lock/index.js +1 -1
- package/dist/fields/fields.css +103 -26
- package/dist/fields/index.d.ts +51 -13
- package/dist/fields/index.js +30 -46
- package/dist/gold/index.js +1 -1
- package/dist/icons/index.d.ts +10 -1
- package/dist/icons/index.js +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/markup/index.d.ts +94 -10
- package/dist/markup/index.js +1 -1
- package/dist/menu/index.d.ts +61 -6
- package/dist/menu/index.js +15 -15
- package/dist/menu/menu.css +17 -6
- package/dist/node-ops/index.d.ts +9 -9
- package/dist/node-ops/index.js +1 -1
- package/dist/panel/index.d.ts +73 -5
- package/dist/panel/index.js +18 -16
- package/dist/panel/panel.css +56 -1
- package/dist/pick/index.d.ts +42 -4
- package/dist/pick/index.js +7 -14
- package/dist/pick/pick.css +14 -0
- package/dist/rail/index.d.ts +6 -6
- package/dist/rail/index.js +1 -1
- package/dist/rail/rail.css +1 -1
- package/dist/strings/catalogue.d.ts +24 -40
- package/dist/strings/catalogue.js +1 -1
- package/dist/strings/index.d.ts +25 -23
- package/dist/strings/index.js +2 -2
- package/dist/style-clipboard/index.d.ts +5 -5
- package/dist/style-clipboard/index.js +1 -1
- package/dist/text-styles/index.d.ts +328 -0
- package/dist/text-styles/index.js +38 -0
- package/dist/text-styles/text-styles.css +309 -0
- package/dist/tree/index.d.ts +44 -3
- package/dist/tree/index.js +1 -1
- package/dist/tree/tree.css +71 -0
- package/dist/{types-CnRzp9oc.d.ts → types-DGcCsxs8.d.ts} +79 -12
- package/dist/{types-DNrn_w4V.d.ts → types-DWS-s9z-.d.ts} +10 -10
- package/dist/{types-pGBXevBU.d.ts → types-Djdq6Xkd.d.ts} +15 -8
- package/dist/{types-Dy6oR6Z2.d.ts → types-E3HrTPg2.d.ts} +20 -14
- package/dist/{types-C7HFvdtk.d.ts → types-VqL6t5HH.d.ts} +82 -5
- package/dist/{watch-DmasQA61.d.ts → watch-BTYOJpQU.d.ts} +19 -2
- package/dist/{wordFit-9B9nqyf3.d.ts → wordFit-D4S36PvB.d.ts} +1 -1
- package/dist/{words-DagJdwIA.d.ts → words-AHHfiaRY.d.ts} +31 -2
- package/dist/{words-D9ChvbNC.d.ts → words-BDignMl_.d.ts} +1 -1
- package/dist/{words-Cqmyey0s.d.ts → words-BMzV04b1.d.ts} +2 -2
- package/dist/words-CJjUKcV5.d.ts +37 -0
- package/dist/words-CRYvAiHX.d.ts +105 -0
- package/dist/{words-B2YLaKEr.d.ts → words-CnnHb9jo.d.ts} +1 -1
- package/dist/{words-CD3WADyb.d.ts → words-CzoyDNHm.d.ts} +4 -0
- package/dist/{words-bOMsUJk9.d.ts → words-DBq7vfHy.d.ts} +59 -6
- package/dist/{words-DOhF-4D4.d.ts → words-DMG4dYq2.d.ts} +1 -1
- package/dist/{words-BK-npta-.d.ts → words-DgHcY5qB.d.ts} +10 -4
- package/dist/{words-B87GIFWH.d.ts → words-is_Vy6hn.d.ts} +1 -1
- package/package.json +14 -8
- package/dist/chunk-66CKSTXP.js +0 -14
- package/dist/chunk-67VZRQLG.js +0 -13
- package/dist/chunk-6PS6STGA.js +0 -1
- package/dist/chunk-7A7O2JWQ.js +0 -1
- package/dist/chunk-H4B72XCJ.js +0 -1
- package/dist/chunk-JE63JHKO.js +0 -1
- package/dist/chunk-KDIVA6WD.js +0 -1
- package/dist/chunk-MCLBHENY.js +0 -1
- package/dist/chunk-QB3BZIRA.js +0 -5
- package/dist/chunk-SJQG5ENJ.js +0 -1
- package/dist/chunk-SUO5627P.js +0 -1
- package/dist/chunk-ZT7M24XD.js +0 -1
- package/dist/editor/index.js +0 -9
- /package/dist/{chunk-GGTPNGFJ.js → chunk-AELNNAFM.js} +0 -0
|
@@ -7,7 +7,7 @@ import { CSSProperties, ReactNode } from 'react';
|
|
|
7
7
|
* what the menus OFFER is not this card's to move. A `label` of `'—'` renders a
|
|
8
8
|
* separator; `header: true` renders a caption, and the FIRST such caption names
|
|
9
9
|
* the menu for assistive tech. */
|
|
10
|
-
interface
|
|
10
|
+
interface EaselContextMenuItem {
|
|
11
11
|
label: string;
|
|
12
12
|
onClick: () => void;
|
|
13
13
|
danger?: boolean;
|
|
@@ -16,7 +16,7 @@ interface EditorContextMenuItem {
|
|
|
16
16
|
* One level only — a child carrying its own `children` is drawn as a plain
|
|
17
17
|
* item, which is all any caller has needed and keeps the flyout from becoming
|
|
18
18
|
* a tree nobody can navigate with a mouse. */
|
|
19
|
-
children?:
|
|
19
|
+
children?: EaselContextMenuItem[];
|
|
20
20
|
/** Draw a tick beside this item — for a submenu whose entries are STATES
|
|
21
21
|
* rather than actions, so it can say which one you are already on. */
|
|
22
22
|
checked?: boolean;
|
|
@@ -65,7 +65,7 @@ interface EditorContextMenuItem {
|
|
|
65
65
|
*
|
|
66
66
|
* A slot left empty is left empty. The default fills all of them.
|
|
67
67
|
*/
|
|
68
|
-
interface
|
|
68
|
+
interface EaselContextMenuSkin {
|
|
69
69
|
/** The box. */
|
|
70
70
|
menu?: string;
|
|
71
71
|
/** The FLYOUT box. Falls back to {@link menu} when a skin gives only one —
|
|
@@ -106,26 +106,33 @@ interface EditorContextMenuSkin {
|
|
|
106
106
|
/** Merged into each row's inline style. */
|
|
107
107
|
itemStyle?: CSSProperties;
|
|
108
108
|
}
|
|
109
|
-
interface
|
|
109
|
+
interface EaselContextMenuProps {
|
|
110
110
|
/** Where the pointer was. The box is placed from here and then kept on
|
|
111
111
|
* screen — see the note on the component. */
|
|
112
112
|
x: number;
|
|
113
113
|
y: number;
|
|
114
|
-
items:
|
|
114
|
+
items: EaselContextMenuItem[];
|
|
115
115
|
onClose: () => void;
|
|
116
116
|
/** Cap the box's height; it scrolls past that. */
|
|
117
117
|
maxHeight?: number;
|
|
118
118
|
/** Defaults to {@link ES_MENU_SKIN}, the storefront editor's approved look. */
|
|
119
|
-
skin?:
|
|
119
|
+
skin?: EaselContextMenuSkin;
|
|
120
120
|
/**
|
|
121
|
-
* Where to portal to. Defaults to `document.body
|
|
121
|
+
* Where to portal to. Defaults to `document.body` (`null` means the default).
|
|
122
122
|
*
|
|
123
123
|
* A host that OVERRIDES `--es-*` on its own editor root should pass that root
|
|
124
124
|
* instead: the default skin re-declares the token defaults on the box (see the
|
|
125
125
|
* component's note), which is right for a box hanging off `<body>` and wrong
|
|
126
126
|
* for one that should inherit a re-themed editor's values.
|
|
127
|
+
*
|
|
128
|
+
* So should a host that wants the box INSIDE ITS LANDMARKS (on the body it
|
|
129
|
+
* is page content outside every landmark: axe-core's `region`) — through
|
|
130
|
+
* `menuPortalTarget(root)`, never the bare root: the box is `position:
|
|
131
|
+
* fixed`, and a transformed, filtered or contained ancestor places and clips
|
|
132
|
+
* it. `menuPortalTarget` answers the root only when none does. The decision
|
|
133
|
+
* is recorded in `./portal`.
|
|
127
134
|
*/
|
|
128
135
|
portalTo?: HTMLElement | null;
|
|
129
136
|
}
|
|
130
137
|
|
|
131
|
-
export type {
|
|
138
|
+
export type { EaselContextMenuItem as E, EaselContextMenuProps as a, EaselContextMenuSkin as b };
|
|
@@ -3,12 +3,12 @@ import { I as ItemSelector, N as NodeSelection } from './plan-DChbUXdS.js';
|
|
|
3
3
|
import { D as Data, S as SlotAddress, a as DataConfig, N as Node } from './types-41704JE4.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* The
|
|
6
|
+
* The easel's UI state, in Puck's shape so the apps' `appState.ui` reads move
|
|
7
7
|
* over unchanged. `itemSelector` and `selectedSlot` are DERIVED from the
|
|
8
8
|
* selection the store holds by id; every other key is the host's own and is
|
|
9
9
|
* kept as written.
|
|
10
10
|
*/
|
|
11
|
-
type
|
|
11
|
+
type EaselUi = Record<string, unknown> & {
|
|
12
12
|
itemSelector: ItemSelector | null;
|
|
13
13
|
/** The selected slot (a column), when a slot rather than a node is selected. */
|
|
14
14
|
selectedSlot: SlotAddress | null;
|
|
@@ -22,7 +22,7 @@ type EditorUi = Record<string, unknown> & {
|
|
|
22
22
|
/** Puck's public `appState`. */
|
|
23
23
|
interface AppState {
|
|
24
24
|
data: Data;
|
|
25
|
-
ui:
|
|
25
|
+
ui: EaselUi;
|
|
26
26
|
}
|
|
27
27
|
type Recordable = {
|
|
28
28
|
recordHistory?: boolean;
|
|
@@ -34,13 +34,19 @@ type SetDataPatch = Partial<Data> | DataInput;
|
|
|
34
34
|
/**
|
|
35
35
|
* The actions the apps dispatch today — Puck 0.20's, with Puck's meaning. Zone
|
|
36
36
|
* keys are `"<parentId>:<slot>"`; `root:default-zone` is the page's own list.
|
|
37
|
+
*
|
|
38
|
+
* `insert` puts the block in with its `defaultProps` and runs NO resolver, as
|
|
39
|
+
* Puck's reducer did not. What ran a new block's `resolveData` in Puck was its
|
|
40
|
+
* own drop from the component list; here that is `easel.resolveNode(id, {
|
|
41
|
+
* trigger: 'insert' })`, called by the host after the insert (pass the action
|
|
42
|
+
* an `id` so there is one to name).
|
|
37
43
|
*/
|
|
38
|
-
type
|
|
44
|
+
type EaselAction = ({
|
|
39
45
|
type: 'setData';
|
|
40
46
|
data: SetDataPatch | ((prev: Data) => SetDataPatch);
|
|
41
47
|
} & Recordable) | ({
|
|
42
48
|
type: 'setUi';
|
|
43
|
-
ui: Partial<
|
|
49
|
+
ui: Partial<EaselUi> | ((prev: EaselUi) => Partial<EaselUi>);
|
|
44
50
|
} & Recordable) | ({
|
|
45
51
|
type: 'set';
|
|
46
52
|
state: Partial<AppState> | ((prev: AppState) => Partial<AppState>);
|
|
@@ -81,7 +87,7 @@ type EditorAction = ({
|
|
|
81
87
|
index: number;
|
|
82
88
|
zone: string;
|
|
83
89
|
} & Recordable);
|
|
84
|
-
/** What a block, the root or the whole
|
|
90
|
+
/** What a block, the root or the whole easel allows. Puck's five. */
|
|
85
91
|
interface Permissions {
|
|
86
92
|
drag: boolean;
|
|
87
93
|
duplicate: boolean;
|
|
@@ -93,7 +99,7 @@ interface Permissions {
|
|
|
93
99
|
/** The config the store needs: the data layer's shape, plus each block's own
|
|
94
100
|
* `permissions` (Puck's per-component permissions). Rendering keys are the
|
|
95
101
|
* renderer's business and pass through untouched. */
|
|
96
|
-
interface
|
|
102
|
+
interface EaselConfig extends DataConfig {
|
|
97
103
|
root?: DataConfig['root'] & {
|
|
98
104
|
permissions?: Partial<Permissions>;
|
|
99
105
|
};
|
|
@@ -102,7 +108,7 @@ interface EditorConfig extends DataConfig {
|
|
|
102
108
|
}) | undefined>;
|
|
103
109
|
}
|
|
104
110
|
/** The state the store holds. The selection is BY ID. */
|
|
105
|
-
interface
|
|
111
|
+
interface EaselCore {
|
|
106
112
|
data: Data;
|
|
107
113
|
selection: NodeSelection;
|
|
108
114
|
/** The host's own UI keys — everything but `itemSelector` / `selectedSlot`. */
|
|
@@ -115,7 +121,7 @@ interface HistoryEntry {
|
|
|
115
121
|
}
|
|
116
122
|
/** Puck's PUBLIC `history` (what `usePuck` hands out): `hasPast` and
|
|
117
123
|
* `hasFuture` are booleans there, read at the state they came with. */
|
|
118
|
-
interface
|
|
124
|
+
interface EaselHistory {
|
|
119
125
|
back: () => void;
|
|
120
126
|
forward: () => void;
|
|
121
127
|
hasPast: boolean;
|
|
@@ -126,18 +132,18 @@ interface EditorHistory {
|
|
|
126
132
|
setHistoryIndex: (index: number) => void;
|
|
127
133
|
}
|
|
128
134
|
/**
|
|
129
|
-
* What `
|
|
135
|
+
* What `useEasel` reads — Puck's `usePuck` state, so the apps' selectors move
|
|
130
136
|
* over by renaming the hook: `appState`, `selectedItem`, `dispatch`, `config`,
|
|
131
137
|
* `history`, `getPermissions`, `getItemById`, `getSelectorForId`. Plus the
|
|
132
138
|
* selection by id (`selection`), which Puck never had.
|
|
133
139
|
*/
|
|
134
|
-
interface
|
|
140
|
+
interface EaselView<C extends EaselConfig = EaselConfig> {
|
|
135
141
|
appState: AppState;
|
|
136
142
|
selection: NodeSelection;
|
|
137
143
|
selectedItem: Node | null;
|
|
138
144
|
config: C;
|
|
139
|
-
dispatch: (action:
|
|
140
|
-
history:
|
|
145
|
+
dispatch: (action: EaselAction) => void;
|
|
146
|
+
history: EaselHistory;
|
|
141
147
|
getPermissions: (params?: {
|
|
142
148
|
item?: Node | null;
|
|
143
149
|
type?: string;
|
|
@@ -150,4 +156,4 @@ interface EditorView<C extends EditorConfig = EditorConfig> {
|
|
|
150
156
|
getSelectorForId: (id: string) => Required<ItemSelector> | undefined;
|
|
151
157
|
}
|
|
152
158
|
|
|
153
|
-
export type { AppState as A,
|
|
159
|
+
export type { AppState as A, EaselConfig as E, HistoryEntry as H, Permissions as P, SetDataPatch as S, EaselView as a, EaselAction as b, EaselCore as c, EaselUi as d, EaselHistory as e };
|
|
@@ -38,6 +38,9 @@ interface FieldNumberProps extends ControlBase {
|
|
|
38
38
|
/** Two small stacked arrows at the cell's end. */
|
|
39
39
|
steppers?: boolean;
|
|
40
40
|
placeholder?: string;
|
|
41
|
+
/** The cell's tooltip — the text box's cells say their name and step here
|
|
42
|
+
* (E5b), since the cell draws no name. */
|
|
43
|
+
title?: string;
|
|
41
44
|
}
|
|
42
45
|
/**
|
|
43
46
|
* A slider row (Site styles, Email styles): the name left and the typed value
|
|
@@ -50,20 +53,94 @@ interface FieldSliderProps extends Omit<FieldNumberProps, 'icon' | 'steppers' |
|
|
|
50
53
|
label: string;
|
|
51
54
|
sliderMin: number;
|
|
52
55
|
sliderMax: number;
|
|
56
|
+
/**
|
|
57
|
+
* The word for "no number of its own: each section draws its own" (plan
|
|
58
|
+
* step E6). Given, the slider gains one spot left of `sliderMin` that means
|
|
59
|
+
* it, and the value reads the word while there is no number.
|
|
60
|
+
*/
|
|
61
|
+
auto?: string;
|
|
53
62
|
}
|
|
54
63
|
interface FieldOption<V = unknown> {
|
|
55
64
|
label: string;
|
|
56
65
|
value: V;
|
|
57
66
|
disabled?: boolean;
|
|
58
67
|
icon?: ReactNode;
|
|
68
|
+
/**
|
|
69
|
+
* The heading this option sits under in the open list — what `<optgroup>`
|
|
70
|
+
* did. Each RUN of options with the same group gets one heading, in the
|
|
71
|
+
* order the options come; an option with none sits under no heading. A
|
|
72
|
+
* heading is not an option: it cannot be chosen and the keys never land on it.
|
|
73
|
+
*/
|
|
74
|
+
group?: string;
|
|
75
|
+
/**
|
|
76
|
+
* A small picture at the head of the row (a product's cover). One option
|
|
77
|
+
* with a `thumb` key gives EVERY row the picture column, so a mixed list
|
|
78
|
+
* keeps its columns; `null` draws the empty well. No option with the key, no
|
|
79
|
+
* column.
|
|
80
|
+
*/
|
|
81
|
+
thumb?: string | null;
|
|
82
|
+
/**
|
|
83
|
+
* One quiet fact at the end of the row (a price, a count). It is not part
|
|
84
|
+
* of the option's name: a screen reader does not hear it, and the closed
|
|
85
|
+
* control never shows it.
|
|
86
|
+
*/
|
|
87
|
+
meta?: string;
|
|
59
88
|
}
|
|
60
|
-
|
|
61
|
-
|
|
89
|
+
/**
|
|
90
|
+
* `ariaLabelledBy` / `ariaLabel` name the button AND its open list. Left out,
|
|
91
|
+
* the button is named by its `<label for>` (or by what it shows) and the list
|
|
92
|
+
* by the button, so the list is never without a name.
|
|
93
|
+
*/
|
|
94
|
+
interface FieldSelectBase<V> extends ControlBase {
|
|
62
95
|
options: readonly FieldOption<V>[];
|
|
63
|
-
|
|
64
|
-
/** Shown when the value names no option. */
|
|
96
|
+
/** Shown when the value names no option (when nothing is on, for `multiple`). */
|
|
65
97
|
placeholder?: string;
|
|
98
|
+
/**
|
|
99
|
+
* A search box at the top of the open list. Typing narrows the options by
|
|
100
|
+
* label and the keys walk what is left; a letter goes into the box, so
|
|
101
|
+
* there is no letter jump. A long list (every product in a catalogue).
|
|
102
|
+
*/
|
|
103
|
+
searchable?: boolean;
|
|
104
|
+
/**
|
|
105
|
+
* The search box's hint and name, in the host's own words ("Search your
|
|
106
|
+
* catalog…"). Left out, the catalogue's `fields.search`.
|
|
107
|
+
*/
|
|
108
|
+
searchPlaceholder?: string;
|
|
109
|
+
/** Each group heading says how many of its options are showing. Derived, never passed. */
|
|
110
|
+
groupCount?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* The list opens IN FLOW, pushing the rows below it down, instead of
|
|
113
|
+
* floating. For a list inside a panel that scrolls, where a floating list is
|
|
114
|
+
* clipped by the panel's edge.
|
|
115
|
+
*/
|
|
116
|
+
inline?: boolean;
|
|
117
|
+
/** Draws an option's row in place of its label (each style in its own face). It is still an option. */
|
|
118
|
+
renderOption?: (option: FieldOption<V>, state: {
|
|
119
|
+
active: boolean;
|
|
120
|
+
chosen: boolean;
|
|
121
|
+
}) => ReactNode;
|
|
122
|
+
}
|
|
123
|
+
/** One of a set. */
|
|
124
|
+
interface FieldSelectOneProps<V = unknown> extends FieldSelectBase<V> {
|
|
125
|
+
multiple?: false;
|
|
126
|
+
value: V | undefined;
|
|
127
|
+
onChange: (value: V) => void;
|
|
128
|
+
/** Draws the closed control's value in place of the chosen label. */
|
|
129
|
+
renderValue?: (chosen: FieldOption<V> | undefined) => ReactNode;
|
|
66
130
|
}
|
|
131
|
+
/**
|
|
132
|
+
* Several of a set (`multiple`). The value is a list, saved in the order the
|
|
133
|
+
* OPTIONS come, never in the order they were ticked: two lists that look the
|
|
134
|
+
* same hold the same data. An empty list is an answer, not a missing one.
|
|
135
|
+
*/
|
|
136
|
+
interface FieldSelectManyProps<V = unknown> extends FieldSelectBase<V> {
|
|
137
|
+
multiple: true;
|
|
138
|
+
value: readonly V[] | undefined;
|
|
139
|
+
onChange: (value: V[]) => void;
|
|
140
|
+
/** Draws the closed control's value in place of the labels of what is on. */
|
|
141
|
+
renderValue?: (on: FieldOption<V>[]) => ReactNode;
|
|
142
|
+
}
|
|
143
|
+
type FieldSelectProps<V = unknown> = FieldSelectOneProps<V> | FieldSelectManyProps<V>;
|
|
67
144
|
interface FieldMeta {
|
|
68
145
|
label?: string;
|
|
69
146
|
/** The tab this field opens; inherited by the fields after it (see above). */
|
|
@@ -148,4 +225,4 @@ type FieldRenderer = (props: {
|
|
|
148
225
|
readOnly?: boolean;
|
|
149
226
|
}) => ReactNode;
|
|
150
227
|
|
|
151
|
-
export type { ArrayFieldDef as A, CustomFieldDef as C, FieldRenderer as F, InspectorFields as I, NumberFieldDef as N, ObjectFieldDef as O, RadioFieldDef as R, SelectFieldDef as S, TextFieldDef as T, InspectorFieldDef as a, FieldTextProps as b, FieldNumberProps as c, FieldSliderProps as d,
|
|
228
|
+
export type { ArrayFieldDef as A, CustomFieldDef as C, FieldRenderer as F, InspectorFields as I, NumberFieldDef as N, ObjectFieldDef as O, RadioFieldDef as R, SelectFieldDef as S, TextFieldDef as T, InspectorFieldDef as a, FieldTextProps as b, FieldNumberProps as c, FieldSliderProps as d, FieldSelectManyProps as e, FieldSelectOneProps as f, FieldOption as g, CustomFieldRenderProps as h, FieldSelectProps as i, SlotFieldDef as j, TextareaFieldDef as k };
|
|
@@ -32,15 +32,32 @@ interface WatchOptions {
|
|
|
32
32
|
* `load` — and a measurement taken then measures nothing. For the editor's
|
|
33
33
|
* canvas pass `BLOCK_SELECTOR`. Watched with a MutationObserver on the frame's
|
|
34
34
|
* document, never polled.
|
|
35
|
+
*
|
|
36
|
+
* ⚠️ "Ready" then means "holds a block", so a page with NO blocks is never
|
|
37
|
+
* ready: the frame is not published, and nothing that needs the canvas (the
|
|
38
|
+
* drag layer, a canvas stylesheet, a context menu) works on an empty page —
|
|
39
|
+
* the one page a first block has to be dropped on. An editor whose page can
|
|
40
|
+
* be empty names something the canvas ALWAYS draws instead — a list,
|
|
41
|
+
* `LIST_SELECTOR`: the page's own is there with nothing in it — or leaves
|
|
42
|
+
* this out.
|
|
35
43
|
*/
|
|
36
44
|
readySelector?: string;
|
|
37
45
|
}
|
|
38
46
|
/**
|
|
39
47
|
* Every block the canvas draws carries this attribute. The markup is the one
|
|
40
|
-
* Puck 0.20 drew, kept by the engine's own canvas (`efficient-easel/
|
|
48
|
+
* Puck 0.20 drew, kept by the engine's own canvas (`efficient-easel/easel`)
|
|
41
49
|
* because both apps' canvas CSS and checks read it.
|
|
42
50
|
*/
|
|
43
51
|
declare const BLOCK_SELECTOR = "[data-puck-component]";
|
|
52
|
+
/**
|
|
53
|
+
* Every LIST the canvas draws carries this attribute — the page's own
|
|
54
|
+
* (`root:default-zone`) and each slot's — whether or not there is a block in
|
|
55
|
+
* it. So it is the `readySelector` for an editor whose page may be EMPTY: the
|
|
56
|
+
* canvas of a page with no blocks holds no `BLOCK_SELECTOR` and would never be
|
|
57
|
+
* published, on the one page a first block has to be dropped on (second host,
|
|
58
|
+
* 2026-10-07: it had typed the attribute out by hand to get this).
|
|
59
|
+
*/
|
|
60
|
+
declare const LIST_SELECTOR = "[data-puck-dropzone]";
|
|
44
61
|
/** The canvas frame: Puck 0.20's, and the engine's own `CanvasFrame` since 0.89.0. */
|
|
45
62
|
declare const CANVAS_SELECTOR = "iframe#preview-frame";
|
|
46
63
|
/**
|
|
@@ -57,4 +74,4 @@ declare function isFrameReady(frame: HTMLIFrameElement): boolean;
|
|
|
57
74
|
*/
|
|
58
75
|
declare function watchCanvasFrame(root: Node, onChange: (target: CanvasTarget | null) => void, { selector, readySelector }?: WatchOptions): () => void;
|
|
59
76
|
|
|
60
|
-
export { BLOCK_SELECTOR as B, type CanvasTarget as C, type WatchOptions as W, CANVAS_SELECTOR as a, isFrameReady as i, watchCanvasFrame as w };
|
|
77
|
+
export { BLOCK_SELECTOR as B, type CanvasTarget as C, LIST_SELECTOR as L, type WatchOptions as W, CANVAS_SELECTOR as a, isFrameReady as i, watchCanvasFrame as w };
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* `SettingsSegmented` the host passes its measured `fit`;
|
|
9
9
|
* the top-bar rail `TopBarRail` measures the words in the browser and
|
|
10
|
-
* hands `
|
|
10
|
+
* hands `EaselRail` the result.
|
|
11
11
|
*
|
|
12
12
|
* Both numbers are the width of TEXT ONLY, in the strip's own type, and neither
|
|
13
13
|
* includes any padding, glyph or gap: those are the strip's, and the sheet adds
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The editor frame's own words (`efficient-easel/strings`, 0.95.0), in two
|
|
3
|
-
* groups: what `EditNotice` says (`NoticeWords`) and the
|
|
4
|
-
*
|
|
3
|
+
* groups: what `EditNotice` says (`NoticeWords`) and the words the rest of the
|
|
4
|
+
* chrome carries when the host gives none (`ChromeWords`), the media panel's
|
|
5
|
+
* head among them.
|
|
5
6
|
*
|
|
6
7
|
* A plain module with no import. Anything with a value in it is a function, so
|
|
7
8
|
* a host puts the name, the noun and the time where its language wants them.
|
|
@@ -73,6 +74,34 @@ type ChromeWords = {
|
|
|
73
74
|
}) => string;
|
|
74
75
|
/** `PanelResizeHandle`: the tooltip. */
|
|
75
76
|
resize: string;
|
|
77
|
+
/** `MediaPanelHead`, browsing: the panel's name. */
|
|
78
|
+
mediaLibrary: string;
|
|
79
|
+
/** `MediaPanelHead`, choosing: the panel's name. `kind` is a `mediaKinds` word. */
|
|
80
|
+
mediaChoose: (v: {
|
|
81
|
+
kind: string;
|
|
82
|
+
}) => string;
|
|
83
|
+
/** `MediaPanelHead`, choosing: the line under the name. `field` is the host's label for the field. */
|
|
84
|
+
mediaFor: (v: {
|
|
85
|
+
field: string;
|
|
86
|
+
}) => string;
|
|
87
|
+
/** What a field can hold, as the head says it, by `MediaPickKind`. */
|
|
88
|
+
mediaKinds: {
|
|
89
|
+
image: string;
|
|
90
|
+
video: string;
|
|
91
|
+
svg: string;
|
|
92
|
+
};
|
|
93
|
+
/** `MediaPanelHead`: the word that leaves choosing. */
|
|
94
|
+
mediaCancel: string;
|
|
95
|
+
/** `MediaPanelHead`: Cancel's tooltip. `kind` is a `mediaKinds` word. */
|
|
96
|
+
mediaKeep: (v: {
|
|
97
|
+
kind: string;
|
|
98
|
+
}) => string;
|
|
99
|
+
/** The Hide panel button at the end of a side panel's head: the tooltip. */
|
|
100
|
+
hidePanel: string;
|
|
101
|
+
/** The same button: its accessible name. */
|
|
102
|
+
hidePanelLabel: (v: {
|
|
103
|
+
side: 'left' | 'right';
|
|
104
|
+
}) => string;
|
|
76
105
|
};
|
|
77
106
|
|
|
78
107
|
export type { ChromeWords as C, NoticeWords as N };
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* A plain module with no import, in drag's own folder: drag may reach only its
|
|
7
7
|
* lane (`tests/drag-leaf-safety.test.ts`), so `AddPanel` and `CanvasDragLayer`
|
|
8
8
|
* do NOT read the strings provider. They take their group as `words`, and a
|
|
9
|
-
* host passes `
|
|
9
|
+
* host passes `useEaselStrings().drag.add` / `.drag.canvas`.
|
|
10
10
|
*/
|
|
11
11
|
type DragWords = {
|
|
12
12
|
add: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as SaveTone } from './types-
|
|
1
|
+
import { S as SaveTone } from './types-DGcCsxs8.js';
|
|
2
2
|
|
|
3
3
|
/** Time and timers, passed in so a test can run minutes in a millisecond. */
|
|
4
4
|
type AutosaveClock = {
|
|
@@ -121,7 +121,7 @@ type SaveWords = {
|
|
|
121
121
|
unsaved: string;
|
|
122
122
|
};
|
|
123
123
|
/**
|
|
124
|
-
* `words` is the host's language (`
|
|
124
|
+
* `words` is the host's language (`useEaselStrings().save`); left out, the
|
|
125
125
|
* pill speaks English as it always has.
|
|
126
126
|
*/
|
|
127
127
|
declare function saveIndicator(state: AutosaveSnapshot, words?: SaveWords): SaveIndicator;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { S as SettingsBucket } from './buckets-CuLM47h9.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The settings panel's own words (`efficient-easel/strings`, 0.95.0): what
|
|
5
|
+
* the tab strip is called, what each tab SAYS, and the Default / Reset part.
|
|
6
|
+
*
|
|
7
|
+
* A bucket's key (`'Content'`, `'Style'`, …) is an identifier — fields name
|
|
8
|
+
* their tab with it and `SETTINGS_BUCKETS` orders them — so it never changes
|
|
9
|
+
* with the language. `buckets` is the word drawn for each key.
|
|
10
|
+
*
|
|
11
|
+
* The panel is hook-free, so nothing here is read from the strings provider:
|
|
12
|
+
* `SettingsTabs` takes its name as `ariaLabel` and each tab's word as the
|
|
13
|
+
* item's `label`, and `Inspector` (which has hooks) passes both.
|
|
14
|
+
* `SettingsDefaultReset` takes `words`, and a host passes the four from
|
|
15
|
+
* `useWords('panel', …)`.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
type PanelWords = {
|
|
19
|
+
/** The tab strip's accessible name. */
|
|
20
|
+
settings: string;
|
|
21
|
+
/** The word each tab shows, by its key. */
|
|
22
|
+
buckets: Record<SettingsBucket, string>;
|
|
23
|
+
/** `SettingsDefaultReset`, resting: the value follows its default. */
|
|
24
|
+
followsDefault: string;
|
|
25
|
+
/** `SettingsDefaultReset`, changed: the button that clears the value. */
|
|
26
|
+
reset: string;
|
|
27
|
+
/** The Reset button's accessible name — which setting it resets. */
|
|
28
|
+
resetName: (p: {
|
|
29
|
+
label: string;
|
|
30
|
+
}) => string;
|
|
31
|
+
/** The Reset button's tooltip, when the host says what the default is. */
|
|
32
|
+
backToDefault: (p: {
|
|
33
|
+
detail: string;
|
|
34
|
+
}) => string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export type { PanelWords as P };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The text-styles list's own words (`efficient-easel/strings`, plan step E6).
|
|
3
|
+
* A style's NAME is the host's data ("Heading 1" is stored); `styleName` is
|
|
4
|
+
* only how a NEW one is named. The fonts' and theme colours' names are the
|
|
5
|
+
* host's too.
|
|
6
|
+
*
|
|
7
|
+
* A plain module with no import. The English is the design's own (both pages,
|
|
8
|
+
* final 2026-10-06): "Body", never "Paragraph" (N10.1); US spelling, "Color".
|
|
9
|
+
*/
|
|
10
|
+
type TextStylesWords = {
|
|
11
|
+
/** The two group headings, in the order they are drawn. */
|
|
12
|
+
groups: {
|
|
13
|
+
heading: string;
|
|
14
|
+
body: string;
|
|
15
|
+
};
|
|
16
|
+
/** The button under each group. */
|
|
17
|
+
add: {
|
|
18
|
+
heading: string;
|
|
19
|
+
body: string;
|
|
20
|
+
};
|
|
21
|
+
/** Beside the button: how many there are of the most allowed. */
|
|
22
|
+
count: (v: {
|
|
23
|
+
n: number;
|
|
24
|
+
max: number;
|
|
25
|
+
}) => string;
|
|
26
|
+
/** The button's tooltip once the group is full. */
|
|
27
|
+
full: (v: {
|
|
28
|
+
kind: 'heading' | 'body';
|
|
29
|
+
max: number;
|
|
30
|
+
}) => string;
|
|
31
|
+
/** A new style's name. `n` counts from 1 within its kind. */
|
|
32
|
+
styleName: (v: {
|
|
33
|
+
kind: 'heading' | 'body';
|
|
34
|
+
n: number;
|
|
35
|
+
}) => string;
|
|
36
|
+
/** Delete's tooltip: the same word as the Layers delete and the node menu. */
|
|
37
|
+
remove: string;
|
|
38
|
+
/** Delete's accessible name. `name` is the style's: "Heading 4". */
|
|
39
|
+
removeNamed: (v: {
|
|
40
|
+
name: string;
|
|
41
|
+
}) => string;
|
|
42
|
+
/** The line an open style's preview is drawn in, unless the host gives its own. */
|
|
43
|
+
sample: string;
|
|
44
|
+
/** The preview's accessible name. */
|
|
45
|
+
preview: string;
|
|
46
|
+
/** A row's grey line. Each part is already words: "16 px", "Auto", "Regular". */
|
|
47
|
+
summary: (v: {
|
|
48
|
+
font: string;
|
|
49
|
+
size: string;
|
|
50
|
+
weight: string;
|
|
51
|
+
}) => string;
|
|
52
|
+
/** A size in the grey line. */
|
|
53
|
+
px: (v: {
|
|
54
|
+
n: number;
|
|
55
|
+
}) => string;
|
|
56
|
+
/** No number of its own: each section draws its own. */
|
|
57
|
+
auto: string;
|
|
58
|
+
/** A weight's name, by the hundred it is nearest. */
|
|
59
|
+
weights: {
|
|
60
|
+
thin: string;
|
|
61
|
+
extraLight: string;
|
|
62
|
+
light: string;
|
|
63
|
+
regular: string;
|
|
64
|
+
medium: string;
|
|
65
|
+
semibold: string;
|
|
66
|
+
bold: string;
|
|
67
|
+
extraBold: string;
|
|
68
|
+
black: string;
|
|
69
|
+
};
|
|
70
|
+
/** Each setting's name in an open style. */
|
|
71
|
+
settings: {
|
|
72
|
+
font: string;
|
|
73
|
+
color: string;
|
|
74
|
+
size: string;
|
|
75
|
+
weight: string;
|
|
76
|
+
/** The B · I row (Site styles). */
|
|
77
|
+
emphasis: string;
|
|
78
|
+
lineSpacing: string;
|
|
79
|
+
letterSpacing: string;
|
|
80
|
+
paragraphSpacing: string;
|
|
81
|
+
letterCase: string;
|
|
82
|
+
largestSize: string;
|
|
83
|
+
};
|
|
84
|
+
bold: string;
|
|
85
|
+
italic: string;
|
|
86
|
+
/** The Italic button's tooltip when the font has no italic. */
|
|
87
|
+
italicMissing: string;
|
|
88
|
+
/** Letter case's buttons. */
|
|
89
|
+
case: {
|
|
90
|
+
auto: string;
|
|
91
|
+
autoTitle: string;
|
|
92
|
+
none: string;
|
|
93
|
+
upper: string;
|
|
94
|
+
lower: string;
|
|
95
|
+
};
|
|
96
|
+
colour: {
|
|
97
|
+
/** The rainbow swatch at the end of the theme's colours. */
|
|
98
|
+
any: string;
|
|
99
|
+
/** What the Color row reads while the style has no colour of its own. */
|
|
100
|
+
follows: string;
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
declare const DEFAULT_TEXT_STYLES_WORDS: TextStylesWords;
|
|
104
|
+
|
|
105
|
+
export { DEFAULT_TEXT_STYLES_WORDS as D, type TextStylesWords as T };
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* A plain module with no import. The style clipboard imports React's JSX
|
|
7
7
|
* runtime and nothing else (`tests/style-clipboard-leaf-safety.test.ts`), so it
|
|
8
8
|
* reads no provider: `styleMenuItems` and `pasteMessage` take these as an
|
|
9
|
-
* argument, and a host passes `
|
|
9
|
+
* argument, and a host passes `useEaselStrings().styleClipboard`.
|
|
10
10
|
*/
|
|
11
11
|
type StyleClipboardWords = {
|
|
12
12
|
/** The Copy style row. */
|
|
@@ -13,6 +13,10 @@ type FieldsWords = {
|
|
|
13
13
|
more: string;
|
|
14
14
|
/** `FieldSelect`: what the box says while nothing is chosen. */
|
|
15
15
|
choose: string;
|
|
16
|
+
/** `FieldSelect` with `searchable`: the search box's hint and name. Optional: a host's older catalogue falls back to the English. */
|
|
17
|
+
search?: string;
|
|
18
|
+
/** `FieldSelect` with `searchable`: what the list says when nothing matches. */
|
|
19
|
+
noMatches?: string;
|
|
16
20
|
/** `ListField` — an array field drawn as rows. */
|
|
17
21
|
list: {
|
|
18
22
|
/** One item's word when the field names none. */
|