@taprootio/espalier 4.17.0 → 4.19.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/CHANGELOG.md +23 -0
- package/custom-elements.json +2542 -2400
- package/dist/cli/theme-check.js +2 -2
- package/dist/date-picker/helpers/styles.js +17 -7
- package/dist/footer/esp-footer.d.ts +1 -0
- package/dist/footer/esp-footer.js +8 -5
- package/dist/header/esp-header-button.d.ts +37 -0
- package/dist/header/esp-header-button.js +9 -4
- package/dist/header/esp-header.d.ts +1 -0
- package/dist/header/esp-header.js +7 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/shared/configured-brand.d.ts +46 -0
- package/dist/shared/configured-brand.js +8 -4
- package/dist/shared/theme-fit-report.d.ts +38 -2
- package/dist/shared/theme-fit-report.js +1 -1
- package/dist/shared/theme.d.ts +50 -0
- package/dist/shared/theme.js +1 -1
- package/espalier.css-data.json +8 -0
- package/espalier.token-manifest.json +12 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
# 4.19.0
|
|
2
|
+
|
|
3
|
+
Filled action labels meet their contrast target, and the theme fit report says when a brand colour did not survive the compile.
|
|
4
|
+
|
|
5
|
+
- **The default filled action changed colour in the light scheme, and this is visible on any site that has not pinned it.** `--esp-color-action-background` resolved to the `raised3` ramp stop in both schemes, which is L 0.80 in the light ramp — a lightness where no ink, not even pure black, reaches the Lc 75 that APCA asks of a button label. Contrast enforcement walked the label to black and stopped 3.7 short, so the stock light theme shipped a button it could not make legible. The mapping is now chosen per scheme: `muted` in light, giving a mid-band surface with a pale label at Lc 76.0, and `raised3` in dark, which is what it already was — **the dark scheme's action pair is unchanged**, at Lc 81.6. Those are the stops a theme declaring an `action` role has always compiled to, so naming a role no longer moves the button either. A theme that pins `semanticMappings.actionBackground` is unaffected.
|
|
6
|
+
- The date picker now reads each of its inks against the surface it sits on. Its focus rings take `--esp-color-text`, which is enforced against the page ground the calendar paints on; they had been taking `--esp-color-action-text`, which is only guaranteed on a filled action and happened to match only while the light theme's action label was near-black. A ring drawn *inside* a selected day is the exception — that cell paints the action surface, so its ring takes `--esp-color-action-text`, and so does today's marker when today is the selected day, where it previously took `--esp-color-border`. A selected day now paints the action pair itself — `--esp-color-action-background` under `--esp-color-action-text` — which is the one surface/ink pairing the engine enforces, reaching Lc 76.0 in light where the old layer-3 ground left its label at 71.3 with nothing guaranteeing it. **A selected day is a deeper, filled swatch in the light scheme as a result.** The dark scheme is unchanged: there the layer-3 and action surfaces resolve to the same colour.
|
|
7
|
+
- `themeFitLints()` gains **`action-anchor-inversion`**. It fires when a filled action renders the opposite way round from the swatches it names — a surface whose swatch wants dark ink took light ink instead, or a declared `action.color`/`action.ink` pair's lightness order reversed. This is the one case where reading the report's per-token deltas does not help: an action's ramp stop is chosen by the engine rather than named by the theme, so re-seating the ramp — the remedy for every other anchored token — cannot move it, and the fix is to pin the token. A brand whose action colour is a light gold or a pastel is the case to watch.
|
|
8
|
+
- `themeFitLints()` gains **`apca-target-unmet`**. It fires when enforcement moved a text token as far as its ramp allows and the pair still missed the legibility floor. The message says which of two things went wrong, measured rather than assumed: the emitted ink is on the weaker side when the opposite pole would have cleared that ground, or the ground itself cannot carry the floor under any ink. It judges against the token's own tier or Lc 75, whichever is lower, so a caption that misses the preferred Lc 90 tier on a tinted wash stays quiet while genuinely illegible text does not.
|
|
9
|
+
- **Both lints are gated.** `espalier theme check` already exits non-zero on any lint, so a theme that trips either one will start failing that command. The per-surface `lints` arrays are part of the committed `--expect` tables, so a theme whose action pair or contrast floor is affected needs one reviewed `--update-expect` refresh.
|
|
10
|
+
- `ThemeFitToken` gains `pairing`, `"declared"` or `"derived"`, on a role-paired ink. `action.ink` defaults to the canvas colour, so an ink that was *derived* is the page ground by contract and is re-lit to the far end of the ramp on purpose — its large `anchor.deltaE` is the contract working, not a brand that went missing. The field is what lets `action-anchor-inversion` leave that case alone. It validates as optional, so a fit table written before this release reports the addition as ordinary drift rather than an unreadable-file error.
|
|
11
|
+
- A theme that declares `action.ink` now derives that ink's ramp stop from the action surface it actually sits on, the same way an undeclared ink already did. Naming the slot still chooses the colour family; the ramp still supplies the lightness. In a light scheme both rules already agreed, so nothing moves there. In a dark scheme the named slot used to start on the wrong side of the ramp and rely on enforcement to carry it back, emitting a weaker label than the ramp could give.
|
|
12
|
+
- The lightness-ramp guide now says which stop its seating procedure cannot reach, and why pinning a light action swatch may still not give you a legible button: under APCA the Lc 75 label tier is unreachable across a mid band of roughly L 0.55 to L 0.83, so a swatch inside it cannot hold a button label at its own lightness — though pinning the stop just past the band often can.
|
|
13
|
+
|
|
14
|
+
# 4.18.0
|
|
15
|
+
|
|
16
|
+
A brand logo holds its place before it loads, the header's menu button is one button, and a stored theme's declared roles finally take effect.
|
|
17
|
+
|
|
18
|
+
- A configured brand logo now reserves its box before the image arrives. Previously the header and footer gave the logo a fixed height and let the image decide its width — so until the bytes landed there was nothing to decide it with: the brand region collapsed to nothing on first paint, and widened to fit the alt text whenever a logo failed to load. Because both schemes swap the logo at runtime, that happened again on every scheme change. A logo that loads is laid out exactly as before, at its own proportions.
|
|
19
|
+
- `--esp-header-brand-logo-aspect-ratio` and `--esp-footer-brand-logo-aspect-ratio` set the proportions of that reserved box (`3 / 1` by default). Set one to your logo's real ratio — per scheme, if your light and dark assets differ — and the region does not resize at all when the image arrives. A loaded image always wins over this value, so it can never crop or letterbox a logo that renders correctly today.
|
|
20
|
+
- The header's menu button is now a single control. It used to expose button semantics twice — once on the `esp-header-button` element and again on the button inside it, under the same name — so screen readers announced a button inside a button and `getByRole("button", { name: "Close navigation" })` matched two elements. It now matches one, and a strict-mode locator that used to fail on the ambiguity works as written. **The elements are unchanged** — same tags, same classes, same nesting — so selectors that name them are unaffected. Two things do change: the outer element no longer carries `role="button"`, so a selector matching on that attribute no longer matches; and a locator that worked around the double match by asking for the *second* of the two (`.nth(1)`) now resolves to nothing. `.first()` and `.last()` both still resolve, to the one remaining button. Keyboard activation, focus placement and return, and the single `esp-clicked` per click or key press are unchanged.
|
|
21
|
+
- `esp-header-button` forwards `aria-controls` and `aria-expanded` to its inner button, alongside the `aria-label` it already forwarded. Set them on the element and they reach the control that actually owns the semantics. Buttons that set neither are unaffected. One limit worth knowing, unchanged by this release: `aria-controls` is an id reference, and a browser resolves it only within the tree the referring element is in — so a value naming an element outside the button's shadow root, such as `esp-header`'s own `drawer-target`, is present as an attribute but resolves to no relationship. `aria-expanded` and `aria-label` are unaffected, since neither is a reference.
|
|
22
|
+
- A stored theme that carries cached color mappings no longer overrides the roles it declares. A theme document that records every resolved mapping plus a marker for which ones a person actually authored was having every mapping treated as authored, so declaring a new `canvas` or `ink` role changed nothing. The roles now recompile the mappings the marker does not claim. **This is visible**: a site whose stored theme carries cached mappings *and* declares roles will see its role-derived colors move to what those roles ask for — which is what it asked for. The rule is the one the marker states, and it is worth reading literally: any mapping the marker does not claim may now move — to what the theme's roles compile, or, where no role produces that token, to whatever it would have resolved to had the entry not been stored at all (the default, or for the type inks the body text mapping, which may itself be a pin you authored). An authored pin never moves. Documents with no marker at all are untouched, and so is a marked document whose stored mappings already match what this version resolves for it — which is why regenerating a default-theme artifact from this version produces identical output.
|
|
23
|
+
|
|
1
24
|
# 4.17.0
|
|
2
25
|
|
|
3
26
|
A banner can dissolve into the section beneath it, and a lightbox swipe stays in the lightbox.
|