Skip to content

Hyper minimal React Box component, built with hypostyle.

Notifications You must be signed in to change notification settings

front-of-house/hypobox-react

Repository files navigation

@hypobox/react

npm version test coverage npm bundle size

Minimalist CSS-in-JS solution for React. Built with hypostyle.

npm i @hypobox/react hypostyle react

Usage

To use @hypobox/react, first have a look at hypostyle. Basically, you provide @hypobox/react a hypostyle instance, and then you style components using attributes on React components that match your hypostyle setup.

Setup

import React from 'react'
import { render } from 'react-dom'
import { hypostyle } from 'hypostyle'
import presets from 'hypostyle/presets'
import { Hypo } from '@hypobox/react'

const instance = hypostyle(presets)

render(
  <Hypo hypostyle={instance}>
    <App />
  </Hypo>
)

Styling

In hypobox, all styling is done via the Box component.

import { Box } from '@hypobox/react'

function App() {
  return <Box color="tomato">Hello world!</Box>
}

If you've configured shorthands in your hypostyle instance (or are using the presets), you can also use those:

<Box c="tomato">Hello world!</Box>

Responsive Styles

Just like hypostyle, you can pass arrays or objects to denote responsive values:

<Box display={['none', 'none', 'flex']} />

Or:

<Box display={{ 2: 'flex' }} />

Macros & Variants

macros especially shine when used with JSX. Imagine the following config:

const instance = hypostyle({
  macros: {
    caps: { textTransform: 'uppercase' },
  },
  variants: {
    link: {
      primary: {
        c: 'blue',
        '&:hover': {
          c: 'black',
        },
      },
    },
  },
})

You can reference those values like this:

<Box as="a" caps link="primary">
  Click me!
</Box>

Custom Styles

For props you don't have configured as shorthands, or for custom values and breakpoints, use the cx prop. Examples:

<Box cx={{ c: 'tomato' }} />
<Box cx={{
  '@media (max-width: 567px)': {
    display: 'none'
  }
}} />

cx also supports passing a function. The function will be callled with the full theme you passed you hypostyle instance:

<Box
  cx={(theme) => ({
    c: theme.tokens.colors.primary,
  })}
/>

Defaults and Extending Components

If you like, compose provides a familiar interface:

import { compose } from '@hypobox/react'

const H1 = compose('h1', { fs: 1 })

And you can use it to extend components as well:

const Headline = compose(H1, { color: 'primary' })

Server Rendering

SSR is very simple. Complete example:

import React from 'react'
import { renderToString } from 'react-dom/server'
import { hypostyle } from 'hypostyle'
import presets from 'hypostyle/presets'
import { Hypo, Box } from '@hypobox/react'

const instance = hypostyle(presets)

const body = renderToString(
  <Hypo hypostyle={instance}>
    <Box f aic jcc>
      Flexy centered content
    </Box>
  </Hypo>
)

const stylesheet = hypo.flush()

const html = `
<!DOCTYPE html>
<html>
  <head>
    <style>${stylesheet}</style>
  </head>
  <body>${body}</body>
</html>
`

Related

License

MIT License © Sure Thing