@deot/docs-playground 1.1.2 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,8 +1,12 @@
1
- import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, ref, renderList, toDisplayString, unref, vModelText, vShow, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
1
+ import { s as isIgnoredFilename } from "./files-BqucFldk.js";
2
+ import { c as NEW_SFC_CODE, i as normalizeCdnURL, n as createBuiltinImports, o as DEFAULT_CDN_URL, r as createBuiltinStyles, s as DEFAULT_ENTRY } from "./cdn-DQoETju_.js";
3
+ import { A as PREVIEW_SCROLLER_USE_CODE, C as toErrorText, D as resolveSandboxMessageSource, E as resolveSandboxContainer, M as PREVIEW_SCROLL_HTML_CLASS, N as PREVIEW_SCROLL_RESET_CODE, O as useSandboxAutoHeight, S as formatSandboxRuntimeError, T as isSandboxMessage, _ as removePlaygroundStyleOverride, a as createRuntimeStore, b as setPlaygroundSiteStyles, c as applyPlaygroundImportMapOverride, d as getPlaygroundImportMapOverrides, f as getPlaygroundSiteModules, g as removePlaygroundImportMapOverride, h as isSafePlaygroundHref, i as createRuntimePreviewOptions, j as PREVIEW_SCROLL_CONTENT_CLASS, k as PREVIEW_SCROLLER_IMPORT_CODE, l as applyPlaygroundStyleOverride, m as getPlaygroundStyleOverrides, n as createReplFile, o as toReplFilename, p as getPlaygroundSiteStyles, s as PlaygroundService, t as PLAYGROUND_RUNTIME_CANVAS_BACKGROUND, u as clearPlaygroundMaps, v as setPlaygroundImportMapOverrides, w as useSandboxRuntimeErrorGuard, x as setPlaygroundStyleOverrides, y as setPlaygroundSiteModules } from "./store-BOyC8F2y.js";
4
+ import { i as whenSassReady } from "./scss-DIh6971q.js";
5
+ import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineAsyncComponent, defineComponent, nextTick, normalizeClass, normalizeStyle, onBeforeUnmount, onMounted, openBlock, ref, renderList, toDisplayString, unref, vModelText, vShow, watch, withCtx, withDirectives, withKeys, withModifiers } from "vue";
2
6
  import { Clipboard, Dropdown, DropdownItem, DropdownMenu, Message, Popconfirm, Portal, Scroller, TransitionFade } from "@deot/vc";
3
7
  import { provideLocale, useLocale } from "@deot/docs-locale";
4
8
  import hljs from "highlight.js";
5
- import { File, Sandbox, useStore } from "@vue/repl";
9
+ import { Sandbox } from "@vue/repl";
6
10
  import { EditorView, basicSetup } from "codemirror";
7
11
  import { css } from "@codemirror/lang-css";
8
12
  import { javascript } from "@codemirror/lang-javascript";
@@ -310,12 +314,6 @@ var files_preview_default = /* @__PURE__ */ defineComponent({
310
314
  }
311
315
  });
312
316
  //#endregion
313
- //#region packages/playground/src/constants.ts
314
- var DEFAULT_ENTRY = "App.vue";
315
- /** 预览样式和默认 import map 共用的 npm CDN 前缀。 */
316
- var DEFAULT_CDN_URL = "https://cdn.jsdelivr.net/npm";
317
- var NEW_SFC_CODE = `<script setup lang="ts"><\/script>\n\n<template>\n <div>\n <slot />\n <\/div>\n<\/template>\n`;
318
- //#endregion
319
317
  //#region packages/playground/src/editor/drag.ts
320
318
  var events = typeof document !== "undefined" && "ontouchstart" in document ? {
321
319
  start: "touchstart",
@@ -439,7 +437,7 @@ var _hoisted_5$4 = ["onKeydown"];
439
437
  var _hoisted_6$3 = ["title"];
440
438
  var _hoisted_7$3 = ["title", "aria-label"];
441
439
  var _hoisted_8$2 = ["title", "aria-label"];
442
- var _hoisted_9$2 = { class: "docs-playground-editor__actions" };
440
+ var _hoisted_9$1 = { class: "docs-playground-editor__actions" };
443
441
  var _hoisted_10$1 = ["title"];
444
442
  var _hoisted_11$1 = ["title", "disabled"];
445
443
  var _hoisted_12$1 = {
@@ -755,7 +753,7 @@ var Editor = new Portal(/* @__PURE__ */ defineComponent({
755
753
  ], 64))], 42, _hoisted_4$4);
756
754
  }), 128))]),
757
755
  _: 1
