A tiny, powerful, framework-agnostic CSS-in-JS library
npm i @dash-ui/styles
Features
Quick start
Check out an example on CodeSandbox
import * as React from "react";
import { styles } from "@dash-ui/styles";
const flushTokens = styles.insertTokens({
color: {
brand: "#ee5b5f",
white: "#fafafa",
},
elevation: {
resting:
"0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
},
radius: {
primary: "4px",
},
});
const flushGlobal = styles.insertGlobal`
body {
min-height: 100vh;
}
`;
const button = styles.variants({
default: ({ radius }) => `
display: inline-block;
border: none;
background: transparent;
padding: 0.5rem 1rem;
font-weight: 700;
border-radius: ${radius.primary};
box-shadow: ${elevation.resting};
color: ${color.white};
/**
* Dash uses a CSS preprocessor called stylis so nesting,
* autoprefixing, etc. come out of the box.
* https://www.npmjs.com/package/stylis
*/
:active {
transform: translateY(1px);
}
`,
brand: ({ color }) => ({
backgroundColor: color.brand,
}),
black: {
backgroundColor: "#000",
},
});
const Component = (props) => (
<div>
{/**
* Styles are composed in the order they're defined in arguments,
* so they are completely deterministic.
*/}
<button className={button("solid", "brand")}>Solid brand</button>
{/**
* That is, in the button below `black`'s background color will
* take precendence over the `brand` background color.
*/}
<button className={button({ outline: true, brand: true, black: true })}>
Solid black
</button>
</div>
);
API docs
Creating styles
| Description |
---|
styles.variants() | styles.variants() is a function for composing style variants in a deterministic way. It returns a function which when called will insert your styles into the DOM and create a unique class name. |
styles.one() | A function that accepts a tagged template literal, style object, or style callback, and returns a function. That function inserts the style into a <style> tag and returns a class name when called. |
styles.cls() | A function that accepts a tagged template literal, style object, or style callback. Calling this will immediately insert the CSS into the DOM and return a unique class name for the styles. This is a shortcut for styles.one({display: 'flex'})() . |
styles.lazy() | A function that uses lazy evalution to create styles with indeterminate values. Calling this will immediately insert the CSS into the DOM and return a unique class name for the styles. |
styles.join() | A function that joins CSS strings, inserts them into the DOM right away, and returns a class name. |
styles.keyframes() | A function that accepts a tagged template literal, style object, or style callback. Using this will immediately insert a global @keyframes definition into the DOM and return the name of the keyframes instance. |
styles.theme() | A function that returns the generated class name for a given theme when using styles.insertThemes() to create CSS variable-based themes. |
styles.insertThemes() | This creates a CSS variable-based theme by defining tokens within a class name selector matching the theme name. Apart from that it works the same way styles.insertTokens() does. This function returns a function that will flush the styles inserted by styles.insertTokens() when it is called. |
styles.insertTokens() | Inserts design tokens into the DOM and makes them available for use in style callbacks. The name of the design tokens is automatically generated based upon the depth of the mapping i.e. foo.bar.baz -> --foo-bar-baz . This function returns a function that will flush the tokens that were inserted when it is called. |
styles.insertGlobal() | A function that accepts a tagged template literal, style object, or style callback. Using this will immediately insert styles into the DOM relative to the root document. This function returns a function that will flush the styles inserted when it is called. |
styles.hash() | The hashing function used for creating unique selector names. |
styles.tokens | The design tokens configured in the instance. |
styles.dash | The instance of underlying the Dash cache used by this instance. This was automatically created by createDash() when createStyles() was called. Dash controls the caching, style sheets, auto-prefixing, and DOM insertion that happens in the styles.variants() instance. |
Server rendering
Dash has robust server rendering utilities out of the box. If you're using React, there
are even more helpers available for Gatsby, Next.js, etc. available in
@dash-ui/react
.
| Description |
---|
createStylesFromCache() | 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. |
createStyleTagFromCache() | 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. |
writeStylesFromCache() | 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. |
createStylesFromString() | 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. |
createStyleTagFromString() | 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. |
writeStylesFromString() | 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 CSS files in an asynchronous environment. |
Creating a custom styles
instance
| Description |
---|
createStyles() | A factory function that returns a new styles instance with your custom configuration options. |
createDash() | Dash is a tiny, performant CSS-in-JS style rule sheet manager similar to Emotion. |
Utilities
| Description |
---|
compileStyles() | A utility function that will compile style objects and callbacks into CSS strings. |
hash() | An FNV-1a hashing algorithm with a 32-bit offset basis. FNV-1a hashes are designed to be fast while maintaining a low collision rate. The high dispersion rate makes them well-suited for hashing nearly identical strings. This is the default hash used by createStyles() . |
TypeScript support
Dash is written in TypeScript. It's also strongly typed, creating a beautiful IntelliSense
experience in VSCode and providing solid insurance to your TypeScript application.
Awesome @dash-ui libraries
Write something awesome for Dash, tell me about it, and
I will put it here.
Why does this exist?
In the days before Emotion was subsumed by the React community and
effectively ruined, there existed a beautiful,
simple CSS-in-JS API. It returned class names instead of objects. It was easy to use. It didn't require
a babel plugin or a JSX pragma. It wasn't inextricably tied to React or React context trees.
About a year after I created that Emotion issue, I started work on Dash. I've worked tirelessly
since to create a library I genuinely liked using. I wanted to create a library that combined the
simplicity of CSS with the versatility of JavaScript - as CSS-in-JS has always intended.
Dash can be used in React, but doesn't rely on it. It can also be used in Vue, Svelte, and
anywhere else you can use JavaScript. Themes are created with CSS variables and selectors,
not React context.
I hope you'll give it a chance.
styles.variants()
styles.variants()
is a function for composing style variants in a deterministic way. It returns a
function which when called will insert your styles into the DOM and create a unique class name.
Example
Play with an example on CodeSandbox
import * as React from "react";
import { styles } from "@dash-ui/styles";
const button = styles.variants({
default: ({ radius }) => `
display: inline-block;
border: none;
background: transparent;
padding: 0.5rem 1rem;
font-weight: 700;
border-radius: ${radius.primary};
box-shadow: ${elevation.resting};
:active {
transform: translateY(1px);
}
`,
primary: ({ color }) => ({
backgroundColor: color.primary,
color: color.white,
}),
black: {
backgroundColor: "#000",
color: "#fff",
},
});
const Component = (props) => (
<React.Fragment>
{/**
* Styles are composed in the order they're defined in arguments,
* so they are completely deterministic. Calling the `button`
* function returns a string class name.
*/}
<button className={button("solid", "brand")}>Solid brand</button>
{/**
* That is, in the button below `black`'s background color will
* take precendence over the `brand` background color because it
* is declared after `brand`.
*/}
<button className={button({ outline: true, brand: true, black: true })}>
Solid black
</button>
</React.Fragment>
);
Arguments
styles<N extends string>(styleMap: StyleMap<N, V>): Style<N, V>
Argument | Type | Required? | Description |
---|
styleMap | StyleMap | Yes | A key/CSS value mapping |
Returns
export type Style<N extends string, V extends DashTokens = DashTokens> = {
(...args: StyleArguments<N>): string;
css(...names: StyleArguments<N>): string;
styles: StyleMap<N, V>;
};
export type StyleArguments<N extends string> = (
| N
| {
[Name in N]?: boolean | null | undefined | string | number;
}
| Falsy
)[];
StyleMap
export type StyleMap<N extends string, V extends DashTokens = DashTokens> = {
[Name in N | "default"]?: StyleValue<V>;
};
export type StyleValue<V extends DashTokens = DashTokens> =
| string
| StyleCallback<V>
| StyleObject;
export type StyleObject = {
[property: string]: StyleObject | string | number;
};
export type StyleCallback<V extends DashTokens = DashTokens> = (
tokens: V
) => StyleObject | string;
styles.one()
A function that accepts a tagged template literal, style object, or style callback, and
returns a function. That function inserts the style into a <style>
tag and returns a
class name when called.
Example
Play with an example on CodeSandbox
import * as React from "react";
import { styles } from "@dash-ui/styles";
const heading = styles.one`
font-size: 2rem;
font-weight: bold;
`;
const heading = styles.one({
fontSize: "2rem",
fontWeight: "bold",
});
const heading = styles.one(({ font }) => ({
fontSize: font.size.heading,
fontWeight: "bold",
}));
const Heading = () => <h1 className={heading()}>Hello world</h1>;
Returns
export type StylesOne = {
(createClassName?: boolean | number | string | null): string;
css(createCss?: boolean | number | string | null): string;
};
styles.cls()
A function that accepts a tagged template literal, style object, or style callback.
Calling this will immediately insert the CSS into the DOM and return a unique class
name for the styles. This is a shortcut for styles.one({display: 'flex'})()
.
Example
Play with an example on CodeSandbox
import * as React from "react";
import { styles } from "@dash-ui/styles";
const Box = () => (
<div
className={styles.cls(
({ color }) => `
width: 200px;
height: 200px;
background-color: ${color.primary};
:hover {
background-color: ${color.secondary};
}
`
)}
/>
);
Returns
string;
styles.lazy()
A function that uses lazy evalution to create styles with indeterminate values.
Calling this will immediately insert the CSS into the DOM and return a unique
class name for the styles.
Example
Play with an example on CodeSandbox
import * as React from "react";
import clsx from "clsx";
import { styles } from "@dash-ui/styles";
const bgColor = styles.lazy((colorName) => ({ color }) => ({
backgroundColor: color[colorName],
}));
const Box = ({ bg = "primary" }) => <div className={bgColor(bg)} />;
Returns
export type StylesLazy<Value extends LazyValue> = {
(value?: Value): string;
css(value?: Value): string;
};
styles.join()
A function that joins CSS strings, inserts them into the DOM right away, and returns a
class name.
Example
Play with an example on CodeSandbox
import * as React from "react";
import { styles } from "@dash-ui/styles";
const bgPrimary = styles.one(
({ color }) => `
background-color: ${color.primary};
`
);
const box = styles.variants({
default: {
width: 200,
height: 200,
},
big: {
width: 400,
height: 400,
},
});
const PrimaryBox = () => (
<div className={styles.join(bgPrimary.css(), box.css("big"))} />
);
Arguments
styles.join(...css: string[]): string
Argument | Type | Required? | Description |
---|
...css | string[] | Yes | One or several CSS strings you want to join into one style |
Returns
string;
styles.keyframes()
A function that accepts a tagged template literal, style object, or style callback.
Invoking it will immediately inject its styles into the DOM and return an animation
name which can then be referenced in other styles.
Example
Play with an example on CodeSandbox
import * as React from "react";
import { styles } from "@dash-ui/styles";
const zoomy = styles.keyframes`
0% {
transform: scale(0.0);
}
60% {
transform: scale(1.4);
}
80% {
transform: scale(1);
}
100% {
transform: scale(0.0);
}
`;
const zoomyBox = styles.one({
animationName: zoomy,
animationDuration: `2000ms`,
animationIterationCount: "infinite",
backgroundColor: "#008489",
width: 100,
height: 100,
margin: "48px auto",
});
const ZoomyBox = () => <div className={zoomyBox()} />;
Returns
string;
styles.theme()
A function that returns the generated class name for a given theme when using
styles.insertThemes()
to create CSS variable-based themes.
Example
Play with an example on CodeSandbox
import * as React from "react";
import { createStyles } from "@dash-ui/styles";
const styles = createStyles({
themes: {
light: {
bgColor: "#FAFAFA",
primaryColor: "#ee5b5f",
},
dark: {
bgColor: "#272727",
primaryColor: "#333",
},
} as const,
});
export const App = () => {
const [mode, setMode] = React.useState<"light" | "dark">("light");
React.useEffect(() =>
styles.insertGlobal(({ bgColor }) => ({
body: { backgroundColor: bgColor },
}))
);
return (
<body className={styles.theme(mode)}>
<div
className={styles.cls(
({ bgColor, primaryColor }) => `
width: 200px;
height: 200px;
background-color: ${primaryColor};
`
)}
/>
<button
onClick={() => setMode((mode) => (mode === "light" ? "dark" : "light"))}
>
Switch to {mode === "light" ? "dark" : "light"} mode
</button>
</body>
);
};
Arguments
theme(name: T): string
Argument | Type | Required? | Description |
---|
name | string | Yes | The name of the theme |
Returns
string;
styles.insertThemes()
This creates a CSS variable-based theme by defining tokens within a class name selector
matching the theme name. Apart from that it works the same way
styles.insertTokens()
does. This function returns a
function that will flush the styles inserted by styles.insertTokens()
when it is called.
Example
Play with an example on CodeSandbox
import * as React from "react";
import { createStyles } from "@dash-ui/styles";
const styles = createStyles({
themes: {
light: {
primaryColor: "#ee5b5f",
},
dark: {
primaryColor: "#272727",
},
},
});
export const App = () => {
const [mode, setMode] = React.useState<"light" | "dark">("light");
const [darkModePrimary, setDarkModePrimary] = React.useState("#272727");
const [lightModePrimary, setLightModePrimary] = React.useState("#ee5b5f");
React.useEffect(
() =>
styles.insertThemes({
light: {
primaryColor: lightModePrimary,
},
dark: {
primaryColor: darkModePrimary,
},
}),
[darkModePrimary, lightModePrimary]
);
return (
<body className={styles.theme(mode)}>
<div
className={styles.cls(
({ primaryColor }) => `
width: 200px;
height: 200px;
background-color: ${primaryColor};
`
)}
/>
<div>
<button
onClick={() =>
setMode((mode) => (mode === "light" ? "dark" : "light"))
}
>
Switch to {mode === "light" ? "dark" : "light"} mode
</button>
</div>
<label>
<h4>Light mode primary color</h4>
<input
value={lightModePrimary}
onChange={(e) => setLightModePrimary(e.target.value)}
/>
</label>
<label>
<h4>Dark mode primary color</h4>
<input
value={darkModePrimary}
onChange={(e) => setDarkModePrimary(e.target.value)}
/>
</label>
</body>
);
};
Arguments
insertThemes(
themes: DeepPartial<
{
[Name in DashThemeNames]: DashTokens
}
>
): () => void
Argument | Type | Required? | Description |
---|
themes | DeepPartial<{[Name in DashThemeNames]: DashTokens}> | Yes | A mapping of theme name/CSS variable pairs. |
Returns
() => void
styles.insertTokens()
Inserts design tokens into the DOM and makes them available for use in style callbacks. The
name of the design tokens is automatically generated based upon the depth of the mapping
i.e. foo.bar.baz
-> --foo-bar-baz
. This function returns a function that will flush
the tokens that were inserted when it is called.
Example
Play with an example on CodeSandbox
import * as React from "react";
import { createStyles } from "@dash-ui/styles";
const styles = createStyles({
tokens: {
primaryColor: "#ee5b5f",
},
});
export const App = () => {
const [primaryColor, setPrimaryColor] = React.useState("#ee5b5f");
React.useEffect(
() =>
styles.insertTokens({
primaryColor,
}),
[primaryColor]
);
return (
<div>
<div
className={styles.cls(
({ primaryColor }) => `
width: 200px;
height: 200px;
background-color: ${primaryColor};
`
)}
/>
<label>
<h4>Primary color</h4>
<input
value={primaryColor}
onChange={(e) => setPrimaryColor(e.target.value)}
/>
</label>
</div>
);
};
Arguments
insertTokens(tokens: DeepPartial<DashTokens>, selector?: string): () => void
Argument | Type | Required? | Default | Description |
---|
tokens | DeepPartial<DashTokens> | Yes | | A map of CSS variable name/value pairs |
selector | string | No | ":root" | Including a selector will only make these CSS variable definitions take effect within the selector, e.g. a class name or ID. |
Returns
() => void
styles.insertGlobal()
A function that accepts a tagged template literal, style object, or style callback. Using
this will immediately insert styles into the DOM relative to the root document. This function
returns a function that will flush the styles inserted when it is called.
Example
Play with an example on CodeSandbox
import * as React from "react";
import { styles } from "@dash-ui/styles";
const flushStyles = styles.insertGlobal({
body: {
minHeight: "100vh",
backgroundColor: "#ee5b5f",
color: "#fff",
fontFamily: "Inter, -apple-system, sans-serif",
},
h1: {
margin: "1rem",
fontSize: "3rem",
},
});
export const App = () => {
return (
<div>
<h1>Hello world</h1>
<button onClick={flushStyles}>Flush styles</button>
</div>
);
};
Returns
() => void
styles.hash()
The hashing function used for creating unique selector names. This can be
configured by creating your own styles
instance with createStyles()
.
Example
import { styles } from "@dash-ui/styles";
console.log(styles.hash("foo: bar;"));
Arguments
hash(string: string): string
Argument | Type | Required? | Description |
---|
string | string | Yes | The string you'd like to hash |
Returns
string;
styles.tokens
The design tokens configured in the instance
Example
import {styles} from '@dash-ui/styles`
styles.insertTokens({foo: 'bar'})
console.log(styles.tokens)
// {foo: 'var(--foo)'}
styles.dash
The instance of underlying the Dash cache used by this instance. This was automatically
created by createDash()
when createStyles()
was called.
Dash controls the caching, style sheets, auto-prefixing, and DOM insertion that happens
in the styles
instance.
Example
import { styles } from "@dash-ui/styles";
styles.dash.insert("foo", ".foo", "display: flex;");
createStyles()
A factory function that returns a new styles
instance with your custom configuration options.
I would suggest that you almost always create your own styles
instance - especially when
using TypeScript.
Example
import {createStyles, createDash} from '@dash-ui/styles`
const styles = createStyles({
dash: createDash({key: 'css', prefix: false}),
mangleTokens: typeof process !== 'undefined' && process.env.NODE_ENV === 'production',
tokens: {
gap: {
sm: '0.25rem',
md: '0.5rem',
lg: '1rem'
}
}
})
const oneStyle = styles.one(({gap}) => `
margin: ${gap.md};
`)
Arguments
function createStyles<
V extends DashTokens = DashTokens,
T extends string = DashThemeNames
>(options: CreateStylesOptions<V, T> = {}): Styles<V, T>;
Returns
A new styles
instance
Styles<V, T>
CreateStylesOptions
Option | Type | Required? | Default | Description |
---|
dash | Dash | No | createDash() | An instance of Dash created by the createDash() factory |
tokens | DashTokens | No | | Inserts design tokens into the DOM and makes them available for use in style callbacks. The name of the design tokens is automatically generated based upon the depth of the mapping i.e. foo.bar.baz -> --foo-bar-baz . |
themes | DashThemes | No | | A mapping of theme name/CSS variable pairs. This Creates a CSS variable-based theme by defining tokens within a class name selector matching the theme name. Apart from that it works the same way tokens does. |
mangleTokens | boolean | {[key: string]: boolean} | No | false | When true this will mangle CSS variable names. You can also provide an object with {key: boolean} pairs of reserved keys which will not be mangled. |
hash | (string: string) => string | No | hash | Use your own hash function for creating selector names. By default Dash uses an fnv1a hashing algorithm. |
createDash()
Dash is a tiny, performant CSS-in-JS style rule sheet manager similar to Emotion.
Example
import { createDash } from "@dash-ui/styles";
const dash = createDash({ key: "css", prefix: false });
dash.insert("flex", ".flex", "display: flex;");
Arguments
function createDash(options: CreateDashOptions = {}): Dash;
Returns
export type Dash = {
readonly key: string;
readonly sheet: DashStyleSheet;
readonly sheets: DashSheets;
readonly stylis: typeof Stylis;
readonly cache: Map<string, string>;
insert(
key: string,
selector: string,
styles: string,
styleSheet?: DashStyleSheet
): void;
readonly inserted: Set<string>;
};
CreateDashOptions
Option | Type | Required? | Default | Description |
---|
key | string | No | "ui" | Keys in sheets used to associate <style> tags with this specific Dash instances via the dash-cache property. This is also used as a class name prefix in styles . |
nonce | string | No | | For security policies. A nonce is an arbitrary number that can be used just once in a cryptographic communication. |
stylisPlugins | Plugable[] | No | | An array of Stylis plugins. See: https://www.npmjs.com/package/stylis |
prefix | boolean | ((key: string, value: any, context: any) => boolean) | No | true | Turns on/off vendor prefixing. When a boolean, all prefixes will be turned on/off. Use a function to define your own prefixes for a given key/value. |
container | HTMLElement | No | document.head | This is the container that <style> tags will be injected into when style rules are inserted. |
compileStyles()
A utility function that will compile style objects and callbacks into CSS strings.
Example
import { compileStyles } from "@dash-ui/styles";
const css = compileStyles({
display: "flex",
"> * + *": {
marginLeft: "0.5rem",
},
});
console.log(css);
const red = compileStyles(({ red }) => ({ color: red }), { red: "var(--red)" });
console.log(red);
Arguments
Argument | Type | Required? | Description |
---|
styles | StyleValue<V> | Falsy | Yes | A style callback, object, or string |
tokens | DashTokens | No | A map of design tokens for style callbacks |
Returns
string;
hash()
An FNV-1a hashing algorithm with a 32-bit offset basis. FNV-1a hashes are designed to be
fast while maintaining a low collision rate. The high dispersion rate makes them
well-suited for hashing nearly identical strings. This is the default hash used by
createStyles()
.
Example
import { hash } from "@dash-ui/styles";
console.log(hash("foo: bar;"));
Arguments
function hash(string: string): string;
Argument | Type | Required? | Description |
---|
string | string | Yes | The string you'd like to hash |
Returns
string;
createStylesFromCache()
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.
Example
import { styles } from "@dash-ui/styles";
import { createStylesFromCache } from "@dash-ui/styles/server";
styles.cls`display: flex;`;
const { css, names } = createStylesFromCache(styles);
console.log(css);
console.log(names);
Arguments
export function createStylesFromCache(
styles = require("@dash-ui/styles").styles,
options: CreateServerStylesOptions = {}
): ServerStylesResult;
Argument | Type | Required? | Default | Description |
---|
styles | styles | No | styles | A styles instance |
options | CreateServerStylesOptions | No | {clearCache: false} | Configuration options |
Returns
export interface ServerStylesResult {
css: string;
names: string[];
}
CreateServerStylesOptions
Option | Type | Required? | Default | Description |
---|
clearCache | boolean | No | false | Clears the Dash inserted cache after styles have been generated. This is useful in synchronous environments when you only want to generate CSS strings for the styles that were actually used in a given page/render. |
createStyleTagFromCache()
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.
Example
import { styles } from "@dash-ui/styles";
import { createStyleTagFromCache } from "@dash-ui/styles/server";
styles.cls`display: flex;`;
const styleTag = createStyleTagFromCache(styles);
console.log(styleTag);
Arguments
export function createStyleTagFromCache(
styles = require("@dash-ui/styles").styles,
options: CreateServerStylesOptions = {}
): string;
Argument | Type | Required? | Default | Description |
---|
styles | styles | No | styles | A styles instance |
options | CreateServerStylesOptions | No | {clearCache: false} | Configuration options |
Returns
string;
writeStylesFromCache()
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.
Example
import { styles } from "@dash-ui/styles";
import { writeStylesFromCache } from "@dash-ui/styles/server";
styles.cls`display: flex;`;
writeStylesFromCache("../public/css", styles).then(
({ filename, css, names }) => {
console.log(filename);
console.log(css);
console.log(names);
}
);
Arguments
async function writeStylesFromCache(
outputPath = "",
styles = require("@dash-ui/styles").styles,
options?: WriteStylesOptions & { clearCache?: boolean }
): Promise<WriteServerStylesResult>;
Argument | Type | Required? | Default | Description |
---|
outputPath | string | No | "" | An absolute or relative path dictating where you want to output the CSS file. |
styles | styles | No | styles | A styles instance |
options | WriteServerStylesOptions & CreateServerStylesOptions | No | {clearCache: false} | Configuration options |
Returns
export interface WriteServerStylesResult {
filename: string;
name: string;
path: string;
css: string;
names: string[];
}
WriteServerStylesOptions
Option | Type | Required? | Description |
---|
name | string | No | Use this if you want to create your own name for the CSS file. By default, this function will create a filename based on the hash of the generated CSS string and the key in Dash. |
hash | (string: string) => string | No | Use a custom hash function for creating the name of your CSS file. By default this function will use the hash function attached to your styles instance. |
createStylesFromString()
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.
Example
import { styles } from "@dash-ui/styles";
import { createStylesFromString } from "@dash-ui/styles/server";
styles.cls`display: flex;`;
const { css, names } = createStylesFromString(
'<div class="ui-1ut9bc3"></div>',
styles
);
console.log(css);
console.log(names);
Arguments
export function createStylesFromString(
html: string,
styles = require("@dash-ui/styles").styles
): ServerStylesResult;
Argument | Type | Required? | Default | Description |
---|
html | string | Yes | | An HTML string |
styles | styles | No | styles | A styles instance |
Returns
export interface ServerStylesResult {
css: string;
names: string[];
}
createStyleTagFromString()
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.
Example
import { styles } from "@dash-ui/styles";
import { createStyleTagFromString } from "@dash-ui/styles/server";
styles.cls`display: flex;`;
const styleTag = createStyleTagFromString(
'<div class="ui-1ut9bc3"></div>',
styles
);
console.log(styleTag);
Arguments
function createStyleTagFromString(
html: string,
styles = require("@dash-ui/styles").styles
): string;
Argument | Type | Required? | Default | Description |
---|
html | string | Yes | | An HTML string |
styles | styles | No | styles | A styles instance |
Returns
string;
writeStylesFromString()
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 CSS files in an asynchronous environment.
Example
import { styles } from "@dash-ui/styles";
import { writeStylesFromString } from "@dash-ui/styles/server";
styles.cls`display: flex;`;
writeStylesFromString(
'<div class="ui-1ut9bc3"></div>',
"../public/css",
styles
).then(({ filename, css, names }) => {
console.log(filename);
console.log(css);
console.log(names);
});
Arguments
async function writeStylesFromString(
html: string,
outputPath = "",
styles = require("@dash-ui/styles").styles,
options?: WriteServerStylesOptions
): Promise<WriteServerStylesResult>;
Argument | Type | Required? | Default | Description |
---|
html | string | Yes | | An HTML string |
outputPath | string | No | "" | An absolute or relative path dictating where you want to output the CSS file. |
styles | styles | No | styles | A styles instance |
options | WriteServerStylesOptions | No | | Configuration options |
Returns
export interface WriteServerStylesResult {
filename: string;
name: string;
path: string;
css: string;
names: string[];
}
Strongly typed tokens
You can strongly type your design tokens a couple of ways. The easiest way is to create your
own styles
instance with createStyles()
:
Play with this example on CodeSandbox
import { createStyles } from "@dash-ui/styles";
export const styles = createStyles({
tokens: {
color: {
red: "#c17",
},
},
});
styles.one(({ color }) => ({
color: color.red,
backgroundColor: color.bgRed,
}));
You can also strongly type your design tokens using a module declaration:
Play with this example on CodeSandbox
const tokens = {
color: {
red: "#c17",
},
};
type AppTokens = typeof tokens;
declare module "@dash-ui/styles" {
export interface DashTokens extends AppTokens {}
}
declare module "@dash-ui/styles" {
export interface DashTokens {
color: {
red: string;
};
}
}
Strongly typed themes
You can strongly type your CSS variable themes a couple of ways. The easiest way is to create your
own styles
instance with createStyles()
:
Play with the example on CodeSandbox
import { createStyles } from "@dash-ui/styles";
export const styles = createStyles({
themes: {
light: {
color: {
bg: "#fafafa",
},
},
dark: {
color: {
bg: "#1a1a1a",
},
},
},
});
styles.one(({ color }) => ({
backgroundColor: color.bg,
color: color.red,
}));
styles.theme("dark");
styles.theme("whoami");
You can also strongly type your CSS variable themes using a module declaration:
Play with the example on CodeSandbox
const themes = {
light: {
color: {
bg: "#fafafa",
},
},
dark: {
color: {
bg: "#1a1a1a",
},
},
};
type AppThemes = typeof themes;
type AppTokens = AppThemes["dark"] & AppThemes["light"];
declare module "@dash-ui/styles" {
export interface DashTokens extends AppTokens {}
export interface DashThemes extends AppThemes {}
}
declare module "@dash-ui/styles" {
export interface DashTokens {
color: {
bg: string;
};
}
export interface DashThemes {
light: DashTokens;
dark: DashTokens;
}
}
Acknowledgements
This library was heavily inspired by the original Emotion and fellow
Coloradan Kye Hohenberger.
I am grateful to have had that base, however, the implementations of the libraries have diverged
quite a bit by now.
LICENSE
MIT