Skip to content

Commit

Permalink
Merge pull request #16 from helpscout/styled-theme-provider
Browse files Browse the repository at this point in the history
Styled + ThemeProvider
  • Loading branch information
ItsJonQ committed May 29, 2018
2 parents 14c539e + 510b312 commit 6cd29df
Show file tree
Hide file tree
Showing 33 changed files with 719 additions and 277 deletions.
5 changes: 4 additions & 1 deletion .babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"presets": ["env", "react"]
"presets": ["env", "react", "flow"],
"plugins": [
"transform-object-rest-spread"
]
}
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package.json
package-lock.json
dist/
coverage/
3 changes: 3 additions & 0 deletions .prettierrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
semi: false
singleQuote: true
trailingComma: es5
21 changes: 9 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,27 @@
# ❄️ Fancy [![npm version](https://badge.fury.io/js/%40helpscout%2Ffancy.svg)](https://badge.fury.io/js/%40helpscout%2Ffancy) [![Build Status](https://travis-ci.org/helpscout/fancy.svg?branch=master)](https://travis-ci.org/helpscout/fancy) [![Coverage Status](https://coveralls.io/repos/github/helpscout/fancy/badge.svg?branch=master)](https://coveralls.io/github/helpscout/fancy?branch=master)
# ❄️ Fancy [![npm version](https://badge.fury.io/js/%40helpscout%2Ffancy.svg)](https://badge.fury.io/js/%40helpscout%2Ffancy) [![Build Status](https://travis-ci.org/helpscout/fancy.svg?branch=master)](https://travis-ci.org/helpscout/fancy) [![Coverage Status](https://coveralls.io/repos/github/helpscout/fancy/badge.svg?branch=master)](https://coveralls.io/github/helpscout/fancy?branch=master)

