1 | function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
2 |
|
3 | function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
4 |
|
5 | function _iterableToArrayLimit(arr, i) { if (typeof Symbol === "undefined" || !(Symbol.iterator in Object(arr))) return; var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
6 |
|
7 | function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
8 |
|
9 | function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
|
10 |
|
11 | function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
12 |
|
13 | function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
14 |
|
15 | function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
|
16 |
|
17 | function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
18 |
|
19 | function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
|
20 |
|
21 | import "core-js/modules/es.weak-map.js";
|
22 | import "core-js/modules/es.object.to-string.js";
|
23 | import "core-js/modules/es.string.iterator.js";
|
24 | import "core-js/modules/es.array.iterator.js";
|
25 | import "core-js/modules/web.dom-collections.iterator.js";
|
26 | import "core-js/modules/es.set.js";
|
27 | import "core-js/modules/web.dom-collections.for-each.js";
|
28 | import "core-js/modules/es.array.includes.js";
|
29 | import "core-js/modules/es.string.includes.js";
|
30 | import "core-js/modules/es.function.name.js";
|
31 | import "core-js/modules/es.array.map.js";
|
32 | import "core-js/modules/es.array.concat.js";
|
33 | import "core-js/modules/es.object.entries.js";
|
34 | import "core-js/modules/es.object.keys.js";
|
35 | import "core-js/modules/es.symbol.js";
|
36 | import "core-js/modules/es.symbol.description.js";
|
37 | import "core-js/modules/es.symbol.iterator.js";
|
38 | import "core-js/modules/es.array.from.js";
|
39 | import "core-js/modules/es.array.slice.js";
|
40 |
|
41 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
42 |
|
43 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
|
44 |
|
45 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
|
46 |
|
47 | import global from 'global';
|
48 | import { logger } from '@storybook/client-logger';
|
49 | import { FORCE_RE_RENDER, STORY_RENDERED, UPDATE_STORY_ARGS, RESET_STORY_ARGS, UPDATE_GLOBALS } from '@storybook/core-events';
|
50 | import { addons } from './index';
|
51 | var globalWindow = global.window;
|
52 | export var HooksContext = function () {
|
53 | function HooksContext() {
|
54 | var _this = this;
|
55 |
|
56 | _classCallCheck(this, HooksContext);
|
57 |
|
58 | this.hookListsMap = void 0;
|
59 | this.mountedDecorators = void 0;
|
60 | this.prevMountedDecorators = void 0;
|
61 | this.currentHooks = void 0;
|
62 | this.nextHookIndex = void 0;
|
63 | this.currentPhase = void 0;
|
64 | this.currentEffects = void 0;
|
65 | this.prevEffects = void 0;
|
66 | this.currentDecoratorName = void 0;
|
67 | this.hasUpdates = void 0;
|
68 | this.currentContext = void 0;
|
69 |
|
70 | this.renderListener = function (storyId) {
|
71 | if (storyId !== _this.currentContext.id) return;
|
72 |
|
73 | _this.triggerEffects();
|
74 |
|
75 | _this.currentContext = null;
|
76 |
|
77 | _this.removeRenderListeners();
|
78 | };
|
79 |
|
80 | this.init();
|
81 | }
|
82 |
|
83 | _createClass(HooksContext, [{
|
84 | key: "init",
|
85 | value: function init() {
|
86 | this.hookListsMap = new WeakMap();
|
87 | this.mountedDecorators = new Set();
|
88 | this.prevMountedDecorators = this.mountedDecorators;
|
89 | this.currentHooks = [];
|
90 | this.nextHookIndex = 0;
|
91 | this.currentPhase = 'NONE';
|
92 | this.currentEffects = [];
|
93 | this.prevEffects = [];
|
94 | this.currentDecoratorName = null;
|
95 | this.hasUpdates = false;
|
96 | this.currentContext = null;
|
97 | }
|
98 | }, {
|
99 | key: "clean",
|
100 | value: function clean() {
|
101 | this.prevEffects.forEach(function (effect) {
|
102 | if (effect.destroy) {
|
103 | effect.destroy();
|
104 | }
|
105 | });
|
106 | this.init();
|
107 | this.removeRenderListeners();
|
108 | }
|
109 | }, {
|
110 | key: "getNextHook",
|
111 | value: function getNextHook() {
|
112 | var hook = this.currentHooks[this.nextHookIndex];
|
113 | this.nextHookIndex += 1;
|
114 | return hook;
|
115 | }
|
116 | }, {
|
117 | key: "triggerEffects",
|
118 | value: function triggerEffects() {
|
119 | var _this2 = this;
|
120 |
|
121 |
|
122 | this.prevEffects.forEach(function (effect) {
|
123 | if (!_this2.currentEffects.includes(effect) && effect.destroy) {
|
124 | effect.destroy();
|
125 | }
|
126 | });
|
127 |
|
128 | this.currentEffects.forEach(function (effect) {
|
129 | if (!_this2.prevEffects.includes(effect)) {
|
130 |
|
131 | effect.destroy = effect.create();
|
132 | }
|
133 | });
|
134 | this.prevEffects = this.currentEffects;
|
135 | this.currentEffects = [];
|
136 | }
|
137 | }, {
|
138 | key: "addRenderListeners",
|
139 | value: function addRenderListeners() {
|
140 | this.removeRenderListeners();
|
141 | var channel = addons.getChannel();
|
142 | channel.on(STORY_RENDERED, this.renderListener);
|
143 | }
|
144 | }, {
|
145 | key: "removeRenderListeners",
|
146 | value: function removeRenderListeners() {
|
147 | var channel = addons.getChannel();
|
148 | channel.removeListener(STORY_RENDERED, this.renderListener);
|
149 | }
|
150 | }]);
|
151 |
|
152 | return HooksContext;
|
153 | }();
|
154 |
|
155 | function hookify(fn) {
|
156 | return function () {
|
157 | var _ref = typeof (arguments.length <= 0 ? undefined : arguments[0]) === 'function' ? arguments.length <= 1 ? undefined : arguments[1] : arguments.length <= 0 ? undefined : arguments[0],
|
158 | hooks = _ref.hooks;
|
159 |
|
160 | var prevPhase = hooks.currentPhase;
|
161 | var prevHooks = hooks.currentHooks;
|
162 | var prevNextHookIndex = hooks.nextHookIndex;
|
163 | var prevDecoratorName = hooks.currentDecoratorName;
|
164 | hooks.currentDecoratorName = fn.name;
|
165 |
|
166 | if (hooks.prevMountedDecorators.has(fn)) {
|
167 | hooks.currentPhase = 'UPDATE';
|
168 | hooks.currentHooks = hooks.hookListsMap.get(fn) || [];
|
169 | } else {
|
170 | hooks.currentPhase = 'MOUNT';
|
171 | hooks.currentHooks = [];
|
172 | hooks.hookListsMap.set(fn, hooks.currentHooks);
|
173 | hooks.prevMountedDecorators.add(fn);
|
174 | }
|
175 |
|
176 | hooks.nextHookIndex = 0;
|
177 | var prevContext = globalWindow.STORYBOOK_HOOKS_CONTEXT;
|
178 | globalWindow.STORYBOOK_HOOKS_CONTEXT = hooks;
|
179 | var result = fn.apply(void 0, arguments);
|
180 | globalWindow.STORYBOOK_HOOKS_CONTEXT = prevContext;
|
181 |
|
182 | if (hooks.currentPhase === 'UPDATE' && hooks.getNextHook() != null) {
|
183 | throw new Error('Rendered fewer hooks than expected. This may be caused by an accidental early return statement.');
|
184 | }
|
185 |
|
186 | hooks.currentPhase = prevPhase;
|
187 | hooks.currentHooks = prevHooks;
|
188 | hooks.nextHookIndex = prevNextHookIndex;
|
189 | hooks.currentDecoratorName = prevDecoratorName;
|
190 | return result;
|
191 | };
|
192 | }
|
193 |
|
194 |
|
195 | var numberOfRenders = 0;
|
196 | var RENDER_LIMIT = 25;
|
197 | export var applyHooks = function applyHooks(applyDecorators) {
|
198 | return function (storyFn, decorators) {
|
199 | var decorated = applyDecorators(hookify(storyFn), decorators.map(function (decorator) {
|
200 | return hookify(decorator);
|
201 | }));
|
202 | return function (context) {
|
203 | var _ref2 = context,
|
204 | hooks = _ref2.hooks;
|
205 | hooks.prevMountedDecorators = hooks.mountedDecorators;
|
206 | hooks.mountedDecorators = new Set([storyFn].concat(_toConsumableArray(decorators)));
|
207 | hooks.currentContext = context;
|
208 | hooks.hasUpdates = false;
|
209 | var result = decorated(context);
|
210 | numberOfRenders = 1;
|
211 |
|
212 | while (hooks.hasUpdates) {
|
213 | hooks.hasUpdates = false;
|
214 | hooks.currentEffects = [];
|
215 | result = decorated(context);
|
216 | numberOfRenders += 1;
|
217 |
|
218 | if (numberOfRenders > RENDER_LIMIT) {
|
219 | throw new Error('Too many re-renders. Storybook limits the number of renders to prevent an infinite loop.');
|
220 | }
|
221 | }
|
222 |
|
223 | hooks.addRenderListeners();
|
224 | return result;
|
225 | };
|
226 | };
|
227 | };
|
228 |
|
229 | var areDepsEqual = function areDepsEqual(deps, nextDeps) {
|
230 | return deps.length === nextDeps.length && deps.every(function (dep, i) {
|
231 | return dep === nextDeps[i];
|
232 | });
|
233 | };
|
234 |
|
235 | var invalidHooksError = function invalidHooksError() {
|
236 | return new Error('Storybook preview hooks can only be called inside decorators and story functions.');
|
237 | };
|
238 |
|
239 | function getHooksContextOrNull() {
|
240 | return globalWindow.STORYBOOK_HOOKS_CONTEXT || null;
|
241 | }
|
242 |
|
243 | function getHooksContextOrThrow() {
|
244 | var hooks = getHooksContextOrNull();
|
245 |
|
246 | if (hooks == null) {
|
247 | throw invalidHooksError();
|
248 | }
|
249 |
|
250 | return hooks;
|
251 | }
|
252 |
|
253 | function useHook(name, callback, deps) {
|
254 | var hooks = getHooksContextOrThrow();
|
255 |
|
256 | if (hooks.currentPhase === 'MOUNT') {
|
257 | if (deps != null && !Array.isArray(deps)) {
|
258 | logger.warn("".concat(name, " received a final argument that is not an array (instead, received ").concat(deps, "). When specified, the final argument must be an array."));
|
259 | }
|
260 |
|
261 | var _hook = {
|
262 | name: name,
|
263 | deps: deps
|
264 | };
|
265 | hooks.currentHooks.push(_hook);
|
266 | callback(_hook);
|
267 | return _hook;
|
268 | }
|
269 |
|
270 | if (hooks.currentPhase === 'UPDATE') {
|
271 | var _hook2 = hooks.getNextHook();
|
272 |
|
273 | if (_hook2 == null) {
|
274 | throw new Error('Rendered more hooks than during the previous render.');
|
275 | }
|
276 |
|
277 | if (_hook2.name !== name) {
|
278 | logger.warn("Storybook has detected a change in the order of Hooks".concat(hooks.currentDecoratorName ? " called by ".concat(hooks.currentDecoratorName) : '', ". This will lead to bugs and errors if not fixed."));
|
279 | }
|
280 |
|
281 | if (deps != null && _hook2.deps == null) {
|
282 | logger.warn("".concat(name, " received a final argument during this render, but not during the previous render. Even though the final argument is optional, its type cannot change between renders."));
|
283 | }
|
284 |
|
285 | if (deps != null && _hook2.deps != null && deps.length !== _hook2.deps.length) {
|
286 | logger.warn("The final argument passed to ".concat(name, " changed size between renders. The order and size of this array must remain constant.\nPrevious: ").concat(_hook2.deps, "\nIncoming: ").concat(deps));
|
287 | }
|
288 |
|
289 | if (deps == null || _hook2.deps == null || !areDepsEqual(deps, _hook2.deps)) {
|
290 | callback(_hook2);
|
291 | _hook2.deps = deps;
|
292 | }
|
293 |
|
294 | return _hook2;
|
295 | }
|
296 |
|
297 | throw invalidHooksError();
|
298 | }
|
299 |
|
300 | function useMemoLike(name, nextCreate, deps) {
|
301 | var _useHook = useHook(name, function (hook) {
|
302 |
|
303 | hook.memoizedState = nextCreate();
|
304 | }, deps),
|
305 | memoizedState = _useHook.memoizedState;
|
306 |
|
307 | return memoizedState;
|
308 | }
|
309 |
|
310 |
|
311 |
|
312 | export function useMemo(nextCreate, deps) {
|
313 | return useMemoLike('useMemo', nextCreate, deps);
|
314 | }
|
315 |
|
316 |
|
317 | export function useCallback(callback, deps) {
|
318 | return useMemoLike('useCallback', function () {
|
319 | return callback;
|
320 | }, deps);
|
321 | }
|
322 |
|
323 | function useRefLike(name, initialValue) {
|
324 | return useMemoLike(name, function () {
|
325 | return {
|
326 | current: initialValue
|
327 | };
|
328 | }, []);
|
329 | }
|
330 |
|
331 |
|
332 |
|
333 | export function useRef(initialValue) {
|
334 | return useRefLike('useRef', initialValue);
|
335 | }
|
336 |
|
337 | function triggerUpdate() {
|
338 | var hooks = getHooksContextOrNull();
|
339 |
|
340 | if (hooks != null && hooks.currentPhase !== 'NONE') {
|
341 | hooks.hasUpdates = true;
|
342 | } else {
|
343 | try {
|
344 | addons.getChannel().emit(FORCE_RE_RENDER);
|
345 | } catch (e) {
|
346 | logger.warn('State updates of Storybook preview hooks work only in browser');
|
347 | }
|
348 | }
|
349 | }
|
350 |
|
351 | function useStateLike(name, initialState) {
|
352 | var stateRef = useRefLike(name,
|
353 | typeof initialState === 'function' ? initialState() : initialState);
|
354 |
|
355 | var setState = function setState(update) {
|
356 |
|
357 | stateRef.current = typeof update === 'function' ? update(stateRef.current) : update;
|
358 | triggerUpdate();
|
359 | };
|
360 |
|
361 | return [stateRef.current, setState];
|
362 | }
|
363 |
|
364 |
|
365 |
|
366 | export function useState(initialState) {
|
367 | return useStateLike('useState', initialState);
|
368 | }
|
369 |
|
370 |
|
371 | export function useReducer(reducer, initialArg, init) {
|
372 | var initialState = init != null ? function () {
|
373 | return init(initialArg);
|
374 | } : initialArg;
|
375 |
|
376 | var _useStateLike = useStateLike('useReducer', initialState),
|
377 | _useStateLike2 = _slicedToArray(_useStateLike, 2),
|
378 | state = _useStateLike2[0],
|
379 | setState = _useStateLike2[1];
|
380 |
|
381 | var dispatch = function dispatch(action) {
|
382 | return setState(function (prevState) {
|
383 | return reducer(prevState, action);
|
384 | });
|
385 | };
|
386 |
|
387 | return [state, dispatch];
|
388 | }
|
389 |
|
390 |
|
391 |
|
392 |
|
393 |
|
394 | export function useEffect(create, deps) {
|
395 | var hooks = getHooksContextOrThrow();
|
396 | var effect = useMemoLike('useEffect', function () {
|
397 | return {
|
398 | create: create
|
399 | };
|
400 | }, deps);
|
401 |
|
402 | if (!hooks.currentEffects.includes(effect)) {
|
403 | hooks.currentEffects.push(effect);
|
404 | }
|
405 | }
|
406 |
|
407 |
|
408 | export function useChannel(eventMap) {
|
409 | var deps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
|
410 | var channel = addons.getChannel();
|
411 | useEffect(function () {
|
412 | Object.entries(eventMap).forEach(function (_ref3) {
|
413 | var _ref4 = _slicedToArray(_ref3, 2),
|
414 | type = _ref4[0],
|
415 | listener = _ref4[1];
|
416 |
|
417 | return channel.on(type, listener);
|
418 | });
|
419 | return function () {
|
420 | Object.entries(eventMap).forEach(function (_ref5) {
|
421 | var _ref6 = _slicedToArray(_ref5, 2),
|
422 | type = _ref6[0],
|
423 | listener = _ref6[1];
|
424 |
|
425 | return channel.removeListener(type, listener);
|
426 | });
|
427 | };
|
428 | }, [].concat(_toConsumableArray(Object.keys(eventMap)), _toConsumableArray(deps)));
|
429 | return useCallback(channel.emit.bind(channel), [channel]);
|
430 | }
|
431 |
|
432 |
|
433 | export function useStoryContext() {
|
434 | var _getHooksContextOrThr = getHooksContextOrThrow(),
|
435 | currentContext = _getHooksContextOrThr.currentContext;
|
436 |
|
437 | if (currentContext == null) {
|
438 | throw invalidHooksError();
|
439 | }
|
440 |
|
441 | return currentContext;
|
442 | }
|
443 |
|
444 |
|
445 | export function useParameter(parameterKey, defaultValue) {
|
446 | var _useStoryContext = useStoryContext(),
|
447 | parameters = _useStoryContext.parameters;
|
448 |
|
449 | if (parameterKey) {
|
450 | var _parameters$parameter;
|
451 |
|
452 | return (_parameters$parameter = parameters[parameterKey]) !== null && _parameters$parameter !== void 0 ? _parameters$parameter : defaultValue;
|
453 | }
|
454 |
|
455 | return undefined;
|
456 | }
|
457 |
|
458 |
|
459 | export function useArgs() {
|
460 | var channel = addons.getChannel();
|
461 |
|
462 | var _useStoryContext2 = useStoryContext(),
|
463 | storyId = _useStoryContext2.id,
|
464 | args = _useStoryContext2.args;
|
465 |
|
466 | var updateArgs = useCallback(function (updatedArgs) {
|
467 | return channel.emit(UPDATE_STORY_ARGS, {
|
468 | storyId: storyId,
|
469 | updatedArgs: updatedArgs
|
470 | });
|
471 | }, [channel, storyId]);
|
472 | var resetArgs = useCallback(function (argNames) {
|
473 | return channel.emit(RESET_STORY_ARGS, {
|
474 | storyId: storyId,
|
475 | argNames: argNames
|
476 | });
|
477 | }, [channel, storyId]);
|
478 | return [args, updateArgs, resetArgs];
|
479 | }
|
480 |
|
481 |
|
482 | export function useGlobals() {
|
483 | var channel = addons.getChannel();
|
484 |
|
485 | var _useStoryContext3 = useStoryContext(),
|
486 | globals = _useStoryContext3.globals;
|
487 |
|
488 | var updateGlobals = useCallback(function (newGlobals) {
|
489 | return channel.emit(UPDATE_GLOBALS, {
|
490 | globals: newGlobals
|
491 | });
|
492 | }, [channel]);
|
493 | return [globals, updateGlobals];
|
494 | } |
\ | No newline at end of file |