ct-component-plus 2.1.10 → 2.2.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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ct-component-plus",
3
3
  "private": false,
4
- "version": "2.1.10",
4
+ "version": "2.2.0",
5
5
  "type": "module",
6
6
  "main": "packages/components/index.js",
7
7
  "files": [
@@ -16,7 +16,7 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "cingta-icon": "^2.1.6",
19
- "element-plus": "2.11.0",
19
+ "element-plus": "~2.4.4",
20
20
  "vue": "^3.2.47"
21
21
  },
22
22
  "devDependencies": {
@@ -5,6 +5,7 @@
5
5
  ns.b(),
6
6
  ns.is('disabled', disabled),
7
7
  ns.is('filterable', filterable),
8
+ componentId,
8
9
  ]"
9
10
  v-model="showValue"
10
11
  :props="propsShow"
@@ -41,6 +42,7 @@ const serviceConfig = inject("$ctServiceConfig");
41
42
 
42
43
  const ns = useNamespace("cascader");
43
44
  const cascaderRef = ref(null);
45
+ const componentId = `ct-cascader-${Math.random().toString(36).slice(2)}`;
44
46
  const checkedText = ref("");
45
47
  const propsShow = computed(() => {
46
48
  return {
@@ -73,6 +75,19 @@ watch(showValue, async (newValue) => {
73
75
  });
74
76
  props.cbs.change(dataList, cascaderRef.value);
75
77
  }
78
+ if (propsShow.value.multiple && props.filterable) {
79
+ await nextTick();
80
+
81
+ // 如果组件内部没找到,尝试在文档中通过类名查找(作为最后的兜底,注意可能会影响页面上其他同类组件,所以最好通过el限制范围,如果el也拿不到才用document)
82
+ const targetInput = document.querySelector(
83
+ `.${componentId} .el-cascader__search-input`
84
+ );
85
+
86
+ if (targetInput) {
87
+ targetInput.value = "";
88
+ targetInput.dispatchEvent(new Event("input", { bubbles: true }));
89
+ }
90
+ }
76
91
  });
