@tmagic/form 1.8.0-manmanyu.10 → 1.8.0-manmanyu.12

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.
@@ -35,6 +35,10 @@ var Form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
35
35
  keyProp: { default: "__key" },
36
36
  popperClass: {},
37
37
  preventSubmitDefault: { type: Boolean },
38
+ useFieldTextInError: {
39
+ type: Boolean,
40
+ default: true
41
+ },
38
42
  extendState: {},
39
43
  showDiff: {},
40
44
  selfDiffFieldTypes: {},
@@ -279,7 +283,7 @@ var Form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
279
283
  Object.entries(invalidFields).forEach(([prop, ValidateError]) => {
280
284
  ValidateError.forEach(({ field, message }) => {
281
285
  const name = field || prop;
282
- const text = getTextByName(name, props.config) || name;
286
+ const text = (props.useFieldTextInError ? getTextByName(name, props.config) : void 0) || name;
283
287
  error.push(`${text} -> ${message}`);
284
288
  });
285
289
  });
@@ -19,6 +19,10 @@ var FormBox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
19
19
  inline: { type: Boolean },
20
20
  labelPosition: {},
21
21
  preventSubmitDefault: { type: Boolean },
22
+ useFieldTextInError: {
23
+ type: Boolean,
24
+ default: true
25
+ },
22
26
  extendState: {}
23
27
  },
24
28
  emits: [
@@ -81,6 +85,7 @@ var FormBox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
81
85
  "label-position": __props.labelPosition,
82
86
  inline: __props.inline,
83
87
  "prevent-submit-default": __props.preventSubmitDefault,
88
+ "use-field-text-in-error": __props.useFieldTextInError,
84
89
  "extend-state": __props.extendState,
85
90
  onChange: changeHandler
86
91
  }, null, 8, [
@@ -93,6 +98,7 @@ var FormBox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
93
98
  "label-position",
94
99
  "inline",
95
100
  "prevent-submit-default",
101
+ "use-field-text-in-error",
96
102
  "extend-state"
97
103
  ]), renderSlot(_ctx.$slots, "default")]),
98
104
  _: 3
@@ -41,6 +41,10 @@ var FormDialog_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
41
41
  type: Boolean,
42
42
  default: true
43
43
  },
44
+ useFieldTextInError: {
45
+ type: Boolean,
46
+ default: true
47
+ },
44
48
  extendState: {},
45
49
  theme: {}
46
50
  },
@@ -195,6 +199,7 @@ var FormDialog_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
195
199
  "label-position": __props.labelPosition,
196
200
  inline: __props.inline,
197
201
  "prevent-submit-default": __props.preventSubmitDefault,
202
+ "use-field-text-in-error": __props.useFieldTextInError,
198
203
  "extend-state": __props.extendState,
199
204
  theme: effectiveTheme.value,
200
205
  onChange: changeHandler
@@ -209,6 +214,7 @@ var FormDialog_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
209
214
  "label-position",
210
215
  "inline",
211
216
  "prevent-submit-default",
217
+ "use-field-text-in-error",
212
218
  "extend-state",
213
219
  "theme"
214
220
  ]), renderSlot(_ctx.$slots, "default")], 4)) : createCommentVNode("v-if", true)]),
@@ -24,6 +24,10 @@ var FormDrawer_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
24
24
  inline: { type: Boolean },
25
25
  labelPosition: {},
26
26
  preventSubmitDefault: { type: Boolean },
27
+ useFieldTextInError: {
28
+ type: Boolean,
29
+ default: true
30
+ },
27
31
  beforeClose: {},
28
32
  extendState: {},
29
33
  theme: {}
@@ -171,6 +175,7 @@ var FormDrawer_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
171
175
  "label-position": __props.labelPosition,
172
176
  inline: __props.inline,
173
177
  "prevent-submit-default": __props.preventSubmitDefault,
