@poveste/app 0.5.2 → 0.5.3
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.css +4 -4
- package/dist/bundled/components/story/StoryVariantGridItem.js +1 -1
- package/dist/bundled/components/story/StoryVariantGridItem.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/bundled/components/story/StoryVariantSinglePreviewNative.vue_vue_type_script_setup_true_lang.js +2 -5
- package/dist/bundled/components/story/StoryVariantSinglePreviewRemote.vue_vue_type_script_setup_true_lang.js +6 -3
- package/dist/bundled/sandbox.js +4 -5
- package/dist/bundled/util/color-scheme.js +11 -1
- package/dist/bundled/util/const.js +2 -1
- package/package.json +4 -4
- package/src/__tests__/color-scheme.spec.ts +55 -0
- package/src/app/components/story/StoryVariantGridItem.vue +2 -4
- package/src/app/components/story/StoryVariantSinglePreviewNative.vue +2 -5
- package/src/app/components/story/StoryVariantSinglePreviewRemote.vue +6 -3
- package/src/app/sandbox.ts +14 -10
- package/src/app/util/color-scheme.ts +13 -0
- package/src/app/util/const.ts +1 -0
package/dist/bundled/app.css
CHANGED
|
@@ -113,11 +113,11 @@
|
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
@scope (:root) to (.__poveste-render-story:not(.__poveste-render-custom-controls)) {
|
|
116
|
-
.bind-icon-color[data-v-
|
|
117
|
-
color: var(--
|
|
116
|
+
.bind-icon-color[data-v-74c04c7c] {
|
|
117
|
+
color: var(--v2e50e6e6);
|
|
118
118
|
}
|
|
119
|
-
.bind-preview-bg[data-v-
|
|
120
|
-
background-color: var(--
|
|
119
|
+
.bind-preview-bg[data-v-74c04c7c] {
|
|
120
|
+
background-color: var(--v7d5058c5);
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
@scope (:root) to (.__poveste-render-story:not(.__poveste-render-custom-controls)) {
|
|
@@ -2,6 +2,6 @@ import _plugin_vue_export_helper_default from "../../_virtual/_plugin-vue_export
|
|
|
2
2
|
import StoryVariantGridItem_vue_vue_type_script_setup_true_lang_default from "./StoryVariantGridItem.vue_vue_type_script_setup_true_lang.js";
|
|
3
3
|
/* empty css */
|
|
4
4
|
//#region src/app/components/story/StoryVariantGridItem.vue
|
|
5
|
-
var StoryVariantGridItem_default = /*#__PURE__*/ _plugin_vue_export_helper_default(StoryVariantGridItem_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-
|
|
5
|
+
var StoryVariantGridItem_default = /*#__PURE__*/ _plugin_vue_export_helper_default(StoryVariantGridItem_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-74c04c7c"]]);
|
|
6
6
|
//#endregion
|
|
7
7
|
export { StoryVariantGridItem_default as default };
|
package/dist/bundled/components/story/StoryVariantGridItem.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { povesteConfig } from "../../util/config.js";
|
|
2
2
|
import { useStoryStore } from "../../stores/story.js";
|
|
3
3
|
import { useScrollOnActive } from "../../util/scroll.js";
|
|
4
|
-
import { usePreviewDark } from "../../util/color-scheme.js";
|
|
4
|
+
import { previewDarkClasses, usePreviewDark } from "../../util/color-scheme.js";
|
|
5
5
|
import { getContrastColor } from "../../util/preview-settings.js";
|
|
6
6
|
import { usePreviewSettingsStore } from "../../stores/preview-settings.js";
|
|
7
7
|
import ToolbarNewTab_default from "../toolbar/ToolbarNewTab.js";
|
|
@@ -34,8 +34,8 @@ var StoryVariantGridItem_vue_vue_type_script_setup_true_lang_default = /*@__PURE
|
|
|
34
34
|
emits: { resize: (_width, _height) => true },
|
|
35
35
|
setup(__props, { emit: __emit }) {
|
|
36
36
|
useCssVars((_ctx) => ({
|
|
37
|
-
"
|
|
38
|
-
"
|
|
37
|
+
"v2e50e6e6": unref(variant).iconColor,
|
|
38
|
+
"v7d5058c5": unref(settings).backgroundColor
|
|
39
39
|
}));
|
|
40
40
|
const props = __props;
|
|
41
41
|
const emit = __emit;
|
|
@@ -126,7 +126,7 @@ var StoryVariantGridItem_vue_vue_type_script_setup_true_lang_default = /*@__PURE
|
|
|
126
126
|
variant: unref(variant),
|
|
127
127
|
story: __props.story,
|
|
128
128
|
dir: unref(settings).textDirection,
|
|
129
|
-
class: normalizeClass(
|
|
129
|
+
class: normalizeClass(unref(previewDark) ? unref(previewDarkClasses)() : void 0),
|
|
130
130
|
onReady
|
|
131
131
|
}, null, 8, [
|
|
132
132
|
"variant",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { povesteConfig } from "../../util/config.js";
|
|
2
2
|
import { useStoryStore } from "../../stores/story.js";
|
|
3
|
-
import { usePreviewDark } from "../../util/color-scheme.js";
|
|
3
|
+
import { previewDarkClasses, usePreviewDark } from "../../util/color-scheme.js";
|
|
4
4
|
import { getContrastColor } from "../../util/preview-settings.js";
|
|
5
5
|
import { usePreviewSettingsStore } from "../../stores/preview-settings.js";
|
|
6
6
|
import GenericRenderStory_default from "./GenericRenderStory.js";
|
|
@@ -47,10 +47,7 @@ var StoryVariantSinglePreviewNative_vue_vue_type_script_setup_true_lang_default
|
|
|
47
47
|
key: `${__props.story.id}-${__props.variant.id}`,
|
|
48
48
|
variant: __props.variant,
|
|
49
49
|
story: __props.story,
|
|
50
|
-
class: normalizeClass(["h-full",
|
|
51
|
-
[unref(povesteConfig).sandboxDarkClass]: unref(previewDark),
|
|
52
|
-
[unref(povesteConfig).theme.darkClass]: unref(previewDark)
|
|
53
|
-
}]),
|
|
50
|
+
class: normalizeClass(["h-full", unref(previewDark) ? unref(previewDarkClasses)() : void 0]),
|
|
54
51
|
dir: unref(settings).textDirection,
|
|
55
52
|
onReady
|
|
56
53
|
}, null, 8, [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EVENT_SEND, PREVIEW_SETTINGS_SYNC, SANDBOX_HEIGHT, SANDBOX_READY, STATE_SYNC } from "../../util/const.js";
|
|
1
|
+
import { EVENT_SEND, PREVIEW_SETTINGS_REQUEST, PREVIEW_SETTINGS_SYNC, SANDBOX_HEIGHT, SANDBOX_READY, STATE_SYNC } from "../../util/const.js";
|
|
2
2
|
import { trackWindow } from "../../util/keyboard.js";
|
|
3
3
|
import { useStoryStore } from "../../stores/story.js";
|
|
4
4
|
import { usePreviewSettingsStore } from "../../stores/preview-settings.js";
|
|
@@ -23,7 +23,7 @@ var StoryVariantSinglePreviewRemote_vue_vue_type_script_setup_true_lang_default
|
|
|
23
23
|
const settings = usePreviewSettingsStore().currentSettings;
|
|
24
24
|
const iframe = ref();
|
|
25
25
|
function syncState() {
|
|
26
|
-
if (iframe.value && props.variant.previewReady) iframe.value.contentWindow.postMessage({
|
|
26
|
+
if (iframe.value?.contentWindow && props.variant.previewReady) iframe.value.contentWindow.postMessage({
|
|
27
27
|
type: STATE_SYNC,
|
|
28
28
|
state: toRawDeep(props.variant.state, true)
|
|
29
29
|
});
|
|
@@ -54,6 +54,9 @@ var StoryVariantSinglePreviewRemote_vue_vue_type_script_setup_true_lang_default
|
|
|
54
54
|
case SANDBOX_READY:
|
|
55
55
|
setPreviewReady();
|
|
56
56
|
break;
|
|
57
|
+
case PREVIEW_SETTINGS_REQUEST:
|
|
58
|
+
syncSettings();
|
|
59
|
+
break;
|
|
57
60
|
case SANDBOX_HEIGHT: if (typeof event.data.h === "number") {
|
|
58
61
|
const next = Math.max(40, event.data.h);
|
|
59
62
|
if (next !== reportedHeight.value) reportedHeight.value = next;
|
|
@@ -86,7 +89,7 @@ var StoryVariantSinglePreviewRemote_vue_vue_type_script_setup_true_lang_default
|
|
|
86
89
|
stopTrackKeyboard?.();
|
|
87
90
|
});
|
|
88
91
|
function syncSettings() {
|
|
89
|
-
if (iframe.value) iframe.value.contentWindow.postMessage({
|
|
92
|
+
if (iframe.value?.contentWindow) iframe.value.contentWindow.postMessage({
|
|
90
93
|
type: PREVIEW_SETTINGS_SYNC,
|
|
91
94
|
settings: toRaw(settings)
|
|
92
95
|
});
|
package/dist/bundled/sandbox.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { povesteConfig } from "./util/config.js";
|
|
2
1
|
import { isDark } from "./util/dark.js";
|
|
3
|
-
import { SANDBOX_HEIGHT, SANDBOX_READY, STATE_SYNC } from "./util/const.js";
|
|
4
|
-
import { resolvePreviewDark } from "./util/color-scheme.js";
|
|
2
|
+
import { PREVIEW_SETTINGS_REQUEST, SANDBOX_HEIGHT, SANDBOX_READY, STATE_SYNC } from "./util/const.js";
|
|
3
|
+
import { previewDarkClasses, resolvePreviewDark } from "./util/color-scheme.js";
|
|
5
4
|
import { applyPreviewSettings, loadStoredPreviewSettings, receivedSettings } from "./util/preview-settings.js";
|
|
6
5
|
import GenericMountStory_default from "./components/story/GenericMountStory.js";
|
|
7
6
|
import { mapFile } from "./util/mapping.js";
|
|
@@ -19,14 +18,14 @@ var query = parseQuery(window.location.search);
|
|
|
19
18
|
var file = ref(mapFile(files.find((f) => f.id === query.storyId)));
|
|
20
19
|
var storedSettings = loadStoredPreviewSettings();
|
|
21
20
|
if (storedSettings) applyPreviewSettings(storedSettings);
|
|
21
|
+
if (window.parent && window.parent !== window) window.parent.postMessage({ type: PREVIEW_SETTINGS_REQUEST }, window.location.origin);
|
|
22
22
|
var prefersDark = usePreferredDark();
|
|
23
23
|
var previewDark = computed(() => resolvePreviewDark(receivedSettings.colorScheme, prefersDark.value, isDark.value));
|
|
24
24
|
var darkClassTargets = [document.documentElement, document.querySelector("#app")];
|
|
25
25
|
watch(previewDark, (value) => {
|
|
26
26
|
for (const el of darkClassTargets) {
|
|
27
27
|
if (!el) continue;
|
|
28
|
-
el.classList.toggle(
|
|
29
|
-
el.classList.toggle(povesteConfig.theme.darkClass, value);
|
|
28
|
+
for (const className of previewDarkClasses()) el.classList.toggle(className, value);
|
|
30
29
|
}
|
|
31
30
|
}, { immediate: true });
|
|
32
31
|
var app = createApp({
|
|
@@ -31,5 +31,15 @@ function usePreviewDark(settings) {
|
|
|
31
31
|
const prefersDark = usePreferredDark();
|
|
32
32
|
return computed(() => resolvePreviewDark(settings.colorScheme, prefersDark.value, isDark.value));
|
|
33
33
|
}
|
|
34
|
+
/**
|
|
35
|
+
* Classes the story root carries in dark mode, identical on all three render
|
|
36
|
+
* paths. The deprecated `sandboxDarkClass` is emitted only when a book sets it
|
|
37
|
+
* (#126).
|
|
38
|
+
*/
|
|
39
|
+
function previewDarkClasses() {
|
|
40
|
+
const { darkClass } = povesteConfig.theme;
|
|
41
|
+
const legacy = povesteConfig.sandboxDarkClass;
|
|
42
|
+
return [.../* @__PURE__ */ new Set([darkClass, legacy])].filter((name) => !!name);
|
|
43
|
+
}
|
|
34
44
|
//#endregion
|
|
35
|
-
export { defaultPreviewColorScheme, resolvePreviewDark, usePreviewDark };
|
|
45
|
+
export { defaultPreviewColorScheme, previewDarkClasses, resolvePreviewDark, usePreviewDark };
|
|
@@ -3,6 +3,7 @@ var STATE_SYNC = "__poveste:state-sync";
|
|
|
3
3
|
var SANDBOX_READY = "__poveste:sandbox-ready";
|
|
4
4
|
var EVENT_SEND = "__poveste:event";
|
|
5
5
|
var PREVIEW_SETTINGS_SYNC = "__poveste:preview-settings-sync";
|
|
6
|
+
var PREVIEW_SETTINGS_REQUEST = "__poveste:preview-settings-request";
|
|
6
7
|
var SANDBOX_HEIGHT = "__poveste:sandbox-height";
|
|
7
8
|
//#endregion
|
|
8
|
-
export { EVENT_SEND, PREVIEW_SETTINGS_SYNC, SANDBOX_HEIGHT, SANDBOX_READY, STATE_SYNC };
|
|
9
|
+
export { EVENT_SEND, PREVIEW_SETTINGS_REQUEST, PREVIEW_SETTINGS_SYNC, SANDBOX_HEIGHT, SANDBOX_READY, STATE_SYNC };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poveste/app",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.3",
|
|
5
5
|
"description": "Pre-bundled UI for Poveste",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Sorin Gitlan"
|
|
@@ -30,9 +30,9 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"fuse.js": "^7.0.0",
|
|
32
32
|
"shiki": "^3.0.0",
|
|
33
|
-
"@poveste/controls": "^0.5.
|
|
34
|
-
"@poveste/shared": "^0.5.
|
|
35
|
-
"@poveste/vendors": "^0.5.
|
|
33
|
+
"@poveste/controls": "^0.5.3",
|
|
34
|
+
"@poveste/shared": "^0.5.3",
|
|
35
|
+
"@poveste/vendors": "^0.5.3"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@tailwindcss/postcss": "^4.3.3",
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
2
|
+
|
|
3
|
+
// `util/config` re-exports a virtual module Vite generates from the book's own
|
|
4
|
+
// config, so the tests supply it directly.
|
|
5
|
+
const config: { theme: { darkClass?: string }, sandboxDarkClass?: string } = { theme: {} }
|
|
6
|
+
|
|
7
|
+
vi.mock('../app/util/config', () => ({
|
|
8
|
+
get povesteConfig() {
|
|
9
|
+
return config
|
|
10
|
+
},
|
|
11
|
+
}))
|
|
12
|
+
|
|
13
|
+
// Touches browser storage on import; unrelated to the pure function under test.
|
|
14
|
+
vi.mock('../app/util/dark', () => ({ isDark: { value: false } }))
|
|
15
|
+
|
|
16
|
+
const { previewDarkClasses } = await import('../app/util/color-scheme')
|
|
17
|
+
|
|
18
|
+
function darkClassesFor({ darkClass = 'dark', sandboxDarkClass }: { darkClass?: string, sandboxDarkClass?: string }) {
|
|
19
|
+
config.theme = { darkClass }
|
|
20
|
+
config.sandboxDarkClass = sandboxDarkClass
|
|
21
|
+
return previewDarkClasses()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
describe('previewDarkClasses', () => {
|
|
25
|
+
it('returns the theme class for a book that configures neither', () => {
|
|
26
|
+
expect(darkClassesFor({})).toEqual(['dark'])
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
// #126: the deprecated option used to default to `dark` and be emitted here
|
|
30
|
+
// too, which is what made the three render paths disagree.
|
|
31
|
+
it('returns the theme class alone when only it is configured', () => {
|
|
32
|
+
expect(darkClassesFor({ darkClass: 'my-dark' })).toEqual(['my-dark'])
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it('appends sandboxDarkClass when a book still sets it', () => {
|
|
36
|
+
expect(darkClassesFor({ darkClass: 'my-dark', sandboxDarkClass: 'legacy' })).toEqual(['my-dark', 'legacy'])
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('returns one class when both names are the same', () => {
|
|
40
|
+
expect(darkClassesFor({ darkClass: 'dark', sandboxDarkClass: 'dark' })).toEqual(['dark'])
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
// `classList.toggle('')` throws, and the sandbox runs it during boot, so an
|
|
44
|
+
// empty entry leaves every preview blank rather than merely unstyled. Only
|
|
45
|
+
// the empty string reaches here — defu fills an undefined class.
|
|
46
|
+
describe('when a configured class name is empty', () => {
|
|
47
|
+
it('drops an empty theme class', () => {
|
|
48
|
+
expect(darkClassesFor({ darkClass: '' })).toEqual([])
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
it('drops an empty sandboxDarkClass', () => {
|
|
52
|
+
expect(darkClassesFor({ sandboxDarkClass: '' })).toEqual(['dark'])
|
|
53
|
+
})
|
|
54
|
+
})
|
|
55
|
+
})
|
|
@@ -8,7 +8,7 @@ import { computed, ref, toRefs } from 'vue'
|
|
|
8
8
|
import { useRouter } from 'vue-router'
|
|
9
9
|
import { usePreviewSettingsStore } from '../../stores/preview-settings'
|
|
10
10
|
import { useStoryStore } from '../../stores/story'
|
|
11
|
-
import { usePreviewDark } from '../../util/color-scheme'
|
|
11
|
+
import { previewDarkClasses, usePreviewDark } from '../../util/color-scheme'
|
|
12
12
|
import { povesteConfig } from '../../util/config'
|
|
13
13
|
import { getSourceCode } from '../../util/docs'
|
|
14
14
|
import { getContrastColor } from '../../util/preview-settings'
|
|
@@ -163,9 +163,7 @@ const useIframe = computed(() => {
|
|
|
163
163
|
:variant="variant"
|
|
164
164
|
:story="story"
|
|
165
165
|
:dir="settings.textDirection"
|
|
166
|
-
:class="
|
|
167
|
-
[povesteConfig.theme.darkClass]: previewDark,
|
|
168
|
-
}"
|
|
166
|
+
:class="previewDark ? previewDarkClasses() : undefined"
|
|
169
167
|
@ready="onReady"
|
|
170
168
|
/>
|
|
171
169
|
</div>
|
|
@@ -3,7 +3,7 @@ import type { Story, Variant } from '../../types'
|
|
|
3
3
|
import { computed } from 'vue'
|
|
4
4
|
import { usePreviewSettingsStore } from '../../stores/preview-settings'
|
|
5
5
|
import { useStoryStore } from '../../stores/story'
|
|
6
|
-
import { usePreviewDark } from '../../util/color-scheme'
|
|
6
|
+
import { previewDarkClasses, usePreviewDark } from '../../util/color-scheme'
|
|
7
7
|
import { povesteConfig } from '../../util/config'
|
|
8
8
|
import { getContrastColor } from '../../util/preview-settings'
|
|
9
9
|
import GenericRenderStory from './GenericRenderStory.vue'
|
|
@@ -57,10 +57,7 @@ const autoApplyContrastColor = computed(() => !!povesteConfig.autoApplyContrastC
|
|
|
57
57
|
:variant="variant"
|
|
58
58
|
:story="story"
|
|
59
59
|
class="h-full"
|
|
60
|
-
:class="
|
|
61
|
-
[povesteConfig.sandboxDarkClass]: previewDark, // @TODO remove
|
|
62
|
-
[povesteConfig.theme.darkClass]: previewDark,
|
|
63
|
-
}"
|
|
60
|
+
:class="previewDark ? previewDarkClasses() : undefined"
|
|
64
61
|
:dir="settings.textDirection"
|
|
65
62
|
@ready="onReady"
|
|
66
63
|
/>
|
|
@@ -7,7 +7,7 @@ import { computed, onBeforeUnmount, ref, toRaw, watch } from 'vue'
|
|
|
7
7
|
import { useEventsStore } from '../../stores/events'
|
|
8
8
|
import { usePreviewSettingsStore } from '../../stores/preview-settings'
|
|
9
9
|
import { useStoryStore } from '../../stores/story'
|
|
10
|
-
import { EVENT_SEND, PREVIEW_SETTINGS_SYNC, SANDBOX_HEIGHT, SANDBOX_READY, STATE_SYNC } from '../../util/const'
|
|
10
|
+
import { EVENT_SEND, PREVIEW_SETTINGS_REQUEST, PREVIEW_SETTINGS_SYNC, SANDBOX_HEIGHT, SANDBOX_READY, STATE_SYNC } from '../../util/const'
|
|
11
11
|
import { trackWindow } from '../../util/keyboard'
|
|
12
12
|
import { getSandboxUrl } from '../../util/sandbox'
|
|
13
13
|
import { toRawDeep } from '../../util/state'
|
|
@@ -26,7 +26,7 @@ const settings = usePreviewSettingsStore().currentSettings
|
|
|
26
26
|
const iframe = ref<HTMLIFrameElement>()
|
|
27
27
|
|
|
28
28
|
function syncState() {
|
|
29
|
-
if (iframe.value && props.variant.previewReady) {
|
|
29
|
+
if (iframe.value?.contentWindow && props.variant.previewReady) {
|
|
30
30
|
iframe.value.contentWindow.postMessage({
|
|
31
31
|
type: STATE_SYNC,
|
|
32
32
|
state: toRawDeep(props.variant.state, true),
|
|
@@ -72,6 +72,9 @@ useEventListener(window, 'message', (event) => {
|
|
|
72
72
|
case SANDBOX_READY:
|
|
73
73
|
setPreviewReady()
|
|
74
74
|
break
|
|
75
|
+
case PREVIEW_SETTINGS_REQUEST:
|
|
76
|
+
syncSettings()
|
|
77
|
+
break
|
|
75
78
|
case SANDBOX_HEIGHT:
|
|
76
79
|
if (typeof event.data.h === 'number') {
|
|
77
80
|
const next = Math.max(40, event.data.h)
|
|
@@ -118,7 +121,7 @@ onBeforeUnmount(() => {
|
|
|
118
121
|
// Settings
|
|
119
122
|
|
|
120
123
|
function syncSettings() {
|
|
121
|
-
if (iframe.value) {
|
|
124
|
+
if (iframe.value?.contentWindow) {
|
|
122
125
|
iframe.value.contentWindow.postMessage({
|
|
123
126
|
type: PREVIEW_SETTINGS_SYNC,
|
|
124
127
|
settings: toRaw(settings),
|
package/src/app/sandbox.ts
CHANGED
|
@@ -8,9 +8,8 @@ import { parseQuery } from 'vue-router'
|
|
|
8
8
|
import GenericMountStory from './components/story/GenericMountStory.vue'
|
|
9
9
|
import GenericRenderStory from './components/story/GenericRenderStory.vue'
|
|
10
10
|
import { setupPluginApi } from './plugin.js'
|
|
11
|
-
import { resolvePreviewDark } from './util/color-scheme.js'
|
|
12
|
-
import {
|
|
13
|
-
import { PREVIEW_SETTINGS_SYNC, SANDBOX_HEIGHT, SANDBOX_READY, STATE_SYNC } from './util/const.js'
|
|
11
|
+
import { previewDarkClasses, resolvePreviewDark } from './util/color-scheme.js'
|
|
12
|
+
import { PREVIEW_SETTINGS_REQUEST, PREVIEW_SETTINGS_SYNC, SANDBOX_HEIGHT, SANDBOX_READY, STATE_SYNC } from './util/const.js'
|
|
14
13
|
import { isDark } from './util/dark.js'
|
|
15
14
|
import { mapFile } from './util/mapping'
|
|
16
15
|
import { applyPreviewSettings, loadStoredPreviewSettings, receivedSettings } from './util/preview-settings.js'
|
|
@@ -28,15 +27,20 @@ if (storedSettings) {
|
|
|
28
27
|
applyPreviewSettings(storedSettings)
|
|
29
28
|
}
|
|
30
29
|
|
|
30
|
+
// The app pushes settings when it sees the iframe load, which is one document
|
|
31
|
+
// swap away from being wrong: a push aimed at a document that is going away is
|
|
32
|
+
// dropped with no error and nothing re-sends it, leaving the sandbox on the
|
|
33
|
+
// stored value or on none at all (#75). Ask instead — a request can only come
|
|
34
|
+
// from a document that is running and listening.
|
|
35
|
+
if (window.parent && window.parent !== window) {
|
|
36
|
+
window.parent.postMessage({ type: PREVIEW_SETTINGS_REQUEST }, window.location.origin)
|
|
37
|
+
}
|
|
38
|
+
|
|
31
39
|
// The story preview has its own color scheme, independent from the app chrome.
|
|
32
40
|
// The fallback covers settings stored before the option existed.
|
|
33
41
|
const prefersDark = usePreferredDark()
|
|
34
42
|
const previewDark = computed(() => resolvePreviewDark(receivedSettings.colorScheme, prefersDark.value, isDark.value))
|
|
35
43
|
|
|
36
|
-
// `sandboxDarkClass` is poveste's own deprecated config option, superseded by
|
|
37
|
-
// `theme.darkClass`. Still honoured on purpose: dropping it would silently stop
|
|
38
|
-
// applying the class for anyone who set it. Removing the option is a breaking
|
|
39
|
-
// config change and belongs to a major, not here.
|
|
40
44
|
/*
|
|
41
45
|
* The class also has to land *inside* the story's `@scope` root, not only on
|
|
42
46
|
* `<html>` (#101).
|
|
@@ -60,9 +64,9 @@ watch(previewDark, (value) => {
|
|
|
60
64
|
for (const el of darkClassTargets) {
|
|
61
65
|
if (!el) continue
|
|
62
66
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
67
|
+
for (const className of previewDarkClasses()) {
|
|
68
|
+
el.classList.toggle(className, value)
|
|
69
|
+
}
|
|
66
70
|
}
|
|
67
71
|
}, {
|
|
68
72
|
immediate: true,
|
|
@@ -34,3 +34,16 @@ export function usePreviewDark(settings: PreviewSettings) {
|
|
|
34
34
|
const prefersDark = usePreferredDark()
|
|
35
35
|
return computed(() => resolvePreviewDark(settings.colorScheme, prefersDark.value, isDark.value))
|
|
36
36
|
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Classes the story root carries in dark mode, identical on all three render
|
|
40
|
+
* paths. The deprecated `sandboxDarkClass` is emitted only when a book sets it
|
|
41
|
+
* (#126).
|
|
42
|
+
*/
|
|
43
|
+
export function previewDarkClasses(): string[] {
|
|
44
|
+
const { darkClass } = povesteConfig.theme
|
|
45
|
+
// eslint-disable-next-line ts/no-deprecated
|
|
46
|
+
const legacy = povesteConfig.sandboxDarkClass
|
|
47
|
+
// Empty entries are dropped: `classList.toggle('')` throws, during boot.
|
|
48
|
+
return [...new Set([darkClass, legacy])].filter((name): name is string => !!name)
|
|
49
|
+
}
|
package/src/app/util/const.ts
CHANGED
|
@@ -2,4 +2,5 @@ export const STATE_SYNC = '__poveste:state-sync'
|
|
|
2
2
|
export const SANDBOX_READY = '__poveste:sandbox-ready'
|
|
3
3
|
export const EVENT_SEND = '__poveste:event'
|
|
4
4
|
export const PREVIEW_SETTINGS_SYNC = '__poveste:preview-settings-sync'
|
|
5
|
+
export const PREVIEW_SETTINGS_REQUEST = '__poveste:preview-settings-request'
|
|
5
6
|
export const SANDBOX_HEIGHT = '__poveste:sandbox-height'
|