@storybook/react 6.5.0-alpha.55 → 6.5.0-alpha.58

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.
@@ -7,7 +7,7 @@ exports.storiesOf = exports.setAddon = exports.raw = exports.getStorybook = expo
7
7
 
8
8
  require("core-js/modules/es.array.concat.js");
9
9
 
10
- var _client = require("@storybook/core/client");
10
+ var _core = require("@storybook/core");
11
11
 
12
12
  require("./globals");
13
13
 
@@ -15,7 +15,7 @@ var _render = require("./render");
15
15
 
16
16
  /* eslint-disable prefer-destructuring */
17
17
  var framework = 'react';
18
- var api = (0, _client.start)(_render.renderToDOM, {
18
+ var api = (0, _core.start)(_render.renderToDOM, {
19
19
  render: _render.render
20
20
  });
21
21
 
@@ -2,20 +2,14 @@
2
2
 
3
3
  function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
4
4
 
5
- require("core-js/modules/es.object.get-prototype-of.js");
6
-
7
- require("core-js/modules/es.reflect.construct.js");
8
-
9
- require("core-js/modules/es.array.iterator.js");
10
-
11
- require("core-js/modules/es.string.iterator.js");
12
-
13
5
  require("core-js/modules/es.weak-map.js");
14
6
 
15
- require("core-js/modules/web.dom-collections.iterator.js");
16
-
17
7
  require("core-js/modules/es.object.get-own-property-descriptor.js");
18
8
 
9
+ require("core-js/modules/es.object.get-prototype-of.js");
10
+
11
+ require("core-js/modules/es.reflect.construct.js");
12
+
19
13
  require("core-js/modules/es.symbol.js");
20
14
 
21
15
  require("core-js/modules/es.symbol.description.js");
@@ -30,21 +24,27 @@ exports.renderToDOM = renderToDOM;
30
24
 
31
25
  require("regenerator-runtime/runtime.js");
32
26
 
27
+ require("core-js/modules/es.array.iterator.js");
28
+
29
+ require("core-js/modules/es.map.js");
30
+
33
31
  require("core-js/modules/es.object.to-string.js");
34
32
 
33
+ require("core-js/modules/es.string.iterator.js");
34
+
35
+ require("core-js/modules/web.dom-collections.iterator.js");
36
+
35
37
  require("core-js/modules/es.promise.js");
36
38
 
39
+ require("core-js/modules/es.string.starts-with.js");
40
+
37
41
  require("core-js/modules/es.array.concat.js");
38
42
 
39
43
  var _global = _interopRequireDefault(require("global"));
40
44
 
41
45
  var _react = _interopRequireWildcard(require("react"));
42
46
 
43
- var _reactDom = _interopRequireDefault(require("react-dom"));
44
-
45
- function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
46
-
47
- function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
47
+ var _reactDom = _interopRequireWildcard(require("react-dom"));
48
48
 
49
49
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
50
50
 
@@ -68,11 +68,17 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
68
68
 
69
69
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
70
70
 
71
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
72
+
73
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
74
+
71
75
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
72
76
 
73
77
  function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
74
78
 
75
- var FRAMEWORK_OPTIONS = _global.default.FRAMEWORK_OPTIONS;
79
+ var FRAMEWORK_OPTIONS = _global.default.FRAMEWORK_OPTIONS; // A map of all rendered React 18 nodes
80
+
81
+ var nodes = new Map();
76
82
 
77
83
  var render = function render(args, context) {
78
84
  var id = context.id,
@@ -89,17 +95,30 @@ exports.render = render;
89
95
 
90
96
  var renderElement = /*#__PURE__*/function () {
91
97
  var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(node, el) {
98
+ var root;
92
99
  return regeneratorRuntime.wrap(function _callee$(_context) {
93
100
  while (1) {
94
101
  switch (_context.prev = _context.next) {
95
102
  case 0:
103
+ _context.next = 2;
104
+ return getReactRoot(el);
105
+
106
+ case 2:
107
+ root = _context.sent;
96
108
  return _context.abrupt("return", new Promise(function (resolve) {
97
- _reactDom.default.render(node, el, function () {
98
- return resolve(null);
99
- });
109
+ if (root) {
110
+ root.render(node);
111
+ setTimeout(function () {
112
+ resolve(null);
113
+ }, 0);
114
+ } else {
115
+ _reactDom.default.render(node, el, function () {
116
+ return resolve(null);
117
+ });
118
+ }
100
119
  }));
101
120
 
102
- case 1:
121
+ case 4:
103
122
  case "end":
104
123
  return _context.stop();
105
124
  }
@@ -112,6 +131,70 @@ var renderElement = /*#__PURE__*/function () {
112
131
  };
113
132
  }();
114
133
 
134
+ var canUseNewReactRootApi = _reactDom.version.startsWith('18') || _reactDom.version.startsWith('0.0.0');
135
+
136
+ var shouldUseNewRootApi = (FRAMEWORK_OPTIONS === null || FRAMEWORK_OPTIONS === void 0 ? void 0 : FRAMEWORK_OPTIONS.legacyRootApi) !== true;
137
+ var isUsingNewReactRootApi = shouldUseNewRootApi && canUseNewReactRootApi;
138
+
139
+ var unmountElement = function unmountElement(el) {
140
+ var root = nodes.get(el);
141
+
142
+ if (root && isUsingNewReactRootApi) {
143
+ root.unmount();
144
+ nodes.delete(el);
145
+ } else {
146
+ _reactDom.default.unmountComponentAtNode(el);
147
+ }
148
+ };
149
+
150
+ var getReactRoot = /*#__PURE__*/function () {
151
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(el) {
152
+ var root, reactDomClient;
153
+ return regeneratorRuntime.wrap(function _callee2$(_context2) {
154
+ while (1) {
155
+ switch (_context2.prev = _context2.next) {
156
+ case 0:
157
+ if (isUsingNewReactRootApi) {
158
+ _context2.next = 2;
159
+ break;
160
+ }
161
+
162
+ return _context2.abrupt("return", null);
163
+
164
+ case 2:
165
+ root = nodes.get(el);
166
+
167
+ if (root) {
168
+ _context2.next = 9;
169
+ break;
170
+ }
171
+
172
+ _context2.next = 6;
173
+ return Promise.resolve().then(function () {
174
+ return _interopRequireWildcard(require('react-dom/client'));
175
+ });
176
+
177
+ case 6:
178
+ reactDomClient = _context2.sent;
179
+ root = reactDomClient.createRoot(el);
180
+ nodes.set(el, root);
181
+
182
+ case 9:
183
+ return _context2.abrupt("return", root);
184
+
185
+ case 10:
186
+ case "end":
187
+ return _context2.stop();
188
+ }
189
+ }
190
+ }, _callee2);
191
+ }));
192
+
193
+ return function getReactRoot(_x3) {
194
+ return _ref2.apply(this, arguments);
195
+ };
196
+ }();
197
+
115
198
  var ErrorBoundary = /*#__PURE__*/function (_ReactComponent) {
116
199
  _inherits(ErrorBoundary, _ReactComponent);
117
200
 
@@ -171,18 +254,18 @@ var ErrorBoundary = /*#__PURE__*/function (_ReactComponent) {
171
254
 
172
255
  var Wrapper = FRAMEWORK_OPTIONS !== null && FRAMEWORK_OPTIONS !== void 0 && FRAMEWORK_OPTIONS.strictMode ? _react.StrictMode : _react.Fragment;
173
256
 
174
- function renderToDOM(_x3, _x4) {
257
+ function renderToDOM(_x4, _x5) {
175
258
  return _renderToDOM.apply(this, arguments);
176
259
  }
177
260
 
178
261
  function _renderToDOM() {
179
- _renderToDOM = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(_ref2, domElement) {
262
+ _renderToDOM = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(_ref3, domElement) {
180
263
  var storyContext, unboundStoryFn, showMain, showException, forceRemount, Story, content, element;
181
- return regeneratorRuntime.wrap(function _callee2$(_context2) {
264
+ return regeneratorRuntime.wrap(function _callee3$(_context3) {
182
265
  while (1) {
183
- switch (_context2.prev = _context2.next) {
266
+ switch (_context3.prev = _context3.next) {
184
267
  case 0:
185
- storyContext = _ref2.storyContext, unboundStoryFn = _ref2.unboundStoryFn, showMain = _ref2.showMain, showException = _ref2.showException, forceRemount = _ref2.forceRemount;
268
+ storyContext = _ref3.storyContext, unboundStoryFn = _ref3.unboundStoryFn, showMain = _ref3.showMain, showException = _ref3.showException, forceRemount = _ref3.forceRemount;
186
269
  Story = unboundStoryFn;
187
270
  content = /*#__PURE__*/_react.default.createElement(ErrorBoundary, {
188
271
  showMain: showMain,
@@ -196,18 +279,18 @@ function _renderToDOM() {
196
279
  // (This is not the case when we change args or globals to the story however)
197
280
 
198
281
  if (forceRemount) {
199
- _reactDom.default.unmountComponentAtNode(domElement);
282
+ unmountElement(domElement);
200
283
  }
201
284
 
202
- _context2.next = 7;
285
+ _context3.next = 7;
203
286
  return renderElement(element, domElement);
204
287
 
205
288
  case 7:
206
289
  case "end":
207
- return _context2.stop();
290
+ return _context3.stop();
208
291
  }
209
292
  }
210
- }, _callee2);
293
+ }, _callee3);
211
294
  }));
212
295
  return _renderToDOM.apply(this, arguments);
213
296
  }
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.webpackFinal = webpackFinal;
7
+
8
+ require("core-js/modules/es.promise.js");
9
+
10
+ var _fsExtra = require("fs-extra");
11
+
12
+ var _webpack = require("webpack");
13
+
14
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
15
+
16
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
17
+
18
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
19
+
20
+ // this is a hack to allow importing react-dom/client even when it's not available
21
+ // this should be removed once we drop support for react-dom < 18
22
+ async function webpackFinal(config) {
23
+ var reactDomPkg = await (0, _fsExtra.readJSON)(require.resolve('react-dom/package.json'));
24
+ return _objectSpread(_objectSpread({}, config), {}, {
25
+ plugins: [...config.plugins, reactDomPkg.version.startsWith('18') || reactDomPkg.version.startsWith('0.0.0') ? null : new _webpack.IgnorePlugin({
26
+ resourceRegExp: /react-dom\/client$/,
27
+ contextRegExp: /(app\/react|@storybook\/react)/ // TODO this needs to work for both in our MONOREPO and in the user's NODE_MODULES
28
+
29
+ })].filter(Boolean)
30
+ });
31
+ }
@@ -12,5 +12,5 @@ var previewAnnotations = function (entries = []) {
12
12
  };
13
13
 
14
14
  exports.previewAnnotations = previewAnnotations;
15
- var addons = [require.resolve('./framework-preset-react'), require.resolve('./framework-preset-cra'), require.resolve('./framework-preset-react-docs')];
15
+ var addons = [require.resolve('./framework-preset-react'), require.resolve('./framework-preset-react-dom-hack'), require.resolve('./framework-preset-cra'), require.resolve('./framework-preset-react-docs')];
16
16
  exports.addons = addons;
@@ -1,7 +1,7 @@
1
1
  import "core-js/modules/es.array.concat.js";
2
2
 
3
3
  /* eslint-disable prefer-destructuring */
4
- import { start } from '@storybook/core/client';
4
+ import { start } from '@storybook/core';
5
5
  import './globals';
6
6
  import { renderToDOM, render } from './render';
7
7
  var framework = 'react';
@@ -21,26 +21,30 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
21
21
  function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
22
22
 
23
23
  import "regenerator-runtime/runtime.js";
24
+
25
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
26
+
27
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
28
+
29
+ import "core-js/modules/es.array.iterator.js";
30
+ import "core-js/modules/es.map.js";
24
31
  import "core-js/modules/es.object.to-string.js";
32
+ import "core-js/modules/es.string.iterator.js";
33
+ import "core-js/modules/web.dom-collections.iterator.js";
25
34
  import "core-js/modules/es.promise.js";
35
+ import "core-js/modules/es.string.starts-with.js";
26
36
  import "core-js/modules/es.array.concat.js";
27
37
  import "core-js/modules/es.object.get-prototype-of.js";
28
38
  import "core-js/modules/es.reflect.construct.js";
29
39
  import "core-js/modules/es.symbol.js";
30
40
  import "core-js/modules/es.symbol.description.js";
31
41
  import "core-js/modules/es.symbol.iterator.js";
32
- import "core-js/modules/es.array.iterator.js";
33
- import "core-js/modules/es.string.iterator.js";
34
- import "core-js/modules/web.dom-collections.iterator.js";
35
-
36
- function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
37
-
38
- function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
39
-
40
42
  import global from 'global';
41
43
  import React, { Component as ReactComponent, StrictMode, Fragment } from 'react';
42
- import ReactDOM from 'react-dom';
43
- var FRAMEWORK_OPTIONS = global.FRAMEWORK_OPTIONS;
44
+ import ReactDOM, { version as reactDomVersion } from 'react-dom';
45
+ var FRAMEWORK_OPTIONS = global.FRAMEWORK_OPTIONS; // A map of all rendered React 18 nodes
46
+
47
+ var nodes = new Map();
44
48
  export var render = function render(args, context) {
45
49
  var id = context.id,
46
50
  Component = context.component;
@@ -54,17 +58,30 @@ export var render = function render(args, context) {
54
58
 
55
59
  var renderElement = /*#__PURE__*/function () {
56
60
  var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(node, el) {
61
+ var root;
57
62
  return regeneratorRuntime.wrap(function _callee$(_context) {
58
63
  while (1) {
59
64
  switch (_context.prev = _context.next) {
60
65
  case 0:
66
+ _context.next = 2;
67
+ return getReactRoot(el);
68
+
69
+ case 2:
70
+ root = _context.sent;
61
71
  return _context.abrupt("return", new Promise(function (resolve) {
62
- ReactDOM.render(node, el, function () {
63
- return resolve(null);
64
- });
72
+ if (root) {
73
+ root.render(node);
74
+ setTimeout(function () {
75
+ resolve(null);
76
+ }, 0);
77
+ } else {
78
+ ReactDOM.render(node, el, function () {
79
+ return resolve(null);
80
+ });
81
+ }
65
82
  }));
66
83
 
67
- case 1:
84
+ case 4:
68
85
  case "end":
69
86
  return _context.stop();
70
87
  }
@@ -77,6 +94,67 @@ var renderElement = /*#__PURE__*/function () {
77
94
  };
78
95
  }();
79
96
 
97
+ var canUseNewReactRootApi = reactDomVersion.startsWith('18') || reactDomVersion.startsWith('0.0.0');
98
+ var shouldUseNewRootApi = (FRAMEWORK_OPTIONS === null || FRAMEWORK_OPTIONS === void 0 ? void 0 : FRAMEWORK_OPTIONS.legacyRootApi) !== true;
99
+ var isUsingNewReactRootApi = shouldUseNewRootApi && canUseNewReactRootApi;
100
+
101
+ var unmountElement = function unmountElement(el) {
102
+ var root = nodes.get(el);
103
+
104
+ if (root && isUsingNewReactRootApi) {
105
+ root.unmount();
106
+ nodes.delete(el);
107
+ } else {
108
+ ReactDOM.unmountComponentAtNode(el);
109
+ }
110
+ };
111
+
112
+ var getReactRoot = /*#__PURE__*/function () {
113
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(el) {
114
+ var root, reactDomClient;
115
+ return regeneratorRuntime.wrap(function _callee2$(_context2) {
116
+ while (1) {
117
+ switch (_context2.prev = _context2.next) {
118
+ case 0:
119
+ if (isUsingNewReactRootApi) {
120
+ _context2.next = 2;
121
+ break;
122
+ }
123
+
124
+ return _context2.abrupt("return", null);
125
+
126
+ case 2:
127
+ root = nodes.get(el);
128
+
129
+ if (root) {
130
+ _context2.next = 9;
131
+ break;
132
+ }
133
+
134
+ _context2.next = 6;
135
+ return import('react-dom/client');
136
+
137
+ case 6:
138
+ reactDomClient = _context2.sent;
139
+ root = reactDomClient.createRoot(el);
140
+ nodes.set(el, root);
141
+
142
+ case 9:
143
+ return _context2.abrupt("return", root);
144
+
145
+ case 10:
146
+ case "end":
147
+ return _context2.stop();
148
+ }
149
+ }
150
+ }, _callee2);
151
+ }));
152
+
153
+ return function getReactRoot(_x3) {
154
+ return _ref2.apply(this, arguments);
155
+ };
156
+ }();
157
+
80
158
  var ErrorBoundary = /*#__PURE__*/function (_ReactComponent) {
81
159
  _inherits(ErrorBoundary, _ReactComponent);
82
160
 
@@ -135,18 +213,18 @@ var ErrorBoundary = /*#__PURE__*/function (_ReactComponent) {
135
213
  }(ReactComponent);
136
214
 
137
215
  var Wrapper = FRAMEWORK_OPTIONS !== null && FRAMEWORK_OPTIONS !== void 0 && FRAMEWORK_OPTIONS.strictMode ? StrictMode : Fragment;
138
- export function renderToDOM(_x3, _x4) {
216
+ export function renderToDOM(_x4, _x5) {
139
217
  return _renderToDOM.apply(this, arguments);
140
218
  }
141
219
 
142
220
  function _renderToDOM() {
143
- _renderToDOM = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(_ref2, domElement) {
221
+ _renderToDOM = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee3(_ref3, domElement) {
144
222
  var storyContext, unboundStoryFn, showMain, showException, forceRemount, Story, content, element;
145
- return regeneratorRuntime.wrap(function _callee2$(_context2) {
223
+ return regeneratorRuntime.wrap(function _callee3$(_context3) {
146
224
  while (1) {
147
- switch (_context2.prev = _context2.next) {
225
+ switch (_context3.prev = _context3.next) {
148
226
  case 0:
149
- storyContext = _ref2.storyContext, unboundStoryFn = _ref2.unboundStoryFn, showMain = _ref2.showMain, showException = _ref2.showException, forceRemount = _ref2.forceRemount;
227
+ storyContext = _ref3.storyContext, unboundStoryFn = _ref3.unboundStoryFn, showMain = _ref3.showMain, showException = _ref3.showException, forceRemount = _ref3.forceRemount;
150
228
  Story = unboundStoryFn;
151
229
  content = /*#__PURE__*/React.createElement(ErrorBoundary, {
152
230
  showMain: showMain,
@@ -160,18 +238,18 @@ function _renderToDOM() {
160
238
  // (This is not the case when we change args or globals to the story however)
161
239
 
162
240
  if (forceRemount) {
163
- ReactDOM.unmountComponentAtNode(domElement);
241
+ unmountElement(domElement);
164
242
  }
165
243
 
166
- _context2.next = 7;
244
+ _context3.next = 7;
167
245
  return renderElement(element, domElement);
168
246
 
169
247
  case 7:
170
248
  case "end":
171
- return _context2.stop();
249
+ return _context3.stop();
172
250
  }
173
251
  }
174
- }, _callee2);
252
+ }, _callee3);
175
253
  }));
176
254
  return _renderToDOM.apply(this, arguments);
177
255
  }
@@ -0,0 +1,21 @@
1
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
2
+
3
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
+
5
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
+
7
+ import "core-js/modules/es.promise.js";
8
+ import { readJSON } from 'fs-extra';
9
+ import { IgnorePlugin } from 'webpack'; // this is a hack to allow importing react-dom/client even when it's not available
10
+ // this should be removed once we drop support for react-dom < 18
11
+
12
+ export async function webpackFinal(config) {
13
+ var reactDomPkg = await readJSON(require.resolve('react-dom/package.json'));
14
+ return _objectSpread(_objectSpread({}, config), {}, {
15
+ plugins: [...config.plugins, reactDomPkg.version.startsWith('18') || reactDomPkg.version.startsWith('0.0.0') ? null : new IgnorePlugin({
16
+ resourceRegExp: /react-dom\/client$/,
17
+ contextRegExp: /(app\/react|@storybook\/react)/ // TODO this needs to work for both in our MONOREPO and in the user's NODE_MODULES
18
+
19
+ })].filter(Boolean)
20
+ });
21
+ }
@@ -2,4 +2,4 @@ import { findDistEsm } from '@storybook/core-common';
2
2
  export var previewAnnotations = function (entries = []) {
3
3
  return [...entries, findDistEsm(__dirname, 'client/preview/config')];
4
4
  };
5
- export var addons = [require.resolve('./framework-preset-react'), require.resolve('./framework-preset-cra'), require.resolve('./framework-preset-react-docs')];
5
+ export var addons = [require.resolve('./framework-preset-react'), require.resolve('./framework-preset-react-dom-hack'), require.resolve('./framework-preset-cra'), require.resolve('./framework-preset-react-docs')];
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable prefer-destructuring */
2
- import { start } from '@storybook/core/client';
2
+ import { start } from '@storybook/core';
3
3
  import './globals';
4
4
  import { renderToDOM, render } from './render';
5
5
  const framework = 'react';
@@ -1,9 +1,11 @@
1
1
  import global from 'global';
2
2
  import React, { Component as ReactComponent, StrictMode, Fragment } from 'react';
3
- import ReactDOM from 'react-dom';
3
+ import ReactDOM, { version as reactDomVersion } from 'react-dom';
4
4
  const {
5
5
  FRAMEWORK_OPTIONS
6
- } = global;
6
+ } = global; // A map of all rendered React 18 nodes
7
+
8
+ const nodes = new Map();
7
9
  export const render = (args, context) => {
8
10
  const {
9
11
  id,
@@ -17,9 +19,53 @@ export const render = (args, context) => {
17
19
  return /*#__PURE__*/React.createElement(Component, args);
18
20
  };
19
21
 
20
- const renderElement = async (node, el) => new Promise(resolve => {
21
- ReactDOM.render(node, el, () => resolve(null));
22
- });
22
+ const renderElement = async (node, el) => {
23
+ // Create Root Element conditionally for new React 18 Root Api
24
+ const root = await getReactRoot(el);
25
+ return new Promise(resolve => {
26
+ if (root) {
27
+ root.render(node);
28
+ setTimeout(() => {
29
+ resolve(null);
30
+ }, 0);
31
+ } else {
32
+ ReactDOM.render(node, el, () => resolve(null));
33
+ }
34
+ });
35
+ };
36
+
37
+ const canUseNewReactRootApi = reactDomVersion.startsWith('18') || reactDomVersion.startsWith('0.0.0');
38
+ const shouldUseNewRootApi = (FRAMEWORK_OPTIONS === null || FRAMEWORK_OPTIONS === void 0 ? void 0 : FRAMEWORK_OPTIONS.legacyRootApi) !== true;
39
+ const isUsingNewReactRootApi = shouldUseNewRootApi && canUseNewReactRootApi;
40
+
41
+ const unmountElement = el => {
42
+ const root = nodes.get(el);
43
+
44
+ if (root && isUsingNewReactRootApi) {
45
+ root.unmount();
46
+ nodes.delete(el);
47
+ } else {
48
+ ReactDOM.unmountComponentAtNode(el);
49
+ }
50
+ };
51
+
52
+ const getReactRoot = async el => {
53
+ if (!isUsingNewReactRootApi) {
54
+ return null;
55
+ }
56
+
57
+ let root = nodes.get(el);
58
+
59
+ if (!root) {
60
+ // Skipping webpack's static analysis of import paths by defining the path value outside the import statement.
61
+ // eslint-disable-next-line import/no-unresolved
62
+ const reactDomClient = await import('react-dom/client');
63
+ root = reactDomClient.createRoot(el);
64
+ nodes.set(el, root);
65
+ }
66
+
67
+ return root;
68
+ };
23
69
 
24
70
  class ErrorBoundary extends ReactComponent {
25
71
  constructor(...args) {
@@ -89,7 +135,7 @@ export async function renderToDOM({
89
135
  // (This is not the case when we change args or globals to the story however)
90
136
 
91
137
  if (forceRemount) {
92
- ReactDOM.unmountComponentAtNode(domElement);
138
+ unmountElement(domElement);
93
139
  }
94
140
 
95
141
  await renderElement(element, domElement);
@@ -0,0 +1,21 @@
1
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
2
+
3
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
4
+
5
+ function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
+
7
+ import "core-js/modules/es.promise.js";
8
+ import { readJSON } from 'fs-extra';
9
+ import { IgnorePlugin } from 'webpack'; // this is a hack to allow importing react-dom/client even when it's not available
10
+ // this should be removed once we drop support for react-dom < 18
11
+
12
+ export async function webpackFinal(config) {
13
+ var reactDomPkg = await readJSON(require.resolve('react-dom/package.json'));
14
+ return _objectSpread(_objectSpread({}, config), {}, {
15
+ plugins: [...config.plugins, reactDomPkg.version.startsWith('18') || reactDomPkg.version.startsWith('0.0.0') ? null : new IgnorePlugin({
16
+ resourceRegExp: /react-dom\/client$/,
17
+ contextRegExp: /(app\/react|@storybook\/react)/ // TODO this needs to work for both in our MONOREPO and in the user's NODE_MODULES
18
+
19
+ })].filter(Boolean)
20
+ });
21
+ }
@@ -2,4 +2,4 @@ import { findDistEsm } from '@storybook/core-common';
2
2
  export var previewAnnotations = function (entries = []) {
3
3
  return [...entries, findDistEsm(__dirname, 'client/preview/config')];
4
4
  };
5
- export var addons = [require.resolve('./framework-preset-react'), require.resolve('./framework-preset-cra'), require.resolve('./framework-preset-react-docs')];
5
+ export var addons = [require.resolve('./framework-preset-react'), require.resolve('./framework-preset-react-dom-hack'), require.resolve('./framework-preset-cra'), require.resolve('./framework-preset-react-docs')];
@@ -0,0 +1,32 @@
1
+ import { Configuration } from 'webpack';
2
+ export declare function webpackFinal(config: Configuration): Promise<{
3
+ plugins: import("webpack").Plugin[];
4
+ mode?: "none" | "production" | "development";
5
+ name?: string;
6
+ context?: string;
7
+ entry?: string | string[] | import("webpack").Entry | import("webpack").EntryFunc;
8
+ devtool?: string | boolean;
9
+ output?: import("webpack").Output;
10
+ module?: import("webpack").Module;
11
+ resolve?: import("webpack").Resolve;
12
+ resolveLoader?: import("webpack").ResolveLoader;
13
+ externals?: string | RegExp | import("webpack").ExternalsObjectElement | import("webpack").ExternalsFunctionElement | import("webpack").ExternalsElement[];
14
+ target?: "node" | "web" | "webworker" | "async-node" | "node-webkit" | "atom" | "electron" | "electron-renderer" | "electron-preload" | "electron-main" | ((compiler?: any) => void);
15
+ bail?: boolean;
16
+ profile?: boolean;
17
+ cache?: boolean | object;
18
+ watch?: boolean;
19
+ watchOptions?: import("webpack").ICompiler.WatchOptions;
20
+ node?: false | import("webpack").Node;
21
+ amd?: {
22
+ [moduleName: string]: boolean;
23
+ };
24
+ recordsPath?: string;
25
+ recordsInputPath?: string;
26
+ recordsOutputPath?: string;
27
+ stats?: import("webpack").Stats.ToStringOptions;
28
+ performance?: false | import("webpack").Options.Performance;
29
+ parallelism?: number;
30
+ optimization?: import("webpack").Options.Optimization;
31
+ infrastructureLogging?: import("webpack").Options.InfrastructureLogging;
32
+ }>;
@@ -1,4 +1,4 @@
1
- import { RenderContext } from '@storybook/store';
1
+ import type { RenderContext } from '@storybook/store';
2
2
  import { ArgsStoryFn } from '@storybook/csf';
3
3
  import { ReactFramework } from './types-6-0';
4
4
  export declare const render: ArgsStoryFn<ReactFramework>;
@@ -0,0 +1,32 @@
1
+ import { Configuration } from 'webpack';
2
+ export declare function webpackFinal(config: Configuration): Promise<{
3
+ plugins: import("webpack").Plugin[];
4
+ mode?: "none" | "production" | "development";
5
+ name?: string;
6
+ context?: string;
7
+ entry?: string | string[] | import("webpack").Entry | import("webpack").EntryFunc;
8
+ devtool?: string | boolean;
9
+ output?: import("webpack").Output;
10
+ module?: import("webpack").Module;
11
+ resolve?: import("webpack").Resolve;
12
+ resolveLoader?: import("webpack").ResolveLoader;
13
+ externals?: string | RegExp | import("webpack").ExternalsObjectElement | import("webpack").ExternalsFunctionElement | import("webpack").ExternalsElement[];
14
+ target?: "node" | "web" | "webworker" | "async-node" | "node-webkit" | "atom" | "electron" | "electron-renderer" | "electron-preload" | "electron-main" | ((compiler?: any) => void);
15
+ bail?: boolean;
16
+ profile?: boolean;
17
+ cache?: boolean | object;
18
+ watch?: boolean;
19
+ watchOptions?: import("webpack").ICompiler.WatchOptions;
20
+ node?: false | import("webpack").Node;
21
+ amd?: {
22
+ [moduleName: string]: boolean;
23
+ };
24
+ recordsPath?: string;
25
+ recordsInputPath?: string;
26
+ recordsOutputPath?: string;
27
+ stats?: import("webpack").Stats.ToStringOptions;
28
+ performance?: false | import("webpack").Options.Performance;
29
+ parallelism?: number;
30
+ optimization?: import("webpack").Options.Optimization;
31
+ infrastructureLogging?: import("webpack").Options.InfrastructureLogging;
32
+ }>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/react",
3
- "version": "6.5.0-alpha.55",
3
+ "version": "6.5.0-alpha.58",
4
4
  "description": "Storybook for React: Develop React Component in isolation with Hot Reloading.",
5
5
  "keywords": [
6
6
  "storybook"
@@ -49,16 +49,16 @@
49
49
  "@babel/preset-flow": "^7.12.1",
50
50
  "@babel/preset-react": "^7.12.10",
51
51
  "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3",
52
- "@storybook/addons": "6.5.0-alpha.55",
53
- "@storybook/client-logger": "6.5.0-alpha.55",
54
- "@storybook/core": "6.5.0-alpha.55",
55
- "@storybook/core-common": "6.5.0-alpha.55",
56
- "@storybook/csf": "0.0.2--canary.507502b.0",
57
- "@storybook/docs-tools": "6.5.0-alpha.55",
58
- "@storybook/node-logger": "6.5.0-alpha.55",
52
+ "@storybook/addons": "6.5.0-alpha.58",
53
+ "@storybook/client-logger": "6.5.0-alpha.58",
54
+ "@storybook/core": "6.5.0-alpha.58",
55
+ "@storybook/core-common": "6.5.0-alpha.58",
56
+ "@storybook/csf": "0.0.2--canary.7c6c115.0",
57
+ "@storybook/docs-tools": "6.5.0-alpha.58",
58
+ "@storybook/node-logger": "6.5.0-alpha.58",
59
59
  "@storybook/react-docgen-typescript-plugin": "1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0",
60
60
  "@storybook/semver": "^7.3.2",
61
- "@storybook/store": "6.5.0-alpha.55",
61
+ "@storybook/store": "6.5.0-alpha.58",
62
62
  "@types/estree": "^0.0.51",
63
63
  "@types/node": "^14.14.20 || ^16.0.0",
64
64
  "@types/webpack-env": "^1.16.0",
@@ -69,6 +69,7 @@
69
69
  "babel-plugin-react-docgen": "^4.2.1",
70
70
  "core-js": "^3.8.2",
71
71
  "escodegen": "^2.0.0",
72
+ "fs-extra": "^9.0.1",
72
73
  "global": "^4.4.0",
73
74
  "html-tags": "^3.1.0",
74
75
  "lodash": "^4.17.21",
@@ -118,6 +119,6 @@
118
119
  "publishConfig": {
119
120
  "access": "public"
120
121
  },
121
- "gitHead": "0d051c3d8efb90e15d8734e6e6914b2439420953",
122
+ "gitHead": "bf25496b2d3d2daa91ab211a9b73b1f4d5b0b52d",
122
123
  "sbmodern": "dist/modern/client/index.js"
123
124
  }
package/types/index.ts CHANGED
@@ -7,5 +7,13 @@ export interface StorybookConfig extends BaseConfig {
7
7
  reactOptions?: {
8
8
  fastRefresh?: boolean;
9
9
  strictMode?: boolean;
10
+ /**
11
+ * Use React's legacy root API to mount components
12
+ * @description
13
+ * React has introduced a new root API with React 18.x to enable a whole set of new features (e.g. concurrent features)
14
+ * If this flag is true, the legacy Root API is used to mount components to make it easier to migrate step by step to React 18.
15
+ * @default false
16
+ */
17
+ legacyRootApi?: boolean;
10
18
  };
11
19
  }