Skip to content

Commit

Permalink
Merge pull request #13 from sure-thing/beta
Browse files Browse the repository at this point in the history
beta - hypostyle v2
  • Loading branch information
estrattonbailey committed Feb 9, 2021
2 parents 7c59494 + c11b7bf commit efccd01
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 245 deletions.
112 changes: 53 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

<br/>

![npm](https://img.shields.io/npm/v/hypobox) [![](https://badgen.net/bundlephobia/minzip/hypobox)](https://bundlephobia.com/result?p=hypobox)

Hyper minimal [hyposcript](https://github.com/sure-thing/hyposcript) `Box`
component, built with [hypostyle](https://github.com/sure-thing/hypostyle) and
[nano-css](https://github.com/streamich/nano-css).
component, built with [hypostyle](https://github.com/sure-thing/hypostyle).

```bash
npm i hypobox
Expand All @@ -13,109 +14,102 @@ npm i hypobox
#### Example

```jsx
<Box f aic fw>
import { Box } from 'hypobox'
;<Box f aic fw>
<Box w={[1, 1 / 2]}>
<H1 c='#333'>Hello world!</H1>
</Box>
<Box w={[1, 1 / 2]}>
<Box
as='button'
c='#333'
css={tokens => ({ '&:hover': { color: tomato; } })}
css={tokens => ({
'&:hover': { color: 'tomato' }
})}
>
Click Me
</Box>
</Box>
</Box>
```

## Overview

> **Note**, all examples here will assume JSX usage. For information on how to
> set that up, check out the
> [hyposcript README](https://github.com/sure-thing/hyposcript#jsx).
## Usage

Hypobox uses [hypostyle](https://github.com/sure-thing/hypostyle) internally,
and so supports the full API of hypostyle. Values provided here will be
_merged_ with the hypostyle [defaults](https://github.com/sure-thing/hypostyle#recommended-defaults).
By default, `hypobox` provisions a default `hypostyle` instance for you, using
`hypostyle`'s [default presets](https://github.com/sure-thing/hypostyle#presets).
To customize this, configure a custom `hypostyle` instance, optionally merging in
the default preset:

```javascript
import { configure, Box } from 'hypobox'
import { hypostyle } from 'hypostyle'
import presets from 'hypostyle/presets'
import { Box, configure } from 'hypobox'

configure({
const hypo = hypostyle({
...presets,
tokens: {
...presets.tokens,
color: {
primary: '#ff4567'
}
},
macros: {
border: {
border: '1px solid black'
outlined: {
border: '1px solid black',
}
}
})

<Box c='primary' border /> // => { color: '#ff4567', border: '1px solid black' }
```

Note: if you plan to customize your implementation with `configure()`, you
should do that before using `Box` or any of the utils.

### Utils

Hypobox also exposes some helpful utils.

#### `css`

Create ad-hoc style definitions, returning a classname.

```javascript
import { css } from 'hypobox'

configure({ ... }) // configure first
configure(hypo)

const cn = css({ c: 'blue' })
<Box c='primary' outlined /> // => { color: '#ff4567', border: '1px solid black' }
```

#### `injectGlobal`

Create global CSS rules with the full flexibility of hypostyle.
> **Note:** if you plan to customize your implementation with `configure()`, you
> should do that before using `Box` or any of the utils.
```javascript
import { injectGlobal } from 'hypobox'
### Everything Else

configure({ ... }) // configure first
Create a `hypostyle` instance as above and use it for everything else. Refer to
the [hypostyle docs](https://github.com/sure-thing/hypostyle) docs for more info
on what's available.

injectGlobal({
'.classname': {
c: 'blue'
}
})
```
### Server Rendering

#### `keyframes`
SSR is pretty similar to what you see in the
[hypostyle](https://github.com/sure-thing/hypostyle#server-usage) docs.

Hypobox exports the `keyframes` helper from
[nano-css](https://github.com/streamich/nano-css/blob/master/docs/keyframes.md).
See those docs for more info.
> **Note:** We recommend using a new `hypostyle` instance for each render to
> ensure no styles are leaked into sequential requests.
### Server Rendering
```javascript
import { hypostyle } from 'hypostyle'
import presets from 'hypostyle/presets'
import { Box, configure } from 'hypobox'

On the server, styles are collected by nano-css. After rendering, call `flush()`
to retrieve generated CSS and clear memory.
const hypo = hypostyle(presets)

```javascript
import { Box, flush } from 'hypobox'
configure(hypo)

const html = (
const body = (
<Box f aic jcc>
Flexy centered content
</Box>
)

const css = flush()
const stylesheet = hypo.flush()

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

### License

MIT License © [Eric Bailey](https://estrattonbailey.com)
MIT License © [Sure Thing](https://github.com/sure-thing)
105 changes: 8 additions & 97 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,103 +1,18 @@
const { h } = require('hyposcript')
const { hypostyle } = require('hypostyle')
const defaults = require('hypostyle/presets/default')
const presets = require('hypostyle/presets')

const { create } = require('nano-css')
const { addon: cache } = require('nano-css/addon/cache')
const { addon: nesting } = require('nano-css/addon/nesting')
const { addon: keyframes } = require('nano-css/addon/keyframes')
const { addon: rule } = require('nano-css/addon/rule')
const { addon: globalAddon } = require('nano-css/addon/global')
let context = hypostyle(presets)

let nano = createNano()
let context = hypostyle(defaults)

function createNano () {
const nano = create()

cache(nano)
nesting(nano)
keyframes(nano)
rule(nano)
globalAddon(nano)

return nano
}

function configure (props) {
const tokens = {
...defaults.tokens,
...(props.tokens || {})
}
const theme = {
tokens,
shorthands: {
...defaults.shorthands,
...(props.shorthands || {})
},
macros: {
...defaults.macros,
...(props.macros || {})
},
variants: {
...defaults.variants,
...(props.variants || {})
}
}

context = {
theme,
...hypostyle(theme)
}
}

function css (style) {
return nano.rule(context.css(style))
function configure (hypo) {
context = hypo
}

function injectGlobal (style) {
return nano.global(context.css(style))
}

function flush () {
context = {
theme: context.theme,
...hypostyle(context.theme)
}

const raw = nano.raw

nano = createNano()

return raw
}

function Box ({
as = 'div',
class: cn = '',
className: cN = '',
css: block,
...props
}) {
const { css: parseHypostyle, pick, theme } = context

const cleaned = pick(props)
const styles = Object.keys(cleaned.styles || {}).length
? parseHypostyle(cleaned.styles)
: undefined
const blockStyles = block
? parseHypostyle(
typeof block === 'function' ? block(theme.tokens) : block || {}
)
: undefined
function Box ({ as = 'div', className = '', css, ...props }) {
const cleaned = context.pick(props)

return h(as, {
class: [
cn || '',
cN || '',
styles && css(styles),
blockStyles && css(blockStyles)
]
className: [className, context.css(cleaned.styles), css && context.css(css)]
.filter(Boolean)
.map(s => s.trim())
.join(' '),
Expand All @@ -107,9 +22,5 @@ function Box ({

module.exports = {
configure,
Box,
css,
injectGlobal,
keyframes: nano.keyframes,
flush
Box
}
50 changes: 47 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
},
"dependencies": {
"hyposcript": "^1.0.1",
"hypostyle": "^1.0.0",
"hypostyle": "^2.3.0",
"nano-css": "^5.3.0"
},
"config": {
Expand Down

0 comments on commit efccd01

Please sign in to comment.