Skip to content

Commit

Permalink
feat: variant hand-written source
Browse files Browse the repository at this point in the history
  • Loading branch information
Akryum committed Feb 14, 2022
1 parent fe71046 commit 43ed14e
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 1 deletion.
77 changes: 77 additions & 0 deletions examples/vue3/src/components/HandWrittenSource.story.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<script lang="ts" setup>
function initState () {
return {
count: 0,
}
}
const source = `<h1>Toto</h1>
<input
v-model.number="count"
type="number"
>
<p>{{ count }}</p>
<template #named="{ shown, hide }">
<MyComponent
v-if="shown"
:item="{ foo: 'bar' }"
@close="hide()"
/>
</template>`
</script>

<template>
<Story title="Hand-written source">
<Variant
title="Source prop"
:init-state="initState"
:source="source"
>
<template #default="{ state }">
<h1>Toto</h1>

<input
v-model.number="state.count"
type="number"
>
</template>
</Variant>
<Variant
title="Source template"
:init-state="initState"
>
<template #default="{ state }">
<h1>Toto</h1>

<input
v-model.number="state.count"
type="number"
>
</template>

<template #source>
<textarea v-pre>
<h1>Toto</h1>

<input
v-model.number="count"
type="number"
>

<p>{{ count }}</p>

<template #named="{ shown, hide }">
<MyComponent
v-if="shown"
:item="{ foo: 'bar' }"
@close="hide()"
/>
</template>
</textarea>
</template>
</Variant>
</Story>
</template>
19 changes: 19 additions & 0 deletions packages/histoire/src/client/app/codegen/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@ export function indent (lines: string[], count = 1) {
return lines.map(line => `${' '.repeat(count)}${line}`)
}

export function unindent (code: string) {
const lines = code.split('\n')
let indentLevel = -1
let indentText: string
const linesToAnalyze = lines.filter(line => line.trim().length > 0)
for (const line of linesToAnalyze) {
const match = /^\s*/.exec(line)
if (match && (indentLevel === -1 || indentLevel > match[0].length)) {
indentLevel = match[0].length
indentText = match[0]
}
}
const result: string[] = []
for (const line of lines) {
result.push(line.replace(indentText, ''))
}
return result.join('\n').trim()
}

interface AutoBuildingOject {
key: string
cache: Record<string | symbol, AutoBuildingOject>
Expand Down
12 changes: 11 additions & 1 deletion packages/histoire/src/client/app/components/StorySourceCode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { getHighlighter, Highlighter, setCDN } from 'shiki'
import { generateSourceCode } from '../codegen/vue3'
import { Variant } from '../types'
import { isDark } from '../util/dark'
import { unindent } from '../codegen/util'
const props = defineProps({
variant: {
Expand Down Expand Up @@ -33,7 +34,16 @@ onMounted(async () => {
watch(() => props.variant, async (value) => {
error.value = null
try {
sourceCode.value = await generateSourceCode(value)
if (value.source) {
sourceCode.value = value.source
} else if (value.slots?.().source) {
const source = value.slots?.().source()[0].children
if (source) {
sourceCode.value = await unindent(source)
}
} else {
sourceCode.value = await generateSourceCode(value)
}
} catch (e) {
console.error(e)
error.value = e.message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ export default defineComponent({
type: Function as PropType<() => any | Promise<any>>,
default: null,
},
source: {
type: String,
default: null,
},
},
setup (props) {
Expand All @@ -29,6 +34,7 @@ export default defineComponent({
}
},
slots: () => vm.proxy.$slots,
source: props.source,
})
}
Expand Down
1 change: 1 addition & 0 deletions packages/histoire/src/client/app/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ export interface Variant {
initState?: () => any
slots?: () => Readonly<any>
state?: any
source?: string
}

0 comments on commit 43ed14e

Please sign in to comment.