@douyinfe/semi-foundation 2.93.0 → 2.94.1
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/aiChatInput/foundation.ts +3 -1
- package/autoComplete/foundation.ts +3 -2
- package/cascader/foundation.ts +8 -3
- package/collapsible/foundation.ts +1 -0
- package/datePicker/datePicker.scss +2 -2
- package/descriptions/foundation.ts +3 -1
- package/form/foundation.ts +61 -29
- package/form/interface.ts +9 -2
- package/input/textareaFoundation.ts +34 -1
- package/lib/cjs/aiChatInput/foundation.js +3 -1
- package/lib/cjs/autoComplete/foundation.d.ts +1 -0
- package/lib/cjs/autoComplete/foundation.js +1 -1
- package/lib/cjs/cascader/foundation.d.ts +1 -0
- package/lib/cjs/cascader/foundation.js +8 -3
- package/lib/cjs/collapsible/foundation.d.ts +1 -0
- package/lib/cjs/datePicker/datePicker.css +2 -2
- package/lib/cjs/datePicker/datePicker.scss +2 -2
- package/lib/cjs/descriptions/foundation.js +3 -1
- package/lib/cjs/form/foundation.d.ts +5 -5
- package/lib/cjs/form/foundation.js +58 -21
- package/lib/cjs/form/interface.d.ts +8 -2
- package/lib/cjs/input/textareaFoundation.d.ts +12 -0
- package/lib/cjs/input/textareaFoundation.js +39 -0
- package/lib/cjs/modal/modalFoundation.d.ts +6 -0
- package/lib/cjs/modal/modalFoundation.js +36 -4
- package/lib/cjs/pagination/foundation.js +28 -7
- package/lib/cjs/pincode/foundation.d.ts +1 -1
- package/lib/cjs/resizable/resizable.css +3 -3
- package/lib/cjs/resizable/variables.scss +2 -2
- package/lib/cjs/select/foundation.d.ts +1 -1
- package/lib/cjs/select/foundation.js +19 -8
- package/lib/cjs/steps/bacisSteps.scss +8 -2
- package/lib/cjs/steps/steps.css +6 -0
- package/lib/cjs/upload/foundation.d.ts +8 -1
- package/lib/cjs/upload/foundation.js +70 -22
- package/lib/cjs/utils/escapeHtml.d.ts +9 -0
- package/lib/cjs/utils/escapeHtml.js +90 -0
- package/lib/cjs/utils/object.js +3 -1
- package/lib/es/aiChatInput/foundation.js +3 -1
- package/lib/es/autoComplete/foundation.d.ts +1 -0
- package/lib/es/autoComplete/foundation.js +1 -1
- package/lib/es/cascader/foundation.d.ts +1 -0
- package/lib/es/cascader/foundation.js +8 -3
- package/lib/es/collapsible/foundation.d.ts +1 -0
- package/lib/es/datePicker/datePicker.css +2 -2
- package/lib/es/datePicker/datePicker.scss +2 -2
- package/lib/es/descriptions/foundation.js +3 -1
- package/lib/es/form/foundation.d.ts +5 -5
- package/lib/es/form/foundation.js +58 -21
- package/lib/es/form/interface.d.ts +8 -2
- package/lib/es/input/textareaFoundation.d.ts +12 -0
- package/lib/es/input/textareaFoundation.js +39 -0
- package/lib/es/modal/modalFoundation.d.ts +6 -0
- package/lib/es/modal/modalFoundation.js +36 -4
- package/lib/es/pagination/foundation.js +28 -7
- package/lib/es/pincode/foundation.d.ts +1 -1
- package/lib/es/resizable/resizable.css +3 -3
- package/lib/es/resizable/variables.scss +2 -2
- package/lib/es/select/foundation.d.ts +1 -1
- package/lib/es/select/foundation.js +19 -8
- package/lib/es/steps/bacisSteps.scss +8 -2
- package/lib/es/steps/steps.css +6 -0
- package/lib/es/upload/foundation.d.ts +8 -1
- package/lib/es/upload/foundation.js +70 -22
- package/lib/es/utils/escapeHtml.d.ts +9 -0
- package/lib/es/utils/escapeHtml.js +84 -0
- package/lib/es/utils/object.js +3 -1
- package/modal/modalFoundation.ts +33 -32
- package/package.json +35 -5
- package/pagination/foundation.ts +25 -7
- package/pincode/foundation.ts +1 -1
- package/resizable/variables.scss +2 -2
- package/select/foundation.ts +19 -8
- package/steps/bacisSteps.scss +8 -2
- package/upload/foundation.ts +81 -24
- package/utils/escapeHtml.ts +94 -0
- package/utils/object.ts +3 -1
|
@@ -548,7 +548,8 @@ export default class CascaderFoundation extends BaseFoundation {
|
|
|
548
548
|
changeOnSelect: allowChange,
|
|
549
549
|
filterLeafOnly,
|
|
550
550
|
multiple,
|
|
551
|
-
enableLeafClick
|
|
551
|
+
enableLeafClick,
|
|
552
|
+
clickToSelect
|
|
552
553
|
} = this.getProps();
|
|
553
554
|
const {
|
|
554
555
|
keyEntities,
|
|
@@ -564,7 +565,9 @@ export default class CascaderFoundation extends BaseFoundation {
|
|
|
564
565
|
const activeKeys = keyEntities[key].path;
|
|
565
566
|
const selectedKey = [key];
|
|
566
567
|
const hasChanged = key !== [...selectedKeys][0];
|
|
567
|
-
|
|
568
|
+
// When clickToSelect is enabled in multiple mode, allow clicking non-leaf nodes to select
|
|
569
|
+
// In single mode, changeOnSelect (allowChange) controls this behavior
|
|
570
|
+
if (!isLeaf && !allowChange && !isSearching && !(multiple && clickToSelect)) {
|
|
568
571
|
this._adapter.updateStates({
|
|
569
572
|
activeKeys: new Set(activeKeys)
|
|
570
573
|
});
|
|
@@ -575,7 +578,9 @@ export default class CascaderFoundation extends BaseFoundation {
|
|
|
575
578
|
this._adapter.updateStates({
|
|
576
579
|
activeKeys: new Set(activeKeys)
|
|
577
580
|
});
|
|
578
|
-
|
|
581
|
+
// clickToSelect: click any node to select (takes precedence over enableLeafClick)
|
|
582
|
+
// enableLeafClick: click leaf node to select
|
|
583
|
+
if (clickToSelect || isLeaf && enableLeafClick) {
|
|
579
584
|
this.onItemCheckboxClick(item);
|
|
580
585
|
}
|
|
581
586
|
} else {
|
|
@@ -624,10 +624,10 @@
|
|
|
624
624
|
height: fit-content;
|
|
625
625
|
border: none;
|
|
626
626
|
}
|
|
627
|
-
.semi-datepicker-range-input-wrapper .semi-input-wrapper:active {
|
|
627
|
+
.semi-datepicker-range-input-wrapper .semi-input-wrapper:active:not(#neverExistElement) {
|
|
628
628
|
background-color: transparent;
|
|
629
629
|
}
|
|
630
|
-
.semi-datepicker-range-input-wrapper .semi-input-wrapper:hover {
|
|
630
|
+
.semi-datepicker-range-input-wrapper .semi-input-wrapper:hover:not(#neverExistElement) {
|
|
631
631
|
background-color: transparent;
|
|
632
632
|
}
|
|
633
633
|
.semi-datepicker-range-input-wrapper-focus {
|
|
@@ -937,11 +937,11 @@ $module-list: #{$prefix}-scrolllist;
|
|
|
937
937
|
height: fit-content;
|
|
938
938
|
border: none;
|
|
939
939
|
|
|
940
|
-
&:active
|
|
940
|
+
&:active:not(#neverExistElement) {
|
|
941
941
|
background-color: transparent;
|
|
942
942
|
}
|
|
943
943
|
|
|
944
|
-
&:hover {
|
|
944
|
+
&:hover:not(#neverExistElement) {
|
|
945
945
|
background-color: transparent;
|
|
946
946
|
}
|
|
947
947
|
}
|
|
@@ -10,12 +10,14 @@ export default class DescriptionsFoundation extends BaseFoundation {
|
|
|
10
10
|
children
|
|
11
11
|
} = this.getProps();
|
|
12
12
|
const columns = this._adapter.getColumns();
|
|
13
|
+
// Filter out hidden items before grouping
|
|
14
|
+
const visibleColumns = columns.filter(item => !item.hidden);
|
|
13
15
|
const horizontalList = [];
|
|
14
16
|
const curSpan = {
|
|
15
17
|
totalSpan: 0,
|
|
16
18
|
itemList: []
|
|
17
19
|
};
|
|
18
|
-
for (const item of
|
|
20
|
+
for (const item of visibleColumns) {
|
|
19
21
|
curSpan.totalSpan += item.span || 1;
|
|
20
22
|
curSpan.itemList.push(item);
|
|
21
23
|
if (curSpan.totalSpan >= column) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import BaseFoundation from '../base/foundation';
|
|
2
2
|
import { Options as ScrollIntoViewOptions } from 'scroll-into-view-if-needed';
|
|
3
|
-
import { BaseFormAdapter, FormState, CallOpts, FieldState, FieldStaff, ComponentProps, setValuesConfig, ArrayFieldStaff } from './interface';
|
|
3
|
+
import { BaseFormAdapter, FormState, CallOpts, FieldState, FieldStaff, ComponentProps, setValuesConfig, ArrayFieldStaff, ValidateOptions } from './interface';
|
|
4
4
|
export type { BaseFormAdapter };
|
|
5
5
|
type ScrollToErrorOpts = {
|
|
6
6
|
field?: string;
|
|
@@ -21,9 +21,9 @@ export default class FormFoundation extends BaseFoundation<BaseFormAdapter> {
|
|
|
21
21
|
unRegisterArrayField(arrayField: string): void;
|
|
22
22
|
getArrayField(arrayField: string): ArrayFieldStaff;
|
|
23
23
|
updateArrayField(arrayField: string, updateValue: any): void;
|
|
24
|
-
validate(fieldPaths?: Array<string>): Promise<unknown>;
|
|
25
|
-
_formValidate(): Promise<unknown>;
|
|
26
|
-
_fieldsValidate(fieldPaths: Array<string
|
|
24
|
+
validate(fieldPaths?: Array<string> | ValidateOptions): Promise<unknown>;
|
|
25
|
+
_formValidate(silent?: boolean): Promise<unknown>;
|
|
26
|
+
_fieldsValidate(fieldPaths: Array<string>, silent?: boolean): Promise<unknown>;
|
|
27
27
|
submit(e?: any): void;
|
|
28
28
|
/**
|
|
29
29
|
* Case A:
|
|
@@ -77,7 +77,7 @@ export default class FormFoundation extends BaseFoundation<BaseFormAdapter> {
|
|
|
77
77
|
};
|
|
78
78
|
getFormApi(): {
|
|
79
79
|
reset: (fields?: Array<string>) => void;
|
|
80
|
-
validate: (fields?: Array<string>) => Promise<unknown>;
|
|
80
|
+
validate: (fields?: Array<string> | ValidateOptions) => Promise<unknown>;
|
|
81
81
|
getValue: (field?: string) => any;
|
|
82
82
|
getValues: () => any;
|
|
83
83
|
getFormState: () => FormState<any>;
|
|
@@ -129,14 +129,27 @@ export default class FormFoundation extends BaseFoundation {
|
|
|
129
129
|
const {
|
|
130
130
|
validateFields
|
|
131
131
|
} = this.getProps();
|
|
132
|
+
// Parse options
|
|
133
|
+
let fields;
|
|
134
|
+
let silent = false;
|
|
135
|
+
if (fieldPaths && !Array.isArray(fieldPaths)) {
|
|
136
|
+
// It's a ValidateOptions object
|
|
137
|
+
const options = fieldPaths;
|
|
138
|
+
fields = options.fields;
|
|
139
|
+
silent = options.silent || false;
|
|
140
|
+
} else {
|
|
141
|
+
// It's an array of fields (or undefined)
|
|
142
|
+
fields = fieldPaths;
|
|
143
|
+
}
|
|
132
144
|
if (validateFields && _isFunction(validateFields)) {
|
|
133
|
-
return this._formValidate();
|
|
145
|
+
return this._formValidate(silent);
|
|
134
146
|
} else {
|
|
135
|
-
return this._fieldsValidate(
|
|
147
|
+
return this._fieldsValidate(fields, silent);
|
|
136
148
|
}
|
|
137
149
|
}
|
|
138
150
|
// form level validate
|
|
139
151
|
_formValidate() {
|
|
152
|
+
let silent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
140
153
|
const {
|
|
141
154
|
values
|
|
142
155
|
} = this.data;
|
|
@@ -154,41 +167,52 @@ export default class FormFoundation extends BaseFoundation {
|
|
|
154
167
|
if (!maybePromisedErrors) {
|
|
155
168
|
const _values = this._adapter.cloneDeep(values);
|
|
156
169
|
resolve(_values);
|
|
157
|
-
|
|
170
|
+
if (!silent) {
|
|
171
|
+
this.injectErrorToField({});
|
|
172
|
+
}
|
|
158
173
|
} else if (isPromise(maybePromisedErrors)) {
|
|
159
174
|
maybePromisedErrors.then(result => {
|
|
160
175
|
// validate success,clear error
|
|
161
176
|
if (!result) {
|
|
162
177
|
const _values = this._adapter.cloneDeep(values);
|
|
163
178
|
resolve(_values);
|
|
164
|
-
|
|
179
|
+
if (!silent) {
|
|
180
|
+
this.injectErrorToField({});
|
|
181
|
+
}
|
|
165
182
|
} else {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
183
|
+
if (!silent) {
|
|
184
|
+
this.data.errors = result;
|
|
185
|
+
this._adapter.notifyChange(this.data);
|
|
186
|
+
this.injectErrorToField(result);
|
|
187
|
+
this._adapter.forceUpdate();
|
|
188
|
+
this._autoScroll(100);
|
|
189
|
+
}
|
|
171
190
|
reject(result);
|
|
172
191
|
}
|
|
173
192
|
}, errors => {
|
|
174
193
|
// validate failed
|
|
175
|
-
|
|
176
|
-
|
|
194
|
+
if (!silent) {
|
|
195
|
+
// this._adapter.notifyChange(this.data);
|
|
196
|
+
this._autoScroll(100);
|
|
197
|
+
}
|
|
177
198
|
reject(errors);
|
|
178
199
|
});
|
|
179
200
|
} else {
|
|
180
201
|
// TODO: current design, returning an empty object will be considered a checksum failure and will be rejected. Only returning an empty string will be considered a success, consider resetting it in 1.0?
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
202
|
+
if (!silent) {
|
|
203
|
+
this.data.errors = maybePromisedErrors;
|
|
204
|
+
this.injectErrorToField(maybePromisedErrors);
|
|
205
|
+
this._adapter.notifyChange(this.data);
|
|
206
|
+
this._adapter.forceUpdate();
|
|
207
|
+
this._autoScroll(100);
|
|
208
|
+
}
|
|
186
209
|
reject(maybePromisedErrors);
|
|
187
210
|
}
|
|
188
211
|
});
|
|
189
212
|
}
|
|
190
213
|
// field level validate
|
|
191
214
|
_fieldsValidate(fieldPaths) {
|
|
215
|
+
let silent = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
192
216
|
const {
|
|
193
217
|
values
|
|
194
218
|
} = this.data;
|
|
@@ -200,24 +224,37 @@ export default class FormFoundation extends BaseFoundation {
|
|
|
200
224
|
// Call each fieldApi for verification
|
|
201
225
|
const fieldValue = this.getValue(fieldPath);
|
|
202
226
|
// When centralized verification, no need to trigger forceUpdate and notify
|
|
227
|
+
// Each field skips individual updates; a single forceUpdate fires after all resolve.
|
|
203
228
|
const opts = {
|
|
204
229
|
notNotify: true,
|
|
205
|
-
notUpdate: true
|
|
230
|
+
notUpdate: true,
|
|
231
|
+
silent
|
|
206
232
|
};
|
|
207
233
|
const validateResult = field.fieldApi.validate(fieldValue, opts);
|
|
208
234
|
promiseSet.push(validateResult);
|
|
209
|
-
|
|
235
|
+
// Only set touched when not in silent mode
|
|
236
|
+
if (!silent) {
|
|
237
|
+
field.fieldApi.setTouched(true, {
|
|
238
|
+
notNotify: true,
|
|
239
|
+
notUpdate: true
|
|
240
|
+
});
|
|
241
|
+
}
|
|
210
242
|
});
|
|
211
243
|
Promise.all(promiseSet).then(() => {
|
|
212
244
|
// After the centralized verification is completed, trigger notify and forceUpdate once.
|
|
213
|
-
|
|
214
|
-
|
|
245
|
+
// But skip UI updates in silent mode
|
|
246
|
+
if (!silent) {
|
|
247
|
+
this._adapter.notifyChange(this.data);
|
|
248
|
+
this._adapter.forceUpdate();
|
|
249
|
+
}
|
|
215
250
|
const errors = this.getError();
|
|
216
251
|
if (this._isValid(targetFields)) {
|
|
217
252
|
const _values = this._adapter.cloneDeep(values);
|
|
218
253
|
resolve(_values);
|
|
219
254
|
} else {
|
|
220
|
-
|
|
255
|
+
if (!silent) {
|
|
256
|
+
this._autoScroll();
|
|
257
|
+
}
|
|
221
258
|
reject(errors);
|
|
222
259
|
}
|
|
223
260
|
});
|
|
@@ -42,6 +42,12 @@ export type ScrollToErrorOptions<K> = {
|
|
|
42
42
|
index?: number;
|
|
43
43
|
scrollOpts?: ScrollIntoViewOptions;
|
|
44
44
|
};
|
|
45
|
+
export interface ValidateOptions<K extends keyof any = keyof any> {
|
|
46
|
+
/** Fields to validate, if not specified, validate all fields */
|
|
47
|
+
fields?: Array<K>;
|
|
48
|
+
/** Whether to validate silently (without updating UI or setting touched state) */
|
|
49
|
+
silent?: boolean;
|
|
50
|
+
}
|
|
45
51
|
export interface BaseFormApi<T extends object = any> {
|
|
46
52
|
/** get value of field */
|
|
47
53
|
getValue: <P extends FieldPath<T>>(field?: P) => FieldPathValue<T, P>;
|
|
@@ -65,8 +71,8 @@ export interface BaseFormApi<T extends object = any> {
|
|
|
65
71
|
submitForm: () => void;
|
|
66
72
|
/** reset form manual */
|
|
67
73
|
reset: (fields?: Array<string>) => void;
|
|
68
|
-
/** trigger validate
|
|
69
|
-
validate: <K extends keyof T, Params extends Array<K>, V extends Params[number]>(fields?: Params) => Promise<{
|
|
74
|
+
/** trigger validate manual */
|
|
75
|
+
validate: <K extends keyof T, Params extends Array<K>, V extends Params[number]>(fields?: Params | ValidateOptions<K>) => Promise<{
|
|
70
76
|
[R in V]: T[R];
|
|
71
77
|
}>;
|
|
72
78
|
getInitValue: <K extends keyof T>(field: K) => any;
|
|
@@ -18,6 +18,8 @@ export interface TextAreaAdapter extends Partial<DefaultAdapter>, Partial<TextAr
|
|
|
18
18
|
notifyPressEnter(e: any): void;
|
|
19
19
|
getRef(): HTMLInputElement;
|
|
20
20
|
notifyHeightUpdate(e: any): void;
|
|
21
|
+
focusInput(): void;
|
|
22
|
+
isEventTarget(e: any): boolean;
|
|
21
23
|
}
|
|
22
24
|
export default class TextAreaFoundation extends BaseFoundation<TextAreaAdapter> {
|
|
23
25
|
static get textAreaDefaultAdapter(): {
|
|
@@ -67,4 +69,14 @@ export default class TextAreaFoundation extends BaseFoundation<TextAreaAdapter>
|
|
|
67
69
|
handleMouseLeave(e: any): void;
|
|
68
70
|
isAllowClear(): boolean;
|
|
69
71
|
handleClear(e: any): void;
|
|
72
|
+
/**
|
|
73
|
+
* trigger when click textarea wrapper
|
|
74
|
+
* @param {Event} e
|
|
75
|
+
*/
|
|
76
|
+
handleClick(e: any): void;
|
|
77
|
+
/**
|
|
78
|
+
* trigger when click textarea counter
|
|
79
|
+
* @param {Event} e
|
|
80
|
+
*/
|
|
81
|
+
handleCounterClick(e: any): void;
|
|
70
82
|
}
|
|
@@ -270,4 +270,43 @@ export default class TextAreaFoundation extends BaseFoundation {
|
|
|
270
270
|
this._adapter.notifyClear(e);
|
|
271
271
|
this.stopPropagation(e);
|
|
272
272
|
}
|
|
273
|
+
/**
|
|
274
|
+
* trigger when click textarea wrapper
|
|
275
|
+
* @param {Event} e
|
|
276
|
+
*/
|
|
277
|
+
handleClick(e) {
|
|
278
|
+
const {
|
|
279
|
+
disabled,
|
|
280
|
+
readonly
|
|
281
|
+
} = this._adapter.getProps();
|
|
282
|
+
const {
|
|
283
|
+
isFocus
|
|
284
|
+
} = this._adapter.getStates();
|
|
285
|
+
if (disabled || readonly || isFocus) {
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
// do not handle bubbling up events
|
|
289
|
+
if (this._adapter.isEventTarget(e)) {
|
|
290
|
+
this._adapter.focusInput();
|
|
291
|
+
this._adapter.toggleFocusing(true);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* trigger when click textarea counter
|
|
296
|
+
* @param {Event} e
|
|
297
|
+
*/
|
|
298
|
+
handleCounterClick(e) {
|
|
299
|
+
const {
|
|
300
|
+
disabled,
|
|
301
|
+
readonly
|
|
302
|
+
} = this._adapter.getProps();
|
|
303
|
+
const {
|
|
304
|
+
isFocus
|
|
305
|
+
} = this._adapter.getStates();
|
|
306
|
+
if (disabled || readonly || isFocus) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
this._adapter.focusInput();
|
|
310
|
+
this._adapter.toggleFocusing(true);
|
|
311
|
+
}
|
|
273
312
|
}
|
|
@@ -61,10 +61,16 @@ export interface ModalState {
|
|
|
61
61
|
onCancelReturnPromiseStatus?: "pending" | "fulfilled" | "rejected";
|
|
62
62
|
}
|
|
63
63
|
export default class ModalFoundation extends BaseFoundation<ModalAdapter> {
|
|
64
|
+
private _debouncedOk;
|
|
65
|
+
private _debouncedCancel;
|
|
66
|
+
private _lastCancelTarget;
|
|
67
|
+
private _lastOkTarget;
|
|
64
68
|
constructor(adapter: ModalAdapter);
|
|
65
69
|
destroy(): void;
|
|
66
70
|
handleCancel(e: any): void;
|
|
67
71
|
handleOk(e: any): void;
|
|
72
|
+
private _invokeCancel;
|
|
73
|
+
private _invokeOk;
|
|
68
74
|
beforeShow(): void;
|
|
69
75
|
afterHide(): void;
|
|
70
76
|
enabledBodyScroll(): void;
|
|
@@ -1,19 +1,51 @@
|
|
|
1
|
+
import _debounce from "lodash/debounce";
|
|
1
2
|
import BaseFoundation from '../base/foundation';
|
|
2
3
|
import isPromise from "../utils/isPromise";
|
|
3
4
|
export default class ModalFoundation extends BaseFoundation {
|
|
4
5
|
constructor(adapter) {
|
|
5
6
|
super(Object.assign({}, adapter));
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
this._debouncedOk = _debounce(e => {
|
|
8
|
+
this._invokeOk(e);
|
|
9
|
+
}, 100, {
|
|
10
|
+
leading: true,
|
|
11
|
+
trailing: false
|
|
12
|
+
});
|
|
13
|
+
this._debouncedCancel = _debounce(e => {
|
|
14
|
+
this._invokeCancel(e);
|
|
15
|
+
}, 100, {
|
|
16
|
+
leading: true,
|
|
17
|
+
trailing: false
|
|
18
|
+
});
|
|
19
|
+
this._lastCancelTarget = null;
|
|
20
|
+
this._lastOkTarget = null;
|
|
9
21
|
this.toggleDisplayNone = (displayNone, callback) => {
|
|
10
22
|
this._adapter.toggleDisplayNone(displayNone, callback);
|
|
11
23
|
};
|
|
12
24
|
}
|
|
13
25
|
destroy() {
|
|
26
|
+
this._debouncedOk.cancel();
|
|
27
|
+
this._debouncedCancel.cancel();
|
|
14
28
|
this.afterHide();
|
|
15
29
|
}
|
|
16
30
|
handleCancel(e) {
|
|
31
|
+
var _a, _b;
|
|
32
|
+
const target = (_b = (_a = e === null || e === void 0 ? void 0 : e.currentTarget) !== null && _a !== void 0 ? _a : e === null || e === void 0 ? void 0 : e.target) !== null && _b !== void 0 ? _b : null;
|
|
33
|
+
if (target !== this._lastCancelTarget) {
|
|
34
|
+
this._debouncedCancel.cancel();
|
|
35
|
+
}
|
|
36
|
+
this._lastCancelTarget = target;
|
|
37
|
+
this._debouncedCancel(e);
|
|
38
|
+
}
|
|
39
|
+
handleOk(e) {
|
|
40
|
+
var _a, _b;
|
|
41
|
+
const target = (_b = (_a = e === null || e === void 0 ? void 0 : e.currentTarget) !== null && _a !== void 0 ? _a : e === null || e === void 0 ? void 0 : e.target) !== null && _b !== void 0 ? _b : null;
|
|
42
|
+
if (target !== this._lastOkTarget) {
|
|
43
|
+
this._debouncedOk.cancel();
|
|
44
|
+
}
|
|
45
|
+
this._lastOkTarget = target;
|
|
46
|
+
this._debouncedOk(e);
|
|
47
|
+
}
|
|
48
|
+
_invokeCancel(e) {
|
|
17
49
|
var _a;
|
|
18
50
|
const result = this._adapter.notifyCancel(e);
|
|
19
51
|
if (isPromise(result)) {
|
|
@@ -32,7 +64,7 @@ export default class ModalFoundation extends BaseFoundation {
|
|
|
32
64
|
});
|
|
33
65
|
}
|
|
34
66
|
}
|
|
35
|
-
|
|
67
|
+
_invokeOk(e) {
|
|
36
68
|
var _a;
|
|
37
69
|
const result = this._adapter.notifyOk(e);
|
|
38
70
|
if (isPromise(result)) {
|
|
@@ -48,7 +48,13 @@ class PaginationFoundation extends BaseFoundation {
|
|
|
48
48
|
prevIsDisabled = false;
|
|
49
49
|
nextIsDisabled = true;
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
const {
|
|
52
|
+
prevDisabled: currentPrevDisabled,
|
|
53
|
+
nextDisabled: currentNextDisabled
|
|
54
|
+
} = this.getStates();
|
|
55
|
+
if (prevIsDisabled !== currentPrevDisabled || nextIsDisabled !== currentNextDisabled) {
|
|
56
|
+
this._adapter.setDisabled(prevIsDisabled, nextIsDisabled);
|
|
57
|
+
}
|
|
52
58
|
}
|
|
53
59
|
goPage(targetPageIndex) {
|
|
54
60
|
if (targetPageIndex === '...') {
|
|
@@ -92,9 +98,17 @@ class PaginationFoundation extends BaseFoundation {
|
|
|
92
98
|
total,
|
|
93
99
|
pageSize
|
|
94
100
|
});
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
this.
|
|
101
|
+
// Only call setState when value actually changed to avoid unnecessary re-renders
|
|
102
|
+
// that can cause infinite loops in React 18's concurrent batching
|
|
103
|
+
if (total !== this.getState('total')) {
|
|
104
|
+
this._adapter.updateTotal(total);
|
|
105
|
+
}
|
|
106
|
+
if (targetPageIndex !== this.getState('currentPage')) {
|
|
107
|
+
this._adapter.setCurrentPage(targetPageIndex);
|
|
108
|
+
}
|
|
109
|
+
if (pageSize !== this.getState('pageSize')) {
|
|
110
|
+
this._adapter.updatePageSize(pageSize);
|
|
111
|
+
}
|
|
98
112
|
}
|
|
99
113
|
updateAllPageNumbers(total, pageSize) {
|
|
100
114
|
// only need to update in small size
|
|
@@ -230,9 +244,16 @@ class PaginationFoundation extends BaseFoundation {
|
|
|
230
244
|
total,
|
|
231
245
|
currentPage
|
|
232
246
|
} = this.getStates();
|
|
233
|
-
//
|
|
234
|
-
const
|
|
235
|
-
|
|
247
|
+
// Check if we should prevent page change when pageSize changes
|
|
248
|
+
const {
|
|
249
|
+
preventPageChangeOnPageSizeChange
|
|
250
|
+
} = this.getProps();
|
|
251
|
+
let newCurrentPage = currentPage;
|
|
252
|
+
if (!preventPageChangeOnPageSizeChange) {
|
|
253
|
+
// After converting the switching page capacity, which page is the current page
|
|
254
|
+
const currentPageFirstItemIndex = (currentPage - 1) * pageSize + 1;
|
|
255
|
+
newCurrentPage = Math.ceil(currentPageFirstItemIndex / newPageSize);
|
|
256
|
+
}
|
|
236
257
|
this.updatePage(newCurrentPage, total, newPageSize);
|
|
237
258
|
if (currentPage !== newCurrentPage) {
|
|
238
259
|
this._adapter.notifyPageChange(newCurrentPage);
|
|
@@ -3,7 +3,7 @@ export interface PinCodeBaseProps {
|
|
|
3
3
|
disabled?: boolean;
|
|
4
4
|
value?: string;
|
|
5
5
|
format?: "number" | "mixed" | RegExp | ((value: string) => boolean);
|
|
6
|
-
onChange
|
|
6
|
+
onChange?: (value: string) => void;
|
|
7
7
|
defaultValue?: string;
|
|
8
8
|
count?: number;
|
|
9
9
|
autoFocus?: boolean;
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
.semi-resizable-resizableHandler {
|
|
10
10
|
position: absolute;
|
|
11
11
|
user-select: none;
|
|
12
|
-
z-index:
|
|
12
|
+
z-index: 10;
|
|
13
13
|
}
|
|
14
14
|
.semi-resizable-resizableHandler-top {
|
|
15
15
|
width: 100%;
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
}
|
|
92
92
|
.semi-resizable-handler {
|
|
93
93
|
user-select: none;
|
|
94
|
-
z-index:
|
|
94
|
+
z-index: 10;
|
|
95
95
|
display: flex;
|
|
96
96
|
align-items: center;
|
|
97
97
|
justify-content: center;
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
height: 100%;
|
|
115
115
|
width: 100%;
|
|
116
116
|
inset: 0;
|
|
117
|
-
z-index:
|
|
117
|
+
z-index: 20;
|
|
118
118
|
opacity: 0;
|
|
119
119
|
position: fixed;
|
|
120
120
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
$z-resizable_handler:
|
|
2
|
-
$z-resizable_background:
|
|
1
|
+
$z-resizable_handler: 10 !default; // 伸缩框组件中handler的z-index,保持较低层级避免覆盖弹出层组件
|
|
2
|
+
$z-resizable_background: 20; // 伸缩框组件中背景的z-index,保持略高于handler
|
|
3
3
|
|
|
4
4
|
$height-row-handler: 10px; // 单个伸缩框中上下handler的高度
|
|
5
5
|
$width-col-handler: 10px; // 单个伸缩框中左右handler的宽度
|
|
@@ -54,7 +54,7 @@ export default class SelectFoundation extends BaseFoundation<SelectAdapter> {
|
|
|
54
54
|
constructor(adapter: SelectAdapter);
|
|
55
55
|
_keydownHandler: (...arg: any[]) => void | null;
|
|
56
56
|
init(): void;
|
|
57
|
-
focus(): void;
|
|
57
|
+
focus(optionsForOpen?: BasicOptionProps[]): void;
|
|
58
58
|
_focusTrigger(): void;
|
|
59
59
|
destroy(): void;
|
|
60
60
|
_setDropdownWidth(): void;
|
|
@@ -34,20 +34,31 @@ export default class SelectFoundation extends BaseFoundation {
|
|
|
34
34
|
}
|
|
35
35
|
const autoFocus = this.getProp('autoFocus');
|
|
36
36
|
if (autoFocus) {
|
|
37
|
-
this.focus();
|
|
37
|
+
this.focus(originalOptions);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
-
focus() {
|
|
40
|
+
focus(optionsForOpen) {
|
|
41
41
|
const isFilterable = this._isFilterable();
|
|
42
42
|
const isMultiple = this._isMultiple();
|
|
43
|
+
const {
|
|
44
|
+
isOpen
|
|
45
|
+
} = this.getStates();
|
|
43
46
|
this._adapter.updateFocusState(true);
|
|
44
47
|
this._adapter.setIsFocusInContainer(false);
|
|
45
|
-
if (isFilterable
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
if (isFilterable) {
|
|
49
|
+
if (isMultiple) {
|
|
50
|
+
// when filter and multiple, focus input and open dropdown
|
|
51
|
+
this.focusInput();
|
|
52
|
+
if (!isOpen) {
|
|
53
|
+
this.open(undefined, optionsForOpen);
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
// when filter and not multiple, show input, focus it and open dropdown
|
|
57
|
+
this.toggle2SearchInput(true);
|
|
58
|
+
if (!isOpen) {
|
|
59
|
+
this.open(undefined, optionsForOpen);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
51
62
|
} else {
|
|
52
63
|
this._focusTrigger();
|
|
53
64
|
}
|
|
@@ -69,11 +69,17 @@ $basicType: #{$module}-basic;
|
|
|
69
69
|
|
|
70
70
|
.#{$item}-title {
|
|
71
71
|
max-width: $width-steps_basic_item_title-maxWidth;
|
|
72
|
+
min-height: $height-steps_basic_item_left-icon;
|
|
73
|
+
display: inline-flex;
|
|
74
|
+
align-items: center;
|
|
72
75
|
|
|
73
76
|
.#{$item}-title-text {
|
|
74
77
|
@include text-overflow-hidden;
|
|
75
|
-
transition: color $transition_duration-steps_item_title-text $transition_function-steps_item_title-text $transition_delay-steps_item_title-text
|
|
76
|
-
|
|
78
|
+
transition: color $transition_duration-steps_item_title-text $transition_function-steps_item_title-text $transition_delay-steps_item_title-text;
|
|
79
|
+
|
|
80
|
+
&-empty {
|
|
81
|
+
width: 0;
|
|
82
|
+
}
|
|
77
83
|
}
|
|
78
84
|
}
|
|
79
85
|
|
package/lib/es/steps/steps.css
CHANGED
|
@@ -193,6 +193,9 @@
|
|
|
193
193
|
}
|
|
194
194
|
.semi-steps-basic.semi-steps-horizontal .semi-steps-item .semi-steps-item-title {
|
|
195
195
|
max-width: 80%;
|
|
196
|
+
min-height: 24px;
|
|
197
|
+
display: inline-flex;
|
|
198
|
+
align-items: center;
|
|
196
199
|
}
|
|
197
200
|
.semi-steps-basic.semi-steps-horizontal .semi-steps-item .semi-steps-item-title .semi-steps-item-title-text {
|
|
198
201
|
overflow: hidden;
|
|
@@ -200,6 +203,9 @@
|
|
|
200
203
|
white-space: nowrap;
|
|
201
204
|
transition: color var(--semi-transition_duration-none) var(--semi-transition_function-easeIn) var(--semi-transition_delay-none);
|
|
202
205
|
}
|
|
206
|
+
.semi-steps-basic.semi-steps-horizontal .semi-steps-item .semi-steps-item-title .semi-steps-item-title-text-empty {
|
|
207
|
+
width: 0;
|
|
208
|
+
}
|
|
203
209
|
.semi-steps-basic.semi-steps-vertical {
|
|
204
210
|
display: flex;
|
|
205
211
|
flex-flow: column nowrap;
|
|
@@ -74,8 +74,10 @@ export interface UploadAdapter<P = Record<string, any>, S = Record<string, any>>
|
|
|
74
74
|
notifyPreviewClick: (file: any) => void;
|
|
75
75
|
notifyDrop: (e: any, files: Array<File>, fileList: Array<BaseFileItem>) => void;
|
|
76
76
|
notifyAcceptInvalid: (invalidFiles: Array<File>) => void;
|
|
77
|
-
registerPastingHandler: (cb?: (params?:
|
|
77
|
+
registerPastingHandler: (cb?: (params?: KeyboardEvent | ClipboardEvent) => void) => void;
|
|
78
78
|
unRegisterPastingHandler: () => void;
|
|
79
|
+
registerPasteEventHandler: (cb?: (params?: ClipboardEvent) => void) => void;
|
|
80
|
+
unRegisterPasteEventHandler: () => void;
|
|
79
81
|
isMac: () => boolean;
|
|
80
82
|
notifyPastingError: (error: Error | PermissionStatus) => void;
|
|
81
83
|
}
|
|
@@ -87,6 +89,11 @@ declare class UploadFoundation<P = Record<string, any>, S = Record<string, any>>
|
|
|
87
89
|
* when _createURL is called multiple times in a sync loop.
|
|
88
90
|
*/
|
|
89
91
|
_localUrls: Record<string, string>;
|
|
92
|
+
/**
|
|
93
|
+
* Flag to prevent duplicate handling of paste events.
|
|
94
|
+
* When paste event is successfully handled, we ignore the subsequent keydown event.
|
|
95
|
+
*/
|
|
96
|
+
_pasteHandled: boolean;
|
|
90
97
|
constructor(adapter: UploadAdapter<P, S>);
|
|
91
98
|
init(): void;
|
|
92
99
|
/**
|