Skip to content

postcss-gradients-interpolation-method #287

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/css-issue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ body:
- PostCSS Focus Within
- PostCSS Font Variant
- PostCSS Gap Properties
- PostCSS Gradients Interpolation Method
- PostCSS HWB Function
- PostCSS Image Set Function
- PostCSS Is Pseudo Class
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/plugin-issue.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ body:
- PostCSS Focus Within
- PostCSS Font Variant
- PostCSS Gap Properties
- PostCSS Gradients Interpolation Method
- PostCSS HWB Function
- PostCSS Image Set Function
- PostCSS Is Pseudo Class
Expand Down
2 changes: 1 addition & 1 deletion .github/bin/new-plugin.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ console.log(`- Creating new plugin ${pluginName}`);

packageInfo.repository.directory = `plugins/${pluginSlug}`;

await fsp.writeFile(path.join(pluginDir, 'package.json'), JSON.stringify(packageInfo, null, 2));
await fsp.writeFile(path.join(pluginDir, 'package.json'), JSON.stringify(packageInfo, null, '\t'));

console.log('- Updated "package.json"');
}
Expand Down
4 changes: 4 additions & 0 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@
- plugins/postcss-gap-properties/**
- experimental/postcss-gap-properties/**

"plugins/postcss-gradients-interpolation-method":
- plugins/postcss-gradients-interpolation-method/**
- experimental/postcss-gradients-interpolation-method/**

"plugins/postcss-hwb-function":
- plugins/postcss-hwb-function/**
- experimental/postcss-hwb-function/**
Expand Down
26 changes: 26 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
--hwb: rgb(230, 93, 26);
}

@supports (background: linear-gradient(0deg, red 0% 1%, red 2%)) {
@supports (background: linear-gradient(red 0%, red 0% 1%, red 2%)) {
:root {
--gradient-prop-2: linear-gradient(90deg, black 25% 50%, blue 50% 75%);
}
Expand All @@ -28,7 +28,7 @@
}
}

@supports (background: repeating-linear-gradient(0deg, red 0% 1%, red 2%)) {
@supports (background: repeating-linear-gradient(red 0%, red 0% 1%, red 2%)) {
:root {
--gradient-prop-5: repeating-linear-gradient(90deg, black 25% 50%, blue 50% 75%);
}
Expand Down
5 changes: 5 additions & 0 deletions plugins/postcss-double-position-gradients/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changes to PostCSS Double Position Gradients

### Unreleased (patch)

- Add typescript support
- Fix `at` keyword with `at 20px 20px` being interpreted as a double position color stop.

### 3.1.0 (February 15, 2022)

- Ignore values in relevant `@supports` rules.
Expand Down
1 change: 1 addition & 0 deletions plugins/postcss-double-position-gradients/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
},
"main": "dist/index.cjs",
"module": "dist/index.mjs",
"types": "dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.mjs",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { includesGradientsFunction } from './is-gradient';
import type { AtRule, Node } from 'postcss';

export function hasSupportsAtRuleAncestor(node) {
export function hasSupportsAtRuleAncestor(node: Node): boolean {
let parent = node.parent;
while (parent) {
if (parent.type !== 'atrule') {
parent = parent.parent;
continue;
}

if (parent.name === 'supports' && includesGradientsFunction(parent.params)) {
if ((parent as AtRule).name === 'supports' && includesGradientsFunction((parent as AtRule).params)) {
return true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
import postcssProgressiveCustomProperties from '@csstools/postcss-progressive-custom-properties';
import type { PluginCreator } from 'postcss';
import valueParser from 'postcss-value-parser';
import { hasSupportsAtRuleAncestor } from './has-supports-at-rule-ancestor';
import { includesGradientsFunction, isGradientsFunctions } from './is-gradient';

const isPunctuationCommaNode = node => node.type === 'div' && node.value === ',';
const keywords = [
'at',
'bottom',
'center',
'circle',
'closest-corner',
'closest-side',
'ellipse',
'farthest-corner',
'farthest-side',
'from',
'in',
'left',
'right',
'to',
'top',
];

function insertBefore(nodes, node, ...values) {
const index = nodes.findIndex(n => n === node);
nodes.splice.apply(nodes, [index - 1, 0].concat(
Array.prototype.slice.call(...values, 0)),
);
}
const isPunctuationCommaNode = node => node.type === 'div' && node.value === ',';

function isNumericNode(node) {
try {
Expand Down Expand Up @@ -63,10 +75,24 @@ const basePlugin = (opts) => {
return x.type !== 'comment' && x.type !== 'space';
});

nodes.forEach((node, index, nodes) => {
const oneValueBack = Object(nodes[index - 1]);
const twoValuesBack = Object(nodes[index - 2]);
const nextNode = Object(nodes[index + 1]);
let inPrefix = false;

nodes.forEach((node, index, currentNodes) => {
if (node.type === 'word' && keywords.includes(node.value)) {
inPrefix = true;
}

if (node.type === 'div' && node.value === ',') {
inPrefix = false;
}

if (inPrefix) {
return;
}

const oneValueBack = Object(currentNodes[index - 1]);
const twoValuesBack = Object(currentNodes[index - 2]);
const nextNode = Object(currentNodes[index + 1]);
const isDoublePositionLength = twoValuesBack.type && isNumericNode(oneValueBack) && isNumericNode(node);

// if the argument concludes a double-position gradient
Expand All @@ -80,11 +106,18 @@ const basePlugin = (opts) => {
after: isPunctuationCommaNode(nextNode) ? '' : ' ',
};

insertBefore(func.nodes, node, [comma, color]);
func.nodes.splice(
// 1 before the current node
func.nodes.indexOf(node) - 1,
// remove none
0,
// insert these :
comma, color,
);
Comment on lines +109 to +116
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

}
});

return false;
return;
});

const modifiedValue = valueAST.toString();
Expand All @@ -103,12 +136,13 @@ const basePlugin = (opts) => {

basePlugin.postcss = true;

/**
* Transform double-position gradients in CSS.
* @param {{preserve?: boolean}} opts
* @returns {import('postcss').Plugin}
*/
const postcssPlugin = (opts) => {
type pluginOptions = {
preserve?: boolean;
enableProgressiveCustomProperties?: boolean;
};

// Transform double-position gradients in CSS.
const postcssPlugin: PluginCreator<pluginOptions> = (opts?: pluginOptions) => {
const options = Object.assign({
enableProgressiveCustomProperties: true,
preserve: true,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export function includesGradientsFunction(str) {
export function includesGradientsFunction(str: string): boolean {
return (
str.includes('conic-gradient(') ||
str.includes('linear-gradient(') ||
Expand All @@ -9,7 +9,7 @@ export function includesGradientsFunction(str) {
);
}

export function isGradientsFunctions(str) {
export function isGradientsFunctions(str: string): boolean {
return (
str ==='conic-gradient' ||
str ==='linear-gradient' ||
Expand Down
13 changes: 13 additions & 0 deletions plugins/postcss-double-position-gradients/test/basic.css
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
.test-linear-gradient {
background-image: linear-gradient(90deg, black 25% 50%, blue 50% 75%);
background-image: linear-gradient(black 25% 50%, blue 50% 75%);
}

.test-linear-gradient-no-spaces {
background-image: linear-gradient(90deg,black 25% 50%,blue 50% 75%);
}

.test-conic-gradient {
background-image: conic-gradient(yellowgreen 40%, gold 0deg 75% , #f06 0deg);
}

.test-radial-gradient {
background-image: radial-gradient(5em circle at 50px 50%, yellow, blue);
}

.test-invalid-function {
background-image: some-func(yellowgreen 40%, gold 0deg 75% , #f06 0deg);
}
Expand Down Expand Up @@ -43,3 +52,7 @@
--gradient-prop-5: repeating-linear-gradient(90deg, black 25% 50%, blue 50% 75%);
--gradient-prop-6: repeating-radial-gradient(red 0 8%, yellow 8% 16%, blue 16% 24%);
}

.test-color-space-interop {
background: linear-gradient(in lab to right, #44C 0% 10%, #795)
}
20 changes: 18 additions & 2 deletions plugins/postcss-double-position-gradients/test/basic.expect.css
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
.test-linear-gradient {
background-image: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%);
background-image: linear-gradient(90deg, black 25% 50%, blue 50% 75%);
background-image: linear-gradient(black 25%,black 50%, blue 50%, blue 75%);
background-image: linear-gradient(black 25% 50%, blue 50% 75%);
}

.test-linear-gradient-no-spaces {
background-image: linear-gradient(90deg,black 25%,black 50%,blue 50%, blue 75%);
background-image: linear-gradient(90deg,black 25% 50%,blue 50% 75%);
}

.test-conic-gradient {
background-image: conic-gradient(yellowgreen 40%, gold 0deg ,gold 75% , #f06 0deg);
background-image: conic-gradient(yellowgreen 40%, gold 0deg 75% , #f06 0deg);
}

.test-radial-gradient {
background-image: radial-gradient(5em circle at 50px 50%, yellow, blue);
}

.test-invalid-function {
background-image: some-func(yellowgreen 40%, gold 0deg 75% , #f06 0deg);
}
Expand Down Expand Up @@ -46,7 +57,7 @@
--gradient-prop-6: repeating-radial-gradient(red 0,red 8%, yellow 8%,yellow 16%, blue 16%, blue 24%);
}

@supports (background: linear-gradient(0deg, red 0% 1%, red 2%)) {
@supports (background: linear-gradient(red 0%, red 0% 1%, red 2%)) {
.test-all-functions-as-custom-properties {
--gradient-prop-2: linear-gradient(90deg, black 25% 50%, blue 50% 75%);
}
Expand All @@ -64,7 +75,7 @@
}
}

@supports (background: repeating-linear-gradient(0deg, red 0% 1%, red 2%)) {
@supports (background: repeating-linear-gradient(red 0%, red 0% 1%, red 2%)) {
.test-all-functions-as-custom-properties {
--gradient-prop-5: repeating-linear-gradient(90deg, black 25% 50%, blue 50% 75%);
}
Expand All @@ -75,3 +86,8 @@
--gradient-prop-6: repeating-radial-gradient(red 0 8%, yellow 8% 16%, blue 16% 24%);
}
}

.test-color-space-interop {
background: linear-gradient(in lab to right, #44C 0%,#44C 10%, #795);
background: linear-gradient(in lab to right, #44C 0% 10%, #795)
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
.test-linear-gradient {
background-image: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%);
background-image: linear-gradient(black 25%,black 50%, blue 50%, blue 75%);
}

.test-linear-gradient-no-spaces {
background-image: linear-gradient(90deg,black 25%,black 50%,blue 50%, blue 75%);
}

.test-conic-gradient {
background-image: conic-gradient(yellowgreen 40%, gold 0deg ,gold 75% , #f06 0deg);
}

.test-radial-gradient {
background-image: radial-gradient(5em circle at 50px 50%, yellow, blue);
}

.test-invalid-function {
background-image: some-func(yellowgreen 40%, gold 0deg 75% , #f06 0deg);
}
Expand Down Expand Up @@ -43,3 +52,7 @@
--gradient-prop-5: repeating-linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%);
--gradient-prop-6: repeating-radial-gradient(red 0,red 8%, yellow 8%,yellow 16%, blue 16%, blue 24%);
}

.test-color-space-interop {
background: linear-gradient(in lab to right, #44C 0%,#44C 10%, #795)
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
--some-var: linear-gradient(90deg, black 25%,black 50%, blue 50%, blue 75%);
}

@supports (background: linear-gradient(0deg, red 0% 1%, red 2%)) {
@supports (background: linear-gradient(red 0%, red 0% 1%, red 2%)) {
:root {
--some-var: linear-gradient(90deg, black 25% 50%, blue 50% 75%);
}
Expand Down
9 changes: 9 additions & 0 deletions plugins/postcss-double-position-gradients/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "dist",
"declarationDir": "."
},
"include": ["./src/**/*"],
"exclude": ["dist"],
}
6 changes: 6 additions & 0 deletions plugins/postcss-gradients-interpolation-method/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules
package-lock.json
yarn.lock
*.result.css
*.result.css.map
dist/*
1 change: 1 addition & 0 deletions plugins/postcss-gradients-interpolation-method/.nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v16.13.1
Loading