@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.
- package/button/button.scss +1 -0
- package/dragMove/foundation.ts +36 -3
- package/lib/cjs/button/button.css +1 -0
- package/lib/cjs/button/button.scss +1 -0
- package/lib/cjs/dragMove/foundation.d.ts +5 -0
- package/lib/cjs/dragMove/foundation.js +27 -3
- package/lib/cjs/progress/progress.css +48 -0
- package/lib/cjs/progress/progress.scss +60 -1
- package/lib/cjs/tree/foundation.js +4 -1
- package/lib/cjs/upload/foundation.d.ts +27 -0
- package/lib/cjs/upload/foundation.js +75 -33
- package/lib/es/button/button.css +1 -0
- package/lib/es/button/button.scss +1 -0
- package/lib/es/dragMove/foundation.d.ts +5 -0
- package/lib/es/dragMove/foundation.js +27 -3
- package/lib/es/progress/progress.css +48 -0
- package/lib/es/progress/progress.scss +60 -1
- package/lib/es/tree/foundation.js +4 -1
- package/lib/es/upload/foundation.d.ts +27 -0
- package/lib/es/upload/foundation.js +75 -33
- package/package.json +4 -4
- package/progress/progress.scss +60 -1
- package/tree/foundation.ts +4 -1
- package/upload/foundation.ts +81 -27
|
@@ -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
|
-
|
|
75
|
-
let
|
|
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.
|
|
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
|
-
@
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
493
|
-
|
|
494
|
-
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
14229
|
-
"@douyinfe/semi-json-viewer-core": "2.
|
|
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": "
|
|
14250
|
+
"gitHead": "c1e3632b90b242defdfe4bfb267bcfaffbb23295",
|
|
14251
14251
|
"devDependencies": {
|
|
14252
14252
|
"@babel/plugin-transform-runtime": "^7.15.8",
|
|
14253
14253
|
"@babel/preset-env": "^7.15.8",
|
package/progress/progress.scss
CHANGED
|
@@ -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
|
-
@
|
|
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';
|