Skip to content
This repository was archived by the owner on Dec 15, 2024. It is now read-only.

Commit f0f5441

Browse files
committed
Add ability to generate repeating gradients (fix #3)
1 parent db2e2e3 commit f0f5441

File tree

4 files changed

+384
-44
lines changed

4 files changed

+384
-44
lines changed

CHANGELOG.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project mostly adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [Unreleased]
8+
## [2.1.0] - 2019-05-24
9+
10+
### Added
11+
- Added repeating gradient utilities, both linear and radial (see `README` for more info)
912

1013
### Changed
1114
- Values that are optional in `linear-gradient()` and `radial-gradient()` (direction, shape, size, and position) are now omitted when the value is the same as the CSS-defined default value
@@ -66,7 +69,8 @@ and this project mostly adheres to [Semantic Versioning](https://semver.org/spec
6669

6770
Initial release
6871

69-
[Unreleased]: https://github.com/benface/tailwindcss-gradients/compare/v2.0.1...HEAD
72+
[Unreleased]: https://github.com/benface/tailwindcss-gradients/compare/v2.1.0...HEAD
73+
[2.1.0]: https://github.com/benface/tailwindcss-gradients/compare/v2.0.1...v2.1.0
7074
[2.0.1]: https://github.com/benface/tailwindcss-gradients/compare/v2.0.0...v2.0.1
7175
[2.0.0]: https://github.com/benface/tailwindcss-gradients/compare/v2.0.0-beta.2...v2.0.0
7276
[2.0.0-beta.2]: https://github.com/benface/tailwindcss-gradients/compare/v2.0.0-beta.1...v2.0.0-beta.2

README.md

+63-24
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,30 @@ npm install tailwindcss-gradients
88

99
## Usage
1010

11+
### Simple
12+
13+
```js
14+
{
15+
theme: {
16+
colors: {
17+
'red': '#f00',
18+
'blue': '#00f',
19+
},
20+
linearGradients: theme => ({
21+
colors: theme('colors'),
22+
}),
23+
radialGradients: theme => ({
24+
colors: theme('colors'),
25+
}),
26+
},
27+
plugins: [
28+
require('tailwindcss-gradients')(),
29+
],
30+
}
31+
```
32+
33+
### Advanced
34+
1135
```js
1236
// tailwind.config.js
1337
{
@@ -27,6 +51,7 @@ npm install tailwindcss-gradients
2751
'red': '#f00',
2852
'red-blue': ['#f00', '#00f'],
2953
'red-green-blue': ['#f00', '#0f0', '#00f'],
54+
'black-white-with-stops': ['#000', '#000 45%', '#fff 55%', '#fff'],
3055
},
3156
},
3257
radialGradients: {
@@ -51,36 +76,39 @@ npm install tailwindcss-gradients
5176
'red': '#f00',
5277
'red-blue': ['#f00', '#00f'],
5378
'red-green-blue': ['#f00', '#0f0', '#00f'],
79+
'black-white-with-stops': ['#000', '#000 45%', '#fff 55%', '#fff'],
5480
},
5581
},
82+
repeatingLinearGradients: theme => ({
83+
directions: theme('linearGradients.directions'), // defaults to the same values as linearGradients’ directions
84+
colors: theme('linearGradients.colors'), // defaults to {}
85+
lengths: { // defaults to {}
86+
'sm': '25px',
87+
'md': '50px',
88+
'lg': '100px',
89+
},
90+
}),
91+
repeatingRadialGradients: theme => ({
92+
shapes: { // defaults to this value
93+
'default': 'ellipse',
94+
},
95+
sizes: { // defaults to this value
96+
'default': 'farthest-corner',
97+
},
98+
positions: theme('radialGradients.positions'), // defaults to the same values as radialGradients’ positions
99+
colors: theme('radialGradients.colors'), // defaults to {}
100+
lengths: { // defaults to {}
101+
'sm': '25px',
102+
'md': '50px',
103+
'lg': '100px',
104+
},
105+
}),
56106
},
57107
variants: {
58108
linearGradients: ['responsive'], // defaults to ['responsive']
59109
radialGradients: ['responsive'], // defaults to ['responsive']
60-
},
61-
plugins: [
62-
require('tailwindcss-gradients')(),
63-
],
64-
}
65-
```
66-
or you can reference your existing theme colors:
67-
```js
68-
{
69-
theme: {
70-
colors: {
71-
'red': '#f00',
72-
'blue': '#00f',
73-
},
74-
linearGradients: theme => ({
75-
// directions: { ... },
76-
colors: theme('colors'),
77-
}),
78-
radialGradients: theme => ({
79-
// shapes: { ... },
80-
// sizes: { ... },
81-
// positions: { ... },
82-
colors: theme('colors'),
83-
}),
110+
repeatingLinearGradients: ['responsive'], // defaults to ['responsive']
111+
repeatingRadialGradients: ['responsive'], // defaults to ['responsive']
84112
},
85113
plugins: [
86114
require('tailwindcss-gradients')(),
@@ -101,4 +129,15 @@ This plugin generates the following utilities:
101129
.bg-radial-[shape-key]-[size-key]-[position-key]-[color-key] {
102130
background-image: radial-gradient([shape-value] [size-value] at [position-value], [color-value-1], [color-value-2], [...]);
103131
}
132+
133+
/* configurable with the "repeatingLinearGradients" theme object */
134+
.bg-gradient-[direction-key]-[color-key]-[length-key] {
135+
background-image: repeating-linear-gradient([direction-value], [color-value-1], [color-value-2], [...] [length-value]);
136+
}
137+
138+
/* configurable with the "repeatingRadialGradients" theme object */
139+
/* note that the "default" [shape-key], [size-key], and [position-key] are omitted from the class */
140+
.bg-radial-[shape-key]-[size-key]-[position-key]-[color-key]-[length-key] {
141+
background-image: repeating-radial-gradient([shape-value] [size-value] at [position-value], [color-value-1], [color-value-2], [...] [length-value]);
142+
}
104143
```

index.js

+97-18
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,18 @@ module.exports = function() {
5454
};
5555
const defaultRadialGradientColors = {};
5656
const defaultRadialGradientVariants = ['responsive'];
57+
const defaultRepeatingLinearGradientDirections = defaultLinearGradientDirections;
58+
const defaultRepeatingLinearGradientColors = defaultLinearGradientColors;
59+
const defaultRepeatingLinearGradientLengths = {};
60+
const defaultRepeatingLinearGradientVariants = ['responsive'];
61+
const defaultRepeatingRadialGradientShapes = defaultRadialGradientShapes;
62+
const defaultRepeatingRadialGradientSizes = {
63+
'default': 'farthest-corner',
64+
};
65+
const defaultRepeatingRadialGradientPositions = defaultRadialGradientPositions;
66+
const defaultRepeatingRadialGradientColors = defaultRadialGradientColors;
67+
const defaultRepeatingRadialGradientLengths = {};
68+
const defaultRepeatingRadialGradientVariants = ['responsive'];
5769

5870
const linearGradientDirections = theme('linearGradients.directions', defaultLinearGradientDirections);
5971
const linearGradientColors = theme('linearGradients.colors', defaultLinearGradientColors);
@@ -63,11 +75,46 @@ module.exports = function() {
6375
const radialGradientPositions = theme('radialGradients.positions', defaultRadialGradientPositions);
6476
const radialGradientColors = theme('radialGradients.colors', defaultRadialGradientColors);
6577
const radialGradientVariants = variants('radialGradients', defaultRadialGradientVariants);
78+
const repeatingLinearGradientDirections = theme('repeatingLinearGradients.directions', defaultRepeatingLinearGradientDirections);
79+
const repeatingLinearGradientColors = theme('repeatingLinearGradients.colors', defaultRepeatingLinearGradientColors);
80+
const repeatingLinearGradientLengths = theme('repeatingLinearGradients.lengths', defaultRepeatingLinearGradientLengths);
81+
const repeatingLinearGradientVariants = variants('repeatingLinearGradients', defaultRepeatingLinearGradientVariants);
82+
const repeatingRadialGradientShapes = theme('repeatingRadialGradients.shapes', defaultRepeatingRadialGradientShapes);
83+
const repeatingRadialGradientSizes = theme('repeatingRadialGradients.sizes', defaultRepeatingRadialGradientSizes);
84+
const repeatingRadialGradientPositions = theme('repeatingRadialGradients.positions', defaultRepeatingRadialGradientPositions);
85+
const repeatingRadialGradientColors = theme('repeatingRadialGradients.colors', defaultRepeatingRadialGradientColors);
86+
const repeatingRadialGradientLengths = theme('repeatingRadialGradients.lengths', defaultRepeatingRadialGradientLengths);
87+
const repeatingRadialGradientVariants = variants('repeatingRadialGradients', defaultRepeatingRadialGradientVariants);
88+
89+
const linearGradientSelector = function(directionKey, colorKey, lengthKey) {
90+
return `.${e(`bg-gradient-${directionKey}-${colorKey}${lengthKey ? `-${lengthKey}` : ''}`)}`;
91+
};
92+
93+
const linearGradientValue = function(direction, colors, length) {
94+
const cssDefaultLinearGradientDirections = ['to bottom', '180deg', '0.5turn', '200grad', '3.1416rad'];
95+
return `${!_.isNil(length) ? 'repeating-' : ''}linear-gradient(${_.includes(cssDefaultLinearGradientDirections, direction) ? '' : `${direction}, `}${colors.join(', ')}${length ? ` ${length}` : ''})`;
96+
};
97+
98+
const radialGradientSelector = function(shapeKey, sizeKey, positionKey, colorKey, lengthKey) {
99+
return `.${e(`bg-radial${shapeKey === 'default' ? '' : `-${shapeKey}`}${sizeKey === 'default' ? '' : `-${sizeKey}`}${positionKey === 'default' ? '' : `-${positionKey}`}-${colorKey}${lengthKey ? `-${lengthKey}` : ''}`)}`;
100+
};
66101

67-
const cssDefaultLinearGradientDirections = ['to bottom', '180deg', '0.5turn', '200grad', '3.1416rad'];
68-
const cssDefaultRadialGradientShape = 'ellipse';
69-
const cssDefaultRadialGradientSize = 'farthest-corner';
70-
const cssDefaultRadialGradientPositions = ['center', 'center center', '50%', '50% 50%', 'center 50%', '50% center'];
102+
const radialGradientValue = function(shape, size, position, colors, length) {
103+
const cssDefaultRadialGradientShape = 'ellipse';
104+
const cssDefaultRadialGradientSize = 'farthest-corner';
105+
const cssDefaultRadialGradientPositions = ['center', 'center center', '50%', '50% 50%', 'center 50%', '50% center'];
106+
let firstArgumentValues = [];
107+
if (shape !== cssDefaultRadialGradientShape) {
108+
firstArgumentValues.push(shape);
109+
}
110+
if (size !== cssDefaultRadialGradientSize) {
111+
firstArgumentValues.push(size);
112+
}
113+
if (!_.includes(cssDefaultRadialGradientPositions, position)) {
114+
firstArgumentValues.push(`at ${position}`);
115+
}
116+
return `${!_.isNil(length) ? 'repeating-' : ''}radial-gradient(${firstArgumentValues.length > 0 ? `${firstArgumentValues.join(' ')}, ` : ''}${colors.join(', ')}${length ? ` ${length}` : ''})`;
117+
};
71118

72119
const linearGradientUtilities = (function() {
73120
let utilities = {};
@@ -77,8 +124,8 @@ module.exports = function() {
77124
return; // continue
78125
}
79126
_.forEach(linearGradientDirections, (direction, directionKey) => {
80-
utilities[`.${e(`bg-gradient-${directionKey}-${colorKey}`)}`] = {
81-
backgroundImage: `linear-gradient(${_.includes(cssDefaultLinearGradientDirections, direction) ? '' : `${direction}, `}${colors.join(', ')})`,
127+
utilities[linearGradientSelector(directionKey, colorKey)] = {
128+
backgroundImage: linearGradientValue(direction, colors),
82129
};
83130
});
84131
});
@@ -95,18 +142,8 @@ module.exports = function() {
95142
_.forEach(radialGradientPositions, (position, positionKey) => {
96143
_.forEach(radialGradientSizes, (size, sizeKey) => {
97144
_.forEach(radialGradientShapes, (shape, shapeKey) => {
98-
let firstArgumentValues = [];
99-
if (shape !== cssDefaultRadialGradientShape) {
100-
firstArgumentValues.push(shape);
101-
}
102-
if (size !== cssDefaultRadialGradientSize) {
103-
firstArgumentValues.push(size);
104-
}
105-
if (!_.includes(cssDefaultRadialGradientPositions, position)) {
106-
firstArgumentValues.push(`at ${position}`);
107-
}
108-
utilities[`.${e(`bg-radial${shapeKey === 'default' ? '' : `-${shapeKey}`}${sizeKey === 'default' ? '' : `-${sizeKey}`}${positionKey === 'default' ? '' : `-${positionKey}`}-${colorKey}`)}`] = {
109-
backgroundImage: `radial-gradient(${firstArgumentValues.length > 0 ? `${firstArgumentValues.join(' ')}, ` : ''}${colors.join(', ')})`,
145+
utilities[radialGradientSelector(shapeKey, sizeKey, positionKey, colorKey)] = {
146+
backgroundImage: radialGradientValue(shape, size, position, colors),
110147
};
111148
});
112149
});
@@ -115,7 +152,49 @@ module.exports = function() {
115152
return utilities;
116153
})();
117154

155+
const repeatingLinearGradientUtilities = (function() {
156+
let utilities = {};
157+
_.forEach(repeatingLinearGradientLengths, (length, lengthKey) => {
158+
_.forEach(repeatingLinearGradientColors, (colors, colorKey) => {
159+
colors = normalizeColors(colors, true);
160+
if (!colors) {
161+
return; // continue
162+
}
163+
_.forEach(repeatingLinearGradientDirections, (direction, directionKey) => {
164+
utilities[linearGradientSelector(directionKey, colorKey, lengthKey)] = {
165+
backgroundImage: linearGradientValue(direction, colors, length),
166+
};
167+
});
168+
});
169+
});
170+
return utilities;
171+
})();
172+
173+
const repeatingRadialGradientUtilities = (function() {
174+
let utilities = {};
175+
_.forEach(repeatingRadialGradientLengths, (length, lengthKey) => {
176+
_.forEach(repeatingRadialGradientColors, (colors, colorKey) => {
177+
colors = normalizeColors(colors, false);
178+
if (!colors) {
179+
return; // continue
180+
}
181+
_.forEach(repeatingRadialGradientPositions, (position, positionKey) => {
182+
_.forEach(repeatingRadialGradientSizes, (size, sizeKey) => {
183+
_.forEach(repeatingRadialGradientShapes, (shape, shapeKey) => {
184+
utilities[radialGradientSelector(shapeKey, sizeKey, positionKey, colorKey, lengthKey)] = {
185+
backgroundImage: radialGradientValue(shape, size, position, colors, length),
186+
};
187+
});
188+
});
189+
});
190+
});
191+
});
192+
return utilities;
193+
})();
194+
118195
addUtilities(linearGradientUtilities, linearGradientVariants);
119196
addUtilities(radialGradientUtilities, radialGradientVariants);
197+
addUtilities(repeatingLinearGradientUtilities, repeatingLinearGradientVariants);
198+
addUtilities(repeatingRadialGradientUtilities, repeatingRadialGradientVariants);
120199
};
121200
};

0 commit comments

Comments
 (0)