mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-14 12:14:41 +01:00
119 lines
2.9 KiB
Vue
119 lines
2.9 KiB
Vue
<template>
|
|
<UCard v-if="component" class="relative flex flex-col" body-class="px-4 py-5 sm:p-6 relative" footer-class="px-4 py-4 sm:px-6 flex-1 lg:overflow-y-auto" style="max-height: calc(100vh - 10rem);">
|
|
<div class="flex justify-center">
|
|
<component :is="is" v-bind="boundProps" />
|
|
</div>
|
|
|
|
<template v-if="props.length" #footer>
|
|
<div class="space-y-3">
|
|
<UInputGroup
|
|
v-for="prop of props"
|
|
:key="prop.key"
|
|
class="capitalize"
|
|
:name="prop.key"
|
|
:label="prop.key"
|
|
>
|
|
<UToggle
|
|
v-if="prop.type === 'Boolean'"
|
|
v-model="prop.value"
|
|
:name="prop.key"
|
|
:label="prop.key"
|
|
/>
|
|
<USelect
|
|
v-else-if="prop.values"
|
|
v-model="prop.value"
|
|
:name="prop.key"
|
|
placeholder="Choose one..."
|
|
:options="prop.values"
|
|
size="sm"
|
|
/>
|
|
<UInput
|
|
v-else-if="prop.type === 'String'"
|
|
v-model="prop.value"
|
|
:name="prop.key"
|
|
size="sm"
|
|
autocomplete="off"
|
|
/>
|
|
<UInput
|
|
v-else-if="prop.type === 'Number'"
|
|
v-model="prop.value"
|
|
type="number"
|
|
:name="prop.key"
|
|
size="sm"
|
|
/>
|
|
<UTextarea
|
|
v-else
|
|
v-model="prop.value"
|
|
:name="prop.key"
|
|
size="sm"
|
|
/>
|
|
</UInputGroup>
|
|
</div>
|
|
</template>
|
|
</UCard>
|
|
</template>
|
|
|
|
<script setup>
|
|
import $ui from '#build/ui'
|
|
|
|
const nuxtApp = useNuxtApp()
|
|
const { params } = useRoute()
|
|
|
|
const is = `U${params.component}`
|
|
|
|
const component = nuxtApp.vueApp.component(is)
|
|
|
|
const { props: componentProps } = await component.__asyncLoader()
|
|
|
|
const refProps = Object.entries(componentProps).map(([key, prop]) => {
|
|
let value = typeof prop.default === 'function' ? prop.default() : prop.default
|
|
let type = prop.type
|
|
if (Array.isArray(type)) {
|
|
type = type[0].name
|
|
} else {
|
|
type = type.name
|
|
}
|
|
|
|
let values
|
|
if (prop.validator) {
|
|
const arrayRegex = prop.validator.toString().match(/\[.*\]/g, '')
|
|
if (arrayRegex) {
|
|
values = JSON.parse(arrayRegex[0].replace(/'/g, '"')).filter(Boolean)
|
|
} else {
|
|
const $uiProp = $ui[params.component.toLowerCase()][key]
|
|
if ($uiProp) {
|
|
values = Object.keys($uiProp).filter(Boolean)
|
|
}
|
|
}
|
|
}
|
|
|
|
if (value) {
|
|
if (type === 'String') {
|
|
value = value.replace(/^'(.*)'$/, '$1')
|
|
} else if (type === 'Array') {
|
|
value = JSON.stringify(value)
|
|
}
|
|
}
|
|
|
|
return {
|
|
key,
|
|
type,
|
|
value,
|
|
values
|
|
}
|
|
})
|
|
|
|
const props = ref(refProps)
|
|
const boundProps = computed(() => {
|
|
const bound = {}
|
|
for (const prop of props.value) {
|
|
try {
|
|
bound[prop.key] = prop.type === 'Array' ? JSON.parse(prop.value) : prop.value
|
|
} catch (e) {
|
|
continue
|
|
}
|
|
}
|
|
return bound
|
|
})
|
|
</script>
|