storybook
Version:
Storybook: Develop, document, and test UI components in isolation
1,525 lines (1,499 loc) • 135 kB
JavaScript
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