focusin-mini-ui 1.0.2 → 1.0.4

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.
Files changed (37) hide show
  1. package/package.json +38 -36
  2. package/packages/fs-col-picker/index.vue +609 -0
  3. package/packages/fs-collapse/index.scss +0 -0
  4. package/packages/fs-collapse/index.vue +113 -0
  5. package/packages/fs-common-audio/index.scss +0 -0
  6. package/packages/fs-common-audio/index.vue +257 -0
  7. package/packages/fs-empty/index.scss +0 -0
  8. package/packages/fs-empty/index.vue +33 -0
  9. package/packages/fs-form/index.scss +0 -0
  10. package/packages/fs-form/index.vue +804 -0
  11. package/packages/fs-list-check/index.scss +0 -0
  12. package/packages/fs-list-check/index.vue +49 -0
  13. package/packages/fs-pop/index.scss +0 -0
  14. package/packages/fs-pop/index.vue +136 -0
  15. package/packages/fs-radio/index.scss +0 -0
  16. package/packages/fs-radio/index.vue +114 -0
  17. package/packages/fs-search-bar/index.scss +0 -0
  18. package/packages/fs-search-bar/index.vue +57 -0
  19. package/packages/fs-select-button/context.ts +20 -0
  20. package/packages/fs-select-button/index.scss +0 -0
  21. package/packages/fs-select-button/index.vue +111 -0
  22. package/packages/fs-select-button/sButton.vue +38 -0
  23. package/packages/fs-table/index.scss +0 -0
  24. package/packages/fs-table/index.vue +94 -0
  25. package/packages/fs-tabs/index.scss +0 -0
  26. package/packages/fs-tabs/index.vue +140 -0
  27. package/packages/fs-time-bar/index.scss +0 -0
  28. package/packages/fs-time-bar/index.vue +168 -0
  29. package/packages/fs-tree/index.scss +0 -0
  30. package/packages/fs-tree/index.vue +249 -0
  31. package/packages/fs-voice-pop/index.scss +0 -0
  32. package/packages/fs-voice-pop/index.vue +150 -0
  33. package/packages/index.js +1 -0
  34. package/style.scss +57 -0
  35. package/utils/common.ts +458 -372
  36. package/packages/fs-demo/index.vue +0 -8
  37. /package/packages/{fs-demo → fs-col-picker}/index.scss +0 -0
package/package.json CHANGED
@@ -1,38 +1,40 @@
1
1
  {
2
- "name": "focusin-mini-ui",
3
- "version": "1.0.2",
4
- "description": "A collection of UniApp components built with Vue3",
5
- "main": "dist/FocusinMiniUi.umd.js",
6
- "module": "dist/FocusinMiniUi.es.js",
7
- "files": [
8
- "dist",
9
- "packages",
10
- "*.scss",
11
- "index.ts",
12
- "utils"
13
- ],
14
- "scripts": {
15
- "dev": "vite",
16
- "build": "vite build",
17
- "prepublishOnly": "npm run build"
18
- },
19
- "peerDependencies": {
20
- "@dcloudio/uni-app": "3.0.0-4020920240930001",
21
- "unocss": "^0.58.9",
22
- "unocss-applet": "^0.7.8",
23
- "wot-design-uni": "^1.7.1",
24
- "vue": "3.4.21",
25
- "vue-demi": "^0.14.10",
26
- "xe-utils": "3.7.4"
27
- },
28
- "devDependencies": {
29
- "vite": "^4.0.0",
30
- "@vitejs/plugin-vue": "^4.0.0",
31
- "tailwindcss": "^3.0.0",
32
- "wot-design-uni": "^1.7.1",
33
- "postcss": "^8.4.49",
34
- "postcss-html": "^1.7.0",
35
- "postcss-scss": "^4.0.9",
36
- "sass": "1.77.8"
37
- }
2
+ "name": "focusin-mini-ui",
3
+ "version": "1.0.4",
4
+ "description": "A collection of UniApp components built with Vue3",
5
+ "main": "index",
6
+ "module": "index",
7
+ "files": [
8
+ "dist",
9
+ "packages",
10
+ "*.scss",
11
+ "index.ts",
12
+ "utils"
13
+ ],
14
+ "scripts": {
15
+ "dev": "vite",
16
+ "build": "vite build",
17
+ "prepublishOnly": "npm run build"
18
+ },
19
+ "peerDependencies": {
20
+ "@dcloudio/uni-app": "3.0.0-4020920240930001",
21
+ "unocss": "^0.58.9",
22
+ "unocss-applet": "^0.7.8",
23
+ "wot-design-uni": "^1.7.1",
24
+ "vue": "3.4.21",
25
+ "vue-demi": "^0.14.10",
26
+ "xe-utils": "3.7.4"
27
+ },
28
+ "devDependencies": {
29
+ "vite": "^4.0.0",
30
+ "@vitejs/plugin-vue": "^4.0.0",
31
+ "tailwindcss": "^3.0.0",
32
+ "wot-design-uni": "^1.7.1",
33
+ "postcss": "^8.4.49",
34
+ "postcss-html": "^1.7.0",
35
+ "postcss-scss": "^4.0.9",
36
+ "sass": "1.77.8",
37
+ "typescript": "^5.7.2",
38
+ "@types/node": "^20.17.9"
39
+ }
38
40
  }
