mirror of
https://github.com/bitwarden/browser
synced 2025-12-11 05:43:41 +00:00
[CL-317] Use storybook theme addon for theme switching (#13451)
This commit is contained in:
1
.github/renovate.json5
vendored
1
.github/renovate.json5
vendored
@@ -209,6 +209,7 @@
|
|||||||
"@storybook/addon-essentials",
|
"@storybook/addon-essentials",
|
||||||
"@storybook/addon-interactions",
|
"@storybook/addon-interactions",
|
||||||
"@storybook/addon-links",
|
"@storybook/addon-links",
|
||||||
|
"@storybook/addon-themes",
|
||||||
"@storybook/angular",
|
"@storybook/angular",
|
||||||
"@storybook/manager-api",
|
"@storybook/manager-api",
|
||||||
"@storybook/theming",
|
"@storybook/theming",
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ const config: StorybookConfig = {
|
|||||||
getAbsolutePath("@storybook/addon-a11y"),
|
getAbsolutePath("@storybook/addon-a11y"),
|
||||||
getAbsolutePath("@storybook/addon-designs"),
|
getAbsolutePath("@storybook/addon-designs"),
|
||||||
getAbsolutePath("@storybook/addon-interactions"),
|
getAbsolutePath("@storybook/addon-interactions"),
|
||||||
|
getAbsolutePath("@storybook/addon-themes"),
|
||||||
{
|
{
|
||||||
// @storybook/addon-docs is part of @storybook/addon-essentials
|
// @storybook/addon-docs is part of @storybook/addon-essentials
|
||||||
// eslint-disable-next-line storybook/no-uninstalled-addons
|
// eslint-disable-next-line storybook/no-uninstalled-addons
|
||||||
|
|||||||
@@ -1,60 +1,30 @@
|
|||||||
import { setCompodocJson } from "@storybook/addon-docs/angular";
|
import { setCompodocJson } from "@storybook/addon-docs/angular";
|
||||||
|
import { withThemeByClassName } from "@storybook/addon-themes";
|
||||||
import { componentWrapperDecorator } from "@storybook/angular";
|
import { componentWrapperDecorator } from "@storybook/angular";
|
||||||
import type { Preview } from "@storybook/angular";
|
import type { Preview } from "@storybook/angular";
|
||||||
|
|
||||||
import docJson from "../documentation.json";
|
import docJson from "../documentation.json";
|
||||||
setCompodocJson(docJson);
|
setCompodocJson(docJson);
|
||||||
|
|
||||||
const decorator = componentWrapperDecorator(
|
const wrapperDecorator = componentWrapperDecorator((story) => {
|
||||||
(story) => {
|
return /*html*/ `
|
||||||
return /*html*/ `
|
<div class="tw-bg-background tw-px-5 tw-py-10">
|
||||||
<div
|
${story}
|
||||||
class="tw-border-2 tw-border-solid tw-px-5 tw-py-10"
|
</div>
|
||||||
[ngClass]="{
|
|
||||||
'tw-bg-[#ffffff] tw-border-secondary-300': theme === 'light',
|
|
||||||
'tw-bg-[#1f242e]': theme === 'dark',
|
|
||||||
}"
|
|
||||||
>
|
|
||||||
${story}
|
|
||||||
</div>
|
|
||||||
`;
|
`;
|
||||||
},
|
});
|
||||||
({ globals }) => {
|
|
||||||
// We need to add the theme class to the body to support body-appended content like popovers and menus
|
|
||||||
document.body.classList.remove("theme_light");
|
|
||||||
document.body.classList.remove("theme_dark");
|
|
||||||
|
|
||||||
document.body.classList.add(`theme_${globals["theme"]}`);
|
|
||||||
|
|
||||||
return { theme: `${globals["theme"]}` };
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const preview: Preview = {
|
const preview: Preview = {
|
||||||
decorators: [decorator],
|
decorators: [
|
||||||
globalTypes: {
|
withThemeByClassName({
|
||||||
theme: {
|
themes: {
|
||||||
description: "Global theme for components",
|
light: "theme_light",
|
||||||
defaultValue: "light",
|
dark: "theme_dark",
|
||||||
toolbar: {
|
|
||||||
title: "Theme",
|
|
||||||
icon: "circlehollow",
|
|
||||||
items: [
|
|
||||||
{
|
|
||||||
title: "Light",
|
|
||||||
value: "light",
|
|
||||||
icon: "sun",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: "Dark",
|
|
||||||
value: "dark",
|
|
||||||
icon: "moon",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
dynamicTitle: true,
|
|
||||||
},
|
},
|
||||||
},
|
defaultTheme: "light",
|
||||||
},
|
}),
|
||||||
|
wrapperDecorator,
|
||||||
|
],
|
||||||
parameters: {
|
parameters: {
|
||||||
controls: {
|
controls: {
|
||||||
matchers: {
|
matchers: {
|
||||||
@@ -69,6 +39,9 @@ const preview: Preview = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
docs: { source: { type: "dynamic", excludeDecorators: true } },
|
docs: { source: { type: "dynamic", excludeDecorators: true } },
|
||||||
|
backgrounds: {
|
||||||
|
disable: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
tags: ["autodocs"],
|
tags: ["autodocs"],
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,10 +9,7 @@ import { ButtonModule } from "../button";
|
|||||||
import { CalloutModule } from "../callout";
|
import { CalloutModule } from "../callout";
|
||||||
import { LayoutComponent } from "../layout";
|
import { LayoutComponent } from "../layout";
|
||||||
import { mockLayoutI18n } from "../layout/mocks";
|
import { mockLayoutI18n } from "../layout/mocks";
|
||||||
import {
|
import { positionFixedWrapperDecorator } from "../stories/storybook-decorators";
|
||||||
disableBothThemeDecorator,
|
|
||||||
positionFixedWrapperDecorator,
|
|
||||||
} from "../stories/storybook-decorators";
|
|
||||||
import { TypographyModule } from "../typography";
|
import { TypographyModule } from "../typography";
|
||||||
import { I18nMockService } from "../utils";
|
import { I18nMockService } from "../utils";
|
||||||
|
|
||||||
@@ -30,7 +27,6 @@ export default {
|
|||||||
},
|
},
|
||||||
decorators: [
|
decorators: [
|
||||||
positionFixedWrapperDecorator(),
|
positionFixedWrapperDecorator(),
|
||||||
disableBothThemeDecorator,
|
|
||||||
moduleMetadata({
|
moduleMetadata({
|
||||||
imports: [
|
imports: [
|
||||||
RouterTestingModule,
|
RouterTestingModule,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
|
|||||||
import { DialogService } from "../../dialog";
|
import { DialogService } from "../../dialog";
|
||||||
import { LayoutComponent } from "../../layout";
|
import { LayoutComponent } from "../../layout";
|
||||||
import { I18nMockService } from "../../utils/i18n-mock.service";
|
import { I18nMockService } from "../../utils/i18n-mock.service";
|
||||||
import { disableBothThemeDecorator, positionFixedWrapperDecorator } from "../storybook-decorators";
|
import { positionFixedWrapperDecorator } from "../storybook-decorators";
|
||||||
|
|
||||||
import { DialogVirtualScrollBlockComponent } from "./components/dialog-virtual-scroll-block.component";
|
import { DialogVirtualScrollBlockComponent } from "./components/dialog-virtual-scroll-block.component";
|
||||||
import { KitchenSinkForm } from "./components/kitchen-sink-form.component";
|
import { KitchenSinkForm } from "./components/kitchen-sink-form.component";
|
||||||
@@ -31,7 +31,6 @@ export default {
|
|||||||
component: LayoutComponent,
|
component: LayoutComponent,
|
||||||
decorators: [
|
decorators: [
|
||||||
positionFixedWrapperDecorator(),
|
positionFixedWrapperDecorator(),
|
||||||
disableBothThemeDecorator,
|
|
||||||
moduleMetadata({
|
moduleMetadata({
|
||||||
imports: [
|
imports: [
|
||||||
KitchenSinkSharedModule,
|
KitchenSinkSharedModule,
|
||||||
|
|||||||
@@ -17,15 +17,3 @@ export const positionFixedWrapperDecorator = (wrapper?: (story: string) => strin
|
|||||||
${wrapper ? wrapper(story) : story}
|
${wrapper ? wrapper(story) : story}
|
||||||
</div>`,
|
</div>`,
|
||||||
);
|
);
|
||||||
|
|
||||||
export const disableBothThemeDecorator = componentWrapperDecorator(
|
|
||||||
(story) => story,
|
|
||||||
({ globals }) => {
|
|
||||||
/**
|
|
||||||
* avoid a bug with the way that we render the same component twice in the same iframe and how
|
|
||||||
* that interacts with the router-outlet
|
|
||||||
*/
|
|
||||||
const themeOverride = globals["theme"] === "both" ? "light" : globals["theme"];
|
|
||||||
return { theme: themeOverride };
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|||||||
17
package-lock.json
generated
17
package-lock.json
generated
@@ -91,6 +91,7 @@
|
|||||||
"@storybook/addon-essentials": "8.5.2",
|
"@storybook/addon-essentials": "8.5.2",
|
||||||
"@storybook/addon-interactions": "8.5.2",
|
"@storybook/addon-interactions": "8.5.2",
|
||||||
"@storybook/addon-links": "8.5.2",
|
"@storybook/addon-links": "8.5.2",
|
||||||
|
"@storybook/addon-themes": "^8.5.2",
|
||||||
"@storybook/angular": "8.5.2",
|
"@storybook/angular": "8.5.2",
|
||||||
"@storybook/manager-api": "8.5.2",
|
"@storybook/manager-api": "8.5.2",
|
||||||
"@storybook/theming": "8.5.2",
|
"@storybook/theming": "8.5.2",
|
||||||
@@ -8713,6 +8714,22 @@
|
|||||||
"storybook": "^8.5.2"
|
"storybook": "^8.5.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@storybook/addon-themes": {
|
||||||
|
"version": "8.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@storybook/addon-themes/-/addon-themes-8.5.2.tgz",
|
||||||
|
"integrity": "sha512-MTJkPwXqLK2Co186EUw2wr+1CpVRMbuWsOmQvhMHeU704kQtSYKkhu/xmaExuDYMupn5xiKG0p8Pt5Ck3fEObQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"ts-dedent": "^2.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/storybook"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"storybook": "^8.5.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@storybook/addon-toolbars": {
|
"node_modules/@storybook/addon-toolbars": {
|
||||||
"version": "8.5.2",
|
"version": "8.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/@storybook/addon-toolbars/-/addon-toolbars-8.5.2.tgz",
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
"@storybook/addon-essentials": "8.5.2",
|
"@storybook/addon-essentials": "8.5.2",
|
||||||
"@storybook/addon-interactions": "8.5.2",
|
"@storybook/addon-interactions": "8.5.2",
|
||||||
"@storybook/addon-links": "8.5.2",
|
"@storybook/addon-links": "8.5.2",
|
||||||
|
"@storybook/addon-themes": "8.5.2",
|
||||||
"@storybook/angular": "8.5.2",
|
"@storybook/angular": "8.5.2",
|
||||||
"@storybook/manager-api": "8.5.2",
|
"@storybook/manager-api": "8.5.2",
|
||||||
"@storybook/theming": "8.5.2",
|
"@storybook/theming": "8.5.2",
|
||||||
|
|||||||
Reference in New Issue
Block a user