mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-25 01:10:40 +01:00
docs(ComponentCode): handle objects
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
import json5 from 'json5'
|
import json5 from 'json5'
|
||||||
import { upperFirst, camelCase } from 'scule'
|
import { upperFirst, camelCase } from 'scule'
|
||||||
import * as theme from '#build/ui'
|
import * as theme from '#build/ui'
|
||||||
|
import { get, set } from '#ui/utils'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
/** List of props to ignore */
|
/** List of props to ignore */
|
||||||
@@ -20,32 +21,54 @@ const name = `U${upperFirst(camelName)}`
|
|||||||
|
|
||||||
const componentProps = reactive({ ...(props.props || {}) })
|
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 componentTheme = theme[camelName]
|
||||||
const meta = await fetchComponentMeta(name as any)
|
const meta = await fetchComponentMeta(name as any)
|
||||||
|
|
||||||
const options = computed(() => Object.keys(props.props || {}).filter((key) => {
|
function mapKeys(obj, parentKey = '') {
|
||||||
return !props.ignore?.includes(key)
|
return Object.entries(obj).flatMap(([key, value]) => {
|
||||||
}).map((key) => {
|
if (typeof value === 'object' && !Array.isArray(value)) {
|
||||||
const prop = meta?.meta?.props?.find((prop: any) => prop.name === key)
|
return mapKeys(value, 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 {
|
const fullKey = parentKey ? `${parentKey}.${key}` : key
|
||||||
name: key,
|
|
||||||
label: key,
|
return !props.ignore?.includes(fullKey) ? fullKey : undefined
|
||||||
items
|
}).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(() => {
|
const code = computed(() => {
|
||||||
let code = `\`\`\`vue
|
let code = `\`\`\`vue
|
||||||
@@ -151,7 +174,14 @@ const { data: ast } = await useAsyncData(`component-code-${name}-${JSON.stringif
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</USelectMenu>
|
</USelectMenu>
|
||||||
<UInput v-else v-model="componentProps[option.name]" color="gray" variant="soft" :ui="{ base: 'rounded rounded-l-none' }" />
|
<UInput
|
||||||
|
v-else
|
||||||
|
:model-value="getComponentProp(option.name)"
|
||||||
|
color="gray"
|
||||||
|
variant="soft"
|
||||||
|
:ui="{ base: 'rounded rounded-l-none' }"
|
||||||
|
@update:model-value="setComponentProp(option.name, $event)"
|
||||||
|
/>
|
||||||
</UFormField>
|
</UFormField>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -40,6 +40,21 @@ export function get(object: Record<string, any>, path: (string | number)[] | str
|
|||||||
return result !== undefined ? result : defaultValue
|
return result !== undefined ? result : defaultValue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function set(object: Record<string, any>, 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 {
|
export function looseToNumber(val: any): any {
|
||||||
const n = Number.parseFloat(val)
|
const n = Number.parseFloat(val)
|
||||||
return Number.isNaN(n) ? val : n
|
return Number.isNaN(n) ? val : n
|
||||||
|
|||||||
Reference in New Issue
Block a user