@d-matrix/utils 1.5.0 → 1.6.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.
@@ -0,0 +1,5 @@
1
+ export * from './useDisableContextMenu';
2
+ export * from './useStateCallback';
3
+ export * from './renderToString';
4
+ export * from './useIsMounted';
5
+ export * from './useCopyToClipboard';
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
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);
@@ -0,0 +1,3 @@
1
+ import { ReactElement } from 'react';
2
+ export declare const render: <P>(element: ReactElement<P, string | import("react").JSXElementConstructor<any>>) => Promise<string>;
3
+ export declare const cleanup: () => void;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
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) {
11
+ if (document === undefined) {
12
+ return reject('只支持浏览器环境');
13
+ }
14
+ container = document.createElement('div');
15
+ container.id = 'template-container';
16
+ container.style.cssText = 'position: absolute; left: -9999px;';
17
+ document.body.appendChild(container);
18
+ react_dom_1.default.render(element, container, function () {
19
+ if (container) {
20
+ resolve(container.innerHTML);
21
+ }
22
+ else {
23
+ reject('组件容器不存在');
24
+ }
25
+ });
26
+ });
27
+ };
28
+ exports.render = render;
29
+ var cleanup = function () {
30
+ if (container === null)
31
+ return;
32
+ var isUnmounted = react_dom_1.default.unmountComponentAtNode(container);
33
+ if (isUnmounted) {
34
+ document.body.removeChild(container);
35
+ container = null;
36
+ }
37
+ };
38
+ exports.cleanup = cleanup;
@@ -0,0 +1,21 @@
1
+ export interface UseCopyToClipboardProps {
2
+ /**
3
+ * 重置复制成功状态延迟
4
+ */
5
+ timeout?: number;
6
+ /**
7
+ * @param copiedText 复制的文本
8
+ * @returns
9
+ */
10
+ onCopy?: (copiedText: string) => void | undefined;
11
+ /**
12
+ *
13
+ * @param error 复制错误对象
14
+ * @returns
15
+ */
16
+ onError?: (error: Error) => void | undefined;
17
+ }
18
+ export declare function useCopyToClipboard(props?: UseCopyToClipboardProps): {
19
+ isCopied: Boolean;
20
+ copyToClipboard: (value: string) => void;
21
+ };
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useCopyToClipboard = void 0;
4
+ var react_1 = require("react");
5
+ var useIsMounted_1 = require("./useIsMounted");
6
+ function useCopyToClipboard(props) {
7
+ var _a = props !== null && props !== void 0 ? props : {}, _b = _a.timeout, timeout = _b === void 0 ? 2000 : _b, onCopy = _a.onCopy, onError = _a.onError;
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) {
11
+ var _a;
12
+ if (!isMounted())
13
+ return;
14
+ if (typeof window === 'undefined' || !((_a = navigator.clipboard) === null || _a === void 0 ? void 0 : _a.writeText)) {
15
+ var error = new Error("Cannot copy to clipboard, navigator.clipboard.writeText is not defined");
16
+ if (process.env.NODE_ENV === 'development')
17
+ console.error(error);
18
+ onError === null || onError === void 0 ? void 0 : onError(error);
19
+ return;
20
+ }
21
+ if (typeof value !== 'string') {
22
+ var error = new Error("Cannot copy typeof " + typeof value + " to clipboard, must be a string");
23
+ if (process.env.NODE_ENV === 'development')
24
+ console.error(error);
25
+ onError === null || onError === void 0 ? void 0 : onError(error);
26
+ return;
27
+ }
28
+ if (value === '') {
29
+ var error = new Error("Cannot copy empty string to clipboard.");
30
+ if (process.env.NODE_ENV === 'development')
31
+ console.error(error);
32
+ onError === null || onError === void 0 ? void 0 : onError(error);
33
+ return;
34
+ }
35
+ navigator.clipboard
36
+ .writeText(value)
37
+ .then(function () {
38
+ setIsCopied(true);
39
+ onCopy === null || onCopy === void 0 ? void 0 : onCopy(value);
40
+ setTimeout(function () {
41
+ setIsCopied(false);
42
+ }, timeout);
43
+ })
44
+ .catch(function (error) { return onError === null || onError === void 0 ? void 0 : onError(error); });
45
+ }, [onCopy, onError, timeout]);
46
+ return { isCopied: isCopied, copyToClipboard: copyToClipboard };
47
+ }
48
+ exports.useCopyToClipboard = useCopyToClipboard;
@@ -0,0 +1,7 @@
1
+ declare type ContextMenuTarget = () => Element | Document | undefined | null;
2
+ /**
3
+ * 在HTML元素上禁用右键菜单
4
+ * @param target 默认为 () => document
5
+ */
6
+ export declare const useDisableContextMenu: (target?: ContextMenuTarget) => void;
7
+ export {};
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useDisableContextMenu = void 0;
4
+ var react_1 = require("react");
5
+ var defaultContextMenuTarget = function () { return document; };
6
+ /**
7
+ * 在HTML元素上禁用右键菜单
8
+ * @param target 默认为 () => document
9
+ */
10
+ var useDisableContextMenu = function (target) {
11
+ if (target === void 0) { target = defaultContextMenuTarget; }
12
+ var targetFn = react_1.useRef(target);
13
+ targetFn.current = target;
14
+ react_1.useEffect(function () {
15
+ var el = targetFn.current();
16
+ if (!el)
17
+ return;
18
+ var onContextMenu = function (e) {
19
+ e.preventDefault();
20
+ };
21
+ el.addEventListener('contextmenu', onContextMenu);
22
+ return function () {
23
+ if (!el)
24
+ return;
25
+ el.removeEventListener('contextmenu', onContextMenu);
26
+ };
27
+ }, []);
28
+ };
29
+ exports.useDisableContextMenu = useDisableContextMenu;
@@ -0,0 +1,2 @@
1
+ /** 用于判断组件是否挂载 */
2
+ export declare function useIsMounted(): () => boolean;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useIsMounted = void 0;
4
+ var react_1 = require("react");
5
+ /** 用于判断组件是否挂载 */
6
+ function useIsMounted() {
7
+ var mountedRef = react_1.useRef(false);
8
+ var get = react_1.useCallback(function () { return mountedRef.current; }, []);
9
+ react_1.useEffect(function () {
10
+ mountedRef.current = true;
11
+ return function () {
12
+ mountedRef.current = false;
13
+ };
14
+ }, []);
15
+ return get;
16
+ }
17
+ exports.useIsMounted = useIsMounted;
@@ -0,0 +1,2 @@
1
+ /** 等价与类组件 setState(updater[, callback]) */
2
+ export declare function useStateCallback<T>(initialState: T): [T, (state: T, cb?: (state: T) => void) => void];
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useStateCallback = void 0;
4
+ var react_1 = require("react");
5
+ /** 等价与类组件 setState(updater[, callback]) */
6
+ function useStateCallback(initialState) {
7
+ var _a = react_1.useState(initialState), state = _a[0], setState = _a[1];
8
+ var cbRef = react_1.useRef(undefined);
9
+ var setStateCallback = react_1.useCallback(function (state, cb) {
10
+ cbRef.current = cb;
11
+ setState(state);
12
+ }, []);
13
+ react_1.useEffect(function () {
14
+ if (cbRef.current) {
15
+ cbRef.current(state);
16
+ cbRef.current = undefined;
17
+ }
18
+ }, [state]);
19
+ return [state, setStateCallback];
20
+ }
21
+ exports.useStateCallback = useStateCallback;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@d-matrix/utils",
3
- "version": "1.5.0",
3
+ "version": "1.6.1",
4
4
  "description": "A dozen of utils for Front-End Development",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -8,7 +8,8 @@
