mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-20 06:51:46 +01:00
docs(ComponentCard): show all props for the code (#797)
Co-authored-by: Benjamin Canac <canacb1@gmail.com>
This commit is contained in:
@@ -41,7 +41,7 @@
|
||||
<ContentSlot v-if="$slots.default" :use="$slots.default" />
|
||||
|
||||
<template v-for="slot in Object.keys(slots || {})" :key="slot" #[slot]>
|
||||
<ContentSlot :name="slot" />
|
||||
<ContentSlot :name="slot" unwrap="p" />
|
||||
</template>
|
||||
</component>
|
||||
</div>
|
||||
@@ -113,6 +113,7 @@ const props = defineProps({
|
||||
const baseProps = reactive({ ...props.baseProps })
|
||||
const componentProps = reactive({ ...props.props })
|
||||
|
||||
const { $prettier } = useNuxtApp()
|
||||
const appConfig = useAppConfig()
|
||||
const route = useRoute()
|
||||
// eslint-disable-next-line vue/no-dupe-keys
|
||||
@@ -124,7 +125,7 @@ const meta = await fetchComponentMeta(name)
|
||||
|
||||
// Computed
|
||||
|
||||
const fullProps = computed(() => ({ ...baseProps, ...componentProps }))
|
||||
const fullProps = computed(() => ({ ...componentProps, ...baseProps }))
|
||||
const vModel = computed({
|
||||
get: () => baseProps.modelValue,
|
||||
set: (value) => {
|
||||
@@ -186,7 +187,7 @@ const propsToSelect = computed(() => Object.keys(componentProps).map((key) => {
|
||||
const code = computed(() => {
|
||||
let code = `\`\`\`html
|
||||
<${name}`
|
||||
for (const [key, value] of Object.entries(componentProps)) {
|
||||
for (const [key, value] of Object.entries(fullProps.value)) {
|
||||
if (value === 'undefined' || value === null) {
|
||||
continue
|
||||
}
|
||||
@@ -206,7 +207,7 @@ const code = computed(() => {
|
||||
code += `>
|
||||
${props.code}</${name}>`
|
||||
} else {
|
||||
code += `>${props.code}</${name}>`
|
||||
code += `>${props.code.endsWith('>') ? `${props.code}\n` : props.code}</${name}>`
|
||||
}
|
||||
} else {
|
||||
code += ' />'
|
||||
@@ -235,16 +236,27 @@ function renderObject (obj: any) {
|
||||
|
||||
const shikiHighlighter = useShikiHighlighter({})
|
||||
const codeHighlighter = async (code: string, lang: string, theme: any, highlights: number[]) => shikiHighlighter.getHighlightedAST(code, lang, theme, { highlights })
|
||||
const { data: ast } = await useAsyncData(`${name}-ast-${JSON.stringify({ props: componentProps, slots: props.slots })}`, () => transformContent('content:_markdown.md', code.value, {
|
||||
markdown: {
|
||||
highlight: {
|
||||
highlighter: codeHighlighter,
|
||||
theme: {
|
||||
light: 'material-theme-lighter',
|
||||
default: 'material-theme',
|
||||
dark: 'material-theme-palenight'
|
||||
}
|
||||
const { data: ast } = await useAsyncData(
|
||||
`${name}-ast-${JSON.stringify({ props: componentProps, slots: props.slots })}`,
|
||||
async () => {
|
||||
let formatted = ''
|
||||
try {
|
||||
formatted = await $prettier.format(code.value) || code.value
|
||||
} catch (error) {
|
||||
formatted = code.value
|
||||
}
|
||||
}
|
||||
}), { watch: [code] })
|
||||
|
||||
return transformContent('content:_markdown.md', formatted, {
|
||||
markdown: {
|
||||
highlight: {
|
||||
highlighter: codeHighlighter,
|
||||
theme: {
|
||||
light: 'material-theme-lighter',
|
||||
default: 'material-theme',
|
||||
dark: 'material-theme-palenight'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}, { watch: [code] })
|
||||
</script>
|
||||
|
||||
@@ -5,8 +5,9 @@
|
||||
</template>
|
||||
|
||||
<template #error="{ error }">
|
||||
<UAlert v-if="error" icon="i-heroicons-exclamation-triangle-20-solid" :title="error" color="red" />
|
||||
<UAlert v-else icon="i-heroicons-check-circle-20-solid" title="Your email is valid" color="green" />
|
||||
<span :class="[error ? 'text-red-500 dark:text-red-400' : 'text-primary-500 dark:text-primary-400']">
|
||||
{{ error ? error : 'Your email is valid' }}
|
||||
</span>
|
||||
</template>
|
||||
</UFormGroup>
|
||||
</template>
|
||||
|
||||
@@ -38,6 +38,7 @@ Use the `color` and `variant` props to change the visual style of the Badge.
|
||||
props:
|
||||
color: 'primary'
|
||||
variant: 'solid'
|
||||
code: Badge
|
||||
---
|
||||
|
||||
Badge
|
||||
@@ -59,6 +60,7 @@ options:
|
||||
- solid
|
||||
excludedProps:
|
||||
- color
|
||||
code: Badge
|
||||
---
|
||||
|
||||
Badge
|
||||
@@ -78,6 +80,7 @@ options:
|
||||
- solid
|
||||
excludedProps:
|
||||
- color
|
||||
code: Badge
|
||||
---
|
||||
|
||||
Badge
|
||||
@@ -97,6 +100,7 @@ options:
|
||||
- solid
|
||||
excludedProps:
|
||||
- color
|
||||
code: Badge
|
||||
---
|
||||
|
||||
Badge
|
||||
@@ -110,6 +114,7 @@ Use the `size` prop to change the size of the Badge.
|
||||
---
|
||||
props:
|
||||
size: 'sm'
|
||||
code: Badge
|
||||
---
|
||||
|
||||
Badge
|
||||
@@ -126,6 +131,7 @@ props:
|
||||
rounded: 'rounded-full'
|
||||
excludedProps:
|
||||
- ui
|
||||
code: Badge
|
||||
---
|
||||
|
||||
Badge
|
||||
|
||||
@@ -36,6 +36,7 @@ Use the `color` and `variant` props to change the visual style of the Button.
|
||||
props:
|
||||
color: 'primary'
|
||||
variant: 'solid'
|
||||
code: Button
|
||||
---
|
||||
|
||||
Button
|
||||
@@ -56,9 +57,10 @@ options:
|
||||
restriction: expected
|
||||
values:
|
||||
- solid
|
||||
- ghost
|
||||
- ghost
|
||||
excludedProps:
|
||||
- color
|
||||
code: Button
|
||||
---
|
||||
|
||||
Button
|
||||
@@ -77,9 +79,10 @@ options:
|
||||
values:
|
||||
- solid
|
||||
- ghost
|
||||
- link
|
||||
- link
|
||||
excludedProps:
|
||||
- color
|
||||
code: Button
|
||||
---
|
||||
|
||||
Button
|
||||
@@ -97,9 +100,10 @@ options:
|
||||
restriction: expected
|
||||
values:
|
||||
- solid
|
||||
- link
|
||||
- link
|
||||
excludedProps:
|
||||
- color
|
||||
code: Button
|
||||
---
|
||||
|
||||
Button
|
||||
@@ -113,6 +117,7 @@ Use the `size` prop to change the size of the Button.
|
||||
---
|
||||
props:
|
||||
size: 'sm'
|
||||
code: Button
|
||||
---
|
||||
|
||||
Button
|
||||
@@ -129,6 +134,7 @@ props:
|
||||
rounded: 'rounded-full'
|
||||
excludedProps:
|
||||
- ui
|
||||
code: Button
|
||||
---
|
||||
|
||||
Button
|
||||
@@ -183,6 +189,7 @@ Use the `disabled` prop to disable the Button.
|
||||
---
|
||||
props:
|
||||
disabled: true
|
||||
code: Button
|
||||
---
|
||||
|
||||
Button
|
||||
@@ -198,6 +205,7 @@ Use the `loading-icon` prop to set a different icon or change it globally in `ui
|
||||
---
|
||||
props:
|
||||
loading: true
|
||||
code: Button
|
||||
---
|
||||
|
||||
Button
|
||||
@@ -211,6 +219,7 @@ Use the `block` prop to make the Button fill the width of its container.
|
||||
---
|
||||
props:
|
||||
block: true
|
||||
code: Button
|
||||
---
|
||||
|
||||
Button
|
||||
@@ -225,6 +234,7 @@ Use the `to` prop to make the Button a link.
|
||||
props:
|
||||
to: 'https://volta.net'
|
||||
target: '_blank'
|
||||
code: Button
|
||||
---
|
||||
|
||||
Button
|
||||
|
||||
@@ -19,7 +19,6 @@ Use the `color` and `variant` props to change the visual style of the Input.
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'input'
|
||||
placeholder: 'Search...'
|
||||
props:
|
||||
color: 'primary'
|
||||
@@ -34,7 +33,6 @@ Besides all the colors from the `ui.colors` object, you can also use the `white`
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'input'
|
||||
placeholder: 'Search...'
|
||||
props:
|
||||
color: 'white'
|
||||
@@ -49,7 +47,6 @@ excludedProps:
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'input'
|
||||
placeholder: 'Search...'
|
||||
props:
|
||||
color: 'gray'
|
||||
@@ -65,8 +62,6 @@ Use the `size` prop to change the size of the Input.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'input'
|
||||
props:
|
||||
size: 'sm'
|
||||
---
|
||||
@@ -80,8 +75,6 @@ We have improved the implementation of certain types such as [Checkbox](/forms/c
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'input'
|
||||
props:
|
||||
type: 'password'
|
||||
---
|
||||
@@ -93,8 +86,6 @@ Use the `placeholder` prop to set a placeholder text.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'input'
|
||||
props:
|
||||
placeholder: 'Search...'
|
||||
---
|
||||
@@ -109,7 +100,6 @@ Use the `leading` and `trailing` props to set the icon position or the `leading-
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'input'
|
||||
placeholder: 'Search...'
|
||||
props:
|
||||
icon: 'i-heroicons-magnifying-glass-20-solid'
|
||||
@@ -134,7 +124,6 @@ Use the `disabled` prop to disable the Input.
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'input'
|
||||
placeholder: 'Search...'
|
||||
props:
|
||||
disabled: true
|
||||
@@ -150,7 +139,6 @@ Use the `loading-icon` prop to set a different icon or change it globally in `ui
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'input'
|
||||
placeholder: 'Searching...'
|
||||
props:
|
||||
loading: true
|
||||
@@ -171,7 +159,6 @@ Use the `#leading` slot to set the content of the leading icon.
|
||||
slots:
|
||||
leading: <UAvatar src="https://avatars.githubusercontent.com/u/739984?v=4" size="3xs" />
|
||||
baseProps:
|
||||
name: 'input'
|
||||
placeholder: 'Search...'
|
||||
---
|
||||
|
||||
@@ -188,7 +175,6 @@ Use the `#trailing` slot to set the content of the trailing icon.
|
||||
slots:
|
||||
trailing: <span class="text-gray-500 dark:text-gray-400 text-xs">EUR</span>
|
||||
baseProps:
|
||||
name: 'input'
|
||||
placeholder: 'Search...'
|
||||
---
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ Use the `color` and `variant` props to change the visual style of the Textarea.
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'textarea'
|
||||
placeholder: 'Search...'
|
||||
props:
|
||||
color: 'primary'
|
||||
@@ -34,7 +33,6 @@ Besides all the colors from the `ui.colors` object, you can also use the `white`
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'textarea'
|
||||
placeholder: 'Search...'
|
||||
props:
|
||||
color: 'white'
|
||||
@@ -49,7 +47,6 @@ excludedProps:
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'textarea'
|
||||
placeholder: 'Search...'
|
||||
props:
|
||||
color: 'gray'
|
||||
@@ -66,7 +63,6 @@ Use the `size` prop to change the size of the Textarea.
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'textarea'
|
||||
props:
|
||||
size: 'sm'
|
||||
---
|
||||
@@ -78,8 +74,6 @@ Use the `placeholder` prop to set a placeholder text.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'textarea'
|
||||
props:
|
||||
placeholder: 'Search...'
|
||||
---
|
||||
@@ -92,7 +86,6 @@ Use the `rows` prop to set the number of rows of the Textarea.
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'input'
|
||||
placeholder: 'Search...'
|
||||
props:
|
||||
rows: 1
|
||||
@@ -106,7 +99,6 @@ Use the `disabled` prop to disable the Textarea.
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'input'
|
||||
placeholder: 'Search...'
|
||||
props:
|
||||
disabled: true
|
||||
@@ -120,7 +112,6 @@ Use the `autoresize` prop to enable the autoresize. Writing more lines than the
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'input'
|
||||
placeholder: 'Search...'
|
||||
modelValue: 'Here is an autoresize Textarea, write new lines to make the Textarea grow up...'
|
||||
props:
|
||||
@@ -135,7 +126,6 @@ Use the `resize` prop to enable the resize control.
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'input'
|
||||
placeholder: 'Search...'
|
||||
props:
|
||||
resize: true
|
||||
|
||||
@@ -27,7 +27,6 @@ Use the `color` and `variant` props to change the visual style of the Select.
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'select'
|
||||
options:
|
||||
- 'United States'
|
||||
- 'Canada'
|
||||
@@ -45,7 +44,6 @@ Besides all the colors from the `ui.colors` object, you can also use the `white`
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'select'
|
||||
options:
|
||||
- 'United States'
|
||||
- 'Canada'
|
||||
@@ -63,7 +61,6 @@ excludedProps:
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'select'
|
||||
options:
|
||||
- 'United States'
|
||||
- 'Canada'
|
||||
@@ -83,7 +80,6 @@ Use the `size` prop to change the size of the Select.
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'select'
|
||||
options:
|
||||
- 'United States'
|
||||
- 'Canada'
|
||||
@@ -100,7 +96,6 @@ Use the `placeholder` prop to set a placeholder text.
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'select'
|
||||
options:
|
||||
- 'United States'
|
||||
- 'Canada'
|
||||
@@ -119,7 +114,6 @@ Use the `trailing-icon` prop to set a different icon or change it globally in `u
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'select'
|
||||
options:
|
||||
- 'United States'
|
||||
- 'Canada'
|
||||
@@ -147,7 +141,6 @@ Use the `disabled` prop to disable the Select.
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'select'
|
||||
options:
|
||||
- 'United States'
|
||||
- 'Canada'
|
||||
@@ -169,7 +162,6 @@ Use the `loading-icon` prop to set a different icon or change it globally in `ui
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'select'
|
||||
options:
|
||||
- 'United States'
|
||||
- 'Canada'
|
||||
@@ -194,7 +186,6 @@ Use the `#leading` slot to set the content of the leading icon.
|
||||
slots:
|
||||
leading: <UAvatar src="https://avatars.githubusercontent.com/u/739984?v=4" size="3xs" />
|
||||
baseProps:
|
||||
name: 'select'
|
||||
options:
|
||||
- 'United States'
|
||||
- 'Canada'
|
||||
@@ -215,7 +206,6 @@ Use the `#trailing` slot to set the content of the trailing icon.
|
||||
slots:
|
||||
trailing: <UIcon name="i-heroicons-arrows-up-down-20-solid" />
|
||||
baseProps:
|
||||
name: 'input'
|
||||
placeholder: 'Search...'
|
||||
---
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@ Use the `label` prop to display a label on the right.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'checkbox1'
|
||||
props:
|
||||
label: 'Label'
|
||||
---
|
||||
@@ -32,7 +30,6 @@ Use the `color` prop to change the style of the Checkbox.
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'checkbox2'
|
||||
label: 'Label'
|
||||
props:
|
||||
color: 'primary'
|
||||
@@ -45,8 +42,6 @@ Use the `required` prop to display a red star next to the label.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'checkbox3'
|
||||
props:
|
||||
label: 'Label'
|
||||
required: true
|
||||
@@ -59,8 +54,6 @@ Use the `help` prop to display some text under the Checkbox.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'checkbox4'
|
||||
props:
|
||||
label: 'Label'
|
||||
help: 'Please check this box'
|
||||
@@ -73,9 +66,6 @@ Use the `disabled` prop to disable the Checkbox.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'checkbox4'
|
||||
modelValue: true
|
||||
props:
|
||||
disabled: true
|
||||
---
|
||||
@@ -91,8 +81,6 @@ Use the `#label` slot to override the content of the label.
|
||||
---
|
||||
slots:
|
||||
label: <span class="italic">Label</span>
|
||||
baseProps:
|
||||
name: 'checkbox5'
|
||||
---
|
||||
|
||||
#label
|
||||
|
||||
@@ -18,8 +18,6 @@ Use the `label` prop to display a label on the right.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'radio1'
|
||||
props:
|
||||
label: 'Label'
|
||||
---
|
||||
@@ -32,7 +30,6 @@ Use the `color` prop to change the style of the Radio.
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'radio2'
|
||||
label: 'Label'
|
||||
props:
|
||||
color: 'primary'
|
||||
@@ -45,8 +42,6 @@ Use the `required` prop to display a red star next to the label.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'radio3'
|
||||
props:
|
||||
label: 'Label'
|
||||
required: true
|
||||
@@ -59,8 +54,6 @@ Use the `help` prop to display some text under the Radio.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'radio4'
|
||||
props:
|
||||
label: 'Label'
|
||||
help: 'Please choose one'
|
||||
@@ -74,9 +67,7 @@ Use the `disabled` prop to disable the Radio.
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'radio5'
|
||||
label: 'Label'
|
||||
value: true
|
||||
props:
|
||||
disabled: true
|
||||
---
|
||||
@@ -92,8 +83,6 @@ Use the `#label` slot to override the content of the label.
|
||||
---
|
||||
slots:
|
||||
label: <span class="italic">Label</span>
|
||||
baseProps:
|
||||
name: 'radio6'
|
||||
---
|
||||
|
||||
#label
|
||||
|
||||
@@ -19,7 +19,6 @@ Use the `color` prop to change the visual style of the Range.
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: range'
|
||||
placeholder: 'Search...'
|
||||
props:
|
||||
color: 'primary'
|
||||
@@ -32,8 +31,6 @@ Use the `size` prop to change the size of the Range.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'range'
|
||||
props:
|
||||
size: 'md'
|
||||
---
|
||||
@@ -45,8 +42,6 @@ Use the `disabled` prop to disable the Range.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'range'
|
||||
props:
|
||||
disabled: true
|
||||
---
|
||||
@@ -58,8 +53,6 @@ Use the `min` and `max` prop to configure the Range.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'range'
|
||||
props:
|
||||
min: 0
|
||||
max: 100
|
||||
@@ -72,8 +65,6 @@ Use the `step` prop to change the step increment.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'range'
|
||||
props:
|
||||
step: 20
|
||||
---
|
||||
|
||||
@@ -10,13 +10,12 @@ links:
|
||||
|
||||
## Usage
|
||||
|
||||
Use the FormGroup component around an [Input](/forms/input), [Textarea](/forms/textarea), [Select](/forms/select) or a [SelectMenu](/forms/select-menu) with the `name` prop to automatically associate a `<label>` element with the form element.
|
||||
Use the FormGroup component around an [Input](/forms/input), [Textarea](/forms/textarea), [Select](/forms/select) or a [SelectMenu](/forms/select-menu) with a `label`. The `<label>` will automatically be associated with the form element so it gets focused on click.
|
||||
|
||||
::component-card
|
||||
---
|
||||
props:
|
||||
label: 'Email'
|
||||
name: 'email'
|
||||
code: >-
|
||||
|
||||
<UInput placeholder="you@example.com" icon="i-heroicons-envelope" />
|
||||
@@ -32,8 +31,6 @@ Use the `required` prop to indicate that the form element is required.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'group-required'
|
||||
props:
|
||||
label: 'Email'
|
||||
required: true
|
||||
@@ -52,8 +49,6 @@ Use the `description` prop to display a description below the label.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'group-description'
|
||||
props:
|
||||
label: 'Email'
|
||||
description: "We'll only use this for spam."
|
||||
@@ -72,8 +67,6 @@ Use the `hint` prop to display a hint above the form element.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'group-hint'
|
||||
props:
|
||||
label: 'Email'
|
||||
hint: 'Optional'
|
||||
@@ -92,8 +85,6 @@ Use the `help` prop to display an help message below the form element.
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'group-help'
|
||||
props:
|
||||
label: 'Email'
|
||||
help: 'We will never share your email with anyone else.'
|
||||
@@ -122,8 +113,6 @@ You can also use the `error` prop as a boolean to mark the form element as inval
|
||||
|
||||
::component-card
|
||||
---
|
||||
baseProps:
|
||||
name: 'group-error'
|
||||
props:
|
||||
label: 'Email'
|
||||
error: true
|
||||
|
||||
@@ -163,7 +163,7 @@ You can also highlight the matches in the command by setting the `fuse.fuseOptio
|
||||
```
|
||||
|
||||
::callout{icon="i-heroicons-light-bulb"}
|
||||
Try it yourself in this documentation's search by pressing :kbd{value="meta"} :kbd{value="K" class="ml-1"}.
|
||||
Try it yourself in this documentation's search by pressing :shortcut{value="meta"} :shortcut{value="K" class="ml-1"}.
|
||||
::
|
||||
|
||||
## Async search
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"nuxt-cloudflare-analytics": "^1.0.8",
|
||||
"nuxt-component-meta": "^0.5.4",
|
||||
"nuxt-og-image": "^2.1.2",
|
||||
"prettier": "^3.0.3",
|
||||
"typescript": "^5.2.2",
|
||||
"ufo": "^1.3.1",
|
||||
"v-calendar": "^3.1.1",
|
||||
|
||||
67
docs/plugins/prettier.ts
Normal file
67
docs/plugins/prettier.ts
Normal file
@@ -0,0 +1,67 @@
|
||||
import type { Options } from 'prettier'
|
||||
import PrettierWorker from '@/workers/prettier.js?worker&inline'
|
||||
|
||||
export interface SimplePrettier {
|
||||
format: (source: string, options?: Options) => Promise<string>;
|
||||
}
|
||||
|
||||
function createPrettierWorkerApi (worker: Worker): SimplePrettier {
|
||||
let counter = 0
|
||||
const handlers = {}
|
||||
|
||||
worker.addEventListener('message', (event) => {
|
||||
const { uid, message, error } = event.data
|
||||
|
||||
if (!handlers[uid]) {
|
||||
return
|
||||
}
|
||||
|
||||
const [resolve, reject] = handlers[uid]
|
||||
delete handlers[uid]
|
||||
|
||||
if (error) {
|
||||
reject(error)
|
||||
} else {
|
||||
resolve(message)
|
||||
}
|
||||
})
|
||||
|
||||
function postMessage<T> (message) {
|
||||
const uid = ++counter
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
handlers[uid] = [resolve, reject]
|
||||
worker.postMessage({ uid, message })
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
format (source: string, options?: Options) {
|
||||
return postMessage({ type: 'format', source, options })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default defineNuxtPlugin({
|
||||
async setup () {
|
||||
let prettier: SimplePrettier
|
||||
if (process.server) {
|
||||
const prettierModule = await import('prettier')
|
||||
prettier = {
|
||||
format (source, options = {
|
||||
parser: 'markdown'
|
||||
}) {
|
||||
return prettierModule.format(source, options)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const worker = new PrettierWorker()
|
||||
prettier = createPrettierWorkerApi(worker)
|
||||
}
|
||||
|
||||
return {
|
||||
provide: {
|
||||
prettier
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
29
docs/workers/prettier.js
Normal file
29
docs/workers/prettier.js
Normal file
@@ -0,0 +1,29 @@
|
||||
/* eslint-disable no-undef */
|
||||
import('https://unpkg.com/prettier@3.0.3/standalone.js')
|
||||
import('https://unpkg.com/prettier@3.0.3/plugins/html.js')
|
||||
import('https://unpkg.com/prettier@3.0.3/plugins/markdown.js')
|
||||
|
||||
self.onmessage = async function (event) {
|
||||
self.postMessage({
|
||||
uid: event.data.uid,
|
||||
message: await handleMessage(event.data.message)
|
||||
})
|
||||
}
|
||||
|
||||
function handleMessage (message) {
|
||||
switch (message.type) {
|
||||
case 'format':
|
||||
return handleFormatMessage(message)
|
||||
}
|
||||
}
|
||||
|
||||
async function handleFormatMessage (message) {
|
||||
const { options, source } = message
|
||||
const formatted = await prettier.format(source, {
|
||||
parser: 'markdown',
|
||||
plugins: prettierPlugins,
|
||||
...options
|
||||
})
|
||||
|
||||
return formatted
|
||||
}
|
||||
9
pnpm-lock.yaml
generated
9
pnpm-lock.yaml
generated
@@ -172,6 +172,9 @@ importers:
|
||||
nuxt-og-image:
|
||||
specifier: ^2.1.2
|
||||
version: 2.1.2(rollup@3.29.1)(vue@3.3.4)
|
||||
prettier:
|
||||
specifier: ^3.0.3
|
||||
version: 3.0.3
|
||||
typescript:
|
||||
specifier: ^5.2.2
|
||||
version: 5.2.2
|
||||
@@ -9873,6 +9876,12 @@ packages:
|
||||
engines: {node: '>= 0.8.0'}
|
||||
dev: true
|
||||
|
||||
/prettier@3.0.3:
|
||||
resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/pretty-bytes@6.1.1:
|
||||
resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==}
|
||||
engines: {node: ^14.13.1 || >=16.0.0}
|
||||
|
||||
Reference in New Issue
Block a user