diff --git a/.storybook/main.js b/.storybook/main.js index a4fbd4430..f2cc52ffa 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -1,13 +1,16 @@ module.exports = { - stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"], + stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"], + staticDirs: ["../public"], + addons: [ "@storybook/addon-links", "@storybook/addon-essentials", "@storybook/preset-create-react-app", "@whitespace/storybook-addon-html", - "storybook-addon-designs", + "@storybook/addon-designs", "@storybook/addon-a11y", ], + typescript: { check: true, checkOptions: {}, @@ -18,4 +21,9 @@ module.exports = { prop.parent ? !/node_modules/.test(prop.parent.fileName) : true, }, }, + + framework: { + name: "@storybook/react-webpack5", + options: {}, + }, }; diff --git a/.storybook/modes.js b/.storybook/modes.js new file mode 100644 index 000000000..9a1d99a51 --- /dev/null +++ b/.storybook/modes.js @@ -0,0 +1,9 @@ +// Set the viewport widths that Chromatic tests with globally. +export const allModes = { + xs: { + viewport: "xs", + }, + xl: { + viewport: "xl", + }, +}; diff --git a/.storybook/preview.js b/.storybook/preview.js index 5a590ca7c..62fd1478d 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,3 +1,6 @@ +import "../src/styles/css/base.css"; +import { allModes } from "../.storybook/modes"; + export const parameters = { layout: "fullscreen", actions: { argTypesRegex: "^on[A-Z].*" }, @@ -7,13 +10,24 @@ export const parameters = { date: /Date$/, }, }, + viewport: { + viewports: { + xs: { name: "XSmall", styles: { width: "400px", height: "900px" } }, + sm: { name: "Small", styles: { width: "640px", height: "900px" } }, + md: { name: "Medium", styles: { width: "768px", height: "900px" } }, + lg: { name: "Large", styles: { width: "1024px", height: "900px" } }, + xl: { name: "XL", styles: { width: "1200px", height: "900px" } }, + "2xl": { name: "2XL", styles: { width: "1536px", height: "900px" } }, + }, + }, chromatic: { // Notifies Chromatic to pause the animations when they finish at a global level // This is because Chromatic doesn't show the cover image when the animation starts with opacity 0 pauseAnimationAtEnd: true, - // Set the viewport widths that Chromatic tests with globally. - // 400 lies between our screen-xs & screen-s variables. - // 1200 is the chromatic viewport we were using as default before adding an extra one for phones. - viewports: [400, 1200], + // Instructs Chromatic to test all stories at the specified viewport + modes: { + "400px": allModes["xs"], + "1200px": allModes["xl"], + }, }, }; diff --git a/package.json b/package.json index 8530ff772..9b64a77af 100644 --- a/package.json +++ b/package.json @@ -3,9 +3,9 @@ "version": "0.1.0", "repository": "https://github.com/danskernesdigitalebibliotek/dpl-design-system", "scripts": { - "storybook": "NODE_OPTIONS=--openssl-legacy-provider start-storybook -p 6006 -s public", - "storybook:axe": "NODE_OPTIONS=--openssl-legacy-provider build-storybook && axe-storybook", - "build-storybook": "NODE_OPTIONS=--openssl-legacy-provider build-storybook -s public", + "storybook": "storybook dev -p 6006", + "storybook:axe": "storybook build && axe-storybook", + "build-storybook": "storybook build", "js:eslint": "eslint 'src/**/*.{js,ts,tsx}' --max-warnings=0", "js:prettier": "prettier 'src/**/*.{js,ts,tsx}'", "js:lint": "concurrently 'yarn:js:eslint' 'yarn:js:prettier -- --check' --raw", @@ -40,14 +40,16 @@ ] }, "devDependencies": { - "@chanzuckerberg/axe-storybook-testing": "^6.0.1", - "@storybook/addon-a11y": "^6.5.9", - "@storybook/addon-actions": "^6.5.9", - "@storybook/addon-essentials": "^6.5.9", - "@storybook/addon-links": "^6.5.9", - "@storybook/node-logger": "^6.3.7", - "@storybook/preset-create-react-app": "^3.2.0", - "@storybook/react": "^6.5.9", + "@chanzuckerberg/axe-storybook-testing": "^8.2.1", + "@storybook/addon-a11y": "^8.3.6", + "@storybook/addon-actions": "^8.3.6", + "@storybook/addon-designs": "^8.0.3", + "@storybook/addon-essentials": "^8.3.6", + "@storybook/addon-links": "^8.3.6", + "@storybook/node-logger": "^8.3.6", + "@storybook/preset-create-react-app": "^8.3.6", + "@storybook/react": "^8.3.6", + "@storybook/react-webpack5": "^8.3.6", "@testing-library/jest-dom": "^6.6.3", "@testing-library/react": "^12.1.5", "@testing-library/user-event": "^14.5.2", @@ -58,7 +60,7 @@ "@types/react-helmet": "^6.1.11", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", - "@whitespace/storybook-addon-html": "^5.0.0", + "@whitespace/storybook-addon-html": "^6.1.1", "chokidar-cli": "^3.0.0", "clsx": "^2.1.1", "concurrently": "^8.2.2", @@ -69,7 +71,7 @@ "eslint-loader": "^4.0.2", "eslint-plugin-import": "^2.31.0", "eslint-plugin-jsx-a11y": "^6.10.0", - "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-prettier": "^5.0.0", "eslint-plugin-react": "^7.37.2", "eslint-plugin-react-hooks": "^4.6.2", "eslint-webpack-plugin": "^4.2.0", @@ -77,20 +79,20 @@ "json": "^11.0.0", "markdownlint-cli2": "^0.4.0", "postcss": "^8.4.47", - "prettier": "^2.7.1", + "prettier": "^3.3.3", "react": "^17.0.2", "react-docgen-typescript": "^2.1.0", "react-dom": "^17.0.2", "react-helmet": "^6.1.0", - "react-scripts": "^4.0.3", + "react-scripts": "^5.0.0", + "react-syntax-highlighter": "^15.6.1", "sass": "1.78.0", "skeleton-screen-css": "^1.1.0", - "storybook-addon-designs": "^6.2.1", - "stylelint": "^14.16.1", - "stylelint-config-prettier": "^9.0.5", - "stylelint-config-recommended-scss": "^8.0.0", - "stylelint-prettier": "^3.0.0", - "stylelint-scss": "^5.3.2", + "storybook": "^8.3.6", + "stylelint": "^16.0.0", + "stylelint-config-recommended-scss": "^14.0.0", + "stylelint-prettier": "^5.0.2", + "stylelint-scss": "^6.7.0", "typescript": "^4.7.4", "web-vitals": "^4.2.4" }, diff --git a/src/index.tsx b/src/index.tsx index 3f0e48eb1..7c05bcf2e 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -7,5 +7,5 @@ ReactDOM.render( , - document.getElementById("root") + document.getElementById("root"), ); diff --git a/src/stories/Blocks/advanced-search/AdvancedSearch.stories.tsx b/src/stories/Blocks/advanced-search/AdvancedSearch.stories.tsx index f4f6a6572..73ef655bf 100644 --- a/src/stories/Blocks/advanced-search/AdvancedSearch.stories.tsx +++ b/src/stories/Blocks/advanced-search/AdvancedSearch.stories.tsx @@ -1,5 +1,5 @@ -import { ComponentStory } from "@storybook/react"; -import { withDesign } from "storybook-addon-designs"; +import { StoryFn } from "@storybook/react"; + import { AdvancedSearch as AdvancedSearchComp, AdvancedSearchProps, @@ -8,30 +8,31 @@ import { export default { title: "Blocks / Advanced Search", component: AdvancedSearchComp, - decorators: [withDesign], argTypes: { inputPlaceholder: { name: "Input placeholder", - defaultValue: "Søgeterm", control: { type: "text" }, }, inputAmount: { name: "Amount of input rows", - defaultValue: 2, control: { type: "number" }, }, cqlPreviewText: { name: "CQL preview text", - defaultValue: - "title = harry potter AND subtitle = and the philosophers stone", control: { type: "text" }, }, isCqlSearch: { name: "Is CQL search?", - defaultValue: false, control: { type: "boolean" }, }, }, + args: { + inputPlaceholder: "Søgeterm", + inputAmount: 2, + cqlPreviewText: + "title = harry potter AND subtitle = and the philosophers stone", + isCqlSearch: false, + }, parameters: { design: { type: "figma", @@ -40,8 +41,8 @@ export default { }, }; -const Template: ComponentStory = ( - args: AdvancedSearchProps +const Template: StoryFn = ( + args: AdvancedSearchProps, ) => ; export const AdvancedSearch = Template.bind({}); diff --git a/src/stories/Blocks/article/Article.stories.tsx b/src/stories/Blocks/article/Article.stories.tsx index e310e757b..40175c01b 100644 --- a/src/stories/Blocks/article/Article.stories.tsx +++ b/src/stories/Blocks/article/Article.stories.tsx @@ -1,38 +1,26 @@ -import { ComponentStory, ComponentMeta } from "@storybook/react"; -import { withDesign } from "storybook-addon-designs"; +import { StoryFn, Meta } from "@storybook/react"; + import Article from "./Article"; export default { title: "Blocks / Article page", component: Article, - decorators: [withDesign], argTypes: { - title: { - defaultValue: "Jesper Stein vinder Læsernes Bogpris for Rampen’", - }, - subtitle: { - defaultValue: - "Jesper Stein har begået en hudløst ærlig og tankevækkende skildring af en skilsmisseramt familie. En selvbiografisk roman, som har ramt læserne i hjertet.", - }, - category: { - defaultValue: "Netmedier", - }, - author: { - defaultValue: "Lene Kuhlmann Frandsen", - }, - date: { - defaultValue: "08. April 21", - }, - tags: { - defaultValue: [ - "dans", - "contemporary", - "modern", - "scenekunst", - "digt", - "3-8 årige", - ], - }, + title: { control: "text" }, + subtitle: { control: "text" }, + category: { control: "text" }, + author: { control: "text" }, + date: { control: "text" }, + tags: { control: "object" }, + }, + args: { + title: "Jesper Stein vinder Læsernes Bogpris for Rampen'", + subtitle: + "Jesper Stein har begået en hudløst ærlig og tankevækkende skildring af en skilsmisseramt familie. En selvbiografisk roman, som har ramt læserne i hjertet.", + category: "Netmedier", + author: "Lene Kuhlmann Frandsen", + date: "08. April 21", + tags: ["dans", "contemporary", "modern", "scenekunst", "digt", "3-8 årige"], }, parameters: { design: { @@ -40,10 +28,8 @@ export default { url: "https://www.figma.com/file/Zx9GrkFA3l4ISvyZD2q0Qi/Designsystem?type=design&node-id=7477%3A39048&mode=dev", }, }, -} as ComponentMeta; +} as Meta; -const Template: ComponentStory = (args) => ( -
-); +const Template: StoryFn = (args) =>
; export const Default = Template.bind({}); diff --git a/src/stories/Blocks/autosuggest/Autosuggest.stories.tsx b/src/stories/Blocks/autosuggest/Autosuggest.stories.tsx index b939097df..0da361cdd 100644 --- a/src/stories/Blocks/autosuggest/Autosuggest.stories.tsx +++ b/src/stories/Blocks/autosuggest/Autosuggest.stories.tsx @@ -1,5 +1,5 @@ -import { ComponentStory } from "@storybook/react"; -import { withDesign } from "storybook-addon-designs"; +import { StoryFn } from "@storybook/react"; + import clsx from "clsx"; import { Autosuggest, AutosuggestProps } from "./Autosuggest"; import AutosuggestMaterialStories from "../../Library/autosuggest-material/AutosuggestMaterial.stories"; @@ -9,11 +9,14 @@ import { autosuggestMaterialSuggestions } from "../../Library/autosuggest-materi export default { title: "Blocks / Autosuggest", component: Autosuggest, - decorators: [withDesign], argTypes: { ...AutosuggestMaterialStories.argTypes, ...AutosuggestTextStories.argTypes, }, + args: { + ...AutosuggestMaterialStories.args, + ...AutosuggestTextStories.args, + }, parameters: { design: { type: "figma", @@ -22,9 +25,7 @@ export default { }, }; -const Template: ComponentStory = ( - args: AutosuggestProps -) => ( +const Template: StoryFn = (args: AutosuggestProps) => ( // Inline styling should be avoided, but this is not really a part of the // component - rather, a fix, to make sure the autosuggests look correct, // even when they're not in the menu structure. @@ -35,25 +36,18 @@ const Template: ComponentStory = ( export const Default = Template.bind({}); -const getStoryArguments = (suggestions: number) => { - return { - ...AutosuggestTextStories.argTypes, - materialSuggestions: { - ...{ ...AutosuggestMaterialStories.argTypes?.materialSuggestions }, - defaultValue: autosuggestMaterialSuggestions.slice(0, suggestions), - }, - classes: { - ...{ ...AutosuggestMaterialStories.argTypes?.classes }, - defaultValue: clsx({ - "autosuggest__material-item--two": suggestions === 2, - "autosuggest__material-item--one": suggestions === 1, - }), - }, - }; -}; +const getStoryArguments = (suggestions: number) => ({ + args: { + materialSuggestions: autosuggestMaterialSuggestions.slice(0, suggestions), + classes: clsx({ + "autosuggest__material-item--two": suggestions === 2, + "autosuggest__material-item--one": suggestions === 1, + }), + }, +}); export const TwoMaterials = Template.bind({}); -TwoMaterials.argTypes = getStoryArguments(2); +TwoMaterials.args = getStoryArguments(2).args; export const OneMaterial = Template.bind({}); -OneMaterial.argTypes = getStoryArguments(1); +OneMaterial.args = getStoryArguments(1).args; diff --git a/src/stories/Blocks/content-list-page/ContentListPage.stories.tsx b/src/stories/Blocks/content-list-page/ContentListPage.stories.tsx index 867294867..5fd0c27e2 100644 --- a/src/stories/Blocks/content-list-page/ContentListPage.stories.tsx +++ b/src/stories/Blocks/content-list-page/ContentListPage.stories.tsx @@ -1,4 +1,4 @@ -import { ComponentStory, ComponentMeta } from "@storybook/react"; +import { StoryFn, Meta } from "@storybook/react"; import ContentListPage from "./ContentListPage"; export default { @@ -11,10 +11,8 @@ export default { }, layout: "fullscreen", }, -} as ComponentMeta; +} as Meta; -const Template: ComponentStory = () => ( - -); +const Template: StoryFn = () => ; export const Default = Template.bind({}); diff --git a/src/stories/Blocks/create-patron/CreatePatron.stories.tsx b/src/stories/Blocks/create-patron/CreatePatron.stories.tsx index a9b5cf341..292dc13c8 100644 --- a/src/stories/Blocks/create-patron/CreatePatron.stories.tsx +++ b/src/stories/Blocks/create-patron/CreatePatron.stories.tsx @@ -1,18 +1,18 @@ -import { ComponentStory } from "@storybook/react"; -import { withDesign } from "storybook-addon-designs"; +import { StoryFn } from "@storybook/react"; import CreatePatron, { CreatePatronProps } from "./CreatePatron"; export default { title: "Blocks / Create Patron", component: CreatePatron, - decorators: [withDesign], argTypes: { headline: { name: "Title", - defaultValue: "Register as patron", control: { type: "text" }, }, }, + args: { + headline: "Register as patron", + }, parameters: { design: { type: "figma", @@ -21,8 +21,8 @@ export default { }, }; -const Template: ComponentStory = ( - args: CreatePatronProps -) => ; +const Template: StoryFn = (args: CreatePatronProps) => ( + +); export const Default = Template.bind({}); diff --git a/src/stories/Blocks/event-page/EventPage.stories.tsx b/src/stories/Blocks/event-page/EventPage.stories.tsx index 389b74096..2807b2b86 100644 --- a/src/stories/Blocks/event-page/EventPage.stories.tsx +++ b/src/stories/Blocks/event-page/EventPage.stories.tsx @@ -1,117 +1,84 @@ -import { ComponentStory, ComponentMeta } from "@storybook/react"; -import { withDesign } from "storybook-addon-designs"; +import { StoryFn, Meta } from "@storybook/react"; + import Event from "./EventPage"; import ImageCredited from "../../Library/image-credited/ImageCredited"; export default { title: "Blocks / Event page", component: Event, - decorators: [withDesign], - argTypes: { - title: { - defaultValue: "Fernisering Modern Dans", - type: "string", - }, - date: { - defaultValue: "06 Dec - 12 Jan 2022", - type: "string", - }, - image: { - defaultValue: ( - - ), - }, - placeholderText: { - defaultValue: "Noget spændende tekst", - type: "string", - }, - descriptionDescription: { - defaultValue: `Foreningen for Integreret Moderne Dans arbejder med at udvide + args: { + title: "Fernisering Modern Dans", + date: "06 Dec - 12 Jan 2022", + image: ( + + ), + placeholderText: "Noget spændende tekst", + descriptionDescription: `Foreningen for Integreret Moderne Dans arbejder med at udvide normalitetsbegrebet i scenekunsten. For hvad er normalt? Rosenreglen og Mødrenes hus. I 2022 udgav hun også den stærkt politiske digtsamling Jeg vil have en statsminister.`, - type: "string", - }, - horizontalTermLineData: { - defaultValue: [ - { - title: "I samme serie ", - linkList: [ - { - text: "Litteratur & Aktivisme", - url: "/", - }, - ], - }, - { - title: "Emneord", - linkList: [ - { - text: "dans", - url: "/", - }, - { - text: "contemporary", - url: "/", - }, - { - text: "modern", - url: "/", - }, - { - text: "scenekunst", - url: "/", - }, - { - text: "digt", - url: "/", - }, - { - text: "3-8 årige", - url: "/", - }, - ], - }, - ], - }, + horizontalTermLineData: [ + { + title: "I samme serie ", + linkList: [{ text: "Litteratur & Aktivisme", url: "/" }], + }, + { + title: "Emneord", + linkList: [ + { text: "dans", url: "/" }, + { text: "contemporary", url: "/" }, + { text: "modern", url: "/" }, + { text: "scenekunst", url: "/" }, + { text: "digt", url: "/" }, + { text: "3-8 årige", url: "/" }, + ], + }, + ], listDescriptionData: { - defaultValue: { - Tid: { value: ["19:30 — 21:00"], type: "standard" }, - Pris: { - value: ["Standard: 65 kr.", "Børn: Gratis"], - type: "standard", - layout: "column", - }, - Sted: { - value: [ - "Hovedbibliotek", - "Greve bibliotek", - "Hovedbibliotek", - "Greve bibliotek", - ], - type: "link", - }, - Adresse: { - value: ["Kampmanns Plads 2, 8000, Aarhus"], - type: "standard", - }, - Målgruppe: { value: ["Alle"], type: "standard" }, + Tid: { value: ["19:30 — 21:00"], type: "standard" }, + Pris: { + value: ["Standard: 65 kr.", "Børn: Gratis"], + type: "standard", + layout: "column", + }, + Sted: { + value: [ + "Hovedbibliotek", + "Greve bibliotek", + "Hovedbibliotek", + "Greve bibliotek", + ], + type: "link", }, + Adresse: { + value: ["Kampmanns Plads 2, 8000, Aarhus"], + type: "standard", + }, + Målgruppe: { value: ["Alle"], type: "standard" }, }, }, + argTypes: { + title: { control: "text" }, + date: { control: "text" }, + image: { control: "object" }, + placeholderText: { control: "text" }, + descriptionDescription: { control: "text" }, + horizontalTermLineData: { control: "object" }, + listDescriptionData: { control: "object" }, + }, parameters: { design: { type: "figma", url: "https://www.figma.com/file/Zx9GrkFA3l4ISvyZD2q0Qi/Designsystem?type=design&node-id=7477-39846&mode=dev", }, }, -} as ComponentMeta; +} as Meta; -const Template: ComponentStory = (args) => ; +const Template: StoryFn = (args) => ; export const Default = Template.bind({}); export const withOutImage = Template.bind({}); diff --git a/src/stories/Blocks/favorites-list/FavoritesList.stories.tsx b/src/stories/Blocks/favorites-list/FavoritesList.stories.tsx index d585eeb15..cfa9e9ef5 100644 --- a/src/stories/Blocks/favorites-list/FavoritesList.stories.tsx +++ b/src/stories/Blocks/favorites-list/FavoritesList.stories.tsx @@ -1,12 +1,12 @@ -import { ComponentMeta, ComponentStory } from "@storybook/react"; +import { Meta, StoryFn } from "@storybook/react"; import FavouritesList from "./FavoritesList"; export default { title: "Blocks / Favourite List", component: FavouritesList, -} as ComponentMeta; +} as Meta; -const Template: ComponentStory = (args) => { +const Template: StoryFn = (args) => { return ; }; diff --git a/src/stories/Blocks/fee-list/FeeListPage.stories.tsx b/src/stories/Blocks/fee-list/FeeListPage.stories.tsx index 5a77c4089..f3d0a163f 100644 --- a/src/stories/Blocks/fee-list/FeeListPage.stories.tsx +++ b/src/stories/Blocks/fee-list/FeeListPage.stories.tsx @@ -1,12 +1,12 @@ -import { ComponentMeta, ComponentStory } from "@storybook/react"; +import { Meta, StoryFn } from "@storybook/react"; import FeeListPage from "./FeeListPage"; export default { title: "Blocks / Fee List", component: FeeListPage, -} as ComponentMeta; +} as Meta; -const Template: ComponentStory = (args) => { +const Template: StoryFn = (args) => { return ; }; diff --git a/src/stories/Blocks/footer/Footer.stories.tsx b/src/stories/Blocks/footer/Footer.stories.tsx index 454fbe9f0..14fb17de4 100644 --- a/src/stories/Blocks/footer/Footer.stories.tsx +++ b/src/stories/Blocks/footer/Footer.stories.tsx @@ -1,11 +1,9 @@ -import { withDesign } from "storybook-addon-designs"; -import { Meta, Story } from "@storybook/react"; +import { Meta, StoryFn } from "@storybook/react"; import Footer, { FooterType } from "./Footer"; export default { title: "Blocks / Footer", component: Footer, - decorators: [withDesign], parameters: { design: { type: "figma", @@ -151,5 +149,5 @@ export default { }, } as Meta; -const Template: Story = (args) =>