178
+ "use-field-text-in-error": __props.useFieldTextInError,
174
179
  "extend-state": __props.extendState,
175
180
  theme: effectiveTheme.value,
176
181
  onChange: changeHandler
@@ -184,6 +189,7 @@ var FormDrawer_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
184
189
  "label-position",
185
190
  "inline",
186
191
  "prevent-submit-default",
192
+ "use-field-text-in-error",
187
193
  "extend-state",
188
194
  "theme"
189
195
  ]), renderSlot(_ctx.$slots, "default")], 512)) : createCommentVNode("v-if", true)]),
@@ -148,7 +148,8 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
148
148
  labelWidth: itemLabelWidth.value,
149
149
  labelPosition: props.config.labelPosition,
150
150
  rules: rule.value,
151
- extra: filterFunction(mForm, props.config.extra, props)
151
+ extra: filterFunction(mForm, props.config.extra, props),
152
+ extraTips: props.config.extraTips
152
153
  }));
153
154
  const itemLabelWidth = computed(() => props.config.labelWidth ?? props.labelWidth);
154
155
  watchEffect(() => {
@@ -1,5 +1,5 @@
1
1
  import GroupListItem_default from "./GroupListItem.js";
2
- import { Fragment, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, openBlock, renderList, renderSlot } from "vue";
2
+ import { Fragment, createBlock, createCommentVNode, createElementBlock, createElementVNode, defineComponent, openBlock, renderList, renderSlot, toDisplayString } from "vue";
3
3
  import { cloneDeep } from "lodash-es";
4
4
  //#region packages/form/src/containers/GroupList.vue?vue&type=script&setup=true&lang.ts
5
5
  var _hoisted_1 = { class: "m-fields-group-list" };
@@ -8,11 +8,12 @@ var _hoisted_3 = {
8
8
  key: 1,
9
9
  class: "el-table__empty-block"
10
10
  };
11
- var _hoisted_4 = {
11
+ var _hoisted_4 = { class: "el-table__empty-text t-table__empty" };
12
+ var _hoisted_5 = {
12
13
  key: 3,
13
14
  class: "m-fields-group-list-footer"
14
15
  };
15
- var _hoisted_5 = { style: {
16
+ var _hoisted_6 = { style: {
16
17
  "display": "flex",
17
18
  "justify-content": "flex-end",
18
19
  "flex": "1"
@@ -63,7 +64,7 @@ var GroupList_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
63
64
  innerHTML: __props.config.extra,
64
65
  style: { "color": "rgba(0, 0, 0, 0.45)" }
65
66
  }, null, 8, _hoisted_2)) : createCommentVNode("v-if", true),
66
- !__props.model[__props.name] || !__props.model[__props.name].length ? (openBlock(), createElementBlock("div", _hoisted_3, [..._cache[1] || (_cache[1] = [createElementVNode("span", { class: "el-table__empty-text t-table__empty" }, "暂无数据", -1)])])) : (openBlock(true), createElementBlock(Fragment, { key: 2 }, renderList(__props.model[__props.name], (item, index) => {
67
+ !__props.model[__props.name] || !__props.model[__props.name].length ? (openBlock(), createElementBlock("div", _hoisted_3, [createElementVNode("span", _hoisted_4, "暂无" + toDisplayString(__props.config.titlePrefix || "") + "数据", 1)])) : (openBlock(true), createElementBlock(Fragment, { key: 2 }, renderList(__props.model[__props.name], (item, index) => {
67
68
  return openBlock(), createBlock(GroupListItem_default, {
68
69
  key: index,
69
70
  model: item,
@@ -94,7 +95,7 @@ var GroupList_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
94
95
  "group-model"
95
96
  ]);
96
97
  }), 128)),
97
- !__props.isCompare ? (openBlock(), createElementBlock("div", _hoisted_4, [renderSlot(_ctx.$slots, "toggle-button"), createElementVNode("div", _hoisted_5, [renderSlot(_ctx.$slots, "add-button")])])) : createCommentVNode("v-if", true)
98
+ !__props.isCompare ? (openBlock(), createElementBlock("div", _hoisted_5, [renderSlot(_ctx.$slots, "toggle-button"), createElementVNode("div", _hoisted_6, [renderSlot(_ctx.$slots, "add-button")])])) : createCommentVNode("v-if", true)
98
99
  ]);
99
100
  };
100
101
  }
@@ -1,7 +1,7 @@
1
1
  import { filterFunction } from "../utils/form.js";
2
2
  import Container_default from "./Container.js";
3
3
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, inject, openBlock, ref, unref, vShow, withCtx, withDirectives } from "vue";
4
- import { TMagicButton, TMagicCard, TMagicIcon, TMagicInputNumber, TMagicPopover } from "@tmagic/design";
4
+ import { TMagicButton, TMagicCard, TMagicIcon, TMagicInputNumber, TMagicPopover, TMagicTooltip } from "@tmagic/design";
5
5
  import { ArrowDown, ArrowRight, Bottom, Delete, DocumentCopy, Position, Top } from "@element-plus/icons-vue";
6
6
  //#region packages/form/src/containers/GroupListItem.vue?vue&type=script&setup=true&lang.ts
7
7
  var _hoisted_1 = { class: "m-fields-group-list-item-header" };
@@ -47,7 +47,10 @@ var GroupListItem_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
47
47
  [mForm?.keyProp || "__key"]: `${props.config[mForm?.keyProp || "__key"]}${String(props.index)}`
48
48
  }));
