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

[core] Enable support for base and variant styles #107

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
2 changes: 2 additions & 0 deletions packages/pigment-css-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@
"cssesc": "^3.0.0",
"csstype": "^3.1.3",
"lodash": "^4.17.21",
"postcss": "^8.4.38",
"postcss-merge-rules": "^7.0.0",
"stylis": "^4.3.1",
"stylis-plugin-rtl": "^2.1.1"
},
Expand Down
21 changes: 15 additions & 6 deletions packages/pigment-css-react/src/processors/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,9 +310,9 @@ export class StyledProcessor extends BaseProcessor {
* which we can use to generate our styles.
* Order of processing styles -
* 1. CSS directly declared in styled call
* 3. Variants declared in styled call
* 2. CSS declared in theme object's styledOverrides
* 3. Variants declared in theme object
* 2. Variants declared in styled call
* 3. CSS declared in theme object's styledOverrides
* 4. Variants declared in theme object
*/
build(values: ValueCache): void {
if (this.isTemplateTag) {
Expand Down Expand Up @@ -449,6 +449,7 @@ export class StyledProcessor extends BaseProcessor {
variantsAccumulator,
themeImportIdentifier,
);

const className = this.getClassName();
this.baseClasses.push(className);
this.collectedStyles.push([className, finalStyle, styleArg]);
Expand Down Expand Up @@ -523,8 +524,8 @@ export class StyledProcessor extends BaseProcessor {
styleArg: ExpressionValue | null,
variantsAccumulator?: VariantData[],
themeImportIdentifier?: string,
) {
const { themeArgs = {} } = this.options as IOptions;
): string {
const { themeArgs = {}, experiments = {} } = this.options as IOptions;
const styleObj = typeof styleObjOrFn === 'function' ? styleObjOrFn(themeArgs) : styleObjOrFn;
if (!styleObj) {
return '';
Expand All @@ -551,7 +552,15 @@ export class StyledProcessor extends BaseProcessor {
if (res.length) {
this.collectedVariables.push(...res);
}
return processCssObject(styleObj, themeArgs);
const cssText = processCssObject(styleObj, themeArgs);

if (experiments.styleLayers) {
if (variantsAccumulator) {
return `@layer pigment-base {${cssText}}`;
}
return `@layer pigment-variant {${cssText}}`;
}
return cssText;
}

public override get asSelector(): string {
Expand Down
7 changes: 7 additions & 0 deletions packages/pigment-css-react/src/utils/cssFnValueToVariable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ export type PluginCustomOptions = {
*/
getDirSelector?: (dir: 'ltr' | 'rtl') => string;
};
experiments?: {
/**
* Wrap generated CSS in layers so that all the base styles come before all the variant styles.
* Experimental right now, but will be default by v1 release.
*/
styleLayers?: boolean;
};
};

type CssFnValueToVariableParams = {
Expand Down
8 changes: 6 additions & 2 deletions packages/pigment-css-react/src/utils/generateCss.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { serializeStyles } from '@emotion/serialize';
import { Theme } from './extendTheme';
import { PluginCustomOptions } from './cssFnValueToVariable';

export function generateTokenCss(theme?: Theme) {
export function generateTokenCss(
theme?: Theme,
experiments: PluginCustomOptions['experiments'] = {},
) {
if (!theme) {
return '';
}
// use emotion to serialize the object to css string
const { styles } = serializeStyles(theme.generateStyleSheets?.() || []);
return styles;
return experiments.styleLayers ? `@layer pigment-base, pigment-variant;\n${styles}` : styles;
}

export function generateThemeTokens(theme?: Theme) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { styled } from '@pigment-css/react';

const SliderRail = styled('span', {
name: 'MuiSlider',
slot: 'Rail',
})({
color: 'red',
variants: [
{
props: { color: 'primary' },
style: {
color: 'tomato',
},
},
{
props: ({ ownerState }) => ownerState.color === 'secondary',
style: {
color: 'salmon',
},
},
],
});

export const SliderOverride = styled(SliderRail)({
color: 'blue',
variants: [
{
props: { color: 'primary' },
style: {
color: 'indigo',
},
},
],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
@layer pigment-base, pigment-variant;
@layer pigment-base {
.srxh6zy {
color: red;
}
}
@layer pigment-variant {
.srxh6zy-1 {
color: tomato;
}
}
@layer pigment-variant {
.srxh6zy-2 {
color: salmon;
}
}
@layer pigment-base {
.srxh6zy-3 {
font-size: 1.5rem;
}
}
@layer pigment-base {
.s1q936we {
color: blue;
}
}
@layer pigment-variant {
.s1q936we-1 {
color: indigo;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { styled as _styled2 } from '@pigment-css/react';
import _theme2 from '@pigment-css/react/theme';
import { styled as _styled } from '@pigment-css/react';
import _theme from '@pigment-css/react/theme';
const SliderRail = /*#__PURE__*/ _styled('span', {
name: 'MuiSlider',
slot: 'Rail',
})({
classes: ['srxh6zy', 'srxh6zy-3'],
variants: [
{
props: {
color: 'primary',
},
className: 'srxh6zy-1',
},
{
props: ({ ownerState }) => ownerState.color === 'secondary',
className: 'srxh6zy-2',
},
],
});
const _exp3 = /*#__PURE__*/ () => SliderRail;
export const SliderOverride = /*#__PURE__*/ _styled2(_exp3())({
classes: ['s1q936we'],
variants: [
{
props: {
color: 'primary',
},
className: 's1q936we-1',
},
],
});
17 changes: 17 additions & 0 deletions packages/pigment-css-react/tests/styled/styled.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,23 @@ describe('Pigment CSS - styled', () => {
expect(output.css).to.equal(fixture.css);
});

it('should work with variants with layers enabled', async () => {
const { output, fixture } = await runTransformation(
path.join(__dirname, 'fixtures/styled-variants-layer.input.js'),
{
themeArgs: {
theme,
},
experiments: {
styleLayers: true,
},
},
);

expect(output.js).to.equal(fixture.js);
expect(output.css).to.equal(fixture.css);
});

it('should work with theme styleOverrides', async () => {
const { output, fixture } = await runTransformation(
path.join(__dirname, 'fixtures/styled-theme-styleOverrides.input.js'),
Expand Down
16 changes: 7 additions & 9 deletions packages/pigment-css-react/tests/testUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
transform as wywTransform,
createFileReporter,
} from '@wyw-in-js/transform';
import { PluginCustomOptions, preprocessor } from '@pigment-css/react/utils';
import { PluginCustomOptions, preprocessor, generateTokenCss } from '@pigment-css/react/utils';
import * as prettier from 'prettier';

import sxTransformPlugin from '../exports/sx-plugin';
Expand All @@ -24,10 +24,7 @@ function runSxTransform(code: string, filename: string) {
});
}

export async function runTransformation(
absolutePath: string,
options?: { themeArgs?: { theme?: any }; css?: PluginCustomOptions['css'] },
) {
export async function runTransformation(absolutePath: string, options?: PluginCustomOptions) {
const cache = new TransformCacheCollection();
const { emitter: eventEmitter } = createFileReporter(false);
const inputFilePath = absolutePath;
Expand All @@ -43,9 +40,7 @@ export async function runTransformation(
const babelResult = await runSxTransform(inputContent, inputFilePath);

const pluginOptions = {
themeArgs: {
theme: options?.themeArgs?.theme,
},
...options,
babelOptions: {
configFile: false,
babelrc: false,
Expand Down Expand Up @@ -80,7 +75,10 @@ export async function runTransformation(
...prettierConfig,
parser: 'babel',
});
const formattedCss = await prettier.format(result.cssText ?? '', {
const baseCss = generateTokenCss(options?.themeArgs?.theme ?? {}, options?.experiments);
const originalCss = baseCss + result.cssText ?? '';

const formattedCss = await prettier.format(originalCss, {
...prettierConfig,
parser: 'css',
});
Expand Down
4 changes: 2 additions & 2 deletions packages/pigment-css-unplugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ export const plugin = createUnplugin<PigmentOptions, true>((options) => {
},
transform(_code, id) {
if (id.endsWith('styles.css')) {
return theme ? generateTokenCss(theme) : _code;
return theme ? generateTokenCss(theme, options.experiments) : _code;
}
if (id.includes('pigment-css-react/theme')) {
return `export default ${
Expand All @@ -370,7 +370,7 @@ export const plugin = createUnplugin<PigmentOptions, true>((options) => {
},
load(id) {
if (id === VIRTUAL_CSS_FILE && theme) {
return generateTokenCss(theme);
return generateTokenCss(theme, options.experiments);
}
if (id === VIRTUAL_THEME_FILE) {
return `export default ${
Expand Down
2 changes: 1 addition & 1 deletion packages/pigment-css-vite-plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export function pigment(options: PigmentOptions) {
},
load(id) {
if (id === VIRTUAL_CSS_FILE) {
return generateTokenCss(theme);
return generateTokenCss(theme, options.experiments);
}
if (id === VIRTUAL_THEME_FILE) {
return `export default ${JSON.stringify(generateThemeTokens(theme))};`;
Expand Down
Loading
Loading