@sit-onyx/storybook-utils 1.0.0-beta.6 → 1.0.0-beta.61
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/package.json +9 -6
- package/src/actions.spec.ts +29 -0
- package/src/actions.ts +70 -58
- package/src/events.ts +777 -0
- package/src/index.css +11 -0
- package/src/index.ts +1 -0
- package/src/preview.spec.ts +3 -9
- package/src/preview.ts +19 -9
- package/src/sbType.spec.ts +38 -0
- package/src/sbType.ts +104 -0
- package/src/theme.ts +1 -1
- package/src/types.ts +1 -49
- package/src/source-code-generator.spec.ts +0 -258
- package/src/source-code-generator.ts +0 -539
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sit-onyx/storybook-utils",
|
|
3
3
|
"description": "Storybook utilities for Vue",
|
|
4
|
-
"version": "1.0.0-beta.
|
|
4
|
+
"version": "1.0.0-beta.61",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "Schwarz IT KG",
|
|
7
7
|
"license": "Apache-2.0",
|
|
@@ -23,14 +23,17 @@
|
|
|
23
23
|
"url": "https://github.com/SchwarzIT/onyx/issues"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
|
-
"@storybook/vue3": ">= 8.
|
|
27
|
-
"storybook": ">= 8.
|
|
26
|
+
"@storybook/vue3": ">= 8.3.0",
|
|
27
|
+
"storybook": ">= 8.3.0",
|
|
28
28
|
"storybook-dark-mode": ">= 4",
|
|
29
|
-
"@sit-onyx/icons": "^1.0.0-beta.
|
|
30
|
-
"sit-onyx": "^1.0.0-beta.
|
|
29
|
+
"@sit-onyx/icons": "^1.0.0-beta.6",
|
|
30
|
+
"sit-onyx": "^1.0.0-beta.55"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"deepmerge-ts": "^7.
|
|
33
|
+
"deepmerge-ts": "^7.1.1"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"vue": "3.5.11"
|
|
34
37
|
},
|
|
35
38
|
"scripts": {
|
|
36
39
|
"build": "tsc --noEmit",
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { StoryContextForEnhancers } from "storybook/internal/types";
|
|
2
|
+
import { expect, test } from "vitest";
|
|
3
|
+
import { enhanceEventArgTypes } from "./actions";
|
|
4
|
+
|
|
5
|
+
test("should enhance event arg types", () => {
|
|
6
|
+
const argTypes = {
|
|
7
|
+
someProp: {
|
|
8
|
+
name: "someProp",
|
|
9
|
+
table: { category: "props" },
|
|
10
|
+
},
|
|
11
|
+
click: {
|
|
12
|
+
name: "click",
|
|
13
|
+
table: { category: "events" },
|
|
14
|
+
},
|
|
15
|
+
} satisfies StoryContextForEnhancers["argTypes"];
|
|
16
|
+
|
|
17
|
+
const result = enhanceEventArgTypes({
|
|
18
|
+
argTypes,
|
|
19
|
+
} as unknown as StoryContextForEnhancers);
|
|
20
|
+
|
|
21
|
+
expect(result).toStrictEqual({
|
|
22
|
+
...argTypes,
|
|
23
|
+
onClick: {
|
|
24
|
+
name: "onClick",
|
|
25
|
+
table: { disable: true },
|
|
26
|
+
action: "click",
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
});
|
package/src/actions.ts
CHANGED
|
@@ -1,85 +1,97 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import { deepmerge } from "deepmerge-ts";
|
|
1
|
+
import type { Decorator } from "@storybook/vue3";
|
|
3
2
|
import { useArgs } from "storybook/internal/preview-api";
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
3
|
+
import type { ArgTypes, ArgTypesEnhancer, StrictInputType } from "storybook/internal/types";
|
|
4
|
+
import { isReactive, reactive, watch, type Events } from "vue";
|
|
5
|
+
import { EVENT_DOC_MAP } from "./events";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
9
|
-
* the given events as well as implementing v-model handlers so that the Storybook controls are updated when you interact with the component.
|
|
10
|
-
* Should be preferred over manually defining argTypes for *.stories.ts files.
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* ```ts
|
|
14
|
-
* // Input.stories.ts
|
|
15
|
-
* import { defineStorybookActionsAndVModels } from '@sit-onyx/storybook-utils';
|
|
16
|
-
* import type { Meta } from '@storybook/vue3';
|
|
17
|
-
* import Input from './Input.vue';
|
|
18
|
-
*
|
|
19
|
-
* const meta: Meta<typeof Input> = {
|
|
20
|
-
* title: 'components/Input',
|
|
21
|
-
* ...defineStorybookActionsAndVModels({
|
|
22
|
-
* component: Input,
|
|
23
|
-
* events: ['update:modelValue', 'change'],
|
|
24
|
-
* }),
|
|
25
|
-
* };
|
|
26
|
-
* ```
|
|
8
|
+
* Adds actions for all argTypes of the 'event' category, so that they are logged via the actions plugin.
|
|
27
9
|
*/
|
|
28
|
-
export const
|
|
29
|
-
|
|
30
|
-
)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
10
|
+
export const enhanceEventArgTypes: ArgTypesEnhancer = ({ argTypes }) => {
|
|
11
|
+
Object.values(argTypes)
|
|
12
|
+
.filter(({ table }) => table?.category === "events")
|
|
13
|
+
.forEach(({ name }) => {
|
|
14
|
+
const eventName = `on${capitalizeFirstLetter(name)}`;
|
|
15
|
+
if (eventName in argTypes) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
argTypes[eventName] = {
|
|
19
|
+
name: eventName,
|
|
20
|
+
table: { disable: true }, // do not add a second table entry for event name prefixed with "on"
|
|
21
|
+
action: name,
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
return argTypes;
|
|
40
25
|
};
|
|
41
26
|
|
|
42
27
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* with "on", e.g. "onClick".
|
|
28
|
+
* Allows logging and documentation for the passed event listener names in Storybook.
|
|
29
|
+
* Will be documented in a extra "Relevant HTML events" section in the Storybook documentation.
|
|
46
30
|
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* const meta: Meta<typeof OnyxButton> = {
|
|
34
|
+
* title: "Buttons/Button",
|
|
35
|
+
* component: OnyxButton,
|
|
36
|
+
* argTypes: {
|
|
37
|
+
* somethingElse: { ...someOtherArgType },
|
|
38
|
+
* ...withNativeEventLogging(["onClick"]),
|
|
39
|
+
* },
|
|
40
|
+
*};
|
|
41
|
+
* ```
|
|
52
42
|
*
|
|
53
|
-
* @
|
|
43
|
+
* @param relevantEvents a list of event names that should be logged
|
|
44
|
+
* @returns Storybook ArgTypes object
|
|
54
45
|
*/
|
|
55
|
-
export const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
46
|
+
export const withNativeEventLogging = (relevantEvents: (keyof Events)[]) =>
|
|
47
|
+
relevantEvents.reduce((argTypes, eventName) => {
|
|
48
|
+
const { constructor, event } = EVENT_DOC_MAP[eventName];
|
|
49
|
+
argTypes[eventName] = {
|
|
50
|
+
name: event.name,
|
|
51
|
+
control: false,
|
|
52
|
+
description: `The native HTML [${event.name}](${event.url}) event which dispatches an [${constructor.name}](${constructor.url}).`,
|
|
53
|
+
table: {
|
|
54
|
+
category: "Relevant HTML events",
|
|
55
|
+
type: { summary: constructor.name },
|
|
56
|
+
},
|
|
57
|
+
action: event.name,
|
|
60
58
|
};
|
|
61
|
-
|
|
62
|
-
argTypes[eventName] = { control: false };
|
|
63
59
|
return argTypes;
|
|
64
|
-
}, {});
|
|
60
|
+
}, {} as ArgTypes);
|
|
61
|
+
|
|
62
|
+
export type WithVModelDecoratorOptions = {
|
|
63
|
+
/**
|
|
64
|
+
* The matcher for the v-model events.
|
|
65
|
+
* @default /^update:/
|
|
66
|
+
*/
|
|
67
|
+
filter: (argType: StrictInputType) => boolean;
|
|
65
68
|
};
|
|
66
69
|
|
|
67
70
|
/**
|
|
68
|
-
* Defines a custom decorator that will implement event handlers for all v-models
|
|
69
|
-
* so that the Storybook controls are updated live when the user interacts with the component
|
|
71
|
+
* Defines a custom decorator that will implement event handlers for all v-models,
|
|
72
|
+
* so that the Storybook controls are updated live when the user interacts with the component.
|
|
73
|
+
* This ensures that the story and component props stay in sync.
|
|
70
74
|
*
|
|
71
75
|
* @example
|
|
72
76
|
* ```ts
|
|
73
|
-
*
|
|
77
|
+
* // .storybook/preview.ts
|
|
74
78
|
*
|
|
75
79
|
* {
|
|
76
|
-
* decorators: [withVModelDecorator
|
|
80
|
+
* decorators: [withVModelDecorator()]
|
|
77
81
|
* }
|
|
78
82
|
* ```
|
|
79
83
|
*/
|
|
80
|
-
|
|
84
|
+
|
|
85
|
+
export const withVModelDecorator = (options?: WithVModelDecoratorOptions): Decorator => {
|
|
81
86
|
return (story, ctx) => {
|
|
82
|
-
const
|
|
87
|
+
const vModelFilter =
|
|
88
|
+
options?.filter ||
|
|
89
|
+
(({ table, name }) => table?.category === "events" && name.startsWith("update:"));
|
|
90
|
+
|
|
91
|
+
const vModelEvents = Object.values(ctx.argTypes)
|
|
92
|
+
.filter(vModelFilter)
|
|
93
|
+
.map(({ name }) => name);
|
|
94
|
+
|
|
83
95
|
if (!vModelEvents.length) return story();
|
|
84
96
|
|
|
85
97
|
const [args, updateArgs] = useArgs();
|