Skip to content

Commit

Permalink
feat: enhance group UX
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed May 1, 2023
1 parent 8426e53 commit 5d0a168
Show file tree
Hide file tree
Showing 14 changed files with 109 additions and 70 deletions.
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@
"author": "Shigma <shigma10826@gmail.com>",
"license": "MIT",
"dependencies": {
"cosmokit": "^1.4.1"
"cosmokit": "^1.4.2"
}
}
2 changes: 1 addition & 1 deletion packages/form/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "schemastery-vue",
"description": "Type driven schema validator",
"version": "3.1.0",
"version": "4.0.0-alpha.4",
"main": "src/index.ts",
"repository": {
"type": "git",
Expand Down
1 change: 1 addition & 0 deletions packages/form/src/base.vue
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ defineProps({
disabled: {} as PropType<boolean>,
prefix: {} as PropType<string>,
initial: {} as PropType<{}>,
foldable: Boolean,
})
defineEmits(['update:modelValue', 'visible-change'])
Expand Down
2 changes: 2 additions & 0 deletions packages/form/src/extensions/bitset.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<schema-base>
<template #title><slot name="title"></slot></template>
<template #desc><slot name="desc"></slot></template>
<template #menu><slot name="menu"></slot></template>
<template #prefix><slot name="prefix"></slot></template>
<template #suffix><slot name="suffix"></slot></template>
<ul class="bottom">
Expand All @@ -28,6 +29,7 @@ defineProps({
disabled: {} as PropType<boolean>,
prefix: {} as PropType<string>,
initial: {} as PropType<{}>,
foldable: Boolean,
})
defineEmits(['update:modelValue'])
Expand Down
117 changes: 60 additions & 57 deletions packages/form/src/extensions/group.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,78 +2,52 @@
<schema-base v-bind="$attrs">
<template #title><slot name="title"></slot></template>
<template #desc><slot name="desc"></slot></template>
<template #menu><slot name="menu"></slot></template>
<template #prefix><slot name="prefix"></slot></template>
<template #suffix><slot name="suffix"></slot></template>
<template #control>
<el-button type="primary" @click="add()" :disabled="disabled">添加项</el-button>
</template>
</schema-base>

<div class="k-schema-group">
<template v-for="([key, _], index) in entries" :key="index">
<template v-if="isObjectSchema(schema.inner)">
<schema-base
:class="{ invalid: entries.filter(e => e[0] === key).length > 1 }">
<template #title v-if="schema.type === 'array'">
<span class="prefix">{{ prefix.slice(0, -1) }}</span>
<span>[{{ key }}]</span>
</template>
<template #title v-else>
<span class="prefix">{{ prefix }}</span>
<el-input v-model="entries[index][0]"></el-input>
</template>
<template #desc>
<k-markdown :source="schema.inner.meta.description"></k-markdown>
</template>
<template #menu>
<el-dropdown-item divided :disabled="!index" @click="up(index)">上移</el-dropdown-item>
<el-dropdown-item :disabled="index === entries.length - 1" @click="down(index)">下移</el-dropdown-item>
<el-dropdown-item @click="del(index)">删除</el-dropdown-item>
</template>
</schema-base>

<div class="k-schema-group">
<k-schema
v-model="entries[index][1]"
:initial="initial?.[key]"
:schema="{ ...schema.inner, meta: { ...schema.inner.meta, description: '' } }"
:disabled="disabled"
:prefix="schema.type === 'array' ? `${prefix.slice(0, -1)}[${key}].` : prefix + key + '.'"
#title>
<span class="prefix">{{ prefix }}</span>
<span>{{ key }}</span>
</k-schema>
</div>
<k-schema
v-for="([key, _], index) in entries"
:key="index"
v-model="entries[index][1]"
:invalid="entries.filter(e => e[0] === key).length > 1"
:initial="(initial ?? schema.meta.default)[key]"
:schema="schema.inner"
:disabled="disabled"
:prefix="schema.type === 'array' ? `${prefix.slice(0, -1)}[${key}].` : prefix + key + '.'"
foldable
>
<template #menu>
<el-dropdown-item divided :disabled="!index" @click="up(index)">上移</el-dropdown-item>
<el-dropdown-item :disabled="index === entries.length - 1" @click="down(index)">下移</el-dropdown-item>
<el-dropdown-item @click="del(index)">删除</el-dropdown-item>
</template>
<k-schema v-else
v-model="entries[index][1]"
:invalid="entries.filter(e => e[0] === key).length > 1"
:initial="initial?.[key]"
:schema="schema.inner"
:disabled="disabled"
:prefix="schema.type === 'array' ? `${prefix.slice(0, -1)}[${key}].` : prefix + key + '.'">
<template #menu>
<el-dropdown-item divided :disabled="!index" @click="up(index)">上移</el-dropdown-item>
<el-dropdown-item :disabled="index === entries.length - 1" @click="down(index)">下移</el-dropdown-item>
<el-dropdown-item @click="del(index)">删除</el-dropdown-item>
</template>
<template #title v-if="schema.type === 'array'">
<span class="prefix">{{ prefix.slice(0, -1) }}</span>
<span>[{{ key }}]</span>
</template>
<template #title v-else>
<span class="prefix">{{ prefix }}</span>
<el-input v-model="entries[index][0]"></el-input>
<template #title>
<span class="prefix">{{ prefix.slice(0, -1) }}</span>
<template v-if="schema.type === 'array'">[{{ key }}]</template>
<template v-else>
['
<span class="entry-input">
<span class="shadow" v-if="entries[index][0]">{{ entries[index][0] }}</span>
<span class="placeholder" v-else>&nbsp;</span>
<input v-model="entries[index][0]"/>
</span>
']
</template>
</k-schema>
</template>
</template>
</k-schema>
</div>
</template>
<script lang="ts" setup>
import { PropType } from 'vue'
import { isObjectSchema, Schema, useEntries } from '../utils'
import { Schema, useEntries } from '../utils'
import SchemaBase from '../base.vue'
defineProps({
Expand All @@ -82,6 +56,7 @@ defineProps({
disabled: {} as PropType<boolean>,
prefix: {} as PropType<string>,
initial: {} as PropType<any>,
foldable: Boolean,
})
defineEmits(['update:modelValue'])
Expand Down Expand Up @@ -111,4 +86,32 @@ const { entries, up, down, add, del } = useEntries()
margin-top: 2rem;
}
.entry-input {
position: relative;
.shadow {
visibility: hidden;
white-space: pre;
}
.placeholder {
min-width: 2rem;
display: inline-block;
}
input {
position: absolute;
left: -.5em;
right: -.5em;
border: none;
padding: 0 .5em;
margin: 0;
font-size: 1em;
font-weight: inherit;
font-family: inherit;
border-radius: 0;
outline: none;
}
}
</style>
1 change: 1 addition & 0 deletions packages/form/src/extensions/intersect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ defineProps({
prefix: {} as PropType<string>,
initial: {} as PropType<any>,
class: {} as PropType<any>,
foldable: Boolean,
})
defineEmits(['update:modelValue'])
Expand Down
12 changes: 11 additions & 1 deletion packages/form/src/extensions/object.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
<template>
<h2 class="k-schema-header" v-if="schema.meta.description">
<schema-base v-if="foldable">
<template #title><slot name="title"></slot></template>
<template #desc>
<k-markdown :source="schema.meta.description"></k-markdown>
</template>
<template #menu><slot name="menu"></slot></template>
</schema-base>
<h2 class="k-schema-header" v-else-if="schema.meta.description">
{{ schema.meta.description }}
</h2>

<k-schema
v-for="(item, key) in schema.dict"
:key="key"
Expand All @@ -21,13 +29,15 @@
import { PropType } from 'vue'
import { Schema, useConfig } from '../utils'
import SchemaBase from '../base.vue'
defineProps({
schema: {} as PropType<Schema>,
modelValue: {} as PropType<any>,
disabled: {} as PropType<boolean>,
prefix: {} as PropType<string>,
initial: {} as PropType<any>,
foldable: Boolean,
class: {} as PropType<any>,
})
Expand Down
2 changes: 2 additions & 0 deletions packages/form/src/extensions/radio.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<schema-base>
<template #title><slot name="title"></slot></template>
<template #desc><slot name="desc"></slot></template>
<template #menu><slot name="menu"></slot></template>
<template #prefix><slot name="prefix"></slot></template>
<template #suffix><slot name="suffix"></slot></template>
<ul class="bottom">
Expand All @@ -28,6 +29,7 @@ defineProps({
disabled: {} as PropType<boolean>,
prefix: {} as PropType<string>,
initial: {} as PropType<{}>,
foldable: Boolean,
})
defineEmits(['update:modelValue'])
Expand Down
2 changes: 2 additions & 0 deletions packages/form/src/extensions/table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<schema-base>
<template #title><slot name="title"></slot></template>
<template #desc><slot name="desc"></slot></template>
<template #menu><slot name="menu"></slot></template>
<template #prefix><slot name="prefix"></slot></template>
<template #suffix><slot name="suffix"></slot></template>
<template #control>
Expand Down Expand Up @@ -49,6 +50,7 @@ defineProps({
disabled: {} as PropType<boolean>,
prefix: {} as PropType<string>,
initial: {} as PropType<{}>,
foldable: Boolean,
})
defineEmits(['update:modelValue'])
Expand Down
4 changes: 4 additions & 0 deletions packages/form/src/extensions/textarea.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<schema-base>
<template #title><slot name="title"></slot></template>
<template #desc><slot name="desc"></slot></template>
<template #menu><slot name="menu"></slot></template>
<template #prefix><slot name="prefix"></slot></template>
<template #suffix><slot name="suffix"></slot></template>
<div class="bottom">
Expand All @@ -26,6 +27,9 @@ const props = defineProps({
schema: {} as PropType<Schema>,
modelValue: {} as PropType<string>,
disabled: {} as PropType<boolean>,
prefix: {} as PropType<string>,
initial: {} as PropType<{}>,
foldable: Boolean,
})
defineEmits(['update:modelValue'])
Expand Down
2 changes: 2 additions & 0 deletions packages/form/src/extensions/tuple.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<schema-base>
<template #title><slot name="title"></slot></template>
<template #desc><slot name="desc"></slot></template>
<template #menu><slot name="menu"></slot></template>
<template #prefix><slot name="prefix"></slot></template>
<template #suffix><slot name="suffix"></slot></template>
<template #control>
Expand Down Expand Up @@ -29,6 +30,7 @@ const props = defineProps({
disabled: {} as PropType<boolean>,
prefix: {} as PropType<string>,
initial: {} as PropType<{}>,
foldable: Boolean,
})
const emit = defineEmits(['update:modelValue'])
Expand Down
6 changes: 5 additions & 1 deletion packages/form/src/extensions/union.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
:initial="initial"
:disabled="disabled"
:prefix="prefix"
:required="!!schema.meta.required && isNullable(schema.meta.default) && isNullable(modelValue)"
:extra="{
required: !!schema.meta.required && isNullable(schema.meta.default) && isNullable(modelValue),
}"
>
<template #title><slot name="title"></slot></template>
<template #desc>
Expand Down Expand Up @@ -41,6 +43,7 @@ const props = defineProps({
prefix: {} as PropType<string>,
initial: {} as PropType<any>,
class: {} as PropType<any>,
foldable: Boolean,
})
const emit = defineEmits(['update:modelValue'])
Expand Down Expand Up @@ -68,6 +71,7 @@ watch(() => props.schema, (value) => {
watch(() => [props.modelValue, props.schema] as const, ([value, schema]) => {
stop?.()
config.value = value
value ??= schema.meta.default
active.value = null
for (const item of choices.value) {
if (!check(item, value)) continue
Expand Down
8 changes: 5 additions & 3 deletions packages/form/src/schema.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@
:prefix="prefix"
:initial="initial"
:disabled="disabled"
:foldable="foldable"
:modelValue="modelValue"
@update:modelValue="$emit('update:modelValue', $event)"
:class="{
changed: !deepEqual(initial, modelValue),
required: required ?? (schema?.meta.required && isNullable(schema?.meta.default) && isNullable(modelValue)),
required: extra?.required ?? (schema?.meta.required && isNullable(schema?.meta.default) && isNullable(modelValue)),
invalid,
}"
>
<template #title><slot name="title"></slot></template>
<template #menu>
<el-dropdown-item @click="$emit('update:modelValue', clone(initial))">撤销更改</el-dropdown-item>
<el-dropdown-item @click="$emit('update:modelValue')">恢复默认值</el-dropdown-item>
<el-dropdown-item @click="$emit('update:modelValue', null)">恢复默认值</el-dropdown-item>
<slot name="menu"></slot>
</template>
<template #desc>
Expand Down Expand Up @@ -50,8 +51,9 @@ const props = defineProps({
initial: {} as PropType<any>,
modelValue: {},
invalid: Boolean,
required: Boolean,
extra: {} as PropType<any>,
disabled: Boolean,
foldable: Boolean,
branch: Boolean,
prefix: { type: String, default: '' },
})
Expand Down
Loading

0 comments on commit 5d0a168

Please sign in to comment.