49
49
  const title = computed(() => {
50
- if (props.config.titleKey && props.model[props.config.titleKey]) return props.model[props.config.titleKey];
50
+ if (props.config.titleKey && props.model[props.config.titleKey]) {
51
+ const { titlePrefix } = props.config;
52
+ return titlePrefix ? `${titlePrefix} ${String(props.index + 1)}: ${props.model[props.config.titleKey]}` : `${props.model[props.config.titleKey]}`;
53
+ }
51
54
  if (props.config.title) return filterFunction(mForm, props.config.title, props);
52
55
  return `${props.config.titlePrefix || "组"} ${String(props.index + 1)}`;
53
56
  });
@@ -103,17 +106,20 @@ var GroupListItem_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
103
106
  _: 1
104
107
  }, 8, ["disabled"]),
105
108
  createElementVNode("span", { innerHTML: title.value }, null, 8, _hoisted_2),
106
- !__props.isCompare ? withDirectives((openBlock(), createBlock(unref(TMagicButton), {
107
- key: 0,
108
- size: "default",
109
- link: "",
110
- class: "delete-button",
111
- icon: unref(Delete),
112
- disabled: __props.disabled,
113
- onClick: removeHandler
114
- }, null, 8, ["icon", "disabled"])), [[vShow, showDelete.value]]) : createCommentVNode("v-if", true),
109
+ createVNode(unref(TMagicTooltip), { content: `删除 ${title.value}` }, {
110
+ default: withCtx(() => [!__props.isCompare ? withDirectives((openBlock(), createBlock(unref(TMagicButton), {
111
+ key: 0,
112
+ size: "default",
113
+ link: "",
114
+ class: "delete-button",
115
+ icon: unref(Delete),
116
+ disabled: __props.disabled,
117
+ onClick: removeHandler
118
+ }, null, 8, ["icon", "disabled"])), [[vShow, showDelete.value]]) : createCommentVNode("v-if", true)]),
119
+ _: 1
120
+ }, 8, ["content"]),
115
121
  copyable.value && !__props.isCompare ? (openBlock(), createBlock(unref(TMagicButton), {
116
- key: 1,
122
+ key: 0,
117
123
  link: "",
118
124
  size: "default",
119
125
  type: "primary",
@@ -124,7 +130,7 @@ var GroupListItem_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
124
130
  default: withCtx(() => [..._cache[6] || (_cache[6] = [createTextVNode("复制", -1)])]),
125
131
  _: 1
126
132
  }, 8, ["icon", "disabled"])) : createCommentVNode("v-if", true),
