Migrating to v3
v3 introduces a simpler model for defining and using hooks, which is more transparent, reduces syntax, and makes the library smaller and more efficient. Let's dive in!
New exports
Previously, the return value of createHooks included a css function. In v3
this is replaced by an on function, along with and, or, and not
functions for constructing complex conditions. Update your css.ts module to
export these new functions instead of css.
Before
// src/css.ts export const { styleSheet, css } = createHooks(/* ... */);
After
// src/css.ts export const { styleSheet, on, and, or, not } = createHooks(/* ... */);
Simplified initialization
In v2, createHooks accepted a configuration object containing a map of hooks,
along with several options. The on function in v3 is smaller in scope than the
css function it replaces, making most of the configuration options redundant.
Key changes:
- Hooks are now identified by their selector logic, no longer using aliases.
- Complex conditions are defined using the
and,or, andnotfunctions instead of configuring them globally.
To migrate:
- Replace the entire configuration object with the values of the existing
hooksobject. - Since
createHooksonly accepts string values, replace any complex hooks with their individual components.
Before
// src/css.ts export const { /* ... */ } = createHooks({ hooks: ({ or }) => ({ "&:hover": "&:hover", "&:intent": or("&:hover", "&:focus"), }), sort: { properties: true, conditionalStyles: true, }, fallback: "revert-layer", debug: true, });
After
// src/css.ts export const { /* ... */ } = createHooks("&:hover", "&:focus");
Defining reusable conditions
For globally-defined complex hooks (like the &:intent example in the previous
section), you can now use the and, or, and not functions to define them as
additional exports from your css.ts module.
Example
// src/css.ts export const intent = or("&:hover", "&:focus");
Pipeline function
The v3 API uses a pipeline function to apply conditional styles. This function can be obtained from third-party utility libraries such as:
pipefrom Remedapipefrom fp-tspipeIntofrom ts-functional-pipe
Alternatively, if you prefer not to install a third-party library, you can
simply copy
this implementation
of a pipe function.
Updating inline styles
Finally, update any inline styles that were previously defined using the css
function:
- Replace
csswithpipe. - Move the
onarray's contents outside of the style object and pass them as additional arguments topipeafter the style object. - Remove the
onfield from the style object. - Update
$function calls to use the new functionon. - Import
onfrom yourcss.tsmodule along withand,or, andnotfunctions as needed for complex conditions.
Before
import { css } from "./css"; function HelloWorld() { return ( <button style={css({ color: "black", on: ($, { or }) => [ $(or("&:hover", "&:focus"), { color: "blue", }), $("&:active", { color: "red", }), ], })} > Hello World </button> ); }
After
import { pipe } from "remeda"; // or from fp-ts, etc. import { on, or } from "./css"; function HelloWorld() { return ( <button style={pipe( { color: "black", }, on(or("&:hover", "&:focus"), { color: "blue", }), on("&:active", { color: "red", }), )} > Hello World </button> ); }
Note If you had globally-defined complex hooks in v2, make sure to replace those references with the reusable conditions exported from your
css.tsmodule.