efficient-easel 0.106.0 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -29
- package/dist/{LinkPicker-W2Rtxetz.d.ts → LinkPicker-hPEr1MJx.d.ts} +6 -4
- package/dist/autosave/index.d.ts +5 -5
- package/dist/chrome/chrome.css +50 -273
- package/dist/chrome/index.d.ts +61 -56
- package/dist/chrome/index.js +1 -1
- package/dist/chunk-4GNPKHV4.js +64 -0
- package/dist/chunk-5545A3PC.js +4 -0
- package/dist/chunk-7SQF6LZL.js +1 -0
- package/dist/chunk-BXMXTO36.js +1 -0
- package/dist/{chunk-JWMNPRTT.js → chunk-CKEPQNSQ.js} +1 -1
- package/dist/{chunk-LY4K2ECT.js → chunk-DJMMTWFP.js} +1 -1
- package/dist/chunk-EA2HTX37.js +5 -0
- package/dist/{chunk-VINYARYJ.js → chunk-FEK3S6HN.js} +1 -1
- package/dist/chunk-FPAVNX3Y.js +6 -0
- package/dist/chunk-HMJS344F.js +1 -0
- package/dist/chunk-JLTZQ4US.js +1 -0
- package/dist/chunk-JMGPPXNQ.js +24 -0
- package/dist/chunk-K56YDHYQ.js +1 -0
- package/dist/chunk-LOMEH6DG.js +1 -0
- package/dist/{chunk-FS5BLARH.js → chunk-MAEXP3KE.js} +1 -1
- package/dist/chunk-MJM6SFD3.js +3 -0
- package/dist/chunk-NLRW4BGG.js +8 -0
- package/dist/chunk-OJAJVH7S.js +5 -0
- package/dist/chunk-ONRYLR2D.js +2 -0
- package/dist/{chunk-WTMHT7BI.js → chunk-ORR3Q4WV.js} +1 -1
- package/dist/chunk-OTEXGJDU.js +5 -0
- package/dist/chunk-P2VEMZH5.js +1 -0
- package/dist/{chunk-MHKBLPQ2.js → chunk-PT6V53OO.js} +1 -1
- package/dist/{chunk-6WH7FA2M.js → chunk-PYCLHOSA.js} +2 -2
- package/dist/chunk-Q27BB5ZC.js +14 -0
- package/dist/chunk-QLD57GBB.js +6 -0
- package/dist/{chunk-PBSEUZD6.js → chunk-QMNML7XH.js} +1 -1
- package/dist/chunk-QR4DLZ3P.js +5 -0
- package/dist/chunk-TJ7YIRWQ.js +21 -0
- package/dist/{chunk-3P6AMTOS.js → chunk-VPFNZ7TB.js} +1 -1
- package/dist/chunk-W3XX2CNW.js +16 -0
- package/dist/chunk-X6DQWK2C.js +1 -0
- package/dist/chunk-XWR5YVA7.js +9 -0
- package/dist/chunk-YABL4EWX.js +7 -0
- package/dist/chunk-ZNNATBDC.js +1 -0
- package/dist/chunk-ZP4G3X44.js +4 -0
- package/dist/copy/copy.css +66 -177
- package/dist/copy/index.d.ts +0 -2
- package/dist/copy/index.js +31 -32
- package/dist/drag/drag.css +31 -11
- package/dist/drag/index.js +1 -1
- package/dist/easel/index.js +1 -1
- package/dist/fields/fields.css +35 -304
- package/dist/fields/index.d.ts +87 -95
- package/dist/fields/index.js +1 -1
- package/dist/gold/gold.css +3 -3
- package/dist/gold/index.d.ts +6 -5
- package/dist/gold/index.js +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/menu/index.d.ts +49 -93
- package/dist/menu/index.js +1 -1
- package/dist/menu/menu.css +37 -246
- package/dist/node-ops/index.d.ts +1 -1
- package/dist/panel/index.d.ts +46 -72
- package/dist/panel/index.js +17 -18
- package/dist/panel/panel.css +143 -372
- package/dist/pick/index.d.ts +52 -33
- package/dist/pick/index.js +7 -7
- package/dist/pick/pick.css +19 -150
- package/dist/rail/index.d.ts +48 -90
- package/dist/rail/index.js +1 -1
- package/dist/rail/rail.css +21 -108
- package/dist/screen/components/AddBlockRow.d.ts +8 -2
- package/dist/screen/components/AddBlockRow.js +1 -1
- package/dist/screen/components/AddChildRow.d.ts +4 -3
- package/dist/screen/components/AddChildRow.js +1 -1
- package/dist/screen/components/AddSidePanel.js +1 -1
- package/dist/screen/components/MediaSidePanel.d.ts +1 -1
- package/dist/screen/components/MediaSidePanel.js +1 -1
- package/dist/screen/components/NodeContextMenu.d.ts +12 -8
- package/dist/screen/components/NodeContextMenu.js +1 -1
- package/dist/screen/components/PageEditGuardNotices.js +1 -1
- package/dist/screen/components/ScreenChrome.js +1 -1
- package/dist/screen/components/ScreenDocumentContext.d.ts +1 -1
- package/dist/screen/components/ScreenDocumentContext.js +1 -1
- package/dist/screen/components/ScreenMount.d.ts +7 -7
- package/dist/screen/components/ScreenMount.js +1 -1
- package/dist/screen/components/ScreenStoreProvider.d.ts +7 -7
- package/dist/screen/components/ScreenStoreProvider.js +1 -1
- package/dist/screen/components/SectionScreenShell.js +16 -16
- package/dist/screen/components/SidePanelHead.d.ts +4 -2
- package/dist/screen/components/SidePanelHead.js +1 -1
- package/dist/screen/components/UiIcon.d.ts +10 -26
- package/dist/screen/components/UiIcon.js +2 -1
- package/dist/screen/components/panel-widths.js +1 -1
- package/dist/screen/components/usePartBridge.d.ts +7 -7
- package/dist/screen/components/usePartBridge.js +1 -1
- package/dist/screen/index.d.ts +7 -7
- package/dist/screen/index.js +1 -1
- package/dist/screen/lib/admin-bridge.d.ts +1 -1
- package/dist/screen/lib/admin-bridge.js +1 -1
- package/dist/screen/lib/chrome-theme.d.ts +20 -12
- package/dist/screen/lib/chrome-theme.js +1 -1
- package/dist/screen/lib/document-addressing.d.ts +1 -1
- package/dist/screen/lib/host-chrome.d.ts +1 -1
- package/dist/screen/lib/host.d.ts +1 -1
- package/dist/screen/lib/key-scope.js +1 -1
- package/dist/screen/lib/links/link-filters.d.ts +1 -1
- package/dist/screen/lib/media-panel.d.ts +1 -1
- package/dist/screen/lib/media-picker.d.ts +1 -1
- package/dist/screen/lib/page-lock.d.ts +1 -1
- package/dist/screen/lib/puck/style-clipboard.d.ts +7 -7
- package/dist/screen/lib/puck/use-section-ops.js +1 -1
- package/dist/screen/lib/screen-parts.d.ts +9 -8
- package/dist/screen/lib/screen-parts.js +1 -1
- package/dist/screen/lib/section-templates.d.ts +1 -1
- package/dist/screen/lib/session-context.d.ts +1 -1
- package/dist/screen/lib/session.d.ts +1 -1
- package/dist/screen/screen.css +33 -206
- package/dist/shell/index.d.ts +134 -118
- package/dist/shell/index.js +1 -1
- package/dist/shell/shell.css +130 -88
- package/dist/strings/catalogue.d.ts +5 -5
- package/dist/strings/catalogue.js +1 -1
- package/dist/strings/index.d.ts +5 -5
- package/dist/strings/index.js +1 -1
- package/dist/style-clipboard/index.d.ts +1 -1
- package/dist/text-styles/index.d.ts +12 -3
- package/dist/text-styles/index.js +33 -38
- package/dist/text-styles/text-styles.css +39 -71
- package/dist/tree/index.d.ts +49 -44
- package/dist/tree/index.js +1 -1
- package/dist/tree/tree.css +31 -653
- package/dist/{types-DJDBtdB2.d.ts → types-BqGnUVX5.d.ts} +32 -32
- package/dist/types-BsyPh6EW.d.ts +99 -0
- package/dist/{types-DWS-s9z-.d.ts → types-CsgMwHHa.d.ts} +14 -11
- package/dist/{types-CqY85foL.d.ts → types-Dt1CFR1S.d.ts} +4 -2
- package/dist/{wordFit-D4S36PvB.d.ts → wordFit-7XpmhcaW.d.ts} +3 -5
- package/dist/words-Cl9xMUYY.d.ts +41 -0
- package/dist/{words-D_Lnw1Gr.d.ts → words-CvFnwGSr.d.ts} +1 -1
- package/package.json +5 -1
- package/dist/chunk-2UX75JDP.js +0 -1
- package/dist/chunk-37OCQYNX.js +0 -65
- package/dist/chunk-3EDSDPIP.js +0 -1
- package/dist/chunk-3QVB4AG2.js +0 -3
- package/dist/chunk-3WSPDAK2.js +0 -1
- package/dist/chunk-5MZ3RNQQ.js +0 -13
- package/dist/chunk-5ZBBXZPV.js +0 -6
- package/dist/chunk-BZ5ASXOL.js +0 -1
- package/dist/chunk-C6BJB5AC.js +0 -2
- package/dist/chunk-DX4XELD6.js +0 -18
- package/dist/chunk-EOJNJCMJ.js +0 -16
- package/dist/chunk-EWVJSRRY.js +0 -6
- package/dist/chunk-H24N5TMZ.js +0 -11
- package/dist/chunk-I6T4TZ5Q.js +0 -8
- package/dist/chunk-KTVH2ZRL.js +0 -15
- package/dist/chunk-M7N2V4TG.js +0 -2
- package/dist/chunk-MS4QRBJ6.js +0 -5
- package/dist/chunk-ND55LTCA.js +0 -5
- package/dist/chunk-OWBO4WKA.js +0 -0
- package/dist/chunk-P6O363EE.js +0 -6
- package/dist/chunk-RW4XBUUW.js +0 -1
- package/dist/chunk-UEVTQBM7.js +0 -10
- package/dist/chunk-VCQVNPTG.js +0 -22
- package/dist/chunk-WZ7TGAAT.js +0 -3
- package/dist/chunk-YC4TB3CJ.js +0 -25
- package/dist/chunk-Z6SOLDWV.js +0 -1
- package/dist/chunk-ZFDCDJNZ.js +0 -16
- package/dist/chunk-ZNS7727Y.js +0 -12
- package/dist/types-Djdq6Xkd.d.ts +0 -138
- package/dist/words-DgHcY5qB.d.ts +0 -33
package/README.md
CHANGED
|
@@ -16,6 +16,45 @@ it since 0.93.0.
|
|
|
16
16
|
> Moving from the old name without touching an import:
|
|
17
17
|
> `"efficient-editor": "npm:efficient-easel@^0.96.0"`.
|
|
18
18
|
|
|
19
|
+
## The shell first — efficient-shell is a peer (UI-24)
|
|
20
|
+
|
|
21
|
+
Harness UI-24 (efficient-harness#117, 2026-10-10): every surface a person
|
|
22
|
+
operates takes its UI from `efficient-shell`. So `efficient-shell` (`^4.163.0`)
|
|
23
|
+
is a **peer dependency**, and every colour, radius and the typeface in easel's
|
|
24
|
+
sheets is an alias of a shell token (`--es-surface`… is `var(--surface)`, the
|
|
25
|
+
accent is the shell's, and so on — `src/shell/shell.css` lists them all).
|
|
26
|
+
|
|
27
|
+
**A host loads the shell's CSS before any easel sheet**, or nothing resolves —
|
|
28
|
+
there are no hex fallbacks, because a fallback is a second palette:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import 'efficient-shell/ui.css'; // or 'efficient-shell/styles.css' — exactly one
|
|
32
|
+
import 'efficient-easel/shell.css'; // then easel's sheets
|
|
33
|
+
import 'efficient-easel/screen.css'; // …
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The shell's `ui.css` is a Tailwind v4 input (its radii and face are declared in
|
|
37
|
+
`@theme default`), so it goes through the host's Tailwind build like every
|
|
38
|
+
portal's. The editor chrome then **follows the shell's theme, dark included**:
|
|
39
|
+
the shell stamps `data-theme="dark"` (or `.dark`) on `<html>` and easel's tokens
|
|
40
|
+
follow. The editor no longer pins itself light (`data-editor-theme` is gone;
|
|
41
|
+
`applyEaselChromeTheme` stamps the bridged theme as `data-theme`). The canvas is
|
|
42
|
+
output and keeps the document's own colours in every theme.
|
|
43
|
+
|
|
44
|
+
Since 1.0 (efficient-easel#199 step 4, part A) the editor's buttons, icon
|
|
45
|
+
buttons, switches, segmented controls, tabs, text and number boxes, the Add
|
|
46
|
+
block menu, the leave prompt, the toast and every explanation are
|
|
47
|
+
efficient-shell's components (`efficient-shell/ui`): they draw in the shell's
|
|
48
|
+
Tailwind classes, which **the host's Tailwind compiles from the shell's dist**
|
|
49
|
+
(the `@source` lines in its `ui.css`). Easel itself emits no Tailwind class.
|
|
50
|
+
The exported names hosts import (`EaselIconButton`, `SettingsSwitch`,
|
|
51
|
+
`SettingsSegmented`, `SettingsTabs`, `FieldText`, `FieldNumber`, …) stay, as
|
|
52
|
+
thin wrappers with the props they had.
|
|
53
|
+
|
|
54
|
+
`tests/own-ui-ratchet.test.ts` lists what easel still draws itself: since
|
|
55
|
+
1.0.0 no primitive is left on it (`OWN_PRIMITIVES` is empty), and its counts —
|
|
56
|
+
explanatory `title=`, raw colours — only go down.
|
|
57
|
+
|
|
19
58
|
## Why
|
|
20
59
|
|
|
21
60
|
The storefront editor (`efficient-storefront`, Next 16 + Puck) and the campaign
|
|
@@ -114,33 +153,32 @@ exported too, for bespoke layouts.
|
|
|
114
153
|
|
|
115
154
|
## Tokens
|
|
116
155
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
156
|
+
Since 1.0.0 the buttons are efficient-shell's `IconRailButton` (its look,
|
|
157
|
+
hover, active, focus and `Tooltip`), inside the shell's `IconRail` (its one
|
|
158
|
+
tab stop and arrow keys). What the tokens still describe is the rail's
|
|
159
|
+
CONTAINER and a measured row's words, the same values two ways — `railTokens`
|
|
160
|
+
(JS) and `rail.css` (CSS custom properties on `.es-rail`):
|
|
120
161
|
|
|
121
162
|
| token | value | CSS var |
|
|
122
163
|
|---|---|---|
|
|
123
164
|
| rail width | `46px` | `--es-rail-w` |
|
|
124
165
|
| rail padding (y) | `8px` | `--es-rail-pad-y` |
|
|
125
166
|
| button gap | `4px` | `--es-rail-gap` |
|
|
126
|
-
| rail radius | `
|
|
127
|
-
| button size | `
|
|
128
|
-
| button radius | `9px` | `--es-rail-btn-radius` |
|
|
167
|
+
| rail radius | `var(--radius-xl)` (12px) | `--es-rail-radius` |
|
|
168
|
+
| button size | `36px` (the shell's) | `--es-rail-btn-size` |
|
|
129
169
|
| icon size | `18px` | `--es-rail-icon-size` |
|
|
130
|
-
| background |
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
170
|
+
| background | `var(--surface)` | `--es-rail-bg` |
|
|
171
|
+
|
|
172
|
+
The button colour tokens (`idle`, `hoverBg`, `hoverFg`, `accent`,
|
|
173
|
+
`accentTint`, `--es-rail-fg`, `--es-rail-hover-*`, `--es-rail-accent*`), the
|
|
174
|
+
button radius and `transition` / `disabledOpacity` were removed in 1.0.0: the
|
|
175
|
+
shell draws the button.
|
|
135
176
|
|
|
136
177
|
`orientation="row"` adds **no new token**. It re-points three of the ones above
|
|
137
178
|
— `--es-rail-bg` to `transparent`, `--es-rail-shadow` to `none`,
|
|
138
179
|
`--es-rail-radius` to `0` — so the card look stays declared in one place, and it
|
|
139
180
|
reuses `--es-rail-pad-y` rotated onto the row's ends and `--es-rail-gap` as-is.
|
|
140
181
|
|
|
141
|
-
Re-theme without new CSS by overriding a var on the element:
|
|
142
|
-
`style={{ ['--es-rail-accent']: brand }}`.
|
|
143
|
-
|
|
144
182
|
## The gold layer — type in place
|
|
145
183
|
|
|
146
184
|
`GoldTextInput` (subpath `efficient-easel/gold`, added in 0.3.0) is the surface a
|
|
@@ -315,7 +353,7 @@ import 'efficient-easel/chrome.css'; // once, after shell.css
|
|
|
315
353
|
</TopBarCluster>
|
|
316
354
|
<TopBarCluster kind="right">
|
|
317
355
|
<SaveState tone="saved" label="" />
|
|
318
|
-
<
|
|
356
|
+
<Button variant="primary">Done</Button>{/* efficient-shell/ui */}
|
|
319
357
|
</TopBarCluster>
|
|
320
358
|
</EaselTopBar>
|
|
321
359
|
…
|
|
@@ -891,25 +929,28 @@ A host built only from the parts, audited with axe-core in a real Chromium.
|
|
|
891
929
|
What follows is how the parts answer it; `scripts/second-host-clickthrough.mjs`
|
|
892
930
|
runs the same rules (`--axe <axe.min.js>`).
|
|
893
931
|
|
|
894
|
-
- **The right-click menu
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
932
|
+
- **The right-click menu is the shell's `ContextMenu` (since 1.0.0).** It is
|
|
933
|
+
portalled to `<body>` by the shell and kept inside the shell window that
|
|
934
|
+
holds what was right-clicked (pass it as `owner`). It is only ever a
|
|
935
|
+
`role="menu"`, never wrapped in a region or a dialog to satisfy axe's
|
|
936
|
+
`region`: a menu is neither. `menuPortalTarget`, `ES_MENU_SKIN` and the
|
|
937
|
+
`portalTo` / `skin` / `maxHeight` behaviour are gone (the props are
|
|
938
|
+
accepted and ignored):
|
|
899
939
|
|
|
900
940
|
```tsx
|
|
901
|
-
import { EaselContextMenu
|
|
941
|
+
import { EaselContextMenu } from 'efficient-easel/menu';
|
|
902
942
|
|
|
903
|
-
<EaselContextMenu
|
|
943
|
+
<EaselContextMenu x={e.clientX} y={e.clientY} owner={e.currentTarget} items={items} onClose={close} />
|
|
904
944
|
```
|
|
905
945
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
946
|
+
Or the shell's own pieces, with the editors' item list as the rows:
|
|
947
|
+
|
|
948
|
+
```tsx
|
|
949
|
+
import { ContextMenu, useContextMenu } from 'efficient-shell/ui';
|
|
950
|
+
import { EaselMenuItems } from 'efficient-easel/menu';
|
|
951
|
+
|
|
952
|
+
{menu.state && <ContextMenu {...menu.props}><EaselMenuItems items={items} onClose={menu.close} /></ContextMenu>}
|
|
953
|
+
```
|
|
913
954
|
- **A dropdown's open list has a name.** In a settings row
|
|
914
955
|
(`InspectorField`) the list is `aria-labelledby` the row's own label. A
|
|
915
956
|
`FieldSelect` on its own is named by `ariaLabelledBy` or `ariaLabel`, and
|
|
@@ -101,10 +101,12 @@ type LinkPickerProps = {
|
|
|
101
101
|
* filter or value the host no longer offers is shown as "(unavailable)" and
|
|
102
102
|
* kept, never silently replaced.
|
|
103
103
|
*
|
|
104
|
-
* Every
|
|
105
|
-
* under one heading per page (`
|
|
106
|
-
*
|
|
107
|
-
* at every
|
|
104
|
+
* Every box is the shell's (harness UI-24, efficient-easel#199): `Select`
|
|
105
|
+
* for a list — the anchors under one heading per page (`SelectOptionGroup`) —
|
|
106
|
+
* `SearchableSelect` for a long one, and `Input` for a typed address; never
|
|
107
|
+
* the browser's `<select>`. The boxes stack, one under the next, at every
|
|
108
|
+
* panel width. A long list of anchors names each one's page as its quiet
|
|
109
|
+
* second line: the shell's `SearchableSelect` takes no groups.
|
|
108
110
|
*/
|
|
109
111
|
declare function LinkPicker({ value, onChange, kinds, rules, filtersFor, label, readOnly }: LinkPickerProps): react.JSX.Element | null;
|
|
110
112
|
|
package/dist/autosave/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { a as Autosave, A as AutosaveSnapshot, b as AutosaveOptions } from '../engine-DBxp_v6B.js';
|
|
2
2
|
export { c as AutosaveClock, d as createAutosave } from '../engine-DBxp_v6B.js';
|
|
3
|
-
import { a as SaveIndicator } from '../words-
|
|
4
|
-
export { S as SaveWords, s as saveIndicator } from '../words-
|
|
5
|
-
import '../types-
|
|
6
|
-
import '../types-
|
|
7
|
-
import '../wordFit-
|
|
3
|
+
import { a as SaveIndicator } from '../words-CvFnwGSr.js';
|
|
4
|
+
export { S as SaveWords, s as saveIndicator } from '../words-CvFnwGSr.js';
|
|
5
|
+
import '../types-Dt1CFR1S.js';
|
|
6
|
+
import '../types-CsgMwHHa.js';
|
|
7
|
+
import '../wordFit-7XpmhcaW.js';
|
|
8
8
|
import 'react';
|
|
9
9
|
import '../edit-lock/index.js';
|
|
10
10
|
import '../panelWidths-D9hTLR25.js';
|
package/dist/chrome/chrome.css
CHANGED
|
@@ -20,7 +20,9 @@
|
|
|
20
20
|
* at the read, not a declaration on a root: a host may set the variables on an
|
|
21
21
|
* ancestor of its own, and a default declared lower down would shadow them.
|
|
22
22
|
*
|
|
23
|
-
*
|
|
23
|
+
* It follows the shell's theme, dark included (UI-24, efficient-harness#117):
|
|
24
|
+
* every colour is an `--es-*` token, and those resolve to efficient-shell's.
|
|
25
|
+
* The 2026-08-06 "light only" ruling is reversed.
|
|
24
26
|
*/
|
|
25
27
|
|
|
26
28
|
/* ── Top bar ─────────────────────────────────────────────────────────────── */
|
|
@@ -93,130 +95,31 @@
|
|
|
93
95
|
margin: 0 4px;
|
|
94
96
|
}
|
|
95
97
|
|
|
96
|
-
/* ── Icon buttons
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
cursor: pointer;
|
|
104
|
-
color: var(--es-icon);
|
|
105
|
-
display: flex;
|
|
106
|
-
align-items: center;
|
|
107
|
-
justify-content: center;
|
|
108
|
-
padding: 0;
|
|
109
|
-
transition: background 0.12s, color 0.12s;
|
|
110
|
-
text-decoration: none;
|
|
111
|
-
}
|
|
112
|
-
.es-iconbtn:hover:not(:disabled) {
|
|
113
|
-
background: var(--es-hover);
|
|
114
|
-
}
|
|
115
|
-
.es-iconbtn:disabled {
|
|
116
|
-
color: var(--es-disabled);
|
|
117
|
-
cursor: default;
|
|
118
|
-
}
|
|
119
|
-
.es-iconbtn--active {
|
|
120
|
-
color: var(--es-text-strong);
|
|
121
|
-
}
|
|
122
|
-
.es-iconbtn--inactive {
|
|
123
|
-
color: var(--es-disabled);
|
|
124
|
-
}
|
|
125
|
-
.es-iconbtn svg {
|
|
98
|
+
/* ── Icon buttons, the device switch and the bar's buttons ──────────────── */
|
|
99
|
+
/* The shell's IconButton, Segmented and Button since efficient-easel issue 199 step 4
|
|
100
|
+
(harness UI-24): their look is the shell's, never redrawn here — a toggle's
|
|
101
|
+
pressed look included (`aria-pressed`, efficient-shell 4.164.0). What stays
|
|
102
|
+
is the glyph size inside. */
|
|
103
|
+
.es-iconbtn svg,
|
|
104
|
+
.es-insp-iconbtn svg {
|
|
126
105
|
width: 16px;
|
|
127
106
|
height: 16px;
|
|
128
107
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
.es-devseg {
|
|
132
|
-
display: flex;
|
|
133
|
-
align-items: center;
|
|
134
|
-
gap: 2px;
|
|
135
|
-
background: var(--es-track-bg);
|
|
136
|
-
border-radius: 9px;
|
|
137
|
-
padding: 2px;
|
|
138
|
-
}
|
|
139
|
-
.es-devseg button {
|
|
140
|
-
width: 30px;
|
|
141
|
-
height: 26px;
|
|
142
|
-
border: none;
|
|
143
|
-
background: transparent;
|
|
144
|
-
border-radius: 6px;
|
|
145
|
-
cursor: pointer;
|
|
146
|
-
color: var(--es-icon);
|
|
147
|
-
display: flex;
|
|
148
|
-
align-items: center;
|
|
149
|
-
justify-content: center;
|
|
150
|
-
padding: 0;
|
|
151
|
-
transition: background 0.12s, color 0.12s, box-shadow 0.12s;
|
|
152
|
-
}
|
|
153
|
-
.es-devseg button.is-active {
|
|
154
|
-
background: var(--es-raised);
|
|
155
|
-
color: var(--es-text-strong);
|
|
156
|
-
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.14);
|
|
108
|
+
.es-devseg-glyph {
|
|
109
|
+
display: inline-flex;
|
|
157
110
|
}
|
|
158
|
-
.es-devseg
|
|
111
|
+
.es-devseg-glyph svg {
|
|
159
112
|
width: 15px;
|
|
160
113
|
height: 15px;
|
|
161
114
|
}
|
|
162
115
|
|
|
163
|
-
/* ── Top-bar buttons ─────────────────────────────────────────────────────── */
|
|
164
|
-
.es-btn-ghost {
|
|
165
|
-
display: flex;
|
|
166
|
-
align-items: center;
|
|
167
|
-
gap: 8px;
|
|
168
|
-
padding: 8px 12px;
|
|
169
|
-
border: 1px solid var(--es-btn-border);
|
|
170
|
-
background: var(--es-panel);
|
|
171
|
-
border-radius: 8px;
|
|
172
|
-
cursor: pointer;
|
|
173
|
-
font: inherit;
|
|
174
|
-
font-size: 13px;
|
|
175
|
-
font-weight: 500;
|
|
176
|
-
color: var(--es-btn-text);
|
|
177
|
-
white-space: nowrap;
|
|
178
|
-
transition: background 0.12s;
|
|
179
|
-
text-decoration: none;
|
|
180
|
-
}
|
|
181
|
-
.es-btn-ghost:hover:not(:disabled) {
|
|
182
|
-
background: var(--es-hover);
|
|
183
|
-
}
|
|
184
|
-
.es-btn-ghost:disabled {
|
|
185
|
-
color: var(--es-disabled);
|
|
186
|
-
border-color: var(--es-btn-border);
|
|
187
|
-
background: var(--es-panel);
|
|
188
|
-
cursor: default;
|
|
189
|
-
}
|
|
190
|
-
.es-btn-ghost:focus-visible {
|
|
191
|
-
outline: 2px solid var(--es-accent);
|
|
192
|
-
outline-offset: 2px;
|
|
193
|
-
}
|
|
194
|
-
/* The ONE primary button in the bar (Publish on the website). */
|
|
195
|
-
.es-btn-primary {
|
|
196
|
-
padding: 8px 16px;
|
|
197
|
-
border: none;
|
|
198
|
-
background: var(--es-accent);
|
|
199
|
-
border-radius: 8px;
|
|
200
|
-
cursor: pointer;
|
|
201
|
-
font: inherit;
|
|
202
|
-
font-size: 13px;
|
|
203
|
-
font-weight: 600;
|
|
204
|
-
color: var(--es-on-accent);
|
|
205
|
-
white-space: nowrap;
|
|
206
|
-
box-shadow: 0 1px 2px var(--es-accent-shadow);
|
|
207
|
-
transition: filter 0.12s;
|
|
208
|
-
}
|
|
209
|
-
.es-btn-primary:hover {
|
|
210
|
-
filter: brightness(1.06);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
116
|
/* ── Save pill ───────────────────────────────────────────────────────────── */
|
|
214
117
|
.es-savestate {
|
|
215
118
|
display: inline-flex;
|
|
216
119
|
align-items: center;
|
|
217
120
|
gap: 8px;
|
|
218
121
|
padding: 4px 12px;
|
|
219
|
-
border-radius:
|
|
122
|
+
border-radius: var(--radius-lg);
|
|
220
123
|
font-size: 12px;
|
|
221
124
|
font-weight: 500;
|
|
222
125
|
white-space: nowrap;
|
|
@@ -248,26 +151,13 @@
|
|
|
248
151
|
.es-savestate.is-error {
|
|
249
152
|
color: var(--es-danger);
|
|
250
153
|
}
|
|
154
|
+
/* The autosave switch (the shell's Switch) with the pill as its label. */
|
|
251
155
|
.es-savestate-toggle {
|
|
252
|
-
|
|
253
|
-
-
|
|
254
|
-
border: 0;
|
|
255
|
-
background: none;
|
|
256
|
-
padding: 0;
|
|
257
|
-
margin: 0;
|
|
258
|
-
font: inherit;
|
|
259
|
-
cursor: pointer;
|
|
260
|
-
border-radius: 8px;
|
|
261
|
-
}
|
|
262
|
-
.es-savestate-toggle:focus-visible {
|
|
263
|
-
outline: none;
|
|
264
|
-
box-shadow: 0 0 0 2px var(--es-accent-shadow);
|
|
265
|
-
}
|
|
266
|
-
.es-savestate-toggle .es-savestate {
|
|
267
|
-
border: 1px solid transparent;
|
|
156
|
+
display: inline-flex;
|
|
157
|
+
align-items: center;
|
|
268
158
|
}
|
|
269
|
-
.es-savestate-toggle
|
|
270
|
-
|
|
159
|
+
.es-savestate-toggle label {
|
|
160
|
+
cursor: pointer;
|
|
271
161
|
}
|
|
272
162
|
/* Paused: boxed, so it reads as a switch turned off, not a passive label. */
|
|
273
163
|
.es-savestate.is-off {
|
|
@@ -357,48 +247,19 @@
|
|
|
357
247
|
}
|
|
358
248
|
|
|
359
249
|
/* ── Resize grips ────────────────────────────────────────────────────────── */
|
|
360
|
-
/*
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
.
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
}
|
|
374
|
-
.es-resizer--left {
|
|
375
|
-
left: var(--es-left-w, 288px);
|
|
376
|
-
justify-content: flex-start;
|
|
377
|
-
}
|
|
378
|
-
.es-resizer--right {
|
|
379
|
-
right: var(--es-right-w, 320px);
|
|
380
|
-
justify-content: flex-end;
|
|
381
|
-
}
|
|
382
|
-
.es-resizer-bar {
|
|
383
|
-
width: 2px;
|
|
384
|
-
border-radius: 2px;
|
|
385
|
-
background: transparent;
|
|
386
|
-
transition: background 0.12s;
|
|
387
|
-
}
|
|
388
|
-
.es-resizer:hover .es-resizer-bar,
|
|
389
|
-
.es-resizer:focus-visible .es-resizer-bar {
|
|
390
|
-
background: var(--es-accent);
|
|
391
|
-
}
|
|
392
|
-
.es-resizer:focus {
|
|
393
|
-
outline: none;
|
|
394
|
-
}
|
|
395
|
-
body.es-col-resizing,
|
|
396
|
-
body.es-col-resizing * {
|
|
397
|
-
cursor: col-resize !important;
|
|
398
|
-
user-select: none !important;
|
|
399
|
-
}
|
|
400
|
-
body.es-col-resizing iframe {
|
|
401
|
-
pointer-events: none !important;
|
|
250
|
+
/* The grip is the shell's `ResizeHandle` (UI-24): its hit area, its bar on
|
|
251
|
+
hover and focus, its cursor during a drag. Only WHERE it sits is the
|
|
252
|
+
editor's: an absolute child of the panel ROW, pinned over the panel↔canvas
|
|
253
|
+
seam from the same width vars the panels read, instead of the shell's
|
|
254
|
+
default edge of its parent. The host's panel row must be `position:
|
|
255
|
+
relative`. (Two classes, to outrank the shell's own edge utility.) */
|
|
256
|
+
.es-resizer.es-resizer--left {
|
|
257
|
+
left: calc(var(--es-left-w, 288px) - 4px);
|
|
258
|
+
right: auto;
|
|
259
|
+
}
|
|
260
|
+
.es-resizer.es-resizer--right {
|
|
261
|
+
right: calc(var(--es-right-w, 320px) - 4px);
|
|
262
|
+
left: auto;
|
|
402
263
|
}
|
|
403
264
|
|
|
404
265
|
/* ── Inspector head ──────────────────────────────────────────────────────── */
|
|
@@ -414,24 +275,16 @@ body.es-col-resizing iframe {
|
|
|
414
275
|
min-width: 0;
|
|
415
276
|
padding: 12px 16px 0;
|
|
416
277
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
gap: 4px;
|
|
278
|
+
/* The link is the shell's Button (`link`) in its Tooltip's wrapper; only its
|
|
279
|
+
truncation is laid out here — a long name is cut inside the panel. */
|
|
280
|
+
span:has(> .es-insp-up-btn) {
|
|
421
281
|
max-width: 100%;
|
|
422
282
|
min-width: 0;
|
|
423
|
-
padding: 0;
|
|
424
|
-
border: 0;
|
|
425
|
-
background: none;
|
|
426
|
-
font: inherit;
|
|
427
|
-
font-size: 12px;
|
|
428
|
-
color: var(--es-accent);
|
|
429
|
-
text-align: left;
|
|
430
|
-
cursor: pointer;
|
|
431
283
|
}
|
|
432
|
-
.es-insp-up-btn
|
|
433
|
-
|
|
434
|
-
|
|
284
|
+
.es-insp-up-btn {
|
|
285
|
+
max-width: 100%;
|
|
286
|
+
min-width: 0;
|
|
287
|
+
overflow: hidden;
|
|
435
288
|
}
|
|
436
289
|
.es-insp-up-arrow {
|
|
437
290
|
flex: none;
|
|
@@ -470,7 +323,9 @@ body.es-col-resizing iframe {
|
|
|
470
323
|
row 2 [Cancel]
|
|
471
324
|
The actions box steps aside (`display: contents`) so its buttons can sit in
|
|
472
325
|
different rows; every glyph button is locked to row 1 and takes the next
|
|
473
|
-
free column, so a head with several tools keeps them side by side.
|
|
326
|
+
free column, so a head with several tools keeps them side by side. Each
|
|
327
|
+
button sits in the shell Tooltip's wrapper, so the grid places the wrapper
|
|
328
|
+
that holds it (`:has(> …)`). */
|
|
474
329
|
@container (width < 260px) {
|
|
475
330
|
.es-insp-head:has(.es-insp-textbtn) {
|
|
476
331
|
display: grid;
|
|
@@ -482,13 +337,13 @@ body.es-col-resizing iframe {
|
|
|
482
337
|
}
|
|
483
338
|
.es-insp-head:has(.es-insp-textbtn) > .es-insp-chip,
|
|
484
339
|
.es-insp-head:has(.es-insp-textbtn) > .es-insp-titles,
|
|
485
|
-
.es-insp-head:has(.es-insp-textbtn) .es-insp-iconbtn {
|
|
340
|
+
.es-insp-head:has(.es-insp-textbtn) .es-insp-actions > :has(> .es-insp-iconbtn) {
|
|
486
341
|
grid-row: 1;
|
|
487
342
|
}
|
|
488
343
|
.es-insp-head:has(.es-insp-textbtn) > .es-insp-actions {
|
|
489
344
|
display: contents;
|
|
490
345
|
}
|
|
491
|
-
.es-insp-head:has(.es-insp-textbtn) .es-insp-textbtn {
|
|
346
|
+
.es-insp-head:has(.es-insp-textbtn) .es-insp-actions > :has(> .es-insp-textbtn) {
|
|
492
347
|
grid-row: 2;
|
|
493
348
|
grid-column: 2;
|
|
494
349
|
justify-self: start;
|
|
@@ -500,7 +355,7 @@ body.es-col-resizing iframe {
|
|
|
500
355
|
.es-insp-chip {
|
|
501
356
|
width: 26px;
|
|
502
357
|
height: 26px;
|
|
503
|
-
border-radius:
|
|
358
|
+
border-radius: var(--radius-md);
|
|
504
359
|
display: flex;
|
|
505
360
|
align-items: center;
|
|
506
361
|
justify-content: center;
|
|
@@ -537,47 +392,12 @@ body.es-col-resizing iframe {
|
|
|
537
392
|
gap: 2px;
|
|
538
393
|
flex: none;
|
|
539
394
|
}
|
|
540
|
-
.es-insp-iconbtn {
|
|
541
|
-
width: 28px;
|
|
542
|
-
height: 28px;
|
|
543
|
-
border: none;
|
|
544
|
-
background: transparent;
|
|
545
|
-
border-radius: 7px;
|
|
546
|
-
cursor: pointer;
|
|
547
|
-
color: var(--es-icon);
|
|
548
|
-
display: flex;
|
|
549
|
-
align-items: center;
|
|
550
|
-
justify-content: center;
|
|
551
|
-
padding: 0;
|
|
552
|
-
transition: background 0.12s, color 0.12s;
|
|
553
|
-
}
|
|
554
|
-
.es-insp-iconbtn:hover {
|
|
555
|
-
background: var(--es-hover);
|
|
556
|
-
color: var(--es-text-strong);
|
|
557
|
-
}
|
|
558
|
-
.es-insp-iconbtn--danger:hover {
|
|
559
|
-
background: var(--es-danger-tint);
|
|
560
|
-
color: var(--es-danger);
|
|
561
|
-
}
|
|
562
|
-
.es-insp-iconbtn[aria-expanded="true"] {
|
|
563
|
-
background: var(--es-accent-tint);
|
|
564
|
-
color: var(--es-accent);
|
|
565
|
-
}
|
|
566
|
-
|
|
567
395
|
/* A side panel's head has two pieces besides its glyph buttons (MediaPanelHead,
|
|
568
396
|
card [MERGE] One Media Panel Head, 2026-10-06; until then each editor's own
|
|
569
397
|
sheet drew them, as `.sf-head-*` and `.cd-head-*`). A MODE's way out is a
|
|
570
|
-
word ("Cancel", "Done") on the
|
|
571
|
-
|
|
572
|
-
editors drew 10, off the 2/4/8/12/16/32 scale); the hairline parts the
|
|
398
|
+
word ("Cancel", "Done") on the shell's small Button (`.es-insp-textbtn`
|
|
399
|
+
names it for the narrow layout above); the hairline parts the
|
|
573
400
|
panel's own tools from the Hide panel button that ends every head. */
|
|
574
|
-
.es-btn-ghost.es-insp-textbtn {
|
|
575
|
-
height: 28px;
|
|
576
|
-
padding: 0 12px;
|
|
577
|
-
font-size: 12.5px;
|
|
578
|
-
border-radius: 7px;
|
|
579
|
-
white-space: nowrap;
|
|
580
|
-
}
|
|
581
401
|
.es-insp-divider {
|
|
582
402
|
width: 1px;
|
|
583
403
|
height: 16px;
|
|
@@ -588,59 +408,16 @@ body.es-col-resizing iframe {
|
|
|
588
408
|
|
|
589
409
|
/* ── Edit notice — somebody else is in here, or a save was refused ───────── */
|
|
590
410
|
/* A bar under the top bar, never a dialog (blueprint 2.5): the operator has to
|
|
591
|
-
be able to read and copy from the screen it warns them about.
|
|
592
|
-
|
|
593
|
-
|
|
411
|
+
be able to read and copy from the screen it warns them about. */
|
|
412
|
+
/* The shell's Banner, with the shell's Buttons as its action (easel issue 199, step 4):
|
|
413
|
+
the wrapper only places it under the top bar. */
|
|
594
414
|
.es-notice {
|
|
595
415
|
box-sizing: border-box;
|
|
596
|
-
display: flex;
|
|
597
|
-
flex-wrap: wrap;
|
|
598
|
-
align-items: center;
|
|
599
|
-
gap: 8px 12px;
|
|
600
416
|
padding: 8px 16px;
|
|
601
417
|
font-family: var(--es-font);
|
|
602
|
-
font-size: 13px;
|
|
603
|
-
line-height: 1.45;
|
|
604
|
-
color: var(--es-text-secondary);
|
|
605
|
-
background: var(--es-app-bg);
|
|
606
|
-
border-bottom: 1px solid var(--es-divider);
|
|
607
|
-
}
|
|
608
|
-
.es-notice.is-warning {
|
|
609
|
-
color: var(--es-text);
|
|
610
|
-
background: color-mix(in srgb, var(--es-preview-tint) 70%, var(--es-panel));
|
|
611
|
-
border-bottom-color: color-mix(in srgb, var(--es-warning) 30%, var(--es-preview-tint));
|
|
612
|
-
}
|
|
613
|
-
.es-notice-text {
|
|
614
|
-
flex: 1 1 320px;
|
|
615
|
-
min-width: 0;
|
|
616
|
-
}
|
|
617
|
-
.es-notice-text strong {
|
|
618
|
-
font-weight: 600;
|
|
619
|
-
color: var(--es-text-strong);
|
|
620
418
|
}
|
|
621
419
|
.es-notice-actions {
|
|
622
420
|
display: flex;
|
|
623
421
|
flex-wrap: wrap;
|
|
624
422
|
gap: 8px;
|
|
625
423
|
}
|
|
626
|
-
.es-notice-btn {
|
|
627
|
-
appearance: none;
|
|
628
|
-
-webkit-appearance: none;
|
|
629
|
-
font: inherit;
|
|
630
|
-
font-size: 12px;
|
|
631
|
-
font-weight: 500;
|
|
632
|
-
padding: 4px 12px;
|
|
633
|
-
border: 1px solid var(--es-btn-border);
|
|
634
|
-
border-radius: var(--es-field-radius);
|
|
635
|
-
background: var(--es-raised);
|
|
636
|
-
color: var(--es-btn-text);
|
|
637
|
-
white-space: nowrap;
|
|
638
|
-
cursor: pointer;
|
|
639
|
-
}
|
|
640
|
-
.es-notice-btn:hover {
|
|
641
|
-
background: var(--es-hover);
|
|
642
|
-
}
|
|
643
|
-
.es-notice-btn:focus-visible {
|
|
644
|
-
outline: 2px solid var(--es-accent);
|
|
645
|
-
outline-offset: 1px;
|
|
646
|
-
}
|