@arcblock/react-hooks 3.4.15 → 3.5.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/package.json +5 -2
- package/build.config.ts +0 -25
- package/src/index.ts +0 -8
- package/src/useBrowser.js +0 -63
- package/src/useInterval.js +0 -22
- package/src/useLineClamp.ts +0 -156
- package/src/useStorage.js +0 -39
- package/vite.config.mjs +0 -25
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcblock/react-hooks",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0",
|
|
4
4
|
"description": "React hooks used by arcblock products",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -33,6 +33,9 @@
|
|
|
33
33
|
"event-target-shim": "^5.0.1",
|
|
34
34
|
"ismobilejs": "^1.1.1"
|
|
35
35
|
},
|
|
36
|
+
"files": [
|
|
37
|
+
"lib"
|
|
38
|
+
],
|
|
36
39
|
"publishConfig": {
|
|
37
40
|
"access": "public"
|
|
38
41
|
},
|
|
@@ -40,5 +43,5 @@
|
|
|
40
43
|
"eslint-plugin-react-hooks": "^4.6.2",
|
|
41
44
|
"jest": "^29.7.0"
|
|
42
45
|
},
|
|
43
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "1cfc816004525cf1b352ec2b64d459f4769f0237"
|
|
44
47
|
}
|
package/build.config.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/* eslint-disable import/no-unresolved */
|
|
2
|
-
import { defineBuildConfig, BuildEntry } from 'unbuild';
|
|
3
|
-
|
|
4
|
-
const pattern = ['**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx', '**/*.png', '!**/*.stories.js', '!**/demo', '**/*.svg'];
|
|
5
|
-
|
|
6
|
-
const shared: BuildEntry = {
|
|
7
|
-
builder: 'mkdist',
|
|
8
|
-
input: './src',
|
|
9
|
-
pattern,
|
|
10
|
-
ext: 'js',
|
|
11
|
-
esbuild: {
|
|
12
|
-
jsx: 'automatic',
|
|
13
|
-
},
|
|
14
|
-
declaration: true,
|
|
15
|
-
};
|
|
16
|
-
export default defineBuildConfig({
|
|
17
|
-
failOnWarn: false,
|
|
18
|
-
entries: [
|
|
19
|
-
{
|
|
20
|
-
...shared,
|
|
21
|
-
outDir: './lib',
|
|
22
|
-
format: 'esm',
|
|
23
|
-
},
|
|
24
|
-
],
|
|
25
|
-
});
|
package/src/index.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
// @ts-expect-error
|
|
2
|
-
export { default as useInterval } from './useInterval';
|
|
3
|
-
// @ts-expect-error
|
|
4
|
-
export { default as useStorage } from './useStorage';
|
|
5
|
-
// @ts-expect-error
|
|
6
|
-
export { default as useBrowser } from './useBrowser';
|
|
7
|
-
|
|
8
|
-
export { default as useLineClamp } from './useLineClamp';
|
package/src/useBrowser.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
2
|
-
import isMobile from 'ismobilejs';
|
|
3
|
-
|
|
4
|
-
const DID_WALLET_TAG = 'ABTWallet';
|
|
5
|
-
const ARC_SPHERE_TAG = 'ArcSphere';
|
|
6
|
-
|
|
7
|
-
function getUaVersion(userAgent, tag) {
|
|
8
|
-
const reg = new RegExp(`${tag}/(?<version>[0-9.]+)`, 'g');
|
|
9
|
-
const result = reg.exec(userAgent);
|
|
10
|
-
const version = result?.groups?.version;
|
|
11
|
-
return version;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export default function useBrowser() {
|
|
15
|
-
const userAgent = window?.navigator?.userAgent;
|
|
16
|
-
const [browser] = useState({
|
|
17
|
-
// FIXME: @zhanghan 待应用中相关代码兼容 arcSphere 的判断后,才能移除 arcSphere 的判断
|
|
18
|
-
// https://github.com/search?q=org%3AArcBlock%20browser.wallet&type=code
|
|
19
|
-
// https://github.com/search?q=org%3Ablocklet+browser.wallet&type=code
|
|
20
|
-
wallet: userAgent.indexOf(DID_WALLET_TAG) > -1 || userAgent.indexOf(ARC_SPHERE_TAG) > -1,
|
|
21
|
-
walletVersion: getUaVersion(userAgent, DID_WALLET_TAG),
|
|
22
|
-
arcSphere: userAgent.indexOf(ARC_SPHERE_TAG) > -1,
|
|
23
|
-
arcSphereVersion: getUaVersion(userAgent, ARC_SPHERE_TAG),
|
|
24
|
-
wechat: /MicroMessenger/i.test(userAgent),
|
|
25
|
-
mobile: {
|
|
26
|
-
apple: {
|
|
27
|
-
phone: false,
|
|
28
|
-
ipod: false,
|
|
29
|
-
tablet: false,
|
|
30
|
-
device: false,
|
|
31
|
-
},
|
|
32
|
-
amazon: {
|
|
33
|
-
phone: false,
|
|
34
|
-
tablet: false,
|
|
35
|
-
device: false,
|
|
36
|
-
},
|
|
37
|
-
android: {
|
|
38
|
-
phone: false,
|
|
39
|
-
tablet: false,
|
|
40
|
-
device: false,
|
|
41
|
-
},
|
|
42
|
-
windows: {
|
|
43
|
-
phone: false,
|
|
44
|
-
tablet: false,
|
|
45
|
-
device: false,
|
|
46
|
-
},
|
|
47
|
-
other: {
|
|
48
|
-
blackberry: false,
|
|
49
|
-
blackberry10: false,
|
|
50
|
-
opera: false,
|
|
51
|
-
firefox: false,
|
|
52
|
-
chrome: false,
|
|
53
|
-
device: false,
|
|
54
|
-
},
|
|
55
|
-
phone: false,
|
|
56
|
-
tablet: false,
|
|
57
|
-
any: false,
|
|
58
|
-
...isMobile(userAgent),
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
return browser;
|
|
63
|
-
}
|
package/src/useInterval.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/* eslint-disable consistent-return */
|
|
2
|
-
import { useEffect, useRef } from 'react';
|
|
3
|
-
|
|
4
|
-
export default function useInterval(callback, delay) {
|
|
5
|
-
const savedCallback = useRef();
|
|
6
|
-
|
|
7
|
-
// Remember the latest callback.
|
|
8
|
-
useEffect(() => {
|
|
9
|
-
savedCallback.current = callback;
|
|
10
|
-
}, [callback]);
|
|
11
|
-
|
|
12
|
-
// Set up the interval.
|
|
13
|
-
useEffect(() => {
|
|
14
|
-
function tick() {
|
|
15
|
-
savedCallback.current();
|
|
16
|
-
}
|
|
17
|
-
if (delay !== null) {
|
|
18
|
-
const id = setInterval(tick, delay);
|
|
19
|
-
return () => clearInterval(id);
|
|
20
|
-
}
|
|
21
|
-
}, [delay]);
|
|
22
|
-
}
|
package/src/useLineClamp.ts
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
// fork from https://github.com/drenther/use-clamp-text
|
|
2
|
-
|
|
3
|
-
/* eslint-disable no-shadow */
|
|
4
|
-
/* eslint-disable import/prefer-default-export */
|
|
5
|
-
import { useDebounceFn, useMemoizedFn, useMount, useReactive, useUpdateEffect } from 'ahooks';
|
|
6
|
-
import { useRef } from 'react';
|
|
7
|
-
|
|
8
|
-
const defaultEllipsis = '…';
|
|
9
|
-
|
|
10
|
-
let keyCount = 0;
|
|
11
|
-
const getNewKey = () => `__clamp_text_key__${keyCount++}`;
|
|
12
|
-
|
|
13
|
-
export default function useLineClamp({
|
|
14
|
-
text,
|
|
15
|
-
ellipsis = defaultEllipsis,
|
|
16
|
-
lines = 3,
|
|
17
|
-
expanded = false,
|
|
18
|
-
debounceTime = 300,
|
|
19
|
-
charWidth = 1.2,
|
|
20
|
-
offset = 1,
|
|
21
|
-
}: {
|
|
22
|
-
text: string;
|
|
23
|
-
ellipsis?: string;
|
|
24
|
-
lines?: number;
|
|
25
|
-
expanded?: boolean;
|
|
26
|
-
debounceTime?: number;
|
|
27
|
-
charWidth?: number;
|
|
28
|
-
offset?: number;
|
|
29
|
-
}) {
|
|
30
|
-
const currentState = useReactive({
|
|
31
|
-
needClamp: true,
|
|
32
|
-
noClamp: false,
|
|
33
|
-
clampedText: '…',
|
|
34
|
-
key: getNewKey(),
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
const textRef = useRef<HTMLElement | null>(undefined);
|
|
38
|
-
const buttonRef = useRef<HTMLElement | null>(undefined);
|
|
39
|
-
const lineHeightRef = useRef(0);
|
|
40
|
-
|
|
41
|
-
const clampLines = useMemoizedFn(({ lineHeight, originalText, expanded, ellipsis, lines }) => {
|
|
42
|
-
if (!textRef.current) {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
const node = textRef.current;
|
|
46
|
-
const button = buttonRef.current;
|
|
47
|
-
if (!originalText || expanded) {
|
|
48
|
-
currentState.noClamp = true;
|
|
49
|
-
currentState.clampedText = originalText;
|
|
50
|
-
currentState.key = getNewKey();
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const maxHeight = lineHeight * lines + 1;
|
|
55
|
-
|
|
56
|
-
let start = 0;
|
|
57
|
-
let middle = 0;
|
|
58
|
-
let end = originalText.length;
|
|
59
|
-
|
|
60
|
-
if (!node.clientHeight) {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
function moveMarkers() {
|
|
65
|
-
const clientHeight = node?.getBoundingClientRect().height ?? 1;
|
|
66
|
-
if (clientHeight <= maxHeight) {
|
|
67
|
-
start = middle + 1;
|
|
68
|
-
} else {
|
|
69
|
-
end = middle - 1;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
while (start <= end) {
|
|
74
|
-
middle = Math.floor((start + end) / 2);
|
|
75
|
-
node.innerText = originalText.slice(0, middle) + ellipsis;
|
|
76
|
-
if (button) {
|
|
77
|
-
node.appendChild(button.cloneNode(true));
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (middle === originalText.length) {
|
|
81
|
-
currentState.needClamp = false;
|
|
82
|
-
currentState.noClamp = true;
|
|
83
|
-
currentState.clampedText = originalText;
|
|
84
|
-
currentState.key = getNewKey();
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
moveMarkers();
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const clampedText =
|
|
91
|
-
originalText.slice(0, Math.max(middle - offset, 0)).trim() + (typeof ellipsis === 'string' ? ellipsis : '');
|
|
92
|
-
|
|
93
|
-
node.innerText = clampedText;
|
|
94
|
-
if (button) node.appendChild(button.cloneNode(true));
|
|
95
|
-
|
|
96
|
-
currentState.needClamp = true;
|
|
97
|
-
currentState.noClamp = false;
|
|
98
|
-
currentState.clampedText = clampedText;
|
|
99
|
-
currentState.key = getNewKey();
|
|
100
|
-
});
|
|
101
|
-
const { run: debouncedClampLines } = useDebounceFn(clampLines, {
|
|
102
|
-
wait: debounceTime,
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
const resizeListener = useMemoizedFn(() => {
|
|
106
|
-
debouncedClampLines({
|
|
107
|
-
lineHeight: lineHeightRef.current,
|
|
108
|
-
originalText: text,
|
|
109
|
-
expanded,
|
|
110
|
-
ellipsis,
|
|
111
|
-
lines,
|
|
112
|
-
charWidth,
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
useMount(() => {
|
|
117
|
-
if (text && !lineHeightRef.current) {
|
|
118
|
-
const lineHeight = (textRef.current?.clientHeight ?? 1) + 1;
|
|
119
|
-
lineHeightRef.current = lineHeight;
|
|
120
|
-
setTimeout(() => {
|
|
121
|
-
clampLines({
|
|
122
|
-
lineHeight,
|
|
123
|
-
originalText: text,
|
|
124
|
-
expanded,
|
|
125
|
-
ellipsis,
|
|
126
|
-
lines,
|
|
127
|
-
charWidth,
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
window.addEventListener('resize', resizeListener);
|
|
132
|
-
return () => {
|
|
133
|
-
window.removeEventListener('resize', resizeListener);
|
|
134
|
-
};
|
|
135
|
-
});
|
|
136
|
-
useUpdateEffect(() => {
|
|
137
|
-
clampLines({
|
|
138
|
-
lineHeight: lineHeightRef.current,
|
|
139
|
-
originalText: text,
|
|
140
|
-
expanded,
|
|
141
|
-
ellipsis,
|
|
142
|
-
lines,
|
|
143
|
-
charWidth,
|
|
144
|
-
});
|
|
145
|
-
}, [expanded, text, charWidth, ellipsis, lines]);
|
|
146
|
-
|
|
147
|
-
return {
|
|
148
|
-
textRef,
|
|
149
|
-
buttonRef,
|
|
150
|
-
needClamp: currentState.needClamp,
|
|
151
|
-
noClamp: currentState.noClamp,
|
|
152
|
-
clampedText: currentState.clampedText,
|
|
153
|
-
key: currentState.key,
|
|
154
|
-
run: resizeListener,
|
|
155
|
-
};
|
|
156
|
-
}
|
package/src/useStorage.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/* eslint-disable react-hooks/rules-of-hooks */
|
|
2
|
-
import { useState, useEffect } from 'react';
|
|
3
|
-
import { EventTarget } from 'event-target-shim';
|
|
4
|
-
|
|
5
|
-
const evtTarget = new EventTarget();
|
|
6
|
-
export default function useStorage(storage, keyPrefix) {
|
|
7
|
-
return (key, defaultValue) => {
|
|
8
|
-
const storeKey = `${keyPrefix}.${key}`;
|
|
9
|
-
const raw = storage.getItem(storeKey);
|
|
10
|
-
const [value, setValue] = useState(raw ? JSON.parse(raw) : defaultValue);
|
|
11
|
-
|
|
12
|
-
const updater = (updatedValue) => {
|
|
13
|
-
setValue(updatedValue);
|
|
14
|
-
storage.setItem(storeKey, JSON.stringify(updatedValue));
|
|
15
|
-
evtTarget.dispatchEvent(new CustomEvent('storage_change', { detail: { key } }));
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
if (defaultValue != null && !raw) {
|
|
19
|
-
updater(defaultValue);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
useEffect(() => {
|
|
23
|
-
const listener = ({ detail }) => {
|
|
24
|
-
if (detail.key === key) {
|
|
25
|
-
const _raw = storage.getItem(storeKey);
|
|
26
|
-
|
|
27
|
-
if (_raw !== raw) {
|
|
28
|
-
setValue(JSON.parse(_raw));
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
evtTarget.addEventListener('storage_change', listener);
|
|
34
|
-
return () => evtTarget.removeEventListener('storage_change', listener);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
return [value, updater];
|
|
38
|
-
};
|
|
39
|
-
}
|
package/vite.config.mjs
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vite';
|
|
2
|
-
import react from '@vitejs/plugin-react';
|
|
3
|
-
import noBundlePlugin from 'vite-plugin-no-bundle';
|
|
4
|
-
import fg from 'fast-glob';
|
|
5
|
-
|
|
6
|
-
export default defineConfig({
|
|
7
|
-
plugins: [
|
|
8
|
-
react({ jsxRuntime: 'automatic' }),
|
|
9
|
-
noBundlePlugin({
|
|
10
|
-
root: 'src',
|
|
11
|
-
copy: ['**/*.png', '**/*.gif', '**/*.jpg', '**/*.jpeg', '**/*.d.ts'],
|
|
12
|
-
}),
|
|
13
|
-
],
|
|
14
|
-
build: {
|
|
15
|
-
lib: {
|
|
16
|
-
entry: fg.sync('src/**/*.{tsx,ts,jsx,js}', {
|
|
17
|
-
ignore: ['**/stories/**', '**/demo/**', '**/*.d.ts', '**/*.stories.*'],
|
|
18
|
-
}),
|
|
19
|
-
formats: ['es'],
|
|
20
|
-
fileName: (format, entryName) => `${entryName}.js`,
|
|
21
|
-
},
|
|
22
|
-
outDir: 'lib',
|
|
23
|
-
emptyOutDir: true,
|
|
24
|
-
},
|
|
25
|
-
});
|