758
- }, 512), createElementVNode("div", _hoisted_9$2, [createElementVNode("button", {
756
+ }, 512), createElementVNode("div", _hoisted_9$1, [createElementVNode("button", {
759
757
  type: "button",
760
758
  title: unref(t)("playground.editor.createFile"),
761
759
  onClick: handleCreate
@@ -833,229 +831,6 @@ var resolvePlaygroundTitleId = (title, explicitId = "", isOccupied) => {
833
831
  while (isOccupied(`${base}-${index}`)) index += 1;
834
832
  return `${base}-${index}`;
835
833
  };
836
- //#endregion
837
- //#region packages/playground/src/core/preview-scroll.ts
838
- /** iframe 包装成功后挂在 `html` 上,供样式与 auto-height 识别。 */
839
- var PREVIEW_SCROLL_HTML_CLASS = "docs-playground-preview-scroll";
840
- /** Scroller 内容节点 class,auto-height 优先测量该节点。 */
841
- var PREVIEW_SCROLL_CONTENT_CLASS = "docs-playground-preview-scroll__content";
842
- /** 重评时先清掉 html class,避免 `await import` 期间仍套用 `height:100%`。 */
843
- var PREVIEW_SCROLL_RESET_CODE = `document.documentElement.classList.remove("${PREVIEW_SCROLL_HTML_CLASS}");`;
844
- /** 动态探测 `@deot/vc`;失败时为空对象,不阻断 DocsLink / 预览挂载。 */
845
- var PREVIEW_SCROLLER_IMPORT_CODE = "const __docsVc=await import(\"@deot/vc\").catch(()=>({}))";
846
- /**
847
- * Vue 的 `mount` 闭包的是 `createApp(root)` 时的根组件,改 `app._component` 不会生效。
848
- * 因此劫持 `app.mount`:等全部 useCode 注册完后,再 `createApp` 包一层 Scroller。
849
- * 前导分号避免接在 `app.component(...)` 后被 ASI 解析成调用返回值。
850
- */
851
- var PREVIEW_SCROLLER_USE_CODE = [
852
- ";(()=>{",
853
- PREVIEW_SCROLL_RESET_CODE,
854
- "const __DocsScroller=__docsVc&&__docsVc.Scroller;",
855
- "if(!__DocsScroller)return;",
856
- "const UserApp=app._component;",
857
- "app.mount=(container,...rest)=>{",
858
- "const next=_createApp({",
859
- "name:\"DocsPreviewRoot\",",
860
- "setup(){return()=>__docsH(__DocsScroller,{",
861
- "height:\"100%\",",
862
- "native:false,",
863
- "autoResize:true,",
864
- "showBar:true,",
865
- `contentClass:"${PREVIEW_SCROLL_CONTENT_CLASS}"`,
866
- "},{default:()=>__docsH(UserApp)})}",
867
- "});",
868
- "next.config.errorHandler=app.config.errorHandler;",
869
- "if(app._context&&next._context){",
870
- "if(app._context.components)Object.assign(next._context.components,app._context.components);",
871
- "if(app._context.directives)Object.assign(next._context.directives,app._context.directives);",
872
- "Object.assign(next._context.provides,app._context.provides);",
873
- "next._context.mixins.push(...app._context.mixins);",
874
- "}",
875
- "window.__app__=next;",
876
- `document.documentElement.classList.add("${PREVIEW_SCROLL_HTML_CLASS}");`,
877
- "return next.mount(container,...rest)",
878
- "}",
879
- "})()"
880
- ].join("");
881
- var PREVIEW_SCROLLER_STYLE = [
882
- `html.${PREVIEW_SCROLL_HTML_CLASS},`,
883
- `html.${PREVIEW_SCROLL_HTML_CLASS} body,`,
884
- `html.${PREVIEW_SCROLL_HTML_CLASS} #app{`,
885
- "height:100%;min-height:100%;margin:0;overflow:hidden",
886
- "}",
887
- `html.${PREVIEW_SCROLL_HTML_CLASS} #app>.vc-scroller,`,
888
- `html.${PREVIEW_SCROLL_HTML_CLASS} #app>.vc-scroller>.vc-scroller__wrapper{`,
889
- "height:100%;max-height:100%;box-sizing:border-box",
890
- "}"
891
- ].join("");
892
- var resolveSandboxContainer = (sandbox) => sandbox?.container ? unref(sandbox.container) : null;
893
- var resolveScrollContent = (iframeDocument) => {
894
- if (!iframeDocument.documentElement.classList.contains("docs-playground-preview-scroll")) return null;
895
- return iframeDocument.querySelector(`.${PREVIEW_SCROLL_CONTENT_CLASS}`);
896
- };
897
- var useSandboxAutoHeight = (sandboxRef) => {
898
- const height = ref(24);
899
- let container = null;
900
- let iframe = null;
901
- let containerObserver = null;
902
- let contentObserver = null;
903
- let scrollMountObserver = null;
904
- let observedScrollNode = null;
905
- let frameId = 0;
906
- const cancelMeasure = () => {
907
- if (!frameId) return;
908
- cancelAnimationFrame(frameId);
909
- frameId = 0;
910
- };
911
- const measureDocumentContent = (iframeWindow, iframeDocument) => {
912
- const { body, documentElement } = iframeDocument;
913
- const bodyStyle = iframeWindow.getComputedStyle(body);
914
- const bodyMargins = (Number.parseFloat(bodyStyle.marginTop) || 0) + (Number.parseFloat(bodyStyle.marginBottom) || 0);
915
- const rootTop = documentElement.getBoundingClientRect().top;
916
- const bodyRect = body.getBoundingClientRect();
917
- const collapsedTop = Math.max(0, bodyRect.top - rootTop);
918
- let childrenBottom = 0;
919
- for (const child of body.children) {
920
- if (iframeWindow.getComputedStyle(child).position === "fixed") continue;
921
- const rect = child.getBoundingClientRect();
922
- const marginBottom = Number.parseFloat(iframeWindow.getComputedStyle(child).marginBottom) || 0;
923
- childrenBottom = Math.max(childrenBottom, rect.bottom + marginBottom - rootTop);
924
- }
925
- const scrollHeight = Math.max(body.scrollHeight, documentElement.scrollHeight);
926
- const overflowingHeight = scrollHeight > (iframe?.clientHeight || 0) + 1 ? scrollHeight : 0;
927
- return Math.ceil(Math.max(body.offsetHeight + bodyMargins + collapsedTop, bodyRect.height + bodyMargins + collapsedTop, childrenBottom, overflowingHeight));
928
- };
929
- const measureScrollContent = (scrollContent) => {
930
- const contentStyle = scrollContent.ownerDocument.defaultView?.getComputedStyle(scrollContent);
931
- const margins = contentStyle ? (Number.parseFloat(contentStyle.marginTop) || 0) + (Number.parseFloat(contentStyle.marginBottom) || 0) : 0;
932
- let childrenBottom = 0;
933
- const rootTop = scrollContent.getBoundingClientRect().top;
934
- for (const child of scrollContent.children) {
935
- const rect = child.getBoundingClientRect();
936
- const marginBottom = Number.parseFloat(scrollContent.ownerDocument.defaultView?.getComputedStyle(child).marginBottom || "0") || 0;
937
- childrenBottom = Math.max(childrenBottom, rect.bottom + marginBottom - rootTop);
938
- }
939
- return Math.ceil(Math.max(scrollContent.scrollHeight + margins, scrollContent.offsetHeight + margins, childrenBottom + margins));
940
- };
941
- const isPendingPreviewApp = (iframeDocument) => {
942
- const app = iframeDocument.getElementById("app");
943
- return app ? app.childElementCount === 0 : !!iframe?.srcdoc;
944
- };
945
- const releaseBootstrapHeight = (target) => {
946
- nextTick(() => {
947
- if (iframe === target) target.style.height = "100%";
948
- });
949
- };
950
- const measure = () => {
951
- frameId = 0;
952
- if (!iframe) return;
953
- try {
954
- const iframeWindow = iframe.contentWindow;
955
- const iframeDocument = iframe.contentDocument;
956
- if (!iframeWindow || !iframeDocument?.body) return;
957
- const scrollContent = resolveScrollContent(iframeDocument);
958
- if (!scrollContent && isPendingPreviewApp(iframeDocument)) return;
959
- const contentHeight = scrollContent ? measureScrollContent(scrollContent) : measureDocumentContent(iframeWindow, iframeDocument);
960
- const nextHeight = Math.max(contentHeight, 24);
961
- if (height.value !== nextHeight) height.value = nextHeight;
962
- releaseBootstrapHeight(iframe);
963
- } catch {
964
- if (height.value !== 24) height.value = 24;
965
- }
966
- };
967
- const scheduleMeasure = () => {
968
- if (frameId) return;
969
- frameId = requestAnimationFrame(measure);
970
- };
971
- const disconnectContent = () => {
972
- contentObserver?.disconnect();
973
- contentObserver = null;
974
- scrollMountObserver?.disconnect();
975
- scrollMountObserver = null;
976
- observedScrollNode = null;
977
- cancelMeasure();
978
- };
979
- const observeContent = () => {
980
- disconnectContent();
981
- if (!iframe) return;
982
- try {
983
- const iframeWindow = iframe.contentWindow;
984
- const iframeDocument = iframe.contentDocument;
985
- const Observer = iframeWindow?.ResizeObserver;
986
- if (!iframeWindow || !iframeDocument?.body || !Observer) {
987
- scheduleMeasure();
988
- return;
989
- }
990
- const observer = new Observer(scheduleMeasure);
991
- observer.observe(iframeDocument.documentElement);
992
- observer.observe(iframeDocument.body);
993
- contentObserver = observer;
994
- const attachScrollContent = (node) => {
995
- if (!node || !contentObserver) return false;
996
- if (observedScrollNode === node) return true;
997
- if (observedScrollNode) contentObserver.unobserve(observedScrollNode);
998
- observedScrollNode = node;
999
- contentObserver.observe(node);
1000
- return true;
1001
- };
1002
- const syncScrollContent = () => {
1003
- attachScrollContent(resolveScrollContent(iframeDocument));
1004
- scheduleMeasure();
1005
- };
1006
- scrollMountObserver = new MutationObserver(syncScrollContent);
1007
- scrollMountObserver.observe(iframeDocument.documentElement, {
1008
- attributes: true,
1009
- attributeFilter: ["class"]
1010
- });
1011
- scrollMountObserver.observe(iframeDocument.body, {
1012
- childList: true,
1013
- subtree: true
1014
- });
1015
- syncScrollContent();
1016
- } catch {
1017
- if (height.value !== 24) height.value = 24;
1018
- }
1019
- };
1020
- const handleIframeLoad = () => observeContent();
1021
- const setIframe = (nextIframe) => {
1022
- if (iframe === nextIframe) return;
1023
- iframe?.removeEventListener("load", handleIframeLoad);
1024
- disconnectContent();
1025
- iframe = nextIframe;
1026
- if (!iframe) {
1027
- height.value = 24;
1028
- return;
1029
- }
1030
- iframe.addEventListener("load", handleIframeLoad);
1031
- iframe.style.height = `${Math.max(window.innerHeight, 24)}px`;
1032
- observeContent();
1033
- };
1034
- const syncIframe = () => setIframe(container?.querySelector("iframe") || null);
1035
- const setContainer = (nextContainer) => {
1036
- if (container === nextContainer) return;
1037
- containerObserver?.disconnect();
1038
- containerObserver = null;
1039
- container = nextContainer;
1040
- setIframe(null);
1041
- if (!container) return;
1042
- containerObserver = new MutationObserver(syncIframe);
1043
- containerObserver.observe(container, {
1044
- childList: true,
1045
- subtree: true
1046
- });
1047
- syncIframe();
1048
- };
1049
- watch(() => resolveSandboxContainer(sandboxRef.value), setContainer, {
1050
- flush: "post",
1051
- immediate: true
1052
- });
1053
- onBeforeUnmount(() => {
1054
- setContainer(null);
1055
- cancelMeasure();
1056
- });
1057
- return height;
1058
- };
1059
834
  var resolvePreviewBoxHeight = (contentHeight, verticalInset = 0, borderWidth = 1) => {
1060
835
  const content = Number.isFinite(contentHeight) ? Math.max(0, contentHeight) : 0;
1061
836
  const inset = Number.isFinite(verticalInset) ? Math.max(0, verticalInset) : 0;
@@ -1134,68 +909,6 @@ var scrollPlaygroundToViewportStart = (el) => {
1134
909
  });
1135
910
  };
1136
911
  //#endregion
1137
- //#region packages/playground/src/core/runtime/error-guard.ts
1138
- var UNKNOWN_RUNTIME_ERROR = "运行时发生未知错误";
1139
- var MODULE_SPECIFIER_RE = /Failed to resolve module specifier|Error resolving module specifier/u;
1140
- var forwardSandboxRuntimeError = (event) => {
1141
- if (!(event instanceof ErrorEvent) || event.error != null || !event.message) return;
1142
- event.stopImmediatePropagation();
1143
- if (event.message === "ResizeObserver loop limit exceeded" || event.message === "ResizeObserver loop completed with undelivered notifications.") return;
1144
- window.parent.postMessage({
1145
- action: "error",
1146
- value: event.message
1147
- }, "*");
1148
- };
1149
- var SANDBOX_RUNTIME_ERROR_CAPTURE_HTML = [
1150
- "<script>",
1151
- `window.addEventListener('error', ${forwardSandboxRuntimeError.toString()}, true);`,
1152
- "<\/script>"
1153
- ].join("\n");
1154
- var toRuntimeErrorMessage = (value, message) => {
1155
- if (typeof value === "string" && value) return value;
1156
- if (value instanceof Error && value.message) return value.message;
1157
- if (value && typeof value === "object" && "message" in value) {
1158
- const valueMessage = value.message;
1159
- if (typeof valueMessage === "string" && valueMessage) return valueMessage;
1160
- }
1161
- if (typeof message === "string" && message) return message;
1162
- if (value !== null && value !== void 0) try {
1163
- return String(value);
1164
- } catch {
1165
- return UNKNOWN_RUNTIME_ERROR;
1166
- }
1167
- return UNKNOWN_RUNTIME_ERROR;
1168
- };
1169
- var normalizeRuntimeErrorMessage = (data) => {
1170
- if (!data || typeof data !== "object") return false;
1171
- const message = data;
1172
- if (message.action !== "error") return false;
1173
- message.value = toRuntimeErrorMessage(message.value, message.message);
1174
- return true;
1175
- };
1176
- var toErrorText = (value) => {
1177
- if (typeof value === "string" && value) return value;
1178
- if (value instanceof Error && value.message) return value.message;
1179
- return "";
1180
- };
1181
- var formatSandboxRuntimeError = (message, importMapTip) => {
1182
- if (!MODULE_SPECIFIER_RE.test(message)) return message;
1183
- return `${message.replace(/\. Relative references must.*$/u, "").replace(/\.$/u, "")}.\n${importMapTip}`;
1184
- };
1185
- var useSandboxRuntimeErrorGuard = (sandboxRef) => {
1186
- const error = ref("");
1187
- if (typeof window === "undefined") return error;
1188
- const handleMessage = (event) => {
1189
- const iframe = resolveSandboxContainer(sandboxRef.value)?.querySelector("iframe");
1190
- if (!iframe || event.source !== iframe.contentWindow) return;
1191
- if (!normalizeRuntimeErrorMessage(event.data)) return;
1192
- error.value = event.data.value;
1193
- };
1194
- window.addEventListener("message", handleMessage, true);
1195
- onBeforeUnmount(() => window.removeEventListener("message", handleMessage, true));
1196
- return error;
1197
- };
1198
- //#endregion
1199
912
  //#region packages/playground/src/core/runtime/viewport.ts
1200
913
  var DEFAULT_VIEWPORT_OPTIONS = ["auto", 375];
1201
914
  var isValidViewport = (viewport) => {
@@ -1401,16 +1114,16 @@ function usePreviewHeightBridge(sandbox, maxHeight = () => Infinity) {
1401
1114
  sync();
1402
1115
  };
1403
1116
  const handleMessage = async (event) => {
1404
- const iframe = resolveSandboxContainer(sandbox.value)?.querySelector("iframe");
1117
+ const current = resolveSandboxMessageSource(sandbox.value);
1405
1118
  const data = event.data;
1406
- if (!iframe?.contentWindow || event.source !== iframe.contentWindow || data?.action !== "docs:height" || typeof data.session !== "string") return;
1119
+ if (!current || event.source !== current || data?.action !== "docs:height" || typeof data.session !== "string") return;
1407
1120
  if (data.operation === "start") {
1408
1121
  reset();
1409
- source = iframe.contentWindow;
1122
+ source = current;
1410
1123
  session = data.session;
1411
1124
  return;
1412
1125
  }
1413
- if (source !== iframe.contentWindow || session !== data.session) return;
1126
+ if (source !== current || session !== data.session) return;
1414
1127
  if (data.operation === "stop") {
1415
1128
  reset();
1416
1129
  return;
@@ -1435,7 +1148,7 @@ function usePreviewHeightBridge(sandbox, maxHeight = () => Infinity) {
1435
1148
  accepted
1436
1149
  }, "*");
1437
1150
  };
1438
- watch(() => resolveSandboxContainer(sandbox.value), reset, { flush: "sync" });
1151
+ watch(() => resolveSandboxMessageSource(sandbox.value), reset, { flush: "sync" });
1439
1152
  if (typeof window !== "undefined") window.addEventListener("message", handleMessage);
1440
1153
  onBeforeUnmount(() => {
1441
1154
  disposed = true;
@@ -1469,7 +1182,7 @@ var _hoisted_8$1 = {
1469
1182
  class: "docs-playground__tool-divider",
1470
1183
  "aria-hidden": "true"
1471
1184
  };
1472
- var _hoisted_9$1 = ["aria-label"];
1185
+ var _hoisted_9 = ["aria-label"];
1473
1186
  var _hoisted_10 = [
1474
1187
  "title",
1475
1188
  "aria-label",
@@ -1642,7 +1355,7 @@ var toolbar_default = /* @__PURE__ */ defineComponent({
1642
1355
  "aria-pressed": item === __props.activeView,
1643
1356
  onClick: ($event) => emit("view-change", item)
1644
1357
  }, toDisplayString(getViewLabel(item)), 11, _hoisted_10);
1645
- }), 128))], 8, _hoisted_9$1)) : createCommentVNode("v-if", true),
1358
+ }), 128))], 8, _hoisted_9)) : createCommentVNode("v-if", true),
1646
1359
  __props.showClose && (__props.showRuntimeActions || showViews.value) ? (openBlock(), createElementBlock("span", _hoisted_11)) : createCommentVNode("v-if", true),
