From 9051b05e0369a4ce8c173762927621e469d4b237 Mon Sep 17 00:00:00 2001 From: Wurielle Date: Thu, 29 Aug 2024 13:44:31 +0200 Subject: [PATCH] feat: improve grid responsive --- .../src/components/layout/grid/grid.shared.ts | 16 +++--- .../components/layout/grid/grid.stories.tsx | 26 ++++----- .../components/layout/grid/grid.styled.tsx | 55 ++++++++++++------- .../react/src/components/layout/grid/grid.tsx | 29 +++------- packages/react/src/utils/css-in-js.ts | 4 +- 5 files changed, 66 insertions(+), 64 deletions(-) diff --git a/packages/react/src/components/layout/grid/grid.shared.ts b/packages/react/src/components/layout/grid/grid.shared.ts index 2a16bfe..7a13f2c 100644 --- a/packages/react/src/components/layout/grid/grid.shared.ts +++ b/packages/react/src/components/layout/grid/grid.shared.ts @@ -1,21 +1,21 @@ import { ElementType, HTMLAttributes } from 'react' import { defineProps, PropsDefinition } from '@/utils/component' import { boxPropsDefinition } from '@/components/layout/box' -import { Screens, Spacing } from '@/tokens' +import { Spacing } from '@/tokens' import { Properties } from 'csstype' -export const gridPropsDefinition = defineProps(({ optional }) => ({ +export const gridPropsDefinition = defineProps(({ optional, responsive }) => ({ ...boxPropsDefinition, - breakpoints: optional(), - gap: optional('3'), - columns: optional(12), - rows: optional(), - align: optional(), + ...responsive({ + gap: optional('3'), + columns: optional(12), + rows: optional(), + align: optional(), + }), })) export const gridColPropsDefinition = defineProps(({ optional, responsive }) => ({ ...boxPropsDefinition, - columns: gridPropsDefinition.columns, ...responsive({ span: optional(), start: optional(), diff --git a/packages/react/src/components/layout/grid/grid.stories.tsx b/packages/react/src/components/layout/grid/grid.stories.tsx index 03116b0..4f3741b 100644 --- a/packages/react/src/components/layout/grid/grid.stories.tsx +++ b/packages/react/src/components/layout/grid/grid.stories.tsx @@ -13,63 +13,63 @@ type Story = StoryObj const Template: StoryFn = (args) => ( - - + + 1 - + 1 - + 2 - + 3 - + 1 - + 2 - + 3 - + 1 - + 1 - + 2 - + 3 - + 4 diff --git a/packages/react/src/components/layout/grid/grid.styled.tsx b/packages/react/src/components/layout/grid/grid.styled.tsx index 83c479c..d05766f 100644 --- a/packages/react/src/components/layout/grid/grid.styled.tsx +++ b/packages/react/src/components/layout/grid/grid.styled.tsx @@ -9,44 +9,57 @@ import { PropsDefinitionWithDefaults } from '@/utils' export const StGrid = styled(StBox)>>((context) => { const { theme: { spacing = _spacing }, - styled: { align, columns, rows, gap }, } = context + const { getResponsive } = defineMixins(context) return [ { display: 'grid', - gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`, - gap: getRemValue(gap, spacing), - }, - !isUndefined(rows) && { - gridTemplateRows: `repeat(${rows}, minmax(0, 1fr))`, - }, - align && { - alignItems: align, }, + getResponsive( + 'rows', + (rows) => + !isUndefined(rows) && { + gridTemplateRows: `repeat(${rows}, minmax(0, 1fr))`, + } + ), + getResponsive( + 'columns', + (columns) => + !isUndefined(columns) && { + gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`, + } + ), + getResponsive( + 'gap', + (gap) => + !isUndefined(gap) && { + gap: getRemValue(gap, spacing), + } + ), + getResponsive( + 'align', + (align) => + !isUndefined(align) && { + alignItems: align, + } + ), ] }) export const StGridCol = styled(StBox)>>((context) => { - const { getResponsive } = defineMixins({ - ...context, - styled: { - ...context.styled, - span: context.styled.span || context.styled.columns, - rowSpan: context.styled.rowSpan || null, - }, - }) + const { getResponsive } = defineMixins(context) return [ { minWidth: 0, flexShrink: 0, }, - getResponsive( - 'span', - (value) => + getResponsive('span', (value) => { + return ( !isUndefined(value) && { gridColumn: `span ${value} / span ${value}`, } - ), + ) + }), getResponsive( 'start', (value) => diff --git a/packages/react/src/components/layout/grid/grid.tsx b/packages/react/src/components/layout/grid/grid.tsx index 0e479fb..f009cd0 100644 --- a/packages/react/src/components/layout/grid/grid.tsx +++ b/packages/react/src/components/layout/grid/grid.tsx @@ -1,15 +1,12 @@ -import { Context, createContext, forwardRef, ForwardRefExoticComponent, PropsWithoutRef, RefAttributes, useContext, useMemo } from 'react' +import { forwardRef, ForwardRefExoticComponent, PropsWithoutRef, RefAttributes, useMemo } from 'react' import { StGrid, StGridCol } from './grid.styled' import { GridColProps, gridColPropsDefinition, GridProps, gridPropsDefinition } from './grid.shared' import { Slot } from '@radix-ui/react-slot' import { useDefinitionProps } from '@/utils/component' -const GridContext = createContext({}) as Context> - const GridCol = forwardRef(function GridCol(props, forwardedRef) { const [gridColProps, { children, asChild, ...htmlProps }] = useDefinitionProps(props, gridColPropsDefinition) const Comp = useMemo(() => (asChild ? StGridCol.withComponent(Slot) : StGridCol), [asChild]) - const { columns } = useContext(GridContext) return ( (function GridCol(props, {...htmlProps} styled={{ ...gridColProps, - columns: columns || gridColProps.columns, }} > {children} @@ -29,24 +25,17 @@ type GridType = ForwardRefExoticComponent & RefAttrib export const Grid = forwardRef(function Grid({ children, ...props }, forwardedRef) { const [gridProps, htmlProps] = useDefinitionProps(props, gridPropsDefinition) - const { columns } = gridProps return ( - - - {children} - - + {children} + ) }) as GridType & { Col: typeof GridCol } diff --git a/packages/react/src/utils/css-in-js.ts b/packages/react/src/utils/css-in-js.ts index aa38072..0a97653 100644 --- a/packages/react/src/utils/css-in-js.ts +++ b/packages/react/src/utils/css-in-js.ts @@ -35,7 +35,7 @@ export const defineMixins = < ) => { const getResponsive = < Prop extends keyof Context['styled'], - Callback extends (value: Context['styled'][Prop], screen: Screen | '', prop: Prop) => InterpolationPrimitive, + Callback extends (value: Context['styled'][Prop], screen: Screen | null, prop: Prop) => InterpolationPrimitive, >( prop: Prop, callback: Callback @@ -43,7 +43,7 @@ export const defineMixins = < const screens = context.theme?.screens || _screens const props = context.styled || {} return [ - callback(props[prop as keyof typeof props] as Context['styled'][Prop], '', prop), + callback(props[prop as keyof typeof props] as Context['styled'][Prop], null, prop), ...(Object.entries(screens) as [Screen, Screens[keyof Screens]][]).map(([screen, { value, margin }]) => { const responsiveProp = `${screen}${String(prop).charAt(0).toUpperCase() + String(prop).slice(1)}` as Prop const responsiveValue = props[responsiveProp as keyof typeof props] as Context['styled'][Prop]