[ @sdxc/u/general ]
combine
Flattens input and merges the flattened utilities' style trees into one declaration set at the host's own level, so unrelated utilities compose as a single mixin with each nested selector kept as a sibling.
import { combine } from "@sdxc/u/general";Quick reference
Every documented call, beside the CSS it emits.
| Call | CSS |
|---|---|
u.combine([u.rounded("lg"), u.border({ color: "neutral", width: 1 })]) | css({ borderRadius: "var(--ui-radius-lg, 0.5rem)", borderColor: "var(--ui-neutral-border)", borderWidth: "1px", borderStyle: "solid" }) |
u.combine([u.when("&:hover", u.bg("brand.tint")), u.when("&:focus", u.bg("brand.tint"))]) | css({ "&:hover": { backgroundColor: "..." }, "&:focus": { backgroundColor: "..." } }) |
Examples
Basic example
Use combine([...]) to merge several utilities into one mixin you can name, export and reuse like any other:
<div mix={[...]}>
<span
mix={[
combine([
bg("brand.tint"),
fg("brand.emphasis"),
rounded("full"),
p(1, 3),
text("sm"),
weight("medium"),
]),
]}
>
Beta
</span>
<span
mix={[
combine([
bg("success.tint"),
fg("success.emphasis"),
rounded("full"),
p(1, 3),
text("sm"),
weight("medium"),
]),
]}
>
Shipped
</span>
</div>Grouping states
State utilities combine too, so a control's whole interaction can live in one mixin. Hover and press the button to try it:
<button
mix={[
p(2, 4),
rounded("md"),
weight("medium"),
border({ color: "neutral.border", width: 1, style: "solid" }),
fg(),
bg(),
transition("background-color, transform"),
combine([hover(bg("neutral.tint")), active(scale(0.96))]),
]}
>
Add to cart
</button>Applying on a state
Wrap the call in a state utility to scope it to one selector.
u.hover(u.combine([u.rounded("lg"), u.border({ color: "neutral", width: 1 })]))Responsive design
Wrap the call in a container query to scope it to one width.
u.at("md", u.combine([u.rounded("lg"), u.border({ color: "neutral", width: 1 })]))Customizing your theme
Customizing colors
Define a palette as --ui-color-{name}-{50..950} and map a tone onto it with the --ui-{tone}-* variables, the way theme.css maps the built-in ones:
:root {
--ui-color-info-50: oklch(0.97 0.02 230);
--ui-color-info-200: oklch(0.88 0.06 230);
--ui-color-info-500: oklch(0.62 0.16 230);
--ui-color-info-600: oklch(0.52 0.18 230);
--ui-color-info-900: oklch(0.3 0.1 230);
--ui-info-bg-tint: var(--ui-color-info-50);
--ui-info-bg-solid: var(--ui-color-info-600);
--ui-info-fg: var(--ui-color-info-600);
--ui-info-fg-muted: var(--ui-color-info-500);
--ui-info-fg-emphasis: var(--ui-color-info-900);
--ui-info-fg-on-solid: white;
--ui-info-border: var(--ui-color-info-200);
--ui-info-border-strong: var(--ui-color-info-600);
--ui-info-ring: var(--ui-color-info-500);
}declare module "@sdxc/u" {
interface ColorPalettes {
info: true;
}
interface SemanticTones {
info: true;
}
}The new name is then accepted wherever the scale is:
bg("info")Customizing radii
Redefine a --ui-radius-* variable to change a step, or declare a new one:
:root {
--ui-radius-2xl: 1rem;
}declare module "@sdxc/u" {
interface Radii {
"2xl": true;
}
}The new name is then accepted wherever the scale is:
rounded("2xl")Signature
u.combine(input: UtilityInput<Node>)