From cc9fc621694239afd9ab404067715a14962a2d5d 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, 31 Mar 2025 14:00:31 +0200 Subject: [PATCH 1/4] Grid redesign --- apps/website/pages/components/grid/code.tsx | 17 + apps/website/pages/components/grid/index.tsx | 24 +- .../pages/components/grid/specifications.tsx | 21 - apps/website/pages/components/grid/usage.tsx | 21 - .../components/flex/FlexPageLayout.tsx | 6 +- .../components/flex/code/FlexCodePage.tsx | 18 +- .../flex/overview/FlexOverviewPage.tsx | 2 +- .../components/grid/GridPageLayout.tsx | 18 +- .../components/grid/code/GridCodePage.tsx | 650 +++++++++--------- .../grid/overview/GridOverviewPage.tsx | 111 +++ .../components/grid/usage/GridUsagePage.tsx | 75 -- packages/lib/src/grid/types.ts | 52 +- 12 files changed, 517 insertions(+), 498 deletions(-) create mode 100644 apps/website/pages/components/grid/code.tsx delete mode 100644 apps/website/pages/components/grid/specifications.tsx delete mode 100644 apps/website/pages/components/grid/usage.tsx create mode 100644 apps/website/screens/components/grid/overview/GridOverviewPage.tsx delete mode 100644 apps/website/screens/components/grid/usage/GridUsagePage.tsx diff --git a/apps/website/pages/components/grid/code.tsx b/apps/website/pages/components/grid/code.tsx new file mode 100644 index 0000000000..5f61370cc9 --- /dev/null +++ b/apps/website/pages/components/grid/code.tsx @@ -0,0 +1,17 @@ +import Head from "next/head"; +import type { ReactElement } from "react"; +import GridPageLayout from "screens/components/grid/GridPageLayout"; +import GridCodePage from "screens/components/grid/code/GridCodePage"; + +const Code = () => ( + <> + + Grid code — Halstack Design System + + + +); + +Code.getLayout = (page: ReactElement) => {page}; + +export default Code; diff --git a/apps/website/pages/components/grid/index.tsx b/apps/website/pages/components/grid/index.tsx index fc9af43e80..f665d13caa 100644 --- a/apps/website/pages/components/grid/index.tsx +++ b/apps/website/pages/components/grid/index.tsx @@ -1,21 +1,17 @@ import Head from "next/head"; import type { ReactElement } from "react"; import GridPageLayout from "screens/components/grid/GridPageLayout"; -import GridCodePage from "screens/components/grid/code/GridCodePage"; +import GridOverviewPage from "screens/components/grid/overview/GridOverviewPage"; -const Index = () => { - return ( - <> - - Grid — Halstack Design System - - - - ); -}; +const Index = () => ( + <> + + Grid — Halstack Design System + + + +); -Index.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; +Index.getLayout = (page: ReactElement) => {page}; export default Index; diff --git a/apps/website/pages/components/grid/specifications.tsx b/apps/website/pages/components/grid/specifications.tsx deleted file mode 100644 index 1ae2513acb..0000000000 --- a/apps/website/pages/components/grid/specifications.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import Head from "next/head"; -import type { ReactElement } from "react"; -import GridPageLayout from "screens/components/grid/GridPageLayout"; -import GridSpecsPage from "screens/components/grid/specs/GridSpecsPage"; - -const Specifications = () => { - return ( - <> - - Grid Specs — Halstack Design System - - - - ); -}; - -Specifications.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; - -export default Specifications; diff --git a/apps/website/pages/components/grid/usage.tsx b/apps/website/pages/components/grid/usage.tsx deleted file mode 100644 index 9d14b142a0..0000000000 --- a/apps/website/pages/components/grid/usage.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import Head from "next/head"; -import type { ReactElement } from "react"; -import GridPageLayout from "screens/components/grid/GridPageLayout"; -import GridUsagePage from "screens/components/grid/usage/GridUsagePage"; - -const Usage = () => { - return ( - <> - - Grid Usage — Halstack Design System - - - - ); -}; - -Usage.getLayout = function getLayout(page: ReactElement) { - return {page}; -}; - -export default Usage; diff --git a/apps/website/screens/components/flex/FlexPageLayout.tsx b/apps/website/screens/components/flex/FlexPageLayout.tsx index d3a5cb052b..115d1feb3b 100644 --- a/apps/website/screens/components/flex/FlexPageLayout.tsx +++ b/apps/website/screens/components/flex/FlexPageLayout.tsx @@ -16,9 +16,9 @@ const FlexPageHeading = ({ children }: { children: ReactNode }) => { - The flex component allows users to build flexible box module based layouts. It serves as a technical - component that abstracts users from working directly with CSS flexible box layout and helps them write more - semantic layouts. + The flex component allows building flexible box module based layouts. It serves as a technical component + that abstracts users from working directly with CSS flexible box layout and helps them write more semantic + layouts. diff --git a/apps/website/screens/components/flex/code/FlexCodePage.tsx b/apps/website/screens/components/flex/code/FlexCodePage.tsx index a9539e54a0..88bf1a8e9b 100644 --- a/apps/website/screens/components/flex/code/FlexCodePage.tsx +++ b/apps/website/screens/components/flex/code/FlexCodePage.tsx @@ -10,8 +10,8 @@ import TableCode, { ExtendedTableCode } from "@/common/TableCode"; import StatusBadge from "@/common/StatusBadge"; const gapTypeString = `{ - rowGap: string; - columnGap: string + columnGap: string; + rowGap: string; }`; const sections = [ @@ -19,12 +19,14 @@ const sections = [ title: "Props", content: ( - - Name - Type - Description - Default - + + + Name + Type + Description + Default + + alignContent diff --git a/apps/website/screens/components/flex/overview/FlexOverviewPage.tsx b/apps/website/screens/components/flex/overview/FlexOverviewPage.tsx index be0fb0d1eb..a22788098f 100644 --- a/apps/website/screens/components/flex/overview/FlexOverviewPage.tsx +++ b/apps/website/screens/components/flex/overview/FlexOverviewPage.tsx @@ -24,7 +24,7 @@ const sections = [ ), }, { - title: "The flexible box layout module", + title: "The flexible box layout", content: ( <> diff --git a/apps/website/screens/components/grid/GridPageLayout.tsx b/apps/website/screens/components/grid/GridPageLayout.tsx index 5e9f243492..3733d96a3c 100644 --- a/apps/website/screens/components/grid/GridPageLayout.tsx +++ b/apps/website/screens/components/grid/GridPageLayout.tsx @@ -1,4 +1,4 @@ -import { DxcParagraph, DxcFlex, DxcLink } from "@dxc-technology/halstack-react"; +import { DxcParagraph, DxcFlex } from "@dxc-technology/halstack-react"; import PageHeading from "@/common/PageHeading"; import TabsPageHeading from "@/common/TabsPageLayout"; import ComponentHeading from "@/common/ComponentHeading"; @@ -6,9 +6,8 @@ import { ReactNode } from "react"; const GridPageHeading = ({ children }: { children: ReactNode }) => { const tabs = [ - { label: "Code", path: "/components/grid" }, - { label: "Usage", path: "/components/grid/usage" }, - { label: "Specifications", path: "/components/grid/specifications" }, + { label: "Overview", path: "/components/grid" }, + { label: "Code", path: "/components/grid/code" }, ]; return ( @@ -17,14 +16,11 @@ const GridPageHeading = ({ children }: { children: ReactNode }) => { - Grid allows users to build applications based on{" "} - - CSS Grid Layout - - . It is a technical component that abstracts users from working directly with CSS Grid properties and allows - them to write more consistent and semantic layouts. + The grid component allows building applications based on the CSS grid layout module. It is a technical + component that abstracts users from working directly with grid properties and allows them to write more + consistent and semantic layouts. - + {children} diff --git a/apps/website/screens/components/grid/code/GridCodePage.tsx b/apps/website/screens/components/grid/code/GridCodePage.tsx index 962ff77387..6a013cbd07 100644 --- a/apps/website/screens/components/grid/code/GridCodePage.tsx +++ b/apps/website/screens/components/grid/code/GridCodePage.tsx @@ -6,210 +6,224 @@ import QuickNavContainerLayout from "@/common/QuickNavContainerLayout"; import Example from "@/common/example/Example"; import basic from "./examples/basic"; import layout from "./examples/layout"; -import TableCode from "@/common/TableCode"; +import TableCode, { ExtendedTableCode } from "@/common/TableCode"; import StatusBadge from "@/common/StatusBadge"; -const coreSpacingTokensTypeString = `'0rem' | '0.125rem' | '0.25rem' | '0.5rem' | '0.75rem' | '1rem' | '1.5rem' | '2rem' | '2.5rem' | '3rem' | '3.5rem' | '4rem' | '5rem' | '6rem' | '7rem'`; +const gapTypeString = `{ + columnGap: string; + rowGap: string; +}`; const sections = [ { title: "Props", content: ( - - Name - Type - Description - Default - - - autoColumns - - string - - - Sets the grid-auto-columns CSS property. See{" "} - - MDN - {" "} - for further information. - - - 'auto' - - - - autoFlow - - 'row' | 'column' | 'row dense' | 'column dense' - - - Sets the grid-auto-flow CSS property. See{" "} - - MDN - {" "} - for further information. - - - 'row' - - - - autoRows - - string - - - Sets the grid-auto-rows CSS property. See{" "} - - MDN - {" "} - for further information. - - - 'auto' - - - - gap - - {coreSpacingTokensTypeString} | Gap - - - Sets the gap CSS property. See{" "} - - MDN - {" "} - for further information. It can be either a value from the range or an object with the following properties: -
    -
  • - rowGap: gutter between rows. -
  • -
  • - columnGap: gutter between columns. -
  • -
- - - '0rem' - - - - placeContent - - - 'normal' | 'start' | 'end' | 'center' | 'stretch' | 'space-between' | 'space-around' | 'space-evenly' | - 'baseline' | PlaceContent - - - - Sets the place-content CSS property. See{" "} - - MDN - {" "} - for further information. It can be either a value from the range or an object with the following properties: -
    -
  • - justifyContent: aligns the grid along the inline (row) axis. -
  • -
  • - alignContent: aligns the grid along the block (column) axis. -
  • -
- - - 'normal' - - - - placeItems - - 'normal' | 'start' | 'end' | 'center' | 'stretch' | 'baseline' | PlaceItems - - - Sets the place-items CSS property. See{" "} - - MDN - {" "} - for further information. It can be either a value from the range or an object with the following properties: -
    -
  • - justifyItems: aligns grid items along the inline (row) axis. -
  • -
  • - alignItems: aligns grid items along the block (column) axis. -
  • -
- - - 'normal' - - - - templateAreas - - string[] - - - Sets the grid-template-areas CSS property. See{" "} - - MDN - {" "} - for further information. - - - - - - templateColumns - - string[] - - - Sets the grid-template-columns CSS property. See{" "} - - MDN - {" "} - for further information. - - - - - - templateRows - - string[] - - - Sets the grid-template-rows CSS property. See{" "} - - MDN - {" "} - for further information. - - - - - - as - - keyof HTMLElementTagNameMap - - Sets a custom HTML tag. - - 'div' - - - - - - - children - - - - React.ReactNode - - Custom content inside the grid container. - - - + + + Name + Type + Description + Default + + + + + as + + keyof HTMLElementTagNameMap + + Sets a custom HTML tag. + + 'div' + + + + autoColumns + + string + + + Sets the grid-auto-columns CSS property. See{" "} + + MDN + {" "} + for further information. + + + 'auto' + + + + autoFlow + + 'row' | 'column' | 'row dense' | 'column dense' + + + Sets the grid-auto-flow CSS property. See{" "} + + MDN + {" "} + for further information. + + + 'row' + + + + autoRows + + string + + + Sets the grid-auto-rows CSS property. See{" "} + + MDN + {" "} + for further information. + + + 'auto' + + + + + + + children + + + + React.ReactNode + + Custom content inside the grid container. + - + + + gap + + Gap +

+ being Message an object with the following properties: +

+ {gapTypeString} + + + Sets the gap CSS property. See{" "} + + MDN + {" "} + for further information. It can be either a value from the range or an object with the following + properties: +
    +
  • + rowGap: gutter between rows. +
  • +
  • + columnGap: gutter between columns. +
  • +
+ + + '0rem' + + + + placeContent + + + 'normal' | 'start' | 'end' | 'center' | 'stretch' | 'space-between' | 'space-around' | 'space-evenly' | + 'baseline' | PlaceContent + + + + Sets the place-content CSS property. See{" "} + + MDN + {" "} + for further information. It can be either a value from the range or an object with the following + properties: +
    +
  • + justifyContent: aligns the grid along the inline (row) axis. +
  • +
  • + alignContent: aligns the grid along the block (column) axis. +
  • +
+ + + 'normal' + + + + placeItems + + 'normal' | 'start' | 'end' | 'center' | 'stretch' | 'baseline' | PlaceItems + + + Sets the place-items CSS property. See{" "} + + MDN + {" "} + for further information. It can be either a value from the range or an object with the following + properties: +
    +
  • + justifyItems: aligns grid items along the inline (row) axis. +
  • +
  • + alignItems: aligns grid items along the block (column) axis. +
  • +
+ + + 'normal' + + + + templateAreas + + string[] + + + Sets the grid-template-areas CSS property. See{" "} + + MDN + {" "} + for further information. + + - + + + templateColumns + + string[] + + + Sets the grid-template-columns CSS property. See{" "} + + MDN + {" "} + for further information. + + - + + + templateRows + + string[] + + + Sets the grid-template-rows CSS property. See{" "} + + MDN + {" "} + for further information. + + - + +
), }, @@ -234,117 +248,121 @@ const sections = [ title: "Props", content: ( - - Name - Type - Description - Default - - - areaName - - string - - - Sets the name of an item so that it can be referenced by a template created with the{" "} - grid-template-areas property. - - - - - - column - - number | string | GridCell - - - Sets the grid-column CSS property. See{" "} - - MDN - {" "} - for further information. It can be either a value from the range or an object with the following - properties: -
    -
  • - start: starting position within the grid column. -
  • -
  • - end: ending position within the grid column. -
  • -
- - - - - - row - - number | string | GridCell - - - Sets the grid-row CSS property. See{" "} - - MDN - {" "} - for further information. It can be either a value from the range or an object with the following - properties: -
    -
  • - start: starting position within the grid row. -
  • -
  • - end: ending position within the grid row. -
  • -
- - - - - - placeSelf - - 'auto' | 'start' | 'end' | 'center' | 'stretch' | 'baseline' | PlaceSelf - - - Sets the place-self CSS property. See{" "} - - MDN - {" "} - for further information. It can be either a value from the range or an object with the following - properties: -
    -
  • - justifySelf: aligns a grid item inside a cell along the inline (row) axis. -
  • -
  • - alignSelf: aligns a grid item inside a cell along the block (column) axis. -
  • -
- - - 'auto' - - - - as - - keyof HTMLElementTagNameMap - - Sets a custom HTML tag. - - 'div' - - - - - - - children - - - - React.ReactNode - - Custom content inside the grid item container. - - - + + + Name + Type + Description + Default + + + + + areaName + + string + + + Sets the name of an item so that it can be referenced by a template created with the{" "} + grid-template-areas property. + + - + + + as + + keyof HTMLElementTagNameMap + + Sets a custom HTML tag. + + 'div' + + + + + + + children + + + + React.ReactNode + + Custom content inside the grid item container. + - + + + column + + number | string | GridCell + + + Sets the grid-column CSS property. See{" "} + + MDN + {" "} + for further information. It can be either a value from the range or an object with the following + properties: +
    +
  • + start: starting position within the grid column. +
  • +
  • + end: ending position within the grid column. +
  • +
+ + - + + + placeSelf + + 'auto' | 'start' | 'end' | 'center' | 'stretch' | 'baseline' | PlaceSelf + + + Sets the place-self CSS property. See{" "} + + MDN + {" "} + for further information. It can be either a value from the range or an object with the following + properties: +
    +
  • + justifySelf: aligns a grid item inside a cell along the inline (row) axis. +
  • +
  • + alignSelf: aligns a grid item inside a cell along the block (column) axis. +
  • +
+ + + 'auto' + + + + row + + number | string | GridCell + + + Sets the grid-row CSS property. See{" "} + + MDN + {" "} + for further information. It can be either a value from the range or an object with the following + properties: +
    +
  • + start: starting position within the grid row. +
  • +
  • + end: ending position within the grid row. +
  • +
+ + - + +
), }, @@ -365,15 +383,13 @@ const sections = [ }, ]; -const GridCodePage = () => { - return ( - - - - - - - ); -}; +const GridCodePage = () => ( + + + + + + +); export default GridCodePage; diff --git a/apps/website/screens/components/grid/overview/GridOverviewPage.tsx b/apps/website/screens/components/grid/overview/GridOverviewPage.tsx new file mode 100644 index 0000000000..9f9c69a90a --- /dev/null +++ b/apps/website/screens/components/grid/overview/GridOverviewPage.tsx @@ -0,0 +1,111 @@ +import { DxcBulletedList, DxcFlex, DxcLink, DxcParagraph } from "@dxc-technology/halstack-react"; +import DocFooter from "@/common/DocFooter"; +import QuickNavContainer from "@/common/QuickNavContainer"; +import QuickNavContainerLayout from "@/common/QuickNavContainerLayout"; +import Code from "@/common/Code"; +import Link from "next/link"; + +const sections = [ + { + title: "Introduction", + content: ( + <> + + The grid component is a powerful layout tool that simplifies the creation of complex and responsive designs. + It allows developers to create structured layouts using rows and columns, making it easier to manage spacing + and alignment within a design. + + + ), + }, + { + title: "The grid layout", + content: ( + <> + + The grid layout module is a two-dimensional layout system for the web. It allows you to create complex layouts + using rows and columns, making it easier to design responsive web pages. The grid layout provides a more + efficient way to align and distribute space among items in a container, even when their size is unknown or + dynamic. + + + Below, we share a series of essential links to help you understand and use the grid component correctly. If + you are not acquainted with these concepts, we strongly recommend taking a moment to review them: + + + + + MDN web docs: CSS grid layout + + + + + Google web.dev: Grid + + + + + ), + }, + { + title: "Best practices", + content: ( + + + Use grid for complex layouts: the grid component is ideal for creating complex layouts with + multiple rows and columns. It allows you to create responsive designs that adapt to different screen sizes. + + + Keep it simple: while the grid component is powerful, it's essential to keep your layouts as + simple as possible. Avoid overcomplicating your designs with too many nested grids or complex structures, + which can reduce the readability and maintainability of your code. + + + Use grid items correctly: they are represented by the DxcGrid.Item tag and + should be used when the decision to follow the Grid layout pattern is assumed only by the parent container. + Ensure that you use the grid items correctly within the grid container. The grid items should be direct + descendants of the grid container to ensure proper alignment and spacing. + + + Prioritize fluidity over fixed sizes: avoid using fixed widths or heights when possible, as + they can lead to layout issues on different devices. Instead, leverage grid properties like{" "} + templateColumns, templateRows, and templateAreas to create scalable + designs. + + + Use grid gaps wisely: the grid component provides a gap property to control spacing between + items. Use this property to create consistent spacing between items and avoid excessive margins or padding. + + + Leverage alignment and justification: use placeContent and{" "} + placeItems strategically to control content positioning within the grid container, ensuring a + well-structured and visually balanced layout. + + + Ensure consistency with design tokens: whenever possible, use the design tokens provided by + the Halstack Design System to maintain visual and functional consistency across applications, even though the + component allows custom values. + + + Combine with other layout techniques: grid is powerful but not always the best tool for every + scenario. Consider using the{" "} + + flex + {" "} + component for one-dimensional layouts or stacked components with simpler structures. + + + ), + }, +]; + +const GridOverviewPage = () => ( + + + + + + +); + +export default GridOverviewPage; diff --git a/apps/website/screens/components/grid/usage/GridUsagePage.tsx b/apps/website/screens/components/grid/usage/GridUsagePage.tsx deleted file mode 100644 index 28259f9678..0000000000 --- a/apps/website/screens/components/grid/usage/GridUsagePage.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import { DxcFlex, DxcParagraph } from "@dxc-technology/halstack-react"; -import DocFooter from "@/common/DocFooter"; -import QuickNavContainer from "@/common/QuickNavContainer"; -import QuickNavContainerLayout from "@/common/QuickNavContainerLayout"; -import Code from "@/common/Code"; - -const sections = [ - { - title: "Usage", - content: ( - <> - - The Grid component allows for both row and column layouts while allowing for a lot of flexibility of item - placement within the grid itself. - - - ), - }, - { - title: "Layout, Spacing, and Placement", - content: ( - <> - - The layout type can be specified using the grid-auto-flow property. This property lets you - control how the auto-placement algorithm works, determining exactly how auto-placed items get flowed into the - grid. Use the gap property to set the space between items and the placement properties{" "} - placeContent and placeItems for more specific controls of how individual items stack - or align within the grid. - - - ), - }, - { - title: "Grid Templates", - content: ( - <> - - You can use templates to define grid areas, columns, and rows. The grid-template-areas property - is used to establish cells within a grid and assign them names. grid-template-columns defines the - line names and track sizing functions of the grid columns while grid-template-rows defines the - line names and track sizing functions of the grid columns. - - - ), - }, - { - title: "Grid Items", - content: ( - <> - - The Grid items are direct descendants of a grid container. They are represented by the{" "} - DxcGrid.Item tag and should be used when the decision to follow the Grid layout pattern is - assumed only by the parent container. - - - In case you are building a complex Grid layout with several nested grid containers, DxcGrid.Item{" "} - becomes very limited and therefore, you will have to wrap the children with DxcGrid. - - - ), - }, -]; - -const GridUsagePage = () => { - return ( - - - - - - - ); -}; - -export default GridUsagePage; diff --git a/packages/lib/src/grid/types.ts b/packages/lib/src/grid/types.ts index 1d4d198f67..49fd152de4 100644 --- a/packages/lib/src/grid/types.ts +++ b/packages/lib/src/grid/types.ts @@ -1,27 +1,25 @@ import { ReactNode } from "react"; -import { CoreSpacingTokensType } from "../common/coreTokens"; -type Gap = { rowGap: CoreSpacingTokensType; columnGap?: CoreSpacingTokensType } | { rowGap?: CoreSpacingTokensType; columnGap: CoreSpacingTokensType } | CoreSpacingTokensType; -type GridCell = { start: number | string; end: number | string }; - -type PlaceSelfValues = "auto" | "start" | "end" | "center" | "stretch" | "baseline"; +type Gap = string | { columnGap?: string; rowGap: string; } | { columnGap: string; rowGap?: string; }; +type GridCell = { end: number | string; start: number | string; }; +type PlaceSelfValues = "auto" | "baseline" | "center" | "end" | "start" | "stretch"; type PlaceContentValues = - | "normal" - | "start" - | "end" + | "baseline" | "center" - | "stretch" - | "space-between" + | "end" + | "normal" | "space-around" + | "space-between" | "space-evenly" - | "baseline"; -type PlaceItemsValues = "normal" | "start" | "end" | "center" | "stretch" | "baseline"; + | "start" + | "stretch"; +type PlaceItemsValues = "baseline" | "center" | "end" | "normal" | "start" | "stretch"; type PlaceObject = { [Property in keyof Type as `${string & Property}${Capitalize}`]: Type[Property]; }; type PlaceGeneric = - | PlaceObject<{ justify?: PlaceValues; align: PlaceValues }, Element> - | PlaceObject<{ justify: PlaceValues; align?: PlaceValues }, Element> + | PlaceObject<{ align: PlaceValues; justify?: PlaceValues; }, Element> + | PlaceObject<{ align?: PlaceValues; justify: PlaceValues; }, Element> | PlaceValues; export type GridItemProps = { @@ -29,18 +27,20 @@ export type GridItemProps = { * Sets the name of an item so that it can be referenced by a template created with the grid-template-areas property. */ areaName?: string; + /** + * Sets a custom HTML tag. + */ + as?: keyof HTMLElementTagNameMap; + /** + * Custom content inside the grid container. + */ + children: ReactNode; /** * Sets the grid-column CSS property. * * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-column */ column?: number | string | GridCell; - /** - * Sets the grid-row CSS property. - * - * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-row - */ - row?: number | string | GridCell; /** * Sets the place-self CSS property. * @@ -48,13 +48,11 @@ export type GridItemProps = { */ placeSelf?: PlaceGeneric; /** - * Sets a custom HTML tag. - */ - as?: keyof HTMLElementTagNameMap; - /** - * Custom content inside the grid container. + * Sets the grid-row CSS property. + * + * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/grid-row */ - children: ReactNode; + row?: number | string | GridCell; }; type Props = GridItemProps & { @@ -81,7 +79,7 @@ type Props = GridItemProps & { * * See MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/gap */ - gap?: CoreSpacingTokensType | Gap; + gap?: Gap; /** * Sets the place-content CSS property. * From a4424b9c9104df5f209b8e05fc2c3c6de36e6c3d 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, 31 Mar 2025 14:07:52 +0200 Subject: [PATCH 2/4] Grid stories updated --- packages/lib/src/grid/Grid.stories.tsx | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/lib/src/grid/Grid.stories.tsx b/packages/lib/src/grid/Grid.stories.tsx index 392dc9e335..738dccb151 100644 --- a/packages/lib/src/grid/Grid.stories.tsx +++ b/packages/lib/src/grid/Grid.stories.tsx @@ -32,7 +32,6 @@ const ColoredContainer = styled.div<{ color?: string; width?: string; height?: s font-size: 1.5rem; font-weight: bold; color: #a46ede; - ${({ width }) => width && `width: ${width}`}; ${({ height }) => height && `height: ${height}`}; `; @@ -101,7 +100,7 @@ const Grid = () => ( templateColumns={["repeat(4, 1fr)"]} templateRows={["40px", "200px", "60px"]} templateAreas={["header header header header", "sidenav main main main", "sidenav footer footer footer"]} - gap={{ rowGap: "0.5rem", columnGap: "1rem" }} + gap={{ rowGap: "var(--spacing-gap-s)", columnGap: "var(--spacing-gap-ml)" }} > @@ -119,7 +118,7 @@ const Grid = () => ( <ExampleContainer> - <DxcGrid templateColumns={["1fr", "1fr", "1fr"]} templateRows={["1fr", "3fr", "1fr"]} gap="0.5rem"> + <DxcGrid templateColumns={["1fr", "1fr", "1fr"]} templateRows={["1fr", "3fr", "1fr"]} gap="var(--spacing-gap-s)"> <DxcGrid.Item column={{ start: 1, end: -1 }}> <ColoredContainer color="yellow" height="100%"> Header @@ -134,7 +133,7 @@ const Grid = () => ( column={{ start: 2, end: -1 }} templateRows={["repeat(4, 1fr)"]} templateColumns={["repeat(2, 1fr)"]} - gap="1rem" + gap="var(--spacing-gap-ml)" > <ColoredContainer /> <ColoredContainer /> From c40e4469abf2c09856df3f53acca5224adcfeff0 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, 31 Mar 2025 14:14:37 +0200 Subject: [PATCH 3/4] Replacing gap values with design tokens --- apps/website/screens/common/QuickNavContainer.tsx | 2 +- .../screens/components/dialog/code/examples/withContent.ts | 2 +- apps/website/screens/components/grid/code/examples/layout.tsx | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/website/screens/common/QuickNavContainer.tsx b/apps/website/screens/common/QuickNavContainer.tsx index 1a7e1f3f82..39b72437e7 100644 --- a/apps/website/screens/common/QuickNavContainer.tsx +++ b/apps/website/screens/common/QuickNavContainer.tsx @@ -31,7 +31,7 @@ const getSubSectionsLinks = (sections: SectionType[]) => { const DxcQuickNavContainer = ({ title = "On this page", sections, startHeadingLevel = 1 }: QuickNavContainerTypes): JSX.Element => ( <MainContainer> - <DxcGrid gap="3rem" templateColumns={["minmax(0, 1fr)"]}> + <DxcGrid gap="var(--spacing-gap-xl)" templateColumns={["minmax(0, 1fr)"]}> {sections.map((section) => ( <Section key={`section-${section.title}`} diff --git a/apps/website/screens/components/dialog/code/examples/withContent.ts b/apps/website/screens/components/dialog/code/examples/withContent.ts index c002921d09..8f42983e2d 100644 --- a/apps/website/screens/components/dialog/code/examples/withContent.ts +++ b/apps/website/screens/components/dialog/code/examples/withContent.ts @@ -22,7 +22,7 @@ const code = `() => { <DxcInset space="1.5rem"> <DxcGrid gap="2rem"> <DxcHeading level={2} text="Delivery address" weight="normal" /> - <DxcGrid templateColumns={["1fr", "1fr"]} templateColumns={["1fr", "1fr"]} gap="1rem"> + <DxcGrid templateColumns={["1fr", "1fr"]} templateColumns={["1fr", "1fr"]} gap="var(--spacing-gap-ml)"> <DxcTextInput label="Street" size="fillParent" /> <DxcTextInput label="City" size="fillParent" /> <DxcGrid.Item column={{ start: 1, end: 3 }}> diff --git a/apps/website/screens/components/grid/code/examples/layout.tsx b/apps/website/screens/components/grid/code/examples/layout.tsx index b6906c1f40..8ba4510b6e 100644 --- a/apps/website/screens/components/grid/code/examples/layout.tsx +++ b/apps/website/screens/components/grid/code/examples/layout.tsx @@ -5,7 +5,7 @@ const code = `() => { return ( <DxcInset space="2rem"> <DxcGrid - gap={{ rowGap: "0.5rem", columnGap: "1rem" }} + gap={{ rowGap: "var(--spacing-gap-s)", columnGap: "var(--spacing-gap-ml)" }} templateColumns={["repeat(4, 1fr)"]} templateRows={["40px", "200px", "60px"]} templateAreas={[ @@ -17,7 +17,7 @@ const code = `() => { <DxcGrid.Item areaName="header" as="header"> <Placeholder height="100%" /> </DxcGrid.Item> - <DxcGrid templateColumns={["repeat(4, 1fr)"]} gap="0.25rem" areaName="main" as="main"> + <DxcGrid templateColumns={["repeat(4, 1fr)"]} gap="var(--spacing-gap-xs)" areaName="main" as="main"> <Placeholder /> <Placeholder /> <Placeholder /> From dfd2bed17810764add0b9d5e21bbab68fbd462c7 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, 31 Mar 2025 17:55:58 +0200 Subject: [PATCH 4/4] Grid documentation updates --- .../components/grid/code/examples/layout.tsx | 2 +- .../grid/overview/GridOverviewPage.tsx | 2 +- .../components/grid/specs/GridSpecsPage.tsx | 37 ------------------ .../grid/specs/images/grid-autoFlow-specs.png | Bin 9109 -> 0 bytes .../specs/images/grid-templates-specs.png | Bin 15766 -> 0 bytes 5 files changed, 2 insertions(+), 39 deletions(-) delete mode 100644 apps/website/screens/components/grid/specs/GridSpecsPage.tsx delete mode 100644 apps/website/screens/components/grid/specs/images/grid-autoFlow-specs.png delete mode 100644 apps/website/screens/components/grid/specs/images/grid-templates-specs.png diff --git a/apps/website/screens/components/grid/code/examples/layout.tsx b/apps/website/screens/components/grid/code/examples/layout.tsx index 8ba4510b6e..aaa2961e6a 100644 --- a/apps/website/screens/components/grid/code/examples/layout.tsx +++ b/apps/website/screens/components/grid/code/examples/layout.tsx @@ -7,7 +7,7 @@ const code = `() => { <DxcGrid gap={{ rowGap: "var(--spacing-gap-s)", columnGap: "var(--spacing-gap-ml)" }} templateColumns={["repeat(4, 1fr)"]} - templateRows={["40px", "200px", "60px"]} + templateRows={["var(--height-xl)", "200px", "var(--height-xxxl)"]} templateAreas={[ "header header header header", "sidenav main main main", diff --git a/apps/website/screens/components/grid/overview/GridOverviewPage.tsx b/apps/website/screens/components/grid/overview/GridOverviewPage.tsx index 9f9c69a90a..a71b9571d1 100644 --- a/apps/website/screens/components/grid/overview/GridOverviewPage.tsx +++ b/apps/website/screens/components/grid/overview/GridOverviewPage.tsx @@ -92,7 +92,7 @@ const sections = [ <Link href="/components/flex" passHref legacyBehavior> <DxcLink>flex</DxcLink> </Link>{" "} - component for one-dimensional layouts or stacked components with simpler structures. + component instead for one-dimensional layouts or stacked components with simpler structures. </DxcBulletedList.Item> </DxcBulletedList> ), diff --git a/apps/website/screens/components/grid/specs/GridSpecsPage.tsx b/apps/website/screens/components/grid/specs/GridSpecsPage.tsx deleted file mode 100644 index aebaf99389..0000000000 --- a/apps/website/screens/components/grid/specs/GridSpecsPage.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { DxcFlex } from "@dxc-technology/halstack-react"; -import Figure from "@/common/Figure"; -import DocFooter from "@/common/DocFooter"; -import Image from "@/common/Image"; -import QuickNavContainer from "@/common/QuickNavContainer"; -import QuickNavContainerLayout from "@/common/QuickNavContainerLayout"; -import gridAutoFlowSpecs from "./images/grid-autoFlow-specs.png"; -import gridTemplateSpecs from "./images/grid-templates-specs.png"; - -const sections = [ - { - title: "Specifications", - content: ( - <> - <Figure caption="Grid auto-flow: row, column and row dense design specifications"> - <Image src={gridAutoFlowSpecs} alt="Grid auto-flow: row, column and rows dense design specifications" /> - </Figure> - <Figure caption="Grid template: areas, rows and columns design specifications"> - <Image src={gridTemplateSpecs} alt="Grid template: areas, rows and columns design specifications" /> - </Figure> - </> - ), - }, -]; - -const GridSpecsPage = () => { - return ( - <DxcFlex direction="column" gap="4rem"> - <QuickNavContainerLayout> - <QuickNavContainer sections={sections} startHeadingLevel={2}></QuickNavContainer> - </QuickNavContainerLayout> - <DocFooter githubLink="https://github.com/dxc-technology/halstack-react/blob/master/apps/website/screens/components/grid/specs/GridSpecsPage.tsx" /> - </DxcFlex> - ); -}; - -export default GridSpecsPage; diff --git a/apps/website/screens/components/grid/specs/images/grid-autoFlow-specs.png b/apps/website/screens/components/grid/specs/images/grid-autoFlow-specs.png deleted file mode 100644 index c07d81e70eb21052a15b8ccedaf9d6a9ebb49fc1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9109 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≶1KtOu0e^zZ8+&hwV85GFN zj!aP1$K4p`<XlWY01y;SAxM5(-!+m(<YIy&G(UQc5;}0(j<>SjiP&(Uac41tG2OMD z2_k-3LbnHZ*pge>rY*@wLLcmHtYK5}U0owaQsr+sQ<tQm2J78%E0XI9A8>I?5UXK> zP-X&I5Mj)Y3CArTRw*z4z`V`$gIJxCaB5p#s9nCwg|5z$yrV;zTC4DFoAa3_QJ!Gm za7otl4N4DyYFl(0_@u8Jk$^uAb<1(f8D^y8(chk~e_4qKDV-gaydJ%Xj!Xeqq*-<v zwB+p)Uq$Y=95BtQi7DM4`A$4mMy+x}q_{djx)7fZs!DNb|0bJ(>&bQHb&vz?CnW|m zExVaTGg$)f_SHoG_!jVnk=QJ->$R8c_eSI3vtameYT8SmJhVJ*MH4EjSsDDP;&$bi z&wEFVtvk;0v2A$0;kesg@7C_OVXth55V-c?J7Qu)nG@tAb=kUmAJ-!hc@;bJ_n||V zpwGcNN`V$4hvf1Iv&c**=13Xnk)vE|dV2~{VyymXJI_5?kt0OBmW?1zSG}z9uc$?d zhlLrh^d4yU!M_P2@;RM^MMMzxM`n<LP84>k4DFRdo$zl?-@Mm0^*ZMkm>q=q<pi~< zehn(mwjuGc0c@_wYghihfb1tce6J&v`5=d_QPQAPK-f7MkmZK>hsw8KM5%|oP~C?f zF*(=)L%&zSXDd%OlSTFZFJ>Vpr{2gEx3?b7Kei}zoh?ZZR04s{&K-`wFFj<*l>dKz i#o_<idmR+kp+9!A!0YB6U)fW{VQOS$Sg-%!$$tSI9;l=M diff --git a/apps/website/screens/components/grid/specs/images/grid-templates-specs.png b/apps/website/screens/components/grid/specs/images/grid-templates-specs.png deleted file mode 100644 index 0c3dc0fb40016f3813cc3bc2d082c6482d0b73e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15766 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