diff --git a/playground/nuxt.schema.ts b/playground/nuxt.schema.ts index 4b43711..f562c3a 100644 --- a/playground/nuxt.schema.ts +++ b/playground/nuxt.schema.ts @@ -1,8 +1,14 @@ -import { field } from '../src/theme' +import { field, group } from '../src/theme' export default defineNuxtSchema({ appConfig: { - someConfig: field({ type: 'string', default: 'schema default' }), - configFromNuxtSchema: field('boolean', true) + parent: group({ + title: 'Parent', + description: 'Parent description', + fields: { + someConfig: field({ type: 'string', default: 'schema default' }), + configFromNuxtSchema: field({ type: 'boolean' }) + } + }) } }) diff --git a/src/runtime/composables/useStudio.ts b/src/runtime/composables/useStudio.ts index a368752..bb0dc93 100644 --- a/src/runtime/composables/useStudio.ts +++ b/src/runtime/composables/useStudio.ts @@ -57,6 +57,12 @@ export const useStudio = () => { const syncPreviewAppConfig = (appConfig?: any) => { const _appConfig = callWithNuxt(nuxtApp, useAppConfig) + + // Set dynamic icons for preview if user is using @nuxt/ui + if (_appConfig?.ui) { + _appConfig.ui.icons = { ..._appConfig.ui.icons, dynamic: true } + } + // Using `defu` to merge with initial config // This is important to revert to default values for missing properties deepAssign(_appConfig, defu(appConfig, initialAppConfig)) diff --git a/src/theme.ts b/src/theme.ts index 1e66567..6a2d3e9 100644 --- a/src/theme.ts +++ b/src/theme.ts @@ -148,39 +148,54 @@ const supportedFields: { [key in InputsTypes]: Schema } = { export type StudioFieldData = PartialSchema & { - type: keyof typeof supportedFields + type?: keyof typeof supportedFields icon?: string + fields?: { [key: string]: InputValue } } /** - * Declares a Nuxt Studio compatible configuration field. + * Helper to build aNuxt Studio compatible configuration schema. * Supports all type of fields provided by Nuxt Studio and all fields supported from Untyped Schema interface. */ -export function field ( - type: keyof typeof supportedFields | StudioFieldData, - defaultValue?: any -): InputValue { - // Custom `type` field should get overwritten by native Schema ones at this stage - const result = defu( - supportedFields[typeof type === 'string' ? type : type.type], - type - ) as StudioFieldData +export function field (schema: StudioFieldData): InputValue { + if (!schema.type) { + throw new Error(`Missing type in schema ${JSON.stringify(schema)}`) + } - // Init tags - if (!result.tags) { result.tags = [] } + // copy of supportedFields + const base = JSON.parse(JSON.stringify(supportedFields[schema.type])) + const result = defu(base, schema) - // Cast `icon` into its tag + if (!result.tags) { + result.tags = [] + } if (result.icon) { result.tags.push(`@studioIcon ${result.icon}`) delete result.icon } + return { + $schema: result + } +} + +export function group (schema: StudioFieldData): InputValue { + const result = { ...schema } + + if (result.icon) { + result.tags = [`@studioIcon ${result.icon}`] + delete result.icon + } - // Cast default value passed as 2nd parameter - if (defaultValue) { - result.default = defaultValue + const fields: Record = {} + if (result.fields) { + for (const key of Object.keys(result.fields)) { + fields[key] = result.fields[key] + } + delete result.fields } return { - $schema: result + $schema: result, + ...fields } }