@storybook/tanstack-react 10.5.6 → 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/preview.d.ts CHANGED
@@ -1,114 +1,12 @@
1
- import { LoaderFunction, Renderer, DecoratorFunction } from 'storybook/internal/types';
2
- import { applyDecorators as applyDecorators$1 } from '@storybook/react/entry-preview-docs';
3
- import { Register, AnyRoute, FileRoutesByPath } from '@tanstack/react-router';
4
- import { RoutesByPath, RouteOptions, ResolveParams, AnyContext } from '@tanstack/router-core';
5
- import { ComponentType } from 'react';
6
- import { Decorator } from '@storybook/react';
7
-
8
- /** Union of every registered full path (e.g. `'/' | '/admin/users' | '/$libraryId/$version'`). */
9
- type RegisteredFullPath = keyof Register['router']['routesByPath'];
10
- type IsAppRouteTree<TRoute> = TRoute extends Register['router']['routeTree'] ? true : false;
11
- type IsRoute<T> = T extends AnyRoute ? true : T extends FileRoutesByPath[keyof FileRoutesByPath] ? true : false;
12
- type ExtractAllPathsFromFileRoutes<TRoute extends FileRoutesByPath[keyof FileRoutesByPath]['preLoaderRoute'] | AnyRoute> = TRoute['path'];
13
- type StoryRoutePath<TRoute = undefined> = TRoute extends FileRoutesByPath[keyof FileRoutesByPath] ? ExtractAllPathsFromFileRoutes<TRoute> : keyof FileRoutesByPath | `/${string}`;
14
- type StoryRouteSearch<TRoute> = IsAppRouteTree<TRoute> extends true ? Record<string, unknown> : TRoute extends FileRoutesByPath[keyof FileRoutesByPath] ? TRoute['preLoaderRoute'] extends {
15
- types: {
16
- allSearch: infer A;
17
- };
18
- } ? A : never : Record<string, unknown>;
19
- type StoryRouteFileOptions<TRoute = undefined> = IsRoute<TRoute> extends true ? TRoute extends {
20
- options: infer O;
21
- } ? Pick<O, Extract<keyof O, 'loader' | 'beforeLoad' | 'validateSearch' | 'loaderDeps' | 'context' | 'params' | 'head' | 'search' | 'parseParams' | 'context'>> : Pick<RouteOptions<unknown>, 'loader' | 'beforeLoad' | 'validateSearch' | 'loaderDeps' | 'context' | 'params' | 'head' | 'search' | 'parseParams' | 'context'> : Pick<RouteOptions<unknown>, 'loader' | 'beforeLoad' | 'validateSearch' | 'loaderDeps' | 'context' | 'params' | 'head' | 'search' | 'parseParams' | 'context'>;
22
- type CreateStoryRouteOptions<TRoute = undefined> = StoryRouteFileOptions<TRoute> & {
23
- path?: StoryRoutePath<TRoute>;
24
- };
25
- type StoryRouteOptions<TRoute = undefined> = CreateStoryRouteOptions<TRoute> | (TRoute extends AnyRoute ? TRoute : AnyRoute);
26
- /**
27
- * Per-route override options for use inside `RouteTreeOverrides`.
28
- * Users can override `loader`, `beforeLoad`, etc. for a specific route.
29
- */
30
- interface RouteOverrideOptions<TRoute extends FileRoutesByPath[keyof FileRoutesByPath]['preLoaderRoute'] | undefined = undefined> {
31
- /** Override the route's component. */
32
- component?: TRoute extends FileRoutesByPath[keyof FileRoutesByPath]['preLoaderRoute'] ? TRoute['options']['component'] | ComponentType : ComponentType;
33
- /** Override the route's loader function. */
34
- loader?: TRoute extends FileRoutesByPath[keyof FileRoutesByPath]['preLoaderRoute'] ? TRoute['options']['loader'] | ((ctx: unknown) => Promise<unknown> | unknown) : (ctx: unknown) => Promise<unknown> | unknown;
35
- /** Override the route's beforeLoad function. */
36
- beforeLoad?: TRoute extends FileRoutesByPath[keyof FileRoutesByPath]['preLoaderRoute'] ? TRoute['options']['beforeLoad'] | ((ctx: unknown) => Promise<void> | void) : (ctx: unknown) => Promise<void> | void;
37
- /** Override the route's search params validation. */
38
- validateSearch?: TRoute extends FileRoutesByPath[keyof FileRoutesByPath]['preLoaderRoute'] ? TRoute['options']['validateSearch'] | ((search: unknown) => Promise<void> | void) : (search: unknown) => Promise<void> | void;
39
- /** Override the route's loader dependencies. */
40
- loaderDeps?: TRoute extends FileRoutesByPath[keyof FileRoutesByPath]['preLoaderRoute'] ? TRoute['options']['loaderDeps'] | string[] : string[];
41
- /** Override the route's context function. */
42
- context?: TRoute extends FileRoutesByPath[keyof FileRoutesByPath]['preLoaderRoute'] ? TRoute['options']['context'] | ((ctx: unknown) => Promise<unknown> | unknown) : (ctx: unknown) => Promise<unknown> | unknown;
43
- }
44
- /**
45
- * A map of route overrides keyed by route ID.
46
- * Each entry can override `loader`, `beforeLoad`, etc. for that route.
47
- *
48
- * @example
49
- * ```ts
50
- * routeOverrides: {
51
- * '/_authed': { beforeLoad: () => {} },
52
- * '/demo/form/simple/$id': {
53
- * loader: async () => ({ name: 'Mock User' }),
54
- * },
55
- * }
56
- * ```
57
- */
58
- type RouteTreeOverrides = Partial<{
59
- [routePath in keyof FileRoutesByPath]: RouteOverrideOptions<FileRoutesByPath[routePath]['preLoaderRoute']> | undefined;
60
- }>;
61
- interface RouterParameters<TRoute = undefined, Path extends TRoute extends AnyRoute ? keyof RoutesByPath<TRoute> : RegisteredFullPath = TRoute extends AnyRoute ? keyof RoutesByPath<TRoute> : keyof FileRoutesByPath> {
62
- route?: StoryRouteOptions<TRoute>;
63
- /**
64
- * Path to resolve the story route against.
65
- * Constrained to known registered paths in route tree mode, but can be any string in app route mode (since the user may be passing a custom `route` that doesn't exist in the registered tree).
66
- */
67
- path?: Path;
68
- /** URL params to interpolate into the path (e.g. `{ id: '42' }` for `/$id`). */
69
- params?: ResolveParams<Path>;
70
- /** Search/query params to append to the URL (e.g. `{ tab: 'details' }`). */
71
- query?: Partial<StoryRouteSearch<TRoute>>;
72
- /**
73
- * Override options for specific routes in the app route tree (route tree mode only).
74
- *
75
- * Each key is a route ID (e.g. `'/about'`, `'__root__'`, `'/demo/form/simple/$id'`).
76
- * Values can override `loader`, `beforeLoad`, etc. for that route.
77
- *
78
- * @example
79
- * ```ts
80
- * routeOverrides: {
81
- * '/_authed': { beforeLoad: () => {} },
82
- * '/demo/form/simple/$id': {
83
- * loader: async () => ({ name: 'Mock User' }),
84
- * },
85
- * }
86
- * ```
87
- */
88
- routeOverrides?: RouteTreeOverrides;
89
- context?: Record<string, unknown>;
90
- /**
91
- *
92
- */
93
- useRouterContext?: ({ storyContext }: {
94
- storyContext: Parameters<Decorator>[1];
95
- }) => AnyContext;
96
- }
97
-
98
- /** Path constraint mirroring `RouterParameters`'s second generic. */
99
- type DefaultStoryPath<TRoute> = TRoute extends AnyRoute ? keyof RoutesByPath<TRoute> : RegisteredFullPath;
100
- interface TanStackPreviewOptions<TRoute = undefined, Path extends DefaultStoryPath<TRoute> = DefaultStoryPath<TRoute>> {
101
- /** Router configuration for stories */
102
- router?: RouterParameters<TRoute, Path>;
103
- }
104
- interface TanStackParameters<TRoute = undefined, Path extends DefaultStoryPath<TRoute> = DefaultStoryPath<TRoute>> {
105
- /** TanStack framework configuration (router integration). */
106
- tanstack?: TanStackPreviewOptions<TRoute, Path>;
107
- }
1
+ import { i as TanStackParameters } from "./chunk-B0pqNVvJ.js";
2
+ import { BeforeEach, DecoratorFunction, LoaderFunction, Renderer } from "storybook/internal/types";
3
+ import { applyDecorators as applyDecorators$1 } from "@storybook/react/entry-preview-docs";
108
4
 
5
+ //#region code/frameworks/tanstack-react/.dts-emit/code/frameworks/tanstack-react/src/preview.d.ts
109
6
  declare const loaders: LoaderFunction<Renderer>[];
7
+ declare const beforeEach: BeforeEach<Renderer>[];
110
8
  declare const applyDecorators: (storyFn: Parameters<typeof applyDecorators$1>[0], allDecorators: DecoratorFunction[]) => any;
111
9
  declare const parameters: TanStackParameters;
112
10
  declare const optimizeDeps: string[];
113
-
114
- export { applyDecorators, loaders, optimizeDeps, parameters };
11
+ //#endregion
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-6UULZFFJ.js";
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.6",
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.6",
79
- "@storybook/react": "10.5.6",
80
- "@storybook/react-vite": "10.5.6"
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.6",
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
+ };