From 08092ed3ae433760b11a91a1844ba8d7ba605b83 Mon Sep 17 00:00:00 2001 From: Matt Hamil Date: Thu, 8 Dec 2016 11:08:29 -0600 Subject: [PATCH] feat: add radial gradients (#15) * feat: add radial gradient support * fixed: linting errors * chore: update README with radial gradient examples * chore: remove Contributors section of README --- README.md | 122 +++++++++++++++++++++++++++++++++++-- src/components/gradient.js | 3 +- src/generator.js | 53 ++++++++++++++++ stories/index.js | 16 +++-- 4 files changed, 182 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 72296d5..0421138 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ ## Installation npm install --save uigradients - + ## Examples -### Gradient Component +### Linear Gradient Component ``` jsx // Import the component... @@ -28,10 +28,28 @@ class App extends Component { ``` > ###### `cherry` is only one of the many presets provided by [_`uigradients`_](https://jsbros.github.io/uigradients/) > A complete list of the gradient presets can be previewed [here](https://595f03bc-218b-4dc7-9045-df52791c557f.sbook.io/?selectedKind=Gradient%20Component&selectedStory=Color%20Previews&full=0&down=1&left=1&panelRight=0&downPanel=kadirahq%2Fstorybook-addon-actions%2Factions-panel). -> Test out these presets, or create your own! But be sure to -[**PR your creation**](https://github.com/JSBros/uigradients/compare) so the -rest of the community can benefit from your ascetic awesomeness! +> Test out these presets, or create your own! But be sure to +[**PR your creation**](https://github.com/JSBros/uigradients/compare) so the +rest of the community can benefit from your ascetic awesomeness! + +### Radial Gradient Component + +``` jsx +import { Gradient } from 'uigradients'; +class App extends Component { + return ( + // Add a "type" attribute on your component and + // set it to "radial" for a radial gradient! + // NOTE: If a "type" attribute is not on + // your component, the gradient type will + // default to linear + +

Wow, a radial gradient!

+
+ ); +} +``` ### Gradient Generator @@ -40,7 +58,7 @@ import { generator } from 'uigradients'; generator({gradient: 'intuitive_purple'}); -/* The function above returns: +/* The function above returns: background-color: ,#DA22FF,; background-image: -webkit-linear-gradient( left, @@ -53,6 +71,59 @@ background-image: linear-gradient( */ ``` +uiGradients also supports [radial gradients](https://developer.mozilla.org/en-US/docs/Web/CSS/radial-gradient). + +When using the `generator` function to create a radial gradient, two additional properties of `type` and `options` should be present on the object passed into `generator`. + +The `type` and `options` properties are only required when generating a radial gradient. Passing an object with only a `gradient` property will generate a linear gradient. + +``` jsx +import { generator } from 'uigradients'; + +generator({ + gradient: 'intuitive_purple', + type: 'radial', + options: { + position: '45px 20px', + shape: 'ellipse', // 'circle' or 'ellipse' + colorStops: ['20%', '50%'], // Can be percentage or pixel values + extent: 'farthest-corner' + } +}); + +/* The function above returns: +background-image: -webkit-radial-gradient( + ellipse farthest-corner at 45px 20px, + #DA22FF 20%, + #9733EE 50%); +background-image: radial-gradient( + ellipse farthest-corner at 45px 20px, + #DA22FF 20%, + #9733EE 50%); +*/ +``` + +#### Configuring the `options` for a Radial Gradient + +If using the `generator` function to create a radial gradient, the following properties are valid configurations for a radial gradient: + +```js +{ + gradient: 'electric_violet', + type: 'radial' + options: { + position: '45px 20px', // defaults to center if omitted + shape: 'ellipse', // defaults to circle if omitted + colorStops: ['20%', '50%'], // the stop position for each color + extent: 'farthest-corner' // valid options are closest-side, closest-corner, farthest-side, and farthest-corner + } +} +``` + +Each property on the `options` object maps to the CSS values for [radial-gradient](https://developer.mozilla.org/en-US/docs/Web/CSS/radial-gradient). + +NOTE: When using the `extent` property, the `position` property must also be set. + ### <💅> Styled Components #### Use the Generator in a styled-component @@ -88,6 +159,45 @@ const Header = styled(Gradient)` ![Awesome!](http://imgur.com/7G9C4eN.png) +#### Or, you can generate a radial gradient + +```js +import { generator } from 'uigradients'; +import styled from 'styled-components'; + +const RadialComponent = styled.div` +${generator({gradient: 'electric_violet', type: 'radial'})} +`; +``` + +#### And render the component + +![Radial gradient](https://i.imgur.com/PcyFqtx.jpg) + +#### Customize a radial gradient + +```js +import { generator } from 'uigradients'; +import styled from 'styled-components'; + +const RadialComponent = styled.div` +${generator({ + gradient: 'electric_violet', + type: 'radial', + options: { + position: '45px 20px', + shape: 'ellipse', + colorStops: ['20%', '50%'], + extent: 'farthest-corner' + } + } +)}`; +``` + +#### And render the component + +![Custom radial gradient](http://i.imgur.com/ESjCRbI.jpg) + ## Author Built by [Garet McKinley](https://github.com/garetmckinley) diff --git a/src/components/gradient.js b/src/components/gradient.js index b175a70..d7d0f9e 100644 --- a/src/components/gradient.js +++ b/src/components/gradient.js @@ -13,7 +13,8 @@ function GradientContainer(props) { GradientContainer.propTypes = { className: React.PropTypes.string, gradient: React.PropTypes.string, - angle: React.PropTypes.number + angle: React.PropTypes.number, + type: React.PropTypes.string }; GradientContainer.defaultProps = { diff --git a/src/generator.js b/src/generator.js index 5d4aa86..f83323d 100644 --- a/src/generator.js +++ b/src/generator.js @@ -1,6 +1,54 @@ import { css } from 'styled-components'; import { gradients, randomGradientName } from './gradients'; +function generateRadialGradientCss(options, gradientColors) { + const { shape, position, extent, colorStops } = options; + return css`background-image: -webkit-radial-gradient( + ${shape} ${extent} at ${position}, + ${gradientColors[0]} ${colorStops[0]}, + ${gradientColors[1]} ${colorStops[1]}); +background-image: -moz-radial-gradient( + ${shape} ${extent} at ${position}, + ${gradientColors[0]} ${colorStops[0]}, + ${gradientColors[1]} ${colorStops[1]}); +background-image: -o-radial-gradient( + ${shape} ${extent} at ${position}, + ${gradientColors[0]} ${colorStops[0]}, + ${gradientColors[1]} ${colorStops[1]}); +background-image: radial-gradient( + ${shape} ${extent} at ${position}, + ${gradientColors[0]} ${colorStops[0]}, + ${gradientColors[1]} ${colorStops[1]});`; +} + +function configRadialGradientOptions(options = {}) { + const { position, shape, colorStops, extent } = options; + const radialConfig = {}; + if (position) { + radialConfig.position = position; + } else { + radialConfig.position = 'center'; + } + if (shape && (shape === 'circle' || shape === 'ellipse')) { + radialConfig.shape = shape; + } else { + radialConfig.shape = 'circle'; + } + if (Array.isArray(colorStops)) { + radialConfig.colorStops = colorStops; + } else { + radialConfig.colorStops = ['', '']; + } + if (extent === 'closest-side' || + extent === 'closest-corner' || + extent === 'farthest-side' || + extent === 'farthest-corner') { + radialConfig.extent = extent; + } else { + radialConfig.extent = ''; + } + return radialConfig; +} function generator(props = {}) { let gradient = ''; @@ -13,6 +61,11 @@ function generator(props = {}) { if (props.angle !== undefined) { angle = props.angle; } + const { type, options } = props; + if (type === 'radial') { + const config = configRadialGradientOptions(options); + return generateRadialGradientCss(config, gradients[gradient]); + } return css`background-color: ${gradients[gradient][0]}; background-image: -webkit-linear-gradient( ${angle}deg, diff --git a/stories/index.js b/stories/index.js index db40ad6..682d18f 100644 --- a/stories/index.js +++ b/stories/index.js @@ -24,11 +24,17 @@ map.forEach(function (value, key) { }); storiesOf('Gradient Component', module) - .add('Color Previews', () => ( + .add('Linear Gradient Previews', () => (
- {GradientPreviews.map(function (value) { - return ({value}) - })} + {GradientPreviews.map(function (value, id) { + return ({value}) + })} +
+ )) + .add('Radial Gradient Previews', () => ( +
+ {GradientPreviews.map(function (value, id) { + return ({value}) + })}
)); -