@stencil/storybook-plugin 0.6.1 → 1.0.0-dev.1783525808.72954f8
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/README.md +42 -138
- package/dist/docs/{index.d.ts → index.d.mts} +2 -4
- package/dist/docs/index.d.mts.map +1 -0
- package/dist/{docs-DFb4MYCm.js → docs/index.mjs} +17 -30
- package/dist/docs/index.mjs.map +1 -0
- package/dist/{entry-preview-C1JSJAGq.js → entry-preview-6xYusSlJ.mjs} +19 -22
- package/dist/entry-preview-6xYusSlJ.mjs.map +1 -0
- package/dist/entry-preview-argtypes.d.mts +14 -0
- package/dist/entry-preview-argtypes.d.mts.map +1 -0
- package/dist/entry-preview-argtypes.mjs +165 -0
- package/dist/entry-preview-argtypes.mjs.map +1 -0
- package/dist/entry-preview-auto-docs.d.mts +1 -0
- package/dist/entry-preview-auto-docs.mjs +11 -0
- package/dist/entry-preview-auto-docs.mjs.map +1 -0
- package/dist/{entry-preview-docs.d.ts → entry-preview-docs.d.mts} +2 -4
- package/dist/entry-preview-docs.d.mts.map +1 -0
- package/dist/{entry-preview-docs.js → entry-preview-docs.mjs} +3 -4
- package/dist/entry-preview-docs.mjs.map +1 -0
- package/dist/{entry-preview.d.ts → entry-preview.d.mts} +2 -5
- package/dist/entry-preview.d.mts.map +1 -0
- package/dist/entry-preview.mjs +2 -0
- package/dist/framework-api-oAIB4EMV.mjs +27 -0
- package/dist/framework-api-oAIB4EMV.mjs.map +1 -0
- package/dist/index.d.mts +677 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +32 -0
- package/dist/index.mjs.map +1 -0
- package/dist/node/{index.d.ts → index.d.mts} +2 -4
- package/dist/node/index.d.mts.map +1 -0
- package/dist/node/{index.js → index.mjs} +2 -2
- package/dist/node/index.mjs.map +1 -0
- package/dist/{preset.d.ts → preset.d.mts} +2 -4
- package/dist/preset.d.mts.map +1 -0
- package/dist/preset.mjs +35 -0
- package/dist/preset.mjs.map +1 -0
- package/dist/{rollup-parseAst-t-4tfMPG.d.ts → rollup-parseAst-DL0ij9mb.d.mts} +1 -1
- package/dist/rollup-parseAst-DL0ij9mb.d.mts.map +1 -0
- package/dist/{types-BZP9npQ9.d.cts → types-KTmT9_JX.d.mts} +2 -2
- package/dist/types-KTmT9_JX.d.mts.map +1 -0
- package/dist/wizard.d.mts +7 -0
- package/dist/wizard.d.mts.map +1 -0
- package/dist/wizard.mjs +159 -0
- package/dist/wizard.mjs.map +1 -0
- package/package.json +33 -33
- package/preset.js +1 -2
- package/dist/chunk-CsX-DzYB.cjs +0 -42
- package/dist/docs/index.cjs +0 -4
- package/dist/docs/index.d.cts +0 -15
- package/dist/docs/index.d.cts.map +0 -1
- package/dist/docs/index.d.ts.map +0 -1
- package/dist/docs/index.js +0 -3
- package/dist/docs-DFb4MYCm.js.map +0 -1
- package/dist/docs-ONVKsKI9.cjs +0 -97
- package/dist/docs-ONVKsKI9.cjs.map +0 -1
- package/dist/entry-preview-C0ipNwpw.cjs +0 -85
- package/dist/entry-preview-C0ipNwpw.cjs.map +0 -1
- package/dist/entry-preview-C1JSJAGq.js.map +0 -1
- package/dist/entry-preview-argtypes.cjs +0 -182
- package/dist/entry-preview-argtypes.cjs.map +0 -1
- package/dist/entry-preview-argtypes.d.cts +0 -19
- package/dist/entry-preview-argtypes.d.cts.map +0 -1
- package/dist/entry-preview-argtypes.d.ts +0 -19
- package/dist/entry-preview-argtypes.d.ts.map +0 -1
- package/dist/entry-preview-argtypes.js +0 -181
- package/dist/entry-preview-argtypes.js.map +0 -1
- package/dist/entry-preview-docs.cjs +0 -19
- package/dist/entry-preview-docs.cjs.map +0 -1
- package/dist/entry-preview-docs.d.cts +0 -11
- package/dist/entry-preview-docs.d.cts.map +0 -1
- package/dist/entry-preview-docs.d.ts.map +0 -1
- package/dist/entry-preview-docs.js.map +0 -1
- package/dist/entry-preview.cjs +0 -6
- package/dist/entry-preview.d.cts +0 -20
- package/dist/entry-preview.d.cts.map +0 -1
- package/dist/entry-preview.d.ts.map +0 -1
- package/dist/entry-preview.js +0 -3
- package/dist/index.cjs +0 -9
- package/dist/index.d.cts +0 -65
- package/dist/index.d.cts.map +0 -1
- package/dist/index.d.ts +0 -40
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -5
- package/dist/node/index.cjs +0 -9
- package/dist/node/index.cjs.map +0 -1
- package/dist/node/index.d.cts +0 -9
- package/dist/node/index.d.cts.map +0 -1
- package/dist/node/index.d.ts.map +0 -1
- package/dist/node/index.js.map +0 -1
- package/dist/preset.cjs +0 -35
- package/dist/preset.cjs.map +0 -1
- package/dist/preset.d.cts +0 -11
- package/dist/preset.d.cts.map +0 -1
- package/dist/preset.d.ts.map +0 -1
- package/dist/preset.js +0 -32
- package/dist/preset.js.map +0 -1
- package/dist/rollup-parseAst-t-4tfMPG.d.ts.map +0 -1
- package/dist/src-BBcTbcCa.js +0 -55
- package/dist/src-BBcTbcCa.js.map +0 -1
- package/dist/src-D0dJRYm2.cjs +0 -91
- package/dist/src-D0dJRYm2.cjs.map +0 -1
- package/dist/types-BZP9npQ9.d.cts.map +0 -1
- package/dist/types-DqHtEV5w.d.ts +0 -71
- package/dist/types-DqHtEV5w.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,175 +1,109 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @stencil/storybook-plugin
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Storybook framework plugin for StencilJS. Provides a zero-config integration with full HMR, automatic argTypes from component metadata, and controls out of the box.
|
|
4
4
|
|
|
5
5
|
## Setup
|
|
6
6
|
|
|
7
|
-
In
|
|
7
|
+
In your Stencil project, install Storybook and the plugin:
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
|
-
|
|
10
|
+
npm install --save-dev storybook @stencil/storybook-plugin
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
```sh
|
|
16
|
-
npm i --save-dev @stencil/storybook-plugin
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Last, update the `.storybook/main.ts` file as following:
|
|
13
|
+
Configure `.storybook/main.ts`:
|
|
20
14
|
|
|
21
15
|
```ts
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"@storybook/addon-interactions",
|
|
28
|
-
],
|
|
16
|
+
import type { StorybookConfig } from '@stencil/storybook-plugin';
|
|
17
|
+
|
|
18
|
+
const config: StorybookConfig = {
|
|
19
|
+
stories: ['../src/**/*.stories.@(ts|tsx)'],
|
|
20
|
+
addons: ['@storybook/addon-essentials'],
|
|
29
21
|
framework: {
|
|
30
|
-
name:
|
|
31
|
-
}
|
|
22
|
+
name: '@stencil/storybook-plugin',
|
|
23
|
+
},
|
|
32
24
|
};
|
|
33
25
|
|
|
34
26
|
export default config;
|
|
35
27
|
```
|
|
36
28
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
```tsx
|
|
44
|
-
import { setCustomElementsManifest } from '@stencil/storybook-plugin';
|
|
45
|
-
import customElements from '../dist/custom-elements.json';
|
|
46
|
-
|
|
47
|
-
setCustomElementsManifest(customElements);
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
This will automatically populate:
|
|
51
|
-
- Component props documentation
|
|
52
|
-
- ArgTypes with proper controls
|
|
53
|
-
- Events documentation
|
|
54
|
-
- Slots documentation
|
|
55
|
-
- CSS custom properties
|
|
29
|
+
That's it. The plugin automatically:
|
|
30
|
+
- Transpiles Stencil components on the fly via `@stencil/unplugin`
|
|
31
|
+
- Generates a Custom Elements Manifest from your component decorators
|
|
32
|
+
- Populates argTypes (props, events, slots, CSS parts/properties) in the docs panel
|
|
33
|
+
- Enables HMR for component changes
|
|
56
34
|
|
|
57
|
-
##
|
|
35
|
+
## Writing Stories
|
|
58
36
|
|
|
59
|
-
|
|
37
|
+
Import your component class directly — no separate registration step needed:
|
|
60
38
|
|
|
61
39
|
```tsx
|
|
62
40
|
import type { Meta, StoryObj } from '@stencil/storybook-plugin';
|
|
63
|
-
import { h } from '@stencil/core';
|
|
64
|
-
|
|
65
41
|
import { MyComponent } from './my-component';
|
|
66
42
|
|
|
67
|
-
const meta = {
|
|
43
|
+
const meta: Meta<MyComponent> = {
|
|
68
44
|
title: 'MyComponent',
|
|
69
45
|
component: MyComponent,
|
|
70
|
-
parameters: {
|
|
71
|
-
|
|
72
|
-
},
|
|
73
|
-
argTypes: {
|
|
74
|
-
first: { control: 'text' },
|
|
75
|
-
last: { control: 'text' },
|
|
76
|
-
middle: { control: 'text' },
|
|
77
|
-
},
|
|
78
|
-
args: { first: 'John', last: 'Doe', middle: 'Michael' },
|
|
79
|
-
} satisfies Meta<MyComponent>;
|
|
46
|
+
parameters: { layout: 'centered' },
|
|
47
|
+
};
|
|
80
48
|
|
|
81
49
|
export default meta;
|
|
82
50
|
type Story = StoryObj<MyComponent>;
|
|
83
51
|
|
|
84
52
|
export const Primary: Story = {
|
|
85
|
-
args: {
|
|
86
|
-
first: 'John',
|
|
87
|
-
last: 'Doe',
|
|
88
|
-
middle: 'Michael',
|
|
89
|
-
},
|
|
90
|
-
render: (props) => {
|
|
91
|
-
return <my-component {...props} />;
|
|
92
|
-
}
|
|
53
|
+
args: { first: 'John', last: 'Doe' },
|
|
93
54
|
};
|
|
94
55
|
```
|
|
95
56
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
```tsx
|
|
99
|
-
import type { Meta, StoryObj } from '@stencil/storybook-plugin';
|
|
100
|
-
import { h } from '@stencil/core';
|
|
57
|
+
### Slots
|
|
101
58
|
|
|
102
|
-
|
|
59
|
+
Pass slot content via `parameters.slots`:
|
|
103
60
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
component: MySlotted,
|
|
107
|
-
parameters: {
|
|
108
|
-
layout: 'centered',
|
|
109
|
-
},
|
|
110
|
-
} satisfies Meta<MySlotted>;
|
|
111
|
-
|
|
112
|
-
export default meta;
|
|
113
|
-
type Story = StoryObj<MySlotted>;
|
|
114
|
-
|
|
115
|
-
export const Primary: Story = {
|
|
116
|
-
args: {},
|
|
61
|
+
```tsx
|
|
62
|
+
export const WithSlot: Story = {
|
|
117
63
|
parameters: {
|
|
118
64
|
slots: {
|
|
119
65
|
default: 'Hello World',
|
|
120
|
-
|
|
66
|
+
footer: <span>Footer content</span>,
|
|
121
67
|
},
|
|
122
|
-
}
|
|
68
|
+
},
|
|
123
69
|
};
|
|
124
70
|
```
|
|
125
71
|
|
|
126
|
-
##
|
|
72
|
+
## Autodocs
|
|
73
|
+
|
|
74
|
+
The docs panel is populated automatically from your `@Component`, `@Prop`, `@Event`, `@Method`, and `@Slot` decorators — including JSDoc comments and tags such as `@since`, `@see`, and `@deprecated`.
|
|
127
75
|
|
|
128
|
-
|
|
76
|
+
No manual CEM setup required.
|
|
129
77
|
|
|
130
|
-
|
|
78
|
+
## Source Code Display
|
|
131
79
|
|
|
132
|
-
|
|
80
|
+
Control the source snippet language via story parameters:
|
|
133
81
|
|
|
134
82
|
```tsx
|
|
135
83
|
export default {
|
|
136
84
|
parameters: {
|
|
137
85
|
docs: {
|
|
138
|
-
source: {
|
|
139
|
-
language: 'html', // or 'jsx', 'tsx'
|
|
140
|
-
},
|
|
86
|
+
source: { language: 'html' }, // 'html' | 'jsx' | 'tsx'
|
|
141
87
|
},
|
|
142
88
|
},
|
|
143
89
|
} satisfies Meta<MyComponent>;
|
|
144
90
|
```
|
|
145
91
|
|
|
146
|
-
**HTML
|
|
92
|
+
**HTML** (default):
|
|
147
93
|
```html
|
|
148
|
-
<my-component
|
|
94
|
+
<my-component first="John"></my-component>
|
|
149
95
|
```
|
|
150
96
|
|
|
151
|
-
**JSX/TSX
|
|
152
|
-
```jsx
|
|
153
|
-
<MyComponent className="example" first="John" />
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
When using `jsx` or `tsx`:
|
|
157
|
-
- Custom elements (with hyphens) are converted to PascalCase: `<my-component>` → `<MyComponent>`
|
|
158
|
-
- Standard HTML elements remain lowercase: `<div>`, `<span>`
|
|
159
|
-
- HTML attributes are converted to JSX equivalents: `class` → `className`, `for` → `htmlFor`, `tabindex` → `tabIndex`
|
|
160
|
-
- Long attribute lists automatically wrap to multiple lines (80 character threshold)
|
|
161
|
-
|
|
162
|
-
### Global Source Format Control
|
|
97
|
+
**JSX/TSX**: custom element tag names are converted to PascalCase, HTML attributes to their JSX equivalents (`class` → `className`, etc.), and long attribute lists are wrapped automatically.
|
|
163
98
|
|
|
164
|
-
|
|
99
|
+
### Global source format toolbar
|
|
165
100
|
|
|
166
|
-
```
|
|
167
|
-
// .storybook/preview.
|
|
101
|
+
```ts
|
|
102
|
+
// .storybook/preview.ts
|
|
168
103
|
export const globalTypes = {
|
|
169
104
|
source: {
|
|
170
105
|
name: 'Source Format',
|
|
171
106
|
defaultValue: 'html',
|
|
172
|
-
description: 'Select the source format',
|
|
173
107
|
toolbar: {
|
|
174
108
|
items: ['html', 'jsx', 'tsx'],
|
|
175
109
|
icon: 'markup',
|
|
@@ -178,34 +112,4 @@ export const globalTypes = {
|
|
|
178
112
|
},
|
|
179
113
|
},
|
|
180
114
|
};
|
|
181
|
-
|
|
182
|
-
export const decorators = [
|
|
183
|
-
(story, context) => {
|
|
184
|
-
const sourceLanguage = context.globals.source || 'html';
|
|
185
|
-
context.parameters.docs = context.parameters.docs || {};
|
|
186
|
-
context.parameters.docs.source = context.parameters.docs.source || {};
|
|
187
|
-
context.parameters.docs.source.language = sourceLanguage;
|
|
188
|
-
return story();
|
|
189
|
-
},
|
|
190
|
-
];
|
|
191
115
|
```
|
|
192
|
-
|
|
193
|
-
This adds a "Source Format" dropdown to the Storybook toolbar, allowing you to switch between HTML and JSX/TSX display on the fly.
|
|
194
|
-
|
|
195
|
-
### Troubleshooting
|
|
196
|
-
|
|
197
|
-
If you encounter any issues with the story rendering, please check the following:
|
|
198
|
-
|
|
199
|
-
- If your `customElementsExportBehavior` is set to a value that lazy loads components, ensure that you are using `defineCustomElements()` in `preview.ts`. You should also define your component as a string in your story file: `component: 'my-component'` as it does not yet exist in the custom element registry.
|
|
200
|
-
- If your `customElementsExportBehavior` is set to a value like `auto-define-custom-elements` or `default`, do not include `defineCustomElements()` in `preview.ts` and use the constructor as the component value in your story file: `component: MyComponent`.
|
|
201
|
-
- Check the console for any error messages.
|
|
202
|
-
|
|
203
|
-
## Limitations
|
|
204
|
-
|
|
205
|
-
This is early development and we are still seeing some limitations we want to see fixed:
|
|
206
|
-
|
|
207
|
-
- Story is completely reloaded when component is changed (no hot module replacement)
|
|
208
|
-
- There is no automation yet for easily scaffolding storybook in a Stencil project.
|
|
209
|
-
- Stories are run in dev mode - no SSR, or serialization happens
|
|
210
|
-
|
|
211
|
-
Please get involved and support the project with code contributions. Thanks!
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StencilRenderer } from "../types-
|
|
1
|
+
import { a as StencilRenderer } from "../types-KTmT9_JX.mjs";
|
|
2
2
|
import { VNode } from "@stencil/core";
|
|
3
3
|
import { DecoratorFunction } from "storybook/internal/types";
|
|
4
4
|
|
|
@@ -8,8 +8,6 @@ declare const renderVNode: (vnode: VNode, mode: RenderMode) => string;
|
|
|
8
8
|
//#endregion
|
|
9
9
|
//#region src/docs/source-decorator.d.ts
|
|
10
10
|
declare const sourceDecorator: DecoratorFunction<StencilRenderer<unknown>>;
|
|
11
|
-
//# sourceMappingURL=source-decorator.d.ts.map
|
|
12
|
-
|
|
13
11
|
//#endregion
|
|
14
12
|
export { renderVNode, sourceDecorator };
|
|
15
|
-
//# sourceMappingURL=index.d.
|
|
13
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/docs/render-vnode.ts","../../src/docs/source-decorator.ts"],"mappings":";;;;;KAEK,UAAA;AAAA,cAiHQ,WAAA,GAAe,KAAA,EAAO,KAAA,EAAO,IAAA,EAAM,UAAU;;;cClG7C,eAAA,EAAiB,iBAAiB,CAAC,eAAA"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { SourceType } from "storybook/internal/docs-tools";
|
|
2
2
|
import { emitTransformCode, useEffect } from "storybook/internal/preview-api";
|
|
3
|
-
|
|
4
3
|
//#region src/docs/render-vnode.ts
|
|
5
4
|
function kebabToPascal(str) {
|
|
6
5
|
return str.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
|
|
@@ -14,14 +13,11 @@ function vnodeToString(node, options, indentLevel = 0) {
|
|
|
14
13
|
const tag = mode === "jsx" && typeof node.$tag$ === "string" && node.$tag$.includes("-") ? kebabToPascal(node.$tag$) : String(node.$tag$);
|
|
15
14
|
const attrArray = node.$attrs$ ? Object.entries(node.$attrs$).filter(([_, value]) => value !== void 0).map(([key, value]) => {
|
|
16
15
|
let attrName = key;
|
|
17
|
-
if (mode === "jsx") {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
};
|
|
23
|
-
attrName = htmlToJsx[key] || key;
|
|
24
|
-
}
|
|
16
|
+
if (mode === "jsx") attrName = {
|
|
17
|
+
class: "className",
|
|
18
|
+
for: "htmlFor",
|
|
19
|
+
tabindex: "tabIndex"
|
|
20
|
+
}[key] || key;
|
|
25
21
|
if (typeof value === "function") return "";
|
|
26
22
|
if (typeof value === "boolean") return value ? attrName : "";
|
|
27
23
|
if (typeof value === "string") return `${attrName}="${value}"`;
|
|
@@ -30,28 +26,21 @@ function vnodeToString(node, options, indentLevel = 0) {
|
|
|
30
26
|
}).filter((attr) => attr.trim()) : [];
|
|
31
27
|
const children = node.$children$ ?? [];
|
|
32
28
|
if (children.length === 0) {
|
|
33
|
-
const attrsStr
|
|
34
|
-
const singleLine = mode === "jsx" ? `${indent}<${tag}${attrsStr
|
|
29
|
+
const attrsStr = attrArray.length > 0 ? " " + attrArray.join(" ") : "";
|
|
30
|
+
const singleLine = mode === "jsx" ? `${indent}<${tag}${attrsStr} />` : `${indent}<${tag}${attrsStr}></${tag}>`;
|
|
35
31
|
if (singleLine.length <= LINE_WIDTH) return singleLine;
|
|
36
|
-
const attrIndent
|
|
37
|
-
const formattedAttrs
|
|
38
|
-
return mode === "jsx" ? `${indent}<${tag}${formattedAttrs
|
|
39
|
-
}
|
|
40
|
-
const attrsStr = attrArray.length > 0 ? " " + attrArray.join(" ") : "";
|
|
41
|
-
const openingTag = `${indent}<${tag}${attrsStr}>`;
|
|
42
|
-
if (openingTag.length <= LINE_WIDTH) {
|
|
43
|
-
const childrenString$1 = children.map((child) => vnodeToString(child, options, indentLevel + 1)).join("\n");
|
|
44
|
-
return `${openingTag}\n${childrenString$1}\n${indent}</${tag}>`;
|
|
32
|
+
const attrIndent = indent + " ";
|
|
33
|
+
const formattedAttrs = attrArray.length > 0 ? "\n" + attrArray.map((attr) => `${attrIndent}${attr}`).join("\n") + "\n" + indent : "";
|
|
34
|
+
return mode === "jsx" ? `${indent}<${tag}${formattedAttrs}/>` : `${indent}<${tag}${formattedAttrs}></${tag}>`;
|
|
45
35
|
}
|
|
36
|
+
const openingTag = `${indent}<${tag}${attrArray.length > 0 ? " " + attrArray.join(" ") : ""}>`;
|
|
37
|
+
if (openingTag.length <= LINE_WIDTH) return `${openingTag}\n${children.map((child) => vnodeToString(child, options, indentLevel + 1)).join("\n")}\n${indent}</${tag}>`;
|
|
46
38
|
const attrIndent = indent + " ";
|
|
47
|
-
|
|
48
|
-
const childrenString = children.map((child) => vnodeToString(child, options, indentLevel + 1)).join("\n");
|
|
49
|
-
return `${indent}<${tag}${formattedAttrs}>\n${childrenString}\n${indent}</${tag}>`;
|
|
39
|
+
return `${indent}<${tag}${attrArray.length > 0 ? "\n" + attrArray.map((attr) => `${attrIndent}${attr}`).join("\n") + "\n" + indent : ""}>\n${children.map((child) => vnodeToString(child, options, indentLevel + 1)).join("\n")}\n${indent}</${tag}>`;
|
|
50
40
|
}
|
|
51
41
|
const renderVNode = (vnode, mode) => {
|
|
52
42
|
return vnodeToString(vnode, { mode });
|
|
53
43
|
};
|
|
54
|
-
|
|
55
44
|
//#endregion
|
|
56
45
|
//#region src/docs/source-decorator.ts
|
|
57
46
|
const skip = (context) => {
|
|
@@ -66,20 +55,18 @@ const sourceDecorator = (storyFn, context) => {
|
|
|
66
55
|
const renderedForSource = context?.parameters.docs?.source?.excludeDecorators ? context.originalStoryFn(context.args, context) : story;
|
|
67
56
|
if (skip(context)) return;
|
|
68
57
|
switch (context.parameters.docs.source.language) {
|
|
69
|
-
case "html":
|
|
58
|
+
case "html":
|
|
70
59
|
emitTransformCode(renderVNode(renderedForSource, "html"), context);
|
|
71
60
|
break;
|
|
72
|
-
}
|
|
73
61
|
case "jsx":
|
|
74
|
-
case "tsx":
|
|
62
|
+
case "tsx":
|
|
75
63
|
emitTransformCode(renderVNode(renderedForSource, "jsx"), context);
|
|
76
64
|
break;
|
|
77
|
-
}
|
|
78
65
|
}
|
|
79
66
|
});
|
|
80
67
|
return story;
|
|
81
68
|
};
|
|
82
|
-
|
|
83
69
|
//#endregion
|
|
84
70
|
export { renderVNode, sourceDecorator };
|
|
85
|
-
|
|
71
|
+
|
|
72
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/docs/render-vnode.ts","../../src/docs/source-decorator.ts"],"sourcesContent":["import { type VNode } from '@stencil/core';\n\ntype RenderMode = 'html' | 'jsx';\n\ninterface RenderOptions {\n mode: RenderMode;\n}\n\nfunction kebabToPascal(str: string): string {\n return str\n .split('-')\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join('');\n}\n\nfunction vnodeToString(node: VNode, options: RenderOptions, indentLevel = 0): string {\n const LINE_WIDTH = 80;\n const indent = ' '.repeat(indentLevel);\n const { mode } = options;\n\n if (node.$text$ !== null) {\n return indent + node.$text$;\n }\n\n if (node.$tag$ === null) {\n return '';\n }\n\n // Convert tag name based on mode\n // Only convert to PascalCase if it's a custom element (has a dash)\n const tag =\n mode === 'jsx' && typeof node.$tag$ === 'string' && node.$tag$.includes('-')\n ? kebabToPascal(node.$tag$)\n : String(node.$tag$);\n\n // Process attributes as array (without leading spaces)\n const attrArray = node.$attrs$\n ? Object.entries(node.$attrs$)\n .filter(([_, value]) => value !== undefined)\n .map(([key, value]) => {\n // Convert HTML attributes to JSX equivalents\n let attrName = key;\n if (mode === 'jsx') {\n // Common HTML to JSX attribute conversions\n const htmlToJsx: Record<string, string> = {\n class: 'className',\n for: 'htmlFor',\n tabindex: 'tabIndex',\n };\n attrName = htmlToJsx[key] || key;\n }\n\n if (typeof value === 'function') {\n // Hide event handlers from source code\n return '';\n }\n\n if (typeof value === 'boolean') {\n return value ? attrName : '';\n }\n\n if (typeof value === 'string') {\n return `${attrName}=\"${value}\"`;\n }\n\n // For JSX, use curly braces for non-string values\n if (mode === 'jsx') {\n return `${attrName}={${JSON.stringify(value)}}`;\n }\n\n // For HTML, convert to string\n return `${attrName}=\"${value}\"`;\n })\n .filter((attr) => attr.trim())\n : [];\n\n const children = node.$children$ ?? [];\n\n // Self-closing tags for JSX when no children\n if (children.length === 0) {\n const attrsStr = attrArray.length > 0 ? ' ' + attrArray.join(' ') : '';\n const singleLine = mode === 'jsx' ? `${indent}<${tag}${attrsStr} />` : `${indent}<${tag}${attrsStr}></${tag}>`;\n\n // If single line fits within LINE_WIDTH, use it\n if (singleLine.length <= LINE_WIDTH) {\n return singleLine;\n }\n\n // Otherwise, break attributes to multiple lines\n const attrIndent = indent + ' ';\n const formattedAttrs =\n attrArray.length > 0 ? '\\n' + attrArray.map((attr) => `${attrIndent}${attr}`).join('\\n') + '\\n' + indent : '';\n\n return mode === 'jsx' ? `${indent}<${tag}${formattedAttrs}/>` : `${indent}<${tag}${formattedAttrs}></${tag}>`;\n }\n\n // Tags with children\n const attrsStr = attrArray.length > 0 ? ' ' + attrArray.join(' ') : '';\n const openingTag = `${indent}<${tag}${attrsStr}>`;\n\n // Check if opening tag fits on one line\n if (openingTag.length <= LINE_WIDTH) {\n const childrenString = children.map((child) => vnodeToString(child, options, indentLevel + 1)).join('\\n');\n return `${openingTag}\\n${childrenString}\\n${indent}</${tag}>`;\n }\n\n // Break opening tag to multiple lines\n const attrIndent = indent + ' ';\n const formattedAttrs =\n attrArray.length > 0 ? '\\n' + attrArray.map((attr) => `${attrIndent}${attr}`).join('\\n') + '\\n' + indent : '';\n const childrenString = children.map((child) => vnodeToString(child, options, indentLevel + 1)).join('\\n');\n\n return `${indent}<${tag}${formattedAttrs}>\\n${childrenString}\\n${indent}</${tag}>`;\n}\n\nexport const renderVNode = (vnode: VNode, mode: RenderMode) => {\n return vnodeToString(vnode, { mode });\n};\n","import { SourceType } from 'storybook/internal/docs-tools';\nimport { emitTransformCode, useEffect } from 'storybook/internal/preview-api';\nimport type { AnnotatedStoryFn, Args, DecoratorFunction } from 'storybook/internal/types';\nimport type { StencilRenderer } from '../types';\nimport { renderVNode } from './render-vnode';\n\ntype StoryFn<TArgs = Args> = AnnotatedStoryFn<StencilRenderer<unknown>, TArgs>;\n\nconst skip = (context: Parameters<DecoratorFunction<StencilRenderer<unknown>>>[1]) => {\n const sourceParams = context?.parameters.docs?.source;\n const isArgsStory = context?.parameters.__isArgsStory;\n\n if (sourceParams.type === SourceType.DYNAMIC) return false;\n\n return !isArgsStory || sourceParams?.code || sourceParams?.type === SourceType.CODE;\n};\n\nexport const sourceDecorator: DecoratorFunction<StencilRenderer<unknown>> = (storyFn, context) => {\n const story = storyFn();\n\n useEffect(() => {\n const renderedForSource = context?.parameters.docs?.source?.excludeDecorators\n ? (context.originalStoryFn as StoryFn)(context.args, context)\n : story;\n\n if (skip(context)) return;\n\n switch (context.parameters.docs.source.language) {\n case 'html': {\n emitTransformCode(renderVNode(renderedForSource, 'html'), context);\n break;\n }\n case 'jsx':\n case 'tsx': {\n emitTransformCode(renderVNode(renderedForSource, 'jsx'), context);\n break;\n }\n }\n });\n\n return story;\n};\n"],"mappings":"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"}
|
|
@@ -1,25 +1,28 @@
|
|
|
1
|
-
import { enhanceArgTypes } from "storybook/internal/docs-tools";
|
|
2
1
|
import { simulatePageLoad } from "storybook/preview-api";
|
|
2
|
+
import { enhanceArgTypes } from "storybook/internal/docs-tools";
|
|
3
3
|
import { h, render } from "@stencil/core";
|
|
4
|
-
|
|
5
|
-
//#region rolldown:runtime
|
|
4
|
+
//#region \0rolldown/runtime.js
|
|
6
5
|
var __defProp = Object.defineProperty;
|
|
7
|
-
var
|
|
6
|
+
var __exportAll = (all, no_symbols) => {
|
|
7
|
+
let target = {};
|
|
8
8
|
for (var name in all) __defProp(target, name, {
|
|
9
9
|
get: all[name],
|
|
10
10
|
enumerable: true
|
|
11
11
|
});
|
|
12
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
13
|
+
return target;
|
|
12
14
|
};
|
|
13
|
-
|
|
14
15
|
//#endregion
|
|
15
16
|
//#region src/render.ts
|
|
16
17
|
const render$1 = (args, context) => {
|
|
17
|
-
const { component, parameters
|
|
18
|
+
const { component, parameters } = context;
|
|
18
19
|
if (Array.isArray(component)) throw new Error("If your story does not contain a render function, you must provide a component property!");
|
|
19
|
-
if (typeof component === "string" && !customElements.get(component)) throw new Error(`Stencil component not
|
|
20
|
-
else if (typeof component !== "string" && !customElements.getName(component))
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
if (typeof component === "string" && !customElements.get(component)) throw new Error(`Stencil component <${component}> is not registered. Make sure it is imported in your story file or in preview.ts.`);
|
|
21
|
+
else if (typeof component !== "string" && !customElements.getName(component)) {
|
|
22
|
+
if (!component.is || !customElements.get(component.is)) throw new Error(`Stencil component is not registered. Make sure the component class is imported in your story file.`);
|
|
23
|
+
}
|
|
24
|
+
const cmpName = typeof component === "string" ? component : customElements.getName(component) ?? component.is;
|
|
25
|
+
const children = Object.entries(parameters.slots || []).map(([key, value]) => {
|
|
23
26
|
const slot = key === "default" ? void 0 : key;
|
|
24
27
|
const child = typeof value === "string" ? h(void 0, { slot }, value) : {
|
|
25
28
|
...value,
|
|
@@ -31,27 +34,21 @@ const render$1 = (args, context) => {
|
|
|
31
34
|
child.$tag$ = child.$tag$ || (slot ? "span" : null);
|
|
32
35
|
return child.$tag$ ? child : child.$children$;
|
|
33
36
|
});
|
|
34
|
-
|
|
35
|
-
return h(Component, { ...args }, children);
|
|
37
|
+
return h(`${cmpName}`, { ...args }, children);
|
|
36
38
|
};
|
|
37
39
|
function renderToCanvas({ storyFn, showMain, storyContext }, canvasElement) {
|
|
38
40
|
const vdom = storyFn();
|
|
39
41
|
showMain();
|
|
40
|
-
|
|
41
|
-
* If the component is not automatically registered after import, register it here
|
|
42
|
-
*/
|
|
43
|
-
if (storyContext.component && storyContext.component.is && !customElements.get(storyContext.component.is)) customElements.define(storyContext.component.is, storyContext.component);
|
|
42
|
+
if (storyContext.component?.is && !customElements.get(storyContext.component.is)) customElements.define(storyContext.component.is, storyContext.component);
|
|
44
43
|
if (canvasElement.firstChild) canvasElement.removeChild(canvasElement.firstChild);
|
|
45
44
|
const element = document.createElement("div");
|
|
46
45
|
canvasElement.appendChild(element);
|
|
47
46
|
render(vdom, element);
|
|
48
47
|
simulatePageLoad(element);
|
|
49
48
|
}
|
|
50
|
-
|
|
51
49
|
//#endregion
|
|
52
50
|
//#region src/entry-preview.ts
|
|
53
|
-
var entry_preview_exports = {
|
|
54
|
-
__export(entry_preview_exports, {
|
|
51
|
+
var entry_preview_exports = /* @__PURE__ */ __exportAll({
|
|
55
52
|
argTypesEnhancers: () => argTypesEnhancers,
|
|
56
53
|
parameters: () => parameters,
|
|
57
54
|
render: () => render$1,
|
|
@@ -59,7 +56,7 @@ __export(entry_preview_exports, {
|
|
|
59
56
|
});
|
|
60
57
|
const parameters = { renderer: "stencil" };
|
|
61
58
|
const argTypesEnhancers = [enhanceArgTypes];
|
|
62
|
-
|
|
63
59
|
//#endregion
|
|
64
|
-
export {
|
|
65
|
-
|
|
60
|
+
export { renderToCanvas as a, render$1 as i, entry_preview_exports as n, parameters as r, argTypesEnhancers as t };
|
|
61
|
+
|
|
62
|
+
//# sourceMappingURL=entry-preview-6xYusSlJ.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry-preview-6xYusSlJ.mjs","names":["render"],"sources":["../src/render.ts","../src/entry-preview.ts"],"sourcesContent":["import { h, render as renderStencil, VNode } from '@stencil/core';\nimport { ArgsStoryFn, RenderContext } from 'storybook/internal/types';\nimport { simulatePageLoad } from 'storybook/preview-api';\n\nimport type { StencilRenderer } from './types';\n\nexport const render: ArgsStoryFn<StencilRenderer<unknown>> = (args, context) => {\n const { component, parameters } = context;\n\n if (Array.isArray(component)) {\n throw new Error('If your story does not contain a render function, you must provide a component property!');\n }\n if (typeof component === 'string' && !customElements.get(component)) {\n throw new Error(\n `Stencil component <${component}> is not registered. Make sure it is imported in your story file or in preview.ts.`,\n );\n } else if (typeof component !== 'string' && !customElements.getName(component)) {\n // After HMR the module re-evaluates and produces a new class reference, so\n // getName returns null even though the tag is still registered under component.is.\n if (!(component as any).is || !customElements.get((component as any).is)) {\n throw new Error(\n `Stencil component is not registered. Make sure the component class is imported in your story file.`,\n );\n }\n }\n const cmpName =\n typeof component === 'string' ? component : (customElements.getName(component) ?? (component as any).is);\n\n const children: any[] = Object.entries<VNode>(parameters.slots || []).map(([key, value]) => {\n // if the parameter key is 'default' don't give it a slot name so it renders just as a child\n const slot = key === 'default' ? undefined : key;\n // if the value it s a string, create a vnode with the string as the children\n const child =\n typeof value === 'string'\n ? h(undefined, { slot }, value)\n : {\n ...value,\n $attrs$: {\n ...value.$attrs$,\n slot,\n },\n };\n // if the value is a fragment and it is a named slot, create a span element with the slot name\n child.$tag$ = child.$tag$ || (slot ? 'span' : null);\n return child.$tag$ ? child : child.$children$;\n });\n\n const Component = `${cmpName}`;\n return h(Component, { ...args }, children);\n};\n\nexport function renderToCanvas(\n { storyFn, showMain, storyContext }: RenderContext<StencilRenderer<unknown>>,\n canvasElement: StencilRenderer<unknown>['canvasElement'],\n) {\n const vdom = storyFn();\n showMain();\n\n if (storyContext.component?.is && !customElements.get(storyContext.component.is)) {\n customElements.define(storyContext.component.is, storyContext.component);\n }\n\n if (canvasElement.firstChild) {\n canvasElement.removeChild(canvasElement.firstChild);\n }\n\n const element = document.createElement('div');\n canvasElement.appendChild(element);\n renderStencil(vdom, element);\n simulatePageLoad(element);\n}\n","import { enhanceArgTypes } from 'storybook/internal/docs-tools';\nimport type { ArgTypesEnhancer, Parameters } from 'storybook/internal/types';\n\nexport const parameters: Parameters = { renderer: 'stencil' };\nexport { render, renderToCanvas } from './render';\nexport const argTypesEnhancers: ArgTypesEnhancer[] = [enhanceArgTypes];\n"],"mappings":";;;;;;;;;;;;;;;;AAMA,MAAaA,YAAiD,MAAM,YAAY;CAC9E,MAAM,EAAE,WAAW,eAAe;CAElC,IAAI,MAAM,QAAQ,SAAS,GACzB,MAAM,IAAI,MAAM,0FAA0F;CAE5G,IAAI,OAAO,cAAc,YAAY,CAAC,eAAe,IAAI,SAAS,GAChE,MAAM,IAAI,MACR,sBAAsB,UAAU,mFAClC;MACK,IAAI,OAAO,cAAc,YAAY,CAAC,eAAe,QAAQ,SAAS;MAGvE,CAAE,UAAkB,MAAM,CAAC,eAAe,IAAK,UAAkB,EAAE,GACrE,MAAM,IAAI,MACR,oGACF;CAAA;CAGJ,MAAM,UACJ,OAAO,cAAc,WAAW,YAAa,eAAe,QAAQ,SAAS,KAAM,UAAkB;CAEvG,MAAM,WAAkB,OAAO,QAAe,WAAW,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW;EAE1F,MAAM,OAAO,QAAQ,YAAY,KAAA,IAAY;EAE7C,MAAM,QACJ,OAAO,UAAU,WACb,EAAE,KAAA,GAAW,EAAE,KAAK,GAAG,KAAK,IAC5B;GACE,GAAG;GACH,SAAS;IACP,GAAG,MAAM;IACT;GACF;EACF;EAEN,MAAM,QAAQ,MAAM,UAAU,OAAO,SAAS;EAC9C,OAAO,MAAM,QAAQ,QAAQ,MAAM;CACrC,CAAC;CAGD,OAAO,EAAE,GADY,WACD,EAAE,GAAG,KAAK,GAAG,QAAQ;AAC3C;AAEA,SAAgB,eACd,EAAE,SAAS,UAAU,gBACrB,eACA;CACA,MAAM,OAAO,QAAQ;CACrB,SAAS;CAET,IAAI,aAAa,WAAW,MAAM,CAAC,eAAe,IAAI,aAAa,UAAU,EAAE,GAC7E,eAAe,OAAO,aAAa,UAAU,IAAI,aAAa,SAAS;CAGzE,IAAI,cAAc,YAChB,cAAc,YAAY,cAAc,UAAU;CAGpD,MAAM,UAAU,SAAS,cAAc,KAAK;CAC5C,cAAc,YAAY,OAAO;CACjC,OAAc,MAAM,OAAO;CAC3B,iBAAiB,OAAO;AAC1B;;;;;;;;;ACnEA,MAAa,aAAyB,EAAE,UAAU,UAAU;AAE5D,MAAa,oBAAwC,CAAC,eAAe"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { a as StencilRenderer } from "./types-KTmT9_JX.mjs";
|
|
2
|
+
import { ArgTypesEnhancer } from "storybook/internal/types";
|
|
3
|
+
|
|
4
|
+
//#region src/entry-preview-argtypes.d.ts
|
|
5
|
+
declare const parameters: {
|
|
6
|
+
docs: {
|
|
7
|
+
extractArgTypes: (component: any) => import("storybook/internal/csf").ArgTypes | null;
|
|
8
|
+
extractComponentDescription: (component: any) => string | undefined;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
declare const argTypesEnhancers: ArgTypesEnhancer<StencilRenderer<unknown>>[];
|
|
12
|
+
//#endregion
|
|
13
|
+
export { argTypesEnhancers, parameters };
|
|
14
|
+
//# sourceMappingURL=entry-preview-argtypes.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry-preview-argtypes.d.mts","names":[],"sources":["../src/entry-preview-argtypes.ts"],"mappings":";;;;cAMa,UAAA;;;;;;cAOA,iBAAA,EAAmB,gBAAgB,CAAC,eAAA"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { n as isValidComponent, r as isValidMetaData, t as getCustomElements } from "./framework-api-oAIB4EMV.mjs";
|
|
2
|
+
import "./index.mjs";
|
|
3
|
+
import { enhanceArgTypes } from "storybook/internal/docs-tools";
|
|
4
|
+
import { logger } from "storybook/internal/client-logger";
|
|
5
|
+
//#region src/docs/infer-type.ts
|
|
6
|
+
/** Extract string/number literal values from a union type string, e.g. `"'sm' | 'md' | 'lg'"`. */
|
|
7
|
+
const parseLiteralValues = (typeText) => {
|
|
8
|
+
const values = [];
|
|
9
|
+
for (const m of typeText.matchAll(/'([^']*)'|"([^"]*)"/g)) values.push(m[1] ?? m[2] ?? "");
|
|
10
|
+
if (values.length === 0) for (const m of typeText.matchAll(/(?<![.\w])-?\d+(?:\.\d+)?(?![.\w])/g)) values.push(m[0]);
|
|
11
|
+
return values.filter(Boolean);
|
|
12
|
+
};
|
|
13
|
+
const inferSBType = (field) => {
|
|
14
|
+
const typeText = field.type?.text ?? "";
|
|
15
|
+
if ([
|
|
16
|
+
"string",
|
|
17
|
+
"number",
|
|
18
|
+
"boolean",
|
|
19
|
+
"symbol"
|
|
20
|
+
].includes(typeText.toLowerCase())) return {
|
|
21
|
+
name: typeText.toLowerCase(),
|
|
22
|
+
raw: typeText
|
|
23
|
+
};
|
|
24
|
+
if (/^\(.*\)\s*=>\s*.*$/.test(typeText)) return {
|
|
25
|
+
name: "function",
|
|
26
|
+
raw: typeText
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
name: "other",
|
|
30
|
+
value: typeText,
|
|
31
|
+
raw: typeText
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
const inferControlType = (field) => {
|
|
35
|
+
const typeText = field.type?.text ?? "";
|
|
36
|
+
switch (typeText) {
|
|
37
|
+
case "string":
|
|
38
|
+
case "string | undefined": return { type: "text" };
|
|
39
|
+
case "number":
|
|
40
|
+
case "number | undefined": return { type: "number" };
|
|
41
|
+
case "boolean":
|
|
42
|
+
case "boolean | undefined": return { type: "boolean" };
|
|
43
|
+
case "Date":
|
|
44
|
+
case "Date | string": return { type: "date" };
|
|
45
|
+
case "function":
|
|
46
|
+
case "function | undefined":
|
|
47
|
+
case "void":
|
|
48
|
+
case "void | undefined": return false;
|
|
49
|
+
default: {
|
|
50
|
+
const values = parseLiteralValues(typeText);
|
|
51
|
+
if (values.length === 0) return { type: "object" };
|
|
52
|
+
return { type: values.length < 5 ? "radio" : "select" };
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
//#endregion
|
|
57
|
+
//#region src/docs/custom-elements.ts
|
|
58
|
+
const cleanTypeText = (text) => text?.replace(/undefined\s*\|\s*/g, "").replace(/\s*\|\s*undefined/g, "").trim() || void 0;
|
|
59
|
+
const withTags = (description, tags, deprecated) => {
|
|
60
|
+
const sections = [];
|
|
61
|
+
if (deprecated !== void 0 && deprecated !== false) sections.push(typeof deprecated === "string" ? `**⚠️ Deprecated:** ${deprecated}` : "**⚠️ Deprecated**");
|
|
62
|
+
if (description) sections.push(description);
|
|
63
|
+
if (tags?.length) sections.push(tags.map(({ name, text }) => `**${name.charAt(0).toUpperCase() + name.slice(1)}:** ${text ?? ""}`.trimEnd()).join("\n\n"));
|
|
64
|
+
return sections.length > 0 ? sections.join("\n\n") : void 0;
|
|
65
|
+
};
|
|
66
|
+
const findDeclaration = (tagName, cem) => {
|
|
67
|
+
for (const mod of cem.modules) {
|
|
68
|
+
const found = (mod.declarations ?? []).find((d) => "customElement" in d && d.tagName === tagName);
|
|
69
|
+
if (found) return found;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
const toEventActionName = (eventName) => {
|
|
73
|
+
const lowerFirst = eventName.replace(/(-|_|:|\.|\s)+(.)?/g, (_, _sep, chr) => chr ? chr.toUpperCase() : "").replace(/^([A-Z])/, (m) => m.toLowerCase());
|
|
74
|
+
return `on${lowerFirst.charAt(0).toUpperCase() + lowerFirst.slice(1)}`;
|
|
75
|
+
};
|
|
76
|
+
const mapNamedItems = (items, category) => items.reduce((acc, item) => {
|
|
77
|
+
acc[item.name] = {
|
|
78
|
+
name: item.name,
|
|
79
|
+
description: item.description,
|
|
80
|
+
control: false,
|
|
81
|
+
table: { category }
|
|
82
|
+
};
|
|
83
|
+
return acc;
|
|
84
|
+
}, {});
|
|
85
|
+
const mapFields = (members) => (members ?? []).filter((m) => m.kind === "field").reduce((acc, field) => {
|
|
86
|
+
acc[field.name] = {
|
|
87
|
+
name: field.attribute ?? field.name,
|
|
88
|
+
description: withTags(field.description, field.tags, field.deprecated),
|
|
89
|
+
control: inferControlType(field),
|
|
90
|
+
table: {
|
|
91
|
+
category: "properties",
|
|
92
|
+
type: { summary: cleanTypeText(field.type?.text) },
|
|
93
|
+
defaultValue: { summary: field.default }
|
|
94
|
+
},
|
|
95
|
+
options: parseLiteralValues(field.type?.text ?? ""),
|
|
96
|
+
type: inferSBType(field)
|
|
97
|
+
};
|
|
98
|
+
return acc;
|
|
99
|
+
}, {});
|
|
100
|
+
const mapMethods = (members) => (members ?? []).filter((m) => m.kind === "method").reduce((acc, method) => {
|
|
101
|
+
acc[method.name] = {
|
|
102
|
+
name: method.name,
|
|
103
|
+
description: withTags(method.description, method.tags, method.deprecated),
|
|
104
|
+
control: false,
|
|
105
|
+
type: { name: "function" },
|
|
106
|
+
table: {
|
|
107
|
+
category: "methods",
|
|
108
|
+
type: { summary: method.return?.type?.text ?? "void" }
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
return acc;
|
|
112
|
+
}, {});
|
|
113
|
+
const mapEvents = (events) => (events ?? []).reduce((acc, event) => {
|
|
114
|
+
const name = toEventActionName(event.name);
|
|
115
|
+
acc[name] = {
|
|
116
|
+
name,
|
|
117
|
+
description: withTags(event.description, event.tags, event.deprecated),
|
|
118
|
+
control: false,
|
|
119
|
+
table: {
|
|
120
|
+
category: "events",
|
|
121
|
+
type: { summary: cleanTypeText(event.type?.text) }
|
|
122
|
+
},
|
|
123
|
+
type: { name: "function" }
|
|
124
|
+
};
|
|
125
|
+
return acc;
|
|
126
|
+
}, {});
|
|
127
|
+
const extractArgTypesFromElements = (tagName, cem) => {
|
|
128
|
+
if (!isValidComponent(tagName) || !isValidMetaData(cem)) return null;
|
|
129
|
+
const decl = findDeclaration(tagName, cem);
|
|
130
|
+
if (!decl) {
|
|
131
|
+
logger.warn(`Component not found in Custom Elements Manifest: ${tagName}`);
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
...mapFields(decl.members),
|
|
136
|
+
...mapEvents(decl.events),
|
|
137
|
+
...mapMethods(decl.members),
|
|
138
|
+
...mapNamedItems(decl.slots ?? [], "slots"),
|
|
139
|
+
...mapNamedItems(decl.cssParts ?? [], "parts"),
|
|
140
|
+
...mapNamedItems(decl.cssProperties ?? [], "styles")
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
const extractArgTypes = (component) => {
|
|
144
|
+
const cem = getCustomElements();
|
|
145
|
+
const tagName = typeof component === "string" ? component : component?.is;
|
|
146
|
+
return extractArgTypesFromElements(tagName, cem);
|
|
147
|
+
};
|
|
148
|
+
const extractComponentDescription = (component) => {
|
|
149
|
+
const cem = getCustomElements();
|
|
150
|
+
const tagName = typeof component === "string" ? component : component?.is;
|
|
151
|
+
if (!isValidComponent(tagName) || !isValidMetaData(cem)) return void 0;
|
|
152
|
+
const decl = findDeclaration(tagName, cem);
|
|
153
|
+
return withTags(decl?.description, decl?.tags, decl?.deprecated);
|
|
154
|
+
};
|
|
155
|
+
//#endregion
|
|
156
|
+
//#region src/entry-preview-argtypes.ts
|
|
157
|
+
const parameters = { docs: {
|
|
158
|
+
extractArgTypes,
|
|
159
|
+
extractComponentDescription
|
|
160
|
+
} };
|
|
161
|
+
const argTypesEnhancers = [enhanceArgTypes];
|
|
162
|
+
//#endregion
|
|
163
|
+
export { argTypesEnhancers, parameters };
|
|
164
|
+
|
|
165
|
+
//# sourceMappingURL=entry-preview-argtypes.mjs.map
|