-
Notifications
You must be signed in to change notification settings - Fork 76
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(themed): add token CSS variable test helper (#9860)
**Related Issue:** #7180 ## Summary Includes helpers which assist developers in testing and theming component tokens as CSS variables. ### EXAMPLE USAGE: #### Demo page ```html <demo-theme tokens="--calcite-button-background-color, --calcite-button-border-color, --calcite-button-text-color" ><calcite-button kind="inverse" scale="l"> Button </calcite-button ></demo-theme> ``` #### Storybook / Chromatic ```ts export const theming_TestOnly = (): string => html` <style> .container { ${setCSSVariables([ "--calcite-button-background-color", "--calcite-button-border-color", "--calcite-button-text-color", ])} } </style> <div class="container"> <calcite-button kind="inverse" scale="l"> Button </calcite-button> </div> `; ``` #### E2E ```ts describe("theme", () => { themed(`<calcite-button kind="inverse" scale="l"> Button </calcite-button>`, { "--calcite-button-background-color": { shadowSelector: ".button", targetProp: "backgroundColor", }, "--calcite-button-text-color": { shadowSelector: ".button", targetProp: "color", } "--calcite-accordion-border-color": { shadowSelector: ".button", targetProp: "borderColor", }, }); }); ```
- Loading branch information
1 parent
22ebe66
commit bcedcf7
Showing
4 changed files
with
165 additions
and
19 deletions.
There are no files selected for viewing
112 changes: 112 additions & 0 deletions
112
packages/calcite-components/src/demos/_assets/demo-theme.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
/** | ||
* | ||
* Sets the value of a CSS variable to a test value. | ||
* This is useful for testing themed components. | ||
* | ||
* @param token - the token as a CSS variable | ||
* @returns string - the new value for the token | ||
*/ | ||
export function getTokenValue(token: string): string { | ||
const tokenValueMap = { | ||
background$: "rgb(252, 244, 52)", | ||
"text-color$": "rgb(239,118,39)", | ||
"border-color$": "rgb(156, 89, 209)", | ||
"background-color$": "rgb(44, 44, 44)", | ||
color$: "rgb(0, 191, 255)", | ||
highlighted$: "rgb(255, 105, 180)", | ||
selected$: "rgb(255, 255, 255)", | ||
shadow$: | ||
"rgb(255, 255, 255) 0px 0px 0px 4px, rgb(255, 105, 180) 0px 0px 0px 5px inset, rgb(0, 191, 255) 0px 0px 0px 9px", | ||
"z-index$": "42", | ||
"(size|space)$": "42px", | ||
} as const; | ||
|
||
const match = Object.entries(tokenValueMap).find(([regexStr]) => { | ||
return new RegExp(regexStr, "g").test(token); | ||
}); | ||
|
||
if (!match) { | ||
console.warn("token not found in tokenValueMap", token); | ||
return tokenValueMap["color$"]; | ||
} | ||
|
||
return match[1]; | ||
} | ||
|
||
/* | ||
* @prop tokens - an array of CSS variables | ||
* @returns a string of CSS variables with their new values. | ||
*/ | ||
export function setCSSVariables(tokens: string[]): string { | ||
return tokens | ||
.map((token) => { | ||
return `${token}: ${getTokenValue(token)};`; | ||
}) | ||
.join("\n"); | ||
} | ||
|
||
/** | ||
* | ||
* @example | ||
* <demo-theme tokens=" | ||
* --calcite-button-background-color, | ||
* --calcite-button-border-color, | ||
* --calcite-button-corner-radius, | ||
* --calcite-button-corner-radius-start-start, | ||
* --calcite-button-corner-radius-start-end, | ||
* --calcite-button-corner-radius-end-start, | ||
* --calcite-button-corner-radius-end-end, | ||
* --calcite-button-loader-color, | ||
* --calcite-button-shadow, | ||
* --calcite-button-text-color, | ||
* --calcite-button-icon-color" | ||
* ><calcite-button kind="inverse" scale="l"> Button </calcite-button></demo-theme> | ||
*/ | ||
export class DemoTheme extends HTMLElement { | ||
_slot: HTMLSlotElement; | ||
|
||
_el: HTMLElement; | ||
|
||
static observedAttributes = ["tokens"]; | ||
|
||
constructor() { | ||
super(); | ||
const shadow = this.attachShadow({ mode: "open" }); | ||
const slot = document.createElement("slot"); | ||
shadow.append(slot); | ||
this._slot = slot; | ||
if (this._slot.assignedNodes().length === 1 && this._slot.assignedNodes()[0].nodeName.includes("calcite")) { | ||
this._el = this._slot.assignedNodes()[0] as HTMLElement; | ||
} | ||
} | ||
|
||
attributeChangedCallback(name: string, oldValue: string, newValue: string): void { | ||
if (newValue !== oldValue && name === "tokens") { | ||
this.updateTheme(newValue); | ||
} | ||
} | ||
|
||
updateTheme(newValue: string): void { | ||
if (typeof newValue === "string") { | ||
let tokensList; | ||
|
||
try { | ||
tokensList = JSON.parse(newValue); | ||
} catch (error) { | ||
tokensList = newValue.split(",").map((t) => t.trim()); | ||
} | ||
|
||
if (Array.isArray(tokensList)) { | ||
const stringifiedTheme = setCSSVariables(tokensList); | ||
|
||
if (this._el) { | ||
this._el.style.cssText = stringifiedTheme; | ||
} else { | ||
this.setAttribute("style", stringifiedTheme); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
customElements.define("demo-theme", DemoTheme); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
packages/calcite-components/src/tests/utils/cssTokenValues.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
/** | ||
* | ||
* Sets the value of a CSS variable to a test value. | ||
* This is useful for testing themed components. | ||
* | ||
* @param token - the token as a CSS variable | ||
* @returns string - the new value for the token | ||
*/ | ||
export function getTokenValue(token: string): string { | ||
const tokenValueMap = { | ||
background$: "rgb(252, 244, 52)", | ||
"text-color$": "rgb(239,118,39)", | ||
"border-color$": "rgb(156, 89, 209)", | ||
"background-color$": "rgb(44, 44, 44)", | ||
color$: "rgb(0, 191, 255)", | ||
highlighted$: "rgb(255, 105, 180)", | ||
selected$: "rgb(255, 255, 255)", | ||
shadow$: | ||
"rgb(255, 255, 255) 0px 0px 0px 4px, rgb(255, 105, 180) 0px 0px 0px 5px inset, rgb(0, 191, 255) 0px 0px 0px 9px", | ||
"z-index$": "42", | ||
"(size|space)$": "42px", | ||
} as const; | ||
|
||
const match = Object.entries(tokenValueMap).find(([regexStr]) => { | ||
return new RegExp(regexStr, "g").test(token); | ||
}); | ||
|
||
if (!match) { | ||
console.warn("token not found in tokenValueMap", token); | ||
return tokenValueMap["color$"]; | ||
} | ||
|
||
return match[1]; | ||
} | ||
|
||
/** | ||
* | ||
* @param tokens - an array of CSS variables | ||
* @returns a string of CSS variables with their new values. | ||
*/ | ||
export function setCSSVariables(tokens: string[]): string { | ||
return tokens | ||
.map((token) => { | ||
return `${token}: ${getTokenValue(token)};`; | ||
}) | ||
.join("\n"); | ||
} |