@poveste/app 0.13.1 → 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 +1 -1
- package/dist/bundled/app.css +16 -16
- 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/BaseOverflowMenu.vue_vue_type_script_setup_true_lang.js +5 -2
- 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/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/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 +3 -2
- 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/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.vue_vue_type_script_setup_true_lang.js +1 -1
- 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/icons.generated.js +0 -1
- package/dist/bundled/util/keyboard.js +1 -0
- package/dist/bundled/util/mapping.js +1 -1
- package/dist/bundled/util/preview-settings.js +1 -1
- package/package.json +5 -5
- package/src/app/App.vue +6 -3
- 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/BaseOverflowMenu.vue +9 -3
- package/src/app/components/base/BaseSplitPane.vue +9 -4
- package/src/app/components/command/CommandPrompts.vue +1 -1
- 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/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 +6 -3
- 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/StoryView.vue +7 -3
- package/src/app/components/story/StoryViewer.vue +3 -3
- package/src/app/components/toolbar/ToolbarBackground.vue +1 -1
- package/src/app/components/toolbar/ToolbarResponsiveSize.vue +23 -3
- 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/icons.generated.ts +1 -1
- package/src/app/util/keyboard.ts +3 -0
- package/src/app/util/mapping.ts +1 -1
- 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
|
@@ -2,6 +2,6 @@ import _plugin_vue_export_helper_default from "../../_virtual/_plugin-vue_export
|
|
|
2
2
|
import StoryResponsivePreview_vue_vue_type_script_setup_true_lang_default from "./StoryResponsivePreview.vue_vue_type_script_setup_true_lang.js";
|
|
3
3
|
/* empty css */
|
|
4
4
|
//#region src/app/components/story/StoryResponsivePreview.vue
|
|
5
|
-
var StoryResponsivePreview_default = /*#__PURE__*/ _plugin_vue_export_helper_default(StoryResponsivePreview_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-
|
|
5
|
+
var StoryResponsivePreview_default = /*#__PURE__*/ _plugin_vue_export_helper_default(StoryResponsivePreview_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-d3057f34"]]);
|
|
6
6
|
//#endregion
|
|
7
7
|
export { StoryResponsivePreview_default as default };
|
package/dist/bundled/components/story/StoryResponsivePreview.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -23,7 +23,7 @@ var StoryResponsivePreview_vue_vue_type_script_setup_true_lang_default = /*@__PU
|
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
setup(__props) {
|
|
26
|
-
useCssVars((_ctx) => ({ "
|
|
26
|
+
useCssVars((_ctx) => ({ "v372ee944": unref(settings).backgroundColor }));
|
|
27
27
|
const props = __props;
|
|
28
28
|
const settings = usePreviewSettingsStore().currentSettings;
|
|
29
29
|
const resizing = ref(false);
|
|
@@ -42,18 +42,29 @@ var StoryResponsivePreview_vue_vue_type_script_setup_true_lang_default = /*@__PU
|
|
|
42
42
|
}
|
|
43
43
|
const previewWrapper = ref();
|
|
44
44
|
function useDragger(el, value, min, max, axis) {
|
|
45
|
+
function wrapperSize() {
|
|
46
|
+
const wrapper = previewWrapper.value;
|
|
47
|
+
if (!wrapper) return null;
|
|
48
|
+
return axis === "x" ? wrapper.clientWidth : wrapper.clientHeight;
|
|
49
|
+
}
|
|
50
|
+
function startFrom() {
|
|
51
|
+
if (value.value !== null) return value.value;
|
|
52
|
+
const size = wrapperSize();
|
|
53
|
+
if (size === null) return min;
|
|
54
|
+
return size - (axis === "x" ? 67 : 70);
|
|
55
|
+
}
|
|
45
56
|
function onMouseDown(event) {
|
|
46
57
|
event.preventDefault();
|
|
47
58
|
event.stopPropagation();
|
|
48
59
|
const start = axis === "x" ? event.clientX : event.clientY;
|
|
49
|
-
const startValue =
|
|
60
|
+
const startValue = startFrom();
|
|
50
61
|
resizing.value = true;
|
|
51
62
|
const removeListeners = [addWindowListener("mousemove", onMouseMove), addWindowListener("mouseup", onMouseUp)];
|
|
52
63
|
function onMouseMove(event) {
|
|
53
|
-
const snapTarget =
|
|
64
|
+
const snapTarget = wrapperSize();
|
|
54
65
|
const delta = (axis === "x" ? event.clientX : event.clientY) - start;
|
|
55
66
|
value.value = Math.max(min, Math.min(max, startValue + delta));
|
|
56
|
-
if (Math.abs(value.value - (snapTarget - 67)) < 16) value.value = null;
|
|
67
|
+
if (snapTarget !== null && Math.abs(value.value - (snapTarget - 67)) < 16) value.value = null;
|
|
57
68
|
}
|
|
58
69
|
function onMouseUp() {
|
|
59
70
|
removeListeners.forEach((fn) => fn());
|
|
@@ -65,7 +76,7 @@ var StoryResponsivePreview_vue_vue_type_script_setup_true_lang_default = /*@__PU
|
|
|
65
76
|
event.preventDefault();
|
|
66
77
|
event.stopPropagation();
|
|
67
78
|
const start = axis === "x" ? event.touches[0].clientX : event.touches[0].clientY;
|
|
68
|
-
const startValue =
|
|
79
|
+
const startValue = startFrom();
|
|
69
80
|
resizing.value = true;
|
|
70
81
|
const removeListeners = [
|
|
71
82
|
addWindowListener("touchmove", onTouchMove),
|
|
@@ -130,7 +141,7 @@ var StoryResponsivePreview_vue_vue_type_script_setup_true_lang_default = /*@__PU
|
|
|
130
141
|
finalWidth: finalWidth.value,
|
|
131
142
|
finalHeight: finalHeight.value,
|
|
132
143
|
resizing: resizing.value
|
|
133
|
-
}, void 0, true)]), isResponsiveEnabled.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [_cache[1] || (_cache[1] = createStaticVNode("<div class=\"absolute top-5 left-8 h-2 w-px bg-gray-400/25\" data-v-
|
|
144
|
+
}, void 0, true)]), isResponsiveEnabled.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [_cache[1] || (_cache[1] = createStaticVNode("<div class=\"absolute top-5 left-8 h-2 w-px bg-gray-400/25\" data-v-d3057f34></div><div class=\"absolute top-5 right-8 h-2 w-px bg-gray-400/25\" data-v-d3057f34></div><div class=\"absolute bottom-5 left-8 h-2 w-px bg-gray-400/25\" data-v-d3057f34></div><div class=\"absolute bottom-5 right-8 h-2 w-px bg-gray-400/25\" data-v-d3057f34></div><div class=\"absolute left-5 top-8 w-2 h-px bg-gray-400/25\" data-v-d3057f34></div><div class=\"absolute left-5 bottom-8 w-2 h-px bg-gray-400/25\" data-v-d3057f34></div><div class=\"absolute right-5 top-8 w-2 h-px bg-gray-400/25\" data-v-d3057f34></div><div class=\"absolute right-5 bottom-8 w-2 h-px bg-gray-400/25\" data-v-d3057f34></div>", 8))], 64)) : createCommentVNode("", true)], 2)], 10, _hoisted_3), isResponsiveEnabled.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
|
|
134
145
|
withDirectives((openBlock(), createElementBlock("div", {
|
|
135
146
|
ref_key: "horizontalDragger",
|
|
136
147
|
ref: horizontalDragger,
|
|
@@ -2,6 +2,6 @@ import _plugin_vue_export_helper_default from "../../_virtual/_plugin-vue_export
|
|
|
2
2
|
import StoryVariantGrid_vue_vue_type_script_setup_true_lang_default from "./StoryVariantGrid.vue_vue_type_script_setup_true_lang.js";
|
|
3
3
|
/* empty css */
|
|
4
4
|
//#region src/app/components/story/StoryVariantGrid.vue
|
|
5
|
-
var StoryVariantGrid_default = /*#__PURE__*/ _plugin_vue_export_helper_default(StoryVariantGrid_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-
|
|
5
|
+
var StoryVariantGrid_default = /*#__PURE__*/ _plugin_vue_export_helper_default(StoryVariantGrid_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-a753c25f"]]);
|
|
6
6
|
//#endregion
|
|
7
7
|
export { StoryVariantGrid_default as default };
|
package/dist/bundled/components/story/StoryVariantGrid.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -2,7 +2,7 @@ import { useStoryStore } from "../../stores/story.js";
|
|
|
2
2
|
import { assignSlots, trimSlots } from "../../util/grid-slots.js";
|
|
3
3
|
import StoryVariantGridItem_default from "./StoryVariantGridItem.js";
|
|
4
4
|
import { useDebounceFn, useResizeObserver } from "@poveste/vendors/vue-use";
|
|
5
|
-
import { Fragment, computed, createBlock, createElementBlock, createElementVNode, defineComponent, normalizeStyle, onBeforeUnmount, onMounted, openBlock, ref, renderList, unref, watch } from "@poveste/vendors/vue";
|
|
5
|
+
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, normalizeStyle, onBeforeUnmount, onMounted, openBlock, ref, renderList, unref, watch } from "@poveste/vendors/vue";
|
|
6
6
|
//#region src/app/components/story/StoryVariantGrid.vue?vue&type=script&setup=true&lang.ts
|
|
7
7
|
var _hoisted_1 = { class: "poveste-story-variant-grid flex flex-col items-stretch h-full __poveste-pane-shadow-from-right" };
|
|
8
8
|
var _hoisted_2 = { class: "flex w-0 flex-1 mx-4" };
|
|
@@ -17,17 +17,18 @@ var StoryVariantGrid_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
17
17
|
setup(__props) {
|
|
18
18
|
const storyStore = useStoryStore();
|
|
19
19
|
const gridTemplateWidth = computed(() => {
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
const layout = storyStore.currentStory?.layout;
|
|
21
|
+
if (layout?.type !== "grid") return;
|
|
22
|
+
const layoutWidth = layout.width;
|
|
22
23
|
if (!layoutWidth) return "200px";
|
|
23
24
|
if (typeof layoutWidth === "number") return `${layoutWidth}px`;
|
|
24
25
|
return layoutWidth;
|
|
25
26
|
});
|
|
26
27
|
const maxItemHeight = ref(0);
|
|
27
|
-
const el = ref(
|
|
28
|
+
const el = ref();
|
|
28
29
|
const scrollTop = ref(0);
|
|
29
30
|
const viewportHeight = ref(0);
|
|
30
|
-
const variants = computed(() => storyStore.currentStory
|
|
31
|
+
const variants = computed(() => storyStore.currentStory?.variants ?? []);
|
|
31
32
|
useResizeObserver(el, () => {
|
|
32
33
|
updateWindow();
|
|
33
34
|
updateSize();
|
|
@@ -60,14 +61,16 @@ var StoryVariantGrid_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
60
61
|
updateWindow();
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
|
-
const gridEl = ref(
|
|
64
|
+
const gridEl = ref();
|
|
64
65
|
const gridColumnWidth = ref(1);
|
|
65
66
|
const viewWidth = ref(1);
|
|
66
67
|
function updateSize() {
|
|
67
68
|
if (!el.value) return;
|
|
68
69
|
viewWidth.value = el.value.clientWidth;
|
|
69
70
|
if (!gridEl.value) return;
|
|
70
|
-
|
|
71
|
+
const templateWidth = gridTemplateWidth.value;
|
|
72
|
+
if (!templateWidth) return;
|
|
73
|
+
if (templateWidth.endsWith("%")) gridColumnWidth.value = viewWidth.value * Number.parseInt(templateWidth) / 100 - gap;
|
|
71
74
|
else gridColumnWidth.value = Number.parseInt(gridTemplateWidth.value);
|
|
72
75
|
}
|
|
73
76
|
onMounted(() => {
|
|
@@ -105,7 +108,9 @@ var StoryVariantGrid_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
105
108
|
}, TRIM_DELAY);
|
|
106
109
|
}
|
|
107
110
|
watch(visibleVariants, (visible) => {
|
|
108
|
-
|
|
111
|
+
const story = storyStore.currentStory;
|
|
112
|
+
if (!story) return;
|
|
113
|
+
slots.value = assignSlots(slots.value, story.id, visible);
|
|
109
114
|
scheduleTrim();
|
|
110
115
|
}, { immediate: true });
|
|
111
116
|
onBeforeUnmount(() => {
|
|
@@ -143,7 +148,7 @@ var StoryVariantGrid_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
143
148
|
gridTemplateColumns: `repeat(${columnCount.value}, ${gridColumnWidth.value}px)`,
|
|
144
149
|
transform: offsetY.value ? `translateY(${offsetY.value}px)` : void 0
|
|
145
150
|
})
|
|
146
|
-
}, [(openBlock(true), createElementBlock(Fragment,
|
|
151
|
+
}, [unref(storyStore).currentStory ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(slots.value, (slot, index) => {
|
|
147
152
|
return openBlock(), createBlock(StoryVariantGridItem_default, {
|
|
148
153
|
key: index,
|
|
149
154
|
variant: slot.variant,
|
|
@@ -158,7 +163,7 @@ var StoryVariantGrid_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
158
163
|
"story",
|
|
159
164
|
"style"
|
|
160
165
|
]);
|
|
161
|
-
}), 128))], 4)], 4)])], 544)]);
|
|
166
|
+
}), 128)) : createCommentVNode("", true)], 4)], 4)])], 544)]);
|
|
162
167
|
};
|
|
163
168
|
}
|
|
164
169
|
});
|
|
@@ -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
|
package/dist/bundled/components/toolbar/ToolbarBackground.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -42,7 +42,7 @@ var ToolbarBackground_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*
|
|
|
42
42
|
}
|
|
43
43
|
];
|
|
44
44
|
const showColorScheme = !povesteConfig.theme.hideColorSchemeSwitch;
|
|
45
|
-
const showDropdown = showColorScheme || !!povesteConfig.backgroundPresets
|
|
45
|
+
const showDropdown = showColorScheme || !!povesteConfig.backgroundPresets?.length;
|
|
46
46
|
return (_ctx, _cache) => {
|
|
47
47
|
const _component_VDropdown = resolveComponent("VDropdown");
|
|
48
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,
|
|
@@ -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
|
}
|
|
@@ -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/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,7 +66,7 @@
|
|
|
66
66
|
"tailwindcss": "^4.3.3",
|
|
67
67
|
"typescript": "5.6.3",
|
|
68
68
|
"vite": "^8.2.0",
|
|
69
|
-
"vitest": "^
|
|
69
|
+
"vitest": "^5.0.0",
|
|
70
70
|
"vue": "^3.5.26",
|
|
71
71
|
"vue-tsc": "^2.1.10"
|
|
72
72
|
},
|
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
|
|
|
@@ -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
|
|
|
@@ -49,15 +49,21 @@ const ChildWrapper = {
|
|
|
49
49
|
const state = reactive({ width: 0, index: props.index })
|
|
50
50
|
|
|
51
51
|
useResizeObserver(el, (entries) => {
|
|
52
|
+
// The observer only fires for an element it is observing, so this is
|
|
53
|
+
// never null here — but `children` is keyed by the element, and an
|
|
54
|
+
// undefined key would silently make a second entry for the same child.
|
|
55
|
+
const element = el.value
|
|
56
|
+
if (!element) return
|
|
52
57
|
const width = entries[0].contentRect.width
|
|
53
|
-
if (!children.value.has(
|
|
54
|
-
children.value.set(
|
|
58
|
+
if (!children.value.has(element)) {
|
|
59
|
+
children.value.set(element, state)
|
|
55
60
|
}
|
|
56
61
|
state.width = width
|
|
57
62
|
})
|
|
58
63
|
|
|
59
64
|
onBeforeUnmount(() => {
|
|
60
|
-
|
|
65
|
+
const element = el.value
|
|
66
|
+
if (element) children.value.delete(element)
|
|
61
67
|
})
|
|
62
68
|
|
|
63
69
|
const visible = computed(() => visibleChildrenCount.value > state.index)
|