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

v1/react package #367

Draft
wants to merge 18 commits into
base: master
Choose a base branch
from
Draft
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 .codesandbox/ci.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
"installCommand": "install:codesandbox",
"node": "18",
"packages": [
"packages/pigment-css-core",
"packages/pigment-css-nextjs-plugin",
"packages/pigment-css-react",
"packages/pigment-css-react-new",
"packages/pigment-css-theme",
"packages/pigment-css-unplugin",
"packages/pigment-css-utils",
Expand Down
4 changes: 4 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
/packages/pigment-css-react/exports/
/packages/pigment-css-react/theme/
/packages/pigment-css-react/tests/**/fixtures
/packages/pigment-css-core/exports/
/packages/pigment-css-core/tests/**/fixtures
/packages/pigment-css-react-new/exports/
/packages/pigment-css-react-new/tests/**/fixtures
/packages/pigment-css-nextjs-plugin/loader.js
# Ignore fixtures
/packages-internal/scripts/typescript-to-proptypes/test/*/*
Expand Down
2 changes: 2 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ module.exports = {
],
'no-use-before-define': 'off',

'react/react-in-jsx-scope': 'off',

// disabled type-aware linting due to performance considerations
'@typescript-eslint/dot-notation': 'off',
'dot-notation': 'error',
Expand Down
29 changes: 29 additions & 0 deletions packages/pigment-css-core/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Pigment CSS

Pigment CSS is a zero-runtime CSS-in-JS library that extracts the colocated styles to their own CSS files at build time.

## Getting started

Pigment CSS supports Next.js and Vite with support for more bundlers in the future.

### Why choose Pigment CSS

Thanks to recent advancements in CSS (like CSS variables and `color-mix()`), "traditional" CSS-in-JS solutions that process styles at runtime are no longer required for unlocking features like color transformations and theme variables which are necessary for maintaining a sophisticated design system.

Pigment CSS addresses the needs of the modern React developer by providing a zero-runtime CSS-in-JS styling solution as a successor to tools like Emotion and styled-components.

Compared to its predecessors, Pigment CSS offers improved DX and runtime performance (though at the cost of increased build time) while also being compatible with React Server Components.
Pigment CSS is built on top of [WyW-in-JS](https://wyw-in-js.dev/), enabling to provide the smoothest possible experience for Material UI users when migrating from Emotion in v5 to Pigment CSS in v6.

### Installation

<!-- #default-branch-switch -->

```bash
npm install @pigment-css/core
npm install --save-dev @pigment-css/nextjs-plugin
```

<!-- Replace this with the documentation link once it is available. -->

For more information and getting started guide, check the [repository README.md](https://github.com/mui/pigment-css).
5 changes: 5 additions & 0 deletions packages/pigment-css-core/exports/css.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Object.defineProperty(exports, '__esModule', {
value: true,
});

exports.default = require('../build/processors/css').CssProcessor;
5 changes: 5 additions & 0 deletions packages/pigment-css-core/exports/keyframes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Object.defineProperty(exports, '__esModule', {
value: true,
});

exports.default = require('../build/processors/keyframes').KeyframesProcessor;
126 changes: 126 additions & 0 deletions packages/pigment-css-core/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
{
"name": "@pigment-css/core",
"version": "0.0.27",
"main": "build/index.js",
"module": "build/index.mjs",
"types": "build/index.d.ts",
"author": "MUI Team",
"description": "A zero-runtime CSS-in-JS library.",
"repository": {
"type": "git",
"url": "git+https://github.com/mui/pigment-css.git",
"directory": "packages/pigment-css-core"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/mui/pigment-css/issues"
},
"homepage": "https://github.com/mui/pigment-css/tree/master/README.md",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/mui-org"
},
"scripts": {
"clean": "rimraf build",
"watch": "tsup --watch --clean false",
"copy-license": "node ../../scripts/pigment-license.mjs",
"build": "tsup",
"test": "cd ../../ && cross-env NODE_ENV=test BABEL_ENV=coverage nyc --reporter=text mocha 'packages/pigment-css-core/**/*.test.{js,ts,tsx}'",
"test:update": "cd ../../ && cross-env NODE_ENV=test UPDATE_FIXTURES=true mocha 'packages/pigment-css-core/**/*.test.{js,ts,tsx}'",
"test:ci": "cd ../../ && cross-env NODE_ENV=test BABEL_ENV=coverage nyc --reporter=lcov --report-dir=./coverage/pigment-css-core mocha 'packages/pigment-css-core/**/*.test.{js,ts,tsx}'",
"typescript": "tsc --noEmit -p ."
},
"dependencies": {
"@babel/types": "^7.25.8",
"@pigment-css/utils": "workspace:*",
"@pigment-css/theme": "workspace:^",
"@wyw-in-js/processor-utils": "^0.5.5",
"@wyw-in-js/shared": "^0.5.5",
"@wyw-in-js/transform": "^0.5.5",
"csstype": "^3.1.3"
},
"devDependencies": {
"@types/chai": "^4.3.14",
"chai": "^4.4.1",
"prettier": "^3.3.3"
},
"sideEffects": false,
"publishConfig": {
"access": "public"
},
"wyw-in-js": {
"tags": {
"keyframes": "./exports/keyframes.js",
"css": "./exports/css.js"
}
},
"files": [
"src",
"build",
"exports",
"package.json",
"styles.css",
"LICENSE"
],
"exports": {
".": {
"types": "./build/index.d.ts",
"import": {
"types": "./build/index.d.mts",
"default": "./build/index.mjs"
},
"require": "./build/index.js",
"default": "./build/index.js"
},
"./package.json": "./package.json",
"./styles.css": "./styles.css",
"./processors/css": {
"import": "./build/processors/css.mjs",
"require": "./build/processors/css.js",
"default": "./build/processors/css.js"
},
"./processors/keyframes": {
"import": "./build/processors/keyframes.mjs",
"require": "./build/processors/keyframes.js",
"default": "./build/processors/keyframes.js"
},
"./exports/*": {
"default": "./exports/*.js"
},
"./runtime": {
"import": "./build/runtime/index.mjs",
"require": "./build/runtime/index.js",
"default": "./build/runtime/index.js"
}
},
"nx": {
"targets": {
"test": {
"cache": false,
"dependsOn": [
"build"
]
},
"test:update": {
"cache": false,
"dependsOn": [
"build"
]
},
"test:ci": {
"cache": false,
"dependsOn": [
"build"
]
},
"build": {
"outputs": [
"{projectRoot}/build"
],
"dependsOn": [
"^build"
]
}
}
}
}
51 changes: 51 additions & 0 deletions packages/pigment-css-core/src/base.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import type * as CSS from 'csstype';
import { Theme, ThemeKey } from '@pigment-css/theme';

