@dash-ui/styles
Version:
A tiny, powerful, framework-agnostic CSS-in-JS library.
230 lines (204 loc) • 6.33 kB
JavaScript
/* eslint-disable @typescript-eslint/no-var-requires */
/**
* Creates a string of CSS based on the dash `inserted` cache. This
* is an extremely fast way to generate a CSS string. It returns an
* object containing the hash names of all of the styles used as well
* as the CSS string.
*
* Note that this function is unsafe in asynchronous render environments
* because multiple pages using the same cache will dirty the results.
* This means it will not work with Gatsby, for example.
*
* @param styles - A `styles()` instance
* @param options - Configuration options
*/
export function createStylesFromCache(styles, options) {
if (styles === void 0) {
styles = require("@dash-ui/styles").styles;
}
if (options === void 0) {
options = {};
}
const {
clearCache = false
} = options;
const {
dash
} = styles;
const styleCache = dash.cache;
const names = new Set([...dash.sheets.keys(), ...dash.inserted.values()]);
let css = "";
for (const name of names) css += styleCache.get(name);
if (clearCache) dash.inserted.clear();
return {
names: [...names],
css
};
}
/**
* Creates a `<style>` tag w/ CSS based on the dash `inserted` cache. This
* is an extremely fast way to generate a `<style>` tag.
*
* Note that this function is unsafe in asynchronous render environments
* because multiple pages using the same cache will dirty the results.
* This means it will not work with Gatsby, for example.
*
* @param styles - A `styles()` instance
* @param options - Configuration options
*/
export function createStyleTagFromCache(styles, options) {
if (styles === void 0) {
styles = require("@dash-ui/styles").styles;
}
if (options === void 0) {
options = {};
}
const {
css,
names
} = createStylesFromCache(styles, options);
const nonceString = styles.dash.sheet.nonce ? ` nonce="${styles.dash.sheet.nonce}"` : "";
return `<style data-dash="${names.join(" ")}" data-cache="${styles.dash.key}"${nonceString}>${css}</style>`;
}
/**
* Writes a CSS to a file based on the dash `inserted` cache. This
* is an extremely fast way to generate a CSS file.
*
* Note that this function is unsafe in asynchronous render environments
* because multiple pages using the same cache will dirty the results.
* This means it will not work with Gatsby, for example.
*
* @param outputPath - An absolute or relative path dictating where you want to
* output the CSS file.
* @param styles - A `styles()` instance
* @param options - Configuration options
*/
export async function writeStylesFromCache(outputPath, styles, options) {
if (outputPath === void 0) {
outputPath = "";
}
if (styles === void 0) {
styles = require("@dash-ui/styles").styles;
}
// Requiring in here prevents webpack errors in stuff like Next.js apps
const fs = require("fs");
const path = require("path");
let {
name,
hash = styles.hash,
clearCache = false
} = options || {};
const {
css,
names
} = createStylesFromCache(styles, {
clearCache
});
name = `${name || styles.dash.key + "-" + hash(css) + ".css"}`;
const filename = path.join(outputPath, name);
await fs.promises.writeFile(filename, css);
return {
filename,
name,
path: outputPath,
css,
names
};
}
/**
* Creates a string of CSS based on an HTML string. This function will
* parse your HTML output for Dash class names and pull the styles associated
* with them from the Dash cache. It returns an object containing the hash names
* of all of the styles used as well as the CSS string.
*
* This is a safe way to generate style strings in an asynchronous environment
*
* @param html - An HTML string
* @param styles - A `styles()` instance
*/
export function createStylesFromString(html, styles) {
if (styles === void 0) {
styles = require("@dash-ui/styles").styles;
}
const {
dash
} = styles;
const styleCache = dash.cache;
const names = new Set(dash.sheets.keys());
let css = "";
for (let name of names) css += styleCache.get(name);
const re = new RegExp(`["\\s'=]${dash.key}-(\\w+)`, "g");
for (const [, name] of html.matchAll(re)) {
if (!names.has(name)) {
css += styleCache.get(name) || "";
names.add(name);
}
}
return {
names: [...names],
css
};
}
/**
* Creates a `<style>` tag w/ CSS based on an HTML string. This function will
* parse your HTML output for Dash class names and pull the styles associated
* with them from the Dash cache.
*
* This is a safe way to generate `<style>` tags in an asynchronous environment.
*
* @param html - An HTML string
* @param styles - A `styles()` instance
*/
export function createStyleTagFromString(html, styles) {
if (styles === void 0) {
styles = require("@dash-ui/styles").styles;
}
const {
css,
names
} = createStylesFromString(html, styles);
const nonceString = styles.dash.sheet.nonce ? ` nonce="${styles.dash.sheet.nonce}"` : "";
return `<style data-dash="${names.join(" ")}" data-cache="${styles.dash.key}"${nonceString}>${css}</style>`;
}
/**
* Writes a CSS to a file based on an HTML string. This function will
* parse your HTML output for Dash class names and pull the styles associated
* with them from the Dash cache.
*
* This is a safe way to generate `<style>` tags in an asynchronous environment.
*
* @param html
* @param styles - A `styles()` instance
* @param outputPath - An absolute or relative path dictating where you want to
* output the CSS file.
* @param options - Configuration options
*/
export async function writeStylesFromString(html, outputPath, styles, options) {
if (outputPath === void 0) {
outputPath = "";
}
if (styles === void 0) {
styles = require("@dash-ui/styles").styles;
}
// Requiring in here prevents webpack errors in stuff like Next.js apps
const fs = require("fs");
const path = require("path");
let {
name,
hash = styles.hash
} = options || {};
const {
css,
names
} = createStylesFromString(html, styles);
name = `${name || styles.dash.key + "-" + hash(css) + ".css"}`;
const filename = path.join(outputPath, name);
await fs.promises.writeFile(filename, css);
return {
filename,
name,
path: outputPath,
css,
names
};
}