77
92
  const popperClassShow = computed(() => {
78
93
  let popperClass = ns.e("dropdown");
@@ -2,14 +2,12 @@
2
2
  <el-date-picker
3
3
  :class="[ns.b()]"
4
4
  v-model="showValue"
5
- :name="componentName"
6
5
  :value-format="valueFormat"
7
6
  :range-separator="rangeSeparator"
8
7
  :clear-icon="clearIcon"
9
8
  :prefix-icon="prefixIcon"
10
9
  :unlink-panels="unlinkPanels"
11
- v-bind="rawAttr"
12
- >
10
+ v-bind="rawAttr">
13
11
  <template #default="cell">
14
12
  <slot v-bind="cell"></slot>
15
13
  </template>
@@ -26,15 +24,6 @@ const emit = defineEmits(datePickerEmits);
26
24
  const attr = useAttrs();
27
25
  const ns = useNamespace("date-picker");
28
26
 
29
- const componentName = computed(() => {
30
- const rawType = props.rawAttr?.type || attr.type;
31
- if (isArray(props.name)) return props.name;
32
- if (rawType && rawType.includes("range")) {
33
- return props.name ? [props.name, props.name] : [];
34
- }
35
- return props.name;
36
- });
37
-
38
27
  const showValue = computed({
39
28
  get() {
40
29
  return props.modelValue;
@@ -1,6 +1,6 @@
1
- import { buriedParamsKey, searchComponentProps } from "../../../hooks";
2
- import clearIcon from "./clear-icon.vue";
3
- import dateIcon from "./date-icon.vue";
1
+ import { buriedParamsKey, searchComponentProps } from '../../../hooks';
2
+ import clearIcon from './clear-icon.vue';
3
+ import dateIcon from './date-icon.vue';
4
4
 
5
5
  export const datePickerEmits = ["update:modelValue", buriedParamsKey];
6
6
  export const datePickerProps = {
@@ -8,31 +8,27 @@ export const datePickerProps = {
8
8
  modelValue: [Date, Number, String, Array],
9
9
  valueFormat: {
10
10
  type: String,
11
- default: "x",
11
+ default: 'x'
12
12
  },
13
13
  addTimestamp: [Number, String, Array, Function],
14
14
  rangeSeparator: {
15
15
  type: String,
16
- default: "",
16
+ default: '',
17
17
  },
18
18
  clearIcon: {
19
19
  type: [String, Object],
20
20
  default() {
21
- return clearIcon;
22
- },
21
+ return clearIcon
22
+ }
23
23
  },
24
24
  prefixIcon: {
25
25
  type: [String, Object],
26
26
  default() {
27
- return dateIcon;
28
- },
27
+ return dateIcon
28
+ }
29
29
  },
30
30
  unlinkPanels: {
31
31
  type: Boolean,
32
- default: true,
33
- },
34
- name: {
35
- type: [String, Array],
36
- default: "",
37
- },
38
- };
32
+ default: true
33
+ }
34
+ }
@@ -3,9 +3,7 @@ import radio from './radio';
3
3
  import checkbox from './checkbox';
4
4
  import input from './input';
5
5
  import inputRange from './input-range';
6
- import numberInputRange from './number-input-range';
7
6
  import select from './select';
8
- import pagingSelect from './paging-select';
9
7
  import yearSelect from './year-select';
10
8
  import datePicker from './date-picker';
11
9
  import cascader from './cascader';
@@ -36,9 +34,7 @@ const components = [
36
34
  checkbox,
37
35
  input,
38
36
  inputRange,
39
- numberInputRange,
40
37
  select,
41
- pagingSelect,
42
38
  yearSelect,
43
39
  datePicker,
44
40
  cascader,
@@ -83,4 +79,4 @@ export default {
83
79
  install
84
80
  }
85
81
  export { CtMessage }
86
- export * from 'element-plus'
82
+ export * from 'element-plus'
@@ -62,7 +62,7 @@ defineExpose({
62
62
  ref: inputRef,
63
63
  });
64
64
  </script>
65
- <style lang="less">
65
+ <style lang='less'>
66
66
  .ct-input {
67
67
  @R: .ct-input;
68
68
  --ct-input-focus-color: var(--ct-color-primary);
@@ -104,4 +104,4 @@ defineExpose({
104
104
  }
105
105
  }
106
106
  }
107
- </style>
107
+ </style>
@@ -1,13 +1,11 @@
1
- import CtSearchBox from "./src/search-box.vue";
1
+ import CtSearchBox from './src/search-box.vue';
2
2
 
3
- import CtInput from "../input";
4
- import CtSelect from "../select";
5
- import CtDatePicker from "../date-picker";
6
- import CtCascader from "../cascader";
7
- import CtYearSelect from "../year-select";
8
- import CtRadio from "../radio";
9
- import CtNumberInputRange from "../number-input-range";
10
- import CtPagingSelect from "../paging-select";
3
+ import CtInput from '../input';
4
+ import CtSelect from '../select';
5
+ import CtDatePicker from '../date-picker';
6
+ import CtCascader from '../cascader';
7
+ import CtYearSelect from '../year-select';
8
+ import CtRadio from '../radio';
11
9
 
12
10
  export const searchComponents = {
13
11
  CtInput,
@@ -15,17 +13,15 @@ export const searchComponents = {
15
13
  CtDatePicker,
16
14
  CtCascader,
17
15
  CtYearSelect,
18
- CtRadio,
19
- CtNumberInputRange,
20
- CtPagingSelect,
21
- };
16
+ CtRadio
17
+ }
22
18
 
23
19
  /* istanbul ignore next */
24
20
  CtSearchBox.install = function (Vue) {
25
- Vue.component("CtSearchBox", CtSearchBox);
21
+ Vue.component('CtSearchBox', CtSearchBox);
26
22
  // for (const key in searchComponents) {
27
23
  // Vue.component(key, searchComponents[key]);
28
24
  // }
29
25
  };
30
26
 
31
- export default CtSearchBox;
27
+ export default CtSearchBox;
@@ -98,7 +98,7 @@ const judgeIsHideLabelTooltip = (item) => {
98
98
 
99
99
  const clickItem = (item) => {
100
100
  emit("clickItem", item);
101
- };
101
+ }
102
102
  const getComponentClass = (item) => {
103
103
  const classList = [];
104
104
  if (item.componentClass) {
@@ -117,16 +117,8 @@ const getComponentStyle = (item) => {
117
117
  return style;
118
118
  };
119
119
  const componentAll = computed(() => {
120
- const {
121
- CtInput,
122
- CtSelect,
123
- CtDatePicker,
124
- CtCascader,
125
- CtYearSelect,
126
- CtRadio,
127
- CtNumberInputRange,
128
- CtPagingSelect,
129
- } = searchComponents;
120
+ const { CtInput, CtSelect, CtDatePicker, CtCascader, CtYearSelect, CtRadio } =
121
+ searchComponents;
130
122
  const componentMap = {
131
123
  0: CtInput,
132
124
  1: CtSelect,
@@ -135,8 +127,6 @@ const componentAll = computed(() => {
135
127
  12: CtYearSelect,
136
128
  13: "div",
137
129
  20: CtRadio,
138
- 21: CtNumberInputRange,
139
- 22: CtPagingSelect,
140
130
  ...userDefinedSearchComponent,
141
131
  };
142
132
  return componentMap;
@@ -249,8 +239,7 @@ onMounted(() => {});
249
239
  }
250
240
  .el-input__wrapper,
251
241
  .el-select__wrapper,
252
- .ct-year-select__wrapper,
253
- .ct-number-input-range__wrapper {
242
+ .ct-year-select__wrapper {
254
243
  --el-select-input-focus-border-color: var(
255
244
  --ct-search-box-inner-border-color
256
245
  );
@@ -5,14 +5,14 @@
5
5
  :class="[ns.b(), ns.is('multiple', multiple)]"
6
6
  v-model="valueModel"
7
7
  collapse-tags
8
- v-bind="bindAttrs"
8
+ v-bind="rawAttr"
9
9
  :multiple="multiple"
10
10
  :filterable="filterable"
11
11
  :clear-icon="clearIcon"
12
12
  :suffix-icon="suffixIcon"
13
13
  :fit-input-width="fitInputWidth"
14
14
  :select-text="selectText"
15
- :popper-class="popperClass"
15
+ :popper-class="ns.e('popper')"
16
16
  @focus="showSearchPrefix"
17
17
  @blur="hideSearchPrefix"
18
18
  @click="focusSearchInput"
@@ -35,7 +35,7 @@
35
35
  </template>
36
36
  </el-input>
37
37
  </div>
38
- <div :class="[ns.e('select')]" v-if="!bindAttrs.multipleLimit">
38
+ <div :class="[ns.e('select')]" v-if="!rawAttr.multipleLimit">
39
39
  <span :class="[ns.e('select-title')]">
40
40
  <span v-if="!keyword">已选{{ selectLength }}项</span>
41
41
  <span v-else>检索结果</span>
@@ -74,12 +74,6 @@
74
74
  </el-select>
75
75
  </template>
76
76
 
77
- <script>
78
- export default {
79
- inheritAttrs: false,
80
- };
81
- </script>
82
-
83
77
  <script setup>
84
78
  import {
85
79
  onMounted,
@@ -89,7 +83,6 @@ import {
89
83
  inject,
90
84
  watchEffect,
91
85
  nextTick,
92
- useAttrs,
93
86
  } from "vue";
94
87
  import { selectEmits, selectProps } from "./index";
95
88
  import { useNamespace, useBuriedParams, useCheckedAll } from "../../../hooks";
@@ -111,70 +104,15 @@ const emit = defineEmits(selectEmits);
111
104
  // };
112
105
  const ns = useNamespace("select");
113
106
  const optionsByApi = ref([]);
114
-
115
- const EMPTY_VALUE = "___CT_EMPTY_STRING___";
116
- const attrs = useAttrs();
117
-
118
- const bindAttrs = computed(() => {
119
- const merged = { ...attrs, ...props.rawAttr };
120
- // 剔除已在组件内部显式处理的属性,避免 v-bind 覆盖或冲突
121
- delete merged["popper-class"];
122
- delete merged["popperClass"];
123
-
124
- if (merged.onChange) {
125
- const original = merged.onChange;
126
- merged.onChange = (val) => {
127
- let realVal = val;
128
- if (Array.isArray(val)) {
129
- realVal = val.map((v) => (v === EMPTY_VALUE ? "" : v));
130
- } else {
131
- if (realVal === EMPTY_VALUE) realVal = "";
132
- }
133
- original(realVal);
134
- };
135
- }
136
- return merged;
137
- });
138
-
139
107
  const showOptions = computed(() => {
140
- const opts = optionsByApi.value.length ? optionsByApi.value : props.options;
141
- return opts.map((item) => {
142
- if (item.value === "") {
143
- return { ...item, value: EMPTY_VALUE };
144
- }
145
- return item;
146
- });
108
+ return optionsByApi.value.length ? optionsByApi.value : props.options;
147
109
  });
148
110
  const valueModel = computed({
149
111
  get() {
150
- const val = props.modelValue;
151
- const hasEmptyOption = showOptions.value.some(
152
- (item) => item.value === EMPTY_VALUE
153
- );
154
- if (props.multiple) {
155
- if (Array.isArray(val)) {
156
- return val.map((v) => {
157
- if (v === "") {
158
- return hasEmptyOption ? EMPTY_VALUE : "";
159
- }
160
- return v;
161
- });
162
- }
163
- return [];
164
- }
165
- if (val === "") {
166
- return hasEmptyOption ? EMPTY_VALUE : "";
167
- }
168
- return val ?? "";
112
+ return props.modelValue || (props.multiple ? [] : props.modelValue);
169
113
  },
170
114
  set(newValue) {
171
- let emitVal = newValue;
172
- if (Array.isArray(emitVal)) {
173
- emitVal = emitVal.map((v) => (v === EMPTY_VALUE ? "" : v));
174
- } else {
175
- if (emitVal === EMPTY_VALUE) emitVal = "";
176
- }
177
- emit("update:modelValue", emitVal);
115
+ emit("update:modelValue", newValue);
178
116
  },
179
117
  });
180
118
  const keyword = ref("");
@@ -217,9 +155,9 @@ const selectText = computed(() => {
217
155
  result = selectObj.value.map((item) => item.label).join(cnt);
218
156
  }
219
157
  }
220
- // nextTick(() => {
221
- // selectRef.value.$refs.reference.input.value = result;
222
- // });
158
+ nextTick(() => {
159
+ selectRef.value.$refs.reference.input.value = result;
160
+ });
223
161
  return result;
224
162
  });
225
163
  const emptyText = computed(() => {
@@ -227,14 +165,6 @@ const emptyText = computed(() => {
227
165
  ? props.noMatchText || "暂无匹配数据"
228
166
  : props.noDataText || "暂无数据";
229
167
  });
230
-
231
- const popperClass = computed(() => {
232
- const defaultClass = ns.e("popper");
233
- const merged = { ...attrs, ...props.rawAttr };
234
- const userClass = merged["popper-class"] || merged["popperClass"] || "";
235
- return `${defaultClass} ${userClass}`.trim();
236
- });
237
-
238
168
  const getUseLabel = (label) => {
239
169
  return typeof label === "string" ? label : String(label);
240
170
  };
@@ -253,10 +183,7 @@ watch(
253
183
  watchEffect(async () => {
254
184
  // 输入框过滤,触发的事件
255
185
  let arr = showOptions.value.filter((item) => {
256
- return (
257
- item.label &&
258
- item.label.toLowerCase().includes(keyword.value.toLowerCase())
259
- );
186
+ return item.label && item.label.includes(keyword.value);
260
187
  });
261
188
  const cbs = props.cbs || {};
262
189
  if (isFunction(cbs.filterCallback)) {
@@ -431,21 +358,7 @@ defineExpose({
431
358
  </script>
432
359
  <style lang="less">
433
360
  .ct-select {
434
- &.el-select {
435
- position: relative;
436
- width: 214px;
437
- &__selected-item {
438
- &:nth-child(1) {
439
- display: none;
440
- }
441
- &:nth-child(2) {
442
- display: none;
443
- }
444
- &:nth-child(3) {
445
- display: flex;
446
- }
447
- }
448
- }
361
+ width: 214px;
449
362
  &__top {
450
363
  padding: 0 16px;
451
364
  font-size: var(--ct-font-size);
@@ -494,7 +407,7 @@ defineExpose({
494
407
  z-index: 3;
495
408
  right: var(--ct-component-inner-padding);
496
409
  top: 50%;
497
- height: calc(var(--ct-component-size) - 8px);
410
+ height: calc(var(--ct-component-size) - 2px);
498
411
  transform: translateY(-50%);
499
412
  background-color: #fff;
500
413
  }
@@ -506,25 +419,18 @@ defineExpose({
506
419
  color: var(--ct-color-grey-sub);
507
420
  }
508
421
  &.is-multiple {
509
- &::after {
510
- content: attr(select-text);
511
- position: absolute;
512
- left: var(--ct-component-inner-padding);
513
- right: calc(var(--ct-component-inner-padding) * 2);
514
- top: 50%;
515
- transform: translateY(-50%);
516
- text-overflow: ellipsis;
517
- overflow: hidden;
518
- white-space: nowrap;
519
- cursor: pointer;
520
- pointer-events: none;
521
- }
522
- .el-select__placeholder.is-transparent {
523
- display: block;
524
- }
525
- .el-select__selected-item {
526
- display: none;
527
- }
422
+ // &::after {
423
+ // content: attr(select-text);
424
+ // position: absolute;
425
+ // left: var(--ct-component-inner-padding);
426
+ // right: calc(var(--ct-component-inner-padding) * 2);
427
+ // top: 50%;
428
+ // transform: translateY(-50%);
429
+ // text-overflow: ellipsis;
430
+ // overflow: hidden;
431
+ // white-space: nowrap;
432
+ // cursor: pointer;
433
+ // }
528
434
  }
529
435
  }
530
436
  </style>
@@ -1,13 +1,13 @@
1
- import { buriedParamsKey, searchComponentProps } from "../../../hooks";
1
+ import { buriedParamsKey, searchComponentProps } from '../../../hooks';
2
2
 
3
3
  export const yearSelectEmits = [
4
4
  "update:modelValue",
5
5
  buriedParamsKey,
6
- "change",
7
- "changeSelect",
8
- "visible-change",
9
- "blur",
10
- "focus",
6
+ 'change',
7
+ 'change-select',
8
+ 'visible-change',
9
+ 'blur',
10
+ 'focus'
11
11
  ];
12
12
  export const yearSelectProps = {
13
13
  ...searchComponentProps,
@@ -15,7 +15,7 @@ export const yearSelectProps = {
15
15
  disabled: Boolean,
16
16
  multiple: {
17
17
  type: Boolean,
18
- default: true,
18
+ default: true
19
19
  },
20
20
  startPlaceholder: String,
21
21
  endPlaceholder: String,
@@ -42,4 +42,4 @@ export const yearSelectProps = {
42
42
  type: [String, Object],
43
43
  default: "至",
44
44
  },
45
- };
45
+ }
@@ -135,12 +135,9 @@ const getYearList = () => {
135
135
  }
136
136
  yearList.value = yearArr;
137
137
  };
138
- watch(
139
- () => props.range,
140
- () => {
141
- getYearList();
142
- }
143
- );
138
+ watch(() => props.range, () => {
139
+ getYearList();
140
+ })
144
141
  const filterHandleE = (str) => {
145
142
  //处理结束年
146
143
  if (judgeYear(str) && judgeRange(str)) {
@@ -210,7 +207,7 @@ onMounted(() => {
210
207
  getYearList();
211
208
  });
212
209
  </script>
213
- <style lang="less">
210
+ <style lang='less'>
214
211
  .ct-year-select {
215
212
  --el-select-input-focus-border-color: transparent;
216
213
  --ct-year-select-select-inner-box-shadow: none;
@@ -276,15 +273,5 @@ onMounted(() => {
276
273
  }
277
274
  }
278
275
  }
279
- .el-select__wrapper {
280
- padding: 1px 12px;
281
- min-height: 30px;
282
- box-shadow: var(--ct-year-select-select-inner-box-shadow);
283
- &.is-focused,
284
- &.is-hovering:not(.is-focused),
285
- &.is-disabled {
286
- box-shadow: var(--ct-year-select-select-inner-box-shadow);
287
- }
288
- }
289
276
  }
290
- </style>
277
+ </style>