From dd532bb110bbbe0cbdba40a9c9bd09cdc36c7e6a Mon Sep 17 00:00:00 2001 From: Benjamin Canac Date: Wed, 17 Jul 2024 15:26:05 +0200 Subject: [PATCH] docs(ComponentCode): handle objects --- docs/app/components/content/ComponentCode.vue | 76 +++++++++++++------ src/runtime/utils/index.ts | 15 ++++ 2 files changed, 68 insertions(+), 23 deletions(-) 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