@storybook/angular 9.0.10 → 9.0.11

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.
@@ -1,37 +1,4 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  exports.AbstractRenderer = exports.STORY_UID_ATTRIBUTE = void 0;
37
4
  const platform_browser_1 = require("@angular/platform-browser");
@@ -41,6 +8,7 @@ const StorybookModule_1 = require("./StorybookModule");
41
8
  const StorybookProvider_1 = require("./StorybookProvider");
42
9
  const BootstrapQueue_1 = require("./utils/BootstrapQueue");
43
10
  const PropertyExtractor_1 = require("./utils/PropertyExtractor");
11
+ const Zoneless_1 = require("./utils/Zoneless");
44
12
  const applicationRefs = new Map();
45
13
  /**
46
14
  * Attribute name for the story UID that may be written to the targetDOMNode.
@@ -115,12 +83,12 @@ class AbstractRenderer {
115
83
  ...(storyFnAngular.applicationConfig?.providers ?? []),
116
84
  ];
117
85
  if (STORYBOOK_ANGULAR_OPTIONS?.experimentalZoneless) {
118
- const { provideExperimentalZonelessChangeDetection } = await Promise.resolve().then(() => __importStar(require('@angular/core')));
119
- if (!provideExperimentalZonelessChangeDetection) {
120
- throw new Error('Experimental zoneless change detection requires Angular 18 or higher');
86
+ const provideZonelessChangeDetectionFn = await (0, Zoneless_1.getProvideZonelessChangeDetectionFn)();
87
+ if (!provideZonelessChangeDetectionFn) {
88
+ throw new Error('Zoneless change detection requires Angular 18 or higher');
121
89
  }
122
90
  else {
123
- providers.unshift(provideExperimentalZonelessChangeDetection());
91
+ providers.unshift(provideZonelessChangeDetectionFn());
124
92
  }
125
93
  }
126
94
  const applicationRef = await (0, BootstrapQueue_1.queueBootstrapping)(() => {
@@ -5,6 +5,7 @@ import { getApplication } from './StorybookModule';
5
5
  import { storyPropsProvider } from './StorybookProvider';
6
6
  import { queueBootstrapping } from './utils/BootstrapQueue';
7
7
  import { PropertyExtractor } from './utils/PropertyExtractor';
8
+ import { getProvideZonelessChangeDetectionFn } from './utils/Zoneless';
8
9
  const applicationRefs = new Map();
9
10
  /**
10
11
  * Attribute name for the story UID that may be written to the targetDOMNode.
@@ -79,12 +80,12 @@ export class AbstractRenderer {
79
80
  ...(storyFnAngular.applicationConfig?.providers ?? []),
80
81
  ];
81
82
  if (STORYBOOK_ANGULAR_OPTIONS?.experimentalZoneless) {
82
- const { provideExperimentalZonelessChangeDetection } = await import('@angular/core');
83
- if (!provideExperimentalZonelessChangeDetection) {
84
- throw new Error('Experimental zoneless change detection requires Angular 18 or higher');
83
+ const provideZonelessChangeDetectionFn = await getProvideZonelessChangeDetectionFn();
84
+ if (!provideZonelessChangeDetectionFn) {
85
+ throw new Error('Zoneless change detection requires Angular 18 or higher');
85
86
  }
86
87
  else {
87
- providers.unshift(provideExperimentalZonelessChangeDetection());
88
+ providers.unshift(provideZonelessChangeDetectionFn());
88
89
  }
89
90
  }
90
91
  const applicationRef = await queueBootstrapping(() => {
@@ -0,0 +1 @@
1
+ export declare const getProvideZonelessChangeDetectionFn: () => Promise<any>;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getProvideZonelessChangeDetectionFn = void 0;
37
+ const getProvideZonelessChangeDetectionFn = async () => {
38
+ const angularCore = await Promise.resolve().then(() => __importStar(require('@angular/core')));
39
+ return 'provideExperimentalZonelessChangeDetection' in angularCore
40
+ ? angularCore.provideExperimentalZonelessChangeDetection
41
+ : 'provideZonelessChangeDetection' in angularCore
42
+ ? angularCore.provideZonelessChangeDetection
43
+ : null;
44
+ };
45
+ exports.getProvideZonelessChangeDetectionFn = getProvideZonelessChangeDetectionFn;
@@ -0,0 +1,8 @@
1
+ export const getProvideZonelessChangeDetectionFn = async () => {
2
+ const angularCore = await import('@angular/core');
3
+ return 'provideExperimentalZonelessChangeDetection' in angularCore
4
+ ? angularCore.provideExperimentalZonelessChangeDetection
5
+ : 'provideZonelessChangeDetection' in angularCore
6
+ ? angularCore.provideZonelessChangeDetection
7
+ : null;
8
+ };
@@ -15,6 +15,98 @@ const { getCommonConfig, getStylesConfig, getDevServerConfig, getTypeScriptConfi
15
15
  */
