├── .babelrc ├── .gitignore ├── .npmignore ├── .nvmrc ├── .prettierrc ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── src ├── blacklisted-attributes.js ├── blacklisted-style-props.js ├── emotion.js ├── other │ └── css-test.js ├── pseudoclasses.js ├── styled-components.js ├── subatomic.js └── validAttr.js ├── themes └── default.js └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "react"], 3 | "plugins": ["transform-object-rest-spread"] 4 | } 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /emotion.js 2 | /styled-components.js 3 | node_modules 4 | .DS_Store -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 8.1.4 -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "singleQuote": true 4 | } 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Gabe Ragland 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | subatomic 3 |
4 | 5 |
6 | Inline style props for emotion and styled-components.
7 | Spend less time naming things. Iterate faster ⚡️ 8 |
9 | 10 |
11 | 12 | --- 13 | 14 |
15 | 16 | Subatomic allows you to style your React components inline so that you can spend more time writing styles and less time thinking of new component names. It integrates with emotion and styled-components so that you have the best of both worlds: The power of your favorite css-in-js library plus an inline style system to help you move fast and try out new ideas. 17 | 18 | ## 💁 Basic Usage 19 | 20 | ``` 21 | npm install --save subatomic 22 | ``` 23 | 24 | Supercharge any component by making `subatomic('element')` the root element. 25 | 26 | ```jsx 27 | import styled from 'emotion'; 28 | import subatomic from 'subatomic/emotion'; 29 | 30 | // Our components 31 | const Box = subatomic('div'); 32 | const H1 = subatomic('h1'); 33 | const Button = styled(subatomic('button'))` 34 | color: white; 35 | background-color: blue; 36 | &:hover { 37 | background-color: lightblue; 38 | } 39 | ` 40 | 41 | // Now we have style props! Tweak any style inline. 42 | 43 |

44 | My Awesome Website 45 |

46 | 47 | All other websites are significantly less awesome 48 | 49 | 52 |
53 | ``` 54 | 55 | > If you use styled-components import from `subatomic/styled-components` instead. 56 | 57 | While that's all you need to know to get started, we also support [responsive styles](#-responsive-style-props), [custom prop logic](#-custom-style-props), [pseudo-classes](#-psuedo-classes) and [dynamic elements](#-dynamic-elements). Read on to see how each of these features would affect the code example above. 58 | 59 | ## 📲 Responsive Style Props 60 | 61 | So let's say you're happy with the awesome website header but everything is way too big on mobile. With just a few tweaks to our example above we can decrease padding and font size on smaller screens. 62 | ```jsx 63 | 64 |

65 | My Awesome Website 66 |

67 | 68 | All other websites are significantly less awesome 69 | 70 | 73 |
74 | ``` 75 | As you can see we're now passing an array of values to the `padding` and `fontSize` props. These map to an array of screen widths (or "responsive breakpoints"). Subatomic uses a default set of breakpoints, so the above example works without any extra configuration, but you can also override them right in your website theme. 76 | 77 | ```jsx 78 | // theme.js 79 | export default { 80 | // These are the default breakpoints 81 | breakpoints: ['576px', '768px', '992px', '1200px'] 82 | } 83 | 84 | // App 85 | import { ThemeProvider } from 'emotion-theming' 86 | import theme from './theme.js' 87 | 88 | const App = props => ( 89 | 90 | {/* ... */} 91 | 92 | ) 93 | ``` 94 | Once your theme is made available via `ThemeProvider` subatomic will automatically use those values instead. For more info about theming see the ThemeProvider docs for [emotion](https://emotion.sh/docs/theming) or [styled-components](https://www.styled-components.com/docs/advanced#theming). 95 | 96 | ## 🌈 Custom Style Props 97 | 98 | Want to use shorter prop names or hook them into your design system? We make that easy as well. In this example we're using some custom props with shorter names (because less typing is cool) and the prop values now map to these locations in our theme: `theme.spacing[i]`, `theme.fontSizes[i]`, `theme.colors.green[2]`. 99 | 100 | ```jsx 101 | 102 |

103 | My Awesome Website 104 |

105 | 106 | All other websites are significantly less awesome 107 | 108 | 111 |
112 | ``` 113 | In the [configuration section](#-configuration) we'll show you how actually set this up, but the basic idea is that you can quickly define styles inline without giving the up the wonderful consistency of a design system. 114 | 115 | ## 👻 Psuedo-classes 116 | 117 | Use any psuedo-class or pseudo-element by prepending it to the prop name. Here we modify ` 123 | ``` 124 | > You can even chain multiple pseudo-classes together. For example: `hoverPlaceholderColor` 125 | 126 | ## 🎩 Dynamic Elements 127 | 128 | Sometimes you want to change the underlying element. You can do that with the `is` prop. In the example below we've renamed `H1` to `Heading` and now use the `is` prop to make the subheading an `h2` element. We also made `Button` an `a` element because we want it to be a link that looks like a button. 129 | 130 | ```jsx 131 | const Heading = subatomic('h1'); 132 | 133 | 134 | 135 | My Awesome Website 136 | 137 | 138 | All other websites are significantly less awesome 139 | 140 | 143 | 144 | ``` 145 | > You can even pass a component. Example: `` 146 | 147 | ## 🤹‍♀️ Tips and Tricks 148 | 149 | ### Composition Is Your Friend 150 | 151 | If you decide you want to turn a chunk of code into a named component you can of course re-write using `styled()` syntax, but consider using composition instead and pass along props using `{...props}` (spread syntax). 152 | 153 | ```jsx 154 | // Our example from above 155 | 156 | 157 | My Awesome Website 158 | 159 | 160 | All other websites are significantly less awesome 161 | 162 | 165 | 166 | 167 | // ⬇ Becomes a reusable component 168 | 169 | const PageHeading ({ title, subtitle, ...props }) => ( 170 | 171 | 172 | {title} 173 | 174 | 175 | {subtitle} 176 | 177 | 178 | ); 179 | 180 | // Lets also break the button out into its own component 181 | const GreenButton = props => ( 182 |