0.2.1 • Published 4 years ago

@asyarb/goobed v0.2.1

Weekly downloads
9
License
MIT
Repository
-
Last release
4 years ago

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.