16
16
  exports.getWebpackConfig = async (baseConfig, { builderOptions, builderContext }) => {
17
17
  /** Get angular-cli Webpack config */
18
+ /**
19
+ * Custom styles config that handles Tailwind 4 compatibility issues.
20
+ *
21
+ * Problem: Angular's getStylesConfig() doesn't support Tailwind 4's new PostCSS plugin
22
+ * architecture. When Tailwind 4 is detected, Angular tries to load it using the old v3 API which
23
+ * throws errors.
24
+ *
25
+ * Solution: Detect Tailwind 4, bypass Angular's automatic Tailwind detection by hiding config
26
+ * files, then manually inject the correct Tailwind 4 PostCSS plugin into the webpack
27
+ * configuration.
28
+ */
29
+ async function getCustomStylesConfig(wco) {
30
+ const { root } = wco;
31
+ /**
32
+ * Detect if Tailwind 4 is being used by checking for the new @tailwindcss/postcss package.
33
+ * Tailwind 4 uses @tailwindcss/postcss instead of the main tailwindcss package for PostCSS
34
+ * integration.
35
+ */
36
+ const isTailwind4 = () => {
37
+ try {
38
+ require.resolve('@tailwindcss/postcss', { paths: [root] });
39
+ return true;
40
+ }
41
+ catch {
42
+ return false;
43
+ }
44
+ };
45
+ if (isTailwind4()) {
46
+ // Monkey patch readdir to make findTailwindConfigurationFile return undefined
47
+ const fs = require('node:fs/promises');
48
+ const originalReaddir = fs.readdir;
49
+ /**
50
+ * Hide Tailwind config files from Angular's automatic detection. This prevents Angular from
51
+ * trying to load Tailwind using the incompatible v3 API. By filtering out tailwind config
52
+ * files, findTailwindConfigurationFile() returns undefined, and Angular skips its built-in
53
+ * Tailwind setup entirely.
54
+ */
55
+ fs.readdir = async function (path, options) {
56
+ const results = await originalReaddir.call(this, path, options);
57
+ const tailwindFiles = [
58
+ 'tailwind.config.js',
59
+ 'tailwind.config.cjs',
60
+ 'tailwind.config.mjs',
61
+ 'tailwind.config.ts',
62
+ ];
63
+ // Filter out tailwind config files from the results
64
+ return results.filter((file) => !tailwindFiles.includes(file));
65
+ };
66
+ // Get styles config without Tailwind interference
67
+ const styleConfig = await getStylesConfig(wco);
68
+ // Restore original readdir immediately after getting styles config
69
+ fs.readdir = originalReaddir;
70
+ /**
71
+ * Manually inject Tailwind 4 PostCSS plugin into the webpack configuration. Since we bypassed
72
+ * Angular's automatic Tailwind detection, we need to manually add the correct Tailwind 4
73
+ * plugin to all PostCSS loader configurations.
74
+ */
75
+ const tailwindPackagePath = require.resolve('@tailwindcss/postcss', { paths: [root] });
76
+ const extraPostcssPlugins = [require(tailwindPackagePath)()];
77
+ /**
78
+ * Navigate through webpack's complex rule structure to find all postcss-loader instances and
79
+ * inject the Tailwind 4 plugin. This preserves Angular's existing PostCSS setup while adding
80
+ * Tailwind 4 support.
81
+ */
82
+ styleConfig.module.rules
83
+ .map((rule) => rule.rules)
84
+ .forEach((rule) => {
85
+ rule.forEach((r) => {
86
+ r.oneOf?.forEach?.((oneOfRule) => {
87
+ return oneOfRule.use.forEach((use) => {
88
+ if (use.loader.includes('postcss-loader') && use.options.postcssOptions) {
89
+ const originalOptionsFn = use.options.postcssOptions;
90
+ // Wrap the original postcssOptions function to append Tailwind 4 plugin
91
+ use.options.postcssOptions = (loaderOptions) => {
92
+ const originalOptions = originalOptionsFn(loaderOptions);
93
+ return {
94
+ ...originalOptions,
95
+ plugins: [...originalOptions.plugins, ...extraPostcssPlugins],
96
+ };
97
+ };
98
+ }
99
+ });
100
+ });
101
+ });
102
+ });
103
+ return styleConfig;
104
+ }
105
+ else {
106
+ // Use Angular's default styles config for Tailwind v3 and other CSS frameworks
107
+ return getStylesConfig(wco);
108
+ }
109
+ }
18
110
  const { config: cliConfig } = await generateI18nBrowserWebpackConfigFromContext({
19
111
  // Default options
20
112
  index: 'noop-index',
@@ -35,7 +127,7 @@ exports.getWebpackConfig = async (baseConfig, { builderOptions, builderContext }
35
127
  aot: false,
36
128
  }, builderContext, (wco) => [
37
129
  getCommonConfig(wco),
38
- getStylesConfig(wco),
130
+ getCustomStylesConfig(wco),
39
131
  getTypeScriptConfig ? getTypeScriptConfig(wco) : getDevServerConfig(wco),
40
132
  ]);
41
133
  if (!builderOptions.experimentalZoneless && !cliConfig.entry.polyfills?.includes('zone.js')) {
@@ -15,6 +15,98 @@ const { getCommonConfig, getStylesConfig, getDevServerConfig, getTypeScriptConfi
15
15
  */
16
16
  exports.getWebpackConfig = async (baseConfig, { builderOptions, builderContext }) => {
17
17
  /** Get angular-cli Webpack config */
18
+ /**
19
+ * Custom styles config that handles Tailwind 4 compatibility issues.
20
+ *
21
+ * Problem: Angular's getStylesConfig() doesn't support Tailwind 4's new PostCSS plugin
22
+ * architecture. When Tailwind 4 is detected, Angular tries to load it using the old v3 API which
23
+ * throws errors.
24
+ *
25
+ * Solution: Detect Tailwind 4, bypass Angular's automatic Tailwind detection by hiding config
26
+ * files, then manually inject the correct Tailwind 4 PostCSS plugin into the webpack
27
+ * configuration.
28
+ */
29
+ async function getCustomStylesConfig(wco) {
30
+ const { root } = wco;
31
+ /**
32
+ * Detect if Tailwind 4 is being used by checking for the new @tailwindcss/postcss package.
33
+ * Tailwind 4 uses @tailwindcss/postcss instead of the main tailwindcss package for PostCSS
34
+ * integration.
35
+ */
36
+ const isTailwind4 = () => {
37
+ try {
38
+ require.resolve('@tailwindcss/postcss', { paths: [root] });
39
+ return true;
40
+ }
41
+ catch {
42
+ return false;
43
+ }
44
+ };
45
+ if (isTailwind4()) {
46
+ // Monkey patch readdir to make findTailwindConfigurationFile return undefined
47
+ const fs = require('node:fs/promises');
48
+ const originalReaddir = fs.readdir;
49
+ /**
50
+ * Hide Tailwind config files from Angular's automatic detection. This prevents Angular from
51
+ * trying to load Tailwind using the incompatible v3 API. By filtering out tailwind config
52
+ * files, findTailwindConfigurationFile() returns undefined, and Angular skips its built-in
53
+ * Tailwind setup entirely.
54
+ */
55
+ fs.readdir = async function (path, options) {
56
+ const results = await originalReaddir.call(this, path, options);
57
+ const tailwindFiles = [
58
+ 'tailwind.config.js',
59
+ 'tailwind.config.cjs',
60
+ 'tailwind.config.mjs',
61
+ 'tailwind.config.ts',
62
+ ];
63
+ // Filter out tailwind config files from the results
64
+ return results.filter((file) => !tailwindFiles.includes(file));
65
+ };
66
+ // Get styles config without Tailwind interference
67
+ const styleConfig = await getStylesConfig(wco);
68
+ // Restore original readdir immediately after getting styles config
69
+ fs.readdir = originalReaddir;
70
+ /**
71
+ * Manually inject Tailwind 4 PostCSS plugin into the webpack configuration. Since we bypassed
72
+ * Angular's automatic Tailwind detection, we need to manually add the correct Tailwind 4
73
+ * plugin to all PostCSS loader configurations.
74
+ */
75
+ const tailwindPackagePath = require.resolve('@tailwindcss/postcss', { paths: [root] });
76
+ const extraPostcssPlugins = [require(tailwindPackagePath)()];
77
+ /**
78
+ * Navigate through webpack's complex rule structure to find all postcss-loader instances and
79
+ * inject the Tailwind 4 plugin. This preserves Angular's existing PostCSS setup while adding
80
+ * Tailwind 4 support.
81
+ */
82
+ styleConfig.module.rules
83
+ .map((rule) => rule.rules)
84
+ .forEach((rule) => {
85
+ rule.forEach((r) => {
86
+ r.oneOf?.forEach?.((oneOfRule) => {
87
+ return oneOfRule.use.forEach((use) => {
88
+ if (use.loader.includes('postcss-loader') && use.options.postcssOptions) {
89
+ const originalOptionsFn = use.options.postcssOptions;
90
+ // Wrap the original postcssOptions function to append Tailwind 4 plugin
91
+ use.options.postcssOptions = (loaderOptions) => {
92
+ const originalOptions = originalOptionsFn(loaderOptions);
93
+ return {
94
+ ...originalOptions,
95
+ plugins: [...originalOptions.plugins, ...extraPostcssPlugins],
96
+ };
97
+ };
98
+ }
99
+ });
100
+ });
101
+ });
102
+ });
103
+ return styleConfig;
104
+ }
105
+ else {
106
+ // Use Angular's default styles config for Tailwind v3 and other CSS frameworks
107
+ return getStylesConfig(wco);
108
+ }
109
+ }
18
110
  const { config: cliConfig } = await generateI18nBrowserWebpackConfigFromContext({
19
111
  // Default options
20
112
  index: 'noop-index',
@@ -35,7 +127,7 @@ exports.getWebpackConfig = async (baseConfig, { builderOptions, builderContext }
35
127
  aot: false,
36
128
  }, builderContext, (wco) => [
37
129
  getCommonConfig(wco),
38
- getStylesConfig(wco),
130
+ getCustomStylesConfig(wco),
39
131
  getTypeScriptConfig ? getTypeScriptConfig(wco) : getDevServerConfig(wco),
40
132
  ]);
41
133
  if (!builderOptions.experimentalZoneless && !cliConfig.entry.polyfills?.includes('zone.js')) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/angular",
3
- "version": "9.0.10",
3
+ "version": "9.0.11",
4
4
  "description": "Storybook for Angular: Develop Angular components in isolation with hot reloading.",
5
5
  "keywords": [
6
6
  "storybook",
@@ -52,8 +52,8 @@
52
52
  "prep": "rimraf dist && jiti ../../../scripts/prepare/tsc.ts"
53
53
  },
54
54
  "dependencies": {
55
- "@storybook/builder-webpack5": "9.0.10",
56
- "@storybook/core-webpack": "9.0.10",
55
+ "@storybook/builder-webpack5": "9.0.11",
56
+ "@storybook/core-webpack": "9.0.11",
57
57
  "@storybook/global": "^5.0.0",
58
58
  "@types/webpack-env": "^1.18.0",
59
59
  "fd-package-json": "^1.2.0",
@@ -96,7 +96,7 @@
96
96
  "@angular/platform-browser": ">=18.0.0 < 21.0.0",
97
97
  "@angular/platform-browser-dynamic": ">=18.0.0 < 21.0.0",
98
98
  "rxjs": "^6.5.3 || ^7.4.0",
99
- "storybook": "^9.0.10",
99
+ "storybook": "^9.0.11",
100
100
  "typescript": "^4.9.0 || ^5.0.0",
101
101
  "zone.js": ">=0.14.0"
102
102
  },