Skip to content
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

refactor: remove css safelist and add IconExtractor #20

Merged
merged 11 commits into from
Jun 21, 2022
6 changes: 6 additions & 0 deletions .changeset/many-bottles-hope.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@cypress-design/css": patch
---

To avoid having every color in the universe in the **safelist**, add the IconExtractor.
Also, remove the entire safelist from the css plugins windi config.
48 changes: 48 additions & 0 deletions css/src/icon-color-plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import createPlugin from 'windicss/plugin';
import { reduce, kebabCase, isObject } from 'lodash';
import { colors } from './colors';
import { DefaultExtractor } from 'vite-plugin-windicss';
import { Extractor } from 'windicss/types/interfaces';

interface RuleConfig {
name: string;
Expand Down Expand Up @@ -157,3 +159,49 @@ export const IconDuotoneColorsPlugin = createPlugin(
addUtilities(addIconUtilityClasses(theme));
}
);

const ICON_ATTRIBUTE_NAMES_TO_CLASS_GENERATOR = {
fillColor: (attrValue: string) => `icon-light-${attrValue}`,
strokeColor: (attrValue: string) => `icon-dark-${attrValue}`,
secondaryFillColor: (attrValue: string) =>
`icon-light-secondary-${attrValue}`,
secondaryStrokeColor: (attrValue: string) =>
`icon-dark-secondary-${attrValue}`,
} as const;

function isIconAttribute(
attrName: string
): attrName is keyof typeof ICON_ATTRIBUTE_NAMES_TO_CLASS_GENERATOR {
return ICON_ATTRIBUTE_NAMES_TO_CLASS_GENERATOR.hasOwnProperty(attrName);
}

/**
* transforms the attributes of icons into classes
* to be kept in the windicss css file after purgecss
*/
export const IconExtractor: Extractor = {
extensions: ['vue', 'js', 'ts', 'tsx'],
extractor: (code, id) => {
const { tags, classes = [], attributes } = DefaultExtractor(code, id);

const additionalColorClasses =
attributes?.names.reduce((set, attrName, index) => {
if (isIconAttribute(attrName)) {
set.add(
ICON_ATTRIBUTE_NAMES_TO_CLASS_GENERATOR[attrName](
attributes.values[index]
)
);
}
return set;
}, new Set<string>()) ?? new Set<string>();

return {
tags,
get classes() {
return [...classes, ...Array.from(additionalColorClasses)];
},
attributes,
};
},
};
35 changes: 0 additions & 35 deletions css/src/safelist.ts

This file was deleted.

5 changes: 2 additions & 3 deletions css/src/windi.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { defineConfig } from 'windicss/helpers';
// @ts-ignore
import InteractionVariants from '@windicss/plugin-interaction-variants';
import { IconDuotoneColorsPlugin } from './icon-color-plugins';
import { safelist } from './safelist';
import { IconDuotoneColorsPlugin, IconExtractor } from './icon-color-plugins';
import { colors } from './colors';
import { shortcuts } from './shortcuts';

Expand All @@ -28,7 +27,6 @@ export default defineConfig({
},
},
},
safelist,
variants: {
// What's hocus?
// Hocus is a portmanteau of hover + focus. This is useful because
Expand All @@ -53,5 +51,6 @@ export default defineConfig({
shortcuts,
extract: {
exclude: ['node_modules/**/*', '.git/**/*'],
extractors: [IconExtractor],
},
});
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"@vue/tsconfig": "^0.1.3",
"axe-core": "^4.4.2",
"concurrently": "^7.1.0",
"cypress": "https://cdn.cypress.io/beta/npm/10.0.0/darwin-x64/10.0-release-fec27a0be952c91b96f3b9b5efd5fe7488312fc4/cypress.tgz",
"cypress": "https://cdn.cypress.io/beta/npm/10.0.0/darwin-x64/10.0-release-d335f5cd8a0d244ada59892c41af51c66c44463f/cypress.tgz",
"cypress-axe": "^0.14.0",
"execa": "^6.1.0",
"hygen": "^6.2.0",
Expand All @@ -55,4 +55,4 @@
"vite": "^2.9.1",
"vue-tsc": "^0.33.9"
}
}
}
25 changes: 23 additions & 2 deletions storybook/intro/.storybook/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { CyCSSWebpackPlugin } = require('@cypress-design/css');
const { CyCSSWebpackPlugin, colors } = require('@cypress-design/css');
const { map, reduce, kebabCase } = require('lodash');
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');

