@tmagic/form 1.8.0-manmanyu.9 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/Form.vue_vue_type_script_setup_true_lang.js +88 -107
- package/dist/es/FormBox.vue_vue_type_script_setup_true_lang.js +21 -5
- package/dist/es/FormDialog.vue_vue_type_script_setup_true_lang.js +21 -5
- package/dist/es/FormDrawer.vue_vue_type_script_setup_true_lang.js +46 -12
- package/dist/es/containers/Col.vue_vue_type_script_setup_true_lang.js +6 -2
- package/dist/es/containers/Container.vue_vue_type_script_setup_true_lang.js +44 -47
- package/dist/es/containers/Fieldset.vue_vue_type_script_setup_true_lang.js +7 -1
- package/dist/es/containers/FlexLayout.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/es/containers/FormLabel.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/containers/GroupList.vue_vue_type_script_setup_true_lang.js +59 -22
- package/dist/es/containers/GroupListItem.vue_vue_type_script_setup_true_lang.js +118 -100
- package/dist/es/containers/Panel.vue_vue_type_script_setup_true_lang.js +8 -3
- package/dist/es/containers/Row.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/es/containers/Step.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/es/containers/Tabs.vue_vue_type_script_setup_true_lang.js +8 -1
- package/dist/es/containers/table/ActionsColumn.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/containers/table/SortColumn.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/containers/table/Table.vue_vue_type_script_setup_true_lang.js +14 -10
- package/dist/es/containers/table/useTableColumns.js +10 -15
- package/dist/es/containers/table-group-list/TableGroupList.vue_vue_type_script_setup_true_lang.js +72 -79
- package/dist/es/containers/table-group-list/useAdd.js +26 -16
- package/dist/es/containers/table-group-list/useScrollLastItemIntoView.js +72 -0
- package/dist/es/fields/Cascader.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/fields/Checkbox.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/CheckboxGroup/Index.js +5 -0
- package/dist/es/fields/{CheckboxGroup.vue_vue_type_script_setup_true_lang.js → CheckboxGroup/Index.vue_vue_type_script_setup_true_lang.js} +6 -7
- package/dist/es/fields/CheckboxGroup/effect.js +8 -0
- package/dist/es/fields/ColorPicker.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Date/Index.js +5 -0
- package/dist/es/fields/{Date.vue_vue_type_script_setup_true_lang.js → Date/Index.vue_vue_type_script_setup_true_lang.js} +5 -7
- package/dist/es/fields/Date/effect.js +10 -0
- package/dist/es/fields/DateTime/Index.js +5 -0
- package/dist/es/fields/{DateTime.vue_vue_type_script_setup_true_lang.js → DateTime/Index.vue_vue_type_script_setup_true_lang.js} +5 -9
- package/dist/es/fields/DateTime/effect.js +15 -0
- package/dist/es/fields/Daterange.vue_vue_type_script_setup_true_lang.js +2 -2
- package/dist/es/fields/Display/Index.js +5 -0
- package/dist/es/fields/{Display.vue_vue_type_script_setup_true_lang.js → Display/Index.vue_vue_type_script_setup_true_lang.js} +6 -7
- package/dist/es/fields/Display/effect.js +8 -0
- package/dist/es/fields/DynamicField/Index.js +5 -0
- package/dist/es/fields/{DynamicField.vue_vue_type_script_setup_true_lang.js → DynamicField/Index.vue_vue_type_script_setup_true_lang.js} +11 -15
- package/dist/es/fields/DynamicField/effect.js +40 -0
- package/dist/es/fields/Hidden.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Link.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/es/fields/Number.vue_vue_type_script_setup_true_lang.js +4 -2
- package/dist/es/fields/NumberRange/Index.js +5 -0
- package/dist/es/fields/{NumberRange.vue_vue_type_script_setup_true_lang.js → NumberRange/Index.vue_vue_type_script_setup_true_lang.js} +5 -6
- package/dist/es/fields/NumberRange/effect.js +8 -0
- package/dist/es/fields/RadioGroup.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/es/fields/Select.vue_vue_type_script_setup_true_lang.js +14 -6
- package/dist/es/fields/Switch.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Text.vue_vue_type_script_setup_true_lang.js +13 -10
- package/dist/es/fields/Textarea.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Time.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Timerange.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/es/headless.js +13 -0
- package/dist/es/index.js +19 -12
- package/dist/es/plugin.js +57 -39
- package/dist/es/schema.js +11 -2
- package/dist/es/style.css +123 -3
- package/dist/es/submitForm.js +270 -72
- package/dist/es/utils/builtInFields.js +49 -0
- package/dist/es/utils/collectFields.js +407 -0
- package/dist/es/utils/config.js +4 -8
- package/dist/es/utils/fieldInnerConfig.js +42 -0
- package/dist/es/utils/fieldValueEffects.js +80 -0
- package/dist/es/utils/form.js +154 -19
- package/dist/es/utils/formStateProxy.js +111 -0
- package/dist/es/utils/registerField.js +158 -0
- package/dist/es/utils/submitHeadless.js +54 -0
- package/dist/es/utils/tableGroupList.js +104 -0
- package/dist/es/utils/typeMatch.js +532 -0
- package/dist/es/utils/validateError.js +57 -0
- package/dist/es/utils/validateValues.js +115 -0
- package/dist/style.css +123 -3
- package/dist/themes/magic-admin.css +576 -14
- package/dist/tmagic-form-headless.umd.cjs +4515 -0
- package/dist/tmagic-form.umd.cjs +3444 -983
- package/package.json +16 -10
- package/src/Form.vue +113 -129
- package/src/FormBox.vue +16 -4
- package/src/FormDialog.vue +16 -5
- package/src/FormDrawer.vue +41 -13
- package/src/containers/Col.vue +3 -0
- package/src/containers/Container.vue +40 -45
- package/src/containers/Fieldset.vue +5 -0
- package/src/containers/FlexLayout.vue +2 -0
- package/src/containers/GroupList.vue +64 -13
- package/src/containers/GroupListItem.vue +88 -81
- package/src/containers/Panel.vue +3 -0
- package/src/containers/Row.vue +2 -0
- package/src/containers/Step.vue +2 -0
- package/src/containers/Tabs.vue +13 -0
- package/src/containers/table/ActionsColumn.vue +1 -1
- package/src/containers/table/Table.vue +5 -3
- package/src/containers/table/usePagination.ts +1 -1
- package/src/containers/table/useSortable.ts +1 -1
- package/src/containers/table/useTableColumns.ts +15 -22
- package/src/containers/table-group-list/TableGroupList.vue +46 -72
- package/src/containers/table-group-list/useAdd.ts +40 -25
- package/src/containers/table-group-list/useScrollLastItemIntoView.ts +94 -0
- package/src/fields/{CheckboxGroup.vue → CheckboxGroup/Index.vue} +3 -8
- package/src/fields/CheckboxGroup/effect.ts +27 -0
- package/src/fields/{Date.vue → Date/Index.vue} +2 -5
- package/src/fields/Date/effect.ts +29 -0
- package/src/fields/{DateTime.vue → DateTime/Index.vue} +2 -16
- package/src/fields/DateTime/effect.ts +36 -0
- package/src/fields/{Display.vue → Display/Index.vue} +3 -7
- package/src/fields/Display/effect.ts +28 -0
- package/src/fields/{DynamicField.vue → DynamicField/Index.vue} +11 -11
- package/src/fields/DynamicField/effect.ts +74 -0
- package/src/fields/Link.vue +3 -4
- package/src/fields/Number.vue +2 -1
- package/src/fields/{NumberRange.vue → NumberRange/Index.vue} +2 -6
- package/src/fields/NumberRange/effect.ts +27 -0
- package/src/fields/RadioGroup.vue +13 -1
- package/src/fields/Select.vue +13 -4
- package/src/headless.ts +78 -0
- package/src/index.ts +46 -9
- package/src/plugin.ts +68 -37
- package/src/schema.ts +13 -2
- package/src/submitForm.ts +410 -131
- package/src/theme/fieldset.scss +1 -0
- package/src/theme/form-box.scss +5 -0
- package/src/theme/form-dialog.scss +1 -1
- package/src/theme/group-list.scss +143 -2
- package/src/theme/table.scss +11 -1
- package/src/theme/themes/magic-admin/index.scss +27 -16
- package/src/utils/builtInFields.ts +69 -0
- package/src/utils/collectFields.ts +561 -0
- package/src/utils/config.ts +7 -15
- package/src/utils/fieldInnerConfig.ts +127 -0
- package/src/utils/fieldValueEffects.ts +140 -0
- package/src/utils/form.ts +230 -30
- package/src/utils/formStateProxy.ts +149 -0
- package/src/utils/registerField.ts +308 -0
- package/src/utils/submitHeadless.ts +206 -0
- package/src/utils/tableGroupList.ts +147 -0
- package/src/utils/typeMatch.ts +948 -0
- package/src/utils/validateError.ts +92 -0
- package/src/utils/validateValues.ts +177 -0
- package/types/headless.d.ts +682 -0
- package/types/index.d.ts +900 -180
- package/dist/es/_virtual/_rolldown/runtime.js +0 -27
- package/dist/es/fields/CheckboxGroup.js +0 -5
- package/dist/es/fields/Date.js +0 -5
- package/dist/es/fields/DateTime.js +0 -5
- package/dist/es/fields/Display.js +0 -5
- package/dist/es/fields/DynamicField.js +0 -5
- package/dist/es/fields/NumberRange.js +0 -5
package/dist/es/containers/table-group-list/TableGroupList.vue_vue_type_script_setup_true_lang.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import { isGroupListType, toGroupListConfig, toTableConfig } from "../../utils/tableGroupList.js";
|
|
1
2
|
import GroupList_default from "../GroupList.js";
|
|
2
3
|
import Table_default from "../table/Table.js";
|
|
3
4
|
import { useAdd } from "./useAdd.js";
|
|
4
|
-
import {
|
|
5
|
+
import { useScrollLastItemIntoView } from "./useScrollLastItemIntoView.js";
|
|
6
|
+
import { computed, createBlock, createSlots, createTextVNode, createVNode, defineComponent, guardReactiveProps, mergeProps, normalizeProps, openBlock, ref, renderSlot, resolveDynamicComponent, toDisplayString, unref, useTemplateRef, withCtx } from "vue";
|
|
5
7
|
import { TMagicButton } from "@tmagic/design";
|
|
6
8
|
import { Grid, Plus } from "@element-plus/icons-vue";
|
|
7
9
|
//#region packages/form/src/containers/table-group-list/TableGroupList.vue?vue&type=script&setup=true&lang.ts
|
|
8
|
-
var TableGroupList_vue_vue_type_script_setup_true_lang_default =
|
|
10
|
+
var TableGroupList_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
9
11
|
name: "MFormTableGroupList",
|
|
10
12
|
inheritAttrs: false,
|
|
11
13
|
__name: "TableGroupList",
|
|
@@ -17,6 +19,7 @@ var TableGroupList_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
17
19
|
name: {},
|
|
18
20
|
prop: {},
|
|
19
21
|
labelWidth: {},
|
|
22
|
+
labelPosition: {},
|
|
20
23
|
disabled: { type: Boolean },
|
|
21
24
|
size: {},
|
|
22
25
|
enableToggleMode: { type: Boolean },
|
|
@@ -33,63 +36,47 @@ var TableGroupList_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
33
36
|
const props = __props;
|
|
34
37
|
const emit = __emit;
|
|
35
38
|
const { addable, newHandler } = useAdd(props, emit);
|
|
36
|
-
const isGroupListType = (type) => type === "groupList" || type === "group-list";
|
|
37
39
|
const displayMode = ref(isGroupListType(props.config.type) ? "groupList" : "table");
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
const zhLength = label.match(/[^\x00-\xff]/g)?.length || 0;
|
|
41
|
-
const chLength = label.length - zhLength;
|
|
42
|
-
return `${Math.max(chLength * 8 + zhLength * 20, 80)}px`;
|
|
43
|
-
};
|
|
44
|
-
const tableConfig = computed(() => {
|
|
45
|
-
if (!isGroupListType(props.config.type)) return props.config;
|
|
46
|
-
const source = props.config;
|
|
47
|
-
return {
|
|
48
|
-
...props.config,
|
|
49
|
-
type: "table",
|
|
50
|
-
groupItems: source.items,
|
|
51
|
-
items: source.tableItems || source.items.map((item) => ({
|
|
52
|
-
...item,
|
|
53
|
-
label: item.label || item.text,
|
|
54
|
-
text: null
|
|
55
|
-
}))
|
|
56
|
-
};
|
|
57
|
-
});
|
|
58
|
-
const groupListConfig = computed(() => {
|
|
59
|
-
if (isGroupListType(props.config.type)) return props.config;
|
|
60
|
-
const source = props.config;
|
|
61
|
-
return {
|
|
62
|
-
...props.config,
|
|
63
|
-
type: "groupList",
|
|
64
|
-
tableItems: source.items,
|
|
65
|
-
items: source.groupItems || source.items.map((item) => {
|
|
66
|
-
const text = item.text || item.label;
|
|
67
|
-
return {
|
|
68
|
-
...item,
|
|
69
|
-
text,
|
|
70
|
-
labelWidth: calcLabelWidth(text),
|
|
71
|
-
span: item.span || 12
|
|
72
|
-
};
|
|
73
|
-
})
|
|
74
|
-
};
|
|
75
|
-
});
|
|
40
|
+
const tableConfig = computed(() => toTableConfig(props.config));
|
|
41
|
+
const groupListConfig = computed(() => toGroupListConfig(props.config));
|
|
76
42
|
const currentConfig = computed(() => displayMode.value === "table" ? tableConfig.value : groupListConfig.value);
|
|
77
43
|
const addButtonSize = computed(() => {
|
|
44
|
+
if (currentConfig.value.addButtonConfig?.sticky) return "default";
|
|
78
45
|
if (displayMode.value === "table") return "small";
|
|
79
46
|
return props.config.enableToggleMode !== false ? "small" : "default";
|
|
80
47
|
});
|
|
48
|
+
const addButtonProps = computed(() => {
|
|
49
|
+
const custom = currentConfig.value.addButtonConfig?.props;
|
|
50
|
+
if (custom) return {
|
|
51
|
+
type: "primary",
|
|
52
|
+
...custom
|
|
53
|
+
};
|
|
54
|
+
if (displayMode.value === "table") return {
|
|
55
|
+
type: "primary",
|
|
56
|
+
plain: true
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
type: "primary",
|
|
60
|
+
text: true
|
|
61
|
+
};
|
|
62
|
+
});
|
|
81
63
|
const toggleDisplayMode = () => {
|
|
82
64
|
displayMode.value = displayMode.value === "table" ? "groupList" : "table";
|
|
83
65
|
};
|
|
66
|
+
const tableGroupListRef = useTemplateRef("tableGroupList");
|
|
67
|
+
const { scrollLastItemIntoView } = useScrollLastItemIntoView(tableGroupListRef, () => Boolean(currentConfig.value.scrollLastItemIntoView) && displayMode.value === "groupList");
|
|
68
|
+
const handleAdd = async () => {
|
|
69
|
+
const expectedCount = await newHandler();
|
|
70
|
+
if (expectedCount !== null) await scrollLastItemIntoView(expectedCount);
|
|
71
|
+
};
|
|
84
72
|
const onChange = (v, eventData) => emit("change", v, eventData);
|
|
85
73
|
const onSelect = (...args) => emit("select", ...args);
|
|
86
74
|
const onAddDiffCount = () => emit("addDiffCount");
|
|
87
|
-
const onAdd = (rows) => {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
75
|
+
const onAdd = async (rows) => {
|
|
76
|
+
let expectedCount = null;
|
|
77
|
+
for (const row of rows) expectedCount = await newHandler(row) ?? expectedCount;
|
|
78
|
+
if (expectedCount !== null) await scrollLastItemIntoView(expectedCount);
|
|
91
79
|
};
|
|
92
|
-
const tableGroupListRef = useTemplateRef("tableGroupList");
|
|
93
80
|
__expose({ toggleRowSelection: (row, selected) => tableGroupListRef.value?.toggleRowSelection?.(row, selected) });
|
|
94
81
|
return (_ctx, _cache) => {
|
|
95
82
|
return openBlock(), createBlock(resolveDynamicComponent(displayMode.value === "table" ? Table_default : GroupList_default), mergeProps({ ref: "tableGroupList" }, _ctx.$attrs, {
|
|
@@ -102,6 +89,7 @@ var TableGroupList_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
102
89
|
"last-values": __props.lastValues,
|
|
103
90
|
prop: __props.prop,
|
|
104
91
|
"label-width": __props.labelWidth,
|
|
92
|
+
"label-position": __props.labelPosition,
|
|
105
93
|
"show-index": __props.showIndex,
|
|
106
94
|
"sort-key": __props.sortKey,
|
|
107
95
|
sort: __props.sort,
|
|
@@ -109,39 +97,43 @@ var TableGroupList_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
109
97
|
onSelect,
|
|
110
98
|
onAddDiffCount,
|
|
111
99
|
onAdd
|
|
112
|
-
}), createSlots({
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
"
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
100
|
+
}), createSlots({ _: 2 }, [
|
|
101
|
+
__props.config.enableToggleMode || __props.enableToggleMode ? {
|
|
102
|
+
name: "toggle-button",
|
|
103
|
+
fn: withCtx(() => [createVNode(unref(TMagicButton), {
|
|
104
|
+
icon: unref(Grid),
|
|
105
|
+
size: "small",
|
|
106
|
+
onClick: toggleDisplayMode
|
|
107
|
+
}, {
|
|
108
|
+
default: withCtx(() => [createTextVNode(toDisplayString(displayMode.value === "table" ? "展开配置" : "切换为表格"), 1)]),
|
|
109
|
+
_: 1
|
|
110
|
+
}, 8, ["icon"])]),
|
|
111
|
+
key: "0"
|
|
112
|
+
} : void 0,
|
|
113
|
+
unref(addable) ? {
|
|
114
|
+
name: "add-button",
|
|
115
|
+
fn: withCtx(() => [createVNode(unref(TMagicButton), mergeProps({
|
|
116
|
+
class: displayMode.value === "table" ? "m-form-table-add-button" : "",
|
|
117
|
+
size: addButtonSize.value,
|
|
118
|
+
icon: unref(Plus),
|
|
119
|
+
disabled: __props.disabled
|
|
120
|
+
}, addButtonProps.value, { onClick: handleAdd }), {
|
|
121
|
+
default: withCtx(() => [createTextVNode(toDisplayString(currentConfig.value.addButtonConfig?.text || (displayMode.value === "table" ? `新增一行${groupListConfig.value.titlePrefix || ""}` : `新增${groupListConfig.value.titlePrefix || ""}`)), 1)]),
|
|
122
|
+
_: 1
|
|
123
|
+
}, 16, [
|
|
124
|
+
"class",
|
|
125
|
+
"size",
|
|
126
|
+
"icon",
|
|
127
|
+
"disabled"
|
|
128
|
+
])]),
|
|
129
|
+
key: "1"
|
|
130
|
+
} : void 0,
|
|
131
|
+
_ctx.$slots.title ? {
|
|
132
|
+
name: "title",
|
|
133
|
+
fn: withCtx((slotProps) => [renderSlot(_ctx.$slots, "title", normalizeProps(guardReactiveProps(slotProps)))]),
|
|
134
|
+
key: "2"
|
|
135
|
+
} : void 0
|
|
136
|
+
]), 1040, [
|
|
145
137
|
"model",
|
|
146
138
|
"name",
|
|
147
139
|
"config",
|
|
@@ -151,6 +143,7 @@ var TableGroupList_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
151
143
|
"last-values",
|
|
152
144
|
"prop",
|
|
153
145
|
"label-width",
|
|
146
|
+
"label-position",
|
|
154
147
|
"show-index",
|
|
155
148
|
"sort-key",
|
|
156
149
|
"sort"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { initValue } from "../../utils/form.js";
|
|
2
|
+
import { applyMountValueEffects } from "../../utils/collectFields.js";
|
|
2
3
|
import { computed, inject } from "vue";
|
|
3
4
|
import { tMagicMessage } from "@tmagic/design";
|
|
4
5
|
//#region packages/form/src/containers/table-group-list/useAdd.ts
|
|
@@ -7,39 +8,46 @@ var useAdd = (props, emit) => {
|
|
|
7
8
|
const addable = computed(() => {
|
|
8
9
|
const modelName = props.name || props.config.name || "";
|
|
9
10
|
if (!modelName) return false;
|
|
10
|
-
if (
|
|
11
|
-
if (typeof props.config.addable === "function") return props.config.addable(mForm, {
|
|
11
|
+
if (typeof props.config.addable === "function") return Boolean(props.config.addable(mForm, {
|
|
12
12
|
model: props.model[modelName],
|
|
13
13
|
formValue: mForm?.values,
|
|
14
14
|
prop: props.prop,
|
|
15
15
|
config: props.config
|
|
16
|
-
});
|
|
17
|
-
|
|
16
|
+
}));
|
|
17
|
+
if (!props.model[modelName]?.length) return true;
|
|
18
|
+
return typeof props.config.addable === "undefined" ? true : Boolean(props.config.addable);
|
|
18
19
|
});
|
|
20
|
+
/**
|
|
21
|
+
* 新增一项,返回新增后列表应有的长度;没有新增(超上限 / 被 beforeAddRow 拦下 / enum 用尽)返回 null。
|
|
22
|
+
*
|
|
23
|
+
* 只抛 change,不直接改 `props.model`:写回由 `MForm` 按 changeRecords 的 propPath 完成。
|
|
24
|
+
* 返回长度是给调用方用的——新项要等写回后才出现在 DOM 里,靠它才能判断等到了没有。
|
|
25
|
+
*/
|
|
19
26
|
const newHandler = async (row) => {
|
|
20
|
-
const modelName = props.name || props.config.name || ""
|
|
21
|
-
|
|
27
|
+
const modelName = `${props.name || props.config.name || ""}`;
|
|
28
|
+
const list = Array.isArray(props.model[modelName]) ? props.model[modelName] : [];
|
|
29
|
+
if (props.config.max && list.length >= props.config.max) {
|
|
22
30
|
tMagicMessage.error(`最多新增配置不能超过${props.config.max}条`);
|
|
23
|
-
return;
|
|
31
|
+
return null;
|
|
24
32
|
}
|
|
25
33
|
if (typeof props.config.beforeAddRow === "function") {
|
|
26
34
|
if (!await props.config.beforeAddRow(mForm, {
|
|
27
|
-
model:
|
|
35
|
+
model: list,
|
|
28
36
|
formValue: mForm?.values,
|
|
29
37
|
prop: props.prop
|
|
30
|
-
})) return;
|
|
38
|
+
})) return null;
|
|
31
39
|
}
|
|
32
40
|
const columns = props.config.items;
|
|
33
41
|
const enumValues = props.config.enum || [];
|
|
34
42
|
let enumV = [];
|
|
35
|
-
const { length } =
|
|
43
|
+
const { length } = list;
|
|
36
44
|
const key = props.config.key || "id";
|
|
37
45
|
let inputs = {};
|
|
38
46
|
if (enumValues.length) {
|
|
39
|
-
if (length >= enumValues.length) return;
|
|
47
|
+
if (length >= enumValues.length) return null;
|
|
40
48
|
enumV = enumValues.filter((item) => {
|
|
41
49
|
let i = 0;
|
|
42
|
-
for (; i < length; i++) if (item[key] ===
|
|
50
|
+
for (; i < length; i++) if (item[key] === list[i][key]) break;
|
|
43
51
|
return i === length;
|
|
44
52
|
});
|
|
45
53
|
if (enumV.length > 0) inputs = enumV[0];
|
|
@@ -48,7 +56,7 @@ var useAdd = (props, emit) => {
|
|
|
48
56
|
});
|
|
49
57
|
else {
|
|
50
58
|
if (typeof props.config.defaultAdd === "function") inputs = await props.config.defaultAdd(mForm, {
|
|
51
|
-
model:
|
|
59
|
+
model: list,
|
|
52
60
|
prop: props.prop,
|
|
53
61
|
formValue: mForm?.values
|
|
54
62
|
});
|
|
@@ -58,11 +66,13 @@ var useAdd = (props, emit) => {
|
|
|
58
66
|
initValues: inputs
|
|
59
67
|
});
|
|
60
68
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
applyMountValueEffects(mForm, columns, inputs);
|
|
70
|
+
if (props.sortKey && length) inputs[props.sortKey] = list[length - 1][props.sortKey] - 1;
|
|
71
|
+
emit("change", [...list, inputs], { changeRecords: [{
|
|
72
|
+
propPath: `${props.prop}.${length}`,
|
|
64
73
|
value: inputs
|
|
65
74
|
}] });
|
|
75
|
+
return length + 1;
|
|
66
76
|
};
|
|
67
77
|
return {
|
|
68
78
|
addable,
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { nextTick } from "vue";
|
|
2
|
+
//#region packages/form/src/containers/table-group-list/useScrollLastItemIntoView.ts
|
|
3
|
+
var nextFrame = () => new Promise((resolve) => requestAnimationFrame(() => resolve()));
|
|
4
|
+
/** 滚动要用的列表根与最后一项;组件已卸载(宿主重建了整棵表单)时返回 null */
|
|
5
|
+
var resolveScrollTarget = (listRef) => {
|
|
6
|
+
const inst = listRef.value;
|
|
7
|
+
const root = inst instanceof HTMLElement ? inst : inst?.$el;
|
|
8
|
+
if (!(root instanceof HTMLElement)) return null;
|
|
9
|
+
const items = root.querySelectorAll(":scope > .m-fields-group-list-item");
|
|
10
|
+
const last = items[items.length - 1];
|
|
11
|
+
return {
|
|
12
|
+
root,
|
|
13
|
+
last: last instanceof HTMLElement ? last : null,
|
|
14
|
+
count: items.length
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
/** 吸顶标题自身的高度:滚动后新项的标题不能被上一层标题压住 */
|
|
18
|
+
var getStickyHeaderOffset = (item) => {
|
|
19
|
+
const header = item.querySelector(":scope > .el-card__header, :scope > .t-card__header");
|
|
20
|
+
if (!(header instanceof HTMLElement)) return 0;
|
|
21
|
+
return Number.parseFloat(getComputedStyle(header).top) || 0;
|
|
22
|
+
};
|
|
23
|
+
/** 吸底「新增」按钮盖住的高度;嵌套列表的 footer 还用 bottom 给外层按钮留了位 */
|
|
24
|
+
var getStickyFooterOffset = (root) => {
|
|
25
|
+
const footer = root.querySelector(":scope > .m-fields-group-list-footer.is-sticky-full");
|
|
26
|
+
if (!(footer instanceof HTMLElement)) return 0;
|
|
27
|
+
return footer.getBoundingClientRect().height + (Number.parseFloat(getComputedStyle(footer).bottom) || 0);
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* 等列表渲染出至少 `expectedCount` 项、且最后一项的 DOM 节点连续两帧不变再返回。
|
|
31
|
+
*
|
|
32
|
+
* 新增只抛 change,写回要经过宿主(如编辑器属性面板)的异步校验与表单值重建,
|
|
33
|
+
* 新项不一定当帧就出现;期间宿主还可能自己再追加项,末尾节点会换掉。
|
|
34
|
+
* 只判「节点不变」会滚到旧的最后一项上,所以先等够数量再等稳定。
|
|
35
|
+
*/
|
|
36
|
+
var waitForStableTarget = async (listRef, expectedCount, timeout = 600) => {
|
|
37
|
+
const deadline = Date.now() + timeout;
|
|
38
|
+
let previous = null;
|
|
39
|
+
while (Date.now() < deadline) {
|
|
40
|
+
const target = resolveScrollTarget(listRef);
|
|
41
|
+
if (!target) return null;
|
|
42
|
+
if (target.count >= expectedCount && target.last && target.last === previous) return target;
|
|
43
|
+
previous = target.last;
|
|
44
|
+
await nextFrame();
|
|
45
|
+
}
|
|
46
|
+
return resolveScrollTarget(listRef);
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* 新增后把最后一项滚进视口,避开吸顶标题与吸底按钮。
|
|
50
|
+
*
|
|
51
|
+
* `enabled` 为 false(未开配置、或不在 group-list 形态)时直接返回。
|
|
52
|
+
*/
|
|
53
|
+
var useScrollLastItemIntoView = (listRef, enabled) => {
|
|
54
|
+
const scrollLastItemIntoView = async (expectedCount) => {
|
|
55
|
+
if (!enabled()) return;
|
|
56
|
+
await nextTick();
|
|
57
|
+
const target = await waitForStableTarget(listRef, expectedCount);
|
|
58
|
+
if (!target?.last) return;
|
|
59
|
+
const { root, last } = target;
|
|
60
|
+
const top = getStickyHeaderOffset(last);
|
|
61
|
+
const bottom = getStickyFooterOffset(root);
|
|
62
|
+
last.style.scrollMarginTop = top ? `${top}px` : "";
|
|
63
|
+
last.style.scrollMarginBottom = bottom ? `${bottom}px` : "";
|
|
64
|
+
last.scrollIntoView({
|
|
65
|
+
behavior: "auto",
|
|
66
|
+
block: "nearest"
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
return { scrollLastItemIntoView };
|
|
70
|
+
};
|
|
71
|
+
//#endregion
|
|
72
|
+
export { useScrollLastItemIntoView };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { useAddField } from "../utils/useAddField.js";
|
|
2
1
|
import { getConfig } from "../utils/config.js";
|
|
3
2
|
import { filterFunction } from "../utils/form.js";
|
|
3
|
+
import { useAddField } from "../utils/useAddField.js";
|
|
4
4
|
import { computed, createBlock, defineComponent, inject, openBlock, ref, unref, watchEffect } from "vue";
|
|
5
5
|
import { TMagicCascader } from "@tmagic/design";
|
|
6
6
|
//#region packages/form/src/fields/Cascader.vue?vue&type=script&setup=true&lang.ts
|
|
7
|
-
var Cascader_vue_vue_type_script_setup_true_lang_default =
|
|
7
|
+
var Cascader_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
8
8
|
name: "MFormCascader",
|
|
9
9
|
__name: "Cascader",
|
|
10
10
|
props: {
|
|
@@ -2,7 +2,7 @@ import { useAddField } from "../utils/useAddField.js";
|
|
|
2
2
|
import { computed, createBlock, createSlots, createTextVNode, defineComponent, openBlock, toDisplayString, unref, withCtx } from "vue";
|
|
3
3
|
import { TMagicCheckbox } from "@tmagic/design";
|
|
4
4
|
//#region packages/form/src/fields/Checkbox.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
-
var Checkbox_vue_vue_type_script_setup_true_lang_default =
|
|
5
|
+
var Checkbox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
6
6
|
name: "MFormCheckbox",
|
|
7
7
|
__name: "Checkbox",
|
|
8
8
|
props: {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import Index_vue_vue_type_script_setup_true_lang_default from "./Index.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
//#region packages/form/src/fields/CheckboxGroup/Index.vue
|
|
3
|
+
var Index_default = Index_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { Index_default as default };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { filterFunction } from "../../utils/form.js";
|
|
2
|
+
import { useAddField } from "../../utils/useAddField.js";
|
|
3
3
|
import { Fragment, computed, createBlock, createElementBlock, createTextVNode, defineComponent, inject, openBlock, renderList, toDisplayString, unref, withCtx } from "vue";
|
|
4
4
|
import { TMagicCheckbox, TMagicCheckboxGroup } from "@tmagic/design";
|
|
5
|
-
//#region packages/form/src/fields/CheckboxGroup.vue?vue&type=script&setup=true&lang.ts
|
|
6
|
-
var
|
|
5
|
+
//#region packages/form/src/fields/CheckboxGroup/Index.vue?vue&type=script&setup=true&lang.ts
|
|
6
|
+
var Index_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
7
7
|
name: "MFormCheckGroup",
|
|
8
|
-
__name: "
|
|
8
|
+
__name: "Index",
|
|
9
9
|
props: {
|
|
10
10
|
config: {},
|
|
11
11
|
model: {},
|
|
@@ -26,7 +26,6 @@ var CheckboxGroup_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
26
26
|
const props = __props;
|
|
27
27
|
const emit = __emit;
|
|
28
28
|
useAddField(props.prop);
|
|
29
|
-
if (props.model && !props.model[props.name]) props.model[props.name] = [];
|
|
30
29
|
const changeHandler = (v) => {
|
|
31
30
|
emit("change", v);
|
|
32
31
|
};
|
|
@@ -63,4 +62,4 @@ var CheckboxGroup_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */
|
|
|
63
62
|
}
|
|
64
63
|
});
|
|
65
64
|
//#endregion
|
|
66
|
-
export {
|
|
65
|
+
export { Index_vue_vue_type_script_setup_true_lang_default as default };
|
|
@@ -2,7 +2,7 @@ import { useAddField } from "../utils/useAddField.js";
|
|
|
2
2
|
import { createBlock, defineComponent, openBlock, unref } from "vue";
|
|
3
3
|
import { TMagicColorPicker } from "@tmagic/design";
|
|
4
4
|
//#region packages/form/src/fields/ColorPicker.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
-
var ColorPicker_vue_vue_type_script_setup_true_lang_default =
|
|
5
|
+
var ColorPicker_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
6
6
|
name: "MFormColorPicker",
|
|
7
7
|
__name: "ColorPicker",
|
|
8
8
|
props: {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import Index_vue_vue_type_script_setup_true_lang_default from "./Index.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
//#region packages/form/src/fields/Date/Index.vue
|
|
3
|
+
var Index_default = Index_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { Index_default as default };
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { useAddField } from "
|
|
2
|
-
import { datetimeFormatter } from "../utils/form.js";
|
|
1
|
+
import { useAddField } from "../../utils/useAddField.js";
|
|
3
2
|
import { createBlock, defineComponent, openBlock, unref } from "vue";
|
|
4
3
|
import { TMagicDatePicker } from "@tmagic/design";
|
|
5
|
-
//#region packages/form/src/fields/Date.vue?vue&type=script&setup=true&lang.ts
|
|
6
|
-
var
|
|
4
|
+
//#region packages/form/src/fields/Date/Index.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
+
var Index_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
7
6
|
name: "MFormDate",
|
|
8
|
-
__name: "
|
|
7
|
+
__name: "Index",
|
|
9
8
|
props: {
|
|
10
9
|
config: {},
|
|
11
10
|
model: {},
|
|
@@ -26,7 +25,6 @@ var Date_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCom
|
|
|
26
25
|
const props = __props;
|
|
27
26
|
const emit = __emit;
|
|
28
27
|
useAddField(props.prop);
|
|
29
|
-
props.model[props.name] = datetimeFormatter(props.model[props.name], "", props.config.valueFormat || "YYYY/MM/DD");
|
|
30
28
|
const changeHandler = (v) => {
|
|
31
29
|
emit("change", v);
|
|
32
30
|
};
|
|
@@ -52,4 +50,4 @@ var Date_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCom
|
|
|
52
50
|
}
|
|
53
51
|
});
|
|
54
52
|
//#endregion
|
|
55
|
-
export {
|
|
53
|
+
export { Index_vue_vue_type_script_setup_true_lang_default as default };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { datetimeFormatter } from "../../utils/form.js";
|
|
2
|
+
//#region packages/form/src/fields/Date/effect.ts
|
|
3
|
+
/** 按 `valueFormat` 归一化日期值。 */
|
|
4
|
+
var effect = ({ config, model }) => {
|
|
5
|
+
if (!model) return;
|
|
6
|
+
const { name, valueFormat } = config;
|
|
7
|
+
model[name] = datetimeFormatter(model[name], "", valueFormat || "YYYY/MM/DD");
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { effect };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import Index_vue_vue_type_script_setup_true_lang_default from "./Index.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
//#region packages/form/src/fields/DateTime/Index.vue
|
|
3
|
+
var Index_default = Index_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { Index_default as default };
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { useAddField } from "
|
|
2
|
-
import { datetimeFormatter } from "../utils/form.js";
|
|
1
|
+
import { useAddField } from "../../utils/useAddField.js";
|
|
3
2
|
import { createBlock, defineComponent, openBlock, unref } from "vue";
|
|
4
3
|
import { TMagicDatePicker } from "@tmagic/design";
|
|
5
|
-
//#region packages/form/src/fields/DateTime.vue?vue&type=script&setup=true&lang.ts
|
|
6
|
-
var
|
|
4
|
+
//#region packages/form/src/fields/DateTime/Index.vue?vue&type=script&setup=true&lang.ts
|
|
5
|
+
var Index_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
7
6
|
name: "MFormDateTime",
|
|
8
|
-
__name: "
|
|
7
|
+
__name: "Index",
|
|
9
8
|
props: {
|
|
10
9
|
config: {},
|
|
11
10
|
model: {},
|
|
@@ -26,9 +25,6 @@ var DateTime_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defin
|
|
|
26
25
|
const props = __props;
|
|
27
26
|
const emit = __emit;
|
|
28
27
|
useAddField(props.prop);
|
|
29
|
-
const value = props.model?.[props.name]?.toString();
|
|
30
|
-
if (props.model) if (!value || value === "Invalid Date") props.model[props.name] = "";
|
|
31
|
-
else props.model[props.name] = datetimeFormatter(props.model[props.name], "", props.config.valueFormat || "YYYY/MM/DD HH:mm:ss");
|
|
32
28
|
const changeHandler = (v) => {
|
|
33
29
|
emit("change", v);
|
|
34
30
|
};
|
|
@@ -57,4 +53,4 @@ var DateTime_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defin
|
|
|
57
53
|
}
|
|
58
54
|
});
|
|
59
55
|
//#endregion
|
|
60
|
-
export {
|
|
56
|
+
export { Index_vue_vue_type_script_setup_true_lang_default as default };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { datetimeFormatter } from "../../utils/form.js";
|
|
2
|
+
//#region packages/form/src/fields/DateTime/effect.ts
|
|
3
|
+
/** 按 `valueFormat` 归一化日期时间值,空值与非法值统一为空字符串。 */
|
|
4
|
+
var effect = ({ config, model }) => {
|
|
5
|
+
if (!model) return;
|
|
6
|
+
const { name, valueFormat } = config;
|
|
7
|
+
const value = model[name]?.toString();
|
|
8
|
+
if (!value || value === "Invalid Date") {
|
|
9
|
+
model[name] = "";
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
model[name] = datetimeFormatter(model[name], "", valueFormat || "YYYY/MM/DD HH:mm:ss");
|
|
13
|
+
};
|
|
14
|
+
//#endregion
|
|
15
|
+
export { effect };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { useAddField } from "../utils/useAddField.js";
|
|
2
1
|
import { datetimeFormatter } from "../utils/form.js";
|
|
2
|
+
import { useAddField } from "../utils/useAddField.js";
|
|
3
3
|
import { createBlock, defineComponent, onUnmounted, openBlock, ref, unref, watch } from "vue";
|
|
4
4
|
import { TMagicDatePicker } from "@tmagic/design";
|
|
5
5
|
//#region packages/form/src/fields/Daterange.vue?vue&type=script&setup=true&lang.ts
|
|
6
|
-
var Daterange_vue_vue_type_script_setup_true_lang_default =
|
|
6
|
+
var Daterange_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
7
7
|
name: "MFormDateRange",
|
|
8
8
|
__name: "Daterange",
|
|
9
9
|
props: {
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import Index_vue_vue_type_script_setup_true_lang_default from "./Index.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
//#region packages/form/src/fields/Display/Index.vue
|
|
3
|
+
var Index_default = Index_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { Index_default as default };
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { filterFunction } from "../../utils/form.js";
|
|
2
|
+
import { useAddField } from "../../utils/useAddField.js";
|
|
3
3
|
import { computed, createCommentVNode, createElementBlock, defineComponent, inject, openBlock, toDisplayString } from "vue";
|
|
4
|
-
//#region packages/form/src/fields/Display.vue?vue&type=script&setup=true&lang.ts
|
|
4
|
+
//#region packages/form/src/fields/Display/Index.vue?vue&type=script&setup=true&lang.ts
|
|
5
5
|
var _hoisted_1 = { key: 0 };
|
|
6
|
-
var
|
|
6
|
+
var Index_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
7
7
|
name: "MFormDisplay",
|
|
8
|
-
__name: "
|
|
8
|
+
__name: "Index",
|
|
9
9
|
props: {
|
|
10
10
|
config: {},
|
|
11
11
|
model: {},
|
|
@@ -24,7 +24,6 @@ var Display_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
|
|
|
24
24
|
setup(__props) {
|
|
25
25
|
const props = __props;
|
|
26
26
|
const mForm = inject("mForm");
|
|
27
|
-
if (props.config.initValue && props.model) props.model[props.name] = props.config.initValue;
|
|
28
27
|
const text = computed(() => {
|
|
29
28
|
if (props.config.displayText) return filterFunction(mForm, props.config.displayText, props);
|
|
30
29
|
return props.model[props.name];
|
|
@@ -36,4 +35,4 @@ var Display_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
|
|
|
36
35
|
}
|
|
37
36
|
});
|
|
38
37
|
//#endregion
|
|
39
|
-
export {
|
|
38
|
+
export { Index_vue_vue_type_script_setup_true_lang_default as default };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import Index_vue_vue_type_script_setup_true_lang_default from "./Index.vue_vue_type_script_setup_true_lang.js";
|
|
2
|
+
//#region packages/form/src/fields/DynamicField/Index.vue
|
|
3
|
+
var Index_default = Index_vue_vue_type_script_setup_true_lang_default;
|
|
4
|
+
//#endregion
|
|
5
|
+
export { Index_default as default };
|