@repobuddy/storybook 2.13.0 → 2.15.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 +36 -17
- package/esm/index.js +33 -21
- package/esm/storybook-addon-tag-badges/index.d.ts +20 -2
- package/esm/storybook-addon-tag-badges/index.js +31 -1
- package/package.json +1 -1
- package/readme.md +4 -0
- package/src/components/story_card.tsx +52 -24
- package/src/contexts/story_card_registry_context.tsx +1 -2
- package/src/contexts/story_card_scope.tsx +2 -2
- package/src/decorators/show_doc_source.tsx +6 -4
- package/src/decorators/with_story_card.tsx +14 -3
- package/src/parameters/define_story_card_param.ts +10 -6
- package/src/storybook-addon-tag-badges/tag_badges.ts +35 -0
- package/styles.css +78 -0
package/esm/index.d.ts
CHANGED
|
@@ -42,10 +42,12 @@ declare function ShowHtml({
|
|
|
42
42
|
//#endregion
|
|
43
43
|
//#region src/components/story_card.d.ts
|
|
44
44
|
/**
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
* Resolved appearance of the card (error | warn | info | source | output).
|
|
46
|
+
* Used for styling; when only `status` is provided it is mapped to this.
|
|
47
|
+
*/
|
|
48
|
+
type StoryCardAppearance = 'error' | 'warn' | 'info' | 'source' | 'output';
|
|
49
|
+
/**
|
|
50
|
+
* @deprecated Use `appearance` instead. Visual status of the card; equivalent to `appearance` for 'error' | 'warn' | 'info'.
|
|
49
51
|
*/
|
|
50
52
|
type StoryCardStatus = 'error' | 'warn' | 'info' | undefined;
|
|
51
53
|
type StoryCardProps = {
|
|
@@ -55,12 +57,18 @@ type StoryCardProps = {
|
|
|
55
57
|
*/
|
|
56
58
|
title?: ReactNode | undefined;
|
|
57
59
|
/**
|
|
58
|
-
*
|
|
59
|
-
* - `'error'`: Red background (rbsb:bg-red-100 rbsb:dark:bg-red-900)
|
|
60
|
-
* - `'warn'`: Yellow background (rbsb:bg-yellow-100 rbsb:dark:bg-yellow-900)
|
|
61
|
-
* - `'info'`: Blue background (rbsb:bg-sky-100 rbsb:dark:bg-sky-900) - default
|
|
60
|
+
* @deprecated Use `appearance` instead. When set, behaves like `appearance` for the same value.
|
|
62
61
|
*/
|
|
63
62
|
status?: StoryCardStatus;
|
|
63
|
+
/**
|
|
64
|
+
* Appearance of the card, affecting its background and border color.
|
|
65
|
+
* - `'error'`: Red
|
|
66
|
+
* - `'warn'`: Yellow
|
|
67
|
+
* - `'info'`: Blue (default when neither appearance nor status is set)
|
|
68
|
+
* - `'source'`: Transparent
|
|
69
|
+
* - `'output'`: Green
|
|
70
|
+
*/
|
|
71
|
+
appearance?: StoryCardAppearance | undefined;
|
|
64
72
|
/**
|
|
65
73
|
* Additional CSS classes or a function to compute classes.
|
|
66
74
|
*
|
|
@@ -68,7 +76,7 @@ type StoryCardProps = {
|
|
|
68
76
|
* If a function is provided, it receives the card state and default className,
|
|
69
77
|
* and should return the final className string.
|
|
70
78
|
*/
|
|
71
|
-
className?: ((state: Pick<StoryCardProps, 'status'> & {
|
|
79
|
+
className?: ((state: Pick<StoryCardProps, 'status' | 'appearance'> & {
|
|
72
80
|
defaultClassName: string;
|
|
73
81
|
}) => string) | string | undefined;
|
|
74
82
|
/**
|
|
@@ -77,14 +85,18 @@ type StoryCardProps = {
|
|
|
77
85
|
*/
|
|
78
86
|
children?: ReactNode | undefined;
|
|
79
87
|
};
|
|
88
|
+
type StoryCardThemeState = Pick<StoryCardProps, 'status' | 'appearance'> & {
|
|
89
|
+
defaultClassName: string;
|
|
90
|
+
};
|
|
80
91
|
/**
|
|
81
|
-
* A card component that displays information with optional title and
|
|
92
|
+
* A card component that displays information with optional title and appearance styling.
|
|
82
93
|
*
|
|
83
94
|
* @param props - StoryCard component props
|
|
84
95
|
* @returns A section element containing the card content
|
|
85
96
|
*/
|
|
86
97
|
declare function StoryCard({
|
|
87
98
|
status,
|
|
99
|
+
appearance,
|
|
88
100
|
className,
|
|
89
101
|
children,
|
|
90
102
|
title
|
|
@@ -115,6 +127,10 @@ declare function showDocSource<TRenderer extends Renderer = Renderer, TArgs = Ar
|
|
|
115
127
|
//#endregion
|
|
116
128
|
//#region src/decorators/with_story_card.d.ts
|
|
117
129
|
type WithStoryCardProps = Omit<StoryCardProps, 'children' | 'className'> & {
|
|
130
|
+
/**
|
|
131
|
+
* @deprecated Use `appearance` instead. When set, behaves like `appearance` for the same value.
|
|
132
|
+
*/
|
|
133
|
+
status?: StoryCardStatus;
|
|
118
134
|
/**
|
|
119
135
|
* Additional CSS classes or a function to compute classes.
|
|
120
136
|
*
|
|
@@ -122,7 +138,7 @@ type WithStoryCardProps = Omit<StoryCardProps, 'children' | 'className'> & {
|
|
|
122
138
|
* If a function is provided, it receives the card state and default className,
|
|
123
139
|
* and should return the final className string.
|
|
124
140
|
*/
|
|
125
|
-
className?: ((state: Pick<StoryCardProps, 'status'> & {
|
|
141
|
+
className?: ((state: Pick<StoryCardProps, 'status' | 'appearance'> & {
|
|
126
142
|
defaultClassName: string;
|
|
127
143
|
}) => string) | string | undefined;
|
|
128
144
|
/**
|
|
@@ -213,10 +229,12 @@ type WithStoryCardProps = Omit<StoryCardProps, 'children' | 'className'> & {
|
|
|
213
229
|
* - If `content` is not provided, it will automatically use the story description,
|
|
214
230
|
* or fall back to the component description.
|
|
215
231
|
* - Cards are collected and displayed in the order they are defined in the decorators array.
|
|
232
|
+
* - The `status` option is deprecated; use `appearance` instead for the same behavior and additional variants (`source`, `output`).
|
|
216
233
|
*/
|
|
217
234
|
declare function withStoryCard<TRenderer extends Renderer = Renderer>({
|
|
218
235
|
title,
|
|
219
236
|
status,
|
|
237
|
+
appearance,
|
|
220
238
|
content: contentProp,
|
|
221
239
|
className,
|
|
222
240
|
...rest
|
|
@@ -722,12 +740,13 @@ interface StoryCardParam {
|
|
|
722
740
|
*/
|
|
723
741
|
title?: ReactNode | undefined;
|
|
724
742
|
/**
|
|
725
|
-
*
|
|
726
|
-
* - `'error'`: Red background
|
|
727
|
-
* - `'warn'`: Yellow background
|
|
728
|
-
* - `'info'`: Blue background - default
|
|
743
|
+
* @deprecated Use `appearance` instead.
|
|
729
744
|
*/
|
|
730
745
|
status?: StoryCardStatus;
|
|
746
|
+
/**
|
|
747
|
+
* Appearance of the card (error | warn | info | source | output). Default: `'info'`.
|
|
748
|
+
*/
|
|
749
|
+
appearance?: StoryCardAppearance | undefined;
|
|
731
750
|
/**
|
|
732
751
|
* Additional CSS classes or a function to compute classes.
|
|
733
752
|
*
|
|
@@ -735,7 +754,7 @@ interface StoryCardParam {
|
|
|
735
754
|
* If a function is provided, it receives the card state and default className,
|
|
736
755
|
* and should return the final className string.
|
|
737
756
|
*/
|
|
738
|
-
className?: ((state: Pick<StoryCardProps, 'status'> & {
|
|
757
|
+
className?: ((state: Pick<StoryCardProps, 'status' | 'appearance'> & {
|
|
739
758
|
defaultClassName: string;
|
|
740
759
|
}) => string) | string | undefined;
|
|
741
760
|
/**
|
|
@@ -921,4 +940,4 @@ type ExtendStoryObj<TMetaOrCmpOrArgs, S extends StoryObj<TMetaOrCmpOrArgs>, E ex
|
|
|
921
940
|
tags?: Array<E['tag'] | (string & {})> | undefined;
|
|
922
941
|
};
|
|
923
942
|
//#endregion
|
|
924
|
-
export { ActionsParam, BackgroundsParam, DocsParam, ExtendMeta, ExtendStoryObj, ExtendsMeta, ExtendsStoryObj, FnToArgTypes, GlobalApiBackgroundsParam, GlobalApiViewportParam, LayoutParam, ShowHtml, ShowHtmlProps, SourceProps, StoryCard, StoryCardParam, StoryCardProps, StoryCardStatus, StorySortParam, StorybookBuiltInParams, TestParam, Viewport, ViewportParam, WithStoryCardProps, defineActionsParam, defineBackgroundsParam, defineDocsParam, defineLayoutParam, defineParameters, defineStoryCardParam, defineTestParam, defineViewportParam, showDocSource, whenRunningInTest, withStoryCard };
|
|
943
|
+
export { ActionsParam, BackgroundsParam, DocsParam, ExtendMeta, ExtendStoryObj, ExtendsMeta, ExtendsStoryObj, FnToArgTypes, GlobalApiBackgroundsParam, GlobalApiViewportParam, LayoutParam, ShowHtml, ShowHtmlProps, SourceProps, StoryCard, StoryCardAppearance, StoryCardParam, StoryCardProps, StoryCardStatus, StoryCardThemeState, StorySortParam, StorybookBuiltInParams, TestParam, Viewport, ViewportParam, WithStoryCardProps, defineActionsParam, defineBackgroundsParam, defineDocsParam, defineLayoutParam, defineParameters, defineStoryCardParam, defineTestParam, defineViewportParam, showDocSource, whenRunningInTest, withStoryCard };
|
package/esm/index.js
CHANGED
|
@@ -39,31 +39,39 @@ function ShowHtml({ selector = "[data-testid=\"subject\"]", config, ...props })
|
|
|
39
39
|
|
|
40
40
|
//#endregion
|
|
41
41
|
//#region src/components/story_card.tsx
|
|
42
|
+
function resolveAppearance(appearance, status) {
|
|
43
|
+
if (appearance !== void 0) return appearance;
|
|
44
|
+
if (status !== void 0) return status;
|
|
45
|
+
return "info";
|
|
46
|
+
}
|
|
42
47
|
function storyCardTheme(state, className) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
return twMerge(typeof className === "function" ? className({
|
|
46
|
-
...state,
|
|
47
|
-
defaultClassName
|
|
48
|
-
}) : twJoin(defaultClassName, className));
|
|
48
|
+
if (!className) return state.defaultClassName;
|
|
49
|
+
return twMerge(typeof className === "function" ? className(state) : twJoin(state.defaultClassName, className));
|
|
49
50
|
}
|
|
50
|
-
const storyCardVariants = cva("rbsb:flex rbsb:flex-col rbsb:gap-1 rbsb:py-3 rbsb:px-4 rbsb:rounded rbsb:text-black rbsb:dark:text-gray-100", {
|
|
51
|
-
variants: {
|
|
52
|
-
error: "rbsb:bg-red-100 rbsb:dark:bg-red-900",
|
|
53
|
-
warn: "rbsb:bg-yellow-100 rbsb:dark:bg-yellow-900",
|
|
54
|
-
info: "rbsb:bg-sky-100 rbsb:dark:bg-sky-900"
|
|
51
|
+
const storyCardVariants = cva("rbsb:flex rbsb:flex-col rbsb:gap-1 rbsb:py-3 rbsb:px-4 rbsb:rounded rbsb:border rbsb:border-solid rbsb:text-black rbsb:dark:text-gray-100", {
|
|
52
|
+
variants: { appearance: {
|
|
53
|
+
error: "rbsb:bg-red-100 rbsb:dark:bg-red-900 rbsb:border-red-300 rbsb:dark:border-red-700",
|
|
54
|
+
warn: "rbsb:bg-yellow-100 rbsb:dark:bg-yellow-900 rbsb:border-yellow-300 rbsb:dark:border-yellow-700",
|
|
55
|
+
info: "rbsb:bg-sky-100 rbsb:dark:bg-sky-900 rbsb:border-sky-300 rbsb:dark:border-sky-700",
|
|
56
|
+
source: "rbsb:bg-gray-100 rbsb:dark:bg-gray-900 rbsb:border-gray-300 rbsb:dark:border-gray-700",
|
|
57
|
+
output: "rbsb:bg-green-100 rbsb:dark:bg-green-900 rbsb:border-green-300 rbsb:dark:border-green-700"
|
|
55
58
|
} },
|
|
56
|
-
defaultVariants: {
|
|
59
|
+
defaultVariants: { appearance: "info" }
|
|
57
60
|
});
|
|
58
61
|
/**
|
|
59
|
-
* A card component that displays information with optional title and
|
|
62
|
+
* A card component that displays information with optional title and appearance styling.
|
|
60
63
|
*
|
|
61
64
|
* @param props - StoryCard component props
|
|
62
65
|
* @returns A section element containing the card content
|
|
63
66
|
*/
|
|
64
|
-
function StoryCard({ status, className, children, title }) {
|
|
67
|
+
function StoryCard({ status, appearance, className, children, title }) {
|
|
68
|
+
const resolvedAppearance = resolveAppearance(appearance, status);
|
|
65
69
|
return /* @__PURE__ */ jsxs("section", {
|
|
66
|
-
className: storyCardTheme({
|
|
70
|
+
className: storyCardTheme({
|
|
71
|
+
status,
|
|
72
|
+
appearance: resolvedAppearance,
|
|
73
|
+
defaultClassName: storyCardVariants({ appearance: resolvedAppearance })
|
|
74
|
+
}, className),
|
|
67
75
|
children: [title && /* @__PURE__ */ jsx("h2", {
|
|
68
76
|
className: "rbsb:text-lg rbsb:font-bold",
|
|
69
77
|
children: title
|
|
@@ -129,13 +137,14 @@ function StoryCardContainer({ children }) {
|
|
|
129
137
|
})
|
|
130
138
|
});
|
|
131
139
|
}
|
|
132
|
-
function StoryCardCollector({ Story, title, status, className, content }) {
|
|
140
|
+
function StoryCardCollector({ Story, title, status, appearance, className, content }) {
|
|
133
141
|
const context = useContext(StoryCardRegistryContext);
|
|
134
142
|
const cardIdRef = useRef(null);
|
|
135
143
|
useLayoutEffect(() => {
|
|
136
144
|
if (cardIdRef.current === null) cardIdRef.current = context.add({
|
|
137
145
|
title,
|
|
138
146
|
status,
|
|
147
|
+
appearance,
|
|
139
148
|
className,
|
|
140
149
|
content
|
|
141
150
|
});
|
|
@@ -183,7 +192,7 @@ function showDocSource(options) {
|
|
|
183
192
|
const sourceCardClassName = (state) => {
|
|
184
193
|
const modifiedState = {
|
|
185
194
|
...state,
|
|
186
|
-
defaultClassName: twJoin(state.defaultClassName, isOriginalSource
|
|
195
|
+
defaultClassName: twJoin(state.defaultClassName, isOriginalSource && "rbsb:bg-transparent rbsb:dark:bg-transparent")
|
|
187
196
|
};
|
|
188
197
|
const className = options?.className;
|
|
189
198
|
return typeof className === "function" ? className(modifiedState) : twJoin(modifiedState.defaultClassName, className);
|
|
@@ -195,7 +204,7 @@ function showDocSource(options) {
|
|
|
195
204
|
Story,
|
|
196
205
|
content: sourceContent,
|
|
197
206
|
className: sourceCardClassName,
|
|
198
|
-
|
|
207
|
+
appearance: "source"
|
|
199
208
|
})
|
|
200
209
|
});
|
|
201
210
|
return /* @__PURE__ */ jsx(ThemeProvider, {
|
|
@@ -208,7 +217,7 @@ function showDocSource(options) {
|
|
|
208
217
|
},
|
|
209
218
|
children: [/* @__PURE__ */ jsx(Story, {}), /* @__PURE__ */ jsx(StoryCard, {
|
|
210
219
|
className: sourceCardClassName,
|
|
211
|
-
|
|
220
|
+
appearance: "source",
|
|
212
221
|
children: sourceContent
|
|
213
222
|
})]
|
|
214
223
|
})
|
|
@@ -295,13 +304,15 @@ function showDocSource(options) {
|
|
|
295
304
|
* - If `content` is not provided, it will automatically use the story description,
|
|
296
305
|
* or fall back to the component description.
|
|
297
306
|
* - Cards are collected and displayed in the order they are defined in the decorators array.
|
|
307
|
+
* - The `status` option is deprecated; use `appearance` instead for the same behavior and additional variants (`source`, `output`).
|
|
298
308
|
*/
|
|
299
|
-
function withStoryCard({ title, status, content: contentProp, className, ...rest } = {}) {
|
|
309
|
+
function withStoryCard({ title, status, appearance, content: contentProp, className, ...rest } = {}) {
|
|
300
310
|
return (Story, { parameters, viewMode }) => {
|
|
301
311
|
if (viewMode === "docs") return /* @__PURE__ */ jsx(Story, {});
|
|
302
312
|
const storyCardParam = parameters.storyCard;
|
|
303
313
|
const finalTitle = title ?? storyCardParam?.title;
|
|
304
|
-
const
|
|
314
|
+
const finalAppearance = appearance ?? storyCardParam?.appearance ?? status ?? storyCardParam?.status ?? "info";
|
|
315
|
+
const finalStatus = status ?? storyCardParam?.status;
|
|
305
316
|
const finalContent = contentProp ?? storyCardParam?.content;
|
|
306
317
|
const finalClassName = className ?? storyCardParam?.className;
|
|
307
318
|
const content = finalContent ?? parameters.docs?.description?.story ?? parameters.docs?.description?.component;
|
|
@@ -311,6 +322,7 @@ function withStoryCard({ title, status, content: contentProp, className, ...rest
|
|
|
311
322
|
content,
|
|
312
323
|
title: finalTitle,
|
|
313
324
|
status: finalStatus,
|
|
325
|
+
appearance: finalAppearance,
|
|
314
326
|
className: finalClassName,
|
|
315
327
|
...rest
|
|
316
328
|
});
|
|
@@ -8,7 +8,7 @@ type TagBadgeParameter = TagBadgeParameters[0];
|
|
|
8
8
|
/**
|
|
9
9
|
* Type representing the names of predefined tags used in Storybook stories.
|
|
10
10
|
*/
|
|
11
|
-
type TagNames = 'editor' | 'source' | 'new' | 'beta' | 'props' | 'deprecated' | 'outdated' | 'danger' | 'todo' | 'code-only' | 'snapshot' | 'unit' | 'integration' | 'keyboard' | 'internal' | 'usecase' | 'version:next';
|
|
11
|
+
type TagNames = 'editor' | 'source' | 'type' | 'new' | 'beta' | 'props' | 'deprecated' | 'outdated' | 'danger' | 'todo' | 'code-only' | 'snapshot' | 'unit' | 'integration' | 'keyboard' | 'internal' | 'usecase' | 'version:next';
|
|
12
12
|
/**
|
|
13
13
|
* Configuration for story tag badges that appear in the Storybook sidebar.
|
|
14
14
|
* Each badge is associated with a specific tag and displays an emoji with a tooltip.
|
|
@@ -28,21 +28,39 @@ type TagNames = 'editor' | 'source' | 'new' | 'beta' | 'props' | 'deprecated' |
|
|
|
28
28
|
*
|
|
29
29
|
* Also includes the default version badge from `storybook-addon-tag-badges`.
|
|
30
30
|
*/
|
|
31
|
+
/** Badge (✏️) for stories with a live editor. Shown in sidebar on story and inherited. */
|
|
31
32
|
declare const editorBadge: TagBadgeParameter;
|
|
33
|
+
/** Badge (🆕) for recently added stories. */
|
|
32
34
|
declare const newBadge: TagBadgeParameter;
|
|
35
|
+
/** Badge (🅱️) for stories covering features in beta. */
|
|
33
36
|
declare const betaBadge: TagBadgeParameter;
|
|
37
|
+
/** Badge (🔧) for stories that demonstrate props or configuration. */
|
|
34
38
|
declare const propsBadge: TagBadgeParameter;
|
|
39
|
+
/** Badge (🪦) for stories documenting deprecated features. */
|
|
35
40
|
declare const deprecatedBadge: TagBadgeParameter;
|
|
41
|
+
/** Badge (⚠️) for stories that need updating. */
|
|
36
42
|
declare const outdatedBadge: TagBadgeParameter;
|
|
43
|
+
/** Badge (🚨) for stories demonstrating dangerous or cautionary patterns. */
|
|
37
44
|
declare const dangerBadge: TagBadgeParameter;
|
|
45
|
+
/** Badge (📋) for stories marked as todo or incomplete. */
|
|
38
46
|
declare const todoBadge: TagBadgeParameter;
|
|
47
|
+
/** Badge (📝) for stories without visual examples (code-only). Hidden in MDX. */
|
|
39
48
|
declare const codeOnlyBadge: TagBadgeParameter;
|
|
49
|
+
/** Badge (<T>) for stories that showcase or document TypeScript types. Hidden in MDX. */
|
|
50
|
+
declare const typeBadge: TagBadgeParameter;
|
|
51
|
+
/** Badge (`</>`) for source-code-focused stories. Hidden in MDX. */
|
|
40
52
|
declare const sourceBadge: TagBadgeParameter;
|
|
53
|
+
/** Badge (📸) for stories with snapshot tests. Shown in toolbar only, not in sidebar. */
|
|
41
54
|
declare const snapshotBadge: TagBadgeParameter;
|
|
55
|
+
/** Badge (🧪) for stories with unit tests. */
|
|
42
56
|
declare const unitBadge: TagBadgeParameter;
|
|
57
|
+
/** Badge (🔗) for stories with integration tests. Hidden in sidebar. */
|
|
43
58
|
declare const integrationBadge: TagBadgeParameter;
|
|
59
|
+
/** Badge (⌨️) for stories that demonstrate or test keyboard interaction. */
|
|
44
60
|
declare const keyboardBadge: TagBadgeParameter;
|
|
61
|
+
/** Badge (🔒) for internal or private-use-only stories. */
|
|
45
62
|
declare const internalBadge: TagBadgeParameter;
|
|
63
|
+
/** Ordered list of all tag badge configs used by the addon (includes version badge). */
|
|
46
64
|
declare const tagBadges: TagBadgeParameters;
|
|
47
65
|
//#endregion
|
|
48
66
|
//#region src/types/_extract_string_literals.d.ts
|
|
@@ -116,4 +134,4 @@ type StoryObj<TMetaOrCmpOrArgs = Args> = ExtendStoryObj<TMetaOrCmpOrArgs, StoryO
|
|
|
116
134
|
tag: TagNames;
|
|
117
135
|
}>;
|
|
118
136
|
//#endregion
|
|
119
|
-
export { Meta, StoryObj, TagNames, betaBadge, codeOnlyBadge, dangerBadge, deprecatedBadge, editorBadge, integrationBadge, internalBadge, keyboardBadge, newBadge, outdatedBadge, propsBadge, snapshotBadge, sourceBadge, tagBadges, todoBadge, unitBadge };
|
|
137
|
+
export { Meta, StoryObj, TagNames, betaBadge, codeOnlyBadge, dangerBadge, deprecatedBadge, editorBadge, integrationBadge, internalBadge, keyboardBadge, newBadge, outdatedBadge, propsBadge, snapshotBadge, sourceBadge, tagBadges, todoBadge, typeBadge, unitBadge };
|
|
@@ -22,6 +22,7 @@ const [, , , , , , versionBadge] = defaultConfig;
|
|
|
22
22
|
*
|
|
23
23
|
* Also includes the default version badge from `storybook-addon-tag-badges`.
|
|
24
24
|
*/
|
|
25
|
+
/** Badge (✏️) for stories with a live editor. Shown in sidebar on story and inherited. */
|
|
25
26
|
const editorBadge = {
|
|
26
27
|
tags: "editor",
|
|
27
28
|
badge: {
|
|
@@ -37,6 +38,7 @@ const editorBadge = {
|
|
|
37
38
|
skipInherited: false
|
|
38
39
|
} }
|
|
39
40
|
};
|
|
41
|
+
/** Badge (🆕) for recently added stories. */
|
|
40
42
|
const newBadge = {
|
|
41
43
|
tags: "new",
|
|
42
44
|
badge: {
|
|
@@ -48,6 +50,7 @@ const newBadge = {
|
|
|
48
50
|
tooltip: "New"
|
|
49
51
|
}
|
|
50
52
|
};
|
|
53
|
+
/** Badge (🅱️) for stories covering features in beta. */
|
|
51
54
|
const betaBadge = {
|
|
52
55
|
tags: "beta",
|
|
53
56
|
badge: {
|
|
@@ -59,6 +62,7 @@ const betaBadge = {
|
|
|
59
62
|
tooltip: "Beta"
|
|
60
63
|
}
|
|
61
64
|
};
|
|
65
|
+
/** Badge (🔧) for stories that demonstrate props or configuration. */
|
|
62
66
|
const propsBadge = {
|
|
63
67
|
tags: "props",
|
|
64
68
|
badge: {
|
|
@@ -70,6 +74,7 @@ const propsBadge = {
|
|
|
70
74
|
tooltip: "Props"
|
|
71
75
|
}
|
|
72
76
|
};
|
|
77
|
+
/** Badge (🪦) for stories documenting deprecated features. */
|
|
73
78
|
const deprecatedBadge = {
|
|
74
79
|
tags: "deprecated",
|
|
75
80
|
badge: {
|
|
@@ -81,6 +86,7 @@ const deprecatedBadge = {
|
|
|
81
86
|
tooltip: "Deprecated"
|
|
82
87
|
}
|
|
83
88
|
};
|
|
89
|
+
/** Badge (⚠️) for stories that need updating. */
|
|
84
90
|
const outdatedBadge = {
|
|
85
91
|
tags: "outdated",
|
|
86
92
|
badge: {
|
|
@@ -92,6 +98,7 @@ const outdatedBadge = {
|
|
|
92
98
|
tooltip: "Outdated"
|
|
93
99
|
}
|
|
94
100
|
};
|
|
101
|
+
/** Badge (🚨) for stories demonstrating dangerous or cautionary patterns. */
|
|
95
102
|
const dangerBadge = {
|
|
96
103
|
tags: "danger",
|
|
97
104
|
badge: {
|
|
@@ -103,6 +110,7 @@ const dangerBadge = {
|
|
|
103
110
|
tooltip: "Dangerous"
|
|
104
111
|
}
|
|
105
112
|
};
|
|
113
|
+
/** Badge (📋) for stories marked as todo or incomplete. */
|
|
106
114
|
const todoBadge = {
|
|
107
115
|
tags: "todo",
|
|
108
116
|
badge: {
|
|
@@ -114,6 +122,7 @@ const todoBadge = {
|
|
|
114
122
|
tooltip: "Todo"
|
|
115
123
|
}
|
|
116
124
|
};
|
|
125
|
+
/** Badge (📝) for stories without visual examples (code-only). Hidden in MDX. */
|
|
117
126
|
const codeOnlyBadge = {
|
|
118
127
|
tags: "code-only",
|
|
119
128
|
badge: {
|
|
@@ -126,6 +135,20 @@ const codeOnlyBadge = {
|
|
|
126
135
|
},
|
|
127
136
|
display: { mdx: false }
|
|
128
137
|
};
|
|
138
|
+
/** Badge (<T>) for stories that showcase or document TypeScript types. Hidden in MDX. */
|
|
139
|
+
const typeBadge = {
|
|
140
|
+
tags: "type",
|
|
141
|
+
badge: {
|
|
142
|
+
text: "<T>",
|
|
143
|
+
style: {
|
|
144
|
+
backgroundColor: "transparent",
|
|
145
|
+
borderColor: "transparent"
|
|
146
|
+
},
|
|
147
|
+
tooltip: "TypeScript Types"
|
|
148
|
+
},
|
|
149
|
+
display: { mdx: false }
|
|
150
|
+
};
|
|
151
|
+
/** Badge (`</>`) for source-code-focused stories. Hidden in MDX. */
|
|
129
152
|
const sourceBadge = {
|
|
130
153
|
tags: "source",
|
|
131
154
|
badge: {
|
|
@@ -138,6 +161,7 @@ const sourceBadge = {
|
|
|
138
161
|
},
|
|
139
162
|
display: { mdx: false }
|
|
140
163
|
};
|
|
164
|
+
/** Badge (📸) for stories with snapshot tests. Shown in toolbar only, not in sidebar. */
|
|
141
165
|
const snapshotBadge = {
|
|
142
166
|
tags: "snapshot",
|
|
143
167
|
badge: {
|
|
@@ -153,6 +177,7 @@ const snapshotBadge = {
|
|
|
153
177
|
toolbar: ["story"]
|
|
154
178
|
}
|
|
155
179
|
};
|
|
180
|
+
/** Badge (🧪) for stories with unit tests. */
|
|
156
181
|
const unitBadge = {
|
|
157
182
|
tags: "unit",
|
|
158
183
|
badge: {
|
|
@@ -165,6 +190,7 @@ const unitBadge = {
|
|
|
165
190
|
},
|
|
166
191
|
display: { sidebar: true }
|
|
167
192
|
};
|
|
193
|
+
/** Badge (🔗) for stories with integration tests. Hidden in sidebar. */
|
|
168
194
|
const integrationBadge = {
|
|
169
195
|
tags: "integration",
|
|
170
196
|
badge: {
|
|
@@ -177,6 +203,7 @@ const integrationBadge = {
|
|
|
177
203
|
},
|
|
178
204
|
display: { sidebar: false }
|
|
179
205
|
};
|
|
206
|
+
/** Badge (⌨️) for stories that demonstrate or test keyboard interaction. */
|
|
180
207
|
const keyboardBadge = {
|
|
181
208
|
tags: "keyboard",
|
|
182
209
|
badge: {
|
|
@@ -188,6 +215,7 @@ const keyboardBadge = {
|
|
|
188
215
|
tooltip: "Keyboard Interaction"
|
|
189
216
|
}
|
|
190
217
|
};
|
|
218
|
+
/** Badge (🔒) for internal or private-use-only stories. */
|
|
191
219
|
const internalBadge = {
|
|
192
220
|
tags: "internal",
|
|
193
221
|
badge: {
|
|
@@ -199,9 +227,11 @@ const internalBadge = {
|
|
|
199
227
|
tooltip: "Internal"
|
|
200
228
|
}
|
|
201
229
|
};
|
|
230
|
+
/** Ordered list of all tag badge configs used by the addon (includes version badge). */
|
|
202
231
|
const tagBadges = [
|
|
203
232
|
editorBadge,
|
|
204
233
|
sourceBadge,
|
|
234
|
+
typeBadge,
|
|
205
235
|
unitBadge,
|
|
206
236
|
integrationBadge,
|
|
207
237
|
keyboardBadge,
|
|
@@ -219,4 +249,4 @@ const tagBadges = [
|
|
|
219
249
|
];
|
|
220
250
|
|
|
221
251
|
//#endregion
|
|
222
|
-
export { betaBadge, codeOnlyBadge, dangerBadge, deprecatedBadge, editorBadge, integrationBadge, internalBadge, keyboardBadge, newBadge, outdatedBadge, propsBadge, snapshotBadge, sourceBadge, tagBadges, todoBadge, unitBadge };
|
|
252
|
+
export { betaBadge, codeOnlyBadge, dangerBadge, deprecatedBadge, editorBadge, integrationBadge, internalBadge, keyboardBadge, newBadge, outdatedBadge, propsBadge, snapshotBadge, sourceBadge, tagBadges, todoBadge, typeBadge, unitBadge };
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# @repobuddy/storybook
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/@repobuddy/storybook)
|
|
4
|
+
[](https://www.npmjs.com/package/@repobuddy/storybook)
|
|
5
|
+
[](https://github.com/repobuddy/storybook/actions/workflows/release.yml)
|
|
6
|
+
|
|
3
7
|
Your repository buddy for Storybook.
|
|
4
8
|
|
|
5
9
|
> [!NOTE]
|
|
@@ -3,10 +3,13 @@ import type { ReactNode } from 'react'
|
|
|
3
3
|
import { twJoin, twMerge } from 'tailwind-merge'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
* Resolved appearance of the card (error | warn | info | source | output).
|
|
7
|
+
* Used for styling; when only `status` is provided it is mapped to this.
|
|
8
|
+
*/
|
|
9
|
+
export type StoryCardAppearance = 'error' | 'warn' | 'info' | 'source' | 'output'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @deprecated Use `appearance` instead. Visual status of the card; equivalent to `appearance` for 'error' | 'warn' | 'info'.
|
|
10
13
|
*/
|
|
11
14
|
export type StoryCardStatus = 'error' | 'warn' | 'info' | undefined
|
|
12
15
|
|
|
@@ -17,12 +20,18 @@ export type StoryCardProps = {
|
|
|
17
20
|
*/
|
|
18
21
|
title?: ReactNode | undefined
|
|
19
22
|
/**
|
|
20
|
-
*
|
|
21
|
-
* - `'error'`: Red background (rbsb:bg-red-100 rbsb:dark:bg-red-900)
|
|
22
|
-
* - `'warn'`: Yellow background (rbsb:bg-yellow-100 rbsb:dark:bg-yellow-900)
|
|
23
|
-
* - `'info'`: Blue background (rbsb:bg-sky-100 rbsb:dark:bg-sky-900) - default
|
|
23
|
+
* @deprecated Use `appearance` instead. When set, behaves like `appearance` for the same value.
|
|
24
24
|
*/
|
|
25
25
|
status?: StoryCardStatus
|
|
26
|
+
/**
|
|
27
|
+
* Appearance of the card, affecting its background and border color.
|
|
28
|
+
* - `'error'`: Red
|
|
29
|
+
* - `'warn'`: Yellow
|
|
30
|
+
* - `'info'`: Blue (default when neither appearance nor status is set)
|
|
31
|
+
* - `'source'`: Transparent
|
|
32
|
+
* - `'output'`: Green
|
|
33
|
+
*/
|
|
34
|
+
appearance?: StoryCardAppearance | undefined
|
|
26
35
|
/**
|
|
27
36
|
* Additional CSS classes or a function to compute classes.
|
|
28
37
|
*
|
|
@@ -30,7 +39,10 @@ export type StoryCardProps = {
|
|
|
30
39
|
* If a function is provided, it receives the card state and default className,
|
|
31
40
|
* and should return the final className string.
|
|
32
41
|
*/
|
|
33
|
-
className?:
|
|
42
|
+
className?:
|
|
43
|
+
| ((state: Pick<StoryCardProps, 'status' | 'appearance'> & { defaultClassName: string }) => string)
|
|
44
|
+
| string
|
|
45
|
+
| undefined
|
|
34
46
|
/**
|
|
35
47
|
* Content to display in the card body.
|
|
36
48
|
* Can be any React node (string, JSX, etc.).
|
|
@@ -38,39 +50,55 @@ export type StoryCardProps = {
|
|
|
38
50
|
children?: ReactNode | undefined
|
|
39
51
|
}
|
|
40
52
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
53
|
+
export type StoryCardThemeState = Pick<StoryCardProps, 'status' | 'appearance'> & { defaultClassName: string }
|
|
54
|
+
|
|
55
|
+
function resolveAppearance(
|
|
56
|
+
appearance: StoryCardProps['appearance'],
|
|
57
|
+
status: StoryCardProps['status']
|
|
58
|
+
): NonNullable<StoryCardAppearance> {
|
|
59
|
+
if (appearance !== undefined) return appearance
|
|
60
|
+
if (status !== undefined) return status
|
|
61
|
+
return 'info'
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function storyCardTheme(state: StoryCardThemeState, className: StoryCardProps['className']) {
|
|
65
|
+
if (!className) return state.defaultClassName
|
|
66
|
+
return twMerge(typeof className === 'function' ? className(state) : twJoin(state.defaultClassName, className))
|
|
47
67
|
}
|
|
48
68
|
|
|
49
69
|
const storyCardVariants = cva(
|
|
50
|
-
'rbsb:flex rbsb:flex-col rbsb:gap-1 rbsb:py-3 rbsb:px-4 rbsb:rounded rbsb:text-black rbsb:dark:text-gray-100',
|
|
70
|
+
'rbsb:flex rbsb:flex-col rbsb:gap-1 rbsb:py-3 rbsb:px-4 rbsb:rounded rbsb:border rbsb:border-solid rbsb:text-black rbsb:dark:text-gray-100',
|
|
51
71
|
{
|
|
52
72
|
variants: {
|
|
53
|
-
|
|
54
|
-
error: 'rbsb:bg-red-100 rbsb:dark:bg-red-900',
|
|
55
|
-
warn: 'rbsb:bg-yellow-100 rbsb:dark:bg-yellow-900',
|
|
56
|
-
info: 'rbsb:bg-sky-100 rbsb:dark:bg-sky-900'
|
|
73
|
+
appearance: {
|
|
74
|
+
error: 'rbsb:bg-red-100 rbsb:dark:bg-red-900 rbsb:border-red-300 rbsb:dark:border-red-700',
|
|
75
|
+
warn: 'rbsb:bg-yellow-100 rbsb:dark:bg-yellow-900 rbsb:border-yellow-300 rbsb:dark:border-yellow-700',
|
|
76
|
+
info: 'rbsb:bg-sky-100 rbsb:dark:bg-sky-900 rbsb:border-sky-300 rbsb:dark:border-sky-700',
|
|
77
|
+
source: 'rbsb:bg-gray-100 rbsb:dark:bg-gray-900 rbsb:border-gray-300 rbsb:dark:border-gray-700',
|
|
78
|
+
output: 'rbsb:bg-green-100 rbsb:dark:bg-green-900 rbsb:border-green-300 rbsb:dark:border-green-700'
|
|
57
79
|
}
|
|
58
80
|
},
|
|
59
81
|
defaultVariants: {
|
|
60
|
-
|
|
82
|
+
appearance: 'info'
|
|
61
83
|
}
|
|
62
84
|
}
|
|
63
85
|
)
|
|
64
86
|
|
|
65
87
|
/**
|
|
66
|
-
* A card component that displays information with optional title and
|
|
88
|
+
* A card component that displays information with optional title and appearance styling.
|
|
67
89
|
*
|
|
68
90
|
* @param props - StoryCard component props
|
|
69
91
|
* @returns A section element containing the card content
|
|
70
92
|
*/
|
|
71
|
-
export function StoryCard({ status, className, children, title }: StoryCardProps) {
|
|
93
|
+
export function StoryCard({ status, appearance, className, children, title }: StoryCardProps) {
|
|
94
|
+
const resolvedAppearance = resolveAppearance(appearance, status)
|
|
95
|
+
const state: StoryCardThemeState = {
|
|
96
|
+
status,
|
|
97
|
+
appearance: resolvedAppearance,
|
|
98
|
+
defaultClassName: storyCardVariants({ appearance: resolvedAppearance })
|
|
99
|
+
}
|
|
72
100
|
return (
|
|
73
|
-
<section className={storyCardTheme(
|
|
101
|
+
<section className={storyCardTheme(state, className)}>
|
|
74
102
|
{title && <h2 className="rbsb:text-lg rbsb:font-bold">{title}</h2>}
|
|
75
103
|
{children}
|
|
76
104
|
</section>
|
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
import type { ReactNode } from 'react'
|
|
2
2
|
import { createContext } from 'react'
|
|
3
|
-
import type { RequiredPick } from 'type-plus'
|
|
4
3
|
import type { StoryCardProps } from '../components/story_card.js'
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Payload for adding a card to the story card registry.
|
|
8
7
|
* Matches the shape of card props with `status` required.
|
|
9
8
|
*/
|
|
10
|
-
export type StoryCardEntry =
|
|
9
|
+
export type StoryCardEntry = Omit<StoryCardProps, 'children'> & { content?: ReactNode }
|
|
11
10
|
|
|
12
11
|
export interface StoryCardRegistryContextValue {
|
|
13
12
|
add: (card: StoryCardEntry) => string
|
|
@@ -59,7 +59,7 @@ type StoryCardEntryWithKey = StoryCardEntry & { key: string }
|
|
|
59
59
|
|
|
60
60
|
interface StoryCardCollectorProps extends StoryCardScopeProps {}
|
|
61
61
|
|
|
62
|
-
function StoryCardCollector({ Story, title, status, className, content }: StoryCardCollectorProps) {
|
|
62
|
+
function StoryCardCollector({ Story, title, status, appearance, className, content }: StoryCardCollectorProps) {
|
|
63
63
|
// StoryCardCollector is an internal component. Context is guaranteed to be not null by `StoryCardContainer`.
|
|
64
64
|
const context = useContext(StoryCardRegistryContext)!
|
|
65
65
|
const cardIdRef = useRef<string | null>(null)
|
|
@@ -68,7 +68,7 @@ function StoryCardCollector({ Story, title, status, className, content }: StoryC
|
|
|
68
68
|
useLayoutEffect(() => {
|
|
69
69
|
// Only add if not already added (handles Strict Mode double-render)
|
|
70
70
|
if (cardIdRef.current === null) {
|
|
71
|
-
cardIdRef.current = context.add({ title, status, className, content })
|
|
71
|
+
cardIdRef.current = context.add({ title, status, appearance, className, content })
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
return () => {
|
|
@@ -58,12 +58,14 @@ export function showDocSource<TRenderer extends Renderer = Renderer, TArgs = Arg
|
|
|
58
58
|
|
|
59
59
|
const showBefore = options?.placement === 'before'
|
|
60
60
|
|
|
61
|
-
const sourceCardClassName = (
|
|
61
|
+
const sourceCardClassName = (
|
|
62
|
+
state: Pick<StoryCardProps, 'status' | 'appearance'> & { defaultClassName: string }
|
|
63
|
+
) => {
|
|
62
64
|
const modifiedState = {
|
|
63
65
|
...state,
|
|
64
66
|
defaultClassName: twJoin(
|
|
65
67
|
state.defaultClassName,
|
|
66
|
-
isOriginalSource
|
|
68
|
+
isOriginalSource && 'rbsb:bg-transparent rbsb:dark:bg-transparent'
|
|
67
69
|
)
|
|
68
70
|
}
|
|
69
71
|
|
|
@@ -78,13 +80,13 @@ export function showDocSource<TRenderer extends Renderer = Renderer, TArgs = Arg
|
|
|
78
80
|
if (showBefore) {
|
|
79
81
|
return (
|
|
80
82
|
<ThemeProvider theme={theme}>
|
|
81
|
-
<StoryCardScope Story={Story} content={sourceContent} className={sourceCardClassName}
|
|
83
|
+
<StoryCardScope Story={Story} content={sourceContent} className={sourceCardClassName} appearance="source" />
|
|
82
84
|
</ThemeProvider>
|
|
83
85
|
)
|
|
84
86
|
}
|
|
85
87
|
|
|
86
88
|
const storyCard = (
|
|
87
|
-
<StoryCard className={sourceCardClassName}
|
|
89
|
+
<StoryCard className={sourceCardClassName} appearance="source">
|
|
88
90
|
{sourceContent}
|
|
89
91
|
</StoryCard>
|
|
90
92
|
)
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import type { ReactNode } from 'react'
|
|
2
2
|
import type { DecoratorFunction, Renderer } from 'storybook/internal/csf'
|
|
3
|
-
import type { StoryCardProps } from '../components/story_card.js'
|
|
3
|
+
import type { StoryCardProps, StoryCardStatus } from '../components/story_card.js'
|
|
4
4
|
import { StoryCardScope } from '../contexts/story_card_scope.js'
|
|
5
5
|
import type { StoryCardParam } from '../parameters/define_story_card_param.js'
|
|
6
6
|
|
|
7
7
|
export type WithStoryCardProps = Omit<StoryCardProps, 'children' | 'className'> & {
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated Use `appearance` instead. When set, behaves like `appearance` for the same value.
|
|
10
|
+
*/
|
|
11
|
+
status?: StoryCardStatus
|
|
8
12
|
/**
|
|
9
13
|
* Additional CSS classes or a function to compute classes.
|
|
10
14
|
*
|
|
@@ -12,7 +16,10 @@ export type WithStoryCardProps = Omit<StoryCardProps, 'children' | 'className'>
|
|
|
12
16
|
* If a function is provided, it receives the card state and default className,
|
|
13
17
|
* and should return the final className string.
|
|
14
18
|
*/
|
|
15
|
-
className?:
|
|
19
|
+
className?:
|
|
20
|
+
| ((state: Pick<StoryCardProps, 'status' | 'appearance'> & { defaultClassName: string }) => string)
|
|
21
|
+
| string
|
|
22
|
+
| undefined
|
|
16
23
|
/**
|
|
17
24
|
* Content to display in the card body.
|
|
18
25
|
* Can be any React node (string, JSX, etc.).
|
|
@@ -102,10 +109,12 @@ export type WithStoryCardProps = Omit<StoryCardProps, 'children' | 'className'>
|
|
|
102
109
|
* - If `content` is not provided, it will automatically use the story description,
|
|
103
110
|
* or fall back to the component description.
|
|
104
111
|
* - Cards are collected and displayed in the order they are defined in the decorators array.
|
|
112
|
+
* - The `status` option is deprecated; use `appearance` instead for the same behavior and additional variants (`source`, `output`).
|
|
105
113
|
*/
|
|
106
114
|
export function withStoryCard<TRenderer extends Renderer = Renderer>({
|
|
107
115
|
title,
|
|
108
116
|
status,
|
|
117
|
+
appearance,
|
|
109
118
|
content: contentProp,
|
|
110
119
|
className,
|
|
111
120
|
...rest
|
|
@@ -118,7 +127,8 @@ export function withStoryCard<TRenderer extends Renderer = Renderer>({
|
|
|
118
127
|
// Decorator props override parameter values
|
|
119
128
|
// Use parameters as fallback when decorator props are not provided
|
|
120
129
|
const finalTitle = title ?? storyCardParam?.title
|
|
121
|
-
const
|
|
130
|
+
const finalAppearance = appearance ?? storyCardParam?.appearance ?? status ?? storyCardParam?.status ?? 'info'
|
|
131
|
+
const finalStatus = status ?? storyCardParam?.status
|
|
122
132
|
const finalContent = contentProp ?? storyCardParam?.content
|
|
123
133
|
const finalClassName = className ?? storyCardParam?.className
|
|
124
134
|
|
|
@@ -132,6 +142,7 @@ export function withStoryCard<TRenderer extends Renderer = Renderer>({
|
|
|
132
142
|
content={content}
|
|
133
143
|
title={finalTitle}
|
|
134
144
|
status={finalStatus}
|
|
145
|
+
appearance={finalAppearance}
|
|
135
146
|
className={finalClassName}
|
|
136
147
|
{...rest}
|
|
137
148
|
/>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from 'react'
|
|
2
|
-
import type { StoryCardProps, StoryCardStatus } from '../components/story_card.js'
|
|
2
|
+
import type { StoryCardAppearance, StoryCardProps, StoryCardStatus } from '../components/story_card.js'
|
|
3
3
|
|
|
4
4
|
export interface StoryCardParam {
|
|
5
5
|
storyCard: {
|
|
@@ -9,12 +9,13 @@ export interface StoryCardParam {
|
|
|
9
9
|
*/
|
|
10
10
|
title?: ReactNode | undefined
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
* - `'error'`: Red background
|
|
14
|
-
* - `'warn'`: Yellow background
|
|
15
|
-
* - `'info'`: Blue background - default
|
|
12
|
+
* @deprecated Use `appearance` instead.
|
|
16
13
|
*/
|
|
17
14
|
status?: StoryCardStatus
|
|
15
|
+
/**
|
|
16
|
+
* Appearance of the card (error | warn | info | source | output). Default: `'info'`.
|
|
17
|
+
*/
|
|
18
|
+
appearance?: StoryCardAppearance | undefined
|
|
18
19
|
/**
|
|
19
20
|
* Additional CSS classes or a function to compute classes.
|
|
20
21
|
*
|
|
@@ -22,7 +23,10 @@ export interface StoryCardParam {
|
|
|
22
23
|
* If a function is provided, it receives the card state and default className,
|
|
23
24
|
* and should return the final className string.
|
|
24
25
|
*/
|
|
25
|
-
className?:
|
|
26
|
+
className?:
|
|
27
|
+
| ((state: Pick<StoryCardProps, 'status' | 'appearance'> & { defaultClassName: string }) => string)
|
|
28
|
+
| string
|
|
29
|
+
| undefined
|
|
26
30
|
/**
|
|
27
31
|
* Content to display in the card body.
|
|
28
32
|
* Can be any React node (string, JSX, etc.).
|
|
@@ -10,6 +10,7 @@ type TagBadgeParameter = TagBadgeParameters[0]
|
|
|
10
10
|
export type TagNames =
|
|
11
11
|
| 'editor'
|
|
12
12
|
| 'source'
|
|
13
|
+
| 'type'
|
|
13
14
|
| 'new'
|
|
14
15
|
| 'beta'
|
|
15
16
|
| 'props'
|
|
@@ -45,6 +46,8 @@ export type TagNames =
|
|
|
45
46
|
*
|
|
46
47
|
* Also includes the default version badge from `storybook-addon-tag-badges`.
|
|
47
48
|
*/
|
|
49
|
+
|
|
50
|
+
/** Badge (✏️) for stories with a live editor. Shown in sidebar on story and inherited. */
|
|
48
51
|
export const editorBadge: TagBadgeParameter = {
|
|
49
52
|
tags: 'editor',
|
|
50
53
|
badge: {
|
|
@@ -63,6 +66,7 @@ export const editorBadge: TagBadgeParameter = {
|
|
|
63
66
|
}
|
|
64
67
|
}
|
|
65
68
|
|
|
69
|
+
/** Badge (🆕) for recently added stories. */
|
|
66
70
|
export const newBadge: TagBadgeParameter = {
|
|
67
71
|
tags: 'new',
|
|
68
72
|
badge: {
|
|
@@ -75,6 +79,7 @@ export const newBadge: TagBadgeParameter = {
|
|
|
75
79
|
}
|
|
76
80
|
}
|
|
77
81
|
|
|
82
|
+
/** Badge (🅱️) for stories covering features in beta. */
|
|
78
83
|
export const betaBadge: TagBadgeParameter = {
|
|
79
84
|
tags: 'beta',
|
|
80
85
|
badge: {
|
|
@@ -87,6 +92,7 @@ export const betaBadge: TagBadgeParameter = {
|
|
|
87
92
|
}
|
|
88
93
|
}
|
|
89
94
|
|
|
95
|
+
/** Badge (🔧) for stories that demonstrate props or configuration. */
|
|
90
96
|
export const propsBadge: TagBadgeParameter = {
|
|
91
97
|
tags: 'props',
|
|
92
98
|
badge: {
|
|
@@ -99,6 +105,7 @@ export const propsBadge: TagBadgeParameter = {
|
|
|
99
105
|
}
|
|
100
106
|
}
|
|
101
107
|
|
|
108
|
+
/** Badge (🪦) for stories documenting deprecated features. */
|
|
102
109
|
export const deprecatedBadge: TagBadgeParameter = {
|
|
103
110
|
tags: 'deprecated',
|
|
104
111
|
badge: {
|
|
@@ -111,6 +118,7 @@ export const deprecatedBadge: TagBadgeParameter = {
|
|
|
111
118
|
}
|
|
112
119
|
}
|
|
113
120
|
|
|
121
|
+
/** Badge (⚠️) for stories that need updating. */
|
|
114
122
|
export const outdatedBadge: TagBadgeParameter = {
|
|
115
123
|
tags: 'outdated',
|
|
116
124
|
badge: {
|
|
@@ -123,6 +131,7 @@ export const outdatedBadge: TagBadgeParameter = {
|
|
|
123
131
|
}
|
|
124
132
|
}
|
|
125
133
|
|
|
134
|
+
/** Badge (🚨) for stories demonstrating dangerous or cautionary patterns. */
|
|
126
135
|
export const dangerBadge: TagBadgeParameter = {
|
|
127
136
|
tags: 'danger',
|
|
128
137
|
badge: {
|
|
@@ -135,6 +144,7 @@ export const dangerBadge: TagBadgeParameter = {
|
|
|
135
144
|
}
|
|
136
145
|
}
|
|
137
146
|
|
|
147
|
+
/** Badge (📋) for stories marked as todo or incomplete. */
|
|
138
148
|
export const todoBadge: TagBadgeParameter = {
|
|
139
149
|
tags: 'todo',
|
|
140
150
|
badge: {
|
|
@@ -147,6 +157,7 @@ export const todoBadge: TagBadgeParameter = {
|
|
|
147
157
|
}
|
|
148
158
|
}
|
|
149
159
|
|
|
160
|
+
/** Badge (📝) for stories without visual examples (code-only). Hidden in MDX. */
|
|
150
161
|
export const codeOnlyBadge: TagBadgeParameter = {
|
|
151
162
|
tags: 'code-only',
|
|
152
163
|
badge: {
|
|
@@ -162,6 +173,23 @@ export const codeOnlyBadge: TagBadgeParameter = {
|
|
|
162
173
|
}
|
|
163
174
|
}
|
|
164
175
|
|
|
176
|
+
/** Badge (<T>) for stories that showcase or document TypeScript types. Hidden in MDX. */
|
|
177
|
+
export const typeBadge: TagBadgeParameter = {
|
|
178
|
+
tags: 'type',
|
|
179
|
+
badge: {
|
|
180
|
+
text: '<T>',
|
|
181
|
+
style: {
|
|
182
|
+
backgroundColor: 'transparent',
|
|
183
|
+
borderColor: 'transparent'
|
|
184
|
+
},
|
|
185
|
+
tooltip: 'TypeScript Types'
|
|
186
|
+
},
|
|
187
|
+
display: {
|
|
188
|
+
mdx: false
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/** Badge (`</>`) for source-code-focused stories. Hidden in MDX. */
|
|
165
193
|
export const sourceBadge: TagBadgeParameter = {
|
|
166
194
|
tags: 'source',
|
|
167
195
|
badge: {
|
|
@@ -177,6 +205,7 @@ export const sourceBadge: TagBadgeParameter = {
|
|
|
177
205
|
}
|
|
178
206
|
}
|
|
179
207
|
|
|
208
|
+
/** Badge (📸) for stories with snapshot tests. Shown in toolbar only, not in sidebar. */
|
|
180
209
|
export const snapshotBadge: TagBadgeParameter = {
|
|
181
210
|
tags: 'snapshot',
|
|
182
211
|
badge: {
|
|
@@ -193,6 +222,7 @@ export const snapshotBadge: TagBadgeParameter = {
|
|
|
193
222
|
}
|
|
194
223
|
}
|
|
195
224
|
|
|
225
|
+
/** Badge (🧪) for stories with unit tests. */
|
|
196
226
|
export const unitBadge: TagBadgeParameter = {
|
|
197
227
|
tags: 'unit',
|
|
198
228
|
badge: {
|
|
@@ -208,6 +238,7 @@ export const unitBadge: TagBadgeParameter = {
|
|
|
208
238
|
}
|
|
209
239
|
}
|
|
210
240
|
|
|
241
|
+
/** Badge (🔗) for stories with integration tests. Hidden in sidebar. */
|
|
211
242
|
export const integrationBadge: TagBadgeParameter = {
|
|
212
243
|
tags: 'integration',
|
|
213
244
|
badge: {
|
|
@@ -223,6 +254,7 @@ export const integrationBadge: TagBadgeParameter = {
|
|
|
223
254
|
}
|
|
224
255
|
}
|
|
225
256
|
|
|
257
|
+
/** Badge (⌨️) for stories that demonstrate or test keyboard interaction. */
|
|
226
258
|
export const keyboardBadge: TagBadgeParameter = {
|
|
227
259
|
tags: 'keyboard',
|
|
228
260
|
badge: {
|
|
@@ -235,6 +267,7 @@ export const keyboardBadge: TagBadgeParameter = {
|
|
|
235
267
|
}
|
|
236
268
|
}
|
|
237
269
|
|
|
270
|
+
/** Badge (🔒) for internal or private-use-only stories. */
|
|
238
271
|
export const internalBadge: TagBadgeParameter = {
|
|
239
272
|
tags: 'internal',
|
|
240
273
|
badge: {
|
|
@@ -247,9 +280,11 @@ export const internalBadge: TagBadgeParameter = {
|
|
|
247
280
|
}
|
|
248
281
|
}
|
|
249
282
|
|
|
283
|
+
/** Ordered list of all tag badge configs used by the addon (includes version badge). */
|
|
250
284
|
export const tagBadges: TagBadgeParameters = [
|
|
251
285
|
editorBadge,
|
|
252
286
|
sourceBadge,
|
|
287
|
+
typeBadge,
|
|
253
288
|
unitBadge,
|
|
254
289
|
integrationBadge,
|
|
255
290
|
keyboardBadge,
|
package/styles.css
CHANGED
|
@@ -3,19 +3,31 @@
|
|
|
3
3
|
@layer theme {
|
|
4
4
|
:root, :host {
|
|
5
5
|
--rbsb-color-red-100: oklch(93.6% 0.032 17.717);
|
|
6
|
+
--rbsb-color-red-300: oklch(80.8% 0.114 19.571);
|
|
6
7
|
--rbsb-color-red-500: oklch(63.7% 0.237 25.331);
|
|
8
|
+
--rbsb-color-red-700: oklch(50.5% 0.213 27.518);
|
|
7
9
|
--rbsb-color-red-800: oklch(44.4% 0.177 26.899);
|
|
8
10
|
--rbsb-color-red-900: oklch(39.6% 0.141 25.723);
|
|
9
11
|
--rbsb-color-amber-300: oklch(87.9% 0.169 91.605);
|
|
10
12
|
--rbsb-color-amber-900: oklch(41.4% 0.112 45.904);
|
|
11
13
|
--rbsb-color-yellow-100: oklch(97.3% 0.071 103.193);
|
|
14
|
+
--rbsb-color-yellow-300: oklch(90.5% 0.182 98.111);
|
|
12
15
|
--rbsb-color-yellow-500: oklch(79.5% 0.184 86.047);
|
|
16
|
+
--rbsb-color-yellow-700: oklch(55.4% 0.135 66.442);
|
|
13
17
|
--rbsb-color-yellow-900: oklch(42.1% 0.095 57.708);
|
|
18
|
+
--rbsb-color-green-100: oklch(96.2% 0.044 156.743);
|
|
14
19
|
--rbsb-color-green-200: oklch(92.5% 0.084 155.995);
|
|
20
|
+
--rbsb-color-green-300: oklch(87.1% 0.15 154.449);
|
|
15
21
|
--rbsb-color-green-500: oklch(72.3% 0.219 149.579);
|
|
22
|
+
--rbsb-color-green-700: oklch(52.7% 0.154 150.069);
|
|
16
23
|
--rbsb-color-green-800: oklch(44.8% 0.119 151.328);
|
|
24
|
+
--rbsb-color-green-900: oklch(39.3% 0.095 152.535);
|
|
25
|
+
--rbsb-color-emerald-200: oklch(90.5% 0.093 164.15);
|
|
26
|
+
--rbsb-color-emerald-800: oklch(43.2% 0.095 166.913);
|
|
17
27
|
--rbsb-color-sky-100: oklch(95.1% 0.026 236.824);
|
|
28
|
+
--rbsb-color-sky-300: oklch(82.8% 0.111 230.318);
|
|
18
29
|
--rbsb-color-sky-500: oklch(68.5% 0.169 237.323);
|
|
30
|
+
--rbsb-color-sky-700: oklch(50% 0.134 242.749);
|
|
19
31
|
--rbsb-color-sky-900: oklch(39.1% 0.09 240.876);
|
|
20
32
|
--rbsb-color-blue-200: oklch(88.2% 0.059 254.128);
|
|
21
33
|
--rbsb-color-blue-500: oklch(62.3% 0.214 259.815);
|
|
@@ -25,7 +37,9 @@
|
|
|
25
37
|
--rbsb-color-rose-400: oklch(71.2% 0.194 13.428);
|
|
26
38
|
--rbsb-color-rose-900: oklch(41% 0.159 10.272);
|
|
27
39
|
--rbsb-color-gray-100: oklch(96.7% 0.003 264.542);
|
|
40
|
+
--rbsb-color-gray-300: oklch(87.2% 0.01 258.338);
|
|
28
41
|
--rbsb-color-gray-500: oklch(55.1% 0.027 264.364);
|
|
42
|
+
--rbsb-color-gray-700: oklch(37.3% 0.034 259.733);
|
|
29
43
|
--rbsb-color-gray-900: oklch(21% 0.034 264.665);
|
|
30
44
|
--rbsb-color-black: #000;
|
|
31
45
|
--rbsb-color-white: #fff;
|
|
@@ -72,28 +86,51 @@
|
|
|
72
86
|
.rbsb\:rounded-lg {
|
|
73
87
|
border-radius: var(--rbsb-radius-lg);
|
|
74
88
|
}
|
|
89
|
+
.rbsb\:border {
|
|
90
|
+
border-style: var(--tw-border-style);
|
|
91
|
+
border-width: 1px;
|
|
92
|
+
}
|
|
75
93
|
.rbsb\:border-2 {
|
|
76
94
|
border-style: var(--tw-border-style);
|
|
77
95
|
border-width: 2px;
|
|
78
96
|
}
|
|
97
|
+
.rbsb\:border-solid {
|
|
98
|
+
--tw-border-style: solid;
|
|
99
|
+
border-style: solid;
|
|
100
|
+
}
|
|
79
101
|
.rbsb\:border-blue-500 {
|
|
80
102
|
border-color: var(--rbsb-color-blue-500);
|
|
81
103
|
}
|
|
104
|
+
.rbsb\:border-gray-300 {
|
|
105
|
+
border-color: var(--rbsb-color-gray-300);
|
|
106
|
+
}
|
|
82
107
|
.rbsb\:border-gray-500 {
|
|
83
108
|
border-color: var(--rbsb-color-gray-500);
|
|
84
109
|
}
|
|
110
|
+
.rbsb\:border-green-300 {
|
|
111
|
+
border-color: var(--rbsb-color-green-300);
|
|
112
|
+
}
|
|
85
113
|
.rbsb\:border-green-500 {
|
|
86
114
|
border-color: var(--rbsb-color-green-500);
|
|
87
115
|
}
|
|
88
116
|
.rbsb\:border-purple-500 {
|
|
89
117
|
border-color: var(--rbsb-color-purple-500);
|
|
90
118
|
}
|
|
119
|
+
.rbsb\:border-red-300 {
|
|
120
|
+
border-color: var(--rbsb-color-red-300);
|
|
121
|
+
}
|
|
91
122
|
.rbsb\:border-red-500 {
|
|
92
123
|
border-color: var(--rbsb-color-red-500);
|
|
93
124
|
}
|
|
125
|
+
.rbsb\:border-sky-300 {
|
|
126
|
+
border-color: var(--rbsb-color-sky-300);
|
|
127
|
+
}
|
|
94
128
|
.rbsb\:border-sky-500 {
|
|
95
129
|
border-color: var(--rbsb-color-sky-500);
|
|
96
130
|
}
|
|
131
|
+
.rbsb\:border-yellow-300 {
|
|
132
|
+
border-color: var(--rbsb-color-yellow-300);
|
|
133
|
+
}
|
|
97
134
|
.rbsb\:border-yellow-500 {
|
|
98
135
|
border-color: var(--rbsb-color-yellow-500);
|
|
99
136
|
}
|
|
@@ -106,9 +143,15 @@
|
|
|
106
143
|
.rbsb\:bg-blue-500 {
|
|
107
144
|
background-color: var(--rbsb-color-blue-500);
|
|
108
145
|
}
|
|
146
|
+
.rbsb\:bg-emerald-200 {
|
|
147
|
+
background-color: var(--rbsb-color-emerald-200);
|
|
148
|
+
}
|
|
109
149
|
.rbsb\:bg-gray-100 {
|
|
110
150
|
background-color: var(--rbsb-color-gray-100);
|
|
111
151
|
}
|
|
152
|
+
.rbsb\:bg-green-100 {
|
|
153
|
+
background-color: var(--rbsb-color-green-100);
|
|
154
|
+
}
|
|
112
155
|
.rbsb\:bg-green-200 {
|
|
113
156
|
background-color: var(--rbsb-color-green-200);
|
|
114
157
|
}
|
|
@@ -184,6 +227,31 @@
|
|
|
184
227
|
.rbsb\:ring-blue-200 {
|
|
185
228
|
--tw-ring-color: var(--rbsb-color-blue-200);
|
|
186
229
|
}
|
|
230
|
+
.rbsb\:dark\:border-gray-700 {
|
|
231
|
+
@media (prefers-color-scheme: dark) {
|
|
232
|
+
border-color: var(--rbsb-color-gray-700);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
.rbsb\:dark\:border-green-700 {
|
|
236
|
+
@media (prefers-color-scheme: dark) {
|
|
237
|
+
border-color: var(--rbsb-color-green-700);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
.rbsb\:dark\:border-red-700 {
|
|
241
|
+
@media (prefers-color-scheme: dark) {
|
|
242
|
+
border-color: var(--rbsb-color-red-700);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
.rbsb\:dark\:border-sky-700 {
|
|
246
|
+
@media (prefers-color-scheme: dark) {
|
|
247
|
+
border-color: var(--rbsb-color-sky-700);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
.rbsb\:dark\:border-yellow-700 {
|
|
251
|
+
@media (prefers-color-scheme: dark) {
|
|
252
|
+
border-color: var(--rbsb-color-yellow-700);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
187
255
|
.rbsb\:dark\:bg-amber-900 {
|
|
188
256
|
@media (prefers-color-scheme: dark) {
|
|
189
257
|
background-color: var(--rbsb-color-amber-900);
|
|
@@ -194,6 +262,11 @@
|
|
|
194
262
|
background-color: var(--rbsb-color-blue-900);
|
|
195
263
|
}
|
|
196
264
|
}
|
|
265
|
+
.rbsb\:dark\:bg-emerald-800 {
|
|
266
|
+
@media (prefers-color-scheme: dark) {
|
|
267
|
+
background-color: var(--rbsb-color-emerald-800);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
197
270
|
.rbsb\:dark\:bg-gray-500 {
|
|
198
271
|
@media (prefers-color-scheme: dark) {
|
|
199
272
|
background-color: var(--rbsb-color-gray-500);
|
|
@@ -209,6 +282,11 @@
|
|
|
209
282
|
background-color: var(--rbsb-color-green-800);
|
|
210
283
|
}
|
|
211
284
|
}
|
|
285
|
+
.rbsb\:dark\:bg-green-900 {
|
|
286
|
+
@media (prefers-color-scheme: dark) {
|
|
287
|
+
background-color: var(--rbsb-color-green-900);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
212
290
|
.rbsb\:dark\:bg-red-900 {
|
|
213
291
|
@media (prefers-color-scheme: dark) {
|
|
214
292
|
background-color: var(--rbsb-color-red-900);
|