ct-component-plus 2.2.1 → 2.2.3

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.2.1",
4
+ "version": "2.2.3",
5
5
  "type": "module",
6
6
  "main": "packages/components/index.js",
7
7
  "files": [
@@ -4,6 +4,7 @@ import checkbox from './checkbox';
4
4
  import input from './input';
5
5
  import inputRange from './input-range';
6
6
  import select from './select';
7
+ import pagingSelect from './paging-select';
7
8
  import yearSelect from './year-select';
8
9
  import datePicker from './date-picker';
9
10
  import cascader from './cascader';
@@ -35,6 +36,7 @@ const components = [
35
36
  input,
36
37
  inputRange,
37
38
  select,
39
+ pagingSelect,
38
40
  yearSelect,
39
41
  datePicker,
40
42
  cascader,
@@ -79,4 +81,4 @@ export default {
79
81
  install
80
82
  }
81
83
  export { CtMessage }
82
- export * from 'element-plus'
84
+ export * from 'element-plus'
@@ -0,0 +1,8 @@
1
+ import CtPagingSelect from "./src/paging-select.vue";
2
+
3
+ /* istanbul ignore next */
4
+ CtPagingSelect.install = function (Vue) {
5
+ Vue.component("CtPagingSelect", CtPagingSelect);
6
+ };
7
+
8
+ export default CtPagingSelect;
@@ -0,0 +1,3 @@
1
+ <template>
2
+ <ct-icon name="arrow-down_line"></ct-icon>
3
+ </template>
@@ -0,0 +1,3 @@
1
+ <template>
2
+ <ct-icon name="close_line"></ct-icon>
3
+ </template>
@@ -0,0 +1,14 @@
1
+ <template>
2
+ <div class="ct-select__empty">
3
+ <span>{{ text }}</span>
4
+ </div>
5
+ </template>
6
+
7
+ <script setup>
8
+ defineProps({
9
+ text: {
10
+ type: String,
11
+ default: "暂无数据",
12
+ },
13
+ });
14
+ </script>
@@ -0,0 +1,50 @@
1
+ import { buriedParamsKey, searchComponentProps } from "../../../hooks";
2
+ import arrowDown from "./arrow-down.vue";
3
+ import clearIcon from "./clear-icon.vue";
4
+
5
+ export const selectEmits = ["update:modelValue", buriedParamsKey];
6
+ export const selectProps = {
7
+ ...searchComponentProps,
8
+ modelValue: [String, Number, Array, Boolean],
9
+ multiple: Boolean,
10
+ filterable: Boolean,
11
+ api: String,
12
+ serviceMethod: String,
13
+ serviceParams: Object,
14
+ mapObj: {
15
+ type: Object,
16
+ default() {
17
+ return {};
18
+ },
19
+ },
20
+ pageSize: {
21
+ type: Number,
22
+ default: 50,
23
+ },
24
+ selectAllText: {
25
+ type: String,
26
+ default: "全部",
27
+ },
28
+ connectors: {
29
+ type: String,
30
+ default: "、",
31
+ },
32
+ fitInputWidth: {
33
+ type: Boolean,
34
+ default: true,
35
+ },
36
+ clearIcon: {
37
+ type: [String, Object],
38
+ default() {
39
+ return clearIcon;
40
+ },
41
+ },
42
+ suffixIcon: {
43
+ type: [String, Object],
44
+ default() {
45
+ return arrowDown;
46
+ },
47
+ },
48
+ noMatchText: String,
49
+ noDataText: String,
50
+ };
@@ -0,0 +1,490 @@
1
+ <template>
2
+ <!-- {{ rawAttr }}-- -->
3
+ <el-select
4
+ ref="selectRef"
5
+ :class="[ns.b(), ns.is('multiple', multiple)]"
6
+ v-model="valueModel"
7
+ collapse-tags
8
+ v-bind="rawAttr"
9
+ :multiple="multiple"
10
+ :filterable="filterable"
11
+ :clear-icon="clearIcon"
12
+ :suffix-icon="suffixIcon"
13
+ :fit-input-width="fitInputWidth"
14
+ :select-text="selectText"
15
+ :popper-class="popperClass"
16
+ @focus="showSearchPrefix"
17
+ @blur="hideSearchPrefix"
18
+ @click="focusSearchInput"
19
+ @visible-change="handleListSort"
20
+ >
21
+ <template #prefix>
22
+ <div
23
+ :class="[ns.e('filterable-icon')]"
24
+ v-if="filterable && showSearch && !multiple"
25
+ >
26
+ <ct-icon name="search_line"></ct-icon>
27
+ </div>
28
+ <slot name="prefix"></slot>
29
+ </template>
30
+ <div :class="[ns.e('top')]" v-if="multiple">
31
+ <div :class="[ns.e('filter')]">
32
+ <el-input v-model="keyword" ref="filterInput" @input="changeKeyword">
33
+ <template #prefix>
34
+ <ct-icon name="search_line"></ct-icon>
35
+ </template>
36
+ </el-input>
37
+ </div>
38
+ <div :class="[ns.e('select')]" v-if="!rawAttr.multipleLimit">
39
+ <span :class="[ns.e('select-title')]">
40
+ <span v-if="!keyword">已选{{ selectLength }}项</span>
41
+ <span v-else>检索结果</span>
42
+ </span>
43
+ </div>
44
+ </div>
45
+ <div
46
+ :class="[ns.e('options')]"
47
+ v-show="!noFilterOptions"
48
+ ref="optionsRef"
49
+ @scroll="handleScrollLoad"
50
+ >
51
+ <slot>
52
+ <el-option
53
+ v-for="(item, index) in filterOptions"
54
+ :key="item.value"
55
+ :label="item.label"
56
+ :value="item.value"
57
+ :disabled="item.disabled"
58
+ >
59
+ <slot name="option" :item="item" :index="index">
60
+ <span :title="selectTooltip ? item.label : undefined">{{
61
+ item.label
62
+ }}</span>
63
+ </slot>
64
+ </el-option>
65
+ </slot>
66
+ </div>
67
+ <Empty :text="emptyText" v-if="multiple && noFilterOptions" />
68
+ <template #empty>
69
+ <div :class="[ns.e('top')]" v-if="multiple">
70
+ <div :class="[ns.e('filter')]">
71
+ <el-input v-model="keyword" ref="filterInput" @input="changeKeyword">
72
+ <template #prefix>
73
+ <ct-icon name="search_line"></ct-icon>
74
+ </template>
75
+ </el-input>
76
+ </div>
77
+ <div :class="[ns.e('select')]" v-if="!rawAttr.multipleLimit">
78
+ <span :class="[ns.e('select-title')]">
79
+ <span v-if="!keyword">已选{{ selectLength }}项</span>
80
+ <span v-else>检索结果</span>
81
+ </span>
82
+ </div>
83
+ </div>
84
+ <slot name="empty">
85
+ <Empty :text="emptyText" />
86
+ </slot>
87
+ </template>
88
+ </el-select>
89
+ </template>
90
+
91
+ <script setup>
92
+ import {
93
+ onMounted,
94
+ computed,
95
+ ref,
96
+ watch,
97
+ inject,
98
+ nextTick,
99
+ useAttrs,
100
+ } from "vue";
101
+ import { selectEmits, selectProps } from "./index";
102
+ import { useNamespace, useBuriedParams } from "../../../hooks";
103
+ import { isFunction, isArray } from "../../../utils";
104
+ import Empty from "./empty.vue";
105
+ const baseDao = inject("$ctBaseDao");
106
+ const serviceConfig = inject("$ctServiceConfig");
107
+ const selectTooltip = inject("$selectTooltip");
108
+
109
+ const props = defineProps(selectProps);
110
+ const emit = defineEmits(selectEmits);
111
+ const attrs = useAttrs();
112
+
113
+ const ns = useNamespace("select");
114
+ const optionsByApi = ref([]);
115
+ const showOptions = computed(() => {
116
+ return optionsByApi.value;
117
+ });
118
+ const valueModel = computed({
119
+ get() {
120
+ return props.modelValue || (props.multiple ? [] : props.modelValue);
121
+ },
122
+ set(newValue) {
123
+ emit("update:modelValue", newValue);
124
+ },
125
+ });
126
+ const keyword = ref("");
127
+ const selectRef = ref(null);
128
+ const filterInput = ref(null);
129
+
130
+ const selectLength = computed(() => {
131
+ return valueModel.value.length;
132
+ });
133
+ const filterOptions = ref([]);
134
+ const noFilterOptions = ref(false);
135
+ const pageNo = ref(1);
136
+ const pageSize = computed(() => props.pageSize || 20);
137
+ const total = ref(0);
138
+ const loading = ref(false);
139
+ const selectObj = computed({
140
+ get() {
141
+ if (!props.multiple)
142
+ return showOptions.value.find((item) => item.value === valueModel.value);
143
+ return showOptions.value.filter((item) => {
144
+ return valueModel.value.includes(item.value);
145
+ });
146
+ },
147
+ set(newValue) {
148
+ if (!props.multiple) {
149
+ valueModel.value = newValue.value;
150
+ } else {
151
+ valueModel.value = newValue.map((item) => item.value);
152
+ }
153
+ },
154
+ });
155
+ const selectText = computed(() => {
156
+ let result = "";
157
+ if (!props.multiple) {
158
+ return result;
159
+ } else {
160
+ if (
161
+ showOptions.value.length &&
162
+ showOptions.value.length === valueModel.value.length
163
+ ) {
164
+ result = props.selectAllText;
165
+ } else {
166
+ const cnt = props.connectors;
167
+ result = selectObj.value.map((item) => item.label).join(cnt);
168
+ }
169
+ }
170
+ //nextTick(() => {
171
+ // if (selectRef.value) {
172
+ // selectRef.value.$refs.reference.input.value = result;
173
+ // }
174
+ //});
175
+ return result;
176
+ });
177
+ const emptyText = computed(() => {
178
+ return showOptions.value.length
179
+ ? props.noMatchText || "暂无匹配数据"
180
+ : props.noDataText || "暂无数据";
181
+ });
182
+
183
+ const popperClass = computed(() => {
184
+ const defaultClass = ns.e("popper");
185
+ const userClass =
186
+ attrs["popper-class"] ||
187
+ attrs["popperClass"] ||
188
+ (props.rawAttr &&
189
+ (props.rawAttr["popper-class"] || props.rawAttr["popperClass"])) ||
190
+ "";
191
+ return `${defaultClass} ${userClass}`.trim();
192
+ });
193
+
194
+ const getUseLabel = (label) => {
195
+ return typeof label === "string" ? label : String(label);
196
+ };
197
+
198
+ watch(
199
+ () => selectText.value,
200
+ (newVal) => {
201
+ if (!selectRef.value) return;
202
+ selectRef.value.selectedLabel = newVal;
203
+ }
204
+ );
205
+ watch(optionsByApi, () => {
206
+ const arr = optionsByApi.value || [];
207
+ if (arr.length) {
208
+ filterOptions.value = arr;
209
+ noFilterOptions.value = false;
210
+ } else {
211
+ filterOptions.value = [];
212
+ noFilterOptions.value = true;
213
+ }
214
+ });
215
+
216
+ const optionsRef = ref(null);
217
+ //针对多选时,已选的项要排在整个列表的最前面
218
+ const handleListSort = (val) => {
219
+ if (props.multiple) {
220
+ if (val) {
221
+ const selectedSet = new Set(valueModel.value);
222
+ filterOptions.value = [
223
+ ...filterOptions.value.filter((item) => selectedSet.has(item.value)), // 选中的项
224
+ ...filterOptions.value.filter((item) => !selectedSet.has(item.value)), // 未选中的项
225
+ ];
226
+ nextTick(() => {
227
+ optionsRef.value.scrollTop = 0;
228
+ });
229
+ } else {
230
+ keyword.value = "";
231
+ if (!valueModel.value.length) {
232
+ filterOptions.value = [...showOptions.value];
233
+ }
234
+ }
235
+ }
236
+ };
237
+ const watchServiceHandle = async (reset = false) => {
238
+ // 通过api获取数据,会监听api以及serviceParams的改变(收集到的依赖改变)都会触发重新查询
239
+ const cbs = props.cbs || {};
240
+ if (props.api && baseDao) {
241
+ try {
242
+ const method = props.serviceMethod || serviceConfig.defaultMethod;
243
+ let params = { ...(props.serviceParams || {}) };
244
+ if (reset) {
245
+ pageNo.value = 1;
246
+ optionsByApi.value = [];
247
+ }
248
+ params.keyword = keyword.value;
249
+ params.page_no = pageNo.value;
250
+ params.page_size = pageSize.value;
251
+ if (isFunction(cbs.beforeSearch)) {
252
+ const paramsHandle = await cbs.beforeSearch(params);
253
+ if (paramsHandle === false) return;
254
+ params = paramsHandle || params;
255
+ }
256
+ loading.value = true;
257
+ baseDao[method](props.api, params)
258
+ .then((res) => {
259
+ const mapObj = props.mapObj || {};
260
+ const {
261
+ list,
262
+ label = "label",
263
+ value = "value",
264
+ self,
265
+ total: totalKey = "total",
266
+ } = mapObj;
267
+ let data = [];
268
+ if (list) {
269
+ data = res[list];
270
+ } else {
271
+ data = res;
272
+ }
273
+ data = data.map((item) => {
274
+ if (self) {
275
+ return { label: getUseLabel(item), value: item };
276
+ }
277
+ return {
278
+ ...item,
279
+ label: getUseLabel(item[label]),
280
+ value: item[value],
281
+ };
282
+ });
283
+ total.value = (res && res[totalKey]) || 0;
284
+ optionsByApi.value =
285
+ pageNo.value > 1 ? optionsByApi.value.concat(data) : data;
286
+ if (isFunction(cbs.afterSearch)) {
287
+ cbs.afterSearch(res, optionsByApi, valueModel);
288
+ }
289
+ })
290
+ .finally(() => {
291
+ loading.value = false;
292
+ });
293
+ } catch (error) {
294
+ console.error(error);
295
+ }
296
+ }
297
+ if (isFunction(cbs.defineSearch)) {
298
+ try {
299
+ const defineSearchHandle = await cbs.defineSearch(
300
+ optionsByApi,
301
+ valueModel
302
+ );
303
+ if (defineSearchHandle === false) return;
304
+ if (defineSearchHandle) {
305
+ optionsByApi.value = defineSearchHandle;
306
+ }
307
+ } catch (error) {}
308
+ }
309
+ };
310
+ watch(
311
+ [
312
+ () => props.api,
313
+ () => props.serviceParams,
314
+ () => props.serviceMethod,
315
+ () => props.mapObj,
316
+ ],
317
+ (newVal, oldVal) => {
318
+ watchServiceHandle(true);
319
+ },
320
+ {
321
+ immediate: true,
322
+ }
323
+ );
324
+ // watch(
325
+ // () => keyword.value,
326
+ // () => {
327
+
328
+ // watchServiceHandle(true);
329
+ // }
330
+ // );
331
+
332
+ function debounce(fn, delay = 300) {
333
+ //防抖
334
+ var timer = null; //借助闭包
335
+ return function (...args) {
336
+ const context = this;
337
+ clearTimeout(timer);
338
+ timer = setTimeout(() => {
339
+ fn.apply(context, args);
340
+ }, delay);
341
+ };
342
+ }
343
+ const changeKeyword = debounce(() => {
344
+ watchServiceHandle(true);
345
+ });
346
+
347
+ const handleScrollLoad = (e) => {
348
+ const el = e.target;
349
+ const reach = el.scrollTop + el.clientHeight >= el.scrollHeight - 2;
350
+ const hasMore = total.value > pageNo.value * pageSize.value;
351
+ if (reach && hasMore && !loading.value) {
352
+ pageNo.value += 1;
353
+ watchServiceHandle();
354
+ }
355
+ };
356
+
357
+ const focusFilter = () => {
358
+ if (filterInput.value && filterInput.value.focus) {
359
+ filterInput.value.focus();
360
+ }
361
+ };
362
+
363
+ const showSearch = ref(false);
364
+ const focusSearchInput = () => {
365
+ setTimeout(() => {
366
+ filterInput.value && filterInput.value.focus();
367
+ // keyword.value = "";
368
+ }, 300);
369
+ };
370
+ const showSearchPrefix = () => {
371
+ showSearch.value = true;
372
+ };
373
+ const hideSearchPrefix = () => {
374
+ showSearch.value = false;
375
+ };
376
+
377
+ useBuriedParams(props, emit, {
378
+ getContent: () => {
379
+ const select = selectObj.value || {};
380
+ if (isArray(select)) {
381
+ return select.map((item) => item.label);
382
+ }
383
+ return select.label;
384
+ },
385
+ });
386
+
387
+ onMounted(() => {
388
+ if (!baseDao) {
389
+ console.error("请先配置baseDao");
390
+ }
391
+ });
392
+ defineExpose({
393
+ ref: selectRef,
394
+ keyword,
395
+ filterInput,
396
+ focusFilter,
397
+ baseDao,
398
+ serviceConfig,
399
+ noFilterOptions,
400
+ selectObj,
401
+ });
402
+ </script>
403
+ <style lang="less">
404
+ .ct-select {
405
+ width: 214px;
406
+ &.el-select {
407
+ position: relative;
408
+ }
409
+ &__top {
410
+ padding: 0 16px;
411
+ font-size: var(--ct-font-size);
412
+ }
413
+ &__options {
414
+ max-height: 274px;
415
+ overflow-y: auto;
416
+ }
417
+ &__select {
418
+ display: flex;
419
+ justify-content: space-between;
420
+ align-items: center;
421
+ margin-bottom: 10px;
422
+ &-title {
423
+ color: var(--ct-color-grey-sub);
424
+ line-height: 1;
425
+ }
426
+ .el-checkbox {
427
+ height: auto;
428
+ }
429
+ }
430
+ &__filter {
431
+ margin-bottom: 16px;
432
+ .el-input {
433
+ --el-input-height: 28px;
434
+ }
435
+ }
436
+ &__popper {
437
+ &.is-multiple {
438
+ min-width: 140px;
439
+ }
440
+ .el-select-dropdown__wrap {
441
+ max-height: unset;
442
+ }
443
+ }
444
+ .el-select__tags {
445
+ display: none;
446
+ }
447
+ .el-input__prefix-inner {
448
+ & > :last-child {
449
+ margin-right: 0;
450
+ }
451
+ }
452
+ &__filterable-icon {
453
+ position: absolute;
454
+ z-index: 3;
455
+ right: var(--ct-component-inner-padding);
456
+ top: 50%;
457
+ height: calc(var(--ct-component-size) - 2px);
458
+ transform: translateY(-50%);
459
+ background-color: #fff;
460
+ }
461
+ &__empty {
462
+ display: flex;
463
+ justify-content: center;
464
+ align-items: center;
465
+ padding: 15px 16px;
466
+ color: var(--ct-color-grey-sub);
467
+ }
468
+ &.is-multiple {
469
+ &::after {
470
+ content: attr(select-text);
471
+ position: absolute;
472
+ left: var(--ct-component-inner-padding);
473
+ right: calc(var(--ct-component-inner-padding) * 2);
474
+ top: 50%;
475
+ transform: translateY(-50%);
476
+ text-overflow: ellipsis;
477
+ overflow: hidden;
478
+ white-space: nowrap;
479
+ cursor: pointer;
480
+ pointer-events: none;
481
+ }
482
+ .el-select__placeholder.is-transparent {
483
+ display: block;
484
+ }
485
+ .el-select__selected-item {
486
+ display: none;
487
+ }
488
+ }
489
+ }
490
+ </style>
@@ -6,6 +6,7 @@ import CtDatePicker from '../date-picker';
6
6
  import CtCascader from '../cascader';
7
7
  import CtYearSelect from '../year-select';
8
8
  import CtRadio from '../radio';
9
+ import CtPagingSelect from '../paging-select';
9
10
 
10
11
  export const searchComponents = {
11
12
  CtInput,
@@ -13,7 +14,8 @@ export const searchComponents = {
13
14
  CtDatePicker,
14
15
  CtCascader,
15
16
  CtYearSelect,
16
- CtRadio
17
+ CtRadio,
18
+ CtPagingSelect,
17
19
  }
18
20
 
19
21
  /* istanbul ignore next */
@@ -2,48 +2,29 @@
2
2
  <div :class="[ns.b()]">
3
3
  <div :class="[ns.e('container')]">
4
4
  <div :class="[ns.e('list')]">
5
- <div
6
- v-for="(item, index) in searchList"
7
- :class="[
8
- ns.e('item'),
9
- ...getComponentClass(item),
10
- ns.is('outer-border', outerBorder),
11
- ]"
12
- :key="item.param || index"
13
- :style="{ ...getComponentStyle(item) }"
14
- @click="clickItem(item)"
15
- >
5
+ <div v-for="(item, index) in searchList" :class="[
6
+ ns.e('item'),
7
+ ...getComponentClass(item),
8
+ ns.is('outer-border', outerBorder),
9
+ ]" :key="item.param || index" :style="{ ...getComponentStyle(item) }" @click="clickItem(item)">
16
10
  <slot v-bind="getComponentSlotScope(item)">
17
11
  <slot name="item-before" v-bind="getComponentSlotScope(item)">
18
12
  </slot>
19
- <span
20
- :class="[
21
- ns.e('item-label'),
22
- ns.is('required', item.required),
23
- ns.is('outer-border', outerBorder),
24
- ]"
25
- >
26
- <el-tooltip
27
- :disabled="judgeIsHideLabelTooltip(item)"
28
- class="box-item"
29
- effect="dark"
30
- :content="item.label"
31
- placement="bottom"
32
- >
13
+ <span :class="[
14
+ ns.e('item-label'),
15
+ ns.is('required', item.required),
16
+ ns.is('outer-border', outerBorder),
17
+ ]">
18
+ <el-tooltip :disabled="judgeIsHideLabelTooltip(item)" class="box-item" effect="dark" :content="item.label"
19
+ placement="bottom">
33
20
  <span>{{ item.label }}</span>
