@liminis/editor 0.2.2 → 0.3.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
CHANGED
|
@@ -43,12 +43,20 @@ produce a broken editor context — peering is what prevents both.
|
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
45
|
pnpm add react@^19 react-dom@^19 \
|
|
46
|
-
lexical@^0.
|
|
47
|
-
@lexical/code-prism@^0.
|
|
48
|
-
@lexical/mark@^0.
|
|
49
|
-
@lexical/selection@^0.
|
|
46
|
+
lexical@^0.49 @lexical/react@^0.49 @lexical/code@^0.49 \
|
|
47
|
+
@lexical/code-prism@^0.49 @lexical/link@^0.49 @lexical/list@^0.49 \
|
|
48
|
+
@lexical/mark@^0.49 @lexical/markdown@^0.49 @lexical/rich-text@^0.49 \
|
|
49
|
+
@lexical/selection@^0.49 @lexical/table@^0.49 @lexical/utils@^0.49
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
> **The Lexical peer ranges are single-caret, not a wide band.** Lexical is
|
|
53
|
+
> also `0.x`, where every minor is permitted to break — unlike React's range
|
|
54
|
+
> above, which spans an untested-but-stable range, the Lexical range names
|
|
55
|
+
> exactly the one minor this package is built and tested against. Expect it
|
|
56
|
+
> to move forward (e.g. to `^0.50`) only after this package has adopted and
|
|
57
|
+
> tested that release, not automatically at every upstream release. See
|
|
58
|
+
> `docs/decisions/adr-92-lexical-peer-range-policy.md`.
|
|
59
|
+
|
|
52
60
|
pnpm v8+ and npm v7+ install peers automatically, so in practice the first
|
|
53
61
|
command is usually enough.
|
|
54
62
|
|
|
@@ -201,22 +209,23 @@ properties under a single package-owned vocabulary, `--liminis-editor-*`.
|
|
|
201
209
|
Every one of them resolves with no host configuration at all — the table
|
|
202
210
|
below exists so you can *override* a palette, and also so you can *consume*
|
|
203
211
|
one: every property this package declares with a value anywhere in
|
|
204
|
-
`styles.css`
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
212
|
+
`styles.css` is part of this package's public API, readable directly by a
|
|
213
|
+
host, not only overridable. That now includes every `--liminis-editor-*` name
|
|
214
|
+
itself (see "Has a default" below) as well as the pre-`0.2.0` names that still
|
|
215
|
+
carry the real defaults (`--vscode-*`, `--slashmd-*`, `--checkbox-*`, and a
|
|
216
|
+
couple of standalone legacy names) — each `--liminis-editor-*` declaration is
|
|
217
|
+
an alias of its previous name (`--liminis-editor-x: var(--previous-name-x);`),
|
|
218
|
+
so both names resolve to the same value and either can be read directly
|
|
219
|
+
(ADR-93). (Legacy names like `--color-*` that appear only as an inner link in
|
|
220
|
+
a fallback chain, with no `:root`/`.dark` declaration of their own, are not
|
|
221
|
+
part of the defined set this paragraph describes — only the property that
|
|
222
|
+
*carries* the value is.) Some hosts read these definitions directly — mapping
|
|
223
|
+
their own design tokens onto them with `var(--x)` — rather than overriding
|
|
224
|
+
them. Renaming or removing a definition is therefore a breaking change, the
|
|
225
|
+
same as any other change to a supported API surface described under
|
|
226
|
+
"Versioning policy" above, and is distinct from renaming a *consumption* site
|
|
227
|
+
(covered separately in "Migrating from the old names" below) — this package's
|
|
228
|
+
CI guards against a definition disappearing unintentionally (ADR-092).
|
|
220
229
|
|
|
221
230
|
**Previous name** is the pre-`0.2.0` name this property replaced — the exact
|
|
222
231
|
name to look for if you're migrating a host that still overrides the old
|
|
@@ -224,87 +233,92 @@ vocabulary (`—` for a property that was never renamed). **Controls** is a
|
|
|
224
233
|
short description of what the token actually affects. **Kind** distinguishes
|
|
225
234
|
tokens that only affect appearance (`Cosmetic`) from the handful that also
|
|
226
235
|
affect layout (`Structural` — heading indents and the base font). **Has a
|
|
227
|
-
default** marks tokens with a
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
236
|
+
default** marks tokens declared with a value in `styles.css` directly; every
|
|
237
|
+
row below now reads "Yes" — each `--liminis-editor-*` name carries its own
|
|
238
|
+
`:root`/`.dark` declaration, an alias that reads its previous name via `var()`
|
|
239
|
+
(ADR-93), so a host reading `--liminis-editor-x` gets a real value with no
|
|
240
|
+
configuration, and a host overriding only the previous name at
|
|
241
|
+
`:root`/`document.documentElement` still wins, because the alias re-resolves
|
|
242
|
+
through that name's own `.dark`/`@media print` overrides at the point of use
|
|
243
|
+
(ADR-93 documents a scope limitation for an override applied to a descendant
|
|
244
|
+
element instead). See "Migrating from the old names" below.
|
|
233
245
|
|
|
234
246
|
This table is generated from `src/` by `node scripts/generate-theming-docs.mjs`
|
|
235
247
|
and checked for staleness in CI (`tests/theming-contract.test.ts`) — a `var(--x)`
|
|
236
248
|
added to the source without regenerating this block fails the build. Do not
|
|
237
249
|
hand-edit the rows between the markers below. See ADR-085 for how the
|
|
238
250
|
generation and drift guard work, ADR-087 for the rename and its compatibility
|
|
239
|
-
design,
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
251
|
+
design, ADR-092 for the separate guard that protects the full *defined* set —
|
|
252
|
+
every token declared with a value in `styles.css`, per the checked-in baseline
|
|
253
|
+
(`scripts/lib/theming-defined-tokens-baseline.json`) — against an
|
|
254
|
+
unintentional rename or removal (run `pnpm docs:theming-baseline` after a
|
|
255
|
+
deliberate one), and ADR-93 for the `--liminis-editor-*` alias declarations
|
|
256
|
+
that make the defined set (baseline) a superset of this table's rows —
|
|
257
|
+
every consumed `--liminis-editor-*` name is now also a defined one — rather
|
|
258
|
+
than the disjoint sets they were before.
|
|
245
259
|
|
|
246
260
|
<!-- theming-tokens:start -->
|
|
247
261
|
| Custom property | Previous name | Controls | Kind | Has a default |
|
|
248
262
|
| --- | --- | --- | --- | --- |
|
|
249
|
-
| `--liminis-editor-background` | `--vscode-background` | Base background color of the editor surface and its popovers/menus. | Cosmetic |
|
|
250
|
-
| `--liminis-editor-bold-color` | `--slashmd-bold-color` | Text color of bold (`**text**`) markdown spans. | Cosmetic |
|
|
251
|
-
| `--liminis-editor-border` | `--vscode-border` | Default border color used throughout the editor chrome. | Cosmetic |
|
|
252
|
-
| `--liminis-editor-button-background` | `--vscode-button-background` | Background of primary action buttons (e.g. the correction panel's "Apply" button). | Cosmetic |
|
|
253
|
-
| `--liminis-editor-button-foreground` | `--vscode-button-foreground` | Text color of primary action buttons. | Cosmetic |
|
|
254
|
-
| `--liminis-editor-callout-caution-bg` | `--slashmd-callout-caution-bg` | Background of "caution" callout blocks. | Cosmetic |
|
|
255
|
-
| `--liminis-editor-callout-caution-border` | `--slashmd-callout-caution-border` | Left border accent of "caution" callout blocks. | Cosmetic |
|
|
256
|
-
| `--liminis-editor-callout-important-bg` | `--slashmd-callout-important-bg` | Background of "important" callout blocks. | Cosmetic |
|
|
257
|
-
| `--liminis-editor-callout-important-border` | `--slashmd-callout-important-border` | Left border accent of "important" callout blocks. | Cosmetic |
|
|
258
|
-
| `--liminis-editor-callout-note-bg` | `--slashmd-callout-note-bg` | Background of "note" callout blocks. | Cosmetic |
|
|
259
|
-
| `--liminis-editor-callout-note-border` | `--slashmd-callout-note-border` | Left border accent of "note" callout blocks. | Cosmetic |
|
|
260
|
-
| `--liminis-editor-callout-tip-bg` | `--slashmd-callout-tip-bg` | Background of "tip" callout blocks. | Cosmetic |
|
|
261
|
-
| `--liminis-editor-callout-tip-border` | `--slashmd-callout-tip-border` | Left border accent of "tip" callout blocks. | Cosmetic |
|
|
262
|
-
| `--liminis-editor-callout-warning-bg` | `--slashmd-callout-warning-bg` | Background of "warning" callout blocks. | Cosmetic |
|
|
263
|
-
| `--liminis-editor-callout-warning-border` | `--slashmd-callout-warning-border` | Left border accent of "warning" callout blocks. | Cosmetic |
|
|
264
|
-
| `--liminis-editor-checkbox-border` | `--checkbox-border` | Border color of unchecked task-list checkboxes. | Cosmetic |
|
|
265
|
-
| `--liminis-editor-code-bg` | `--vscode-code-bg` | Background of inline code spans and fenced code blocks. | Cosmetic |
|
|
266
|
-
| `--liminis-editor-errorForeground` | `--vscode-errorForeground` | Text color for error and validation messages. | Cosmetic |
|
|
267
|
-
| `--liminis-editor-external-link` | `--vscode-external-link` | Text color of links that point outside the document. | Cosmetic |
|
|
268
|
-
| `--liminis-editor-focus-border` | `--vscode-focus-border` | Border color of the toolbar link-input field when focused. | Cosmetic |
|
|
269
|
-
| `--liminis-editor-focusBorder` | `--vscode-focusBorder` | Color of the drag-and-drop position indicator while reordering blocks. | Cosmetic |
|
|
270
|
-
| `--liminis-editor-font-family` | `--vscode-font-family` | Base font family for the editor content. | Structural |
|
|
271
|
-
| `--liminis-editor-font-size` | `--vscode-font-size` | Base font size for the editor content. | Structural |
|
|
272
|
-
| `--liminis-editor-foreground` | `--vscode-foreground` | Default text color throughout the editor. | Cosmetic |
|
|
273
|
-
| `--liminis-editor-foreground-muted` | `--vscode-foreground-muted` | Hover border color for the frontmatter tray's raw-view toggle. | Cosmetic |
|
|
274
|
-
| `--liminis-editor-h1-color` | `--slashmd-h1-color` | Text color of level-1 (`#`) headings. | Cosmetic |
|
|
275
|
-
| `--liminis-editor-h1-indent` | `--slashmd-h1-indent` | Left margin of level-1 (`#`) headings. | Structural |
|
|
276
|
-
| `--liminis-editor-h2-color` | `--slashmd-h2-color` | Text color of level-2 (`##`) headings. | Cosmetic |
|
|
277
|
-
| `--liminis-editor-h2-indent` | `--slashmd-h2-indent` | Left margin of level-2 (`##`) headings. | Structural |
|
|
278
|
-
| `--liminis-editor-h3-color` | `--slashmd-h3-color` | Text color of level-3 (`###`) headings. | Cosmetic |
|
|
279
|
-
| `--liminis-editor-h3-indent` | `--slashmd-h3-indent` | Left margin of level-3 (`###`) headings. | Structural |
|
|
280
|
-
| `--liminis-editor-h4-color` | `--slashmd-h4-color` | Text color of level-4 (`####`) headings. | Cosmetic |
|
|
281
|
-
| `--liminis-editor-h4-indent` | `--slashmd-h4-indent` | Left margin of level-4 (`####`) headings. | Structural |
|
|
282
|
-
| `--liminis-editor-h5-color` | `--slashmd-h5-color` | Text color of level-5 (`#####`) headings. | Cosmetic |
|
|
283
|
-
| `--liminis-editor-h5-indent` | `--slashmd-h5-indent` | Left margin of level-5 (`#####`) headings. | Structural |
|
|
284
|
-
| `--liminis-editor-input-bg` | `--vscode-input-bg` | Background of the toolbar link-input field. | Cosmetic |
|
|
285
|
-
| `--liminis-editor-inputValidation-errorBackground` | `--vscode-inputValidation-errorBackground` | Background of inline validation-error messages. | Cosmetic |
|
|
286
|
-
| `--liminis-editor-italic-color` | `--slashmd-italic-color` | Text color of italic (`*text*`) markdown spans. | Cosmetic |
|
|
287
|
-
| `--liminis-editor-link` | `--vscode-link` | Text color of in-document links. | Cosmetic |
|
|
288
|
-
| `--liminis-editor-menu-background` | `--vscode-menu-background` | Background of context menus (block, selection and correction menus). | Cosmetic |
|
|
289
|
-
| `--liminis-editor-menu-border` | `--vscode-menu-border` | Border color of context menus. | Cosmetic |
|
|
290
|
-
| `--liminis-editor-menu-foreground` | `--vscode-menu-foreground` | Text color of context menu items. | Cosmetic |
|
|
291
|
-
| `--liminis-editor-menu-selectionBackground` | `--vscode-menu-selectionBackground` | Background of a hovered/selected context menu item. | Cosmetic |
|
|
292
|
-
| `--liminis-editor-menu-separatorBackground` | `--vscode-menu-separatorBackground` | Color of separator lines inside context menus. | Cosmetic |
|
|
293
|
-
| `--liminis-editor-muted-100` | `--color-muted-100` | Background of the C4 diagram layout-toggle buttons when inactive. | Cosmetic |
|
|
294
|
-
| `--liminis-editor-muted-foreground` | `--color-muted-foreground` | Icon/text color of the C4 diagram layout-toggle buttons when inactive. | Cosmetic |
|
|
295
|
-
| `--liminis-editor-notificationsInfoIcon-foreground` | `--vscode-notificationsInfoIcon-foreground` | Color of informational icons in inline notifications. | Cosmetic |
|
|
296
|
-
| `--liminis-editor-primary` | `--color-primary` | Icon/text color of the C4 diagram layout-toggle buttons when active. | Cosmetic |
|
|
297
|
-
| `--liminis-editor-primary-100` | `--color-primary-100` | Background of the C4 diagram layout-toggle buttons when active. | Cosmetic |
|
|
298
|
-
| `--liminis-editor-selection` | `--vscode-selection` | Background color of selected/highlighted text. | Cosmetic |
|
|
299
|
-
| `--liminis-editor-token-comment` | `--slashmd-token-comment` | Syntax-highlight color for comments in fenced code blocks. | Cosmetic |
|
|
300
|
-
| `--liminis-editor-token-function` | `--slashmd-token-function` | Syntax-highlight color for function names in fenced code blocks. | Cosmetic |
|
|
301
|
-
| `--liminis-editor-token-keyword` | `--slashmd-token-keyword` | Syntax-highlight color for keywords in fenced code blocks. | Cosmetic |
|
|
302
|
-
| `--liminis-editor-token-operator` | `--slashmd-token-operator` | Syntax-highlight color for operators in fenced code blocks. | Cosmetic |
|
|
303
|
-
| `--liminis-editor-token-property` | `--slashmd-token-property` | Syntax-highlight color for object properties in fenced code blocks. | Cosmetic |
|
|
304
|
-
| `--liminis-editor-token-punctuation` | `--slashmd-token-punctuation` | Syntax-highlight color for punctuation in fenced code blocks. | Cosmetic |
|
|
305
|
-
| `--liminis-editor-token-selector` | `--slashmd-token-selector` | Syntax-highlight color for CSS selectors in fenced code blocks. | Cosmetic |
|
|
306
|
-
| `--liminis-editor-token-variable` | `--slashmd-token-variable` | Syntax-highlight color for variables in fenced code blocks. | Cosmetic |
|
|
307
|
-
| `--liminis-editor-toolbar-hoverBackground` | `--vscode-toolbar-hoverBackground` | Background of a toolbar button on hover. | Cosmetic |
|
|
263
|
+
| `--liminis-editor-background` | `--vscode-background` | Base background color of the editor surface and its popovers/menus. | Cosmetic | Yes |
|
|
264
|
+
| `--liminis-editor-bold-color` | `--slashmd-bold-color` | Text color of bold (`**text**`) markdown spans. | Cosmetic | Yes |
|
|
265
|
+
| `--liminis-editor-border` | `--vscode-border` | Default border color used throughout the editor chrome. | Cosmetic | Yes |
|
|
266
|
+
| `--liminis-editor-button-background` | `--vscode-button-background` | Background of primary action buttons (e.g. the correction panel's "Apply" button). | Cosmetic | Yes |
|
|
267
|
+
| `--liminis-editor-button-foreground` | `--vscode-button-foreground` | Text color of primary action buttons. | Cosmetic | Yes |
|
|
268
|
+
| `--liminis-editor-callout-caution-bg` | `--slashmd-callout-caution-bg` | Background of "caution" callout blocks. | Cosmetic | Yes |
|
|
269
|
+
| `--liminis-editor-callout-caution-border` | `--slashmd-callout-caution-border` | Left border accent of "caution" callout blocks. | Cosmetic | Yes |
|
|
270
|
+
| `--liminis-editor-callout-important-bg` | `--slashmd-callout-important-bg` | Background of "important" callout blocks. | Cosmetic | Yes |
|
|
271
|
+
| `--liminis-editor-callout-important-border` | `--slashmd-callout-important-border` | Left border accent of "important" callout blocks. | Cosmetic | Yes |
|
|
272
|
+
| `--liminis-editor-callout-note-bg` | `--slashmd-callout-note-bg` | Background of "note" callout blocks. | Cosmetic | Yes |
|
|
273
|
+
| `--liminis-editor-callout-note-border` | `--slashmd-callout-note-border` | Left border accent of "note" callout blocks. | Cosmetic | Yes |
|
|
274
|
+
| `--liminis-editor-callout-tip-bg` | `--slashmd-callout-tip-bg` | Background of "tip" callout blocks. | Cosmetic | Yes |
|
|
275
|
+
| `--liminis-editor-callout-tip-border` | `--slashmd-callout-tip-border` | Left border accent of "tip" callout blocks. | Cosmetic | Yes |
|
|
276
|
+
| `--liminis-editor-callout-warning-bg` | `--slashmd-callout-warning-bg` | Background of "warning" callout blocks. | Cosmetic | Yes |
|
|
277
|
+
| `--liminis-editor-callout-warning-border` | `--slashmd-callout-warning-border` | Left border accent of "warning" callout blocks. | Cosmetic | Yes |
|
|
278
|
+
| `--liminis-editor-checkbox-border` | `--checkbox-border` | Border color of unchecked task-list checkboxes. | Cosmetic | Yes |
|
|
279
|
+
| `--liminis-editor-code-bg` | `--vscode-code-bg` | Background of inline code spans and fenced code blocks. | Cosmetic | Yes |
|
|
280
|
+
| `--liminis-editor-errorForeground` | `--vscode-errorForeground` | Text color for error and validation messages. | Cosmetic | Yes |
|
|
281
|
+
| `--liminis-editor-external-link` | `--vscode-external-link` | Text color of links that point outside the document. | Cosmetic | Yes |
|
|
282
|
+
| `--liminis-editor-focus-border` | `--vscode-focus-border` | Border color of the toolbar link-input field when focused. | Cosmetic | Yes |
|
|
283
|
+
| `--liminis-editor-focusBorder` | `--vscode-focusBorder` | Color of the drag-and-drop position indicator while reordering blocks. | Cosmetic | Yes |
|
|
284
|
+
| `--liminis-editor-font-family` | `--vscode-font-family` | Base font family for the editor content. | Structural | Yes |
|
|
285
|
+
| `--liminis-editor-font-size` | `--vscode-font-size` | Base font size for the editor content. | Structural | Yes |
|
|
286
|
+
| `--liminis-editor-foreground` | `--vscode-foreground` | Default text color throughout the editor. | Cosmetic | Yes |
|
|
287
|
+
| `--liminis-editor-foreground-muted` | `--vscode-foreground-muted` | Hover border color for the frontmatter tray's raw-view toggle. | Cosmetic | Yes |
|
|
288
|
+
| `--liminis-editor-h1-color` | `--slashmd-h1-color` | Text color of level-1 (`#`) headings. | Cosmetic | Yes |
|
|
289
|
+
| `--liminis-editor-h1-indent` | `--slashmd-h1-indent` | Left margin of level-1 (`#`) headings. | Structural | Yes |
|
|
290
|
+
| `--liminis-editor-h2-color` | `--slashmd-h2-color` | Text color of level-2 (`##`) headings. | Cosmetic | Yes |
|
|
291
|
+
| `--liminis-editor-h2-indent` | `--slashmd-h2-indent` | Left margin of level-2 (`##`) headings. | Structural | Yes |
|
|
292
|
+
| `--liminis-editor-h3-color` | `--slashmd-h3-color` | Text color of level-3 (`###`) headings. | Cosmetic | Yes |
|
|
293
|
+
| `--liminis-editor-h3-indent` | `--slashmd-h3-indent` | Left margin of level-3 (`###`) headings. | Structural | Yes |
|
|
294
|
+
| `--liminis-editor-h4-color` | `--slashmd-h4-color` | Text color of level-4 (`####`) headings. | Cosmetic | Yes |
|
|
295
|
+
| `--liminis-editor-h4-indent` | `--slashmd-h4-indent` | Left margin of level-4 (`####`) headings. | Structural | Yes |
|
|
296
|
+
| `--liminis-editor-h5-color` | `--slashmd-h5-color` | Text color of level-5 (`#####`) headings. | Cosmetic | Yes |
|
|
297
|
+
| `--liminis-editor-h5-indent` | `--slashmd-h5-indent` | Left margin of level-5 (`#####`) headings. | Structural | Yes |
|
|
298
|
+
| `--liminis-editor-input-bg` | `--vscode-input-bg` | Background of the toolbar link-input field. | Cosmetic | Yes |
|
|
299
|
+
| `--liminis-editor-inputValidation-errorBackground` | `--vscode-inputValidation-errorBackground` | Background of inline validation-error messages. | Cosmetic | Yes |
|
|
300
|
+
| `--liminis-editor-italic-color` | `--slashmd-italic-color` | Text color of italic (`*text*`) markdown spans. | Cosmetic | Yes |
|
|
301
|
+
| `--liminis-editor-link` | `--vscode-link` | Text color of in-document links. | Cosmetic | Yes |
|
|
302
|
+
| `--liminis-editor-menu-background` | `--vscode-menu-background` | Background of context menus (block, selection and correction menus). | Cosmetic | Yes |
|
|
303
|
+
| `--liminis-editor-menu-border` | `--vscode-menu-border` | Border color of context menus. | Cosmetic | Yes |
|
|
304
|
+
| `--liminis-editor-menu-foreground` | `--vscode-menu-foreground` | Text color of context menu items. | Cosmetic | Yes |
|
|
305
|
+
| `--liminis-editor-menu-selectionBackground` | `--vscode-menu-selectionBackground` | Background of a hovered/selected context menu item. | Cosmetic | Yes |
|
|
306
|
+
| `--liminis-editor-menu-separatorBackground` | `--vscode-menu-separatorBackground` | Color of separator lines inside context menus. | Cosmetic | Yes |
|
|
307
|
+
| `--liminis-editor-muted-100` | `--color-muted-100` | Background of the C4 diagram layout-toggle buttons when inactive. | Cosmetic | Yes |
|
|
308
|
+
| `--liminis-editor-muted-foreground` | `--color-muted-foreground` | Icon/text color of the C4 diagram layout-toggle buttons when inactive. | Cosmetic | Yes |
|
|
309
|
+
| `--liminis-editor-notificationsInfoIcon-foreground` | `--vscode-notificationsInfoIcon-foreground` | Color of informational icons in inline notifications. | Cosmetic | Yes |
|
|
310
|
+
| `--liminis-editor-primary` | `--color-primary` | Icon/text color of the C4 diagram layout-toggle buttons when active. | Cosmetic | Yes |
|
|
311
|
+
| `--liminis-editor-primary-100` | `--color-primary-100` | Background of the C4 diagram layout-toggle buttons when active. | Cosmetic | Yes |
|
|
312
|
+
| `--liminis-editor-selection` | `--vscode-selection` | Background color of selected/highlighted text. | Cosmetic | Yes |
|
|
313
|
+
| `--liminis-editor-token-comment` | `--slashmd-token-comment` | Syntax-highlight color for comments in fenced code blocks. | Cosmetic | Yes |
|
|
314
|
+
| `--liminis-editor-token-function` | `--slashmd-token-function` | Syntax-highlight color for function names in fenced code blocks. | Cosmetic | Yes |
|
|
315
|
+
| `--liminis-editor-token-keyword` | `--slashmd-token-keyword` | Syntax-highlight color for keywords in fenced code blocks. | Cosmetic | Yes |
|
|
316
|
+
| `--liminis-editor-token-operator` | `--slashmd-token-operator` | Syntax-highlight color for operators in fenced code blocks. | Cosmetic | Yes |
|
|
317
|
+
| `--liminis-editor-token-property` | `--slashmd-token-property` | Syntax-highlight color for object properties in fenced code blocks. | Cosmetic | Yes |
|
|
318
|
+
| `--liminis-editor-token-punctuation` | `--slashmd-token-punctuation` | Syntax-highlight color for punctuation in fenced code blocks. | Cosmetic | Yes |
|
|
319
|
+
| `--liminis-editor-token-selector` | `--slashmd-token-selector` | Syntax-highlight color for CSS selectors in fenced code blocks. | Cosmetic | Yes |
|
|
320
|
+
| `--liminis-editor-token-variable` | `--slashmd-token-variable` | Syntax-highlight color for variables in fenced code blocks. | Cosmetic | Yes |
|
|
321
|
+
| `--liminis-editor-toolbar-hoverBackground` | `--vscode-toolbar-hoverBackground` | Background of a toolbar button on hover. | Cosmetic | Yes |
|
|
308
322
|
<!-- theming-tokens:end -->
|
|
309
323
|
|
|
310
324
|
**A worked example.** To match a host's own palette, override a subset of
|
|
@@ -348,6 +362,25 @@ prefix swap (`--checkbox-border` became `--liminis-editor-checkbox-border`,
|
|
|
348
362
|
not `--liminis-editor-border`, to avoid colliding with `--vscode-border`'s
|
|
349
363
|
new name), so look it up rather than deriving it.
|
|
350
364
|
|
|
365
|
+
Reading, not just overriding, is also migratable: a host that currently reads
|
|
366
|
+
a legacy name directly (e.g. mapping its own design tokens onto
|
|
367
|
+
`--vscode-foreground`) can switch that read to the corresponding
|
|
368
|
+
`--liminis-editor-*` name and get an identical value, **as long as it isn't
|
|
369
|
+
also setting the `--liminis-editor-*` name itself** — a directly-set
|
|
370
|
+
`--liminis-editor-*` value always wins over the previous name's own value,
|
|
371
|
+
by ordinary cascade precedence (see "Has a default" below), so the two reads
|
|
372
|
+
are identical only while the host relies solely on the previous name. Until
|
|
373
|
+
ADR-93, `--liminis-editor-*` names were only ever *consumed*, never
|
|
374
|
+
themselves declared with a value — there was nothing for such a host to
|
|
375
|
+
migrate its reads to. Every `--liminis-editor-*` name now carries its own
|
|
376
|
+
`:root`/`.dark` alias declaration that resolves to the previous name's own
|
|
377
|
+
value in that legacy-only case, so the read migration is a like-for-like
|
|
378
|
+
swap with no observable difference (see verveguy/zusammen#129, the migration
|
|
379
|
+
this addresses). This guarantee holds for a previous-name override applied
|
|
380
|
+
at `:root`/`document.documentElement`, the standard integration point; see
|
|
381
|
+
ADR-93 for a documented limitation when a host scopes its override to a
|
|
382
|
+
descendant element instead.
|
|
383
|
+
|
|
351
384
|
## Annotations
|
|
352
385
|
|
|
353
386
|
An annotation is a range-anchored marker over document text whose anchor
|
|
@@ -240,6 +240,20 @@ function CursorRestorePlugin({ contentVersion, cursorToRestoreRef, }) {
|
|
|
240
240
|
const cursorToRestore = cursorToRestoreRef.current;
|
|
241
241
|
if (!cursorToRestore)
|
|
242
242
|
return;
|
|
243
|
+
// Only restore the caret if the user was actually in the editor when the
|
|
244
|
+
// reload arrived. A content reload is not always the user's doing: an
|
|
245
|
+
// agent writing the open file reaches here too, and re-focusing then pulls
|
|
246
|
+
// the caret out of whatever the user is typing in — a chat prompt beside
|
|
247
|
+
// the editor, say — mid-sentence. Restoring a caret nobody is looking at
|
|
248
|
+
// buys nothing, so an unfocused editor is left entirely alone (no
|
|
249
|
+
// selection write either, so reconciliation cannot move focus as a side
|
|
250
|
+
// effect). Same rule as `AutoFocusPlugin`: never take focus unasked.
|
|
251
|
+
// Read synchronously, before the update below can perturb focus.
|
|
252
|
+
const rootElement = editor.getRootElement();
|
|
253
|
+
const hadFocus = rootElement !== null &&
|
|
254
|
+
(rootElement === document.activeElement || rootElement.contains(document.activeElement));
|
|
255
|
+
if (!hadFocus)
|
|
256
|
+
return;
|
|
243
257
|
console.log('[CursorRestorePlugin] Restoring cursor', {
|
|
244
258
|
contentVersion,
|
|
245
259
|
offset: cursorToRestore.offset,
|
|
@@ -262,11 +276,9 @@ function CursorRestorePlugin({ contentVersion, cursorToRestoreRef, }) {
|
|
|
262
276
|
console.log('[CursorRestorePlugin] Selection restored at offset', newOffset);
|
|
263
277
|
}
|
|
264
278
|
});
|
|
265
|
-
// Re-focus the editor
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
rootElement.focus({ preventScroll: true });
|
|
269
|
-
}
|
|
279
|
+
// Re-focus the editor. Reached only when it already had focus above, so
|
|
280
|
+
// this restores focus the reload disturbed rather than taking it.
|
|
281
|
+
rootElement.focus({ preventScroll: true });
|
|
270
282
|
});
|
|
271
283
|
}, [editor, contentVersion, cursorToRestoreRef]);
|
|
272
284
|
return null;
|
package/dist/styles.css
CHANGED
|
@@ -107,6 +107,135 @@
|
|
|
107
107
|
--slashmd-callout-caution-border: oklch(0.63 0.24 27);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
/* ========================================
|
|
111
|
+
PUBLIC ALIASES — --liminis-editor-* names (ADR-93)
|
|
112
|
+
|
|
113
|
+
The package's own :root/.dark declarations above keep carrying the real
|
|
114
|
+
defaults, under the legacy names, exactly as before. Every alias below
|
|
115
|
+
only reads a legacy name via var() — it never declares an independent
|
|
116
|
+
value — so a host overriding only the legacy name still wins: the alias
|
|
117
|
+
re-resolves through .dark and the @media print block's overrides of that
|
|
118
|
+
legacy name, since a var() reference resolves per-element at the point of
|
|
119
|
+
use, not at the point this declaration is parsed. This lets a host read
|
|
120
|
+
--liminis-editor-* directly (verveguy/zusammen#129) without disabling the
|
|
121
|
+
ADR-087 fallback layer that a host supplying only the legacy name relies
|
|
122
|
+
on.
|
|
123
|
+
|
|
124
|
+
Scope of the "legacy name still wins" guarantee: this re-resolution is
|
|
125
|
+
correct for a legacy override applied at (or that plainly inherits down
|
|
126
|
+
to) :root/document.documentElement — the standard integration point, and
|
|
127
|
+
the only one covered by this package's own e2e coverage. It does NOT
|
|
128
|
+
extend to a legacy override scoped to an arbitrary DESCENDANT element
|
|
129
|
+
between :root and the editor's own DOM (e.g. a per-widget wrapper div a
|
|
130
|
+
host might apply its own theme vars to): a custom property inherits its
|
|
131
|
+
parent's already-*computed* value, not the var() expression, so this
|
|
132
|
+
:root-declared alias is fixed at parse time using :root's own value and
|
|
133
|
+
won't pick up a change made lower in the tree. Re-declaring the alias on
|
|
134
|
+
every element (`*`) was tried and rejected: it fixes the descendant case
|
|
135
|
+
but then shadows a --liminis-editor-* override a host sets on an
|
|
136
|
+
ancestor of the element being read, breaking the higher-priority
|
|
137
|
+
guarantee (User Story 3) that a directly-set --liminis-editor-* name
|
|
138
|
+
always wins — confirmed by test, not assumed. Scoping the redeclaration
|
|
139
|
+
to a known package wrapper class (e.g. .editor-app-root) was also tried
|
|
140
|
+
and rejected: not every integration renders that wrapper (this repo's
|
|
141
|
+
own examples/electron shell doesn't), so the alias would go undefined
|
|
142
|
+
there. See ADR-93 for the full trade-off and verveguy/liminis-editor#93's
|
|
143
|
+
PR review thread for the CSS-inheritance mechanics that rule out a
|
|
144
|
+
`:root`-only or `*`-only fix satisfying both scenarios at once.
|
|
145
|
+
======================================== */
|
|
146
|
+
:root {
|
|
147
|
+
/* Aliases for tokens with an existing --vscode-, --slashmd- or --checkbox- default */
|
|
148
|
+
--liminis-editor-background: var(--vscode-background);
|
|
149
|
+
--liminis-editor-bold-color: var(--slashmd-bold-color);
|
|
150
|
+
--liminis-editor-border: var(--vscode-border);
|
|
151
|
+
--liminis-editor-callout-caution-bg: var(--slashmd-callout-caution-bg);
|
|
152
|
+
--liminis-editor-callout-caution-border: var(--slashmd-callout-caution-border);
|
|
153
|
+
--liminis-editor-callout-important-bg: var(--slashmd-callout-important-bg);
|
|
154
|
+
--liminis-editor-callout-important-border: var(--slashmd-callout-important-border);
|
|
155
|
+
--liminis-editor-callout-note-bg: var(--slashmd-callout-note-bg);
|
|
156
|
+
--liminis-editor-callout-note-border: var(--slashmd-callout-note-border);
|
|
157
|
+
--liminis-editor-callout-tip-bg: var(--slashmd-callout-tip-bg);
|
|
158
|
+
--liminis-editor-callout-tip-border: var(--slashmd-callout-tip-border);
|
|
159
|
+
--liminis-editor-callout-warning-bg: var(--slashmd-callout-warning-bg);
|
|
160
|
+
--liminis-editor-callout-warning-border: var(--slashmd-callout-warning-border);
|
|
161
|
+
--liminis-editor-checkbox-border: var(--checkbox-border);
|
|
162
|
+
--liminis-editor-code-bg: var(--vscode-code-bg);
|
|
163
|
+
--liminis-editor-external-link: var(--vscode-external-link);
|
|
164
|
+
--liminis-editor-font-family: var(--vscode-font-family);
|
|
165
|
+
--liminis-editor-font-size: var(--vscode-font-size);
|
|
166
|
+
--liminis-editor-foreground: var(--vscode-foreground);
|
|
167
|
+
--liminis-editor-h1-color: var(--slashmd-h1-color);
|
|
168
|
+
--liminis-editor-h1-indent: var(--slashmd-h1-indent);
|
|
169
|
+
--liminis-editor-h2-color: var(--slashmd-h2-color);
|
|
170
|
+
--liminis-editor-h2-indent: var(--slashmd-h2-indent);
|
|
171
|
+
--liminis-editor-h3-color: var(--slashmd-h3-color);
|
|
172
|
+
--liminis-editor-h3-indent: var(--slashmd-h3-indent);
|
|
173
|
+
--liminis-editor-h4-color: var(--slashmd-h4-color);
|
|
174
|
+
--liminis-editor-h4-indent: var(--slashmd-h4-indent);
|
|
175
|
+
--liminis-editor-h5-color: var(--slashmd-h5-color);
|
|
176
|
+
--liminis-editor-h5-indent: var(--slashmd-h5-indent);
|
|
177
|
+
--liminis-editor-italic-color: var(--slashmd-italic-color);
|
|
178
|
+
--liminis-editor-link: var(--vscode-link);
|
|
179
|
+
--liminis-editor-selection: var(--vscode-selection);
|
|
180
|
+
--liminis-editor-token-comment: var(--slashmd-token-comment);
|
|
181
|
+
--liminis-editor-token-function: var(--slashmd-token-function);
|
|
182
|
+
--liminis-editor-token-keyword: var(--slashmd-token-keyword);
|
|
183
|
+
--liminis-editor-token-operator: var(--slashmd-token-operator);
|
|
184
|
+
--liminis-editor-token-property: var(--slashmd-token-property);
|
|
185
|
+
--liminis-editor-token-punctuation: var(--slashmd-token-punctuation);
|
|
186
|
+
--liminis-editor-token-selector: var(--slashmd-token-selector);
|
|
187
|
+
--liminis-editor-token-variable: var(--slashmd-token-variable);
|
|
188
|
+
|
|
189
|
+
/* Aliases preserving an existing nested consumption-site fallback chain —
|
|
190
|
+
these two legacy names have no --vscode-* declaration of their own, only
|
|
191
|
+
an existing fallback to a second legacy name at their consumption site. */
|
|
192
|
+
--liminis-editor-input-bg: var(--vscode-input-bg, var(--vscode-code-bg));
|
|
193
|
+
--liminis-editor-foreground-muted: var(--vscode-foreground-muted, var(--vscode-border));
|
|
194
|
+
|
|
195
|
+
/* Aliases for tokens with no CSS custom property backing anywhere — only an
|
|
196
|
+
inline literal fallback at their consumption site(s). The literal below
|
|
197
|
+
reproduces that existing light-mode fallback so a host supplying nothing
|
|
198
|
+
sees no change (FR-002); a host setting the legacy name still wins
|
|
199
|
+
(FR-003). Where the same token's literal differs by site (errorForeground,
|
|
200
|
+
toolbar-hoverBackground), a single canonical value is chosen here — see
|
|
201
|
+
ADR-93 for the two accepted visual deltas this causes at three sites. */
|
|
202
|
+
--liminis-editor-button-background: var(--vscode-button-background, #007acc);
|
|
203
|
+
--liminis-editor-button-foreground: var(--vscode-button-foreground, #ffffff);
|
|
204
|
+
--liminis-editor-menu-background: var(--vscode-menu-background, #ffffff);
|
|
205
|
+
--liminis-editor-menu-border: var(--vscode-menu-border, #d4d4d4);
|
|
206
|
+
--liminis-editor-menu-foreground: var(--vscode-menu-foreground, #333333);
|
|
207
|
+
--liminis-editor-menu-selectionBackground: var(--vscode-menu-selectionBackground, #e8e8e8);
|
|
208
|
+
--liminis-editor-menu-separatorBackground: var(--vscode-menu-separatorBackground, #d4d4d4);
|
|
209
|
+
--liminis-editor-toolbar-hoverBackground: var(--vscode-toolbar-hoverBackground, rgba(128, 128, 128, 0.15));
|
|
210
|
+
--liminis-editor-notificationsInfoIcon-foreground: var(--vscode-notificationsInfoIcon-foreground, #3794ff);
|
|
211
|
+
--liminis-editor-inputValidation-errorBackground: var(--vscode-inputValidation-errorBackground, rgba(255, 0, 0, 0.15));
|
|
212
|
+
--liminis-editor-errorForeground: var(--vscode-errorForeground, #f14c4c);
|
|
213
|
+
--liminis-editor-focus-border: var(--vscode-focus-border, #007acc);
|
|
214
|
+
--liminis-editor-focusBorder: var(--vscode-focusBorder, #007acc);
|
|
215
|
+
|
|
216
|
+
/* Aliases for liminis-app's own Tailwind @theme brand tokens — the package
|
|
217
|
+
only ever supplied a literal final fallback for these, never asserted
|
|
218
|
+
ownership; this alias makes that existing fallback reachable under the
|
|
219
|
+
new name too, without changing what it resolves to. */
|
|
220
|
+
--liminis-editor-primary: var(--color-primary, #3b82f6);
|
|
221
|
+
--liminis-editor-primary-100: var(--color-primary-100, rgba(59, 130, 246, 0.1));
|
|
222
|
+
--liminis-editor-muted-foreground: var(--color-muted-foreground, #6b7280);
|
|
223
|
+
--liminis-editor-muted-100: var(--color-muted-100, rgba(128, 128, 128, 0.1));
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.dark {
|
|
227
|
+
/* Dark-mode literal overrides for the subset of the no-CSS-backing group
|
|
228
|
+
above whose consumption sites select a different literal in dark mode
|
|
229
|
+
(via a JS `isDark`/`dark` check reading the same .dark class this
|
|
230
|
+
selector keys off) rather than a single literal used in both themes. */
|
|
231
|
+
--liminis-editor-button-background: var(--vscode-button-background, #0e639c);
|
|
232
|
+
--liminis-editor-menu-background: var(--vscode-menu-background, #252526);
|
|
233
|
+
--liminis-editor-menu-border: var(--vscode-menu-border, #454545);
|
|
234
|
+
--liminis-editor-menu-foreground: var(--vscode-menu-foreground, #cccccc);
|
|
235
|
+
--liminis-editor-menu-selectionBackground: var(--vscode-menu-selectionBackground, #094771);
|
|
236
|
+
--liminis-editor-menu-separatorBackground: var(--vscode-menu-separatorBackground, #454545);
|
|
237
|
+
}
|
|
238
|
+
|
|
110
239
|
* {
|
|
111
240
|
box-sizing: border-box;
|
|
112
241
|
}
|
|
@@ -1038,6 +1167,7 @@ body {
|
|
|
1038
1167
|
}
|
|
1039
1168
|
|
|
1040
1169
|
.drag-handle:hover .drag-handle-icon {
|
|
1170
|
+
/* Superseded by --liminis-editor-toolbar-hoverBackground's canonical 0.15-alpha default (ADR-93) */
|
|
1041
1171
|
background: var(--liminis-editor-toolbar-hoverBackground, var(--vscode-toolbar-hoverBackground, rgba(128, 128, 128, 0.1)));
|
|
1042
1172
|
}
|
|
1043
1173
|
|
|
@@ -1077,6 +1207,7 @@ body {
|
|
|
1077
1207
|
|
|
1078
1208
|
.block-delete-button:hover .block-delete-icon {
|
|
1079
1209
|
background: var(--liminis-editor-inputValidation-errorBackground, var(--vscode-inputValidation-errorBackground, rgba(255, 0, 0, 0.15)));
|
|
1210
|
+
/* Superseded by --liminis-editor-errorForeground's canonical #f14c4c default (ADR-93) */
|
|
1080
1211
|
color: var(--liminis-editor-errorForeground, var(--vscode-errorForeground, #f44336));
|
|
1081
1212
|
}
|
|
1082
1213
|
|
|
@@ -1592,6 +1723,7 @@ body {
|
|
|
1592
1723
|
}
|
|
1593
1724
|
|
|
1594
1725
|
.search-close-button:hover {
|
|
1726
|
+
/* Superseded by --liminis-editor-errorForeground's canonical #f14c4c default (ADR-93) */
|
|
1595
1727
|
color: var(--liminis-editor-errorForeground, var(--vscode-errorForeground, #f44336));
|
|
1596
1728
|
}
|
|
1597
1729
|
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# ADR-92: The Lexical Peer Range Bumps Forward by a Narrow Single Caret, Never a Wide Band
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-08-20
|
|
4
|
+
**Status:** Accepted
|
|
5
|
+
**Supersedes:** none
|
|
6
|
+
**Amends:** none
|
|
7
|
+
**Issue:** #92 (verveguy/liminis-editor)
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
|
|
11
|
+
Every published version of `@liminis/editor`, including `0.2.2`, declared its
|
|
12
|
+
Lexical peer range as `^0.44.0` across all twelve Lexical family packages
|
|
13
|
+
(`lexical` and eleven `@lexical/*` scoped packages). Lexical itself moved on
|
|
14
|
+
to `0.49.0`. Because Lexical is a `0.x` package, `^0.44.0` resolves under
|
|
15
|
+
semver to `>=0.44.0 <0.45.0` — it admits patch releases of 0.44 only, and
|
|
16
|
+
excludes every 0.45+ release regardless of whether that particular release
|
|
17
|
+
was actually breaking. The practical effect: this package pinned every host
|
|
18
|
+
application to a Lexical line five minors behind, with no published version
|
|
19
|
+
offering a path forward.
|
|
20
|
+
|
|
21
|
+
This surfaced while refreshing `liminis-app`'s dependencies
|
|
22
|
+
(verveguy/liminis#1026): the Lexical family was bumped 0.44.0 → 0.49.0 and
|
|
23
|
+
tested in isolation there. It passed `liminis-app`'s own typecheck, lint,
|
|
24
|
+
build, and 3275-test suite — and was still wrong, because `liminis-app` would
|
|
25
|
+
have shipped in violation of this package's declared peer contract. That
|
|
26
|
+
app's suite does not exercise the editor deeply enough for a green run to be
|
|
27
|
+
evidence of Lexical compatibility; the only suite that can answer that
|
|
28
|
+
question is this package's own.
|
|
29
|
+
|
|
30
|
+
The peer-range shape was an open question, not a foregone conclusion: widen
|
|
31
|
+
the range to admit 0.44 through 0.49 (matching the issue's own suggested
|
|
32
|
+
example), or narrow it to `^0.49.0` and drop 0.44–0.48 support outright.
|
|
33
|
+
|
|
34
|
+
## Decision
|
|
35
|
+
|
|
36
|
+
**The twelve Lexical peer ranges move to `^0.49.0` — a narrow single-caret
|
|
37
|
+
bump, not a wide multi-version band.** This is a deliberate, permanent
|
|
38
|
+
policy choice about how this package treats Lexical peer ranges going
|
|
39
|
+
forward, not a one-time bump: every future Lexical minor this package adopts
|
|
40
|
+
gets the same treatment — the range moves forward by exactly one caret,
|
|
41
|
+
paired with running the full suite against the new version, rather than
|
|
42
|
+
widening to claim a span of untested minors as compatible.
|
|
43
|
+
|
|
44
|
+
### Why narrow, not wide
|
|
45
|
+
|
|
46
|
+
**Widening a peer range later is patch-safe; narrowing one is breaking.**
|
|
47
|
+
Starting narrow keeps both options open — if a wide band is ever wanted, it
|
|
48
|
+
can be added without breaking anyone. Starting wide commits the package to a
|
|
49
|
+
claim it can only walk back by breaking whoever relied on the wide end.
|
|
50
|
+
|
|
51
|
+
**This package's existing range philosophy for `react` does not transfer to
|
|
52
|
+
Lexical.** The `//peerDependencies` manifest comment already documents that
|
|
53
|
+
ranges are "the compatibility contract, not the tested matrix," and that
|
|
54
|
+
narrowing `react`'s range to match its `devDependency` version "would only
|
|
55
|
+
reject working consumers." That reasoning is sound for React specifically
|
|
56
|
+
*because* React's untested span sits inside a **stable major** — a
|
|
57
|
+
regression there is a bug in React, not a permitted outcome of its
|
|
58
|
+
versioning scheme. Lexical is `0.x`, where semver explicitly permits every
|
|
59
|
+
minor release to be breaking. A range like `>=0.44.0 <0.50.0` would assert
|
|
60
|
+
compatibility with six minors, five of them never run against this
|
|
61
|
+
package's own suite — a materially different, and unjustified, claim.
|
|
62
|
+
|
|
63
|
+
**No known consumer wants Lexical 0.44.** Both known consumers of this
|
|
64
|
+
package (`liminis-app` and the package's own test/build pipeline) are moving
|
|
65
|
+
*toward* 0.49, not sitting on 0.44 and wanting to stay there. The wide
|
|
66
|
+
band's benefit — "don't reject a working consumer on an old version" — is
|
|
67
|
+
close to hypothetical here, while its cost — asserting untested compatibility
|
|
68
|
+
across four intermediate minors known to contain breaking changes (see
|
|
69
|
+
Consequences) — is real.
|
|
70
|
+
|
|
71
|
+
A wide band remains available later, but only backed by CI matrix testing
|
|
72
|
+
across the band's endpoints — that is separate work, out of scope for this
|
|
73
|
+
decision.
|
|
74
|
+
|
|
75
|
+
### What was verified before this decision was acted on
|
|
76
|
+
|
|
77
|
+
The twelve packages were bumped to `0.49.0` in both `peerDependencies` and
|
|
78
|
+
`devDependencies` (kept in lockstep, per this package's existing pairing
|
|
79
|
+
between the tested version and the declared floor), and the full
|
|
80
|
+
verification chain — `pnpm typecheck`, `pnpm lint`, `pnpm build`,
|
|
81
|
+
`pnpm test` (1591 tests), and `pnpm verify:package` (the packed-tarball
|
|
82
|
+
install-and-typecheck check against a fresh consumer) — ran clean with **no
|
|
83
|
+
source changes required**, despite Lexical's own changelog listing several
|
|
84
|
+
breaking changes in the 0.45–0.49 window (a `config()` protocol rework for
|
|
85
|
+
node classes in 0.49.0; `insertNodes` linebreak-handling changes and a
|
|
86
|
+
deprecated-export removal in 0.46.0; selection/backspace/reconcile changes
|
|
87
|
+
in 0.45.0). This package's sixteen custom Lexical node classes all define
|
|
88
|
+
explicit `getType`/`clone`/`importJSON` statics rather than relying on
|
|
89
|
+
auto-synthesis, which structurally avoided the highest-risk part of the
|
|
90
|
+
0.49.0 change; the rest of the changelog's items apparently do not intersect
|
|
91
|
+
this package's actual usage patterns, since the suite exercises them and
|
|
92
|
+
passed unmodified.
|
|
93
|
+
|
|
94
|
+
## Consequences
|
|
95
|
+
|
|
96
|
+
**Positive:**
|
|
97
|
+
|
|
98
|
+
- Consumers can now install this package alongside the current Lexical
|
|
99
|
+
release; the multi-minor stall the issue described cannot recur until
|
|
100
|
+
Lexical ships another minor this package hasn't yet adopted.
|
|
101
|
+
- The Lexical peer range's compatibility claim is now backed by an actual CI
|
|
102
|
+
run against the exact version it names — peer and devDependency are both
|
|
103
|
+
`0.49.0`, so no untested span exists in it. (React's own range still has
|
|
104
|
+
an intentionally untested lower half — peer `^19.2.0` vs. devDependency
|
|
105
|
+
`^19.2.5` — per the `//peerDependencies` note; that is unchanged by this
|
|
106
|
+
decision and follows the opposite, stable-major reasoning explained
|
|
107
|
+
above.)
|
|
108
|
+
- The policy is written down (`//lexicalPeerPolicy` in `package.json`, this
|
|
109
|
+
ADR, and the README's install section), so the next Lexical minor is a
|
|
110
|
+
known, bounded task rather than a rediscovery of this issue's reasoning.
|
|
111
|
+
|
|
112
|
+
**Negative:**
|
|
113
|
+
|
|
114
|
+
- **This is a breaking change.** `^0.44.0` and `^0.49.0` are non-overlapping
|
|
115
|
+
ranges; any consumer still on Lexical 0.44.0–0.48.x will see an
|
|
116
|
+
unmet-peer-dependency warning on installing the next release and must
|
|
117
|
+
upgrade its Lexical family to 0.49.0 first. That is the intended effect of
|
|
118
|
+
narrowing, not a regression.
|
|
119
|
+
- **The stall this issue describes will recur at every future Lexical
|
|
120
|
+
minor**, by design: this package's range never gets ahead of what it has
|
|
121
|
+
actually tested. The mitigation is that each recurrence is now a known,
|
|
122
|
+
bounded task (bump twelve versions, run the suite, adjust the range) with
|
|
123
|
+
a written rationale, rather than an accumulating five-minor gap discovered
|
|
124
|
+
incidentally by a downstream consumer's dependency refresh.
|
|
125
|
+
|
|
126
|
+
**Neutral:**
|
|
127
|
+
|
|
128
|
+
- `react`/`react-dom` peer ranges and all non-Lexical dependencies are
|
|
129
|
+
unaffected; this decision only concerns the Lexical family, and does not
|
|
130
|
+
reopen or alter the existing React range philosophy.
|
|
131
|
+
- No Lexical-API-floor guard test (the kind `tests/package-manifest-contract.test.ts`
|
|
132
|
+
already has for React) was added. That guard exists for React because its
|
|
133
|
+
range makes an untested-lower-half claim that needs policing; the narrow
|
|
134
|
+
Lexical range makes no such claim, so there is nothing analogous to guard
|
|
135
|
+
against.
|
|
136
|
+
|
|
137
|
+
## References
|
|
138
|
+
|
|
139
|
+
- Issue #92 (this decision), verveguy/liminis#1026 (the originating
|
|
140
|
+
`liminis-app` dependency refresh that surfaced the stall)
|
|
141
|
+
- `package.json` — the `//peerDependencies` and `//lexicalPeerPolicy`
|
|
142
|
+
manifest comments; the twelve `peerDependencies`/`devDependencies` entries
|
|
143
|
+
- `README.md` — "Install" section, the Lexical `pnpm add` block and the
|
|
144
|
+
peer-range policy callout
|
|
145
|
+
- `CHANGELOG.md` — the `## Unreleased` / `### Breaking changes` entry
|
|
146
|
+
recording this bump
|
|
147
|
+
- `docs/decisions/adr-078.md`, `docs/decisions/adr-079.md` — prior ADRs on
|
|
148
|
+
consumer-facing package surface, cited as precedent for treating this as
|
|
149
|
+
ADR-worthy
|
|
150
|
+
- Related: #78 (a required member made 0.2.0 type-level breaking), #79
|
|
151
|
+
(token definitions documented as public API) — prior instances of
|
|
152
|
+
consumer-facing surface needing explicit treatment
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
# ADR-93: `--liminis-editor-*` Names Are Defined as Aliases of Their Legacy Names
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-08-20
|
|
4
|
+
**Status:** Accepted
|
|
5
|
+
**Supersedes:** none
|
|
6
|
+
**Amends:** none
|
|
7
|
+
**Issue:** #93 (verveguy/liminis-editor)
|
|
8
|
+
|
|
9
|
+
## Context
|
|
10
|
+
|
|
11
|
+
ADR-087 (#51) renamed every *consumption* site to `--liminis-editor-*`,
|
|
12
|
+
deliberately leaving every *definition* site (`:root`, `.dark`, the
|
|
13
|
+
`@media print` block) declaring the old, pre-`0.2.0` names. ADR-092 (#79)
|
|
14
|
+
built a checked-in baseline guarding those definitions, and explicitly
|
|
15
|
+
deferred a third item: whether the package should ever *define*
|
|
16
|
+
`--liminis-editor-*` names directly, with the legacy names kept as an
|
|
17
|
+
alias layer underneath.
|
|
18
|
+
|
|
19
|
+
That gap is not theoretical. Zusammen, a downstream host, reads this
|
|
20
|
+
package's definitions directly — `var(--vscode-background)`,
|
|
21
|
+
`var(--vscode-border)`, etc. — mapping its own design-system tokens onto
|
|
22
|
+
them rather than overriding them
|
|
23
|
+
([verveguy/zusammen#129](https://github.com/verveguy/zusammen/issues/129)).
|
|
24
|
+
It wants to migrate those reads onto `--liminis-editor-*` instead, but
|
|
25
|
+
before this change there was nothing to migrate to: every row in the
|
|
26
|
+
README's token table read "Has a default: No (inline fallback only)."
|
|
27
|
+
|
|
28
|
+
**The naive fix is the trap ADR-087 already reasoned through once, now on
|
|
29
|
+
the definition side.** Adding `--liminis-editor-foreground: <default>;` to
|
|
30
|
+
the package's own `:root` unconditionally would resolve every one of the
|
|
31
|
+
250 consumption chains (`var(--liminis-editor-foreground, var(--vscode-foreground))`)
|
|
32
|
+
at the new name before ever reaching the old one — silently disabling the
|
|
33
|
+
ADR-087 fallback layer. A host like `liminis-app`, which supplies only
|
|
34
|
+
`--color-primary`/`--color-muted-foreground` (its own Tailwind `@theme`
|
|
35
|
+
tokens, coincidentally the fallback names `C4Component.tsx` already uses),
|
|
36
|
+
would stop tracking its own overrides with no error and no failing test —
|
|
37
|
+
exactly the failure mode ADR-092 exists to guard against.
|
|
38
|
+
|
|
39
|
+
Two further, non-obvious problems surfaced during implementation, not
|
|
40
|
+
anticipated by the plan:
|
|
41
|
+
|
|
42
|
+
1. **A definition-side alias's own `var()` reference is textually
|
|
43
|
+
indistinguishable from a consumption site.** `scripts/lib/theming-tokens.mjs`'s
|
|
44
|
+
`consumptionSitesIn()` scans raw text for depth-0 `var(--x` occurrences
|
|
45
|
+
with no awareness of whether the enclosing statement is a custom-property
|
|
46
|
+
*declaration* (`--liminis-editor-foreground: var(--vscode-foreground);`)
|
|
47
|
+
or an ordinary property/JS-style value (`color: var(--liminis-editor-foreground, ...)`).
|
|
48
|
+
Adding the alias block as originally planned would have made every one
|
|
49
|
+
of the ~40 flat-aliased legacy names register as a newly "consumed"
|
|
50
|
+
token, growing the README table and `TOKEN_DESCRIPTIONS` maintenance
|
|
51
|
+
surface for tokens no host-facing code actually reads — a regression
|
|
52
|
+
against this issue's own explicit Out of Scope ("does not add or remove
|
|
53
|
+
rows" from the consumed/documented table).
|
|
54
|
+
2. **A CSS block comment containing a literal `*/` substring inside its
|
|
55
|
+
text terminates early.** An early draft of the new `:root` block's
|
|
56
|
+
header comment read `--vscode-*/--slashmd-*/--checkbox-*` — the `*/`
|
|
57
|
+
embedded in `--vscode-*/--slashmd-*` closed the comment there, both for
|
|
58
|
+
real CSS parsers and for this repo's own `stripCssComments()`, leaving
|
|
59
|
+
the remainder of the intended comment as live (invalid) CSS text. This
|
|
60
|
+
would have shipped a real authoring bug, not just a test artifact.
|
|
61
|
+
|
|
62
|
+
## Decision
|
|
63
|
+
|
|
64
|
+
**Legacy names keep carrying the real defaults. Each `--liminis-editor-*`
|
|
65
|
+
name becomes a new declaration that reads its legacy name via `var()`** —
|
|
66
|
+
`--liminis-editor-foreground: var(--vscode-foreground);` — added in a new
|
|
67
|
+
`:root`/`.dark` block placed immediately after the package's existing
|
|
68
|
+
`:root`/`.dark` blocks in `src/styles.css`. This is the direction the
|
|
69
|
+
spec's Background illustrated and Research confirmed by inspecting this
|
|
70
|
+
file's cascade structure directly: a CSS custom property resolves against
|
|
71
|
+
the *element's own* cascade at the point of use, not at declaration time,
|
|
72
|
+
so a single `:root`-level alias re-resolves correctly through `.dark`'s and
|
|
73
|
+
the `@media print` block's overrides of the *legacy* name it points to —
|
|
74
|
+
no per-block alias duplication is needed, and neither `.dark` nor the print
|
|
75
|
+
block needed to change for the ~40 tokens with a real existing declaration.
|
|
76
|
+
|
|
77
|
+
**All 59 renamed tokens (`PREVIOUS_NAME`'s full set) get a real declaration
|
|
78
|
+
in this pass, not only the two the originating issue named.** FR-001 says
|
|
79
|
+
"every token it currently consumes"; inspection of every consumption site
|
|
80
|
+
found 19 tokens with no existing `:root`/`.dark` legacy declaration to
|
|
81
|
+
alias to, not 2, split into three groups:
|
|
82
|
+
|
|
83
|
+
- **2 tokens** (`--vscode-input-bg`, `--vscode-foreground-muted`) resolve
|
|
84
|
+
today through an existing *nested* fallback at their own consumption
|
|
85
|
+
site. Their alias preserves that chain rather than flattening it:
|
|
86
|
+
`--liminis-editor-input-bg: var(--vscode-input-bg, var(--vscode-code-bg));`.
|
|
87
|
+
- **13 tokens** have no CSS custom property backing anywhere — only a
|
|
88
|
+
literal inline fallback at each consumption site (e.g.
|
|
89
|
+
`var(--vscode-focus-border, #007acc)`). Their alias reproduces that
|
|
90
|
+
literal as the alias's own fallback:
|
|
91
|
+
`--liminis-editor-focus-border: var(--vscode-focus-border, #007acc);` —
|
|
92
|
+
a host supplying nothing sees the same literal as before (FR-002); a
|
|
93
|
+
host supplying the legacy name still wins (FR-003). 6 of these 13 vary by
|
|
94
|
+
theme via a JS `isDark`/`dark` ternary at their consumption sites
|
|
95
|
+
(`button-background`, all 5 `menu-*` tokens); those 6 get a matching
|
|
96
|
+
`.dark` override in the new block, mirroring the same light/dark split
|
|
97
|
+
their consumption sites already express in JS.
|
|
98
|
+
- **4 tokens** (`--color-primary`, `--color-primary-100`,
|
|
99
|
+
`--color-muted-foreground`, `--color-muted-100`) are `liminis-app`'s own
|
|
100
|
+
Tailwind `@theme` brand tokens, for which the package only ever supplied
|
|
101
|
+
a literal final fallback, never asserted ownership. They are aliased
|
|
102
|
+
identically to the 13 above — the mechanism doesn't newly assert
|
|
103
|
+
ownership, it makes the existing fallback literal reachable under the new
|
|
104
|
+
name too.
|
|
105
|
+
|
|
106
|
+
**Two of the 17 no-backing tokens have a real cross-site literal
|
|
107
|
+
inconsistency, discovered by direct inspection (one — `--vscode-errorForeground`
|
|
108
|
+
— was already flagged by Specify; the second — `--vscode-toolbar-hoverBackground`
|
|
109
|
+
— was not):**
|
|
110
|
+
|
|
111
|
+
| Token | Sites | Canonical value chosen |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| `--vscode-errorForeground` | `#f14c4c` (2 sites: `.editor-link-broken`, `:hover`) vs. `#f44336` (2 sites: `.block-delete-button:hover .block-delete-icon`, `.search-close-button:hover`) | `#f14c4c` — tie broken toward the more semantically central "broken link" indicator over two hover-only chrome details |
|
|
114
|
+
| `--vscode-toolbar-hoverBackground` | `rgba(128, 128, 128, 0.15)` (2 sites) vs. `rgba(128, 128, 128, 0.1)` (1 site, `.drag-handle:hover .drag-handle-icon`) | `rgba(128, 128, 128, 0.15)` — majority (2 of 3) |
|
|
115
|
+
|
|
116
|
+
Once a token has a single real definition, it necessarily wins over every
|
|
117
|
+
site's own inline fallback (fallback only applies when the property is
|
|
118
|
+
genuinely unset) — there is no mechanism that both defines the token
|
|
119
|
+
(FR-001) and preserves two different resolved values at different sites.
|
|
120
|
+
**This unifies 3 sites' rendered color to the canonical value, a small,
|
|
121
|
+
real, intentional visual change**, called out here per this repository's
|
|
122
|
+
convention of recording what a decision costs. The three affected call
|
|
123
|
+
sites (`src/styles.css:1148`, `:1188`, `:1704`) each carry a one-line
|
|
124
|
+
comment noting they are superseded by the new canonical default. The
|
|
125
|
+
spec's Out of Scope section explicitly permits this as a side effect of
|
|
126
|
+
choosing FR-001's value, not as a design goal in its own right.
|
|
127
|
+
|
|
128
|
+
**Consumption sites are left untouched.** All 224 `styles.css` sites and 26
|
|
129
|
+
`.tsx` sites keep their existing `var(--liminis-editor-x, var(--old-name-x, ...))`
|
|
130
|
+
chains. Simplifying them to a single `var(--liminis-editor-x)` call was
|
|
131
|
+
identified as optional cleanup (spec Assumptions) but would strip every
|
|
132
|
+
renamed token's `immediateFallback`, breaking `resolvesToPreviousName()`
|
|
133
|
+
(FR-011's existing drift guard) for all 59 tokens unless that guard were
|
|
134
|
+
also redesigned to check the *definition* site's alias target instead —
|
|
135
|
+
a materially larger, coordinated change deferred out of this issue's scope.
|
|
136
|
+
The now-redundant nested legacy fallback at each site is provably dead code
|
|
137
|
+
once its definition-side alias exists, left in place rather than removed.
|
|
138
|
+
|
|
139
|
+
**`scripts/lib/theming-tokens.mjs`'s `consumptionSitesIn()` gains a
|
|
140
|
+
declaration-value check.** A new helper,
|
|
141
|
+
`isCustomPropertyDeclarationValue(text, varStartIndex)`, walks back from a
|
|
142
|
+
depth-0 `var(` to the nearest statement boundary (`;`, `{`, or `}`) and
|
|
143
|
+
tests whether everything between that boundary and the `var(` is exactly
|
|
144
|
+
`--name:` — the shape only a custom-property declaration's value position
|
|
145
|
+
can have (an ordinary CSS property name never starts with `--`). Each
|
|
146
|
+
site now carries an `isDeclarationValue` flag; `consumedTokens()`'s Pass 1
|
|
147
|
+
skips depth-0 sites where it is true. This keeps the "consumed" inventory —
|
|
148
|
+
and therefore the README table's row set and the `TOKEN_DESCRIPTIONS`
|
|
149
|
+
maintenance surface — exactly as it was before this issue, satisfying its
|
|
150
|
+
Out of Scope constraint, while still letting `defaultedTokens()` (a
|
|
151
|
+
separate, unchanged function that just scans for any `--name:` declaration)
|
|
152
|
+
pick up all 59 new aliases as newly "defined."
|
|
153
|
+
|
|
154
|
+
**No other change to `theming-tokens.mjs` or its `.d.mts`.**
|
|
155
|
+
`isCustomPropertyDeclarationValue` is internal, not exported;
|
|
156
|
+
`defaultedTokens()` needed no change to recognize the new aliases; the
|
|
157
|
+
ADR-092 baseline guard, `resolvesWithoutHost()`, and `resolvesToPreviousName()`
|
|
158
|
+
all continue to operate over the same "consumed"/"defined" definitions they
|
|
159
|
+
already had, now simply seeing a larger defined set.
|
|
160
|
+
|
|
161
|
+
## Consequences
|
|
162
|
+
|
|
163
|
+
**Good:**
|
|
164
|
+
|
|
165
|
+
- A host can now read `--liminis-editor-x` directly and get a real value in
|
|
166
|
+
every override state — the entire point of this issue and the
|
|
167
|
+
prerequisite for zusammen#129's read migration (FR-001, SC-001, SC-006).
|
|
168
|
+
- A host supplying only a legacy name **at `:root`/`document.documentElement`**
|
|
169
|
+
is unaffected: the alias's `var()` re-resolves through that name's own
|
|
170
|
+
`.dark`/`@media print` overrides at the point of use, verified directly
|
|
171
|
+
against this file's actual cascade structure rather than assumed from the
|
|
172
|
+
general CSS-custom-property theory alone (FR-002, FR-003, User Story 2).
|
|
173
|
+
This is the standard integration point and the one this package's own
|
|
174
|
+
e2e coverage exercises. It does not extend to a legacy override scoped to
|
|
175
|
+
an arbitrary descendant element — see Bad/accepted below.
|
|
176
|
+
- The ADR-092 baseline guard now protects all 59 new alias declarations the
|
|
177
|
+
same way it already protected the legacy ones — a future accidental
|
|
178
|
+
deletion of an alias fails `pnpm test`, naming the token (FR-005, US4).
|
|
179
|
+
- The declaration-value fix to `consumptionSitesIn()` is general: it holds
|
|
180
|
+
for any future alias declaration of this shape without further
|
|
181
|
+
special-casing, not just the 59 added here.
|
|
182
|
+
- The premature-comment-close bug was caught by the same regenerated test
|
|
183
|
+
suite that caught the consumption-site pollution, before either shipped —
|
|
184
|
+
the CI guards this issue extends are what surfaced both problems.
|
|
185
|
+
|
|
186
|
+
**Bad / accepted:**
|
|
187
|
+
|
|
188
|
+
- **The `:root`-only alias does not track a legacy-name override scoped to
|
|
189
|
+
a descendant element below `:root`** (e.g. a per-widget wrapper div a
|
|
190
|
+
host applies its own theme vars to, rather than `document.documentElement`
|
|
191
|
+
itself) — found during PR review (CodeRabbit), confirmed empirically in
|
|
192
|
+
a running Electron app, not merely reasoned about. A custom property
|
|
193
|
+
inherits its parent's already-*computed* value, not the `var()`
|
|
194
|
+
expression that produced it, so the alias's `var(--legacy-x)` is fixed
|
|
195
|
+
using `:root`'s own value of `--legacy-x` and does not re-evaluate for a
|
|
196
|
+
change made further down the tree. Two alternatives were tried and
|
|
197
|
+
rejected, each empirically, in a running app:
|
|
198
|
+
- **Re-declaring the alias on every element (`*`)** does fix the
|
|
199
|
+
descendant case, but then an element's own `*`-matched declaration
|
|
200
|
+
shadows whatever `--liminis-editor-x` value it would otherwise have
|
|
201
|
+
inherited from an ancestor — including a host's own direct
|
|
202
|
+
`--liminis-editor-x` override set on that ancestor. This broke User
|
|
203
|
+
Story 3 (a directly-set `--liminis-editor-*` name must win), which is
|
|
204
|
+
higher-confidence/already-tested behavior — confirmed by a real,
|
|
205
|
+
reproducible test failure, not a theoretical concern.
|
|
206
|
+
- **Scoping the redeclaration to the package's own root wrapper class**
|
|
207
|
+
(`.editor-app-root`) reduces but does not eliminate that same
|
|
208
|
+
shadowing (still breaks a `--liminis-editor-*` override set above
|
|
209
|
+
`.editor-app-root`), and is additionally unreliable on its own terms:
|
|
210
|
+
not every integration renders that wrapper — this repo's own
|
|
211
|
+
`examples/electron` shell mounts a lower-level component without it,
|
|
212
|
+
so the alias would go undeclared there, confirmed by inspecting the
|
|
213
|
+
actual DOM in a running instance.
|
|
214
|
+
- No mechanism was found that recomputes a legacy-name change made
|
|
215
|
+
anywhere below `:root` (User Story 2) while also respecting a
|
|
216
|
+
`--liminis-editor-*` override set on any ancestor of the read element
|
|
217
|
+
(User Story 3) — CSS custom-property inheritance passes down an
|
|
218
|
+
already-resolved value, not a live formula, so a property can prefer
|
|
219
|
+
"inherit if my ancestor set one" or "always recompute from a
|
|
220
|
+
dependency," but not both conditionally per-element without a
|
|
221
|
+
mechanism this package doesn't have (e.g. `@property` plus JS
|
|
222
|
+
reconciliation, well beyond this issue's scope). **The `:root`-only
|
|
223
|
+
design is kept, and this scope limitation is accepted and documented**
|
|
224
|
+
here and in `src/styles.css`'s alias-block comment, per this
|
|
225
|
+
repository's convention of recording what a decision costs rather than
|
|
226
|
+
silently narrowing FR-002/FR-003's stated guarantee. Extending it to
|
|
227
|
+
arbitrary DOM scope, if a specific host needs it, is deferred to a
|
|
228
|
+
follow-up issue — it is a materially larger design problem than this
|
|
229
|
+
ADR anticipated.
|
|
230
|
+
- Three consumption sites (`--vscode-errorForeground` at 2 sites,
|
|
231
|
+
`--vscode-toolbar-hoverBackground` at 1 site) render a different,
|
|
232
|
+
intentionally-unified color than before this change. A host relying on
|
|
233
|
+
the specific pre-existing `#f44336`/`0.1`-alpha rendering at exactly
|
|
234
|
+
those sites will see a small visual shift. This is an unavoidable
|
|
235
|
+
consequence of giving these two tokens a single real definition (FR-001)
|
|
236
|
+
when their own consumption sites already disagreed with each other —
|
|
237
|
+
there is no mechanism that satisfies FR-001 without picking one value.
|
|
238
|
+
- The checked-in baseline grows from 41 to 100 entries in one change. Per
|
|
239
|
+
ADR-092's own design the guard is one-directional (`missing` fails,
|
|
240
|
+
`added` never does), so this is a mechanical `pnpm docs:theming-baseline`
|
|
241
|
+
diff, not a CI risk — but it is a large diff for a human reviewer to
|
|
242
|
+
read line-by-line.
|
|
243
|
+
- Every one of the 250 existing consumption sites keeps a nested legacy
|
|
244
|
+
fallback that is now provably redundant dead code (the definition-side
|
|
245
|
+
alias means the fallback branch can never be reached in practice). Removing
|
|
246
|
+
it was explicitly deferred (see Decision) rather than done here, so this
|
|
247
|
+
verbosity persists in `styles.css` and the five `.tsx` files until a
|
|
248
|
+
future change picks it up.
|
|
249
|
+
- `consumptionSitesIn()`'s declaration-value detection is a text-boundary
|
|
250
|
+
heuristic (nearest `;`/`{`/`}` before the `var(`), not a real CSS parser.
|
|
251
|
+
It is correct for every declaration in this codebase today (all
|
|
252
|
+
single-line), but a future multi-line custom-property declaration split
|
|
253
|
+
across a statement boundary could evade it.
|
|
254
|
+
|
|
255
|
+
**Neutral:**
|
|
256
|
+
|
|
257
|
+
- The `@media print` block needed no changes: its `:root, .dark { ... }`
|
|
258
|
+
selector already overrides every legacy name it touches, and each new
|
|
259
|
+
alias's `var()` reference re-resolves through that override the same way
|
|
260
|
+
it re-resolves through `.dark`'s.
|
|
261
|
+
- `liminis-app`'s own `--color-primary`/`--color-muted-foreground` overrides
|
|
262
|
+
are unaffected either way — the 4 brand-token aliases only make their
|
|
263
|
+
existing fallback literal reachable under the new name too, without
|
|
264
|
+
changing what either name resolves to when the host supplies its usual
|
|
265
|
+
overrides (SC-003).
|
|
266
|
+
|
|
267
|
+
## References
|
|
268
|
+
|
|
269
|
+
- Issue #93 (this decision); Issue #79 / ADR-092's "Not decided here" —
|
|
270
|
+
this decision's direct origin (Item 3)
|
|
271
|
+
- `docs/decisions/adr-087.md` — the consumption-side rename and fallback
|
|
272
|
+
design this decision extends to the definition side, and the trap
|
|
273
|
+
("that alternative is broken...") this decision's alias direction avoids
|
|
274
|
+
repeating on the definition side
|
|
275
|
+
- `docs/decisions/adr-092.md` — the checked-in baseline guard this
|
|
276
|
+
decision's new declarations are added to
|
|
277
|
+
- `src/styles.css` — the new `:root`/`.dark` alias block (after the
|
|
278
|
+
existing `.dark` block); the three superseded-literal comments at the
|
|
279
|
+
drag-handle-hover, block-delete-hover, and search-close-hover sites
|
|
280
|
+
- `scripts/lib/theming-tokens.mjs` — `isCustomPropertyDeclarationValue()`,
|
|
281
|
+
`consumptionSitesIn()`'s new `isDeclarationValue` field, and
|
|
282
|
+
`consumedTokens()`'s Pass 1 filter
|
|
283
|
+
- `scripts/lib/theming-defined-tokens-baseline.json` — regenerated via
|
|
284
|
+
`pnpm docs:theming-baseline`, 41 → 100 entries
|
|
285
|
+
- `README.md`, "Theming: CSS custom properties" — regenerated table and
|
|
286
|
+
hand-rewritten prose describing the alias mechanism
|
|
287
|
+
- [verveguy/zusammen#129](https://github.com/verveguy/zusammen/issues/129)
|
|
288
|
+
— the downstream migration this decision unblocks
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liminis/editor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"//publishing": "Publishing is deliberate, never incidental. `private: true` was this package's guard until verveguy/liminis-editor#39 took the publish decision; it is gone because that decision was taken, not because it was tidied away. The guard is now `prepublishOnly` -> scripts/guard-publish.mjs, which refuses unless LIMINIS_ALLOW_PUBLISH=1 is set explicitly. That variable is set at step scope in .github/workflows/publish.yml and nowhere else, so a release is the only path that publishes. Note that `npm publish --dry-run` does NOT report a private package as blocked (npm 10.8.2), which is why the guard is a script rather than a flag.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Lexical-based markdown WYSIWYG editor with mdast round-trip and a host-injection seam",
|
|
@@ -80,20 +80,21 @@
|
|
|
80
80
|
"build:examples": "node scripts/build-examples.mjs",
|
|
81
81
|
"build:site": "node scripts/build-site.mjs"
|
|
82
82
|
},
|
|
83
|
-
"//peerDependencies": "Ranges are the compatibility contract, not the tested matrix. CI resolves one point version per range (currently react 19.2.x latest and lexical 0.
|
|
83
|
+
"//peerDependencies": "Ranges are the compatibility contract, not the tested matrix. CI resolves one point version per range (currently react 19.2.x latest and lexical 0.49.x latest), so every caret range here has an untested lower half \u2014 narrowing `react` to the devDependency's `^19.2.5` would not change that, it would only reject working consumers. The react floor is not a claim, it is enforced: `tests/package-manifest-contract.test.ts` (\"imports no React API newer than the declared 19.2.0 peer floor\") scans every source file for post-19.0 named imports \u2014 `useEffectEvent`, `Activity`, `cacheSignal`, `ViewTransition`, `captureOwnerStack` \u2014 and fails if one appears. Reaching for a newer API therefore breaks CI until you raise the floor here too, which is the pairing this note would otherwise only assert. Raise a floor when the code actually starts needing a later API, not to mirror whatever CI happened to install. This reasoning does not extend to the Lexical ranges below \u2014 see `//lexicalPeerPolicy`.",
|
|
84
|
+
"//lexicalPeerPolicy": "The twelve Lexical ranges are a single-caret bump per Lexical minor actually adopted and tested here, not a wide multi-version band. `react`'s untested lower half (above) is safe because a break there would be a bug in a stable major; Lexical is `0.x`, where every minor is permitted to break, so a wide band would claim compatibility with untested, potentially-breaking releases. Widening a range later is patch-safe; narrowing one is breaking \u2014 so this stays narrow by default and moves forward only when the code is actually run against the new minor. See docs/decisions/adr-92-lexical-peer-range-policy.md.",
|
|
84
85
|
"peerDependencies": {
|
|
85
|
-
"@lexical/code": "^0.
|
|
86
|
-
"@lexical/code-prism": "^0.
|
|
87
|
-
"@lexical/link": "^0.
|
|
88
|
-
"@lexical/list": "^0.
|
|
89
|
-
"@lexical/mark": "^0.
|
|
90
|
-
"@lexical/markdown": "^0.
|
|
91
|
-
"@lexical/react": "^0.
|
|
92
|
-
"@lexical/rich-text": "^0.
|
|
93
|
-
"@lexical/selection": "^0.
|
|
94
|
-
"@lexical/table": "^0.
|
|
95
|
-
"@lexical/utils": "^0.
|
|
96
|
-
"lexical": "^0.
|
|
86
|
+
"@lexical/code": "^0.49.0",
|
|
87
|
+
"@lexical/code-prism": "^0.49.0",
|
|
88
|
+
"@lexical/link": "^0.49.0",
|
|
89
|
+
"@lexical/list": "^0.49.0",
|
|
90
|
+
"@lexical/mark": "^0.49.0",
|
|
91
|
+
"@lexical/markdown": "^0.49.0",
|
|
92
|
+
"@lexical/react": "^0.49.0",
|
|
93
|
+
"@lexical/rich-text": "^0.49.0",
|
|
94
|
+
"@lexical/selection": "^0.49.0",
|
|
95
|
+
"@lexical/table": "^0.49.0",
|
|
96
|
+
"@lexical/utils": "^0.49.0",
|
|
97
|
+
"lexical": "^0.49.0",
|
|
97
98
|
"react": "^19.2.0",
|
|
98
99
|
"react-dom": "^19.2.0"
|
|
99
100
|
},
|
|
@@ -122,17 +123,17 @@
|
|
|
122
123
|
},
|
|
123
124
|
"devDependencies": {
|
|
124
125
|
"@eslint/js": "^10.0.1",
|
|
125
|
-
"@lexical/code": "^0.
|
|
126
|
-
"@lexical/code-prism": "^0.
|
|
127
|
-
"@lexical/link": "^0.
|
|
128
|
-
"@lexical/list": "^0.
|
|
129
|
-
"@lexical/mark": "^0.
|
|
130
|
-
"@lexical/markdown": "^0.
|
|
131
|
-
"@lexical/react": "^0.
|
|
132
|
-
"@lexical/rich-text": "^0.
|
|
133
|
-
"@lexical/selection": "^0.
|
|
134
|
-
"@lexical/table": "^0.
|
|
135
|
-
"@lexical/utils": "^0.
|
|
126
|
+
"@lexical/code": "^0.49.0",
|
|
127
|
+
"@lexical/code-prism": "^0.49.0",
|
|
128
|
+
"@lexical/link": "^0.49.0",
|
|
129
|
+
"@lexical/list": "^0.49.0",
|
|
130
|
+
"@lexical/mark": "^0.49.0",
|
|
131
|
+
"@lexical/markdown": "^0.49.0",
|
|
132
|
+
"@lexical/react": "^0.49.0",
|
|
133
|
+
"@lexical/rich-text": "^0.49.0",
|
|
134
|
+
"@lexical/selection": "^0.49.0",
|
|
135
|
+
"@lexical/table": "^0.49.0",
|
|
136
|
+
"@lexical/utils": "^0.49.0",
|
|
136
137
|
"@testing-library/react": "^16.3.2",
|
|
137
138
|
"@types/mdast": "^4.0.4",
|
|
138
139
|
"@types/node": "^25.6.0",
|
|
@@ -146,7 +147,7 @@
|
|
|
146
147
|
"eslint-plugin-react-refresh": "^0.5.2",
|
|
147
148
|
"globals": "^17.5.0",
|
|
148
149
|
"happy-dom": "^20.9.0",
|
|
149
|
-
"lexical": "^0.
|
|
150
|
+
"lexical": "^0.49.0",
|
|
150
151
|
"react": "^19.2.5",
|
|
151
152
|
"react-dom": "^19.2.5",
|
|
152
153
|
"tsc-alias": "^1.9.1",
|