@repobuddy/storybook 0.9.4 → 0.10.0
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/esm/index.d.ts +3 -1
- package/esm/index.js +3 -1
- package/esm/parameters/define_parameters.d.ts +4 -2
- package/esm/parameters/story_sort.d.ts +27 -0
- package/esm/parameters/story_sort.js +1 -0
- package/esm/storybook-dark-mode/dark_mode_docs_container.d.ts +26 -0
- package/esm/storybook-dark-mode/dark_mode_docs_container.js +32 -0
- package/esm/storybook-dark-mode/define_dark_mode.d.ts +38 -0
- package/esm/storybook-dark-mode/define_dark_mode.js +18 -0
- package/esm/storybook-dark-mode/index.d.ts +3 -0
- package/esm/storybook-dark-mode/index.js +3 -0
- package/esm/storybook-dark-mode/with_story_root.d.ts +15 -0
- package/esm/storybook-dark-mode/with_story_root.js +61 -0
- package/package.json +25 -4
- package/readme.md +40 -0
- package/src/index.ts +3 -1
- package/src/parameters/define_parameters.ts +2 -3
- package/src/parameters/story_sort.ts +29 -0
- package/src/storybook-dark-mode/dark_mode_docs_container.mdx +33 -0
- package/src/storybook-dark-mode/dark_mode_docs_container.tsx +43 -0
- package/src/storybook-dark-mode/define_dark_mode.ts +40 -0
- package/src/storybook-dark-mode/index.ts +3 -0
- package/src/storybook-dark-mode/with_story_root.tsx +97 -0
- package/esm/parameters/define_story_sort.d.ts +0 -55
- package/esm/parameters/define_story_sort.js +0 -28
- package/esm/react/index.d.ts +0 -2
- package/esm/react/index.js +0 -2
- package/src/parameters/define_story_sort.ts +0 -58
- package/src/react/index.ts +0 -2
- /package/esm/{react/decorators → decorators}/show_doc_source.d.ts +0 -0
- /package/esm/{react/decorators → decorators}/show_doc_source.js +0 -0
- /package/esm/{react/decorators → decorators}/when_running_in_test.d.ts +0 -0
- /package/esm/{react/decorators → decorators}/when_running_in_test.js +0 -0
- /package/esm/{react/decorators → decorators}/when_running_in_text.ctx.d.ts +0 -0
- /package/esm/{react/decorators → decorators}/when_running_in_text.ctx.js +0 -0
- /package/src/{react/decorators → decorators}/show_doc_source.tsx +0 -0
- /package/src/{react/decorators → decorators}/when_running_in_test.tsx +0 -0
- /package/src/{react/decorators → decorators}/when_running_in_text.ctx.ts +0 -0
package/esm/index.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
export * from '@repobuddy/test';
|
|
2
|
+
export * from './decorators/show_doc_source.tsx';
|
|
3
|
+
export * from './decorators/when_running_in_test.tsx';
|
|
2
4
|
export * from './parameters/define_actions_param.ts';
|
|
3
5
|
export * from './parameters/define_backgrounds_param.ts';
|
|
4
6
|
export * from './parameters/define_docs_param.ts';
|
|
5
7
|
export * from './parameters/define_layout_param.ts';
|
|
6
8
|
export * from './parameters/define_parameters.ts';
|
|
7
|
-
export * from './parameters/define_story_sort.ts';
|
|
8
9
|
export * from './parameters/define_test_param.ts';
|
|
9
10
|
export * from './parameters/define_viewport_param.ts';
|
|
11
|
+
export * from './parameters/story_sort.ts';
|
package/esm/index.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
export * from '@repobuddy/test';
|
|
2
|
+
export * from "./decorators/show_doc_source.js";
|
|
3
|
+
export * from "./decorators/when_running_in_test.js";
|
|
2
4
|
export * from "./parameters/define_actions_param.js";
|
|
3
5
|
export * from "./parameters/define_backgrounds_param.js";
|
|
4
6
|
export * from "./parameters/define_docs_param.js";
|
|
5
7
|
export * from "./parameters/define_layout_param.js";
|
|
6
8
|
export * from "./parameters/define_parameters.js";
|
|
7
|
-
export * from "./parameters/define_story_sort.js";
|
|
8
9
|
export * from "./parameters/define_test_param.js";
|
|
9
10
|
export * from "./parameters/define_viewport_param.js";
|
|
11
|
+
export * from "./parameters/story_sort.js";
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { BackgroundsParam, GlobalApiBackgroundsParam } from './define_backgrounds_param.ts';
|
|
2
2
|
import type { DocsParam } from './define_docs_param.ts';
|
|
3
3
|
import type { LayoutParam } from './define_layout_param.ts';
|
|
4
|
-
import type { StorySortParam } from './define_story_sort.ts';
|
|
5
4
|
import type { TestParam } from './define_test_param.ts';
|
|
6
5
|
import type { ViewportParam } from './define_viewport_param.ts';
|
|
7
|
-
|
|
6
|
+
import type { StorySortParam } from './story_sort.ts';
|
|
7
|
+
export type StorybookBuiltInParams = Partial<BackgroundsParam | GlobalApiBackgroundsParam> & Partial<DocsParam> & Partial<LayoutParam> & Partial<TestParam> & Partial<ViewportParam> & {
|
|
8
|
+
options?: StorySortParam & Record<string, any>;
|
|
9
|
+
} & Record<string, any>;
|
|
8
10
|
/**
|
|
9
11
|
* Defines parameters for Storybook stories, combining built-in parameters with custom ones.
|
|
10
12
|
*
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
type StorySortConfig = {
|
|
2
|
+
includeNames?: boolean;
|
|
3
|
+
locales?: string;
|
|
4
|
+
method?: 'alphabetical' | 'alphabetical-by-kind' | 'custom';
|
|
5
|
+
order?: string[];
|
|
6
|
+
[k: string]: unknown;
|
|
7
|
+
};
|
|
8
|
+
type Story = {
|
|
9
|
+
id: string;
|
|
10
|
+
importPath: string;
|
|
11
|
+
name: string;
|
|
12
|
+
title: string;
|
|
13
|
+
};
|
|
14
|
+
type StorySortFn = (a: Story, b: Story) => number;
|
|
15
|
+
/**
|
|
16
|
+
* Interface for story sorting parameters in Storybook.
|
|
17
|
+
* Used to define how stories should be sorted in the navigation sidebar.
|
|
18
|
+
*/
|
|
19
|
+
export interface StorySortParam {
|
|
20
|
+
/**
|
|
21
|
+
* Configuration for story sorting. Can be either:
|
|
22
|
+
* - A StorySortConfig object specifying sort method and options
|
|
23
|
+
* - A custom sorting function that takes two stories and returns their sort order
|
|
24
|
+
*/
|
|
25
|
+
storySort: StorySortConfig | StorySortFn;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type DocsContextProps } from '@storybook/blocks';
|
|
2
|
+
import { type ThemeVars } from '@storybook/theming';
|
|
3
|
+
import { type PropsWithChildren } from 'react';
|
|
4
|
+
/**
|
|
5
|
+
* Creates a `DocsContainer` for `storybook` that works with `storybook-dark-mode`.
|
|
6
|
+
*
|
|
7
|
+
* @see https://github.com/hipstersmoothie/storybook-dark-mode/issues/282
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* // .storybook/preview.tsx
|
|
12
|
+
* const preview: Preview = {
|
|
13
|
+
* parameters: {
|
|
14
|
+
* docs: {
|
|
15
|
+
* container: createDarkModeDocsContainer()
|
|
16
|
+
* }
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function createDarkModeDocsContainer(customThemes?: {
|
|
22
|
+
light: ThemeVars;
|
|
23
|
+
dark: ThemeVars;
|
|
24
|
+
}): (props: PropsWithChildren<{
|
|
25
|
+
context: DocsContextProps;
|
|
26
|
+
}>) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { DocsContainer } from '@storybook/blocks';
|
|
3
|
+
import { themes } from '@storybook/theming';
|
|
4
|
+
import { useEffect, useState } from 'react';
|
|
5
|
+
import { DARK_MODE_EVENT_NAME } from 'storybook-dark-mode';
|
|
6
|
+
/**
|
|
7
|
+
* Creates a `DocsContainer` for `storybook` that works with `storybook-dark-mode`.
|
|
8
|
+
*
|
|
9
|
+
* @see https://github.com/hipstersmoothie/storybook-dark-mode/issues/282
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* // .storybook/preview.tsx
|
|
14
|
+
* const preview: Preview = {
|
|
15
|
+
* parameters: {
|
|
16
|
+
* docs: {
|
|
17
|
+
* container: createDarkModeDocsContainer()
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function createDarkModeDocsContainer(customThemes = themes) {
|
|
24
|
+
return function DarkModeDocsContainer(props) {
|
|
25
|
+
const [isDark, setDark] = useState(true);
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
props.context.channel.on(DARK_MODE_EVENT_NAME, setDark);
|
|
28
|
+
return () => props.context.channel.removeListener(DARK_MODE_EVENT_NAME, setDark);
|
|
29
|
+
}, [props.context.channel]);
|
|
30
|
+
return (_jsx(DocsContainer, { ...props, theme: isDark ? customThemes.dark : customThemes.light, children: props.children }));
|
|
31
|
+
};
|
|
32
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ThemeVars } from '@storybook/theming';
|
|
2
|
+
/**
|
|
3
|
+
* Configuration parameters for `storybook-dark-mode`.
|
|
4
|
+
*/
|
|
5
|
+
export interface DarkModeParam {
|
|
6
|
+
/** The current theme ('dark' or 'light') */
|
|
7
|
+
current?: 'dark' | 'light';
|
|
8
|
+
/** CSS class(es) to apply in dark mode */
|
|
9
|
+
darkClass?: string | string[];
|
|
10
|
+
/** CSS class(es) to apply in light mode */
|
|
11
|
+
lightClass?: string | string[];
|
|
12
|
+
/** Dark theme variables */
|
|
13
|
+
dark?: ThemeVars;
|
|
14
|
+
/** Light theme variables */
|
|
15
|
+
light?: ThemeVars;
|
|
16
|
+
/** Element to apply theme classes to ('html' or 'body') */
|
|
17
|
+
classTarget?: 'html' | 'body';
|
|
18
|
+
/** Whether to apply theme styles to preview iframe */
|
|
19
|
+
stylePreview?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Defines `storybook-dark-mode` parameters for Storybook stories.
|
|
23
|
+
*
|
|
24
|
+
* @see https://storybook.js.org/addons/@storybook/addon-themes#dark-mode
|
|
25
|
+
*
|
|
26
|
+
* @param darkMode - Configuration for dark mode parameters
|
|
27
|
+
* @param darkMode.current - The current theme ('dark' or 'light')
|
|
28
|
+
* @param darkMode.darkClass - CSS class(es) to apply in dark mode
|
|
29
|
+
* @param darkMode.lightClass - CSS class(es) to apply in light mode
|
|
30
|
+
* @param darkMode.dark - Dark theme variables
|
|
31
|
+
* @param darkMode.light - Light theme variables
|
|
32
|
+
* @param darkMode.classTarget - Element to apply theme classes to ('html' or 'body')
|
|
33
|
+
* @param darkMode.stylePreview - Whether to apply theme styles to preview iframe
|
|
34
|
+
* @returns An object containing the dark mode parameter configuration
|
|
35
|
+
*/
|
|
36
|
+
export declare function defineDarkModeParam(darkMode: DarkModeParam): {
|
|
37
|
+
darkMode: DarkModeParam;
|
|
38
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defines `storybook-dark-mode` parameters for Storybook stories.
|
|
3
|
+
*
|
|
4
|
+
* @see https://storybook.js.org/addons/@storybook/addon-themes#dark-mode
|
|
5
|
+
*
|
|
6
|
+
* @param darkMode - Configuration for dark mode parameters
|
|
7
|
+
* @param darkMode.current - The current theme ('dark' or 'light')
|
|
8
|
+
* @param darkMode.darkClass - CSS class(es) to apply in dark mode
|
|
9
|
+
* @param darkMode.lightClass - CSS class(es) to apply in light mode
|
|
10
|
+
* @param darkMode.dark - Dark theme variables
|
|
11
|
+
* @param darkMode.light - Light theme variables
|
|
12
|
+
* @param darkMode.classTarget - Element to apply theme classes to ('html' or 'body')
|
|
13
|
+
* @param darkMode.stylePreview - Whether to apply theme styles to preview iframe
|
|
14
|
+
* @returns An object containing the dark mode parameter configuration
|
|
15
|
+
*/
|
|
16
|
+
export function defineDarkModeParam(darkMode) {
|
|
17
|
+
return { darkMode };
|
|
18
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { CSSProperties } from '@just-web/css';
|
|
2
|
+
import type { DecoratorFunction } from 'storybook/internal/types';
|
|
3
|
+
interface StoryRootOptions {
|
|
4
|
+
classTarget?: 'html' | 'body' | undefined;
|
|
5
|
+
dark?: {
|
|
6
|
+
className?: string | string[] | undefined;
|
|
7
|
+
style?: CSSProperties | undefined;
|
|
8
|
+
} | undefined;
|
|
9
|
+
light?: {
|
|
10
|
+
className?: string | string[] | undefined;
|
|
11
|
+
style?: CSSProperties | undefined;
|
|
12
|
+
} | undefined;
|
|
13
|
+
}
|
|
14
|
+
export declare function withStoryRoot(param: StoryRootOptions): DecoratorFunction<any, any>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { toDOMStyle } from '@just-web/css';
|
|
3
|
+
import { useDarkMode } from 'storybook-dark-mode';
|
|
4
|
+
export function withStoryRoot(param) {
|
|
5
|
+
return function storyRootDecorator(Story) {
|
|
6
|
+
const dark = useDarkMode();
|
|
7
|
+
if (param.classTarget === 'html') {
|
|
8
|
+
if (dark) {
|
|
9
|
+
removeClass(param.light?.className);
|
|
10
|
+
addClass(param.dark?.className);
|
|
11
|
+
removeStyle(param.light?.style);
|
|
12
|
+
addStyle(param.dark?.style);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
removeClass(param.dark?.className);
|
|
16
|
+
addClass(param.light?.className);
|
|
17
|
+
removeStyle(param.dark?.style);
|
|
18
|
+
addStyle(param.light?.style);
|
|
19
|
+
}
|
|
20
|
+
return _jsx(Story, {});
|
|
21
|
+
}
|
|
22
|
+
if (dark) {
|
|
23
|
+
return (_jsx("div", { className: typeof param.dark?.className === 'string' ? param.dark.className : param.dark?.className?.join(' '), style: param.dark?.style, children: _jsx(Story, {}) }));
|
|
24
|
+
}
|
|
25
|
+
return (_jsx("div", { className: typeof param.light?.className === 'string' ? param.light.className : param.light?.className?.join(' '), style: param.light?.style, children: _jsx(Story, {}) }));
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function addClass(className) {
|
|
29
|
+
if (!className)
|
|
30
|
+
return;
|
|
31
|
+
if (typeof className === 'string') {
|
|
32
|
+
document.body.classList.add(...className.split(' '));
|
|
33
|
+
}
|
|
34
|
+
else if (Array.isArray(className)) {
|
|
35
|
+
document.body.classList.add(...className);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function removeClass(className) {
|
|
39
|
+
if (!className)
|
|
40
|
+
return;
|
|
41
|
+
if (typeof className === 'string') {
|
|
42
|
+
document.body.classList.remove(...className.split(' '));
|
|
43
|
+
}
|
|
44
|
+
else if (Array.isArray(className)) {
|
|
45
|
+
document.body.classList.remove(...className);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function addStyle(style) {
|
|
49
|
+
if (style) {
|
|
50
|
+
for (const [key, value] of Object.entries(toDOMStyle(style))) {
|
|
51
|
+
document.body.style.setProperty(key, value);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function removeStyle(style) {
|
|
56
|
+
if (style) {
|
|
57
|
+
for (const key of Object.keys(toDOMStyle(style))) {
|
|
58
|
+
document.body.style.removeProperty(key);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@repobuddy/storybook",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Storybook repo buddy",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"storybook",
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"types": "./esm/manager/index.d.ts",
|
|
24
24
|
"default": "./esm/manager/index.js"
|
|
25
25
|
},
|
|
26
|
-
"./
|
|
27
|
-
"types": "./esm/
|
|
28
|
-
"default": "./esm/
|
|
26
|
+
"./storybook-dark-mode": {
|
|
27
|
+
"types": "./esm/storybook-dark-mode/index.d.ts",
|
|
28
|
+
"default": "./esm/storybook-dark-mode/index.js"
|
|
29
29
|
},
|
|
30
30
|
"./testing": {
|
|
31
31
|
"types": "./esm/testing.d.ts",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"!**/*.{spec,test,unit,accept,integrate,system,perf,stress,study,stories}.*"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
+
"@just-web/css": "^0.4.0",
|
|
41
42
|
"@repobuddy/test": "^1.0.0"
|
|
42
43
|
},
|
|
43
44
|
"devDependencies": {
|
|
@@ -66,6 +67,26 @@
|
|
|
66
67
|
"vite": "^6.3.4",
|
|
67
68
|
"vitest": "^3.1.2"
|
|
68
69
|
},
|
|
70
|
+
"peerDependencies": {
|
|
71
|
+
"@storybook/blocks": ">= 8.6.12",
|
|
72
|
+
"@storybook/theming": ">= 8.6.12",
|
|
73
|
+
"storybook-addon-tag-badges": ">= 1.4.0",
|
|
74
|
+
"storybook-dark-mode": ">= 4.0.2"
|
|
75
|
+
},
|
|
76
|
+
"peerDependenciesMeta": {
|
|
77
|
+
"@storybook/blocks": {
|
|
78
|
+
"optional": true
|
|
79
|
+
},
|
|
80
|
+
"@storybook/theming": {
|
|
81
|
+
"optional": true
|
|
82
|
+
},
|
|
83
|
+
"storybook-addon-tag-badges": {
|
|
84
|
+
"optional": true
|
|
85
|
+
},
|
|
86
|
+
"storybook-dark-mode": {
|
|
87
|
+
"optional": true
|
|
88
|
+
}
|
|
89
|
+
},
|
|
69
90
|
"scripts": {
|
|
70
91
|
"build": "tsc",
|
|
71
92
|
"clean": "rimraf .turbo coverage esm storybook-static *.tsbuildinfo",
|
package/readme.md
CHANGED
|
@@ -86,5 +86,45 @@ import { addons } from '@storybook/manager-api'
|
|
|
86
86
|
addons.setConfig({ tagBadges })
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
+
### `storybook-dark-mode` support
|
|
90
|
+
|
|
91
|
+
[`@repobuddy/storybook`][`@repobuddy/storybook`] provides a few utilities to work with `storybook-dark-mode`.
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
// .storybook/preview.tsx
|
|
95
|
+
import { defineDarkModeParam, withStoryRoot, createDarkModeDocsContainer } from '@repobuddy/storybook/storybook-dark-mode'
|
|
96
|
+
|
|
97
|
+
export const preview: Preview = {
|
|
98
|
+
parameters: {
|
|
99
|
+
docs: {
|
|
100
|
+
container: createDarkModeDocsContainer()
|
|
101
|
+
},
|
|
102
|
+
darkMode: defineDarkModeParam({
|
|
103
|
+
classTarget: 'html',
|
|
104
|
+
darkClass: 'dark',
|
|
105
|
+
stylePreview: true
|
|
106
|
+
})
|
|
107
|
+
},
|
|
108
|
+
decorators: [withStoryRoot({
|
|
109
|
+
classTarget: 'html',
|
|
110
|
+
dark: {
|
|
111
|
+
className: 'dark:bg-black dark:text-white'
|
|
112
|
+
}
|
|
113
|
+
})]
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### `withStoryRoot`
|
|
118
|
+
|
|
119
|
+
The `withStoryRoot` decorator allows you to use `storybook-dark-mode` to change the background color of the story.
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { withStoryRoot } from '@repobuddy/storybook/storybook-dark-mode'
|
|
123
|
+
|
|
124
|
+
export const MyStory: StoryObj = {
|
|
125
|
+
decorators: [withStoryRoot()]
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
89
129
|
[`@repobuddy/storybook`]: https://github.com/repobuddy/storybook
|
|
90
130
|
[`storybook-addon-tag-badges`]: https://github.com/Sidnioulz/storybook-addon-tag-badges
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
export * from '@repobuddy/test'
|
|
2
|
+
export * from './decorators/show_doc_source.tsx'
|
|
3
|
+
export * from './decorators/when_running_in_test.tsx'
|
|
2
4
|
export * from './parameters/define_actions_param.ts'
|
|
3
5
|
export * from './parameters/define_backgrounds_param.ts'
|
|
4
6
|
export * from './parameters/define_docs_param.ts'
|
|
5
7
|
export * from './parameters/define_layout_param.ts'
|
|
6
8
|
export * from './parameters/define_parameters.ts'
|
|
7
|
-
export * from './parameters/define_story_sort.ts'
|
|
8
9
|
export * from './parameters/define_test_param.ts'
|
|
9
10
|
export * from './parameters/define_viewport_param.ts'
|
|
11
|
+
export * from './parameters/story_sort.ts'
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import type { BackgroundsParam, GlobalApiBackgroundsParam } from './define_backgrounds_param.ts'
|
|
2
2
|
import type { DocsParam } from './define_docs_param.ts'
|
|
3
3
|
import type { LayoutParam } from './define_layout_param.ts'
|
|
4
|
-
import type { StorySortParam } from './define_story_sort.ts'
|
|
5
4
|
import type { TestParam } from './define_test_param.ts'
|
|
6
5
|
import type { ViewportParam } from './define_viewport_param.ts'
|
|
6
|
+
import type { StorySortParam } from './story_sort.ts'
|
|
7
7
|
|
|
8
8
|
export type StorybookBuiltInParams = Partial<BackgroundsParam | GlobalApiBackgroundsParam> &
|
|
9
9
|
Partial<DocsParam> &
|
|
10
10
|
Partial<LayoutParam> &
|
|
11
|
-
Partial<StorySortParam> &
|
|
12
11
|
Partial<TestParam> &
|
|
13
|
-
Partial<ViewportParam>
|
|
12
|
+
Partial<ViewportParam> & { options?: StorySortParam & Record<string, any> } & Record<string, any>
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
15
|
* Defines parameters for Storybook stories, combining built-in parameters with custom ones.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
type StorySortConfig = {
|
|
2
|
+
includeNames?: boolean
|
|
3
|
+
locales?: string
|
|
4
|
+
method?: 'alphabetical' | 'alphabetical-by-kind' | 'custom'
|
|
5
|
+
order?: string[]
|
|
6
|
+
[k: string]: unknown
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
type Story = {
|
|
10
|
+
id: string
|
|
11
|
+
importPath: string
|
|
12
|
+
name: string
|
|
13
|
+
title: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
type StorySortFn = (a: Story, b: Story) => number
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Interface for story sorting parameters in Storybook.
|
|
20
|
+
* Used to define how stories should be sorted in the navigation sidebar.
|
|
21
|
+
*/
|
|
22
|
+
export interface StorySortParam {
|
|
23
|
+
/**
|
|
24
|
+
* Configuration for story sorting. Can be either:
|
|
25
|
+
* - A StorySortConfig object specifying sort method and options
|
|
26
|
+
* - A custom sorting function that takes two stories and returns their sort order
|
|
27
|
+
*/
|
|
28
|
+
storySort: StorySortConfig | StorySortFn
|
|
29
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Meta } from '@storybook/blocks'
|
|
2
|
+
|
|
3
|
+
# `createDarkModeDocsContainer`
|
|
4
|
+
|
|
5
|
+
<Meta title="storybook-dark-mode/createDarkModeDocsContainer" />
|
|
6
|
+
|
|
7
|
+
Creates a `DocsContainer` for `storybook` that works with `storybook-dark-mode`.
|
|
8
|
+
|
|
9
|
+
## Usage
|
|
10
|
+
|
|
11
|
+
It can be called with no arguments to use the default themes from `@storybook/theming`.
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
// .storybook/preview.tsx
|
|
15
|
+
import { createDarkModeDocsContainer } from '@repobuddy/storybook/react'
|
|
16
|
+
|
|
17
|
+
export const preview: Preview = {
|
|
18
|
+
parameters: {
|
|
19
|
+
docs: {
|
|
20
|
+
container: createDarkModeDocsContainer()
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
It can also be called with a custom themes.
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
container: createDarkModeDocsContainer({
|
|
30
|
+
light: customThemes.light,
|
|
31
|
+
dark: customThemes.dark
|
|
32
|
+
})
|
|
33
|
+
```
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { DocsContainer, type DocsContextProps } from '@storybook/blocks'
|
|
2
|
+
import { type ThemeVars, themes } from '@storybook/theming'
|
|
3
|
+
import { type PropsWithChildren, useEffect, useState } from 'react'
|
|
4
|
+
import { DARK_MODE_EVENT_NAME } from 'storybook-dark-mode'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a `DocsContainer` for `storybook` that works with `storybook-dark-mode`.
|
|
8
|
+
*
|
|
9
|
+
* @see https://github.com/hipstersmoothie/storybook-dark-mode/issues/282
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* // .storybook/preview.tsx
|
|
14
|
+
* const preview: Preview = {
|
|
15
|
+
* parameters: {
|
|
16
|
+
* docs: {
|
|
17
|
+
* container: createDarkModeDocsContainer()
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function createDarkModeDocsContainer(
|
|
24
|
+
customThemes: {
|
|
25
|
+
light: ThemeVars
|
|
26
|
+
dark: ThemeVars
|
|
27
|
+
} = themes
|
|
28
|
+
) {
|
|
29
|
+
return function DarkModeDocsContainer(props: PropsWithChildren<{ context: DocsContextProps }>) {
|
|
30
|
+
const [isDark, setDark] = useState(true)
|
|
31
|
+
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
props.context.channel.on(DARK_MODE_EVENT_NAME, setDark)
|
|
34
|
+
|
|
35
|
+
return () => props.context.channel.removeListener(DARK_MODE_EVENT_NAME, setDark)
|
|
36
|
+
}, [props.context.channel])
|
|
37
|
+
return (
|
|
38
|
+
<DocsContainer {...props} theme={isDark ? customThemes.dark : customThemes.light}>
|
|
39
|
+
{props.children}
|
|
40
|
+
</DocsContainer>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { ThemeVars } from '@storybook/theming'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Configuration parameters for `storybook-dark-mode`.
|
|
5
|
+
*/
|
|
6
|
+
export interface DarkModeParam {
|
|
7
|
+
/** The current theme ('dark' or 'light') */
|
|
8
|
+
current?: 'dark' | 'light'
|
|
9
|
+
/** CSS class(es) to apply in dark mode */
|
|
10
|
+
darkClass?: string | string[]
|
|
11
|
+
/** CSS class(es) to apply in light mode */
|
|
12
|
+
lightClass?: string | string[]
|
|
13
|
+
/** Dark theme variables */
|
|
14
|
+
dark?: ThemeVars
|
|
15
|
+
/** Light theme variables */
|
|
16
|
+
light?: ThemeVars
|
|
17
|
+
/** Element to apply theme classes to ('html' or 'body') */
|
|
18
|
+
classTarget?: 'html' | 'body'
|
|
19
|
+
/** Whether to apply theme styles to preview iframe */
|
|
20
|
+
stylePreview?: boolean
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Defines `storybook-dark-mode` parameters for Storybook stories.
|
|
25
|
+
*
|
|
26
|
+
* @see https://storybook.js.org/addons/@storybook/addon-themes#dark-mode
|
|
27
|
+
*
|
|
28
|
+
* @param darkMode - Configuration for dark mode parameters
|
|
29
|
+
* @param darkMode.current - The current theme ('dark' or 'light')
|
|
30
|
+
* @param darkMode.darkClass - CSS class(es) to apply in dark mode
|
|
31
|
+
* @param darkMode.lightClass - CSS class(es) to apply in light mode
|
|
32
|
+
* @param darkMode.dark - Dark theme variables
|
|
33
|
+
* @param darkMode.light - Light theme variables
|
|
34
|
+
* @param darkMode.classTarget - Element to apply theme classes to ('html' or 'body')
|
|
35
|
+
* @param darkMode.stylePreview - Whether to apply theme styles to preview iframe
|
|
36
|
+
* @returns An object containing the dark mode parameter configuration
|
|
37
|
+
*/
|
|
38
|
+
export function defineDarkModeParam(darkMode: DarkModeParam) {
|
|
39
|
+
return { darkMode }
|
|
40
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { CSSProperties } from '@just-web/css'
|
|
2
|
+
import { toDOMStyle } from '@just-web/css'
|
|
3
|
+
import { useDarkMode } from 'storybook-dark-mode'
|
|
4
|
+
import type { DecoratorFunction } from 'storybook/internal/types'
|
|
5
|
+
|
|
6
|
+
interface StoryRootOptions {
|
|
7
|
+
classTarget?: 'html' | 'body' | undefined
|
|
8
|
+
dark?:
|
|
9
|
+
| {
|
|
10
|
+
className?: string | string[] | undefined
|
|
11
|
+
style?: CSSProperties | undefined
|
|
12
|
+
}
|
|
13
|
+
| undefined
|
|
14
|
+
light?:
|
|
15
|
+
| {
|
|
16
|
+
className?: string | string[] | undefined
|
|
17
|
+
style?: CSSProperties | undefined
|
|
18
|
+
}
|
|
19
|
+
| undefined
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function withStoryRoot(param: StoryRootOptions): DecoratorFunction<any, any> {
|
|
23
|
+
return function storyRootDecorator(Story) {
|
|
24
|
+
const dark = useDarkMode()
|
|
25
|
+
if (param.classTarget === 'html') {
|
|
26
|
+
if (dark) {
|
|
27
|
+
removeClass(param.light?.className)
|
|
28
|
+
addClass(param.dark?.className)
|
|
29
|
+
removeStyle(param.light?.style)
|
|
30
|
+
addStyle(param.dark?.style)
|
|
31
|
+
} else {
|
|
32
|
+
removeClass(param.dark?.className)
|
|
33
|
+
addClass(param.light?.className)
|
|
34
|
+
removeStyle(param.dark?.style)
|
|
35
|
+
addStyle(param.light?.style)
|
|
36
|
+
}
|
|
37
|
+
return <Story />
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (dark) {
|
|
41
|
+
return (
|
|
42
|
+
<div
|
|
43
|
+
className={
|
|
44
|
+
typeof param.dark?.className === 'string' ? param.dark.className : param.dark?.className?.join(' ')
|
|
45
|
+
}
|
|
46
|
+
style={param.dark?.style}
|
|
47
|
+
>
|
|
48
|
+
<Story />
|
|
49
|
+
</div>
|
|
50
|
+
)
|
|
51
|
+
}
|
|
52
|
+
return (
|
|
53
|
+
<div
|
|
54
|
+
className={
|
|
55
|
+
typeof param.light?.className === 'string' ? param.light.className : param.light?.className?.join(' ')
|
|
56
|
+
}
|
|
57
|
+
style={param.light?.style}
|
|
58
|
+
>
|
|
59
|
+
<Story />
|
|
60
|
+
</div>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function addClass(className: string | string[] | undefined) {
|
|
66
|
+
if (!className) return
|
|
67
|
+
if (typeof className === 'string') {
|
|
68
|
+
document.body.classList.add(...className.split(' '))
|
|
69
|
+
} else if (Array.isArray(className)) {
|
|
70
|
+
document.body.classList.add(...className)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function removeClass(className: string | string[] | undefined) {
|
|
75
|
+
if (!className) return
|
|
76
|
+
if (typeof className === 'string') {
|
|
77
|
+
document.body.classList.remove(...className.split(' '))
|
|
78
|
+
} else if (Array.isArray(className)) {
|
|
79
|
+
document.body.classList.remove(...className)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function addStyle(style: CSSProperties | undefined) {
|
|
84
|
+
if (style) {
|
|
85
|
+
for (const [key, value] of Object.entries(toDOMStyle(style)!)) {
|
|
86
|
+
document.body.style.setProperty(key, value as any)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function removeStyle(style: CSSProperties | undefined) {
|
|
92
|
+
if (style) {
|
|
93
|
+
for (const key of Object.keys(toDOMStyle(style)!)) {
|
|
94
|
+
document.body.style.removeProperty(key)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
type StorySortConfig = {
|
|
2
|
-
includeNames?: boolean;
|
|
3
|
-
locales?: string;
|
|
4
|
-
method?: 'alphabetical' | 'alphabetical-by-kind' | 'custom';
|
|
5
|
-
order?: string[];
|
|
6
|
-
[k: string]: unknown;
|
|
7
|
-
};
|
|
8
|
-
type Story = {
|
|
9
|
-
id: string;
|
|
10
|
-
importPath: string;
|
|
11
|
-
name: string;
|
|
12
|
-
title: string;
|
|
13
|
-
};
|
|
14
|
-
type StorySortFn = (a: Story, b: Story) => number;
|
|
15
|
-
/**
|
|
16
|
-
* Interface for story sorting parameters in Storybook.
|
|
17
|
-
* Used to define how stories should be sorted in the navigation sidebar.
|
|
18
|
-
*/
|
|
19
|
-
export interface StorySortParam {
|
|
20
|
-
/**
|
|
21
|
-
* Configuration for story sorting. Can be either:
|
|
22
|
-
* - A StorySortConfig object specifying sort method and options
|
|
23
|
-
* - A custom sorting function that takes two stories and returns their sort order
|
|
24
|
-
*/
|
|
25
|
-
storySort: StorySortConfig | StorySortFn;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Defines story sorting parameters for Storybook navigation.
|
|
29
|
-
*
|
|
30
|
-
* @see https://storybook.js.org/docs/api/parameters#optionsstorysort
|
|
31
|
-
*
|
|
32
|
-
* @param storySort - Configuration for how stories should be sorted. Can be either:
|
|
33
|
-
* - A configuration object specifying sort method and options
|
|
34
|
-
* - A custom sorting function that takes two stories and returns their sort order
|
|
35
|
-
* @returns An object containing the story sort configuration
|
|
36
|
-
*
|
|
37
|
-
* @example
|
|
38
|
-
* // Alphabetical sorting
|
|
39
|
-
* defineStorySort({ method: 'alphabetical' })
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* // Custom order
|
|
43
|
-
* defineStorySort({
|
|
44
|
-
* method: 'custom',
|
|
45
|
-
* order: ['Introduction', 'Components', '*']
|
|
46
|
-
* })
|
|
47
|
-
*
|
|
48
|
-
* @example
|
|
49
|
-
* // Custom sort function
|
|
50
|
-
* defineStorySort((a, b) => a.title.localeCompare(b.title))
|
|
51
|
-
*/
|
|
52
|
-
export declare function defineStorySort(storySort: StorySortParam['storySort']): {
|
|
53
|
-
storySort: StorySortConfig | StorySortFn;
|
|
54
|
-
};
|
|
55
|
-
export {};
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Defines story sorting parameters for Storybook navigation.
|
|
3
|
-
*
|
|
4
|
-
* @see https://storybook.js.org/docs/api/parameters#optionsstorysort
|
|
5
|
-
*
|
|
6
|
-
* @param storySort - Configuration for how stories should be sorted. Can be either:
|
|
7
|
-
* - A configuration object specifying sort method and options
|
|
8
|
-
* - A custom sorting function that takes two stories and returns their sort order
|
|
9
|
-
* @returns An object containing the story sort configuration
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* // Alphabetical sorting
|
|
13
|
-
* defineStorySort({ method: 'alphabetical' })
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* // Custom order
|
|
17
|
-
* defineStorySort({
|
|
18
|
-
* method: 'custom',
|
|
19
|
-
* order: ['Introduction', 'Components', '*']
|
|
20
|
-
* })
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* // Custom sort function
|
|
24
|
-
* defineStorySort((a, b) => a.title.localeCompare(b.title))
|
|
25
|
-
*/
|
|
26
|
-
export function defineStorySort(storySort) {
|
|
27
|
-
return { storySort };
|
|
28
|
-
}
|
package/esm/react/index.d.ts
DELETED
package/esm/react/index.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
type StorySortConfig = {
|
|
2
|
-
includeNames?: boolean
|
|
3
|
-
locales?: string
|
|
4
|
-
method?: 'alphabetical' | 'alphabetical-by-kind' | 'custom'
|
|
5
|
-
order?: string[]
|
|
6
|
-
[k: string]: unknown
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
type Story = {
|
|
10
|
-
id: string
|
|
11
|
-
importPath: string
|
|
12
|
-
name: string
|
|
13
|
-
title: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
type StorySortFn = (a: Story, b: Story) => number
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Interface for story sorting parameters in Storybook.
|
|
20
|
-
* Used to define how stories should be sorted in the navigation sidebar.
|
|
21
|
-
*/
|
|
22
|
-
export interface StorySortParam {
|
|
23
|
-
/**
|
|
24
|
-
* Configuration for story sorting. Can be either:
|
|
25
|
-
* - A StorySortConfig object specifying sort method and options
|
|
26
|
-
* - A custom sorting function that takes two stories and returns their sort order
|
|
27
|
-
*/
|
|
28
|
-
storySort: StorySortConfig | StorySortFn
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Defines story sorting parameters for Storybook navigation.
|
|
33
|
-
*
|
|
34
|
-
* @see https://storybook.js.org/docs/api/parameters#optionsstorysort
|
|
35
|
-
*
|
|
36
|
-
* @param storySort - Configuration for how stories should be sorted. Can be either:
|
|
37
|
-
* - A configuration object specifying sort method and options
|
|
38
|
-
* - A custom sorting function that takes two stories and returns their sort order
|
|
39
|
-
* @returns An object containing the story sort configuration
|
|
40
|
-
*
|
|
41
|
-
* @example
|
|
42
|
-
* // Alphabetical sorting
|
|
43
|
-
* defineStorySort({ method: 'alphabetical' })
|
|
44
|
-
*
|
|
45
|
-
* @example
|
|
46
|
-
* // Custom order
|
|
47
|
-
* defineStorySort({
|
|
48
|
-
* method: 'custom',
|
|
49
|
-
* order: ['Introduction', 'Components', '*']
|
|
50
|
-
* })
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* // Custom sort function
|
|
54
|
-
* defineStorySort((a, b) => a.title.localeCompare(b.title))
|
|
55
|
-
*/
|
|
56
|
-
export function defineStorySort(storySort: StorySortParam['storySort']) {
|
|
57
|
-
return { storySort }
|
|
58
|
-
}
|
package/src/react/index.ts
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|