@douyinfe/semi-foundation 2.101.1 → 2.103.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.
@@ -20,10 +20,15 @@ export default class DragMoveFoundation<P = Record<string, any>, S = Record<stri
20
20
  yMin: number;
21
21
  startOffsetX: number;
22
22
  startOffsetY: number;
23
+ startClientX: number;
24
+ startClientY: number;
25
+ startLeft: number;
26
+ startTop: number;
23
27
  get constrainer(): HTMLElement;
24
28
  get handler(): HTMLElement;
25
29
  constructor(adapter: DragMoveAdapter<P, S>);
26
30
  init(): void;
31
+ updatePositionStrategy: () => void;
27
32
  _registerStartEvent: () => void;
28
33
  _unRegisterStartEvent: () => void;
29
34
  destroy(): void;
@@ -11,6 +11,9 @@ export default class DragMoveFoundation extends BaseFoundation {
11
11
  }
12
12
  constructor(adapter) {
13
13
  super(Object.assign({}, adapter));
14
+ this.updatePositionStrategy = () => {
15
+ this.element.style.position = this.getProp('positionStrategy') === 'relative' ? 'relative' : 'absolute';
16
+ };
14
17
  this._registerStartEvent = () => {
15
18
  this.handler.addEventListener('mousedown', this.onMouseDown);
16
19
  this.handler.addEventListener('touchstart', this.onTouchStart);
@@ -38,6 +41,14 @@ export default class DragMoveFoundation extends BaseFoundation {
38
41
  document.removeEventListener('touchcancel', this._onTouchCancel);
39
42
  };
40
43
  this._calcOffset = e => {
44
+ if (this.getProp('positionStrategy') === 'relative') {
45
+ const style = window.getComputedStyle(this.element);
46
+ this.startClientX = e.clientX;
47
+ this.startClientY = e.clientY;
48
+ this.startLeft = parseFloat(style.left) || 0;
49
+ this.startTop = parseFloat(style.top) || 0;
50
+ return;
51
+ }
41
52
  this.startOffsetX = e.clientX - this.element.offsetLeft;
42
53
  this.startOffsetY = e.clientY - this.element.offsetTop;
43
54
  };
@@ -71,8 +82,9 @@ export default class DragMoveFoundation extends BaseFoundation {
71
82
  const {
72
83
  customMove
73
84
  } = this.getProps();
74
- let newLeft = e.clientX - this.startOffsetX;
75
- let newTop = e.clientY - this.startOffsetY;
85
+ const useRelativePosition = this.getProp('positionStrategy') === 'relative';
86
+ let newLeft = useRelativePosition ? this.startLeft + e.clientX - this.startClientX : e.clientX - this.startOffsetX;
87
+ let newTop = useRelativePosition ? this.startTop + e.clientY - this.startClientY : e.clientY - this.startOffsetY;
76
88
  if (this.constrainer) {
77
89
  newLeft = clampValueInRange(newLeft, this.xMin, this.xMax);
78
90
  newTop = clampValueInRange(newTop, this.yMin, this.yMax);
@@ -114,7 +126,7 @@ export default class DragMoveFoundation extends BaseFoundation {
114
126
  throw new Error('drag element must be a valid element');
115
127
  }
116
128
  this.element = element;
117
- this.element.style.position = 'absolute';
129
+ this.updatePositionStrategy();
118
130
  this.handler.style.cursor = 'move';
119
131
  this._registerStartEvent();
120
132
  }
@@ -129,6 +141,18 @@ export default class DragMoveFoundation extends BaseFoundation {
129
141
  _calcMoveRange() {
130
142
  // Calculate the range within which an element can move
131
143
  if (this.constrainer) {
144
+ if (this.getProp('positionStrategy') === 'relative') {
145
+ const elementRect = this.element.getBoundingClientRect();
146
+ const constrainerRect = this.constrainer.getBoundingClientRect();
147
+ const style = window.getComputedStyle(this.element);
148
+ const currentLeft = parseFloat(style.left) || 0;
149
+ const currentTop = parseFloat(style.top) || 0;
150
+ this.xMin = currentLeft + constrainerRect.left - elementRect.left;
151
+ this.xMax = currentLeft + constrainerRect.right - elementRect.right;
152
+ this.yMin = currentTop + constrainerRect.top - elementRect.top;
153
+ this.yMax = currentTop + constrainerRect.bottom - elementRect.bottom;
154
+ return;
155
+ }
132
156
  let node = this.element.offsetParent;
133
157
  let startX = 0;
134
158
  let startY = 0;
@@ -20,6 +20,7 @@
20
20
  .semi-progress-horizontal .semi-progress-track {
21
21
  height: 100%;
22
22
  width: 100%;
23
+ overflow: hidden;
23
24
  }
24
25
  .semi-progress-horizontal .semi-progress-track-inner {
25
26
  height: 100%;
@@ -28,6 +29,11 @@
28
29
  transition: width 0.3s;
29
30
  transition-timing-function: cubic-bezier(0.62, 0.05, 0.36, 0.95);
30
31
  }
32
+ .semi-progress-horizontal .semi-progress-track-inner-indeterminate {
33
+ width: 35%;
34
+ transition: none;
35
+ animation: semi-progress-indeterminate-slide 1.6s ease-in-out infinite;
36
+ }
31
37
  .semi-progress-horizontal .semi-progress-line-text {
32
38
  min-width: 45px;
33
39
  font-weight: 600;
@@ -48,6 +54,7 @@
48
54
  .semi-progress-vertical .semi-progress-track {
49
55
  height: 100%;
50
56
  width: 100%;
57
+ overflow: hidden;
51
58
  }
52
59
  .semi-progress-vertical .semi-progress-track-inner {
53
60
  background-color: var(--semi-color-success);
@@ -56,6 +63,12 @@
56
63
  transition: height 0.3s;
57
64
  transition-timing-function: cubic-bezier(0.62, 0.05, 0.36, 0.95);
58
65
  }
66
+ .semi-progress-vertical .semi-progress-track-inner-indeterminate {
67
+ height: 35%;
68
+ width: 100%;
69
+ transition: none;
70
+ animation: semi-progress-indeterminate-slide-vertical 1.6s ease-in-out infinite;
71
+ }
59
72
  .semi-progress-vertical .semi-progress-line-text {
60
73
  font-weight: 600;
61
74
  margin-top: 8px;
@@ -77,6 +90,11 @@
77
90
  transform-origin: 50% 50%;
78
91
  stroke: var(--semi-color-success);
79
92
  }
93
+ .semi-progress-circle-ring-inner-indeterminate {
94
+ transform: rotate(0deg);
95
+ transform-origin: 50% 50%;
96
+ animation: semi-progress-indeterminate-rotate 1.2s linear infinite;
97
+ }
80
98
  .semi-progress-circle-text {
81
99
  position: absolute;
82
100
  top: 50%;
@@ -88,6 +106,36 @@
88
106
  color: var(--semi-color-mode-minor-text);
89
107
  }
90
108
 
109
+ @keyframes semi-progress-indeterminate-slide {
110
+ 0% {
111
+ transform: translateX(-120%);
112
+ }
113
+ 55% {
114
+ transform: translateX(300%);
115
+ }
116
+ 100% {
117
+ transform: translateX(300%);
118
+ }
119
+ }
120
+ @keyframes semi-progress-indeterminate-slide-vertical {
121
+ 0% {
122
+ transform: translateY(-120%);
123
+ }
124
+ 55% {
125
+ transform: translateY(300%);
126
+ }
127
+ 100% {
128
+ transform: translateY(300%);
129
+ }
130
+ }
131
+ @keyframes semi-progress-indeterminate-rotate {
132
+ from {
133
+ transform: rotate(0deg);
134
+ }
135
+ to {
136
+ transform: rotate(360deg);
137
+ }
138
+ }
91
139
  .semi-rtl .semi-progress,
92
140
  .semi-portal-rtl .semi-progress {
93
141
  direction: rtl;
@@ -23,6 +23,7 @@ $module: #{$prefix}-progress;
23
23
  .#{$module}-track {
24
24
  height: 100%;
25
25
  width: 100%;
26
+ overflow: hidden;
26
27
  }
27
28
 
28
29
  .#{$module}-track-inner {
@@ -33,6 +34,12 @@ $module: #{$prefix}-progress;
33
34
  transition-timing-function: $motion-progress-transition_timing_function;
34
35
  }
35
36
 
37
+ .#{$module}-track-inner-indeterminate {
38
+ width: 35%;
39
+ transition: none;
40
+ animation: semi-progress-indeterminate-slide 1.6s ease-in-out infinite;
41
+ }
42
+
36
43
  .#{$module}-line-text {
37
44
  min-width: $width-progress_line_text;
38
45
  font-weight: $font-progress_line_text-fontWeight;
@@ -57,6 +64,7 @@ $module: #{$prefix}-progress;
57
64
  .#{$module}-track {
58
65
  height: 100%;
59
66
  width: 100%;
67
+ overflow: hidden;
60
68
  }
61
69
 
62
70
  .#{$module}-track-inner {
@@ -67,6 +75,13 @@ $module: #{$prefix}-progress;
67
75
  transition-timing-function: $motion-progress-transition_timing_function;
68
76
  }
69
77
 
78
+ .#{$module}-track-inner-indeterminate {
79
+ height: 35%;
80
+ width: 100%;
81
+ transition: none;
82
+ animation: semi-progress-indeterminate-slide-vertical 1.6s ease-in-out infinite;
83
+ }
84
+
70
85
  .#{$module}-line-text {
71
86
  font-weight: $font-progress_line_text-fontWeight;
72
87
  margin-top: $spacing-progress_vertical_line_text-marginTop;
@@ -95,6 +110,12 @@ $module: #{$prefix}-progress;
95
110
  stroke: $color-progress_track_inner-bg;
96
111
  }
97
112
 
113
+ &-ring-inner-indeterminate {
114
+ transform: rotate(0deg);
115
+ transform-origin: 50% 50%;
116
+ animation: semi-progress-indeterminate-rotate 1.2s linear infinite;
117
+ }
118
+
98
119
  &-text {
99
120
  position: absolute;
100
121
  top: 50%;
@@ -108,4 +129,42 @@ $module: #{$prefix}-progress;
108
129
  }
109
130
  }