export type CSSProperties = CSS.PropertiesFallback<number | string> & {
[index: `--${string}`]: string;
[index: `$${string}`]: string;
};

type CSSPropertiesBase = {
[K in keyof CSSProperties]: CSSProperties[K];
};

export type CSSPropertiesMultiValue = {
[K in keyof CSSProperties]:
| ThemeKey
| CSSProperties[K]
| Array<Extract<CSSProperties[K], string>>;
};

export type CSSPseudosNoCallback = { [K in CSS.Pseudos]?: CSSObjectNoCallback };

export interface CSSOthersObjectNoCallback {
[selector: string]: CSSObjectNoCallback;
}

export type CSSObjectNoCallback =
| CSSPropertiesMultiValue
| CSSPseudosNoCallback
| CSSOthersObjectNoCallback;

export type CSSPropertiesMultiValueWithProps<Props extends object> = {
[K in keyof CSSPropertiesMultiValue]:
| CSSPropertiesMultiValue[K]
| ((props: Props) => CSSPropertiesBase[K]);
};

export type CSSPseudos<Props extends object> = { [K in CSS.Pseudos]?: CSSObject<Props> };

export interface CSSOthersObject<Props extends object> {
[selector: string]: CSSObject<Props>;
}

export type CSSObject<Props extends object> =
| CSSPropertiesMultiValueWithProps<Props>
| CSSPseudos<Props>
| CSSOthersObject<Props>;

