/
Utility Functions
Create custom shorthand properties that transform into CSS
Utility functions create shorthand properties that transform into CSS objects. They're applied before theme token resolution, enabling theme tokens in utility values.
How Utilities Work
- CSS object is processed
- Utility functions are applied (transform shorthand → CSS properties)
- Theme tokens are resolved
- CSS is generated and injected
Basic Setup
Define utility functions in your createStoop configuration:
import { createStoop } from "stoop";
import type { CSS, UtilityFunction } from "stoop";
type CSSPropertyValue = string | number;
const utils: Record<string, UtilityFunction> = {
px: (value: CSSPropertyValue | CSS | undefined): CSS => {
const val = typeof value === "string" || typeof value === "number"
? String(value)
: "";
return { paddingLeft: val, paddingRight: val };
},
py: (value: CSSPropertyValue | CSS | undefined): CSS => {
const val = typeof value === "string" || typeof value === "number"
? String(value)
: "";
return { paddingTop: val, paddingBottom: val };
},
};
const stoop = createStoop({
theme: {
space: {
small: "8px",
medium: "16px",
large: "24px",
},
},
utils,
});
export const { styled, css } = stoop;
Common Utility Examples
Spacing Utilities
const utils = {
// Padding
px: (value) => ({ paddingLeft: value, paddingRight: value }),
py: (value) => ({ paddingTop: value, paddingBottom: value }),
pt: (value) => ({ paddingTop: value }),
pr: (value) => ({ paddingRight: value }),
pb: (value) => ({ paddingBottom: value }),
pl: (value) => ({ paddingLeft: value }),
// Margin
mx: (value) => ({ marginLeft: value, marginRight: value }),
my: (value) => ({ marginTop: value, marginBottom: value }),
mt: (value) => ({ marginTop: value }),
mr: (value) => ({ marginRight: value }),
mb: (value) => ({ marginBottom: value }),
ml: (value) => ({ marginLeft: value }),
};
Usage with Theme Tokens
const Button = styled("button", {
px: "$medium", // → paddingLeft: "16px", paddingRight: "16px"
py: "$small", // → paddingTop: "8px", paddingBottom: "8px"
mt: "$large", // → marginTop: "24px"
});
Complex Utilities
Utilities return complex CSS objects, including nested selectors and media queries:
const utils = {
hidden: (value: CSSPropertyValue | CSS | undefined): CSS => {
const breakpoint = typeof value === "string" ? value : "";
if (breakpoint === "mobile") {
return {
"@media (max-width: 768px)": {
display: "none",
},
};
}
if (breakpoint === "desktop") {
return {
"@media (min-width: 769px)": {
display: "none",
},
};
}
return { display: "none" };
},
// Responsive spacing using media query shortcuts
// (Requires media queries defined in theme config)
responsivePadding: (value) => ({
padding: value,
"@media (max-width: 768px)": {
padding: "$small",
},
"@media (min-width: 769px)": {
padding: "$large",
},
}),
};
Using Utilities
In Styled Components
const Box = styled("div", {
px: "$medium",
my: "$large",
hidden: "mobile", // Hide on mobile breakpoint
});
In css() Function
const buttonClass = css({
px: "$medium",
py: "$small",
mx: "auto",
});
With the css Prop
<Box css={{ px: "$large", mt: "$medium" }}>
Content
</Box>
Utility Function Type
A utility function has the following signature:
type UtilityFunction = (
value: CSSPropertyValue | CSS | undefined
) => CSS;
- Input: string, number, CSS object, or undefined
- Output: CSS object
Best Practices
- Use theme tokens; utilities work great with theme tokens (
$medium,$primary, etc.) - Keep utilities simple; each utility should do one thing well
- Handle edge cases; handle undefined/null values gracefully
- Use TypeScript for type safety
- Document complex utilities with examples
Advanced Example
Complete example with multiple utilities:
import { createStoop } from "stoop";
import type { CSS, UtilityFunction } from "stoop";
type CSSPropertyValue = string | number;
const utils: Record<string, UtilityFunction> = {
// Spacing
px: (value) => {
const val = String(value || "");
return { paddingLeft: val, paddingRight: val };
},
py: (value) => {
const val = String(value || "");
return { paddingTop: val, paddingBottom: val };
},
mx: (value) => {
const val = String(value || "");
return { marginLeft: val, marginRight: val };
},
my: (value) => {
const val = String(value || "");
return { marginTop: val, marginBottom: val };
},
// Layout utilities (value parameter unused - these are boolean flags)
flex: () => ({ display: "flex" }),
grid: () => ({ display: "grid" }),
// Visibility
hidden: (value) => {
if (value === "mobile") {
return {
"@media (max-width: 768px)": {
display: "none",
},
};
}
return { display: "none" };
},
};
const stoop = createStoop({
theme: {
space: { small: "8px", medium: "16px", large: "24px" },
},
utils,
});
export const { styled, css } = stoop;
// Usage
const Card = styled("div", {
px: "$medium",
py: "$large",
mx: "auto",
flex: undefined, // Layout utility - no value needed
});
Notes
- Utilities are applied before theme token resolution
- Utilities work in styled components,
css()function, and thecssprop - Utilities can return nested CSS objects with media queries
- Utility names must not conflict with CSS property names
Related Pages
- Creating Components - Use utilities in styled components
- Theme Setup - Configure utilities in your theme
- API Reference - Complete API documentation