@asyarb/goobed
v0.2.1
Published
Very opinionated light abstractions for CSS-in-JS styling built on top of [`goober`](https://github.com/cristianbote/goober).
Downloads
8
Readme
Goobed (TBD)
Very opinionated light abstractions for CSS-in-JS styling built
on top of goober
.
Installation
# Install package and required `goober` peer-dependency:
yarn install @asyarb/goobed goober
# If you plan on using <Box />, install the required `clsx` peer-dependency.
yarn install clsx
Usage
CSS-style function
import { createSx } from '@asyarb/goobed';
const breakpoints = {
sm: '48rem',
md: '75rem',
};
const sx = createSx(breakpoints);
// Use it inline to create styles:
const Example = () => <div className={sx({ display: 'block' })} />;
// sx() just returns a valid className, so it's usage is straightforward:
const redClassName = sx({ color: 'red' });
const PlainClassExample = () => <div className={redColor} />;
// Define mobile-first, responsive styles with auto-complete for breakpoints:
const responsiveClassName = sx({ color: 'red', sm: { color: 'blue' } });
React Integration
import { createBox } from '@asyarb/goobed';
const { Box, sx } = createBox(breakpoints); // => sx() is also available!
// <Box /> supports a convenience `sx` prop for styling:
const BoxSXExample = () => <Box sx={{ display: 'block' }} />;
// <Box /> supports polymorphism via the `as` prop with full TypeScript support:
const BoxAsExample = () => <Box as="img" src="..." sx={{ width: '300px' }} />;
const TypeSafetyExample = () => <Box as="a" loading="lazy" />; // => 'loading' is not a property of HTMLAnchorElement.
// <Box /> supports auto-completed responsive styling too:
const BoxResponsive = () => (
<Box sx={{ color: 'red', sm: { color: 'blue' } }} />
);
Extending Box
Creating components with sx
support can be done like the following:
import { BoxProps } from '@asyarb/goobed';
import { Box, breakpoints } from '../path/to/Box-And-Breakpoints';
// Define your component's props as a union of BoxProps.
type StackProps<T extends React.ElementType = 'div'> = BoxProps<
typeof breakpoints,
T
> & {
space: string;
};
// Extending React.ElementType is required for type-safe polymorphism.
const Stack = <T extends React.ElementType = 'div'>({
as,
sx,
space,
...props
}: StackProps<T>) => (
<Box
as={as as React.ElementType}
sx={{ display: 'flex', flexDirection: 'column', gap: space, ...sx }}
{...props}
/>
);
const Usage = () => <Stack space="1rem" />;
SSR
See goober
's documentation on
setting up SSR. For NextJS example, check their examples repo.
Why?
Goober (imo) provides a nice balance of performance, flexibility and performance size for css-in-js. This library just provides mostly type-level and responsive helpers for authoring styles without sacrificing run-time performance.