├── .babelrc ├── .gitignore ├── .npmignore ├── README.md ├── __snapshots__ └── test.js.snap ├── docs ├── Animations.js ├── App.js ├── Banner.js ├── Box.js ├── Btn.js ├── Cat.js ├── Columns.js ├── Demo.js ├── Example.js ├── Features.js ├── Flex.js ├── Footer.js ├── H1.js ├── Header.js ├── Heading.js ├── Icon.js ├── Input.js ├── Intro.js ├── Label.js ├── Lead.js ├── Link.js ├── ListItem.js ├── Pre.js ├── Slider.js ├── Spacer.js ├── Spin.js ├── Square.js ├── Text.js ├── Textarea.js ├── Theme.js ├── Theming.js ├── bundle.js ├── entry.js ├── icon.png ├── index.html └── styles.js ├── package.json ├── src └── index.js ├── test.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "env", 4 | "stage-0", 5 | "react" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | docs 2 | __snapshots__ 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # diet-cola 3 | 4 | A lightweight 5 | [styled-components](https://github.com/styled-components/styled-components) 6 | clone for creating React UI component primitives. 7 | Built with 8 | [stylis](https://github.com/thysultan/stylis.js) and 9 | [glamor](https://github.com/threepointone/glamor). 10 | 11 | ```sh 12 | npm i diet-cola 13 | ``` 14 | 15 | ```js 16 | import dc from 'diet-cola' 17 | 18 | const Button = dc('button')(` 19 | font-family: inherit; 20 | font-size: inherit; 21 | padding: 8px; 22 | margin: 0; 23 | color: white; 24 | background-color: tomato; 25 | border: 0; 26 | border-radius: 4px; 27 | appearance: none; 28 | &:hover { 29 | background-color: black; 30 | } 31 | `) 32 | ``` 33 | 34 | ## Features 35 | 36 | - Under 10KB 37 | - Create UI component primitives with a simple API 38 | - Use plain CSS strings 39 | - Pseudoclass support 40 | - Media query support 41 | - CSS animation support 42 | - Injects style before rendering 43 | - Server-side rendering support 44 | 45 | 46 | ## Motivation 47 | 48 | Styled Components is an excellent API for creating UI component primitives in React, 49 | but in its current state, it has several features that might not be needed for most use cases. 50 | This library is also meant as a proof of concept of using existing libraries to create a small, custom css-in-js solution. 51 | 52 | 53 | ## Differences 54 | 55 | Compared to styled-components, diet-cola: 56 | 57 | - Has no theme support - (though thematic constants can be imported) 58 | - No dynamic styling 59 | - Styles injected on module instantiation, independent of render props 60 | - No React Native support 61 | - No management of HTML elements or attributes 62 | - Relies on the glamor and stylis libraries 63 | - Only 48 custom LOC 64 | - Potentially smaller and more performant 65 | 66 | 67 | ### Related: 68 | 69 | - [cxs-components](https://github.com/jxnblk/cxs/tree/master/packages/cxs-components) 70 | - [cxs](https://github.com/jxnblk/cxs) 71 | - [glamor](https://github.com/threepointone/glamor) 72 | - [stylis](https://github.com/thysultan/stylis.js) 73 | - [styled-components](https://github.com/styled-components/styled-components) 74 | 75 | 76 | MIT License 77 | -------------------------------------------------------------------------------- /__snapshots__/test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`handles keyframes 1`] = ` 4 | 9 | `; 10 | 11 | exports[`handles pseudoclasses 1`] = ` 12 | 17 | `; 18 | 19 | exports[`renders 1`] = ` 20 |
23 | Hello 24 |
25 | `; 26 | 27 | exports[`supports composition 1`] = ` 28 |