export type ThemeArgs = {
theme: Theme;
};
export type Primitive = string | null | undefined | boolean | number;
70 changes: 70 additions & 0 deletions packages/pigment-css-core/src/css.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { CSSObjectNoCallback, CSSProperties, Primitive, ThemeArgs } from './base';

export type CssFn<Props extends object> = (props: Props) => string | number;

type Variants = {
[VariantGroup: string]: {
[VariantName: string]: CSSObjectNoCallback;
};
};

type VariantNames<T extends Variants> = {
[K in keyof T]?: keyof T[K];
};

type CompoundVariant<T extends Variants> = VariantNames<T> & {
css: CSSProperties;
};

type CVAConfig<V extends Variants> = {
variants?: V;
compoundVariants?: CompoundVariant<V>[];
defaultVariants?: VariantNames<V>;
};

export type ClassNameOptions =
| {
variantName: string;
variantValue: string;
}
| {
isCv: true;
};

export interface BaseInterface {
/**
* Corresponds to css class name for `css` or `styled` function calls and keyframe name for `keyframes` function call.
*/
className?: string | ((opts?: ClassNameOptions) => string);
}

type TemplateLiteralItems = Primitive | CSSProperties;

type CSSWithVariants<V extends Variants> = CSSObjectNoCallback & CVAConfig<V>;

type CssValue<V extends Variants> = CSSWithVariants<V> | string;

type CssArg<V extends Variants> = ((themeArgs: ThemeArgs) => CssValue<V>) | CssValue<V>;

type CssReturn = {
className: string;
style?: CSSProperties;
};

type CssReturnFn<Props extends {}> = (props: Props) => CssReturn;

interface CssNoOption {
(
arg: TemplateStringsArray,
...templateArgs: (TemplateLiteralItems | CssFn<{}>)[]
): CssReturnFn<{}>;

<V extends Variants>(...args: CssArg<V>[]): CssReturnFn<VariantNames<V>>;
}

interface CssWithOption {
<M extends BaseInterface>(metadata: M): CssNoOption;
}

declare const css: CssNoOption & CssWithOption;
export default css;
30 changes: 30 additions & 0 deletions packages/pigment-css-core/src/css.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { generateErrorMessage } from './utils';

export default function css() {
console.error(generateErrorMessage('css'));
}

/**
const cls1 = css({
className() {
return 'class-name',
},
})<Props>({
color: 'red',
backgroundColor: (props) => props.isRed ? 'red' : 'blue',
variants: {
size: {
small: {
padding: 2,
}
}
},
compoundVariants: [],
defaultVariants: {},
});

const {className, style} = cls1({
isRed: true,
size: 'small',
});
*/
4 changes: 4 additions & 0 deletions packages/pigment-css-core/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from '@pigment-css/theme';
export * from './base';
export { default as css } from './css';
export { default as keyframes } from './keyframes';
26 changes: 26 additions & 0 deletions packages/pigment-css-core/src/keyframes.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { CSSPropertiesMultiValue, Primitive, ThemeArgs } from './base';
import { BaseInterface } from './css';

interface KeyframesObject {
[key: string]: {
[K in keyof CSSPropertiesMultiValue]:
| CSSPropertiesMultiValue[K]
| Array<CSSPropertiesMultiValue[K]>;
};
}

type KeyframesFn = (themeArgs: ThemeArgs) => string;
type KeyframesArg = KeyframesObject | string | ((themeArgs: ThemeArgs) => KeyframesObject | string);

interface KeyframesNoOption {
(arg: TemplateStringsArray, ...templateArgs: (Primitive | KeyframesFn)[]): string;
(arg: KeyframesArg): string;
}

interface KeyframesWithOption {
<M extends BaseInterface>(metadata: M): KeyframesNoOption;
}

declare const keyframes: KeyframesNoOption & KeyframesWithOption;

export default keyframes;
10 changes: 10 additions & 0 deletions packages/pigment-css-core/src/keyframes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { generateErrorMessage } from './utils';

/**
* `__wyw_dynamic_import` is a special global var that is set during the evaluation phase by wyw.
* So during eval phase, it can happen that some code is calling the runtime function.
* We do not want to throw error in that case as we want the evaluation to happen.
*/
export default function keyframes() {
console.error(generateErrorMessage('keyframes'));
}
Loading
Loading