Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add storybook #854

Merged
merged 9 commits into from
Sep 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions web/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ package-lock.json
.idea/
.env.local.yaml
/src/pluginSystem.js

*storybook.log
21 changes: 21 additions & 0 deletions web/.storybook/main.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type { StorybookConfig } from "@storybook/react-vite";

export default {
"stories": ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
"addons": [
"@storybook/addon-links",
"@storybook/addon-essentials",
"storybook-dark-mode",
"@storybook/addon-interactions",
"@storybook/addon-themes",
"@storybook/addon-a11y"
],
"framework": {
"name": "@storybook/react-vite",
"options": {}
},
"core": {
"builder": "@storybook/builder-vite"
},
"staticDirs": ["./static", "../public"]
} as StorybookConfig;
64 changes: 64 additions & 0 deletions web/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import type { Preview } from "@storybook/react";
import { useDarkMode as useStorybookUiDarkMode } from "storybook-dark-mode";
import { darkTheme, lightTheme } from "./theme";
import React, { useEffect } from "react";
import { OnyxiaUi } from "../src/ui/theme";
import { injectCustomFontFaceIfNotAlreadyDone } from "../src/ui/theme/injectCustomFontFaceIfNotAlreadyDone";
import {
Language,
languagesPrettyPrint,
useLang,
fallbackLanguage
} from "../src/ui/i18n";
import { assert } from "tsafe/assert";
import { is } from "tsafe/is";

injectCustomFontFaceIfNotAlreadyDone();

const languagesGlobal = Object.entries(languagesPrettyPrint).map(([value, title]) => ({
value: value as Language,
title
}));

const preview: Preview = {
parameters: {
backgrounds: { disable: true },
darkMode: {
light: lightTheme,
dark: darkTheme
},
docs: { disable: true, hidden: true }
},
globalTypes: {
locale: {
name: "Locale",
description: "Internationalization locale",
defaultValue: fallbackLanguage,
toolbar: {
icon: "globe",
items: languagesGlobal
}
}
},
argTypes: {},
decorators: [
(Story, { globals: { locale } }) => {
const isStorybookUiDark = useStorybookUiDarkMode();
const { lang, setLang } = useLang();

assert(is<Language>(locale));

useEffect(() => {
if (lang !== locale) setLang(locale);
}, [locale]);

return (
<OnyxiaUi darkMode={isStorybookUiDark}>
<Story />
</OnyxiaUi>
);
}
]
};

export default preview;
Binary file added web/.storybook/static/onyxiaLogo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions web/.storybook/theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { create } from "@storybook/theming";

export const darkTheme = create({
"base": "dark",
"appBg": "#2c323f",
"appContentBg": "#2c323f",
"appPreviewBg": "#2c323f",
"barBg": "#2c323f",
"colorSecondary": "#ff562c",
"textColor": "#f1f0eb",
"brandImage": "onyxiaLogo.png",
"brandTitle": "Onyxia UI",
"brandUrl": "https://github.com/InseeFrLab/onyxia-ui",
"fontBase": '"Work Sans","Open Sans", sans-serif',
"fontCode": "monospace"
});

