Skip to content

Commit

Permalink
feat: support experimental schema.i18n()
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed May 14, 2023
1 parent 7a8f653 commit d4e17e2
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 16 deletions.
20 changes: 19 additions & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ namespace Schema {
role?: string
extra?: any
link?: string
description?: string
description?: string | Dict<string>
comment?: string
pattern?: { source: string; flags?: string }
max?: number
Expand Down Expand Up @@ -145,6 +145,7 @@ interface Schema<S = any, T = S> extends Schema.Base<T> {
set(key: string, value: Schema): Schema<S, T>
push(value: Schema): Schema<S, T>
simplify(value?: any): any
i18n(messages: Dict): Schema<S, T>
}

Schema.prototype = Object.create(Function.prototype)
Expand Down Expand Up @@ -176,6 +177,23 @@ Schema.prototype.push = function push(value) {
return this
}

Schema.prototype.i18n = function i18n(messages) {
this.meta.description = valueMap(messages, (data) => {
if (!data || typeof data === 'string') return data
return data.$description
})
if (this.type === 'object') {
for (const key in this.dict!) {
this.dict[key].i18n(valueMap(messages, (data) => data?.[key]))
}
} else if (['union', 'intersect'].includes(this.type)) {
for (const item of this.list!) {
item.i18n(messages)
}
}
return this
}

for (const key of ['required', 'hidden']) {
Object.assign(Schema.prototype, {
[key](this: Schema, value = true) {
Expand Down
16 changes: 10 additions & 6 deletions packages/form/src/extensions/object.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
<template #title><slot name="title"></slot></template>
<template #desc>
<slot name="desc">
<k-markdown :source="schema?.meta.description"></k-markdown>
<k-markdown :source="description"></k-markdown>
</slot>
</template>
<template #menu><slot name="menu"></slot></template>
<template #prefix><slot name="prefix"></slot></template>
<template #suffix><slot name="suffix"></slot></template>
</schema-base>
<h2 class="k-schema-header" v-else-if="schema.meta.description">
{{ schema.meta.description }}
<h2 class="k-schema-header" v-else-if="description">
{{ description }}
</h2>
<k-schema
Expand Down Expand Up @@ -39,11 +39,11 @@ export default {
<script lang="ts" setup>
import { PropType } from 'vue'
import { Schema, useConfig } from '../utils'
import { PropType, computed } from 'vue'
import { Schema, useConfig, useI18nText } from '../utils'
import SchemaBase from '../base.vue'
defineProps({
const props = defineProps({
schema: {} as PropType<Schema>,
modelValue: {} as PropType<any>,
disabled: {} as PropType<boolean>,
Expand All @@ -54,6 +54,10 @@ defineProps({
defineEmits(['update:modelValue'])
const tt = useI18nText()
const config = useConfig()
const description = computed(() => tt(props.schema.meta.description))
</script>
6 changes: 4 additions & 2 deletions packages/form/src/extensions/radio.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
:label="item.value"
:disabled="disabled"
v-model="config"
>{{ item.meta.description || item.value }}</el-radio>
>{{ tt(item.meta.description) || item.value }}</el-radio>
</li>
</ul>
</schema-base>
Expand All @@ -20,7 +20,7 @@
<script lang="ts" setup>
import { PropType } from 'vue'
import { getChoices, Schema, useConfig } from '../utils'
import { getChoices, Schema, useConfig, useI18nText } from '../utils'
import SchemaBase from '../base.vue'
defineProps({
Expand All @@ -33,6 +33,8 @@ defineProps({
defineEmits(['update:modelValue'])
const tt = useI18nText()
const config = useConfig()
</script>
10 changes: 6 additions & 4 deletions packages/form/src/extensions/union.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
>
<template #title><slot name="title"></slot></template>
<template #desc>
<k-markdown :source="schema.meta.description"></k-markdown>
<k-markdown :source="tt(schema.meta.description)"></k-markdown>
</template>
<template #prefix>
<el-select
Expand All @@ -25,7 +25,7 @@
v-for="(item, index) in choices"
:key="index"
:value="index"
:label="item.meta.description || item.value"
:label="tt(item.meta.description) || item.value"
></el-option>
</el-select>
</template>
Expand All @@ -36,7 +36,7 @@
<script lang="ts" setup>
import { computed, PropType, ref, watch, WatchStopHandle } from 'vue'
import { check, deepEqual, getChoices, getFallback, isNullable, Schema } from '../utils'
import { check, deepEqual, getChoices, getFallback, isNullable, Schema, useI18nText } from '../utils'
const props = defineProps({
schema: {} as PropType<Schema>,
Expand All @@ -49,6 +49,8 @@ const props = defineProps({
const emit = defineEmits(['update:modelValue'])
const tt = useI18nText()
const config = ref()
const choices = ref<Schema[]>()
const cache = ref<any[]>()
Expand Down Expand Up @@ -85,7 +87,7 @@ watch(() => [props.modelValue, props.schema] as const, ([value, schema]) => {
const selectModel = computed({
get() {
if (active.value === props.schema) return
return active.value?.meta.description || active.value?.value
return tt(active.value?.meta.description) || active.value?.value
},
set(index) {
if (active.value === choices.value[index]) return
Expand Down
6 changes: 4 additions & 2 deletions packages/form/src/schema.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
</template>
<template #desc>
<slot name="desc">
<k-markdown :source="schema?.meta.description"></k-markdown>
<k-markdown :source="tt(schema?.meta.description)"></k-markdown>
</slot>
</template>
<template #prefix><slot name="prefix"></slot></template>
Expand All @@ -41,7 +41,7 @@
<script lang="ts" setup>
import { computed, PropType } from 'vue'
import { clone, deepEqual, isNullable, Schema } from './utils'
import { clone, deepEqual, isNullable, Schema, useI18nText } from './utils'
import form from '.'
import SchemaPrimitive from './primitive.vue'
import SchemaBase from './base.vue'
Expand All @@ -58,6 +58,8 @@ const props = defineProps({
defineEmits(['update:modelValue'])
const tt = useI18nText()
const isPrimitive = computed(() => {
return ['string', 'number', 'boolean'].includes(props.schema?.type)
&& (isNullable(props.modelValue) || typeof props.modelValue === props.schema.type)
Expand Down
16 changes: 15 additions & 1 deletion packages/form/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,24 @@
import Schema from 'schemastery'
import { clone, deepEqual, valueMap } from 'cosmokit'
import { clone, deepEqual, Dict, valueMap } from 'cosmokit'
import { getCurrentInstance, ref, watch, WatchStopHandle } from 'vue'
import { fallbackWithLocaleChain } from '@intlify/core-base'
import { useI18n } from 'vue-i18n'

export * from 'cosmokit'
export { Schema }

export function useI18nText() {
const composer = useI18n()
const context: any = {}
return (message: string | Dict<string>) => {
if (!message || typeof message === 'string') return message
const locales = fallbackWithLocaleChain(context, composer.fallbackLocale.value, composer.locale.value)
for (const locale of locales) {
if (locale in message) return message[locale]
}
}
}

const dynamic = ['function', 'transform', 'is']

export function getChoices(schema: Schema) {
Expand Down

0 comments on commit d4e17e2

Please sign in to comment.