diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 8656dea03..e4bb0fe1c 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -5,7 +5,7 @@ Have a usage question? ====================== The issue tracker isn't the best place for usage questions. This format is not well-suited for Q&A, and questions here don't have as much visibility as they do elsewhere. Before you ask a question, here are some resources to get help first: -- Read the docs: https://github.com/styled-components/styled-components/blob/master/docs +- Read the docs: https://www.styled-components.com/docs - Look for/ask questions on stack overflow: https://stackoverflow.com/questions/ask?tags=styled-components - Ask in chat: https://gitter.im/styled-components/styled-components diff --git a/README.md b/README.md index ad868b46c..185d669e1 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ - + styled-components
@@ -19,413 +19,27 @@ npm install --save styled-components ![size](http://img.badgesize.io/https://unpkg.com/styled-components/dist/styled-components.min.js?label=size) ![module formats: umd, cjs, esm](https://img.shields.io/badge/module%20formats-umd%2C%20cjs%2C%20esm-green.svg) -Utilising [tagged template literals](./docs/tagged-template-literals.md) (a recent addition to JavaScript) and the [power of CSS](./docs/css-we-support.md), `styled-components` allows you to write actual CSS code to style your components. It also removes the mapping between components and styles – using components as a low-level styling construct could not be easier! +Utilising [tagged template literals](https://www.styled-components.com/docs/advanced#tagged-template-literals) (a recent addition to JavaScript) and the [power of CSS](https://www.styled-components.com/docs/api#supported-css), `styled-components` allows you to write actual CSS code to style your components. It also removes the mapping between components and styles – using components as a low-level styling construct could not be easier! -`styled-components` is compatible with both React (for web) and ReactNative – meaning it's the perfect choice even for truly universal apps! See the [ReactNative section](#react-native) for more information +`styled-components` is compatible with both React (for web) and ReactNative – meaning it's the perfect choice even for truly universal apps! See the [documentation about ReactNative](https://www.styled-components.com/docs/basics#react-native) for more information. > **Note:** If you're not using `npm` as your package manager, aren't using a module bundler or aren't sure about either of those jump to [Alternative Installation Methods](#alternative-installation-methods). -*Made by [Glen Maddern](https://twitter.com/glenmaddern) and [Max Stoiber](https://twitter.com/mxstbr), supported by [Front End Center](https://frontend.center) and [Thinkmill](http://thinkmill.com.au/). Thank you for making this project possible!* - -## Usage - -### Basic - -This creates two react components, `` and `<Wrapper>`: - -```JSX -import React from 'react'; - -import styled from 'styled-components'; - -// Create a <Title> react component that renders an <h1> which is -// centered, palevioletred and sized at 1.5em -const Title = styled.h1` - font-size: 1.5em; - text-align: center; - color: palevioletred; -`; - -// Create a <Wrapper> react component that renders a <section> with -// some padding and a papayawhip background -const Wrapper = styled.section` - padding: 4em; - background: papayawhip; -`; -``` - -*(The CSS rules are automatically vendor prefixed, so you don't have to think about it!)* - -You render them like so: - -```JSX -// Use them like any other React component – except they're styled! -<Wrapper> - <Title>Hello World, this is my first styled component! - -``` - -
- - Screenshot of the above code ran in a browser -
Live demo
-
-
- -### Passed props - -Styled components pass on all their props. This is a styled ``: - -```JS -import React from 'react'; -import styled from 'styled-components'; - -// Create an component that'll render an tag with some styles -const Input = styled.input` - font-size: 1.25em; - padding: 0.5em; - margin: 0.5em; - color: palevioletred; - background: papayawhip; - border: none; - border-radius: 3px; - - &:hover { - box-shadow: inset 1px 1px 2px rgba(0,0,0,0.1); - } -`; -``` - -You can just pass a `placeholder` prop into the `styled-component`. It will pass it on to the DOM node like any other react component: - -```JSX -// Render a styled input with a placeholder of "@mxstbr" - -``` - -Here is one input without any content showing the placeholder, and one with some content: - -
- - Screenshot of the above code ran in a browser -
Live demo
-
-
- -### Adapting based on props - -This is a button component that has a `primary` state. By setting `primary` to `true` when rendering it we adjust the background and text color. *(see [tips and tricks](./docs/tips-and-tricks.md#component-adjustments) for more examples of this pattern!)* - -```JSX -import styled from 'styled-components'; - -const Button = styled.button` - /* Adapt the colors based on primary prop */ - background: ${props => props.primary ? 'palevioletred' : 'white'}; - color: ${props => props.primary ? 'white' : 'palevioletred'}; - - font-size: 1em; - margin: 1em; - padding: 0.25em 1em; - border: 2px solid palevioletred; - border-radius: 3px; -`; - -export default Button; -``` - -```JSX - - -``` - -
- - Screenshot of the above code ran in a browser -
Live demo
-
-
- -#### Styling Components instead of Elements - -`styled` also works perfectly for styling your own or third-party components, like a `react-router` ``! - -```JS -import styled from 'styled-components'; -import { Link } from 'react-router'; - -const StyledLink = styled(Link)` - color: palevioletred; - display: block; - margin: 0.5em 0; - font-family: Helvetica, Arial, sans-serif; - - &:hover { - text-decoration: underline; - } -`; -``` - -```JSX -Standard, unstyled Link -This Link is styled! -``` - -
- - Screenshot of the above code ran in a browser -
Live demo
-
-
- -> **Note:** `styled-components` generate a real stylesheet with classes. The class names are then passed to the react component (including third party components) via the `className` prop. For the styles to be applied, third-party components must attach the passed-in `className` prop to a DOM node. See [Using `styled-components` with existing CSS](./docs/existing-css.md) for more information! -> -> You can also pass tag names into the `styled()` call, like so: `styled('div')`. In fact, the styled.tagname helpers are just aliases of `styled('tagname')`! - -### Extending styles - -Taking the `Button` component from above and removing the primary rules, this is what we're left with – just a normal button: - -```JSX -import styled from 'styled-components'; - -const Button = styled.button` - background: white; - color: palevioletred; - font-size: 1em; - margin: 1em; - padding: 0.25em 1em; - border: 2px solid palevioletred; - border-radius: 3px; -`; - -export default Button; -``` - -Let's say someplace else you want to use your button component, but just in this one case you want the color and border color to be `tomato` instead of `palevioletred`. Now you _could_ pass in an interpolated function and change them based on some props, but that's quite a lot of effort for overriding the styles once. - -To do this in an easier way you can call `extend` on the component to generate another. You style it like any other styled-component. It overrides duplicate styles from the initial component and keeps the others around: - -```JSX -// TomatoButton.js - -import React from 'react'; -import styled from 'styled-components'; - -import Button from './Button'; - -const TomatoButton = Button.extend` - color: tomato; - border-color: tomato; -`; - -export default TomatoButton; -``` - -This is what our `TomatoButton` looks like, even though we have only specified the `color` and the `border-color`. Instead of copy and pasting or factoring out the styles into a separate function we've now reused them. - -
- - Screenshot of the above code ran in a browser -
Live demo
-
-
- -
- -### Animations - -CSS animations with `@keyframes` aren't scoped to a single component but you still don't want them to be global. This is why we export a `keyframes` helper which will generate a unique name for your keyframes. You can then use that unique name throughout your app. - -This way, you get all the benefits of using JavaScript, are avoiding name clashes and get your keyframes like always: - -```JS -import styled, { keyframes } from 'styled-components'; - -// keyframes returns a unique name based on a hash of the contents of the keyframes -const rotate360 = keyframes` - from { - transform: rotate(0deg); - } - - to { - transform: rotate(360deg); - } -`; - -// Here we create a component that will rotate everything we pass in over two seconds -const Rotate = styled.div` - display: inline-block; - animation: ${rotate360} 2s linear infinite; -`; -``` - -This will now rotate it's children over and over again, for example our logo: - -```JSX -< 💅 > -``` - -
- - Animated GIF of the above code ran in a browser -
Live demo
-
-
- -### React Native - -`styled-components` has a ReactNative mode that works _exactly_ the same, except you import the things from `styled-components/native`: - -```JSX -import styled from 'styled-components/native'; - -const StyledView = styled.View` - background-color: papayawhip; -`; - -const StyledText = styled.Text` - color: palevioletred; -`; - -class MyReactNativeComponent extends React.Component { - render() { - return ( - - Hello World! - - ) - } -} -``` - -We also support more complex styles (like `transform`), which would normally be an array, and shorthands (e.g. for `margin`) thanks to [`css-to-react-native`](https://github.com/styled-components/css-to-react-native)! Imagine how you'd write the property in ReactNative, guess how you'd transfer it to CSS and you're probably right: - -```JS -const RotatedBox = styled.View` - transform: rotate(90deg); - text-shadow-offset: 10px 5px; - font-variant: small-caps; - margin: 5px 7px 2px; -` -``` - -> You cannot use the `keyframes` and `injectGlobal` helpers since ReactNative doesn't support keyframes or global styles. We will also log a warning if you use media queries or nesting in your CSS. - -### Theming - -`styled-components` has full theming support by exporting a wrapper `` component. This component provides a theme to all react components underneath itself in the render tree, even multiple levels deep. - -To illustrate this, let's create a component that renders its children with a theme. We do so by wrapping all its children in a `ThemeProvider` that has a `theme`: - -```JSX -import { ThemeProvider } from 'styled-components'; - -const theme = { - main: 'mediumseagreen', -}; - -// Create a GreenSection component that renders its children wrapped in -// a ThemeProvider with a green theme -const GreenSection = (props) => { - return ( - - {props.children} - - ); -} -``` - -Second, let's create a styled component that adapts to the theme. - -`styled-components` injects the current theme via `props.theme` into the components, which means you can adapt your component to the theme with interpolated functions. - -We'll create a `button` that adapts based on the `main` property of the theme: - -```JS -// Button.js -import styled from 'styled-components'; - -const Button = styled.button` - /* Color the background and border with theme.main */ - background: ${props => props.theme.main}; - border: 2px solid ${props => props.theme.main}; - - /* …more styles here… */ -`; -``` - -Now, when we render the `Button` inside a `GreenSection`, it'll be green! - -```JSX - -
- {/* Notice how there's no code changes for the button, it just - adapts to the theme passed from GreenSection! */} - -
-
- {/* This works unlimited levels deep within the component - tree since we use React's context to pass the theme down. */} - -
-
-
-
-``` - -
- - Screenshot of the above code ran in a browser -
Live demo
-
-
- -See the [theming doc](./docs/theming.md) for more detailed instructions. - -> **Note:** Please make sure you sanitize user input if you accept custom themes from users! See the [security doc](./docs/security.md) for more information. - -#### Defaults - -The problem with the above code is that if the button is rendered outside a `ThemeProvider`, it won't have any background or border! - -There is an easy remedy though. Since `Button` is just a react component we can assign `defaultProps`, which will be used if no theme is provided: - -```JS -// Button.js -import styled from 'styled-components'; - -const Button = styled.button` - /* Color the background and border with theme.main */ - background: ${props => props.theme.main}; - border: 2px solid ${props => props.theme.main}; - - /* …more styles here… */ -`; - -// Set the default theme, in our case main will be -// palevioletred if no other theme is specified -Button.defaultProps = { - theme: { - main: 'palevioletred', - }, -}; -``` +*Made by [Glen Maddern](https://twitter.com/glenmaddern), [Max Stoiber](https://twitter.com/mxstbr) and [Phil Plückthun](https://twitter.com/_philpl), supported by [Front End Center](https://frontend.center) and [Thinkmill](http://thinkmill.com.au/). Thank you for making this project possible!* ## Docs -See [the documentation](./docs) for more information about using `styled-components`. +**See the documentation at [styled-components.com/docs](https://www.styled-components/docs)** for more information about using `styled-components`! + +### Quicklinks -### Table of Contents +Quicklinks to some of the most-visited pages: -- [API Reference](./docs/api.md) -- [Flow Support](./docs/flow-support.md) -- [Tips and Tricks](./docs/tips-and-tricks.md) -- [Tagged Template Literals](./docs/tagged-template-literals.md): How do they work? -- [Using `styled-components` with existing CSS](./docs/existing-css.md): Some edge cases you should be aware of when using `styled-components` with an existing CSS codebase -- [What CSS we support](./docs/css-we-support.md): What parts & extensions of CSS can you use within a component? *(Spoiler: all of CSS plus even more)* -- [Theming](./docs/theming.md): How to work with themes -- [FAQ](./docs/faq.md): Frequently Asked Questions +- [**Gettings started**](https://www.styled-components.com/docs/basics) +- [API Reference](https://styled-components.com/docs/api) +- [Theming](https://www.styled-components.com/docs/advanced#theming) +- [Server-side rendering](https://www.styled-components.com/docs/advanced#server-side-rendering) +- [Tagged Template Literals explained](https://www.styled-components.com/docs/advanced#tagged-template-literals) ## Linting @@ -557,7 +171,7 @@ If `styled-components` isn't quite what you're looking for, maybe something in t ## License -Licensed under the MIT License, Copyright © 2016 Glen Maddern and Maximilian Stoiber. +Licensed under the MIT License, Copyright © 2017 Glen Maddern and Maximilian Stoiber. See [LICENSE](./LICENSE) for more information. diff --git a/docs/README.md b/docs/README.md index fd79ba692..19136831e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,16 +1,3 @@ # Documentation -This is the `styled-components` documentation. - -## Table of Contents - -- [API Reference](./api.md): A reference for all APIs that we export or return -- [Tips and Tricks](./tips-and-tricks.md): A few handy tips for working with `styled-components` -- [Tagged Template Literals](./tagged-template-literals.md): How do they work? -- [Using `styled-components` with existing CSS](./existing-css.md): Some edge cases you should be aware of when using `styled-components` with an existing CSS codebase -- [What CSS we support](./css-we-support.md): What parts & extensions of CSS can you use within a component? -- [Theming](./theming.md): How to work with themes -- [Security](./security.md): Security considerations when allowing users to configure themes -- [React Native](./react-native.md): Details for React Native -- [Typescript](./typescript-support.md): Typescript Support -- [FAQ](./faq.md): Frequently Asked Questions +**The documentation has been moved to [styled-components.com](https://www.styled-components.com/docs), please update your bookmarks!** diff --git a/docs/api.md b/docs/api.md index 2f55e8aa7..2b92f6b70 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1,295 +1 @@ -# API Reference - -The APIs marked as `web` work with React, the APIs marked as `native` work with ReactNative. To switch to ReactNative mode: - -```JS -import styled, { css } from 'styled-components/native'; -``` - -## Primary - -### `styled` - -Default export. `web`, `native`. - -This is a low-level factory we use to create the `styled.tagname` helper methods. - -#### Arguments - -1. `component`|`tagname` _(Function|String)_: Either a valid react component or a tagname like `'div'`. - -#### Returns - -(`Anonymous Function`): A function that takes your [`TaggedTemplateLiteral`](#taggedtemplateliteral) and turns it into a [`StyledComponent`](#styledcomponent). - -#### Example - -```JS -import styled from 'styled-components'; - -const Button = styled.button` - background: palevioletred; - border-radius: 3px; - border: none; - color: white; -`; - -const TomatoButton = styled(Button)` - background: tomato; -`; -``` - -```JSX - -I am tomato -``` - -#### Tips - -- We encourage you to not use the `styled('tagname')` notation directly. Instead, rely on the `styled.tagname` helpers like `styled.button`. We define all valid HTML5 and SVG elements. (it's an automatic fat finger check too) - - -### `TaggedTemplateLiteral` - -`web`, `native`. - -This is what you pass into your `styled` calls – a tagged template literal. This is an ES6 language feature, so you can learn more about the basics on [MDN](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Template_literals#Tagged_template_literals). - -> We are aware that this isn't an export, but it's a big part of what you'll be writing in your app, so it lives here. - -#### Input - -This can take any combination of - -- `Rule` (`String`): Any CSS rule -- `Interpolation` (`String`|`Function`): If this is a string, we take it as-is. If this is a function, we pass in the props passed to the component as the first (and only) argument. - -> **Note**: You can also pass an Object as an interpolation, and we will treat it like inline styles. This is highly discouraged, as the CSS syntax has support for media queries, nesting, etc., which the object syntax doesn't. - -The properties that are passed into an interpolated function get attached a special property, `theme`, which is injected by a higher level [`ThemeProvider`](#themeprovider) component. - -#### Examples - -```JS -import styled from 'styled-components'; - -const padding = '3em'; - -const Section = styled.section` - color: white; - padding: ${padding}; - - /* Adjust the background from the properties */ - background: ${(props) => props.background}; - - /* Adapt based on the theme set in a parent ThemeProvider */ - border: ${(props) => props.theme.main} -`; - -// Set the default theme and props fallback -Section.defaultProps = { - background: 'palevioletred', - theme: { - main: 'palevioletred', - }, -}; -``` - -```JSX - - - - -``` - -#### Tips - -- You're writing CSS, but with the power of JavaScript - utilise it! (see [Tips and Tricks](./tips-and-tricks.md) for some ideas) -- Use `defaultProps` for defaulting certain props or a theme. (it will inherit with the `styled(StyledComponent)` notation) - - -### `css` - -`web`, `native`. - -A helper function to generate CSS from a template literal with interpolations. You need to use this if you return a template literal with interpolations inside an interpolation. (this is due to how tagged template literals work) - -If you're just returning a normal string you do not need to use this. - -#### Arguments - -1. `TaggedTemplateLiteral`: A tagged template literal with your keyframes inside. - -#### Returns - -- `Interpolations` (`Array`): A flattened data structure which you can pass into an interpolation. - -#### Examples - -```JS -import styled, { css } from 'styled-components'; - -const StyledComp = styled.div` -${(props) => { - if (props.complex) { - // Returning a template literal with interpolations? You need to use `css` - return css` - color: ${ props => props.whiteColor ? 'white': 'black' } - `; - } else { - // Returning a standard string? No need to use `css` - return 'color: blue;'; - } -}} -`; -``` - -If you leave off the `css` your function will be `toString()`ed and you'll not get the results you expected. - - -### `StyledComponent` - -`web`, `native`. - -A styled react component. This is returned when you call `styled.tagname` or `styled(Component)` with styles. - -#### Tips - -- This component can take any prop. It passes it on the HTML node if it's a valid attribute, otherwise it only passes it into interpolated functions. (see [TaggedTemplateLiteral](#taggedtemplateliteral)) -- You can pass an arbitrary classname to a styled component without problem and it will be applied next to the styles defined by the `styled` call. (e.g. ``) - -## Helpers - -### `keyframes` - -`web` only. - -A helper method to create keyframes for animations. - -#### Arguments - -1. `TaggedTemplateLiteral`: A tagged template literal with your keyframes inside. - -#### Returns - -`name` ( `String`): A unique name for these keyframes, to be used in your `animation` declarations. - -#### Example - -```JS -// keyframes.js -import { keyframes } from 'styled-components'; - -const fadeIn = keyframes` - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } -`; - -export { - fadeIn, -} -``` - -```JS -import styled from 'styled-components'; -import { fadeIn } from '../keyframes'; - -const FadeInButton = styled.button` - animation: 1s ${fadeIn} ease-out; -`; -``` - - -### `ThemeProvider` - -`web`, `native`. - -A helper component for theming. Injects the theme into all styled components anywhere beneath it in the component tree. - -#### Props - -- `theme` _(Object)_: The data that should be injected into the child styled components. - -#### Example - -```JS -const Box = styled.div` - color: ${props => props.theme.color}; -`; -``` - -```JSX - - I'm mediumseagreen! - -``` - -### `injectGlobal` - -`web` only. - -A helper method to write global CSS. Does not return a component, adds the styles to the stylesheet directly. - -**We do not encourage the use of this. Use once per app at most, contained in a single file.** This is an escape hatch. Only use it for the rare `@font-face` definition or `body` styling. - -#### Arguments - -1. `TaggedTemplateLiteral`: A tagged template literal with your global styles inside. - -#### Example - -```JS -// global-styles.js - -import { injectGlobal } from 'styled-components'; - -injectGlobal` - @font-face { - font-family: 'Operator Mono'; - src: url('../fonts/Operator-Mono.ttf'); - } - - body { - margin: 0; - } -`; -``` - -### `withTheme` - -`web`, `native`. - -This is a `higher order component` to get the current theme from [`ThemeProvider`](#themeprovider) and pass it to another component as a `theme` prop. - -#### Arguments - -1. `component` _(Function|class)_: Any valid react component that can handle a `theme` prop. - -#### Returns - -(`component`): The passed component inside a wrapper. The passed component will receive a `theme` prop with the current theme object. - -#### Example - -```JS -import { withTheme } from 'styled-components' - -class MyComponent extends React.Component { - render() { - const { theme } = this.props - - console.log('Current theme: ', theme); - // ... - } -} - -export default withTheme(MyComponent) -``` - -#### Tips - -- Only use this if you need to get the theme as a prop. If you just need to set a valid stylesheet property, you can use normal [theming](./theming.md) for this. +**The documentation has been moved to [styled-components.com](https://styled-components.com/docs/api), please update your bookmarks!** diff --git a/docs/css-we-support.md b/docs/css-we-support.md index 94323ad72..9b1b57dba 100644 --- a/docs/css-we-support.md +++ b/docs/css-we-support.md @@ -1,38 +1 @@ -# CSS We Support - -Within a styled component, we support all of CSS, including nesting – since we generate an actual stylesheet and not inline styles, whatever works in CSS works in a styled component! - -```js -styled.div` - any: selector; - something: that needs prefixes; /* will be prefixed */ - &:pseudo-selectors { - all good; - } - @media (min-width: 600px) { - aint-no: thing; - } - > h1 { - direct-descendants: fine too; /* all descendants work fine too - but not recommended. */ - } - html.what-about-contextual & { - sall: good; - } -` -``` - -> **Note:** Ampersands (`&`) get replaced by our generated, unique classname for that styled component, making it easy to have complex logic - -On top of that you can always use `injectGlobal` for actually global things, like `@font-face`: - -```js -import { injectGlobal } from 'styled-components' - -injectGlobal` - @font-face { - font-family: 'Operator Mono'; - src: url('../fonts/Operator-Mono.ttf'); - } -` -``` +**The documentation has been moved to [styled-components.com](https://www.styled-components.com/docs/api#supported-css), please update your bookmarks!** diff --git a/docs/existing-css.md b/docs/existing-css.md index 4a46a11de..ec4980fc9 100644 --- a/docs/existing-css.md +++ b/docs/existing-css.md @@ -1,73 +1 @@ -# Using `styled-components` with existing CSS - -`styled-components` generate an actual stylesheet with classes, and attaches those classes to the DOM nodes of styled components via the `className` prop. It injects the generated stylesheet at the end of the HEAD of the document. - -## Styling normal React components - -If you use the `styled(MyNormalComponent)` notation and `MyNormalComponent` does not render the passed-in `className` prop the styles will **not** be applied. - -To avoid this issue, make sure your component (in this case `MyNormalComponent`) attaches the passed-in `className` to a DOM node: - -```JSX -class MyNormalComponent extends React.Component { - render() { - return ( - // Attach the passed-in className to the DOM node -
- ); - } -} -``` - -If you have pre-existing styles with a class, you can combine the global class with the `styled-components` one: - -```JSX -class MyNormalComponent extends React.Component { - render() { - return ( - // Use a global class with existing styling in combination with - // allowing this component to be styled with styled-components -
- ); - } -} -``` - -## Global class always overridden - -You can apply a global CSS class to a styled component by adding a `className` prop. This will work, but if a specific CSS property (e.g. `background-color`) is defined in both the global CSS _and_ the styled component the results may not be what your expecting! - -A contrived example: - -```JS -// MyComponent.js -const MyComponent = styled.div`background-color: green;`; -``` - -```CSS -/* my-component.css */ -.red-bg { - background-color: red; -} -``` - -```JSX -// For some reason this component still has a green background, -// even though you're trying to override it with the "red-bg" class! - -``` - -This is because `styled-components` injects the stylesheet at the end of the HEAD. If the CSS class you wrote is before the injected styles in the DOM, because of the cascade, the last styles targeting the same element (in this case the `styled-components` ones) will win! - -You can easily fix this by moving your CSS class to the beginning of the body in the DOM. - -Sadly, some tools (like the webpack `style-loader`) give you no control over the place they inject the CSS into, meaning you cannot move them after the `styled-components` one. - -The easy fix for that is bumping up the specificity of the CSS class you're overriding with, by writing it twice: - -```CSS -/* my-component.css */ -.red-bg.red-bg { - background-color: red; -} -``` +**The documentation has been moved to [styled-components.com](https://www.styled-components.com/docs/advanced#existing-css), please update your bookmarks!** diff --git a/docs/flow-support.md b/docs/flow-support.md index 070a24b93..3740aa4d0 100644 --- a/docs/flow-support.md +++ b/docs/flow-support.md @@ -1,27 +1 @@ -# Flow Support - -To use flowtype with the public api of styled-components we recommend that -you use the library definition in [flow-typed]. - -To install it you can use the flow-typed cli or download it manually from -the git repository and storing it in a flow-typed folder in the same folder -as your flowconfig. - -### Installing the libdef with flow-typed - -```shell -npm i -g flow-typed # if you do not already have flow-typed -flow-typed install styled-components@ -``` - -### Ignore styled-components sources from flow - -You should add this to your flowconfig if you run into flow errors from the -styled-components package in node_modules. - -``` -[ignore] -.*/node_modules/styled-components/.* -``` - -[flow-typed]: https://github.com/flowtype/flow-typed +**The documentation has been moved to [styled-components.com](https://www.styled-components.com/docs/api#flow), please update your bookmarks!** diff --git a/docs/react-native.md b/docs/react-native.md index 062ecc110..f8e706d2f 100644 --- a/docs/react-native.md +++ b/docs/react-native.md @@ -1,75 +1 @@ -# React Native - - -`styled-components` has a ReactNative mode that works _exactly_ the same, except you import the things from `styled-components/native`: - -```JSX -import styled from 'styled-components/native'; - -const StyledView = styled.View` - background-color: papayawhip; -`; - -const StyledText = styled.Text` - color: palevioletred; -`; - -class MyReactNativeComponent extends React.Component { - render() { - return ( - - Hello World! - - ) - } -} -``` - -We also support more complex styles (like `transform`), which would normally be an array, and shorthands (e.g. for `margin`) thanks to [`css-to-react-native`](https://github.com/styled-components/css-to-react-native)! Imagine how you'd write the property in ReactNative, guess how you'd transfer it to CSS and you're probably right: - -```JS -const RotatedBox = styled.View` - transform: rotate(90deg); - text-shadow-offset: 10 5; - font-variant: small-caps; - margin: 5 7 2; -` -``` - -> You cannot use the `keyframes` and `injectGlobal` helpers since ReactNative doesn't support keyframes or global styles. We will also log a warning if you use media queries or nesting in your CSS. - -## Animations - -To get React Native animations working, you'll want to define all your non-changing styles in the usual way, and then bind animation with `createAnimatedComponent` and pass your `Animated.Value`s in as style props. - -```js -const StyledView = styled.View` - height: 100; - width: 100; - background-color: red; -` -const AnimatedStyledView = Animated.createAnimatedComponent(StyledView) - -class AnimateOpacity extends Component { - constructor() { - super() - - this.state = { - opacity: new Animated.Value(0) - } - } - - componentWillMount() { - Animated.timing(this.state.opacity, { - toValue: 1, - duration: 1000, - }).start() - } - - render() { - const { opacity } = this.state; - // Pass in your animated values here! - return - } -} -``` +**The documentation has been moved to [styled-components.com](https://www.styled-components.com/docs/basics#react-native), please update your bookmarks!** diff --git a/docs/security.md b/docs/security.md index 5f91ad02b..8354cc7e9 100644 --- a/docs/security.md +++ b/docs/security.md @@ -1,62 +1 @@ -# Security - -**Please do not forget to sanitize and validate input!** - -`styled-components` allows you to interpolate all kinds of things into your CSS. Some of these interpolations can consist of more than one declaration: - -```JS -// This totally works! -const red = 'color: palevioletred; background: papayawhip;'; - -const Button = styled.button` - ${red} -` -``` - -As powerful as this is, it's also a potential security hazard if you're not mindful because it allows CSS injection. Imagine something like this: - -```JS -import { someCSS } from '../utils-my-coworker-wrote'; - -const Box = styled.div` - ${someCSS} -` -``` - -Now you glanced at this `someCSS` variable and somewhere inside the code this is declared: - -```JS -const someCSS = ` - /* More styles here */ - background: url(/api/withdraw-funds); - /* More styles here */ -` -``` - -**⚠ OH NO ⚠** whenever you render this `Box` all of the users funds are withdrawn! - -### Be very careful when interpolating more than a simple value. - -This is obviously a made-up example, but CSS injection can be unobvious and have bad repercussions. (some IE versions [execute arbitrary JavaScript within `url` declarations](http://httpsecure.org/?works=css-injection) or [within the `expression` directive](https://stackoverflow.com/questions/3607894/cross-site-scripting-in-css-stylesheets) 😱) - ----- - -This is especially important when you take user input: - -Imagine you have an app which allows users to provide custom themes by pasting some CSS. Somebody posts a dark theme on their blog so users can have a "night mode". Super cool! - -Somewhere within this long string of CSS you let your users provide, the poster embedded our tiny declaration again: - -```CSS -.YourApp__navbar__item--active { - background: url(/api/withdraw-funds); -} -``` - -**⚠ OH NO ⚠** suddenly, every user that finds this random theme on Google and copy and pastes it to your app interface withdraws all their funds! - -### Constrain user input - -If you let users input or configure themes, please make sure to constrain the inputs. The most important thing to keep in mind is to never let users provide more than simple values. As soon as you allow arbitrary CSS declarations, exploits like the one above become possible. For example, let users provide just six hex colors to configure the general skin of your app! - -By applying constraints to your themes, validation becomes much easier – run a short regex (like `/^#([A-F0-9]{6}|[A-F0-9]{3})$/i` for hex colors) or validation functions over the inputs to make sure what's provided contains nothing but simple values. +**The documentation has been moved to [styled-components.com](https://www.styled-components.com/docs/advanced#security), please update your bookmarks!** diff --git a/docs/tagged-template-literals.md b/docs/tagged-template-literals.md index 8c463272a..cd71b5b5e 100644 --- a/docs/tagged-template-literals.md +++ b/docs/tagged-template-literals.md @@ -1,72 +1 @@ -# ES6 Tagged Template Literals - -**For an alternate explanation see @mxstbr's blog post: [The magic behind :nail_care: styled-components](http://mxstbr.blog/2016/11/styled-components-magic-explained/)** - -Tagged Template Literals are a new feature in ES6 that lets you define _custom string interpolation_ rules, which is how we're able to create styled components. - -If you have no interpolations, they're very similar. This: - -```js -myFunction`some string here` -``` - -is equivalent to this: - -```js -myFunction(['some string here']) -``` - -When you use interpolations, a normal template string simply calls toString() on each interpolation and joins the string together: - -```js -const str = `1 + 2 = ${1 + 2}. Array: ${ [1,2,3] }. Object: ${ { a: 1 } }` -//#> "1 + 2 = 3. Array: 1,2,3. Object: [object Object]" -``` - -But if you pass this to a template function, you get passed all the strings and interpolations and can do whatever you like! - -```js -const myFunction = (...args) => JSON.stringify([...args]) -myFunction`1 + 2 = ${1 + 2}. Array: ${ [1,2,3] }. Object: ${ { a: 1 } }` -//#> [ -//#> ["1 + 2 = ", ". Array: ", ". Object: ", "" ], -//#> 3, -//#> [ 1, 2, 3 ], -//#> { "a": 1 } -//#> ] -``` - -The string chunks and interpolations are passed as follows: - -```js -myFunction( stringChunks, ...interpolations) -``` - -It's a little annoying to work with but it means that we can turn - -```js -styled.div` - color: tomato; - ${ props => props.background} -` -``` -into an object and re-evaluate it whenever a StyledComponent's componentWillReceiveProps lifecycle method is called. Neat hey! - -## In Styled Components - -Whenever you call ``styled.xyz` ... ` ``, underneath we call `css` with the CSS code. You can use `css` yourself if you ever need a chunk of CSS to work like a styled component: (kind of like a mixin!) - -```js -import styled, { css } from 'styled-components' - -const chunk = css` - color: red; - ${ props => props.background && 'background: white' } -` - -const Div = styled.div` - ${ chunk } -` -``` - -If you leave off the `css` in `chunk` your function will be `toString()`ed and you'll not get the results you expected. +**The documentation has been moved to [styled-components.com](https://www.styled-components.com/docs/advanced#tagged-template-literals), please update your bookmarks!** diff --git a/docs/theming.md b/docs/theming.md index 648a337f9..88d65ec5b 100644 --- a/docs/theming.md +++ b/docs/theming.md @@ -1,78 +1 @@ -# Theming - -Theming is a first-class citizen in `styled-components`. We want to make it as easy as possible to use a reusable and sharable component library. - -## Using theming - -We export a `` component that takes a `theme` prop. The `theme` you provide there is injected into your styled components via `props.theme`: - -```JSX -import styled, { ThemeProvider } from 'styled-components'; - -const Button = styled.button` - /* Set the background of this button from the theme */ - background: ${props => props.theme.main}; -`; - -// Create a green theme -const greenTheme = { - main: 'mediumseagreen', -}; - -// Create a red theme -const redTheme = { - main: 'palevioletred', -}; - -const MyApp = () => { - return ( -
- {/* All children of this component will be green */} - - - - {/* All children of this component will be red */} - -
- -
-
-
- ); -} -``` - -Please make sure you sanitize user input if you accept custom themes from users! See the [security doc](./security.md) for more information. - -## Function themes - -You can also pass a `theme` that is a function from `outerTheme => newValues`. This can be useful to make themes that are themselves contextual. - -```js -/* A theme that swaps the 'fg' and 'bg' colours for all its children. */ - -const InvertColors = ({children}) => ( - ({ fg: outerTheme.bg, bg: outerTheme.fg })}> - { children } - -) -``` - -## Getting the theme outside styled components - -If you ever need to get the current `theme` outside styled components (e.g. inside big components), you can use the `withTheme` Higher Order Component: - -```JS -import { withTheme } from 'styled-components' - -class MyComponent extends React.Component { - render() { - const { theme } = this.props - - console.log('Current theme: ', theme); - // ... - } -} - -export default withTheme(MyComponent) -``` +**The documentation has been moved to [styled-components.com](https://www.styled-components.com/docs/advanced#theming), please update your bookmarks!** diff --git a/docs/typescript-support.md b/docs/typescript-support.md index fae8c578a..524d382d5 100644 --- a/docs/typescript-support.md +++ b/docs/typescript-support.md @@ -1,135 +1 @@ -# Typescript Support - -`styled-components` has typescript definitions to allow the library to be -used in any Typescript project. - -To use the library you can import it as you normally do with any TS dependency. - -``` -import styled from 'styled-components' -``` - -## Example - -A very basic example can be found [here](https://github.com/patrick91/Styled-Components-Typescript-Example). - -## Define a Theme Interface - -By default every styled component will have the theme prop set to `any`. -When building complex apps it would be better to have autocomplete and -error checks everywhere. - -To have autocomplete and checks around the theme prop we should first define -the theme interface we would like to use throught our app: - -```ts -// theme.ts -export default interface ThemeInterface { - primaryColor: string; - primaryColorInverted: string; -} -``` - -then we can re-export the styled function with our custom theme interface: - -```ts -// my-styled-components.ts -import * as styledComponents from "styled-components"; -import { ThemedStyledComponentsModule } from "styled-components"; - -import ThemeInterface from "./theme"; - -const { - default: styled, - css, - injectGlobal, - keyframes, - ThemeProvider -} = styledComponents as ThemedStyledComponentsModule; - -export default styled; -export { css, injectGlobal, keyframes, ThemeProvider }; -``` - -Finally, instead of importing the styled functions from the `styled-components` module, -we import it from our custom module. - -```ts -import * as React from "react"; - -// same for css, etc -import styled from "themed-components"; - - -const Link = styled.a` - font-family: 'Cabin'; - font-weight: bold; - font-size: 1.2rem; - letter-spacing: 0.05em; - color: {props => props.theme.primaryColor}; - display: block; - cursor: pointer; - - transition: 0.3s background ease-out; - - &:hover { - background: rgba(255, 255, 255, 0.2); - } -`; - - -export default Link; -``` - -## Caveats - -### Class Name - -When defining a component you'd need to have `className` marked as optional -in the propTypes interface: - -```ts -interface LogoProps { - className?: string; -} - - -class Logo extends React.Component { - render() { - return
- Logo -
; - } -} - -const LogoStyled = styled(Logo)` - font-family: 'Helvetica'; - font-weight: bold; - font-size: 1.8rem; -`; -``` - -This is because typescript won't understand that `LogoStyled` has already a `className` set. - -### Stateless Component - - -To use stateless components and have typechecking for the props you'd need to -define the component alongside with its type, like this: - -```ts -interface BoxProps { - theme?: ThemeInterface; - borders?: boolean; - className?: string; -} - - -const Box:React.StatelessComponent = (props) => -
{props.children}
; - - -const StyledBox = styled(Box)` - padding: ${props => props.theme.lateralPadding}; -`; -``` +**The documentation has been moved to [styled-components.com](https://www.styled-components.com/docs/api#typescript), please update your bookmarks!**