@@ -0,0 +1,609 @@
1
+ <template>
2
+ <view
3
+ :class="`wd-col-picker ${cell.border.value ? 'is-border' : ''} ${customClass}`"
4
+ :style="customStyle"
5
+ >
6
+ <view class="wd-col-picker__field" @click="showPicker">
7
+ <slot v-if="useDefaultSlot"></slot>
8
+ <view
9
+ v-else
10
+ :class="`wd-col-picker__cell ${disabled && 'is-disabled'} ${readonly && 'is-readonly'} ${
11
+ alignRight && 'is-align-right'
12
+ } ${error && 'is-error'} ${size && 'is-' + size}`"
13
+ >
14
+ <view
15
+ v-if="label || useLabelSlot"
16
+ :class="`wd-col-picker__label ${isRequired && 'is-required'} ${customLabelClass}`"
17
+ :style="labelWidth ? 'min-width:' + labelWidth + ';max-width:' + labelWidth + ';' : ''"
18
+ >
19
+ <block v-if="label">{{ label }}</block>
20
+ <slot v-else name="label"></slot>
21
+ </view>
22
+ <view class="wd-col-picker__body">
23
+ <view class="wd-col-picker__value-wraper">
24
+ <view
25
+ :class="`wd-col-picker__value ${ellipsis && 'is-ellipsis'} ${customValueClass} ${
26
+ showValue ? '' : 'wd-col-picker__value--placeholder'
27
+ }`"
28
+ >
29
+ {{ showValue || placeholder || translate('placeholder') }}
30
+ </view>
31
+ <wd-icon
32
+ v-if="!disabled && !readonly"
33
+ custom-class="wd-col-picker__arrow"
34
+ name="arrow-right"
35
+ />
36
+ </view>
37
+ <view v-if="errorMessage" class="wd-col-picker__error-message">{{ errorMessage }}</view>
38
+ </view>
39
+ </view>
40
+ </view>
41
+ <wd-action-sheet
42
+ v-model="pickerShow"
43
+ :duration="250"
44
+ :title="title || translate('title')"
45
+ :close-on-click-modal="closeOnClickModal"
46
+ :z-index="zIndex"
47
+ :safe-area-inset-bottom="safeAreaInsetBottom"
48
+ @open="handlePickerOpend"
49
+ @close="handlePickerClose"
50
+ @closed="handlePickerClosed"
51
+ >
52
+ <wd-search
53
+ v-model="filterVal"
54
+ placeholder="请输入"
55
+ hide-cancel
56
+ placeholder-left
57
+ @change="handleFilterChange"
58
+ />
59
+ <view class="wd-col-picker__selected">
60
+ <scroll-view :scroll-x="true" scroll-with-animation :scroll-left="scrollLeft">
61
+ <view class="wd-col-picker__selected-container">
62
+ <view
63
+ v-for="(_, colIndex) in selectList"
64
+ :key="colIndex"
65
+ :class="`wd-col-picker__selected-item ${colIndex === currentCol && 'is-selected'}`"
66
+ @click="handleColClick(colIndex)"
67
+ >
68
+ {{ selectShowList[colIndex] || translate('select') }}
69
+ </view>
70
+ <view class="wd-col-picker__selected-line" :style="state.lineStyle"></view>
71
+ </view>
72
+ </scroll-view>
73
+ </view>
74
+ <view class="wd-col-picker__list-container">
75
+ <view
76
+ v-for="(col, colIndex) in selectList"
77
+ :key="colIndex"
78
+ class="wd-col-picker__list"
79
+ :style="colIndex === currentCol ? 'display: block;' : 'display: none;'"
80
+ >
81
+ <view
82
+ style="display: flex; justify-content: space-between"
83
+ v-for="(item, index) in col"
84
+ :key="index"
85
+ :class="`wd-col-picker__list-item ${
86
+ pickerColSelected[colIndex] &&
87
+ item[valueKey] === pickerColSelected[colIndex] &&
88
+ 'is-selected'
89
+ } ${item.disabled && 'is-disabled'}`"
90
+ @click="chooseItem(colIndex, index)"
91
+ >
92
+ <view>
93
+ <view class="wd-col-picker__list-item-label">{{ item[labelKey] }}</view>
94
+ <view v-if="item[tipKey]" class="wd-col-picker__list-item-tip">
95
+ {{ item[tipKey] }}
96
+ </view>
97
+ </view>
98
+ <wd-icon
99
+ custom-class="wd-col-picker__checked"
100
+ name="check"
101
+ v-if="pickerColSelected[colIndex] && item[valueKey] === pickerColSelected[colIndex]"
102
+ ></wd-icon>
103
+ </view>
104
+ <view v-if="loading" class="wd-col-picker__loading">
105
+ <wd-loading :color="loadingColor" />
106
+ </view>
107
+ </view>
108
+ </view>
109
+ </wd-action-sheet>
110
+ </view>
111
+ </template>
112
+ <script lang="ts" setup>
113
+ import wdIcon from 'wot-design-uni/components/wd-icon/wd-icon.vue';
114
+ import wdLoading from 'wot-design-uni/components/wd-loading/wd-loading.vue';
115
+ import wdActionSheet from 'wot-design-uni/components/wd-action-sheet/wd-action-sheet.vue';
116
+
117
+ import {
118
+ computed,
119
+ getCurrentInstance,
120
+ onMounted,
121
+ ref,
122
+ watch,
123
+ type CSSProperties,
124
+ reactive,
125
+ nextTick,
126
+ } from 'vue';
127
+ import {
128
+ addUnit,
129
+ debounce,
130
+ getRect,
131
+ isArray,
132
+ isBoolean,
133
+ isDef,
134
+ isFunction,
135
+ objToStyle,
136
+ } from '../../utils/common';
137
+ import { useCell } from '../../composables/useCell';
138
+ import { FORM_KEY, type FormItemRule } from 'wot-design-uni/components/wd-form/types';
139
+ import { useParent } from '../../composables/useParent';
140
+ import { useTranslate } from '../../composables/useTranslate';
141
+ import {
142
+ colPickerProps,
143
+ type ColPickerExpose,
144
+ } from 'wot-design-uni/components/wd-col-picker/types';
145
+ import XEUtils from 'xe-utils';
146
+
147
+ const { translate } = useTranslate('col-picker');
148
+
149
+ const $container = '.wd-col-picker__selected-container';
150
+ const $item = '.wd-col-picker__selected-item';
151
+ const filterVal = ref<string>('');
152
+ const props = defineProps(colPickerProps);
153
+ const emit = defineEmits(['close', 'update:modelValue', 'confirm']);
154
+ const cell = useCell();
155
+ const pickerShow = ref<boolean>(false);
156
+ const currentCol = ref<number>(0);
157
+ const selectList = ref<Record<string, any>[][]>([]);
158
+ const pickerColSelected = ref<(string | number)[]>([]);
159
+ const selectShowList = ref<Record<string, any>[]>([]);
160
+ const loading = ref<boolean>(false);
161
+ const isChange = ref<boolean>(false);
162
+ const lastSelectList = ref<Record<string, any>[][]>([]);
163
+ const lastPickerColSelected = ref<(string | number)[]>([]);
164
+ const scrollLeft = ref<number>(0);
165
+ const inited = ref<boolean>(false);
166
+ const isCompleting = ref<boolean>(false);
167
+
168
+ const state = reactive({
169
+ lineStyle: 'display:none;', // 激活项边框线样式
170
+ });
171
+
172
+ const { proxy } = getCurrentInstance() as any;
173
+ const originalData = ref<Record<string, any>[][]>([]); // Store original all columns data
174
+
175
+ // Initialize original data when component mounts or props.columns changes
176
+ watch(
177
+ () => props.columns,
178
+ (newValue) => {
179
+ if (newValue.length > 0) {
180
+ originalData.value = XEUtils.clone(newValue, true);
181
+ }
182
+ },
183
+ { immediate: true, deep: true }
184
+ );
185
+
186
+ const deepFilter = (data: Record<string, any>[], searchText: string): Record<string, any>[] => {
187
+ return XEUtils.searchTree(data, (item) =>
188
+ item[props.labelKey]?.toLowerCase().includes(searchText.toLowerCase())
189
+ );
190
+ };
191
+
192
+ const handleFilterChange = debounce(function () {
193
+ const searchText = filterVal.value.trim().toLowerCase();
194
+
195
+ if (searchText === '') {
196
+ selectList.value = originalData.value;
197
+ console.log(originalData.value);
198
+ pickerColSelected.value = [originalData.value[0][props.labelKey]];
199
+ currentCol.value = 0;
200
+ return;
201
+ }
202
+
203
+ if (selectList.value.length > 0 && originalData.value.length > 0) {
204
+ const cc = XEUtils.clone(originalData.value, true);
205
+ const filteredData = deepFilter(cc[0], searchText);
206
+ selectList.value = [];
207
+ pickerColSelected.value = [];
208
+ selectList.value[0] = filteredData;
209
+ console.log(filteredData[0][props.labelKey]);
210
+ pickerColSelected.value = [filteredData[0][props.labelKey]];
211
+
212
+ currentCol.value = 0;
213
+ updateLineAndScroll(true);
214
+ }
215
+ }, 300);
216
+ const updateLineAndScroll = debounce(function (animation = true) {
217
+ setLineStyle(animation);
218
+ lineScrollIntoView();
219
+ }, 50);
220
+
221
+ const showValue = computed(() => {
222
+ const selectedItems = (props.modelValue || []).map((item, colIndex) => {
223
+ return getSelectedItem(item, colIndex, selectList.value);
224
+ });
225
+
226
+ if (props.displayFormat) {
227
+ return props.displayFormat(selectedItems);
228
+ } else {
229
+ return selectedItems
230
+ .map((item) => {
231
+ return item[props.labelKey];
232
+ })
233
+ .join('');
234
+ }
235
+ });
236
+
237
+ watch(
238
+ () => props.modelValue,
239
+ (newValue) => {
240
+ if (newValue === pickerColSelected.value) return;
241
+ pickerColSelected.value = newValue;
242
+ newValue.map((item, colIndex) => {
243
+ return getSelectedItem(item, colIndex, selectList.value)[props.labelKey];
244
+ });
245
+ handleAutoComplete();
246
+ },
247
+ {
248
+ deep: true,
249
+ immediate: true,
250
+ }
251
+ );
252
+
253
+ watch(
254
+ () => props.columns,
255
+ (newValue, oldValue) => {
256
+ if (newValue.length && !isArray(newValue[0])) {
257
+ console.error(
258
+ '[wot design] error(wd-col-picker): the columns props of wd-col-picker should be a two-dimensional array'
259
+ );
260
+ return;
261
+ }
262
+ if (newValue.length === 0 && !oldValue) return;
263
+
264
+ const newSelectedList = newValue.slice(0);
265
+
266
+ selectList.value = newSelectedList;
267
+
268
+ selectShowList.value = pickerColSelected.value.map((item, colIndex) => {
269
+ return getSelectedItem(item, colIndex, newSelectedList)[props.labelKey];
270
+ });
271
+ lastSelectList.value = newSelectedList;
272
+
273
+ if (newSelectedList.length > 0) {
274
+ currentCol.value = newSelectedList.length - 1;
275
+ }
276
+ },
277
+ {
278
+ deep: true,
279
+ immediate: true,
280
+ }
281
+ );
282
+
283
+ watch(
284
+ () => props.columnChange,
285
+ (fn) => {
286
+ if (fn && !isFunction(fn)) {
287
+ console.error('The type of columnChange must be Function');
288
+ }
289
+ },
290
+ {
291
+ deep: true,
292
+ immediate: true,
293
+ }
294
+ );
295
+
296
+ watch(
297
+ () => props.displayFormat,
298
+ (fn) => {
299
+ if (fn && !isFunction(fn)) {
300
+ console.error('The type of displayFormat must be Function');
301
+ }
302
+ },
303
+ {
304
+ deep: true,
305
+ immediate: true,
306
+ }
307
+ );
308
+
309
+ watch(
310
+ () => props.beforeConfirm,
311
+ (fn) => {
312
+ if (fn && !isFunction(fn)) {
313
+ console.error('The type of beforeConfirm must be Function');
314
+ }
315
+ },
316
+ {
317
+ deep: true,
318
+ immediate: true,
319
+ }
320
+ );
321
+
322
+ const { parent: form } = useParent(FORM_KEY);
323
+
324
+ // 表单校验错误信息
325
+ const errorMessage = computed(() => {
326
+ if (form && props.prop && form.errorMessages && form.errorMessages[props.prop]) {
327
+ return form.errorMessages[props.prop];
328
+ } else {
329
+ return '';
330
+ }
331
+ });
332
+
333
+ // 是否展示必填
334
+ const isRequired = computed(() => {
335
+ let formRequired = false;
336
+ if (form && form.props.rules) {
337
+ const rules = form.props.rules;
338
+ for (const key in rules) {
339
+ if (
340
+ Object.prototype.hasOwnProperty.call(rules, key) &&
341
+ key === props.prop &&
342
+ Array.isArray(rules[key])
343
+ ) {
344
+ formRequired = rules[key].some((rule: FormItemRule) => rule.required);
345
+ }
346
+ }
347
+ }
348
+ return props.required || props.rules.some((rule) => rule.required) || formRequired;
349
+ });
350
+
351
+ onMounted(() => {
352
+ inited.value = true;
353
+ });
354
+
355
+ // 打开弹框
356
+ function open() {
357
+ showPicker();
358
+ }
359
+ // 关闭弹框
360
+ function close() {
361
+ handlePickerClose();
362
+ }
363
+ function handlePickerOpend() {
364
+ updateLineAndScroll(false);
365
+ }
366
+
367
+ function handlePickerClose() {
368
+ pickerShow.value = false;
369
+ emit('close');
370
+ }
371
+
372
+ function handlePickerClosed() {
373
+ if (isChange.value) {
374
+ setTimeout(() => {
375
+ selectList.value = lastSelectList.value.slice(0);
376
+ pickerColSelected.value = lastPickerColSelected.value.slice(0);
377
+ selectShowList.value = lastPickerColSelected.value.map((item, colIndex) => {
378
+ return getSelectedItem(item, colIndex, lastSelectList.value)[props.labelKey];
379
+ });
380
+ currentCol.value = lastSelectList.value.length - 1;
381
+ isChange.value = false;
382
+ }, 250);
383
+ }
384
+ }
385
+
386
+ function showPicker() {
387
+ const { disabled, readonly } = props;
388
+
389
+ if (disabled || readonly) return;
390
+ pickerShow.value = true;
391
+ lastPickerColSelected.value = pickerColSelected.value.slice(0);
392
+ lastSelectList.value = selectList.value.slice(0);
393
+ }
394
+
395
+ function getSelectedItem(
396
+ value: string | number,
397
+ colIndex: number,
398
+ selectList: Record<string, any>[][]
399
+ ) {
400
+ const { valueKey, labelKey } = props;
401
+ if (selectList[colIndex]) {
402
+ const selecteds = selectList[colIndex].filter((item) => {
403
+ return item[valueKey] === value;
404
+ });
405
+
406
+ if (selecteds.length > 0) {
407
+ return selecteds[0];
408
+ }
409
+ }
410
+
411
+ return {
412
+ [valueKey]: value,
413
+ [labelKey]: '',
414
+ };
415
+ }
416
+
417
+ function chooseItem(colIndex: number, index: number) {
418
+ const item = selectList.value[colIndex][index];
419
+ if (item.disabled) return;
420
+
421
+ const newPickerColSelected = pickerColSelected.value.slice(0, colIndex);
422
+ newPickerColSelected.push(item[props.valueKey]);
423
+ isChange.value = true;
424
+ pickerColSelected.value = newPickerColSelected;
425
+ selectList.value = selectList.value.slice(0, colIndex + 1);
426
+ selectShowList.value = newPickerColSelected.map((item, colIndex) => {
427
+ return getSelectedItem(item, colIndex, selectList.value)[props.labelKey];
428
+ });
429
+
430
+ if (selectShowList.value[colIndex] && colIndex === currentCol.value) {
431
+ updateLineAndScroll(true);
432
+ }
433
+
434
+ handleColChange(colIndex, item, index);
435
+ }
436
+
437
+ function handleColChange(
438
+ colIndex: number,
439
+ item: Record<string, any>,
440
+ index: number,
441
+ callback?: () => void
442
+ ) {
443
+ loading.value = true;
444
+ const { columnChange, beforeConfirm } = props;
445
+ columnChange &&
446
+ columnChange({
447
+ selectedItem: item,
448
+ index: colIndex,
449
+ rowIndex: index,
450
+ resolve: (nextColumn: Record<string, any>[]) => {
451
+ if (!isArray(nextColumn)) {
452
+ console.error(
453
+ '[wot design] error(wd-col-picker): the data of each column of wd-col-picker should be an array'
454
+ );
455
+ return;
456
+ }
457
+
458
+ const newSelectList = selectList.value.slice(0);
459
+ newSelectList[colIndex + 1] = nextColumn;
460
+
461
+ selectList.value = newSelectList;
462
+ loading.value = false;
463
+ currentCol.value = colIndex + 1;
464
+
465
+ updateLineAndScroll(true);
466
+ if (typeof callback === 'function') {
467
+ isCompleting.value = false;
468
+ selectShowList.value = pickerColSelected.value.map((item, colIndex) => {
469
+ return getSelectedItem(item, colIndex, selectList.value)[props.labelKey];
470
+ });
471
+ callback();
472
+ }
473
+ },
474
+ finish: (isOk?: boolean) => {
475
+ // 每设置展示数据回显
476
+ if (typeof callback === 'function') {
477
+ loading.value = false;
478
+ isCompleting.value = false;
479
+ return;
480
+ }
481
+ if (isBoolean(isOk) && !isOk) {
482
+ loading.value = false;
483
+ return;
484
+ }
485
+
486
+ if (beforeConfirm) {
487
+ beforeConfirm(
488
+ pickerColSelected.value,
489
+ pickerColSelected.value.map((item, colIndex) => {
490
+ return getSelectedItem(item, colIndex, selectList.value);
491
+ }),
492
+ (isPass: boolean) => {
493
+ if (isPass) {
494
+ onConfirm();
495
+ } else {
496
+ loading.value = false;
497
+ }
498
+ }
499
+ );
500
+ } else {
501
+ onConfirm();
502
+ }
503
+ },
504
+ });
505
+ }
506
+ function onConfirm() {
507
+ isChange.value = false;
508
+ loading.value = false;
509
+ pickerShow.value = false;
510
+
511
+ emit('update:modelValue', pickerColSelected.value);
512
+ emit('confirm', {
513
+ value: pickerColSelected.value,
514
+ selectedItems: pickerColSelected.value.map((item, colIndex) => {
515
+ return getSelectedItem(item, colIndex, selectList.value);
516
+ }),
517
+ });
518
+ }
519
+ function handleColClick(index: number) {
520
+ isChange.value = true;
521
+ currentCol.value = index;
522
+ updateLineAndScroll(true);
523
+ }
524
+ /**
525
+ * @description 更新navBar underline的偏移量
526
+ * @param {Boolean} animation 是否伴随动画
527
+ */
528
+ function setLineStyle(animation: boolean = true) {
529
+ if (!inited.value) return;
530
+ const { lineWidth, lineHeight } = props;
531
+ getRect($item, true, proxy)
532
+ .then((rects) => {
533
+ const lineStyle: CSSProperties = {};
534
+ if (isDef(lineWidth)) {
535
+ lineStyle.width = addUnit(lineWidth);
536
+ }
537
+ if (isDef(lineHeight)) {
538
+ lineStyle.height = addUnit(lineHeight);
539
+ lineStyle.borderRadius = `calc(${addUnit(lineHeight)} / 2)`;
540
+ }
541
+ const rect = rects[currentCol.value];
542
+ const left =
543
+ rects.slice(0, currentCol.value).reduce((prev, curr) => prev + Number(curr.width), 0) +
544
+ Number(rect.width) / 2;
545
+ lineStyle.transform = `translateX(${left}px) translateX(-50%)`;
546
+
547
+ if (animation) {
548
+ lineStyle.transition = 'width 300ms ease, transform 300ms ease';
549
+ }
550
+
551
+ state.lineStyle = objToStyle(lineStyle);
552
+ })
553
+ .catch(() => {});
554
+ }
555
+ /**
556
+ * @description scroll-view滑动到active的tab_nav
557
+ */
558
+ function lineScrollIntoView() {
559
+ if (!inited.value) return;
560
+ Promise.all([getRect($item, true, proxy), getRect($container, false, proxy)])
561
+ .then(([navItemsRects, navRect]) => {
562
+ if (!isArray(navItemsRects) || navItemsRects.length === 0) return;
563
+ // 选中元素
564
+ const selectItem = navItemsRects[currentCol.value];
565
+ // 选中元素之前的节点的宽度总和
566
+ const offsetLeft = navItemsRects
567
+ .slice(0, currentCol.value)
568
+ .reduce((prev, curr) => prev + Number(curr.width), 0);
569
+ // scroll-view滑动到selectItem的偏移量
570
+ scrollLeft.value = offsetLeft - ((navRect as any).width - Number(selectItem.width)) / 2;
571
+ })
572
+ .catch(() => {});
573
+ }
574
+
575
+ // 递归列数据补齐
576
+ function diffColumns(colIndex: number) {
577
+ // colIndex 为 -1 时,item 为空对象,>=0 时则具有 value 属性
578
+ const item = colIndex === -1 ? {} : { [props.valueKey]: props.modelValue[colIndex] };
579
+ handleColChange(colIndex, item, -1, () => {
580
+ // 如果 columns 长度还小于 value 长度,colIndex + 1,继续递归补齐
581
+ if (selectList.value.length < props.modelValue.length) {
582
+ diffColumns(colIndex + 1);
583
+ }
584
+ });
585
+ }
586
+ function handleAutoComplete() {
587
+ if (props.autoComplete) {
588
+ // 如果 columns 数组长度为空,或者长度小于 value 的长度,自动触发 columnChange 来补齐数据
589
+ if (selectList.value.length < props.modelValue.length || selectList.value.length === 0) {
590
+ // isCompleting 是否在自动补全,锁操作
591
+ if (!isCompleting.value) {
592
+ // 如果 columns 长度为空,则传入的 colIndex 为 -1
593
+ const colIndex = selectList.value.length === 0 ? -1 : selectList.value.length - 1;
594
+ diffColumns(colIndex);
595
+ }
596
+ isCompleting.value = true;
597
+ }
598
+ }
599
+ }
600
+
601
+ defineExpose<ColPickerExpose>({
602
+ close,
603
+ open,
604
+ });
605
+ </script>
606
+
607
+ <style lang="scss" scoped>
608
+ @import 'wot-design-uni/components/wd-col-picker/index.scss';
609
+ </style>
File without changes