8
8
  "prebuild": "npm run clean",
9
9
  "clean": "rimraf dist",
10
10
  "cy:open": "cypress open",
11
- "cy:run": "cypress run",
11
+ "cy:component": "cypress run --component --spec",
12
+ "cy:component:all": "cypress run --component",
12
13
  "test:tsd": "tsd",
13
14
  "postversion": "git push && git push --tags"
14
15
  },
package/readme.md CHANGED
@@ -66,10 +66,28 @@ const TestComp = () => {
66
66
 
67
67
  返回值`setState()`函数类似类组件中的`setState(updater[, callback])`,可以在`callback`中获取更新后的`state`
68
68
 
69
- - `useMountedRef(): React.MutableRefObject<boolean>`
69
+ - `useIsMounted(): () => boolean`
70
70
 
71
71
  获取当前组件是否已挂载的 Hook
72
72
 
73
+ ```ts
74
+ const Test = () => {
75
+ const isMounted = useIsMounted();
76
+
77
+ useEffect(() => {
78
+ if (isMounted()) {
79
+ console.log('component mounted')
80
+ }
81
+ }, [isMounted]);
82
+
83
+ return null
84
+ };
85
+ ```
86
+
87
+ - `useCopyToClipboard(props?: UseCopyToClipboardProps)`
88
+
89
+ 复制文本到剪切板, 用法见[测试](./tests/react.cy.tsx)
90
+
73
91
  ### dom
74
92
 
75
93
  - `scrollToTop(element: Element | null | undefined): void`
package/dist/react.d.ts DELETED
@@ -1,14 +0,0 @@
1
- import { ReactElement } from 'react';
2
- export declare const render: <P>(element: ReactElement<P, string | import("react").JSXElementConstructor<any>>) => Promise<string>;
3
- export declare const cleanup: () => void;
4
- declare type ContextMenuTarget = () => Element | Document | undefined | null;
5
- /**
6
- * 在HTML元素上禁用右键菜单
7
- * @param target 默认为 () => document
8
- */
9
- export declare const useDisableContextMenu: (target?: ContextMenuTarget) => void;
10
- /** 等价与类组件 setState(updater[, callback]) */
11
- export declare function useStateCallback<T>(initialState: T): [T, (state: T, cb?: (state: T) => void) => void];
12
- /** 用于判断组件是否挂载 */
13
- export declare function useMountedRef(): React.MutableRefObject<boolean>;
14
- export {};
package/dist/react.js DELETED
@@ -1,93 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.useMountedRef = exports.useStateCallback = exports.useDisableContextMenu = exports.cleanup = exports.render = void 0;
7
- var react_1 = require("react");
8
- var react_dom_1 = __importDefault(require("react-dom"));
9
- var container;
10
- var render = function (element) {
11
- return new Promise(function (resolve, reject) {
12
- if (document === undefined) {
13
- return reject('只支持浏览器环境');
14
- }
15
- container = document.createElement('div');
16
- container.id = 'template-container';
17
- container.style.cssText = 'position: absolute; left: -9999px;';
18
- document.body.appendChild(container);
19
- react_dom_1.default.render(element, container, function () {
20
- if (container) {
21
- resolve(container.innerHTML);
22
- }
23
- else {
24
- reject('组件容器不存在');
25
- }
26
- });
27
- });
28
- };
29
- exports.render = render;
30
- var cleanup = function () {
31
- if (container === null)
32
- return;
33
- var isUnmounted = react_dom_1.default.unmountComponentAtNode(container);
34
- if (isUnmounted) {
35
- document.body.removeChild(container);
36
- container = null;
37
- }
38
- };
39
- exports.cleanup = cleanup;
40
- var defaultContextMenuTarget = function () { return document; };
41
- /**
42
- * 在HTML元素上禁用右键菜单
43
- * @param target 默认为 () => document
44
- */
45
- var useDisableContextMenu = function (target) {
46
- if (target === void 0) { target = defaultContextMenuTarget; }
47
- var targetFn = react_1.useRef(target);
48
- targetFn.current = target;
49
- react_1.useEffect(function () {
50
- var el = targetFn.current();
51
- if (!el)
52
- return;
53
- var onContextMenu = function (e) {
54
- e.preventDefault();
55
- };
56
- el.addEventListener('contextmenu', onContextMenu);
57
- return function () {
58
- if (!el)
59
- return;
60
- el.removeEventListener('contextmenu', onContextMenu);
61
- };
62
- }, []);
63
- };
64
- exports.useDisableContextMenu = useDisableContextMenu;
65
- /** 等价与类组件 setState(updater[, callback]) */
66
- function useStateCallback(initialState) {
67
- var _a = react_1.useState(initialState), state = _a[0], setState = _a[1];
68
- var cbRef = react_1.useRef(undefined);
69
- var setStateCallback = react_1.useCallback(function (state, cb) {
70
- cbRef.current = cb;
71
- setState(state);
72
- }, []);
73
- react_1.useEffect(function () {
74
- if (cbRef.current) {
75
- cbRef.current(state);
76
- cbRef.current = undefined;
77
- }
78
- }, [state]);
79
- return [state, setStateCallback];
80
- }
81
- exports.useStateCallback = useStateCallback;
82
- /** 用于判断组件是否挂载 */
83
- function useMountedRef() {
84
- var mountedRef = react_1.useRef(false);
85
- react_1.useEffect(function () {
86
- mountedRef.current = true;
87
- return function () {
88
- mountedRef.current = false;
89
- };
90
- }, []);
91
- return mountedRef;
92
- }
93
- exports.useMountedRef = useMountedRef;