export const lightTheme = create({
"base": "light",
"appBg": "#f1f0eb",
"appContentBg": "#f1f0eb",
"appPreviewBg": "#f1f0eb",
"barBg": "#f1f0eb",
"colorSecondary": "#ff562c",
"textColor": "#2c323f",
"textInverseColor": "#f1f0eb",
"brandImage": "onyxiaLogo.png",
"brandTitle": "Onyxia UI",
"brandUrl": "https://github.com/InseeFrLab/onyxia-ui",
"fontBase": '"Work Sans","Open Sans", sans-serif',
"fontCode": "monospace"
});
24 changes: 20 additions & 4 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
"_format": "prettier '**/*.{ts,tsx,json,md}'",
"format": "yarn _format --write",
"format:check": "yarn _format --list-different",
"emails-domain-accept-list-helper": "tsx scripts/emails-domain-accept-list-helper.ts"
"emails-domain-accept-list-helper": "tsx scripts/emails-domain-accept-list-helper.ts",
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build",
"prestorybook": "tsx scripts/unyamlify-env-local.ts"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.513.0",
Expand Down Expand Up @@ -64,6 +67,17 @@
"zod": "^3.22.4"
},
"devDependencies": {
"@chromatic-com/storybook": "^1.8.0",
"@storybook/addon-a11y": "^8.2.9",
"@storybook/addon-essentials": "^8.2.9",
"@storybook/addon-interactions": "^8.2.9",
"@storybook/addon-links": "^8.2.9",
"@storybook/addon-onboarding": "^8.2.9",
"@storybook/addon-themes": "^8.2.9",
"@storybook/blocks": "^8.2.9",
"@storybook/react": "^8.2.9",
"@storybook/react-vite": "^8.2.9",
"@storybook/test": "^8.2.9",
"@types/bytes": "^3.1.4",
"@types/color": "^3.0.3",
"@types/file-saver": "^2.0.2",
Expand All @@ -75,22 +89,24 @@
"@types/react": "^18.2.43",
"@types/react-dom": "^18.2.17",
"@types/ungap__structured-clone": "0.3.0",
"@vitejs/plugin-react": "^4.2.1",
"eslint-config-prettier": "^9.1.0",
"@typescript-eslint/eslint-plugin": "^7.0.2",
"@typescript-eslint/parser": "^7.0.2",
"@vitejs/plugin-react": "^4.2.1",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.5",
"eslint-plugin-storybook": "^0.8.0",
"eslint-plugin-tss-unused-classes": "^1.0.2",
"husky": "^9.0.11",
"lint-staged": "^15.2.2",
"prettier": "^3.2.5",
"storybook": "^8.2.9",
"storybook-dark-mode": "^4.0.2",
"tsx": "^4.7.1",
"typescript": "^5.4.5",
"vite": "^5.0.8",
"vite-envs": "^4.4.2",
"vite-envs": "^4.4.5",
"vite-plugin-commonjs": "^0.10.1",
"vite-tsconfig-paths": "^4.3.1"
},
Expand Down
12 changes: 10 additions & 2 deletions web/src/ui/App/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ import { injectGlobalStatesInSearchParams } from "powerhooks/useGlobalState";
import { evtLang, I18nFetchingSuspense } from "ui/i18n";
import {
OnyxiaUi,
ScreenScalerOutOfRangeFallbackProvider,
loadThemedFavicon,
injectCustomFontFaceIfNotAlreadyDone
injectCustomFontFaceIfNotAlreadyDone,
targetWindowInnerWidth
} from "ui/theme";
import { PortraitModeUnsupported } from "ui/shared/PortraitModeUnsupported";
import { addParamToUrl } from "powerhooks/tools/urlSearchParams";
Expand All @@ -23,11 +23,19 @@ import { Main } from "./Main";
import { AutoLogoutCountdown } from "./AutoLogoutCountdown";
import { onyxiaInstancePublicUrlKey } from "keycloak-theme/login/onyxiaInstancePublicUrl";
import { useDomRect } from "powerhooks/useDomRect";
import { enableScreenScaler } from "screen-scaler/react";

loadThemedFavicon();
// NOTE: We do that only to showcase the app with an other font with the URL.
injectCustomFontFaceIfNotAlreadyDone();

// NOTE: This must happen very early-on, if overwrite some DOM APIs.
const { ScreenScalerOutOfRangeFallbackProvider } = enableScreenScaler({
"rootDivId": "root",
"targetWindowInnerWidth": ({ zoomFactor, isPortraitOrientation }) =>
isPortraitOrientation ? undefined : targetWindowInnerWidth * zoomFactor
});

