diff --git a/src/color-swatch/color-swatch.js b/src/color-swatch/color-swatch.js index b15b9ad..d25ce09 100644 --- a/src/color-swatch/color-swatch.js +++ b/src/color-swatch/color-swatch.js @@ -27,6 +27,7 @@ const Self = class ColorSwatch extends ColorElement { super(); this._el = { + swatch: this.shadowRoot.querySelector("slot[name=swatch]::slotted(*), #swatch"), wrapper: this.shadowRoot.querySelector("#wrapper"), label: this.shadowRoot.querySelector("[part=label]"), colorWrapper: this.shadowRoot.querySelector("[part=color]"), @@ -205,7 +206,7 @@ const Self = class ColorSwatch extends ColorElement { return null; } - return ColorSwatch.Color.get(this.value); + return ColorSwatch.resolveColor(this.value, this._el.swatch); }, set (value) { this.value = ColorSwatch.Color.get(value)?.display(); diff --git a/src/common/color-element.js b/src/common/color-element.js index d34b15e..7b33edc 100644 --- a/src/common/color-element.js +++ b/src/common/color-element.js @@ -32,6 +32,9 @@ const Self = class ColorElement extends NudeElement { static all = {}; static dependencies = new Set(); + /** @type {Map} */ + static #resolvedColors = new Map(); + static globalStyles = [{ css: baseGlobalStyles }]; constructor () { @@ -137,6 +140,43 @@ const Self = class ColorElement extends NudeElement { customElements.define(this.tagName, this); } + + /** + * Resolve a color value and cache it. + * @param {string} value Color value to resolve. + * @param {Element} element Element to get computed style from to resolve the color value. + * @returns {Color | null} Resolved color value or null if the value cannot be resolved. + */ + static resolveColor (value, element) { + try { + return Self.Color.get(value); + } + catch {} + + // Color.js can't parse the color value; possibly one of the values we can handle gracefully + if (Self.#resolvedColors.has(value)) { + let color = Self.#resolvedColors.get(value); + return Self.Color.get(color); + } + + if (!globalThis.CSS?.supports("color", value) || !element) { + // Not supported/invalid value, or no element to resolve the color value from + return null; + } + + // One of the supported color values; resolve and cache it + let backgroundColor = element.style.backgroundColor; + element.style.backgroundColor = value; + let color = getComputedStyle(element).backgroundColor; + element.style.backgroundColor = backgroundColor; + + let resolvedColor = Self.resolveColor(color); + if (resolvedColor) { + Self.#resolvedColors.set(value, color); + } + + return resolvedColor; + } }; export default Self;