@poveste/app 0.13.0 → 0.14.0
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/bundled/App.vue_vue_type_script_setup_true_lang.js +26 -34
- package/dist/bundled/app.css +18 -24
- package/dist/bundled/components/HomeView.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/bundled/components/app/AppLogo.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/bundled/components/app/Breadcrumb.js +1 -1
- package/dist/bundled/components/app/Breadcrumb.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/bundled/components/app/TopBar.vue_vue_type_script_setup_true_lang.js +4 -3
- package/dist/bundled/components/base/BaseCheckbox.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/bundled/components/base/BaseListItemLink.js +6 -3
- package/dist/bundled/components/base/BaseListItemLink.vue_vue_type_script_lang.js +10 -4
- package/dist/bundled/components/base/BaseOverflowMenu.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/bundled/components/base/BaseOverflowTab.js +6 -3
- package/dist/bundled/components/base/BaseOverflowTab.vue_vue_type_script_lang.js +4 -0
- package/dist/bundled/components/base/BaseSplitPane.js +1 -1
- package/dist/bundled/components/base/BaseSplitPane.vue_vue_type_script_setup_true_lang.js +6 -4
- package/dist/bundled/components/base/BaseTab.js +6 -3
- package/dist/bundled/components/base/BaseTab.vue_vue_type_script_lang.js +4 -0
- package/dist/bundled/components/command/CommandPrompts.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/bundled/components/command/CommandPromptsModal.vue_vue_type_script_setup_true_lang.js +4 -3
- package/dist/bundled/components/command/PromptSelect.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/bundled/components/command/PromptText.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/bundled/components/panel/PaneTabs.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/bundled/components/panel/StatePresets.vue_vue_type_script_setup_true_lang.js +30 -20
- package/dist/bundled/components/panel/StoryControls.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/bundled/components/panel/StoryDocs.vue_vue_type_script_setup_true_lang.js +3 -1
- package/dist/bundled/components/panel/StoryEvent.vue_vue_type_script_setup_true_lang.js +5 -1
- package/dist/bundled/components/panel/StoryEvents.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/bundled/components/panel/StorySidePanel.vue_vue_type_script_setup_true_lang.js +7 -5
- package/dist/bundled/components/panel/StorySourceCode.js +1 -1
- package/dist/bundled/components/panel/StorySourceCode.vue_vue_type_script_setup_true_lang.js +6 -5
- package/dist/bundled/components/search/SearchPane.vue_vue_type_script_setup_true_lang.js +15 -7
- package/dist/bundled/components/story/GenericMountStory.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/bundled/components/story/GenericRenderStory.vue_vue_type_script_setup_true_lang.js +2 -1
- package/dist/bundled/components/story/StoryResponsivePreview.js +1 -1
- package/dist/bundled/components/story/StoryResponsivePreview.vue_vue_type_script_setup_true_lang.js +17 -6
- package/dist/bundled/components/story/StoryVariantGrid.js +1 -1
- package/dist/bundled/components/story/StoryVariantGrid.vue_vue_type_script_setup_true_lang.js +15 -10
- package/dist/bundled/components/story/StoryVariantSingle.js +1 -1
- package/dist/bundled/components/story/StoryVariantSingle.vue_vue_type_script_setup_true_lang.js +21 -33
- package/dist/bundled/components/story/StoryVariantSingleView.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/bundled/components/story/StoryView.vue_vue_type_script_setup_true_lang.js +3 -2
- package/dist/bundled/components/story/StoryViewer.js +1 -1
- package/dist/bundled/components/story/StoryViewer.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/bundled/components/toolbar/ToolbarBackground.js +1 -3
- package/dist/bundled/components/toolbar/ToolbarBackground.vue_vue_type_script_setup_true_lang.js +2 -6
- package/dist/bundled/components/toolbar/ToolbarResponsiveSize.vue_vue_type_script_setup_true_lang.js +17 -16
- package/dist/bundled/plugin.js +4 -3
- package/dist/bundled/sandbox.js +2 -2
- package/dist/bundled/stores/folder.js +1 -1
- package/dist/bundled/util/commands.js +20 -9
- package/dist/bundled/util/docs.js +2 -1
- package/dist/bundled/util/grid-slots.js +1 -1
- package/dist/bundled/util/highlighter.js +1 -1
- package/dist/bundled/util/icons.generated.js +0 -1
- package/dist/bundled/util/keyboard.js +1 -0
- package/dist/bundled/util/mapping.js +6 -2
- package/dist/bundled/util/preview-settings.js +1 -1
- package/dist/style.css +14 -2
- package/package.json +8 -6
- package/src/app/App.vue +36 -29
- package/src/app/components/HomeView.vue +1 -1
- package/src/app/components/app/AppLogo.vue +6 -2
- package/src/app/components/app/Breadcrumb.vue +2 -1
- package/src/app/components/app/TopBar.vue +7 -2
- package/src/app/components/base/BaseCheckbox.vue +1 -1
- package/src/app/components/base/BaseListItemLink.vue +12 -1
- package/src/app/components/base/BaseOverflowMenu.vue +9 -3
- package/src/app/components/base/BaseOverflowTab.vue +12 -1
- package/src/app/components/base/BaseSplitPane.vue +9 -4
- package/src/app/components/base/BaseTab.vue +12 -1
- package/src/app/components/command/CommandPrompts.vue +10 -2
- package/src/app/components/command/CommandPromptsModal.vue +1 -0
- package/src/app/components/command/PromptSelect.vue +2 -1
- package/src/app/components/command/PromptText.vue +7 -3
- package/src/app/components/panel/PaneTabs.vue +4 -4
- package/src/app/components/panel/StatePresets.vue +26 -5
- package/src/app/components/panel/StoryControls.vue +1 -1
- package/src/app/components/panel/StoryDocs.vue +3 -1
- package/src/app/components/panel/StoryEvent.vue +7 -2
- package/src/app/components/panel/StoryEvents.vue +4 -1
- package/src/app/components/panel/StorySidePanel.vue +2 -0
- package/src/app/components/panel/StorySourceCode.vue +11 -8
- package/src/app/components/search/SearchPane.vue +14 -5
- package/src/app/components/story/GenericMountStory.vue +2 -1
- package/src/app/components/story/GenericRenderStory.vue +2 -1
- package/src/app/components/story/StoryResponsivePreview.vue +30 -5
- package/src/app/components/story/StoryVariantGrid.vue +33 -16
- package/src/app/components/story/StoryVariantSingle.vue +44 -52
- package/src/app/components/story/StoryVariantSingleView.vue +1 -1
- package/src/app/components/story/StoryView.vue +7 -3
- package/src/app/components/story/StoryViewer.vue +3 -3
- package/src/app/components/toolbar/ToolbarBackground.vue +1 -8
- package/src/app/components/toolbar/ToolbarResponsiveSize.vue +23 -3
- package/src/app/components/tree/StoryGroup.vue +1 -1
- package/src/app/plugin.ts +7 -3
- package/src/app/sandbox.ts +1 -1
- package/src/app/stores/folder.ts +1 -1
- package/src/app/types.ts +2 -2
- package/src/app/util/commands.ts +26 -16
- package/src/app/util/docs.ts +2 -1
- package/src/app/util/grid-slots.ts +1 -1
- package/src/app/util/highlighter.ts +9 -1
- package/src/app/util/icons.generated.ts +1 -1
- package/src/app/util/keyboard.ts +3 -0
- package/src/app/util/mapping.ts +6 -2
- package/src/app/util/preview-settings.ts +1 -1
- package/src/app/util/scroll.ts +5 -1
- package/src/app/util/state.ts +1 -1
- package/src/app/util/variant.ts +4 -1
- package/src/app/components/base/BaseCopyIcon.vue +0 -34
|
@@ -27,7 +27,8 @@ var StoryView_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
|
|
|
27
27
|
const router = useRouter();
|
|
28
28
|
const route = useRoute();
|
|
29
29
|
watch(() => storyStore.currentVariant, (value) => {
|
|
30
|
-
|
|
30
|
+
const story = storyStore.currentStory;
|
|
31
|
+
if (value && story) story.lastSelectedVariant = value;
|
|
31
32
|
}, { immediate: true });
|
|
32
33
|
watch(() => [storyStore.currentStory, storyStore.currentVariant], () => {
|
|
33
34
|
if (!storyStore.currentVariant && autoSelectsVariant(storyStore.currentStory)) setVariant((storyStore.currentStory.lastSelectedVariant ?? storyStore.currentStory.variants[0]).id);
|
|
@@ -41,7 +42,7 @@ var StoryView_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
|
|
|
41
42
|
}
|
|
42
43
|
});
|
|
43
44
|
}
|
|
44
|
-
const docsOnlyScroller = ref(
|
|
45
|
+
const docsOnlyScroller = ref();
|
|
45
46
|
function scrollDocsToTop() {
|
|
46
47
|
docsOnlyScroller.value?.scrollTo(0, 0);
|
|
47
48
|
}
|
|
@@ -2,6 +2,6 @@ import _plugin_vue_export_helper_default from "../../_virtual/_plugin-vue_export
|
|
|
2
2
|
import StoryViewer_vue_vue_type_script_setup_true_lang_default from "./StoryViewer.vue_vue_type_script_setup_true_lang.js";
|
|
3
3
|
/* empty css */
|
|
4
4
|
//#region src/app/components/story/StoryViewer.vue
|
|
5
|
-
var StoryViewer_default = /*#__PURE__*/ _plugin_vue_export_helper_default(StoryViewer_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-
|
|
5
|
+
var StoryViewer_default = /*#__PURE__*/ _plugin_vue_export_helper_default(StoryViewer_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-5e1183de"]]);
|
|
6
6
|
//#endregion
|
|
7
7
|
export { StoryViewer_default as default };
|
|
@@ -9,7 +9,7 @@ var _hoisted_1 = { class: "poveste-story-viewer bg-gray-50 h-full dark:bg-gray-7
|
|
|
9
9
|
var StoryViewer_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
10
10
|
__name: "StoryViewer",
|
|
11
11
|
setup(__props) {
|
|
12
|
-
useCssVars((_ctx) => ({ "
|
|
12
|
+
useCssVars((_ctx) => ({ "v96d17610": variant.value?.iconColor }));
|
|
13
13
|
const storyStore = useStoryStore();
|
|
14
14
|
const variant = computed(() => storyStore.currentVariant);
|
|
15
15
|
const isMenuOpened = ref(false);
|
|
@@ -20,7 +20,7 @@ var StoryViewer_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defi
|
|
|
20
20
|
isMenuOpened.value = false;
|
|
21
21
|
});
|
|
22
22
|
return (_ctx, _cache) => {
|
|
23
|
-
return openBlock(), createElementBlock(Fragment, null, [createElementVNode("div", _hoisted_1, [unref(storyStore).currentStory
|
|
23
|
+
return openBlock(), createElementBlock(Fragment, null, [createElementVNode("div", _hoisted_1, [unref(storyStore).currentStory?.layout?.type === "grid" ? (openBlock(), createBlock(StoryVariantGrid_default, { key: 0 })) : unref(storyStore).currentStory?.layout?.type === "single" ? (openBlock(), createBlock(StoryVariantSingle_default, {
|
|
24
24
|
key: 1,
|
|
25
25
|
onOpenVariantMenu: _cache[0] || (_cache[0] = ($event) => isMenuOpened.value = true)
|
|
26
26
|
})) : createCommentVNode("", true)]), createVNode(MobileOverlay_default, {
|
|
@@ -28,7 +28,7 @@ var StoryViewer_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defi
|
|
|
28
28
|
opened: isMenuOpened.value,
|
|
29
29
|
onClose: closeMenu
|
|
30
30
|
}, {
|
|
31
|
-
default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(storyStore).currentStory
|
|
31
|
+
default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(unref(storyStore).currentStory?.variants ?? [], (v, index) => {
|
|
32
32
|
return openBlock(), createBlock(StoryVariantListItem_default, {
|
|
33
33
|
key: index,
|
|
34
34
|
variant: v
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import _plugin_vue_export_helper_default from "../../_virtual/_plugin-vue_export-helper.js";
|
|
2
1
|
import ToolbarBackground_vue_vue_type_script_setup_true_lang_default from "./ToolbarBackground.vue_vue_type_script_setup_true_lang.js";
|
|
3
|
-
/* empty css */
|
|
4
2
|
//#region src/app/components/toolbar/ToolbarBackground.vue
|
|
5
|
-
var ToolbarBackground_default =
|
|
3
|
+
var ToolbarBackground_default = ToolbarBackground_vue_vue_type_script_setup_true_lang_default;
|
|
6
4
|
//#endregion
|
|
7
5
|
export { ToolbarBackground_default as default };
|
package/dist/bundled/components/toolbar/ToolbarBackground.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { povesteConfig } from "../../util/config.js";
|
|
2
2
|
import { usePreviewSettingsStore } from "../../stores/preview-settings.js";
|
|
3
3
|
import BaseCheckbox_default from "../base/BaseCheckbox.js";
|
|
4
|
-
import { Fragment, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, normalizeStyle, openBlock, renderList, resolveComponent, resolveDirective, toDisplayString, unref,
|
|
4
|
+
import { Fragment, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, normalizeStyle, openBlock, renderList, resolveComponent, resolveDirective, toDisplayString, unref, withCtx, withDirectives } from "@poveste/vendors/vue";
|
|
5
5
|
import { Icon } from "@poveste/vendors/iconify";
|
|
6
6
|
//#region src/app/components/toolbar/ToolbarBackground.vue?vue&type=script&setup=true&lang.ts
|
|
7
7
|
var _hoisted_1 = { class: "flex items-center gap-1 px-2.5 py-1.5 hover:bg-white/50 dark:hover:bg-white/10 hover:text-primary-500 dark:hover:text-primary-400 cursor-pointer text-gray-900 dark:text-gray-100 transition-colors group" };
|
|
@@ -22,10 +22,6 @@ var _hoisted_8 = { key: 0 };
|
|
|
22
22
|
var ToolbarBackground_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
23
23
|
__name: "ToolbarBackground",
|
|
24
24
|
setup(__props) {
|
|
25
|
-
useCssVars((_ctx) => ({
|
|
26
|
-
"ca113a48": unref(settings).backgroundColor,
|
|
27
|
-
"v0083f4ef": _ctx.contrastColor
|
|
28
|
-
}));
|
|
29
25
|
const previewSettings = usePreviewSettingsStore();
|
|
30
26
|
const settings = previewSettings.currentSettings;
|
|
31
27
|
const colorSchemeOptions = [
|
|
@@ -46,7 +42,7 @@ var ToolbarBackground_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*
|
|
|
46
42
|
}
|
|
47
43
|
];
|
|
48
44
|
const showColorScheme = !povesteConfig.theme.hideColorSchemeSwitch;
|
|
49
|
-
const showDropdown = showColorScheme || !!povesteConfig.backgroundPresets
|
|
45
|
+
const showDropdown = showColorScheme || !!povesteConfig.backgroundPresets?.length;
|
|
50
46
|
return (_ctx, _cache) => {
|
|
51
47
|
const _component_VDropdown = resolveComponent("VDropdown");
|
|
52
48
|
const _directive_tooltip = resolveDirective("tooltip");
|
package/dist/bundled/components/toolbar/ToolbarResponsiveSize.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { povesteConfig } from "../../util/config.js";
|
|
2
2
|
import { usePreviewSettingsStore } from "../../stores/preview-settings.js";
|
|
3
3
|
import BaseCheckbox_default from "../base/BaseCheckbox.js";
|
|
4
|
-
import { Fragment, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, openBlock, renderList, resolveComponent, resolveDirective, toDisplayString, unref, vModelText, withCtx, withDirectives } from "@poveste/vendors/vue";
|
|
4
|
+
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, isRef, normalizeClass, openBlock, renderList, resolveComponent, resolveDirective, toDisplayString, unref, vModelText, withCtx, withDirectives } from "@poveste/vendors/vue";
|
|
5
5
|
import { Icon } from "@poveste/vendors/iconify";
|
|
6
6
|
//#region src/app/components/toolbar/ToolbarResponsiveSize.vue?vue&type=script&setup=true&lang.ts
|
|
7
7
|
var _hoisted_1 = { class: "flex flex-col items-stretch" };
|
|
@@ -17,6 +17,17 @@ var ToolbarResponsiveSize_vue_vue_type_script_setup_true_lang_default = /*@__PUR
|
|
|
17
17
|
__name: "ToolbarResponsiveSize",
|
|
18
18
|
setup(__props) {
|
|
19
19
|
const settings = usePreviewSettingsStore().currentSettings;
|
|
20
|
+
function autoWhenEmpty(key) {
|
|
21
|
+
return computed({
|
|
22
|
+
get: () => settings[key],
|
|
23
|
+
set: (value) => {
|
|
24
|
+
const parsed = typeof value === "number" ? value : Number.parseFloat(value ?? "");
|
|
25
|
+
settings[key] = Number.isFinite(parsed) ? parsed : null;
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
const responsiveWidth = autoWhenEmpty("responsiveWidth");
|
|
30
|
+
const responsiveHeight = autoWhenEmpty("responsiveHeight");
|
|
20
31
|
return (_ctx, _cache) => {
|
|
21
32
|
const _component_VDropdown = resolveComponent("VDropdown");
|
|
22
33
|
const _directive_tooltip = resolveDirective("tooltip");
|
|
@@ -36,30 +47,20 @@ var ToolbarResponsiveSize_vue_vue_type_script_setup_true_lang_default = /*@__PUR
|
|
|
36
47
|
}, 8, ["modelValue"]),
|
|
37
48
|
createElementVNode("div", _hoisted_2, [
|
|
38
49
|
withDirectives(createElementVNode("input", {
|
|
39
|
-
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) =>
|
|
50
|
+
"onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => isRef(responsiveWidth) ? responsiveWidth.value = $event : null),
|
|
40
51
|
type: "number",
|
|
41
52
|
class: "bg-transparent border border-gray-200 dark:border-gray-850 rounded w-20 opacity-50 focus:opacity-100 flex-1 min-w-0",
|
|
42
53
|
step: "16",
|
|
43
54
|
placeholder: "Auto"
|
|
44
|
-
}, null, 512), [[
|
|
45
|
-
vModelText,
|
|
46
|
-
unref(settings).responsiveWidth,
|
|
47
|
-
void 0,
|
|
48
|
-
{ number: true }
|
|
49
|
-
], [_directive_tooltip, "Responsive width (px)"]]),
|
|
55
|
+
}, null, 512), [[vModelText, unref(responsiveWidth)], [_directive_tooltip, "Responsive width (px)"]]),
|
|
50
56
|
_cache[4] || (_cache[4] = createElementVNode("span", { class: "opacity-50" }, "×", -1)),
|
|
51
57
|
withDirectives(createElementVNode("input", {
|
|
52
|
-
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) =>
|
|
58
|
+
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => isRef(responsiveHeight) ? responsiveHeight.value = $event : null),
|
|
53
59
|
type: "number",
|
|
54
60
|
class: "bg-transparent border border-gray-200 dark:border-gray-850 rounded w-20 opacity-50 focus:opacity-100 flex-1 min-w-0",
|
|
55
61
|
step: "16",
|
|
56
62
|
placeholder: "Auto"
|
|
57
|
-
}, null, 512), [[
|
|
58
|
-
vModelText,
|
|
59
|
-
unref(settings).responsiveHeight,
|
|
60
|
-
void 0,
|
|
61
|
-
{ number: true }
|
|
62
|
-
], [_directive_tooltip, "Responsive height (px)"]])
|
|
63
|
+
}, null, 512), [[vModelText, unref(responsiveHeight)], [_directive_tooltip, "Responsive height (px)"]])
|
|
63
64
|
]),
|
|
64
65
|
(openBlock(true), createElementBlock(Fragment, null, renderList(unref(povesteConfig).responsivePresets, (preset, index) => {
|
|
65
66
|
return openBlock(), createElementBlock("button", {
|
|
@@ -67,7 +68,7 @@ var ToolbarResponsiveSize_vue_vue_type_script_setup_true_lang_default = /*@__PUR
|
|
|
67
68
|
class: normalizeClass(["px-4 py-3 cursor-pointer text-left flex gap-4", [unref(settings).responsiveWidth === preset.width && unref(settings).responsiveHeight === preset.height ? "bg-primary-500 hover:bg-primary-600 text-white dark:text-black" : "bg-transparent hover:bg-primary-100 dark:hover:bg-primary-700"]]),
|
|
68
69
|
onClick: ($event) => {
|
|
69
70
|
unref(settings).responsiveWidth = preset.width;
|
|
70
|
-
unref(settings).responsiveHeight = preset.height;
|
|
71
|
+
unref(settings).responsiveHeight = preset.height ?? null;
|
|
71
72
|
hide();
|
|
72
73
|
}
|
|
73
74
|
}, [createTextVNode(toDisplayString(preset.label) + " ", 1), createElementVNode("span", _hoisted_4, [
|
package/dist/bundled/plugin.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { router } from "./router.js";
|
|
2
2
|
//#region src/app/plugin.ts
|
|
3
3
|
function setupPluginApi() {
|
|
4
|
-
|
|
4
|
+
const hot = import.meta.hot;
|
|
5
|
+
if (!hot) return;
|
|
5
6
|
const listeners = {};
|
|
6
|
-
|
|
7
|
+
hot.on("poveste:dev-event-result", ({ event, result }) => {
|
|
7
8
|
const set = listeners[event];
|
|
8
9
|
if (set) for (const listener of set) listener(result);
|
|
9
10
|
});
|
|
@@ -21,7 +22,7 @@ function setupPluginApi() {
|
|
|
21
22
|
window.__HST_PLUGIN_API__ = {
|
|
22
23
|
sendEvent: (event, payload) => {
|
|
23
24
|
return new Promise((resolve) => {
|
|
24
|
-
|
|
25
|
+
hot.send(`poveste:dev-event`, {
|
|
25
26
|
event,
|
|
26
27
|
payload
|
|
27
28
|
});
|
package/dist/bundled/sandbox.js
CHANGED
|
@@ -38,8 +38,8 @@ if (storedSettings) applyPreviewSettings(storedSettings);
|
|
|
38
38
|
if (window.parent && window.parent !== window) window.parent.postMessage({ type: PREVIEW_SETTINGS_REQUEST }, window.location.origin);
|
|
39
39
|
function reportUncaught(error) {
|
|
40
40
|
reportStoryError(error, {
|
|
41
|
-
storyId: storyId.value,
|
|
42
|
-
variantId: variantId.value
|
|
41
|
+
storyId: storyId.value ?? void 0,
|
|
42
|
+
variantId: variantId.value ?? void 0
|
|
43
43
|
});
|
|
44
44
|
}
|
|
45
45
|
window.addEventListener("error", (event) => {
|
|
@@ -29,7 +29,7 @@ var useFolderStore = defineStore("folder", () => {
|
|
|
29
29
|
}
|
|
30
30
|
const storyStore = useStoryStore();
|
|
31
31
|
watch(() => storyStore.currentStory, (story) => {
|
|
32
|
-
if (story) openFileFolders(story.file.path);
|
|
32
|
+
if (story?.file) openFileFolders(story.file.path);
|
|
33
33
|
});
|
|
34
34
|
return {
|
|
35
35
|
isFolderOpened,
|
|
@@ -2,20 +2,31 @@ import { router } from "../router.js";
|
|
|
2
2
|
import { useStoryStore } from "../stores/story.js";
|
|
3
3
|
import { openInEditor } from "./open-in-editor.js";
|
|
4
4
|
//#region src/app/util/commands.ts
|
|
5
|
+
/**
|
|
6
|
+
* The path "Open file in editor" should open, or undefined when there is none.
|
|
7
|
+
*
|
|
8
|
+
* `Story.file` is optional, and `let file: string` used to be assigned
|
|
9
|
+
* `story.file?.filePath` in both branches — so a story without a file produced
|
|
10
|
+
* `file: undefined`, and `openInEditor` sent
|
|
11
|
+
* `__open-in-editor?file=undefined` to the dev server: a request to open a file
|
|
12
|
+
* literally named "undefined", with nothing said in the UI (#667).
|
|
13
|
+
*
|
|
14
|
+
* A docs-only story prefers its markdown, falling back to the component file
|
|
15
|
+
* when the story has both.
|
|
16
|
+
*/
|
|
17
|
+
function editableFilePath(story) {
|
|
18
|
+
const file = story?.file;
|
|
19
|
+
if (!file) return void 0;
|
|
20
|
+
return story?.docsOnly ? file.docsFilePath ?? file.filePath : file.filePath;
|
|
21
|
+
}
|
|
5
22
|
var builtinCommands = [{
|
|
6
23
|
id: "builtin:open-in-editor",
|
|
7
24
|
label: "Open file in editor",
|
|
8
25
|
icon: "carbon:script-reference",
|
|
9
|
-
showIf: ({ route }) => route.name === "story" && !!useStoryStore().currentStory,
|
|
10
|
-
getParams: () => {
|
|
11
|
-
const story = useStoryStore().currentStory;
|
|
12
|
-
let file;
|
|
13
|
-
if (story.docsOnly) file = story.file?.docsFilePath ?? story.file?.filePath;
|
|
14
|
-
else file = story.file?.filePath;
|
|
15
|
-
return { file };
|
|
16
|
-
},
|
|
26
|
+
showIf: ({ route }) => route.name === "story" && !!editableFilePath(useStoryStore().currentStory),
|
|
27
|
+
getParams: () => ({ file: editableFilePath(useStoryStore().currentStory) }),
|
|
17
28
|
clientAction: ({ file }) => {
|
|
18
|
-
openInEditor(file);
|
|
29
|
+
if (file) openInEditor(file);
|
|
19
30
|
}
|
|
20
31
|
}, {
|
|
21
32
|
id: "builtin:poveste-docs",
|
|
@@ -7,7 +7,8 @@ async function getSourceCode(story, variant) {
|
|
|
7
7
|
const source = variant.slots?.().source()[0].children;
|
|
8
8
|
if (source) return unindent(source);
|
|
9
9
|
} else {
|
|
10
|
-
const
|
|
10
|
+
const supportPluginId = story.file?.supportPluginId;
|
|
11
|
+
const clientPlugin = supportPluginId ? clientSupportPlugins[supportPluginId] : void 0;
|
|
11
12
|
if (clientPlugin) return (await clientPlugin()).generateSourceCode(variant);
|
|
12
13
|
}
|
|
13
14
|
const sourceLoader = story.file?.source;
|
|
@@ -11,7 +11,7 @@ function assignSlots(slots, storyId, visible) {
|
|
|
11
11
|
const next = slots.map((slot) => slot.storyId === storyId && position.has(slot.variant.id) ? {
|
|
12
12
|
...slot,
|
|
13
13
|
visible: true,
|
|
14
|
-
order: position.get(slot.variant.id)
|
|
14
|
+
order: position.get(slot.variant.id) ?? 0
|
|
15
15
|
} : {
|
|
16
16
|
...slot,
|
|
17
17
|
visible: false,
|
|
@@ -18,7 +18,7 @@ var highlighterPromise;
|
|
|
18
18
|
function getHighlighter() {
|
|
19
19
|
highlighterPromise ??= createHighlighterCore({
|
|
20
20
|
langs: [import("shiki/langs/html.mjs"), import("shiki/langs/jsx.mjs")],
|
|
21
|
-
themes: [import("shiki/themes/github-light.mjs"), import("shiki/themes/github-dark.mjs")],
|
|
21
|
+
themes: [import("shiki/themes/github-light-high-contrast.mjs"), import("shiki/themes/github-dark.mjs")],
|
|
22
22
|
engine: createOnigurumaEngine(import("shiki/wasm"))
|
|
23
23
|
}).catch((e) => {
|
|
24
24
|
highlighterPromise = void 0;
|
|
@@ -6,7 +6,6 @@ var iconCollections = [
|
|
|
6
6
|
"add-alt": { "body": "<path fill=\"currentColor\" d=\"M16 4c6.6 0 12 5.4 12 12s-5.4 12-12 12S4 22.6 4 16S9.4 4 16 4m0-2C8.3 2 2 8.3 2 16s6.3 14 14 14s14-6.3 14-14S23.7 2 16 2\"/><path fill=\"currentColor\" d=\"M24 15h-7V8h-2v7H8v2h7v7h2v-7h7z\"/>" },
|
|
7
7
|
"area": { "body": "<path fill=\"currentColor\" d=\"M27 22.142V9.858A3.992 3.992 0 1 0 22.142 5H9.858A3.992 3.992 0 1 0 5 9.858v12.284A3.992 3.992 0 1 0 9.858 27h12.284A3.992 3.992 0 1 0 27 22.142M26 4a2 2 0 1 1-2 2a2 2 0 0 1 2-2M4 6a2 2 0 1 1 2 2a2 2 0 0 1-2-2m2 22a2 2 0 1 1 2-2a2 2 0 0 1-2 2m16.142-3H9.858A4 4 0 0 0 7 22.142V9.858A4 4 0 0 0 9.858 7h12.284A4 4 0 0 0 25 9.858v12.284A3.99 3.99 0 0 0 22.142 25M26 28a2 2 0 1 1 2-2a2.003 2.003 0 0 1-2 2\"/>" },
|
|
8
8
|
"audio-console": { "body": "<path fill=\"currentColor\" d=\"M28 14.005h-1v-12h-2v12h-1a2 2 0 0 0-2 2v2a2 2 0 0 0 2 2h1v10h2v-10h1a2.003 2.003 0 0 0 2-2v-2a2 2 0 0 0-2-2m0 4h-4v-2h4Zm-10-12h-1v-4h-2v4h-1a2 2 0 0 0-2 2v2a2 2 0 0 0 2 2h1v18h2v-18h1a2 2 0 0 0 2-2v-2a2 2 0 0 0-2-2m0 4h-4v-2h4Zm-10 10H7v-18H5v18H4a2 2 0 0 0-2 2v2a2 2 0 0 0 2 2h1v4h2v-4h1a2 2 0 0 0 2-2v-2a2 2 0 0 0-2-2m0 4H4v-2h4Z\"/>" },
|
|
9
|
-
"bring-forward": { "body": "<path fill=\"currentColor\" d=\"M12 15h-2v-3a2 2 0 0 1 2-2h3v2h-3Zm3 15h-3a2 2 0 0 1-2-2v-3h2v3h3Zm3-2h4v2h-4zm10 2h-3v-2h3v-3h2v3a2 2 0 0 1-2 2M10 18h2v4h-2zm18 0h2v4h-2zm2-3h-2v-3h-3v-2h3a2 2 0 0 1 2 2Zm-12-5h4v2h-4z\"/><path fill=\"currentColor\" d=\"M8 22H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v4h-2V4H4v16h4Z\"/>" },
|
|
10
9
|
"caret-down": { "body": "<path fill=\"currentColor\" d=\"m24 12l-8 10l-8-10z\"/>" },
|
|
11
10
|
"caret-right": { "body": "<path fill=\"currentColor\" d=\"m12 8l10 8l-10 8z\"/>" },
|
|
12
11
|
"checkbox": { "body": "<path fill=\"currentColor\" d=\"M26 4H6a2 2 0 0 0-2 2v20a2 2 0 0 0 2 2h20a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2M6 26V6h20v20Z\"/>" },
|
|
@@ -88,6 +88,7 @@ function isMatchingShortcut(shortcut) {
|
|
|
88
88
|
function isMatchingCombination(combination) {
|
|
89
89
|
const splitted = combination.split("+").map((key) => key.trim());
|
|
90
90
|
const targetKey = splitted.pop();
|
|
91
|
+
if (!targetKey) return false;
|
|
91
92
|
for (const mod in modifiers) if (splitted.includes(mod) !== modifiers[mod].pressed) return false;
|
|
92
93
|
return pressedKeys.has(targetKey);
|
|
93
94
|
}
|
|
@@ -45,8 +45,12 @@ function mapVariant(variant, existingVariant) {
|
|
|
45
45
|
_hPropState: {},
|
|
46
46
|
_hPropDefs: {}
|
|
47
47
|
}),
|
|
48
|
-
setupApp:
|
|
49
|
-
slots: () => ({
|
|
48
|
+
setupApp: void 0,
|
|
49
|
+
slots: () => ({
|
|
50
|
+
default: void 0,
|
|
51
|
+
controls: void 0,
|
|
52
|
+
source: void 0
|
|
53
|
+
}),
|
|
50
54
|
previewReady: false
|
|
51
55
|
};
|
|
52
56
|
return result;
|
|
@@ -24,7 +24,7 @@ function applyPreviewSettings(settings) {
|
|
|
24
24
|
if (povesteConfig.autoApplyContrastColor) document.documentElement.style.color = contrastColor;
|
|
25
25
|
}
|
|
26
26
|
function getContrastColor(setting) {
|
|
27
|
-
return povesteConfig.backgroundPresets
|
|
27
|
+
return povesteConfig.backgroundPresets?.find((preset) => preset.color === setting.backgroundColor)?.contrastColor ?? "unset";
|
|
28
28
|
}
|
|
29
29
|
//#endregion
|
|
30
30
|
export { PREVIEW_SETTINGS_STORAGE_KEY, applyPreviewSettings, getContrastColor, loadStoredPreviewSettings, receivedSettings };
|
package/dist/style.css
CHANGED
|
@@ -1625,6 +1625,9 @@
|
|
|
1625
1625
|
background-color: color-mix(in oklab, var(--color-primary-500) 25%, transparent);
|
|
1626
1626
|
}
|
|
1627
1627
|
}
|
|
1628
|
+
.bg-primary-700 {
|
|
1629
|
+
background-color: var(--color-primary-700);
|
|
1630
|
+
}
|
|
1628
1631
|
.bg-transparent {
|
|
1629
1632
|
background-color: transparent;
|
|
1630
1633
|
}
|
|
@@ -1861,8 +1864,8 @@
|
|
|
1861
1864
|
.text-primary-500 {
|
|
1862
1865
|
color: var(--color-primary-500);
|
|
1863
1866
|
}
|
|
1864
|
-
.text-primary-
|
|
1865
|
-
color: var(--color-primary-
|
|
1867
|
+
.text-primary-700 {
|
|
1868
|
+
color: var(--color-primary-700);
|
|
1866
1869
|
}
|
|
1867
1870
|
.text-primary-800 {
|
|
1868
1871
|
color: var(--color-primary-800);
|
|
@@ -2130,6 +2133,9 @@
|
|
|
2130
2133
|
.hover\:bg-primary-600:hover {
|
|
2131
2134
|
background-color: var(--color-primary-600);
|
|
2132
2135
|
}
|
|
2136
|
+
.hover\:bg-primary-800:hover {
|
|
2137
|
+
background-color: var(--color-primary-800);
|
|
2138
|
+
}
|
|
2133
2139
|
.hover\:bg-white\/50:hover {
|
|
2134
2140
|
background-color: color-mix(in srgb, #fff 50%, transparent);
|
|
2135
2141
|
}
|
|
@@ -2288,6 +2294,9 @@
|
|
|
2288
2294
|
.dark\:bg-primary-400:where(.ptw-dark, .ptw-dark *) {
|
|
2289
2295
|
background-color: var(--color-primary-400);
|
|
2290
2296
|
}
|
|
2297
|
+
.dark\:bg-primary-500:where(.ptw-dark, .ptw-dark *) {
|
|
2298
|
+
background-color: var(--color-primary-500);
|
|
2299
|
+
}
|
|
2291
2300
|
.dark\:bg-primary-600:where(.ptw-dark, .ptw-dark *) {
|
|
2292
2301
|
background-color: var(--color-primary-600);
|
|
2293
2302
|
}
|
|
@@ -2385,6 +2394,9 @@
|
|
|
2385
2394
|
.dark\:hover\:bg-gray-800:where(.ptw-dark, .ptw-dark *):hover {
|
|
2386
2395
|
background-color: var(--color-gray-800);
|
|
2387
2396
|
}
|
|
2397
|
+
.dark\:hover\:bg-primary-600:where(.ptw-dark, .ptw-dark *):hover {
|
|
2398
|
+
background-color: var(--color-primary-600);
|
|
2399
|
+
}
|
|
2388
2400
|
.dark\:hover\:bg-primary-700:where(.ptw-dark, .ptw-dark *):hover {
|
|
2389
2401
|
background-color: var(--color-primary-700);
|
|
2390
2402
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poveste/app",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.14.0",
|
|
5
5
|
"description": "Pre-bundled UI for Poveste",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Sorin Gitlan",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"node": "^22.22.2 || ^24.15.0 || >=26.0.0"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@poveste/controls": "^0.
|
|
42
|
-
"@poveste/shared": "^0.
|
|
43
|
-
"@poveste/vendors": "^0.
|
|
41
|
+
"@poveste/controls": "^0.14.0",
|
|
42
|
+
"@poveste/shared": "^0.14.0",
|
|
43
|
+
"@poveste/vendors": "^0.14.0",
|
|
44
44
|
"fuse.js": "^7.0.0",
|
|
45
45
|
"shiki": "^3.0.0"
|
|
46
46
|
},
|
|
@@ -66,11 +66,13 @@
|
|
|
66
66
|
"tailwindcss": "^4.3.3",
|
|
67
67
|
"typescript": "5.6.3",
|
|
68
68
|
"vite": "^8.2.0",
|
|
69
|
-
"vitest": "^
|
|
70
|
-
"vue": "^3.5.26"
|
|
69
|
+
"vitest": "^5.0.0",
|
|
70
|
+
"vue": "^3.5.26",
|
|
71
|
+
"vue-tsc": "^2.1.10"
|
|
71
72
|
},
|
|
72
73
|
"scripts": {
|
|
73
74
|
"build": "pnpm run icons && rimraf dist && vite build && pnpm run build:css && node ./scripts/copy.mjs",
|
|
75
|
+
"typecheck": "vue-tsc --noEmit",
|
|
74
76
|
"build:css": "postcss src/app/style/main.pcss -o ./dist/style.css",
|
|
75
77
|
"icons": "node ./scripts/icons.mjs",
|
|
76
78
|
"test": "vitest run",
|
package/src/app/App.vue
CHANGED
|
@@ -5,7 +5,7 @@ export default {
|
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<script lang="ts" setup>
|
|
8
|
-
import type { StoryFile, Tree } from './types'
|
|
8
|
+
import type { Story, StoryFile, Tree } from './types'
|
|
9
9
|
import { useTitle } from '@vueuse/core'
|
|
10
10
|
import { onUpdate, files as rawFiles, tree as rawTree } from 'virtual:$poveste-stories'
|
|
11
11
|
import { computed, onMounted, ref, watch } from 'vue'
|
|
@@ -41,8 +41,11 @@ onUpdate((newFiles: StoryFile[], newTree: Tree) => {
|
|
|
41
41
|
tree.value = newTree
|
|
42
42
|
})
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
// The accumulator needs a type: `[]` alone infers `never[]`, so the push was an
|
|
45
|
+
// error about the seed rather than about the story. A file whose story has not
|
|
46
|
+
// been collected yet contributes nothing.
|
|
47
|
+
const stories = computed(() => files.value.reduce<Story[]>((acc, file) => {
|
|
48
|
+
if (file.story) acc.push(file.story)
|
|
46
49
|
return acc
|
|
47
50
|
}, []))
|
|
48
51
|
|
|
@@ -141,52 +144,55 @@ const storyListVisible = computed(() => !!layoutStore.settings.storyListVisible)
|
|
|
141
144
|
}"
|
|
142
145
|
>
|
|
143
146
|
<div
|
|
144
|
-
|
|
145
|
-
class="
|
|
147
|
+
class="h-full flex flex-col"
|
|
148
|
+
:class="{ 'divide-y divide-gray-100 dark:divide-gray-800': isMobile }"
|
|
146
149
|
>
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
<!--
|
|
151
|
+
The mobile chrome is a sibling of `main`, not a child: `AppHeader`
|
|
152
|
+
carries the page's banner and its only `h1`, and a `header` inside
|
|
153
|
+
`main` is neither (#310).
|
|
154
|
+
-->
|
|
155
|
+
<template v-if="isMobile">
|
|
156
|
+
<div class="flex items-center gap-2 pr-4">
|
|
157
|
+
<AppHeader class="flex-1" />
|
|
158
|
+
<AppActions
|
|
159
|
+
class="flex-none"
|
|
160
|
+
@layout="isLayoutOpen = true"
|
|
161
|
+
@search="isSearchOpen = true"
|
|
162
|
+
/>
|
|
163
|
+
</div>
|
|
164
|
+
<Breadcrumb
|
|
165
|
+
:tree="tree"
|
|
166
|
+
:stories="stories"
|
|
153
167
|
/>
|
|
154
|
-
</
|
|
155
|
-
<Breadcrumb
|
|
156
|
-
:tree="tree"
|
|
157
|
-
:stories="stories"
|
|
158
|
-
/>
|
|
159
|
-
<main class="grow flex flex-col min-h-0">
|
|
160
|
-
<RouterView class="grow" />
|
|
161
|
-
</main>
|
|
162
|
-
</div>
|
|
168
|
+
</template>
|
|
163
169
|
|
|
164
|
-
<template v-else>
|
|
165
170
|
<!--
|
|
166
171
|
With the story list hidden `AppHeader` goes with it, taking the page's
|
|
167
172
|
only `h1` and its banner. A heading has to exist in every layout, and
|
|
168
173
|
it has to sit inside a landmark, so this stands in for it (#310).
|
|
169
174
|
-->
|
|
170
175
|
<header
|
|
171
|
-
v-if="!storyListVisible"
|
|
176
|
+
v-else-if="!storyListVisible"
|
|
172
177
|
class="sr-only"
|
|
173
178
|
>
|
|
174
179
|
<h1>{{ povesteConfig.theme?.title ?? 'Poveste' }}</h1>
|
|
175
180
|
</header>
|
|
176
181
|
|
|
177
182
|
<!--
|
|
178
|
-
One split pane
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
183
|
+
One split pane for every layout, mobile included. Each chrome used to
|
|
184
|
+
be a branch carrying its own `RouterView`, so switching between them
|
|
185
|
+
moved the routed view in the tree and cold-booted the sandbox under
|
|
186
|
+
it. The settings toggles were #596; `isMobile` is a live media query,
|
|
187
|
+
so this one fired on a window resize (#600).
|
|
182
188
|
-->
|
|
183
189
|
<BaseSplitPane
|
|
184
190
|
save-id="main-horiz"
|
|
185
191
|
:min="5"
|
|
186
192
|
:max="50"
|
|
187
193
|
:default-split="15"
|
|
188
|
-
:show-first="storyListVisible"
|
|
189
|
-
class="h-
|
|
194
|
+
:show-first="!isMobile && storyListVisible"
|
|
195
|
+
class="flex-1 min-h-0"
|
|
190
196
|
>
|
|
191
197
|
<template #first>
|
|
192
198
|
<div class="flex flex-col h-full bg-gray-100 dark:bg-gray-750 __poveste-pane-shadow-from-right">
|
|
@@ -207,6 +213,7 @@ const storyListVisible = computed(() => !!layoutStore.settings.storyListVisible)
|
|
|
207
213
|
<template #last>
|
|
208
214
|
<main class="flex flex-col h-full">
|
|
209
215
|
<TopBar
|
|
216
|
+
v-if="!isMobile"
|
|
210
217
|
@layout="isLayoutOpen = true"
|
|
211
218
|
@search="isSearchOpen = true"
|
|
212
219
|
/>
|
|
@@ -214,7 +221,7 @@ const storyListVisible = computed(() => !!layoutStore.settings.storyListVisible)
|
|
|
214
221
|
</main>
|
|
215
222
|
</template>
|
|
216
223
|
</BaseSplitPane>
|
|
217
|
-
</
|
|
224
|
+
</div>
|
|
218
225
|
|
|
219
226
|
<LayoutModal
|
|
220
227
|
v-if="!isMobile"
|
|
@@ -5,7 +5,7 @@ import { useStoryStore } from '../stores/story'
|
|
|
5
5
|
import { customLogos, povesteConfig } from '../util/config'
|
|
6
6
|
import HomeCounter from './app/HomeCounter.vue'
|
|
7
7
|
|
|
8
|
-
const logoUrl = computed(() => povesteConfig.theme?.logo?.square ? customLogos
|
|
8
|
+
const logoUrl = computed(() => povesteConfig.theme?.logo?.square ? customLogos?.square ?? PovesteLogo : PovesteLogo)
|
|
9
9
|
const storyStore = useStoryStore()
|
|
10
10
|
|
|
11
11
|
const stats = computed(() => {
|
|
@@ -6,11 +6,15 @@ import PovesteLogoLight from '../../assets/poveste-text.svg'
|
|
|
6
6
|
import { customLogos, povesteConfig } from '../../util/config'
|
|
7
7
|
import { isDark } from '../../util/dark'
|
|
8
8
|
|
|
9
|
+
// `theme.logo` is what the config asked for; `customLogos` is the resolved URL
|
|
10
|
+
// map from the virtual module. Two objects, so a check on one narrows nothing
|
|
11
|
+
// about the other — and falling back to the bundled logo beats rendering an
|
|
12
|
+
// `<img>` with no `src` if they ever disagree.
|
|
9
13
|
const logoUrl = computed(() => {
|
|
10
14
|
if (isDark.value) {
|
|
11
|
-
return povesteConfig.theme.logo?.dark ? customLogos
|
|
15
|
+
return povesteConfig.theme.logo?.dark ? customLogos?.dark ?? PovesteLogoDark : PovesteLogoDark
|
|
12
16
|
}
|
|
13
|
-
return povesteConfig.theme.logo?.light ? customLogos
|
|
17
|
+
return povesteConfig.theme.logo?.light ? customLogos?.light ?? PovesteLogoLight : PovesteLogoLight
|
|
14
18
|
})
|
|
15
19
|
|
|
16
20
|
const altText = computed(() => `${povesteConfig.theme.title} logo`)
|
|
@@ -16,7 +16,8 @@ const storyStore = useStoryStore()
|
|
|
16
16
|
const story = computed(() => storyStore.currentStory)
|
|
17
17
|
|
|
18
18
|
const folders = computed(() => {
|
|
19
|
-
|
|
19
|
+
// No story, or a story with no file behind it, means no trail to draw.
|
|
20
|
+
return story.value?.file?.path.slice(0, -1) ?? []
|
|
20
21
|
})
|
|
21
22
|
|
|
22
23
|
const isMenuOpened = ref(false)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
+
import { computed } from 'vue'
|
|
2
3
|
import { useStoryStore } from '../../stores/story'
|
|
3
4
|
import DevOnlyToolbarOpenInEditor from '../toolbar/DevOnlyToolbarOpenInEditor.vue'
|
|
4
5
|
import ToolbarBackground from '../toolbar/ToolbarBackground.vue'
|
|
@@ -15,6 +16,10 @@ defineEmits({
|
|
|
15
16
|
})
|
|
16
17
|
|
|
17
18
|
const storyStore = useStoryStore()
|
|
19
|
+
|
|
20
|
+
// Named once so the `v-if` and the binding below read the same value; a story
|
|
21
|
+
// without a file has nothing to open.
|
|
22
|
+
const editableFile = computed(() => storyStore.currentStory?.file?.filePath)
|
|
18
23
|
</script>
|
|
19
24
|
|
|
20
25
|
<template>
|
|
@@ -51,8 +56,8 @@ const storyStore = useStoryStore()
|
|
|
51
56
|
:story="storyStore.currentStory"
|
|
52
57
|
/>
|
|
53
58
|
<DevOnlyToolbarOpenInEditor
|
|
54
|
-
v-if="__POVESTE_DEV__"
|
|
55
|
-
:file="
|
|
59
|
+
v-if="__POVESTE_DEV__ && editableFile"
|
|
60
|
+
:file="editableFile"
|
|
56
61
|
tooltip="Edit story in editor"
|
|
57
62
|
/>
|
|
58
63
|
</TopBarChip>
|
|
@@ -28,7 +28,7 @@ const progress = computed(() => props.modelValue ? 1 : 0)
|
|
|
28
28
|
const dashoffset = computed(() => (1 - progress.value) * dasharray.value)
|
|
29
29
|
|
|
30
30
|
watch(path, () => {
|
|
31
|
-
dasharray.value = path.value
|
|
31
|
+
dasharray.value = path.value?.getTotalLength?.() ?? 21.21
|
|
32
32
|
})
|
|
33
33
|
</script>
|
|
34
34
|
|