@storybook/tanstack-react 10.5.7 → 10.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_browser-chunks/{chunk-6UULZFFJ.js → chunk-TR4QWDPU.js} +38 -14
- package/dist/{chunk-CT6Edisg.d.ts → chunk-B0pqNVvJ.d.ts} +5 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/node/index.d.ts +1 -1
- package/dist/node/index.js +6 -6
- package/dist/preset.js +20 -13
- package/dist/preview.d.ts +4 -3
- package/dist/preview.js +3 -1
- package/package.json +5 -5
- package/template/stories/LoaderContextInjection.stories.tsx +45 -0
- package/template/stories/RouterContextInjection.stories.tsx +45 -0
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
var preview_exports = {};
|
|
10
10
|
__export(preview_exports, {
|
|
11
11
|
applyDecorators: () => applyDecorators,
|
|
12
|
+
beforeEach: () => beforeEach,
|
|
12
13
|
loaders: () => loaders,
|
|
13
14
|
optimizeDeps: () => optimizeDeps,
|
|
14
15
|
parameters: () => parameters
|
|
@@ -16,16 +17,16 @@ __export(preview_exports, {
|
|
|
16
17
|
import { applyDecorators as reactApplyDecorators } from "@storybook/react/entry-preview-docs";
|
|
17
18
|
|
|
18
19
|
// src/routing/decorator.tsx
|
|
19
|
-
import React from "react";
|
|
20
20
|
import {
|
|
21
21
|
createMemoryHistory,
|
|
22
22
|
createRootRoute,
|
|
23
23
|
createRoute as createRoute2,
|
|
24
24
|
createRouter,
|
|
25
|
-
|
|
25
|
+
defaultStringifySearch,
|
|
26
26
|
interpolatePath,
|
|
27
|
-
|
|
27
|
+
RouterProvider
|
|
28
28
|
} from "@tanstack/react-router";
|
|
29
|
+
import React from "react";
|
|
29
30
|
|
|
30
31
|
// src/routing/duplicate-tree.ts
|
|
31
32
|
import {
|
|
@@ -133,17 +134,15 @@ var StoryContext = React.createContext({ Story: () => null }), StoryFromContext
|
|
|
133
134
|
return React.createElement(Story, null);
|
|
134
135
|
}, tanstackRouteDecorator = (Story, context) => React.createElement(TanStackRouterStory, { Story, context });
|
|
135
136
|
function TanStackRouterStory({ Story, context }) {
|
|
136
|
-
let routerContext = context.parameters.tanstack?.router?.useRouterContext?.({
|
|
137
|
+
let router = context.tanstackRouter, routerContext = context.parameters.tanstack?.router?.useRouterContext?.({
|
|
137
138
|
storyContext: context
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
...routerContext
|
|
146
|
-
}),
|
|
139
|
+
});
|
|
140
|
+
if (!router)
|
|
141
|
+
throw new Error(
|
|
142
|
+
"No story router found on the story context: the `routerBeforeEach` hook of @storybook/tanstack-react did not run before rendering. Note that portable stories are not supported by this framework."
|
|
143
|
+
);
|
|
144
|
+
let providerContext = React.useMemo(
|
|
145
|
+
() => routerContext,
|
|
147
146
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
148
147
|
[context.id, routerContext]
|
|
149
148
|
);
|
|
@@ -242,6 +241,30 @@ function resolveTree(Story, context) {
|
|
|
242
241
|
};
|
|
243
242
|
}
|
|
244
243
|
|
|
244
|
+
// src/routing/before-each.ts
|
|
245
|
+
var storyRouters = /* @__PURE__ */ new Map(), routerBeforeEach = async (context) => {
|
|
246
|
+
let cached = storyRouters.get(context.id);
|
|
247
|
+
if (cached) {
|
|
248
|
+
context.tanstackRouter = cached;
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
let storyContext = context, parameterContext = (context.parameters.tanstack?.router ?? {}).context, routerContext = typeof parameterContext == "function" ? parameterContext({ storyContext }) : parameterContext, router = createStoryRouter({
|
|
252
|
+
Story: StoryFromContext,
|
|
253
|
+
context: storyContext,
|
|
254
|
+
routerContext
|
|
255
|
+
}), load = router.load();
|
|
256
|
+
if (context.abortSignal && !context.abortSignal.aborted ? (load.catch(() => {
|
|
257
|
+
}), await Promise.race([
|
|
258
|
+
load,
|
|
259
|
+
new Promise(
|
|
260
|
+
(resolve) => context.abortSignal.addEventListener("abort", () => resolve(), { once: !0 })
|
|
261
|
+
)
|
|
262
|
+
])) : await load, !context.abortSignal?.aborted)
|
|
263
|
+
return storyRouters.set(context.id, router), context.tanstackRouter = router, () => {
|
|
264
|
+
storyRouters.delete(context.id);
|
|
265
|
+
};
|
|
266
|
+
};
|
|
267
|
+
|
|
245
268
|
// src/routing/loader.ts
|
|
246
269
|
import { RootRoute as RootRoute3 } from "@tanstack/react-router";
|
|
247
270
|
function getComponentFromRoute(route) {
|
|
@@ -262,7 +285,7 @@ var routeComponentLoader = (context) => {
|
|
|
262
285
|
};
|
|
263
286
|
|
|
264
287
|
// src/preview.tsx
|
|
265
|
-
var loaders = [routeComponentLoader], applyDecorators = (storyFn, allDecorators) => (
|
|
288
|
+
var loaders = [routeComponentLoader], beforeEach = [routerBeforeEach], applyDecorators = (storyFn, allDecorators) => (
|
|
266
289
|
// reorder decorators so `jsxDecorator` is innermost, and `tanstackRouteDecorator` is just outside it
|
|
267
290
|
// There is an issue if `tanstackRouteDecorator` is innermost. All stories crashes due to a bug with the jsxDecorator.
|
|
268
291
|
reactApplyDecorators(storyFn, [
|
|
@@ -279,6 +302,7 @@ var loaders = [routeComponentLoader], applyDecorators = (storyFn, allDecorators)
|
|
|
279
302
|
|
|
280
303
|
export {
|
|
281
304
|
loaders,
|
|
305
|
+
beforeEach,
|
|
282
306
|
applyDecorators,
|
|
283
307
|
parameters,
|
|
284
308
|
optimizeDeps,
|
|
@@ -86,10 +86,11 @@ interface RouterParameters<TRoute = undefined, Path extends (TRoute extends AnyR
|
|
|
86
86
|
* ```
|
|
87
87
|
*/
|
|
88
88
|
routeOverrides?: RouteTreeOverrides;
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
/** Object or factory; the factory runs before initial router load outside React, so loader and beforeLoad can read its values. */
|
|
90
|
+
context?: Record<string, unknown> | ((options: {
|
|
91
|
+
storyContext: Parameters<Decorator>[1];
|
|
92
|
+
}) => Record<string, unknown>);
|
|
93
|
+
/** React hook render context reaches components, not the initial loader or beforeLoad; use the context factory for loader-visible values. */
|
|
93
94
|
useRouterContext?: ({
|
|
94
95
|
storyContext
|
|
95
96
|
}: {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as TanStackPreviewOptions, c as IsRoute, d as StoryRouteOptions, i as TanStackParameters, l as RouterParameters, n as FrameworkOptions, o as TanStackTypes, r as StorybookConfig, s as CreateStoryRouteOptions, t as DefaultStoryPath, u as StoryRouteFileOptions } from "./chunk-
|
|
1
|
+
import { a as TanStackPreviewOptions, c as IsRoute, d as StoryRouteOptions, i as TanStackParameters, l as RouterParameters, n as FrameworkOptions, o as TanStackTypes, r as StorybookConfig, s as CreateStoryRouteOptions, t as DefaultStoryPath, u as StoryRouteFileOptions } from "./chunk-B0pqNVvJ.js";
|
|
2
2
|
import { ComponentType } from "react";
|
|
3
3
|
import { AddonTypes, InferTypes, PreviewAddon } from "storybook/internal/csf";
|
|
4
4
|
import { Args, ArgsStoryFn, ComponentAnnotations, DecoratorFunction, Parameters, ProjectAnnotations, Renderer, StoryAnnotations } from "storybook/internal/types";
|
package/dist/index.js
CHANGED
package/dist/node/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as StorybookConfig } from "../chunk-
|
|
1
|
+
import { r as StorybookConfig } from "../chunk-B0pqNVvJ.js";
|
|
2
2
|
|
|
3
3
|
//#region code/frameworks/tanstack-react/.dts-emit/code/frameworks/tanstack-react/src/node/index.d.ts
|
|
4
4
|
declare function defineMain(config: StorybookConfig): StorybookConfig;
|
package/dist/node/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import CJS_COMPAT_NODE_URL_466ftmvrh3c from 'node:url';
|
|
2
|
+
import CJS_COMPAT_NODE_PATH_466ftmvrh3c from 'node:path';
|
|
3
|
+
import CJS_COMPAT_NODE_MODULE_466ftmvrh3c from "node:module";
|
|
4
4
|
|
|
5
|
-
var __filename =
|
|
6
|
-
var __dirname =
|
|
7
|
-
var require =
|
|
5
|
+
var __filename = CJS_COMPAT_NODE_URL_466ftmvrh3c.fileURLToPath(import.meta.url);
|
|
6
|
+
var __dirname = CJS_COMPAT_NODE_PATH_466ftmvrh3c.dirname(__filename);
|
|
7
|
+
var require = CJS_COMPAT_NODE_MODULE_466ftmvrh3c.createRequire(import.meta.url);
|
|
8
8
|
|
|
9
9
|
// ------------------------------------------------------------
|
|
10
10
|
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
|
package/dist/preset.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import CJS_COMPAT_NODE_URL_466ftmvrh3c from 'node:url';
|
|
2
|
+
import CJS_COMPAT_NODE_PATH_466ftmvrh3c from 'node:path';
|
|
3
|
+
import CJS_COMPAT_NODE_MODULE_466ftmvrh3c from "node:module";
|
|
4
4
|
|
|
5
|
-
var __filename =
|
|
6
|
-
var __dirname =
|
|
7
|
-
var require =
|
|
5
|
+
var __filename = CJS_COMPAT_NODE_URL_466ftmvrh3c.fileURLToPath(import.meta.url);
|
|
6
|
+
var __dirname = CJS_COMPAT_NODE_PATH_466ftmvrh3c.dirname(__filename);
|
|
7
|
+
var require = CJS_COMPAT_NODE_MODULE_466ftmvrh3c.createRequire(import.meta.url);
|
|
8
8
|
|
|
9
9
|
// ------------------------------------------------------------
|
|
10
10
|
// end of CJS compatibility banner, injected by Storybook's esbuild configuration
|
|
@@ -30,6 +30,17 @@ var dirname = function(p) {
|
|
|
30
30
|
// src/preset.ts
|
|
31
31
|
import { viteFinal as reactViteFinal } from "@storybook/react-vite/preset";
|
|
32
32
|
|
|
33
|
+
// src/plugins/incompatible-plugins.ts
|
|
34
|
+
var matchesPluginName = (p, matches) => {
|
|
35
|
+
if (Array.isArray(p))
|
|
36
|
+
return p.some((entry) => matchesPluginName(entry, matches));
|
|
37
|
+
let pluginRecord = p;
|
|
38
|
+
return typeof p == "object" && p !== null && "name" in pluginRecord && typeof pluginRecord.name == "string" && matches(pluginRecord.name);
|
|
39
|
+
}, isTanStackStartPlugin = (p) => matchesPluginName(p, (name) => name.startsWith("tanstack-start") || name.includes("rsc:")), isCloudflareVitePlugin = (p) => matchesPluginName(
|
|
40
|
+
p,
|
|
41
|
+
(name) => name === "vite-plugin-cloudflare" || name.startsWith("vite-plugin-cloudflare:")
|
|
42
|
+
);
|
|
43
|
+
|
|
33
44
|
// src/plugins/server-code-elimination.ts
|
|
34
45
|
import { types as t, transformSync } from "storybook/internal/babel";
|
|
35
46
|
var SERVER_FN_RE = /\bcreateServerFn\b/, MIDDLEWARE_RE = /\bcreateMiddleware\b/, ISOMORPHIC_FN_RE = /\bcreateIsomorphicFn\b/, SERVER_ONLY_FN_RE = /\bcreateServerOnlyFn\b/, CLIENT_ONLY_FN_RE = /\bcreateClientOnlyFn\b/, ROUTE_FACTORY_RE = /\b(createFileRoute|createRootRoute|createRootRouteWithContext|createRoute)\b/, ROUTE_FACTORIES = /* @__PURE__ */ new Set([
|
|
@@ -413,17 +424,13 @@ var core = async (config, options) => {
|
|
|
413
424
|
"@tanstack/react-router > @tanstack/react-store",
|
|
414
425
|
"use-sync-external-store/shim/with-selector"
|
|
415
426
|
], viteFinal = async (config, options) => {
|
|
416
|
-
let reactConfig = await reactViteFinal(config, options),
|
|
417
|
-
if (Array.isArray(p))
|
|
418
|
-
return p.some(isTanStackStartPlugin);
|
|
419
|
-
let pluginRecord = p;
|
|
420
|
-
return typeof p == "object" && p !== null && "name" in pluginRecord && typeof pluginRecord.name == "string" && (pluginRecord.name.startsWith("tanstack-start") || pluginRecord.name.includes("rsc:"));
|
|
421
|
-
}, startMockPath = fileURLToPath(import.meta.resolve("./export-mocks/start.js")), startStorageContextMockPath = fileURLToPath(
|
|
427
|
+
let reactConfig = await reactViteFinal(config, options), startMockPath = fileURLToPath(import.meta.resolve("./export-mocks/start.js")), startStorageContextMockPath = fileURLToPath(
|
|
422
428
|
import.meta.resolve("./export-mocks/start-storage-context.js")
|
|
423
429
|
), routerMockPath = fileURLToPath(
|
|
424
430
|
import.meta.resolve("@storybook/tanstack-react/react-router")
|
|
425
431
|
), plugins = [
|
|
426
|
-
|
|
432
|
+
// Drop user plugins that are incompatible with Storybook — see ./plugins/incompatible-plugins.ts
|
|
433
|
+
...(reactConfig.plugins ?? []).filter((p) => !isTanStackStartPlugin(p) && !isCloudflareVitePlugin(p)),
|
|
427
434
|
serverCodeEliminationPlugin({ excludeFiles: [dirname(startMockPath)] }),
|
|
428
435
|
serverOnlyStubPlugin(),
|
|
429
436
|
moduleInterceptionPlugin({ startMockPath, startStorageContextMockPath, routerMockPath })
|
package/dist/preview.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { i as TanStackParameters } from "./chunk-
|
|
2
|
-
import { DecoratorFunction, LoaderFunction, Renderer } from "storybook/internal/types";
|
|
1
|
+
import { i as TanStackParameters } from "./chunk-B0pqNVvJ.js";
|
|
2
|
+
import { BeforeEach, DecoratorFunction, LoaderFunction, Renderer } from "storybook/internal/types";
|
|
3
3
|
import { applyDecorators as applyDecorators$1 } from "@storybook/react/entry-preview-docs";
|
|
4
4
|
|
|
5
5
|
//#region code/frameworks/tanstack-react/.dts-emit/code/frameworks/tanstack-react/src/preview.d.ts
|
|
6
6
|
declare const loaders: LoaderFunction<Renderer>[];
|
|
7
|
+
declare const beforeEach: BeforeEach<Renderer>[];
|
|
7
8
|
declare const applyDecorators: (storyFn: Parameters<typeof applyDecorators$1>[0], allDecorators: DecoratorFunction[]) => any;
|
|
8
9
|
declare const parameters: TanStackParameters;
|
|
9
10
|
declare const optimizeDeps: string[];
|
|
10
11
|
//#endregion
|
|
11
|
-
export { applyDecorators, loaders, optimizeDeps, parameters };
|
|
12
|
+
export { applyDecorators, beforeEach, loaders, optimizeDeps, parameters };
|
package/dist/preview.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
applyDecorators,
|
|
3
|
+
beforeEach,
|
|
3
4
|
loaders,
|
|
4
5
|
optimizeDeps,
|
|
5
6
|
parameters
|
|
6
|
-
} from "./_browser-chunks/chunk-
|
|
7
|
+
} from "./_browser-chunks/chunk-TR4QWDPU.js";
|
|
7
8
|
import "./_browser-chunks/chunk-LTDGLEVR.js";
|
|
8
9
|
import "./_browser-chunks/chunk-4BE7D4DS.js";
|
|
9
10
|
export {
|
|
10
11
|
applyDecorators,
|
|
12
|
+
beforeEach,
|
|
11
13
|
loaders,
|
|
12
14
|
optimizeDeps,
|
|
13
15
|
parameters
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@storybook/tanstack-react",
|
|
3
|
-
"version": "10.5.
|
|
3
|
+
"version": "10.5.8",
|
|
4
4
|
"description": "Storybook for TanStack (React, Vite): Router and Start ready Storybook framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"storybook",
|
|
@@ -75,9 +75,9 @@
|
|
|
75
75
|
"!src/**/*"
|
|
76
76
|
],
|
|
77
77
|
"dependencies": {
|
|
78
|
-
"@storybook/builder-vite": "10.5.
|
|
79
|
-
"@storybook/react": "10.5.
|
|
80
|
-
"@storybook/react-vite": "10.5.
|
|
78
|
+
"@storybook/builder-vite": "10.5.8",
|
|
79
|
+
"@storybook/react": "10.5.8",
|
|
80
|
+
"@storybook/react-vite": "10.5.8"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
83
|
"@tanstack/react-router": "^1.168.10",
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
"@tanstack/start-client-core": "^1.167.9",
|
|
96
96
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
|
97
97
|
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
|
98
|
-
"storybook": "^10.5.
|
|
98
|
+
"storybook": "^10.5.8",
|
|
99
99
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
|
|
100
100
|
},
|
|
101
101
|
"peerDependenciesMeta": {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/tanstack-react';
|
|
4
|
+
|
|
5
|
+
import { expect, within } from 'storybook/test';
|
|
6
|
+
|
|
7
|
+
const loaderCalls: unknown[] = [];
|
|
8
|
+
|
|
9
|
+
function LoaderContextViewer() {
|
|
10
|
+
return <p data-testid="loader-context">{String(loaderCalls[0] ?? 'missing')}</p>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const meta = {
|
|
14
|
+
component: LoaderContextViewer,
|
|
15
|
+
parameters: {
|
|
16
|
+
tanstack: {
|
|
17
|
+
router: {
|
|
18
|
+
context: () => {
|
|
19
|
+
loaderCalls.length = 0;
|
|
20
|
+
return { injected: 'from-factory' };
|
|
21
|
+
},
|
|
22
|
+
route: {
|
|
23
|
+
loader: ({ context }: { context: unknown }) => {
|
|
24
|
+
loaderCalls.push((context as any)?.injected ?? null);
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
} satisfies Meta<typeof LoaderContextViewer>;
|
|
31
|
+
|
|
32
|
+
export default meta;
|
|
33
|
+
|
|
34
|
+
type Story = StoryObj<typeof meta>;
|
|
35
|
+
|
|
36
|
+
/** Factory router context is visible to the route loader before render. */
|
|
37
|
+
export const FactoryValuesReachLoader: Story = {
|
|
38
|
+
play: async ({ canvasElement }) => {
|
|
39
|
+
const canvas = within(canvasElement);
|
|
40
|
+
await expect(canvas.getByTestId('loader-context')).toHaveTextContent('from-factory');
|
|
41
|
+
|
|
42
|
+
await expect(loaderCalls.length).toBeGreaterThan(0);
|
|
43
|
+
await expect(loaderCalls.every((call) => call === 'from-factory')).toBe(true);
|
|
44
|
+
},
|
|
45
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { Meta, StoryObj } from '@storybook/tanstack-react';
|
|
4
|
+
|
|
5
|
+
import { useRouter } from '@tanstack/react-router';
|
|
6
|
+
import { expect, within } from 'storybook/test';
|
|
7
|
+
|
|
8
|
+
const InjectedContext = React.createContext('missing-provider');
|
|
9
|
+
|
|
10
|
+
function RouterContextViewer() {
|
|
11
|
+
const router = useRouter();
|
|
12
|
+
const injected = (router.options.context as { injected?: string } | undefined)?.injected;
|
|
13
|
+
return <p data-testid="injected-router-context">{injected ?? 'missing-context'}</p>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const meta = {
|
|
17
|
+
component: RouterContextViewer,
|
|
18
|
+
decorators: [
|
|
19
|
+
(Story) => (
|
|
20
|
+
<InjectedContext.Provider value="from-react-hook">
|
|
21
|
+
<Story />
|
|
22
|
+
</InjectedContext.Provider>
|
|
23
|
+
),
|
|
24
|
+
],
|
|
25
|
+
parameters: {
|
|
26
|
+
tanstack: {
|
|
27
|
+
router: {
|
|
28
|
+
useRouterContext: () => ({ injected: React.useContext(InjectedContext) }),
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
} satisfies Meta<typeof RouterContextViewer>;
|
|
33
|
+
|
|
34
|
+
export default meta;
|
|
35
|
+
|
|
36
|
+
type Story = StoryObj<typeof meta>;
|
|
37
|
+
|
|
38
|
+
/** Hook-derived values read from a decorator's React provider must reach the story's router. */
|
|
39
|
+
export const HookValuesReachRouter: Story = {
|
|
40
|
+
play: async ({ canvasElement }) => {
|
|
41
|
+
await expect(within(canvasElement).getByTestId('injected-router-context')).toHaveTextContent(
|
|
42
|
+
'from-react-hook'
|
|
43
|
+
);
|
|
44
|
+
},
|
|
45
|
+
};
|