31 | `; 32 | -------------------------------------------------------------------------------- /docs/Animations.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const Box = require('./Box') 3 | const Heading = require('./Heading') 4 | const Spin = require('./Spin') 5 | const Cat = require('./Cat') 6 | 7 | module.exports = () => ( 8 | 9 | CSS Animations 10 | 11 | 12 | 13 | 14 | ) 15 | -------------------------------------------------------------------------------- /docs/App.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const Header = require('./Header') 3 | const Intro = require('./Intro') 4 | const Features = require('./Features') 5 | const Example = require('./Example') 6 | const Demo = require('./Demo') 7 | const Animations = require('./Animations') 8 | // const Theming = require('./Theming') 9 | const Footer = require('./Footer') 10 | 11 | module.exports = class extends React.Component { 12 | state = {} 13 | update = fn => this.setState(fn) 14 | 15 | render () { 16 | return ( 17 |
18 |
19 | 20 | 21 | 22 | 23 | {/* 24 | 25 | 26 | */} 27 |
28 |
29 | ) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /docs/Banner.js: -------------------------------------------------------------------------------- 1 | const dc = require('diet-cola') 2 | 3 | module.exports = dc('header')(` 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | padding-left: 48px; 8 | padding-right: 48px; 9 | padding-top: 128px; 10 | padding-bottom: 128px; 11 | background-color: #0cf; 12 | background-image: linear-gradient(-60deg, rgba(255, 0, 0, 1), rgba(0, 255, 255, 1)); 13 | background-blend-mode: overlay; 14 | 15 | animation-name: rotate; 16 | animation-duration: 16s; 17 | animation-timing-function: linear; 18 | animation-iteration-count: infinite; 19 | 20 | @keyframes rotate { 21 | 0% { background-color: #0cf } 22 | 33% { background-color: #f0c } 23 | 66% { background-color: #c0f } 24 | 100% { background-color: #0cf } 25 | } 26 | `) 27 | -------------------------------------------------------------------------------- /docs/Box.js: -------------------------------------------------------------------------------- 1 | const dc = require('diet-cola') 2 | 3 | module.exports = dc('div')(`padding:32px;`) 4 | -------------------------------------------------------------------------------- /docs/Btn.js: -------------------------------------------------------------------------------- 1 | const dc = require('diet-cola') 2 | const { space, colors } = require('./styles') 3 | 4 | module.exports = dc('a')(` 5 | display: inline-flex; 6 | padding: ${space[1]}px; 7 | text-decoration: none; 8 | color: ${colors.white}; 9 | background-color: ${colors.blue}; 10 | border-radius: 4px; 11 | &:hover { 12 | box-shadow: inset 0 0 0 128px rgba(0, 0, 0, .125); 13 | } 14 | &:focus { 15 | outline: none; 16 | box-shadow: 0 0 0 2px ${colors.blue}; 17 | } 18 | &:active { 19 | box-shadow: inset 0 0 0 128px rgba(0, 0, 0, .25); 20 | } 21 | `) 22 | -------------------------------------------------------------------------------- /docs/Cat.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const Square = require('./Square') 3 | 4 | module.exports = () => ( 5 | 6 | ) 7 | -------------------------------------------------------------------------------- /docs/Columns.js: -------------------------------------------------------------------------------- 1 | const dc = require('diet-cola') 2 | 3 | module.exports = dc('ul')(` 4 | list-style: none; 5 | padding: 0; 6 | column-width: 16em; 7 | `) 8 | -------------------------------------------------------------------------------- /docs/Demo.js: -------------------------------------------------------------------------------- 1 | const React = require('react') 2 | const { throttle, debounce } = require('lodash') 3 | const dc = require('diet-cola') 4 | const Flex = require('./Flex') 5 | const Box = require('./Box') 6 | const Heading = require('./Heading') 7 | const Textarea = require('./Textarea') 8 | 9 | const initCss = `font-family: inherit; 10 | font-size: inherit; 11 | font-weight: bold; 12 | margin: 0; 13 | padding: 12px; 14 | color: #032; 15 | background-color: #0fc; 16 | border: 0; 17 | border-radius: 4px; 18 | appearance: none; 19 | &:hover { 20 | background-color: black; 21 | } 22 | ` 23 | 24 | module.exports = class extends React.Component { 25 | state = { 26 | css: initCss, 27 | Btn: null 28 | } 29 | 30 | update = fn => this.setState(fn, () => { 31 | this.getBtn() 32 | }) 33 | 34 | getBtn = throttle(() => { 35 | const Btn = dc('button')(this.state.css) 36 | this.setState({ Btn }) 37 | }, 500) 38 | 39 | componentWillMount () { 40 | this.getBtn() 41 | } 42 | 43 | render () { 44 | const { Btn, css } = this.state 45 | 46 | return ( 47 | 48 | Demo 49 | 50 |