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
, andnot
functions instead of configuring them globally.
To migrate:
- Replace the entire configuration object with the values of the existing
hooks
object. - Since
createHooks
only 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:
pipe
from Remedapipe
from fp-tspipeInto
from 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
css
withpipe
. - Move the
on
array's contents outside of the style object and pass them as additional arguments topipe
after the style object. - Remove the
on
field from the style object. - Update
$
function calls to use the new functionon
. - Import
on
from yourcss.ts
module along withand
,or
, andnot
functions 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.ts
module.