diff --git a/docs/app/components/content/ComponentCode.vue b/docs/app/components/content/ComponentCode.vue
index 80cae498..fbadd81d 100644
--- a/docs/app/components/content/ComponentCode.vue
+++ b/docs/app/components/content/ComponentCode.vue
@@ -2,6 +2,7 @@
import json5 from 'json5'
import { upperFirst, camelCase } from 'scule'
import * as theme from '#build/ui'
+import { get, set } from '#ui/utils'
const props = defineProps<{
/** List of props to ignore */
@@ -20,32 +21,54 @@ const name = `U${upperFirst(camelName)}`
const componentProps = reactive({ ...(props.props || {}) })
+function getComponentProp(name: string) {
+ return get(componentProps, name)
+}
+
+function setComponentProp(name: string, value: any) {
+ set(componentProps, name, value)
+}
+
const componentTheme = theme[camelName]
const meta = await fetchComponentMeta(name as any)
-const options = computed(() => Object.keys(props.props || {}).filter((key) => {
- return !props.ignore?.includes(key)
-}).map((key) => {
- const prop = meta?.meta?.props?.find((prop: any) => prop.name === key)
- const items = props.items?.[key]?.length
- ? props.items[key].map(item => ({
- value: item,
- label: item
- }))
- : prop?.type === 'boolean'
- ? [{ value: true, label: 'true' }, { value: false, label: 'false' }]
- : Object.keys(componentTheme?.variants?.[key] || {}).map(variant => ({
- value: variant,
- label: variant,
- chip: key === 'color' ? { color: variant } : undefined
- })).filter(variant => key === 'color' ? !['error'].includes(variant.value) : true)
+function mapKeys(obj, parentKey = '') {
+ return Object.entries(obj).flatMap(([key, value]) => {
+ if (typeof value === 'object' && !Array.isArray(value)) {
+ return mapKeys(value, key)
+ }
- return {
- name: key,
- label: key,
- items
- }
-}))
+ const fullKey = parentKey ? `${parentKey}.${key}` : key
+
+ return !props.ignore?.includes(fullKey) ? fullKey : undefined
+ }).filter(Boolean)
+}
+
+const options = computed(() => {
+ const keys = mapKeys(props.props || {})
+
+ return keys.map((key) => {
+ const prop = meta?.meta?.props?.find((prop: any) => prop.name === key)
+ const items = props.items?.[key]?.length
+ ? props.items[key].map(item => ({
+ value: item,
+ label: item
+ }))
+ : prop?.type === 'boolean'
+ ? [{ value: true, label: 'true' }, { value: false, label: 'false' }]
+ : Object.keys(componentTheme?.variants?.[key] || {}).map(variant => ({
+ value: variant,
+ label: variant,
+ chip: key === 'color' ? { color: variant } : undefined
+ })).filter(variant => key === 'color' ? !['error'].includes(variant.value) : true)
+
+ return {
+ name: key,
+ label: key,
+ items
+ }
+ })
+})
const code = computed(() => {
let code = `\`\`\`vue
@@ -151,7 +174,14 @@ const { data: ast } = await useAsyncData(`component-code-${name}-${JSON.stringif
/>
-
+
diff --git a/src/runtime/utils/index.ts b/src/runtime/utils/index.ts
index 39d2e6fa..a39be2d9 100644
--- a/src/runtime/utils/index.ts
+++ b/src/runtime/utils/index.ts
@@ -40,6 +40,21 @@ export function get(object: Record, path: (string | number)[] | str
return result !== undefined ? result : defaultValue
}
+export function set(object: Record, path: (string | number)[] | string, value: any): void {
+ if (typeof path === 'string') {
+ path = path.split('.').map((key) => {
+ const numKey = Number(key)
+ return Number.isNaN(numKey) ? key : numKey
+ })
+ }
+
+ path.reduce((acc, key, i) => {
+ if (acc[key] === undefined) acc[key] = {}
+ if (i === path.length - 1) acc[key] = value
+ return acc[key]
+ }, object)
+}
+
export function looseToNumber(val: any): any {
const n = Number.parseFloat(val)
return Number.isNaN(n) ? val : n