Skip to content
This repository has been archived by the owner on Nov 26, 2024. It is now read-only.

Commit

Permalink
fix: css theme variables doc display (#672)
Browse files Browse the repository at this point in the history
* fix: css theme variables doc display

* chore: adding removed comment
  • Loading branch information
georgewrmarshall authored Apr 25, 2024
1 parent 71f48fa commit 751a507
Showing 1 changed file with 37 additions and 16 deletions.
53 changes: 37 additions & 16 deletions docs/utils/getCSSVariablesFromStylesheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,58 @@ export type Color = {
};

/**
* Retrieves CSS variables from the stylesheet.
* Retrieves CSS variables from the stylesheet, correctly handling combined selectors.
*
* @param varPrefix - The prefix of the CSS variables to retrieve.
* @returns An object containing the retrieved CSS variables.
*/
function getCSSVariablesFromStylesheet(varPrefix: string): Color {
const cssVariables: Color = {};

// Iterate over all stylesheets accessible to the document
Array.from(document.styleSheets)
.flatMap((styleSheet) => {
try {
// Access rules from the stylesheet, handle security errors when accessing cross-origin stylesheets
return Array.from(styleSheet.cssRules);
} catch (err) {
console.error(
'Access denied to stylesheet: ',
styleSheet.href,
'; Error: ',
err.message,
);
return [];
}
})
.filter((cssRule) => cssRule.type === CSSRule.STYLE_RULE)
.filter(
(cssRule: CSSRule) => (cssRule as CSSStyleRule).selectorText === ':root',
)
.flatMap((cssRule: CSSRule) => Array.from((cssRule as CSSStyleRule).style))
.filter((varName) => varName.startsWith(varPrefix))
.forEach((varName) => {
const name = varName.split('-').slice(2).join('-');
const color = getComputedStyle(document.documentElement)
.getPropertyValue(varName)
.trim();
cssVariables[name] = {
color,
name: `var(${varName})`,
};
.filter((cssRule) => cssRule.type === CSSRule.STYLE_RULE) // Filter for style rules only
.filter((cssRule: CSSRule) => {
// Handle combined selectors by splitting and trimming each individual selector
const selectors = (cssRule as CSSStyleRule).selectorText.split(',');
return selectors.some(
(selector) =>
selector.trim() === ':root' ||
selector.trim() === "[data-theme='light']",
);
})
.forEach((cssRule: CSSRule) => {
// Extract styles from the rules
const style = (cssRule as CSSStyleRule).style;
// Iterate over each property in the style rule
for (let i = 0; i < style.length; i++) {
const varName = style[i];
if (varName.startsWith(varPrefix)) {
// Get the actual CSS variable value from the computed styles of the document's root element
const value = getComputedStyle(document.documentElement)
.getPropertyValue(varName)
.trim();
const name = varName.replace(varPrefix, '').replace(/-/g, ' ');
cssVariables[name] = {
color: value,
name: `var(${varName})`,
};
}
}
});

return cssVariables;
Expand Down

0 comments on commit 751a507

Please sign in to comment.