Skip to content

Commit 06a0e6e

Browse files
committed
Rewrite
1 parent 37d8157 commit 06a0e6e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+470
-3079
lines changed

.babelrc

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
{
22
"presets": [
3-
"es2015",
4-
"stage-0",
3+
"env",
54
"react"
65
]
76
}

.gitignore

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
1+
coverage
2+
.nyc_output
23
dist
3-
example/bundle.js

.npmignore

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
2-
example
1+
docs
32
src
4-
test
3+
test.js
54
.travis.yml
65
.babelrc
76
webpack.config.js
7+
coverage
8+
.nyc_output

README.md

+78-146
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,19 @@
44
[![Build Status](https://travis-ci.org/jxnblk/cxs.svg?branch=master)](https://travis-ci.org/jxnblk/cxs)
55
[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)
66

7-
Functional CSS for functional UI components
7+
High performance, lightweight CSS-in-JS
88

99
```js
10-
const className = cxs({ color: 'tomato' })
10+
const className = cxs(`color: tomato`)
1111
```
1212

13-
CXS is a functional CSS-in-JS solution that uses atomic styles
14-
to maximize deduplication and help with dead code elimination.
13+
CXS is a minimal CSS-in-JS solution that uses
14+
an API that closely follows the native CSSStyleSheet API
15+
to maximize performance and reduce bloat.
1516

1617
## Features
1718

18-
- Three different [modes](#modes) of operation: Atomic, Lite, & Monolithic
19-
- < 5KB
20-
- Avoids collisions with atomic rulesets
19+
- < 1.5KB
2120
- Deduplicates repeated styles
2221
- Dead-code elimination
2322
- Framework independent
@@ -26,8 +25,7 @@ to maximize deduplication and help with dead code elimination.
2625
- Pseudoclasses
2726
- Nested selectors
2827
- Avoid maintaining separate stylesheets
29-
- Use plain JS objects and types
30-
- No tagged template literals
28+
- Use plain CSS strings
3129

3230
## Install
3331

@@ -49,50 +47,38 @@ const Box = (props) => {
4947
)
5048
}
5149

52-
const className = cxs({
53-
padding: 32,
54-
backgroundColor: 'tomato'
55-
})
50+
const className = cxs(`
51+
padding: 32px;
52+
backgroundColor: tomato;
53+
`)
5654

5755
export default Box
5856
```
5957

6058
### Pseudoclasses
6159

6260
```js
63-
cxs({
64-
color: 'tomato',
65-
':hover': {
66-
color: 'red'
67-
}
68-
})
61+
cxs('color: tomato')
62+
.hover('color: red')
6963
```
7064

7165
### Media Queries
7266

7367
```js
74-
cxs({
75-
color: 'tomato',
76-
'@media (min-width: 40em)': {
77-
color: 'red'
78-
}
68+
cxs('color: tomato')
69+
.media('@media (min-width: 40em)', 'color: red')
7970
})
8071
```
8172

8273
### Nested Selectors
8374

8475
```js
85-
cxs({
86-
color: 'tomato',
87-
h1: {
88-
color: 'red'
89-
}
90-
})
76+
cxs('color: tomato', ' > h1')
9177
```
9278

9379
### Server-Side Rendering
9480

95-
To use CXS in server environments, use the `getCss()` function to get the static CSS string *after* rendering a view.
81+
To use CXS in server environments, use the `css` getter to get the static CSS string *after* rendering a view.
9682

9783
```js
9884
import React from 'react'
@@ -101,170 +87,116 @@ import cxs from 'cxs'
10187
import App from './App'
10288

10389
const html = ReactDOMServer.renderToString(<App />)
104-
const css = cxs.getCss()
90+
const css = cxs.css
10591

10692
const doc = `<!DOCTYPE html>
10793
<style>${css}</style>
10894
${html}
10995
`
11096

111-
// Optionally reset the cache for the next render
97+
// Reset the cache for the next render
11298
cxs.reset()
11399

114100
```
115101

116-
## Modes
117-
118-
CXS offers three different modes of operation, which produce different rules and class names.
102+
## API
119103

120104
```js
121-
import cxsAtomic from 'cxs'
122-
import cxsMonolithic from 'cxs/monolithic'
123-
import cxsLite from 'cxs/lite'
124-
125-
const styles = {
126-
margin: 0,
127-
marginBottom: 32,
128-
padding: 16,
129-
color: 'tomato',
130-
':hover': {
131-
color: 'orangered'
132-
},
133-
'@media (min-width: 40em)': {
134-
padding: 32
135-
}
136-
}
105+
const rule = cxs(cssDeclarations, descendantSelector, mediaQuery, className)
106+
// cxsRuleObject
137107

138-
// Each mode returns a different set of class names
108+
// className
109+
rule.toString() // '_0'
139110

140-
cxsAtomic(styles)
141-
// m-0 mb-32 p-16 c-tomato -hover-c-orangered _zsp35u
111+
// The following methods all return a rule object,
112+
// which allows them to be chained together
142113

143-
cxsMonolithic(styles)
144-
// _q5nmba
114+
// Adds a pseudoclass rule with the same className
115+
rule.hover()
116+
rule.focus()
117+
rule.active()
118+
rule.disabled()
145119

146-
cxsLite(styles)
147-
// a b c d e f
148-
```
120+
// Adds a media query rule with the same className
121+
rule.media(mediaQuery, cssDeclarations)
149122

150-
### Atomic Mode (Default)
151-
152-
```js
153-
import cxs from 'cxs'
123+
// Adds another rule with the same className
124+
rule.push()
154125
```
155126

156-
The default mode is the atomic mode.
157-
This creates atomic rulesets and attempts to create human readable classnames.
158-
If a classname is longer than 24 characters, a hashed classname will be used instead.
159-
160-
### Lite Mode
161-
162127
```js
163-
import cxs from 'cxs/lite'
164-
```
128+
import cxs from 'cxs'
165129

166-
For super fast performance, use the `cxs/lite` module.
167-
Lite mode creates alphabetic class names in a sequential order and does not support nested selectors.
130+
// Creates styles and returns micro classnames
131+
cxs('color: tomato')
168132

169-
Since the class names in cxs/lite are *not* created in a functional manner,
170-
when using cxs/lite on both the server and client, the styles will need to be rehydrated.
133+
// Gets a CSS string of attached rules. Useful for server-side rendering
134+
cxs.css
171135

172-
```js
173-
// Server
174-
const css = cxs.getCss()
136+
// Clear the cache and flush the stylesheet.
137+
// This is useful for cleaning up in server-side contexts.
175138
cxs.reset()
176-
177-
const html = `<!DOCTYPE html>
178-
<style id='cxs-style'>${css}</style>
179-
${body}
180-
`
181139
```
182140

183-
```js
184-
// Client
185-
import cxs from 'cxs/lite'
186-
187-
const styleTag = document.getElementById('cxs-style')
188-
const serverCss = styleTag.innerHTML
141+
Additional exports
189142

190-
cxs.rehydrate(serverCss)
191143
```
192-
193-
### Monolithic Mode
194-
195-
```js
196-
import cxs from 'cxs/monolithic'
144+
import {
145+
Sheet, // create stylesheet function
146+
sheet, // cxs stylesheet instance
147+
css, // string of rendered CSS - same as cxs.css
148+
reset // same as cxs.reset
149+
} from 'cxs'
197150
```
198151

199-
To create encapsulated monolithic styles with CXS and use single hashed class names, import the monolithic module.
152+
## React Components
200153

201-
The monolithic module also accepts custom selectors for styling things like the body element.
154+
CXS also has a higher order component for creating styled React components, similar to [styled-components][0] API.
202155

203156
```js
204-
cxs('body', {
205-
fontFamily: '-apple-system, sans-serif',
206-
margin: 0,
207-
lineHeight: 1.5
208-
})
209-
```
157+
import cxs from 'cxs/component'
210158

211-
## API
212-
213-
```js
214-
import cxs from 'cxs'
159+
const Heading = cxs(`
160+
margin: 0;
161+
font-size: 32px;
162+
line-height: 1.25;
163+
`).component('h1')
164+
```
215165

216-
// Creates styles and returns micro classnames
217-
cxs({ color: 'tomato' })
166+
Unlike styled-components, CXS components can be composed with other higher order components and works seamlessly with libraries like [Recompose][1]
218167

219-
// Returns a CSS string of attached rules. Useful for server-side rendering
220-
cxs.getCss()
168+
## JS Objects
221169

222-
// Clear the cache and flush the glamor stylesheet.
223-
// This is useful for cleaning up in server-side contexts.
224-
cxs.reset()
225-
```
170+
T/K
226171

227-
Additional exports
172+
```js
173+
import cxs from 'cxs/object'
228174

229-
```
230-
import {
231-
// The threepointone/glamor StyleSheet instance
232-
// See https://github.com/threepointone/glamor
233-
sheet,
234-
// Same as cxs.getCss
235-
getCss,
236-
// Same as cxs.reset
237-
reset
238-
} from 'cxs'
175+
const style = cxs({
176+
color: 'tomato'
177+
})
239178
```
240179

241180
### Vendor prefixes
242181

243182
CXS **does not** handle vendor prefixing to keep the module size at a minimum.
244183
To add vendor prefixes, use a prefixing module like [`inline-style-prefixer`](https://github.com/rofrischmann/inline-style-prefixer)
245184

246-
```js
247-
import cxs from 'cxs'
248-
import prefixer from 'inline-style-prefixer/static'
249-
250-
const prefixed = prefixer({
251-
display: 'flex'
252-
})
253-
const cx = cxs(prefixed)
254-
```
255-
256-
### Browser support
185+
<!--
186+
```js
187+
import cxs from 'cxs'
188+
import prefixer from 'inline-style-prefixer/static'
257189
258-
IE9+, due to the following:
259-
- `Array.filter`
260-
- `Array.map`
261-
- `Array.forEach`
190+
const prefixed = prefixer({
191+
display: 'flex'
192+
})
193+
const cx = cxs(prefixed)
194+
```
195+
-->
262196

263197
## Related
264198

265-
- [cxs-components](https://github.com/jxnblk/cxs/tree/master/packages/cxs-components)
266-
- [react-cxs](https://github.com/jxnblk/cxs/tree/master/packages/react-cxs)
267-
- [react-cxs-hoc](https://github.com/jxnblk/cxs/tree/master/packages/react-cxs-hoc)
199+
[0]: https://www.styled-components.com (styled-components)
200+
[1]: https://github.com/acdlite/recompose (Recompose)
268201

269202
[MIT License](LICENSE.md)
270-

atomic.js

-1
This file was deleted.

component.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('./dist/component')

example/App.js

-18
This file was deleted.

0 commit comments

Comments
 (0)