34
21
  </el-tooltip>
35
22
  <span :class="[ns.is('required')]" v-if="!outerBorder">:</span>
36
23
  </span>
37
24
  <div :class="[ns.e('item-component')]">
38
- <slot
39
- :name="item.componentName || item.param"
40
- v-bind="getComponentSlotScope(item)"
41
- >
42
- <component
43
- :is="getComponent(item.type)"
44
- v-model="searchParamsCurrent[item.param]"
45
- v-bind="getComponentProps(item)"
46
- >
25
+ <slot :name="item.componentName || item.param" v-bind="getComponentSlotScope(item)">
26
+ <component :is="getComponent(item.type)" v-model="searchParamsCurrent[item.param]"
27
+ v-bind="getComponentProps(item)">
47
28
  </component>
48
29
  </slot>
49
30
  </div>
@@ -52,9 +33,7 @@
52
33
  </div>
53
34
  <div :class="[ns.e('buttons')]">
54
35
  <slot name="solt-search">
55
- <ct-button type="border-plain" @click="resetData" v-if="haveReset"
56
- >重置</ct-button
57
- >
36
+ <ct-button type="border-plain" @click="resetData" v-if="haveReset">重置</ct-button>
58
37
  <ct-button type="border" @click="doSearch">{{
59
38
  searchBtnName
60
39
  }}</ct-button>
