Skip to content
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
10 changes: 4 additions & 6 deletions .github/workflows/chromatic-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ jobs:
- name: Update npm to 11.15.0
run: npm install -g npm@11.15.0
- run: npm ci
- uses: chromaui/action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
onlyChanged: true
exitOnceUploaded: true # We don't want it to fail CI, we'll be using the GitHub Check
- name: Run chromatic
run: npx chromatic --project-token ${{ secrets.CHROMATIC_PROJECT_TOKEN }} --only-changed --exit-once-uploaded
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ src/style-config/assets.scss
storybook-static/
.swc/
bundle-stats/
debug-storybook.log

playwright/test-results
playwright/test-report
Expand Down
2 changes: 1 addition & 1 deletion .storybook/interaction-toggle/reduced-motion.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useCallback, useEffect, useState } from "react";

import { IconButton } from "@storybook/components";
import { IconButton } from "storybook/internal/components";
import { CheckIcon, CrossIcon } from "@storybook/icons";
import { INTERACTION_TOGGLE_TOOL_ID } from "./constants";

Expand Down
53 changes: 38 additions & 15 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { StorybookConfig } from "@storybook/react-vite";
// This file has been automatically migrated to valid ESM format by Storybook.
import { fileURLToPath } from "node:url";
import type { StorybookConfig } from "@storybook/react-vite";
import type { UserConfig } from "vite";

import react from "@vitejs/plugin-react";
import { viteStaticCopy } from "vite-plugin-static-copy";

import path from "path";
import path, { dirname } from "path";

import glob from "glob";

import remarkGfm from "remark-gfm";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);

