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..b3419d9c --- /dev/null +++ b/apps/pigment-css-next-app/src/app/grid/demo3.tsx @@ -0,0 +1,43 @@ +'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..4ac3c87a --- /dev/null +++ b/apps/pigment-css-next-app/src/app/grid/page.tsx @@ -0,0 +1,272 @@ +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..ee70440f --- /dev/null +++ b/apps/pigment-css-vite-app/src/pages/grid.tsx @@ -0,0 +1,303 @@ +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 c0c2d053..7619f5d3 100644 --- a/packages/pigment-css-react/package.json +++ b/packages/pigment-css-react/package.json @@ -161,6 +161,15 @@ }, "require": "./build/Stack.js", "default": "./build/Stack.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..200b192d --- /dev/null +++ b/packages/pigment-css-react/src/Grid.jsx @@ -0,0 +1,226 @@ +/* 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 { gridAtomics } from './baseAtomics'; +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 GridComponent = styled('div')({ + 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 = { + 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..58c57166 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/baseAtomics.js b/packages/pigment-css-react/src/baseAtomics.js new file mode 100644 index 00000000..03995b50 --- /dev/null +++ b/packages/pigment-css-react/src/baseAtomics.js @@ -0,0 +1,121 @@ +import { generateAtomics } from './generateAtomics'; + +export const stackAtomics = generateAtomics(({ theme }) => ({ + conditions: Object.keys(theme.breakpoints.values).reduce((acc, breakpoint) => { + acc[breakpoint] = `@media (min-width: ${theme.breakpoints.values[breakpoint]}${ + theme.breakpoints.unit ?? 'px' + })`; + return acc; + }, {}), + defaultCondition: theme.breakpoints?.keys?.[0] ?? 'xs', + properties: { + display: ['flex', 'inline-flex'], + flexDirection: ['column', 'column-reverse', 'row', 'row-reverse'], + justifyContent: [ + 'end', + 'start', + 'flex-end', + 'flex-start', + 'center', + 'space-between', + 'space-around', + 'space-evenly', + ], + alignItems: [ + 'center', + 'end', + 'flex-end', + 'flex-start', + 'self-end', + 'self-start', + 'start', + 'baseline', + 'normal', + 'stretch', + ], + gap: ['--Stack-gap'], + }, + shorthands: { + direction: ['flexDirection'], + spacing: ['gap'], + }, + multipliers: { + gap: 8, + }, +})); + +export const gridAtomics = generateAtomics(({ theme }) => ({ + conditions: Object.keys(theme.breakpoints.values).reduce((acc, breakpoint) => { + acc[breakpoint] = `@media (min-width: ${theme.breakpoints.values[breakpoint]}${ + theme.breakpoints.unit ?? 'px' + })`; + return acc; + }, {}), + defaultCondition: theme.breakpoints?.keys?.[0] ?? 'xs', + 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'], + }, + shorthands: { + direction: ['flexDirection'], + }, + 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 '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-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 '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))'; + }, + }, +})); diff --git a/packages/pigment-css-react/src/generateAtomics.js b/packages/pigment-css-react/src/generateAtomics.js index 7b0c2fdc..f9433768 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 {string} 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,34 +51,47 @@ 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(styleClasses[value][breakpoint]); } } if (typeof propertyValue === 'string' || typeof propertyValue === 'number') { - 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/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/generateAtomics.test.js b/packages/pigment-css-react/tests/generateAtomics.test.js index 940f108f..7d752b35 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 57dfbe01..e2b94548 100644 --- a/packages/pigment-css-react/tsup.config.ts +++ b/packages/pigment-css-react/tsup.config.ts @@ -20,7 +20,7 @@ const baseConfig: Options = { external, }; -const BASE_FILES = ['index.ts', 'theme.ts', 'Box.jsx', 'RtlProvider.tsx', 'Stack.jsx']; +const BASE_FILES = ['index.ts', 'theme.ts', 'Box.jsx', 'RtlProvider.tsx', 'Stack.jsx', 'Grid.jsx']; export default defineConfig([ {