API

  1. styletron-engine-atomic
  2. styletron-react

styletron-engine-atomic

Atomic implementation of the styletron-standard engine interface. This package styletron-engine-atomic provides two named exports:

  • Client - Client-side engine class
  • Server - Server-side engine class

Client

import { Client } from "styletron-engine-atomic";

.constructor(opts?: {prefix?: string, hydrate?: HTMLStyleElement[], container: Element})

Options
  • prefix?: string The prefix to be used for all generated atomic identifiers (e.g. class names, @keyframes names, etc.)
  • hydrate?: HTMLStyleElement[] Collection of server-rendered style elements. Hydration is required when server-side rendering.
  • container?: Element The element that new stylesheets should be appended to. Defaults to the parent element of the first stylesheet passed via hydrate, otherwise defaults to document.head.
const instance = new Client();

Server

import { Server } from "styletron-engine-atomic";

.constructor(opts?: {prefix?: string})

Options
  • prefix?: string The prefix to be used for all generated atomic identifiers (e.g. class names, @keyframes names, etc.)
const instance = new Server();

.getStylesheets() => Array<{css: string, attrs: {[string]: string}}>

Returns styles as an array of stylesheet objects.

.getStylesheetsHtml(className: string) => string

Returns styles as a string of HTML that can also be used for client-side hydration.

.getCss() => string

Returns styles as a string of CSS for purely server-side rendering use cases where no client-side hydration is needed.

Universal methods

These methods exist on both the server and client instances.

.renderStyle(style) => string

Renders a given style object, returning the corresponding generated class name.

instance.renderStyle({
  color: "red",
  fontSize: "12px"
});
// → "a b"

.renderKeyframes(keyframes) => string

Renders a given keyframes object, returning the corresponding generated @keyframes rule name.

const animationName = instance.renderKeyframes({
  from: { color: "red" },
  to: { color: "blue" }
});
// → "a"

.renderFontFace(fontFace) => string

Renders a given font face object, returning the font-family name from the corresponding generated @font-face rule.

const fontFamily = instance.renderFontFace({
  src: "..."
});
// → "a"

styletron-react

The styletron-react package consists of the following named exports:

styled

import { styled } from "styletron-react";

The styled function is used to create a styled component.

Params

  1. base (string | React.ComponentType)
  2. style (Style | (props: Object) => Style)
// Static styles
const Foo = styled("div", { color: "red" });

<Foo />;

// Prop-driven styles
const Foo = styled("div", props => {
  return { color: props.$fraction < 0.5 ? "red" : "green" };
});

<Foo $fraction={Math.random()} />;

withStyle

import { withStyle } from "styletron-react";

Use withStyle for style composition via deep object merging.

Params

  1. styledComponent (StyledComponent)
  2. style (Style | (props: Object) => Style)

Examples

const Foo = styled("div");

// Static styles
const Bar = withStyle(Foo, {":hover": {background: "green"}});

// Props-driven styles
const Bar = withStyle(Foo, props => ({
  ":hover": {background: props.$green ? "green" : "white"}
});

withStyleDeep has been deprecated in v5 of Styletron. withStyle now performs a deep object merge by default as this was what was generally desired.

withTransform

import { withTransform } from "styletron-react";

If you need more control over your styling composition, withTransform allows for direct style manipulation via an arbitrary transformation function.

Params

  1. styledComponent (StyledComponent)
  2. transform ((style: Style, props: Object) => Style)

Examples

const Foo = styled("div");

const Bar = withTransform(Foo, (style, props) => {
  let display =
    style.display === "none"
      ? "none"
      : props.$inline === true
      ? "inline-flex"
      : "flex";
  return { ...style, display };
});

withWrapper

import { withWrapper } from "styletron-react";

Use withWrapper to add wrapping components while preserving the ability to compose styles later on.

Params

  1. styledComponent (StyledComponent)
  2. wrapFn (StyledComponent => props => ReactElement)

Examples

// New proposed React context API
const { Provider, Consumer } = React.createContext(/* ... */);

const Foo = styled("div", { color: "red" });

const Wrapped = withWrapper(Foo, Styled => props => (
  <Consumer>{value => <Styled {...props} arbitraryProp={value} />}</Consumer>
));

// Style composition still works as normal
const Bar = withStyle(Wrapped, { background: "red" });

Provider

import { Provider } from "styletron-react";

A Styletron engine must be provided using the Provider component.

Props

  • value (StyletronEngine)
  • debugMode? (true | "ssr" | false)

Examples

import { Provider } from "styletron-react";
import { Client as Styletron } from "styletron-engine-atomic";

const engine = new Styletron();

const App = () => (
  <Provider value={engine}>
    <RootComponent />
  </Provider>
);

Browser debug mode

In the browser, there's an optional debug mode which will render debug classes to styled elements which point to the JS source location of the styled component. This mode can be enabled with the debugMode prop on the client side Provider. Note that in a Node context debugMode does not do anything.

Example

Providing the debug utility

Instantiate the debug utility and pass it to the Provider.

+ import {DebugEngine} from "styletron-react";

+ const debug = process.env.NODE_ENV === "production"
+   ? void 0
+   : new DebugEngine();

const App = () => (
- <Provider value={engine}>
+ <Provider value={engine} debug={debug}>
    <RootComponent/>
  </Provider>
);

Hydrating from SSR

When hydrating from SSR, set the debugAfterHydration prop to true to prevent warnings from mismatched client/server rendered markup. This will trigger a one-time re-render after initial hydration to add the debug classes.

import {Provider, DebugEngine} from "styletron-react";

const debug = process.env.NODE_ENV === "production"
  ? void 0
  : new DebugEngine();

const App = () => (
-  <Provider value={engine} debug={debug}>
+  <Provider value={engine} debug={debug} debugAfterHydration>
    <RootComponent/>
  </Provider>
);

Debug utility interface

interface DebugEngine {
  debug({stackIndex, stackInfo}) : string
}

No-op engine fallback

If you forget to wrap your application with Styletron's Provider, Styletron switches to a no-op mode (rather than crashing) and will log a warning to the console. You probably do not want this for your actual app, but it is a useful convenience when writing tests where you do not care about styling output. In those cases, you do not have to worry about setting up Styletron's Provider.

Just be sure to set NODE_ENV=test to prevent a whole bunch of console warnings.

createStyled

import { createStyled } from "styletron-react";

Returns a styled function.

Params

  • opts.getInitialStyle: (void => StyleObject)
  • opts.driver: ((StyleObject, Engine) => string)
  • opts.wrapper: (StatelessFunctionalComponent<*> => StatelessFunctionalComponent<*>)

Examples

import { createStyled } from "styletron-react";
import type { StyleObject, StandardEngine } from "styletron-standard";

function driver(style: StyleObject, engine: any): string {
  return engine.someMethod(style);
}

function getInitialStyle(): StyleObject {
  return {};
}

const wrapper = StyledComponent => props => (
  <div>
    <StyledComponent {...props} />
  </div>
);

const styled = createStyled({ getInitialStyle, driver, wrapper });

useStyletron

A React Hook that returns a function for generating Styletron CSS classes.

css Params

  1. style ((StyleObject) => string)

Examples

import { useStyletron } from "styletron-react";

const Button = () => {
  // Use `css` to generate a string containing CSS classes
  const [css] = useStyletron();

  // Note how we pass the generated string directly to the `className` prop
  return <button className={css({ color: "blue" })}>Blue Button</button>;
};