@deot/docs-playground 1.0.8 → 1.0.10

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
@@ -81,16 +81,42 @@ var highlightCodeByLanguage = (code, language) => {
81
81
  var highlightCode = (code, filename) => highlightCodeByLanguage(code, resolveHighlightLanguage(filename));
82
82
  //#endregion
83
83
  //#region packages/playground/src/icon/icons.ts
84
- var PLAYGROUND_ICON_PATHS = {
85
- runtime: "M5 3h14a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2Zm3 18h8m-4-3v3m-2-13 5 3-5 3V8Z",
86
- files: "M6 2h8l5 5v13a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2Zm8 0v6h5m-9 5-2 2 2 2m5-4 2 2-2 2",
87
- copy: "M9 8h10a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H9a2 2 0 0 1-2-2V10a2 2 0 0 1 2-2Zm-2 8H5a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v4",
88
- editor: "M8 8 4 12l4 4m8-8 4 4-4 4m-3-10-2 12",
89
- viewport: "M3 4h12v10H3V4Zm3 14h6m-3-4v4m9-9h3v11h-6V9h3m0 9h0"
84
+ var strokeIcon = (path) => ({
85
+ path,
86
+ fill: "none",
87
+ stroke: "currentColor"
88
+ });
89
+ var solidIcon = (path) => ({
90
+ path,
91
+ fill: "currentColor",
92
+ stroke: "none"
93
+ });
94
+ var PLAYGROUND_ICONS = {
95
+ runtime: strokeIcon("M5 3h14a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2Zm3 18h8m-4-3v3m-2-13 5 3-5 3V8Z"),
96
+ files: strokeIcon("M6 2h8l5 5v13a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2Zm8 0v6h5m-9 5-2 2 2 2m5-4 2 2-2 2"),
97
+ copy: strokeIcon(["M9 8h10a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H9a2 2 0 0 1-2-2V10a2 2 0 0 1 2-2Z", "m-2 8H5a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v4"].join("")),
98
+ refresh: solidIcon(["M12 2.5a9.5 9.5 0 1 1 0 19 1 1 0 1 1 0-2 7.5 7.5 0 1 0-7.5-7.8l.24-.23a.75.75 0 1 1 1.06 1.06", "L4.03 14.3a.75.75 0 0 1-1.06 0L1.2 12.53a.75.75 0 1 1 1.06-1.06l.24.24A9.5 9.5 0 0 1 12 2.5"].join("")),
99
+ editor: solidIcon([
100
+ "M9.38 19.32a.82.82 0 0 1-.71-1.23l5.85-10.13a.82.82 0 0 1 1.42.82l-5.85 10.13a.8.8 0 0 1-.71.4",
101
+ "m-2.52-.76a.8.8 0 0 1-.58-.25l-4.13-4.12a1.06 1.06 0 0 1 0-1.5l4.13-4.12a.82.82 0 1 1 1.16 1.16",
102
+ "l-3.72 3.71 3.72 3.71a.82.82 0 0 1-.58 1.4m10.9 0a.82.82 0 0 1-.58-1.4l3.7-3.7-3.7-3.72",
103
+ "a.82.82 0 1 1 1.16-1.16l4.12 4.13c.41.4.41 1.08 0 1.49l-4.12 4.12a.8.8 0 0 1-.59.25"
104
+ ].join("")),
105
+ viewport: solidIcon([
106
+ "M21.82 2.93c-.3-.3-.7-.47-1.1-.47H4.6c-.87 0-1.58.7-1.58 1.58v4.18h1.12V3.67h17v12.54",
107
+ "c0 .25-.2.46-.45.46H9.49v1.13h.67q-.25.66-.6 1.11l-.06.06v1.86h7.86a.56.56 0 1 0 0-1.13",
108
+ "q-1.46 0-2.2-1.9h5.55c.87 0 1.57-.71 1.57-1.59V4.04a1.6 1.6 0 0 0-.46-1.11M10.55 19.6",
109
+ "c.43-.63.66-1.08.92-1.81h2.37c.25.8.51 1.26.97 1.77l.03.05zM8.12 8.4H2.9",
110
+ "c-.64 0-1.17.53-1.17 1.19v10.75c0 .66.53 1.19 1.17 1.19h5.21c.65 0 1.18-.53 1.18-1.19V9.6",
111
+ "a1.16 1.16 0 0 0-1.17-1.19M8.1 20.36H2.94V9.64h5.15z"
112
+ ].join("")),
113
+ expand: strokeIcon("M6 9l6 6 6-6"),
114
+ popup: strokeIcon(["M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3", "M3 16v3a2 2 0 0 0 2 2h3"].join(""))
90
115
  };
91
116
  //#endregion
92
117
  //#region packages/playground/src/icon/icon.vue?vue&type=script&setup=true&lang.ts
93
- var _hoisted_1$5 = ["d"];
118
+ var _hoisted_1$7 = ["fill", "stroke"];
119
+ var _hoisted_2$6 = ["d"];
94
120
  //#endregion
95
121
  //#region packages/playground/src/icon/icon.vue
96
122
  var icon_default = /* @__PURE__ */ defineComponent({
@@ -101,6 +127,7 @@ var icon_default = /* @__PURE__ */ defineComponent({
101
127
  },
102
128
  setup(__props) {
103
129
  const props = __props;
130
+ const icon = computed(() => PLAYGROUND_ICONS[props.name]);
104
131
  const sizeStyle = computed(() => {
105
132
  if (props.size == null) return;
106
133
  const value = typeof props.size === "number" ? `${props.size}px` : props.size;
@@ -114,13 +141,13 @@ var icon_default = /* @__PURE__ */ defineComponent({
114
141
  class: "docs-playground-icon",
115
142
  viewBox: "0 0 24 24",
116
143
  style: normalizeStyle(sizeStyle.value),
117
- fill: "none",
118
- stroke: "currentColor",
144
+ fill: icon.value.fill,
145
+ stroke: icon.value.stroke,
119
146
  "stroke-width": "1.8",
120
147
  "stroke-linecap": "round",
121
148
  "stroke-linejoin": "round",
122
149
  "aria-hidden": "true"
123
- }, [createElementVNode("path", { d: unref(PLAYGROUND_ICON_PATHS)[__props.name] }, null, 8, _hoisted_1$5)], 4);
150
+ }, [createElementVNode("path", { d: icon.value.path }, null, 8, _hoisted_2$6)], 12, _hoisted_1$7);
124
151
  };
125
152
  }
126
153
  });
@@ -129,7 +156,7 @@ var icon_default = /* @__PURE__ */ defineComponent({
129
156
  var github_default = "pre code.hljs{display:block;padding:1em;overflow-x:auto}code.hljs{padding:3px 5px}.hljs{color:#24292e;background:#fff}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#d73a49}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#6f42c1}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id,.hljs-variable{color:#005cc5}.hljs-meta .hljs-string,.hljs-regexp,.hljs-string{color:#032f62}.hljs-built_in,.hljs-symbol{color:#e36209}.hljs-code,.hljs-comment,.hljs-formula{color:#6a737d}.hljs-name,.hljs-quote,.hljs-selector-pseudo,.hljs-selector-tag{color:#22863a}.hljs-subst{color:#24292e}.hljs-section{font-weight:700;color:#005cc5}.hljs-bullet{color:#735c0f}.hljs-emphasis{font-style:italic;color:#24292e}.hljs-strong{font-weight:700;color:#24292e}.hljs-addition{color:#22863a;background-color:#f0fff4}.hljs-deletion{color:#b31d28;background-color:#ffeef0}[data-doc-theme=dark] .hljs,[data-vc-theme=dark] .hljs{color:#c9d1d9;background:#0d1117}[data-doc-theme=dark] .hljs-doctag,[data-doc-theme=dark] .hljs-keyword,[data-doc-theme=dark] .hljs-meta .hljs-keyword,[data-doc-theme=dark] .hljs-template-tag,[data-doc-theme=dark] .hljs-template-variable,[data-doc-theme=dark] .hljs-type,[data-doc-theme=dark] .hljs-variable.language_,[data-vc-theme=dark] .hljs-doctag,[data-vc-theme=dark] .hljs-keyword,[data-vc-theme=dark] .hljs-meta .hljs-keyword,[data-vc-theme=dark] .hljs-template-tag,[data-vc-theme=dark] .hljs-template-variable,[data-vc-theme=dark] .hljs-type,[data-vc-theme=dark] .hljs-variable.language_{color:#ff7b72}[data-doc-theme=dark] .hljs-title,[data-doc-theme=dark] .hljs-title.class_,[data-doc-theme=dark] .hljs-title.function_,[data-vc-theme=dark] .hljs-title,[data-vc-theme=dark] .hljs-title.class_,[data-vc-theme=dark] .hljs-title.function_{color:#d2a8ff}[data-doc-theme=dark] .hljs-attr,[data-doc-theme=dark] .hljs-literal,[data-doc-theme=dark] .hljs-number,[data-doc-theme=dark] .hljs-variable,[data-vc-theme=dark] .hljs-attr,[data-vc-theme=dark] .hljs-literal,[data-vc-theme=dark] .hljs-number,[data-vc-theme=dark] .hljs-variable{color:#79c0ff}[data-doc-theme=dark] .hljs-regexp,[data-doc-theme=dark] .hljs-string,[data-vc-theme=dark] .hljs-regexp,[data-vc-theme=dark] .hljs-string{color:#a5d6ff}[data-doc-theme=dark] .hljs-code,[data-doc-theme=dark] .hljs-comment,[data-vc-theme=dark] .hljs-code,[data-vc-theme=dark] .hljs-comment{color:#8b949e}[data-doc-theme=dark] .hljs-name,[data-doc-theme=dark] .hljs-selector-tag,[data-vc-theme=dark] .hljs-name,[data-vc-theme=dark] .hljs-selector-tag{color:#7ee787}";
130
157
  //#endregion
131
158
  //#region packages/playground/src/core/code-preview/code-preview.scss?inline
132
- var code_preview_default$1 = ".docs-code-preview{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;min-height:0;overflow:hidden;background:var(--docs-background-color-soft,var(--vc-background-color,#f7f8fa));border-radius:8px}.docs-code-preview__language{z-index:1;overflow:hidden;font-size:12px;line-height:18px;text-overflow:ellipsis;white-space:nowrap}.docs-code-preview__copy,.docs-code-preview__language{position:absolute;top:6px;right:12px;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;width:28px;height:28px;color:var(--docs-foreground-color-mute,var(--vc-color-dark-extralight,#71717a));-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.docs-code-preview__copy{z-index:2;padding:0;pointer-events:none;cursor:pointer;background:var(--docs-background-color-soft,var(--vc-background-color,#f7f8fa));border:1px solid var(--docs-border-color,var(--vc-color-light-deeper,#d4d4d8));border-radius:8px;opacity:0;-webkit-transition:opacity .15s ease,background-color .15s ease;transition:opacity .15s ease,background-color .15s ease}.docs-code-preview__copy:hover{background:var(--docs-background-color,var(--vc-background-color-light,#fff))}.docs-code-preview__copy:focus-visible{pointer-events:auto;opacity:1}.docs-code-preview:hover .docs-code-preview__copy{pointer-events:auto;opacity:1}.docs-code-preview__code{width:100%;min-height:0;margin:0;overflow:auto;-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto}.docs-code-preview__code,.docs-code-preview__code code.hljs{background:var(--docs-background-color-soft,var(--vc-background-color,#f7f8fa))}.docs-code-preview__code code.hljs{min-height:100%;padding:12px 56px 12px 24px;-webkit-box-sizing:border-box;box-sizing:border-box}";
159
+ var code_preview_default$1 = ".docs-code-preview{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;min-height:0;overflow:hidden;background:var(--docs-background-color-soft,var(--vc-background-color,#f7f8fa));border-radius:8px}.docs-code-preview__language{z-index:1;min-width:28px;padding:0 8px;font-size:12px;line-height:18px;white-space:nowrap;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-transition:opacity .15s ease;transition:opacity .15s ease}.docs-code-preview__copy,.docs-code-preview__language{position:absolute;top:6px;right:12px;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;height:28px;color:var(--docs-foreground-color-mute,var(--vc-color-dark-extralight,#71717a));-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.docs-code-preview__copy{z-index:2;width:28px;padding:0;pointer-events:none;cursor:pointer;background:var(--docs-background-color-soft,var(--vc-background-color,#f7f8fa));border:1px solid var(--docs-border-color,var(--vc-color-light-deeper,#d4d4d8));border-radius:8px;opacity:0;-webkit-transition:opacity .15s ease,background-color .15s ease;transition:opacity .15s ease,background-color .15s ease}.docs-code-preview__copy:hover{background:var(--docs-background-color,var(--vc-background-color-light,#fff))}.docs-code-preview__copy:focus-visible{pointer-events:auto;opacity:1}.docs-code-preview:has(.docs-code-preview__copy:focus-visible) .docs-code-preview__language,.docs-code-preview:hover .docs-code-preview__language{opacity:0}.docs-code-preview:has(.docs-code-preview__copy:focus-visible) .docs-code-preview__copy,.docs-code-preview:hover .docs-code-preview__copy{pointer-events:auto;opacity:1}.docs-code-preview__code{width:100%;min-height:0;margin:0;overflow:auto;-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto}.docs-code-preview__code,.docs-code-preview__code code.hljs{background:var(--docs-background-color-soft,var(--vc-background-color,#f7f8fa))}.docs-code-preview__code code.hljs{min-height:100%;padding:12px 96px 12px 24px;-webkit-box-sizing:border-box;box-sizing:border-box}";
133
160
  //#endregion
134
161
  //#region packages/playground/src/core/code-preview/style.ts
135
162
  var CODE_PREVIEW_STYLE_ID = "docs-code-preview-style";
@@ -146,10 +173,10 @@ var ensureCodePreviewStyle = () => {
146
173
  };
147
174
  //#endregion
148
175
  //#region packages/playground/src/core/code-preview/code-preview.vue?vue&type=script&setup=true&lang.ts
149
- var _hoisted_1$4 = { class: "docs-code-preview" };
150
- var _hoisted_2$3 = ["title"];
151
- var _hoisted_3$3 = { class: "docs-code-preview__code" };
152
- var _hoisted_4$3 = ["innerHTML"];
176
+ var _hoisted_1$6 = { class: "docs-code-preview" };
177
+ var _hoisted_2$5 = ["title"];
178
+ var _hoisted_3$5 = { class: "docs-code-preview__code" };
179
+ var _hoisted_4$5 = ["innerHTML"];
153
180
  //#endregion
154
181
  //#region packages/playground/src/core/code-preview/code-preview.vue
155
182
  var code_preview_default = /* @__PURE__ */ defineComponent({
@@ -180,12 +207,12 @@ var code_preview_default = /* @__PURE__ */ defineComponent({
180
207
  const highlightLanguage = computed(() => props.language || resolveHighlightLanguage(props.filename));
181
208
  const highlightedCode = computed(() => highlightCodeByLanguage(props.code, highlightLanguage.value));
182
209
  return (_ctx, _cache) => {
183
- return openBlock(), createElementBlock("div", _hoisted_1$4, [
210
+ return openBlock(), createElementBlock("div", _hoisted_1$6, [
184
211
  languageLabel.value ? (openBlock(), createElementBlock("span", {
185
212
  key: 0,
186
213
  class: "docs-code-preview__language",
187
214
  title: languageLabel.value
188
- }, toDisplayString(languageLabel.value), 9, _hoisted_2$3)) : createCommentVNode("v-if", true),
215
+ }, toDisplayString(languageLabel.value), 9, _hoisted_2$5)) : createCommentVNode("v-if", true),
189
216
  createVNode(unref(Clipboard), {
190
217
  class: "docs-code-preview__copy",
191
218
  value: __props.code,
@@ -202,10 +229,10 @@ var code_preview_default = /* @__PURE__ */ defineComponent({
202
229
  "aria-label"
203
230
  ]),
204
231
  createCommentVNode(" eslint-disable-next-line vue/no-v-html "),
205
- createElementVNode("pre", _hoisted_3$3, [createElementVNode("code", {
232
+ createElementVNode("pre", _hoisted_3$5, [createElementVNode("code", {
206
233
  class: "hljs",
207
234
  innerHTML: highlightedCode.value
208
- }, null, 8, _hoisted_4$3)])
235
+ }, null, 8, _hoisted_4$5)])
209
236
  ]);
210
237
  };
211
238
  }
@@ -231,15 +258,15 @@ var filesEqual = (left, right) => {
231
258
  var playgroundViewMessage = (view) => view === "runtime" ? "playground.runtime.preview" : "playground.runtime.files";
232
259
  //#endregion
233
260
  //#region packages/playground/src/core/files-preview/files-preview.vue?vue&type=script&setup=true&lang.ts
234
- var _hoisted_1$3 = { class: "docs-playground-files" };
235
- var _hoisted_2$2 = { class: "docs-playground-files__toolbar" };
236
- var _hoisted_3$2 = ["data-filename", "onClick"];
237
- var _hoisted_4$2 = {
261
+ var _hoisted_1$5 = { class: "docs-playground-files" };
262
+ var _hoisted_2$4 = { class: "docs-playground-files__toolbar" };
263
+ var _hoisted_3$4 = ["data-filename", "onClick"];
264
+ var _hoisted_4$4 = {
238
265
  key: 0,
239
266
  class: "docs-playground-files__entry"
240
267
  };
241
- var _hoisted_5$2 = { class: "docs-playground-files__actions" };
242
- var _hoisted_6$2 = {
268
+ var _hoisted_5$4 = { class: "docs-playground-files__actions" };
269
+ var _hoisted_6$3 = {
243
270
  key: 0,
244
271
  class: "docs-playground__views docs-playground__views--files"
245
272
  };
@@ -273,7 +300,7 @@ var files_preview_default = /* @__PURE__ */ defineComponent({
273
300
  };
274
301
  const handleView = (view) => emit("view-change", view);
275
302
  return (_ctx, _cache) => {
276
- return openBlock(), createElementBlock("div", _hoisted_1$3, [createElementVNode("div", _hoisted_2$2, [createVNode(unref(Scroller), {
303
+ return openBlock(), createElementBlock("div", _hoisted_1$5, [createElementVNode("div", _hoisted_2$4, [createVNode(unref(Scroller), {
277
304
  class: "docs-playground-files__scroller",
278
305
  "auto-resize": true,
279
306
  native: false,
@@ -290,10 +317,10 @@ var files_preview_default = /* @__PURE__ */ defineComponent({
290
317
  class: normalizeClass(["docs-playground-files__tab", { "is-active": filename === __props.activeFilename }]),
291
318
  "data-filename": filename,
292
319
  onClick: ($event) => handleActive(filename)
293
- }, [createElementVNode("span", null, toDisplayString(filename), 1), filename === __props.entry ? (openBlock(), createElementBlock("small", _hoisted_4$2, toDisplayString(unref(t)("playground.files.entry")), 1)) : createCommentVNode("v-if", true)], 10, _hoisted_3$2);
320
+ }, [createElementVNode("span", null, toDisplayString(filename), 1), filename === __props.entry ? (openBlock(), createElementBlock("small", _hoisted_4$4, toDisplayString(unref(t)("playground.files.entry")), 1)) : createCommentVNode("v-if", true)], 10, _hoisted_3$4);
294
321
  }), 128))]),
295
322
  _: 1
296
- }), createElementVNode("div", _hoisted_5$2, [__props.views.length > 1 ? (openBlock(), createElementBlock("div", _hoisted_6$2, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.views, (item) => {
323
+ }), createElementVNode("div", _hoisted_5$4, [__props.views.length > 1 ? (openBlock(), createElementBlock("div", _hoisted_6$3, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.views, (item) => {
297
324
  return openBlock(), createElementBlock("button", {
298
325
  key: item,
299
326
  type: "button",
@@ -434,25 +461,26 @@ var Drag = class {
434
461
  };
435
462
  //#endregion
436
463
  //#region packages/playground/src/editor/editor.vue?vue&type=script&setup=true&lang.ts
437
- var _hoisted_1$2 = { class: "docs-playground-editor" };
438
- var _hoisted_2$1 = ["title"];
439
- var _hoisted_3$1 = { class: "docs-playground-editor__files" };
440
- var _hoisted_4$1 = [
464
+ var _hoisted_1$4 = { class: "docs-playground-editor" };
465
+ var _hoisted_2$3 = ["title"];
466
+ var _hoisted_3$3 = { class: "docs-playground-editor__files" };
467
+ var _hoisted_4$3 = [
441
468
  "data-filename",
442
469
  "onClick",
443
470
  "onDblclick"
444
471
  ];
445
- var _hoisted_5$1 = ["onKeydown"];
446
- var _hoisted_6$1 = ["title"];
472
+ var _hoisted_5$3 = ["onKeydown"];
473
+ var _hoisted_6$2 = ["title"];
447
474
  var _hoisted_7$1 = ["title", "aria-label"];
448
475
  var _hoisted_8$1 = ["title", "aria-label"];
449
- var _hoisted_9$1 = { class: "docs-playground-editor__actions" };
450
- var _hoisted_10$1 = ["title"];
476
+ var _hoisted_9 = { class: "docs-playground-editor__actions" };
477
+ var _hoisted_10 = ["title"];
451
478
  var _hoisted_11 = ["title", "disabled"];
452
479
  var _hoisted_12 = {
453
480
  key: 0,
454
481
  class: "docs-playground-editor__error"
455
482
  };
483
+ var EDITOR_SCROLLER_MAX_HEIGHT = "calc(100vh - 110px)";
456
484
  //#endregion
457
485
  //#region packages/playground/src/editor/index.ts
458
486
  var Editor = new Portal(/* @__PURE__ */ defineComponent({
@@ -481,6 +509,7 @@ var Editor = new Portal(/* @__PURE__ */ defineComponent({
481
509
  },
482
510
  setup(__props) {
483
511
  const SUPPORTED_FILE_RE = /\.(vue|js|ts|jsx|tsx|css|s[ac]ss|json|html)$/i;
512
+ /** 浮层留白 20px + 标题栏 44px + 文件栏 46px,避免大文件把标签栏挤扁。 */
484
513
  const props = __props;
485
514
  const { t } = useLocale(computed(() => props.locale));
486
515
  const initialFiles = Object.keys(props.files).length ? props.files : { "App.vue": props.value };
@@ -492,6 +521,7 @@ var Editor = new Portal(/* @__PURE__ */ defineComponent({
492
521
  const textarea = ref(null);
493
522
  const filenameInput = ref(null);
494
523
  const scroller = ref(null);
524
+ const editorScroller = ref(null);
495
525
  const editor = ref(null);
496
526
  const bar = ref(null);
497
527
  const wrapper = ref(null);
@@ -499,6 +529,10 @@ var Editor = new Portal(/* @__PURE__ */ defineComponent({
499
529
  const renamingFilename = ref("");
500
530
  const filenameDraft = ref("");
501
531
  const codeErrorText = computed(() => props.getCodeErrors().map((item) => item instanceof Error ? item.message : item).join("\n"));
532
+ let editorResize;
533
+ const refreshEditorScroller = () => {
534
+ editorScroller.value?.refresh();
535
+ };
502
536
  const setFilenameInput = (el) => {
503
537
  filenameInput.value = el instanceof HTMLInputElement ? el : null;
504
538
  };
@@ -536,11 +570,13 @@ var Editor = new Portal(/* @__PURE__ */ defineComponent({
536
570
  filename
537
571
  });
538
572
  if (filename === currentEntry.value) props.onChange(code);
573
+ nextTick(refreshEditorScroller);
539
574
  })
540
575
  ],
541
576
  parent: textarea.value
542
577
  });
543
578
  editor.value.focus();
579
+ nextTick(refreshEditorScroller);
544
580
  };
545
581
  const handleActive = (filename) => {
546
582
  if (filename === activeFilename.value || editorFiles.value[filename] === void 0) return;
@@ -664,13 +700,18 @@ var Editor = new Portal(/* @__PURE__ */ defineComponent({
664
700
  wrapper: wrapper.value,
665
701
  container: window
666
702
  });
703
+ if (typeof ResizeObserver !== "undefined") {
704
+ editorResize = new ResizeObserver(refreshEditorScroller);
705
+ editorResize.observe(textarea.value);
706
+ }
667
707
  });
668
708
  onBeforeUnmount(() => {
709
+ editorResize?.disconnect();
669
710
  drag.value?.off();
670
711
  editor.value?.destroy();
671
712
  });
672
713
  return (_ctx, _cache) => {
673
- return openBlock(), createElementBlock("div", _hoisted_1$2, [createVNode(unref(TransitionFade), { onAfterLeave: handleHide }, {
714
+ return openBlock(), createElementBlock("div", _hoisted_1$4, [createVNode(unref(TransitionFade), { onAfterLeave: handleHide }, {
674
715
  default: withCtx(() => [withDirectives(createElementVNode("div", {
675
716
  ref_key: "wrapper",
676
717
  ref: wrapper,
@@ -687,8 +728,8 @@ var Editor = new Portal(/* @__PURE__ */ defineComponent({
687
728
  title: unref(t)("playground.common.close"),
688
729
  style: { "cursor": "pointer" },
689
730
  onClick: handleHide
690
- }, "✕", 8, _hoisted_2$1)], 512),
691
- createElementVNode("div", _hoisted_3$1, [createVNode(unref(Scroller), {
731
+ }, "✕", 8, _hoisted_2$3)], 512),
732
+ createElementVNode("div", _hoisted_3$3, [createVNode(unref(Scroller), {
692
733
  ref_key: "scroller",
693
734
  ref: scroller,
694
735
  class: "docs-playground-editor__scroller",
@@ -716,11 +757,11 @@ var Editor = new Portal(/* @__PURE__ */ defineComponent({
716
757
  onDblclick: _cache[2] || (_cache[2] = withModifiers(() => {}, ["stop"])),
717
758
  onBlur: handleRenameSubmit,
718
759
  onKeydown: [withKeys(withModifiers(handleRenameSubmit, ["prevent"]), ["enter"]), withKeys(withModifiers(handleRenameCancel, ["prevent"]), ["esc"])]
719
- }, null, 40, _hoisted_5$1)), [[vModelText, filenameDraft.value]]) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
760
+ }, null, 40, _hoisted_5$3)), [[vModelText, filenameDraft.value]]) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
720
761
  filename === currentEntry.value ? (openBlock(), createElementBlock("span", {
721
762
  key: 0,
722
763
  title: unref(t)("playground.editor.entry")
723
- }, "●", 8, _hoisted_6$1)) : createCommentVNode("v-if", true),
764
+ }, "●", 8, _hoisted_6$2)) : createCommentVNode("v-if", true),
724
765
  createElementVNode("span", null, toDisplayString(filename), 1),
725
766
  filename === currentEntry.value ? (openBlock(), createElementBlock("button", {
726
767
  key: 1,
@@ -745,25 +786,37 @@ var Editor = new Portal(/* @__PURE__ */ defineComponent({
745
786
  }, null, 8, _hoisted_8$1)]),
746
787
  _: 2
747
788
  }, 1032, ["title", "onOk"]))
748
- ], 64))], 42, _hoisted_4$1);
789
+ ], 64))], 42, _hoisted_4$3);
749
790
  }), 128))]),
750
791
  _: 1
751
- }, 512), createElementVNode("div", _hoisted_9$1, [createElementVNode("button", {
792
+ }, 512), createElementVNode("div", _hoisted_9, [createElementVNode("button", {
752
793
  type: "button",
753
794
  title: unref(t)("playground.editor.createFile"),
754
795
  onClick: handleCreate
755
- }, "+", 8, _hoisted_10$1), createElementVNode("button", {
796
+ }, "+", 8, _hoisted_10), createElementVNode("button", {
756
797
  type: "button",
757
798
  title: unref(t)("playground.editor.setEntry"),
758
799
  disabled: activeFilename.value === currentEntry.value,
759
800
  onClick: handleEntry
760
801
  }, toDisplayString(unref(t)("playground.editor.setEntry")), 9, _hoisted_11)])]),
761
802
  codeErrorText.value ? (openBlock(), createElementBlock("div", _hoisted_12, toDisplayString(codeErrorText.value), 1)) : createCommentVNode("v-if", true),
762
- createElementVNode("div", {
763
- ref_key: "textarea",
764
- ref: textarea,
765
- class: "docs-playground-editor__editor"
766
- }, null, 512)
803
+ createVNode(unref(Scroller), {
804
+ ref_key: "editorScroller",
805
+ ref: editorScroller,
806
+ class: "docs-playground-editor__body",
807
+ "auto-resize": true,
808
+ native: false,
809
+ "show-bar": true,
810
+ always: true,
811
+ "max-height": EDITOR_SCROLLER_MAX_HEIGHT
812
+ }, {
813
+ default: withCtx(() => [createElementVNode("div", {
814
+ ref_key: "textarea",
815
+ ref: textarea,
816
+ class: "docs-playground-editor__editor"
817
+ }, null, 512)]),
818
+ _: 1
819
+ }, 512)
767
820
  ], 512), [[vShow, isActive.value]])]),
768
821
  _: 1
769
822
  })]);
@@ -879,6 +932,77 @@ var useSandboxAutoHeight = (sandboxRef) => {
879
932
  });
880
933
  return height;
881
934
  };
935
+ var CLIPPING_OVERFLOW = /* @__PURE__ */ new Set([
936
+ "auto",
937
+ "scroll",
938
+ "hidden",
939
+ "overlay"
940
+ ]);
941
+ var SCROLLABLE_OVERFLOW = /* @__PURE__ */ new Set([
942
+ "auto",
943
+ "scroll",
944
+ "overlay"
945
+ ]);
946
+ var getWindowInnerHeight = () => typeof window === "undefined" ? 0 : window.innerHeight;
947
+ var getPlaygroundHost = (el) => el?.closest(".docs-playground") ?? el;
948
+ var isPlaygroundExpandEnabled = (expand) => {
949
+ if (expand === true) return true;
950
+ return typeof expand === "number" && Number.isFinite(expand) && expand > 0;
951
+ };
952
+ var resolveRemainingPreviewHeight = ({ viewportHeight, chromeHeight, gap = 16 }) => Math.max(0, Math.round((Number.isFinite(viewportHeight) ? viewportHeight : 0) - (Number.isFinite(chromeHeight) ? Math.max(0, chromeHeight) : 0) - (Number.isFinite(gap) ? gap : 16)));
953
+ var resolveExpandedPreviewHeight = (expand, availableHeight) => {
954
+ if (expand === true) return Math.max(24, Math.round(Number.isFinite(availableHeight) ? availableHeight : 0));
955
+ return Math.max(24, Math.round(expand));
956
+ };
957
+ var getVisibleViewportRect = (el) => {
958
+ const viewportHeight = getWindowInnerHeight();
959
+ let top = 0;
960
+ let bottom = viewportHeight;
961
+ if (typeof window === "undefined" || !el) return {
962
+ top,
963
+ bottom,
964
+ height: Math.max(0, Math.round(bottom - top))
965
+ };
966
+ let node = getPlaygroundHost(el)?.parentElement ?? null;
967
+ while (node && node !== document.documentElement) {
968
+ const overflowY = getComputedStyle(node).overflowY;
969
+ if (CLIPPING_OVERFLOW.has(overflowY)) {
970
+ const rect = node.getBoundingClientRect();
971
+ if (Number.isFinite(rect.top)) top = Math.max(top, rect.top);
972
+ if (Number.isFinite(rect.bottom)) bottom = Math.min(bottom, rect.bottom);
973
+ }
974
+ node = node.parentElement;
975
+ }
976
+ return {
977
+ top,
978
+ bottom,
979
+ height: Math.max(0, Math.round(bottom - top))
980
+ };
981
+ };
982
+ var findScrollableAncestor = (el) => {
983
+ if (!el || typeof window === "undefined") return null;
984
+ let node = getPlaygroundHost(el)?.parentElement ?? null;
985
+ while (node && node !== document.documentElement) {
986
+ const overflowY = getComputedStyle(node).overflowY;
987
+ if (SCROLLABLE_OVERFLOW.has(overflowY) && node.scrollHeight > node.clientHeight + 1) return node;
988
+ node = node.parentElement;
989
+ }
990
+ return null;
991
+ };
992
+ var scrollPlaygroundToViewportStart = (el) => {
993
+ if (!el) return;
994
+ const host = getPlaygroundHost(el) ?? el;
995
+ const scroller = findScrollableAncestor(host);
996
+ if (scroller) {
997
+ const delta = host.getBoundingClientRect().top - scroller.getBoundingClientRect().top;
998
+ scroller.scrollTop = Math.max(0, scroller.scrollTop + delta);
999
+ return;
1000
+ }
1001
+ if (typeof host.scrollIntoView === "function") host.scrollIntoView({
1002
+ block: "start",
1003
+ behavior: "auto"
1004
+ });
1005
+ };
882
1006
  //#endregion
883
1007
  //#region packages/playground/src/core/runtime/error-guard.ts
884
1008
  var UNKNOWN_RUNTIME_ERROR = "运行时发生未知错误";
@@ -942,6 +1066,89 @@ var useSandboxRuntimeErrorGuard = (sandboxRef) => {
942
1066
  return error;
943
1067
  };
944
1068
  //#endregion
1069
+ //#region packages/playground/src/core/runtime/viewport.ts
1070
+ var DEFAULT_VIEWPORT_OPTIONS = ["auto", 375];
1071
+ var isValidViewport = (viewport) => {
1072
+ if (viewport === "auto") return true;
1073
+ if (typeof viewport === "number") return Number.isFinite(viewport) && viewport > 0;
1074
+ return Array.isArray(viewport) && viewport.length === 2 && viewport.every((value) => typeof value === "number" && Number.isFinite(value) && value > 0);
1075
+ };
1076
+ var getViewportKey = (viewport) => Array.isArray(viewport) ? `${viewport[0]}x${viewport[1]}` : String(viewport);
1077
+ var viewportEquals = (left, right) => getViewportKey(left) === getViewportKey(right);
1078
+ var cloneViewport = (viewport) => Array.isArray(viewport) ? [viewport[0], viewport[1]] : viewport;
1079
+ var normalizeViewportOptions = (options) => {
1080
+ const source = options === void 0 ? DEFAULT_VIEWPORT_OPTIONS : options;
1081
+ const normalized = [];
1082
+ for (const viewport of source) {
1083
+ if (!isValidViewport(viewport)) continue;
1084
+ if (normalized.some((item) => viewportEquals(item, viewport))) continue;
1085
+ normalized.push(cloneViewport(viewport));
1086
+ }
1087
+ return normalized;
1088
+ };
1089
+ var resolveInitialViewport = (viewport, options) => isValidViewport(viewport) ? cloneViewport(viewport) : cloneViewport(options[0] || "auto");
1090
+ var includeActiveViewport = (options, viewport) => {
1091
+ if (!options.length || options.some((item) => viewportEquals(item, viewport))) return options;
1092
+ return [...options, cloneViewport(viewport)];
1093
+ };
1094
+ var getViewportWidth = (viewport) => {
1095
+ if (viewport === "auto") return null;
1096
+ return Array.isArray(viewport) ? viewport[0] : viewport;
1097
+ };
1098
+ var getViewportHeight = (viewport) => Array.isArray(viewport) ? viewport[1] : null;
1099
+ var formatViewportLabel = (viewport, autoLabel = "Auto") => {
1100
+ if (viewport === "auto") return autoLabel;
1101
+ return Array.isArray(viewport) ? `${viewport[0]} × ${viewport[1]}px` : `${viewport}px`;
1102
+ };
1103
+ var getWindowInnerSize = () => {
1104
+ if (typeof window === "undefined") return {
1105
+ width: 0,
1106
+ height: 0
1107
+ };
1108
+ return {
1109
+ width: window.innerWidth,
1110
+ height: window.innerHeight
1111
+ };
1112
+ };
1113
+ var resolvePopupRequestedSize = (viewport, screen = getWindowInnerSize(), gap = 40) => {
1114
+ const safeGap = Number.isFinite(gap) ? Math.max(0, gap) : 40;
1115
+ const maxWidth = Math.max(0, Math.round((Number.isFinite(screen.width) ? screen.width : 0) - safeGap));
1116
+ const maxHeight = Math.max(0, Math.round((Number.isFinite(screen.height) ? screen.height : 0) - safeGap));
1117
+ const viewportWidth = getViewportWidth(viewport);
1118
+ const viewportHeight = getViewportHeight(viewport);
1119
+ return {
1120
+ width: viewportWidth ?? maxWidth,
1121
+ height: viewportHeight ?? maxHeight,
1122
+ maxWidth,
1123
+ maxHeight
1124
+ };
1125
+ };
1126
+ /**
1127
+ * 壳层封顶到 `screen - gap`。未设 viewport 边时,画布铺满工具栏以下区域;
1128
+ * 请求尺寸大于可用区域时由 Scroller 处理溢出。
1129
+ * @param viewport 当前 playground 视口配置。
1130
+ * @param screen 屏幕可用宽高,默认取 `window.inner*`.
1131
+ * @param gap 相对屏幕边缘的留白。
1132
+ * @returns 壳层、内容区与画布尺寸,以及是否需要滚动。
1133
+ */
1134
+ var resolvePopupLayout = (viewport, screen = getWindowInnerSize(), gap = 40) => {
1135
+ const requested = resolvePopupRequestedSize(viewport, screen, gap);
1136
+ const shellWidth = Math.min(requested.width, requested.maxWidth);
1137
+ const shellHeight = Math.min(requested.height, requested.maxHeight);
1138
+ const bodyHeight = Math.max(0, shellHeight - 44);
1139
+ const canvasWidth = getViewportWidth(viewport) ?? shellWidth;
1140
+ const canvasHeight = getViewportHeight(viewport) ?? bodyHeight;
1141
+ return {
1142
+ shellWidth,
1143
+ shellHeight,
1144
+ bodyHeight,
1145
+ canvasWidth,
1146
+ canvasHeight,
1147
+ needsScrollX: canvasWidth > shellWidth,
1148
+ needsScrollY: canvasHeight > bodyHeight
1149
+ };
1150
+ };
1151
+ //#endregion
945
1152
  //#region packages/playground/src/core/runtime/theme.ts
946
1153
  var resolveElementTheme = (element) => {
947
1154
  const vcTheme = element?.getAttribute("data-vc-theme");
@@ -1034,40 +1241,157 @@ var useSandboxTheme = (sandboxRef) => {
1034
1241
  });
1035
1242
  };
1036
1243
  //#endregion
1037
- //#region packages/playground/src/core/runtime/viewport.ts
1038
- var DEFAULT_VIEWPORT_OPTIONS = ["auto", 375];
1039
- var isValidViewport = (viewport) => {
1040
- if (viewport === "auto") return true;
1041
- if (typeof viewport === "number") return Number.isFinite(viewport) && viewport > 0;
1042
- return Array.isArray(viewport) && viewport.length === 2 && viewport.every((value) => typeof value === "number" && Number.isFinite(value) && value > 0);
1043
- };
1044
- var getViewportKey = (viewport) => Array.isArray(viewport) ? `${viewport[0]}x${viewport[1]}` : String(viewport);
1045
- var viewportEquals = (left, right) => getViewportKey(left) === getViewportKey(right);
1046
- var cloneViewport = (viewport) => Array.isArray(viewport) ? [viewport[0], viewport[1]] : viewport;
1047
- var normalizeViewportOptions = (options) => {
1048
- const source = options === void 0 ? DEFAULT_VIEWPORT_OPTIONS : options;
1049
- const normalized = [];
1050
- for (const viewport of source) {
1051
- if (!isValidViewport(viewport)) continue;
1052
- if (normalized.some((item) => viewportEquals(item, viewport))) continue;
1053
- normalized.push(cloneViewport(viewport));
1244
+ //#region packages/playground/src/core/runtime/toolbar.vue?vue&type=script&setup=true&lang.ts
1245
+ var _hoisted_1$3 = { class: "docs-playground__tools" };
1246
+ var _hoisted_2$2 = ["title", "aria-label"];
1247
+ var _hoisted_3$2 = [
1248
+ "title",
1249
+ "aria-label",
1250
+ "aria-expanded"
1251
+ ];
1252
+ var _hoisted_4$2 = ["title", "aria-label"];
1253
+ var _hoisted_5$2 = ["title", "aria-label"];
1254
+ var _hoisted_6$1 = ["title", "aria-label"];
1255
+ //#endregion
1256
+ //#region packages/playground/src/core/runtime/toolbar.vue
1257
+ var toolbar_default = /* @__PURE__ */ defineComponent({
1258
+ __name: "toolbar",
1259
+ props: {
1260
+ copyValue: {},
1261
+ viewport: { default: "auto" },
1262
+ viewportOptions: { default: () => ["auto", 375] },
1263
+ showOpenPopup: {
1264
+ type: Boolean,
1265
+ default: false
1266
+ },
1267
+ showClose: {
1268
+ type: Boolean,
1269
+ default: false
1270
+ }
1271
+ },
1272
+ emits: [
1273
+ "refresh",
1274
+ "edit",
1275
+ "open-popup",
1276
+ "close-popup",
1277
+ "viewport-change"
1278
+ ],
1279
+ setup(__props, { emit: __emit }) {
1280
+ const props = __props;
1281
+ const emit = __emit;
1282
+ const { t } = useLocale();
1283
+ const viewportMenuVisible = ref(false);
1284
+ const viewportLabel = computed(() => formatViewportLabel(props.viewport, t("playground.runtime.auto")));
1285
+ const handleViewport = (index) => {
1286
+ const viewport = props.viewportOptions[index];
1287
+ if (viewport && !viewportEquals(viewport, props.viewport)) emit("viewport-change", viewport);
1288
+ };
1289
+ watch(() => props.viewportOptions.length, (length) => {
1290
+ if (length <= 1) viewportMenuVisible.value = false;
1291
+ });
1292
+ return (_ctx, _cache) => {
1293
+ return openBlock(), createElementBlock("div", _hoisted_1$3, [
1294
+ createElementVNode("button", {
1295
+ type: "button",
1296
+ class: "docs-playground__tool docs-playground__refresh",
1297
+ "data-action": "refresh",
1298
+ title: unref(t)("playground.runtime.refresh"),
1299
+ "aria-label": unref(t)("playground.runtime.refresh"),
1300
+ onClick: _cache[0] || (_cache[0] = ($event) => emit("refresh"))
1301
+ }, [createVNode(unref(icon_default), { name: "refresh" })], 8, _hoisted_2$2),
1302
+ __props.viewportOptions.length > 1 ? (openBlock(), createBlock(unref(Dropdown), {
1303
+ key: 0,
1304
+ modelValue: viewportMenuVisible.value,
1305
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => viewportMenuVisible.value = $event),
1306
+ class: "docs-playground__viewport-menu",
1307
+ portal: true,
1308
+ trigger: "click",
1309
+ placement: "bottom-right"
1310
+ }, {
1311
+ content: withCtx(() => [createVNode(unref(DropdownMenu), {
1312
+ class: "docs-playground__viewport-options",
1313
+ role: "menu",
1314
+ "aria-label": unref(t)("playground.runtime.viewportMenu")
1315
+ }, {
1316
+ default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.viewportOptions, (item, index) => {
1317
+ return openBlock(), createBlock(unref(DropdownItem), {
1318
+ key: unref(getViewportKey)(item),
1319
+ class: "docs-playground__viewport-option",
1320
+ value: index,
1321
+ selected: unref(viewportEquals)(item, __props.viewport),
1322
+ role: "menuitemradio",
1323
+ "aria-checked": unref(viewportEquals)(item, __props.viewport),
1324
+ onClick: ($event) => handleViewport(index)
1325
+ }, {
1326
+ default: withCtx(() => [createTextVNode(toDisplayString(unref(formatViewportLabel)(item, unref(t)("playground.runtime.auto"))), 1)]),
1327
+ _: 2
1328
+ }, 1032, [
1329
+ "value",
1330
+ "selected",
1331
+ "aria-checked",
1332
+ "onClick"
1333
+ ]);
1334
+ }), 128))]),
1335
+ _: 1
1336
+ }, 8, ["aria-label"])]),
1337
+ default: withCtx(() => [createElementVNode("button", {
1338
+ type: "button",
1339
+ class: normalizeClass(["docs-playground__tool docs-playground__viewport-trigger", { "is-active": __props.viewport !== "auto" }]),
1340
+ title: unref(t)("playground.runtime.viewport", { value: viewportLabel.value }),
1341
+ "aria-label": unref(t)("playground.runtime.viewport", { value: viewportLabel.value }),
1342
+ "aria-expanded": viewportMenuVisible.value,
1343
+ "aria-haspopup": "menu"
1344
+ }, [createVNode(unref(icon_default), { name: "viewport" })], 10, _hoisted_3$2)]),
1345
+ _: 1
1346
+ }, 8, ["modelValue"])) : createCommentVNode("v-if", true),
1347
+ createVNode(unref(Clipboard), {
1348
+ class: "docs-playground__tool",
1349
+ value: __props.copyValue,
1350
+ tag: "button",
1351
+ type: "button",
1352
+ title: unref(t)("playground.common.copy"),
1353
+ "aria-label": unref(t)("playground.common.copy")
1354
+ }, {
1355
+ default: withCtx(() => [createVNode(unref(icon_default), { name: "copy" })]),
1356
+ _: 1
1357
+ }, 8, [
1358
+ "value",
1359
+ "title",
1360
+ "aria-label"
1361
+ ]),
1362
+ createElementVNode("button", {
1363
+ type: "button",
1364
+ class: "docs-playground__tool docs-playground__editor",
1365
+ "data-action": "edit",
1366
+ title: unref(t)("playground.runtime.editFiles"),
1367
+ "aria-label": unref(t)("playground.runtime.editFiles"),
1368
+ onClick: _cache[2] || (_cache[2] = ($event) => emit("edit"))
1369
+ }, [createVNode(unref(icon_default), { name: "editor" })], 8, _hoisted_4$2),
1370
+ __props.showOpenPopup ? (openBlock(), createElementBlock("button", {
1371
+ key: 1,
1372
+ type: "button",
1373
+ class: "docs-playground__tool docs-playground__popup",
1374
+ "data-action": "open-popup",
1375
+ title: unref(t)("playground.runtime.openPopup"),
1376
+ "aria-label": unref(t)("playground.runtime.openPopup"),
1377
+ onClick: _cache[3] || (_cache[3] = ($event) => emit("open-popup"))
1378
+ }, [createVNode(unref(icon_default), { name: "popup" })], 8, _hoisted_5$2)) : createCommentVNode("v-if", true),
1379
+ __props.showClose ? (openBlock(), createElementBlock("button", {
1380
+ key: 2,
1381
+ type: "button",
1382
+ class: "docs-playground__tool docs-playground__popup-close",
1383
+ "data-action": "close-popup",
1384
+ title: unref(t)("playground.runtime.closePopup"),
1385
+ "aria-label": unref(t)("playground.runtime.closePopup"),
1386
+ onClick: _cache[4] || (_cache[4] = ($event) => emit("close-popup"))
1387
+ }, [..._cache[5] || (_cache[5] = [createElementVNode("span", {
1388
+ class: "docs-playground__popup-close-mark",
1389
+ "aria-hidden": "true"
1390
+ }, "✕", -1)])], 8, _hoisted_6$1)) : createCommentVNode("v-if", true)
1391
+ ]);
1392
+ };
1054
1393
  }
1055
- return normalized;
1056
- };
1057
- var resolveInitialViewport = (viewport, options) => isValidViewport(viewport) ? cloneViewport(viewport) : cloneViewport(options[0] || "auto");
1058
- var includeActiveViewport = (options, viewport) => {
1059
- if (!options.length || options.some((item) => viewportEquals(item, viewport))) return options;
1060
- return [...options, cloneViewport(viewport)];
1061
- };
1062
- var getViewportWidth = (viewport) => {
1063
- if (viewport === "auto") return null;
1064
- return Array.isArray(viewport) ? viewport[0] : viewport;
1065
- };
1066
- var getViewportHeight = (viewport) => Array.isArray(viewport) ? viewport[1] : null;
1067
- var formatViewportLabel = (viewport, autoLabel = "Auto") => {
1068
- if (viewport === "auto") return autoLabel;
1069
- return Array.isArray(viewport) ? `${viewport[0]} × ${viewport[1]}px` : `${viewport}px`;
1070
- };
1394
+ });
1071
1395
  //#endregion
1072
1396
  //#region packages/playground/src/cdn.ts
1073
1397
  var PREVIEW_STYLE_ASSETS = [
@@ -1416,6 +1740,12 @@ var DOCS_LINK_USE_CODE = [
1416
1740
  "})"
1417
1741
  ].join("");
1418
1742
  var escapeHtmlAttr = (value) => value.replace(/&/gu, "&amp;").replace(/"/gu, "&quot;").replace(/'/gu, "&#39;").replace(/</gu, "&lt;").replace(/>/gu, "&gt;");
1743
+ /**
1744
+ * runtime 画布色。`previewInset` 露出的 padding、iframe chrome 和 sandbox
1745
+ * `html`/`body` 必须共用这一变量,暗色下 `--docs-background-color` 与
1746
+ * `--vc-background-color-light` 不同,否则会出现色带割裂。
1747
+ */
1748
+ var PLAYGROUND_RUNTIME_CANVAS_BACKGROUND = "var(--vc-background-color-light, var(--docs-background-color, #fff))";
1419
1749
  var createRuntimePreviewOptions = (cdnURL = DEFAULT_CDN_URL) => {
1420
1750
  return {
1421
1751
  showRuntimeError: false,
@@ -1429,8 +1759,8 @@ var createRuntimePreviewOptions = (cdnURL = DEFAULT_CDN_URL) => {
1429
1759
  ...getPlaygroundStyleOverrides()
1430
1760
  }).map((href) => `<link rel="stylesheet" href="${escapeHtmlAttr(href)}">`),
1431
1761
  "<style>",
1432
- "html,body{height:auto;min-height:0}",
1433
- "body{color:var(--vc-foreground-color,#080f20);background:var(--vc-background-color-light,#fff)}",
1762
+ `html,body{height:auto;min-height:0;background:${PLAYGROUND_RUNTIME_CANVAS_BACKGROUND}}`,
1763
+ "body{color:var(--vc-foreground-color,#080f20)}",
1434
1764
  "</style>"
1435
1765
  ].join("\n"),
1436
1766
  customCode: {
@@ -1476,40 +1806,203 @@ var createRuntimeStore = (files, entry, options) => {
1476
1806
  return store;
1477
1807
  };
1478
1808
  //#endregion
1479
- //#region packages/playground/src/core/runtime/runtime.vue?vue&type=script&setup=true&lang.ts
1480
- var _hoisted_1$1 = {
1809
+ //#region packages/playground/src/core/runtime/alone/wrapper.vue?vue&type=script&setup=true&lang.ts
1810
+ var _hoisted_1$2 = ["aria-label"];
1811
+ var _hoisted_2$1 = { class: "docs-playground-popup__frame" };
1812
+ var _hoisted_3$1 = { class: "docs-playground-popup__header" };
1813
+ var _hoisted_4$1 = {
1481
1814
  key: 0,
1482
1815
  class: "docs-playground__runtime-error",
1483
1816
  role: "alert"
1484
1817
  };
1818
+ var _hoisted_5$1 = { class: "docs-playground-popup__body" };
1819
+ //#endregion
1820
+ //#region packages/playground/src/core/runtime/alone/index.ts
1821
+ var Alone = new Portal(/* @__PURE__ */ defineComponent({
1822
+ __name: "wrapper",
1823
+ props: {
1824
+ store: {},
1825
+ copyValue: {},
1826
+ viewport: { default: "auto" },
1827
+ viewportOptions: { default: () => ["auto", 375] },
1828
+ previewOptions: {},
1829
+ clearConsole: {
1830
+ type: Boolean,
1831
+ default: true
1832
+ }
1833
+ },
1834
+ emits: [
1835
+ "edit",
1836
+ "navigate",
1837
+ "viewport-change",
1838
+ "portal-fulfilled"
1839
+ ],
1840
+ setup(__props, { emit: __emit }) {
1841
+ const props = __props;
1842
+ const emit = __emit;
1843
+ const { t } = useLocale();
1844
+ const currentViewport = ref(props.viewport);
1845
+ const sandboxRef = ref(null);
1846
+ const sandboxKey = ref(0);
1847
+ const layoutTick = ref(0);
1848
+ const runtimeError = useSandboxRuntimeErrorGuard(sandboxRef);
1849
+ useSandboxTheme(sandboxRef);
1850
+ const storeErrors = computed(() => (props.store.errors || []).map(toErrorText).filter(Boolean).join("\n"));
1851
+ const errorText = computed(() => {
1852
+ const runtime = runtimeError.value ? formatSandboxRuntimeError(runtimeError.value, t("playground.runtime.importMapTip")) : "";
1853
+ return [storeErrors.value, runtime].filter(Boolean).join("\n\n");
1854
+ });
1855
+ const layout = computed(() => {
1856
+ layoutTick.value;
1857
+ return resolvePopupLayout(currentViewport.value);
1858
+ });
1859
+ const shellStyle = computed(() => ({
1860
+ width: `${layout.value.shellWidth}px`,
1861
+ height: `${layout.value.shellHeight}px`
1862
+ }));
1863
+ const canvasStyle = computed(() => ({
1864
+ width: `${layout.value.canvasWidth}px`,
1865
+ height: `${layout.value.canvasHeight}px`,
1866
+ background: PLAYGROUND_RUNTIME_CANVAS_BACKGROUND
1867
+ }));
1868
+ const handleRefresh = () => {
1869
+ runtimeError.value = "";
1870
+ sandboxKey.value++;
1871
+ };
1872
+ const handleViewportChange = (viewport) => {
1873
+ currentViewport.value = viewport;
1874
+ emit("viewport-change", viewport);
1875
+ };
1876
+ const handleClose = () => emit("portal-fulfilled");
1877
+ const isPlaygroundEditorOpen = () => {
1878
+ if (typeof document === "undefined") return false;
1879
+ const editor = document.querySelector(".docs-playground-editor__wrapper");
1880
+ if (!(editor instanceof HTMLElement)) return false;
1881
+ const style = getComputedStyle(editor);
1882
+ return style.display !== "none" && style.visibility !== "hidden";
1883
+ };
1884
+ const handleKeydown = (event) => {
1885
+ if (event.key !== "Escape") return;
1886
+ if (isPlaygroundEditorOpen()) return;
1887
+ event.preventDefault();
1888
+ handleClose();
1889
+ };
1890
+ const handleResize = () => {
1891
+ layoutTick.value++;
1892
+ };
1893
+ const handleBridgeMessage = (event) => {
1894
+ const iframe = resolveSandboxContainer(sandboxRef.value)?.querySelector("iframe");
1895
+ if (!iframe || event.source !== iframe.contentWindow) return;
1896
+ const data = event.data;
1897
+ if (!data || data.action !== "docs:navigate" || typeof data.to !== "string") return;
1898
+ emit("navigate", data.to);
1899
+ };
1900
+ watch(() => props.viewport, (viewport) => {
1901
+ currentViewport.value = viewport;
1902
+ });
1903
+ if (typeof window !== "undefined") {
1904
+ window.addEventListener("keydown", handleKeydown);
1905
+ window.addEventListener("resize", handleResize);
1906
+ window.addEventListener("message", handleBridgeMessage);
1907
+ }
1908
+ onBeforeUnmount(() => {
1909
+ window.removeEventListener("keydown", handleKeydown);
1910
+ window.removeEventListener("resize", handleResize);
1911
+ window.removeEventListener("message", handleBridgeMessage);
1912
+ });
1913
+ return (_ctx, _cache) => {
1914
+ return openBlock(), createElementBlock("div", {
1915
+ class: "docs-playground-popup",
1916
+ role: "dialog",
1917
+ "aria-modal": "true",
1918
+ "aria-label": unref(t)("playground.runtime.openPopup")
1919
+ }, [createElementVNode("div", {
1920
+ class: "docs-playground-popup__mask",
1921
+ "data-action": "popup-mask",
1922
+ onClick: handleClose
1923
+ }), createElementVNode("div", {
1924
+ class: "docs-playground-popup__shell",
1925
+ style: normalizeStyle(shellStyle.value)
1926
+ }, [createElementVNode("div", _hoisted_2$1, [
1927
+ createElementVNode("div", _hoisted_3$1, [createVNode(toolbar_default, {
1928
+ "copy-value": __props.copyValue,
1929
+ viewport: currentViewport.value,
1930
+ "viewport-options": __props.viewportOptions,
1931
+ "show-close": true,
1932
+ onRefresh: handleRefresh,
1933
+ onEdit: _cache[0] || (_cache[0] = ($event) => emit("edit")),
1934
+ onClosePopup: handleClose,
1935
+ onViewportChange: handleViewportChange
1936
+ }, null, 8, [
1937
+ "copy-value",
1938
+ "viewport",
1939
+ "viewport-options"
1940
+ ])]),
1941
+ errorText.value ? (openBlock(), createElementBlock("pre", _hoisted_4$1, toDisplayString(errorText.value), 1)) : createCommentVNode("v-if", true),
1942
+ createElementVNode("div", _hoisted_5$1, [createVNode(unref(Scroller), {
1943
+ class: "docs-playground-popup__scroller",
1944
+ "content-class": "docs-playground-popup__scroller-content",
1945
+ "auto-resize": true,
1946
+ native: false,
1947
+ "show-bar": true,
1948
+ height: "100%"
1949
+ }, {
1950
+ default: withCtx(() => [createElementVNode("div", {
1951
+ class: "docs-playground-popup__canvas",
1952
+ style: normalizeStyle(canvasStyle.value)
1953
+ }, [(openBlock(), createBlock(unref(Sandbox), {
1954
+ key: sandboxKey.value,
1955
+ ref_key: "sandboxRef",
1956
+ ref: sandboxRef,
1957
+ store: __props.store,
1958
+ "auto-store-init": false,
1959
+ "clear-console": __props.clearConsole,
1960
+ "preview-options": __props.previewOptions
1961
+ }, null, 8, [
1962
+ "store",
1963
+ "clear-console",
1964
+ "preview-options"
1965
+ ]))], 4)]),
1966
+ _: 1
1967
+ })])
1968
+ ])], 4)], 8, _hoisted_1$2);
1969
+ };
1970
+ }
1971
+ }), {
1972
+ name: "docs-playground-alone",
1973
+ leaveDelay: 0,
1974
+ multiple: false
1975
+ });
1976
+ //#endregion
1977
+ //#region packages/playground/src/core/runtime/runtime.vue?vue&type=script&setup=true&lang.ts
1978
+ var _hoisted_1$1 = { class: "docs-playground-runtime-host" };
1485
1979
  var _hoisted_2 = {
1486
- key: 1,
1487
- class: "docs-playground-runtime"
1980
+ key: 0,
1981
+ class: "docs-playground__runtime-error",
1982
+ role: "alert"
1488
1983
  };
1489
1984
  var _hoisted_3 = { class: "docs-playground__header" };
1490
- var _hoisted_4 = { class: "docs-playground__tools" };
1491
- var _hoisted_5 = [
1492
- "title",
1493
- "aria-label",
1494
- "aria-expanded"
1495
- ];
1496
- var _hoisted_6 = ["title", "aria-label"];
1497
- var _hoisted_7 = {
1985
+ var _hoisted_4 = {
1498
1986
  key: 0,
1499
1987
  class: "docs-playground__views"
1500
1988
  };
1501
- var _hoisted_8 = [
1989
+ var _hoisted_5 = [
1502
1990
  "title",
1503
1991
  "aria-label",
1504
1992
  "aria-pressed",
1505
1993
  "onClick"
1506
1994
  ];
1507
- var _hoisted_9 = {
1995
+ var _hoisted_6 = {
1508
1996
  key: 0,
1509
1997
  class: "docs-playground__runtime-error",
1510
1998
  role: "alert"
1511
1999
  };
1512
- var _hoisted_10 = { class: "docs-playground-runtime__viewport-stage" };
2000
+ var _hoisted_7 = { class: "docs-playground-runtime__viewport-stage" };
2001
+ var _hoisted_8 = [
2002
+ "aria-expanded",
2003
+ "title",
2004
+ "aria-label"
2005
+ ];
1513
2006
  //#endregion
1514
2007
  //#region packages/playground/src/core/runtime/runtime.vue
1515
2008
  var runtime_default = /* @__PURE__ */ defineComponent({
@@ -1526,6 +2019,7 @@ var runtime_default = /* @__PURE__ */ defineComponent({
1526
2019
  type: Boolean,
1527
2020
  default: false
1528
2021
  },
2022
+ expand: { type: [Boolean, Number] },
1529
2023
  viewport: { default: "auto" },
1530
2024
  viewportOptions: { default: () => ["auto", 375] }
1531
2025
  },
@@ -1541,18 +2035,24 @@ var runtime_default = /* @__PURE__ */ defineComponent({
1541
2035
  const getViewText = (view) => t(playgroundViewMessage(view));
1542
2036
  const emit = __emit;
1543
2037
  const joinCode = (...values) => values.filter(Boolean).join("\n");
1544
- const mergedPreviewOptions = computed(() => {
2038
+ const mergePreviewOptions = (extraHeadHTML) => {
1545
2039
  const runtimePreviewOptions = createRuntimePreviewOptions(props.options.cdnURL);
1546
2040
  return {
1547
2041
  ...runtimePreviewOptions,
1548
2042
  ...props.previewOptions,
1549
- headHTML: [runtimePreviewOptions.headHTML, props.previewOptions?.headHTML].filter(Boolean).join("\n"),
2043
+ headHTML: [
2044
+ runtimePreviewOptions.headHTML,
2045
+ props.previewOptions?.headHTML,
2046
+ extraHeadHTML
2047
+ ].filter(Boolean).join("\n"),
1550
2048
  customCode: {
1551
2049
  importCode: joinCode(runtimePreviewOptions.customCode?.importCode, props.previewOptions?.customCode?.importCode),
1552
2050
  useCode: joinCode(runtimePreviewOptions.customCode?.useCode, props.previewOptions?.customCode?.useCode)
1553
2051
  }
1554
2052
  };
1555
- });
2053
+ };
2054
+ const mergedPreviewOptions = computed(() => mergePreviewOptions());
2055
+ const popupPreviewOptions = computed(() => mergePreviewOptions("<style>html,body{height:100%;min-height:100%}</style>"));
1556
2056
  const clearConsole = {
1557
2057
  "BASE_URL": "/",
1558
2058
  "DEV": false,
@@ -1563,6 +2063,7 @@ var runtime_default = /* @__PURE__ */ defineComponent({
1563
2063
  const copyValue = computed(() => props.files[props.entry] || "");
1564
2064
  const store = createRuntimeStore(props.files, props.entry, props.options);
1565
2065
  const sandboxRef = ref(null);
2066
+ const sandboxKey = ref(0);
1566
2067
  const runtimeHeight = useSandboxAutoHeight(sandboxRef);
1567
2068
  const runtimeError = useSandboxRuntimeErrorGuard(sandboxRef);
1568
2069
  useSandboxTheme(sandboxRef);
@@ -1578,11 +2079,63 @@ var runtime_default = /* @__PURE__ */ defineComponent({
1578
2079
  if (!data || data.action !== "docs:navigate" || typeof data.to !== "string") return;
1579
2080
  emit("navigate", data.to);
1580
2081
  };
1581
- if (typeof window !== "undefined") window.addEventListener("message", handleBridgeMessage);
1582
- onBeforeUnmount(() => window.removeEventListener("message", handleBridgeMessage));
1583
- const viewportMenuVisible = ref(false);
1584
- const viewportLabel = computed(() => formatViewportLabel(props.viewport, t("playground.runtime.auto")));
1585
- const desiredViewportHeight = computed(() => getViewportHeight(props.viewport) || runtimeHeight.value);
2082
+ const runtimeRoot = ref(null);
2083
+ const previewExpanded = ref(false);
2084
+ /** `expand: true` 时在展开瞬间冻结,避免滚动重算高度造成抖动。 */
2085
+ const frozenExpandedHeight = ref(0);
2086
+ const measurePreviewChromeHeight = () => {
2087
+ const root = runtimeRoot.value;
2088
+ if (!root) return 0;
2089
+ const header = root.querySelector(".docs-playground__header");
2090
+ const error = root.querySelector(".docs-playground__runtime-error");
2091
+ return (header instanceof HTMLElement ? header.offsetHeight : 0) + (error instanceof HTMLElement ? error.offsetHeight : 0);
2092
+ };
2093
+ const measureExpandedPreviewHeight = () => {
2094
+ if (typeof window === "undefined") return runtimeHeight.value;
2095
+ const chromeHeight = measurePreviewChromeHeight();
2096
+ return resolveExpandedPreviewHeight(true, resolveRemainingPreviewHeight({
2097
+ viewportHeight: getVisibleViewportRect(runtimeRoot.value).height,
2098
+ chromeHeight
2099
+ }));
2100
+ };
2101
+ const syncFrozenExpandedHeight = () => {
2102
+ if (!previewExpanded.value || props.expand !== true) return;
2103
+ frozenExpandedHeight.value = measureExpandedPreviewHeight();
2104
+ };
2105
+ if (typeof window !== "undefined") {
2106
+ window.addEventListener("message", handleBridgeMessage);
2107
+ window.addEventListener("resize", syncFrozenExpandedHeight);
2108
+ }
2109
+ const canExpandPreview = computed(() => !props.styleless && isPlaygroundExpandEnabled(props.expand));
2110
+ const expandLabel = computed(() => t(previewExpanded.value ? "playground.runtime.collapsePreview" : "playground.runtime.expandPreview"));
2111
+ const desiredViewportHeight = computed(() => {
2112
+ if (previewExpanded.value && props.expand === true) return frozenExpandedHeight.value;
2113
+ if (previewExpanded.value && isPlaygroundExpandEnabled(props.expand)) return resolveExpandedPreviewHeight(props.expand, 0);
2114
+ const fixedHeight = getViewportHeight(props.viewport);
2115
+ if (fixedHeight) return fixedHeight;
2116
+ return runtimeHeight.value;
2117
+ });
2118
+ const scrollExpandedPreviewIntoView = () => {
2119
+ scrollPlaygroundToViewportStart(runtimeRoot.value);
2120
+ };
2121
+ const handleTogglePreviewExpand = () => {
2122
+ if (!canExpandPreview.value) return;
2123
+ if (!previewExpanded.value) {
2124
+ if (props.expand === true) frozenExpandedHeight.value = measureExpandedPreviewHeight();
2125
+ else frozenExpandedHeight.value = 0;
2126
+ previewExpanded.value = true;
2127
+ nextTick(scrollExpandedPreviewIntoView);
2128
+ return;
2129
+ }
2130
+ previewExpanded.value = false;
2131
+ frozenExpandedHeight.value = 0;
2132
+ };
2133
+ watch(canExpandPreview, (enabled) => {
2134
+ if (!enabled) {
2135
+ previewExpanded.value = false;
2136
+ frozenExpandedHeight.value = 0;
2137
+ }
2138
+ });
1586
2139
  const normalizedPreviewInset = computed(() => {
1587
2140
  const value = props.previewInset;
1588
2141
  if (typeof value === "number") return Number.isFinite(value) && value >= 0 ? [value, value] : [10, 10];
@@ -1593,7 +2146,8 @@ var runtime_default = /* @__PURE__ */ defineComponent({
1593
2146
  const [vertical, horizontal] = normalizedPreviewInset.value;
1594
2147
  return {
1595
2148
  height: `${desiredViewportHeight.value + vertical * 2}px`,
1596
- padding: vertical === horizontal ? `${vertical}px` : `${vertical}px ${horizontal}px`
2149
+ padding: vertical === horizontal ? `${vertical}px` : `${vertical}px ${horizontal}px`,
2150
+ background: PLAYGROUND_RUNTIME_CANVAS_BACKGROUND
1597
2151
  };
1598
2152
  });
1599
2153
  const stylelessStyle = computed(() => errorText.value ? void 0 : { height: `${desiredViewportHeight.value}px` });
@@ -1645,14 +2199,30 @@ var runtime_default = /* @__PURE__ */ defineComponent({
1645
2199
  onActiveChange: (filename) => store.setActive(toReplFilename(filename))
1646
2200
  });
1647
2201
  };
2202
+ const handleInlineRefresh = () => {
2203
+ runtimeError.value = "";
2204
+ sandboxKey.value++;
2205
+ };
2206
+ const handleClosePopup = () => {
2207
+ Alone.destroy();
2208
+ };
2209
+ const handleOpenPopup = () => {
2210
+ Alone.popup({
2211
+ store,
2212
+ copyValue: copyValue.value,
2213
+ viewport: props.viewport,
2214
+ viewportOptions: props.viewportOptions,
2215
+ previewOptions: popupPreviewOptions.value,
2216
+ clearConsole,
2217
+ onEdit: handleEditor,
2218
+ onViewportChange: handleViewportChange,
2219
+ onNavigate: (to) => emit("navigate", to)
2220
+ });
2221
+ };
1648
2222
  const handleView = (view) => emit("view-change", view);
1649
- const handleViewport = (index) => {
1650
- const viewport = props.viewportOptions[index];
1651
- if (viewport && !viewportEquals(viewport, props.viewport)) emit("viewport-change", viewport);
2223
+ const handleViewportChange = (viewport) => {
2224
+ emit("viewport-change", viewport);
1652
2225
  };
1653
- watch(() => props.viewportOptions.length, (length) => {
1654
- if (length <= 1) viewportMenuVisible.value = false;
1655
- });
1656
2226
  watch(() => props.files, (files) => {
1657
2227
  if (filesEqual(files, syncedFiles)) return;
1658
2228
  syncedFiles = { ...files };
@@ -1666,12 +2236,22 @@ var runtime_default = /* @__PURE__ */ defineComponent({
1666
2236
  store.mainFile = toReplFilename(entry);
1667
2237
  store.setActive(toReplFilename(entry));
1668
2238
  });
2239
+ watch(() => props.activeView, (view) => {
2240
+ if (view !== "runtime") handleClosePopup();
2241
+ });
2242
+ onBeforeUnmount(() => {
2243
+ window.removeEventListener("message", handleBridgeMessage);
2244
+ window.removeEventListener("resize", syncFrozenExpandedHeight);
2245
+ handleClosePopup();
2246
+ });
1669
2247
  return (_ctx, _cache) => {
1670
- return __props.styleless ? (openBlock(), createElementBlock("div", {
2248
+ return openBlock(), createElementBlock("div", _hoisted_1$1, [__props.styleless ? (openBlock(), createElementBlock("div", {
1671
2249
  key: 0,
2250
+ ref_key: "runtimeRoot",
2251
+ ref: runtimeRoot,
1672
2252
  class: "docs-playground-runtime--styleless",
1673
2253
  style: normalizeStyle(stylelessStyle.value)
1674
- }, [errorText.value ? (openBlock(), createElementBlock("pre", _hoisted_1$1, toDisplayString(errorText.value), 1)) : createCommentVNode("v-if", true), createElementVNode("div", {
2254
+ }, [errorText.value ? (openBlock(), createElementBlock("pre", _hoisted_2, toDisplayString(errorText.value), 1)) : createCommentVNode("v-if", true), createElementVNode("div", {
1675
2255
  class: "docs-playground-runtime__viewport",
1676
2256
  style: normalizeStyle(viewportStyle.value)
1677
2257
  }, [createVNode(unref(Sandbox), {
@@ -1680,77 +2260,26 @@ var runtime_default = /* @__PURE__ */ defineComponent({
1680
2260
  store: unref(store),
1681
2261
  "auto-store-init": false,
1682
2262
  "preview-options": mergedPreviewOptions.value
1683
- }, null, 8, ["store", "preview-options"])], 4)], 4)) : (openBlock(), createElementBlock("div", _hoisted_2, [
1684
- createElementVNode("div", _hoisted_3, [createElementVNode("div", _hoisted_4, [
1685
- __props.viewportOptions.length > 1 ? (openBlock(), createBlock(unref(Dropdown), {
1686
- key: 0,
1687
- modelValue: viewportMenuVisible.value,
1688
- "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => viewportMenuVisible.value = $event),
1689
- class: "docs-playground__viewport-menu",
1690
- portal: true,
1691
- trigger: "click",
1692
- placement: "bottom-right"
1693
- }, {
1694
- content: withCtx(() => [createVNode(unref(DropdownMenu), {
1695
- class: "docs-playground__viewport-options",
1696
- role: "menu",
1697
- "aria-label": unref(t)("playground.runtime.viewportMenu")
1698
- }, {
1699
- default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.viewportOptions, (item, index) => {
1700
- return openBlock(), createBlock(unref(DropdownItem), {
1701
- key: unref(getViewportKey)(item),
1702
- class: "docs-playground__viewport-option",
1703
- value: index,
1704
- selected: unref(viewportEquals)(item, __props.viewport),
1705
- role: "menuitemradio",
1706
- "aria-checked": unref(viewportEquals)(item, __props.viewport),
1707
- onClick: ($event) => handleViewport(index)
1708
- }, {
1709
- default: withCtx(() => [createTextVNode(toDisplayString(unref(formatViewportLabel)(item, unref(t)("playground.runtime.auto"))), 1)]),
1710
- _: 2
1711
- }, 1032, [
1712
- "value",
1713
- "selected",
1714
- "aria-checked",
1715
- "onClick"
1716
- ]);
1717
- }), 128))]),
1718
- _: 1
1719
- }, 8, ["aria-label"])]),
1720
- default: withCtx(() => [createElementVNode("button", {
1721
- type: "button",
1722
- class: normalizeClass(["docs-playground__tool docs-playground__viewport-trigger", { "is-active": __props.viewport !== "auto" }]),
1723
- title: unref(t)("playground.runtime.viewport", { value: viewportLabel.value }),
1724
- "aria-label": unref(t)("playground.runtime.viewport", { value: viewportLabel.value }),
1725
- "aria-expanded": viewportMenuVisible.value,
1726
- "aria-haspopup": "menu"
1727
- }, [createVNode(unref(icon_default), { name: "viewport" })], 10, _hoisted_5)]),
1728
- _: 1
1729
- }, 8, ["modelValue"])) : createCommentVNode("v-if", true),
1730
- createVNode(unref(Clipboard), {
1731
- class: "docs-playground__tool",
1732
- value: copyValue.value,
1733
- tag: "button",
1734
- type: "button",
1735
- title: unref(t)("playground.common.copy"),
1736
- "aria-label": unref(t)("playground.common.copy")
1737
- }, {
1738
- default: withCtx(() => [createVNode(unref(icon_default), { name: "copy" })]),
1739
- _: 1
1740
- }, 8, [
1741
- "value",
1742
- "title",
1743
- "aria-label"
1744
- ]),
1745
- createElementVNode("button", {
1746
- type: "button",
1747
- class: "docs-playground__tool docs-playground__editor",
1748
- "data-action": "edit",
1749
- title: unref(t)("playground.runtime.editFiles"),
1750
- "aria-label": unref(t)("playground.runtime.editFiles"),
1751
- onClick: handleEditor
1752
- }, [createVNode(unref(icon_default), { name: "editor" })], 8, _hoisted_6)
1753
- ]), __props.views.length > 1 ? (openBlock(), createElementBlock("div", _hoisted_7, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.views, (item) => {
2263
+ }, null, 8, ["store", "preview-options"])], 4)], 4)) : (openBlock(), createElementBlock("div", {
2264
+ key: 1,
2265
+ ref_key: "runtimeRoot",
2266
+ ref: runtimeRoot,
2267
+ class: "docs-playground-runtime"
2268
+ }, [
2269
+ createElementVNode("div", _hoisted_3, [createVNode(toolbar_default, {
2270
+ "copy-value": copyValue.value,
2271
+ viewport: __props.viewport,
2272
+ "viewport-options": __props.viewportOptions,
2273
+ "show-open-popup": true,
2274
+ onRefresh: handleInlineRefresh,
2275
+ onEdit: handleEditor,
2276
+ onOpenPopup: handleOpenPopup,
2277
+ onViewportChange: handleViewportChange
2278
+ }, null, 8, [
2279
+ "copy-value",
2280
+ "viewport",
2281
+ "viewport-options"
2282
+ ]), __props.views.length > 1 ? (openBlock(), createElementBlock("div", _hoisted_4, [(openBlock(true), createElementBlock(Fragment, null, renderList(__props.views, (item) => {
1754
2283
  return openBlock(), createElementBlock("button", {
1755
2284
  key: item,
1756
2285
  type: "button",
@@ -1759,24 +2288,34 @@ var runtime_default = /* @__PURE__ */ defineComponent({
1759
2288
  "aria-label": getViewText(item),
1760
2289
  "aria-pressed": item === __props.activeView,
1761
2290
  onClick: ($event) => handleView(item)
1762
- }, [createVNode(unref(icon_default), { name: item }, null, 8, ["name"])], 10, _hoisted_8);
2291
+ }, [createVNode(unref(icon_default), { name: item }, null, 8, ["name"])], 10, _hoisted_5);
1763
2292
  }), 128))])) : createCommentVNode("v-if", true)]),
1764
- errorText.value ? (openBlock(), createElementBlock("pre", _hoisted_9, toDisplayString(errorText.value), 1)) : createCommentVNode("v-if", true),
2293
+ errorText.value ? (openBlock(), createElementBlock("pre", _hoisted_6, toDisplayString(errorText.value), 1)) : createCommentVNode("v-if", true),
1765
2294
  createElementVNode("section", {
1766
- class: "docs-playground__preview",
2295
+ class: normalizeClass(["docs-playground__preview", { "is-expanded": previewExpanded.value }]),
1767
2296
  style: normalizeStyle(previewStyle.value)
1768
- }, [createElementVNode("div", _hoisted_10, [createElementVNode("div", {
2297
+ }, [createElementVNode("div", _hoisted_7, [createElementVNode("div", {
1769
2298
  class: "docs-playground-runtime__viewport",
1770
2299
  style: normalizeStyle(viewportStyle.value)
1771
- }, [createVNode(unref(Sandbox), {
2300
+ }, [(openBlock(), createBlock(unref(Sandbox), {
2301
+ key: sandboxKey.value,
1772
2302
  ref_key: "sandboxRef",
1773
2303
  ref: sandboxRef,
1774
2304
  store: unref(store),
1775
2305
  "auto-store-init": false,
1776
2306
  "clear-console": clearConsole,
1777
2307
  "preview-options": mergedPreviewOptions.value
1778
- }, null, 8, ["store", "preview-options"])], 4)])], 4)
1779
- ]));
2308
+ }, null, 8, ["store", "preview-options"]))], 4)]), canExpandPreview.value ? (openBlock(), createElementBlock("button", {
2309
+ key: 0,
2310
+ type: "button",
2311
+ class: normalizeClass(["docs-playground__expand", { "is-expanded": previewExpanded.value }]),
2312
+ "data-action": "expand-preview",
2313
+ "aria-expanded": previewExpanded.value,
2314
+ title: expandLabel.value,
2315
+ "aria-label": expandLabel.value,
2316
+ onClick: handleTogglePreviewExpand
2317
+ }, [createVNode(unref(icon_default), { name: "expand" })], 10, _hoisted_8)) : createCommentVNode("v-if", true)], 6)
2318
+ ], 512))]);
1780
2319
  };
1781
2320
  }
1782
2321
  });
@@ -1803,6 +2342,7 @@ var playground_default = /* @__PURE__ */ defineComponent({
1803
2342
  },
1804
2343
  options: { default: () => ({}) },
1805
2344
  previewInset: { default: 0 },
2345
+ expand: { type: [Boolean, Number] },
1806
2346
  previewOptions: {},
1807
2347
  locale: {}
1808
2348
  },
@@ -1936,6 +2476,7 @@ var playground_default = /* @__PURE__ */ defineComponent({
1936
2476
  options: __props.options,
1937
2477
  "preview-options": __props.previewOptions,
1938
2478
  "preview-inset": __props.previewInset,
2479
+ expand: __props.expand,
1939
2480
  styleless: true,
1940
2481
  viewport: activeViewport.value,
1941
2482
  "viewport-options": selectableViewportOptions.value,
@@ -1948,6 +2489,7 @@ var playground_default = /* @__PURE__ */ defineComponent({
1948
2489
  "options",
1949
2490
  "preview-options",
1950
2491
  "preview-inset",
2492
+ "expand",
1951
2493
  "viewport",
1952
2494
  "viewport-options"
1953
2495
  ])) : (openBlock(), createElementBlock("div", {
@@ -1962,6 +2504,7 @@ var playground_default = /* @__PURE__ */ defineComponent({
1962
2504
  options: __props.options,
1963
2505
  "preview-options": __props.previewOptions,
1964
2506
  "preview-inset": __props.previewInset,
2507
+ expand: __props.expand,
1965
2508
  "active-view": activeView.value,
1966
2509
  views: normalizedViews.value,
1967
2510
  viewport: activeViewport.value,
@@ -1976,6 +2519,7 @@ var playground_default = /* @__PURE__ */ defineComponent({
1976
2519
  "options",
1977
2520
  "preview-options",
1978
2521
  "preview-inset",
2522
+ "expand",
1979
2523
  "active-view",
1980
2524
  "views",
1981
2525
  "viewport",