@storybook/addon-links
Version:
Storybook Links: Link stories together to build demos and prototypes with your UI components
92 lines (89 loc) • 2.99 kB
JavaScript
import {
PARAM_KEY,
__name
} from "./chunk-D24LJQWS.js";
// src/utils.ts
import { SELECT_STORY, STORY_CHANGED } from "storybook/internal/core-events";
import { toId } from "storybook/internal/csf";
import { global } from "@storybook/global";
import { addons, makeDecorator } from "storybook/preview-api";
var { document, HTMLElement } = global;
function parseQuery(queryString) {
const query = {};
const pairs = (queryString[0] === "?" ? queryString.substring(1) : queryString).split("&").filter(Boolean);
for (let i = 0; i < pairs.length; i++) {
const pair = pairs[i].split("=");
query[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1] || "");
}
return query;
}
__name(parseQuery, "parseQuery");
var navigate = /* @__PURE__ */ __name((params) => addons.getChannel().emit(SELECT_STORY, params), "navigate");
var hrefTo = /* @__PURE__ */ __name((title, name) => {
return new Promise((resolve) => {
const { location } = document;
const query = parseQuery(location.search);
const existingId = query.id;
const titleToLink = title || existingId.split("--", 2)[0];
const id = toId(titleToLink, name);
const path = `/story/${id}`;
const sbPath = location.pathname.replace(/iframe\.html$/, "");
const url = `${location.origin + sbPath}?${Object.entries({ path }).map((item) => `${item[0]}=${item[1]}`).join("&")}`;
resolve(url);
});
}, "hrefTo");
var valueOrCall = /* @__PURE__ */ __name((args) => (value) => typeof value === "function" ? value(...args) : value, "valueOrCall");
var linkTo = /* @__PURE__ */ __name((idOrTitle, nameInput) => (...args) => {
const resolver = valueOrCall(args);
const title = resolver(idOrTitle);
const name = nameInput ? resolver(nameInput) : false;
if (title?.match(/--/) && !name) {
navigate({ storyId: title });
} else if (name && title) {
navigate({ kind: title, story: name });
} else if (title) {
navigate({ kind: title });
} else if (name) {
navigate({ story: name });
}
}, "linkTo");
var linksListener = /* @__PURE__ */ __name((e) => {
const { target } = e;
if (!(target instanceof HTMLElement)) {
return;
}
const element = target;
const { sbKind: kind, sbStory: story } = element.dataset;
if (kind || story) {
e.preventDefault();
navigate({ kind, story });
}
}, "linksListener");
var hasListener = false;
var on = /* @__PURE__ */ __name(() => {
if (!hasListener) {
hasListener = true;
document.addEventListener("click", linksListener);
}
}, "on");
var off = /* @__PURE__ */ __name(() => {
if (hasListener) {
hasListener = false;
document.removeEventListener("click", linksListener);
}
}, "off");
var withLinks = makeDecorator({
name: "withLinks",
parameterName: PARAM_KEY,
wrapper: /* @__PURE__ */ __name((getStory, context) => {
on();
addons.getChannel().once(STORY_CHANGED, off);
return getStory(context);
}, "wrapper")
});
export {
navigate,
hrefTo,
linkTo,
withLinks
};