Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(<markdown>): support fallback default slot #1405

Merged
merged 3 commits into from
Aug 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/components/content/ExampleTheTitle.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<h1 class="text-4xl">
<Markdown unwrap="p" />
<Markdown :use="$slots.default" unwrap="p" />
</h1>
</template>
2 changes: 1 addition & 1 deletion docs/components/content/MyButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defineProps({

<template>
<button :class="type">
<Markdown unwrap="p" />
<Markdown :use="$slots.default" unwrap="p" />
</button>
</template>

Expand Down
4 changes: 2 additions & 2 deletions docs/content/3.guide/1.writing/3.mdc.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ The `unwrap` prop accepts an HTML tag that will be used to unwrap the content, u
```html [TheTitle.vue]
<template>
<h1 class="text-4xl">
<Markdown unwrap="p" />
<Markdown :use="$slots.default" unwrap="p" />
</h1>
</template>
```
Expand Down Expand Up @@ -189,7 +189,7 @@ defineProps(['type'])

<template>
<div :class="[type]">
<Markdown unwrap="p" />
<Markdown :use="$slots.default" unwrap="p" />
</div>
</template>
```
Expand Down
3 changes: 1 addition & 2 deletions docs/content/4.api/1.components/5.markdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@ It is useful when creating components that you want to use in your Markdown cont
## Props

- `use`{lang=ts}: The slot to bind on, you must provide a `use`{lang=ts} via `$slots.{your_slot}`{lang=ts} in `<template>`{lang=html}.
- Type: `String`{lang=ts} or `Function`
- Type: Vue slot `Function`
- Example: `$slots.default`{lang=ts}
- *Warning*: Using a plain string won't let you profit from reactivity for that component.
- `unwrap`{lang=ts}: Whether to unwrap the content or not. This is useful when you want to extract the content nested in native Markdown syntax. Each specified tag will get removed from AST.
- Type: `Boolean`{lang=ts} or `String`{lang=ts}
- Default: `false`{lang=ts}
Expand Down
2 changes: 1 addition & 1 deletion docs/content/6.blog/1.announcing-v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ MDC is Markdown, so nothing changes and you can keep using the `.md` extension.

<template>
<button :class="type">
<Markdown unwrap="p" />
<Markdown :use="$slots.default" unwrap="p" />
</button>
</template>
```
Expand Down
18 changes: 12 additions & 6 deletions src/runtime/components/Markdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export default defineComponent({
* A slot name or function
*/
use: {
type: [String, Function],
default: 'default'
type: Function,
default: undefined
},
/**
* Tags to unwrap separated by spaces
Expand All @@ -28,24 +28,30 @@ export default defineComponent({
},
setup (props) {
const { parent } = getCurrentInstance()
const { between } = useSlots()
const { between, default: fallbackSlot } = useSlots()

const tags = computed(() => {
if (typeof props.unwrap === 'string') { return props.unwrap.split(' ') }
return ['*']
})

return {
fallbackSlot,
tags,
between,
parent
}
},
render ({ use, unwrap, between, tags, parent }) {
render ({ use, unwrap, fallbackSlot, between, tags, parent }) {
try {
const slot: Slot = typeof use === 'string' ? parent?.slots[use] || parent?.parent?.slots[use] : use
let slot: Slot = use
if (typeof use === 'string') {
slot = parent?.slots[use] || parent?.parent?.slots[use]
// eslint-disable-next-line no-console
console.warn(`Please set :use="$slots.${use}" in <Markdown> component to enable reactivity`)
}

if (!slot) { return h('div') }
if (!slot) { return fallbackSlot ? fallbackSlot() : h('div') }

if (!unwrap) { return [slot()] }

Expand Down
6 changes: 6 additions & 0 deletions test/basic.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ describe('Basic usage', async () => {
expect(html).contains('Content (v2)')
})

test('Partials specials chars', async () => {
const html = await $fetch('/_partial/markdown')
expect(html).contains('><!--[--> Default title <!--]--></h1>')
expect(html).contains('<p><!--[-->p1<!--]--></p>')
})

test('Warning for invalid file name', () => {
expect(spyConsoleWarn).toHaveBeenCalled()
expect(spyConsoleWarn).toHaveBeenCalledWith('Ignoring [content:with-\'invalid\'-char.md]. File name should not contain any of the following characters: \', ", ?, #, /')
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/basic/components/content/Alert.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div>
<Markdown />
<Markdown :use="$slots.default" />
</div>
</template>
14 changes: 14 additions & 0 deletions test/fixtures/basic/components/content/TestMarkdown.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template>
<div>
<h1 class="text-3xl font-bold text-primary-900 dark:text-primary-100">
<Markdown :use="$slots.title" unwrap="p">
Default title
</Markdown>
</h1>
<p>
<Markdown :use="$slots.default" unwrap="p">
Default paragraph
</Markdown>
</p>
</div>
</template>
3 changes: 3 additions & 0 deletions test/fixtures/basic/content/_partial/markdown.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
::test-markdown
p1
::