@@ -117,7 +96,15 @@ const getComponentStyle = (item) => {
117
96
  return style;
118
97
  };
119
98
  const componentAll = computed(() => {
120
- const { CtInput, CtSelect, CtDatePicker, CtCascader, CtYearSelect, CtRadio } =
99
+ const {
100
+ CtInput,
101
+ CtSelect,
102
+ CtDatePicker,
103
+ CtCascader,
104
+ CtYearSelect,
105
+ CtRadio,
106
+ CtPagingSelect,
107
+ } =
121
108
  searchComponents;
122
109
  const componentMap = {
123
110
  0: CtInput,
@@ -127,6 +114,7 @@ const componentAll = computed(() => {
127
114
  12: CtYearSelect,
128
115
  13: "div",
129
116
  20: CtRadio,
117
+ 22: CtPagingSelect,
130
118
  ...userDefinedSearchComponent,
131
119
  };
132
120
  return componentMap;
@@ -193,34 +181,36 @@ defineExpose({
193
181
  buriedParams,
194
182
  doSearch,
195
183
  });
196
- onMounted(() => {});
184
+ onMounted(() => { });
197
185
  </script>
198
186
  <style lang="less">
199
187
  .ct-search-box {
200
188
  --ct-search-box-item-margin-right: 16px;
201
189
  --ct-search-box-item-margin-top: 14px;
190
+
202
191
  .el-input {
203
192
  --ct-input-default-width: auto;
204
193
  }
194
+
205
195
  &__list {
206
196
  display: flex;
207
197
  align-items: center;
208
198
  flex-wrap: wrap;
209
199
  margin-right: calc(-1 * var(--ct-search-box-item-margin-right));
210
200
  margin-top: calc(-1 * var(--ct-search-box-item-margin-top));
211
- > * {
201
+
202
+ >* {
212
203
  margin-right: var(--ct-search-box-item-margin-right);
213
204
  margin-top: var(--ct-search-box-item-margin-top);
214
205
  }
215
206
  }
207
+
216
208
  &__item {
217
209
  display: flex;
218
210
  align-items: center;
219
- width: calc(
220
- (100% - v-bind(rowNumber) * var(--ct-search-box-item-margin-right)) /
221
- v-bind(rowNumber)
222
- );
211
+ width: calc((100% - v-bind(rowNumber) * var(--ct-search-box-item-margin-right)) / v-bind(rowNumber));
223
212
  --ct-search-box-item-component-width: 100%;
213
+
224
214
  &.is-outer-border {
225
215
  --ct-font-size: 13px;
226
216
  --el-font-size-base: var(--ct-font-size, 13px);
@@ -231,45 +221,55 @@ onMounted(() => {});
231
221
  padding-left: 14px;
232
222
  box-shadow: 0 0 0 1px var(--ct-search-box-border-color);
233
223
  border-radius: var(--ct-border-radius);
224
+
234
225
  &:hover {
235
226
  --ct-search-box-border-color: var(--ct-color-grey-sub);
236
227
  }
228
+
237
229
  &:focus-within {
238
230
  --ct-search-box-border-color: var(--ct-color-primary);
239
231
  }
232
+
240
233
  .el-input__wrapper,
241
234
  .el-select__wrapper,
242
235
  .ct-year-select__wrapper {
243
- --el-select-input-focus-border-color: var(
244
- --ct-search-box-inner-border-color
245
- );
236
+ --el-select-input-focus-border-color: var(--ct-search-box-inner-border-color);
246
237
  box-shadow: 0 0 0 1px var(--ct-search-box-inner-border-color) !important;
247
238
  }
248
239
  }
240
+
249
241
  .ct-radio {
250
242
  padding: 0 var(--ct-component-inner-padding);
243
+
251
244
  .el-radio {
252
245
  margin-right: 12px;
246
+
253
247
  &:last-child {
254
248
  margin-right: 0;
255
249
  }
256
250
  }
257
251
  }
252
+
258
253
  &-label {
259
254
  line-height: 1;
255
+
260
256
  &.is-outer-border {
261
257
  color: var(--ct-color-grey-sub);
262
258
  }
263
259
  }
260
+
264
261
  &-component {
265
262
  flex: 1;
266
- > * {
263
+
264
+ >* {
267
265
  width: var(--ct-search-box-item-component-width) !important;
268
266
  }
269
267
  }
270
268
  }
269
+
271
270
  &__buttons {
272
271
  margin-left: auto;
272
+
273
273
  button {
274
274
  width: 96px;
275
275
  padding: 0;