From c7c11f657b96896b59e0d5e9caae10a47a5b6eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20G=C3=B3mez=20Pinta?= <44321109+GomezIvann@users.noreply.github.com> Date: Mon, 17 Apr 2023 14:33:43 +0200 Subject: [PATCH 1/8] First iteration of Grid component --- lib/src/grid/Grid.stories.tsx | 83 +++++++++++++++++++++++++++++++++++ lib/src/grid/Grid.tsx | 41 +++++++++++++++++ lib/src/grid/types.ts | 55 +++++++++++++++++++++++ lib/src/main.ts | 2 + 4 files changed, 181 insertions(+) create mode 100644 lib/src/grid/Grid.stories.tsx create mode 100644 lib/src/grid/Grid.tsx create mode 100644 lib/src/grid/types.ts diff --git a/lib/src/grid/Grid.stories.tsx b/lib/src/grid/Grid.stories.tsx new file mode 100644 index 000000000..34b04c816 --- /dev/null +++ b/lib/src/grid/Grid.stories.tsx @@ -0,0 +1,83 @@ +import React from "react"; +import Title from "../../.storybook/components/Title"; +import styled from "styled-components"; +import DxcGrid from "./Grid"; + +export default { + title: "Grid", + component: DxcGrid, +}; + +export const Chromatic = () => ( + <> + + <Container height="300px"> + <DxcGrid + templateColumns={["repeat(4, 1fr)"]} + templateRows={["auto"]} + templateAreas={["header header header header", "sidenav main main main", "footer footer footer footer"]} + gap="0.5rem" + > + <DxcGrid area="header"> + <Placeholder /> + </DxcGrid> + <DxcGrid area="main"> + <Placeholder /> + </DxcGrid> + <DxcGrid area="sidenav"> + <Placeholder /> + </DxcGrid> + <DxcGrid area="footer"> + <Placeholder /> + </DxcGrid> + </DxcGrid> + </Container> + <Title title="Grid Application Layout" level={4} /> + <div style={{ margin: "2.5rem" }}> + <DxcGrid templateColumns={["1fr", "1fr", "1fr"]} templateRows={["1fr", "3fr", "1fr"]} gap="0.5rem"> + <DxcGrid column={{ start: 1, end: -1 }}> + <ColoredContainer color="yellow">Header</ColoredContainer> + </DxcGrid> + <DxcGrid column={1}> + <ColoredContainer color="lightcyan">Sidenav</ColoredContainer> + </DxcGrid> + <DxcGrid column={{ start: 2, end: -1 }}> + <ColoredContainer color="white">Main</ColoredContainer> + </DxcGrid> + <DxcGrid column={{ start: 1, end: -1 }}> + <ColoredContainer color="black">Footer</ColoredContainer> + </DxcGrid> + </DxcGrid> + </div> + </> +); + +const Container = styled.div<{ height?: string }>` + display: grid; + overflow: auto; + background: #f2eafa; + margin: 2.5rem; + ${({ height }) => height && `height: ${height}`}; +`; + +const Placeholder = styled.div<{ width?: string; height?: string }>` + border: 1px solid #a46ede; + background-color: #e5d5f6; + ${({ width }) => width && `width: ${width}`}; + ${({ height }) => height && `height: ${height}`}; +`; + +const ColoredContainer = styled.div<{ color?: string }>` + box-sizing: border-box; + display: flex; + justify-content: center; + align-items: center; + background-color: ${({ color }) => color}; + padding: 1rem; + border: 1px solid #a46ede; + border-radius: 0.5rem; + font-family: Open Sans, sans-serif; + font-size: 1.5rem; + font-weight: bold; + color: #a46ede; +`; diff --git a/lib/src/grid/Grid.tsx b/lib/src/grid/Grid.tsx new file mode 100644 index 000000000..69fb62e94 --- /dev/null +++ b/lib/src/grid/Grid.tsx @@ -0,0 +1,41 @@ +import React from "react"; +import styled from "styled-components"; +import GridPropsType from "./types"; + +const DxcGrid = styled.div<GridPropsType>` + display: grid; + + // Grid container + ${({ templateColumns }) => templateColumns && `grid-template-columns: ${templateColumns.join(" ")};`} + ${({ templateRows }) => templateRows && `grid-template-rows: ${templateRows.join(" ")};`} + ${({ templateAreas }) => templateAreas && `grid-template-areas: ${templateAreas.map((row) => `"${row}"`).join(" ")};`} + ${({ gap }) => gap && `gap: ${typeof gap === "string" ? gap : `${gap.rowGap} ${gap.columnGap}`};`} + ${({ autoColumns }) => autoColumns && `grid-auto-columns: ${autoColumns};`} + ${({ autoRows }) => autoRows && `grid-auto-rows: ${autoRows};`} + ${({ autoFlow }) => autoFlow && `grid-auto-flow: ${autoFlow};`} + ${({ placeItems }) => + placeItems && + `place-items: ${ + typeof placeItems === "string" ? placeItems : `${placeItems.alignItems} ${placeItems.justifyItems}` + };`} + ${({ placeContent }) => + placeContent && + `place-content: ${ + typeof placeContent === "string" ? placeContent : `${placeContent.alignContent} ${placeContent.justifyContent}` + };`} + + // Grid item + ${({ column }) => + column && + `grid-column: ${ + typeof column === "string" || typeof column === "number" ? column : `${column.start} / ${column.end};` + };`} + ${({ row }) => + row && `grid-row: ${typeof row === "string" || typeof row === "number" ? row : `${row.start} / ${row.end};`};`} + ${({ area }) => area && `grid-area: ${area};`} + ${({ placeSelf }) => + placeSelf && + `place-self: ${typeof placeSelf === "string" ? placeSelf : `${placeSelf.alignSelf} ${placeSelf.justifySelf}`};`} +`; + +export default DxcGrid; diff --git a/lib/src/grid/types.ts b/lib/src/grid/types.ts new file mode 100644 index 000000000..5f2439829 --- /dev/null +++ b/lib/src/grid/types.ts @@ -0,0 +1,55 @@ +type Spaces = "0rem" | "0.125rem" | "0.25rem" | "0.5rem" | "1rem" | "1.5rem" | "2rem" | "3rem" | "4rem" | "5rem"; +type Gap = { rowGap: Spaces; columnGap: Spaces }; +type GridCell = { start?: number | string; end?: number | string }; + +type Props = { + as?: keyof HTMLElementTagNameMap; + children: React.ReactNode; + + // Grid Container + autoColumns?: string; + autoRows?: string; + autoFlow?: "row" | "column" | "row dense" | "column dense"; + gap?: Spaces | Gap; + placeItems?: + | { + alignItems: "start" | "end" | "center" | "stretch" | "baseline"; + justifyItems: "start" | "end" | "center" | "stretch"; + } + | "start" + | "end" + | "center" + | "stretch" + | "baseline"; + placeContent?: + | { + alignContent: "start" | "end" | "center" | "stretch" | "space-between" | "space-around" | "space-evenly"; + justifyContent: "start" | "end" | "center" | "stretch" | "space-between" | "space-around" | "space-evenly"; + } + | "start" + | "end" + | "center" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly"; + templateColumns?: string[]; + templateRows?: string[]; + templateAreas?: string[]; + + // Grid Item + area?: string; + column?: number | string | GridCell; + row?: number | string | GridCell; + placeSelf?: + | { + alignSelf?: "start" | "end" | "center" | "stretch" | "baseline"; + justifySelf?: "start" | "end" | "center" | "stretch"; + } + | "start" + | "end" + | "center" + | "stretch"; +}; + +export default Props; diff --git a/lib/src/main.ts b/lib/src/main.ts index d345d6a25..331c36c83 100644 --- a/lib/src/main.ts +++ b/lib/src/main.ts @@ -39,6 +39,7 @@ import DxcFlex from "./flex/Flex"; import DxcTypography from "./typography/Typography"; import DxcParagraph from "./paragraph/Paragraph"; import DxcBulletedList from "./bulleted-list/BulletedList"; +import DxcGrid from "./grid/Grid"; import HalstackContext, { HalstackProvider, HalstackLanguageContext } from "./HalstackContext"; import { BackgroundColorProvider } from "./BackgroundColorContext"; @@ -89,4 +90,5 @@ export { DxcTypography, DxcParagraph, DxcBulletedList, + DxcGrid, }; From 97a1c68dc6da92f644153c8338d3ec3a0042cb9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20G=C3=B3mez=20Pinta?= <44321109+GomezIvann@users.noreply.github.com> Date: Tue, 18 Apr 2023 14:44:10 +0200 Subject: [PATCH 2/8] More updates to the Grid component --- app/src/pages/Grid.jsx | 68 +++++++++++++++++++++++++++++++++ app/src/paths.js | 6 +++ lib/src/grid/Grid.stories.tsx | 72 ++++++++++++++++++++++++++++++++--- lib/src/grid/Grid.tsx | 8 ++-- lib/src/grid/types.ts | 24 ++++++------ 5 files changed, 156 insertions(+), 22 deletions(-) create mode 100644 app/src/pages/Grid.jsx diff --git a/app/src/pages/Grid.jsx b/app/src/pages/Grid.jsx new file mode 100644 index 000000000..790ac8166 --- /dev/null +++ b/app/src/pages/Grid.jsx @@ -0,0 +1,68 @@ +import React from "react"; +import { DxcGrid } from "@dxc-technology/halstack-react"; +import styled from "styled-components"; + +const App = () => ( + <div style={{ margin: "1rem" }}> + <h2>Template areas layout</h2> + <Container height="300px"> + <DxcGrid + templateColumns={["repeat(4, 1fr)"]} + templateRows={["auto"]} + templateAreas={[ + "header header header header", + "sidenav . main main", + "footer footer footer footer", + ]} + gap="0.5rem" + > + <DxcGrid area="header"> + <Placeholder /> + </DxcGrid> + <DxcGrid area="main"> + <Placeholder /> + </DxcGrid> + <DxcGrid area="sidenav"> + <Placeholder /> + </DxcGrid> + <DxcGrid area="footer"> + <Placeholder /> + </DxcGrid> + </DxcGrid> + </Container> + </div> +); + +const Container = styled.div` + display: grid; + overflow: auto; + margin: 2.5rem; + ${({ height }) => height && `height: ${height}`}; +`; + +const Placeholder = styled.div` + border: 1px solid #a46ede; + background-color: ${({ color }) => color ?? "#f2eafa;"}; + ${({ width }) => width && `width: ${width}`}; + ${({ height }) => height && `height: ${height}`}; +`; + +const ColoredContainer = styled.div` + box-sizing: border-box; + display: flex; + justify-content: center; + align-items: center; + background-color: ${({ color }) => color}; + padding: 1rem; + border: 1px solid #a46ede; + border-radius: 0.5rem; + font-family: Open Sans, sans-serif; + font-size: 1.5rem; + font-weight: bold; + color: #a46ede; + + ${({ width }) => width && `width: ${width}`}; + ${({ height }) => height && `height: ${height}`}; +`; + +export default App; diff --git a/app/src/paths.js b/app/src/paths.js index f65681c57..b3453a8f0 100644 --- a/app/src/paths.js +++ b/app/src/paths.js @@ -35,6 +35,7 @@ import Select from "./pages/Select"; import FileInput from "./pages/FileInput"; import QuickNav from "./pages/QuickNav"; import NavTabs from "./pages/NavTabs"; +import Grid from "./pages/Grid"; const componentsMap = [ { @@ -112,6 +113,11 @@ const componentsMap = [ name: "Footer", component: Footer, }, + { + path: "grid", + name: "Grid", + component: Grid, + }, { path: "header", name: "Header", diff --git a/lib/src/grid/Grid.stories.tsx b/lib/src/grid/Grid.stories.tsx index 34b04c816..22047731d 100644 --- a/lib/src/grid/Grid.stories.tsx +++ b/lib/src/grid/Grid.stories.tsx @@ -1,5 +1,6 @@ import React from "react"; import Title from "../../.storybook/components/Title"; +import ExampleContainer from "../../.storybook/components/ExampleContainer"; import styled from "styled-components"; import DxcGrid from "./Grid"; @@ -15,7 +16,7 @@ export const Chromatic = () => ( <DxcGrid templateColumns={["repeat(4, 1fr)"]} templateRows={["auto"]} - templateAreas={["header header header header", "sidenav main main main", "footer footer footer footer"]} + templateAreas={["header header header header", "sidenav . main main", "footer footer footer footer"]} gap="0.5rem" > <DxcGrid area="header"> @@ -49,25 +50,83 @@ export const Chromatic = () => ( </DxcGrid> </DxcGrid> </div> + <Title title="Overlapping" level={4} /> + <div style={{ marginTop: "2.5rem", marginRight: "2.5rem", marginBottom: "4rem", marginLeft: "2.5rem" }}> + <DxcGrid templateRows={["50px", "50px"]}> + <ColoredContainer color="yellow" height="100px"> + 1 + </ColoredContainer> + <ColoredContainer color="transparent" height="100px"> + 2 + </ColoredContainer> + </DxcGrid> + </div> + <Title title="Implicit Grids" level={4} /> + <div style={{ margin: "2.5rem" }}> + <DxcGrid templateColumns={["50px"]} templateRows={["50px", "50px"]} autoRows="50px" autoColumns="50px"> + <DxcGrid> + <ColoredContainer height="50px">1</ColoredContainer> + </DxcGrid> + <DxcGrid row={2}> + <ColoredContainer height="50px">3</ColoredContainer> + </DxcGrid> + <DxcGrid row={6} column={1}> + <ColoredContainer height="50px">5</ColoredContainer> + </DxcGrid> + <DxcGrid row={3}> + <ColoredContainer height="50px">4</ColoredContainer> + </DxcGrid> + <DxcGrid row={{ start: 1, end: 2 }} column={{ start: 5, end: 6 }}> + <ColoredContainer height="50px">2</ColoredContainer> + </DxcGrid> + </DxcGrid> + </div> + <Title title="Autoflow 'row' (default)" level={4} /> + <ExampleContainer> + <DxcGrid templateColumns={["repeat(5, 1fr)"]} templateRows={["1fr", "1fr"]} autoFlow="row" autoColumns="1fr"> + <DxcGrid row={{ start: 1, end: -1 }} column={1}> + <ColoredContainer color="lightsalmon">1</ColoredContainer> + </DxcGrid> + <ColoredContainer color="lightyellow">2</ColoredContainer> + <ColoredContainer color="lightcyan">3</ColoredContainer> + <ColoredContainer color="lightgreen">4</ColoredContainer> + <DxcGrid row={{ start: 1, end: -1 }} column={-2}> + <ColoredContainer color="lightpink">5</ColoredContainer> + </DxcGrid> + </DxcGrid> + </ExampleContainer> + <Title title="Autoflow 'column'" level={4} /> + <ExampleContainer> + <DxcGrid templateColumns={["repeat(5, 1fr)"]} templateRows={["1fr", "1fr"]} autoFlow="column" autoColumns="1fr"> + <DxcGrid row={{ start: 1, end: -1 }} column={1}> + <ColoredContainer color="lightsalmon">1</ColoredContainer> + </DxcGrid> + <ColoredContainer color="lightyellow">2</ColoredContainer> + <ColoredContainer color="lightcyan">3</ColoredContainer> + <ColoredContainer color="lightgreen">4</ColoredContainer> + <DxcGrid row={{ start: 1, end: -1 }} column={-2}> + <ColoredContainer color="lightpink">5</ColoredContainer> + </DxcGrid> + </DxcGrid> + </ExampleContainer> </> ); const Container = styled.div<{ height?: string }>` display: grid; overflow: auto; - background: #f2eafa; margin: 2.5rem; ${({ height }) => height && `height: ${height}`}; `; -const Placeholder = styled.div<{ width?: string; height?: string }>` +const Placeholder = styled.div<{ color?: string; width?: string; height?: string }>` border: 1px solid #a46ede; - background-color: #e5d5f6; + background-color: ${({ color }) => color ?? "#f2eafa;"}; ${({ width }) => width && `width: ${width}`}; ${({ height }) => height && `height: ${height}`}; `; -const ColoredContainer = styled.div<{ color?: string }>` +const ColoredContainer = styled.div<{ color?: string; width?: string; height?: string }>` box-sizing: border-box; display: flex; justify-content: center; @@ -80,4 +139,7 @@ const ColoredContainer = styled.div<{ color?: string }>` font-size: 1.5rem; font-weight: bold; color: #a46ede; + + ${({ width }) => width && `width: ${width}`}; + ${({ height }) => height && `height: ${height}`}; `; diff --git a/lib/src/grid/Grid.tsx b/lib/src/grid/Grid.tsx index 69fb62e94..dc3a6a9de 100644 --- a/lib/src/grid/Grid.tsx +++ b/lib/src/grid/Grid.tsx @@ -2,10 +2,10 @@ import React from "react"; import styled from "styled-components"; import GridPropsType from "./types"; -const DxcGrid = styled.div<GridPropsType>` - display: grid; +const DxcGrid = (props: GridPropsType): JSX.Element => <Grid {...props} />; - // Grid container +const Grid = styled.div<GridPropsType>` + display: grid; ${({ templateColumns }) => templateColumns && `grid-template-columns: ${templateColumns.join(" ")};`} ${({ templateRows }) => templateRows && `grid-template-rows: ${templateRows.join(" ")};`} ${({ templateAreas }) => templateAreas && `grid-template-areas: ${templateAreas.map((row) => `"${row}"`).join(" ")};`} @@ -23,8 +23,6 @@ const DxcGrid = styled.div<GridPropsType>` `place-content: ${ typeof placeContent === "string" ? placeContent : `${placeContent.alignContent} ${placeContent.justifyContent}` };`} - - // Grid item ${({ column }) => column && `grid-column: ${ diff --git a/lib/src/grid/types.ts b/lib/src/grid/types.ts index 5f2439829..10e5edfc9 100644 --- a/lib/src/grid/types.ts +++ b/lib/src/grid/types.ts @@ -1,6 +1,6 @@ type Spaces = "0rem" | "0.125rem" | "0.25rem" | "0.5rem" | "1rem" | "1.5rem" | "2rem" | "3rem" | "4rem" | "5rem"; type Gap = { rowGap: Spaces; columnGap: Spaces }; -type GridCell = { start?: number | string; end?: number | string }; +type GridCell = { start: number | string; end: number | string }; type Props = { as?: keyof HTMLElementTagNameMap; @@ -11,16 +11,6 @@ type Props = { autoRows?: string; autoFlow?: "row" | "column" | "row dense" | "column dense"; gap?: Spaces | Gap; - placeItems?: - | { - alignItems: "start" | "end" | "center" | "stretch" | "baseline"; - justifyItems: "start" | "end" | "center" | "stretch"; - } - | "start" - | "end" - | "center" - | "stretch" - | "baseline"; placeContent?: | { alignContent: "start" | "end" | "center" | "stretch" | "space-between" | "space-around" | "space-evenly"; @@ -33,9 +23,19 @@ type Props = { | "space-between" | "space-around" | "space-evenly"; + placeItems?: + | { + alignItems: "start" | "end" | "center" | "stretch" | "baseline"; + justifyItems: "start" | "end" | "center" | "stretch"; + } + | "start" + | "end" + | "center" + | "stretch" + | "baseline"; + templateAreas?: string[]; templateColumns?: string[]; templateRows?: string[]; - templateAreas?: string[]; // Grid Item area?: string; From 2b6284cd2fb723b8c50f5ed5c3e972a253b166c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20G=C3=B3mez=20Pinta?= <44321109+GomezIvann@users.noreply.github.com> Date: Thu, 20 Apr 2023 11:47:56 +0200 Subject: [PATCH 3/8] Updating some Grid types --- lib/src/grid/types.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/src/grid/types.ts b/lib/src/grid/types.ts index 10e5edfc9..179d718d3 100644 --- a/lib/src/grid/types.ts +++ b/lib/src/grid/types.ts @@ -13,8 +13,8 @@ type Props = { gap?: Spaces | Gap; placeContent?: | { - alignContent: "start" | "end" | "center" | "stretch" | "space-between" | "space-around" | "space-evenly"; - justifyContent: "start" | "end" | "center" | "stretch" | "space-between" | "space-around" | "space-evenly"; + alignContent?: "start" | "end" | "center" | "stretch" | "space-between" | "space-around" | "space-evenly"; + justifyContent?: "start" | "end" | "center" | "stretch" | "space-between" | "space-around" | "space-evenly"; } | "start" | "end" @@ -25,8 +25,8 @@ type Props = { | "space-evenly"; placeItems?: | { - alignItems: "start" | "end" | "center" | "stretch" | "baseline"; - justifyItems: "start" | "end" | "center" | "stretch"; + alignItems?: "start" | "end" | "center" | "stretch" | "baseline"; + justifyItems?: "start" | "end" | "center" | "stretch"; } | "start" | "end" From 957b733307f15f92758f140f6f36a98948c00044 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20G=C3=B3mez=20Pinta?= <44321109+GomezIvann@users.noreply.github.com> Date: Thu, 20 Apr 2023 17:27:32 +0200 Subject: [PATCH 4/8] Updates to the API based on the feedback --- lib/src/grid/Grid.stories.tsx | 18 +++++++++----- lib/src/grid/Grid.tsx | 14 +++++++++-- lib/src/grid/types.ts | 44 ++++++++++++++++++++++++----------- 3 files changed, 54 insertions(+), 22 deletions(-) diff --git a/lib/src/grid/Grid.stories.tsx b/lib/src/grid/Grid.stories.tsx index 22047731d..e1f290b58 100644 --- a/lib/src/grid/Grid.stories.tsx +++ b/lib/src/grid/Grid.stories.tsx @@ -11,24 +11,30 @@ export default { export const Chromatic = () => ( <> + <Title title="Template areas layout" level={4} /> + <Container height="300px"> + <DxcGrid placeItems="center"> + <ColoredContainer color="lightyellow">Centered div</ColoredContainer> + </DxcGrid> + </Container> <Title title="Template areas layout" level={4} /> <Container height="300px"> <DxcGrid templateColumns={["repeat(4, 1fr)"]} templateRows={["auto"]} - templateAreas={["header header header header", "sidenav . main main", "footer footer footer footer"]} - gap="0.5rem" + templateAreas={["header header header header", "sidenav main main main", "sidenav footer footer footer"]} + gap={{ rowGap: "0.5rem", columnGap: "1rem" }} > - <DxcGrid area="header"> + <DxcGrid areaName="header"> <Placeholder /> </DxcGrid> - <DxcGrid area="main"> + <DxcGrid areaName="main"> <Placeholder /> </DxcGrid> - <DxcGrid area="sidenav"> + <DxcGrid areaName="sidenav"> <Placeholder /> </DxcGrid> - <DxcGrid area="footer"> + <DxcGrid areaName="footer"> <Placeholder /> </DxcGrid> </DxcGrid> diff --git a/lib/src/grid/Grid.tsx b/lib/src/grid/Grid.tsx index dc3a6a9de..f05970d72 100644 --- a/lib/src/grid/Grid.tsx +++ b/lib/src/grid/Grid.tsx @@ -4,12 +4,22 @@ import GridPropsType from "./types"; const DxcGrid = (props: GridPropsType): JSX.Element => <Grid {...props} />; +const getGap = (gap: GridPropsType["gap"]) => { + if (typeof gap === "string") return `gap: ${gap};`; + else { + let res = ""; + if (gap.rowGap) res += `row-gap: ${gap.rowGap};`; + if (gap.columnGap) res += ` column-gap: ${gap.columnGap};`; + return res; + } +}; + const Grid = styled.div<GridPropsType>` display: grid; ${({ templateColumns }) => templateColumns && `grid-template-columns: ${templateColumns.join(" ")};`} ${({ templateRows }) => templateRows && `grid-template-rows: ${templateRows.join(" ")};`} ${({ templateAreas }) => templateAreas && `grid-template-areas: ${templateAreas.map((row) => `"${row}"`).join(" ")};`} - ${({ gap }) => gap && `gap: ${typeof gap === "string" ? gap : `${gap.rowGap} ${gap.columnGap}`};`} + ${({ gap }) => gap != null && getGap(gap)} ${({ autoColumns }) => autoColumns && `grid-auto-columns: ${autoColumns};`} ${({ autoRows }) => autoRows && `grid-auto-rows: ${autoRows};`} ${({ autoFlow }) => autoFlow && `grid-auto-flow: ${autoFlow};`} @@ -30,7 +40,7 @@ const Grid = styled.div<GridPropsType>` };`} ${({ row }) => row && `grid-row: ${typeof row === "string" || typeof row === "number" ? row : `${row.start} / ${row.end};`};`} - ${({ area }) => area && `grid-area: ${area};`} + ${({ areaName }) => areaName && `grid-area: ${areaName};`} ${({ placeSelf }) => placeSelf && `place-self: ${typeof placeSelf === "string" ? placeSelf : `${placeSelf.alignSelf} ${placeSelf.justifySelf}`};`} diff --git a/lib/src/grid/types.ts b/lib/src/grid/types.ts index 179d718d3..18acdb6a6 100644 --- a/lib/src/grid/types.ts +++ b/lib/src/grid/types.ts @@ -1,21 +1,34 @@ type Spaces = "0rem" | "0.125rem" | "0.25rem" | "0.5rem" | "1rem" | "1.5rem" | "2rem" | "3rem" | "4rem" | "5rem"; -type Gap = { rowGap: Spaces; columnGap: Spaces }; +type Gap = { rowGap?: Spaces; columnGap?: Spaces }; type GridCell = { start: number | string; end: number | string }; type Props = { - as?: keyof HTMLElementTagNameMap; - children: React.ReactNode; - - // Grid Container autoColumns?: string; autoRows?: string; autoFlow?: "row" | "column" | "row dense" | "column dense"; gap?: Spaces | Gap; placeContent?: | { - alignContent?: "start" | "end" | "center" | "stretch" | "space-between" | "space-around" | "space-evenly"; - justifyContent?: "start" | "end" | "center" | "stretch" | "space-between" | "space-around" | "space-evenly"; + alignContent?: + | "normal" + | "start" + | "end" + | "center" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly"; + justifyContent?: + | "normal" + | "start" + | "end" + | "center" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly"; } + | "normal" | "start" | "end" | "center" @@ -25,9 +38,10 @@ type Props = { | "space-evenly"; placeItems?: | { - alignItems?: "start" | "end" | "center" | "stretch" | "baseline"; - justifyItems?: "start" | "end" | "center" | "stretch"; + alignItems?: "normal" | "start" | "end" | "center" | "stretch" | "baseline"; + justifyItems?: "normal" | "start" | "end" | "center" | "stretch"; } + | "normal" | "start" | "end" | "center" @@ -36,20 +50,22 @@ type Props = { templateAreas?: string[]; templateColumns?: string[]; templateRows?: string[]; - - // Grid Item - area?: string; + areaName?: string; column?: number | string | GridCell; row?: number | string | GridCell; placeSelf?: | { - alignSelf?: "start" | "end" | "center" | "stretch" | "baseline"; - justifySelf?: "start" | "end" | "center" | "stretch"; + alignSelf?: "auto" | "start" | "end" | "center" | "stretch" | "baseline"; + justifySelf?: "auto" | "start" | "end" | "center" | "stretch"; } + | "auto" | "start" | "end" | "center" | "stretch"; + + as?: keyof HTMLElementTagNameMap; + children: React.ReactNode; }; export default Props; From 86a5fd4b314dec38afce9f8f7767097414b91a38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20G=C3=B3mez=20Pinta?= <44321109+GomezIvann@users.noreply.github.com> Date: Fri, 21 Apr 2023 10:27:35 +0200 Subject: [PATCH 5/8] More Grid updates --- lib/src/grid/Grid.tsx | 11 +++++------ lib/src/grid/types.ts | 17 ++++++++++------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/src/grid/Grid.tsx b/lib/src/grid/Grid.tsx index f05970d72..d61cff136 100644 --- a/lib/src/grid/Grid.tsx +++ b/lib/src/grid/Grid.tsx @@ -6,12 +6,11 @@ const DxcGrid = (props: GridPropsType): JSX.Element => <Grid {...props} />; const getGap = (gap: GridPropsType["gap"]) => { if (typeof gap === "string") return `gap: ${gap};`; - else { - let res = ""; - if (gap.rowGap) res += `row-gap: ${gap.rowGap};`; - if (gap.columnGap) res += ` column-gap: ${gap.columnGap};`; - return res; - } + + let res = ""; + if (gap.rowGap != null) res += `row-gap: ${gap.rowGap};`; + if (gap.columnGap != null) res += ` column-gap: ${gap.columnGap};`; + return res; }; const Grid = styled.div<GridPropsType>` diff --git a/lib/src/grid/types.ts b/lib/src/grid/types.ts index 18acdb6a6..c17d4f579 100644 --- a/lib/src/grid/types.ts +++ b/lib/src/grid/types.ts @@ -17,7 +17,8 @@ type Props = { | "stretch" | "space-between" | "space-around" - | "space-evenly"; + | "space-evenly" + | "baseline"; justifyContent?: | "normal" | "start" @@ -26,7 +27,8 @@ type Props = { | "stretch" | "space-between" | "space-around" - | "space-evenly"; + | "space-evenly" + | "baseline"; } | "normal" | "start" @@ -35,11 +37,12 @@ type Props = { | "stretch" | "space-between" | "space-around" - | "space-evenly"; + | "space-evenly" + | "baseline"; placeItems?: | { alignItems?: "normal" | "start" | "end" | "center" | "stretch" | "baseline"; - justifyItems?: "normal" | "start" | "end" | "center" | "stretch"; + justifyItems?: "normal" | "start" | "end" | "center" | "stretch" | "baseline"; } | "normal" | "start" @@ -56,14 +59,14 @@ type Props = { placeSelf?: | { alignSelf?: "auto" | "start" | "end" | "center" | "stretch" | "baseline"; - justifySelf?: "auto" | "start" | "end" | "center" | "stretch"; + justifySelf?: "auto" | "start" | "end" | "center" | "stretch" | "baseline"; } | "auto" | "start" | "end" | "center" - | "stretch"; - + | "stretch" + | "baseline"; as?: keyof HTMLElementTagNameMap; children: React.ReactNode; }; From 1b76df2721931a8db32a6e17434410e0da91a25e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20G=C3=B3mez=20Pinta?= <44321109+GomezIvann@users.noreply.github.com> Date: Mon, 24 Apr 2023 18:01:50 +0200 Subject: [PATCH 6/8] Grid.GridItem added & completed visual testing --- app/src/pages/Grid.jsx | 68 ----------- app/src/paths.js | 8 +- lib/src/grid/Grid.stories.tsx | 224 ++++++++++++++++++++++------------ lib/src/grid/Grid.tsx | 49 +++++--- lib/src/grid/types.ts | 37 +++--- 5 files changed, 198 insertions(+), 188 deletions(-) delete mode 100644 app/src/pages/Grid.jsx diff --git a/app/src/pages/Grid.jsx b/app/src/pages/Grid.jsx deleted file mode 100644 index 790ac8166..000000000 --- a/app/src/pages/Grid.jsx +++ /dev/null @@ -1,68 +0,0 @@ -import React from "react"; -import { DxcGrid } from "@dxc-technology/halstack-react"; -import styled from "styled-components"; - -const App = () => ( - <div style={{ margin: "1rem" }}> - <h2>Template areas layout</h2> - <Container height="300px"> - <DxcGrid - templateColumns={["repeat(4, 1fr)"]} - templateRows={["auto"]} - templateAreas={[ - "header header header header", - "sidenav . main main", - "footer footer footer footer", - ]} - gap="0.5rem" - > - <DxcGrid area="header"> - <Placeholder /> - </DxcGrid> - <DxcGrid area="main"> - <Placeholder /> - </DxcGrid> - <DxcGrid area="sidenav"> - <Placeholder /> - </DxcGrid> - <DxcGrid area="footer"> - <Placeholder /> - </DxcGrid> - </DxcGrid> - </Container> - </div> -); - -const Container = styled.div` - display: grid; - overflow: auto; - margin: 2.5rem; - ${({ height }) => height && `height: ${height}`}; -`; - -const Placeholder = styled.div` - border: 1px solid #a46ede; - background-color: ${({ color }) => color ?? "#f2eafa;"}; - ${({ width }) => width && `width: ${width}`}; - ${({ height }) => height && `height: ${height}`}; -`; - -const ColoredContainer = styled.div` - box-sizing: border-box; - display: flex; - justify-content: center; - align-items: center; - background-color: ${({ color }) => color}; - padding: 1rem; - border: 1px solid #a46ede; - border-radius: 0.5rem; - font-family: Open Sans, sans-serif; - font-size: 1.5rem; - font-weight: bold; - color: #a46ede; - - ${({ width }) => width && `width: ${width}`}; - ${({ height }) => height && `height: ${height}`}; -`; - -export default App; diff --git a/app/src/paths.js b/app/src/paths.js index b3453a8f0..d31346ee5 100644 --- a/app/src/paths.js +++ b/app/src/paths.js @@ -35,7 +35,6 @@ import Select from "./pages/Select"; import FileInput from "./pages/FileInput"; import QuickNav from "./pages/QuickNav"; import NavTabs from "./pages/NavTabs"; -import Grid from "./pages/Grid"; const componentsMap = [ { @@ -113,11 +112,6 @@ const componentsMap = [ name: "Footer", component: Footer, }, - { - path: "grid", - name: "Grid", - component: Grid, - }, { path: "header", name: "Header", @@ -230,4 +224,4 @@ const componentsMap = [ }, ]; -export default componentsMap; \ No newline at end of file +export default componentsMap; diff --git a/lib/src/grid/Grid.stories.tsx b/lib/src/grid/Grid.stories.tsx index e1f290b58..8486aa517 100644 --- a/lib/src/grid/Grid.stories.tsx +++ b/lib/src/grid/Grid.stories.tsx @@ -3,6 +3,7 @@ import Title from "../../.storybook/components/Title"; import ExampleContainer from "../../.storybook/components/ExampleContainer"; import styled from "styled-components"; import DxcGrid from "./Grid"; +import DxcInset from "../inset/Inset"; export default { title: "Grid", @@ -11,108 +12,182 @@ export default { export const Chromatic = () => ( <> - <Title title="Template areas layout" level={4} /> - <Container height="300px"> - <DxcGrid placeItems="center"> - <ColoredContainer color="lightyellow">Centered div</ColoredContainer> + <Title title="Default" level={4} /> + <ExampleContainer> + <DxcGrid> + <ColoredContainer /> + <ColoredContainer /> + <ColoredContainer /> + </DxcGrid> + </ExampleContainer> + <Title title="Place items" level={4} /> + <ExampleContainer> + <DxcGrid templateRows={["200px"]} placeItems="center"> + <ColoredContainer height="50px" width="50px" /> + </DxcGrid> + <DxcGrid placeItems={{ justifyItems: "end" }}> + <ColoredContainer /> + <ColoredContainer /> + <ColoredContainer /> + </DxcGrid> + <DxcGrid templateRows={["repeat(3, 100px)"]} placeItems={{ alignItems: "end", justifyItems: "center" }}> + <ColoredContainer height="50px" width="50px" /> + <ColoredContainer height="50px" width="50px" /> + <ColoredContainer height="50px" width="50px" /> + </DxcGrid> + </ExampleContainer> + <Title title="Place content" level={4} /> + <Container height="200px"> + <DxcGrid placeContent="center"> + <ColoredContainer height="50px" width="50px" /> + <ColoredContainer height="50px" width="50px" /> + </DxcGrid> + </Container> + <Container height="200px"> + <DxcGrid placeContent={{ alignContent: "center" }}> + <ColoredContainer height="50px" width="50px" /> + </DxcGrid> + </Container> + <Container height="200px"> + <DxcGrid placeContent={{ alignContent: "center", justifyContent: "end" }}> + <ColoredContainer height="50px" width="50px" /> </DxcGrid> </Container> - <Title title="Template areas layout" level={4} /> - <Container height="300px"> + <Title title="Place self" level={4} /> + <ExampleContainer> + <DxcGrid templateRows={["repeat(3, 100px)"]}> + <DxcGrid.GridItem placeSelf="center"> + <ColoredContainer height="50px" width="50px" /> + </DxcGrid.GridItem> + <DxcGrid.GridItem placeSelf={{ alignSelf: "end" }}> + <ColoredContainer height="40px" width="40px" /> + <ColoredContainer height="30px" width="30px" /> + </DxcGrid.GridItem> + <DxcGrid.GridItem placeSelf={{ alignSelf: "center", justifySelf: "end" }}> + <ColoredContainer height="50px" width="50px" /> + </DxcGrid.GridItem> + </DxcGrid> + </ExampleContainer> + <Title title="Halstack layout using template areas" level={4} /> + <ExampleContainer> <DxcGrid templateColumns={["repeat(4, 1fr)"]} - templateRows={["auto"]} + templateRows={["40px", "200px", "60px"]} templateAreas={["header header header header", "sidenav main main main", "sidenav footer footer footer"]} gap={{ rowGap: "0.5rem", columnGap: "1rem" }} > - <DxcGrid areaName="header"> - <Placeholder /> - </DxcGrid> - <DxcGrid areaName="main"> - <Placeholder /> - </DxcGrid> - <DxcGrid areaName="sidenav"> - <Placeholder /> - </DxcGrid> - <DxcGrid areaName="footer"> - <Placeholder /> - </DxcGrid> + <DxcGrid.GridItem areaName="header" as="header"> + <ColoredContainer height="100%" /> + </DxcGrid.GridItem> + <DxcGrid.GridItem areaName="main" as="main"> + <ColoredContainer height="100%" /> + </DxcGrid.GridItem> + <DxcGrid.GridItem areaName="sidenav" as="nav"> + <ColoredContainer height="100%" /> + </DxcGrid.GridItem> + <DxcGrid.GridItem areaName="footer" as="footer"> + <ColoredContainer height="100%" /> + </DxcGrid.GridItem> </DxcGrid> - </Container> - <Title title="Grid Application Layout" level={4} /> - <div style={{ margin: "2.5rem" }}> + </ExampleContainer> + <Title title="Template rows and columns with flexible sizes" level={4} /> + <ExampleContainer> <DxcGrid templateColumns={["1fr", "1fr", "1fr"]} templateRows={["1fr", "3fr", "1fr"]} gap="0.5rem"> - <DxcGrid column={{ start: 1, end: -1 }}> - <ColoredContainer color="yellow">Header</ColoredContainer> - </DxcGrid> - <DxcGrid column={1}> - <ColoredContainer color="lightcyan">Sidenav</ColoredContainer> - </DxcGrid> - <DxcGrid column={{ start: 2, end: -1 }}> - <ColoredContainer color="white">Main</ColoredContainer> - </DxcGrid> - <DxcGrid column={{ start: 1, end: -1 }}> - <ColoredContainer color="black">Footer</ColoredContainer> - </DxcGrid> + <DxcGrid.GridItem column={{ start: 1, end: -1 }}> + <ColoredContainer color="yellow" height="100%"> + Header + </ColoredContainer> + </DxcGrid.GridItem> + <DxcGrid.GridItem column={1}> + <ColoredContainer color="lightcyan" height="100%"> + Sidenav + </ColoredContainer> + </DxcGrid.GridItem> + <DxcGrid + column={{ start: 2, end: -1 }} + templateRows={["repeat(4, 1fr)"]} + templateColumns={["repeat(2, 1fr)"]} + gap="1rem" + > + <ColoredContainer /> + <ColoredContainer /> + <ColoredContainer /> + <ColoredContainer /> + <ColoredContainer /> + <ColoredContainer /> + <ColoredContainer /> + <ColoredContainer /> + </DxcGrid> + <DxcGrid.GridItem column={{ start: 1, end: -1 }}> + <ColoredContainer color="black" height="100%"> + Footer + </ColoredContainer> + </DxcGrid.GridItem> </DxcGrid> - </div> + </ExampleContainer> <Title title="Overlapping" level={4} /> - <div style={{ marginTop: "2.5rem", marginRight: "2.5rem", marginBottom: "4rem", marginLeft: "2.5rem" }}> - <DxcGrid templateRows={["50px", "50px"]}> - <ColoredContainer color="yellow" height="100px"> - 1 - </ColoredContainer> - <ColoredContainer color="transparent" height="100px"> - 2 - </ColoredContainer> - </DxcGrid> - </div> - <Title title="Implicit Grids" level={4} /> - <div style={{ margin: "2.5rem" }}> + <DxcInset bottom="2rem"> + <ExampleContainer> + <DxcGrid templateRows={["50px", "50px"]}> + <ColoredContainer color="yellow" height="100px"> + 1 + </ColoredContainer> + <ColoredContainer color="transparent" height="100px"> + 2 + </ColoredContainer> + </DxcGrid> + </ExampleContainer> + </DxcInset> + <Title title="Implicit rows and columns" level={4} /> + <ExampleContainer> <DxcGrid templateColumns={["50px"]} templateRows={["50px", "50px"]} autoRows="50px" autoColumns="50px"> - <DxcGrid> + <DxcGrid.GridItem> <ColoredContainer height="50px">1</ColoredContainer> - </DxcGrid> - <DxcGrid row={2}> + </DxcGrid.GridItem> + <DxcGrid.GridItem row={2}> <ColoredContainer height="50px">3</ColoredContainer> - </DxcGrid> - <DxcGrid row={6} column={1}> + </DxcGrid.GridItem> + <DxcGrid.GridItem row={6} column={1}> <ColoredContainer height="50px">5</ColoredContainer> - </DxcGrid> - <DxcGrid row={3}> + </DxcGrid.GridItem> + <DxcGrid.GridItem row={3}> <ColoredContainer height="50px">4</ColoredContainer> - </DxcGrid> - <DxcGrid row={{ start: 1, end: 2 }} column={{ start: 5, end: 6 }}> + </DxcGrid.GridItem> + <DxcGrid.GridItem row={{ start: 1, end: 2 }} column={{ start: 5, end: 7 }}> <ColoredContainer height="50px">2</ColoredContainer> - </DxcGrid> + </DxcGrid.GridItem> </DxcGrid> - </div> + </ExampleContainer> <Title title="Autoflow 'row' (default)" level={4} /> <ExampleContainer> <DxcGrid templateColumns={["repeat(5, 1fr)"]} templateRows={["1fr", "1fr"]} autoFlow="row" autoColumns="1fr"> - <DxcGrid row={{ start: 1, end: -1 }} column={1}> - <ColoredContainer color="lightsalmon">1</ColoredContainer> - </DxcGrid> + <DxcGrid.GridItem row={{ start: 1, end: "span 2" }} column={1}> + <ColoredContainer height="100%">1</ColoredContainer> + </DxcGrid.GridItem> <ColoredContainer color="lightyellow">2</ColoredContainer> <ColoredContainer color="lightcyan">3</ColoredContainer> <ColoredContainer color="lightgreen">4</ColoredContainer> - <DxcGrid row={{ start: 1, end: -1 }} column={-2}> - <ColoredContainer color="lightpink">5</ColoredContainer> - </DxcGrid> + <DxcGrid.GridItem row={{ start: 1, end: -1 }} column={-2}> + <ColoredContainer color="lightpink" height="100%"> + 5 + </ColoredContainer> + </DxcGrid.GridItem> </DxcGrid> </ExampleContainer> <Title title="Autoflow 'column'" level={4} /> <ExampleContainer> <DxcGrid templateColumns={["repeat(5, 1fr)"]} templateRows={["1fr", "1fr"]} autoFlow="column" autoColumns="1fr"> - <DxcGrid row={{ start: 1, end: -1 }} column={1}> - <ColoredContainer color="lightsalmon">1</ColoredContainer> - </DxcGrid> + <DxcGrid.GridItem row={{ start: 1, end: -1 }} column={1}> + <ColoredContainer height="100%">1</ColoredContainer> + </DxcGrid.GridItem> <ColoredContainer color="lightyellow">2</ColoredContainer> <ColoredContainer color="lightcyan">3</ColoredContainer> <ColoredContainer color="lightgreen">4</ColoredContainer> - <DxcGrid row={{ start: 1, end: -1 }} column={-2}> - <ColoredContainer color="lightpink">5</ColoredContainer> - </DxcGrid> + <DxcGrid.GridItem row={{ start: 1, end: -1 }} column={-2}> + <ColoredContainer color="lightpink" height="100%"> + 5 + </ColoredContainer> + </DxcGrid.GridItem> </DxcGrid> </ExampleContainer> </> @@ -125,19 +200,12 @@ const Container = styled.div<{ height?: string }>` ${({ height }) => height && `height: ${height}`}; `; -const Placeholder = styled.div<{ color?: string; width?: string; height?: string }>` - border: 1px solid #a46ede; - background-color: ${({ color }) => color ?? "#f2eafa;"}; - ${({ width }) => width && `width: ${width}`}; - ${({ height }) => height && `height: ${height}`}; -`; - const ColoredContainer = styled.div<{ color?: string; width?: string; height?: string }>` box-sizing: border-box; display: flex; justify-content: center; align-items: center; - background-color: ${({ color }) => color}; + background-color: ${({ color }) => color ?? "#e5d5f6"}; padding: 1rem; border: 1px solid #a46ede; border-radius: 0.5rem; diff --git a/lib/src/grid/Grid.tsx b/lib/src/grid/Grid.tsx index d61cff136..6f8313177 100644 --- a/lib/src/grid/Grid.tsx +++ b/lib/src/grid/Grid.tsx @@ -1,37 +1,32 @@ import React from "react"; import styled from "styled-components"; -import GridPropsType from "./types"; +import GridPropsType, { GridItemProps } from "./types"; const DxcGrid = (props: GridPropsType): JSX.Element => <Grid {...props} />; -const getGap = (gap: GridPropsType["gap"]) => { - if (typeof gap === "string") return `gap: ${gap};`; - - let res = ""; - if (gap.rowGap != null) res += `row-gap: ${gap.rowGap};`; - if (gap.columnGap != null) res += ` column-gap: ${gap.columnGap};`; - return res; -}; - const Grid = styled.div<GridPropsType>` display: grid; ${({ templateColumns }) => templateColumns && `grid-template-columns: ${templateColumns.join(" ")};`} ${({ templateRows }) => templateRows && `grid-template-rows: ${templateRows.join(" ")};`} ${({ templateAreas }) => templateAreas && `grid-template-areas: ${templateAreas.map((row) => `"${row}"`).join(" ")};`} - ${({ gap }) => gap != null && getGap(gap)} ${({ autoColumns }) => autoColumns && `grid-auto-columns: ${autoColumns};`} ${({ autoRows }) => autoRows && `grid-auto-rows: ${autoRows};`} ${({ autoFlow }) => autoFlow && `grid-auto-flow: ${autoFlow};`} + ${({ gap }) => + gap != null && + (typeof gap === "string" ? `gap: ${gap};` : `row-gap: ${gap.rowGap ?? ""}; column-gap: ${gap.columnGap ?? ""};`)} ${({ placeItems }) => placeItems && - `place-items: ${ - typeof placeItems === "string" ? placeItems : `${placeItems.alignItems} ${placeItems.justifyItems}` - };`} + (typeof placeItems === "string" + ? `place-items: ${placeItems}` + : `align-items: ${placeItems.alignItems ?? ""}; justify-items: ${placeItems.justifyItems ?? ""};`)} ${({ placeContent }) => placeContent && - `place-content: ${ - typeof placeContent === "string" ? placeContent : `${placeContent.alignContent} ${placeContent.justifyContent}` - };`} + (typeof placeContent === "string" + ? `place-content: ${placeContent}` + : `align-content: ${placeContent.alignContent ?? ""}; justify-content: ${placeContent.justifyContent ?? ""};`)} + + ${({ areaName }) => areaName && `grid-area: ${areaName};`} ${({ column }) => column && `grid-column: ${ @@ -39,10 +34,28 @@ const Grid = styled.div<GridPropsType>` };`} ${({ row }) => row && `grid-row: ${typeof row === "string" || typeof row === "number" ? row : `${row.start} / ${row.end};`};`} + ${({ placeSelf }) => + placeSelf && + (typeof placeSelf === "string" + ? `place-self: ${placeSelf}` + : `align-self: ${placeSelf.alignSelf ?? ""}; justify-self: ${placeSelf.justifySelf ?? ""};`)} +`; + +const GridItem = styled.div<GridItemProps>` ${({ areaName }) => areaName && `grid-area: ${areaName};`} + ${({ column }) => + column && + `grid-column: ${ + typeof column === "string" || typeof column === "number" ? column : `${column.start} / ${column.end};` + };`} + ${({ row }) => + row && `grid-row: ${typeof row === "string" || typeof row === "number" ? row : `${row.start} / ${row.end};`};`} ${({ placeSelf }) => placeSelf && - `place-self: ${typeof placeSelf === "string" ? placeSelf : `${placeSelf.alignSelf} ${placeSelf.justifySelf}`};`} + (typeof placeSelf === "string" + ? `place-self: ${placeSelf}` + : `align-self: ${placeSelf.alignSelf ?? ""}; justify-self: ${placeSelf.justifySelf ?? ""};`)} `; +DxcGrid.GridItem = GridItem; export default DxcGrid; diff --git a/lib/src/grid/types.ts b/lib/src/grid/types.ts index c17d4f579..719a52dc1 100644 --- a/lib/src/grid/types.ts +++ b/lib/src/grid/types.ts @@ -2,7 +2,26 @@ type Spaces = "0rem" | "0.125rem" | "0.25rem" | "0.5rem" | "1rem" | "1.5rem" | " type Gap = { rowGap?: Spaces; columnGap?: Spaces }; type GridCell = { start: number | string; end: number | string }; -type Props = { +export type GridItemProps = { + areaName?: string; + column?: number | string | GridCell; + row?: number | string | GridCell; + placeSelf?: + | { + alignSelf?: "auto" | "start" | "end" | "center" | "stretch" | "baseline"; + justifySelf?: "auto" | "start" | "end" | "center" | "stretch" | "baseline"; + } + | "auto" + | "start" + | "end" + | "center" + | "stretch" + | "baseline"; + as?: keyof HTMLElementTagNameMap; + children: React.ReactNode; +}; + +type Props = GridItemProps & { autoColumns?: string; autoRows?: string; autoFlow?: "row" | "column" | "row dense" | "column dense"; @@ -53,22 +72,6 @@ type Props = { templateAreas?: string[]; templateColumns?: string[]; templateRows?: string[]; - areaName?: string; - column?: number | string | GridCell; - row?: number | string | GridCell; - placeSelf?: - | { - alignSelf?: "auto" | "start" | "end" | "center" | "stretch" | "baseline"; - justifySelf?: "auto" | "start" | "end" | "center" | "stretch" | "baseline"; - } - | "auto" - | "start" - | "end" - | "center" - | "stretch" - | "baseline"; - as?: keyof HTMLElementTagNameMap; - children: React.ReactNode; }; export default Props; From 4ece72b610bc549a564efe2239fab1129914e796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20G=C3=B3mez=20Pinta?= <44321109+GomezIvann@users.noreply.github.com> Date: Tue, 25 Apr 2023 16:17:42 +0200 Subject: [PATCH 7/8] Adding new types to restrict props --- lib/src/grid/Grid.stories.tsx | 2 +- lib/src/grid/types.ts | 79 +++++++++++------------------------ 2 files changed, 25 insertions(+), 56 deletions(-) diff --git a/lib/src/grid/Grid.stories.tsx b/lib/src/grid/Grid.stories.tsx index 8486aa517..c5813d587 100644 --- a/lib/src/grid/Grid.stories.tsx +++ b/lib/src/grid/Grid.stories.tsx @@ -153,7 +153,7 @@ export const Chromatic = () => ( <DxcGrid.GridItem row={3}> <ColoredContainer height="50px">4</ColoredContainer> </DxcGrid.GridItem> - <DxcGrid.GridItem row={{ start: 1, end: 2 }} column={{ start: 5, end: 7 }}> + <DxcGrid.GridItem row={{ start: 1, end: 2 }} column={{ start: 5, end: "span 2" }}> <ColoredContainer height="50px">2</ColoredContainer> </DxcGrid.GridItem> </DxcGrid> diff --git a/lib/src/grid/types.ts b/lib/src/grid/types.ts index 719a52dc1..d4aeaba3a 100644 --- a/lib/src/grid/types.ts +++ b/lib/src/grid/types.ts @@ -1,22 +1,32 @@ type Spaces = "0rem" | "0.125rem" | "0.25rem" | "0.5rem" | "1rem" | "1.5rem" | "2rem" | "3rem" | "4rem" | "5rem"; -type Gap = { rowGap?: Spaces; columnGap?: Spaces }; +type Gap = { rowGap: Spaces; columnGap?: Spaces } | { rowGap?: Spaces; columnGap: Spaces } | Spaces; type GridCell = { start: number | string; end: number | string }; +type PlaceSelfValues = "auto" | "start" | "end" | "center" | "stretch" | "baseline"; +type PlaceContentValues = + | "normal" + | "start" + | "end" + | "center" + | "stretch" + | "space-between" + | "space-around" + | "space-evenly" + | "baseline"; +type PlaceItemsValues = "normal" | "start" | "end" | "center" | "stretch" | "baseline"; +type PlaceObject<Type, S extends string> = { + [Property in keyof Type as `${string & Property}${Capitalize<string & S>}`]: Type[Property]; +}; +type PlaceGeneric<PlaceValues, Element extends string> = + | PlaceObject<{ justify?: PlaceValues; align: PlaceValues }, Element> + | PlaceObject<{ justify: PlaceValues; align?: PlaceValues }, Element> + | PlaceValues; + export type GridItemProps = { areaName?: string; column?: number | string | GridCell; row?: number | string | GridCell; - placeSelf?: - | { - alignSelf?: "auto" | "start" | "end" | "center" | "stretch" | "baseline"; - justifySelf?: "auto" | "start" | "end" | "center" | "stretch" | "baseline"; - } - | "auto" - | "start" - | "end" - | "center" - | "stretch" - | "baseline"; + placeSelf?: PlaceGeneric<PlaceSelfValues, "self">; as?: keyof HTMLElementTagNameMap; children: React.ReactNode; }; @@ -26,49 +36,8 @@ type Props = GridItemProps & { autoRows?: string; autoFlow?: "row" | "column" | "row dense" | "column dense"; gap?: Spaces | Gap; - placeContent?: - | { - alignContent?: - | "normal" - | "start" - | "end" - | "center" - | "stretch" - | "space-between" - | "space-around" - | "space-evenly" - | "baseline"; - justifyContent?: - | "normal" - | "start" - | "end" - | "center" - | "stretch" - | "space-between" - | "space-around" - | "space-evenly" - | "baseline"; - } - | "normal" - | "start" - | "end" - | "center" - | "stretch" - | "space-between" - | "space-around" - | "space-evenly" - | "baseline"; - placeItems?: - | { - alignItems?: "normal" | "start" | "end" | "center" | "stretch" | "baseline"; - justifyItems?: "normal" | "start" | "end" | "center" | "stretch" | "baseline"; - } - | "normal" - | "start" - | "end" - | "center" - | "stretch" - | "baseline"; + placeContent?: PlaceGeneric<PlaceContentValues, "content">; + placeItems?: PlaceGeneric<PlaceItemsValues, "items">; templateAreas?: string[]; templateColumns?: string[]; templateRows?: string[]; From e33664d9acb052fda07ae4a591412e7f559a69e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20G=C3=B3mez=20Pinta?= <44321109+GomezIvann@users.noreply.github.com> Date: Thu, 27 Apr 2023 09:21:53 +0200 Subject: [PATCH 8/8] Variable refactor for better undestanding in Grid --- lib/src/grid/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/grid/types.ts b/lib/src/grid/types.ts index d4aeaba3a..b5ca51ce9 100644 --- a/lib/src/grid/types.ts +++ b/lib/src/grid/types.ts @@ -14,8 +14,8 @@ type PlaceContentValues = | "space-evenly" | "baseline"; type PlaceItemsValues = "normal" | "start" | "end" | "center" | "stretch" | "baseline"; -type PlaceObject<Type, S extends string> = { - [Property in keyof Type as `${string & Property}${Capitalize<string & S>}`]: Type[Property]; +type PlaceObject<Type, Suffix extends string> = { + [Property in keyof Type as `${string & Property}${Capitalize<string & Suffix>}`]: Type[Property]; }; type PlaceGeneric<PlaceValues, Element extends string> = | PlaceObject<{ justify?: PlaceValues; align: PlaceValues }, Element>