The sx prop
Style any component with sx. Static values compile to CSS, and theme functions run in the browser.
sx takes a style object, an array of them, or a function of the theme. The @hone-ui/sx build
plugin compiles static objects to CSS, so nothing styles at runtime.
<Box sx={{ p: 2, color: 'primary.main', '&:hover': { opacity: 0.8 } }} />Custom breakpoints
Media queries can't read CSS variables, so the plugin needs its own copy of your breakpoints. Put
them in one object and give it to both createTheme and the plugin. The object has the same
shape as the theme option: values and an optional unit.
export const breakpoints = {
values: { mobile: 0, tablet: 640, laptop: 1024, desktop: 1200 },
};import sx from '@hone-ui/sx/vite';
import { breakpoints } from './src/breakpoints';
export default { plugins: [sx({ breakpoints })] };import { withSx } from '@hone-ui/sx/next';
import { breakpoints } from './src/breakpoints';
export default withSx({}, { breakpoints });import { createTheme } from '@hone-ui/react';
import { breakpoints } from './breakpoints';
export const theme = createTheme({ breakpoints });Responsive objects and arrays then use your names, smallest first. { mobile: 1, tablet: 2 }
compiles to a base rule and a min-width:640px rule. [1, null, 3] maps to mobile, tablet
and laptop in order. A written @media (min-width:640px) key, such as the string
theme.breakpoints.up('tablet') returns, joins the tablet rule.
Custom names replace the defaults, so xs to xl stop working. Overriding only default names
({ values: { md: 1000 } }) keeps the others. For TypeScript, add your names to
BreakpointOverrides. The fallback for uncompiled objects reads the same names from the theme,
but keeps only the smallest breakpoint.
Stack keeps the default breakpoints.
Custom palette colors
sx resolves 'neutral.main' only if the plugin knows the palette key neutral. Pass the same
palette object to createTheme and to the plugin, as with breakpoints. The
theming guide has the setup.
Functions of the theme
A function receives the current theme. Arrays can hold functions, and a single property can be a function.
import { Backdrop, Box } from '@hone-ui/react';
<Backdrop open sx={(theme) => ({ color: '#fff', zIndex: theme.zIndex.drawer + 1 })} />;
<Box sx={[{ p: 2 }, (theme) => ({ bgcolor: theme.vars.palette.background.paper })]} />;
<Box sx={{ color: (theme) => theme.vars.palette.primary.main }} />;Read colors from theme.vars.palette. Its values are CSS variables, so they follow dark mode;
theme.palette holds one scheme's values and stays light in dark mode.
The plugin leaves these to the component, which calls the function with the theme from the
nearest ThemeProvider and applies the result as inline styles. In an array, entries before
the first function compile. Entries after it stay inline too, so they still override the
function. Put a function last to keep the most entries compiled.
Because the result is inline styles, a function cannot return selectors ('&:hover'), media
queries or breakpoints above the smallest one (xs unless your theme names them differently). A development warning names what was dropped. Put those in a
static object next to the function.
Client components only
A function cannot cross from a Server Component to a Client Component, so write function sx
inside a file marked 'use client'. The plugin does not know whether a file is a Server
Component, so it does not check. A server-rendered component such as Box throws an error that
says to add 'use client', and Next.js reports the file when a Server Component passes a
function to a Client Component.