UNPKG

storybook

Version:

Storybook: Develop, document, and test UI components in isolation

1,525 lines (1,499 loc) • 135 kB
import { UniversalStore, parse, stringify } from "../_browser-chunks/chunk-XDGMHOV7.js"; import { StatusTypeIdMismatchError } from "../_browser-chunks/chunk-6A7OIVEL.js"; import { StatusTypeIdMismatchError as StatusTypeIdMismatchError2 } from "../_browser-chunks/chunk-FDWKXLBI.js"; import { StorybookError } from "../_browser-chunks/chunk-LASUB7TL.js"; import { countBy, dequal, partition } from "../_browser-chunks/chunk-SYS437NN.js"; import { require_picocolors_browser } from "../_browser-chunks/chunk-VUAFL5XK.js"; import { isEqual } from "../_browser-chunks/chunk-ZNRFDIVA.js"; import "../_browser-chunks/chunk-AB7OOPUX.js"; import { mapValues, mergeWith, pick, toMerged } from "../_browser-chunks/chunk-UTNZYD2N.js"; import "../_browser-chunks/chunk-FSBVR7H5.js"; import { require_memoizerific } from "../_browser-chunks/chunk-NVV6MIOE.js"; import { dedent } from "../_browser-chunks/chunk-OPCDBBL3.js"; import { __commonJS, __export, __name, __toESM } from "../_browser-chunks/chunk-MM7DTO55.js"; // ../node_modules/toggle-selection/index.js var require_toggle_selection = __commonJS({ "../node_modules/toggle-selection/index.js"(exports, module) { module.exports = function() { var selection = document.getSelection(); if (!selection.rangeCount) { return function() { }; } var active = document.activeElement; var ranges = []; for (var i = 0; i < selection.rangeCount; i++) { ranges.push(selection.getRangeAt(i)); } switch (active.tagName.toUpperCase()) { // .toUpperCase handles XHTML case "INPUT": case "TEXTAREA": active.blur(); break; default: active = null; break; } selection.removeAllRanges(); return function() { selection.type === "Caret" && selection.removeAllRanges(); if (!selection.rangeCount) { ranges.forEach(function(range) { selection.addRange(range); }); } active && active.focus(); }; }; } }); // ../node_modules/copy-to-clipboard/index.js var require_copy_to_clipboard = __commonJS({ "../node_modules/copy-to-clipboard/index.js"(exports, module) { "use strict"; var deselectCurrent = require_toggle_selection(); var clipboardToIE11Formatting = { "text/plain": "Text", "text/html": "Url", "default": "Text" }; var defaultMessage = "Copy to clipboard: #{key}, Enter"; function format(message) { var copyKey = (/mac os x/i.test(navigator.userAgent) ? "\u2318" : "Ctrl") + "+C"; return message.replace(/#{\s*key\s*}/g, copyKey); } __name(format, "format"); function copy2(text, options) { var debug, message, reselectPrevious, range, selection, mark, success = false; if (!options) { options = {}; } debug = options.debug || false; try { reselectPrevious = deselectCurrent(); range = document.createRange(); selection = document.getSelection(); mark = document.createElement("span"); mark.textContent = text; mark.ariaHidden = "true"; mark.style.all = "unset"; mark.style.position = "fixed"; mark.style.top = 0; mark.style.clip = "rect(0, 0, 0, 0)"; mark.style.whiteSpace = "pre"; mark.style.webkitUserSelect = "text"; mark.style.MozUserSelect = "text"; mark.style.msUserSelect = "text"; mark.style.userSelect = "text"; mark.addEventListener("copy", function(e) { e.stopPropagation(); if (options.format) { e.preventDefault(); if (typeof e.clipboardData === "undefined") { debug && console.warn("unable to use e.clipboardData"); debug && console.warn("trying IE specific stuff"); window.clipboardData.clearData(); var format2 = clipboardToIE11Formatting[options.format] || clipboardToIE11Formatting["default"]; window.clipboardData.setData(format2, text); } else { e.clipboardData.clearData(); e.clipboardData.setData(options.format, text); } } if (options.onCopy) { e.preventDefault(); options.onCopy(e.clipboardData); } }); document.body.appendChild(mark); range.selectNodeContents(mark); selection.addRange(range); var successful = document.execCommand("copy"); if (!successful) { throw new Error("copy command was unsuccessful"); } success = true; } catch (err) { debug && console.error("unable to copy using execCommand: ", err); debug && console.warn("trying IE specific stuff"); try { window.clipboardData.setData(options.format || "text", text); options.onCopy && options.onCopy(window.clipboardData); success = true; } catch (err2) { debug && console.error("unable to copy using clipboardData: ", err2); debug && console.error("falling back to prompt"); message = format("message" in options ? options.message : defaultMessage); window.prompt(message, text); } } finally { if (selection) { if (typeof selection.removeRange == "function") { selection.removeRange(range); } else { selection.removeAllRanges(); } } if (mark) { document.body.removeChild(mark); } reselectPrevious(); } return success; } __name(copy2, "copy"); module.exports = copy2; } }); // ../node_modules/store2/dist/store2.js var require_store2 = __commonJS({ "../node_modules/store2/dist/store2.js"(exports, module) { (function(window2, define) { var _ = { version: "2.14.4", areas: {}, apis: {}, nsdelim: ".", // utilities inherit: /* @__PURE__ */ __name(function(api, o) { for (var p in api) { if (!o.hasOwnProperty(p)) { Object.defineProperty(o, p, Object.getOwnPropertyDescriptor(api, p)); } } return o; }, "inherit"), stringify: /* @__PURE__ */ __name(function(d, fn) { return d === void 0 || typeof d === "function" ? d + "" : JSON.stringify(d, fn || _.replace); }, "stringify"), parse: /* @__PURE__ */ __name(function(s, fn) { try { return JSON.parse(s, fn || _.revive); } catch (e) { return s; } }, "parse"), // extension hooks fn: /* @__PURE__ */ __name(function(name, fn) { _.storeAPI[name] = fn; for (var api in _.apis) { _.apis[api][name] = fn; } }, "fn"), get: /* @__PURE__ */ __name(function(area, key) { return area.getItem(key); }, "get"), set: /* @__PURE__ */ __name(function(area, key, string) { area.setItem(key, string); }, "set"), remove: /* @__PURE__ */ __name(function(area, key) { area.removeItem(key); }, "remove"), key: /* @__PURE__ */ __name(function(area, i) { return area.key(i); }, "key"), length: /* @__PURE__ */ __name(function(area) { return area.length; }, "length"), clear: /* @__PURE__ */ __name(function(area) { area.clear(); }, "clear"), // core functions Store: /* @__PURE__ */ __name(function(id, area, namespace) { var store3 = _.inherit(_.storeAPI, function(key, data, overwrite) { if (arguments.length === 0) { return store3.getAll(); } if (typeof data === "function") { return store3.transact(key, data, overwrite); } if (data !== void 0) { return store3.set(key, data, overwrite); } if (typeof key === "string" || typeof key === "number") { return store3.get(key); } if (typeof key === "function") { return store3.each(key); } if (!key) { return store3.clear(); } return store3.setAll(key, data); }); store3._id = id; try { var testKey = "__store2_test"; area.setItem(testKey, "ok"); store3._area = area; area.removeItem(testKey); } catch (e) { store3._area = _.storage("fake"); } store3._ns = namespace || ""; if (!_.areas[id]) { _.areas[id] = store3._area; } if (!_.apis[store3._ns + store3._id]) { _.apis[store3._ns + store3._id] = store3; } return store3; }, "Store"), storeAPI: { // admin functions area: /* @__PURE__ */ __name(function(id, area) { var store3 = this[id]; if (!store3 || !store3.area) { store3 = _.Store(id, area, this._ns); if (!this[id]) { this[id] = store3; } } return store3; }, "area"), namespace: /* @__PURE__ */ __name(function(namespace, singleArea, delim) { delim = delim || this._delim || _.nsdelim; if (!namespace) { return this._ns ? this._ns.substring(0, this._ns.length - delim.length) : ""; } var ns = namespace, store3 = this[ns]; if (!store3 || !store3.namespace) { store3 = _.Store(this._id, this._area, this._ns + ns + delim); store3._delim = delim; if (!this[ns]) { this[ns] = store3; } if (!singleArea) { for (var name in _.areas) { store3.area(name, _.areas[name]); } } } return store3; }, "namespace"), isFake: /* @__PURE__ */ __name(function(force) { if (force) { this._real = this._area; this._area = _.storage("fake"); } else if (force === false) { this._area = this._real || this._area; } return this._area.name === "fake"; }, "isFake"), toString: /* @__PURE__ */ __name(function() { return "store" + (this._ns ? "." + this.namespace() : "") + "[" + this._id + "]"; }, "toString"), // storage functions has: /* @__PURE__ */ __name(function(key) { if (this._area.has) { return this._area.has(this._in(key)); } return !!(this._in(key) in this._area); }, "has"), size: /* @__PURE__ */ __name(function() { return this.keys().length; }, "size"), each: /* @__PURE__ */ __name(function(fn, fill) { for (var i = 0, m = _.length(this._area); i < m; i++) { var key = this._out(_.key(this._area, i)); if (key !== void 0) { if (fn.call(this, key, this.get(key), fill) === false) { break; } } if (m > _.length(this._area)) { m--; i--; } } return fill || this; }, "each"), keys: /* @__PURE__ */ __name(function(fillList) { return this.each(function(k, v, list) { list.push(k); }, fillList || []); }, "keys"), get: /* @__PURE__ */ __name(function(key, alt) { var s = _.get(this._area, this._in(key)), fn; if (typeof alt === "function") { fn = alt; alt = null; } return s !== null ? _.parse(s, fn) : alt != null ? alt : s; }, "get"), getAll: /* @__PURE__ */ __name(function(fillObj) { return this.each(function(k, v, all) { all[k] = v; }, fillObj || {}); }, "getAll"), transact: /* @__PURE__ */ __name(function(key, fn, alt) { var val = this.get(key, alt), ret = fn(val); this.set(key, ret === void 0 ? val : ret); return this; }, "transact"), set: /* @__PURE__ */ __name(function(key, data, overwrite) { var d = this.get(key), replacer; if (d != null && overwrite === false) { return data; } if (typeof overwrite === "function") { replacer = overwrite; overwrite = void 0; } return _.set(this._area, this._in(key), _.stringify(data, replacer), overwrite) || d; }, "set"), setAll: /* @__PURE__ */ __name(function(data, overwrite) { var changed, val; for (var key in data) { val = data[key]; if (this.set(key, val, overwrite) !== val) { changed = true; } } return changed; }, "setAll"), add: /* @__PURE__ */ __name(function(key, data, replacer) { var d = this.get(key); if (d instanceof Array) { data = d.concat(data); } else if (d !== null) { var type = typeof d; if (type === typeof data && type === "object") { for (var k in data) { d[k] = data[k]; } data = d; } else { data = d + data; } } _.set(this._area, this._in(key), _.stringify(data, replacer)); return data; }, "add"), remove: /* @__PURE__ */ __name(function(key, alt) { var d = this.get(key, alt); _.remove(this._area, this._in(key)); return d; }, "remove"), clear: /* @__PURE__ */ __name(function() { if (!this._ns) { _.clear(this._area); } else { this.each(function(k) { _.remove(this._area, this._in(k)); }, 1); } return this; }, "clear"), clearAll: /* @__PURE__ */ __name(function() { var area = this._area; for (var id in _.areas) { if (_.areas.hasOwnProperty(id)) { this._area = _.areas[id]; this.clear(); } } this._area = area; return this; }, "clearAll"), // internal use functions _in: /* @__PURE__ */ __name(function(k) { if (typeof k !== "string") { k = _.stringify(k); } return this._ns ? this._ns + k : k; }, "_in"), _out: /* @__PURE__ */ __name(function(k) { return this._ns ? k && k.indexOf(this._ns) === 0 ? k.substring(this._ns.length) : void 0 : ( // so each() knows to skip it k ); }, "_out") }, // end _.storeAPI storage: /* @__PURE__ */ __name(function(name) { return _.inherit(_.storageAPI, { items: {}, name }); }, "storage"), storageAPI: { length: 0, has: /* @__PURE__ */ __name(function(k) { return this.items.hasOwnProperty(k); }, "has"), key: /* @__PURE__ */ __name(function(i) { var c = 0; for (var k in this.items) { if (this.has(k) && i === c++) { return k; } } }, "key"), setItem: /* @__PURE__ */ __name(function(k, v) { if (!this.has(k)) { this.length++; } this.items[k] = v; }, "setItem"), removeItem: /* @__PURE__ */ __name(function(k) { if (this.has(k)) { delete this.items[k]; this.length--; } }, "removeItem"), getItem: /* @__PURE__ */ __name(function(k) { return this.has(k) ? this.items[k] : null; }, "getItem"), clear: /* @__PURE__ */ __name(function() { for (var k in this.items) { this.removeItem(k); } }, "clear") } // end _.storageAPI }; var store2 = ( // safely set this up (throws error in IE10/32bit mode for local files) _.Store("local", function() { try { return localStorage; } catch (e) { } }()) ); store2.local = store2; store2._ = _; store2.area("session", function() { try { return sessionStorage; } catch (e) { } }()); store2.area("page", _.storage("page")); if (typeof define === "function" && define.amd !== void 0) { define("store2", [], function() { return store2; }); } else if (typeof module !== "undefined" && module.exports) { module.exports = store2; } else { if (window2.store) { _.conflict = window2.store; } window2.store = store2; } })(exports, exports && exports.define); } }); // src/manager-api/root.tsx import React4, { Component, Fragment, useCallback as useCallback2, useContext, useEffect, useMemo, useRef as useRef2, useState } from "react"; import { DOCS_PREPARED as DOCS_PREPARED2, SET_STORIES as SET_STORIES2, SHARED_STATE_CHANGED, SHARED_STATE_SET, STORY_CHANGED as STORY_CHANGED2, STORY_PREPARED as STORY_PREPARED2 } from "storybook/internal/core-events"; // src/manager-api/context.ts import { createContext as ReactCreateContext } from "react"; var createContext = /* @__PURE__ */ __name(({ api, state }) => ReactCreateContext({ api, state }), "createContext"); // src/manager-api/lib/merge.ts import { logger } from "storybook/internal/client-logger"; var merge_default = /* @__PURE__ */ __name((a, ...b) => { let target = {}; target = mergeWith( {}, a, (objValue, srcValue) => { if (Array.isArray(srcValue) && Array.isArray(objValue)) { srcValue.forEach((s) => { const existing = objValue.find((o) => o === s || isEqual(o, s)); if (!existing) { objValue.push(s); } }); return objValue; } if (Array.isArray(objValue)) { logger.log(["the types mismatch, picking", objValue]); return objValue; } } ); for (const obj of b) { target = mergeWith(target, obj, (objValue, srcValue) => { if (Array.isArray(srcValue) && Array.isArray(objValue)) { srcValue.forEach((s) => { const existing = objValue.find((o) => o === s || isEqual(o, s)); if (!existing) { objValue.push(s); } }); return objValue; } if (Array.isArray(objValue)) { logger.log(["the types mismatch, picking", objValue]); return objValue; } }); } return target; }, "default"); var noArrayMerge = /* @__PURE__ */ __name((a, ...b) => { let target = {}; target = mergeWith( {}, a, (objValue, srcValue) => { if (Array.isArray(srcValue)) { return srcValue; } } ); for (const obj of b) { target = mergeWith(target, obj, (objValue, srcValue) => { if (Array.isArray(srcValue)) { return srcValue; } }); } return target; }, "noArrayMerge"); // src/manager-api/initial-state.ts var main = /* @__PURE__ */ __name((...additions) => additions.reduce((acc, item) => merge_default(acc, item), {}), "main"); var initial_state_default = main; // src/manager-api/lib/addons.ts import { logger as logger2 } from "storybook/internal/client-logger"; import { SET_CONFIG } from "storybook/internal/core-events"; import { Addon_TypesEnum } from "storybook/internal/types"; import { global } from "@storybook/global"; // src/manager-api/lib/storybook-channel-mock.ts import { Channel } from "storybook/internal/channels"; function mockChannel() { const transport = { setHandler: /* @__PURE__ */ __name(() => { }, "setHandler"), send: /* @__PURE__ */ __name(() => { }, "send") }; return new Channel({ transport }); } __name(mockChannel, "mockChannel"); // src/manager-api/lib/addons.ts var _AddonStore = class _AddonStore { constructor() { this.loaders = {}; this.elements = {}; this.config = {}; this.getChannel = /* @__PURE__ */ __name(() => { if (!this.channel) { this.setChannel(mockChannel()); } return this.channel; }, "getChannel"); this.ready = /* @__PURE__ */ __name(() => this.promise, "ready"); this.hasChannel = /* @__PURE__ */ __name(() => !!this.channel, "hasChannel"); this.setChannel = /* @__PURE__ */ __name((channel) => { this.channel = channel; this.resolve(); }, "setChannel"); this.setConfig = /* @__PURE__ */ __name((value) => { Object.assign(this.config, value); if (this.hasChannel()) { this.getChannel().emit(SET_CONFIG, this.config); } else { this.ready().then((channel) => { channel.emit(SET_CONFIG, this.config); }); } }, "setConfig"); this.getConfig = /* @__PURE__ */ __name(() => this.config, "getConfig"); /** * Registers an addon loader function. * * @param {string} id - The id of the addon loader. * @param {(api: API) => void} callback - The function that will be called to register the addon. * @returns {void} */ this.register = /* @__PURE__ */ __name((id, callback) => { if (this.loaders[id]) { logger2.warn(`${id} was loaded twice, this could have bad side-effects`); } this.loaders[id] = callback; }, "register"); this.loadAddons = /* @__PURE__ */ __name((api) => { Object.values(this.loaders).forEach((value) => value(api)); }, "loadAddons"); this.promise = new Promise((res) => { this.resolve = () => res(this.getChannel()); }); } getElements(type) { if (!this.elements[type]) { this.elements[type] = {}; } return this.elements[type]; } /** * Adds an addon to the addon store. * * @param {string} id - The id of the addon. * @param {Addon_Type} addon - The addon to add. * @returns {void} */ add(id, addon) { const { type } = addon; const collection = this.getElements(type); collection[id] = { ...addon, id }; } experimental_getRegisteredAddons() { return Object.keys(this.loaders); } }; __name(_AddonStore, "AddonStore"); var AddonStore = _AddonStore; var KEY = "__STORYBOOK_ADDONS_MANAGER"; function getAddonsStore() { if (!global[KEY]) { global[KEY] = new AddonStore(); } return global[KEY]; } __name(getAddonsStore, "getAddonsStore"); var addons = getAddonsStore(); // src/manager-api/modules/addons.ts var addons_exports = {}; __export(addons_exports, { ensurePanel: () => ensurePanel, init: () => init }); import { Addon_TypesEnum as Addon_TypesEnum2 } from "storybook/internal/types"; function ensurePanel(panels, selectedPanel, currentPanel) { const keys2 = Object.keys(panels); if (keys2.indexOf(selectedPanel) >= 0) { return selectedPanel; } if (keys2.length) { return keys2[0]; } return currentPanel; } __name(ensurePanel, "ensurePanel"); var init = /* @__PURE__ */ __name(({ provider, store: store2, fullAPI }) => { const api = { getElements: /* @__PURE__ */ __name((type) => provider.getElements(type), "getElements"), getSelectedPanel: /* @__PURE__ */ __name(() => { const { selectedPanel } = store2.getState(); return ensurePanel(api.getElements(Addon_TypesEnum2.PANEL), selectedPanel, selectedPanel); }, "getSelectedPanel"), setSelectedPanel: /* @__PURE__ */ __name((panelName) => { store2.setState({ selectedPanel: panelName }, { persistence: "session" }); }, "setSelectedPanel"), setAddonState(addonId, newStateOrMerger, options) { const merger = typeof newStateOrMerger === "function" ? newStateOrMerger : () => newStateOrMerger; return store2.setState( (s) => ({ ...s, addons: { ...s.addons, [addonId]: merger(s.addons[addonId]) } }), options ).then(() => api.getAddonState(addonId)); }, getAddonState: /* @__PURE__ */ __name((addonId) => { return store2.getState().addons[addonId] || globalThis?.STORYBOOK_ADDON_STATE[addonId]; }, "getAddonState") }; return { api, state: { selectedPanel: ensurePanel( api.getElements(Addon_TypesEnum2.PANEL), store2.getState().selectedPanel ), addons: {} } }; }, "init"); // src/manager-api/modules/channel.ts var channel_exports = {}; __export(channel_exports, { init: () => init2 }); var init2 = /* @__PURE__ */ __name(({ provider }) => { const api = { getChannel: /* @__PURE__ */ __name(() => provider.channel, "getChannel"), on: /* @__PURE__ */ __name((type, handler) => { provider.channel?.on(type, handler); return () => provider.channel?.off(type, handler); }, "on"), off: /* @__PURE__ */ __name((type, handler) => provider.channel?.off(type, handler), "off"), once: /* @__PURE__ */ __name((type, handler) => provider.channel?.once(type, handler), "once"), emit: /* @__PURE__ */ __name((type, data, ...args) => { if (data?.options?.target && data.options.target !== "storybook-preview-iframe" && !data.options.target.startsWith("storybook-ref-")) { data.options.target = data.options.target !== "storybook_internal" ? `storybook-ref-${data.options.target}` : "storybook-preview-iframe"; } provider.channel?.emit(type, data, ...args); }, "emit") }; return { api, state: {} }; }, "init"); // src/manager-api/modules/globals.ts var globals_exports = {}; __export(globals_exports, { init: () => init4 }); import { logger as logger4 } from "storybook/internal/client-logger"; import { GLOBALS_UPDATED, SET_GLOBALS, UPDATE_GLOBALS } from "storybook/internal/core-events"; // src/manager-api/lib/events.ts import { logger as logger3 } from "storybook/internal/client-logger"; // src/manager-api/modules/refs.ts var refs_exports = {}; __export(refs_exports, { defaultStoryMapper: () => defaultStoryMapper, getSourceType: () => getSourceType, init: () => init3 }); import { global as global2 } from "@storybook/global"; // src/manager-api/lib/stories.ts import { sanitize } from "storybook/internal/csf"; var import_memoizerific = __toESM(require_memoizerific(), 1); // src/manager-api/lib/intersect.ts var intersect_default = /* @__PURE__ */ __name((a, b) => { if (!Array.isArray(a) || !Array.isArray(b) || !a.length || !b.length) { return []; } return a.reduce((acc, aValue) => { if (b.includes(aValue)) { acc.push(aValue); } return acc; }, []); }, "default"); // src/manager-api/lib/stories.ts var TITLE_PATH_SEPARATOR = /\s*\/\s*/; var denormalizeStoryParameters = /* @__PURE__ */ __name(({ globalParameters, kindParameters, stories }) => { return mapValues(stories, (storyData) => ({ ...storyData, parameters: combineParameters( globalParameters, kindParameters[storyData.kind], storyData.parameters ) })); }, "denormalizeStoryParameters"); var transformSetStoriesStoryDataToPreparedStoryIndex = /* @__PURE__ */ __name((stories) => { const entries = Object.entries(stories).reduce( (acc, [id, story]) => { if (!story) { return acc; } const { docsOnly, fileName, ...parameters } = story.parameters; const base = { title: story.kind, id, name: story.name, importPath: fileName }; if (docsOnly) { acc[id] = { type: "docs", tags: ["stories-mdx"], storiesImports: [], ...base }; } else { const { argTypes, args, initialArgs } = story; acc[id] = { type: "story", subtype: "story", ...base, parameters, argTypes, args, initialArgs }; } return acc; }, {} ); return { v: 5, entries }; }, "transformSetStoriesStoryDataToPreparedStoryIndex"); var transformStoryIndexV2toV3 = /* @__PURE__ */ __name((index) => { return { v: 3, stories: Object.values(index.stories).reduce( (acc, entry) => { acc[entry.id] = { ...entry, title: entry.kind, name: entry.name || entry.story, importPath: entry.parameters.fileName || "" }; return acc; }, {} ) }; }, "transformStoryIndexV2toV3"); var transformStoryIndexV3toV4 = /* @__PURE__ */ __name((index) => { const countByTitle = countBy(Object.values(index.stories), (item) => item.title); return { v: 4, entries: Object.values(index.stories).reduce( (acc, entry) => { let type = "story"; if (entry.parameters?.docsOnly || entry.name === "Page" && countByTitle[entry.title] === 1) { type = "docs"; } acc[entry.id] = { type, ...type === "docs" && { tags: ["stories-mdx"], storiesImports: [] }, ...entry }; delete acc[entry.id].story; delete acc[entry.id].kind; return acc; }, {} ) }; }, "transformStoryIndexV3toV4"); var transformStoryIndexV4toV5 = /* @__PURE__ */ __name((index) => { return { v: 5, entries: Object.values(index.entries).reduce( (acc, entry) => { acc[entry.id] = { ...entry, tags: entry.tags ? ["dev", "test", ...entry.tags] : ["dev"] }; return acc; }, {} ) }; }, "transformStoryIndexV4toV5"); var transformStoryIndexToStoriesHash = /* @__PURE__ */ __name((input, { provider, docsOptions, filters, allStatuses }) => { if (!input.v) { throw new Error("Composition: Missing stories.json version"); } let index = input; index = index.v === 2 ? transformStoryIndexV2toV3(index) : index; index = index.v === 3 ? transformStoryIndexV3toV4(index) : index; index = index.v === 4 ? transformStoryIndexV4toV5(index) : index; index = index; const indexEntries = Object.values(index.entries); const filterFunctions = Object.values(filters); const entryValues = indexEntries.filter((entry) => { const statuses = allStatuses[entry.id] ?? {}; if (Object.values(statuses).some(({ value }) => value === "status-value:error")) { return true; } if (filterFunctions.every((fn) => fn({ ...entry, statuses }))) { return true; } const children = indexEntries.filter((item) => "parent" in item && item.parent === entry.id); return children.some((child) => filterFunctions.every((fn) => fn({ ...child, statuses }))); }); const { sidebar = {} } = provider.getConfig(); const { showRoots, collapsedRoots = [], renderLabel } = sidebar; const setShowRoots = typeof showRoots !== "undefined"; const storiesHashOutOfOrder = entryValues.reduce((acc, item) => { if (docsOptions.docsMode && item.type !== "docs") { return acc; } const { title } = item; const groups = title.trim().split(TITLE_PATH_SEPARATOR); const root = (!setShowRoots || showRoots) && groups.length > 1 ? [groups.shift()] : []; const names = [...root, ...groups]; const paths = names.reduce((list, name, idx) => { const parent = idx > 0 && list[idx - 1]; const id = sanitize(parent ? `${parent}-${name}` : name); if (name.trim() === "") { throw new Error(dedent`Invalid title ${title} ending in slash.`); } if (parent === id) { throw new Error( dedent` Invalid part '${name}', leading to id === parentId ('${id}'), inside title '${title}' Did you create a path that uses the separator char accidentally, such as 'Vue <docs/>' where '/' is a separator char? See https://github.com/storybookjs/storybook/issues/6128 ` ); } list.push(id); return list; }, []); paths.forEach((id, idx) => { const childId = paths[idx + 1] || item.id; if (root.length && idx === 0) { acc[id] = merge_default(acc[id] || {}, { type: "root", id, name: names[idx], tags: [], depth: idx, renderLabel, startCollapsed: collapsedRoots.includes(id), // Note that this will later get appended to the previous list of children (see below) children: [childId] }); } else if ((!acc[id] || acc[id].type === "component") && idx === paths.length - 1) { acc[id] = merge_default(acc[id] || {}, { type: "component", id, name: names[idx], tags: [], parent: paths[idx - 1], depth: idx, renderLabel, ...childId && { children: [childId] } }); } else { acc[id] = merge_default(acc[id] || {}, { type: "group", id, name: names[idx], tags: [], parent: paths[idx - 1], depth: idx, renderLabel, ...childId && { children: [childId] } }); } }); acc[item.id] = { tags: [], ...item, depth: paths.length, parent: "parent" in item ? item.parent : paths[paths.length - 1], renderLabel, prepared: !!item.parameters }; return acc; }, {}); function addItem(acc, item) { if (!acc[item.id]) { acc[item.id] = item; if ("children" in item && item.children) { item.children.forEach((childId) => addItem(acc, storiesHashOutOfOrder[childId])); item.tags = item.children.reduce((currentTags, childId) => { return currentTags === null ? acc[childId].tags : intersect_default(currentTags, acc[childId].tags); }, null) || []; } } if (item.type === "component") { const firstChild = acc[item.children[0]]; if (firstChild && "importPath" in firstChild) { item.importPath = firstChild.importPath; } } return acc; } __name(addItem, "addItem"); let storiesHash = Object.values(storiesHashOutOfOrder).filter((i) => i.type !== "root" && !i.parent).reduce((acc, item) => addItem(acc, item), {}); storiesHash = Object.values(storiesHashOutOfOrder).filter((i) => i.type === "root").reduce(addItem, storiesHash); storiesHash = Object.values(storiesHash).reduce((acc, item) => { if (item.type === "story" && item.subtype === "test") { const story = acc[item.parent]; const component = acc[story.parent]; acc[component.id] = { ...component, // Remove test from the component node as it will be attached to the story node instead children: component.children && component.children.filter((id) => id !== item.id) }; acc[story.id] = { ...story, // Add test to the story node children: (story.children || []).concat(item.id) }; acc[item.id] = { ...item, depth: item.depth + 1 }; } else { acc[item.id] = item; } return acc; }, {}); return storiesHash; }, "transformStoryIndexToStoriesHash"); var addPreparedStories = /* @__PURE__ */ __name((newHash, oldHash) => { if (!oldHash) { return newHash; } return Object.fromEntries( Object.entries(newHash).map(([id, newEntry]) => { const oldEntry = oldHash[id]; if (newEntry.type === "story" && oldEntry?.type === "story" && oldEntry.prepared) { if ("children" in oldEntry) { delete oldEntry.children; } return [id, { ...oldEntry, ...newEntry, prepared: true }]; } return [id, newEntry]; }) ); }, "addPreparedStories"); var getComponentLookupList = (0, import_memoizerific.default)(1)((hash) => { return Object.entries(hash).reduce((acc, i) => { const value = i[1]; if (value.type === "component") { acc.push([...value.children]); } return acc; }, []); }); var getStoriesLookupList = (0, import_memoizerific.default)(1)((hash) => { return Object.keys(hash).filter((k) => ["story", "docs"].includes(hash[k].type)); }); // src/manager-api/modules/refs.ts var { location, fetch } = global2; var getSourceType = /* @__PURE__ */ __name((source, refId) => { const { origin: localOrigin, pathname: localPathname } = location; const { origin: sourceOrigin, pathname: sourcePathname } = new URL(source); const localFull = `${localOrigin + localPathname}`.replace("/iframe.html", "").replace(/\/$/, ""); const sourceFull = `${sourceOrigin + sourcePathname}`.replace("/iframe.html", "").replace(/\/$/, ""); if (localFull === sourceFull) { return ["local", sourceFull]; } if (refId || source) { return ["external", sourceFull]; } return [null, null]; }, "getSourceType"); var defaultStoryMapper = /* @__PURE__ */ __name((b, a) => { return { ...a, kind: a.kind.replace("|", "/") }; }, "defaultStoryMapper"); var addRefIds = /* @__PURE__ */ __name((input, ref) => { return Object.entries(input).reduce((acc, [id, item]) => { return { ...acc, [id]: { ...item, refId: ref.id } }; }, {}); }, "addRefIds"); async function handleRequest(request) { if (!request) { return {}; } try { const response = await request; if (response === false || response === true) { throw new Error("Unexpected boolean response"); } if (!response.ok) { throw new Error(`Unexpected response not OK: ${response.statusText}`); } const json = await response.json(); if (json.entries || json.stories) { return { storyIndex: json }; } return json; } catch (err) { return { indexError: err }; } } __name(handleRequest, "handleRequest"); var parseUrl = /* @__PURE__ */ __name((url) => { const credentialsRegex = /https?:\/\/(.+:.+)@/; let cleanUrl = url; let authorization; const [, credentials] = url.match(credentialsRegex) || []; if (credentials) { cleanUrl = url.replace(`${credentials}@`, ""); authorization = btoa(`${credentials}`); } return { url: cleanUrl, authorization }; }, "parseUrl"); var map = /* @__PURE__ */ __name((input, ref, options) => { const { storyMapper } = options; if (storyMapper) { return Object.entries(input).reduce((acc, [id, item]) => { return { ...acc, [id]: storyMapper(ref, item) }; }, {}); } return input; }, "map"); var init3 = /* @__PURE__ */ __name(({ store: store2, provider, singleStory, docsOptions = {} }, { runCheck = true } = {}) => { const api = { findRef: /* @__PURE__ */ __name((source) => { const refs2 = api.getRefs(); return Object.values(refs2).find(({ url }) => url.match(source)); }, "findRef"), changeRefVersion: /* @__PURE__ */ __name(async (id, url) => { const { versions, title } = api.getRefs()[id]; const ref = { id, url, versions, title, index: {}, filteredIndex: {}, expanded: true }; await api.setRef(id, { ...ref, type: "unknown" }, false); await api.checkRef(ref); }, "changeRefVersion"), changeRefState: /* @__PURE__ */ __name((id, previewInitialized) => { const { [id]: ref, ...updated } = api.getRefs(); updated[id] = { ...ref, previewInitialized }; store2.setState({ refs: updated }); }, "changeRefState"), checkRef: /* @__PURE__ */ __name(async (ref) => { const { id, url, version: version2, type } = ref; const isPublic = type === "server-checked"; const loadedData = {}; const query = version2 ? `?version=${version2}` : ""; const credentials = isPublic ? "omit" : "include"; const urlParseResult = parseUrl(url); const headers = { Accept: "application/json" }; if (urlParseResult.authorization) { Object.assign(headers, { Authorization: `Basic ${urlParseResult.authorization}` }); } const [indexResult, storiesResult] = await Promise.all( ["index.json", "stories.json"].map( async (file) => handleRequest( fetch(`${urlParseResult.url}/${file}${query}`, { headers, credentials }) ) ) ); if (!indexResult.indexError || !storiesResult.indexError) { const metadata = await handleRequest( fetch(`${urlParseResult.url}/metadata.json${query}`, { headers, credentials, cache: "no-cache" }).catch(() => false) ); Object.assign(loadedData, { ...indexResult.indexError ? storiesResult : indexResult, ...!metadata.indexError && metadata }); } else if (!isPublic) { loadedData.indexError = { message: dedent` Error: Loading of ref failed at fetch (lib/api/src/modules/refs.ts) URL: ${urlParseResult.url} We weren't able to load the above URL, it's possible a CORS error happened. Please check your dev-tools network tab. ` }; } const versions = ref.versions && Object.keys(ref.versions).length ? ref.versions : loadedData.versions; await api.setRef(id, { id, url: urlParseResult.url, ...loadedData, ...versions ? { versions } : {}, type: !loadedData.storyIndex ? "auto-inject" : "lazy" }); }, "checkRef"), getRefs: /* @__PURE__ */ __name(() => { const { refs: refs2 = {} } = store2.getState(); return refs2; }, "getRefs"), setRef: /* @__PURE__ */ __name(async (id, { storyIndex, setStoriesData, ...rest }, ready = false) => { if (singleStory) { return; } let internal_index; let index; let filteredIndex; const { filters } = store2.getState(); const { storyMapper = defaultStoryMapper } = provider.getConfig(); const ref = api.getRefs()[id]; if (storyIndex || setStoriesData) { internal_index = setStoriesData ? transformSetStoriesStoryDataToPreparedStoryIndex( map(setStoriesData, ref, { storyMapper }) ) : storyIndex; filteredIndex = transformStoryIndexToStoriesHash(storyIndex, { provider, docsOptions, filters, allStatuses: {} }); index = transformStoryIndexToStoriesHash(storyIndex, { provider, docsOptions, filters: {}, allStatuses: {} }); } if (index) { index = addRefIds(index, ref); } if (filteredIndex) { filteredIndex = addRefIds(filteredIndex, ref); } await api.updateRef(id, { ...ref, ...rest, index, filteredIndex, internal_index }); }, "setRef"), updateRef: /* @__PURE__ */ __name(async (id, data) => { const { [id]: ref, ...updated } = api.getRefs(); updated[id] = { ...ref, ...data }; const ordered = Object.keys(initialState).reduce((obj, key) => { obj[key] = updated[key]; return obj; }, {}); await store2.setState({ refs: ordered }); }, "updateRef") }; const refs = !singleStory && global2.REFS || {}; const initialState = refs; if (runCheck) { new Promise(async (resolve) => { for (const ref of Object.values(refs)) { await api.checkRef({ ...ref, stories: {} }); } resolve(void 0); }); } return { api, state: { refs: initialState } }; }, "init"); // src/manager-api/lib/events.ts var getEventMetadata = /* @__PURE__ */ __name((context, fullAPI) => { const { source, refId, type } = context; const [sourceType, sourceLocation] = getSourceType(source, refId); let ref; if (refId || sourceType === "external") { ref = refId && fullAPI.getRefs()[refId] ? fullAPI.getRefs()[refId] : fullAPI.findRef(sourceLocation); } const meta = { source, sourceType, sourceLocation, refId, ref, type }; switch (true) { case typeof refId === "string": case sourceType === "local": case sourceType === "external": { return meta; } // if we couldn't find the source, something risky happened, we ignore the input, and log a warning default: { logger3.warn(`Received a ${type} frame that was not configured as a ref`); return null; } } }, "getEventMetadata"); // src/manager-api/modules/globals.ts var init4 = /* @__PURE__ */ __name(({ store: store2, fullAPI, provider }) => { const api = { getGlobals() { return store2.getState().globals; }, getUserGlobals() { return store2.getState().userGlobals; }, getStoryGlobals() { return store2.getState().storyGlobals; }, getGlobalTypes() { return store2.getState().globalTypes; }, updateGlobals(newGlobals) { provider.channel?.emit(UPDATE_GLOBALS, { globals: newGlobals, options: { target: "storybook-preview-iframe" } }); } }; const state = { globals: {}, userGlobals: {}, storyGlobals: {}, globalTypes: {} }; const updateGlobals = /* @__PURE__ */ __name(({ globals, storyGlobals, userGlobals }) => { const { globals: currentGlobals, userGlobals: currentUserGlobals, storyGlobals: currentStoryGlobals } = store2.getState(); if (!dequal(globals, currentGlobals)) { store2.setState({ globals }); } if (!dequal(userGlobals, currentUserGlobals)) { store2.setState({ userGlobals }); } if (!dequal(storyGlobals, currentStoryGlobals)) { store2.setState({ storyGlobals }); } }, "updateGlobals"); provider.channel?.on( GLOBALS_UPDATED, /* @__PURE__ */ __name(function handleGlobalsUpdated({ globals, storyGlobals, userGlobals }) { const { ref } = getEventMetadata(this, fullAPI); if (!ref) { updateGlobals({ globals, storyGlobals, userGlobals }); } else { logger4.warn( "received a GLOBALS_UPDATED from a non-local ref. This is not currently supported." ); } }, "handleGlobalsUpdated") ); provider.channel?.on( SET_GLOBALS, /* @__PURE__ */ __name(function handleSetGlobals({ globals, globalTypes }) { const { ref } = getEventMetadata(this, fullAPI); const currentGlobals = store2.getState()?.globals; if (!ref) { store2.setState({ globals, userGlobals: globals, globalTypes }); } else if (Object.keys(globals).length > 0) { logger4.warn("received globals from a non-local ref. This is not currently supported."); } if (currentGlobals && Object.keys(currentGlobals).length !== 0 && !dequal(globals, currentGlobals)) { api.updateGlobals(currentGlobals); } }, "handleSetGlobals") ); return { api, state }; }, "init"); // src/manager-api/modules/layout.ts var layout_exports = {}; __export(layout_exports, { ActiveTabs: () => ActiveTabs, defaultLayoutState: () => defaultLayoutState, focusableUIElements: () => focusableUIElements, init: () => init5 }); import { SET_CONFIG as SET_CONFIG2 } from "storybook/internal/core-events"; import { global as global3 } from "@storybook/global"; import { create } from "storybook/theming/create"; var { document: document2 } = global3; var isFunction = /* @__PURE__ */ __name((val) => typeof val === "function", "isFunction"); var ActiveTabs = { SIDEBAR: "sidebar", CANVAS: "canvas", ADDONS: "addons" }; var defaultLayoutState = { ui: { enableShortcuts: true }, layout: { initialActive: ActiveTabs.CANVAS, showToolbar: true, navSize: 300, bottomPanelHeight: 300, rightPanelWidth: 400, recentVisibleSizes: { navSize: 300, bottomPanelHeight: 300, rightPanelWidth: 400 }, panelPosition: "bottom", showTabs: true }, layoutCustomisations: { showSidebar: void 0, showToolbar: void 0 }, selectedPanel: void 0, theme: create() }; var focusableUIElements = { storySearchField: "storybook-explorer-searchfield", storyListMenu: "storybook-explorer-menu", storyPanelRoot: "storybook-panel-root" }; var getIsNavShown = /* @__PURE__ */ __name((state) => { return state.layout.navSize > 0; }, "getIsNavShown"); var getIsPanelShown = /* @__PURE__ */ __name((state) => { const { bottomPanelHeight, rightPanelWidth, panelPosition } = state.layout; return panelPosition === "bottom" && bottomPanelHeight > 0 || panelPosition === "right" && rightPanelWidth > 0; }, "getIsPanelShown"); var getIsFullscreen = /* @__PURE__ */ __name((state) => { return !getIsNavShown(state) && !getIsPanelShown(state); }, "getIsFullscreen"); var getRecentVisibleSizes = /* @__PURE__ */ __name((layoutState) => { return { navSize: layoutState.navSize > 0 ? layoutState.navSize : layoutState.recentVisibleSizes.navSize, bottomPanelHeight: layoutState.bottomPanelHeight > 0 ? layoutState.bottomPanelHeight : layoutState.recentVisibleSizes.bottomPanelHeight, rightPanelWidth: layoutState.rightPanelWidth > 0 ? layoutState.rightPanelWidth : layoutState.recentVisibleSizes.rightPanelWidth }; }, "getRecentVisibleSizes"); var init5 = /* @__PURE__ */ __name(({ store: store2, provider, singleStory }) => { const api = { toggleFullscreen(nextState) { return store2.setState( (state) => { const isFull