Expand All @@ -8,7 +9,6 @@ module.exports = {
'@storybook/addon-links',
'@storybook/addon-essentials',
'storybook-addon-designs',
// "@storybook/addon-interactions",
],
framework: '@storybook/react',
refs: (config, { configType }) => {
Expand Down Expand Up @@ -78,6 +78,27 @@ module.exports = {
path.resolve(__dirname, '../stories/src/*.tsx'),
],
},
safelist: reduce(
{ ...colors, transparent: { ONLY: true }, current: { ONLY: true } },
(acc, variants, colorName) => {
const name = kebabCase(colorName);

return `${acc}
${map(variants, (_, k) => {
if (k === 'DEFAULT') return ``;
const variantName = k === 'ONLY' ? name : `${name}-${k}`;
return `
bg-${variantName}
text-${variantName}
before:bg-${variantName}
before:text-${variantName}
icon-light-${variantName}
icon-dark-${variantName}
icon-light-secondary-${variantName}
icon-dark-secondary-${variantName}`;
}).join(' ')}`;
}
),
})
);
return config;
Expand Down
10 changes: 5 additions & 5 deletions storybook/intro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@
},
"devDependencies": {
"@babel/core": "^7.17.9",
"@storybook/addon-actions": "^6.4.22",
"@storybook/addon-essentials": "^6.4.22",
"@storybook/addon-links": "^6.4.22",
"@storybook/react": "^6.4.22",
"@storybook/addon-actions": "^6.5.0",
"@storybook/addon-essentials": "^6.5.0",
"@storybook/addon-links": "^6.5.0",
"@storybook/react": "^6.5.0",
"chroma-js": "^2.4.2",
"copy-webpack-plugin": "^6.3.2",
"flat": "^5.0.2",
Expand All @@ -27,4 +27,4 @@
"windicss": "^3.5.1",
"windicss-webpack-plugin": "^1.6.10"
}
}
}
10 changes: 5 additions & 5 deletions storybook/react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
},
"devDependencies": {
"@babel/core": "^7.17.9",
"@storybook/addon-actions": "^6.4.22",
"@storybook/addon-essentials": "^6.4.22",
"@storybook/addon-links": "^6.4.22",
"@storybook/addon-actions": "^6.5.0",
"@storybook/addon-essentials": "^6.5.0",
"@storybook/addon-links": "^6.5.0",
"@storybook/preset-scss": "^1.0.3",
"@storybook/react": "^6.4.22",
"@storybook/react": "^6.5.0",
"chroma-js": "^2.4.2",
"copyfiles": "^2.4.1",
"css-loader": "5",
Expand All @@ -34,4 +34,4 @@
},
"author": "",
"license": "ISC"
}
}
10 changes: 5 additions & 5 deletions storybook/vue/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@
},
"devDependencies": {
"@babel/core": "^7.17.9",
"@storybook/addon-actions": "^6.4.22",
"@storybook/addon-essentials": "^6.4.22",
"@storybook/addon-links": "^6.4.22",
"@storybook/addon-actions": "^6.5.0",
"@storybook/addon-essentials": "^6.5.0",
"@storybook/addon-links": "^6.5.0",
"@storybook/builder-vite": "^0.1.29",
"@storybook/vue3": "^6.4.22",
"@storybook/vue3": "^6.5.0",
"@types/node": "^16.11.26",
"babel-loader": "^8.2.4",
"copyfiles": "^2.4.1",
"storybook-addon-designs": "^6.2.1",
"vite-plugin-windicss": "^1.8.4",
"windicss": "^3.5.1"
}
}
}