@poveste/app 0.17.0 → 0.17.1
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 +1 -1
- package/dist/bundled/components/panel/StorySourceCode.js +1 -1
- package/dist/bundled/components/panel/StorySourceCode.vue_vue_type_script_setup_true_lang.js +5 -15
- package/dist/bundled/util/docs.js +20 -10
- package/package.json +4 -4
- package/src/__tests__/source-code.spec.ts +55 -0
- package/src/app/components/panel/StorySourceCode.vue +8 -24
- package/src/app/components/story/GenericMountStory.vue +2 -1
- package/src/app/components/story/GenericRenderStory.vue +2 -1
- package/src/app/util/docs.ts +24 -17
- package/src/virtual.d.ts +7 -0
package/dist/bundled/app.css
CHANGED
|
@@ -150,7 +150,7 @@ from {
|
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
@scope (:root) to (.__poveste-render-story:not(.__poveste-render-custom-controls)) {
|
|
153
|
-
.__poveste-code-placeholder[data-v-
|
|
153
|
+
.__poveste-code-placeholder[data-v-ed711d57] {
|
|
154
154
|
color: inherit;
|
|
155
155
|
font-size: inherit;
|
|
156
156
|
}
|
|
@@ -2,6 +2,6 @@ import _plugin_vue_export_helper_default from "../../_virtual/_plugin-vue_export
|
|
|
2
2
|
import StorySourceCode_vue_vue_type_script_setup_true_lang_default from "./StorySourceCode.vue_vue_type_script_setup_true_lang.js";
|
|
3
3
|
/* empty css */
|
|
4
4
|
//#region src/app/components/panel/StorySourceCode.vue
|
|
5
|
-
var StorySourceCode_default = /*#__PURE__*/ _plugin_vue_export_helper_default(StorySourceCode_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-
|
|
5
|
+
var StorySourceCode_default = /*#__PURE__*/ _plugin_vue_export_helper_default(StorySourceCode_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-ed711d57"]]);
|
|
6
6
|
//#endregion
|
|
7
7
|
export { StorySourceCode_default as default };
|
package/dist/bundled/components/panel/StorySourceCode.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { isDark } from "../../util/dark.js";
|
|
2
2
|
import BaseEmpty_default from "../base/BaseEmpty.js";
|
|
3
|
+
import { getDynamicSourceCode, getStaticSourceCode, loadGenerateSourceCode } from "../../util/docs.js";
|
|
3
4
|
import { getHighlighter } from "../../util/highlighter.js";
|
|
4
5
|
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, markRaw, nextTick, normalizeClass, onMounted, openBlock, ref, shallowRef, toDisplayString, unref, watch, watchEffect, withCtx } from "@poveste/vendors/vue";
|
|
5
6
|
import { Icon } from "@poveste/vendors/iconify";
|
|
6
7
|
import { HstCopyIcon, HstTooltip } from "@poveste/controls";
|
|
7
|
-
import { clientSupportPlugins } from "virtual:$poveste-support-plugins-client";
|
|
8
|
-
import { unindent } from "@poveste/shared";
|
|
9
8
|
//#region src/app/components/panel/StorySourceCode.vue?vue&type=script&setup=true&lang.ts
|
|
10
9
|
var _hoisted_1 = { class: "poveste-story-source-code bg-gray-50 dark:bg-gray-750 h-full overflow-hidden flex flex-col" };
|
|
11
10
|
var _hoisted_2 = {
|
|
@@ -29,12 +28,8 @@ var StorySourceCode_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
29
28
|
const props = __props;
|
|
30
29
|
const generateSourceCodeFn = shallowRef(null);
|
|
31
30
|
watchEffect(async () => {
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
if (clientPlugin) {
|
|
35
|
-
const pluginModule = await clientPlugin();
|
|
36
|
-
generateSourceCodeFn.value = markRaw(pluginModule.generateSourceCode);
|
|
37
|
-
}
|
|
31
|
+
const generate = await loadGenerateSourceCode(props.story);
|
|
32
|
+
if (generate) generateSourceCodeFn.value = markRaw(generate);
|
|
38
33
|
});
|
|
39
34
|
const highlighter = shallowRef();
|
|
40
35
|
const dynamicSourceCode = ref("");
|
|
@@ -45,11 +40,7 @@ var StorySourceCode_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
45
40
|
error.value = null;
|
|
46
41
|
dynamicSourceCode.value = "";
|
|
47
42
|
try {
|
|
48
|
-
|
|
49
|
-
else if (props.variant.slots?.().source) {
|
|
50
|
-
const source = props.variant.slots?.().source()[0].children;
|
|
51
|
-
if (source) dynamicSourceCode.value = await unindent(source);
|
|
52
|
-
} else dynamicSourceCode.value = await generateSourceCodeFn.value(props.variant);
|
|
43
|
+
dynamicSourceCode.value = await getDynamicSourceCode(props.variant, generateSourceCodeFn.value) ?? "";
|
|
53
44
|
} catch (e) {
|
|
54
45
|
console.error(e);
|
|
55
46
|
error.value = e instanceof Error ? e.message : String(e);
|
|
@@ -62,8 +53,7 @@ var StorySourceCode_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/
|
|
|
62
53
|
const staticSourceCode = ref("");
|
|
63
54
|
watch(() => [props.story, props.story?.file?.source], async () => {
|
|
64
55
|
staticSourceCode.value = "";
|
|
65
|
-
|
|
66
|
-
if (sourceLoader) staticSourceCode.value = (await sourceLoader()).default;
|
|
56
|
+
staticSourceCode.value = await getStaticSourceCode(props.story) ?? "";
|
|
67
57
|
}, { immediate: true });
|
|
68
58
|
const displayedSourceCode = computed(() => {
|
|
69
59
|
if (displayedSource.value === "dynamic") return dynamicSourceCode.value;
|
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
import { clientSupportPlugins } from "virtual:$poveste-support-plugins-client";
|
|
2
2
|
import { unindent } from "@poveste/shared";
|
|
3
3
|
//#region src/app/util/docs.ts
|
|
4
|
-
|
|
4
|
+
/** What the variant declares, or what its framework generates from it; `undefined` when neither has anything. */
|
|
5
|
+
async function getDynamicSourceCode(variant, generate) {
|
|
5
6
|
if (variant.source) return variant.source;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const supportPluginId = story.file?.supportPluginId;
|
|
11
|
-
const clientPlugin = supportPluginId ? clientSupportPlugins[supportPluginId] : void 0;
|
|
12
|
-
if (clientPlugin) return (await clientPlugin()).generateSourceCode(variant);
|
|
7
|
+
const sourceSlot = variant.slots?.().source;
|
|
8
|
+
if (sourceSlot) {
|
|
9
|
+
const source = sourceSlot()[0].children;
|
|
10
|
+
return source ? unindent(source) : void 0;
|
|
13
11
|
}
|
|
12
|
+
return await generate?.(variant) || void 0;
|
|
13
|
+
}
|
|
14
|
+
async function getStaticSourceCode(story) {
|
|
14
15
|
const sourceLoader = story.file?.source;
|
|
15
|
-
|
|
16
|
+
return sourceLoader ? (await sourceLoader()).default : void 0;
|
|
17
|
+
}
|
|
18
|
+
async function loadGenerateSourceCode(story) {
|
|
19
|
+
const supportPluginId = story.file?.supportPluginId;
|
|
20
|
+
const clientPlugin = supportPluginId ? clientSupportPlugins[supportPluginId] : void 0;
|
|
21
|
+
return clientPlugin ? (await clientPlugin()).generateSourceCode : void 0;
|
|
22
|
+
}
|
|
23
|
+
async function getSourceCode(story, variant) {
|
|
24
|
+
const generate = async (v) => (await loadGenerateSourceCode(story))?.(v);
|
|
25
|
+
return await getDynamicSourceCode(variant, generate) || getStaticSourceCode(story);
|
|
16
26
|
}
|
|
17
27
|
//#endregion
|
|
18
|
-
export { getSourceCode };
|
|
28
|
+
export { getDynamicSourceCode, getSourceCode, getStaticSourceCode, loadGenerateSourceCode };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poveste/app",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.17.
|
|
4
|
+
"version": "0.17.1",
|
|
5
5
|
"description": "Pre-bundled UI for Poveste",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Sorin Gitlan",
|
|
@@ -34,9 +34,9 @@
|
|
|
34
34
|
"node": ">=24.15.0"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@poveste/controls": "^0.17.
|
|
38
|
-
"@poveste/shared": "^0.17.
|
|
39
|
-
"@poveste/vendors": "^0.17.
|
|
37
|
+
"@poveste/controls": "^0.17.1",
|
|
38
|
+
"@poveste/shared": "^0.17.1",
|
|
39
|
+
"@poveste/vendors": "^0.17.1",
|
|
40
40
|
"fuse.js": "^7.0.0",
|
|
41
41
|
"shiki": "^4.4.3"
|
|
42
42
|
},
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { Story, Variant } from '../app/types'
|
|
2
|
+
import { describe, expect, it, vi } from 'vitest'
|
|
3
|
+
import { getSourceCode } from '../app/util/docs'
|
|
4
|
+
|
|
5
|
+
const plugin = vi.hoisted(() => ({ generateSourceCode: (() => undefined) as (variant: unknown) => unknown, loads: 0 }))
|
|
6
|
+
|
|
7
|
+
vi.mock('virtual:$poveste-support-plugins-client', () => ({
|
|
8
|
+
clientSupportPlugins: {
|
|
9
|
+
framework: async () => {
|
|
10
|
+
plugin.loads++
|
|
11
|
+
return { generateSourceCode: (variant: unknown) => plugin.generateSourceCode(variant) }
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
}))
|
|
15
|
+
|
|
16
|
+
const FILE = '<Story title="Grid" />'
|
|
17
|
+
|
|
18
|
+
function storyWithFile() {
|
|
19
|
+
return { file: { supportPluginId: 'framework', source: async () => ({ default: FILE }) } } as unknown as Story
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
describe('getSourceCode with a framework plugin', () => {
|
|
23
|
+
it('returns the story file when the plugin returns nothing synchronously, as plugin-svelte does', async () => {
|
|
24
|
+
plugin.generateSourceCode = () => undefined
|
|
25
|
+
|
|
26
|
+
const source = await getSourceCode(storyWithFile(), {} as Variant)
|
|
27
|
+
|
|
28
|
+
expect(source).toBe(FILE)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
it('returns the story file when the plugin resolves to an empty string', async () => {
|
|
32
|
+
plugin.generateSourceCode = async () => ''
|
|
33
|
+
|
|
34
|
+
const source = await getSourceCode(storyWithFile(), {} as Variant)
|
|
35
|
+
|
|
36
|
+
expect(source).toBe(FILE)
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it('prefers what the plugin generates', async () => {
|
|
40
|
+
plugin.generateSourceCode = async () => '<Button />'
|
|
41
|
+
|
|
42
|
+
const source = await getSourceCode(storyWithFile(), {} as Variant)
|
|
43
|
+
|
|
44
|
+
expect(source).toBe('<Button />')
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
it('returns a variant\'s declared source without loading the plugin', async () => {
|
|
48
|
+
plugin.loads = 0
|
|
49
|
+
|
|
50
|
+
const source = await getSourceCode(storyWithFile(), { source: '<Declared />' } as Variant)
|
|
51
|
+
|
|
52
|
+
expect(source).toBe('<Declared />')
|
|
53
|
+
expect(plugin.loads).toBe(0)
|
|
54
|
+
})
|
|
55
|
+
})
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import type { HighlighterCore } from 'shiki/core'
|
|
3
3
|
import type { Story, Variant } from '../../types'
|
|
4
|
+
import type { GenerateSourceCode } from '../../util/docs'
|
|
4
5
|
import { Icon } from '@iconify/vue'
|
|
5
6
|
import { HstCopyIcon, HstTooltip } from '@poveste/controls'
|
|
6
|
-
import { unindent } from '@poveste/shared'
|
|
7
|
-
import { clientSupportPlugins } from 'virtual:$poveste-support-plugins-client'
|
|
8
7
|
import { computed, markRaw, nextTick, onMounted, ref, shallowRef, watch, watchEffect } from 'vue'
|
|
9
8
|
import { isDark } from '../../util/dark'
|
|
9
|
+
import { getDynamicSourceCode, getStaticSourceCode, loadGenerateSourceCode } from '../../util/docs'
|
|
10
10
|
import { getHighlighter } from '../../util/highlighter'
|
|
11
11
|
import BaseEmpty from '../base/BaseEmpty.vue'
|
|
12
12
|
|
|
@@ -17,14 +17,12 @@ const props = defineProps<{
|
|
|
17
17
|
|
|
18
18
|
// `ref(null)` infers `Ref<null>`, so the assignment below and the call further
|
|
19
19
|
// down were both errors about a type nobody meant to declare.
|
|
20
|
-
const generateSourceCodeFn = shallowRef<
|
|
20
|
+
const generateSourceCodeFn = shallowRef<GenerateSourceCode | null>(null)
|
|
21
21
|
|
|
22
22
|
watchEffect(async () => {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const pluginModule = await clientPlugin()
|
|
27
|
-
generateSourceCodeFn.value = markRaw(pluginModule.generateSourceCode)
|
|
23
|
+
const generate = await loadGenerateSourceCode(props.story)
|
|
24
|
+
if (generate) {
|
|
25
|
+
generateSourceCodeFn.value = markRaw(generate)
|
|
28
26
|
}
|
|
29
27
|
})
|
|
30
28
|
|
|
@@ -43,18 +41,7 @@ watch(() => [props.variant, generateSourceCodeFn.value], async () => {
|
|
|
43
41
|
error.value = null
|
|
44
42
|
dynamicSourceCode.value = ''
|
|
45
43
|
try {
|
|
46
|
-
|
|
47
|
-
dynamicSourceCode.value = props.variant.source
|
|
48
|
-
}
|
|
49
|
-
else if (props.variant.slots?.().source) {
|
|
50
|
-
const source = props.variant.slots?.().source()[0].children
|
|
51
|
-
if (source) {
|
|
52
|
-
dynamicSourceCode.value = await unindent(source)
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
dynamicSourceCode.value = await generateSourceCodeFn.value(props.variant)
|
|
57
|
-
}
|
|
44
|
+
dynamicSourceCode.value = (await getDynamicSourceCode(props.variant, generateSourceCodeFn.value)) ?? ''
|
|
58
45
|
}
|
|
59
46
|
catch (e) {
|
|
60
47
|
console.error(e)
|
|
@@ -75,10 +62,7 @@ watch(() => [props.variant, generateSourceCodeFn.value], async () => {
|
|
|
75
62
|
const staticSourceCode = ref('')
|
|
76
63
|
watch(() => [props.story, props.story?.file?.source], async () => {
|
|
77
64
|
staticSourceCode.value = ''
|
|
78
|
-
|
|
79
|
-
if (sourceLoader) {
|
|
80
|
-
staticSourceCode.value = (await sourceLoader()).default
|
|
81
|
-
}
|
|
65
|
+
staticSourceCode.value = (await getStaticSourceCode(props.story)) ?? ''
|
|
82
66
|
}, {
|
|
83
67
|
immediate: true,
|
|
84
68
|
})
|
|
@@ -5,6 +5,7 @@ export default {
|
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<script lang="ts" setup>
|
|
8
|
+
import type { Component } from 'vue'
|
|
8
9
|
import type { Story } from '../../types'
|
|
9
10
|
import { clientSupportPlugins } from 'virtual:$poveste-support-plugins-client'
|
|
10
11
|
import { markRaw, ref, watchEffect } from 'vue'
|
|
@@ -13,7 +14,7 @@ const props = defineProps<{
|
|
|
13
14
|
story: Story
|
|
14
15
|
}>()
|
|
15
16
|
|
|
16
|
-
const mountComponent = ref(null)
|
|
17
|
+
const mountComponent = ref<Component | null>(null)
|
|
17
18
|
|
|
18
19
|
watchEffect(async () => {
|
|
19
20
|
const supportPluginId = props.story.file?.supportPluginId
|
|
@@ -5,6 +5,7 @@ export default {
|
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<script lang="ts" setup>
|
|
8
|
+
import type { Component } from 'vue'
|
|
8
9
|
import type { Story } from '../../types'
|
|
9
10
|
import { clientSupportPlugins } from 'virtual:$poveste-support-plugins-client'
|
|
10
11
|
import { markRaw, ref, watchEffect } from 'vue'
|
|
@@ -13,7 +14,7 @@ const props = defineProps<{
|
|
|
13
14
|
story: Story
|
|
14
15
|
}>()
|
|
15
16
|
|
|
16
|
-
const mountComponent = ref(null)
|
|
17
|
+
const mountComponent = ref<Component | null>(null)
|
|
17
18
|
|
|
18
19
|
watchEffect(async () => {
|
|
19
20
|
const supportPluginId = props.story.file?.supportPluginId
|
package/src/app/util/docs.ts
CHANGED
|
@@ -1,28 +1,35 @@
|
|
|
1
|
+
import type { ClientSupportPlugin } from '@poveste/shared'
|
|
1
2
|
import type { Story, Variant } from '../types'
|
|
2
3
|
import { unindent } from '@poveste/shared'
|
|
3
4
|
import { clientSupportPlugins } from 'virtual:$poveste-support-plugins-client'
|
|
4
5
|
|
|
5
|
-
export
|
|
6
|
+
export type GenerateSourceCode = ClientSupportPlugin['generateSourceCode']
|
|
7
|
+
|
|
8
|
+
/** What the variant declares, or what its framework generates from it; `undefined` when neither has anything. */
|
|
9
|
+
export async function getDynamicSourceCode(variant: Variant, generate: GenerateSourceCode | undefined): Promise<string | undefined> {
|
|
6
10
|
if (variant.source) {
|
|
7
11
|
return variant.source
|
|
8
12
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
else {
|
|
16
|
-
const supportPluginId = story.file?.supportPluginId
|
|
17
|
-
const clientPlugin = supportPluginId ? clientSupportPlugins[supportPluginId] : undefined
|
|
18
|
-
if (clientPlugin) {
|
|
19
|
-
const pluginModule = await clientPlugin()
|
|
20
|
-
return pluginModule.generateSourceCode(variant)
|
|
21
|
-
}
|
|
13
|
+
const sourceSlot = variant.slots?.().source
|
|
14
|
+
if (sourceSlot) {
|
|
15
|
+
const source = sourceSlot()[0].children
|
|
16
|
+
return source ? unindent(source) : undefined
|
|
22
17
|
}
|
|
18
|
+
return (await generate?.(variant)) || undefined
|
|
19
|
+
}
|
|
23
20
|
|
|
21
|
+
export async function getStaticSourceCode(story: Story): Promise<string | undefined> {
|
|
24
22
|
const sourceLoader = story.file?.source
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
return sourceLoader ? (await sourceLoader()).default : undefined
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function loadGenerateSourceCode(story: Story): Promise<GenerateSourceCode | undefined> {
|
|
27
|
+
const supportPluginId = story.file?.supportPluginId
|
|
28
|
+
const clientPlugin = supportPluginId ? clientSupportPlugins[supportPluginId] : undefined
|
|
29
|
+
return clientPlugin ? (await clientPlugin()).generateSourceCode : undefined
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function getSourceCode(story: Story, variant: Variant): Promise<string | undefined> {
|
|
33
|
+
const generate: GenerateSourceCode = async v => (await loadGenerateSourceCode(story))?.(v)
|
|
34
|
+
return (await getDynamicSourceCode(variant, generate)) || getStaticSourceCode(story)
|
|
28
35
|
}
|
package/src/virtual.d.ts
CHANGED
|
@@ -4,4 +4,11 @@ declare module 'virtual:$poveste-commands' {
|
|
|
4
4
|
export const registeredCommands: ClientCommand[]
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
+
declare module 'virtual:$poveste-support-plugins-client' {
|
|
8
|
+
import type { ClientSupportPlugin } from '@poveste/shared'
|
|
9
|
+
import type { Component } from 'vue'
|
|
10
|
+
|
|
11
|
+
export const clientSupportPlugins: Record<string, () => Promise<ClientSupportPlugin<Component>>>
|
|
12
|
+
}
|
|
13
|
+
|
|
7
14
|
declare module 'virtual:*';
|