mirror of https://github.com/halo-dev/halo
feat: add min and max props for repeater input (#3965)
#### What type of PR is this? /area console /kind feature /milestone 2.6.x #### What this PR does / why we need it: Console 端的 FormKit Repeater 输入框支持 min 和 max 参数用于限制项目数量。 <img width="630" alt="image" src="https://github.com/halo-dev/halo/assets/21301288/541da770-0439-4731-a796-a58277c33e05"> #### Which issue(s) this PR fixes: Fixes #3449 #### Special notes for your reviewer: 定义方式: ```yaml - $formkit: repeater name: test_repeater label: 测试 Repeater min: 2 max: 3 children: - $formkit: text name: test_text label: 测试 Text - $formkit: select name: test_select label: 测试 Select options: - value: prose-gray label: prose-gray - value: prose-slate label: prose-slate - value: prose-zinc label: prose-zinc - value: prose-neutral label: prose-neutral - value: prose-stone label: prose-stone ``` #### Does this PR introduce a user-facing change? ```release-note Console 端的 FormKit Repeater 输入框支持 min 和 max 参数用于限制项目数量。 ```pull/3983/head^2
parent
537d511cc0
commit
6dd98d2c0c
|
@ -16,6 +16,9 @@
|
||||||
- 参数
|
- 参数
|
||||||
1. accepts:允许上传的文件类型,如:`image/*`
|
1. accepts:允许上传的文件类型,如:`image/*`
|
||||||
- `repeater`: 定义一个对象集合,可以让使用者可视化的操作集合。
|
- `repeater`: 定义一个对象集合,可以让使用者可视化的操作集合。
|
||||||
|
- 参数
|
||||||
|
1. min: 最小数量,默认为 `0`
|
||||||
|
2. max: 最大数量,默认为 `Infinity`,即无限制。
|
||||||
- `menuCheckbox`:选择一组菜单
|
- `menuCheckbox`:选择一组菜单
|
||||||
- `menuRadio`:选择一个菜单
|
- `menuRadio`:选择一个菜单
|
||||||
- `menuItemSelect`:选择菜单项
|
- `menuItemSelect`:选择菜单项
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
import type { FormKitFrameworkContext } from "@formkit/core";
|
import type { FormKitFrameworkContext } from "@formkit/core";
|
||||||
import { group } from "@formkit/inputs";
|
import { group } from "@formkit/inputs";
|
||||||
import type { PropType } from "vue";
|
import type { PropType } from "vue";
|
||||||
|
import { onMounted } from "vue";
|
||||||
import cloneDeep from "lodash.clonedeep";
|
import cloneDeep from "lodash.clonedeep";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
|
@ -18,6 +19,9 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const min = Number(props.context.min) || 0;
|
||||||
|
const max = Number(props.context.max) || Infinity;
|
||||||
|
|
||||||
const handleAppend = (index: number) => {
|
const handleAppend = (index: number) => {
|
||||||
const value = cloneDeep(props.context._value);
|
const value = cloneDeep(props.context._value);
|
||||||
value.splice(index + 1, 0, {});
|
value.splice(index + 1, 0, {});
|
||||||
|
@ -25,6 +29,10 @@ const handleAppend = (index: number) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleRemove = (index: number) => {
|
const handleRemove = (index: number) => {
|
||||||
|
if (props.context._value?.length <= min) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const value = cloneDeep(props.context._value);
|
const value = cloneDeep(props.context._value);
|
||||||
value.splice(index, 1);
|
value.splice(index, 1);
|
||||||
props.context.node.input(value);
|
props.context.node.input(value);
|
||||||
|
@ -49,6 +57,18 @@ const handleMoveDown = (index: number) => {
|
||||||
value.splice(index + 1, 0, value.splice(index, 1)[0]);
|
value.splice(index + 1, 0, value.splice(index, 1)[0]);
|
||||||
props.context.node.input(value);
|
props.context.node.input(value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const value = cloneDeep(props.context._value);
|
||||||
|
const differenceCount = min - value?.length || 0;
|
||||||
|
|
||||||
|
if (differenceCount > 0) {
|
||||||
|
for (let i = 0; i < differenceCount; i++) {
|
||||||
|
value.push({});
|
||||||
|
}
|
||||||
|
props.context.node.input(value);
|
||||||
|
}
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -73,7 +93,8 @@ const handleMoveDown = (index: number) => {
|
||||||
<li
|
<li
|
||||||
class="cursor-pointer text-gray-500 transition-all hover:text-primary"
|
class="cursor-pointer text-gray-500 transition-all hover:text-primary"
|
||||||
:class="{
|
:class="{
|
||||||
'cursor-not-allowed opacity-50 hover:!text-gray-500': index === 0,
|
'!cursor-not-allowed opacity-50 hover:!text-gray-500':
|
||||||
|
index === 0,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<IconArrowUpCircleLine
|
<IconArrowUpCircleLine
|
||||||
|
@ -83,6 +104,10 @@ const handleMoveDown = (index: number) => {
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
class="cursor-pointer text-gray-500 transition-all hover:text-primary"
|
class="cursor-pointer text-gray-500 transition-all hover:text-primary"
|
||||||
|
:class="{
|
||||||
|
'!cursor-not-allowed opacity-50 hover:!text-gray-500':
|
||||||
|
context._value?.length <= min,
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<IconCloseCircle class="h-5 w-5" @click="handleRemove(index)" />
|
<IconCloseCircle class="h-5 w-5" @click="handleRemove(index)" />
|
||||||
</li>
|
</li>
|
||||||
|
@ -94,7 +119,7 @@ const handleMoveDown = (index: number) => {
|
||||||
<li
|
<li
|
||||||
class="cursor-pointer text-gray-500 transition-all hover:text-primary"
|
class="cursor-pointer text-gray-500 transition-all hover:text-primary"
|
||||||
:class="{
|
:class="{
|
||||||
'cursor-not-allowed opacity-50 hover:!text-gray-500':
|
'!cursor-not-allowed opacity-50 hover:!text-gray-500':
|
||||||
index === context._value.length - 1,
|
index === context._value.length - 1,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
|
@ -108,7 +133,11 @@ const handleMoveDown = (index: number) => {
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div :class="context.classes.add">
|
<div :class="context.classes.add">
|
||||||
<VButton type="secondary" @click="handleAppend(context._value.length)">
|
<VButton
|
||||||
|
:disabled="context._value?.length >= max"
|
||||||
|
type="secondary"
|
||||||
|
@click="handleAppend(context._value.length)"
|
||||||
|
>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<IconAddCircle class="h-full w-full" />
|
<IconAddCircle class="h-full w-full" />
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -23,6 +23,7 @@ export const repeater: FormKitTypeDefinition = {
|
||||||
messages(message("$message.value"))
|
messages(message("$message.value"))
|
||||||
),
|
),
|
||||||
type: "list",
|
type: "list",
|
||||||
|
props: ["min", "max"],
|
||||||
library: {
|
library: {
|
||||||
Repeater: Repeater,
|
Repeater: Repeater,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue