Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p

## [Unreleased]

### Added

- `utils`
- `useComputedStyleFallback` option for `CssCustomProperties`: if the CSSOM does not provide any property name for the used selector, e.g. because the declarations are part of a constructed and adopted stylesheet, then the names are read from the computed style of the matching element; disabled by default because the computed style also contains all inherited custom properties

### Changed

- `<CodeEditor />`
Expand All @@ -14,6 +19,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- the two-column display is only used if the container is wide enough, this way property name columns do not get too small
- in narrower containers, property name and value are displayed as stacked rows
- make the breakpoint configurable via SCSS (`$eccgui-propertyvalue-size-column-breakpoint-small`)
- `utils`
- values of CSS custom properties are resolved via the computed style of a matching element now, so they always represent what the browser really applies, e.g. references to other custom properties are already replaced

### Fixed

Expand All @@ -25,6 +32,13 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p
- `<HandleDefault />`
- default handle class names were removed as soon as an `intent` was given
- fix runtime error if the element holding the handle tools is not available
- `utils`
- CSS custom properties are also found if their rule is nested inside a cascade layer (`@layer`) or another grouping rule like `@media`, `@supports` or `@container`; this affects `textToColorHash()`, `getEnabledColorsFromPalette()`, `getEnabledColorPropertiesFromPalette()` and `getColorConfiguration()`
- CSS custom properties are also found if the given selector is only one part of the selector list of a rule, e.g. `:root, :host`
- stylesheets that are loaded from another origin do not break the collection of CSS custom properties anymore
- collecting CSS custom properties does not throw an error anymore in test environments where the style declaration of a CSS rule is not an iterable object, e.g. in jsdom
- empty results are not cached anymore, this way they are read again if the stylesheets are loaded later on
- `minimalColorDistance` is part of the cache key of `getEnabledColorsFromPalette()` and `getEnabledColorPropertiesFromPalette()` now

## [26.0.0] - 2026-07-08

Expand Down
63 changes: 63 additions & 0 deletions src/common/utils/CssCustomProperties.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import CssCustomProperties from "./CssCustomProperties";

describe("CssCustomProperties in jsdom", () => {
beforeEach(() => {
const style = document.createElement("style");
style.textContent = `
:root { --eccgui-color-palette-blue-500: #1c6ecb; }
.config { --note-yellow: #ffde8f; }
`;
document.head.appendChild(style);
});

it("reads property names of a style rule without iterating the declaration", () => {
expect(
CssCustomProperties.listLocalCssStyleRuleProperties({
selectorText: ":root",
propertyType: "custom",
}),
).toEqual([["--eccgui-color-palette-blue-500", "#1c6ecb"]]);
});

it("does not throw for scoped selectors", () => {
expect(() =>
new CssCustomProperties({ selectorText: ".config", returnObject: false }).customProperties(),
).not.toThrow();
});

describe("useComputedStyleFallback", () => {
beforeEach(() => {
// the property is not part of any stylesheet, so the CSSOM does not know its name
const element = document.createElement("div");
element.classList.add("without-stylesheet");
element.style.setProperty("--only-computed", "#c0ffee");
document.body.appendChild(element);
});

it("is disabled by default", () => {
expect(
new CssCustomProperties({
selectorText: ".without-stylesheet",
}).customProperties(),
).toEqual({});
});

it("reads the names from the computed style if the CSSOM does not provide any", () => {
expect(
new CssCustomProperties({
selectorText: ".without-stylesheet",
useComputedStyleFallback: true,
}).customProperties(),
).toEqual({ "only-computed": "#c0ffee" });
});

it("is not used if the CSSOM provides names", () => {
expect(
new CssCustomProperties({
selectorText: ".config",
useComputedStyleFallback: true,
}).customProperties(),
).toEqual({ "note-yellow": "#ffde8f" });
});
});
});
Loading
Loading