110
131
 
111
- @import './rtl.scss';
132
+ @keyframes semi-progress-indeterminate-slide {
133
+ 0% {
134
+ transform: translateX(-120%);
135
+ }
136
+
137
+ 55% {
138
+ transform: translateX(300%);
139
+ }
140
+
141
+ 100% {
142
+ transform: translateX(300%);
143
+ }
144
+ }
145
+
146
+ @keyframes semi-progress-indeterminate-slide-vertical {
147
+ 0% {
148
+ transform: translateY(-120%);
149
+ }
150
+
151
+ 55% {
152
+ transform: translateY(300%);
153
+ }
154
+
155
+ 100% {
156
+ transform: translateY(300%);
157
+ }
158
+ }
159
+
160
+ @keyframes semi-progress-indeterminate-rotate {
161
+ from {
162
+ transform: rotate(0deg);
163
+ }
164
+
165
+ to {
166
+ transform: rotate(360deg);
167
+ }
168
+ }
169
+
170
+ @import './rtl.scss';
@@ -432,7 +432,10 @@ export default class TreeFoundation extends BaseFoundation {
432
432
  this._adapter.cacheFlattenNodes(motionType === 'hide' && this._isAnimated());
433
433
  if (!this._isExpandControlled()) {
434
434
  const flattenNodes = flattenTreeData(treeData, expandedKeys, keyMaps, isSearching && showFilteredOnly && filteredShownKeys);
435
- const motionKeys = this._isAnimated() ? getMotionKeys(eventKey, expandedKeys, keyEntities) : [];
435
+ let motionKeys = this._isAnimated() ? getMotionKeys(eventKey, expandedKeys, keyEntities) : [];
436
+ if (isSearching && showFilteredOnly) {
437
+ motionKeys = motionKeys.filter(key => filteredShownKeys.has(key));
438
+ }
436
439
  const newState = {
437
440
  [expandedStateKey]: expandedKeys,
438
441
  flattenNodes,
@@ -94,6 +94,33 @@ declare class UploadFoundation<P = Record<string, any>, S = Record<string, any>>
94
94
  * When paste event is successfully handled, we ignore the subsequent keydown event.
95
95
  */
96
96
  _pasteHandled: boolean;
97
+ /**
98
+ * Working copy of fileList used during a synchronous startUpload batch.
99
+ * Do NOT rely on React state fileList here: setState is async (batched in React 18),
100
+ * so reading getState('fileList') between iterations of a sync loop returns a stale
101
+ * snapshot and earlier removals get overwritten by later ones (see #3335).
102
+ * Seeded at the start of startUpload and cleared when the sync loop finishes (see
103
+ * try/finally in startUpload); async (promise) results fall back to _latestFileList
104
+ * then React state.
105
+ */
106
+ _batchFileList: Array<BaseFileItem> | null;
107
+ /**
108
+ * The most recent fileList produced by handleBeforeUploadResultInObject.
109
+ * Unlike React state (which is flushed asynchronously under React 18 automatic
110
+ * batching), this is updated synchronously, so a later async beforeUpload result
111
+ * composes with earlier sync removals of the same batch instead of reading a stale
112
+ * snapshot (mixed sync + async beforeUpload results, see #3335).
113
+ */
114
+ _latestFileList: Array<BaseFileItem> | null;
115
+ /**
116
+ * Unify all fileList commits: keep _latestFileList in sync synchronously so async
117
+ * beforeUpload results compose with recent mutations even before React flushes
118
+ * setState (React 18 automatic batching). (#3335)
119
+ */
120
+ updateFileListInternal(newFileList: Array<BaseFileItem>, callback?: () => void): void;
121
+ /** Keep the synchronous snapshot aligned with an externally controlled fileList. */
122
+ syncLatestFileList(fileList: Array<BaseFileItem>): void;
123
+ getLatestFileList(): Array<BaseFileItem>;
97
124
  constructor(adapter: UploadAdapter<P, S>);
98
125
  init(): void;
99
126
  /**
@@ -41,6 +41,25 @@ const {
41
41
  TRIGGER_AUTO
42
42
  } = strings;
43
43
  class UploadFoundation extends BaseFoundation {
44
+ /**
45
+ * Unify all fileList commits: keep _latestFileList in sync synchronously so async
46
+ * beforeUpload results compose with recent mutations even before React flushes
47
+ * setState (React 18 automatic batching). (#3335)
48
+ */
49
+ updateFileListInternal(newFileList, callback) {
50
+ if (this._batchFileList) {
51
+ this._batchFileList = newFileList;
52
+ }
53
+ this._latestFileList = newFileList;
54
+ this._adapter.updateFileList(newFileList, callback);
55
+ }
56
+ /** Keep the synchronous snapshot aligned with an externally controlled fileList. */
57
+ syncLatestFileList(fileList) {
58
+ this._latestFileList = fileList.slice();
59
+ }
60
+ getLatestFileList() {
61
+ return this._batchFileList || this._latestFileList || this.getState('fileList');
62
+ }
44
63
  constructor(adapter) {
45
64
  super(Object.assign({}, adapter));
46
65
  this.destroyState = false;
@@ -55,10 +74,29 @@ class UploadFoundation extends BaseFoundation {
55
74
  * When paste event is successfully handled, we ignore the subsequent keydown event.
56
75
  */
57
76
  this._pasteHandled = false;
77
+ /**
78
+ * Working copy of fileList used during a synchronous startUpload batch.
79
+ * Do NOT rely on React state fileList here: setState is async (batched in React 18),
80
+ * so reading getState('fileList') between iterations of a sync loop returns a stale
81
+ * snapshot and earlier removals get overwritten by later ones (see #3335).
82
+ * Seeded at the start of startUpload and cleared when the sync loop finishes (see
83
+ * try/finally in startUpload); async (promise) results fall back to _latestFileList
84
+ * then React state.
85
+ */
86
+ this._batchFileList = null;
87
+ /**
88
+ * The most recent fileList produced by handleBeforeUploadResultInObject.
89
+ * Unlike React state (which is flushed asynchronously under React 18 automatic
90
+ * batching), this is updated synchronously, so a later async beforeUpload result
91
+ * composes with earlier sync removals of the same batch instead of reading a stale
92
+ * snapshot (mixed sync + async beforeUpload results, see #3335).
93
+ */
94
+ this._latestFileList = null;
58
95
  }
59
96
  init() {
60
97
  // make sure state reset, otherwise may cause upload abort in React StrictMode, like https://github.com/DouyinFE/semi-design/pull/843
61
98
  this.destroyState = false;
99
+ this.syncLatestFileList(this.getState('fileList'));
62
100
  // In controlled mode, parent may keep and pass back fileList with blob url.
63
101
  // Sync them into internal map so later remove/clear can revoke correctly.
64
102
  this._syncLocalUrlsFromFileList();
@@ -108,6 +146,8 @@ class UploadFoundation extends BaseFoundation {
108
146
  if (!disabled) {
109
147
  this.unbindPastingHandler();
110
148
  }
149
+ this._batchFileList = null;
150
+ this._latestFileList = null;
111
151
  this.destroyState = true;
112
152
  }
113
153
  /**
@@ -324,7 +364,7 @@ class UploadFoundation extends BaseFoundation {
324
364
  currentFile: newFileItem,
325
365
  fileList: newFileList
326
366
  });
327
- this._adapter.updateFileList(newFileList, () => {
367
+ this.updateFileListInternal(newFileList, () => {
328
368
  this._adapter.resetReplaceInput();
329
369
  if (!newFileItem._sizeInvalid) {
330
370
  this.upload(newFileItem);
@@ -368,7 +408,7 @@ class UploadFoundation extends BaseFoundation {
368
408
  fileList: currentFiles,
369
409
  currentFile: currentFiles[0]
370
410
  });
371
- this._adapter.updateFileList(currentFiles, () => {
411
+ this.updateFileListInternal(currentFiles, () => {
372
412
  if (uploadTrigger === TRIGGER_AUTO) {
373
413
  this.startUpload(currentFiles);
374
414
  }
@@ -392,7 +432,7 @@ class UploadFoundation extends BaseFoundation {
392
432
  });
393
433
  }
394
434
  });
395
- this._adapter.updateFileList(fileList, () => {
435
+ this.updateFileListInternal(fileList, () => {
396
436
  if (uploadTrigger === TRIGGER_AUTO) {
397
437
  this.startUpload(currentFiles);
398
438
  }
@@ -476,7 +516,7 @@ class UploadFoundation extends BaseFoundation {
476
516
  fileList: newFileList,
477
517
  currentFile: null
478
518
  });
479
- this._adapter.updateFileList(newFileList, () => {
519
+ this.updateFileListInternal(newFileList, () => {
480
520
  if (uploadTrigger === TRIGGER_AUTO) {
481
521
  this.startUpload(fileItemList);
482
522
  }
@@ -485,15 +525,24 @@ class UploadFoundation extends BaseFoundation {
485
525
  /* istanbul ignore next */
486
526
  manualUpload() {
487
527
  // find the list of files that have not been uploaded
488
- const waitToUploadFileList = this.getState('fileList').filter(item => item.status === FILE_STATUS_WAIT_UPLOAD);
528
+ const waitToUploadFileList = this.getLatestFileList().filter(item => item.status === FILE_STATUS_WAIT_UPLOAD);
489
529
  this.startUpload(waitToUploadFileList);
490
530
  }
491
531
  startUpload(fileList) {
492
- fileList.forEach(file => {
493
- if (!file._sizeInvalid) {
494
- this.upload(file);
495
- }
496
- });
532
+ // Seed a working copy so multiple synchronous beforeUpload results
533
+ // (e.g. several files returning autoRemove) compose correctly instead of each
534
+ // reading a stale React state snapshot and overwriting earlier removals. (#3335)
535
+ // try/finally guarantees the working copy is cleared even if beforeUpload throws.
536
+ this._batchFileList = this.getLatestFileList().slice();
537
+ try {
538
+ fileList.forEach(file => {
539
+ if (!file._sizeInvalid) {
540
+ this.upload(file);
541
+ }
542
+ });
543
+ } finally {
544
+ this._batchFileList = null;
545
+ }
497
546
  }
498
547
  upload(file) {
499
548
  const {
@@ -504,9 +553,7 @@ class UploadFoundation extends BaseFoundation {
504
553
  return;
505
554
  }
506
555
  if (typeof beforeUpload === 'function') {
507
- const {
508
- fileList
509
- } = this.getStates();
556
+ const fileList = this.getLatestFileList();
510
557
  const buResult = this._adapter.notifyBeforeUpload({
511
558
  file,
512
559
  fileList
@@ -571,7 +618,11 @@ class UploadFoundation extends BaseFoundation {
571
618
  validateMessage,
572
619
  fileInstance
573
620
  } = buResult;
574
- let newFileList = this.getState('fileList').slice();
621
+ // During a synchronous startUpload batch, read from the working copy; for async
622
+ // (promise) results read from the most recent synchronous snapshot, falling back
623
+ // to React state. This keeps mixed sync + async beforeUpload results composing
624
+ // correctly under React 18 automatic batching. (#3335)
625
+ let newFileList = this.getLatestFileList().slice();
575
626
  if (autoRemove) {
576
627
  this._releaseFileUrl(file.uid);
577
628
  newFileList = newFileList.filter(item => item.uid !== file.uid);
@@ -593,7 +644,7 @@ class UploadFoundation extends BaseFoundation {
593
644
  }
594
645
  newFileList[index].shouldUpload = shouldUpload;
595
646
  }
596
- this._adapter.updateFileList(newFileList);
647
+ this.updateFileListInternal(newFileList);
597
648
  this._adapter.notifyChange({
598
649
  fileList: newFileList,
599
650
  currentFile: file
@@ -707,10 +758,7 @@ class UploadFoundation extends BaseFoundation {
707
758
  e,
708
759
  fileInstance
709
760
  } = _ref2;
710
- const {
711
- fileList
712
- } = this.getStates();
713
- const newFileList = fileList.slice();
761
+ const newFileList = this.getLatestFileList().slice();
714
762
  let percent = 0;
715
763
  if (e.total > 0) {
716
764
  percent = Number((e.loaded / e.total * 100 * numbers.PROGRESS_COEFFICIENT).toFixed(0)) || 0;
@@ -722,7 +770,7 @@ class UploadFoundation extends BaseFoundation {
722
770
  newFileList[index].percent = percent;
723
771
  newFileList[index].status = FILE_STATUS_UPLOADING;
724
772
  this._adapter.notifyProgress(percent, fileInstance, newFileList);
725
- this._adapter.updateFileList(newFileList);
773
+ this.updateFileListInternal(newFileList);
726
774
  this._adapter.notifyChange({
727
775
  fileList: newFileList,
728
776
  currentFile: newFileList[index]
@@ -734,9 +782,7 @@ class UploadFoundation extends BaseFoundation {
734
782
  xhr,
735
783
  fileInstance
736
784
  } = _ref3;
737
- const {
738
- fileList
739
- } = this.getStates();
785
+ const fileList = this.getLatestFileList();
740
786
  const index = this._getFileIndex(fileInstance, fileList);
741
787
  if (index < 0) {
742
788
  return;
@@ -764,9 +810,7 @@ class UploadFoundation extends BaseFoundation {
764
810
  xhr,
765
811
  response
766
812
  } = _ref4;
767
- const {
768
- fileList
769
- } = this.getStates();
813
+ const fileList = this.getLatestFileList();
770
814
  let body = null;
771
815
  const index = this._getFileIndex(fileInstance, fileList);
772
816
  if (index < 0) {
@@ -817,7 +861,7 @@ class UploadFoundation extends BaseFoundation {
817
861
  fileList: newFileList,
818
862
  currentFile: newFileList[index]
819
863
  });
820
- this._adapter.updateFileList(newFileList);
864
+ this.updateFileListInternal(newFileList);
821
865
  }
822
866
  _getFileIndex(file, fileList) {
823
867
  return fileList.findIndex(item => item.uid === file.uid);
@@ -845,7 +889,7 @@ class UploadFoundation extends BaseFoundation {
845
889
  newFileList.splice(index, 1);
846
890
  this._releaseFileUrl(file.uid);
847
891
  this._adapter.notifyRemove(file.fileInstance, newFileList, file);
848
- this._adapter.updateFileList(newFileList);
892
+ this.updateFileListInternal(newFileList);
849
893
  this._adapter.notifyChange({
850
894
  fileList: newFileList,
851
895
  currentFile: file
@@ -858,9 +902,7 @@ class UploadFoundation extends BaseFoundation {
858
902
  xhr,
859
903
  fileInstance
860
904
  } = _ref5;
861
- const {
862
- fileList
863
- } = this.getStates();
905
+ const fileList = this.getLatestFileList();
864
906
  const index = this._getFileIndex(fileInstance, fileList);
865
907
  if (index < 0) {
866
908
  return;
@@ -878,7 +920,7 @@ class UploadFoundation extends BaseFoundation {
878
920
  newFileList[index].response = error;
879
921
  newFileList[index].event = e;
880
922
  this._adapter.notifyError(error, fileInstance, newFileList, xhr);
881
- this._adapter.updateFileList(newFileList);
923
+ this.updateFileListInternal(newFileList);
882
924
  this._adapter.notifyChange({
883
925
  currentFile: newFileList[index],
884
926
  fileList: newFileList
@@ -899,7 +941,7 @@ class UploadFoundation extends BaseFoundation {
899
941
  return;
900
942
  }
901
943
  this._releaseAllFileUrls();
902
- this._adapter.updateFileList([]);
944
+ this.updateFileListInternal([]);
903
945
  this._adapter.notifyClear();
904
946
  this._adapter.notifyChange({
905
947
  fileList: []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@douyinfe/semi-foundation",
3
- "version": "2.101.1",
3
+ "version": "2.103.0",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "clean": "rimraf lib",
@@ -14225,8 +14225,8 @@
14225
14225
  }
14226
14226
  },
14227
14227
  "dependencies": {
14228
- "@douyinfe/semi-animation": "2.101.1",
14229
- "@douyinfe/semi-json-viewer-core": "2.101.1",
14228
+ "@douyinfe/semi-animation": "2.103.0",
14229
+ "@douyinfe/semi-json-viewer-core": "2.103.0",
14230
14230
  "@mdx-js/mdx": "^3.0.1",
14231
14231
  "async-validator": "^3.5.0",
14232
14232
  "classnames": "^2.2.6",
@@ -14247,7 +14247,7 @@
14247
14247
  "*.scss",
14248
14248
  "*.css"
14249
14249
  ],
14250
- "gitHead": "90a1ea2a8f3bc714279cdaada5fa30e97d8e26d4",
14250
+ "gitHead": "c1e3632b90b242defdfe4bfb267bcfaffbb23295",
14251
14251
  "devDependencies": {
14252
14252
  "@babel/plugin-transform-runtime": "^7.15.8",
14253
14253
  "@babel/preset-env": "^7.15.8",
@@ -23,6 +23,7 @@ $module: #{$prefix}-progress;
23
23
  .#{$module}-track {
24
24
  height: 100%;
25
25
  width: 100%;
26
+ overflow: hidden;
26
27
  }
27
28
 
28
29
  .#{$module}-track-inner {
@@ -33,6 +34,12 @@ $module: #{$prefix}-progress;
33
34
  transition-timing-function: $motion-progress-transition_timing_function;
34
35
  }
35
36
 
37
+ .#{$module}-track-inner-indeterminate {
38
+ width: 35%;
39
+ transition: none;
40
+ animation: semi-progress-indeterminate-slide 1.6s ease-in-out infinite;
41
+ }
42
+
36
43
  .#{$module}-line-text {
37
44
  min-width: $width-progress_line_text;
38
45
  font-weight: $font-progress_line_text-fontWeight;
@@ -57,6 +64,7 @@ $module: #{$prefix}-progress;
57
64
  .#{$module}-track {
58
65
  height: 100%;
59
66
  width: 100%;
67
+ overflow: hidden;
60
68
  }
61
69
 
62
70
  .#{$module}-track-inner {
@@ -67,6 +75,13 @@ $module: #{$prefix}-progress;
67
75
  transition-timing-function: $motion-progress-transition_timing_function;
68
76
  }
69
77
 
78
+ .#{$module}-track-inner-indeterminate {
79
+ height: 35%;
80
+ width: 100%;
81
+ transition: none;
82
+ animation: semi-progress-indeterminate-slide-vertical 1.6s ease-in-out infinite;
83
+ }
84
+
70
85
  .#{$module}-line-text {
71
86
  font-weight: $font-progress_line_text-fontWeight;
72
87
  margin-top: $spacing-progress_vertical_line_text-marginTop;
@@ -95,6 +110,12 @@ $module: #{$prefix}-progress;
95
110
  stroke: $color-progress_track_inner-bg;
96
111
  }
97
112
 
113
+ &-ring-inner-indeterminate {
114
+ transform: rotate(0deg);
115
+ transform-origin: 50% 50%;
116
+ animation: semi-progress-indeterminate-rotate 1.2s linear infinite;
117
+ }
118
+
98
119
  &-text {
99
120
  position: absolute;
100
121
  top: 50%;
@@ -108,4 +129,42 @@ $module: #{$prefix}-progress;
108
129
  }
109
130
  }
110
131
 
111
- @import './rtl.scss';
132
+ @keyframes semi-progress-indeterminate-slide {
133
+ 0% {
134
+ transform: translateX(-120%);
135
+ }
136
+
137
+ 55% {
138
+ transform: translateX(300%);
139
+ }
140
+
141
+ 100% {
142
+ transform: translateX(300%);
143
+ }
144
+ }
145
+
146
+ @keyframes semi-progress-indeterminate-slide-vertical {
147
+ 0% {
148
+ transform: translateY(-120%);
149
+ }
150
+
151
+ 55% {
152
+ transform: translateY(300%);
153
+ }
154
+
155
+ 100% {
156
+ transform: translateY(300%);
157
+ }
158
+ }
159
+
160
+ @keyframes semi-progress-indeterminate-rotate {
161
+ from {
162
+ transform: rotate(0deg);
163
+ }
164
+
165
+ to {
166
+ transform: rotate(360deg);
167
+ }
168
+ }
169
+
170
+ @import './rtl.scss';