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([