> A simple way to include CSS with React Components.
* **Tiny**, around 1.7 KB gzipped
* **One dependency** - ([Stylis](https://github.com/thysultan/stylis.js))
* **Write** plain ol' CSS. Period.
* **Pre-processing** when you need it. Powered by [Stylis](https://github.com/thysultan/stylis.js).
* **Uniquely** generated classNames, [CSS Modules](https://github.com/css-modules/css-modules) style.
* **Integrate** with ease into your existing setup. No fiddling with Webpack required.

- **Tiny**, around 2.05 KB gzipped
- **One dependency** - ([Stylis](https://github.com/thysultan/stylis.js))
- **Write** plain ol' CSS. Period.
- **Pre-processing** when you need it. Powered by [Stylis](https://github.com/thysultan/stylis.js).
- **Uniquely** generated classNames, [CSS Modules](https://github.com/css-modules/css-modules) style.
- **Integrate** with ease into your existing setup. No fiddling with Webpack required.

## 🔧 Installation

```
npm install --save @helpscout/fancy
```


## 🕹 Usage

Here's a quick example of how you can compose regular CSS with your React components.

```jsx
import React from 'react'
import fancy from '@helpscout/fancy'
import styled from '@helpscout/fancy'

const css = `
.Button {
Expand All @@ -40,10 +38,9 @@ const Button = props => {
</button>
}

export default fancy(css)(Button)
export default styled(Button)(css)
```


## 📘 Documentation

[View the docs](./docs/) to get started with Fancy!
9 changes: 5 additions & 4 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Documentation

* [Getting Started](./getting-started.md)
* [Nesting](./nesting.md)
* [Dynamic Styles](./dynamic-styles.md)
* [Dynamic ClassNames](./dynamic-classnames.md)
- [Getting Started](./getting-started.md)
- [Nesting](./nesting.md)
- [Dynamic Styles](./dynamic-styles.md)
- [Dynamic ClassNames](./dynamic-classnames.md)
- [Theming](./theming.md)
15 changes: 4 additions & 11 deletions docs/dynamic-classnames.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ In this guide, we're going to be using dynamic classNames generated by Fancy (in

This feature was popularized by [CSS Modules](https://github.com/css-modules/css-modules).


### Basic Example

Fancy provides you with a "styles" prop, that contains unique classNames that is generated from and maps to your defined CSS.
Expand All @@ -22,7 +21,7 @@ const css = `
border: 1px solid black;
}
`
const StyledCard = fancy(css)(Card)
const StyledCard = styled(Card)(css)
```

#### Result (CSS)
Expand All @@ -46,8 +45,6 @@ Fancy **preserves** your original className. This is allow for reusability of yo

Note: This feature is **only available** to class-based selectors. Selectors like `div` or `#id` will not receive unique classNames.



### BEM example

Fancy will generate unique classNames for BEM-style nested selectors.
Expand All @@ -71,7 +68,7 @@ const css = `
}
}
`
const StyledCard = fancy(css)(Card)
const StyledCard = styled(css)(Card)
```

#### Result (CSS)
Expand All @@ -90,8 +87,6 @@ const StyledCard = fancy(css)(Card)
}
```



### Multiple classNames example

Fancy's unique className generator isn't limited to a single className scope. Include as many as you need!
Expand All @@ -115,7 +110,7 @@ const css = `
padding: 20px;
}
`
const StyledCard = fancy(css)(Card)
const StyledCard = styled(css)(Card)
```

#### Result (CSS)
Expand All @@ -134,8 +129,6 @@ const StyledCard = fancy(css)(Card)
}
```



### Sibling classNames

Fancy allows for you to create sibling rules, indicated by `+` or `~`.
Expand All @@ -157,7 +150,7 @@ const css = `
}
}
`
const StyledCard = fancy(css)(Card)
const StyledCard = styled(css)(Card)
```

#### Result (CSS)
Expand Down
7 changes: 3 additions & 4 deletions docs/dynamic-styles.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,17 @@ You can define dynamic styles by passing a `function` into `fancy`. It will have
### Example

```jsx
const Card = props => (<div {...props} />)
const css = (props) => `
const Card = props => <div {...props} />
const css = props => `
div {
background: ${props.title ? 'red' : 'blue'};
position: relative;
border: 1px solid black;
}
`
const StyledCard = fancy(css)(Card)
const StyledCard = styled(Card)(css)
```


### 🤔 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.
16 changes: 4 additions & 12 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ 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!
Expand All @@ -25,29 +24,24 @@ const css = `

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 => (
<button className='Button' {...props} />
)
const Button = props => <button className="Button" {...props} />
```

Note: The reference the CSS `className` to match the CSS you wrote. Fancy does not generated uniquely hashed classNames for you. See [CSS Modules](https://github.com/css-modules/css-modules) for that feature.


### Step 4: Compose your CSS with your component

When exporting your component, compose it with the `fancy` higher-order component along with your CSS styles.

```jsx
export default fancy(css)(Button)
export default styled(Buton)(css)
```


### Final code

```jsx
Expand All @@ -61,11 +55,9 @@ const css = `
}
`

const Button = props => (
<button className='Button' {...props} />
)
const Button = props => <button className="Button" {...props} />

export default fancy(css)(Button)
export default styled(Button)(css)
```

### Results
Expand Down
9 changes: 3 additions & 6 deletions docs/nesting.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

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
Expand All @@ -19,12 +18,10 @@ const css = `
`

const Card = props => (
<div className='Card'>
<div className='Card__block'>
{props.children}
</div>
<div className="Card">
<div className="Card__block">{props.children}</div>
</div>
)

const StyledCard = fancy(css)(Card)
const StyledCard = styled(Card)(css)
```
53 changes: 53 additions & 0 deletions docs/theming.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Theming

Fancy comes with `Theme.Provider`. Added to the top-level of your app, it can modify fancy styled components via a special `props.theme` prop.

Define your theme props to `Theme.Provider` as `theme`.

### Example

```jsx
import styled, { ThemeProvider } from '@helpscout/fancy'

const css = props => `
.Card {
background: ${props.theme.dark ? 'black' : 'white'};
position: relative;
border: 1px solid black;
}
`

const Card = props => (
<div className="Card">
<div className="Card__block">{props.children}</div>
</div>
)

const StyledCard = styled(Card)(css)

const App = () => {
;<div id="App">
<ThemeProvider theme={{ dark: true }}>
<div>
...
<StyledCard />
...
</div>
</ThemeProvider>
</div>
}
```

## Scoping

`Theme.Provider` has another special `scope` prop that allows you to define additional selectors to scope your fancy `styled` component CSS under.

### Example

```jsx
<ThemeProvider scope="html #App">
<StyledCard />
</ThemeProvider>
```

If the hashed CSS classes for `StyledCard` was `.Card__213jdhx`, they will now render as `html #App .Card__213jdhx`.
Loading

0 comments on commit 6cd29df

Please sign in to comment.