Acme
diff --git a/src/stories/Introduction.mdx b/src/stories/Introduction.mdx
index 46e1e0f..a262365 100644
--- a/src/stories/Introduction.mdx
+++ b/src/stories/Introduction.mdx
@@ -1,12 +1,12 @@
-import { Meta } from "@storybook/addon-docs/blocks";
-import Code from "./assets/code-brackets.svg";
-import Colors from "./assets/colors.svg";
-import Comments from "./assets/comments.svg";
-import Direction from "./assets/direction.svg";
-import Flow from "./assets/flow.svg";
-import Plugin from "./assets/plugin.svg";
-import Repo from "./assets/repo.svg";
-import StackAlt from "./assets/stackalt.svg";
+import { Meta } from '@storybook/addon-docs/blocks';
+import Code from './assets/code-brackets.svg';
+import Colors from './assets/colors.svg';
+import Comments from './assets/comments.svg';
+import Direction from './assets/direction.svg';
+import Flow from './assets/flow.svg';
+import Plugin from './assets/plugin.svg';
+import Repo from './assets/repo.svg';
+import StackAlt from './assets/stackalt.svg';
@@ -126,33 +126,21 @@ We recommend building UIs with a [**component-driven**](https://componentdriven.
Configure
- TipEdit the Markdown in{" "}
- stories/Introduction.stories.mdx
+ TipEdit the Markdown in stories/Introduction.stories.mdx
diff --git a/src/stories/Page.tsx b/src/stories/Page.tsx
index 885f2b4..b89b80b 100644
--- a/src/stories/Page.tsx
+++ b/src/stories/Page.tsx
@@ -29,18 +29,16 @@ export const Page: React.FC = () => {
process starting with atomic components and ending with pages.
- Render pages with mock data. This makes it easy to build and review page states without
- needing to navigate to them in your app. Here are some handy patterns for managing page
- data in Storybook:
+ Render pages with mock data. This makes it easy to build and review page states without needing to navigate to
+ them in your app. Here are some handy patterns for managing page data in Storybook:
-
- Use a higher-level connected component. Storybook helps you compose such data from the
- "args" of child component stories
+ Use a higher-level connected component. Storybook helps you compose such data from the args of child
+ component stories
-
- Assemble data in the page component from your services. You can mock these services out
- using Storybook.
+ Assemble data in the page component from your services. You can mock these services out using Storybook.
diff --git a/src/stories/button.css b/src/stories/button.css
index 663afa4..dc91dc7 100644
--- a/src/stories/button.css
+++ b/src/stories/button.css
@@ -1,5 +1,5 @@
.storybook-button {
- font-family: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-weight: 700;
border: 0;
border-radius: 3em;
diff --git a/src/stories/header.css b/src/stories/header.css
index c714b7c..44c549d 100644
--- a/src/stories/header.css
+++ b/src/stories/header.css
@@ -1,5 +1,5 @@
.wrapper {
- font-family: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
padding: 15px 20px;
display: flex;
diff --git a/src/stories/page.css b/src/stories/page.css
index 435173d..fb64fe4 100644
--- a/src/stories/page.css
+++ b/src/stories/page.css
@@ -1,5 +1,5 @@
section {
- font-family: "Nunito Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 24px;
padding: 48px 20px;
diff --git a/src/withHTML.ts b/src/withHTML.ts
index b34ea1e..c693198 100644
--- a/src/withHTML.ts
+++ b/src/withHTML.ts
@@ -1,41 +1,43 @@
-import { useChannel } from "storybook/internal/preview-api";
-import type {
- Renderer,
- PartialStoryFn as StoryFunction,
-} from "storybook/internal/types";
-import { EVENTS } from "./constants";
-import { Parameters } from "./types";
+import { useChannel } from 'storybook/internal/preview-api';
+import type { Renderer, PartialStoryFn as StoryFunction } from 'storybook/internal/types';
+import { EVENTS } from './constants';
+import { Parameters } from './types';
export const withHTML = (
storyFn: StoryFunction,
- {
- parameters: { html: parameters = {} } = {},
- }: { parameters?: { html?: Parameters } },
+ { parameters: { html: parameters = {} } = {} }: { parameters?: { html?: Parameters } },
) => {
const emit = useChannel({});
- setTimeout(() => {
- const rootSelector = parameters.root || "#storybook-root, #root";
+ setTimeout(async () => {
+ const rootSelector = parameters.root || '#storybook-root, #root';
const root = document.querySelector(rootSelector);
let code: string = root ? root.innerHTML : `${rootSelector} not found.`;
const { removeEmptyComments, removeComments, transform } = parameters;
if (removeEmptyComments) {
- code = code.replace(//g, "");
+ code = code.replace(//g, '');
}
if (removeComments === true) {
- code = code.replace(//g, "");
+ code = code.replace(//g, '');
} else if (removeComments instanceof RegExp) {
- code = code.replace(//g, (match, p1) =>
- removeComments.test(p1) ? "" : match,
- );
+ code = code.replace(//g, (match, p1) => (removeComments.test(p1) ? '' : match));
}
- if (typeof transform === "function") {
+ if (typeof transform === 'function') {
try {
code = transform(code);
} catch (e) {
console.error(e);
}
}
+
+ const prettier = await import('prettier/standalone');
+ const prettierPluginHtml = await import('prettier/plugins/html');
+
+ code = await prettier.format(code, {
+ parser: 'html',
+ plugins: [prettierPluginHtml]
+ });
+
emit(EVENTS.CODE_UPDATE, { code, options: parameters });
}, 0);
diff --git a/tsconfig.json b/tsconfig.json
index ece12d3..cf6b418 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,18 +1,23 @@
{
"compilerOptions": {
- "allowSyntheticDefaultImports": true,
- "baseUrl": ".",
"esModuleInterop": true,
- "experimentalDecorators": true,
- "incremental": false,
- "isolatedModules": true,
+ "skipLibCheck": true,
+ "target": "esnext", // Node 20 according to https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping#node-20
+ "allowJs": true,
+ "resolveJsonModule": true,
+ "moduleDetection": "force",
+ "moduleResolution": "bundler",
+ "module": "preserve",
"jsx": "react",
- "lib": ["es2020", "dom"],
- "module": "commonjs",
+ "isolatedModules": true,
+ "verbatimModuleSyntax": true,
+ "strict": true,
+ "noUncheckedIndexedAccess": true,
+ "noImplicitOverride": true,
"noImplicitAny": true,
- "rootDir": "./src",
- "skipLibCheck": true,
- "target": "ES2020"
+ "lib": ["esnext", "dom", "dom.iterable"],
+ "baseUrl": ".",
+ "rootDir": "."
},
- "include": ["src/**/*"]
+ "include": ["src/**/*", "tsup.config.ts"]
}
diff --git a/tsup.config.ts b/tsup.config.ts
index 18529b8..35a4ed4 100644
--- a/tsup.config.ts
+++ b/tsup.config.ts
@@ -1,116 +1,81 @@
-import { defineConfig, type Options } from "tsup";
-import { readFile } from "node:fs/promises";
-import { globalPackages as globalManagerPackages } from "storybook/internal/manager/globals";
-import { globalPackages as globalPreviewPackages } from "storybook/internal/preview/globals";
+import { defineConfig, type Options } from 'tsup';
-// The current browsers supported by Storybook v7
-const BROWSER_TARGET: Options["target"] = [
- "chrome100",
- "safari15",
- "firefox91",
-];
-const NODE_TARGET: Options["target"] = ["node18"];
+const NODE_TARGET = 'node20.19'; // Minimum Node version supported by Storybook 10
-type BundlerConfig = {
- bundler?: {
- exportEntries?: string[];
- nodeEntries?: string[];
- managerEntries?: string[];
- previewEntries?: string[];
- };
-};
-
-export default defineConfig(async (options) => {
+export default defineConfig(async () => {
// reading the three types of entries from package.json, which has the following structure:
// {
// ...
// "bundler": {
- // "exportEntries": ["./src/index.ts"],
// "managerEntries": ["./src/manager.ts"],
- // "previewEntries": ["./src/preview.ts"]
+ // "previewEntries": ["./src/preview.ts", "./src/index.ts"]
// "nodeEntries": ["./src/preset.ts"]
// }
// }
- const packageJson = (await readFile("./package.json", "utf8").then(
- JSON.parse,
- )) as BundlerConfig;
+ const packageJson = (await import('./package.json', { with: { type: 'json' } })).default;
+
const {
- bundler: {
- exportEntries = [],
- managerEntries = [],
- previewEntries = [],
- nodeEntries = [],
- } = {},
+ bundler: { managerEntries = [], previewEntries = [], nodeEntries = [] },
} = packageJson;
const commonConfig: Options = {
- splitting: false,
- minify: !options.watch,
+ /*
+ keep this line commented until https://github.com/egoist/tsup/issues/1270 is resolved
+ clean: options.watch ? false : true,
+ */
+ clean: false,
+ format: ['esm'],
treeshake: true,
- sourcemap: true,
- clean: options.watch ? false : true,
+ splitting: true,
+ /*
+ The following packages are provided by Storybook and should always be externalized
+ Meaning they shouldn't be bundled with the addon, and they shouldn't be regular dependencies either
+ */
+ external: ['react', 'react-dom', '@storybook/icons'],
};
const configs: Options[] = [];
- // export entries are entries meant to be manually imported by the user
- // they are not meant to be loaded by the manager or preview
- // they'll be usable in both node and browser environments, depending on which features and modules they depend on
- if (exportEntries.length) {
- configs.push({
- ...commonConfig,
- entry: exportEntries,
- dts: {
- resolve: true,
- },
- format: ["esm", "cjs"],
- target: [...BROWSER_TARGET, ...NODE_TARGET],
- platform: "neutral",
- external: [...globalManagerPackages, ...globalPreviewPackages],
- });
- }
-
- // manager entries are entries meant to be loaded into the manager UI
- // they'll have manager-specific packages externalized and they won't be usable in node
- // they won't have types generated for them as they're usually loaded automatically by Storybook
+ /*
+ manager entries are entries meant to be loaded into the manager UI
+ they'll have manager-specific packages externalized and they won't be usable in node
+ they won't have types generated for them as they're usually loaded automatically by Storybook
+ */
if (managerEntries.length) {
configs.push({
...commonConfig,
entry: managerEntries,
- format: ["esm"],
- target: BROWSER_TARGET,
- platform: "browser",
- external: globalManagerPackages,
+ platform: 'browser',
+ target: 'esnext', // we can use esnext for manager entries since Storybook will bundle the addon's manager entries again anyway
});
}
- // preview entries are entries meant to be loaded into the preview iframe
- // they'll have preview-specific packages externalized and they won't be usable in node
- // they'll have types generated for them so they can be imported when setting up Portable Stories
+ /*
+ preview entries are entries meant to be loaded into the preview iframe
+ they'll have preview-specific packages externalized and they won't be usable in node
+ they'll have types generated for them so they can be imported by users when setting up Portable Stories or using CSF factories
+ */
if (previewEntries.length) {
configs.push({
...commonConfig,
entry: previewEntries,
- dts: {
- resolve: true,
- },
- format: ["esm", "cjs"],
- target: BROWSER_TARGET,
- platform: "browser",
- external: globalPreviewPackages,
+ platform: 'browser',
+ target: 'esnext', // we can use esnext for preview entries since the builders will bundle the addon's preview entries again anyway
+ dts: true,
});
}
- // node entries are entries meant to be used in node-only
- // this is useful for presets, which are loaded by Storybook when setting up configurations
- // they won't have types generated for them as they're usually loaded automatically by Storybook
+ /*
+ node entries are entries meant to be used in node-only
+ this is useful for presets, which are loaded by Storybook when setting up configurations
+ they won't have types generated for them as they're usually loaded automatically by Storybook
+ */
if (nodeEntries.length) {
configs.push({
...commonConfig,
entry: nodeEntries,
- format: ["cjs"],
+ platform: 'node',
target: NODE_TARGET,
- platform: "node",
});
}
diff --git a/vite.config.ts b/vite.config.ts
index 9cc50ea..627a319 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,5 +1,5 @@
-import { defineConfig } from "vite";
-import react from "@vitejs/plugin-react";
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({