diff --git a/LICENSE b/LICENSE index 6fa6712..ebbc2d8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,21 @@ -Copyright (c) 2018 Jon Quach (https://jonquach.com) +The MIT License (MIT) -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Copyright (c) 2018 Help Scout -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md index 393f490..0e9d20b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ > A simple way to include CSS with React Components. -* **Tiny**, at less than 850 bytes gzipped +* **Tiny**, at less than 1 KB gzipped * **Only one dependency - ([Stylis](https://github.com/thysultan/stylis.js))** * **Write plain ol' CSS.** Period. * **Built-in pre-processing** when you need it. Powered by [Stylis](https://github.com/thysultan/stylis.js). @@ -18,57 +18,11 @@ npm install --save @helpscout/fancy ## πŸ•Ή Usage -#### Step 1: Import `withStyles` from Fancy +Here's a quick example of how you can compose regular CSS with your React components. ```jsx import React from 'react' -import { withStyles } from '@helpscout/fancy' -``` - - -#### Step 2: Define your styles - -Write your CSS styles as a string. This is default out-of-the-box CSS. Use things like `:hover`, `@media` queries, as you normally would! - -```jsx -const css = ` - .Button { - background: white; - border: 1px solid #eee; - } -` -``` - -Note: You can of course use string interpolation. It's still JS after all! - - -#### Step 3: Create your component - -Create your component as you normally would. - -```jsx -const Button = props => ( - - ... - - -``` - -That's it! You're done πŸ™Œ. You've created a CSS-ready component. - - -### Dynamic styles - -You can define dynamic styles by passing a `function` into `withStyles`. It will have access to a component's `props`, allowing you to define custom rules for various `prop` values. - -#### Example - -```jsx -const Card = props => (
) -const css = (props) => ` - div { - background: ${props.title ? 'red' : 'blue'}; - position: relative; - border: 1px solid black; - } -` -const StyledCard = withStyles(css)(Card) -``` +## πŸ“˜ Documentation -This technique is similar to the ones found in [Styled Components](https://www.styled-components.com/). +[View the docs](./docs/) to get started with Fancy! diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..63c73b7 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,5 @@ +# Documentation + +* [Getting Started](./getting-started.md) +* [Dynamic Styles](./dynamic-styles.md) +* [Nesting](./nesting.md) diff --git a/docs/dynamic-styles.md b/docs/dynamic-styles.md new file mode 100644 index 0000000..7e6075d --- /dev/null +++ b/docs/dynamic-styles.md @@ -0,0 +1,26 @@ +# Dynamic styles + +In this guide, we're going to be making our CSS styles dynamic, based on your React component's props. + +This technique is similar to the ones found in [Styled Components](https://www.styled-components.com/). + +You can define dynamic styles by passing a `function` into `fancy`. It will have access to a component's `props`, allowing you to define custom rules for various `prop` values. + +### Example + +```jsx +const Card = props => (
) +const css = (props) => ` + div { + background: ${props.title ? 'red' : 'blue'}; + position: relative; + border: 1px solid black; + } +` +const StyledCard = fancy(css)(Card) +``` + + +### πŸ€” How does it work… + +Under the hood, Fancy does a `diff` check in it's virtual Stylesheet (not unlike how React handles VDOM diffing) every time a [component updates](https://reactjs.org/docs/react-component.html#componentdidupdate). If an update occurs, it regenerates the style rules and re-injects it into the document stylesheet. diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..a63283e --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,91 @@ +# Getting Started + +In this guide, we're going to be "fancifying" a React component with some basic CSS styles. + +### Step 1: Import Fancy + +```jsx +import React from 'react' +import fancy from '@helpscout/fancy' +``` + + +### Step 2: Define your styles + +Write your CSS styles as a string. This is default out-of-the-box CSS. Use things like `:hover`, `@media` queries, as you normally would! + +```jsx +const css = ` + .Button { + background: white; + border: 1px solid #eee; + } +` +``` + +Note: You can of course use string interpolation. It's still JS after all! + + +### Step 3: Create your component + +Create your component as you normally would. + +```jsx +const Button = props => ( + + ... + + +``` + +That's it! You're done πŸ™Œ. You've created a CSS-ready component. diff --git a/docs/nesting.md b/docs/nesting.md new file mode 100644 index 0000000..03be38c --- /dev/null +++ b/docs/nesting.md @@ -0,0 +1,30 @@ +# Nesting + +Fancy comes with [stylis](https://github.com/thysultan/stylis.js), a tiny CSS pre-processor. This (amazing) little library provides nifty features like nesting, similar to what you'd get with Less or Sass. + + +### Example + +```jsx +const css = ` + .Card { + background: white; + position: relative; + border: 1px solid black; + + &__block { + padding: 20px; + } + } +` + +const Card = props => ( +
+
+ {props.children} +
+
+) + +const StyledCard = fancy(css)(Card) +``` diff --git a/src/__tests__/fancy.test.js b/src/__tests__/fancy.test.js new file mode 100644 index 0000000..38ec3ec --- /dev/null +++ b/src/__tests__/fancy.test.js @@ -0,0 +1,143 @@ +import React from 'react' +import { mount } from 'enzyme' +import fancy from '../index' + +const removeStyle = fancy.StyleSheet.removeRule + +/** + * Integration tests to ensure that fancy is exported correctly. + */ + +describe('HOC Composition', () => { + const Button = props => (