const projectRoot = path.resolve(__dirname, "../");
const ignoreTests = process.env.IGNORE_TESTS === "true";
const enableReactStrictMode = process.env.ENABLE_REACT_STRICT_MODE === "true";
Expand Down Expand Up @@ -45,8 +51,6 @@ const config: StorybookConfig = {

addons: [
"@storybook/addon-a11y",
"@storybook/addon-actions",
"@storybook/addon-controls",
{
name: "@storybook/addon-docs",
options: {
Expand All @@ -57,22 +61,20 @@ const config: StorybookConfig = {
},
},
},
"@storybook/addon-interactions",
"storybook-addon-pseudo-states",
"@storybook/addon-essentials",
"@storybook/addon-toolbars",
"@storybook/addon-viewport",
"@chromatic-com/storybook",
],
Comment on lines 52 to 66

Copilot AI Apr 10, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The addons list drops @storybook/addon-actions, @storybook/addon-controls, and @storybook/addon-viewport / @storybook/addon-essentials, but the codebase still uses action(...) across many *-test.stories.tsx and relies on controls/viewport parameters in preview.ts. Unless Storybook v10 is configured elsewhere to include these capabilities, this will remove expected UI panels/behavior. Re-add @storybook/addon-essentials (or the specific addons you need) to keep actions/controls/viewport working.

Copilot uses AI. Check for mistakes.

staticDirs: ["../.assets", "../logo"],

viteFinal: async (config) => {
viteFinal: async (config: UserConfig) => {
const { mergeConfig } = await import("vite");

return mergeConfig(config, {
plugins: [
react(),
react({
exclude: [/\.storybook\//],
}),
viteStaticCopy({
targets: [
{
Expand Down Expand Up @@ -111,12 +113,12 @@ const config: StorybookConfig = {
},

...(isChromatic && {
previewHead: (head) => `
${head}
previewHead: (head: string | undefined) => `
${head || ""}
<meta name="robots" content="noindex">
`,
managerHead: (head) => `
${head}
managerHead: (head: string | undefined) => `
${head || ""}
<meta name="robots" content="noindex">
`,
}),
Expand All @@ -127,7 +129,28 @@ const config: StorybookConfig = {
// Exclude legacy Switch component from react-docgen as it's intended to be removed
// in a future release and causes confusion for Storybook generating docs.
reactDocgenTypescriptOptions: {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: when running storybook locally we're met with quite a few Vite warnings for docgen skipping

Vite warning: Skipping docgen for
│  "/Users/thomas.davies/development-work/carbon/.storybook/utils/deprecation-warning.component.tsx"
│  because it is not included in the active TypeScript project.
│  Plugin: vite:react-docgen-typescript
│  File:

Could we do some sort of exclusion in here to avoid this?

exclude: ["**/switch/switch.component.tsx"],
exclude: ["**/switch/switch.component.tsx", "**/.storybook/**"],
shouldExtractLiteralValuesFromEnum: true,
shouldRemoveUndefinedFromOptional: true,
shouldIncludePropTagMap: true,
propFilter: (prop) => {
const parentFile = prop.parent?.fileName;

if (!parentFile) {
return true;
}

if (parentFile.includes(".storybook")) {
return false;
}

// Prevent inherited DOM and third-party utility types from flooding docs tables.
if (parentFile.includes("/node_modules/")) {
return false;
}

return true;
},
},
},

Expand Down
73 changes: 73 additions & 0 deletions .storybook/manager-head.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,76 @@
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5" />
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" />

<style>
#storybook-explorer-toolbar,
[role="toolbar"],
[role="region"][data-testid="sb-preview-toolbar"] {
background-color: #000000 !important;
background: #000000 !important;
box-shadow: black 0px -1px 0px 0px inset !important;
}

#storybook-explorer-toolbar *,
[role="toolbar"] * {
color: #FFFFFF !important;
}

#storybook-explorer-toolbar button,
#storybook-explorer-toolbar svg,
[role="toolbar"] button,
[role="toolbar"] svg {
color: #FFFFFF !important;
fill: #FFFFFF !important;
}

[role="toolbar"] button,
[role="toolbar"] button *,
[role="toolbar"] div {
background-color: transparent !important;
background: transparent !important;
}

[role="toolbar"] button:hover,
[role="toolbar"] button * {
color: #FFFFFF !important;
fill: #FFFFFF !important;
}

[role="toolbar"] button:hover,
[role="toolbar"] button:hover * {
color: #00DC00 !important;
fill: #00DC00 !important;
opacity: 0.8 !important;
}

[role="toolbar"] button[aria-label*="Locale"],
[role="toolbar"] button[aria-label*="Colour Mode"],
[role="toolbar"] button[aria-label*="Theme"],
[role="toolbar"] button[aria-label*="locale"],
[role="toolbar"] button[aria-label*="mode"],
[role="toolbar"] button[aria-label*="theme"],
[role="toolbar"] button[aria-label*="Locale"] *,
[role="toolbar"] button[aria-label*="Colour Mode"] *,
[role="toolbar"] button[aria-label*="Theme"] *,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question (non-blocking): would * not cover the below where we're targeting svg children?

[role="toolbar"] button[aria-label*="locale"] *,
[role="toolbar"] button[aria-label*="mode"] *,
[role="toolbar"] button[aria-label*="theme"] * {
color: #00DC00 !important;
fill: #00DC00 !important;
}

[role="toolbar"] button[title*="version"] *,
[role="toolbar"] button[aria-label*="interaction"] * {
color: #00DC00 !important;
fill: #00DC00 !important;
}

[role="toolbar"] button[title*="version"],
[role="toolbar"] button[aria-label*="interaction"] {
color: #00DC00 !important;
fill: #00DC00 !important;
box-shadow: #00DC00 0px 0px 0px 1px inset !important;
}

</style>
15 changes: 2 additions & 13 deletions .storybook/manager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { addons, types } from "@storybook/manager-api";
import { addons, types } from "storybook/manager-api";
import sageTheme from "./sage-docs-theme";
import { ADDON_ID, TOOL_ID } from "./version-picker/constants";
import {
Expand All @@ -7,7 +7,6 @@ import {
} from "./interaction-toggle/constants";
import { InteractionToggle } from "./interaction-toggle/reduced-motion";
import VersionPicker from "./version-picker";
import { API_PreparedIndexEntry, API_StatusObject } from "@storybook/types";

addons.register(ADDON_ID, () => {
addons.add(TOOL_ID, {
Expand All @@ -30,15 +29,5 @@ addons.register(INTERACTION_TOGGLE_ADDON_ID, () => {
addons.setConfig({
theme: sageTheme,
panelPosition: "bottom",
sidebar: {
filters: {
patterns: (
item: API_PreparedIndexEntry & {
status: Record<string, API_StatusObject | null>;
},
): boolean => {
return !(item.tags ?? []).includes("hideInSidebar");
},
},
},
selectedPanel: "storybook/a11y/panel",
});
70 changes: 65 additions & 5 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Preview } from "@storybook/react";
import { configure } from "@storybook/test";
import { Preview } from "@storybook/react-vite";
import { configure } from "storybook/test";

import "../src/style/fonts.css";

Expand All @@ -11,6 +11,65 @@ import { withThemeProvider, globalThemeProvider } from "./withThemeProvider";
import withReducedMotion from "./with-reduced-motion";
import withFusionTokens from "./with-fusion-tokens";

type DocgenProp = {
tags?: {
deprecated?: string;
};
};

type DocgenComponent = {
__docgenInfo?: {
props?: Record<string, DocgenProp | undefined>;
};
};

// Temporary workaround for Storybook docs not rendering JSDoc @deprecated tag text
// from extracted argTypes in this repo's current Storybook version line.
const deprecatedJsDocArgTypesEnhancer = ((context) => {
const component = context.component as DocgenComponent | undefined;
const docgenProps = component?.__docgenInfo?.props;

if (!docgenProps) {
return context.argTypes;
}

const nextArgTypes = Object.entries(context.argTypes).reduce(
(acc, [argName, argType]) => {
const deprecationMessage = docgenProps[argName]?.tags?.deprecated;

if (!deprecationMessage) {
acc[argName] = argType;
return acc;
}

const normalizedMessage = deprecationMessage.trim();

if (!normalizedMessage) {
acc[argName] = argType;
return acc;
}

const nextJsDocTags = {
...(argType.table?.jsDocTags as Record<string, unknown> | undefined),
deprecated: normalizedMessage,
};

acc[argName] = {
...argType,
table: {
...argType.table,
jsDocTags: nextJsDocTags,
},
};

return acc;
},
{} as typeof context.argTypes,
);

return nextArgTypes;
}) satisfies NonNullable<Preview["argTypesEnhancers"]>[number];

// Configure the testIdAttribute to look for data-role when querying elements using `getByTestId`.
configure({ testIdAttribute: "data-role" });

Expand Down Expand Up @@ -40,7 +99,7 @@ const parameters = {
},
},
chromatic: { disableSnapshot: false },
viewport: { viewports: customViewports },
viewport: { options: customViewports },
viewMode: import.meta.env.STORYBOOK_VIEW_MODE,
};

Expand Down Expand Up @@ -83,8 +142,8 @@ const globalTypes = {
showName: true,
},
},
...globalThemeProvider,
};
...(globalThemeProvider as object),
} as Preview["globalTypes"];

const decorators = [
withGlobalStyles,
Expand All @@ -108,6 +167,7 @@ const loaders =
const preview: Preview = {
parameters,
decorators,
argTypesEnhancers: [deprecatedJsDocArgTypesEnhancer],
globalTypes,
loaders,
};
Expand Down
16 changes: 5 additions & 11 deletions .storybook/sage-docs-theme.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { create } from "@storybook/theming/create";
import { create } from "storybook/theming/create";

export default create({
base: "light",
Expand All @@ -9,28 +9,22 @@ export default create({
// UI
appBg: "#FFFFFF",
appContentBg: "#f2f5f6",
appBorderColor: "#000000",
appBorderColor: "#CCD1D2",
appBorderRadius: 4,

// Typography
fontBase: '"Sage UI", sans-serif',
fontCode: "monospace",

// Text colors
textColor: "rgba(0,0,0,0.9)",
textColor: "rgba(0,0,0,1)",
textInverseColor: "rgba(255,255,255,1)",

// Toolbar default and active colors
barTextColor: "white",
barSelectedColor: "#00DC00",
barBg: "#000000",

// Form colors
inputBg: "white",
inputBorder: "#668592",
inputTextColor: "rgba(0,0,0,0.9)",
inputBorderRadius: 0,

brandTitle: "Carbon by Sage",
brandUrl: "https://carbon.sage.com",
brandImage: "carbon-by-sage-logo.png",
});

2 changes: 1 addition & 1 deletion .storybook/sage-storybook-theme.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { create } from "@storybook/theming/create";
import { create } from "storybook/theming/create";

export default create({
base: "light",
Expand Down
Loading
Loading