Vue Component Documentation
Add Vue documentation for a component on the site-demo documentation site: demo files, prop table integration, and MDX page wiring.
For general documentation site conventions (page structure, frontmatter, DemoBlock, PropTable, file layout), see packages/site-demo/README.md.
Prerequisites
- •The component must exist in
@lumx/vue(checkpackages/lumx-vue/src/components/) - •An MDX page should exist at
packages/site-demo/content/product/components/<component>/index.mdx - •React demos should exist in
packages/site-demo/content/product/components/<component>/react/
Steps
Step 1: Gather Context
- •Read the React demos in
content/product/components/<component>/react/ - •Read the MDX page at
content/product/components/<component>/index.mdx - •Check available Vue components by reading
packages/lumx-vue/src/components/<component>/index.ts - •Check if any Vue demos already exist in
content/product/components/<component>/vue/
Step 2: Create Vue Demo Files
Create Vue demos in content/product/components/<component>/vue/ matching each React demo.
File naming: Match the React demo numbering: demo1.vue, demo2.vue, etc.
Template structure:
<template>
<!-- Component usage -->
</template>
<script setup lang="ts">
import { ref } from 'vue'; // only if stateful
import { mdiPencil } from '@lumx/icons'; // only if icons are used
import { ComponentName, type Theme } from '@lumx/vue';
defineProps<{ theme?: Theme }>(); // only if withThemeSwitcher
</script>
When to include theme prop: Only when the corresponding DemoBlock in the MDX uses withThemeSwitcher.
Key conversion rules (React to Vue):
- •Props: camelCase to kebab-case in templates (
leftIcon->:left-icon,isDisabled->is-disabled) - •Events: React callbacks to Vue events (
onChange={handler}->@change="handler",onClick->@click) - •State:
useStatetoref()(const [checked, setChecked] = useState(false)->const checked = ref(false)) - •State updates in events:
@change="checked = $event"or@click="active = !active" - •Icons: Import from
@lumx/icons - •Missing components: If a React demo uses a component not in
@lumx/vue, substitute with available components or plain HTML - •Always verify that imported components exist in
@lumx/vuebefore using them
Step 3: Update the MDX Page
Update content/product/components/<component>/index.mdx:
- •Frontmatter: Ensure
frameworks: ['react', 'vue'] - •Rename React demo imports from
Demo1toReactDemo1if needed (multi-framework convention) - •Add Vue demo imports as
VueDemo1,VueDemo2, etc. - •Update DemoBlock to include both frameworks:
demo={{ react: ReactDemo1, vue: VueDemo1 }} - •Add Vue PropTable import using the
lumx-docs:@lumx/vue/...prefix - •Update PropTable to include Vue docs:
docs={{ react: ReactButton, vue: VueButton }}
Example MDX diff:
import ReactButton from 'lumx-docs:@lumx/react/components/button/Button';
+import VueButton from 'lumx-docs:@lumx/vue/components/button/Button';
-<PropTable docs={{ react: ReactButton }} />
+<PropTable docs={{ react: ReactButton, vue: VueButton }} />
Step 4: Verify
- •All Vue demo files created, matching the React demo count
- •All imports in the MDX file are correct
- •DemoBlock components reference both
reactandvuedemos - •PropTable components include both
reactandvuedoc imports - •Frontmatter includes both frameworks
Vue PropTable Docgen
The prop table documentation is auto-extracted from Vue component source files by plugins/lumx-prop-table/vue-docgen.js. It extracts:
- •Props: From the exported
*Propstype alias (e.g.,ButtonProps = VueToJSXProps<UIProps>) - •Events: From exported
emitSchemaobjects or inlineemits: [...]arrays in defineComponent options - •Slots: By detecting
slots.defaultusage in the component source
You can test the extraction for any Vue component via CLI:
node packages/site-demo/plugins/lumx-prop-table/vue-docgen.js packages/lumx-vue/src/components/<component>/<Component>.tsx
File Structure
Before (React-only)
content/product/components/<component>/ ├── react/ │ ├── demo1.tsx │ └── demo2.tsx └── index.mdx
After (both frameworks)
content/product/components/<component>/ ├── react/ │ ├── demo1.tsx │ └── demo2.tsx ├── vue/ │ ├── demo1.vue │ └── demo2.vue └── index.mdx # Updated with Vue imports, DemoBlock, and PropTable