@d-matrix/utils 1.8.0 → 1.9.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/dist/algorithm.js +7 -16
- package/dist/clipboard.js +45 -79
- package/dist/date.js +10 -19
- package/dist/dom.js +3 -8
- package/dist/file.d.ts +10 -0
- package/dist/file.js +40 -63
- package/dist/index.js +8 -30
- package/dist/react/enhancedComponent.js +7 -35
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +7 -18
- package/dist/react/renderToString.js +7 -15
- package/dist/react/useCopyToClipboard.js +14 -18
- package/dist/react/useDeepCompareRef.d.ts +2 -0
- package/dist/react/useDeepCompareRef.js +11 -0
- package/dist/react/useDisableContextMenu.js +8 -13
- package/dist/react/useIsMounted.js +6 -10
- package/dist/react/useStateCallback.js +6 -10
- package/dist/support.js +3 -9
- package/dist/timer.d.ts +5 -0
- package/dist/timer.js +5 -0
- package/dist/types.js +1 -2
- package/package.json +5 -1
- package/readme.md +24 -0
package/dist/algorithm.js
CHANGED
|
@@ -1,21 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
return to;
|
|
6
|
-
};
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.moveMulti = void 0;
|
|
9
|
-
var removeSymbol = Symbol('Placeholder for removed element');
|
|
10
|
-
var moveMulti = function (arr, indexes, start) {
|
|
11
|
-
var cloned = arr.slice();
|
|
12
|
-
for (var i = 0; i < cloned.length; i++) {
|
|
1
|
+
const removeSymbol = Symbol('Placeholder for removed element');
|
|
2
|
+
export const moveMulti = (arr, indexes, start) => {
|
|
3
|
+
const cloned = arr.slice();
|
|
4
|
+
for (let i = 0; i < cloned.length; i++) {
|
|
13
5
|
if (indexes.includes(i)) {
|
|
14
6
|
cloned[i] = removeSymbol;
|
|
15
7
|
}
|
|
16
8
|
}
|
|
17
|
-
|
|
18
|
-
cloned.splice
|
|
19
|
-
return cloned.filter(
|
|
9
|
+
const els = arr.filter((__, i) => indexes.includes(i));
|
|
10
|
+
cloned.splice(start, 0, ...els);
|
|
11
|
+
return cloned.filter((v) => v !== removeSymbol);
|
|
20
12
|
};
|
|
21
|
-
exports.moveMulti = moveMulti;
|
package/dist/clipboard.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
2
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
3
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -8,87 +7,54 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
8
|
});
|
|
10
9
|
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
10
|
+
export function writeImage(element) {
|
|
11
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
if (!element)
|
|
14
|
+
return reject('element is not defined');
|
|
15
|
+
const canvas = document.createElement('canvas');
|
|
16
|
+
const ctx = canvas.getContext('2d');
|
|
17
|
+
if (ctx === null) {
|
|
18
|
+
reject('canvas 2d context初始化失败');
|
|
19
|
+
return;
|
|
32
20
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
21
|
+
const img = new Image();
|
|
22
|
+
//浏览器在加载图像时要使用匿名身份验证,以允许跨域资源共享(CORS)。
|
|
23
|
+
img.crossOrigin = 'anonymous';
|
|
24
|
+
if (typeof element === 'string') {
|
|
25
|
+
img.src = element;
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
img.src = element.src;
|
|
29
|
+
}
|
|
30
|
+
img.onload = () => {
|
|
31
|
+
//创建一个画布,赋予画布宽高为图片的原始宽高
|
|
32
|
+
if (typeof element === 'string') {
|
|
33
|
+
canvas.width = img.width;
|
|
34
|
+
canvas.height = img.height;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
canvas.width = element.naturalWidth;
|
|
38
|
+
canvas.height = element.naturalHeight;
|
|
39
|
+
}
|
|
40
|
+
//防止有缓存,绘制之前先清除画布
|
|
41
|
+
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
|
42
|
+
ctx.drawImage(img, 0, 0);
|
|
43
|
+
//将canvas转为blob
|
|
44
|
+
canvas.toBlob((blob) => {
|
|
45
|
+
if (blob === null) {
|
|
46
|
+
reject('canvas to blob失败');
|
|
50
47
|
return;
|
|
51
48
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
img.onload = function () {
|
|
62
|
-
//创建一个画布,赋予画布宽高为图片的原始宽高
|
|
63
|
-
if (typeof element === 'string') {
|
|
64
|
-
canvas.width = img.width;
|
|
65
|
-
canvas.height = img.height;
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
canvas.width = element.naturalWidth;
|
|
69
|
-
canvas.height = element.naturalHeight;
|
|
70
|
-
}
|
|
71
|
-
//防止有缓存,绘制之前先清除画布
|
|
72
|
-
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
|
|
73
|
-
ctx.drawImage(img, 0, 0);
|
|
74
|
-
//将canvas转为blob
|
|
75
|
-
canvas.toBlob(function (blob) {
|
|
76
|
-
var _a;
|
|
77
|
-
if (blob === null) {
|
|
78
|
-
reject('canvas to blob失败');
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
navigator.clipboard
|
|
82
|
-
.write([
|
|
83
|
-
new ClipboardItem((_a = {},
|
|
84
|
-
_a[blob.type] = blob,
|
|
85
|
-
_a)),
|
|
86
|
-
])
|
|
87
|
-
.then(resolve, reject);
|
|
88
|
-
});
|
|
89
|
-
};
|
|
90
|
-
})];
|
|
49
|
+
navigator.clipboard
|
|
50
|
+
.write([
|
|
51
|
+
new ClipboardItem({
|
|
52
|
+
[blob.type]: blob,
|
|
53
|
+
}),
|
|
54
|
+
])
|
|
55
|
+
.then(resolve, reject);
|
|
56
|
+
});
|
|
57
|
+
};
|
|
91
58
|
});
|
|
92
59
|
});
|
|
93
60
|
}
|
|
94
|
-
exports.writeImage = writeImage;
|
package/dist/date.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getRecentYears = exports.rangeOfYears = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* Generates an array of numbers representing a range of years between the start year and the end year.
|
|
6
3
|
*
|
|
@@ -8,33 +5,27 @@ exports.getRecentYears = exports.rangeOfYears = void 0;
|
|
|
8
5
|
* @param {number} end - the ending year of the range (defaults to the current year)
|
|
9
6
|
* @return {number[]} an array of numbers representing the range of years
|
|
10
7
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
};
|
|
17
|
-
exports.rangeOfYears = rangeOfYears;
|
|
18
|
-
function getRecentYears(recentYears, type, suffix) {
|
|
19
|
-
if (suffix === void 0) { suffix = '年'; }
|
|
20
|
-
var thisYear = new Date().getFullYear();
|
|
8
|
+
export const rangeOfYears = (start, end = new Date().getFullYear()) => Array(end - start + 1)
|
|
9
|
+
.fill(start)
|
|
10
|
+
.map((year, index) => year + index);
|
|
11
|
+
export function getRecentYears(recentYears, type, suffix = '年') {
|
|
12
|
+
const thisYear = new Date().getFullYear();
|
|
21
13
|
if (type === 'number[]') {
|
|
22
|
-
|
|
23
|
-
for (
|
|
14
|
+
const result = [];
|
|
15
|
+
for (let i = 0; i < recentYears; i++) {
|
|
24
16
|
result.push(thisYear - i);
|
|
25
17
|
}
|
|
26
18
|
return result;
|
|
27
19
|
}
|
|
28
20
|
if (type === 'object[]') {
|
|
29
|
-
|
|
30
|
-
for (
|
|
21
|
+
const result = [];
|
|
22
|
+
for (let i = 0; i < recentYears; i++) {
|
|
31
23
|
result.push({
|
|
32
24
|
value: thisYear - i,
|
|
33
|
-
label:
|
|
25
|
+
label: `${thisYear - i}${suffix}`,
|
|
34
26
|
});
|
|
35
27
|
}
|
|
36
28
|
return result;
|
|
37
29
|
}
|
|
38
30
|
throw new Error('type must be "number[]" or "object[]"');
|
|
39
31
|
}
|
|
40
|
-
exports.getRecentYears = getRecentYears;
|
package/dist/dom.js
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.strip = exports.scrollToTop = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* 元素滚动条滚动到顶部
|
|
6
3
|
*/
|
|
7
|
-
function scrollToTop(element) {
|
|
4
|
+
export function scrollToTop(element) {
|
|
8
5
|
if (element) {
|
|
9
6
|
if (element.scrollTop === 0) {
|
|
10
7
|
return;
|
|
@@ -18,15 +15,13 @@ function scrollToTop(element) {
|
|
|
18
15
|
}
|
|
19
16
|
}
|
|
20
17
|
}
|
|
21
|
-
exports.scrollToTop = scrollToTop;
|
|
22
18
|
/**
|
|
23
19
|
* Strips HTML tags from a given string and returns the plain text content.
|
|
24
20
|
*
|
|
25
21
|
* @param {string} html - The HTML string to strip tags from.
|
|
26
22
|
* @return {string} The plain text content of the HTML string.
|
|
27
23
|
*/
|
|
28
|
-
function strip(html) {
|
|
29
|
-
|
|
24
|
+
export function strip(html) {
|
|
25
|
+
let doc = new DOMParser().parseFromString(html !== null && html !== void 0 ? html : '', 'text/html');
|
|
30
26
|
return doc.body.textContent || '';
|
|
31
27
|
}
|
|
32
|
-
exports.strip = strip;
|
package/dist/file.d.ts
CHANGED
|
@@ -36,4 +36,14 @@ export declare function isImageExists(src: string, img?: HTMLImageElement): Prom
|
|
|
36
36
|
export declare function getFilenameFromContentDispositionHeader(header: {
|
|
37
37
|
['content-disposition']: string;
|
|
38
38
|
}): string;
|
|
39
|
+
declare const HyperLinkTargets: readonly ["_self", "_black", "_parent", "_top"];
|
|
40
|
+
export declare type HyperLinkTarget = (typeof HyperLinkTargets)[number];
|
|
41
|
+
/**
|
|
42
|
+
* 文件下载
|
|
43
|
+
* @param source 文件地址或blob对象
|
|
44
|
+
* @param fileName 文件名
|
|
45
|
+
* @param isPreview 是否
|
|
46
|
+
*/
|
|
47
|
+
export declare function download(source: Blob, fileName?: string): void;
|
|
48
|
+
export declare function download(source: string, fileName?: string, target?: HyperLinkTarget): void;
|
|
39
49
|
export {};
|
package/dist/file.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
2
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
3
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -8,48 +7,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
8
|
});
|
|
10
9
|
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
13
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (_) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.getFilenameFromContentDispositionHeader = exports.isImageExists = exports.validateImageSize = exports.toImage = void 0;
|
|
40
10
|
/**
|
|
41
11
|
* 转换BlobPart或者文件地址为图片对象
|
|
42
12
|
* @param file 传入文件 或者 url
|
|
43
13
|
* @returns 返回 一个图片详情对象
|
|
44
14
|
*/
|
|
45
|
-
|
|
46
|
-
return new Promise(
|
|
47
|
-
|
|
15
|
+
export const toImage = (file, options) => {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const image = new Image();
|
|
48
18
|
if (typeof file === 'string') {
|
|
49
19
|
image.src = file;
|
|
50
20
|
}
|
|
51
21
|
else {
|
|
52
|
-
|
|
22
|
+
const blob = URL.createObjectURL(new Blob([file], options));
|
|
53
23
|
image.src = blob;
|
|
54
24
|
}
|
|
55
25
|
// 如果有缓存,读缓存
|
|
@@ -68,57 +38,64 @@ var toImage = function (file, options) {
|
|
|
68
38
|
}
|
|
69
39
|
});
|
|
70
40
|
};
|
|
71
|
-
exports.toImage = toImage;
|
|
72
41
|
/**
|
|
73
42
|
* 图片宽,高校验
|
|
74
43
|
* @param file 传入文件 或者 url
|
|
75
44
|
* @param limitSize 限制宽度, 高度
|
|
76
45
|
* @returns isOK: 是否超出宽高; width, height: 图片的宽高
|
|
77
46
|
*/
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return
|
|
81
|
-
|
|
82
|
-
case 0: return [4 /*yield*/, exports.toImage(file, options)];
|
|
83
|
-
case 1:
|
|
84
|
-
image = _a.sent();
|
|
85
|
-
return [2 /*return*/, { isOk: image.width <= limitSize.width && image.height <= limitSize.height, width: image.width, height: image.height }];
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
}); };
|
|
89
|
-
exports.validateImageSize = validateImageSize;
|
|
47
|
+
export const validateImageSize = (file, limitSize, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
48
|
+
const image = yield toImage(file, options);
|
|
49
|
+
return { isOk: image.width <= limitSize.width && image.height <= limitSize.height, width: image.width, height: image.height };
|
|
50
|
+
});
|
|
90
51
|
/**
|
|
91
52
|
* 检测图片地址是否可用
|
|
92
53
|
* @param src 图片地址
|
|
93
54
|
* @param img HTMLImageElement
|
|
94
55
|
* @returns Promise<boolean>
|
|
95
56
|
*/
|
|
96
|
-
function isImageExists(src, img) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
img.onload = function () { return resolve(true); };
|
|
105
|
-
img.onerror = function () { return resolve(false); };
|
|
106
|
-
})];
|
|
57
|
+
export function isImageExists(src, img = new Image()) {
|
|
58
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
if (!src)
|
|
60
|
+
return false;
|
|
61
|
+
return new Promise((resolve) => {
|
|
62
|
+
img.src = src;
|
|
63
|
+
img.onload = () => resolve(true);
|
|
64
|
+
img.onerror = () => resolve(false);
|
|
107
65
|
});
|
|
108
66
|
});
|
|
109
67
|
}
|
|
110
|
-
exports.isImageExists = isImageExists;
|
|
111
68
|
/**
|
|
112
69
|
* 从Content-Disposition中获取文件名
|
|
113
70
|
* @param header 包含Content-Disposition, 值为'attachment;filename=%E5%A4%A7%E8%A1%8C%E6%8C%87%E5%AF%BC2024-06-27-2024-06-28.xlsx'
|
|
114
71
|
* @returns string
|
|
115
72
|
*
|
|
116
73
|
*/
|
|
117
|
-
function getFilenameFromContentDispositionHeader(header) {
|
|
118
|
-
|
|
74
|
+
export function getFilenameFromContentDispositionHeader(header) {
|
|
75
|
+
const contentDisposition = header['content-disposition'];
|
|
119
76
|
if (!contentDisposition)
|
|
120
77
|
return '';
|
|
121
|
-
|
|
78
|
+
const filename = contentDisposition.split('filename=')[1].split(';')[0];
|
|
122
79
|
return decodeURIComponent(filename);
|
|
123
80
|
}
|
|
124
|
-
|
|
81
|
+
const HyperLinkTargets = ['_self', '_black', '_parent', '_top'];
|
|
82
|
+
export function download(source, fileName = '', target) {
|
|
83
|
+
const link = document.createElement('a');
|
|
84
|
+
if (typeof source === 'string') {
|
|
85
|
+
if (typeof target === 'string' && HyperLinkTargets.includes(target)) {
|
|
86
|
+
link.target = target;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
link.download = fileName;
|
|
90
|
+
}
|
|
91
|
+
link.href = source;
|
|
92
|
+
}
|
|
93
|
+
if (source instanceof Blob) {
|
|
94
|
+
const url = window.URL.createObjectURL(source);
|
|
95
|
+
link.href = url;
|
|
96
|
+
link.download = fileName;
|
|
97
|
+
}
|
|
98
|
+
document.body.appendChild(link);
|
|
99
|
+
link.click();
|
|
100
|
+
document.body.removeChild(link);
|
|
101
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,30 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
-
if (mod && mod.__esModule) return mod;
|
|
16
|
-
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
-
__setModuleDefault(result, mod);
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.support = exports.file = exports.algorithm = exports.types = exports.date = exports.dom = exports.react = exports.clipboard = void 0;
|
|
23
|
-
exports.clipboard = __importStar(require("./clipboard"));
|
|
24
|
-
exports.react = __importStar(require("./react"));
|
|
25
|
-
exports.dom = __importStar(require("./dom"));
|
|
26
|
-
exports.date = __importStar(require("./date"));
|
|
27
|
-
exports.types = __importStar(require("./types"));
|
|
28
|
-
exports.algorithm = __importStar(require("./algorithm"));
|
|
29
|
-
exports.file = __importStar(require("./file"));
|
|
30
|
-
exports.support = __importStar(require("./support"));
|
|
1
|
+
export * as clipboard from './clipboard';
|
|
2
|
+
export * as react from './react';
|
|
3
|
+
export * as dom from './dom';
|
|
4
|
+
export * as date from './date';
|
|
5
|
+
export * as types from './types';
|
|
6
|
+
export * as algorithm from './algorithm';
|
|
7
|
+
export * as file from './file';
|
|
8
|
+
export * as support from './support';
|
|
@@ -1,44 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
var __extends = (this && this.__extends) || (function () {
|
|
3
|
-
var extendStatics = function (d, b) {
|
|
4
|
-
extendStatics = Object.setPrototypeOf ||
|
|
5
|
-
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
|
6
|
-
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
|
7
|
-
return extendStatics(d, b);
|
|
8
|
-
};
|
|
9
|
-
return function (d, b) {
|
|
10
|
-
if (typeof b !== "function" && b !== null)
|
|
11
|
-
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
|
12
|
-
extendStatics(d, b);
|
|
13
|
-
function __() { this.constructor = d; }
|
|
14
|
-
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
|
-
};
|
|
16
|
-
})();
|
|
17
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
18
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
19
|
-
};
|
|
20
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
-
exports.EnhancedComponent = void 0;
|
|
22
|
-
var react_1 = __importDefault(require("react"));
|
|
1
|
+
import React from 'react';
|
|
23
2
|
/**
|
|
24
3
|
* react component 的增强类
|
|
25
4
|
*/
|
|
26
|
-
|
|
27
|
-
__extends(EnhancedComponent, _super);
|
|
28
|
-
function EnhancedComponent() {
|
|
29
|
-
return _super !== null && _super.apply(this, arguments) || this;
|
|
30
|
-
}
|
|
5
|
+
export class EnhancedComponent extends React.Component {
|
|
31
6
|
/**
|
|
32
7
|
* setState 方法的同步版本
|
|
33
8
|
* @param state
|
|
34
9
|
* @returns Promise
|
|
35
10
|
*/
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
_this.setState(state, resolve);
|
|
11
|
+
setStateAsync(state) {
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
this.setState(state, resolve);
|
|
40
14
|
});
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
}(react_1.default.Component));
|
|
44
|
-
exports.EnhancedComponent = EnhancedComponent;
|
|
15
|
+
}
|
|
16
|
+
}
|
package/dist/react/index.d.ts
CHANGED
package/dist/react/index.js
CHANGED
|
@@ -1,18 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}));
|
|
9
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
10
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
11
|
-
};
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
__exportStar(require("./useDisableContextMenu"), exports);
|
|
14
|
-
__exportStar(require("./useStateCallback"), exports);
|
|
15
|
-
__exportStar(require("./renderToString"), exports);
|
|
16
|
-
__exportStar(require("./useIsMounted"), exports);
|
|
17
|
-
__exportStar(require("./useCopyToClipboard"), exports);
|
|
18
|
-
__exportStar(require("./enhancedComponent"), exports);
|
|
1
|
+
export * from './useDisableContextMenu';
|
|
2
|
+
export * from './useStateCallback';
|
|
3
|
+
export * from './renderToString';
|
|
4
|
+
export * from './useIsMounted';
|
|
5
|
+
export * from './useCopyToClipboard';
|
|
6
|
+
export * from './enhancedComponent';
|
|
7
|
+
export * from './useDeepCompareRef';
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.cleanup = exports.render = void 0;
|
|
7
|
-
var react_dom_1 = __importDefault(require("react-dom"));
|
|
8
|
-
var container;
|
|
9
|
-
var render = function (element) {
|
|
10
|
-
return new Promise(function (resolve, reject) {
|
|
1
|
+
import ReactDOM from 'react-dom';
|
|
2
|
+
let container;
|
|
3
|
+
export const render = (element) => {
|
|
4
|
+
return new Promise((resolve, reject) => {
|
|
11
5
|
if (document === undefined) {
|
|
12
6
|
return reject('只支持浏览器环境');
|
|
13
7
|
}
|
|
@@ -15,7 +9,7 @@ var render = function (element) {
|
|
|
15
9
|
container.id = 'template-container';
|
|
16
10
|
container.style.cssText = 'position: absolute; left: -9999px;';
|
|
17
11
|
document.body.appendChild(container);
|
|
18
|
-
|
|
12
|
+
ReactDOM.render(element, container, () => {
|
|
19
13
|
if (container) {
|
|
20
14
|
resolve(container.innerHTML);
|
|
21
15
|
}
|
|
@@ -25,14 +19,12 @@ var render = function (element) {
|
|
|
25
19
|
});
|
|
26
20
|
});
|
|
27
21
|
};
|
|
28
|
-
|
|
29
|
-
var cleanup = function () {
|
|
22
|
+
export const cleanup = () => {
|
|
30
23
|
if (container === null)
|
|
31
24
|
return;
|
|
32
|
-
|
|
25
|
+
const isUnmounted = ReactDOM.unmountComponentAtNode(container);
|
|
33
26
|
if (isUnmounted) {
|
|
34
27
|
document.body.removeChild(container);
|
|
35
28
|
container = null;
|
|
36
29
|
}
|
|
37
30
|
};
|
|
38
|
-
exports.cleanup = cleanup;
|
|
@@ -1,32 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
var isMounted = useIsMounted_1.useIsMounted();
|
|
9
|
-
var _c = react_1.useState(false), isCopied = _c[0], setIsCopied = _c[1];
|
|
10
|
-
var copyToClipboard = react_1.useCallback(function (value) {
|
|
1
|
+
import { useCallback, useState } from 'react';
|
|
2
|
+
import { useIsMounted } from './useIsMounted';
|
|
3
|
+
export function useCopyToClipboard(props) {
|
|
4
|
+
const { timeout = 2000, onCopy, onError } = props !== null && props !== void 0 ? props : {};
|
|
5
|
+
const isMounted = useIsMounted();
|
|
6
|
+
const [isCopied, setIsCopied] = useState(false);
|
|
7
|
+
const copyToClipboard = useCallback((value) => {
|
|
11
8
|
var _a;
|
|
12
9
|
if (!isMounted())
|
|
13
10
|
return;
|
|
14
11
|
if (typeof window === 'undefined' || !((_a = navigator.clipboard) === null || _a === void 0 ? void 0 : _a.writeText)) {
|
|
15
|
-
|
|
12
|
+
const error = new Error(`Cannot copy to clipboard, navigator.clipboard.writeText is not defined`);
|
|
16
13
|
if (process.env.NODE_ENV === 'development')
|
|
17
14
|
console.error(error);
|
|
18
15
|
onError === null || onError === void 0 ? void 0 : onError(error);
|
|
19
16
|
return;
|
|
20
17
|
}
|
|
21
18
|
if (typeof value !== 'string') {
|
|
22
|
-
|
|
19
|
+
const error = new Error(`Cannot copy typeof ${typeof value} to clipboard, must be a string`);
|
|
23
20
|
if (process.env.NODE_ENV === 'development')
|
|
24
21
|
console.error(error);
|
|
25
22
|
onError === null || onError === void 0 ? void 0 : onError(error);
|
|
26
23
|
return;
|
|
27
24
|
}
|
|
28
25
|
if (value === '') {
|
|
29
|
-
|
|
26
|
+
const error = new Error(`Cannot copy empty string to clipboard.`);
|
|
30
27
|
if (process.env.NODE_ENV === 'development')
|
|
31
28
|
console.error(error);
|
|
32
29
|
onError === null || onError === void 0 ? void 0 : onError(error);
|
|
@@ -34,15 +31,14 @@ function useCopyToClipboard(props) {
|
|
|
34
31
|
}
|
|
35
32
|
navigator.clipboard
|
|
36
33
|
.writeText(value)
|
|
37
|
-
.then(
|
|
34
|
+
.then(() => {
|
|
38
35
|
setIsCopied(true);
|
|
39
36
|
onCopy === null || onCopy === void 0 ? void 0 : onCopy(value);
|
|
40
|
-
setTimeout(
|
|
37
|
+
setTimeout(() => {
|
|
41
38
|
setIsCopied(false);
|
|
42
39
|
}, timeout);
|
|
43
40
|
})
|
|
44
|
-
.catch(
|
|
41
|
+
.catch((error) => onError === null || onError === void 0 ? void 0 : onError(error));
|
|
45
42
|
}, [onCopy, onError, timeout]);
|
|
46
|
-
return { isCopied
|
|
43
|
+
return { isCopied, copyToClipboard };
|
|
47
44
|
}
|
|
48
|
-
exports.useCopyToClipboard = useCopyToClipboard;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { useRef } from 'react';
|
|
2
|
+
import isEqual from 'react-fast-compare';
|
|
3
|
+
export const useDeepCompareRef = (deps) => {
|
|
4
|
+
const ref = useRef();
|
|
5
|
+
const signalRef = useRef(0);
|
|
6
|
+
if (deps === undefined || !isEqual(deps, ref.current)) {
|
|
7
|
+
ref.current = deps;
|
|
8
|
+
signalRef.current += 1;
|
|
9
|
+
}
|
|
10
|
+
return signalRef;
|
|
11
|
+
};
|
|
@@ -1,29 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.useDisableContextMenu = void 0;
|
|
4
|
-
var react_1 = require("react");
|
|
5
|
-
var defaultContextMenuTarget = function () { return document; };
|
|
1
|
+
import { useEffect, useRef } from "react";
|
|
2
|
+
const defaultContextMenuTarget = () => document;
|
|
6
3
|
/**
|
|
7
4
|
* 在HTML元素上禁用右键菜单
|
|
8
5
|
* @param target 默认为 () => document
|
|
9
6
|
*/
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
var targetFn = react_1.useRef(target);
|
|
7
|
+
export const useDisableContextMenu = (target = defaultContextMenuTarget) => {
|
|
8
|
+
const targetFn = useRef(target);
|
|
13
9
|
targetFn.current = target;
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const el = targetFn.current();
|
|
16
12
|
if (!el)
|
|
17
13
|
return;
|
|
18
|
-
|
|
14
|
+
const onContextMenu = (e) => {
|
|
19
15
|
e.preventDefault();
|
|
20
16
|
};
|
|
21
17
|
el.addEventListener('contextmenu', onContextMenu);
|
|
22
|
-
return
|
|
18
|
+
return () => {
|
|
23
19
|
if (!el)
|
|
24
20
|
return;
|
|
25
21
|
el.removeEventListener('contextmenu', onContextMenu);
|
|
26
22
|
};
|
|
27
23
|
}, []);
|
|
28
24
|
};
|
|
29
|
-
exports.useDisableContextMenu = useDisableContextMenu;
|
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useIsMounted = void 0;
|
|
4
|
-
var react_1 = require("react");
|
|
1
|
+
import { useCallback, useEffect, useRef } from 'react';
|
|
5
2
|
/** 用于判断组件是否挂载 */
|
|
6
|
-
function useIsMounted() {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
export function useIsMounted() {
|
|
4
|
+
const mountedRef = useRef(false);
|
|
5
|
+
const get = useCallback(() => mountedRef.current, []);
|
|
6
|
+
useEffect(() => {
|
|
10
7
|
mountedRef.current = true;
|
|
11
|
-
return
|
|
8
|
+
return () => {
|
|
12
9
|
mountedRef.current = false;
|
|
13
10
|
};
|
|
14
11
|
}, []);
|
|
15
12
|
return get;
|
|
16
13
|
}
|
|
17
|
-
exports.useIsMounted = useIsMounted;
|
|
@@ -1,16 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.useStateCallback = void 0;
|
|
4
|
-
var react_1 = require("react");
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
5
2
|
/** 等价与类组件 setState(updater[, callback]) */
|
|
6
|
-
function useStateCallback(initialState) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
export function useStateCallback(initialState) {
|
|
4
|
+
const [state, setState] = useState(initialState);
|
|
5
|
+
const cbRef = useRef(undefined);
|
|
6
|
+
const setStateCallback = useCallback((state, cb) => {
|
|
10
7
|
cbRef.current = cb;
|
|
11
8
|
setState(state);
|
|
12
9
|
}, []);
|
|
13
|
-
|
|
10
|
+
useEffect(() => {
|
|
14
11
|
if (cbRef.current) {
|
|
15
12
|
cbRef.current(state);
|
|
16
13
|
cbRef.current = undefined;
|
|
@@ -18,4 +15,3 @@ function useStateCallback(initialState) {
|
|
|
18
15
|
}, [state]);
|
|
19
16
|
return [state, setStateCallback];
|
|
20
17
|
}
|
|
21
|
-
exports.useStateCallback = useStateCallback;
|
package/dist/support.js
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isSharedWorker = exports.isWebSocket = exports.isBrowserEnv = void 0;
|
|
4
1
|
/**
|
|
5
2
|
* 是否是浏览器环境
|
|
6
3
|
*/
|
|
7
|
-
|
|
8
|
-
exports.isBrowserEnv = isBrowserEnv;
|
|
4
|
+
export const isBrowserEnv = () => typeof window !== 'undefined';
|
|
9
5
|
/**
|
|
10
6
|
* 是否支持WebSocket
|
|
11
7
|
*/
|
|
12
|
-
|
|
13
|
-
exports.isWebSocket = isWebSocket;
|
|
8
|
+
export const isWebSocket = () => typeof WebSocket !== 'undefined';
|
|
14
9
|
/**
|
|
15
10
|
* 是否支持SharedWorker
|
|
16
11
|
*/
|
|
17
|
-
|
|
18
|
-
exports.isSharedWorker = isSharedWorker;
|
|
12
|
+
export const isSharedWorker = () => typeof SharedWorker !== 'undefined';
|
package/dist/timer.d.ts
ADDED
package/dist/timer.js
ADDED
package/dist/types.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@d-matrix/utils",
|
|
3
|
-
"
|
|
3
|
+
"sideEffects": false,
|
|
4
|
+
"version": "1.9.0",
|
|
4
5
|
"description": "A dozen of utils for Front-End Development",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
7
|
"scripts": {
|
|
@@ -48,5 +49,8 @@
|
|
|
48
49
|
"expect-type": "^0.19.0",
|
|
49
50
|
"rimraf": "^5.0.5",
|
|
50
51
|
"vite": "^4.5.2"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"react-fast-compare": "^3.2.2"
|
|
51
55
|
}
|
|
52
56
|
}
|
package/readme.md
CHANGED
|
@@ -15,6 +15,7 @@ A dozen of utils for Front-End Development
|
|
|
15
15
|
- [algorithm](#algorithm)
|
|
16
16
|
- [file](#file)
|
|
17
17
|
- [support](#support)
|
|
18
|
+
- [timer](#timer)
|
|
18
19
|
|
|
19
20
|
### clipboard
|
|
20
21
|
|
|
@@ -115,6 +116,10 @@ import { react } from '@d-matrix/utils';
|
|
|
115
116
|
}
|
|
116
117
|
```
|
|
117
118
|
|
|
119
|
+
- `useDeepCompareRef(deps: DependencyList): React.MutableRefObject<number>`
|
|
120
|
+
|
|
121
|
+
深比较`deps`。返回`ref`,`ref.current`是一个自增数字,每次`deps`变化,`ref.current`加`1`。用法见[测试](./tests/react.cy.tsx)
|
|
122
|
+
|
|
118
123
|
### dom
|
|
119
124
|
|
|
120
125
|
- `scrollToTop(element: Element | null | undefined): void`
|
|
@@ -230,6 +235,14 @@ const filename = file.getFilenameFromContentDispositionHeader(header);
|
|
|
230
235
|
// '大行指导2024-06-27-2024-06-28.xlsx'
|
|
231
236
|
```
|
|
232
237
|
|
|
238
|
+
- `download(source: string | Blob, fileName = '', target?: HyperLinkTarget): void`
|
|
239
|
+
|
|
240
|
+
文件下载,`source`是文件地址或`blob`对象。
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
type HyperLinkTarget = "_self" | "_black" | "_parent" | "_top"
|
|
244
|
+
```
|
|
245
|
+
|
|
233
246
|
## support
|
|
234
247
|
|
|
235
248
|
- `isBrowserEnv(): boolean`
|
|
@@ -244,6 +257,17 @@ const filename = file.getFilenameFromContentDispositionHeader(header);
|
|
|
244
257
|
|
|
245
258
|
是否支持SharedWorker
|
|
246
259
|
|
|
260
|
+
## timer
|
|
261
|
+
|
|
262
|
+
- `sleep(ms?: number): Promise<unknown>`
|
|
263
|
+
|
|
264
|
+
使用`setTimeout`与`Promise`实现,暂停执行`ms`毫秒
|
|
265
|
+
|
|
266
|
+
```
|
|
267
|
+
await sleep(3000); // 暂停3秒
|
|
268
|
+
console.log('continue'); // 继续执行
|
|
269
|
+
```
|
|
270
|
+
|
|
247
271
|
## 测试
|
|
248
272
|
|
|
249
273
|
运行全部组件测试
|