From fe348b48c69ec60c9f703eac46fb5bb831f0c8d7 Mon Sep 17 00:00:00 2001 From: KeJun Date: Mon, 9 Oct 2023 16:44:47 +0800 Subject: [PATCH] docs(ComponentExample): automatically read code (#789) --- docs/components/content/ComponentExample.vue | 58 ++- docs/composables/useContentExamplesCode.ts | 27 ++ docs/content/1.getting-started/5.examples.md | 128 +---- docs/content/2.elements/1.accordion.md | 131 +----- docs/content/2.elements/2.alert.md | 22 +- docs/content/2.elements/6.dropdown.md | 128 +---- docs/content/2.elements/8.kbd.md | 19 +- docs/content/3.forms/1.input.md | 47 +- docs/content/3.forms/10.form.md | 255 +--------- docs/content/3.forms/2.textarea.md | 16 +- docs/content/3.forms/3.select.md | 48 +- docs/content/3.forms/4.select-menu.md | 357 +------------- docs/content/3.forms/5.checkbox.md | 16 +- docs/content/3.forms/6.radio.md | 30 +- docs/content/3.forms/7.toggle.md | 14 - docs/content/3.forms/8.range.md | 16 +- docs/content/3.forms/9.form-group.md | 43 +- docs/content/4.data/1.table.md | 438 ++---------------- .../5.navigation/1.vertical-navigation.md | 200 +------- .../content/5.navigation/2.command-palette.md | 190 +------- docs/content/5.navigation/3.pagination.md | 46 +- docs/content/5.navigation/4.tabs.md | 304 +----------- docs/content/6.overlays/1.modal.md | 177 +------ docs/content/6.overlays/2.slideover.md | 134 +----- docs/content/6.overlays/3.popover.md | 55 +-- docs/content/6.overlays/4.tooltip.md | 13 +- docs/content/6.overlays/5.context-menu.md | 37 +- docs/content/6.overlays/6.notification.md | 86 +--- docs/content/7.layout/1.card.md | 18 +- docs/content/7.layout/2.container.md | 12 +- docs/content/7.layout/3.skeleton.md | 18 +- docs/content/7.layout/4.divider.md | 69 +-- docs/modules/content-examples-code.ts | 138 ++++++ docs/nuxt.config.ts | 3 +- docs/server/api/content-examples-code.get.ts | 19 + 35 files changed, 387 insertions(+), 2925 deletions(-) create mode 100644 docs/composables/useContentExamplesCode.ts create mode 100644 docs/modules/content-examples-code.ts create mode 100644 docs/server/api/content-examples-code.get.ts diff --git a/docs/components/content/ComponentExample.vue b/docs/components/content/ComponentExample.vue index f90db16c..774e11d9 100644 --- a/docs/components/content/ComponentExample.vue +++ b/docs/components/content/ComponentExample.vue @@ -1,15 +1,44 @@ diff --git a/docs/composables/useContentExamplesCode.ts b/docs/composables/useContentExamplesCode.ts new file mode 100644 index 00000000..06030160 --- /dev/null +++ b/docs/composables/useContentExamplesCode.ts @@ -0,0 +1,27 @@ +const useContentExamplesCodeState = () => useState('content-examples-code', () => ({})) + +export async function fetchContentExampleCode (name?: string) { + if (!name) return + const state = useContentExamplesCodeState() + + if (state.value[name]?.then) { + await state.value[name] + return state.value[name] + } + if (state.value[name]) { return state.value[name] } + + // add to nitro prerender + if (process.server) { + const event = useRequestEvent() + event.node.res.setHeader( + 'x-nitro-prerender', + [event.node.res.getHeader('x-nitro-prerender'), `/api/content-examples-code/${name}.json`].filter(Boolean).join(',') + ) + } + state.value[name] = $fetch(`/api/content-examples-code/${name}.json`).then((data) => { + state.value[name] = data + }) + + await state.value[name] + return state.value[name] +} diff --git a/docs/content/1.getting-started/5.examples.md b/docs/content/1.getting-started/5.examples.md index c2405c50..f90e614f 100644 --- a/docs/content/1.getting-started/5.examples.md +++ b/docs/content/1.getting-started/5.examples.md @@ -109,43 +109,13 @@ const attrs = [{ You can use it inside a [Popover](/overlays/popover) component to display it when clicking on a [Button](/elements/button). -::component-example -#default -:date-picker-example - -#code -```vue - - - -``` -:: +:component-example{component="date-picker-example"} ### Table Here is an example of a Table component with all its features implemented. -::component-example ---- -padding: false ---- - -#default -:table-example-advanced -:: +:component-example{component="table-example-advanced" hiddenCode :padding="false" } ::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/dev/docs/components/content/examples/TableExampleAdvanced.vue"} Take a look at the component! @@ -160,14 +130,14 @@ Our theming system provides a lot of flexibility to customize the components. Here is some examples of what you can do with the [CommandPalette](/navigation/command-palette). #### Algolia - ::component-example --- padding: false +component: 'command-palette-theme-algolia' +componentProps: + class: 'max-h-[480px] rounded-md' +hiddenCode: true --- - -#default -:command-palette-theme-algolia{class="max-h-[480px] rounded-md"} :: ::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/dev/docs/components/content/themes/CommandPaletteThemeAlgolia.vue#L23"} @@ -179,10 +149,11 @@ Take a look at the component! ::component-example --- padding: false +component: 'command-palette-theme-raycast' +componentProps: + class: 'max-h-[480px] rounded-md' +hiddenCode: true --- - -#default -:command-palette-theme-raycast{class="max-h-[480px] rounded-md"} :: ::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/dev/docs/components/content/themes/CommandPaletteThemeRaycast.vue#L30"} @@ -191,81 +162,11 @@ Take a look at the component! ### VerticalNavigation -::component-example -#default -:vertical-navigation-theme-tailwind -#code -```vue - - - -``` -:: +:component-example{component="vertical-navigation-theme-tailwind"} ### Pagination -::component-example -#default -:pagination-theme-rounded -#code -```vue - - - -``` -:: +:component-example{component="pagination-theme-rounded"} ## RTL Support @@ -273,10 +174,7 @@ Here are some examples of how components look like in RTL mode. ### Pagination -::component-example -#default -:pagination-example-r-t-l -:: +:component-example{component="pagination-example-r-t-l" hiddenCode} ::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/dev/docs/components/content/examples/PaginationExampleRTL.vue"} Take a look at the component! diff --git a/docs/content/2.elements/1.accordion.md b/docs/content/2.elements/1.accordion.md index 434ac93c..d24a3dd6 100644 --- a/docs/content/2.elements/1.accordion.md +++ b/docs/content/2.elements/1.accordion.md @@ -19,31 +19,7 @@ Pass an array to the `items` prop of the Accordion component. Each item can have - `defaultOpen` - Determines whether the item is initially open or closed. - `closeOthers` - Determines whether the item click close others or not. **It only works with multiple mode**. -::component-example -#default -:accordion-example-basic - -#code -```vue - - - -``` -:: +:component-example{component="accordion-example-basic"} ### Style @@ -72,7 +48,7 @@ options: - solid - outline - ghost - - soft + - soft - link - name: size restriction: included @@ -169,112 +145,13 @@ You can use slots to customize the buttons and items content of the Accordion. Use the `#default` slot to customize the trigger buttons. You will have access to the `item`, `index`, `open` properties and `close` method in the slot scope. -::component-example -#default -:accordion-example-default-slot - -#code -```vue - - - -``` -:: +:component-example{component="accordion-example-default-slot"} ### `item` Use the `#item` slot to customize the items content or pass a `slot` property to customize a specific item. You will have access to the `item`, `index`, `open` properties and `close` method in the slot scope. -::component-example -#default -:accordion-example-item-slot - -#code -```vue - - - -``` -:: +:component-example{component="accordion-example-item-slot"} ## Props diff --git a/docs/content/2.elements/2.alert.md b/docs/content/2.elements/2.alert.md index cf543670..aba0556d 100644 --- a/docs/content/2.elements/2.alert.md +++ b/docs/content/2.elements/2.alert.md @@ -83,7 +83,7 @@ options: - name: color restriction: included values: - - white + - white excludedProps: - icon --- @@ -161,25 +161,7 @@ Use the `#title` and `#description` slots to customize the Alert. This can be handy when you want to display HTML content. To achieve this, you can define those slots and use the `v-html` directive. -::component-example -#default -:alert-example-html - -#code -```vue - -``` -:: +:component-example{component="alert-example-html"} ## Props diff --git a/docs/content/2.elements/6.dropdown.md b/docs/content/2.elements/6.dropdown.md index 06fae6f1..dcb8a6af 100644 --- a/docs/content/2.elements/6.dropdown.md +++ b/docs/content/2.elements/6.dropdown.md @@ -24,81 +24,13 @@ Pass an array of arrays to the `items` prop of the Dropdown component. Each arra You can also pass any property from the [NuxtLink](https://nuxt.com/docs/api/components/nuxt-link#props) component such as `to`, `exact`, etc. -::component-example -#default -:dropdown-example-basic - -#code -```vue - - - -``` -:: +:component-example{component="dropdown-example-basic"} ### Mode Use the `mode` prop to switch between `click` and `hover` modes. -::component-example -#default -:dropdown-example-mode - -#code -```vue - - - -``` -:: +:component-example{component="dropdown-example-mode"} ## Slots @@ -106,61 +38,7 @@ const items = [ Use the `#item` slot to customize the items content or pass a `slot` property to customize a specific item. You will have access to the `item` property in the slot scope. -::component-example -#default -:dropdown-example-slot - -#code -```vue - - - -``` -:: +:component-example{component="dropdown-example-slot"} ## Props diff --git a/docs/content/2.elements/8.kbd.md b/docs/content/2.elements/8.kbd.md index 4e109507..eb03f953 100644 --- a/docs/content/2.elements/8.kbd.md +++ b/docs/content/2.elements/8.kbd.md @@ -32,24 +32,7 @@ props: As explained in the [Shortcuts](/getting-started/shortcuts) page, you can use the `metaSymbol` property of the `useShortcuts` composable to display the meta key according to the user's OS. -::component-example -#default -:kbd-example - -#code -```vue - - - -``` -:: +:component-example{component="kbd-example"} ### Size diff --git a/docs/content/3.forms/1.input.md b/docs/content/3.forms/1.input.md index 5a5a9d15..4bdb9114 100644 --- a/docs/content/3.forms/1.input.md +++ b/docs/content/3.forms/1.input.md @@ -10,21 +10,7 @@ links: Use a `v-model` to make the Input reactive. -::component-example -#default -:input-example - -#code -```vue - - - -``` -:: +:component-example{component="input-example"} ### Style @@ -119,8 +105,8 @@ options: - name: color restriction: included values: - - white - - gray + - white + - gray excludedProps: - icon --- @@ -197,32 +183,7 @@ baseProps: You can for example create a clearable Input by injecting a [Button](/elements/button) in the `trailing` slot that displays when some text is entered. -::component-example -#default -:input-example-clearable - -#code -```vue - - - -``` -:: +:component-example{component="input-example-clearable"} ::callout{icon="i-heroicons-exclamation-triangle-20-solid"} As leading and trailing icons are wrapped around a `pointer-events-none` class, if you inject a clickable element in the slot, you need to remove this class to make it clickable by adding `:ui="{ icon: { trailing: { pointer: '' } } }"` to the Input. diff --git a/docs/content/3.forms/10.form.md b/docs/content/3.forms/10.form.md index d204b957..32e259c7 100644 --- a/docs/content/3.forms/10.form.md +++ b/docs/content/3.forms/10.form.md @@ -17,54 +17,7 @@ The Form component requires the `validate` and `state` props for form validation - `message` - the error message to display. - `path` - the path to the form element matching the `name`. -::component-example -#default -:form-example-basic{class="space-y-4 w-60"} - -#code -```vue - - - -``` -:: +:component-example{component="form-example-basic" :componentProps='{"class": "space-y-4 w-60"}'} ## Schema @@ -72,213 +25,20 @@ You can provide a schema from [Yup](#yup), [Zod](#zod) or [Joi](#joi), [Valibot] ### Yup -::component-example -#default -:form-example-yup{class="space-y-4 w-60"} - -#code -```vue - - - -``` -:: +:component-example{component="form-example-yup" :componentProps='{"class": "space-y-4 w-60"}'} ### Zod -::component-example -#default -:form-example-zod{class="space-y-4 w-60"} - -#code -```vue - - - -``` -:: +:component-example{component="form-example-zod" :componentProps='{"class": "space-y-4 w-60"}'} ### Joi -::component-example -#default -:form-example-joi{class="space-y-4 w-60"} +:component-example{component="form-example-joi" :componentProps='{"class": "space-y-4 w-60"}'} -#code -```vue - - - -``` -:: ### Valibot -::component-example -#default -:form-example-valibot{class="space-y-4 w-60"} - -#code -```vue - - - -``` -:: +:component-example{component="form-example-valibot" :componentProps='{"class": "space-y-4 w-60"}'} ## Other libraries @@ -372,10 +132,7 @@ async function submit (event: FormSubmitEvent) { The Form component automatically triggers validation upon `submit`, `input`, `blur` or `change` events. This ensures that any errors are displayed as soon as the user interacts with the form elements. You can control when validation happens this using the `validate-on` prop. -::component-example -#default -:form-example-elements{class="space-y-4 w-60"} -:: +:component-example{component="form-example-elements" :componentProps='{"class": "space-y-4 w-60"}' hiddenCode } ::callout{icon="i-simple-icons-github" to="https://github.com/nuxt/ui/blob/dev/docs/components/content/examples/FormExampleElements.vue"} Take a look at the component! diff --git a/docs/content/3.forms/2.textarea.md b/docs/content/3.forms/2.textarea.md index 0b49f78e..b03a8210 100644 --- a/docs/content/3.forms/2.textarea.md +++ b/docs/content/3.forms/2.textarea.md @@ -10,21 +10,7 @@ links: Use a `v-model` to make the Textarea reactive. -::component-example -#default -:textarea-example - -#code -```vue - - - -``` -:: +:component-example{component="textarea-example"} ### Style diff --git a/docs/content/3.forms/3.select.md b/docs/content/3.forms/3.select.md index 03181cd3..2b85a39a 100644 --- a/docs/content/3.forms/3.select.md +++ b/docs/content/3.forms/3.select.md @@ -12,55 +12,13 @@ The Select component is a wrapper around the native `