const { CoreProvider } = createCoreProvider({
"apiUrl": import.meta.env.ONYXIA_API_URL,
"getCurrentLang": () => evtLang.state,
Expand Down
3 changes: 2 additions & 1 deletion web/src/ui/i18n/resources/no.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,8 @@ export const translations: Translations<"no"> = {
"url textField label": "URL",
"url textField helper text": "URL til S3-tjenesten",
"region textField label": "AWS S3-region",
"region textField helper text": "Eksempel: eu-west-1, hvis du er usikker, la det stå tomt",
"region textField helper text":
"Eksempel: eu-west-1, hvis du er usikker, la det stå tomt",
"workingDirectoryPath textField label": "Arbeidsmappesti",
"workingDirectoryPath textField helper text": (
<>
Expand Down
23 changes: 13 additions & 10 deletions web/src/ui/pages/catalog/Catalog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -163,16 +163,19 @@ export default function Catalog(props: Props) {
/>
{availableCatalogs.length > 1 && route.params.search === "" && (
<div className={classes.catalogSwitcher}>
{availableCatalogs.map(({ catalogId, catalogName }) => (
<CatalogSwitcherButton
key={catalogId}
isSelected={catalogId === selectedCatalog.id}
text={resolveLocalizedString(catalogName)}
onClick={() =>
routes.catalog({ catalogId }).replace()
}
/>
))}
{availableCatalogs.map(({ catalogId, catalogName }) => {
console.log("text", resolveLocalizedString(catalogName));
return (
<CatalogSwitcherButton
key={catalogId}
isSelected={catalogId === selectedCatalog.id}
text={resolveLocalizedString(catalogName)}
onClick={() =>
routes.catalog({ catalogId }).replace()
}
/>
);
})}
</div>
)}
<div ref={scrollableDivRef} className={classes.cardsWrapper}>
Expand Down
84 changes: 84 additions & 0 deletions web/src/ui/pages/catalog/CatalogChartCard.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import type { Meta, StoryObj } from "@storybook/react";
import { CatalogChartCard } from "./CatalogChartCard";
import { action } from "@storybook/addon-actions";
import { StringWithHighlights } from "core/usecases/catalog";

const meta = {
title: "Pages/Catalog/CatalogChartCard",
component: CatalogChartCard
} satisfies Meta<typeof CatalogChartCard>;

export default meta;

type Story = StoryObj<typeof meta>;

const exampleChartNameWithHighlights: StringWithHighlights = {
charArray: [
"E",
"x",
"a",
"m",
"p",
"l",
"e",
" ",
"C",
"h",
"a",
"r",
"t",
" ",
"N",
"a",
"m",
"e"
],
highlightedIndexes: [0, 1, 2, 3, 4, 5, 6] // Highlights "Example"
};

const exampleChartDescriptionWithHighlights: StringWithHighlights = {
charArray: [
"T",
"h",
"i",
"s",
" ",
"i",
"s",
" ",
"a",
"n",
" ",
"e",
"x",
"a",
"m",
"p",
"l",
"e",
" ",
"d",
"e",
"s",
"c",
"r",
"i",
"p",
"t",
"i",
"o",
"n"
],
highlightedIndexes: [11, 12, 13, 14, 15, 16, 17] // Highlights "example"
};

export const Default: Story = {
args: {
chartNameWithHighlights: exampleChartNameWithHighlights,
chartDescriptionWithHighlights: exampleChartDescriptionWithHighlights,
projectHomepageUrl: "https://example.com",
iconUrl:
"https://minio.lab.sspcloud.fr/projet-onyxia/assets/servicesImg/vscode.png",
onRequestLaunch: action("Launch button clicked")
}
};
19 changes: 19 additions & 0 deletions web/src/ui/pages/catalog/CatalogNoSearchMatches.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { Meta, StoryObj } from "@storybook/react";
import { CatalogNoSearchMatches } from "./CatalogNoSearchMatches";
import { action } from "@storybook/addon-actions";

const meta = {
title: "Pages/Catalog/CatalogNoSearchMatches",
component: CatalogNoSearchMatches
} satisfies Meta<typeof CatalogNoSearchMatches>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
search: "example service",
onGoBackClick: action("Go back clicked")
}
};
20 changes: 20 additions & 0 deletions web/src/ui/pages/catalog/CatalogSwitcherButton.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Meta, StoryObj } from "@storybook/react";
import { CatalogSwitcherButton } from "./CatalogSwitcherButton";
import { action } from "@storybook/addon-actions";

const meta = {
title: "Pages/Catalog/CatalogSwitcherButton",
component: CatalogSwitcherButton
} satisfies Meta<typeof CatalogSwitcherButton>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
isSelected: false,
onClick: action("Button clicked"),
text: <span>Interactive services</span>
}
};
Loading
Loading