@repobuddy/storybook 2.1.2 → 2.2.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 +110 -1
- package/esm/index.js +160 -2
- package/esm/manager/index.d.ts +1 -0
- package/esm/manager/index.js +1 -0
- package/esm/storybook-addon-tag-badges/index.d.ts +2 -1
- package/esm/storybook-addon-tag-badges/index.js +1 -0
- package/esm/storybook-dark-mode/index.d.ts +1 -0
- package/esm/storybook-dark-mode/index.js +1 -0
- package/package.json +18 -13
- package/readme.md +6 -2
- package/src/decorators/with_story_card.tsx +235 -0
- package/src/index.ts +1 -0
- package/src/storybook-addon-tag-badges/tag_badges.ts +1 -0
- package/styles.css +344 -0
- package/src/variants/index.ts +0 -3
- package/src/variants/package.json +0 -3
- package/src/variants/preset.ts +0 -22
package/esm/index.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
|
|
1
2
|
import { UserConfig } from "htmlfy";
|
|
3
|
+
import { ReactNode } from "react";
|
|
2
4
|
import * as react_jsx_runtime0 from "react/jsx-runtime";
|
|
3
5
|
import { ClassNameProps, StyleProps } from "@just-web/css";
|
|
4
6
|
import { Args, DecoratorFunction, Renderer } from "storybook/internal/csf";
|
|
7
|
+
import { ClassValue } from "class-variance-authority/types";
|
|
5
8
|
import { Decorator, Meta, StoryContext, StoryObj, StrictArgs } from "@storybook/react-vite";
|
|
6
9
|
export * from "@repobuddy/test";
|
|
7
10
|
|
|
@@ -32,6 +35,112 @@ declare function ShowHtml({
|
|
|
32
35
|
*/
|
|
33
36
|
declare function showDocSource<TRenderer extends Renderer = Renderer, TArgs = Args>(): DecoratorFunction<TRenderer, TArgs>;
|
|
34
37
|
//#endregion
|
|
38
|
+
//#region src/decorators/with_story_card.d.ts
|
|
39
|
+
type StoryCardProps = {
|
|
40
|
+
/**
|
|
41
|
+
* Optional title displayed as a heading in the card.
|
|
42
|
+
* Can be any React node (string, JSX, etc.).
|
|
43
|
+
*/
|
|
44
|
+
title?: ReactNode | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Visual status of the card, affecting its background color.
|
|
47
|
+
* - `'error'`: Red background (bg-red-100 dark:bg-red-900)
|
|
48
|
+
* - `'warn'`: Yellow background (bg-yellow-100 dark:bg-yellow-900)
|
|
49
|
+
* - `'info'`: Blue background (bg-sky-100 dark:bg-sky-900) - default
|
|
50
|
+
*/
|
|
51
|
+
status?: 'error' | 'warn' | 'info' | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Additional CSS classes or a function to compute classes.
|
|
54
|
+
*
|
|
55
|
+
* If a string is provided, it will be merged with the default classes.
|
|
56
|
+
* If a function is provided, it receives the card state and default className,
|
|
57
|
+
* and should return the final className string.
|
|
58
|
+
*/
|
|
59
|
+
className?: ((state: Pick<StoryCardProps, 'status'> & {
|
|
60
|
+
defaultClassName: string;
|
|
61
|
+
}) => string) | ClassValue | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Content to display in the card body.
|
|
64
|
+
* Can be any React node (string, JSX, etc.).
|
|
65
|
+
*
|
|
66
|
+
* If not provided, the decorator will automatically use:
|
|
67
|
+
* 1. Story description (`parameters.docs.description.story`)
|
|
68
|
+
* 2. Component description (`parameters.docs.description.component`)
|
|
69
|
+
* 3. Nothing (card won't render if no content and no title)
|
|
70
|
+
*/
|
|
71
|
+
content?: ReactNode | undefined;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* A decorator that adds a card section to display additional information about the story.
|
|
75
|
+
*
|
|
76
|
+
* The card is automatically hidden when the story is shown in docs mode.
|
|
77
|
+
* Multiple decorators can be chained together,
|
|
78
|
+
* and all cards will be collected and displayed above the story content.
|
|
79
|
+
*
|
|
80
|
+
* @returns A Storybook decorator function.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* Basic usage - automatically uses component or story description:
|
|
84
|
+
* ```tsx
|
|
85
|
+
* export const MyStory: Story = {
|
|
86
|
+
* parameters: defineDocsParam({
|
|
87
|
+
* description: {
|
|
88
|
+
* story: 'This description will be shown in the card'
|
|
89
|
+
* }
|
|
90
|
+
* }),
|
|
91
|
+
* decorators: [withStoryCard()]
|
|
92
|
+
* }
|
|
93
|
+
* ```
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* With custom content:
|
|
97
|
+
* ```tsx
|
|
98
|
+
* export const MyStory: Story = {
|
|
99
|
+
* decorators: [
|
|
100
|
+
* withStoryCard({
|
|
101
|
+
* content: <p>This is a custom message displayed in the card.</p>
|
|
102
|
+
* })
|
|
103
|
+
* ]
|
|
104
|
+
* }
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* With title and status:
|
|
109
|
+
* ```tsx
|
|
110
|
+
* export const MyStory: Story = {
|
|
111
|
+
* decorators: [
|
|
112
|
+
* withStoryCard({
|
|
113
|
+
* title: 'Important Notice',
|
|
114
|
+
* status: 'warn',
|
|
115
|
+
* content: <p>Please review this carefully.</p>
|
|
116
|
+
* })
|
|
117
|
+
* ]
|
|
118
|
+
* }
|
|
119
|
+
* ```
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* Multiple cards:
|
|
123
|
+
* ```tsx
|
|
124
|
+
* export const MyStory: Story = {
|
|
125
|
+
* decorators: [
|
|
126
|
+
* withStoryCard({ title: 'First Card', status: 'info' }),
|
|
127
|
+
* withStoryCard({ title: 'Second Card', status: 'warn' })
|
|
128
|
+
* ]
|
|
129
|
+
* }
|
|
130
|
+
* ```
|
|
131
|
+
*
|
|
132
|
+
* @remarks
|
|
133
|
+
* - The card will not render if both `content` and `title` are missing.
|
|
134
|
+
* - If `content` is not provided, it will automatically use the story description,
|
|
135
|
+
* or fall back to the component description.
|
|
136
|
+
* - Cards are collected and displayed in the order they are defined in the decorators array.
|
|
137
|
+
*/
|
|
138
|
+
declare function withStoryCard<TRenderer extends Renderer = Renderer>({
|
|
139
|
+
title,
|
|
140
|
+
content: contentProp,
|
|
141
|
+
...rest
|
|
142
|
+
}?: StoryCardProps): DecoratorFunction<TRenderer>;
|
|
143
|
+
//#endregion
|
|
35
144
|
//#region src/parameters/define_actions_param.d.ts
|
|
36
145
|
interface ActionsParam {
|
|
37
146
|
actions: {
|
|
@@ -571,4 +680,4 @@ type ExtendStoryObj<TMetaOrCmpOrArgs, S extends StoryObj<TMetaOrCmpOrArgs>, E ex
|
|
|
571
680
|
tags?: Array<E['tag'] | (string & {})> | undefined;
|
|
572
681
|
};
|
|
573
682
|
//#endregion
|
|
574
|
-
export { ActionsParam, BackgroundsParam, DocsParam, ExtendMeta, ExtendStoryObj, GlobalApiBackgroundsParam, GlobalApiViewportParam, LayoutParam, ShowHtml, ShowHtmlProps, SourceProps, StorySortParam, StorybookBuiltInParams, TestParam, Viewport, ViewportParam, defineActionsParam, defineBackgroundsParam, defineDocsParam, defineLayoutParam, defineParameters, defineTestParam, defineViewportParam, showDocSource, whenRunningInTest };
|
|
683
|
+
export { ActionsParam, BackgroundsParam, DocsParam, ExtendMeta, ExtendStoryObj, GlobalApiBackgroundsParam, GlobalApiViewportParam, LayoutParam, ShowHtml, ShowHtmlProps, SourceProps, StoryCardProps, StorySortParam, StorybookBuiltInParams, TestParam, Viewport, ViewportParam, defineActionsParam, defineBackgroundsParam, defineDocsParam, defineLayoutParam, defineParameters, defineTestParam, defineViewportParam, showDocSource, whenRunningInTest, withStoryCard };
|
package/esm/index.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
+
|
|
1
2
|
import { isRunningInTest } from "@repobuddy/test";
|
|
2
3
|
import { prettify } from "htmlfy";
|
|
3
|
-
import { useEffect, useState } from "react";
|
|
4
|
+
import { createContext, useContext, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
4
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
6
|
import { SyntaxHighlighter } from "storybook/internal/components";
|
|
6
7
|
import { addons } from "storybook/preview-api";
|
|
7
8
|
import { ThemeProvider, convert, themes } from "storybook/theming";
|
|
9
|
+
import { cva } from "class-variance-authority";
|
|
10
|
+
import { twMerge } from "tailwind-merge";
|
|
8
11
|
|
|
9
12
|
export * from "@repobuddy/test"
|
|
10
13
|
|
|
@@ -67,6 +70,161 @@ function showDocSource() {
|
|
|
67
70
|
};
|
|
68
71
|
}
|
|
69
72
|
|
|
73
|
+
//#endregion
|
|
74
|
+
//#region src/decorators/with_story_card.tsx
|
|
75
|
+
/**
|
|
76
|
+
* A decorator that adds a card section to display additional information about the story.
|
|
77
|
+
*
|
|
78
|
+
* The card is automatically hidden when the story is shown in docs mode.
|
|
79
|
+
* Multiple decorators can be chained together,
|
|
80
|
+
* and all cards will be collected and displayed above the story content.
|
|
81
|
+
*
|
|
82
|
+
* @returns A Storybook decorator function.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* Basic usage - automatically uses component or story description:
|
|
86
|
+
* ```tsx
|
|
87
|
+
* export const MyStory: Story = {
|
|
88
|
+
* parameters: defineDocsParam({
|
|
89
|
+
* description: {
|
|
90
|
+
* story: 'This description will be shown in the card'
|
|
91
|
+
* }
|
|
92
|
+
* }),
|
|
93
|
+
* decorators: [withStoryCard()]
|
|
94
|
+
* }
|
|
95
|
+
* ```
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* With custom content:
|
|
99
|
+
* ```tsx
|
|
100
|
+
* export const MyStory: Story = {
|
|
101
|
+
* decorators: [
|
|
102
|
+
* withStoryCard({
|
|
103
|
+
* content: <p>This is a custom message displayed in the card.</p>
|
|
104
|
+
* })
|
|
105
|
+
* ]
|
|
106
|
+
* }
|
|
107
|
+
* ```
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* With title and status:
|
|
111
|
+
* ```tsx
|
|
112
|
+
* export const MyStory: Story = {
|
|
113
|
+
* decorators: [
|
|
114
|
+
* withStoryCard({
|
|
115
|
+
* title: 'Important Notice',
|
|
116
|
+
* status: 'warn',
|
|
117
|
+
* content: <p>Please review this carefully.</p>
|
|
118
|
+
* })
|
|
119
|
+
* ]
|
|
120
|
+
* }
|
|
121
|
+
* ```
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* Multiple cards:
|
|
125
|
+
* ```tsx
|
|
126
|
+
* export const MyStory: Story = {
|
|
127
|
+
* decorators: [
|
|
128
|
+
* withStoryCard({ title: 'First Card', status: 'info' }),
|
|
129
|
+
* withStoryCard({ title: 'Second Card', status: 'warn' })
|
|
130
|
+
* ]
|
|
131
|
+
* }
|
|
132
|
+
* ```
|
|
133
|
+
*
|
|
134
|
+
* @remarks
|
|
135
|
+
* - The card will not render if both `content` and `title` are missing.
|
|
136
|
+
* - If `content` is not provided, it will automatically use the story description,
|
|
137
|
+
* or fall back to the component description.
|
|
138
|
+
* - Cards are collected and displayed in the order they are defined in the decorators array.
|
|
139
|
+
*/
|
|
140
|
+
function withStoryCard({ title, content: contentProp, ...rest } = {}) {
|
|
141
|
+
return (Story, { parameters, viewMode }) => {
|
|
142
|
+
if (viewMode === "docs") return /* @__PURE__ */ jsx(Story, {});
|
|
143
|
+
const content = contentProp ?? parameters.docs?.description?.story ?? parameters.docs?.description?.component;
|
|
144
|
+
if (!content && !title) return /* @__PURE__ */ jsx(Story, {});
|
|
145
|
+
return /* @__PURE__ */ jsx(StoryCardContainerWrapper, {
|
|
146
|
+
Story,
|
|
147
|
+
content,
|
|
148
|
+
title,
|
|
149
|
+
...rest
|
|
150
|
+
});
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function StoryCardContainerWrapper({ Story, ...props }) {
|
|
154
|
+
const context = useContext(StoryCardContext);
|
|
155
|
+
const collector = /* @__PURE__ */ jsx(StoryCardCollector, {
|
|
156
|
+
Story,
|
|
157
|
+
...props
|
|
158
|
+
});
|
|
159
|
+
if (context === null) return /* @__PURE__ */ jsx(StoryCardContainer, { children: collector });
|
|
160
|
+
return collector;
|
|
161
|
+
}
|
|
162
|
+
const StoryCardContext = createContext(null);
|
|
163
|
+
function StoryCardContainer({ children }) {
|
|
164
|
+
const [cards, setCards] = useState([]);
|
|
165
|
+
const contextValue = useMemo(() => ({
|
|
166
|
+
addCard(card) {
|
|
167
|
+
const id = `story-card-${crypto.randomUUID()}`;
|
|
168
|
+
setCards((cards$1) => [...cards$1, {
|
|
169
|
+
...card,
|
|
170
|
+
id
|
|
171
|
+
}]);
|
|
172
|
+
return id;
|
|
173
|
+
},
|
|
174
|
+
removeCard(id) {
|
|
175
|
+
setCards((cards$1) => cards$1.filter((card) => card.id !== id));
|
|
176
|
+
}
|
|
177
|
+
}), []);
|
|
178
|
+
return /* @__PURE__ */ jsx(StoryCardContext.Provider, {
|
|
179
|
+
value: contextValue,
|
|
180
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
181
|
+
className: "flex flex-col gap-2",
|
|
182
|
+
children: [cards.map(({ id, status, className, content, title }) => /* @__PURE__ */ jsxs("section", {
|
|
183
|
+
className: storyCardTheme({ status }, className),
|
|
184
|
+
children: [title && /* @__PURE__ */ jsx("h2", {
|
|
185
|
+
className: "text-lg font-bold",
|
|
186
|
+
children: title
|
|
187
|
+
}), content]
|
|
188
|
+
}, id)), children]
|
|
189
|
+
})
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
function StoryCardCollector({ Story, title, status, className, content }) {
|
|
193
|
+
const context = useContext(StoryCardContext);
|
|
194
|
+
const cardIdRef = useRef(null);
|
|
195
|
+
useLayoutEffect(() => {
|
|
196
|
+
if (cardIdRef.current === null) cardIdRef.current = context.addCard({
|
|
197
|
+
title,
|
|
198
|
+
status,
|
|
199
|
+
className,
|
|
200
|
+
content
|
|
201
|
+
});
|
|
202
|
+
return () => {
|
|
203
|
+
if (cardIdRef.current !== null) {
|
|
204
|
+
context.removeCard(cardIdRef.current);
|
|
205
|
+
cardIdRef.current = null;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
}, []);
|
|
209
|
+
return /* @__PURE__ */ jsx(Story, {});
|
|
210
|
+
}
|
|
211
|
+
const storyCardTheme = (state, className) => {
|
|
212
|
+
const defaultClassName = storyCardVariants(state);
|
|
213
|
+
if (!className) return defaultClassName;
|
|
214
|
+
return twMerge(defaultClassName, typeof className === "function" ? className({
|
|
215
|
+
...state,
|
|
216
|
+
defaultClassName
|
|
217
|
+
}) : className);
|
|
218
|
+
};
|
|
219
|
+
const storyCardVariants = cva("flex flex-col gap-1 py-3 px-4 rounded text-black dark:text-gray-100", {
|
|
220
|
+
variants: { status: {
|
|
221
|
+
error: "bg-red-100 dark:bg-red-900",
|
|
222
|
+
warn: "bg-yellow-100 dark:bg-yellow-900",
|
|
223
|
+
info: "bg-sky-100 dark:bg-sky-900"
|
|
224
|
+
} },
|
|
225
|
+
defaultVariants: { status: "info" }
|
|
226
|
+
});
|
|
227
|
+
|
|
70
228
|
//#endregion
|
|
71
229
|
//#region src/parameters/define_actions_param.ts
|
|
72
230
|
/**
|
|
@@ -248,4 +406,4 @@ function whenRunningInTest(decoratorOrHandler) {
|
|
|
248
406
|
}
|
|
249
407
|
|
|
250
408
|
//#endregion
|
|
251
|
-
export { ShowHtml, defineActionsParam, defineBackgroundsParam, defineDocsParam, defineLayoutParam, defineParameters, defineTestParam, defineViewportParam, showDocSource, whenRunningInTest };
|
|
409
|
+
export { ShowHtml, defineActionsParam, defineBackgroundsParam, defineDocsParam, defineLayoutParam, defineParameters, defineTestParam, defineViewportParam, showDocSource, whenRunningInTest, withStoryCard };
|
package/esm/manager/index.d.ts
CHANGED
package/esm/manager/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
import { TagBadgeParameters } from "storybook-addon-tag-badges/manager-helpers";
|
|
2
3
|
import { Args, Meta as Meta$1, StoryObj as StoryObj$1 } from "@storybook/react-vite";
|
|
3
4
|
|
|
@@ -6,7 +7,7 @@ type TagBadgeParameter = TagBadgeParameters[0];
|
|
|
6
7
|
/**
|
|
7
8
|
* Type representing the names of predefined tags used in Storybook stories.
|
|
8
9
|
*/
|
|
9
|
-
type TagNames = 'editor' | 'new' | 'beta' | 'props' | 'deprecated' | 'outdated' | 'danger' | 'todo' | 'code-only' | 'snapshot' | 'unit' | 'integration' | 'keyboard' | 'internal';
|
|
10
|
+
type TagNames = 'editor' | 'new' | 'beta' | 'props' | 'deprecated' | 'outdated' | 'danger' | 'todo' | 'code-only' | 'snapshot' | 'unit' | 'integration' | 'keyboard' | 'internal' | 'usecase';
|
|
10
11
|
/**
|
|
11
12
|
* Configuration for story tag badges that appear in the Storybook sidebar.
|
|
12
13
|
* Each badge is associated with a specific tag and displays an emoji with a tooltip.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@repobuddy/storybook",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Storybook repo buddy",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"storybook",
|
|
@@ -38,44 +38,46 @@
|
|
|
38
38
|
"./storybook-dark-mode": {
|
|
39
39
|
"types": "./esm/storybook-dark-mode/index.d.ts",
|
|
40
40
|
"default": "./esm/storybook-dark-mode/index.js"
|
|
41
|
-
}
|
|
41
|
+
},
|
|
42
|
+
"./styles.css": "./styles.css"
|
|
42
43
|
},
|
|
43
44
|
"files": [
|
|
44
45
|
"cjs",
|
|
45
46
|
"esm",
|
|
46
47
|
"src",
|
|
48
|
+
"styles.css",
|
|
47
49
|
"!**/*.{spec,test,unit,accept,integrate,system,perf,stress,study,stories}.*",
|
|
48
50
|
"!**/*.mdx"
|
|
49
51
|
],
|
|
50
52
|
"dependencies": {
|
|
51
53
|
"@just-web/css": "^0.7.0",
|
|
52
54
|
"@repobuddy/test": "^1.0.0",
|
|
53
|
-
"
|
|
54
|
-
"htmlfy": "^1.0.0"
|
|
55
|
+
"class-variance-authority": "^0.7.1",
|
|
56
|
+
"htmlfy": "^1.0.0",
|
|
57
|
+
"tailwind-merge": "^3.4.0"
|
|
55
58
|
},
|
|
56
59
|
"devDependencies": {
|
|
57
60
|
"@repobuddy/vitest": "^2.0.0",
|
|
58
61
|
"@storybook-community/storybook-dark-mode": "^7.0.2",
|
|
59
62
|
"@storybook/addon-docs": "^10.0.7",
|
|
60
|
-
"@storybook/addon-themes": "^10.0.7",
|
|
61
63
|
"@storybook/addon-vitest": "^10.0.7",
|
|
62
64
|
"@storybook/react-vite": "^10.0.7",
|
|
63
65
|
"@tailwindcss/cli": "^4.1.17",
|
|
64
66
|
"@tailwindcss/vite": "^4.1.17",
|
|
65
|
-
"@vitest/browser": "^4.0.
|
|
66
|
-
"@vitest/browser-playwright": "^4.0.
|
|
67
|
-
"@vitest/coverage-v8": "^4.0.
|
|
67
|
+
"@vitest/browser": "^4.0.16",
|
|
68
|
+
"@vitest/browser-playwright": "^4.0.16",
|
|
69
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
68
70
|
"dedent": "^1.7.0",
|
|
69
|
-
"
|
|
71
|
+
"npm-run-all2": "^8.0.4",
|
|
70
72
|
"react": "^19.2.0",
|
|
71
73
|
"react-dom": "^19.2.0",
|
|
72
74
|
"rimraf": "^6.1.0",
|
|
73
75
|
"storybook": "^10.0.8",
|
|
74
76
|
"storybook-addon-tag-badges": "^3.0.2",
|
|
75
77
|
"tailwindcss": "^4.1.17",
|
|
76
|
-
"tsdown": "^0.
|
|
77
|
-
"vite": "^7.
|
|
78
|
-
"vitest": "^4.0.
|
|
78
|
+
"tsdown": "^0.18.0",
|
|
79
|
+
"vite": "^7.3.0",
|
|
80
|
+
"vitest": "^4.0.16"
|
|
79
81
|
},
|
|
80
82
|
"peerDependencies": {
|
|
81
83
|
"@storybook-community/storybook-dark-mode": "^7.0.0",
|
|
@@ -91,7 +93,9 @@
|
|
|
91
93
|
}
|
|
92
94
|
},
|
|
93
95
|
"scripts": {
|
|
94
|
-
"build": "
|
|
96
|
+
"build": "run-p build:*",
|
|
97
|
+
"build:code": "tsdown",
|
|
98
|
+
"build:css": "tailwindcss -i ./tailwind.css -o ./styles.css",
|
|
95
99
|
"clean": "rimraf .turbo coverage cjs esm storybook-static *.tsbuildinfo",
|
|
96
100
|
"coverage": "vitest run --coverage",
|
|
97
101
|
"sb": "storybook dev -p 6006",
|
|
@@ -100,6 +104,7 @@
|
|
|
100
104
|
"test:dark": "vitest run --config=vitest.config.dark.ts",
|
|
101
105
|
"test:light": "vitest run --config=vitest.config.light.ts",
|
|
102
106
|
"test:theme": "vitest run --config=vitest.config.theme.ts",
|
|
107
|
+
"test:types": "tsc --noEmit",
|
|
103
108
|
"w": "vitest"
|
|
104
109
|
}
|
|
105
110
|
}
|
package/readme.md
CHANGED
|
@@ -4,9 +4,11 @@ Your repository buddy for Storybook.
|
|
|
4
4
|
|
|
5
5
|
> [!NOTE]
|
|
6
6
|
>
|
|
7
|
-
>
|
|
7
|
+
> For Storybook 10, please use version `2.x`.
|
|
8
8
|
>
|
|
9
|
-
> For Storybook
|
|
9
|
+
> For Storybook 9, please use version `1.x`.
|
|
10
|
+
>
|
|
11
|
+
> For Storybook 8.x, please use version `0.x`.
|
|
10
12
|
|
|
11
13
|
## Install
|
|
12
14
|
|
|
@@ -14,6 +16,8 @@ Your repository buddy for Storybook.
|
|
|
14
16
|
pnpm add -D @repobuddy/storybook
|
|
15
17
|
```
|
|
16
18
|
|
|
19
|
+
If you use the components in the library, import `@repobuddy/storybook/styles.css`.
|
|
20
|
+
|
|
17
21
|
## Features
|
|
18
22
|
|
|
19
23
|
### Typed Parameters
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { cva } from 'class-variance-authority'
|
|
2
|
+
import type { ClassValue } from 'class-variance-authority/types'
|
|
3
|
+
import {
|
|
4
|
+
createContext,
|
|
5
|
+
useContext,
|
|
6
|
+
useLayoutEffect,
|
|
7
|
+
useMemo,
|
|
8
|
+
useRef,
|
|
9
|
+
useState,
|
|
10
|
+
type ComponentType,
|
|
11
|
+
type ReactNode
|
|
12
|
+
} from 'react'
|
|
13
|
+
import type { DecoratorFunction, Renderer } from 'storybook/internal/csf'
|
|
14
|
+
import { twMerge } from 'tailwind-merge'
|
|
15
|
+
|
|
16
|
+
export type StoryCardProps = {
|
|
17
|
+
/**
|
|
18
|
+
* Optional title displayed as a heading in the card.
|
|
19
|
+
* Can be any React node (string, JSX, etc.).
|
|
20
|
+
*/
|
|
21
|
+
title?: ReactNode | undefined
|
|
22
|
+
/**
|
|
23
|
+
* Visual status of the card, affecting its background color.
|
|
24
|
+
* - `'error'`: Red background (bg-red-100 dark:bg-red-900)
|
|
25
|
+
* - `'warn'`: Yellow background (bg-yellow-100 dark:bg-yellow-900)
|
|
26
|
+
* - `'info'`: Blue background (bg-sky-100 dark:bg-sky-900) - default
|
|
27
|
+
*/
|
|
28
|
+
status?: 'error' | 'warn' | 'info' | undefined
|
|
29
|
+
/**
|
|
30
|
+
* Additional CSS classes or a function to compute classes.
|
|
31
|
+
*
|
|
32
|
+
* If a string is provided, it will be merged with the default classes.
|
|
33
|
+
* If a function is provided, it receives the card state and default className,
|
|
34
|
+
* and should return the final className string.
|
|
35
|
+
*/
|
|
36
|
+
className?:
|
|
37
|
+
| ((state: Pick<StoryCardProps, 'status'> & { defaultClassName: string }) => string)
|
|
38
|
+
| ClassValue
|
|
39
|
+
| undefined
|
|
40
|
+
/**
|
|
41
|
+
* Content to display in the card body.
|
|
42
|
+
* Can be any React node (string, JSX, etc.).
|
|
43
|
+
*
|
|
44
|
+
* If not provided, the decorator will automatically use:
|
|
45
|
+
* 1. Story description (`parameters.docs.description.story`)
|
|
46
|
+
* 2. Component description (`parameters.docs.description.component`)
|
|
47
|
+
* 3. Nothing (card won't render if no content and no title)
|
|
48
|
+
*/
|
|
49
|
+
content?: ReactNode | undefined
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* A decorator that adds a card section to display additional information about the story.
|
|
54
|
+
*
|
|
55
|
+
* The card is automatically hidden when the story is shown in docs mode.
|
|
56
|
+
* Multiple decorators can be chained together,
|
|
57
|
+
* and all cards will be collected and displayed above the story content.
|
|
58
|
+
*
|
|
59
|
+
* @returns A Storybook decorator function.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* Basic usage - automatically uses component or story description:
|
|
63
|
+
* ```tsx
|
|
64
|
+
* export const MyStory: Story = {
|
|
65
|
+
* parameters: defineDocsParam({
|
|
66
|
+
* description: {
|
|
67
|
+
* story: 'This description will be shown in the card'
|
|
68
|
+
* }
|
|
69
|
+
* }),
|
|
70
|
+
* decorators: [withStoryCard()]
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* With custom content:
|
|
76
|
+
* ```tsx
|
|
77
|
+
* export const MyStory: Story = {
|
|
78
|
+
* decorators: [
|
|
79
|
+
* withStoryCard({
|
|
80
|
+
* content: <p>This is a custom message displayed in the card.</p>
|
|
81
|
+
* })
|
|
82
|
+
* ]
|
|
83
|
+
* }
|
|
84
|
+
* ```
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* With title and status:
|
|
88
|
+
* ```tsx
|
|
89
|
+
* export const MyStory: Story = {
|
|
90
|
+
* decorators: [
|
|
91
|
+
* withStoryCard({
|
|
92
|
+
* title: 'Important Notice',
|
|
93
|
+
* status: 'warn',
|
|
94
|
+
* content: <p>Please review this carefully.</p>
|
|
95
|
+
* })
|
|
96
|
+
* ]
|
|
97
|
+
* }
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* Multiple cards:
|
|
102
|
+
* ```tsx
|
|
103
|
+
* export const MyStory: Story = {
|
|
104
|
+
* decorators: [
|
|
105
|
+
* withStoryCard({ title: 'First Card', status: 'info' }),
|
|
106
|
+
* withStoryCard({ title: 'Second Card', status: 'warn' })
|
|
107
|
+
* ]
|
|
108
|
+
* }
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
111
|
+
* @remarks
|
|
112
|
+
* - The card will not render if both `content` and `title` are missing.
|
|
113
|
+
* - If `content` is not provided, it will automatically use the story description,
|
|
114
|
+
* or fall back to the component description.
|
|
115
|
+
* - Cards are collected and displayed in the order they are defined in the decorators array.
|
|
116
|
+
*/
|
|
117
|
+
export function withStoryCard<TRenderer extends Renderer = Renderer>({
|
|
118
|
+
title,
|
|
119
|
+
content: contentProp,
|
|
120
|
+
...rest
|
|
121
|
+
}: StoryCardProps = {}): DecoratorFunction<TRenderer> {
|
|
122
|
+
return (Story, { parameters, viewMode }) => {
|
|
123
|
+
if (viewMode === 'docs') return <Story />
|
|
124
|
+
|
|
125
|
+
const content = contentProp ?? parameters.docs?.description?.story ?? parameters.docs?.description?.component
|
|
126
|
+
if (!content && !title) return <Story />
|
|
127
|
+
|
|
128
|
+
return <StoryCardContainerWrapper Story={Story} content={content} title={title} {...rest} />
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
interface StoryCardContainerWrapperProps extends StoryCardProps {
|
|
133
|
+
Story: ComponentType
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function StoryCardContainerWrapper({ Story, ...props }: StoryCardContainerWrapperProps) {
|
|
137
|
+
const context = useContext(StoryCardContext)
|
|
138
|
+
const collector = <StoryCardCollector Story={Story} {...props} />
|
|
139
|
+
|
|
140
|
+
if (context === null) {
|
|
141
|
+
return <StoryCardContainer>{collector}</StoryCardContainer>
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return collector
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
interface StoryCardContextValue {
|
|
148
|
+
addCard: (card: StoryCardProps) => string
|
|
149
|
+
removeCard: (id: string) => void
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const StoryCardContext = createContext<StoryCardContextValue | null>(null)
|
|
153
|
+
|
|
154
|
+
type StoryCardWithId = StoryCardProps & { id: string }
|
|
155
|
+
|
|
156
|
+
function StoryCardContainer({ children }: { children: ReactNode }) {
|
|
157
|
+
const [cards, setCards] = useState<StoryCardWithId[]>([])
|
|
158
|
+
|
|
159
|
+
const contextValue: StoryCardContextValue = useMemo(
|
|
160
|
+
() => ({
|
|
161
|
+
addCard(card) {
|
|
162
|
+
const id = `story-card-${crypto.randomUUID()}`
|
|
163
|
+
setCards((cards) => [...cards, { ...card, id }])
|
|
164
|
+
return id
|
|
165
|
+
},
|
|
166
|
+
removeCard(id) {
|
|
167
|
+
setCards((cards) => cards.filter((card) => card.id !== id))
|
|
168
|
+
}
|
|
169
|
+
}),
|
|
170
|
+
[]
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
return (
|
|
174
|
+
<StoryCardContext.Provider value={contextValue}>
|
|
175
|
+
<div className="flex flex-col gap-2">
|
|
176
|
+
{cards.map(({ id, status, className, content, title }) => (
|
|
177
|
+
<section key={id} className={storyCardTheme({ status }, className)}>
|
|
178
|
+
{title && <h2 className="text-lg font-bold">{title}</h2>}
|
|
179
|
+
{content}
|
|
180
|
+
</section>
|
|
181
|
+
))}
|
|
182
|
+
{children}
|
|
183
|
+
</div>
|
|
184
|
+
</StoryCardContext.Provider>
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
interface StoryCardCollectorProps extends StoryCardProps {
|
|
189
|
+
Story: ComponentType
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function StoryCardCollector({ Story, title, status, className, content }: StoryCardCollectorProps) {
|
|
193
|
+
// StoryCardCollector is an internal component. Context is guaranteed to be not null by `StoryCardContainer`.
|
|
194
|
+
const context = useContext(StoryCardContext)!
|
|
195
|
+
const cardIdRef = useRef<string | null>(null)
|
|
196
|
+
|
|
197
|
+
// Collect this card once into the collection
|
|
198
|
+
useLayoutEffect(() => {
|
|
199
|
+
// Only add if not already added (handles Strict Mode double-render)
|
|
200
|
+
if (cardIdRef.current === null) {
|
|
201
|
+
cardIdRef.current = context.addCard({ title, status, className, content })
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return () => {
|
|
205
|
+
if (cardIdRef.current !== null) {
|
|
206
|
+
context.removeCard(cardIdRef.current)
|
|
207
|
+
cardIdRef.current = null
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}, [])
|
|
211
|
+
|
|
212
|
+
return <Story />
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const storyCardTheme = (state: Pick<StoryCardProps, 'status'>, className: StoryCardProps['className']) => {
|
|
216
|
+
const defaultClassName = storyCardVariants(state)
|
|
217
|
+
if (!className) return defaultClassName
|
|
218
|
+
return twMerge(
|
|
219
|
+
defaultClassName,
|
|
220
|
+
typeof className === 'function' ? className({ ...state, defaultClassName }) : className
|
|
221
|
+
)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const storyCardVariants = cva('flex flex-col gap-1 py-3 px-4 rounded text-black dark:text-gray-100', {
|
|
225
|
+
variants: {
|
|
226
|
+
status: {
|
|
227
|
+
error: 'bg-red-100 dark:bg-red-900',
|
|
228
|
+
warn: 'bg-yellow-100 dark:bg-yellow-900',
|
|
229
|
+
info: 'bg-sky-100 dark:bg-sky-900'
|
|
230
|
+
}
|
|
231
|
+
},
|
|
232
|
+
defaultVariants: {
|
|
233
|
+
status: 'info'
|
|
234
|
+
}
|
|
235
|
+
})
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from '@repobuddy/test'
|
|
2
2
|
export * from './components/show_html.tsx'
|
|
3
3
|
export * from './decorators/show_doc_source.tsx'
|
|
4
|
+
export * from './decorators/with_story_card.tsx'
|
|
4
5
|
export * from './parameters/define_actions_param.ts'
|
|
5
6
|
export * from './parameters/define_backgrounds_param.ts'
|
|
6
7
|
export * from './parameters/define_docs_param.ts'
|
package/styles.css
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties;
|
|
3
|
+
@layer theme, base, components, utilities;
|
|
4
|
+
@layer theme {
|
|
5
|
+
:root, :host {
|
|
6
|
+
--color-red-100: oklch(93.6% 0.032 17.717);
|
|
7
|
+
--color-red-800: oklch(44.4% 0.177 26.899);
|
|
8
|
+
--color-red-900: oklch(39.6% 0.141 25.723);
|
|
9
|
+
--color-amber-300: oklch(87.9% 0.169 91.605);
|
|
10
|
+
--color-amber-900: oklch(41.4% 0.112 45.904);
|
|
11
|
+
--color-yellow-100: oklch(97.3% 0.071 103.193);
|
|
12
|
+
--color-yellow-900: oklch(42.1% 0.095 57.708);
|
|
13
|
+
--color-green-200: oklch(92.5% 0.084 155.995);
|
|
14
|
+
--color-green-800: oklch(44.8% 0.119 151.328);
|
|
15
|
+
--color-sky-100: oklch(95.1% 0.026 236.824);
|
|
16
|
+
--color-sky-500: oklch(68.5% 0.169 237.323);
|
|
17
|
+
--color-sky-900: oklch(39.1% 0.09 240.876);
|
|
18
|
+
--color-blue-500: oklch(62.3% 0.214 259.815);
|
|
19
|
+
--color-rose-400: oklch(71.2% 0.194 13.428);
|
|
20
|
+
--color-rose-900: oklch(41% 0.159 10.272);
|
|
21
|
+
--color-gray-100: oklch(96.7% 0.003 264.542);
|
|
22
|
+
--color-gray-500: oklch(55.1% 0.027 264.364);
|
|
23
|
+
--color-black: #000;
|
|
24
|
+
--color-white: #fff;
|
|
25
|
+
--spacing: 0.25rem;
|
|
26
|
+
--text-lg: 1.125rem;
|
|
27
|
+
--text-lg--line-height: calc(1.75 / 1.125);
|
|
28
|
+
--font-weight-extralight: 200;
|
|
29
|
+
--font-weight-bold: 700;
|
|
30
|
+
--font-weight-extrabold: 800;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
@layer utilities {
|
|
34
|
+
.static {
|
|
35
|
+
position: static;
|
|
36
|
+
}
|
|
37
|
+
.container {
|
|
38
|
+
width: 100%;
|
|
39
|
+
@media (width >= 40rem) {
|
|
40
|
+
max-width: 40rem;
|
|
41
|
+
}
|
|
42
|
+
@media (width >= 48rem) {
|
|
43
|
+
max-width: 48rem;
|
|
44
|
+
}
|
|
45
|
+
@media (width >= 64rem) {
|
|
46
|
+
max-width: 64rem;
|
|
47
|
+
}
|
|
48
|
+
@media (width >= 80rem) {
|
|
49
|
+
max-width: 80rem;
|
|
50
|
+
}
|
|
51
|
+
@media (width >= 96rem) {
|
|
52
|
+
max-width: 96rem;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
.flex {
|
|
56
|
+
display: flex;
|
|
57
|
+
}
|
|
58
|
+
.hidden {
|
|
59
|
+
display: none;
|
|
60
|
+
}
|
|
61
|
+
.inline {
|
|
62
|
+
display: inline;
|
|
63
|
+
}
|
|
64
|
+
.transform {
|
|
65
|
+
transform: var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);
|
|
66
|
+
}
|
|
67
|
+
.flex-col {
|
|
68
|
+
flex-direction: column;
|
|
69
|
+
}
|
|
70
|
+
.gap-1 {
|
|
71
|
+
gap: calc(var(--spacing) * 1);
|
|
72
|
+
}
|
|
73
|
+
.gap-2 {
|
|
74
|
+
gap: calc(var(--spacing) * 2);
|
|
75
|
+
}
|
|
76
|
+
.gap-4 {
|
|
77
|
+
gap: calc(var(--spacing) * 4);
|
|
78
|
+
}
|
|
79
|
+
.rounded {
|
|
80
|
+
border-radius: 0.25rem;
|
|
81
|
+
}
|
|
82
|
+
.border {
|
|
83
|
+
border-style: var(--tw-border-style);
|
|
84
|
+
border-width: 1px;
|
|
85
|
+
}
|
|
86
|
+
.border-2 {
|
|
87
|
+
border-style: var(--tw-border-style);
|
|
88
|
+
border-width: 2px;
|
|
89
|
+
}
|
|
90
|
+
.border-blue-500 {
|
|
91
|
+
border-color: var(--color-blue-500);
|
|
92
|
+
}
|
|
93
|
+
.bg-amber-300 {
|
|
94
|
+
background-color: var(--color-amber-300);
|
|
95
|
+
}
|
|
96
|
+
.bg-black {
|
|
97
|
+
background-color: var(--color-black);
|
|
98
|
+
}
|
|
99
|
+
.bg-gray-100 {
|
|
100
|
+
background-color: var(--color-gray-100);
|
|
101
|
+
}
|
|
102
|
+
.bg-green-200 {
|
|
103
|
+
background-color: var(--color-green-200);
|
|
104
|
+
}
|
|
105
|
+
.bg-green-800 {
|
|
106
|
+
background-color: var(--color-green-800);
|
|
107
|
+
}
|
|
108
|
+
.bg-red-100 {
|
|
109
|
+
background-color: var(--color-red-100);
|
|
110
|
+
}
|
|
111
|
+
.bg-red-800 {
|
|
112
|
+
background-color: var(--color-red-800);
|
|
113
|
+
}
|
|
114
|
+
.bg-rose-400 {
|
|
115
|
+
background-color: var(--color-rose-400);
|
|
116
|
+
}
|
|
117
|
+
.bg-sky-100 {
|
|
118
|
+
background-color: var(--color-sky-100);
|
|
119
|
+
}
|
|
120
|
+
.bg-sky-500 {
|
|
121
|
+
background-color: var(--color-sky-500);
|
|
122
|
+
}
|
|
123
|
+
.bg-white {
|
|
124
|
+
background-color: var(--color-white);
|
|
125
|
+
}
|
|
126
|
+
.bg-yellow-100 {
|
|
127
|
+
background-color: var(--color-yellow-100);
|
|
128
|
+
}
|
|
129
|
+
.p-2 {
|
|
130
|
+
padding: calc(var(--spacing) * 2);
|
|
131
|
+
}
|
|
132
|
+
.p-4 {
|
|
133
|
+
padding: calc(var(--spacing) * 4);
|
|
134
|
+
}
|
|
135
|
+
.px-4 {
|
|
136
|
+
padding-inline: calc(var(--spacing) * 4);
|
|
137
|
+
}
|
|
138
|
+
.py-3 {
|
|
139
|
+
padding-block: calc(var(--spacing) * 3);
|
|
140
|
+
}
|
|
141
|
+
.text-lg {
|
|
142
|
+
font-size: var(--text-lg);
|
|
143
|
+
line-height: var(--tw-leading, var(--text-lg--line-height));
|
|
144
|
+
}
|
|
145
|
+
.font-bold {
|
|
146
|
+
--tw-font-weight: var(--font-weight-bold);
|
|
147
|
+
font-weight: var(--font-weight-bold);
|
|
148
|
+
}
|
|
149
|
+
.font-extrabold {
|
|
150
|
+
--tw-font-weight: var(--font-weight-extrabold);
|
|
151
|
+
font-weight: var(--font-weight-extrabold);
|
|
152
|
+
}
|
|
153
|
+
.font-extralight {
|
|
154
|
+
--tw-font-weight: var(--font-weight-extralight);
|
|
155
|
+
font-weight: var(--font-weight-extralight);
|
|
156
|
+
}
|
|
157
|
+
.text-black {
|
|
158
|
+
color: var(--color-black);
|
|
159
|
+
}
|
|
160
|
+
.text-white {
|
|
161
|
+
color: var(--color-white);
|
|
162
|
+
}
|
|
163
|
+
.shadow-lg {
|
|
164
|
+
--tw-shadow: 0 10px 15px -3px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 4px 6px -4px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
|
|
165
|
+
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
166
|
+
}
|
|
167
|
+
.dark\:bg-amber-900 {
|
|
168
|
+
&:where(.dark, .dark *) {
|
|
169
|
+
background-color: var(--color-amber-900);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
.dark\:bg-black {
|
|
173
|
+
&:where(.dark, .dark *) {
|
|
174
|
+
background-color: var(--color-black);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
.dark\:bg-gray-500 {
|
|
178
|
+
&:where(.dark, .dark *) {
|
|
179
|
+
background-color: var(--color-gray-500);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
.dark\:bg-green-800 {
|
|
183
|
+
&:where(.dark, .dark *) {
|
|
184
|
+
background-color: var(--color-green-800);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
.dark\:bg-red-900 {
|
|
188
|
+
&:where(.dark, .dark *) {
|
|
189
|
+
background-color: var(--color-red-900);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
.dark\:bg-rose-900 {
|
|
193
|
+
&:where(.dark, .dark *) {
|
|
194
|
+
background-color: var(--color-rose-900);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
.dark\:bg-sky-900 {
|
|
198
|
+
&:where(.dark, .dark *) {
|
|
199
|
+
background-color: var(--color-sky-900);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
.dark\:bg-yellow-900 {
|
|
203
|
+
&:where(.dark, .dark *) {
|
|
204
|
+
background-color: var(--color-yellow-900);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
.dark\:font-extrabold {
|
|
208
|
+
&:where(.dark, .dark *) {
|
|
209
|
+
--tw-font-weight: var(--font-weight-extrabold);
|
|
210
|
+
font-weight: var(--font-weight-extrabold);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
.dark\:text-gray-100 {
|
|
214
|
+
&:where(.dark, .dark *) {
|
|
215
|
+
color: var(--color-gray-100);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
.dark\:text-white {
|
|
219
|
+
&:where(.dark, .dark *) {
|
|
220
|
+
color: var(--color-white);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
@property --tw-rotate-x {
|
|
225
|
+
syntax: "*";
|
|
226
|
+
inherits: false;
|
|
227
|
+
}
|
|
228
|
+
@property --tw-rotate-y {
|
|
229
|
+
syntax: "*";
|
|
230
|
+
inherits: false;
|
|
231
|
+
}
|
|
232
|
+
@property --tw-rotate-z {
|
|
233
|
+
syntax: "*";
|
|
234
|
+
inherits: false;
|
|
235
|
+
}
|
|
236
|
+
@property --tw-skew-x {
|
|
237
|
+
syntax: "*";
|
|
238
|
+
inherits: false;
|
|
239
|
+
}
|
|
240
|
+
@property --tw-skew-y {
|
|
241
|
+
syntax: "*";
|
|
242
|
+
inherits: false;
|
|
243
|
+
}
|
|
244
|
+
@property --tw-border-style {
|
|
245
|
+
syntax: "*";
|
|
246
|
+
inherits: false;
|
|
247
|
+
initial-value: solid;
|
|
248
|
+
}
|
|
249
|
+
@property --tw-font-weight {
|
|
250
|
+
syntax: "*";
|
|
251
|
+
inherits: false;
|
|
252
|
+
}
|
|
253
|
+
@property --tw-shadow {
|
|
254
|
+
syntax: "*";
|
|
255
|
+
inherits: false;
|
|
256
|
+
initial-value: 0 0 #0000;
|
|
257
|
+
}
|
|
258
|
+
@property --tw-shadow-color {
|
|
259
|
+
syntax: "*";
|
|
260
|
+
inherits: false;
|
|
261
|
+
}
|
|
262
|
+
@property --tw-shadow-alpha {
|
|
263
|
+
syntax: "<percentage>";
|
|
264
|
+
inherits: false;
|
|
265
|
+
initial-value: 100%;
|
|
266
|
+
}
|
|
267
|
+
@property --tw-inset-shadow {
|
|
268
|
+
syntax: "*";
|
|
269
|
+
inherits: false;
|
|
270
|
+
initial-value: 0 0 #0000;
|
|
271
|
+
}
|
|
272
|
+
@property --tw-inset-shadow-color {
|
|
273
|
+
syntax: "*";
|
|
274
|
+
inherits: false;
|
|
275
|
+
}
|
|
276
|
+
@property --tw-inset-shadow-alpha {
|
|
277
|
+
syntax: "<percentage>";
|
|
278
|
+
inherits: false;
|
|
279
|
+
initial-value: 100%;
|
|
280
|
+
}
|
|
281
|
+
@property --tw-ring-color {
|
|
282
|
+
syntax: "*";
|
|
283
|
+
inherits: false;
|
|
284
|
+
}
|
|
285
|
+
@property --tw-ring-shadow {
|
|
286
|
+
syntax: "*";
|
|
287
|
+
inherits: false;
|
|
288
|
+
initial-value: 0 0 #0000;
|
|
289
|
+
}
|
|
290
|
+
@property --tw-inset-ring-color {
|
|
291
|
+
syntax: "*";
|
|
292
|
+
inherits: false;
|
|
293
|
+
}
|
|
294
|
+
@property --tw-inset-ring-shadow {
|
|
295
|
+
syntax: "*";
|
|
296
|
+
inherits: false;
|
|
297
|
+
initial-value: 0 0 #0000;
|
|
298
|
+
}
|
|
299
|
+
@property --tw-ring-inset {
|
|
300
|
+
syntax: "*";
|
|
301
|
+
inherits: false;
|
|
302
|
+
}
|
|
303
|
+
@property --tw-ring-offset-width {
|
|
304
|
+
syntax: "<length>";
|
|
305
|
+
inherits: false;
|
|
306
|
+
initial-value: 0px;
|
|
307
|
+
}
|
|
308
|
+
@property --tw-ring-offset-color {
|
|
309
|
+
syntax: "*";
|
|
310
|
+
inherits: false;
|
|
311
|
+
initial-value: #fff;
|
|
312
|
+
}
|
|
313
|
+
@property --tw-ring-offset-shadow {
|
|
314
|
+
syntax: "*";
|
|
315
|
+
inherits: false;
|
|
316
|
+
initial-value: 0 0 #0000;
|
|
317
|
+
}
|
|
318
|
+
@layer properties {
|
|
319
|
+
@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))) {
|
|
320
|
+
*, ::before, ::after, ::backdrop {
|
|
321
|
+
--tw-rotate-x: initial;
|
|
322
|
+
--tw-rotate-y: initial;
|
|
323
|
+
--tw-rotate-z: initial;
|
|
324
|
+
--tw-skew-x: initial;
|
|
325
|
+
--tw-skew-y: initial;
|
|
326
|
+
--tw-border-style: solid;
|
|
327
|
+
--tw-font-weight: initial;
|
|
328
|
+
--tw-shadow: 0 0 #0000;
|
|
329
|
+
--tw-shadow-color: initial;
|
|
330
|
+
--tw-shadow-alpha: 100%;
|
|
331
|
+
--tw-inset-shadow: 0 0 #0000;
|
|
332
|
+
--tw-inset-shadow-color: initial;
|
|
333
|
+
--tw-inset-shadow-alpha: 100%;
|
|
334
|
+
--tw-ring-color: initial;
|
|
335
|
+
--tw-ring-shadow: 0 0 #0000;
|
|
336
|
+
--tw-inset-ring-color: initial;
|
|
337
|
+
--tw-inset-ring-shadow: 0 0 #0000;
|
|
338
|
+
--tw-ring-inset: initial;
|
|
339
|
+
--tw-ring-offset-width: 0px;
|
|
340
|
+
--tw-ring-offset-color: #fff;
|
|
341
|
+
--tw-ring-offset-shadow: 0 0 #0000;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
package/src/variants/index.ts
DELETED
package/src/variants/preset.ts
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* User specifies `@repobuddy/storybook/variants/addon` in the `.storybook/main.ts`.
|
|
3
|
-
*
|
|
4
|
-
* Storybook loads it on the server side.
|
|
5
|
-
*
|
|
6
|
-
* It provides a default export (or in CJS, `module.exports =`) that contains:
|
|
7
|
-
*
|
|
8
|
-
* - `managerEntries` a function that returns an array of strings on where to load the manager (on the client side)
|
|
9
|
-
* - `previewAnnotations` a function that returns an array of strings on where to load the preview (on the client side)
|
|
10
|
-
* - `experimental_serverChannel` a function that handles the server-side channel
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
console.info('variants.preset.js.load')
|
|
14
|
-
|
|
15
|
-
// export const managerEntries = ['@storybook-community/storybook-dark-mode/manager']
|
|
16
|
-
// const previewAnnotations = (entry = []) => [...entry, require.resolve('@storybook-community/storybook-dark-mode')]
|
|
17
|
-
// const previewAnnotations = [ require.resolve('@storybook-community/storybook-dark-mode')]
|
|
18
|
-
|
|
19
|
-
// module.exports = {
|
|
20
|
-
// managerEntries,
|
|
21
|
-
// // previewAnnotations
|
|
22
|
-
// }
|