diff --git a/apps/pigment-css-next-app/src/app/grid/demo3.tsx b/apps/pigment-css-next-app/src/app/grid/demo3.tsx
new file mode 100644
index 00000000..3fcf1662
--- /dev/null
+++ b/apps/pigment-css-next-app/src/app/grid/demo3.tsx
@@ -0,0 +1,49 @@
+'use client';
+import * as React from 'react';
+import Grid from '@pigment-css/react/Grid';
+import { styled } from '@pigment-css/react';
+
+const Item = styled.div`
+ background-color: #fff;
+ border: 1px solid #ced7e0;
+ padding: 8px;
+ border-radius: 4px;
+ text-align: center;
+`;
+
+export default function GridDemo3() {
+ const [spacing, setSpacing] = React.useState(2);
+ return (
+
+
+ {[0, 1, 2].map((value) => (
+
+
+
+ ))}
+
+
+ Spacing:
+ {[0, 0.5, 1, 2, 3, 4, 8, 12].map((value) => (
+
+
+
+ ))}
+
+
+ );
+}
diff --git a/apps/pigment-css-next-app/src/app/grid/page.tsx b/apps/pigment-css-next-app/src/app/grid/page.tsx
new file mode 100644
index 00000000..52c27519
--- /dev/null
+++ b/apps/pigment-css-next-app/src/app/grid/page.tsx
@@ -0,0 +1,259 @@
+import Box from '@pigment-css/react/Box';
+import Grid from '@pigment-css/react/Grid';
+import { styled } from '@pigment-css/react';
+import GridDemo3 from './demo3';
+
+const Item = styled.div`
+ background-color: #fff;
+ border: 1px solid #ced7e0;
+ padding: 8px;
+ border-radius: 4px;
+ text-align: center;
+`;
+
+function GridDemo1() {
+ return (
+
+
+ - size=8
+
+
+ - size=4
+
+
+ - size=4
+
+
+ - size=8
+
+
+ );
+}
+
+function GridDemo2() {
+ return (
+
+
+ - xs=6 md=8
+
+
+ - xs=6 md=4
+
+
+ - xs=6 md=4
+
+
+ - xs=6 md=8
+
+
+ );
+}
+
+function GridDemo4() {
+ return (
+
+
+ - 1
+
+
+ - 2
+
+
+ - 3
+
+
+ - 4
+
+
+ );
+}
+
+function GridDemo5() {
+ return (
+
+ {Array.from(Array(6)).map((_, index) => (
+
+ - {index + 1}
+
+ ))}
+
+ );
+}
+
+function GridDemo6() {
+ return (
+
+
+ - grow
+
+
+ - size=6
+
+
+ - grow
+
+
+ );
+}
+
+function GridDemo7() {
+ return (
+
+
+ - Variable width item
+
+
+ - size=6
+
+
+ - grow
+
+
+ );
+}
+
+function GridDemo8() {
+ return (
+
+
+
+ - Email subscribe section
+
+
+
+ -
+
+ Category A
+
+
+ Link 1.1
+ Link 1.2
+ Link 1.3
+
+
+
+
+ -
+
+ Category B
+
+
+ Link 2.1
+ Link 2.2
+ Link 2.3
+
+
+
+
+ -
+
+ Category C
+
+
+ Link 3.1
+ Link 3.2
+ Link 3.3
+
+
+
+
+ -
+
+ Category D
+
+
+ Link 4.1
+ Link 4.2
+ Link 4.3
+
+
+
+
+
+
+ - © Copyright
+
+
+
+ - Link A
+
+
+ - Link B
+
+
+ - Link C
+
+
+
+
+
+ );
+}
+
+function GridDemo9() {
+ return (
+
+
+ - size=8
+
+
+ - size=8
+
+
+ );
+}
+
+function GridDemo10() {
+ return (
+
+
+ - 1
+
+
+ - 2
+
+
+ - 3
+
+
+ - 4
+
+
+ );
+}
+
+const demos = [
+ { id: '1', component: GridDemo1 },
+ { id: '2', component: GridDemo2 },
+ { id: '3', component: GridDemo3 },
+ { id: '4', component: GridDemo4 },
+ { id: '5', component: GridDemo5 },
+ { id: '6', component: GridDemo6 },
+ { id: '7', component: GridDemo7 },
+ { id: '8', component: GridDemo8 },
+ { id: '9', component: GridDemo9 },
+ { id: '10', component: GridDemo10 },
+];
+
+export default function InteractiveGrid() {
+ return (
+
+
Benchmark v5
+
Benchmark next
+ {demos.map((demo) => {
+ const Demo = demo.component;
+ return (
+
+
Grid Demo {demo.id}
+
+
+ );
+ })}
+
+ );
+}
diff --git a/apps/pigment-css-vite-app/src/pages/grid.tsx b/apps/pigment-css-vite-app/src/pages/grid.tsx
new file mode 100644
index 00000000..1558e622
--- /dev/null
+++ b/apps/pigment-css-vite-app/src/pages/grid.tsx
@@ -0,0 +1,296 @@
+import * as React from 'react';
+import Box from '@pigment-css/react/Box';
+import Grid from '@pigment-css/react/Grid';
+import { styled } from '@pigment-css/react';
+
+const Item = styled.div`
+ background-color: #fff;
+ border: 1px solid #ced7e0;
+ padding: 8px;
+ border-radius: 4px;
+ text-align: center;
+`;
+
+function GridDemo1() {
+ return (
+
+
+ - size=8
+
+
+ - size=4
+
+
+ - size=4
+
+
+ - size=8
+
+
+ );
+}
+
+function GridDemo2() {
+ return (
+
+
+ - xs=6 md=8
+
+
+ - xs=6 md=4
+
+
+ - xs=6 md=4
+
+
+ - xs=6 md=8
+
+
+ );
+}
+
+function GridDemo3() {
+ const [spacing, setSpacing] = React.useState(2);
+ return (
+
+
+ {[0, 1, 2].map((value) => (
+
+
+
+ ))}
+
+
+ Spacing:
+ {[0, 0.5, 1, 2, 3, 4, 8, 12].map((value) => (
+
+
+
+ ))}
+
+
+ );
+}
+
+function GridDemo4() {
+ return (
+
+
+ - 1
+
+
+ - 2
+
+
+ - 3
+
+
+ - 4
+
+
+ );
+}
+
+function GridDemo5() {
+ return (
+
+ {Array.from(Array(6)).map((_, index) => (
+
+ - {index + 1}
+
+ ))}
+
+ );
+}
+
+function GridDemo6() {
+ return (
+
+
+ - grow
+
+
+ - size=6
+
+
+ - grow
+
+
+ );
+}
+
+function GridDemo7() {
+ return (
+
+
+ - Variable width item
+
+
+ - size=6
+
+
+ - grow
+
+
+ );
+}
+
+function GridDemo8() {
+ return (
+
+
+
+ - Email subscribe section
+
+
+
+ -
+
+ Category A
+
+
+ Link 1.1
+ Link 1.2
+ Link 1.3
+
+
+
+
+ -
+
+ Category B
+
+
+ Link 2.1
+ Link 2.2
+ Link 2.3
+
+
+
+
+ -
+
+ Category C
+
+
+ Link 3.1
+ Link 3.2
+ Link 3.3
+
+
+
+
+ -
+
+ Category D
+
+
+ Link 4.1
+ Link 4.2
+ Link 4.3
+
+
+
+
+
+
+ - © Copyright
+
+
+
+ - Link A
+
+
+ - Link B
+
+
+ - Link C
+
+
+
+
+
+ );
+}
+
+function GridDemo9() {
+ return (
+
+
+ - size=8
+
+
+ - size=8
+
+
+ );
+}
+
+function GridDemo10() {
+ return (
+
+
+ - 1
+
+
+ - 2
+
+
+ - 3
+
+
+ - 4
+
+
+ );
+}
+
+const demos = [
+ { id: '1', component: GridDemo1 },
+ { id: '2', component: GridDemo2 },
+ { id: '3', component: GridDemo3 },
+ { id: '4', component: GridDemo4 },
+ { id: '5', component: GridDemo5 },
+ { id: '6', component: GridDemo6 },
+ { id: '7', component: GridDemo7 },
+ { id: '8', component: GridDemo8 },
+ { id: '9', component: GridDemo9 },
+ { id: '10', component: GridDemo10 },
+];
+
+export default function InteractiveGrid() {
+ return (
+
+
Benchmark v5
+
Benchmark next
+ {demos.map((demo) => {
+ const Demo = demo.component;
+ return (
+
+
Grid Demo {demo.id}
+
+
+ );
+ })}
+
+ );
+}
diff --git a/packages/pigment-css-react/package.json b/packages/pigment-css-react/package.json
index cf84dea8..ac0cded2 100644
--- a/packages/pigment-css-react/package.json
+++ b/packages/pigment-css-react/package.json
@@ -179,6 +179,15 @@
},
"require": "./build/Hidden.js",
"default": "./build/Hidden.js"
+ },
+ "./Grid": {
+ "types": "./build/Grid.d.ts",
+ "import": {
+ "types": "./build/Grid.d.mts",
+ "default": "./build/Grid.mjs"
+ },
+ "require": "./build/Grid.js",
+ "default": "./build/Grid.js"
}
},
"nx": {
diff --git a/packages/pigment-css-react/src/Grid.d.ts b/packages/pigment-css-react/src/Grid.d.ts
new file mode 100644
index 00000000..262d8c85
--- /dev/null
+++ b/packages/pigment-css-react/src/Grid.d.ts
@@ -0,0 +1,22 @@
+import * as CSS from 'csstype';
+
+import { Breakpoint } from './base';
+import { PolymorphicComponent } from './Box';
+
+type CssProperty = T | Array | Partial>;
+
+type GridBaseProps = {
+ className?: string;
+ columns?: CssProperty;
+ columnSpacing?: CssProperty;
+ container?: boolean;
+ direction?: CssProperty;
+ offset?: CssProperty;
+ rowSpacing?: CssProperty;
+ size?: CssProperty;
+ spacing?: CssProperty;
+};
+
+declare const Grid: PolymorphicComponent;
+
+export default Grid;
diff --git a/packages/pigment-css-react/src/Grid.jsx b/packages/pigment-css-react/src/Grid.jsx
new file mode 100644
index 00000000..b8703257
--- /dev/null
+++ b/packages/pigment-css-react/src/Grid.jsx
@@ -0,0 +1,311 @@
+/* eslint-disable @typescript-eslint/no-unused-expressions */
+/* eslint-disable react/jsx-filename-extension */
+import clsx from 'clsx';
+import PropTypes from 'prop-types';
+import * as React from 'react';
+
+import { generateAtomics } from './generateAtomics';
+import styled from './styled';
+
+function isGridComponent(element) {
+ // For server components `muiName` is avaialble in element.type._payload.value.muiName
+ // relevant info - https://github.com/facebook/react/blob/2807d781a08db8e9873687fccc25c0f12b4fb3d4/packages/react/src/ReactLazy.js#L45
+ // eslint-disable-next-line no-underscore-dangle
+ return element.type.muiName === 'Grid' || element.type?._payload?.value?.muiName === 'Grid';
+}
+
+const gridAtomics = generateAtomics(({ theme }) => {
+ const conditions = {};
+ Object.entries(theme.breakpoints.values)
+ .sort((a, b) => a[1] - b[1])
+ .forEach(([breakpoint, value]) => {
+ conditions[breakpoint] = `@media (min-width: ${value}${theme.breakpoints.unit ?? 'px'})`;
+ });
+ return {
+ conditions,
+ defaultCondition: theme.breakpoints?.keys?.[0],
+ properties: {
+ flexDirection: ['column', 'column-reverse', 'row', 'row-reverse'],
+ '--Grid-parent-column-count': ['--Grid-parent-column-count'],
+ '--Grid-parent-column-spacing': ['--Grid-parent-column-spacing'],
+ '--Grid-parent-row-spacing': ['--Grid-parent-row-spacing'],
+ '--Grid-self-column-span': ['--Grid-self-column-span'],
+ '--Grid-self-width': ['--Grid-self-width'],
+ '--Grid-self-max-width': ['--Grid-self-max-width'],
+ '--Grid-self-flex': ['--Grid-self-flex'],
+ '--Grid-self-column-spacing': ['--Grid-self-column-spacing'],
+ '--Grid-self-row-spacing': ['--Grid-self-row-spacing'],
+ '--Grid-self-offset': ['--Grid-self-offset'],
+ '--Grid-self-margin-left': ['--Grid-self-margin-left'],
+ },
+ unitless: ['--Grid-parent-column-count', '--Grid-self-column-span', '--Grid-self-offset'],
+ multipliers: {
+ '--Grid-parent-column-spacing': Array.isArray(theme.vars?.spacing)
+ ? theme.vars.spacing[0]
+ : theme.vars?.spacing,
+ '--Grid-parent-row-spacing': Array.isArray(theme.vars?.spacing)
+ ? theme.vars.spacing[0]
+ : theme.vars?.spacing,
+ '--Grid-self-column-spacing': Array.isArray(theme.vars?.spacing)
+ ? theme.vars.spacing[0]
+ : theme.vars?.spacing,
+ '--Grid-self-row-spacing': Array.isArray(theme.vars?.spacing)
+ ? theme.vars.spacing[0]
+ : theme.vars?.spacing,
+ },
+ inlineGetters: {
+ '--Grid-self-width': (value) => {
+ if (value === 'grow') {
+ return 'unset';
+ }
+
+ if (value === 'auto') {
+ return 'auto';
+ }
+
+ return 'var(--Grid-fixed-width)';
+ },
+ '--Grid-self-max-width': (value) => {
+ if (value === 'grow') {
+ return '100%';
+ }
+
+ if (value === 'auto') {
+ return 'none';
+ }
+
+ return 'unset';
+ },
+ '--Grid-self-flex': (value) => {
+ if (value === 'grow') {
+ return '1 1 0';
+ }
+
+ if (value === 'auto') {
+ return '0 0 auto';
+ }
+
+ return '0 1 auto';
+ },
+ '--Grid-self-margin-left': (value) => {
+ if (value === 'auto') {
+ return 'auto';
+ }
+
+ return 'var(--Grid-fixed-offset)';
+ },
+ },
+ };
+});
+
+const GridComponent = styled('div')({
+ '--Grid-fixed-width':
+ 'calc(100% * var(--Grid-self-column-span) / var(--Grid-parent-column-count) - (var(--Grid-parent-column-count) - var(--Grid-self-column-span)) * var(--Grid-parent-column-spacing) / var(--Grid-parent-column-count))',
+ '--Grid-fixed-offset':
+ 'calc(100% * var(--Grid-self-offset) / var(--Grid-parent-column-count) + var(--Grid-parent-column-spacing) * var(--Grid-self-offset) / var(--Grid-parent-column-count))',
+ variants: [
+ {
+ props: { container: true },
+ style: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ gap: 'var(--Grid-self-row-spacing) var(--Grid-self-column-spacing)',
+ },
+ },
+ {
+ props: ({ size }) => size !== undefined,
+ style: {
+ width: 'var(--Grid-self-width)',
+ maxWidth: 'var(--Grid-self-max-width)',
+ flex: 'var(--Grid-self-flex)',
+ },
+ },
+ {
+ props: ({ offset }) => offset !== undefined,
+ style: {
+ marginLeft: 'var(--Grid-self-margin-left)',
+ },
+ },
+ ],
+});
+
+const Grid = React.forwardRef(function Grid(
+ {
+ children,
+ columns,
+ spacing,
+ columnSpacing,
+ rowSpacing,
+ direction = 'row',
+ style,
+ className,
+ component = 'div',
+ container = false,
+ size,
+ offset,
+ // internal props
+ // eslint-disable-next-line react/prop-types
+ unstable_parent_columns,
+ // eslint-disable-next-line react/prop-types
+ unstable_parent_column_spacing,
+ // eslint-disable-next-line react/prop-types
+ unstable_parent_row_spacing,
+ ...rest
+ },
+ ref,
+) {
+ const selfColumns = columns ?? unstable_parent_columns ?? 12;
+ const selfColumnSpacing = columnSpacing ?? spacing ?? unstable_parent_column_spacing ?? 0;
+ const selfRowSpacing = rowSpacing ?? spacing ?? unstable_parent_row_spacing ?? 0;
+
+ const gridAtomicsObj = {
+ flexDirection: direction,
+ };
+
+ if (unstable_parent_columns !== undefined) {
+ gridAtomicsObj['--Grid-parent-column-count'] = unstable_parent_columns;
+ }
+
+ if (unstable_parent_column_spacing !== undefined) {
+ gridAtomicsObj['--Grid-parent-column-spacing'] = unstable_parent_column_spacing;
+ }
+
+ if (unstable_parent_row_spacing !== undefined) {
+ gridAtomicsObj['--Grid-parent-row-spacing'] = unstable_parent_row_spacing;
+ }
+
+ if (container) {
+ gridAtomicsObj['--Grid-self-column-spacing'] = selfColumnSpacing;
+ gridAtomicsObj['--Grid-self-row-spacing'] = selfRowSpacing;
+ }
+
+ if (size) {
+ gridAtomicsObj['--Grid-self-column-span'] = size;
+ gridAtomicsObj['--Grid-self-width'] = size;
+ gridAtomicsObj['--Grid-self-max-width'] = size;
+ gridAtomicsObj['--Grid-self-flex'] = size;
+ }
+ if (offset) {
+ gridAtomicsObj['--Grid-self-offset'] = offset;
+ gridAtomicsObj['--Grid-self-margin-left'] = offset;
+ }
+
+ const ownerState = { container, size, offset };
+
+ const gridClasses = gridAtomics(gridAtomicsObj);
+ return (
+
+ {React.Children.map(children, (child) => {
+ if (React.isValidElement(child) && isGridComponent(child)) {
+ return React.cloneElement(child, {
+ unstable_parent_columns: selfColumns,
+ unstable_parent_column_spacing: selfColumnSpacing,
+ unstable_parent_row_spacing: selfRowSpacing,
+ });
+ }
+ return child;
+ })}
+
+ );
+});
+
+Grid.muiName = 'Grid';
+
+process.env.NODE_ENV !== 'production' &&
+ (Grid.propTypes /* remove-proptypes */ = {
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
+ // │ These PropTypes are generated from the TypeScript type definitions. │
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
+ // └─────────────────────────────────────────────────────────────────────┘
+ /**
+ * The content of the component.
+ */
+ children: PropTypes.node,
+ /**
+ * @ignore
+ */
+ className: PropTypes.string,
+ /**
+ * @ignore
+ */
+ columns: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
+ PropTypes.arrayOf(PropTypes.number),
+ PropTypes.number,
+ PropTypes.object,
+ ]),
+ /**
+ * @ignore
+ */
+ columnSpacing: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
+ PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired),
+ PropTypes.number,
+ PropTypes.object,
+ PropTypes.string,
+ ]),
+ /**
+ * The component used for the root node.
+ * Either a string to use a HTML element or a component.
+ */
+ component: PropTypes.elementType,
+ /**
+ * @ignore
+ */
+ container: PropTypes.bool,
+ /**
+ * @ignore
+ */
+ direction: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
+ PropTypes.oneOf(['column', 'column-reverse', 'row', 'row-reverse']),
+ PropTypes.arrayOf(PropTypes.oneOf(['column', 'column-reverse', 'row', 'row-reverse'])),
+ PropTypes.object,
+ ]),
+ /**
+ * @ignore
+ */
+ offset: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
+ PropTypes.arrayOf(PropTypes.number),
+ PropTypes.number,
+ PropTypes.object,
+ ]),
+ /**
+ * @ignore
+ */
+ rowSpacing: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
+ PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired),
+ PropTypes.number,
+ PropTypes.object,
+ PropTypes.string,
+ ]),
+ /**
+ * @ignore
+ */
+ size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
+ PropTypes.arrayOf(PropTypes.number),
+ PropTypes.number,
+ PropTypes.object,
+ ]),
+ /**
+ * @ignore
+ */
+ spacing: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
+ PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired),
+ PropTypes.number,
+ PropTypes.object,
+ PropTypes.string,
+ ]),
+ /**
+ * @ignore
+ */
+ style: PropTypes.object,
+ });
+
+Grid.displayName = 'Grid';
+
+export default Grid;
diff --git a/packages/pigment-css-react/src/Stack.jsx b/packages/pigment-css-react/src/Stack.jsx
index ea1db349..1545c214 100644
--- a/packages/pigment-css-react/src/Stack.jsx
+++ b/packages/pigment-css-react/src/Stack.jsx
@@ -23,7 +23,9 @@ const stackAtomics = generateAtomics(({ theme }) => {
direction: ['flexDirection'],
spacing: ['gap'],
},
- multiplier: Array.isArray(theme.vars?.spacing) ? theme.vars.spacing[0] : theme.vars?.spacing,
+ multipliers: {
+ gap: Array.isArray(theme.vars?.spacing) ? theme.vars.spacing[0] : theme.vars?.spacing,
+ },
};
});
diff --git a/packages/pigment-css-react/src/generateAtomics.js b/packages/pigment-css-react/src/generateAtomics.js
index 927f389b..b78ccfd6 100644
--- a/packages/pigment-css-react/src/generateAtomics.js
+++ b/packages/pigment-css-react/src/generateAtomics.js
@@ -12,7 +12,8 @@ export function generateAtomics() {
* @property {Object.} shorthands
* @property {string[]} conditions
* @property {string} defaultCondition
- * @property {string} multiplier
+ * @property {string[]} unitless
+ * @property {Object.} multipliers
*/
/**
@@ -21,14 +22,27 @@ export function generateAtomics() {
*
* @param {RuntimeConfig} runtimeConfig
*/
-export function atomics({ styles, shorthands, conditions, defaultCondition, multiplier }) {
+export function atomics({
+ styles,
+ shorthands,
+ conditions,
+ defaultCondition,
+ unitless = [],
+ multipliers = {},
+ inlineGetters = {},
+}) {
function addStyles(cssProperty, propertyValue, classes, inlineStyle) {
const styleClasses = styles[cssProperty];
if (!styleClasses) {
return;
}
- function handlePrimitive(value, breakpoint = defaultCondition) {
+ function handlePrimitive(
+ value,
+ multiplier = undefined,
+ inlineGetter = undefined,
+ breakpoint = defaultCondition,
+ ) {
if (!(value in styleClasses)) {
const keys = Object.keys(styleClasses);
if (keys.length !== 1) {
@@ -37,11 +51,14 @@ export function atomics({ styles, shorthands, conditions, defaultCondition, mult
const key = keys[0];
let styleValue = value;
if (typeof value === 'number') {
- styleValue = multiplier ? `calc(${value} * ${multiplier})` : `${value}px`;
+ if (multiplier) {
+ styleValue = `calc(${value} * ${multiplier})`;
+ } else if (!unitless.includes(cssProperty)) {
+ styleValue = `${value}px`;
+ }
}
classes.push(styleClasses[key][breakpoint]);
- inlineStyle[`${key}${breakpoint === defaultCondition ? '' : `-${breakpoint}`}`] =
- styleValue;
+ inlineStyle[`${key}-${breakpoint}`] = inlineGetter ? inlineGetter(styleValue) : styleValue;
} else {
classes.push(
typeof styleClasses[value] !== 'object'
@@ -56,23 +73,33 @@ export function atomics({ styles, shorthands, conditions, defaultCondition, mult
typeof propertyValue === 'number' ||
typeof propertyValue === 'boolean'
) {
- handlePrimitive(propertyValue);
+ handlePrimitive(propertyValue, multipliers[cssProperty], inlineGetters[cssProperty]);
} else if (Array.isArray(propertyValue)) {
propertyValue.forEach((value, index) => {
- if (value) {
+ if (value !== undefined && value !== null) {
const breakpoint = conditions[index];
if (!breakpoint) {
return;
}
- handlePrimitive(value, conditions[index]);
+ handlePrimitive(
+ value,
+ multipliers[cssProperty],
+ inlineGetters[cssProperty],
+ conditions[index],
+ );
}
});
} else if (propertyValue) {
Object.keys(propertyValue).forEach((condition) => {
- if (propertyValue[condition]) {
+ if (propertyValue[condition] !== undefined && propertyValue[condition] !== null) {
const propertyClasses = styleClasses[propertyValue[condition]];
if (!propertyClasses) {
- handlePrimitive(propertyValue[condition], condition);
+ handlePrimitive(
+ propertyValue[condition],
+ multipliers[cssProperty],
+ inlineGetters[cssProperty],
+ condition,
+ );
return;
}
classes.push(propertyClasses[condition]);
diff --git a/packages/pigment-css-react/src/processors/styled.ts b/packages/pigment-css-react/src/processors/styled.ts
index 1168b9ae..46ae5883 100644
--- a/packages/pigment-css-react/src/processors/styled.ts
+++ b/packages/pigment-css-react/src/processors/styled.ts
@@ -416,10 +416,7 @@ export class StyledProcessor extends BaseProcessor {
}
}
- const styledImportIdentifier = t.addNamedImport(
- this.tagSource.imported,
- process.env.PACKAGE_NAME as string,
- );
+ const styledImportIdentifier = t.addNamedImport('styled', process.env.PACKAGE_NAME as string);
const styledCall = t.callExpression(
styledImportIdentifier,
componentMetaExpression ? [componentName, componentMetaExpression] : [componentName],
diff --git a/packages/pigment-css-react/src/utils/convertAtomicsToCss.ts b/packages/pigment-css-react/src/utils/convertAtomicsToCss.ts
index 4408e0bb..b398a5cd 100644
--- a/packages/pigment-css-react/src/utils/convertAtomicsToCss.ts
+++ b/packages/pigment-css-react/src/utils/convertAtomicsToCss.ts
@@ -7,7 +7,9 @@ export type Atomics = {
[key: string]: string[];
};
shorthands: Record;
- multiplier?: string;
+ unitless: string[];
+ multipliers?: Record;
+ inlineGetters: Record string>;
};
export type RuntimeConfig = {
@@ -15,7 +17,9 @@ export type RuntimeConfig = {
styles: Record>>;
shorthands: Atomics['shorthands'];
defaultCondition: string;
- multiplier?: string;
+ unitless: string[];
+ multipliers?: Record;
+ inlineGetters: Record string>;
};
function getClassName(...items: string[]) {
@@ -28,7 +32,9 @@ export function convertAtomicsToCss(
defaultCondition,
properties,
shorthands = {},
- multiplier = undefined,
+ unitless = [],
+ multipliers = {},
+ inlineGetters = {},
}: Atomics,
mainClassName: string,
isGlobal = false,
@@ -40,7 +46,9 @@ export function convertAtomicsToCss(
shorthands,
conditions: Object.keys(conditions),
defaultCondition,
- multiplier,
+ unitless,
+ multipliers,
+ inlineGetters,
};
let count = 1;
function getCount() {
@@ -58,9 +66,7 @@ export function convertAtomicsToCss(
Object.entries(properties).forEach(([cssPropertyName, propertyValues]) => {
propertyValues.forEach((propertyValue) => {
const propValue = propertyValue.startsWith('--')
- ? cssesc(
- `var(${propertyValue}${conditionName === defaultCondition ? '' : `-${conditionName}`})`,
- )
+ ? cssesc(`var(${propertyValue}-${conditionName})`)
: propertyValue;
const className =
isGlobal || debug
diff --git a/packages/pigment-css-react/tests/Container/fixtures/Container.output.js b/packages/pigment-css-react/tests/Container/fixtures/Container.output.js
index 3c555ead..e9df81ba 100644
--- a/packages/pigment-css-react/tests/Container/fixtures/Container.output.js
+++ b/packages/pigment-css-react/tests/Container/fixtures/Container.output.js
@@ -1,8 +1,8 @@
-import _default from '@pigment-css/react';
+import { styled as _styled } from '@pigment-css/react';
import _theme from '@pigment-css/react/theme';
import * as React from 'react';
import PropTypes from 'prop-types';
-const ContainerRoot = /*#__PURE__*/ _default('div', {
+const ContainerRoot = /*#__PURE__*/ _styled('div', {
name: 'MuiContainer',
slot: 'Root',
})({
diff --git a/packages/pigment-css-react/tests/Grid/Grid.spec.tsx b/packages/pigment-css-react/tests/Grid/Grid.spec.tsx
new file mode 100644
index 00000000..28c84e3a
--- /dev/null
+++ b/packages/pigment-css-react/tests/Grid/Grid.spec.tsx
@@ -0,0 +1,60 @@
+import * as React from 'react';
+import Grid from '../../src/Grid';
+
+function BasicUsageSpec() {
+ return (
+
+
+ size=8
+
+
+ );
+}
+
+function ResponsiveSpec() {
+ return (
+
+
+ size=8
+
+ {/* @ts-expect-error invalid breakpoint */}
+
+ invalid breakpoint
+
+
+ );
+}
+
+function SizeValuesSpec() {
+ return (
+
+
+ auto
+
+
+ size=6
+
+
+ grow
+
+ {/* @ts-expect-error invalid size value */}
+
+ invalid size value
+
+
+ );
+}
+
+function OffsetValueSpec() {
+ return (
+
+
+ size=6 offset=2
+
+ {/* @ts-expect-error invalid offset value */}
+
+ invalid offset value
+
+
+ );
+}
diff --git a/packages/pigment-css-react/tests/Grid/Grid.test.js b/packages/pigment-css-react/tests/Grid/Grid.test.js
new file mode 100644
index 00000000..db2f7cbb
--- /dev/null
+++ b/packages/pigment-css-react/tests/Grid/Grid.test.js
@@ -0,0 +1,39 @@
+import * as React from 'react';
+import path from 'node:path';
+import { createBreakpoints } from '@mui/system';
+import { createRenderer } from '@mui/internal-test-utils';
+import { runTransformation, expect } from '../testUtils';
+import GridOutput from './fixtures/Grid.output';
+
+describe('Pigment CSS - Grid', () => {
+ const { render } = createRenderer();
+
+ it('should transform and render sx prop', async () => {
+ const { output, fixture } = await runTransformation(
+ path.join(__dirname, '../../src/Grid.jsx'),
+ {
+ themeArgs: {
+ theme: {
+ breakpoints: createBreakpoints({}),
+ },
+ },
+ outputDir: path.join(__dirname, 'fixtures'),
+ },
+ );
+ expect(output.js).to.equal(fixture.js);
+ expect(output.css).to.equal(fixture.css);
+ });
+
+ it('should render the basic example', () => {
+ const { getByTestId } = render(
+
+
+ size=8
+
+ ,
+ );
+
+ expect(getByTestId('grid-container')).not.to.equal(null);
+ expect(getByTestId('grid-item')).not.to.equal(null);
+ });
+});
diff --git a/packages/pigment-css-react/tests/Grid/fixtures/Grid.output.css b/packages/pigment-css-react/tests/Grid/fixtures/Grid.output.css
new file mode 100644
index 00000000..d5e06b3e
--- /dev/null
+++ b/packages/pigment-css-react/tests/Grid/fixtures/Grid.output.css
@@ -0,0 +1,369 @@
+.g1s0u14x1 {
+ flex-direction: column;
+}
+.g1s0u14x2 {
+ flex-direction: column-reverse;
+}
+.g1s0u14x3 {
+ flex-direction: row;
+}
+.g1s0u14x4 {
+ flex-direction: row-reverse;
+}
+.g1s0u14x5 {
+ --Grid-parent-column-count: var(--Grid-parent-column-count-xs);
+}
+.g1s0u14x6 {
+ --Grid-parent-column-spacing: var(--Grid-parent-column-spacing-xs);
+}
+.g1s0u14x7 {
+ --Grid-parent-row-spacing: var(--Grid-parent-row-spacing-xs);
+}
+.g1s0u14x8 {
+ --Grid-self-column-span: var(--Grid-self-column-span-xs);
+}
+.g1s0u14x9 {
+ --Grid-self-width: var(--Grid-self-width-xs);
+}
+.g1s0u14x10 {
+ --Grid-self-max-width: var(--Grid-self-max-width-xs);
+}
+.g1s0u14x11 {
+ --Grid-self-flex: var(--Grid-self-flex-xs);
+}
+.g1s0u14x12 {
+ --Grid-self-column-spacing: var(--Grid-self-column-spacing-xs);
+}
+.g1s0u14x13 {
+ --Grid-self-row-spacing: var(--Grid-self-row-spacing-xs);
+}
+.g1s0u14x14 {
+ --Grid-self-offset: var(--Grid-self-offset-xs);
+}
+.g1s0u14x15 {
+ --Grid-self-margin-left: var(--Grid-self-margin-left-xs);
+}
+@media (min-width: 600px) {
+ .g1s0u14x16 {
+ flex-direction: column;
+ }
+}
+@media (min-width: 600px) {
+ .g1s0u14x17 {
+ flex-direction: column-reverse;
+ }
+}
+@media (min-width: 600px) {
+ .g1s0u14x18 {
+ flex-direction: row;
+ }
+}
+@media (min-width: 600px) {
+ .g1s0u14x19 {
+ flex-direction: row-reverse;
+ }
+}
+@media (min-width: 600px) {
+ .g1s0u14x20 {
+ --Grid-parent-column-count: var(--Grid-parent-column-count-sm);
+ }
+}
+@media (min-width: 600px) {
+ .g1s0u14x21 {
+ --Grid-parent-column-spacing: var(--Grid-parent-column-spacing-sm);
+ }
+}
+@media (min-width: 600px) {
+ .g1s0u14x22 {
+ --Grid-parent-row-spacing: var(--Grid-parent-row-spacing-sm);
+ }
+}
+@media (min-width: 600px) {
+ .g1s0u14x23 {
+ --Grid-self-column-span: var(--Grid-self-column-span-sm);
+ }
+}
+@media (min-width: 600px) {
+ .g1s0u14x24 {
+ --Grid-self-width: var(--Grid-self-width-sm);
+ }
+}
+@media (min-width: 600px) {
+ .g1s0u14x25 {
+ --Grid-self-max-width: var(--Grid-self-max-width-sm);
+ }
+}
+@media (min-width: 600px) {
+ .g1s0u14x26 {
+ --Grid-self-flex: var(--Grid-self-flex-sm);
+ }
+}
+@media (min-width: 600px) {
+ .g1s0u14x27 {
+ --Grid-self-column-spacing: var(--Grid-self-column-spacing-sm);
+ }
+}
+@media (min-width: 600px) {
+ .g1s0u14x28 {
+ --Grid-self-row-spacing: var(--Grid-self-row-spacing-sm);
+ }
+}
+@media (min-width: 600px) {
+ .g1s0u14x29 {
+ --Grid-self-offset: var(--Grid-self-offset-sm);
+ }
+}
+@media (min-width: 600px) {
+ .g1s0u14x30 {
+ --Grid-self-margin-left: var(--Grid-self-margin-left-sm);
+ }
+}
+@media (min-width: 900px) {
+ .g1s0u14x31 {
+ flex-direction: column;
+ }
+}
+@media (min-width: 900px) {
+ .g1s0u14x32 {
+ flex-direction: column-reverse;
+ }
+}
+@media (min-width: 900px) {
+ .g1s0u14x33 {
+ flex-direction: row;
+ }
+}
+@media (min-width: 900px) {
+ .g1s0u14x34 {
+ flex-direction: row-reverse;
+ }
+}
+@media (min-width: 900px) {
+ .g1s0u14x35 {
+ --Grid-parent-column-count: var(--Grid-parent-column-count-md);
+ }
+}
+@media (min-width: 900px) {
+ .g1s0u14x36 {
+ --Grid-parent-column-spacing: var(--Grid-parent-column-spacing-md);
+ }
+}
+@media (min-width: 900px) {
+ .g1s0u14x37 {
+ --Grid-parent-row-spacing: var(--Grid-parent-row-spacing-md);
+ }
+}
+@media (min-width: 900px) {
+ .g1s0u14x38 {
+ --Grid-self-column-span: var(--Grid-self-column-span-md);
+ }
+}
+@media (min-width: 900px) {
+ .g1s0u14x39 {
+ --Grid-self-width: var(--Grid-self-width-md);
+ }
+}
+@media (min-width: 900px) {
+ .g1s0u14x40 {
+ --Grid-self-max-width: var(--Grid-self-max-width-md);
+ }
+}
+@media (min-width: 900px) {
+ .g1s0u14x41 {
+ --Grid-self-flex: var(--Grid-self-flex-md);
+ }
+}
+@media (min-width: 900px) {
+ .g1s0u14x42 {
+ --Grid-self-column-spacing: var(--Grid-self-column-spacing-md);
+ }
+}
+@media (min-width: 900px) {
+ .g1s0u14x43 {
+ --Grid-self-row-spacing: var(--Grid-self-row-spacing-md);
+ }
+}
+@media (min-width: 900px) {
+ .g1s0u14x44 {
+ --Grid-self-offset: var(--Grid-self-offset-md);
+ }
+}
+@media (min-width: 900px) {
+ .g1s0u14x45 {
+ --Grid-self-margin-left: var(--Grid-self-margin-left-md);
+ }
+}
+@media (min-width: 1200px) {
+ .g1s0u14x46 {
+ flex-direction: column;
+ }
+}
+@media (min-width: 1200px) {
+ .g1s0u14x47 {
+ flex-direction: column-reverse;
+ }
+}
+@media (min-width: 1200px) {
+ .g1s0u14x48 {
+ flex-direction: row;
+ }
+}
+@media (min-width: 1200px) {
+ .g1s0u14x49 {
+ flex-direction: row-reverse;
+ }
+}
+@media (min-width: 1200px) {
+ .g1s0u14x50 {
+ --Grid-parent-column-count: var(--Grid-parent-column-count-lg);
+ }
+}
+@media (min-width: 1200px) {
+ .g1s0u14x51 {
+ --Grid-parent-column-spacing: var(--Grid-parent-column-spacing-lg);
+ }
+}
+@media (min-width: 1200px) {
+ .g1s0u14x52 {
+ --Grid-parent-row-spacing: var(--Grid-parent-row-spacing-lg);
+ }
+}
+@media (min-width: 1200px) {
+ .g1s0u14x53 {
+ --Grid-self-column-span: var(--Grid-self-column-span-lg);
+ }
+}
+@media (min-width: 1200px) {
+ .g1s0u14x54 {
+ --Grid-self-width: var(--Grid-self-width-lg);
+ }
+}
+@media (min-width: 1200px) {
+ .g1s0u14x55 {
+ --Grid-self-max-width: var(--Grid-self-max-width-lg);
+ }
+}
+@media (min-width: 1200px) {
+ .g1s0u14x56 {
+ --Grid-self-flex: var(--Grid-self-flex-lg);
+ }
+}
+@media (min-width: 1200px) {
+ .g1s0u14x57 {
+ --Grid-self-column-spacing: var(--Grid-self-column-spacing-lg);
+ }
+}
+@media (min-width: 1200px) {
+ .g1s0u14x58 {
+ --Grid-self-row-spacing: var(--Grid-self-row-spacing-lg);
+ }
+}
+@media (min-width: 1200px) {
+ .g1s0u14x59 {
+ --Grid-self-offset: var(--Grid-self-offset-lg);
+ }
+}
+@media (min-width: 1200px) {
+ .g1s0u14x60 {
+ --Grid-self-margin-left: var(--Grid-self-margin-left-lg);
+ }
+}
+@media (min-width: 1536px) {
+ .g1s0u14x61 {
+ flex-direction: column;
+ }
+}
+@media (min-width: 1536px) {
+ .g1s0u14x62 {
+ flex-direction: column-reverse;
+ }
+}
+@media (min-width: 1536px) {
+ .g1s0u14x63 {
+ flex-direction: row;
+ }
+}
+@media (min-width: 1536px) {
+ .g1s0u14x64 {
+ flex-direction: row-reverse;
+ }
+}
+@media (min-width: 1536px) {
+ .g1s0u14x65 {
+ --Grid-parent-column-count: var(--Grid-parent-column-count-xl);
+ }
+}
+@media (min-width: 1536px) {
+ .g1s0u14x66 {
+ --Grid-parent-column-spacing: var(--Grid-parent-column-spacing-xl);
+ }
+}
+@media (min-width: 1536px) {
+ .g1s0u14x67 {
+ --Grid-parent-row-spacing: var(--Grid-parent-row-spacing-xl);
+ }
+}
+@media (min-width: 1536px) {
+ .g1s0u14x68 {
+ --Grid-self-column-span: var(--Grid-self-column-span-xl);
+ }
+}
+@media (min-width: 1536px) {
+ .g1s0u14x69 {
+ --Grid-self-width: var(--Grid-self-width-xl);
+ }
+}
+@media (min-width: 1536px) {
+ .g1s0u14x70 {
+ --Grid-self-max-width: var(--Grid-self-max-width-xl);
+ }
+}
+@media (min-width: 1536px) {
+ .g1s0u14x71 {
+ --Grid-self-flex: var(--Grid-self-flex-xl);
+ }
+}
+@media (min-width: 1536px) {
+ .g1s0u14x72 {
+ --Grid-self-column-spacing: var(--Grid-self-column-spacing-xl);
+ }
+}
+@media (min-width: 1536px) {
+ .g1s0u14x73 {
+ --Grid-self-row-spacing: var(--Grid-self-row-spacing-xl);
+ }
+}
+@media (min-width: 1536px) {
+ .g1s0u14x74 {
+ --Grid-self-offset: var(--Grid-self-offset-xl);
+ }
+}
+@media (min-width: 1536px) {
+ .g1s0u14x75 {
+ --Grid-self-margin-left: var(--Grid-self-margin-left-xl);
+ }
+}
+.g1i5ygey {
+ --Grid-fixed-width: calc(
+ 100% * var(--Grid-self-column-span) / var(--Grid-parent-column-count) -
+ (var(--Grid-parent-column-count) - var(--Grid-self-column-span)) *
+ var(--Grid-parent-column-spacing) / var(--Grid-parent-column-count)
+ );
+ --Grid-fixed-offset: calc(
+ 100% * var(--Grid-self-offset) / var(--Grid-parent-column-count) +
+ var(--Grid-parent-column-spacing) * var(--Grid-self-offset) / var(--Grid-parent-column-count)
+ );
+}
+.g1i5ygey-1 {
+ display: flex;
+ flex-wrap: wrap;
+ gap: var(--Grid-self-row-spacing) var(--Grid-self-column-spacing);
+}
+.g1i5ygey-2 {
+ width: var(--Grid-self-width);
+ max-width: var(--Grid-self-max-width);
+ flex: var(--Grid-self-flex);
+}
+.g1i5ygey-3 {
+ margin-left: var(--Grid-self-margin-left);
+}
diff --git a/packages/pigment-css-react/tests/Grid/fixtures/Grid.output.js b/packages/pigment-css-react/tests/Grid/fixtures/Grid.output.js
new file mode 100644
index 00000000..559bf4f9
--- /dev/null
+++ b/packages/pigment-css-react/tests/Grid/fixtures/Grid.output.js
@@ -0,0 +1,386 @@
+import { styled as _styled } from '@pigment-css/react';
+import _theme from '@pigment-css/react/theme';
+import { atomics as _atomics } from '@pigment-css/react';
+/* eslint-disable @typescript-eslint/no-unused-expressions */
+/* eslint-disable react/jsx-filename-extension */
+import clsx from 'clsx';
+import PropTypes from 'prop-types';
+import * as React from 'react';
+function isGridComponent(element) {
+ // For server components `muiName` is avaialble in element.type._payload.value.muiName
+ // relevant info - https://github.com/facebook/react/blob/2807d781a08db8e9873687fccc25c0f12b4fb3d4/packages/react/src/ReactLazy.js#L45
+ // eslint-disable-next-line no-underscore-dangle
+ return element.type.muiName === 'Grid' || element.type?._payload?.value?.muiName === 'Grid';
+}
+const gridAtomics = /*#__PURE__*/ _atomics({
+ styles: {
+ flexDirection: {
+ column: {
+ xs: 'g1s0u14x1',
+ sm: 'g1s0u14x16',
+ md: 'g1s0u14x31',
+ lg: 'g1s0u14x46',
+ xl: 'g1s0u14x61',
+ },
+ 'column-reverse': {
+ xs: 'g1s0u14x2',
+ sm: 'g1s0u14x17',
+ md: 'g1s0u14x32',
+ lg: 'g1s0u14x47',
+ xl: 'g1s0u14x62',
+ },
+ row: {
+ xs: 'g1s0u14x3',
+ sm: 'g1s0u14x18',
+ md: 'g1s0u14x33',
+ lg: 'g1s0u14x48',
+ xl: 'g1s0u14x63',
+ },
+ 'row-reverse': {
+ xs: 'g1s0u14x4',
+ sm: 'g1s0u14x19',
+ md: 'g1s0u14x34',
+ lg: 'g1s0u14x49',
+ xl: 'g1s0u14x64',
+ },
+ },
+ '--Grid-parent-column-count': {
+ '--Grid-parent-column-count': {
+ xs: 'g1s0u14x5',
+ sm: 'g1s0u14x20',
+ md: 'g1s0u14x35',
+ lg: 'g1s0u14x50',
+ xl: 'g1s0u14x65',
+ },
+ },
+ '--Grid-parent-column-spacing': {
+ '--Grid-parent-column-spacing': {
+ xs: 'g1s0u14x6',
+ sm: 'g1s0u14x21',
+ md: 'g1s0u14x36',
+ lg: 'g1s0u14x51',
+ xl: 'g1s0u14x66',
+ },
+ },
+ '--Grid-parent-row-spacing': {
+ '--Grid-parent-row-spacing': {
+ xs: 'g1s0u14x7',
+ sm: 'g1s0u14x22',
+ md: 'g1s0u14x37',
+ lg: 'g1s0u14x52',
+ xl: 'g1s0u14x67',
+ },
+ },
+ '--Grid-self-column-span': {
+ '--Grid-self-column-span': {
+ xs: 'g1s0u14x8',
+ sm: 'g1s0u14x23',
+ md: 'g1s0u14x38',
+ lg: 'g1s0u14x53',
+ xl: 'g1s0u14x68',
+ },
+ },
+ '--Grid-self-width': {
+ '--Grid-self-width': {
+ xs: 'g1s0u14x9',
+ sm: 'g1s0u14x24',
+ md: 'g1s0u14x39',
+ lg: 'g1s0u14x54',
+ xl: 'g1s0u14x69',
+ },
+ },
+ '--Grid-self-max-width': {
+ '--Grid-self-max-width': {
+ xs: 'g1s0u14x10',
+ sm: 'g1s0u14x25',
+ md: 'g1s0u14x40',
+ lg: 'g1s0u14x55',
+ xl: 'g1s0u14x70',
+ },
+ },
+ '--Grid-self-flex': {
+ '--Grid-self-flex': {
+ xs: 'g1s0u14x11',
+ sm: 'g1s0u14x26',
+ md: 'g1s0u14x41',
+ lg: 'g1s0u14x56',
+ xl: 'g1s0u14x71',
+ },
+ },
+ '--Grid-self-column-spacing': {
+ '--Grid-self-column-spacing': {
+ xs: 'g1s0u14x12',
+ sm: 'g1s0u14x27',
+ md: 'g1s0u14x42',
+ lg: 'g1s0u14x57',
+ xl: 'g1s0u14x72',
+ },
+ },
+ '--Grid-self-row-spacing': {
+ '--Grid-self-row-spacing': {
+ xs: 'g1s0u14x13',
+ sm: 'g1s0u14x28',
+ md: 'g1s0u14x43',
+ lg: 'g1s0u14x58',
+ xl: 'g1s0u14x73',
+ },
+ },
+ '--Grid-self-offset': {
+ '--Grid-self-offset': {
+ xs: 'g1s0u14x14',
+ sm: 'g1s0u14x29',
+ md: 'g1s0u14x44',
+ lg: 'g1s0u14x59',
+ xl: 'g1s0u14x74',
+ },
+ },
+ '--Grid-self-margin-left': {
+ '--Grid-self-margin-left': {
+ xs: 'g1s0u14x15',
+ sm: 'g1s0u14x30',
+ md: 'g1s0u14x45',
+ lg: 'g1s0u14x60',
+ xl: 'g1s0u14x75',
+ },
+ },
+ },
+ shorthands: {},
+ conditions: ['xs', 'sm', 'md', 'lg', 'xl'],
+ defaultCondition: 'xs',
+ unitless: ['--Grid-parent-column-count', '--Grid-self-column-span', '--Grid-self-offset'],
+ multipliers: {
+ '--Grid-parent-column-spacing': undefined,
+ '--Grid-parent-row-spacing': undefined,
+ '--Grid-self-column-spacing': undefined,
+ '--Grid-self-row-spacing': undefined,
+ },
+ inlineGetters: {
+ '--Grid-self-width': (value) => {
+ if (value === 'grow') {
+ return 'unset';
+ }
+ if (value === 'auto') {
+ return 'auto';
+ }
+ return 'var(--Grid-fixed-width)';
+ },
+ '--Grid-self-max-width': (value) => {
+ if (value === 'grow') {
+ return '100%';
+ }
+ if (value === 'auto') {
+ return 'none';
+ }
+ return 'unset';
+ },
+ '--Grid-self-flex': (value) => {
+ if (value === 'grow') {
+ return '1 1 0';
+ }
+ if (value === 'auto') {
+ return '0 0 auto';
+ }
+ return '0 1 auto';
+ },
+ '--Grid-self-margin-left': (value) => {
+ if (value === 'auto') {
+ return 'auto';
+ }
+ return 'var(--Grid-fixed-offset)';
+ },
+ },
+});
+const GridComponent = /*#__PURE__*/ _styled('div')({
+ classes: ['g1i5ygey'],
+ variants: [
+ {
+ props: {
+ container: true,
+ },
+ className: 'g1i5ygey-1',
+ },
+ {
+ props: ({ size }) => size !== undefined,
+ className: 'g1i5ygey-2',
+ },
+ {
+ props: ({ offset }) => offset !== undefined,
+ className: 'g1i5ygey-3',
+ },
+ ],
+});
+const Grid = React.forwardRef(function Grid(
+ {
+ children,
+ columns,
+ spacing,
+ columnSpacing,
+ rowSpacing,
+ direction = 'row',
+ style,
+ className,
+ component = 'div',
+ container = false,
+ size,
+ offset,
+ // internal props
+ // eslint-disable-next-line react/prop-types
+ unstable_parent_columns,
+ // eslint-disable-next-line react/prop-types
+ unstable_parent_column_spacing,
+ // eslint-disable-next-line react/prop-types
+ unstable_parent_row_spacing,
+ ...rest
+ },
+ ref,
+) {
+ const selfColumns = columns ?? unstable_parent_columns ?? 12;
+ const selfColumnSpacing = columnSpacing ?? spacing ?? unstable_parent_column_spacing ?? 0;
+ const selfRowSpacing = rowSpacing ?? spacing ?? unstable_parent_row_spacing ?? 0;
+ const gridAtomicsObj = {
+ flexDirection: direction,
+ };
+ if (unstable_parent_columns !== undefined) {
+ gridAtomicsObj['--Grid-parent-column-count'] = unstable_parent_columns;
+ }
+ if (unstable_parent_column_spacing !== undefined) {
+ gridAtomicsObj['--Grid-parent-column-spacing'] = unstable_parent_column_spacing;
+ }
+ if (unstable_parent_row_spacing !== undefined) {
+ gridAtomicsObj['--Grid-parent-row-spacing'] = unstable_parent_row_spacing;
+ }
+ if (container) {
+ gridAtomicsObj['--Grid-self-column-spacing'] = selfColumnSpacing;
+ gridAtomicsObj['--Grid-self-row-spacing'] = selfRowSpacing;
+ }
+ if (size) {
+ gridAtomicsObj['--Grid-self-column-span'] = size;
+ gridAtomicsObj['--Grid-self-width'] = size;
+ gridAtomicsObj['--Grid-self-max-width'] = size;
+ gridAtomicsObj['--Grid-self-flex'] = size;
+ }
+ if (offset) {
+ gridAtomicsObj['--Grid-self-offset'] = offset;
+ gridAtomicsObj['--Grid-self-margin-left'] = offset;
+ }
+ const ownerState = {
+ container,
+ size,
+ offset,
+ };
+ const gridClasses = gridAtomics(gridAtomicsObj);
+ return (
+
+ {React.Children.map(children, (child) => {
+ if (React.isValidElement(child) && isGridComponent(child)) {
+ return React.cloneElement(child, {
+ unstable_parent_columns: selfColumns,
+ unstable_parent_column_spacing: selfColumnSpacing,
+ unstable_parent_row_spacing: selfRowSpacing,
+ });
+ }
+ return child;
+ })}
+
+ );
+});
+Grid.muiName = 'Grid';
+process.env.NODE_ENV !== 'production' &&
+ (Grid.propTypes /* remove-proptypes */ = {
+ // ┌────────────────────────────── Warning ──────────────────────────────┐
+ // │ These PropTypes are generated from the TypeScript type definitions. │
+ // │ To update them, edit the d.ts file and run `pnpm proptypes`. │
+ // └─────────────────────────────────────────────────────────────────────┘
+ /**
+ * The content of the component.
+ */
+ children: PropTypes.node,
+ /**
+ * @ignore
+ */
+ className: PropTypes.string,
+ /**
+ * @ignore
+ */
+ columns: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
+ PropTypes.arrayOf(PropTypes.number),
+ PropTypes.number,
+ PropTypes.object,
+ ]),
+ /**
+ * @ignore
+ */
+ columnSpacing: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
+ PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired),
+ PropTypes.number,
+ PropTypes.object,
+ PropTypes.string,
+ ]),
+ /**
+ * The component used for the root node.
+ * Either a string to use a HTML element or a component.
+ */
+ component: PropTypes.elementType,
+ /**
+ * @ignore
+ */
+ container: PropTypes.bool,
+ /**
+ * @ignore
+ */
+ direction: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
+ PropTypes.oneOf(['column', 'column-reverse', 'row', 'row-reverse']),
+ PropTypes.arrayOf(PropTypes.oneOf(['column', 'column-reverse', 'row', 'row-reverse'])),
+ PropTypes.object,
+ ]),
+ /**
+ * @ignore
+ */
+ offset: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
+ PropTypes.arrayOf(PropTypes.number),
+ PropTypes.number,
+ PropTypes.object,
+ ]),
+ /**
+ * @ignore
+ */
+ rowSpacing: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
+ PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired),
+ PropTypes.number,
+ PropTypes.object,
+ PropTypes.string,
+ ]),
+ /**
+ * @ignore
+ */
+ size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
+ PropTypes.arrayOf(PropTypes.number),
+ PropTypes.number,
+ PropTypes.object,
+ ]),
+ /**
+ * @ignore
+ */
+ spacing: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([
+ PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired),
+ PropTypes.number,
+ PropTypes.object,
+ PropTypes.string,
+ ]),
+ /**
+ * @ignore
+ */
+ style: PropTypes.object,
+ });
+Grid.displayName = 'Grid';
+export default Grid;
diff --git a/packages/pigment-css-react/tests/Hidden/fixtures/Hidden.output.js b/packages/pigment-css-react/tests/Hidden/fixtures/Hidden.output.js
index 18c20b17..bc35b6af 100644
--- a/packages/pigment-css-react/tests/Hidden/fixtures/Hidden.output.js
+++ b/packages/pigment-css-react/tests/Hidden/fixtures/Hidden.output.js
@@ -44,7 +44,9 @@ const hiddenAtomics = /*#__PURE__*/ _atomics({
'xlDown',
],
defaultCondition: undefined,
- multiplier: undefined,
+ unitless: [],
+ multipliers: {},
+ inlineGetters: {},
});
const Hidden = React.forwardRef(function Hidden(
{ className, component = 'div', style, ...props },
diff --git a/packages/pigment-css-react/tests/generateAtomics.test.js b/packages/pigment-css-react/tests/generateAtomics.test.js
index 7fd9ae9d..e37dd1f6 100644
--- a/packages/pigment-css-react/tests/generateAtomics.test.js
+++ b/packages/pigment-css-react/tests/generateAtomics.test.js
@@ -47,7 +47,10 @@ const atomic = atomics({
// @ts-ignore This is not expected while calling the pre-transpiled generateAtomics
conditions: ['xs', 'sm', 'md', 'lg', 'xl'],
defaultCondition: 'xs',
- multiplier: '8px',
+ unitless: [],
+ multipliers: {
+ gap: '8px',
+ },
});
describe('generateAtomics', () => {
@@ -62,7 +65,7 @@ describe('generateAtomics', () => {
).to.deep.equal({
className: 'gap--Stack-gap-lg gap--Stack-gap-xs',
style: {
- '--Stack-gap': 'calc(2 * 8px)',
+ '--Stack-gap-xs': 'calc(2 * 8px)',
'--Stack-gap-lg': 'calc(1 * 8px)',
},
});
@@ -77,7 +80,7 @@ describe('generateAtomics', () => {
).to.deep.equal({
className: 'flex-direction-row-xs gap--Stack-gap-xs',
style: {
- '--Stack-gap': 'calc(1 * 8px)',
+ '--Stack-gap-xs': 'calc(1 * 8px)',
},
});
});
@@ -104,7 +107,7 @@ describe('generateAtomics', () => {
className:
'flex-direction-row-xs flex-direction-column-sm gap--Stack-gap-xs gap--Stack-gap-sm',
style: {
- '--Stack-gap': 'calc(1 * 8px)',
+ '--Stack-gap-xs': 'calc(1 * 8px)',
'--Stack-gap-sm': 'calc(2 * 8px)',
},
});
@@ -132,7 +135,7 @@ describe('generateAtomics', () => {
className:
'flex-direction-row-xs flex-direction-column-sm gap--Stack-gap-xs gap--Stack-gap-sm',
style: {
- '--Stack-gap': 'calc(1 * 8px)',
+ '--Stack-gap-xs': 'calc(1 * 8px)',
'--Stack-gap-sm': 'calc(2 * 8px)',
},
});
diff --git a/packages/pigment-css-react/tsup.config.ts b/packages/pigment-css-react/tsup.config.ts
index 1bab5658..897964a6 100644
--- a/packages/pigment-css-react/tsup.config.ts
+++ b/packages/pigment-css-react/tsup.config.ts
@@ -28,6 +28,7 @@ const BASE_FILES = [
'Stack.jsx',
'Container.jsx',
'Hidden.jsx',
+ 'Grid.jsx',
];
export default defineConfig([