From 1dc6cfb28204ba3450de8f7c5733a2fce239c63c Mon Sep 17 00:00:00 2001 From: pplancq Date: Tue, 4 Feb 2025 09:45:01 +0100 Subject: [PATCH 1/4] chore(design-system,slash): add custom viewports for Storybook --- apps/slash-stories-css/.storybook/main.ts | 1 + apps/slash-stories-css/.storybook/preview.ts | 5 ++ .../slash-stories-css/.storybook/viewPorts.ts | 52 +++++++++++++++++++ apps/slash-stories-css/package.json | 1 + apps/slash-stories/.storybook/main.ts | 1 + apps/slash-stories/.storybook/preview.ts | 4 ++ apps/slash-stories/.storybook/viewPorts.ts | 52 +++++++++++++++++++ apps/slash-stories/package.json | 1 + package-lock.json | 2 + 9 files changed, 119 insertions(+) create mode 100644 apps/slash-stories-css/.storybook/viewPorts.ts create mode 100644 apps/slash-stories/.storybook/viewPorts.ts diff --git a/apps/slash-stories-css/.storybook/main.ts b/apps/slash-stories-css/.storybook/main.ts index 27ea44293..1a044a056 100644 --- a/apps/slash-stories-css/.storybook/main.ts +++ b/apps/slash-stories-css/.storybook/main.ts @@ -15,6 +15,7 @@ const config: StorybookConfig = { getAbsolutePath("@storybook/addon-essentials"), getAbsolutePath("@chromatic-com/storybook"), getAbsolutePath("@storybook/addon-interactions"), + getAbsolutePath("@storybook/addon-viewport"), ], framework: { name: getAbsolutePath("@storybook/html-vite"), diff --git a/apps/slash-stories-css/.storybook/preview.ts b/apps/slash-stories-css/.storybook/preview.ts index 29097e6d5..51b99282c 100644 --- a/apps/slash-stories-css/.storybook/preview.ts +++ b/apps/slash-stories-css/.storybook/preview.ts @@ -1,8 +1,12 @@ import "@axa-fr/design-system-slash-css/dist/common/icons.scss"; import type { Preview } from "@storybook/html"; +import { viewPorts } from "./viewPorts"; const preview: Preview = { parameters: { + viewport: { + viewports: viewPorts, + }, controls: { matchers: { color: /(background|color)$/i, @@ -13,4 +17,5 @@ const preview: Preview = { tags: ["autodocs"], }; +// eslint-disable-next-line import/no-default-export export default preview; diff --git a/apps/slash-stories-css/.storybook/viewPorts.ts b/apps/slash-stories-css/.storybook/viewPorts.ts new file mode 100644 index 000000000..38b00d8cb --- /dev/null +++ b/apps/slash-stories-css/.storybook/viewPorts.ts @@ -0,0 +1,52 @@ +import type { ViewportMap } from "@storybook/addon-viewport"; + +export const viewPorts: ViewportMap = { + tabletPortrait: { + name: "Tablet Portrait ", + styles: { + width: "772px", + height: "100%", + }, + type: "tablet", + }, + tabletLandscape: { + name: "Tablet Landscape", + styles: { + width: "1016px", + height: "100%", + }, + type: "tablet", + }, + desktopS: { + name: "Desktop S", + styles: { + width: "1272px", + height: "100%", + }, + type: "desktop", + }, + desktopM: { + name: "Desktop M", + styles: { + width: "1432px", + height: "100%", + }, + type: "desktop", + }, + desktopL: { + name: "Desktop L", + styles: { + width: "1672px", + height: "100%", + }, + type: "desktop", + }, + desktopXL: { + name: "Desktop XL", + styles: { + width: "1912px", + height: "100%", + }, + type: "desktop", + }, +}; diff --git a/apps/slash-stories-css/package.json b/apps/slash-stories-css/package.json index 9667c454a..35be55a20 100644 --- a/apps/slash-stories-css/package.json +++ b/apps/slash-stories-css/package.json @@ -20,6 +20,7 @@ "@chromatic-com/storybook": "^3.2.4", "@storybook/addon-essentials": "^8.5.5", "@storybook/addon-interactions": "^8.5.5", + "@storybook/addon-viewport": "^8.5.5", "@storybook/blocks": "^8.5.5", "@storybook/html": "^8.5.5", "@storybook/html-vite": "^8.5.5", diff --git a/apps/slash-stories/.storybook/main.ts b/apps/slash-stories/.storybook/main.ts index 8a7c75d72..662314dfc 100644 --- a/apps/slash-stories/.storybook/main.ts +++ b/apps/slash-stories/.storybook/main.ts @@ -20,6 +20,7 @@ const config: StorybookConfig = { getAbsolutePath("@storybook/addon-essentials"), getAbsolutePath("@chromatic-com/storybook"), getAbsolutePath("@storybook/addon-interactions"), + getAbsolutePath("@storybook/addon-viewport"), getAbsolutePath("@chromatic-com/storybook"), ], framework: { diff --git a/apps/slash-stories/.storybook/preview.ts b/apps/slash-stories/.storybook/preview.ts index d80f37cbc..c8eb0c81d 100644 --- a/apps/slash-stories/.storybook/preview.ts +++ b/apps/slash-stories/.storybook/preview.ts @@ -1,9 +1,13 @@ import "@axa-fr/design-system-slash-css/dist/common/icons.scss"; import "@fontsource/source-sans-pro"; import type { Preview } from "@storybook/react"; +import { viewPorts } from "./viewPorts"; const preview: Preview = { parameters: { + viewport: { + viewports: viewPorts, + }, controls: { matchers: { color: /(background|color)$/i, diff --git a/apps/slash-stories/.storybook/viewPorts.ts b/apps/slash-stories/.storybook/viewPorts.ts new file mode 100644 index 000000000..38b00d8cb --- /dev/null +++ b/apps/slash-stories/.storybook/viewPorts.ts @@ -0,0 +1,52 @@ +import type { ViewportMap } from "@storybook/addon-viewport"; + +export const viewPorts: ViewportMap = { + tabletPortrait: { + name: "Tablet Portrait ", + styles: { + width: "772px", + height: "100%", + }, + type: "tablet", + }, + tabletLandscape: { + name: "Tablet Landscape", + styles: { + width: "1016px", + height: "100%", + }, + type: "tablet", + }, + desktopS: { + name: "Desktop S", + styles: { + width: "1272px", + height: "100%", + }, + type: "desktop", + }, + desktopM: { + name: "Desktop M", + styles: { + width: "1432px", + height: "100%", + }, + type: "desktop", + }, + desktopL: { + name: "Desktop L", + styles: { + width: "1672px", + height: "100%", + }, + type: "desktop", + }, + desktopXL: { + name: "Desktop XL", + styles: { + width: "1912px", + height: "100%", + }, + type: "desktop", + }, +}; diff --git a/apps/slash-stories/package.json b/apps/slash-stories/package.json index 4cc2f854d..0c3e8c573 100644 --- a/apps/slash-stories/package.json +++ b/apps/slash-stories/package.json @@ -21,6 +21,7 @@ "@storybook/addon-essentials": "^8.5.5", "@storybook/addon-interactions": "^8.5.5", "@storybook/addon-onboarding": "^8.5.5", + "@storybook/addon-viewport": "^8.5.5", "@storybook/blocks": "^8.5.5", "@storybook/react": "^8.5.5", "@storybook/react-vite": "^8.5.5", diff --git a/package-lock.json b/package-lock.json index 3ef2db281..32ef8fe97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -129,6 +129,7 @@ "@storybook/addon-essentials": "^8.5.5", "@storybook/addon-interactions": "^8.5.5", "@storybook/addon-onboarding": "^8.5.5", + "@storybook/addon-viewport": "^8.5.5", "@storybook/blocks": "^8.5.5", "@storybook/react": "^8.5.5", "@storybook/react-vite": "^8.5.5", @@ -151,6 +152,7 @@ "@chromatic-com/storybook": "^3.2.4", "@storybook/addon-essentials": "^8.5.5", "@storybook/addon-interactions": "^8.5.5", + "@storybook/addon-viewport": "^8.5.5", "@storybook/blocks": "^8.5.5", "@storybook/html": "^8.5.5", "@storybook/html-vite": "^8.5.5", From a36b1aa7955c7cf7ad98419285a1efbf12d48a88 Mon Sep 17 00:00:00 2001 From: pplancq Date: Tue, 4 Feb 2025 11:39:03 +0100 Subject: [PATCH 2/4] feat(slash): add Grid component and breakpoint utility --- apps/slash-stories-css/src/Grid.mdx | 45 +++++++++++++++++ apps/slash-stories-css/src/Grid.stories.ts | 26 ++++++++++ apps/slash-stories/src/Grid.mdx | 57 ++++++++++++++++++++++ apps/slash-stories/src/Grid.stories.tsx | 44 +++++++++++++++++ slash/css/src/Grid/Grid.scss | 45 +++++++++++++++++ slash/css/src/common/breakpoint.scss | 36 ++++++++++++++ slash/css/src/slash.scss | 1 + slash/react/src/Grid/Grid.tsx | 36 ++++++++++++++ slash/react/src/index.ts | 1 + 9 files changed, 291 insertions(+) create mode 100644 apps/slash-stories-css/src/Grid.mdx create mode 100644 apps/slash-stories-css/src/Grid.stories.ts create mode 100644 apps/slash-stories/src/Grid.mdx create mode 100644 apps/slash-stories/src/Grid.stories.tsx create mode 100644 slash/css/src/Grid/Grid.scss create mode 100644 slash/css/src/common/breakpoint.scss create mode 100644 slash/react/src/Grid/Grid.tsx diff --git a/apps/slash-stories-css/src/Grid.mdx b/apps/slash-stories-css/src/Grid.mdx new file mode 100644 index 000000000..6ab779bd7 --- /dev/null +++ b/apps/slash-stories-css/src/Grid.mdx @@ -0,0 +1,45 @@ +import { Meta, Markdown } from "@storybook/addon-docs"; +import * as GridStories from "./Grid.stories"; + + + +## Grid + +### Import + +#### Grid only + +```js +import "@axa-fr/design-system-slash-react/dist/Grid/Grid.scss"; // or +import "@axa-fr/design-system-slash-react/dist/Grid/Grid.css"; +``` + +#### Global + +```tsx +import "@axa-fr/design-system-slash-react/dist/slash.scss"; // or +import "@axa-fr/design-system-slash-react/dist/slash.css"; +``` + +### Use + +```html +
Content
+``` + +### Breakpoints and Margins + +> ⚠ To handle the rounded edges implemented by Edge, we are forced to reduce each of the breakpoints by 8px + + + {` +| Breakpoint | columns | body | margin | comment | +|-------------------------------------|---------|---------|------------------|---------------------| +| Portrait Tablet (772px to 1015px) | 1 | 700 px | Scale - 36px min | | +| Landscape Tablet (1016px to 1271px) | 1 | 936 px | Scale - 40px min | | +| S Desktop (1272px to 1431px) | 1 | 1160 px | Scale - 56px min | 150% - Laptop | +| M Desktop (1432px to 1671px) | 1 | 1320 px | Scale - 56px min | 125% - Laptop | +| L Desktop (1672px to 1911px) | 1 | 1560 px | Scale - 56px min | 100% - Laptop | +| XL Desktop (1912 to ∞ px) | 1 | 1800 px | Scale - 56px min | 100% - Large screen | +`} + diff --git a/apps/slash-stories-css/src/Grid.stories.ts b/apps/slash-stories-css/src/Grid.stories.ts new file mode 100644 index 000000000..68de6db57 --- /dev/null +++ b/apps/slash-stories-css/src/Grid.stories.ts @@ -0,0 +1,26 @@ +import type { Meta, StoryObj } from "@storybook/html"; +import "@axa-fr/design-system-slash-css/dist/Grid/Grid.scss"; + +const meta: Meta = { + title: "Fondations/Breakpoints/Grid", +}; + +export default meta; + +export const Grid: StoryObj = { + render: () => { + const div = document.createElement("div"); + div.innerHTML = `
+
+
`; + + div.style.backgroundColor = "orange"; + div.style.opacity = "0.4"; + + return div; + }, + tags: ["!autodocs"], + parameters: { + layout: "fullscreen", + }, +}; diff --git a/apps/slash-stories/src/Grid.mdx b/apps/slash-stories/src/Grid.mdx new file mode 100644 index 000000000..c4d703932 --- /dev/null +++ b/apps/slash-stories/src/Grid.mdx @@ -0,0 +1,57 @@ +import { Meta, Markdown } from "@storybook/addon-docs"; +import * as GridStories from "./Grid.stories"; + + + +## Grid + +### Import + +```tsx +import { Grid } from "@axa-fr/design-system-slash-react"; +``` + +### Use + +#### Grid Example: + +```tsx +export const Main = () => Content; +``` + +### Breakpoints and Margins + +> ⚠ To handle the rounded edges implemented by Edge, we are forced to reduce each of the breakpoints by 8px + + + {` +| Breakpoint | columns | body | margin | comment | +|-------------------------------------|---------|---------|------------------|---------------------| +| Portrait Tablet (772px to 1015px) | 1 | 700 px | Scale - 36px min | | +| Landscape Tablet (1016px to 1271px) | 1 | 936 px | Scale - 40px min | | +| S Desktop (1272px to 1431px) | 1 | 1160 px | Scale - 56px min | 150% - Laptop | +| M Desktop (1432px to 1671px) | 1 | 1320 px | Scale - 56px min | 125% - Laptop | +| L Desktop (1672px to 1911px) | 1 | 1560 px | Scale - 56px min | 100% - Laptop | +| XL Desktop (1912 to ∞ px) | 1 | 1800 px | Scale - 56px min | 100% - Large screen | +`} + + +### Customize root element of Grid + +The `component` prop overrides the root element, which is by default an `div` tag, and all associated props. + +```tsx +import { Grid } from "@axa-fr/design-system-slash-react"; + +export const Main = () => Content; +``` + +```tsx +import { Grid } from "@axa-fr/design-system-slash-react"; +import { MainComponent } from "./MainComponent"; + +export const Main = () => Content; +``` diff --git a/apps/slash-stories/src/Grid.stories.tsx b/apps/slash-stories/src/Grid.stories.tsx new file mode 100644 index 000000000..de1bf6427 --- /dev/null +++ b/apps/slash-stories/src/Grid.stories.tsx @@ -0,0 +1,44 @@ +import type { Meta, StoryObj } from "@storybook/react"; +import { Grid } from "@axa-fr/design-system-slash-react"; + +const meta: Meta = { + title: "Fondations/Breakpoints/Grid", + component: Grid, + parameters: { + layout: "fullscreen", + }, +}; + +export default meta; + +export const GridStory: StoryObj = { + name: "Grid", + render: ({ ...props }) => { + return ( +
+ +
+ +
+ ); + }, + argTypes: { + className: { + table: { + disable: true, + }, + }, + component: { + table: { + disable: true, + }, + }, + }, +}; diff --git a/slash/css/src/Grid/Grid.scss b/slash/css/src/Grid/Grid.scss new file mode 100644 index 000000000..2ff5b19e9 --- /dev/null +++ b/slash/css/src/Grid/Grid.scss @@ -0,0 +1,45 @@ +@use "../common/common" as common; +@use "../common/breakpoint" as breakpoint; + +.af-grid { + --grid-body-width: var(--body-width-tablet-portrait); + + width: var(--grid-body-width); + margin-inline: auto; +} + +@include breakpoint.media-less-than-width(tablet-portrait) { + .af-grid { + margin-inline: common.px-to-rem(36); + } +} + +@include breakpoint.media-exceeds-width(tablet-landscape) { + .af-grid { + --grid-body-width: var(--body-width-tablet-landscape); + } +} + +@include breakpoint.media-exceeds-width(desktop-s) { + .af-grid { + --grid-body-width: var(--body-width-desktop-s); + } +} + +@include breakpoint.media-exceeds-width(desktop-m) { + .af-grid { + --grid-body-width: var(--body-width-desktop-m); + } +} + +@include breakpoint.media-exceeds-width(desktop-l) { + .af-grid { + --grid-body-width: var(--body-width-desktop-l); + } +} + +@include breakpoint.media-exceeds-width(desktop-xl) { + .af-grid { + --grid-body-width: var(--body-width-desktop-xl); + } +} diff --git a/slash/css/src/common/breakpoint.scss b/slash/css/src/common/breakpoint.scss new file mode 100644 index 000000000..881126f91 --- /dev/null +++ b/slash/css/src/common/breakpoint.scss @@ -0,0 +1,36 @@ +@use "sass:map"; +@use "./common" as common; + +:root { + --body-width-tablet-portrait: #{common.px-to-rem(700)}; + --body-width-tablet-landscape: #{common.px-to-rem(936)}; + --body-width-desktop-s: #{common.px-to-rem(1160)}; + --body-width-desktop-m: #{common.px-to-rem(1320)}; + --body-width-desktop-l: #{common.px-to-rem(1560)}; + --body-width-desktop-xl: #{common.px-to-rem(1800)}; +} + +$breakpoints: ( + tablet-portrait: common.px-to-rem(772), + tablet-landscape: common.px-to-rem(1016), + desktop-s: common.px-to-rem(1272), + desktop-m: common.px-to-rem(1432), + desktop-l: common.px-to-rem(1672), + desktop-xl: common.px-to-rem(1912), +) !default; + +@mixin media-exceeds-width($name) { + $value: map.get($breakpoints, $name); + + @media (width >= $value) { + @content; + } +} + +@mixin media-less-than-width($name) { + $value: map.get($breakpoints, $name); + + @media (width < $value) { + @content; + } +} diff --git a/slash/css/src/slash.scss b/slash/css/src/slash.scss index 60f41af17..c0a3e1434 100644 --- a/slash/css/src/slash.scss +++ b/slash/css/src/slash.scss @@ -31,3 +31,4 @@ @use "./Link/Link"; @use "./Popover/Popover"; @use "./Loader/Loader"; +@use "./Grid/Grid"; diff --git a/slash/react/src/Grid/Grid.tsx b/slash/react/src/Grid/Grid.tsx new file mode 100644 index 000000000..65972bcc5 --- /dev/null +++ b/slash/react/src/Grid/Grid.tsx @@ -0,0 +1,36 @@ +import { + type ComponentProps, + type ElementType, + type ForwardedRef, + forwardRef, + type PropsWithChildren, +} from "react"; +import classNames from "classnames"; + +import "@axa-fr/design-system-slash-css/dist/Grid/Grid.scss"; + +export type GridProps = { + component?: C; + className?: string; +} & ComponentProps; + +export const Grid = forwardRef( + ( + { + className, + component: Component = "div", + ...props + }: PropsWithChildren>, + ref: ForwardedRef, + ) => { + return ( + + ); + }, +); + +Grid.displayName = "Grid"; diff --git a/slash/react/src/index.ts b/slash/react/src/index.ts index b256d3fdf..137c0ea2a 100644 --- a/slash/react/src/index.ts +++ b/slash/react/src/index.ts @@ -72,6 +72,7 @@ export { Svg } from "./Svg"; export { Tabs } from "./Tabs/Tabs"; export { Title } from "./Title/Title"; export { getComponentClassName } from "./utilities"; +export { Grid } from "./Grid/Grid"; export * from "./Accordion"; export * from "./Popover"; From 9f5e0e4ba2d1f38a1a02892a3bfd24e74dc14b55 Mon Sep 17 00:00:00 2001 From: pplancq Date: Tue, 18 Feb 2025 08:41:10 +0100 Subject: [PATCH 3/4] test(slash): add tests for Grid components --- slash/react/src/Grid/__tests__/Grid.test.tsx | 29 ++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 slash/react/src/Grid/__tests__/Grid.test.tsx diff --git a/slash/react/src/Grid/__tests__/Grid.test.tsx b/slash/react/src/Grid/__tests__/Grid.test.tsx new file mode 100644 index 000000000..3bda58596 --- /dev/null +++ b/slash/react/src/Grid/__tests__/Grid.test.tsx @@ -0,0 +1,29 @@ +import { render, screen } from "@testing-library/react"; +import { Grid } from "../Grid"; + +describe("Grid component", () => { + it("should render with default props", () => { + render(Content); + + const element = screen.getByText("Content"); + + expect(element).toHaveClass("af-grid"); + }); + + it("should render with custom component", () => { + render(Content); + + const element = screen.getByText("Content"); + + expect(element.tagName).toStrictEqual("SECTION"); + }); + + it("should apply additional class names", () => { + render(Content); + + const element = screen.getByText("Content"); + + expect(element).toHaveClass("af-grid"); + expect(element).toHaveClass("custom-class"); + }); +}); From f12f66511e6058182dea86f0c66db8c02a7bfef9 Mon Sep 17 00:00:00 2001 From: pplancq Date: Tue, 4 Feb 2025 11:50:21 +0100 Subject: [PATCH 4/4] chore(slash): start order top folder with same ordre of zeroheight documentation --- apps/slash-stories-css/.storybook/preview.ts | 5 +++++ apps/slash-stories-css/src/icons.stories.ts | 2 +- apps/slash-stories/.storybook/preview.ts | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/apps/slash-stories-css/.storybook/preview.ts b/apps/slash-stories-css/.storybook/preview.ts index 51b99282c..508823ea2 100644 --- a/apps/slash-stories-css/.storybook/preview.ts +++ b/apps/slash-stories-css/.storybook/preview.ts @@ -13,6 +13,11 @@ const preview: Preview = { date: /Date$/i, }, }, + options: { + storySort: { + order: ["Fondations", "Components"], + }, + }, }, tags: ["autodocs"], }; diff --git a/apps/slash-stories-css/src/icons.stories.ts b/apps/slash-stories-css/src/icons.stories.ts index 1c1b32883..0022b22aa 100644 --- a/apps/slash-stories-css/src/icons.stories.ts +++ b/apps/slash-stories-css/src/icons.stories.ts @@ -3,7 +3,7 @@ import type { Meta, StoryObj } from "@storybook/html"; import "./icons.stories.css"; const meta: Meta = { - title: "icons", + title: "Fondations/icons", }; export default meta; diff --git a/apps/slash-stories/.storybook/preview.ts b/apps/slash-stories/.storybook/preview.ts index c8eb0c81d..de0c1d0cd 100644 --- a/apps/slash-stories/.storybook/preview.ts +++ b/apps/slash-stories/.storybook/preview.ts @@ -14,6 +14,11 @@ const preview: Preview = { date: /Date$/i, }, }, + options: { + storySort: { + order: ["Fondations", "Components"], + }, + }, }, tags: ["autodocs"], };