1647
1360
  __props.showClose ? (openBlock(), createElementBlock("button", {
1648
1361
  key: 3,
@@ -1661,647 +1374,6 @@ var toolbar_default = /* @__PURE__ */ defineComponent({
1661
1374
  }
1662
1375
  });
1663
1376
  //#endregion
1664
- //#region packages/playground/src/cdn.ts
1665
- var PREVIEW_STYLE_ASSETS = [
1666
- "@deot/style/dist/index.normalize-only.css",
1667
- "@deot/vc-components/dist/index.style.css",
1668
- "@deot/style/dist/index.css"
1669
- ];
1670
- var BUILTIN_IMPORT_ASSETS = {
1671
- "@deot/vc": "@deot/vc/dist/index.js",
1672
- "@deot/vc-shared": "@deot/vc-shared/dist/index.js",
1673
- "@deot/vc-hooks": "@deot/vc-hooks/dist/index.js",
1674
- "@deot/vc-components": "@deot/vc-components/dist/index.js",
1675
- "@deot/helper-resize": "@deot/helper-resize/dist/index.js",
1676
- "@deot/helper-utils": "@deot/helper-utils/dist/index.js",
1677
- "@deot/helper-cache": "@deot/helper-cache/dist/index.js",
1678
- "@deot/helper-fp": "@deot/helper-fp/dist/index.js",
1679
- "@deot/helper-dom": "@deot/helper-dom/dist/index.js",
1680
- "@deot/helper-wheel": "@deot/helper-wheel/dist/index.js",
1681
- "@deot/helper-validator": "@deot/helper-validator/dist/index.js",
1682
- "@deot/helper-load": "@deot/helper-load/dist/index.js",
1683
- "@deot/helper-scheduler": "@deot/helper-scheduler/dist/index.js",
1684
- "@deot/helper-emitter": "@deot/helper-emitter/dist/index.js",
1685
- "@deot/helper-is": "@deot/helper-is/dist/index.js",
1686
- "@deot/helper-device": "@deot/helper-device/dist/index.js",
1687
- "@deot/helper-route": "@deot/helper-route/dist/index.js",
1688
- "@deot/helper-unicode": "@deot/helper-unicode/dist/index.js",
1689
- "@deot/helper": "@deot/helper/dist/index.js",
1690
- "normalize-wheel": "normalize-wheel-es/dist/index.mjs",
1691
- "photoswipe": "photoswipe/dist/photoswipe.esm.js",
1692
- "photoswipe/lightbox": "photoswipe/dist/photoswipe-lightbox.esm.js",
1693
- "vue": "vue/dist/vue.runtime.esm-browser.js",
1694
- "vue/server-renderer": "vue/dist/server-renderer.esm-browser.js"
1695
- };
1696
- var normalizeCdnURL = (cdnURL = DEFAULT_CDN_URL) => {
1697
- return cdnURL.trim().replace(/\/+$/u, "") || "https://cdn.jsdelivr.net/npm";
1698
- };
1699
- var cdnJoin = (origin, asset) => `${origin}/${asset.replace(/^\/+/u, "")}`;
1700
- var jsdelivrEsmURL = (asset) => cdnJoin(DEFAULT_CDN_URL, asset);
1701
- var SASS_CDN_URL = jsdelivrEsmURL("sass/+esm");
1702
- var cdnAsset = (cdnURL, asset) => cdnJoin(normalizeCdnURL(cdnURL), asset);
1703
- var createBuiltinImports = (cdnURL = DEFAULT_CDN_URL) => ({
1704
- ...Object.fromEntries(Object.entries(BUILTIN_IMPORT_ASSETS).map(([specifier, asset]) => [specifier, cdnAsset(cdnURL, asset)])),
1705
- "lodash-es": jsdelivrEsmURL("lodash-es/+esm")
1706
- });
1707
- var createBuiltinStyles = (cdnURL = DEFAULT_CDN_URL) => Object.fromEntries(PREVIEW_STYLE_ASSETS.map((asset) => [asset, cdnAsset(cdnURL, asset)]));
1708
- //#endregion
1709
- //#region packages/playground/src/import-map.ts
1710
- /**
1711
- * 站点级同步内存:`$docs.modules` / `$docs.styles` 与管理页 import、CSS 覆盖。
1712
- */
1713
- var normalize = (value) => value.trim();
1714
- var isSafePlaygroundHref = (href) => {
1715
- const next = href.trim();
1716
- if (!next) return false;
1717
- if (/^https?:\/\//iu.test(next)) return true;
1718
- return next.startsWith("/") && !next.startsWith("//");
1719
- };
1720
- var filterSafeHrefs = (value = {}) => Object.fromEntries(Object.entries(value).filter((entry) => typeof entry[1] === "string" && isSafePlaygroundHref(entry[1])));
1721
- var sanitizeMap = (value = {}) => filterSafeHrefs(Object.fromEntries(Object.entries(value).map(([alias, url]) => [normalize(alias), normalize(url)]).filter(([alias]) => Boolean(alias))));
1722
- var createMapStore = () => {
1723
- let data = {};
1724
- const snapshot = () => ({ ...data });
1725
- const drop = (alias) => {
1726
- if (data[alias] === void 0) return snapshot();
1727
- const next = { ...data };
1728
- delete next[alias];
1729
- data = next;
1730
- return snapshot();
1731
- };
1732
- return {
1733
- get: snapshot,
1734
- set: (value = {}) => {
1735
- data = sanitizeMap(value);
1736
- },
1737
- apply: (alias, url) => {
1738
- const nextAlias = normalize(alias);
1739
- const nextUrl = normalize(url);
1740
- if (!nextAlias) return snapshot();
1741
- if (!isSafePlaygroundHref(nextUrl)) return drop(nextAlias);
1742
- data = {
1743
- ...data,
1744
- [nextAlias]: nextUrl
1745
- };
1746
- return snapshot();
1747
- },
1748
- remove: (alias) => {
1749
- const nextAlias = normalize(alias);
1750
- return nextAlias ? drop(nextAlias) : snapshot();
1751
- }
1752
- };
1753
- };
1754
- var siteModules = createMapStore();
1755
- var siteStyles = createMapStore();
1756
- var importOverrides = createMapStore();
1757
- var styleOverrides = createMapStore();
1758
- /**
1759
- * 站点默认 import。合并时夹在内置 CDN 与实例 `builtinImportMap` 之间。
1760
- */
1761
- var getPlaygroundSiteModules = siteModules.get;
1762
- var setPlaygroundSiteModules = siteModules.set;
1763
- /**
1764
- * 站点默认预览 CSS。合并时夹在内置样式表与管理页覆盖之间。
1765
- */
1766
- var getPlaygroundSiteStyles = siteStyles.get;
1767
- var setPlaygroundSiteStyles = siteStyles.set;
1768
- var getPlaygroundImportMapOverrides = importOverrides.get;
1769
- var setPlaygroundImportMapOverrides = importOverrides.set;
1770
- var applyPlaygroundImportMapOverride = importOverrides.apply;
1771
- var removePlaygroundImportMapOverride = importOverrides.remove;
1772
- var getPlaygroundStyleOverrides = styleOverrides.get;
1773
- var setPlaygroundStyleOverrides = styleOverrides.set;
1774
- var applyPlaygroundStyleOverride = styleOverrides.apply;
1775
- var removePlaygroundStyleOverride = styleOverrides.remove;
1776
- var clearPlaygroundMaps = () => {
1777
- [
1778
- siteModules,
1779
- siteStyles,
1780
- importOverrides,
1781
- styleOverrides
1782
- ].forEach((store) => store.set());
1783
- };
1784
- //#endregion
1785
- //#region packages/playground/src/preview-service.ts
1786
- /** Preview iframe 内的高度服务;class 会被序列化到 iframe 执行。 */
1787
- var PlaygroundService = class {
1788
- target;
1789
- vue;
1790
- session;
1791
- /* istanbul ignore next -- class 会被序列化到没有覆盖率运行时的 iframe。 */
1792
- sequence = 0;
1793
- /* istanbul ignore next -- class 会被序列化到没有覆盖率运行时的 iframe。 */
1794
- disposed = false;
1795
- manual;
1796
- /* istanbul ignore next -- class 会被序列化到没有覆盖率运行时的 iframe。 */
1797
- requests = /* @__PURE__ */ new Set();
1798
- /* istanbul ignore next -- class 会被序列化到没有覆盖率运行时的 iframe。 */
1799
- owners = /* @__PURE__ */ new Set();
1800
- /**
1801
- * @param target 当前预览窗口。
1802
- * @param vue 与预览应用共用的 Vue 实例。
1803
- */
1804
- /* istanbul ignore next -- class 会被序列化到没有覆盖率运行时的 iframe。 */
1805
- constructor(target, vue) {
1806
- this.target = target;
1807
- this.vue = vue;
1808
- this.session = `${Date.now()}-${Math.random()}`;
1809
- this.dispose = this.dispose.bind(this);
1810
- this.post("start");
1811
- this.target.addEventListener("pagehide", this.dispose);
1812
- }
1813
- /**
1814
- * 申请手动临时高度;新请求会替换上一个手动请求。
1815
- * @param height iframe 最小高度。
1816
- * @returns iframe 是否在超时前应用目标高度。
1817
- */
1818
- enable(height) {
1819
- this.validateHeight(height);
1820
- this.manual?.release();
1821
- this.manual = this.createRequest(height);
1822
- return this.manual.ready;
1823
- }
1824
- /** 释放手动临时高度,不影响 `run` 创建的请求。 */
1825
- disable() {
1826
- this.manual?.release();
1827
- this.manual = void 0;
1828
- }
1829
- /**
1830
- * 创建等待高度后执行的事件处理函数。
1831
- * @param height iframe 最小高度。
1832
- * @param optionsOrHandler 可见状态配置,或最后一个 handler。
1833
- * @param lastHandler 使用配置时的最后一个 handler。
1834
- * @returns 保留 handler 参数和结果的异步事件处理函数。
1835
- */
1836
- run(height, optionsOrHandler, lastHandler) {
1837
- this.validateHeight(height);
1838
- if (optionsOrHandler === void 0) return (visible) => {
1839
- if (visible) return this.enable(height);
1840
- this.disable();
1841
- return Promise.resolve(void 0);
1842
- };
1843
- const visible = (typeof optionsOrHandler === "function" ? {} : optionsOrHandler).visible;
1844
- if (visible !== void 0 && !this.vue.isRef(visible) && typeof visible !== "function") throw new TypeError("Playground visible must be a ref or getter");
1845
- const handler = typeof optionsOrHandler === "function" ? optionsOrHandler : lastHandler ?? (this.vue.isRef(visible) ? () => {
1846
- visible.value = true;
1847
- } : void 0);
1848
- if (typeof handler !== "function") throw new TypeError("Playground run requires a handler");
1849
- let ownerDisposed = false;
1850
- let current;
1851
- let pending;
1852
- const disposeOwner = () => {
1853
- ownerDisposed = true;
1854
- current?.release();
1855
- this.owners.delete(disposeOwner);
1856
- };
1857
- this.owners.add(disposeOwner);
1858
- if (this.vue.getCurrentScope()) this.vue.onScopeDispose(disposeOwner);
1859
- return (...args) => {
1860
- if (this.disposed || ownerDisposed) return Promise.resolve(void 0);
1861
- if (pending) return pending;
1862
- const request = current = this.createRequest(height);
1863
- let executionFinished = false;
1864
- const unlock = () => {
1865
- if (executionFinished && request.released && current === request) {
1866
- pending = void 0;
1867
- current = void 0;
1868
- }
1869
- };
1870
- request.closed.then(unlock);
1871
- const execution = (async () => {
1872
- try {
1873
- if (!await request.ready || ownerDisposed || this.disposed) return void 0;
1874
- if (visible) request.watch(visible);
1875
- const result = await handler(...args);
1876
- if (!visible || !this.vue.toValue(visible)) request.release();
1877
- return result;
1878
- } catch (error) {
1879
- request.release();
1880
- throw error;
1881
- } finally {
1882
- executionFinished = true;
1883
- unlock();
1884
- }
1885
- })();
1886
- pending = execution;
1887
- return execution;
1888
- };
1889
- }
1890
- /** 释放当前预览应用持有的全部高度和监听。 */
1891
- /* istanbul ignore next -- 注入测试会从序列化后的 iframe class 调用该方法。 */
1892
- dispose() {
1893
- if (this.disposed) return;
1894
- this.disposed = true;
1895
- for (const disposeOwner of this.owners) disposeOwner();
1896
- for (const request of this.requests) request.release();
1897
- this.post("stop");
1898
- this.target.removeEventListener("pagehide", this.dispose);
1899
- if (this.target.$docsPlayground === this) delete this.target.$docsPlayground;
1900
- }
1901
- /** @param height iframe 最小高度。 */
1902
- validateHeight(height) {
1903
- if (!Number.isFinite(height) || height <= 0) throw new TypeError("Playground height must be a positive finite number");
1904
- }
1905
- /**
1906
- * @param operation 请求操作。
1907
- * @param id 请求标识。
1908
- * @param height iframe 最小高度。
1909
- */
1910
- /* istanbul ignore next -- 构造和销毁时会从序列化后的 iframe class 调用该方法。 */
1911
- post(operation, id = 0, height = 0) {
1912
- this.target.parent.postMessage({
1913
- action: "docs:height",
1914
- session: this.session,
1915
- operation,
1916
- id,
1917
- height
1918
- }, "*");
1919
- }
1920
- /**
1921
- * @param height iframe 最小高度。
1922
- * @returns 内部等待与释放句柄。
1923
- */
1924
- createRequest(height) {
1925
- this.validateHeight(height);
1926
- const id = ++this.sequence;
1927
- let released = false;
1928
- let settled = false;
1929
- let frame = 0;
1930
- let timer = 0;
1931
- let stopWatch;
1932
- let resolveReady;
1933
- let resolveClosed;
1934
- const ready = new Promise((resolve) => {
1935
- resolveReady = resolve;
1936
- });
1937
- const closed = new Promise((resolve) => {
1938
- resolveClosed = resolve;
1939
- });
1940
- const stopWaiting = () => {
1941
- this.target.cancelAnimationFrame(frame);
1942
- if (timer) {
1943
- this.target.clearTimeout(timer);
1944
- timer = 0;
1945
- }
1946
- this.target.removeEventListener("message", onMessage);
1947
- };
1948
- const release = () => {
1949
- if (released) return;
1950
- released = true;
1951
- stopWaiting();
1952
- stopWatch?.();
1953
- resolveReady(false);
1954
- resolveClosed();
1955
- this.requests.delete(request);
1956
- this.post("release", id);
1957
- };
1958
- const check = () => {
1959
- if (released) return;
1960
- if (this.target.innerHeight >= height) {
1961
- settled = true;
1962
- stopWaiting();
1963
- resolveReady(true);
1964
- } else frame = this.target.requestAnimationFrame(check);
1965
- };
1966
- const onMessage = (event) => {
1967
- const data = event.data;
1968
- if (event.source !== this.target.parent || data?.action !== "docs:height:applied" || data.session !== this.session || data.id !== id || settled) return;
1969
- if (!data.accepted) release();
1970
- else check();
1971
- };
1972
- const request = {
1973
- ready,
1974
- closed,
1975
- get released() {
1976
- return released;
1977
- },
1978
- release,
1979
- watch: (visible) => {
1980
- stopWatch = this.vue.watch(() => this.vue.toValue(visible), (value) => {
1981
- if (!value) release();
1982
- }, { flush: "sync" });
1983
- }
1984
- };
1985
- this.requests.add(request);
1986
- if (this.disposed) release();
1987
- else {
1988
- this.target.addEventListener("message", onMessage);
1989
- timer = this.target.setTimeout(() => {
1990
- timer = 0;
1991
- release();
1992
- }, 2e3);
1993
- this.post("enable", id, height);
1994
- }
1995
- return request;
1996
- }
1997
- };
1998
- var PREVIEW_SERVICE_IMPORT_CODE = "import * as __docsPreviewVue from \"vue\"";
1999
- var PREVIEW_SERVICE_USE_CODE = [
2000
- `;const __docsPlayground=new (${PlaygroundService.toString()})(window,__docsPreviewVue);`,
2001
- "app.provide(\"docs:playground\",__docsPlayground);",
2002
- "window.$docsPlayground=__docsPlayground;",
2003
- "app.mixin({beforeUnmount(){if(this===this.$root)__docsPlayground.dispose()}});"
2004
- ].join("");
2005
- //#endregion
2006
- //#region packages/playground/src/core/scss.ts
2007
- var SCHEME = "docs-playground";
2008
- var STYLE_EXTS = [".scss", ".sass"];
2009
- var VUE_SCSS_STYLE_RE = /<style\b[^>]*\blang\s*=\s*(['"]?)s[ac]ss\1/i;
2010
- var LANG_ATTR_RE = /\s*lang\s*=\s*(['"]?)s[ac]ss\1/i;
2011
- var SCSS_ERROR_MARK = "[playground-sass]";
2012
- var INJECT_START = "/* docs-playground-scss-start */";
2013
- var INJECT_END = "/* docs-playground-scss-end */";
2014
- var EMPTY_JS = "export default {}\n";
2015
- var boundStores = /* @__PURE__ */ new WeakSet();
2016
- var wrappedCompilers = /* @__PURE__ */ new WeakSet();
2017
- var testLoader;
2018
- var loadedSass;
2019
- var loadPromise;
2020
- var fileCode = (value) => typeof value === "string" ? value : value.code;
2021
- var playgroundPath = (url) => decodeURIComponent(url.pathname.replace(/^\/+/u, ""));
2022
- var toPlaygroundUrl = (filename) => new URL(`${SCHEME}:///${filename.replace(/^\/+/u, "")}`);
2023
- var basename = (path) => path.split("/").pop() || path;
2024
- var scssSyntax = (filename, lang) => lang === "sass" || /\.sass$/i.test(filename) ? "indented" : "scss";
2025
- var errorText = (item) => item instanceof Error ? item.message : String(item);
2026
- var isScssFile = (filename) => /\.s[ac]ss$/i.test(filename);
2027
- var vueSourceNeedsScss = (source) => VUE_SCSS_STYLE_RE.test(source);
2028
- var resolveSassModule = async (url) => {
2029
- const mod = await import(
2030
- /* @vite-ignore */
2031
- url
2032
- );
2033
- const sass = typeof mod.compileString === "function" ? mod : mod.default;
2034
- if (typeof sass?.compileString !== "function") throw new Error(`Sass module at ${url} does not export compileString`);
2035
- return sass;
2036
- };
2037
- var loadSass = () => {
2038
- loadPromise ??= (testLoader ?? (() => resolveSassModule(SASS_CDN_URL)))().then((sass) => {
2039
- loadedSass = sass;
2040
- return sass;
2041
- });
2042
- return loadPromise;
2043
- };
2044
- var isScssPartial = (filename) => isScssFile(filename) && basename(filename).startsWith("_");
2045
- var filesNeedScss = (files) => Object.entries(files).some(([filename, value]) => isScssFile(filename) || /\.vue$/i.test(filename) && vueSourceNeedsScss(fileCode(value)));
2046
- var whenSassReady = (files, run) => {
2047
- if (!filesNeedScss(files) || loadedSass) run();
2048
- else loadSass().then(run);
2049
- };
2050
- var toPlaygroundFileMap = (files) => Object.fromEntries(Object.entries(files).map(([filename, value]) => [filename, fileCode(value)]));
2051
- var formatScssError = (filename, message) => `${SCSS_ERROR_MARK} ${filename}: ${message}`;
2052
- var scssFail = (filename, error) => formatScssError(filename, errorText(error));
2053
- var withUnderscore = (path) => {
2054
- const base = basename(path);
2055
- if (base.startsWith("_")) return path;
2056
- return `${path.slice(0, -base.length)}_${base}`;
2057
- };
2058
- var matchFileKey = (files, path) => [
2059
- path,
2060
- path.startsWith("src/") ? path : `src/${path}`,
2061
- path.replace(/^src\//u, "")
2062
- ].find((key) => files[key] !== void 0);
2063
- var stylesheetCandidates = (requestPath) => {
2064
- if (isScssFile(requestPath)) return [requestPath, withUnderscore(requestPath)];
2065
- return STYLE_EXTS.flatMap((ext) => [
2066
- `${requestPath}${ext}`,
2067
- withUnderscore(`${requestPath}${ext}`),
2068
- `${requestPath}/index${ext}`,
2069
- withUnderscore(`${requestPath}/index${ext}`)
2070
- ]);
2071
- };
2072
- var resolvePlaygroundStylesheet = (files, requestPath) => {
2073
- const found = [...new Set(stylesheetCandidates(requestPath).map((path) => matchFileKey(files, path)).filter((key) => Boolean(key)))];
2074
- if (found.length > 1) throw new Error(`Ambiguous Sass import "${requestPath}": ${found.join(", ")}`);
2075
- return found[0] ?? null;
2076
- };
2077
- var createPlaygroundImporter = (getFiles) => ({
2078
- canonicalize(url, context) {
2079
- if (/^[a-zA-Z][\w+.-]*:/u.test(url) && !url.startsWith(`${SCHEME}:`)) return null;
2080
- try {
2081
- const resolved = resolvePlaygroundStylesheet(getFiles(), playgroundPath(new URL(url, context.containingUrl ?? toPlaygroundUrl(""))));
2082
- return resolved ? toPlaygroundUrl(resolved) : null;
2083
- } catch {
2084
- return null;
2085
- }
2086
- },
2087
- load(canonicalUrl) {
2088
- const files = getFiles();
2089
- const key = playgroundPath(canonicalUrl);
2090
- return files[key] === void 0 ? null : {
2091
- contents: files[key],
2092
- syntax: scssSyntax(key)
2093
- };
2094
- }
2095
- });
2096
- var compileScssSource = (source, filename, sass, files, lang) => {
2097
- const importer = createPlaygroundImporter(() => files);
2098
- return sass.compileString(source, {
2099
- syntax: scssSyntax(filename, lang),
2100
- url: toPlaygroundUrl(filename),
2101
- importer,
2102
- importers: [importer]
2103
- }).css;
2104
- };
2105
- var rewriteVueSfcStyles = (source, filename, parse, sass, files) => {
2106
- const scssStyles = parse(source, { filename }).descriptor.styles.filter((style) => style.lang === "scss" || style.lang === "sass");
2107
- if (!scssStyles.length) return {
2108
- code: source,
2109
- errors: []
2110
- };
2111
- const errors = [];
2112
- let code = source;
2113
- for (const style of [...scssStyles].sort((left, right) => right.loc.start.offset - left.loc.start.offset)) {
2114
- const before = code.slice(0, style.loc.start.offset);
2115
- const after = code.slice(style.loc.end.offset);
2116
- const openStart = before.lastIndexOf("<style");
2117
- if (openStart < 0) {
2118
- errors.push(formatScssError(filename, "unable to locate <style> opening tag"));
2119
- continue;
2120
- }
2121
- try {
2122
- const css = compileScssSource(style.content, filename, sass, files, style.lang);
2123
- code = `${before.slice(0, openStart)}${before.slice(openStart).replace(LANG_ATTR_RE, "")}${css}${after}`;
2124
- } catch (error) {
2125
- errors.push(scssFail(filename, error));
2126
- }
2127
- }
2128
- return {
2129
- code,
2130
- errors
2131
- };
2132
- };
2133
- var appendParseErrors = (result, errors) => errors.length ? {
2134
- ...result,
2135
- errors: [...result.errors, ...errors.map((item) => new Error(item))]
2136
- } : result;
2137
- var wrapCompiler = (compiler, getFiles) => {
2138
- if (wrappedCompilers.has(compiler)) return compiler;
2139
- const originalParse = compiler.parse.bind(compiler);
2140
- const wrapped = { ...compiler };
2141
- wrapped.parse = ((source, options) => {
2142
- const filename = options?.filename || "anonymous.vue";
2143
- if (!vueSourceNeedsScss(source)) return originalParse(source, options);
2144
- const rewritten = loadedSass ? rewriteVueSfcStyles(source, filename, originalParse, loadedSass, getFiles()) : {
2145
- code: source,
2146
- errors: [formatScssError(filename, "compiler is not loaded")]
2147
- };
2148
- return appendParseErrors(originalParse(rewritten.errors.length ? source : rewritten.code, options), rewritten.errors);
2149
- });
2150
- wrappedCompilers.add(wrapped);
2151
- return wrapped;
2152
- };
2153
- var withInjectedCss = (css, extra) => {
2154
- const start = css.indexOf(INJECT_START);
2155
- const end = start < 0 ? -1 : css.indexOf(INJECT_END, start);
2156
- const base = (start < 0 ? css : `${css.slice(0, start)}${end >= 0 ? css.slice(end + 30) : ""}`).trimEnd();
2157
- if (!extra.trim()) return base;
2158
- const block = `${INJECT_START}\n${extra.trim()}\n${INJECT_END}`;
2159
- return base ? `${base}\n${block}` : block;
2160
- };
2161
- var isStandaloneScssError = (item) => {
2162
- const text = errorText(item);
2163
- return text.startsWith(SCSS_ERROR_MARK) && /\.s[ac]ss:/i.test(text);
2164
- };
2165
- var syncScssErrors = (store, scssErrors) => {
2166
- const next = [...scssErrors, ...store.errors.filter((item) => !isStandaloneScssError(item))];
2167
- if (next.map(String).join("\0") === store.errors.map(String).join("\0")) return;
2168
- store.errors = next;
2169
- };
2170
- var applyStandaloneScss = (store, sass = loadedSass) => {
2171
- if (!sass) return [];
2172
- const fileMap = toPlaygroundFileMap(store.files);
2173
- const errors = [];
2174
- const injected = [];
2175
- for (const [filename, file] of Object.entries(store.files)) {
2176
- if (!isScssFile(filename) || !file.compiled) continue;
2177
- try {
2178
- const css = compileScssSource(file.code, filename, sass, fileMap);
2179
- file.compiled.css = css;
2180
- file.compiled.js = EMPTY_JS;
2181
- file.compiled.ssr = EMPTY_JS;
2182
- if (!isScssPartial(filename) && css.trim()) injected.push(css);
2183
- } catch (error) {
2184
- errors.push(scssFail(filename, error));
2185
- }
2186
- }
2187
- const main = store.files[store.mainFile];
2188
- if (main?.compiled) {
2189
- const next = withInjectedCss(main.compiled.css || "", injected.join("\n"));
2190
- if (next !== (main.compiled.css || "")) main.compiled.css = next;
2191
- }
2192
- syncScssErrors(store, errors);
2193
- return errors;
2194
- };
2195
- var bindPlaygroundScss = (store) => {
2196
- if (boundStores.has(store)) return;
2197
- boundStores.add(store);
2198
- const getFiles = () => toPlaygroundFileMap(store.files);
2199
- const installCompiler = () => {
2200
- if (typeof store.compiler?.parse === "function") store.compiler = wrapCompiler(store.compiler, getFiles);
2201
- };
2202
- installCompiler();
2203
- watch(() => store.compiler, installCompiler);
2204
- watch(() => [
2205
- store.mainFile,
2206
- store.files[store.mainFile]?.compiled?.css,
2207
- store.errors.map(String).join("\0"),
2208
- Object.entries(store.files).filter(([filename]) => isScssFile(filename)).map(([filename, file]) => `${filename}:${file.code}`).join("\n")
2209
- ].join("\0"), () => {
2210
- if (loadedSass) applyStandaloneScss(store);
2211
- });
2212
- const originalSetFiles = store.setFiles.bind(store);
2213
- store.setFiles = async (newFiles, mainFile) => {
2214
- if (filesNeedScss(newFiles) && !loadedSass) await loadSass();
2215
- return originalSetFiles(newFiles, mainFile);
2216
- };
2217
- };
2218
- //#endregion
2219
- //#region packages/playground/src/core/store.ts
2220
- var DOCS_LINK_IMPORT_CODE = "import { h as __docsH } from \"vue\"";
2221
- var DOCS_LINK_USE_CODE = [
2222
- PREVIEW_SCROLL_RESET_CODE,
2223
- "app.component(\"DocsLink\",{",
2224
- "props:{to:{type:String,default:\"\"}},",
2225
- "setup(props,{slots}){return()=>__docsH(\"a\",{",
2226
- "href:props.to,",
2227
- "style:{color:\"inherit\",textDecoration:\"none\"},",
2228
- "onClick(event){event.preventDefault();window.parent.postMessage({action:\"docs:navigate\",to:props.to},\"*\")}",
2229
- "},slots.default?.())}",
2230
- "})"
2231
- ].join("");
2232
- var escapeHtmlAttr = (value) => value.replace(/&/gu, "&amp;").replace(/"/gu, "&quot;").replace(/'/gu, "&#39;").replace(/</gu, "&lt;").replace(/>/gu, "&gt;");
2233
- /**
2234
- * runtime 画布色。`previewInset` 露出的 padding、iframe chrome 和 sandbox
2235
- * `html`/`body` 必须共用这一变量,暗色下 `--docs-background-color` 与
2236
- * `--vc-background-color-light` 不同,否则会出现色带割裂。
2237
- */
2238
- var PLAYGROUND_RUNTIME_CANVAS_BACKGROUND = "var(--vc-background-color-light, var(--docs-background-color, #fff))";
2239
- var createRuntimePreviewOptions = (cdnURL = DEFAULT_CDN_URL, options = {}) => {
2240
- const previewScroller = options.previewScroller === true;
2241
- const hrefs = Object.values({
2242
- ...createBuiltinStyles(cdnURL),
2243
- ...getPlaygroundSiteStyles(),
2244
- ...getPlaygroundStyleOverrides()
2245
- });
2246
- const styleBlocks = [
2247
- `html,body{height:auto;min-height:0;background:${PLAYGROUND_RUNTIME_CANVAS_BACKGROUND}}`,
2248
- "body{color:var(--vc-foreground-color,#080f20)}",
2249
- ...previewScroller ? [PREVIEW_SCROLLER_STYLE] : []
2250
- ];
2251
- return {
2252
- showRuntimeError: false,
2253
- showRuntimeWarning: false,
2254
- headHTML: [
2255
- SANDBOX_RUNTIME_ERROR_CAPTURE_HTML,
2256
- "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">",
2257
- ...hrefs.map((href) => `<link rel="stylesheet" href="${escapeHtmlAttr(href)}">`),
2258
- "<style>",
2259
- ...styleBlocks,
2260
- "</style>"
2261
- ].join("\n"),
2262
- customCode: {
2263
- importCode: `${DOCS_LINK_IMPORT_CODE}\n${PREVIEW_SERVICE_IMPORT_CODE}`,
2264
- useCode: `${DOCS_LINK_USE_CODE}\n${PREVIEW_SERVICE_USE_CODE}`
2265
- }
2266
- };
2267
- };
2268
- var toReplFilename = (filename) => filename.startsWith("src/") ? filename : `src/${filename}`;
2269
- var createReplFile = (filename, code) => {
2270
- const replFilename = toReplFilename(filename);
2271
- return new File(replFilename, code);
2272
- };
2273
- var createRuntimeStore = (files, entry, options) => {
2274
- const { cdnURL, builtinImportMap, ...storeOptions } = options;
2275
- const replFiles = ref(Object.fromEntries(Object.entries(files).map(([filename, code]) => {
2276
- const file = createReplFile(filename, code);
2277
- return [file.filename, file];
2278
- })));
2279
- const mainFile = ref(toReplFilename(entry));
2280
- const activeFilename = ref(toReplFilename(entry));
2281
- const store = useStore({
2282
- ...storeOptions,
2283
- files: replFiles,
2284
- mainFile,
2285
- activeFilename,
2286
- builtinImportMap: ref({
2287
- ...builtinImportMap,
2288
- imports: {
2289
- ...createBuiltinImports(cdnURL),
2290
- ...getPlaygroundSiteModules(),
2291
- ...filterSafeHrefs(builtinImportMap?.imports),
2292
- ...getPlaygroundImportMapOverrides()
2293
- }
2294
- }),
2295
- template: ref({
2296
- welcomeSFC: files[entry],
2297
- newSFC: NEW_SFC_CODE
2298
- })
2299
- });
2300
- bindPlaygroundScss(store);
2301
- whenSassReady(files, () => store.init());
2302
- return store;
2303
- };
2304
- //#endregion
2305
1377
  //#region packages/playground/src/core/runtime/alone/wrapper.vue?vue&type=script&setup=true&lang.ts
2306
1378
  var _hoisted_1$2 = ["aria-label"];
2307
1379
  var _hoisted_2$2 = { class: "docs-playground-popup__frame" };
@@ -2328,6 +1400,17 @@ var Alone = new Portal(/* @__PURE__ */ defineComponent({
2328
1400
  clearConsole: {
2329
1401
  type: Boolean,
2330
1402
  default: true
1403
+ },
1404
+ local: {
1405
+ type: Boolean,
1406
+ default: true
1407
+ },
1408
+ files: { default: () => ({}) },
1409
+ entry: { default: "" },
1410
+ options: { default: () => ({}) },
1411
+ previewScroller: {
1412
+ type: Boolean,
1413
+ default: false
2331
1414
  }
2332
1415
  },
2333
1416
  emits: [
@@ -2337,20 +1420,28 @@ var Alone = new Portal(/* @__PURE__ */ defineComponent({
2337
1420
  "portal-fulfilled"
2338
1421
  ],
2339
1422
  setup(__props, { emit: __emit }) {
1423
+ const LocalSandbox = defineAsyncComponent(() => import("./local-sandbox-DvcgaBOa.js").then((n) => n.t));
2340
1424
  const props = __props;
2341
1425
  const emit = __emit;
2342
1426
  const { t } = useLocale();
2343
1427
  const currentViewport = ref(props.viewport);
2344
1428
  const sandboxRef = ref(null);
1429
+ const localError = ref({
1430
+ compile: "",
1431
+ runtime: ""
1432
+ });
1433
+ const handleLocalError = (payload) => {
1434
+ localError.value = payload;
1435
+ };
2345
1436
  const availableHeight = () => Math.max(0, getWindowInnerSize().height - 40 - 44);
2346
1437
  const temporaryHeight = usePreviewHeightBridge(sandboxRef, availableHeight);
2347
1438
  const sandboxKey = ref(0);
2348
1439
  const layoutTick = ref(0);
2349
1440
  const runtimeError = useSandboxRuntimeErrorGuard(sandboxRef);
2350
1441
  useSandboxTheme(sandboxRef);
2351
- const storeErrors = computed(() => (props.store.errors || []).map(toErrorText).filter(Boolean).join("\n"));
1442
+ const storeErrors = computed(() => props.local ? localError.value.compile : (props.store?.errors || []).map(toErrorText).filter(Boolean).join("\n"));
2352
1443
  const errorText = computed(() => {
2353
- const runtime = runtimeError.value ? formatSandboxRuntimeError(runtimeError.value, t("playground.runtime.importMapTip")) : "";
1444
+ const runtime = props.local ? localError.value.runtime : runtimeError.value ? formatSandboxRuntimeError(runtimeError.value, t("playground.runtime.importMapTip")) : "";
2354
1445
  return [storeErrors.value, runtime].filter(Boolean).join("\n\n");
2355
1446
  });
2356
1447
  const layout = computed(() => {
@@ -2377,6 +1468,10 @@ var Alone = new Portal(/* @__PURE__ */ defineComponent({
2377
1468
  }));
2378
1469
  const handleRefresh = () => {
2379
1470
  runtimeError.value = "";
1471
+ localError.value = {
1472
+ compile: "",
1473
+ runtime: ""
1474
+ };
2380
1475
  sandboxKey.value++;
2381
1476
  };
2382
1477
  const handleViewportChange = (viewport) => {
@@ -2401,8 +1496,7 @@ var Alone = new Portal(/* @__PURE__ */ defineComponent({
2401
1496
  layoutTick.value++;
2402
1497
  };
2403
1498
  const handleBridgeMessage = (event) => {
2404
- const iframe = resolveSandboxContainer(sandboxRef.value)?.querySelector("iframe");
2405
- if (!iframe || event.source !== iframe.contentWindow) return;
1499
+ if (!isSandboxMessage(sandboxRef.value, event)) return;
2406
1500
  const data = event.data;
2407
1501
  if (!data || data.action !== "docs:navigate" || typeof data.to !== "string") return;
2408
1502
  emit("navigate", data.to);
@@ -2464,7 +1558,23 @@ var Alone = new Portal(/* @__PURE__ */ defineComponent({
2464
1558
  default: withCtx(() => [createElementVNode("div", {
2465
1559
  class: "docs-playground-popup__canvas",
2466
1560
  style: normalizeStyle(canvasStyle.value)
2467
- }, [(openBlock(), createBlock(unref(Sandbox), {
1561
+ }, [__props.local ? (openBlock(), createBlock(unref(LocalSandbox), {
1562
+ key: sandboxKey.value,
1563
+ ref_key: "sandboxRef",
1564
+ ref: sandboxRef,
1565
+ files: __props.files,
1566
+ entry: __props.entry,
1567
+ options: __props.options,
1568
+ "preview-scroller": __props.previewScroller,
1569
+ "clear-console": __props.clearConsole,
1570
+ onError: handleLocalError
1571
+ }, null, 8, [
1572
+ "files",
1573
+ "entry",
1574
+ "options",
1575
+ "preview-scroller",
1576
+ "clear-console"
1577
+ ])) : __props.store ? (openBlock(), createBlock(unref(Sandbox), {
2468
1578
  key: sandboxKey.value,
2469
1579
  ref_key: "sandboxRef",
2470
1580
  ref: sandboxRef,
@@ -2476,7 +1586,7 @@ var Alone = new Portal(/* @__PURE__ */ defineComponent({
2476
1586
  "store",
2477
1587
  "clear-console",
2478
1588
  "preview-options"
2479
- ]))], 4)]),
1589
+ ])) : createCommentVNode("v-if", true)], 4)]),
2480
1590
  _: 1
2481
1591
  })])
2482
1592
  ])], 4)], 8, _hoisted_1$2);
@@ -2489,26 +1599,25 @@ var Alone = new Portal(/* @__PURE__ */ defineComponent({
2489
1599
  });
2490
1600
  //#endregion
2491
1601
  //#region packages/playground/src/core/runtime/runtime.vue?vue&type=script&setup=true&lang.ts
2492
- var _hoisted_1$1 = { class: "docs-playground-runtime-host" };
2493
- var _hoisted_2$1 = {
1602
+ var _hoisted_1$1 = {
2494
1603
  key: 0,
2495
1604
  class: "docs-playground__runtime-error",
2496
1605
  role: "alert"
2497
1606
  };
2498
- var _hoisted_3$1 = {
1607
+ var _hoisted_2$1 = {
2499
1608
  key: 0,
2500
1609
  class: "docs-playground__header"
2501
1610
  };
2502
- var _hoisted_4$1 = ["id", "title"];
2503
- var _hoisted_5$1 = ["href"];
2504
- var _hoisted_6 = { class: "docs-playground__title-text" };
2505
- var _hoisted_7 = {
1611
+ var _hoisted_3$1 = ["id", "title"];
1612
+ var _hoisted_4$1 = ["href"];
1613
+ var _hoisted_5$1 = { class: "docs-playground__title-text" };
1614
+ var _hoisted_6 = {
2506
1615
  key: 1,
2507
1616
  class: "docs-playground__runtime-error",
2508
1617
  role: "alert"
2509
1618
  };
2510
- var _hoisted_8 = { class: "docs-playground-runtime__viewport-stage" };
2511
- var _hoisted_9 = [
1619
+ var _hoisted_7 = { class: "docs-playground-runtime__viewport-stage" };
1620
+ var _hoisted_8 = [
2512
1621
  "aria-expanded",
2513
1622
  "title",
2514
1623
  "aria-label"
@@ -2541,7 +1650,11 @@ var runtime_default = /* @__PURE__ */ defineComponent({
2541
1650
  title: { default: "" },
2542
1651
  id: { default: "" },
2543
1652
  viewport: { default: "auto" },
2544
- viewportOptions: { default: () => ["auto", 375] }
1653
+ viewportOptions: { default: () => ["auto", 375] },
1654
+ local: {
1655
+ type: Boolean,
1656
+ default: true
1657
+ }
2545
1658
  },
2546
1659
  emits: [
2547
1660
  "files-change",
@@ -2550,6 +1663,7 @@ var runtime_default = /* @__PURE__ */ defineComponent({
2550
1663
  "navigate"
2551
1664
  ],
2552
1665
  setup(__props, { expose: __expose, emit: __emit }) {
1666
+ const LocalSandbox = defineAsyncComponent(() => import("./local-sandbox-DvcgaBOa.js").then((n) => n.t));
2553
1667
  const props = __props;
2554
1668
  const { locale, t } = useLocale();
2555
1669
  const displayTitle = computed(() => props.title.trim());
@@ -2587,21 +1701,33 @@ var runtime_default = /* @__PURE__ */ defineComponent({
2587
1701
  "SSR": false
2588
1702
  }.MODE !== "development";
2589
1703
  const copyValue = computed(() => props.files[props.entry] || "");
2590
- const store = createRuntimeStore(props.files, props.entry, props.options);
1704
+ const store = props.local ? null : createRuntimeStore(props.files, props.entry, props.options);
1705
+ const storeReady = computed(() => store && !store.loading && Object.values(store.files).every((file) => isIgnoredFilename(file.filename) || !/\.(?:vue|[jt]sx?|json|s[ac]ss)$/.test(file.filename) || !file.code.trim() || !!file.compiled.js));
2591
1706
  const sandboxRef = ref(null);
1707
+ const localError = ref({
1708
+ compile: "",
1709
+ runtime: ""
1710
+ });
1711
+ const handleLocalError = (payload) => {
1712
+ localError.value = payload;
1713
+ };
2592
1714
  const temporaryHeight = usePreviewHeightBridge(sandboxRef);
2593
1715
  const sandboxKey = ref(0);
2594
1716
  const runtimeHeight = useSandboxAutoHeight(sandboxRef);
2595
1717
  const runtimeError = useSandboxRuntimeErrorGuard(sandboxRef);
2596
1718
  useSandboxTheme(sandboxRef);
2597
- const compileErrorText = computed(() => (store.errors || []).map(toErrorText).filter(Boolean).join("\n"));
1719
+ const compileErrorText = computed(() => {
1720
+ if (props.local) return localError.value.compile;
1721
+ return (store?.errors || []).map(toErrorText).filter(Boolean).join("\n");
1722
+ });
2598
1723
  const errorText = computed(() => {
2599
- const runtime = runtimeError.value ? formatSandboxRuntimeError(runtimeError.value, t("playground.runtime.importMapTip")) : "";
1724
+ let runtime = "";
1725
+ if (props.local) runtime = localError.value.runtime;
1726
+ else if (runtimeError.value) runtime = formatSandboxRuntimeError(runtimeError.value, t("playground.runtime.importMapTip"));
2600
1727
  return [compileErrorText.value, runtime].filter(Boolean).join("\n\n");
2601
1728
  });
2602
1729
  const handleBridgeMessage = (event) => {
2603
- const iframe = resolveSandboxContainer(sandboxRef.value)?.querySelector("iframe");
2604
- if (!iframe || event.source !== iframe.contentWindow) return;
1730
+ if (!isSandboxMessage(sandboxRef.value, event)) return;
2605
1731
  const data = event.data;
2606
1732
  if (!data || data.action !== "docs:navigate" || typeof data.to !== "string") return;
2607
1733
  emit("navigate", data.to);
@@ -2634,16 +1760,21 @@ var runtime_default = /* @__PURE__ */ defineComponent({
2634
1760
  }) - vertical * 2 - 2);
2635
1761
  };
2636
1762
  const syncFrozenExpandedHeight = () => {
2637
- if (!previewExpanded.value || props.expandable !== true) return;
1763
+ if (props.local || !previewExpanded.value || props.expandable !== true) return;
2638
1764
  frozenExpandedHeight.value = measureExpandedPreviewHeight();
2639
1765
  };
2640
1766
  if (typeof window !== "undefined") {
2641
1767
  window.addEventListener("message", handleBridgeMessage);
2642
1768
  window.addEventListener("resize", syncFrozenExpandedHeight);
2643
1769
  }
2644
- const canExpandPreview = computed(() => !props.styleless && isPlaygroundExpandable(props.expandable));
1770
+ const canExpandPreview = computed(() => !props.local && !props.styleless && isPlaygroundExpandable(props.expandable));
2645
1771
  const expandLabel = computed(() => t(previewExpanded.value ? "playground.runtime.collapsePreview" : "playground.runtime.expandPreview"));
2646
1772
  const baseViewportHeight = computed(() => {
1773
+ if (props.local) {
1774
+ const fixedHeight = getViewportHeight(props.viewport);
1775
+ if (fixedHeight) return fixedHeight;
1776
+ return runtimeHeight.value;
1777
+ }
2647
1778
  if (previewExpanded.value && props.expandable === true) return frozenExpandedHeight.value;
2648
1779
  if (previewExpanded.value && isPlaygroundExpandable(props.expandable)) return resolveExpandedPreviewHeight(props.expandable, 0);
2649
1780
  const fixedHeight = getViewportHeight(props.viewport);
@@ -2655,7 +1786,7 @@ var runtime_default = /* @__PURE__ */ defineComponent({
2655
1786
  scrollPlaygroundToViewportStart(runtimeRoot.value);
2656
1787
  };
2657
1788
  const handleTogglePreviewExpand = () => {
2658
- if (!canExpandPreview.value) return;
1789
+ if (props.local || !canExpandPreview.value) return;
2659
1790
  if (!previewExpanded.value) {
2660
1791
  if (props.expandable === true) frozenExpandedHeight.value = measureExpandedPreviewHeight();
2661
1792
  else frozenExpandedHeight.value = 0;
@@ -2695,7 +1826,7 @@ var runtime_default = /* @__PURE__ */ defineComponent({
2695
1826
  syncedFiles = { ...files };
2696
1827
  syncedEntry = entry;
2697
1828
  const apply = () => {
2698
- switch (action.type) {
1829
+ if (store) switch (action.type) {
2699
1830
  case "update": {
2700
1831
  const file = store.files[toReplFilename(action.filename)];
2701
1832
  if (file) file.code = files[action.filename];
@@ -2717,20 +1848,28 @@ var runtime_default = /* @__PURE__ */ defineComponent({
2717
1848
  }
2718
1849
  emit("files-change", files, entry, action);
2719
1850
  };
2720
- whenSassReady(files, apply);
1851
+ if (store) whenSassReady(files, apply);
1852
+ else apply();
2721
1853
  };
2722
1854
  const handleEditor = () => {
2723
1855
  Editor.popup({
2724
1856
  files: { ...props.files },
2725
1857
  entry: props.entry,
2726
1858
  locale: locale.value,
2727
- getCodeErrors: () => store.errors,
1859
+ getCodeErrors: () => {
1860
+ if (!props.local) return store?.errors || [];
1861
+ return localError.value.compile ? [localError.value.compile] : [];
1862
+ },
2728
1863
  onFilesChange: handleFilesChange,
2729
- onActiveChange: (filename) => store.setActive(toReplFilename(filename))
1864
+ onActiveChange: (filename) => store?.setActive(toReplFilename(filename))
2730
1865
  });
2731
1866
  };
2732
1867
  const handleInlineRefresh = () => {
2733
1868
  runtimeError.value = "";
1869
+ localError.value = {
1870
+ compile: "",
1871
+ runtime: ""
1872
+ };
2734
1873
  sandboxKey.value++;
2735
1874
  };
2736
1875
  const handleClosePopup = () => {
@@ -2738,6 +1877,11 @@ var runtime_default = /* @__PURE__ */ defineComponent({
2738
1877
  };
2739
1878
  const handleOpenPopup = () => {
2740
1879
  Alone.popup({
1880
+ local: props.local,
1881
+ files: props.files,
1882
+ entry: props.entry,
1883
+ options: props.options,
1884
+ previewScroller: props.previewScroller,
2741
1885
  store,
2742
1886
  copyValue: copyValue.value,
2743
1887
  title: props.title,
@@ -2758,11 +1902,16 @@ var runtime_default = /* @__PURE__ */ defineComponent({
2758
1902
  syncedFiles = { ...files };
2759
1903
  syncedEntry = props.entry;
2760
1904
  runtimeError.value = "";
2761
- store.setFiles(files, props.entry);
1905
+ localError.value = {
1906
+ compile: "",
1907
+ runtime: ""
1908
+ };
1909
+ if (store) store.setFiles(files, props.entry);
2762
1910
  }, { deep: true });
2763
1911
  watch(() => props.entry, (entry) => {
2764
1912
  if (!entry || entry === syncedEntry) return;
2765
1913
  syncedEntry = entry;
1914
+ if (!store) return;
2766
1915
  store.mainFile = toReplFilename(entry);
2767
1916
  store.setActive(toReplFilename(entry));
2768
1917
  });
@@ -2780,28 +1929,46 @@ var runtime_default = /* @__PURE__ */ defineComponent({
2780
1929
  openPopup: handleOpenPopup
2781
1930
  });
2782
1931
  return (_ctx, _cache) => {
2783
- return openBlock(), createElementBlock("div", _hoisted_1$1, [__props.styleless ? (openBlock(), createElementBlock("div", {
1932
+ return openBlock(), createElementBlock("div", { class: normalizeClass(["docs-playground-runtime-host", { "docs-playground-runtime-host--direct": __props.local && __props.styleless }]) }, [__props.styleless ? (openBlock(), createElementBlock("div", {
2784
1933
  key: 0,
2785
1934
  ref_key: "runtimeRoot",
2786
1935
  ref: runtimeRoot,
2787
1936
  class: "docs-playground-runtime--styleless",
2788
1937
  style: normalizeStyle(stylelessStyle.value)
2789
- }, [errorText.value ? (openBlock(), createElementBlock("pre", _hoisted_2$1, toDisplayString(errorText.value), 1)) : createCommentVNode("v-if", true), createElementVNode("div", {
1938
+ }, [errorText.value ? (openBlock(), createElementBlock("pre", _hoisted_1$1, toDisplayString(errorText.value), 1)) : createCommentVNode("v-if", true), createElementVNode("div", {
2790
1939
  class: "docs-playground-runtime__viewport",
2791
1940
  style: normalizeStyle(viewportStyle.value)
2792
- }, [createVNode(unref(Sandbox), {
1941
+ }, [__props.local ? (openBlock(), createBlock(unref(LocalSandbox), {
1942
+ key: 0,
1943
+ ref_key: "sandboxRef",
1944
+ ref: sandboxRef,
1945
+ files: __props.files,
1946
+ entry: __props.entry,
1947
+ options: __props.options,
1948
+ "preview-scroller": __props.previewScroller,
1949
+ "clear-console": clearConsole,
1950
+ "auto-height": !unref(getViewportHeight)(__props.viewport),
1951
+ onError: handleLocalError
1952
+ }, null, 8, [
1953
+ "files",
1954
+ "entry",
1955
+ "options",
1956
+ "preview-scroller",
1957
+ "auto-height"
1958
+ ])) : unref(store) && storeReady.value ? (openBlock(), createBlock(unref(Sandbox), {
1959
+ key: 1,
2793
1960
  ref_key: "sandboxRef",
2794
1961
  ref: sandboxRef,
2795
1962
  store: unref(store),
2796
1963
  "auto-store-init": false,
2797
1964
  "preview-options": mergedPreviewOptions.value
2798
- }, null, 8, ["store", "preview-options"])], 4)], 4)) : (openBlock(), createElementBlock("div", {
1965
+ }, null, 8, ["store", "preview-options"])) : createCommentVNode("v-if", true)], 4)], 4)) : (openBlock(), createElementBlock("div", {
2799
1966
  key: 1,
2800
1967
  ref_key: "runtimeRoot",
2801
1968
  ref: runtimeRoot,
2802
1969
  class: "docs-playground-runtime"
2803
1970
  }, [
2804
- !__props.hideChrome ? (openBlock(), createElementBlock("div", _hoisted_3$1, [displayTitle.value ? (openBlock(), createElementBlock("span", {
1971
+ !__props.hideChrome ? (openBlock(), createElementBlock("div", _hoisted_2$1, [displayTitle.value ? (openBlock(), createElementBlock("span", {
2805
1972
  key: 0,
2806
1973
  ref_key: "titleEl",
2807
1974
  ref: titleEl,
@@ -2812,7 +1979,7 @@ var runtime_default = /* @__PURE__ */ defineComponent({
2812
1979
  }, [createElementVNode("a", {
2813
1980
  class: "docs-playground__title-anchor",
2814
1981
  href: `#${titleId.value}`
2815
- }, "#", 8, _hoisted_5$1), createElementVNode("span", _hoisted_6, toDisplayString(displayTitle.value), 1)], 8, _hoisted_4$1)) : createCommentVNode("v-if", true), createVNode(toolbar_default, {
1982
+ }, "#", 8, _hoisted_4$1), createElementVNode("span", _hoisted_5$1, toDisplayString(displayTitle.value), 1)], 8, _hoisted_3$1)) : createCommentVNode("v-if", true), createVNode(toolbar_default, {
2816
1983
  "copy-value": copyValue.value,
2817
1984
  viewport: __props.viewport,
2818
1985
  "viewport-options": __props.viewportOptions,
@@ -2826,14 +1993,31 @@ var runtime_default = /* @__PURE__ */ defineComponent({
2826
1993
  "viewport",
2827
1994
  "viewport-options"
2828
1995
  ])])) : createCommentVNode("v-if", true),
2829
- errorText.value ? (openBlock(), createElementBlock("pre", _hoisted_7, toDisplayString(errorText.value), 1)) : createCommentVNode("v-if", true),
1996
+ errorText.value ? (openBlock(), createElementBlock("pre", _hoisted_6, toDisplayString(errorText.value), 1)) : createCommentVNode("v-if", true),
2830
1997
  createElementVNode("section", {
2831
1998
  class: normalizeClass(["docs-playground__preview", { "is-expanded": previewExpanded.value }]),
2832
1999
  style: normalizeStyle(previewStyle.value)
2833
- }, [createElementVNode("div", _hoisted_8, [createElementVNode("div", {
2000
+ }, [createElementVNode("div", _hoisted_7, [createElementVNode("div", {
2834
2001
  class: "docs-playground-runtime__viewport",
2835
2002
  style: normalizeStyle(viewportStyle.value)
2836
- }, [(openBlock(), createBlock(unref(Sandbox), {
2003
+ }, [__props.local ? (openBlock(), createBlock(unref(LocalSandbox), {
2004
+ key: sandboxKey.value,
2005
+ ref_key: "sandboxRef",
2006
+ ref: sandboxRef,
2007
+ files: __props.files,
2008
+ entry: __props.entry,
2009
+ options: __props.options,
2010
+ "preview-scroller": __props.previewScroller,
2011
+ "clear-console": clearConsole,
2012
+ "auto-height": !unref(getViewportHeight)(__props.viewport),
2013
+ onError: handleLocalError
2014
+ }, null, 8, [
2015
+ "files",
2016
+ "entry",
2017
+ "options",
2018
+ "preview-scroller",
2019
+ "auto-height"
2020
+ ])) : unref(store) && storeReady.value ? (openBlock(), createBlock(unref(Sandbox), {
2837
2021
  key: sandboxKey.value,
2838
2022
  ref_key: "sandboxRef",
2839
2023
  ref: sandboxRef,
@@ -2841,7 +2025,7 @@ var runtime_default = /* @__PURE__ */ defineComponent({
2841
2025
  "auto-store-init": false,
2842
2026
  "clear-console": clearConsole,
2843
2027
  "preview-options": mergedPreviewOptions.value
2844
- }, null, 8, ["store", "preview-options"]))], 4)]), canExpandPreview.value ? (openBlock(), createElementBlock("button", {
2028
+ }, null, 8, ["store", "preview-options"])) : createCommentVNode("v-if", true)], 4)]), canExpandPreview.value ? (openBlock(), createElementBlock("button", {
2845
2029
  key: 0,
2846
2030
  type: "button",
2847
2031
  class: normalizeClass(["docs-playground__expand", { "is-expanded": previewExpanded.value }]),
@@ -2850,8 +2034,8 @@ var runtime_default = /* @__PURE__ */ defineComponent({
2850
2034
  title: expandLabel.value,
2851
2035
  "aria-label": expandLabel.value,
2852
2036
  onClick: handleTogglePreviewExpand
2853
- }, [createVNode(unref(icon_default), { name: "expand" })], 10, _hoisted_9)) : createCommentVNode("v-if", true)], 6)
2854
- ], 512))]);
2037
+ }, [createVNode(unref(icon_default), { name: "expand" })], 10, _hoisted_8)) : createCommentVNode("v-if", true)], 6)
2038
+ ], 512))], 2);
2855
2039
  };
2856
2040
  }
2857
2041
  });
@@ -2892,6 +2076,10 @@ var playground_default = /* @__PURE__ */ defineComponent({
2892
2076
  type: Boolean,
2893
2077
  default: false
2894
2078
  },
2079
+ local: {
2080
+ type: Boolean,
2081
+ default: true
2082
+ },
2895
2083
  previewOptions: {},
2896
2084
  locale: {}
2897
2085
  },
@@ -3050,7 +2238,8 @@ var playground_default = /* @__PURE__ */ defineComponent({
3050
2238
  "preview-options": __props.previewOptions,
3051
2239
  "preview-inset": __props.previewInset,
3052
2240
  "preview-scroller": __props.previewScroller,
3053
- expandable: __props.expandable,
2241
+ local: __props.local,
2242
+ expandable: __props.local ? false : __props.expandable,
3054
2243
  styleless: true,
3055
2244
  title: __props.title,
3056
2245
  id: __props.id,
@@ -3066,6 +2255,7 @@ var playground_default = /* @__PURE__ */ defineComponent({
3066
2255
  "preview-options",
3067
2256
  "preview-inset",
3068
2257
  "preview-scroller",
2258
+ "local",
3069
2259
  "expandable",
3070
2260
  "title",
3071
2261
  "id",
@@ -3119,7 +2309,8 @@ var playground_default = /* @__PURE__ */ defineComponent({
3119
2309
  "preview-options": __props.previewOptions,
3120
2310
  "preview-inset": __props.previewInset,
3121
2311
  "preview-scroller": __props.previewScroller,
3122
- expandable: __props.expandable,
2312
+ local: __props.local,
2313
+ expandable: __props.local ? false : __props.expandable,
3123
2314
  "hide-chrome": true,
3124
2315
  title: __props.title,
3125
2316
  id: __props.id,
@@ -3137,6 +2328,7 @@ var playground_default = /* @__PURE__ */ defineComponent({
3137
2328
  "preview-options",
3138
2329
  "preview-inset",
3139
2330
  "preview-scroller",
2331
+ "local",
3140
2332
  "expandable",
3141
2333
  "title",
3142
2334
  "id",