@douyinfe/semi-foundation 2.43.0-alpha.0 → 2.43.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/cascader/cascader.scss +0 -1
- package/cascader/foundation.ts +0 -7
- package/lib/cjs/cascader/cascader.scss +0 -1
- package/lib/cjs/cascader/foundation.d.ts +0 -6
- package/lib/cjs/tagInput/foundation.js +28 -19
- package/lib/cjs/tree/foundation.d.ts +2 -0
- package/lib/cjs/upload/foundation.d.ts +9 -0
- package/lib/cjs/upload/foundation.js +66 -0
- package/lib/es/cascader/cascader.scss +0 -1
- package/lib/es/cascader/foundation.d.ts +0 -6
- package/lib/es/tagInput/foundation.js +28 -19
- package/lib/es/tree/foundation.d.ts +2 -0
- package/lib/es/upload/foundation.d.ts +9 -0
- package/lib/es/upload/foundation.js +66 -0
- package/package.json +3 -3
- package/tagInput/foundation.ts +26 -17
- package/tree/foundation.ts +5 -1
- package/upload/foundation.ts +73 -1
package/cascader/cascader.scss
CHANGED
package/cascader/foundation.ts
CHANGED
|
@@ -28,12 +28,6 @@ export interface BasicData {
|
|
|
28
28
|
pathData?: BasicCascaderData[]
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
export interface Virtualize {
|
|
32
|
-
itemSize: number;
|
|
33
|
-
height?: number | string;
|
|
34
|
-
width?: number | string
|
|
35
|
-
}
|
|
36
|
-
|
|
37
31
|
export interface BasicEntities {
|
|
38
32
|
[idx: string]: BasicEntity
|
|
39
33
|
}
|
|
@@ -163,7 +157,6 @@ export interface BasicCascaderProps {
|
|
|
163
157
|
leafOnly?: boolean;
|
|
164
158
|
enableLeafClick?: boolean;
|
|
165
159
|
preventScroll?: boolean;
|
|
166
|
-
virtualizeInSearch?: Virtualize;
|
|
167
160
|
onClear?: () => void;
|
|
168
161
|
triggerRender?: (props: BasicTriggerRenderProps) => any;
|
|
169
162
|
onListScroll?: (e: any, panel: BasicScrollPanelProps) => void;
|
|
@@ -6,11 +6,6 @@ export interface BasicData {
|
|
|
6
6
|
searchText: any[];
|
|
7
7
|
pathData?: BasicCascaderData[];
|
|
8
8
|
}
|
|
9
|
-
export interface Virtualize {
|
|
10
|
-
itemSize: number;
|
|
11
|
-
height?: number | string;
|
|
12
|
-
width?: number | string;
|
|
13
|
-
}
|
|
14
9
|
export interface BasicEntities {
|
|
15
10
|
[idx: string]: BasicEntity;
|
|
16
11
|
}
|
|
@@ -110,7 +105,6 @@ export interface BasicCascaderProps {
|
|
|
110
105
|
leafOnly?: boolean;
|
|
111
106
|
enableLeafClick?: boolean;
|
|
112
107
|
preventScroll?: boolean;
|
|
113
|
-
virtualizeInSearch?: Virtualize;
|
|
114
108
|
onClear?: () => void;
|
|
115
109
|
triggerRender?: (props: BasicTriggerRenderProps) => any;
|
|
116
110
|
onListScroll?: (e: any, panel: BasicScrollPanelProps) => void;
|
|
@@ -41,10 +41,15 @@ class TagInputFoundation extends _foundation.default {
|
|
|
41
41
|
}
|
|
42
42
|
};
|
|
43
43
|
this.handleInputCompositionStart = e => {
|
|
44
|
+
const {
|
|
45
|
+
maxLength
|
|
46
|
+
} = this.getProps();
|
|
47
|
+
if (!(0, _isNumber2.default)(maxLength)) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
44
50
|
this._adapter.setEntering(true);
|
|
45
51
|
};
|
|
46
52
|
this.handleInputCompositionEnd = e => {
|
|
47
|
-
this._adapter.setEntering(false);
|
|
48
53
|
const {
|
|
49
54
|
value
|
|
50
55
|
} = e.target;
|
|
@@ -53,27 +58,31 @@ class TagInputFoundation extends _foundation.default {
|
|
|
53
58
|
onInputExceed,
|
|
54
59
|
separator
|
|
55
60
|
} = this.getProps();
|
|
61
|
+
if (!(0, _isNumber2.default)(maxLength)) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
this._adapter.setEntering(false);
|
|
56
65
|
let allowChange = true;
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (inputArr[index].length > maxLength) {
|
|
65
|
-
allowChange = false;
|
|
66
|
-
(0, _isFunction2.default)(onInputExceed) && onInputExceed(value);
|
|
67
|
-
break;
|
|
68
|
-
}
|
|
66
|
+
const inputArr = (0, _getSplitedArray.default)(value, separator);
|
|
67
|
+
let index = 0;
|
|
68
|
+
for (; index < inputArr.length; index++) {
|
|
69
|
+
if (inputArr[index].length > maxLength) {
|
|
70
|
+
allowChange = false;
|
|
71
|
+
(0, _isFunction2.default)(onInputExceed) && onInputExceed(value);
|
|
72
|
+
break;
|
|
69
73
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
this._adapter.setInputValue(newInputArr.join(separator));
|
|
74
|
+
}
|
|
75
|
+
if (!allowChange) {
|
|
76
|
+
const newInputArr = inputArr.slice(0, index);
|
|
77
|
+
if (index < inputArr.length) {
|
|
78
|
+
newInputArr.push(inputArr[index].slice(0, maxLength));
|
|
76
79
|
}
|
|
80
|
+
this._adapter.setInputValue(newInputArr.join(separator));
|
|
81
|
+
} else {
|
|
82
|
+
// Why does it need to be updated here instead of in onChange when the value meets the maxLength limit?
|
|
83
|
+
// Because in firefox, the state change in InputCompositionEnd causes onChange to not be triggered after
|
|
84
|
+
// the composition input completes input.
|
|
85
|
+
this._adapter.setInputValue(value);
|
|
77
86
|
}
|
|
78
87
|
};
|
|
79
88
|
/**
|
|
@@ -73,9 +73,14 @@ export interface UploadAdapter<P = Record<string, any>, S = Record<string, any>>
|
|
|
73
73
|
notifyPreviewClick: (file: any) => void;
|
|
74
74
|
notifyDrop: (e: any, files: Array<File>, fileList: Array<BaseFileItem>) => void;
|
|
75
75
|
notifyAcceptInvalid: (invalidFiles: Array<File>) => void;
|
|
76
|
+
registerPastingHandler: (cb?: (params?: any) => void) => void;
|
|
77
|
+
unRegisterPastingHandler: () => void;
|
|
78
|
+
isMac: () => boolean;
|
|
79
|
+
notifyPastingError: (error: Error | PermissionStatus) => void;
|
|
76
80
|
}
|
|
77
81
|
declare class UploadFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<UploadAdapter<P, S>, P, S> {
|
|
78
82
|
constructor(adapter: UploadAdapter<P, S>);
|
|
83
|
+
init(): void;
|
|
79
84
|
destroy(): void;
|
|
80
85
|
getError({ action, xhr, message, fileName }: {
|
|
81
86
|
action: string;
|
|
@@ -163,5 +168,9 @@ declare class UploadFoundation<P = Record<string, any>, S = Record<string, any>>
|
|
|
163
168
|
checkFileFormat(accept: string, file: File): boolean;
|
|
164
169
|
retry(fileItem: BaseFileItem): void;
|
|
165
170
|
handlePreviewClick(fileItem: BaseFileItem): void;
|
|
171
|
+
readFileFromClipboard(clipboardItems: any): void;
|
|
172
|
+
handlePasting(e: any): void;
|
|
173
|
+
bindPastingHandler(): void;
|
|
174
|
+
unbindPastingHandler(): void;
|
|
166
175
|
}
|
|
167
176
|
export default UploadFoundation;
|
|
@@ -51,8 +51,24 @@ class UploadFoundation extends _foundation.default {
|
|
|
51
51
|
constructor(adapter) {
|
|
52
52
|
super(Object.assign({}, adapter));
|
|
53
53
|
}
|
|
54
|
+
init() {
|
|
55
|
+
const {
|
|
56
|
+
disabled,
|
|
57
|
+
addOnPasting
|
|
58
|
+
} = this.getProps();
|
|
59
|
+
if (addOnPasting && !disabled) {
|
|
60
|
+
this.bindPastingHandler();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
54
63
|
destroy() {
|
|
64
|
+
const {
|
|
65
|
+
disabled,
|
|
66
|
+
addOnPasting
|
|
67
|
+
} = this.getProps();
|
|
55
68
|
this.releaseMemory();
|
|
69
|
+
if (addOnPasting && !disabled) {
|
|
70
|
+
this.unbindPastingHandler();
|
|
71
|
+
}
|
|
56
72
|
}
|
|
57
73
|
getError(_ref) {
|
|
58
74
|
let {
|
|
@@ -912,6 +928,56 @@ class UploadFoundation extends _foundation.default {
|
|
|
912
928
|
handlePreviewClick(fileItem) {
|
|
913
929
|
this._adapter.notifyPreviewClick(fileItem);
|
|
914
930
|
}
|
|
931
|
+
readFileFromClipboard(clipboardItems) {
|
|
932
|
+
for (const clipboardItem of clipboardItems) {
|
|
933
|
+
for (const type of clipboardItem.types) {
|
|
934
|
+
// types maybe: text/plain, image/png, text/html
|
|
935
|
+
if (type.startsWith('image')) {
|
|
936
|
+
clipboardItem.getType(type).then(blob => {
|
|
937
|
+
return blob.arrayBuffer();
|
|
938
|
+
}).then(buffer => {
|
|
939
|
+
const format = type.split('/')[1];
|
|
940
|
+
const file = new File([buffer], `upload.${format}`, {
|
|
941
|
+
type
|
|
942
|
+
});
|
|
943
|
+
this.handleChange([file]);
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
handlePasting(e) {
|
|
950
|
+
const isMac = this._adapter.isMac();
|
|
951
|
+
const isCombineKeydown = isMac ? e.metaKey : e.ctrlKey;
|
|
952
|
+
if (isCombineKeydown && e.code === 'KeyV' && e.target === document.body) {
|
|
953
|
+
// https://github.com/microsoft/TypeScript/issues/33923
|
|
954
|
+
const permissionName = "clipboard-read";
|
|
955
|
+
// The main thread should not be blocked by clipboard, so callback writing is required here. No await here
|
|
956
|
+
navigator.permissions.query({
|
|
957
|
+
name: permissionName
|
|
958
|
+
}).then(result => {
|
|
959
|
+
console.log(result);
|
|
960
|
+
if (result.state === 'granted' || result.state === 'prompt') {
|
|
961
|
+
// user has authorized or will authorize
|
|
962
|
+
navigator.clipboard.read().then(clipboardItems => {
|
|
963
|
+
// Process the data read from the pasteboard
|
|
964
|
+
// Check the returned data type to determine if it is image data, and process accordingly
|
|
965
|
+
this.readFileFromClipboard(clipboardItems);
|
|
966
|
+
});
|
|
967
|
+
} else {
|
|
968
|
+
this._adapter.notifyPastingError(result);
|
|
969
|
+
}
|
|
970
|
+
}).catch(error => {
|
|
971
|
+
this._adapter.notifyPastingError(error);
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
bindPastingHandler() {
|
|
976
|
+
this._adapter.registerPastingHandler(event => this.handlePasting(event));
|
|
977
|
+
}
|
|
978
|
+
unbindPastingHandler() {
|
|
979
|
+
this._adapter.unRegisterPastingHandler();
|
|
980
|
+
}
|
|
915
981
|
}
|
|
916
982
|
var _default = UploadFoundation;
|
|
917
983
|
exports.default = _default;
|
|
@@ -6,11 +6,6 @@ export interface BasicData {
|
|
|
6
6
|
searchText: any[];
|
|
7
7
|
pathData?: BasicCascaderData[];
|
|
8
8
|
}
|
|
9
|
-
export interface Virtualize {
|
|
10
|
-
itemSize: number;
|
|
11
|
-
height?: number | string;
|
|
12
|
-
width?: number | string;
|
|
13
|
-
}
|
|
14
9
|
export interface BasicEntities {
|
|
15
10
|
[idx: string]: BasicEntity;
|
|
16
11
|
}
|
|
@@ -110,7 +105,6 @@ export interface BasicCascaderProps {
|
|
|
110
105
|
leafOnly?: boolean;
|
|
111
106
|
enableLeafClick?: boolean;
|
|
112
107
|
preventScroll?: boolean;
|
|
113
|
-
virtualizeInSearch?: Virtualize;
|
|
114
108
|
onClear?: () => void;
|
|
115
109
|
triggerRender?: (props: BasicTriggerRenderProps) => any;
|
|
116
110
|
onListScroll?: (e: any, panel: BasicScrollPanelProps) => void;
|
|
@@ -34,10 +34,15 @@ class TagInputFoundation extends BaseFoundation {
|
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
36
|
this.handleInputCompositionStart = e => {
|
|
37
|
+
const {
|
|
38
|
+
maxLength
|
|
39
|
+
} = this.getProps();
|
|
40
|
+
if (!_isNumber(maxLength)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
37
43
|
this._adapter.setEntering(true);
|
|
38
44
|
};
|
|
39
45
|
this.handleInputCompositionEnd = e => {
|
|
40
|
-
this._adapter.setEntering(false);
|
|
41
46
|
const {
|
|
42
47
|
value
|
|
43
48
|
} = e.target;
|
|
@@ -46,27 +51,31 @@ class TagInputFoundation extends BaseFoundation {
|
|
|
46
51
|
onInputExceed,
|
|
47
52
|
separator
|
|
48
53
|
} = this.getProps();
|
|
54
|
+
if (!_isNumber(maxLength)) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
this._adapter.setEntering(false);
|
|
49
58
|
let allowChange = true;
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (inputArr[index].length > maxLength) {
|
|
58
|
-
allowChange = false;
|
|
59
|
-
_isFunction(onInputExceed) && onInputExceed(value);
|
|
60
|
-
break;
|
|
61
|
-
}
|
|
59
|
+
const inputArr = getSplitedArray(value, separator);
|
|
60
|
+
let index = 0;
|
|
61
|
+
for (; index < inputArr.length; index++) {
|
|
62
|
+
if (inputArr[index].length > maxLength) {
|
|
63
|
+
allowChange = false;
|
|
64
|
+
_isFunction(onInputExceed) && onInputExceed(value);
|
|
65
|
+
break;
|
|
62
66
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
this._adapter.setInputValue(newInputArr.join(separator));
|
|
67
|
+
}
|
|
68
|
+
if (!allowChange) {
|
|
69
|
+
const newInputArr = inputArr.slice(0, index);
|
|
70
|
+
if (index < inputArr.length) {
|
|
71
|
+
newInputArr.push(inputArr[index].slice(0, maxLength));
|
|
69
72
|
}
|
|
73
|
+
this._adapter.setInputValue(newInputArr.join(separator));
|
|
74
|
+
} else {
|
|
75
|
+
// Why does it need to be updated here instead of in onChange when the value meets the maxLength limit?
|
|
76
|
+
// Because in firefox, the state change in InputCompositionEnd causes onChange to not be triggered after
|
|
77
|
+
// the composition input completes input.
|
|
78
|
+
this._adapter.setInputValue(value);
|
|
70
79
|
}
|
|
71
80
|
};
|
|
72
81
|
/**
|
|
@@ -73,9 +73,14 @@ export interface UploadAdapter<P = Record<string, any>, S = Record<string, any>>
|
|
|
73
73
|
notifyPreviewClick: (file: any) => void;
|
|
74
74
|
notifyDrop: (e: any, files: Array<File>, fileList: Array<BaseFileItem>) => void;
|
|
75
75
|
notifyAcceptInvalid: (invalidFiles: Array<File>) => void;
|
|
76
|
+
registerPastingHandler: (cb?: (params?: any) => void) => void;
|
|
77
|
+
unRegisterPastingHandler: () => void;
|
|
78
|
+
isMac: () => boolean;
|
|
79
|
+
notifyPastingError: (error: Error | PermissionStatus) => void;
|
|
76
80
|
}
|
|
77
81
|
declare class UploadFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<UploadAdapter<P, S>, P, S> {
|
|
78
82
|
constructor(adapter: UploadAdapter<P, S>);
|
|
83
|
+
init(): void;
|
|
79
84
|
destroy(): void;
|
|
80
85
|
getError({ action, xhr, message, fileName }: {
|
|
81
86
|
action: string;
|
|
@@ -163,5 +168,9 @@ declare class UploadFoundation<P = Record<string, any>, S = Record<string, any>>
|
|
|
163
168
|
checkFileFormat(accept: string, file: File): boolean;
|
|
164
169
|
retry(fileItem: BaseFileItem): void;
|
|
165
170
|
handlePreviewClick(fileItem: BaseFileItem): void;
|
|
171
|
+
readFileFromClipboard(clipboardItems: any): void;
|
|
172
|
+
handlePasting(e: any): void;
|
|
173
|
+
bindPastingHandler(): void;
|
|
174
|
+
unbindPastingHandler(): void;
|
|
166
175
|
}
|
|
167
176
|
export default UploadFoundation;
|
|
@@ -44,8 +44,24 @@ class UploadFoundation extends BaseFoundation {
|
|
|
44
44
|
constructor(adapter) {
|
|
45
45
|
super(Object.assign({}, adapter));
|
|
46
46
|
}
|
|
47
|
+
init() {
|
|
48
|
+
const {
|
|
49
|
+
disabled,
|
|
50
|
+
addOnPasting
|
|
51
|
+
} = this.getProps();
|
|
52
|
+
if (addOnPasting && !disabled) {
|
|
53
|
+
this.bindPastingHandler();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
47
56
|
destroy() {
|
|
57
|
+
const {
|
|
58
|
+
disabled,
|
|
59
|
+
addOnPasting
|
|
60
|
+
} = this.getProps();
|
|
48
61
|
this.releaseMemory();
|
|
62
|
+
if (addOnPasting && !disabled) {
|
|
63
|
+
this.unbindPastingHandler();
|
|
64
|
+
}
|
|
49
65
|
}
|
|
50
66
|
getError(_ref) {
|
|
51
67
|
let {
|
|
@@ -905,5 +921,55 @@ class UploadFoundation extends BaseFoundation {
|
|
|
905
921
|
handlePreviewClick(fileItem) {
|
|
906
922
|
this._adapter.notifyPreviewClick(fileItem);
|
|
907
923
|
}
|
|
924
|
+
readFileFromClipboard(clipboardItems) {
|
|
925
|
+
for (const clipboardItem of clipboardItems) {
|
|
926
|
+
for (const type of clipboardItem.types) {
|
|
927
|
+
// types maybe: text/plain, image/png, text/html
|
|
928
|
+
if (type.startsWith('image')) {
|
|
929
|
+
clipboardItem.getType(type).then(blob => {
|
|
930
|
+
return blob.arrayBuffer();
|
|
931
|
+
}).then(buffer => {
|
|
932
|
+
const format = type.split('/')[1];
|
|
933
|
+
const file = new File([buffer], `upload.${format}`, {
|
|
934
|
+
type
|
|
935
|
+
});
|
|
936
|
+
this.handleChange([file]);
|
|
937
|
+
});
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
handlePasting(e) {
|
|
943
|
+
const isMac = this._adapter.isMac();
|
|
944
|
+
const isCombineKeydown = isMac ? e.metaKey : e.ctrlKey;
|
|
945
|
+
if (isCombineKeydown && e.code === 'KeyV' && e.target === document.body) {
|
|
946
|
+
// https://github.com/microsoft/TypeScript/issues/33923
|
|
947
|
+
const permissionName = "clipboard-read";
|
|
948
|
+
// The main thread should not be blocked by clipboard, so callback writing is required here. No await here
|
|
949
|
+
navigator.permissions.query({
|
|
950
|
+
name: permissionName
|
|
951
|
+
}).then(result => {
|
|
952
|
+
console.log(result);
|
|
953
|
+
if (result.state === 'granted' || result.state === 'prompt') {
|
|
954
|
+
// user has authorized or will authorize
|
|
955
|
+
navigator.clipboard.read().then(clipboardItems => {
|
|
956
|
+
// Process the data read from the pasteboard
|
|
957
|
+
// Check the returned data type to determine if it is image data, and process accordingly
|
|
958
|
+
this.readFileFromClipboard(clipboardItems);
|
|
959
|
+
});
|
|
960
|
+
} else {
|
|
961
|
+
this._adapter.notifyPastingError(result);
|
|
962
|
+
}
|
|
963
|
+
}).catch(error => {
|
|
964
|
+
this._adapter.notifyPastingError(error);
|
|
965
|
+
});
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
bindPastingHandler() {
|
|
969
|
+
this._adapter.registerPastingHandler(event => this.handlePasting(event));
|
|
970
|
+
}
|
|
971
|
+
unbindPastingHandler() {
|
|
972
|
+
this._adapter.unRegisterPastingHandler();
|
|
973
|
+
}
|
|
908
974
|
}
|
|
909
975
|
export default UploadFoundation;
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@douyinfe/semi-foundation",
|
|
3
|
-
"version": "2.43.0
|
|
3
|
+
"version": "2.43.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build:lib": "node ./scripts/compileLib.js",
|
|
7
7
|
"prepublishOnly": "npm run build:lib"
|
|
8
8
|
},
|
|
9
9
|
"dependencies": {
|
|
10
|
-
"@douyinfe/semi-animation": "2.43.0
|
|
10
|
+
"@douyinfe/semi-animation": "2.43.0",
|
|
11
11
|
"async-validator": "^3.5.0",
|
|
12
12
|
"classnames": "^2.2.6",
|
|
13
13
|
"date-fns": "^2.29.3",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"*.scss",
|
|
24
24
|
"*.css"
|
|
25
25
|
],
|
|
26
|
-
"gitHead": "
|
|
26
|
+
"gitHead": "aa918000b24c716c67439b47d1e7fdf5707d30ff",
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@babel/plugin-transform-runtime": "^7.15.8",
|
|
29
29
|
"@babel/preset-env": "^7.15.8",
|
package/tagInput/foundation.ts
CHANGED
|
@@ -66,36 +66,45 @@ class TagInputFoundation extends BaseFoundation<TagInputAdapter> {
|
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
handleInputCompositionStart = (e: any) => {
|
|
69
|
+
const { maxLength } = this.getProps();
|
|
70
|
+
if (!isNumber(maxLength)) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
69
73
|
this._adapter.setEntering(true);
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
handleInputCompositionEnd = (e: any) => {
|
|
73
|
-
this._adapter.setEntering(false);
|
|
74
77
|
const { value } = e.target;
|
|
75
78
|
const {
|
|
76
79
|
maxLength,
|
|
77
80
|
onInputExceed,
|
|
78
81
|
separator
|
|
79
82
|
} = this.getProps();
|
|
83
|
+
if (!isNumber(maxLength)) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
this._adapter.setEntering(false);
|
|
80
87
|
let allowChange = true;
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
isFunction(onInputExceed) && onInputExceed(value);
|
|
89
|
-
break;
|
|
90
|
-
}
|
|
88
|
+
const inputArr = getSplitedArray(value, separator);
|
|
89
|
+
let index = 0;
|
|
90
|
+
for (; index < inputArr.length; index++) {
|
|
91
|
+
if (inputArr[index].length > maxLength) {
|
|
92
|
+
allowChange = false;
|
|
93
|
+
isFunction(onInputExceed) && onInputExceed(value);
|
|
94
|
+
break;
|
|
91
95
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
this._adapter.setInputValue(newInputArr.join(separator));
|
|
96
|
+
}
|
|
97
|
+
if (!allowChange) {
|
|
98
|
+
const newInputArr = inputArr.slice(0, index);
|
|
99
|
+
if (index < inputArr.length) {
|
|
100
|
+
newInputArr.push(inputArr[index].slice(0, maxLength));
|
|
98
101
|
}
|
|
102
|
+
this._adapter.setInputValue(newInputArr.join(separator));
|
|
103
|
+
} else {
|
|
104
|
+
// Why does it need to be updated here instead of in onChange when the value meets the maxLength limit?
|
|
105
|
+
// Because in firefox, the state change in InputCompositionEnd causes onChange to not be triggered after
|
|
106
|
+
// the composition input completes input.
|
|
107
|
+
this._adapter.setInputValue(value);
|
|
99
108
|
}
|
|
100
109
|
}
|
|
101
110
|
|
package/tree/foundation.ts
CHANGED
|
@@ -156,7 +156,11 @@ export interface BasicRenderFullLabelProps {
|
|
|
156
156
|
expanded: boolean;
|
|
157
157
|
/* Is it unfolding */
|
|
158
158
|
loading: boolean
|
|
159
|
-
}
|
|
159
|
+
};
|
|
160
|
+
/* Whether the node meets the search conditions */
|
|
161
|
+
filtered: boolean | undefined;
|
|
162
|
+
/* Current search box input */
|
|
163
|
+
searchWord: string | undefined
|
|
160
164
|
}
|
|
161
165
|
|
|
162
166
|
export interface BasicSearchRenderProps {
|
package/upload/foundation.ts
CHANGED
|
@@ -84,7 +84,12 @@ export interface UploadAdapter<P = Record<string, any>, S = Record<string, any>>
|
|
|
84
84
|
notifyClear: () => void;
|
|
85
85
|
notifyPreviewClick: (file: any) => void;
|
|
86
86
|
notifyDrop: (e: any, files: Array<File>, fileList: Array<BaseFileItem>) => void;
|
|
87
|
-
notifyAcceptInvalid: (invalidFiles: Array<File>) => void
|
|
87
|
+
notifyAcceptInvalid: (invalidFiles: Array<File>) => void;
|
|
88
|
+
registerPastingHandler: (cb?: (params?: any) => void) => void;
|
|
89
|
+
unRegisterPastingHandler: () => void;
|
|
90
|
+
isMac: () => boolean;
|
|
91
|
+
notifyPastingError: (error: Error | PermissionStatus) => void
|
|
92
|
+
// notifyPasting: () => void;
|
|
88
93
|
}
|
|
89
94
|
|
|
90
95
|
class UploadFoundation<P = Record<string, any>, S = Record<string, any>> extends BaseFoundation<UploadAdapter<P, S>, P, S> {
|
|
@@ -92,8 +97,19 @@ class UploadFoundation<P = Record<string, any>, S = Record<string, any>> extends
|
|
|
92
97
|
super({ ...adapter });
|
|
93
98
|
}
|
|
94
99
|
|
|
100
|
+
init(): void {
|
|
101
|
+
const { disabled, addOnPasting } = this.getProps();
|
|
102
|
+
if (addOnPasting && !disabled) {
|
|
103
|
+
this.bindPastingHandler();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
95
107
|
destroy() {
|
|
108
|
+
const { disabled, addOnPasting } = this.getProps();
|
|
96
109
|
this.releaseMemory();
|
|
110
|
+
if (addOnPasting && !disabled) {
|
|
111
|
+
this.unbindPastingHandler();
|
|
112
|
+
}
|
|
97
113
|
}
|
|
98
114
|
|
|
99
115
|
getError({ action, xhr, message, fileName }: { action: string;xhr: XMLHttpRequest;message?: string;fileName: string }): XhrError {
|
|
@@ -847,6 +863,62 @@ class UploadFoundation<P = Record<string, any>, S = Record<string, any>> extends
|
|
|
847
863
|
handlePreviewClick(fileItem: BaseFileItem): void {
|
|
848
864
|
this._adapter.notifyPreviewClick(fileItem);
|
|
849
865
|
}
|
|
866
|
+
|
|
867
|
+
readFileFromClipboard(clipboardItems) {
|
|
868
|
+
for (const clipboardItem of clipboardItems) {
|
|
869
|
+
for (const type of clipboardItem.types) {
|
|
870
|
+
// types maybe: text/plain, image/png, text/html
|
|
871
|
+
if (type.startsWith('image')) {
|
|
872
|
+
clipboardItem.getType(type).then(blob => {
|
|
873
|
+
return blob.arrayBuffer();
|
|
874
|
+
}).then((buffer) => {
|
|
875
|
+
const format = type.split('/')[1];
|
|
876
|
+
const file = new File([buffer], `upload.${format}`, { type });
|
|
877
|
+
this.handleChange([file]);
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
handlePasting(e: any) {
|
|
885
|
+
const isMac = this._adapter.isMac();
|
|
886
|
+
const isCombineKeydown = isMac ? e.metaKey : e.ctrlKey;
|
|
887
|
+
|
|
888
|
+
if (isCombineKeydown && e.code === 'KeyV' && e.target === document.body) {
|
|
889
|
+
// https://github.com/microsoft/TypeScript/issues/33923
|
|
890
|
+
const permissionName = "clipboard-read" as PermissionName;
|
|
891
|
+
// The main thread should not be blocked by clipboard, so callback writing is required here. No await here
|
|
892
|
+
navigator.permissions
|
|
893
|
+
.query({ name: permissionName })
|
|
894
|
+
.then(result => {
|
|
895
|
+
console.log(result);
|
|
896
|
+
if (result.state === 'granted' || result.state === 'prompt') {
|
|
897
|
+
// user has authorized or will authorize
|
|
898
|
+
navigator.clipboard
|
|
899
|
+
.read()
|
|
900
|
+
.then(clipboardItems => {
|
|
901
|
+
// Process the data read from the pasteboard
|
|
902
|
+
// Check the returned data type to determine if it is image data, and process accordingly
|
|
903
|
+
this.readFileFromClipboard(clipboardItems);
|
|
904
|
+
});
|
|
905
|
+
} else {
|
|
906
|
+
this._adapter.notifyPastingError(result);
|
|
907
|
+
}
|
|
908
|
+
})
|
|
909
|
+
.catch(error => {
|
|
910
|
+
this._adapter.notifyPastingError(error);
|
|
911
|
+
});
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
bindPastingHandler(): void {
|
|
916
|
+
this._adapter.registerPastingHandler((event) => this.handlePasting(event));
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
unbindPastingHandler() {
|
|
920
|
+
this._adapter.unRegisterPastingHandler();
|
|
921
|
+
}
|
|
850
922
|
}
|
|
851
923
|
|
|
852
924
|
export default UploadFoundation;
|