127
- movable.value && !__props.isCompare ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [withDirectives(createVNode(unref(TMagicButton), {
133
+ movable.value && !__props.isCompare ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [withDirectives(createVNode(unref(TMagicButton), {
128
134
  link: "",
129
135
  size: "default",
130
136
  disabled: __props.disabled,
@@ -144,7 +150,7 @@ var GroupListItem_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
144
150
  _: 1
145
151
  }, 8, ["disabled", "icon"]), [[vShow, __props.index !== length.value - 1]])], 64)) : createCommentVNode("v-if", true),
146
152
  __props.config.moveSpecifyLocation && !__props.isCompare ? (openBlock(), createBlock(unref(TMagicPopover), {
147
- key: 3,
153
+ key: 2,
148
154
  trigger: "click",
149
155
  placement: "top",
150
156
  width: "200",
@@ -190,7 +196,7 @@ var GroupListItem_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
190
196
  _: 1
191
197
  }, 8, ["visible"])) : createCommentVNode("v-if", true),
192
198
  itemExtra.value ? (openBlock(), createElementBlock("span", {
193
- key: 4,
199
+ key: 3,
194
200
  innerHTML: itemExtra.value,
195
201
  class: "m-form-tip"
196
202
  }, null, 8, _hoisted_4)) : createCommentVNode("v-if", true)
@@ -99,14 +99,16 @@ var Table_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComp
99
99
  "default-expand-all": true,
100
100
  key: updateKey.value,
101
101
  onSelect: unref(selectHandle),
102
- onSortChange: sortChangeHandler
102
+ onSortChange: sortChangeHandler,
103
+ "empty-text": `暂无${__props.config.titlePrefix || ""}数据`
103
104
  }, null, 8, [
104
105
  "row-key",
105
106
  "columns",
106
107
  "data",
107
108
  "border",
108
109
  "max-height",
109
- "onSelect"
110
+ "onSelect",
111
+ "empty-text"
110
112
  ])) : createCommentVNode("v-if", true)]),
111
113
  _: 1
112
114
  }, 8, ["disabled"]),
