From 06f16923bdc29affd101334a365441e1408fa7b8 Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Fri, 7 Jun 2024 16:16:31 -0400 Subject: [PATCH 01/14] Grid init --- apps/pigment-css-vite-app/src/pages/grid.tsx | 50 +++++ packages/pigment-css-react/package.json | 9 + packages/pigment-css-react/src/Grid.d.ts | 20 ++ packages/pigment-css-react/src/Grid.jsx | 198 ++++++++++++++++++ packages/pigment-css-react/src/baseAtomics.js | 95 +++++++++ .../pigment-css-react/src/generateAtomics.js | 20 +- .../src/utils/convertAtomicsToCss.ts | 12 +- .../tests/generateAtomics.test.js | 5 +- packages/pigment-css-react/tsup.config.ts | 2 +- 9 files changed, 399 insertions(+), 12 deletions(-) create mode 100644 apps/pigment-css-vite-app/src/pages/grid.tsx create mode 100644 packages/pigment-css-react/src/Grid.d.ts create mode 100644 packages/pigment-css-react/src/Grid.jsx create mode 100644 packages/pigment-css-react/src/baseAtomics.js 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..caa557fa --- /dev/null +++ b/apps/pigment-css-vite-app/src/pages/grid.tsx @@ -0,0 +1,50 @@ +import * as React from 'react'; +import Grid from '@pigment-css/react/Grid'; +import { styled } from '@pigment-css/react'; + +const Card = styled.div` + transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + border-radius: 4px; + box-shadow: + rgba(0, 0, 0, 0.2) 0px 2px 1px -1px, + rgba(0, 0, 0, 0.14) 0px 1px 1px 0px, + rgba(0, 0, 0, 0.12) 0px 1px 3px 0px; + background-image: linear-gradient(rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.05)); + padding: 8px 16px; + font-family: Roboto, Helvetica, Arial, sans-serif; + font-weight: 400; + font-size: 0.875rem; + line-height: 1.43; + letter-spacing: 0.01071em; + background-color: rgb(26, 32, 39); + width: 100%; + text-wrap: nowrap; + color: white; +`; + +const items = [ + { id: '1', size: 1, offset: 0}, + { id: '2', size: 1, offset: 0}, + { id: '3', size: 1, offset: 0}, + { id: '4', size: 1, offset: 0}, + { id: '5', size: 1, offset: 0}, + { id: '6', size: 1, offset: 0}, +] + +export default function InteractiveGrid() { + + return ( + + {items.map(({ id, size, offset}) => ( + Item {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..ee6e31d5 --- /dev/null +++ b/packages/pigment-css-react/src/Grid.d.ts @@ -0,0 +1,20 @@ +import * as CSS from 'csstype'; + +import { Breakpoint } from './base'; +import { PolymorphicComponent } from './Box'; + +type CssProperty = T | Array | Partial>; + +type GridBaseProps = { + display?: CssProperty<'flex' | 'inline-flex'>; + spacing?: CssProperty; + direction?: CssProperty; + justifyContent?: CssProperty; + alignItems?: CssProperty; + divider?: React.ReactNode; + className?: string; +}; + +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..9e60dab9 --- /dev/null +++ b/packages/pigment-css-react/src/Grid.jsx @@ -0,0 +1,198 @@ +/* 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'; + + +const itemStyle = { + width: 'calc(100% * var(--Column-span) / var(--Column-count) - (var(--Column-count) - var(--Column-span)) * var(--Column-gap) / var(--Column-count))', + marginLeft: 'calc(100% * var(--Item-offset) / var(--Column-count) + var(--Column-gap) * var(--Item-offset) / var(--Column-count))' +} + +const containerStyle = { + gap: 'var(--Row-gap) var(--Column-gap)', +} + +const Grid = React.forwardRef(function Grid( + { + children, + spacing = 0, + columnSpacing, + rowSpacing, + style, + className, + display = 'flex', + component = 'div', + direction = 'column', + flexWrap = 'wrap', + columns = 12, + container = false, + size, + offset, + alignItems, + justifyContent, + ...rest + }, + ref, +) { + const GridAtomicsObj = { + display, + direction, + flexWrap, + }; + if (alignItems) { + GridAtomicsObj.alignItems = alignItems; + } + if (justifyContent) { + GridAtomicsObj.justifyContent = justifyContent; + } + if (container) { + GridAtomicsObj['--Column-count'] = columns; + GridAtomicsObj['--Column-gap'] = spacing; + GridAtomicsObj['--Row-gap'] = spacing; + + if (columnSpacing) { + GridAtomicsObj['--Column-gap'] = columnSpacing; + } + + if (rowSpacing) { + GridAtomicsObj['--Row-gap'] = rowSpacing; + } + } + if (size) { + GridAtomicsObj['--Column-span'] = size; + } + if (offset) { + GridAtomicsObj['--Item-offset'] = offset; + } + const GridClasses = gridAtomics(GridAtomicsObj); + const Component = component; + return ( + + {children} + + ); +}); + +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`. │ + // └─────────────────────────────────────────────────────────────────────┘ + /** + * @ignore + */ + alignItems: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ + PropTypes.oneOf([ + 'center', + 'end', + 'flex-end', + 'flex-start', + 'self-end', + 'self-start', + 'start', + 'baseline', + 'normal', + 'stretch', + ]), + PropTypes.arrayOf( + PropTypes.oneOf([ + 'center', + 'end', + 'flex-end', + 'flex-start', + 'self-end', + 'self-start', + 'start', + 'baseline', + 'normal', + 'stretch', + ]), + ), + PropTypes.object, + ]), + /** + * The content of the component. + */ + children: PropTypes.node, + /** + * @ignore + */ + className: PropTypes.string, + /** + * The component used for the root node. + * Either a string to use a HTML element or a component. + */ + component: PropTypes.elementType, + /** + * @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 + */ + display: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ + PropTypes.oneOf(['flex', 'inline-flex']), + PropTypes.arrayOf(PropTypes.oneOf(['flex', 'inline-flex']).isRequired), + PropTypes.object, + ]), + /** + * @ignore + */ + divider: PropTypes.node, + /** + * @ignore + */ + justifyContent: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ + PropTypes.oneOf([ + 'end', + 'start', + 'flex-end', + 'flex-start', + 'center', + 'space-between', + 'space-around', + 'space-evenly', + ]), + PropTypes.arrayOf( + PropTypes.oneOf([ + 'end', + 'start', + 'flex-end', + 'flex-start', + 'center', + 'space-between', + 'space-around', + 'space-evenly', + ]), + ), + 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, + ]), + }) + : void 0; + +Grid.displayName = 'Grid'; + +export default Grid; diff --git a/packages/pigment-css-react/src/baseAtomics.js b/packages/pigment-css-react/src/baseAtomics.js new file mode 100644 index 00000000..4d98e9ad --- /dev/null +++ b/packages/pigment-css-react/src/baseAtomics.js @@ -0,0 +1,95 @@ +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: { + display: ['flex', 'inline-flex'], + flexDirection: ['column', 'column-reverse', 'row', 'row-reverse'], + flexWrap: ['wrap', 'nowrap', 'wrap-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', + ], + '--Column-count': ['--Column-count'], + '--Column-span': ['--Column-span'], + '--Column-gap': ['--Column-gap'], + '--Row-gap': ['--Row-gap'], + '--Item-offset': ['--Item-offset'] + }, + shorthands: { + direction: ['flexDirection'], + }, + unitless: ['--Column-count', '--Column-span', '--Item-offset'], + multipliers: { + '--Column-gap': 8, + '--Row-gap': 8, + }, +})); diff --git a/packages/pigment-css-react/src/generateAtomics.js b/packages/pigment-css-react/src/generateAtomics.js index 7b0c2fdc..0ba18255 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,21 @@ export function generateAtomics() { * * @param {RuntimeConfig} runtimeConfig */ -export function atomics({ styles, shorthands, conditions, defaultCondition, multiplier }) { +export function atomics({ + styles, + shorthands, + conditions, + defaultCondition, + unitless, + multipliers = {}, +}) { function addStyles(cssProperty, propertyValue, classes, inlineStyle) { const styleClasses = styles[cssProperty]; if (!styleClasses) { return; } - function handlePrimitive(value, breakpoint = defaultCondition) { + function handlePrimitive(value, multiplier = 1, breakpoint = defaultCondition) { if (!(value in styleClasses)) { const keys = Object.keys(styleClasses); if (keys.length !== 1) { @@ -48,7 +56,7 @@ export function atomics({ styles, shorthands, conditions, defaultCondition, mult } if (typeof propertyValue === 'string' || typeof propertyValue === 'number') { - handlePrimitive(propertyValue); + handlePrimitive(propertyValue, multipliers[cssProperty]); } else if (Array.isArray(propertyValue)) { propertyValue.forEach((value, index) => { if (value) { @@ -56,7 +64,7 @@ export function atomics({ styles, shorthands, conditions, defaultCondition, mult if (!breakpoint) { return; } - handlePrimitive(value, conditions[index]); + handlePrimitive(value, multipliers[cssProperty], conditions[index]); } }); } else if (propertyValue) { @@ -64,7 +72,7 @@ export function atomics({ styles, shorthands, conditions, defaultCondition, mult if (propertyValue[condition]) { const propertyClasses = styleClasses[propertyValue[condition]]; if (!propertyClasses) { - handlePrimitive(propertyValue[condition], condition); + handlePrimitive(propertyValue[condition], multipliers[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..137051ba 100644 --- a/packages/pigment-css-react/src/utils/convertAtomicsToCss.ts +++ b/packages/pigment-css-react/src/utils/convertAtomicsToCss.ts @@ -7,7 +7,8 @@ export type Atomics = { [key: string]: string[]; }; shorthands: Record; - multiplier?: string; + unitless: string[]; + multipliers?: Record; }; export type RuntimeConfig = { @@ -15,7 +16,8 @@ export type RuntimeConfig = { styles: Record>>; shorthands: Atomics['shorthands']; defaultCondition: string; - multiplier?: string; + unitless: string[]; + multipliers?: Record; }; function getClassName(...items: string[]) { @@ -28,7 +30,8 @@ export function convertAtomicsToCss( defaultCondition, properties, shorthands = {}, - multiplier = undefined, + unitless = [], + multipliers = {}, }: Atomics, mainClassName: string, isGlobal = false, @@ -40,7 +43,8 @@ export function convertAtomicsToCss( shorthands, conditions: Object.keys(conditions), defaultCondition, - multiplier, + unitless, + multipliers, }; let count = 1; function getCount() { diff --git a/packages/pigment-css-react/tests/generateAtomics.test.js b/packages/pigment-css-react/tests/generateAtomics.test.js index 940f108f..e602801c 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', () => { 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([ { From dc8759e135714c25d9a8709dc00df61caacd9cac Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Fri, 7 Jun 2024 17:43:49 -0400 Subject: [PATCH 02/14] Add row direction --- packages/pigment-css-react/src/Grid.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pigment-css-react/src/Grid.jsx b/packages/pigment-css-react/src/Grid.jsx index 9e60dab9..5cba90ca 100644 --- a/packages/pigment-css-react/src/Grid.jsx +++ b/packages/pigment-css-react/src/Grid.jsx @@ -26,7 +26,7 @@ const Grid = React.forwardRef(function Grid( className, display = 'flex', component = 'div', - direction = 'column', + direction = 'row', flexWrap = 'wrap', columns = 12, container = false, From 51dc95d6e373003b5a76dc442356fbbb95d19887 Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Mon, 10 Jun 2024 13:39:24 -0400 Subject: [PATCH 03/14] Implement shared styles through styled --- packages/pigment-css-react/src/Grid.jsx | 39 ++++++++++++++++--------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/packages/pigment-css-react/src/Grid.jsx b/packages/pigment-css-react/src/Grid.jsx index 5cba90ca..0ad86d42 100644 --- a/packages/pigment-css-react/src/Grid.jsx +++ b/packages/pigment-css-react/src/Grid.jsx @@ -5,16 +5,25 @@ import PropTypes from 'prop-types'; import * as React from 'react'; import { gridAtomics } from './baseAtomics'; +import styled from './styled'; - -const itemStyle = { - width: 'calc(100% * var(--Column-span) / var(--Column-count) - (var(--Column-count) - var(--Column-span)) * var(--Column-gap) / var(--Column-count))', - marginLeft: 'calc(100% * var(--Item-offset) / var(--Column-count) + var(--Column-gap) * var(--Item-offset) / var(--Column-count))' -} - -const containerStyle = { - gap: 'var(--Row-gap) var(--Column-gap)', -} +const GridComponent = styled('div')({ + variants: [ + { + props: { container: true }, + style: { + gap: 'var(--Row-gap) var(--Column-gap)', + } + }, + { + props: { container: false }, + style: { + width: 'calc(100% * var(--Column-span) / var(--Column-count) - (var(--Column-count) - var(--Column-span)) * var(--Column-gap) / var(--Column-count))', + marginLeft: 'calc(100% * var(--Item-offset) / var(--Column-count) + var(--Column-gap) * var(--Item-offset) / var(--Column-count))' + } + } + ] +}) const Grid = React.forwardRef(function Grid( { @@ -68,17 +77,21 @@ const Grid = React.forwardRef(function Grid( if (offset) { GridAtomicsObj['--Item-offset'] = offset; } + + const ownerState = { container }; + const GridClasses = gridAtomics(GridAtomicsObj); - const Component = component; return ( - {children} - + ); }); From 14f5bf38371ae19e37edff0461d4213823ec0ce5 Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Tue, 11 Jun 2024 16:39:01 -0400 Subject: [PATCH 04/14] Support keywords in size and offset props --- apps/pigment-css-vite-app/src/pages/grid.tsx | 40 +++++----------- packages/pigment-css-react/src/Grid.jsx | 19 ++++---- packages/pigment-css-react/src/baseAtomics.js | 48 ++++++++++++++++++- .../pigment-css-react/src/generateAtomics.js | 30 ++++++++++-- .../src/utils/convertAtomicsToCss.ts | 4 ++ 5 files changed, 98 insertions(+), 43 deletions(-) diff --git a/apps/pigment-css-vite-app/src/pages/grid.tsx b/apps/pigment-css-vite-app/src/pages/grid.tsx index caa557fa..e0ec1d75 100644 --- a/apps/pigment-css-vite-app/src/pages/grid.tsx +++ b/apps/pigment-css-vite-app/src/pages/grid.tsx @@ -3,48 +3,32 @@ import Grid from '@pigment-css/react/Grid'; import { styled } from '@pigment-css/react'; const Card = styled.div` - transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + background-color: #fff; + border: 1px solid #ced7e0; + padding: 8px; border-radius: 4px; - box-shadow: - rgba(0, 0, 0, 0.2) 0px 2px 1px -1px, - rgba(0, 0, 0, 0.14) 0px 1px 1px 0px, - rgba(0, 0, 0, 0.12) 0px 1px 3px 0px; - background-image: linear-gradient(rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.05)); - padding: 8px 16px; - font-family: Roboto, Helvetica, Arial, sans-serif; - font-weight: 400; - font-size: 0.875rem; - line-height: 1.43; - letter-spacing: 0.01071em; - background-color: rgb(26, 32, 39); - width: 100%; - text-wrap: nowrap; - color: white; + text-align: center; `; const items = [ - { id: '1', size: 1, offset: 0}, - { id: '2', size: 1, offset: 0}, - { id: '3', size: 1, offset: 0}, - { id: '4', size: 1, offset: 0}, - { id: '5', size: 1, offset: 0}, - { id: '6', size: 1, offset: 0}, + { id: '1', size: 2}, + { id: '2', size: 2}, ] export default function InteractiveGrid() { return ( +
- {items.map(({ id, size, offset}) => ( - Item {id} + {items.map(({ id, size, offset, extraText}) => ( + Item {id}{extraText} ))} +
); } diff --git a/packages/pigment-css-react/src/Grid.jsx b/packages/pigment-css-react/src/Grid.jsx index 0ad86d42..c8ed9cd5 100644 --- a/packages/pigment-css-react/src/Grid.jsx +++ b/packages/pigment-css-react/src/Grid.jsx @@ -8,20 +8,18 @@ import { gridAtomics } from './baseAtomics'; import styled from './styled'; const GridComponent = styled('div')({ + width: 'var(--Column-width)', + maxWidth: 'var(--Column-max-width)', + flex: 'var(--Column-flex)', + marginLeft: 'var(--Item-margin-left)', variants: [ { props: { container: true }, style: { + display: 'flex', gap: 'var(--Row-gap) var(--Column-gap)', } }, - { - props: { container: false }, - style: { - width: 'calc(100% * var(--Column-span) / var(--Column-count) - (var(--Column-count) - var(--Column-span)) * var(--Column-gap) / var(--Column-count))', - marginLeft: 'calc(100% * var(--Item-offset) / var(--Column-count) + var(--Column-gap) * var(--Item-offset) / var(--Column-count))' - } - } ] }) @@ -33,7 +31,6 @@ const Grid = React.forwardRef(function Grid( rowSpacing, style, className, - display = 'flex', component = 'div', direction = 'row', flexWrap = 'wrap', @@ -48,7 +45,6 @@ const Grid = React.forwardRef(function Grid( ref, ) { const GridAtomicsObj = { - display, direction, flexWrap, }; @@ -73,9 +69,14 @@ const Grid = React.forwardRef(function Grid( } if (size) { GridAtomicsObj['--Column-span'] = size; + GridAtomicsObj['--Column-width'] = size; + GridAtomicsObj['--Column-max-width'] = size; + GridAtomicsObj['--Column-flex'] = size; + } if (offset) { GridAtomicsObj['--Item-offset'] = offset; + GridAtomicsObj['--Item-margin-left'] = offset; } const ownerState = { container }; diff --git a/packages/pigment-css-react/src/baseAtomics.js b/packages/pigment-css-react/src/baseAtomics.js index 4d98e9ad..7a05e0ce 100644 --- a/packages/pigment-css-react/src/baseAtomics.js +++ b/packages/pigment-css-react/src/baseAtomics.js @@ -78,11 +78,15 @@ export const gridAtomics = generateAtomics(({ theme }) => ({ 'normal', 'stretch', ], + '--Column-width': ['--Column-width'], + '--Column-max-width': ['--Column-max-width'], + '--Column-flex': ['--Column-flex'], '--Column-count': ['--Column-count'], '--Column-span': ['--Column-span'], '--Column-gap': ['--Column-gap'], '--Row-gap': ['--Row-gap'], - '--Item-offset': ['--Item-offset'] + '--Item-offset': ['--Item-offset'], + '--Item-margin-left': ['--Item-margin-left'], }, shorthands: { direction: ['flexDirection'], @@ -92,4 +96,46 @@ export const gridAtomics = generateAtomics(({ theme }) => ({ '--Column-gap': 8, '--Row-gap': 8, }, + inlineGetters: { + '--Column-width': (value) => { + if (value === 'grow') { + return 'unset'; + } + + if (value === 'auto') { + return 'auto'; + } + + return 'calc(100% * var(--Column-span) / var(--Column-count) - (var(--Column-count) - var(--Column-span)) * var(--Column-gap) / var(--Column-count))'; + }, + '--Column-max-width': (value) => { + if (value === 'grow') { + return '100%'; + } + + if (value === 'auto') { + return 'none'; + } + + return 'unset'; + }, + '--Column-flex': (value) => { + if (value === 'grow') { + return '1 1 0'; + } + + if (value === 'auto') { + return '0 0 auto'; + } + + return '0 1 auto'; + }, + '--Item-margin-left': (value) => { + if (value === 'auto') { + return 'auto'; + } + + return 'calc(100% * var(--Item-offset) / var(--Column-count) + var(--Column-gap) * var(--Item-offset) / var(--Column-count))'; + }, + }, })); diff --git a/packages/pigment-css-react/src/generateAtomics.js b/packages/pigment-css-react/src/generateAtomics.js index 0ba18255..41284c45 100644 --- a/packages/pigment-css-react/src/generateAtomics.js +++ b/packages/pigment-css-react/src/generateAtomics.js @@ -6,6 +6,10 @@ export function generateAtomics() { ); } +function defaultInlineGetter(styleValue, cssProperty, unitless) { + return unitless.includes(cssProperty) ? styleValue : `${styleValue}px`; +} + /** * @typedef {Object} RuntimeConfig * @property {Object.>>} styles @@ -29,6 +33,7 @@ export function atomics({ defaultCondition, unitless, multipliers = {}, + inlineGetters = {}, }) { function addStyles(cssProperty, propertyValue, classes, inlineStyle) { const styleClasses = styles[cssProperty]; @@ -36,7 +41,12 @@ export function atomics({ return; } - function handlePrimitive(value, multiplier = 1, breakpoint = defaultCondition) { + function handlePrimitive( + value, + multiplier = 1, + inlineGetter = defaultInlineGetter, + breakpoint = defaultCondition, + ) { if (!(value in styleClasses)) { const keys = Object.keys(styleClasses); if (keys.length !== 1) { @@ -49,14 +59,14 @@ export function atomics({ } classes.push(styleClasses[key][breakpoint]); inlineStyle[`${key}${breakpoint === defaultCondition ? '' : `-${breakpoint}`}`] = - styleValue; + inlineGetter(styleValue, cssProperty, unitless); } else { classes.push(styleClasses[value][breakpoint]); } } if (typeof propertyValue === 'string' || typeof propertyValue === 'number') { - handlePrimitive(propertyValue, multipliers[cssProperty]); + handlePrimitive(propertyValue, multipliers[cssProperty], inlineGetters[cssProperty]); } else if (Array.isArray(propertyValue)) { propertyValue.forEach((value, index) => { if (value) { @@ -64,7 +74,12 @@ export function atomics({ if (!breakpoint) { return; } - handlePrimitive(value, multipliers[cssProperty], conditions[index]); + handlePrimitive( + value, + multipliers[cssProperty], + inlineGetters[cssProperty], + conditions[index], + ); } }); } else if (propertyValue) { @@ -72,7 +87,12 @@ export function atomics({ if (propertyValue[condition]) { const propertyClasses = styleClasses[propertyValue[condition]]; if (!propertyClasses) { - handlePrimitive(propertyValue[condition], multipliers[cssProperty], 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 137051ba..3fb1e8fc 100644 --- a/packages/pigment-css-react/src/utils/convertAtomicsToCss.ts +++ b/packages/pigment-css-react/src/utils/convertAtomicsToCss.ts @@ -9,6 +9,7 @@ export type Atomics = { shorthands: Record; unitless: string[]; multipliers?: Record; + inlineGetters: Record string>; }; export type RuntimeConfig = { @@ -18,6 +19,7 @@ export type RuntimeConfig = { defaultCondition: string; unitless: string[]; multipliers?: Record; + inlineGetters: Record string>; }; function getClassName(...items: string[]) { @@ -32,6 +34,7 @@ export function convertAtomicsToCss( shorthands = {}, unitless = [], multipliers = {}, + inlineGetters = {}, }: Atomics, mainClassName: string, isGlobal = false, @@ -45,6 +48,7 @@ export function convertAtomicsToCss( defaultCondition, unitless, multipliers, + inlineGetters, }; let count = 1; function getCount() { From b98980a3debd78903209f9b496c8c8c82609f285 Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Thu, 13 Jun 2024 16:56:01 -0400 Subject: [PATCH 05/14] Support nested grids and refactor code --- apps/pigment-css-vite-app/src/pages/grid.tsx | 301 +++++++++++++++++- packages/pigment-css-react/src/Grid.d.ts | 14 +- packages/pigment-css-react/src/Grid.jsx | 204 ++++++------ packages/pigment-css-react/src/baseAtomics.js | 64 ++-- 4 files changed, 424 insertions(+), 159 deletions(-) diff --git a/apps/pigment-css-vite-app/src/pages/grid.tsx b/apps/pigment-css-vite-app/src/pages/grid.tsx index e0ec1d75..ee70440f 100644 --- a/apps/pigment-css-vite-app/src/pages/grid.tsx +++ b/apps/pigment-css-vite-app/src/pages/grid.tsx @@ -1,8 +1,9 @@ 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 Card = styled.div` +const Item = styled.div` background-color: #fff; border: 1px solid #ced7e0; padding: 8px; @@ -10,25 +11,293 @@ const Card = styled.div` text-align: center; `; -const items = [ - { id: '1', size: 2}, - { id: '2', size: 2}, -] +function GridDemo1() { + return ( + + + size=8 + + + size=4 + + + size=4 + + + size=8 + + + ) +} -export default function InteractiveGrid() { +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 ( -
- - {items.map(({ id, size, offset, extraText}) => ( - Item {id}{extraText} +
+ + {[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/src/Grid.d.ts b/packages/pigment-css-react/src/Grid.d.ts index ee6e31d5..262d8c85 100644 --- a/packages/pigment-css-react/src/Grid.d.ts +++ b/packages/pigment-css-react/src/Grid.d.ts @@ -6,13 +6,15 @@ import { PolymorphicComponent } from './Box'; type CssProperty = T | Array | Partial>; type GridBaseProps = { - display?: CssProperty<'flex' | 'inline-flex'>; - spacing?: CssProperty; - direction?: CssProperty; - justifyContent?: CssProperty; - alignItems?: CssProperty; - divider?: React.ReactNode; className?: string; + columns?: CssProperty; + columnSpacing?: CssProperty; + container?: boolean; + direction?: CssProperty; + offset?: CssProperty; + rowSpacing?: CssProperty; + size?: CssProperty; + spacing?: CssProperty; }; declare const Grid: PolymorphicComponent; diff --git a/packages/pigment-css-react/src/Grid.jsx b/packages/pigment-css-react/src/Grid.jsx index c8ed9cd5..200b192d 100644 --- a/packages/pigment-css-react/src/Grid.jsx +++ b/packages/pigment-css-react/src/Grid.jsx @@ -7,79 +7,104 @@ 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')({ - width: 'var(--Column-width)', - maxWidth: 'var(--Column-max-width)', - flex: 'var(--Column-flex)', - marginLeft: 'var(--Item-margin-left)', variants: [ { props: { container: true }, style: { display: 'flex', - gap: 'var(--Row-gap) var(--Column-gap)', + 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, - spacing = 0, + columns, + spacing, columnSpacing, rowSpacing, + direction = 'row', style, className, component = 'div', - direction = 'row', - flexWrap = 'wrap', - columns = 12, container = false, size, offset, - alignItems, - justifyContent, + // 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, - flexWrap, }; - if (alignItems) { - GridAtomicsObj.alignItems = alignItems; + + if (unstable_parent_columns !== undefined) { + GridAtomicsObj['--Grid-parent-column-count'] = unstable_parent_columns; } - if (justifyContent) { - GridAtomicsObj.justifyContent = justifyContent; + + if (unstable_parent_column_spacing !== undefined) { + GridAtomicsObj['--Grid-parent-column-spacing'] = unstable_parent_column_spacing; } - if (container) { - GridAtomicsObj['--Column-count'] = columns; - GridAtomicsObj['--Column-gap'] = spacing; - GridAtomicsObj['--Row-gap'] = spacing; - if (columnSpacing) { - GridAtomicsObj['--Column-gap'] = columnSpacing; - } + if (unstable_parent_row_spacing !== undefined) { + GridAtomicsObj['--Grid-parent-row-spacing'] = unstable_parent_row_spacing; + } - if (rowSpacing) { - GridAtomicsObj['--Row-gap'] = rowSpacing; - } + if (container) { + GridAtomicsObj['--Grid-self-column-spacing'] = selfColumnSpacing; + GridAtomicsObj['--Grid-self-row-spacing'] = selfRowSpacing; } + if (size) { - GridAtomicsObj['--Column-span'] = size; - GridAtomicsObj['--Column-width'] = size; - GridAtomicsObj['--Column-max-width'] = size; - GridAtomicsObj['--Column-flex'] = 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['--Item-offset'] = offset; - GridAtomicsObj['--Item-margin-left'] = offset; + GridAtomicsObj['--Grid-self-offset'] = offset; + GridAtomicsObj['--Grid-self-margin-left'] = offset; } - const ownerState = { container }; + const ownerState = { container, size, offset }; const GridClasses = gridAtomics(GridAtomicsObj); return ( @@ -91,49 +116,28 @@ const Grid = React.forwardRef(function Grid( {...rest} ownerState={ownerState} > - {children} + {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 */ = { + && (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`. │ // └─────────────────────────────────────────────────────────────────────┘ - /** - * @ignore - */ - alignItems: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ - PropTypes.oneOf([ - 'center', - 'end', - 'flex-end', - 'flex-start', - 'self-end', - 'self-start', - 'start', - 'baseline', - 'normal', - 'stretch', - ]), - PropTypes.arrayOf( - PropTypes.oneOf([ - 'center', - 'end', - 'flex-end', - 'flex-start', - 'self-end', - 'self-start', - 'start', - 'baseline', - 'normal', - 'stretch', - ]), - ), - PropTypes.object, - ]), /** * The content of the component. */ @@ -142,11 +146,32 @@ process.env.NODE_ENV !== 'production' * @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 */ @@ -158,41 +183,26 @@ process.env.NODE_ENV !== 'production' /** * @ignore */ - display: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ - PropTypes.oneOf(['flex', 'inline-flex']), - PropTypes.arrayOf(PropTypes.oneOf(['flex', 'inline-flex']).isRequired), + offset: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ + PropTypes.arrayOf(PropTypes.number), + PropTypes.number, PropTypes.object, ]), /** * @ignore */ - divider: PropTypes.node, + rowSpacing: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ + PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired), + PropTypes.number, + PropTypes.object, + PropTypes.string, + ]), /** * @ignore */ - justifyContent: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ - PropTypes.oneOf([ - 'end', - 'start', - 'flex-end', - 'flex-start', - 'center', - 'space-between', - 'space-around', - 'space-evenly', - ]), - PropTypes.arrayOf( - PropTypes.oneOf([ - 'end', - 'start', - 'flex-end', - 'flex-start', - 'center', - 'space-between', - 'space-around', - 'space-evenly', - ]), - ), + size: PropTypes /* @typescript-to-proptypes-ignore */.oneOfType([ + PropTypes.arrayOf(PropTypes.number), + PropTypes.number, PropTypes.object, ]), /** @@ -204,8 +214,12 @@ process.env.NODE_ENV !== 'production' PropTypes.object, PropTypes.string, ]), + /** + * @ignore + */ + style: PropTypes.object, + }) - : void 0; Grid.displayName = 'Grid'; diff --git a/packages/pigment-css-react/src/baseAtomics.js b/packages/pigment-css-react/src/baseAtomics.js index 7a05e0ce..9a2bd815 100644 --- a/packages/pigment-css-react/src/baseAtomics.js +++ b/packages/pigment-css-react/src/baseAtomics.js @@ -53,51 +53,31 @@ export const gridAtomics = generateAtomics(({ theme }) => ({ }, {}), defaultCondition: theme.breakpoints?.keys?.[0] ?? 'xs', properties: { - display: ['flex', 'inline-flex'], flexDirection: ['column', 'column-reverse', 'row', 'row-reverse'], - flexWrap: ['wrap', 'nowrap', 'wrap-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', - ], - '--Column-width': ['--Column-width'], - '--Column-max-width': ['--Column-max-width'], - '--Column-flex': ['--Column-flex'], - '--Column-count': ['--Column-count'], - '--Column-span': ['--Column-span'], - '--Column-gap': ['--Column-gap'], - '--Row-gap': ['--Row-gap'], - '--Item-offset': ['--Item-offset'], - '--Item-margin-left': ['--Item-margin-left'], + '--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: ['--Column-count', '--Column-span', '--Item-offset'], + unitless: ['--Grid-parent-column-count', '--Grid-self-column-span', '--Grid-self-offset'], multipliers: { - '--Column-gap': 8, - '--Row-gap': 8, + '--Grid-parent-column-spacing': 8, + '--Grid-parent-row-spacing': 8, + '--Grid-self-column-spacing': 8, + '--Grid-self-row-spacing': 8, }, inlineGetters: { - '--Column-width': (value) => { + '--Grid-self-width': (value) => { if (value === 'grow') { return 'unset'; } @@ -106,9 +86,9 @@ export const gridAtomics = generateAtomics(({ theme }) => ({ return 'auto'; } - return 'calc(100% * var(--Column-span) / var(--Column-count) - (var(--Column-count) - var(--Column-span)) * var(--Column-gap) / var(--Column-count))'; + 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))'; }, - '--Column-max-width': (value) => { + '--Grid-self-max-width': (value) => { if (value === 'grow') { return '100%'; } @@ -119,7 +99,7 @@ export const gridAtomics = generateAtomics(({ theme }) => ({ return 'unset'; }, - '--Column-flex': (value) => { + '--Grid-self-flex': (value) => { if (value === 'grow') { return '1 1 0'; } @@ -130,12 +110,12 @@ export const gridAtomics = generateAtomics(({ theme }) => ({ return '0 1 auto'; }, - '--Item-margin-left': (value) => { + '--Grid-self-margin-left': (value) => { if (value === 'auto') { return 'auto'; } - return 'calc(100% * var(--Item-offset) / var(--Column-count) + var(--Column-gap) * var(--Item-offset) / var(--Column-count))'; + 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))'; }, }, })); From a07098ac303806daf031c5eb699ac7e9cd34f421 Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Mon, 17 Jun 2024 11:25:36 -0400 Subject: [PATCH 06/14] Use RSC in grid demos --- .../src/app/grid/demo3.tsx | 43 +++ .../src/app/grid/page.tsx | 272 ++++++++++++++++++ 2 files changed, 315 insertions(+) create mode 100644 apps/pigment-css-next-app/src/app/grid/demo3.tsx create mode 100644 apps/pigment-css-next-app/src/app/grid/page.tsx 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}

    + +
    + ); + })} +
    + ); +} From ec26cbb0fed52fda3104838d893d441aea4b724c Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Mon, 17 Jun 2024 14:21:23 -0400 Subject: [PATCH 07/14] Adjust to atomics changes --- packages/pigment-css-react/src/Stack.jsx | 4 +++- packages/pigment-css-react/src/baseAtomics.js | 8 +++---- .../pigment-css-react/src/generateAtomics.js | 23 +++++++++---------- .../src/utils/convertAtomicsToCss.ts | 4 +--- .../tests/generateAtomics.test.js | 8 +++---- 5 files changed, 23 insertions(+), 24 deletions(-) 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 index 9a2bd815..03995b50 100644 --- a/packages/pigment-css-react/src/baseAtomics.js +++ b/packages/pigment-css-react/src/baseAtomics.js @@ -71,10 +71,10 @@ export const gridAtomics = generateAtomics(({ theme }) => ({ }, unitless: ['--Grid-parent-column-count', '--Grid-self-column-span', '--Grid-self-offset'], multipliers: { - '--Grid-parent-column-spacing': 8, - '--Grid-parent-row-spacing': 8, - '--Grid-self-column-spacing': 8, - '--Grid-self-row-spacing': 8, + '--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) => { diff --git a/packages/pigment-css-react/src/generateAtomics.js b/packages/pigment-css-react/src/generateAtomics.js index 41284c45..f9433768 100644 --- a/packages/pigment-css-react/src/generateAtomics.js +++ b/packages/pigment-css-react/src/generateAtomics.js @@ -6,10 +6,6 @@ export function generateAtomics() { ); } -function defaultInlineGetter(styleValue, cssProperty, unitless) { - return unitless.includes(cssProperty) ? styleValue : `${styleValue}px`; -} - /** * @typedef {Object} RuntimeConfig * @property {Object.>>} styles @@ -31,7 +27,7 @@ export function atomics({ shorthands, conditions, defaultCondition, - unitless, + unitless = [], multipliers = {}, inlineGetters = {}, }) { @@ -43,8 +39,8 @@ export function atomics({ function handlePrimitive( value, - multiplier = 1, - inlineGetter = defaultInlineGetter, + multiplier = undefined, + inlineGetter = undefined, breakpoint = defaultCondition, ) { if (!(value in styleClasses)) { @@ -55,11 +51,14 @@ export function atomics({ 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}`}`] = - inlineGetter(styleValue, cssProperty, unitless); + inlineStyle[`${key}-${breakpoint}`] = inlineGetter ? inlineGetter(styleValue) : styleValue; } else { classes.push(styleClasses[value][breakpoint]); } @@ -69,7 +68,7 @@ export function atomics({ 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; @@ -84,7 +83,7 @@ export function atomics({ }); } 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( diff --git a/packages/pigment-css-react/src/utils/convertAtomicsToCss.ts b/packages/pigment-css-react/src/utils/convertAtomicsToCss.ts index 3fb1e8fc..b398a5cd 100644 --- a/packages/pigment-css-react/src/utils/convertAtomicsToCss.ts +++ b/packages/pigment-css-react/src/utils/convertAtomicsToCss.ts @@ -66,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 e602801c..7d752b35 100644 --- a/packages/pigment-css-react/tests/generateAtomics.test.js +++ b/packages/pigment-css-react/tests/generateAtomics.test.js @@ -65,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)', }, }); @@ -80,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)', }, }); }); @@ -107,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)', }, }); @@ -135,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)', }, }); From 3a60d2d5a42799c8d1e99047281a3e5a9b68a4c5 Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Mon, 17 Jun 2024 14:58:07 -0400 Subject: [PATCH 08/14] Move gridAtomics to Grid file --- packages/pigment-css-react/src/Grid.jsx | 80 +++++++++++- packages/pigment-css-react/src/baseAtomics.js | 121 ------------------ .../pigment-css-react/src/generateAtomics.js | 2 +- 3 files changed, 80 insertions(+), 123 deletions(-) delete mode 100644 packages/pigment-css-react/src/baseAtomics.js diff --git a/packages/pigment-css-react/src/Grid.jsx b/packages/pigment-css-react/src/Grid.jsx index 200b192d..9158342b 100644 --- a/packages/pigment-css-react/src/Grid.jsx +++ b/packages/pigment-css-react/src/Grid.jsx @@ -4,7 +4,7 @@ import clsx from 'clsx'; import PropTypes from 'prop-types'; import * as React from 'react'; -import { gridAtomics } from './baseAtomics'; +import { generateAtomics } from './generateAtomics'; import styled from './styled'; function isGridComponent(element) { @@ -14,7 +14,85 @@ function isGridComponent(element) { return element.type.muiName === 'Grid' || element.type?._payload?.value?.muiName === 'Grid'; } +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 '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 }, diff --git a/packages/pigment-css-react/src/baseAtomics.js b/packages/pigment-css-react/src/baseAtomics.js deleted file mode 100644 index 03995b50..00000000 --- a/packages/pigment-css-react/src/baseAtomics.js +++ /dev/null @@ -1,121 +0,0 @@ -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 f9433768..d6678265 100644 --- a/packages/pigment-css-react/src/generateAtomics.js +++ b/packages/pigment-css-react/src/generateAtomics.js @@ -13,7 +13,7 @@ export function generateAtomics() { * @property {string[]} conditions * @property {string} defaultCondition * @property {string[]} unitless - * @property {string} multipliers + * @property {Object.} multipliers */ /** From 5c118ed09b014a3259948b38dd38d7e46593b141 Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Mon, 17 Jun 2024 15:47:47 -0400 Subject: [PATCH 09/14] prettier --- .../src/app/grid/demo3.tsx | 24 +- .../src/app/grid/page.tsx | 55 ++--- apps/pigment-css-vite-app/src/pages/grid.tsx | 79 +++---- packages/pigment-css-react/src/Grid.jsx | 211 +++++++++--------- packages/pigment-css-react/src/Stack.jsx | 2 +- 5 files changed, 182 insertions(+), 189 deletions(-) diff --git a/apps/pigment-css-next-app/src/app/grid/demo3.tsx b/apps/pigment-css-next-app/src/app/grid/demo3.tsx index b3419d9c..3fcf1662 100644 --- a/apps/pigment-css-next-app/src/app/grid/demo3.tsx +++ b/apps/pigment-css-next-app/src/app/grid/demo3.tsx @@ -16,28 +16,34 @@ export default function GridDemo3() { return (
    - {[0, 1, 2].map((value) => ( - + {[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 index 4ac3c87a..52c27519 100644 --- a/apps/pigment-css-next-app/src/app/grid/page.tsx +++ b/apps/pigment-css-next-app/src/app/grid/page.tsx @@ -27,7 +27,7 @@ function GridDemo1() { size=8 - ) + ); } function GridDemo2() { @@ -46,7 +46,7 @@ function GridDemo2() { xs=6 md=8 - ) + ); } function GridDemo4() { @@ -65,7 +65,7 @@ function GridDemo4() { 4 - ) + ); } function GridDemo5() { @@ -77,7 +77,7 @@ function GridDemo5() { ))} - ) + ); } function GridDemo6() { @@ -93,7 +93,7 @@ function GridDemo6() { grow - ) + ); } function GridDemo7() { @@ -109,7 +109,7 @@ function GridDemo7() { grow - ) + ); } function GridDemo8() { @@ -122,10 +122,7 @@ function GridDemo8() { - + Category A @@ -137,10 +134,7 @@ function GridDemo8() { - + Category B @@ -152,10 +146,7 @@ function GridDemo8() { - + Category C @@ -167,10 +158,7 @@ function GridDemo8() { - + Category D @@ -185,7 +173,7 @@ function GridDemo8() { size={12} container direction={{ xs: 'column', sm: 'row' }} - sx={{ fontSize: '12px', justifyContent: 'space-between', alignItems: 'center'}} + sx={{ fontSize: '12px', justifyContent: 'space-between', alignItems: 'center' }} > © Copyright @@ -204,20 +192,20 @@ function GridDemo8() { - ) + ); } function GridDemo9() { return ( - + size=8 - + size=8 - ) + ); } function GridDemo10() { @@ -226,17 +214,17 @@ function GridDemo10() { 1 - + 2 - + 3 4 - ) + ); } const demos = [ @@ -250,15 +238,14 @@ const demos = [ { id: '8', component: GridDemo8 }, { id: '9', component: GridDemo9 }, { id: '10', component: GridDemo10 }, -] +]; export default function InteractiveGrid() { - return ( -
    +
    Benchmark v5 Benchmark next - {demos.map(demo => { + {demos.map((demo) => { const Demo = demo.component; return (
    diff --git a/apps/pigment-css-vite-app/src/pages/grid.tsx b/apps/pigment-css-vite-app/src/pages/grid.tsx index ee70440f..1558e622 100644 --- a/apps/pigment-css-vite-app/src/pages/grid.tsx +++ b/apps/pigment-css-vite-app/src/pages/grid.tsx @@ -27,7 +27,7 @@ function GridDemo1() { size=8 - ) + ); } function GridDemo2() { @@ -46,7 +46,7 @@ function GridDemo2() { xs=6 md=8 - ) + ); } function GridDemo3() { @@ -54,30 +54,36 @@ function GridDemo3() { return (
    - {[0, 1, 2].map((value) => ( - + {[0, 1, 2].map((value) => ( + - - ))} + /> + + ))} - + Spacing: {[0, 0.5, 1, 2, 3, 4, 8, 12].map((value) => ( ))} - +
    - ) + ); } function GridDemo4() { @@ -96,7 +102,7 @@ function GridDemo4() { 4 - ) + ); } function GridDemo5() { @@ -108,7 +114,7 @@ function GridDemo5() { ))} - ) + ); } function GridDemo6() { @@ -124,7 +130,7 @@ function GridDemo6() { grow - ) + ); } function GridDemo7() { @@ -140,7 +146,7 @@ function GridDemo7() { grow - ) + ); } function GridDemo8() { @@ -153,10 +159,7 @@ function GridDemo8() { - + Category A @@ -168,10 +171,7 @@ function GridDemo8() { - + Category B @@ -183,10 +183,7 @@ function GridDemo8() { - + Category C @@ -198,10 +195,7 @@ function GridDemo8() { - + Category D @@ -216,7 +210,7 @@ function GridDemo8() { size={12} container direction={{ xs: 'column', sm: 'row' }} - sx={{ fontSize: '12px', justifyContent: 'space-between', alignItems: 'center'}} + sx={{ fontSize: '12px', justifyContent: 'space-between', alignItems: 'center' }} > © Copyright @@ -235,20 +229,20 @@ function GridDemo8() { - ) + ); } function GridDemo9() { return ( - + size=8 - + size=8 - ) + ); } function GridDemo10() { @@ -257,17 +251,17 @@ function GridDemo10() { 1 - + 2 - + 3 4 - ) + ); } const demos = [ @@ -281,15 +275,14 @@ const demos = [ { id: '8', component: GridDemo8 }, { id: '9', component: GridDemo9 }, { id: '10', component: GridDemo10 }, -] +]; export default function InteractiveGrid() { - return ( -
    +
    Benchmark v5 Benchmark next - {demos.map(demo => { + {demos.map((demo) => { const Demo = demo.component; return (
    diff --git a/packages/pigment-css-react/src/Grid.jsx b/packages/pigment-css-react/src/Grid.jsx index 9158342b..7fbefc4d 100644 --- a/packages/pigment-css-react/src/Grid.jsx +++ b/packages/pigment-css-react/src/Grid.jsx @@ -41,10 +41,18 @@ export const gridAtomics = generateAtomics(({ theme }) => ({ }, 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, + '--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) => { @@ -91,8 +99,10 @@ export const gridAtomics = generateAtomics(({ theme }) => ({ })); 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))', + '--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 }, @@ -100,7 +110,7 @@ const GridComponent = styled('div')({ display: 'flex', flexWrap: 'wrap', gap: 'var(--Grid-self-row-spacing) var(--Grid-self-column-spacing)', - } + }, }, { props: ({ size }) => size !== undefined, @@ -108,16 +118,16 @@ const GridComponent = styled('div')({ 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( { @@ -144,7 +154,6 @@ const Grid = React.forwardRef(function Grid( }, 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; @@ -175,7 +184,6 @@ const Grid = React.forwardRef(function Grid( GridAtomicsObj['--Grid-self-width'] = size; GridAtomicsObj['--Grid-self-max-width'] = size; GridAtomicsObj['--Grid-self-flex'] = size; - } if (offset) { GridAtomicsObj['--Grid-self-offset'] = offset; @@ -210,94 +218,93 @@ const Grid = React.forwardRef(function Grid( 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, - - }) +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'; diff --git a/packages/pigment-css-react/src/Stack.jsx b/packages/pigment-css-react/src/Stack.jsx index 58c57166..1545c214 100644 --- a/packages/pigment-css-react/src/Stack.jsx +++ b/packages/pigment-css-react/src/Stack.jsx @@ -24,7 +24,7 @@ const stackAtomics = generateAtomics(({ theme }) => { spacing: ['gap'], }, multipliers: { - gap: Array.isArray(theme.vars?.spacing) ? theme.vars.spacing[0] : theme.vars?.spacing + gap: Array.isArray(theme.vars?.spacing) ? theme.vars.spacing[0] : theme.vars?.spacing, }, }; }); From e5568d383d4b292809a57ea8878a7c0debda3866 Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Tue, 18 Jun 2024 09:46:29 -0400 Subject: [PATCH 10/14] Use proper casing in Grid component --- packages/pigment-css-react/src/Grid.jsx | 30 ++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/pigment-css-react/src/Grid.jsx b/packages/pigment-css-react/src/Grid.jsx index 7fbefc4d..dc284811 100644 --- a/packages/pigment-css-react/src/Grid.jsx +++ b/packages/pigment-css-react/src/Grid.jsx @@ -158,47 +158,47 @@ const Grid = React.forwardRef(function Grid( const selfColumnSpacing = columnSpacing ?? spacing ?? unstable_parent_column_spacing ?? 0; const selfRowSpacing = rowSpacing ?? spacing ?? unstable_parent_row_spacing ?? 0; - const GridAtomicsObj = { + const gridAtomicsObj = { direction, }; if (unstable_parent_columns !== undefined) { - GridAtomicsObj['--Grid-parent-column-count'] = unstable_parent_columns; + gridAtomicsObj['--Grid-parent-column-count'] = unstable_parent_columns; } if (unstable_parent_column_spacing !== undefined) { - GridAtomicsObj['--Grid-parent-column-spacing'] = unstable_parent_column_spacing; + gridAtomicsObj['--Grid-parent-column-spacing'] = unstable_parent_column_spacing; } if (unstable_parent_row_spacing !== undefined) { - GridAtomicsObj['--Grid-parent-row-spacing'] = unstable_parent_row_spacing; + gridAtomicsObj['--Grid-parent-row-spacing'] = unstable_parent_row_spacing; } if (container) { - GridAtomicsObj['--Grid-self-column-spacing'] = selfColumnSpacing; - GridAtomicsObj['--Grid-self-row-spacing'] = selfRowSpacing; + 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; + 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; + gridAtomicsObj['--Grid-self-offset'] = offset; + gridAtomicsObj['--Grid-self-margin-left'] = offset; } const ownerState = { container, size, offset }; - const GridClasses = gridAtomics(GridAtomicsObj); + const gridClasses = gridAtomics(gridAtomicsObj); return ( From daa5ae3b29475ca1efae478d20aedf0932a784d0 Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Tue, 18 Jun 2024 09:58:54 -0400 Subject: [PATCH 11/14] Improve gridAtomics --- packages/pigment-css-react/src/Grid.jsx | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/packages/pigment-css-react/src/Grid.jsx b/packages/pigment-css-react/src/Grid.jsx index dc284811..24efd910 100644 --- a/packages/pigment-css-react/src/Grid.jsx +++ b/packages/pigment-css-react/src/Grid.jsx @@ -14,14 +14,16 @@ function isGridComponent(element) { return element.type.muiName === 'Grid' || element.type?._payload?.value?.muiName === 'Grid'; } -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', +export 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'], @@ -36,9 +38,6 @@ export const gridAtomics = generateAtomics(({ theme }) => ({ '--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) @@ -96,7 +95,7 @@ export const gridAtomics = generateAtomics(({ theme }) => ({ return 'var(--Grid-fixed-offset)'; }, }, -})); +}}); const GridComponent = styled('div')({ '--Grid-fixed-width': @@ -159,7 +158,7 @@ const Grid = React.forwardRef(function Grid( const selfRowSpacing = rowSpacing ?? spacing ?? unstable_parent_row_spacing ?? 0; const gridAtomicsObj = { - direction, + flexDirection: direction, }; if (unstable_parent_columns !== undefined) { From 195ec31a5227931508b39aff3f9f6bb13ba4ddef Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Tue, 18 Jun 2024 11:26:26 -0400 Subject: [PATCH 12/14] prettier --- packages/pigment-css-react/src/Grid.jsx | 133 ++++++++++++------------ 1 file changed, 67 insertions(+), 66 deletions(-) diff --git a/packages/pigment-css-react/src/Grid.jsx b/packages/pigment-css-react/src/Grid.jsx index 24efd910..3313fd30 100644 --- a/packages/pigment-css-react/src/Grid.jsx +++ b/packages/pigment-css-react/src/Grid.jsx @@ -22,80 +22,81 @@ export const gridAtomics = generateAtomics(({ theme }) => { 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'; - } + 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'; - } + if (value === 'auto') { + return 'auto'; + } - return 'var(--Grid-fixed-width)'; - }, - '--Grid-self-max-width': (value) => { - if (value === 'grow') { - return '100%'; - } + return 'var(--Grid-fixed-width)'; + }, + '--Grid-self-max-width': (value) => { + if (value === 'grow') { + return '100%'; + } - if (value === 'auto') { - return 'none'; - } + if (value === 'auto') { + return 'none'; + } - return 'unset'; - }, - '--Grid-self-flex': (value) => { - if (value === 'grow') { - return '1 1 0'; - } + return 'unset'; + }, + '--Grid-self-flex': (value) => { + if (value === 'grow') { + return '1 1 0'; + } - if (value === 'auto') { - return '0 0 auto'; - } + if (value === 'auto') { + return '0 0 auto'; + } - return '0 1 auto'; - }, - '--Grid-self-margin-left': (value) => { - if (value === 'auto') { - return 'auto'; - } + return '0 1 auto'; + }, + '--Grid-self-margin-left': (value) => { + if (value === 'auto') { + return 'auto'; + } - return 'var(--Grid-fixed-offset)'; + return 'var(--Grid-fixed-offset)'; + }, }, - }, -}}); + }; +}); const GridComponent = styled('div')({ '--Grid-fixed-width': From 129c4aadec320614c7666ca56ffc41126c4e329c Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Wed, 19 Jun 2024 09:56:20 -0400 Subject: [PATCH 13/14] Init grid tests --- packages/pigment-css-react/src/Grid.jsx | 2 +- .../tests/Grid/Grid.spec.tsx | 60 +++ .../pigment-css-react/tests/Grid/Grid.test.js | 21 + .../tests/Grid/fixtures/Grid.output.css | 369 +++++++++++++++++ .../tests/Grid/fixtures/Grid.output.js | 386 ++++++++++++++++++ .../tests/Hidden/fixtures/Hidden.output.js | 4 +- 6 files changed, 840 insertions(+), 2 deletions(-) create mode 100644 packages/pigment-css-react/tests/Grid/Grid.spec.tsx create mode 100644 packages/pigment-css-react/tests/Grid/Grid.test.js create mode 100644 packages/pigment-css-react/tests/Grid/fixtures/Grid.output.css create mode 100644 packages/pigment-css-react/tests/Grid/fixtures/Grid.output.js diff --git a/packages/pigment-css-react/src/Grid.jsx b/packages/pigment-css-react/src/Grid.jsx index 3313fd30..b8703257 100644 --- a/packages/pigment-css-react/src/Grid.jsx +++ b/packages/pigment-css-react/src/Grid.jsx @@ -14,7 +14,7 @@ function isGridComponent(element) { return element.type.muiName === 'Grid' || element.type?._payload?.value?.muiName === 'Grid'; } -export const gridAtomics = generateAtomics(({ theme }) => { +const gridAtomics = generateAtomics(({ theme }) => { const conditions = {}; Object.entries(theme.breakpoints.values) .sort((a, b) => a[1] - b[1]) 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..f3372a18 --- /dev/null +++ b/packages/pigment-css-react/tests/Grid/Grid.test.js @@ -0,0 +1,21 @@ +import path from 'node:path'; +import { createBreakpoints } from '@mui/system'; +import { runTransformation, expect } from '../testUtils'; + +describe('Pigment CSS - Grid', () => { + 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); + }); +}); 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..bfd392d0 --- /dev/null +++ b/packages/pigment-css-react/tests/Grid/fixtures/Grid.output.js @@ -0,0 +1,386 @@ +import _default 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__*/ _default('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 }, From 59a9ad43c453a25d2c37652338b9ebc134f8ec4e Mon Sep 17 00:00:00 2001 From: Diego Andai Date: Wed, 19 Jun 2024 11:34:16 -0400 Subject: [PATCH 14/14] Add basic example test --- .../pigment-css-react/src/processors/styled.ts | 5 +---- .../Container/fixtures/Container.output.js | 4 ++-- .../pigment-css-react/tests/Grid/Grid.test.js | 18 ++++++++++++++++++ .../tests/Grid/fixtures/Grid.output.js | 4 ++-- 4 files changed, 23 insertions(+), 8 deletions(-) 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/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.test.js b/packages/pigment-css-react/tests/Grid/Grid.test.js index f3372a18..db2f7cbb 100644 --- a/packages/pigment-css-react/tests/Grid/Grid.test.js +++ b/packages/pigment-css-react/tests/Grid/Grid.test.js @@ -1,8 +1,13 @@ +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'), @@ -18,4 +23,17 @@ describe('Pigment CSS - Grid', () => { 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.js b/packages/pigment-css-react/tests/Grid/fixtures/Grid.output.js index bfd392d0..559bf4f9 100644 --- a/packages/pigment-css-react/tests/Grid/fixtures/Grid.output.js +++ b/packages/pigment-css-react/tests/Grid/fixtures/Grid.output.js @@ -1,4 +1,4 @@ -import _default from '@pigment-css/react'; +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 */ @@ -190,7 +190,7 @@ const gridAtomics = /*#__PURE__*/ _atomics({ }, }, }); -const GridComponent = /*#__PURE__*/ _default('div')({ +const GridComponent = /*#__PURE__*/ _styled('div')({ classes: ['g1i5ygey'], variants: [ {