@aurelia/storybook 2.0.0 → 2.2.1
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/.github/workflows/ci.yml +61 -0
- package/.github/workflows/publish.yml +82 -0
- package/.github/workflows/storybook-preview.yml +62 -0
- package/CHANGELOG.md +5 -0
- package/README.md +381 -148
- package/__tests__/create-aurelia-app.test.ts +94 -0
- package/__tests__/preset.test.ts +32 -3
- package/__tests__/preview.test.ts +9 -131
- package/__tests__/render.test.ts +15 -26
- package/apps/hello-world/.storybook/main.ts +0 -1
- package/apps/hello-world/package-lock.json +4585 -2609
- package/apps/hello-world/package.json +13 -23
- package/apps/hello-world/src/components/feedback-form.html +111 -0
- package/apps/hello-world/src/components/feedback-form.ts +45 -0
- package/apps/hello-world/src/components/notification-center.html +119 -0
- package/apps/hello-world/src/components/notification-center.ts +27 -0
- package/apps/hello-world/src/components/stat-card.html +107 -0
- package/apps/hello-world/src/components/stat-card.ts +41 -0
- package/apps/hello-world/src/components/weather-widget.html +89 -0
- package/apps/hello-world/src/components/weather-widget.ts +31 -0
- package/apps/hello-world/src/hello-world.html +44 -2
- package/apps/hello-world/src/services/weather-service.ts +15 -0
- package/apps/hello-world/src/stories/feedback-form.stories.ts +58 -0
- package/apps/hello-world/src/stories/hello-world.stories.ts +24 -14
- package/apps/hello-world/src/stories/notification-center.stories.ts +88 -0
- package/apps/hello-world/src/stories/stat-card.stories.ts +75 -0
- package/apps/hello-world/src/stories/weather-widget.stories.ts +62 -0
- package/apps/hello-world/tsconfig.json +4 -3
- package/apps/hello-world/vite.config.ts +0 -2
- package/apps/hello-world-rsbuild/.storybook/main.ts +16 -0
- package/apps/hello-world-rsbuild/.storybook/preview.ts +1 -0
- package/apps/hello-world-rsbuild/.stylelintrc.json +5 -0
- package/apps/hello-world-rsbuild/README.md +28 -0
- package/apps/hello-world-rsbuild/eslint.config.mjs +25 -0
- package/apps/hello-world-rsbuild/favicon.ico +0 -0
- package/apps/hello-world-rsbuild/index.html +17 -0
- package/apps/hello-world-rsbuild/package-lock.json +11131 -0
- package/apps/hello-world-rsbuild/package.json +56 -0
- package/apps/hello-world-rsbuild/src/components/feedback-form.html +111 -0
- package/apps/hello-world-rsbuild/src/components/feedback-form.ts +45 -0
- package/apps/hello-world-rsbuild/src/components/notification-center.html +119 -0
- package/apps/hello-world-rsbuild/src/components/notification-center.ts +27 -0
- package/apps/hello-world-rsbuild/src/components/stat-card.html +107 -0
- package/apps/hello-world-rsbuild/src/components/stat-card.ts +41 -0
- package/apps/hello-world-rsbuild/src/components/weather-widget.html +89 -0
- package/apps/hello-world-rsbuild/src/components/weather-widget.ts +31 -0
- package/apps/hello-world-rsbuild/src/hello-world.html +48 -0
- package/apps/hello-world-rsbuild/src/hello-world.ts +17 -0
- package/apps/hello-world-rsbuild/src/main.ts +6 -0
- package/apps/hello-world-rsbuild/src/my-app.html +1 -0
- package/apps/hello-world-rsbuild/src/my-app.ts +3 -0
- package/apps/hello-world-rsbuild/src/resource.d.ts +15 -0
- package/apps/hello-world-rsbuild/src/services/weather-service.ts +15 -0
- package/apps/hello-world-rsbuild/src/stories/feedback-form.stories.ts +58 -0
- package/apps/hello-world-rsbuild/src/stories/hello-world.stories.ts +64 -0
- package/apps/hello-world-rsbuild/src/stories/notification-center.stories.ts +88 -0
- package/apps/hello-world-rsbuild/src/stories/stat-card.stories.ts +75 -0
- package/apps/hello-world-rsbuild/src/stories/weather-widget.stories.ts +62 -0
- package/apps/hello-world-rsbuild/test/my-app.spec.ts +15 -0
- package/apps/hello-world-rsbuild/test/setup.ts +29 -0
- package/apps/hello-world-rsbuild/tsconfig.json +19 -0
- package/apps/hello-world-rsbuild/tsconfig.vitest.json +11 -0
- package/apps/hello-world-rsbuild/vite.config.ts +17 -0
- package/apps/hello-world-rsbuild/vitest.config.ts +15 -0
- package/apps/hello-world-webpack/.storybook/main.ts +0 -1
- package/apps/hello-world-webpack/package-lock.json +3553 -768
- package/apps/hello-world-webpack/package.json +8 -10
- package/apps/hello-world-webpack/src/components/feedback-form.html +111 -0
- package/apps/hello-world-webpack/src/components/feedback-form.ts +45 -0
- package/apps/hello-world-webpack/src/components/notification-center.html +119 -0
- package/apps/hello-world-webpack/src/components/notification-center.ts +27 -0
- package/apps/hello-world-webpack/src/components/stat-card.html +107 -0
- package/apps/hello-world-webpack/src/components/stat-card.ts +41 -0
- package/apps/hello-world-webpack/src/components/weather-widget.html +89 -0
- package/apps/hello-world-webpack/src/components/weather-widget.ts +31 -0
- package/apps/hello-world-webpack/src/hello-world.html +44 -2
- package/apps/hello-world-webpack/src/my-app.stories.ts +6 -4
- package/apps/hello-world-webpack/src/services/weather-service.ts +15 -0
- package/apps/hello-world-webpack/src/stories/feedback-form.stories.ts +58 -0
- package/apps/hello-world-webpack/src/stories/hello-world.stories.ts +25 -15
- package/apps/hello-world-webpack/src/stories/notification-center.stories.ts +88 -0
- package/apps/hello-world-webpack/src/stories/stat-card.stories.ts +75 -0
- package/apps/hello-world-webpack/src/stories/weather-widget.stories.ts +62 -0
- package/apps/hello-world-webpack/tsconfig.json +1 -1
- package/dist/index.d.ts +25 -0
- package/dist/index.js +68 -14
- package/dist/index.js.map +1 -1
- package/dist/preset.d.ts +21 -0
- package/dist/preset.js +46 -2
- package/dist/preset.js.map +1 -1
- package/dist/preview/helpers.d.ts +2 -0
- package/dist/preview/helpers.js +6 -0
- package/dist/preview/helpers.js.map +1 -0
- package/dist/preview/render.d.ts +7 -0
- package/dist/preview/render.js +66 -15
- package/dist/preview/render.js.map +1 -1
- package/dist/preview/storybook-types-runtime.d.ts +1 -0
- package/dist/preview/storybook-types-runtime.js +5 -0
- package/dist/preview/storybook-types-runtime.js.map +1 -0
- package/dist/preview/storybook-types.d.ts +27 -0
- package/dist/preview/types-runtime.d.ts +1 -0
- package/dist/preview/types-runtime.js +5 -0
- package/dist/preview/types-runtime.js.map +1 -0
- package/dist/preview/types.d.ts +44 -0
- package/dist/preview.d.ts +3 -0
- package/dist/preview.js +71 -16
- package/dist/preview.js.map +1 -1
- package/dist/webpack.d.ts +10 -0
- package/dist/webpack.js +19 -1
- package/dist/webpack.js.map +1 -1
- package/package.json +58 -13
- package/rollup.config.mjs +5 -3
- package/scripts/sync-versions.cjs +55 -0
- package/src/index.ts +11 -1
- package/src/preset.ts +32 -2
- package/src/preview/helpers.ts +7 -0
- package/src/preview/render.ts +98 -30
- package/src/preview/storybook-types-runtime.ts +2 -0
- package/src/preview/storybook-types.ts +34 -0
- package/src/preview/types-runtime.ts +2 -0
- package/src/preview/types.ts +57 -2
- package/src/preview.ts +11 -1
- package/src/webpack.ts +19 -0
- package/apps/hello-world/.yarnrc.yml +0 -2
- package/apps/hello-world-webpack/.yarnrc.yml +0 -2
- package/dist/index.mjs +0 -132
- package/dist/index.mjs.map +0 -1
- package/dist/preset.mjs +0 -60
- package/dist/preset.mjs.map +0 -1
- package/dist/preview/render.mjs +0 -114
- package/dist/preview/render.mjs.map +0 -1
- package/dist/preview/types.js +0 -2
- package/dist/preview/types.js.map +0 -1
- package/dist/preview/types.mjs +0 -2
- package/dist/preview/types.mjs.map +0 -1
- package/dist/preview.mjs +0 -114
- package/dist/preview.mjs.map +0 -1
- package/dist/webpack.mjs +0 -21
- package/dist/webpack.mjs.map +0 -1
- /package/{jest.config.js → jest.config.cjs} +0 -0
package/README.md
CHANGED
|
@@ -1,132 +1,167 @@
|
|
|
1
1
|
# @aurelia/storybook
|
|
2
2
|
|
|
3
|
-
> **Note:** Storybook support is
|
|
3
|
+
> **Note:** Storybook support is still early-stage. Expect a few rough edges while Aurelia 2 finishes its beta cycle, and please report anything that feels off.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`@aurelia/storybook` is the glue between Aurelia 2 components and Storybook 10. It wires Aurelia's `enhance()` API into Storybook's rendering pipeline so you can preview, test, and document your components with either the Vite or Webpack builders.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Compatibility at a Glance
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
| Item | Supported versions | Notes |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| Storybook | 10.x (ESM) | Tested with 10.0.5+; works with `storybook dev`/`storybook build` commands. |
|
|
12
|
+
| Aurelia | 2.0.0-beta.25+ | Uses Aurelia's `enhance()` APIs under the hood. |
|
|
13
|
+
| Bundlers | `@storybook/builder-vite` (Vite 5) · `@storybook/builder-webpack5` · `storybook-builder-rsbuild` (Rsbuild/Rspack) | Pick whichever matches your app; they share the same Aurelia preview runtime. |
|
|
14
|
+
| Node.js | ≥ 20.19.0 or ≥ 22.12.0 | Matches the engines field in `package.json` and Storybook 10's baseline.
|
|
13
15
|
|
|
14
|
-
##
|
|
16
|
+
## Requirements
|
|
17
|
+
|
|
18
|
+
- An Aurelia 2 application (TypeScript or JavaScript) already set up with either Vite or Webpack.
|
|
19
|
+
- Storybook 10.x installed in the project. (Run `npx storybook@latest init` if you are starting fresh.)
|
|
20
|
+
- The peer dependencies listed in [`package.json`](package.json) that align with the Aurelia 2 beta train you are targeting.
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
## Installation
|
|
17
23
|
|
|
18
24
|
```bash
|
|
19
|
-
npm install --save-dev @aurelia/storybook
|
|
25
|
+
npm install --save-dev @aurelia/storybook storybook @storybook/builder-vite
|
|
26
|
+
# or, for Webpack builds:
|
|
27
|
+
npm install --save-dev @aurelia/storybook storybook @storybook/builder-webpack5
|
|
28
|
+
# or, for Rsbuild/Rspack builds:
|
|
29
|
+
npm install --save-dev @aurelia/storybook storybook storybook-builder-rsbuild @rsbuild/core
|
|
20
30
|
```
|
|
21
31
|
|
|
22
|
-
|
|
32
|
+
Add whichever addons you need (`@storybook/addon-links`, `@storybook/addon-actions`, etc.). Essentials functionality now ships with Storybook 10 core, so most projects only add optional extras.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Quick Start (Vite Builder)
|
|
37
|
+
|
|
38
|
+
1. **Install** the dev dependencies as shown above (or with `pnpm`/`yarn`).
|
|
39
|
+
2. **Create `.storybook/main.ts`:**
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
// .storybook/main.ts
|
|
43
|
+
import { mergeConfig, type InlineConfig } from 'vite';
|
|
44
|
+
import type { StorybookConfig } from 'storybook/internal/types';
|
|
45
|
+
|
|
46
|
+
const config: StorybookConfig & { viteFinal?: (config: InlineConfig) => InlineConfig | Promise<InlineConfig> } = {
|
|
47
|
+
stories: ['../src/stories/**/*.stories.@(ts|tsx|js|jsx|mdx)'],
|
|
48
|
+
addons: ['@storybook/addon-links'],
|
|
49
|
+
framework: {
|
|
50
|
+
name: '@aurelia/storybook',
|
|
51
|
+
options: {},
|
|
52
|
+
},
|
|
53
|
+
core: {
|
|
54
|
+
builder: '@storybook/builder-vite',
|
|
55
|
+
},
|
|
56
|
+
viteFinal: async (viteConfig) => {
|
|
57
|
+
// Ensure problematic Aurelia deps are excluded from pre-bundling.
|
|
58
|
+
viteConfig.optimizeDeps = viteConfig.optimizeDeps ?? {};
|
|
59
|
+
viteConfig.optimizeDeps.exclude = Array.from(new Set([...(viteConfig.optimizeDeps.exclude ?? []), '@aurelia/runtime-html']));
|
|
60
|
+
|
|
61
|
+
return mergeConfig(viteConfig, {
|
|
62
|
+
define: {
|
|
63
|
+
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV ?? 'development'),
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export default config;
|
|
70
|
+
```
|
|
23
71
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
```
|
|
72
|
+
- Excluding `@aurelia/runtime-html` keeps Vite from trying to pre-bundle Aurelia's DOM runtime, which is already ESM friendly.
|
|
73
|
+
- The `define` shim avoids `process is not defined` errors when Storybook code (or Aurelia plugins) look for `process.env.NODE_ENV` in the preview iframe.
|
|
27
74
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
1. **Preset Setup**:
|
|
37
|
-
The package comes with a minimal Storybook preset (see [src/preset.ts](src/preset.ts)) that allows you to adjust Vite's configuration if needed. Storybook will use this preset to set up the build system for your Aurelia stories.
|
|
38
|
-
|
|
39
|
-
2. **Framework Setup**:
|
|
40
|
-
For a full Aurelia 2 integration with Vite and a TypeScript configuration, ensure that your Storybook configuration files are set up as follows:
|
|
41
|
-
|
|
42
|
-
- **.storybook/main.ts**
|
|
43
|
-
Create or update your `.storybook/main.ts` file with the following contents:
|
|
44
|
-
|
|
45
|
-
```typescript
|
|
46
|
-
import type { StorybookConfig } from 'storybook/internal/types';
|
|
47
|
-
import { mergeConfig, type InlineConfig } from 'vite';
|
|
48
|
-
|
|
49
|
-
const config: StorybookConfig & { viteFinal?: (config: InlineConfig, options: { configType: string }) => InlineConfig | Promise<InlineConfig> } = {
|
|
50
|
-
stories: ['../src/stories/**/*.stories.@(ts|tsx|js|jsx|mdx)'],
|
|
51
|
-
addons: [
|
|
52
|
-
// Additional addons (essentials are now built into Storybook 9 core):
|
|
53
|
-
'@storybook/addon-links'
|
|
54
|
-
],
|
|
55
|
-
framework: {
|
|
56
|
-
name: '@aurelia/storybook',
|
|
57
|
-
options: {},
|
|
58
|
-
},
|
|
59
|
-
core: {
|
|
60
|
-
builder: '@storybook/builder-vite',
|
|
61
|
-
},
|
|
62
|
-
viteFinal: async (viteConfig) => {
|
|
63
|
-
viteConfig.optimizeDeps = viteConfig.optimizeDeps || {};
|
|
64
|
-
viteConfig.optimizeDeps.exclude = viteConfig.optimizeDeps.exclude || [];
|
|
65
|
-
if (!viteConfig.optimizeDeps.exclude.includes('@aurelia/runtime-html')) {
|
|
66
|
-
viteConfig.optimizeDeps.exclude.push('@aurelia/runtime-html');
|
|
67
|
-
}
|
|
68
|
-
return mergeConfig(viteConfig, {
|
|
69
|
-
// ...any additional Vite configuration
|
|
70
|
-
});
|
|
71
|
-
},
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export default config;
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
- **.storybook/preview.ts**
|
|
78
|
-
Next, update or create your `.storybook/preview.ts` file with the following code to import the render functions from the Aurelia Storybook plugin:
|
|
79
|
-
|
|
80
|
-
```typescript
|
|
81
|
-
// .storybook/preview.ts
|
|
82
|
-
// Import the render function from the plugin package.
|
|
83
|
-
export { render, renderToCanvas } from '@aurelia/storybook';
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
> **Note:** Essential features like actions, controls, backgrounds, and viewport are now built into Storybook 10 core and don't need to be installed separately. However, if you need to use the `action()` function in your stories (for programmatic actions), you may still need to install `@storybook/addon-actions`. Additional addons like `@storybook/addon-links` can be installed and added to the `addons` array in your configuration.
|
|
87
|
-
|
|
88
|
-
### Using with Webpack
|
|
89
|
-
|
|
90
|
-
If you prefer to use Webpack instead of Vite, update your `.storybook/main.ts` configuration:
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
import type { StorybookConfig } from 'storybook/internal/types';
|
|
94
|
-
|
|
95
|
-
const config: StorybookConfig = {
|
|
96
|
-
stories: ['../src/**/*.stories.@(ts|tsx|js|jsx|mdx)'],
|
|
97
|
-
addons: [
|
|
98
|
-
'@storybook/addon-links'
|
|
99
|
-
],
|
|
100
|
-
framework: {
|
|
101
|
-
name: '@aurelia/storybook',
|
|
102
|
-
options: {},
|
|
103
|
-
},
|
|
104
|
-
core: {
|
|
105
|
-
builder: '@storybook/builder-webpack5',
|
|
106
|
-
},
|
|
107
|
-
};
|
|
75
|
+
3. **Create `.storybook/preview.ts`:**
|
|
76
|
+
|
|
77
|
+
```ts
|
|
78
|
+
// .storybook/preview.ts
|
|
79
|
+
export { render, renderToCanvas } from '@aurelia/storybook';
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
4. **Add `storybook` scripts** to `package.json`:
|
|
108
83
|
|
|
109
|
-
|
|
110
|
-
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"scripts": {
|
|
87
|
+
"storybook": "storybook dev -p 6006",
|
|
88
|
+
"build-storybook": "storybook build"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
111
92
|
|
|
112
|
-
|
|
93
|
+
5. **Run Storybook:** `npm run storybook` starts the dev server at http://localhost:6006.
|
|
113
94
|
|
|
114
|
-
|
|
115
|
-
Add the following scripts to your `package.json` file to work with Storybook:
|
|
95
|
+
## Quick Start (Webpack Builder)
|
|
116
96
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
"storybook": "storybook dev -p 6006",
|
|
120
|
-
"build-storybook": "storybook build"
|
|
121
|
-
}
|
|
122
|
-
```
|
|
123
|
-
These scripts will allow you to start Storybook in development mode and build it for production.
|
|
97
|
+
1. Install `@storybook/builder-webpack5` instead of the Vite builder.
|
|
98
|
+
2. Create `.storybook/main.ts`:
|
|
124
99
|
|
|
125
|
-
|
|
100
|
+
```ts
|
|
101
|
+
import type { StorybookConfig } from 'storybook/internal/types';
|
|
102
|
+
|
|
103
|
+
const config: StorybookConfig = {
|
|
104
|
+
stories: ['../src/**/*.stories.@(ts|tsx|js|jsx|mdx)'],
|
|
105
|
+
addons: ['@storybook/addon-links'],
|
|
106
|
+
framework: {
|
|
107
|
+
name: '@aurelia/storybook',
|
|
108
|
+
options: {},
|
|
109
|
+
},
|
|
110
|
+
core: {
|
|
111
|
+
builder: '@storybook/builder-webpack5',
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
export default config;
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
The preset embedded in this package injects the `ts-loader` + `@aurelia/webpack-loader` rules so you typically do not need extra config, but `webpackFinal` is available if you need to extend it further.
|
|
119
|
+
|
|
120
|
+
3. Reuse the same `.storybook/preview.ts` and `package.json` scripts as in the Vite quick start.
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Quick Start (Rsbuild/Rspack Builder)
|
|
125
|
+
|
|
126
|
+
1. Install `storybook-builder-rsbuild` and `@rsbuild/core`.
|
|
127
|
+
2. Create `.storybook/main.ts`:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
import type { StorybookConfig } from 'storybook/internal/types';
|
|
131
|
+
|
|
132
|
+
const config: StorybookConfig = {
|
|
133
|
+
stories: ['../src/**/*.stories.@(ts|tsx|js|jsx|mdx)'],
|
|
134
|
+
addons: ['@storybook/addon-links'],
|
|
135
|
+
framework: {
|
|
136
|
+
name: '@aurelia/storybook',
|
|
137
|
+
options: {},
|
|
138
|
+
},
|
|
139
|
+
core: {
|
|
140
|
+
builder: 'storybook-builder-rsbuild',
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export default config;
|
|
145
|
+
```
|
|
126
146
|
|
|
127
|
-
Aurelia
|
|
147
|
+
The Aurelia preset injects the `ts-loader` + `@aurelia/webpack-loader` rules via `rsbuildFinal`,
|
|
148
|
+
so most projects do not need extra Rsbuild configuration. If you do, add your own `rsbuildFinal`
|
|
149
|
+
and merge with `@rsbuild/core`'s `mergeRsbuildConfig`.
|
|
128
150
|
|
|
129
|
-
|
|
151
|
+
3. Reuse the same `.storybook/preview.ts` and `package.json` scripts as in the Vite quick start.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Writing Aurelia Stories
|
|
156
|
+
|
|
157
|
+
Story files look exactly like standard Storybook CSF stories. The framework export automatically:
|
|
158
|
+
|
|
159
|
+
- Registers the component you set on the default export.
|
|
160
|
+
- Uses `renderToCanvas` to bootstrap an Aurelia app inside Storybook's preview iframe.
|
|
161
|
+
- Generates a template for you if you omit the `render` function (it binds every declared `bindable`).
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
// src/stories/hello-world.stories.ts
|
|
130
165
|
import { HelloWorld } from '../hello-world';
|
|
131
166
|
import { fn, userEvent, within } from 'storybook/test';
|
|
132
167
|
|
|
@@ -138,82 +173,280 @@ const meta = {
|
|
|
138
173
|
}),
|
|
139
174
|
argTypes: {
|
|
140
175
|
message: { control: 'text' },
|
|
141
|
-
onIncrement: { action: 'increment' }
|
|
142
|
-
}
|
|
176
|
+
onIncrement: { action: 'increment' },
|
|
177
|
+
},
|
|
143
178
|
};
|
|
144
179
|
|
|
145
180
|
export default meta;
|
|
146
181
|
|
|
147
182
|
export const DefaultHelloWorld = {
|
|
148
183
|
args: {
|
|
149
|
-
message:
|
|
150
|
-
onIncrement: fn()
|
|
151
|
-
}
|
|
184
|
+
message: 'Hello from Storybook!',
|
|
185
|
+
onIncrement: fn(),
|
|
186
|
+
},
|
|
152
187
|
};
|
|
153
188
|
|
|
154
189
|
export const InteractiveHelloWorld = {
|
|
155
190
|
args: {
|
|
156
|
-
message:
|
|
157
|
-
onIncrement: fn()
|
|
191
|
+
message: 'Try clicking the button!',
|
|
192
|
+
onIncrement: fn(),
|
|
158
193
|
},
|
|
159
|
-
|
|
194
|
+
async play({ canvasElement }: { canvasElement: HTMLElement }) {
|
|
160
195
|
const canvas = within(canvasElement);
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
await userEvent.click(button);
|
|
164
|
-
await userEvent.click(button);
|
|
165
|
-
await userEvent.click(button);
|
|
166
|
-
}
|
|
196
|
+
await userEvent.click(canvas.getByRole('button'));
|
|
197
|
+
},
|
|
167
198
|
};
|
|
168
199
|
|
|
169
200
|
export const NoArgs = {
|
|
170
|
-
render: () => ({
|
|
171
|
-
template: `<hello-world></hello-world>`
|
|
172
|
-
})
|
|
201
|
+
render: () => ({ template: `<hello-world></hello-world>` }),
|
|
173
202
|
};
|
|
174
203
|
|
|
175
204
|
export const WithCustomTemplate = {
|
|
176
205
|
render: () => ({
|
|
177
|
-
template: `<hello-world message.bind="message">Click me!</hello-world
|
|
206
|
+
template: `<hello-world message.bind="message">Click me!</hello-world>`,
|
|
178
207
|
}),
|
|
179
208
|
args: {
|
|
180
|
-
message:
|
|
181
|
-
}
|
|
209
|
+
message: 'This is a custom message',
|
|
210
|
+
},
|
|
211
|
+
};
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Helper for Typed Story Results
|
|
215
|
+
|
|
216
|
+
If you want stronger typing (especially for `props`), you can use the helper and types exported by the package:
|
|
217
|
+
|
|
218
|
+
```ts
|
|
219
|
+
import { defineAureliaStory, type AureliaStoryResult } from '@aurelia/storybook';
|
|
220
|
+
|
|
221
|
+
const render = (args: { title: string }): AureliaStoryResult<{ title: string }> =>
|
|
222
|
+
defineAureliaStory({
|
|
223
|
+
template: `<my-card title.bind="title"></my-card>`,
|
|
224
|
+
props: args,
|
|
225
|
+
});
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
You can also import directly from `@aurelia/storybook/preview` or `@aurelia/storybook/preview/types` if you prefer.
|
|
229
|
+
|
|
230
|
+
### Story Result Contract
|
|
231
|
+
|
|
232
|
+
When you provide a custom `render` function, return an object with any of the following fields. The Aurelia runtime consumes them while creating the preview app:
|
|
233
|
+
|
|
234
|
+
| Field | Type | Purpose |
|
|
235
|
+
| --- | --- | --- |
|
|
236
|
+
| `template` | `string` | Markup that will be enhanced inside Storybook's canvas. Required when you do not rely on the auto-generated template. |
|
|
237
|
+
| `components` | `unknown[]` | Additional custom elements, value converters, etc. to register via `aurelia.register(...)`. |
|
|
238
|
+
| `items` | `unknown[]` | Any DI registrations (e.g., `Registration.instance(...)`, services, or Aurelia plugins). |
|
|
239
|
+
| `container` | `IContainer` | Supply a pre-configured Aurelia DI container if you need full control. |
|
|
240
|
+
| `innerHtml` | `string` | Optional projection content used when a component template is auto-generated from the `component` export. |
|
|
241
|
+
| `props` | `Record<string, any>` | Story-specific props that merge with Storybook `args`. Useful when you need defaults that should not surface as controls.
|
|
242
|
+
|
|
243
|
+
## Registering Aurelia Dependencies & DI
|
|
244
|
+
|
|
245
|
+
Use the `components`, `items`, or `container` fields to bring along everything your component needs:
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
import { DI, Registration } from 'aurelia';
|
|
249
|
+
import { HttpClient } from '@aurelia/fetch-client';
|
|
250
|
+
import { OrdersPanel } from '../orders-panel';
|
|
251
|
+
|
|
252
|
+
const container = DI.createContainer();
|
|
253
|
+
container.register(
|
|
254
|
+
HttpClient,
|
|
255
|
+
Registration.instance('apiBaseUrl', 'https://api.example.com')
|
|
256
|
+
);
|
|
257
|
+
|
|
258
|
+
export const WithServices = {
|
|
259
|
+
render: () => ({
|
|
260
|
+
template: `<orders-panel api-base-url.bind="apiBaseUrl"></orders-panel>`,
|
|
261
|
+
components: [OrdersPanel],
|
|
262
|
+
container,
|
|
263
|
+
props: {
|
|
264
|
+
apiBaseUrl: 'https://api.example.com',
|
|
265
|
+
},
|
|
266
|
+
}),
|
|
182
267
|
};
|
|
183
268
|
```
|
|
184
269
|
|
|
185
|
-
|
|
270
|
+
Because the Aurelia app lives for the lifetime of the story iframe, DI registrations persist until the story is torn down or Storybook forces a remount. If you need a clean state between stories, set `parameters: { forceRemount: true }` on the story or click the *Remount component* toolbar button in Storybook.
|
|
186
271
|
|
|
187
|
-
|
|
188
|
-
The integration exports a render function (`renderToCanvas`) that Storybook calls to mount your Aurelia component on the preview canvas. It clears the canvas, enhances it with Aurelia, and notifies Storybook when rendering is complete.
|
|
272
|
+
### Global Aurelia Configuration (Preview + Story Parameters)
|
|
189
273
|
|
|
190
|
-
|
|
191
|
-
Once the canvas is cleared, the integration instantiates a new Aurelia instance, registers your component (and any additional Aurelia modules you may specify), and calls the Aurelia `enhance()` API to bind your component's view to the DOM.
|
|
274
|
+
You can register global resources/plugins and customize the DI container via Storybook parameters. The framework reads `parameters.aurelia` from the merged Storybook context (preview + component + story):
|
|
192
275
|
|
|
193
|
-
|
|
194
|
-
|
|
276
|
+
```ts
|
|
277
|
+
// .storybook/preview.ts
|
|
278
|
+
import { Registration } from 'aurelia';
|
|
279
|
+
import { CurrencyValueConverter } from '../src/resources/currency';
|
|
280
|
+
import { FeatureFlags } from '../src/services/feature-flags';
|
|
281
|
+
|
|
282
|
+
export const parameters = {
|
|
283
|
+
aurelia: {
|
|
284
|
+
register: [CurrencyValueConverter],
|
|
285
|
+
configureContainer: (container) => {
|
|
286
|
+
container.register(Registration.instance(FeatureFlags, { beta: true }));
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
You can also override or extend per story:
|
|
293
|
+
|
|
294
|
+
```ts
|
|
295
|
+
export const WithOverrides = {
|
|
296
|
+
parameters: {
|
|
297
|
+
aurelia: {
|
|
298
|
+
configureContainer: (container) => {
|
|
299
|
+
container.register(Registration.instance('apiBaseUrl', 'https://staging.example.com'));
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
These hooks run when the Aurelia app is created. If you rely on different container setups per story, use `parameters: { forceRemount: true }` to ensure a fresh app instance.
|
|
307
|
+
|
|
308
|
+
#### Parameters API (Quick Reference)
|
|
309
|
+
|
|
310
|
+
```ts
|
|
311
|
+
export const parameters = {
|
|
312
|
+
aurelia: {
|
|
313
|
+
// Register global resources/plugins
|
|
314
|
+
register: [MyElement, MyValueConverter],
|
|
315
|
+
// Optional aliases for parity with story results
|
|
316
|
+
components: [MyElement],
|
|
317
|
+
items: [Registration.instance(MyService, new MyService())],
|
|
318
|
+
// Configure the DI container
|
|
319
|
+
configureContainer: (container, context) => {
|
|
320
|
+
// ...
|
|
321
|
+
},
|
|
322
|
+
// Configure the Aurelia instance
|
|
323
|
+
configure: (aurelia, context) => {
|
|
324
|
+
// ...
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
};
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Cookbook
|
|
331
|
+
|
|
332
|
+
### 1) Register global resources once
|
|
333
|
+
|
|
334
|
+
```ts
|
|
335
|
+
// .storybook/preview.ts
|
|
336
|
+
import { Registration } from 'aurelia';
|
|
337
|
+
import { CurrencyValueConverter } from '../src/resources/currency';
|
|
338
|
+
import { FeatureFlags } from '../src/services/feature-flags';
|
|
339
|
+
|
|
340
|
+
export const parameters = {
|
|
341
|
+
aurelia: {
|
|
342
|
+
register: [CurrencyValueConverter],
|
|
343
|
+
configureContainer: (container) => {
|
|
344
|
+
container.register(Registration.instance(FeatureFlags, { beta: true }));
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
```
|
|
349
|
+
|
|
350
|
+
### 2) Mock a service per story
|
|
351
|
+
|
|
352
|
+
```ts
|
|
353
|
+
import { Registration } from 'aurelia';
|
|
354
|
+
import { IWeatherService } from '../src/services/weather-service';
|
|
355
|
+
|
|
356
|
+
export const WithMockedService = {
|
|
357
|
+
render: (args) =>
|
|
358
|
+
defineAureliaStory({
|
|
359
|
+
template: `<weather-widget location.bind="location"></weather-widget>`,
|
|
360
|
+
props: args,
|
|
361
|
+
items: [
|
|
362
|
+
Registration.instance(IWeatherService, {
|
|
363
|
+
getWeather: async () => ({ location: 'Seattle', condition: 'Sunny' }),
|
|
364
|
+
}),
|
|
365
|
+
],
|
|
366
|
+
}),
|
|
367
|
+
};
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
### 3) Force a clean DI container per story
|
|
371
|
+
|
|
372
|
+
```ts
|
|
373
|
+
export const CleanState = {
|
|
374
|
+
parameters: { forceRemount: true },
|
|
375
|
+
render: (args) =>
|
|
376
|
+
defineAureliaStory({
|
|
377
|
+
template: `<my-component value.bind="value"></my-component>`,
|
|
378
|
+
props: args,
|
|
379
|
+
}),
|
|
380
|
+
};
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
## Example Apps Inside This Repo
|
|
384
|
+
|
|
385
|
+
- `apps/hello-world` – Vite-based Aurelia starter that consumes `@aurelia/storybook`.
|
|
386
|
+
- `apps/hello-world-webpack` – Equivalent Webpack example.
|
|
387
|
+
|
|
388
|
+
To try them out:
|
|
389
|
+
|
|
390
|
+
```bash
|
|
391
|
+
cd apps/hello-world
|
|
392
|
+
npm install
|
|
393
|
+
npm run storybook
|
|
394
|
+
|
|
395
|
+
cd ../hello-world-webpack
|
|
396
|
+
npm install
|
|
397
|
+
npm run storybook
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Each sample project now includes a small library of showcase stories you can open in Storybook to see different aspects of the integration:
|
|
401
|
+
|
|
402
|
+
- `HelloWorld` – the minimal counter example wired to Storybook controls and actions.
|
|
403
|
+
- `StatCard` – demonstrates args-driven styling and wiring the `onRefresh` action.
|
|
404
|
+
- `NotificationCenter` – renders repeating templates and exercises dismissal actions + play functions.
|
|
405
|
+
- `FeedbackForm` – shows two-way bindings, form state, and Storybook interaction tests that fill and submit inputs.
|
|
406
|
+
- `WeatherWidget` – uses Aurelia's DI plus `items` registration in the story to provide a mock `WeatherService` implementation.
|
|
407
|
+
|
|
408
|
+
These are great references when you want to compare your configuration against a working baseline or copy/paste patterns into your own component library.
|
|
409
|
+
|
|
410
|
+
## Troubleshooting & Tips
|
|
411
|
+
|
|
412
|
+
- **`process is not defined` inside the preview iframe** – Add `define: { 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV ?? 'development') }` in your `viteFinal` merge (shown above).
|
|
413
|
+
- **Vite fails while pre-bundling Aurelia packages** – Ensure `@aurelia/runtime-html` (and any other Aurelia libs that re-export DOM globals) are listed in `optimizeDeps.exclude`.
|
|
414
|
+
- **State leaks between stories** – By default we reuse the Aurelia app instance for performance. Pass `parameters: { forceRemount: true }` to stories that must start fresh.
|
|
415
|
+
- **Need additional Storybook addons?** – Add them to the `addons` array as usual. The Aurelia framework only controls rendering, so controls, actions, interactions, and testing addons all work normally.
|
|
195
416
|
|
|
196
417
|
## Development
|
|
197
418
|
|
|
198
|
-
|
|
419
|
+
This repository publishes the Storybook framework itself. Helpful scripts:
|
|
199
420
|
|
|
200
|
-
|
|
421
|
+
- `npm run build` – bundle the framework with Rollup.
|
|
422
|
+
- `npm run build:types` – emit `.d.ts` files via `tsc`.
|
|
423
|
+
- `npm run watch` – development build with Rollup watch mode.
|
|
424
|
+
- `npm run test` – run the Jest suite (uses the JSDOM environment).
|
|
201
425
|
|
|
202
|
-
|
|
203
|
-
npm run build
|
|
204
|
-
```
|
|
426
|
+
While developing, you can link the package into one of the sample apps in `apps/` to manual-test Storybook changes end to end.
|
|
205
427
|
|
|
206
|
-
|
|
428
|
+
## Releases & Changelog
|
|
207
429
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
430
|
+
- Keep `CHANGELOG.md` updated for each release (use the **Unreleased** section while working).
|
|
431
|
+
- Align example app versions with the root package before tagging:
|
|
432
|
+
- `npm run sync:versions`
|
|
433
|
+
- Tag releases as `vX.Y.Z` so the publish workflow can run.
|
|
434
|
+
|
|
435
|
+
Publish flow (automated via GitHub Actions):
|
|
436
|
+
1. Update `package.json` version.
|
|
437
|
+
2. Generate `CHANGELOG.md` from conventional commits: `npm run changelog`.
|
|
438
|
+
3. Run `npm run sync:versions` and commit changes.
|
|
439
|
+
4. Create tag `vX.Y.Z` and push it.
|
|
440
|
+
|
|
441
|
+
## Troubleshooting
|
|
211
442
|
|
|
212
|
-
|
|
443
|
+
- **AUR0153 duplicate element registration**: ensure the same component isn't registered multiple times within the same story/container.
|
|
444
|
+
- **Args undefined during first render**: defensively handle optional args in components (e.g., fallbacks for arrays/strings).
|
|
445
|
+
- **Rsbuild `loader.loadModule is not a function`**: avoid `ts-loader` in Rsbuild/Rspack builds; use the built-in Rsbuild TS handling.
|
|
213
446
|
|
|
214
447
|
## Contributing
|
|
215
448
|
|
|
216
|
-
|
|
449
|
+
Bug reports, docs tweaks, and feature PRs are all welcome. Please open an issue to discuss significant changes, and spin up one of the example apps to verify the behavior you are touching.
|
|
217
450
|
|
|
218
451
|
## License
|
|
219
452
|
|
|
@@ -221,4 +454,4 @@ Contributions, bug reports, and feature requests are welcome. Please open an iss
|
|
|
221
454
|
|
|
222
455
|
## Acknowledgements
|
|
223
456
|
|
|
224
|
-
Special shout out to Dmitry (@ekzobrain on GitHub) for the work he did on Storybook support for earlier versions of Storybook, which helped lay
|
|
457
|
+
Special shout out to Dmitry (@ekzobrain on GitHub) for the work he did on Storybook support for earlier versions of Storybook, which helped lay the groundwork for this implementation: [https://github.com/ekzobrain/storybook](https://github.com/ekzobrain/storybook).
|