@@ -70,6 +70,7 @@ var useTableColumns = (props, emit, currentPage, pageSize, modelName) => {
70
70
  const defaultFixed = isMagicAdmin.value ? "right" : "left";
71
71
  let actionFixed = props.config.fixed === false ? void 0 : defaultFixed;
72
72
  if (typeof props.config.fixed === "string" && ["left", "right"].includes(props.config.fixed)) actionFixed = props.config.fixed;
73
+ const actionFlat = props.config.flat === void 0 && isMagicAdmin.value ? true : props.config.flat;
73
74
  const actionColumn = {
74
75
  props: {
75
76
  label: "操作",
@@ -79,7 +80,7 @@ var useTableColumns = (props, emit, currentPage, pageSize, modelName) => {
79
80
  },
80
81
  cell: ({ row, $index }) => h(ActionsColumn_default, {
81
82
  row,
82
- flat: props.config.flat,
83
+ flat: actionFlat,
83
84
  index: $index,
84
85
  model: props.model,
85
86
  config: props.config,
@@ -1,6 +1,6 @@
1
1
  import { useAddField } from "../utils/useAddField.js";
2
2
  import { createBlock, createCommentVNode, defineComponent, inject, openBlock, ref, unref, watch } from "vue";
3
- import { TMagicInputNumber } from "@tmagic/design";
3
+ import { TMagicInputNumber, isMagicAdminTheme } from "@tmagic/design";
4
4
  //#region packages/form/src/fields/Number.vue?vue&type=script&setup=true&lang.ts
5
5
  var Number_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
6
6
  name: "MFormNumber",
@@ -24,6 +24,7 @@ var Number_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCom
24
24
  setup(__props, { emit: __emit }) {
25
25
  const props = __props;
26
26
  const emit = __emit;
27
+ const isMagicAdmin = isMagicAdminTheme();
27
28
  const value = ref();
28
29
  watch(() => props.model[props.name], (v) => {
29
30
  value.value = v;
@@ -43,7 +44,7 @@ var Number_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCom
43
44
  modelValue: value.value,
44
45
  "onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => value.value = $event),
45
46
  clearable: "",
46
- "controls-position": "right",
47
+ "controls-position": unref(isMagicAdmin) ? "" : "right",
47
48
  size: __props.size,
48
49
  max: __props.config.max,
49
50
  min: __props.config.min,
@@ -54,6 +55,7 @@ var Number_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCom
54
55
  onInput: inputHandler
55
56
  }, null, 8, [
56
57
  "modelValue",
58
+ "controls-position",
57
59
  "size",
58
60
  "max",
59
61
  "min",
package/dist/es/style.css CHANGED
@@ -298,6 +298,7 @@ fieldset.m-fieldset .m-form-tip {
298
298
  display: flex;
299
299
  justify-content: space-between;
300
300
  margin-top: 10px;
301
+ margin-bottom: 16px;
301
302
  }
302
303
 
303
304
  .m-form-panel .el-card__header:hover {
@@ -28,13 +28,20 @@ import { createApp, defineComponent, h, nextTick, ref, watch } from "vue";
28
28
  * initValues: { name: 'foo' },
29
29
  * returnChangeRecords: true,
30
30
  * });
31
+ *
32
+ * // 调试模式:可见地渲染表单,点击「确定」才提交:
33
+ * const values = await submitForm({
34
+ * config: [...],
35
+ * initValues: { name: 'foo' },
36
+ * debug: true,
37
+ * });
31
38
  * ```
32
39
  */
33
40
  var submitForm = (options) => {
34
- const { native, appContext, timeout = 1e4, returnChangeRecords, ...formProps } = options;
41
+ const { native, appContext, timeout = 1e4, returnChangeRecords, debug = false, ...formProps } = options;
35
42
  return new Promise((resolve, reject) => {
36
43
  const container = document.createElement("div");
37
- container.style.display = "none";
44
+ if (!debug) container.style.display = "none";
38
45
  document.body.appendChild(container);
39
46
  let cleaned = false;
40
47
  let timer = null;
@@ -42,22 +49,106 @@ var submitForm = (options) => {
42
49
  name: "MFormSubmitWrapper",
43
50
  setup() {
44
51
  const formRef = ref(null);
45
- const stop = watch(() => formRef.value?.initialized, async (initialized) => {
46
- if (!initialized) return;
47
- stop();
52
+ const errorMsg = ref("");
53
+ const doSubmit = async () => {
48
54
  try {
49
55
  await nextTick();
50
- const changeRecords = [...formRef.value.changeRecords ?? []];
56
+ const changeRecords = [...formRef.value?.changeRecords ?? []];
51
57
  const result = await formRef.value.submitForm(native);
52
58
  resolve(returnChangeRecords ? {
53
59
  values: result,
54
60
  changeRecords
55
61
  } : result);
62
+ cleanup();
56
63
  } catch (err) {
64
+ if (debug) {
65
+ errorMsg.value = err instanceof Error ? err.message : String(err);
66
+ return;
67
+ }
57
68
  reject(err);
58
- } finally {
59
69
  cleanup();
60
70
  }
71
+ };
72
+ if (debug) {
73
+ const handleCancel = () => {
74
+ reject(/* @__PURE__ */ new Error("submitForm canceled in debug mode."));
75
+ cleanup();
76
+ };
77
+ const btnBase = {
78
+ padding: "8px 20px",
79
+ fontSize: "14px",
80
+ lineHeight: "1",
81
+ border: "1px solid #dcdfe6",
82
+ borderRadius: "4px",
83
+ cursor: "pointer"
84
+ };
85
+ return () => h("div", { style: {
86
+ position: "fixed",
87
+ inset: "0",
88
+ zIndex: "10000",
89
+ display: "flex",
90
+ alignItems: "center",
91
+ justifyContent: "center",
92
+ background: "rgba(0, 0, 0, 0.5)"
93
+ } }, [h("div", { style: {
94
+ display: "flex",
95
+ flexDirection: "column",
96
+ width: "600px",
97
+ maxWidth: "90vw",
98
+ maxHeight: "85vh",
99
+ background: "#fff",
100
+ borderRadius: "8px",
101
+ boxShadow: "0 8px 24px rgba(0, 0, 0, 0.2)",
102
+ overflow: "hidden"
103
+ } }, [
104
+ h("div", { style: {
105
+ padding: "16px 20px",
106
+ fontSize: "16px",
107
+ fontWeight: "600",
108
+ borderBottom: "1px solid #ebeef5"
109
+ } }, "submitForm 调试"),
110
+ h("div", { style: {
111
+ flex: "1",
112
+ padding: "20px",
113
+ overflow: "auto"
114
+ } }, [h(Form_default, {
115
+ ...formProps,
116
+ ref: formRef
117
+ }), errorMsg.value ? h("div", {
118
+ style: {
119
+ marginTop: "12px",
120
+ color: "#f56c6c",
121
+ fontSize: "13px",
122
+ lineHeight: "1.5"
123
+ },
124
+ innerHTML: errorMsg.value
125
+ }) : null]),
126
+ h("div", { style: {
127
+ display: "flex",
128
+ justifyContent: "flex-end",
129
+ gap: "12px",
130
+ padding: "12px 20px",
131
+ borderTop: "1px solid #ebeef5"
132
+ } }, [h("button", {
133
+ type: "button",
134
+ onClick: handleCancel,
135
+ style: { ...btnBase }
136
+ }, "取消"), h("button", {
137
+ type: "button",
138
+ onClick: doSubmit,
139
+ style: {
140
+ ...btnBase,
141
+ color: "#fff",
142
+ background: "#409eff",
143
+ borderColor: "#409eff"
144
+ }
145
+ }, "确定")])
146
+ ])]);
147
+ }
148
+ const stop = watch(() => formRef.value?.initialized, (initialized) => {
149
+ if (!initialized) return;
150
+ stop();
151
+ doSubmit();
61
152
  }, {
62
153
  flush: "post",
63
154
  immediate: true
@@ -81,7 +172,7 @@ var submitForm = (options) => {
81
172
  } catch {}
82
173
  container.parentNode?.removeChild(container);
83
174
  };
84
- if (timeout > 0) timer = setTimeout(() => {
175
+ if (timeout > 0 && !debug) timer = setTimeout(() => {
85
176
  if (!cleaned) {
86
177
  reject(/* @__PURE__ */ new Error(`submitForm timeout after ${timeout}ms: form is not initialized.`));
87
178
  cleanup();
package/dist/style.css CHANGED
@@ -298,6 +298,7 @@ fieldset.m-fieldset .m-form-tip {
298
298
  display: flex;
299
299
  justify-content: space-between;
300
300
  margin-top: 10px;
301
+ margin-bottom: 16px;
301
302
  }
302
303
 
303
304
  .m-form-panel .el-card__header:hover {
@@ -298,6 +298,7 @@ fieldset.m-fieldset .m-form-tip {
298
298
  display: flex;
299
299
  justify-content: space-between;
300
300
  margin-top: 10px;
301
+ margin-bottom: 16px;
301
302
  }
302
303
 
303
304
  .m-form-panel .el-card__header:hover {