Skip to content
This repository has been archived by the owner on Jul 4, 2019. It is now read-only.

Commit

Permalink
Edit docs
Browse files Browse the repository at this point in the history
  • Loading branch information
jxnblk committed May 29, 2017
1 parent a8b5f0a commit 10577a6
Show file tree
Hide file tree
Showing 26 changed files with 697 additions and 124 deletions.
128 changes: 125 additions & 3 deletions README.md
Expand Up @@ -3,13 +3,16 @@

CSSOM-based CSS-in-JS library

- Browser-only
- Updates CSS rules in the stylesheet without changing the className

```sh
npm i superstyle
```

Superstyle is an experimental CSS-in-JS utility
library that uses CSSOM to patch updates to styles after injection.
Using plain JavaScript objects to author styles, superstyle
helps promote style encapsulation while making use of native
browser CSS APIs.

```js
// Usage
import sx from 'superstyle'
Expand Down Expand Up @@ -40,6 +43,125 @@ const rule = sx({
})
```

## API

### `superstyle`

(function) returns a superstyle [rule](#rule) object

```js
superstyle({ color: 'magenta' })
```

#### `superstyle.sheet`

(CSSStyleSheet) stylesheet object with additional helper methods

#### `sheet.css`

(getter) returns a string of CSS rules

```js
const css = sheet.css
```

#### `sheet.insert()`

(function) accepts an array of CSS rule strings and returns an array of corresponding CSSRule objects

```js
const cssRules = sheet.insert([ '.hello{color: magenta}' ])
```

### `rule`

(object) core object with className, set method and references to CSSRules

```js
const rule = superstyle({ color: 'magenta' })
```

#### `rule.className`

(string) unique className for the ruleset

```js
el.className = rule.className
```

#### `rule.set()`

(function) method to update the style object

```js
rule.set({ color: 'magenta' })
```

#### `rule.rules`

(array) array of CSSRules that correspond to the given rule

#### `rule.css`

(getter) string of CSS for the rule


### React higher-order component

Superstyle also includes a React higher order component (HOC) for creating components with static styles that can be updated with a `css` prop.
Import the HOC from `superstyle/react`.

```jsx
import superstyle from 'superstyle/react'

// Any component that accepts the `className` prop
const Button = props =>
<button {...props} />
)

// Static style object
const style = {
display: 'inline-flex',
fontFamily: 'inherit',
fontSize: 'inherit',
margin: 0,
paddingTop: 12,
paddingBottom: 12,
paddingLeft: 24,
paddingRight: 24,
color: 'white',
backgroundColor: '#07c',
border: 0,
borderRadius: 3,
appearance: 'none'
}

export default superstyle(style)(Button)
```

```jsx
<div>
<Button css={{ backgroundColor: 'magenta' }}>
Hello
</Button>
</div>
```

The higher order component also accepts strings for HTML tags to create primitive components.

```js
const Button = superstyle({
...style
})('button')
```


## Is this production-ready?

No. This is a proof-of-concept and has not been tested well enough for use in production. For a more stable CSS-in-JS library, try
[glamor](https://github.com/threepointone/glamor),
[cxs](https://github.com/jxnblk/cxs),
or [styled-components](https://github.com/styled-components/styled-components)

---

Expand Down
22 changes: 22 additions & 0 deletions docs/About.js
@@ -0,0 +1,22 @@
import React from 'react'
import Container from './Container'
import Subhead from './Subhead'
import Lead from './Lead'

const About = props => (
<section>
<Container py4>
<Subhead my3>About</Subhead>
<Lead children={copy} />
</Container>
</section>
)

const copy = `Superstyle is an experimental CSS-in-JS utility
library that uses CSSOM to patch updates to styles after injection.
Using plain JavaScript objects to author styles, superstyle
helps promote style encapsulation while making use of native
browser CSS APIs.
`

export default About
73 changes: 42 additions & 31 deletions docs/App.js
Expand Up @@ -4,30 +4,49 @@ import hello from 'hello-color'
import PropTypes from 'prop-types'
import colors from './colors'
import Header from './Header'
import About from './About'
import Usage from './Usage'
import ReactDemo from './ReactDemo'
import CSS from './CSS'
import Footer from './Footer'
import { inc } from './updaters'

const backgroundColor = colors[10][4]
const color = hello(backgroundColor).color
const alpha = colors[2][4]
const beta = hello(alpha).color

const base = sx({
'--text': color,
'--color-b': backgroundColor,
color: 'var(--color-b)',
// backgroundColor,
transitionProperty: 'color, background-color',
'--alpha': alpha,
'--beta': beta,
// color: 'var(--beta)',
transitionProperty: 'color',
transitionDuration: '.4s',
transitionTimingFunction: 'ease-out',

})

export default class App extends React.Component {
state = {
backgroundColor,
alpha,
count: 0
}

update = fn => this.setState(fn)

updateColors = () => {
const { alpha } = this.state
const beta = hello(alpha).color

base.set({
'--alpha': alpha,
'--beta': beta,
})
}

stop = () => {
if (this.timer) {
clearInterval(this.timer)
}
}

static childContextTypes = {
update: PropTypes.func
}
Expand All @@ -38,17 +57,15 @@ export default class App extends React.Component {
}
}

componentDidUpdate (last, state) {
if (state !== this.state) {
const { backgroundColor } = this.state
const color = hello(backgroundColor).color
componentDidMount () {
this.timer = setInterval(() => {
this.update(inc)
}, 3000)
}

base.set({
'--text': color,
'--color-b': backgroundColor,
// color,
// backgroundColor
})
componentDidUpdate (last, state) {
if (state.count !== this.state.count) {
this.updateColors()
}
}

Expand All @@ -59,23 +76,17 @@ export default class App extends React.Component {
...this.props,
...this.state,
color,
stop: this.stop
}

console.log(base.refs)
base.set({
// testing
':focus': {
backgroundColor: 'tomato',
':hover': {
backgroundColor: 'green',
}
}
})

return (
<div className={base.className}>
<Header {...props} />
<CSS />
<About {...props} />
<Usage {...props} />
<ReactDemo {...props} />
<CSS {...props} />
<Footer {...props} />
</div>
)
}
Expand Down
16 changes: 16 additions & 0 deletions docs/Banner.js
@@ -0,0 +1,16 @@
import superstyle from 'superstyle/react'

const Banner = superstyle({
minHeight: '70vh',
color: 'white',
backgroundColor: 'var(--beta)',
backgroundSize: 'cover',
backgroundPosition: 'center center',
// backgroundPosition: '20vw center',
backgroundBlendMode: 'screen',
transitionProperty: 'background-color, background-image',
transitionDuration: '.5s',
transitionTimingFunction: 'ease-out',
})('header')

export default Banner
4 changes: 3 additions & 1 deletion docs/Box.js
@@ -1,4 +1,6 @@
import superstyle from 'superstyle/react'
import hoc from './style-hoc'

const Box = superstyle()('div')
export default Box

export default hoc(Box)
36 changes: 27 additions & 9 deletions docs/Button.js
@@ -1,24 +1,42 @@
import superstyle from 'superstyle/react'
import hoc from './style-hoc'
import { darken } from './colors'

const darken = n => `rgba(0,0,0,${n})`
const Button = superstyle({
display: 'inline-flex',
fontFamily: 'inherit',
fontSize: 14,
fontWeight: 'bold',
textDecoration: 'none',
textTransform: 'uppercase',
letterSpacing: '0.3em',
margin: 0,
padding: 16,
paddingTop: 12,
paddingBottom: 12,
paddingLeft: 24,
paddingRight: 24,
color: 'white',
// backgroundColor: darken(3/8),
backgroundColor: 'var(--color-b)',
backgroundColor: 'var(--beta)',
border: 0,
borderRadius: 4,
backgroundBlendMode: 'multiply',
borderRadius: 2,
backgroundBlendMode: 'overlay',
opacity: 7/8,
boxShadow: `0 0 64px ${darken(1/4)}`,

':hover': {
// backgroundColor: darken(5/8)
opacity: 1,
boxShadow: `0 0 64px ${darken(1/2)}` // , inset 0 0 0 999px ${darken(1/4)}`
},

':focus': {
outline: 'none',
boxShadow: `inset 0 0 2px 0px var(--alpha), 0 0 0 2px var(--beta)`,
opacity: 1,
},

':active': {
boxShadow: `inset 0 0 0 999px ${darken(1/2)}`
}
})('button')
})('a')

export default Button
export default hoc(Button)
29 changes: 21 additions & 8 deletions docs/CSS.js
@@ -1,15 +1,28 @@
import React from 'react'
import sx, { sheet } from 'superstyle'
import superstyle from 'superstyle/react'
import { css as beautify } from 'js-beautify'
import Container from './Container'
import Subhead from './Subhead'
import Code from './Code'
import Pre from './Pre'

const Pre = superstyle({
whiteSpace: 'pre-wrap'
})('pre')
const CSS = props => {
const css = sheet.css

const CSS = props => (
<div>
<Pre>{sheet.css}</Pre>
</div>
)
return (
<Container py4>
<Subhead>CSS for this page</Subhead>
<Code>{css.length} bytes</Code>
<Pre
css={{
maxHeight: 512,
overflow: 'auto',
}}
children={beautify(css)}
/>
</Container>
)
}

export default CSS

0 comments on commit 10577a6

Please sign in to comment.