tona-hooks 1.0.20 → 1.0.22
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/README.md +158 -4
- package/README.zh-CN.md +169 -0
- package/dist/index.d.ts +12 -3
- package/dist/index.js +64 -26
- package/package.json +20 -20
package/README.md
CHANGED
|
@@ -1,15 +1,169 @@
|
|
|
1
1
|
# tona-hooks
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="../../assets/tona.png" alt="Tona" width="100" />
|
|
5
|
+
</p>
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
React hooks collection for CNBlogs theme development.
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/tona-hooks"><img src="https://img.shields.io/npm/v/tona-hooks?style=flat-square" alt="npm version"></a>
|
|
13
|
+
<a href="LICENSE"><img src="https://img.shields.io/npm/l/tona-hooks?style=flat-square" alt="license"></a>
|
|
14
|
+
<a href="https://preactjs.com"><img src="https://img.shields.io/badge/Preact->=10.0.0-673AB8?style=flat-square&logo=preact" alt="Preact"></a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
**English** | [中文](./README.zh-CN.md)
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
- **Preact Compatible** - Built for Preact, works with React
|
|
22
|
+
- **CNBlogs Optimized** - Hooks designed specifically for CNBlogs environment
|
|
23
|
+
- **TypeScript Support** - Full type definitions included
|
|
24
|
+
- **Lightweight** - Tree-shakeable and minimal footprint
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
6
27
|
|
|
7
28
|
```bash
|
|
8
29
|
npm install tona-hooks
|
|
9
30
|
```
|
|
10
31
|
|
|
11
|
-
|
|
32
|
+
```bash
|
|
33
|
+
pnpm add tona-hooks
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
yarn add tona-hooks
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { useQueryDOM, useLocalStorage, useScroll } from 'tona-hooks'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Available Hooks
|
|
47
|
+
|
|
48
|
+
### `useAjaxComplete`
|
|
49
|
+
|
|
50
|
+
Listen for AJAX requests completion.
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { useAjaxComplete } from 'tona-hooks'
|
|
54
|
+
|
|
55
|
+
useAjaxComplete((event, xhr, settings) => {
|
|
56
|
+
console.log('AJAX completed:', settings.url)
|
|
57
|
+
})
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### `useEffectOnce`
|
|
61
|
+
|
|
62
|
+
Run effect only once on mount.
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { useEffectOnce } from 'tona-hooks'
|
|
66
|
+
|
|
67
|
+
useEffectOnce(() => {
|
|
68
|
+
console.log('Component mounted')
|
|
69
|
+
})
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### `useEventCallback`
|
|
73
|
+
|
|
74
|
+
Create a stable callback reference.
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { useEventCallback } from 'tona-hooks'
|
|
78
|
+
|
|
79
|
+
const handleClick = useEventCallback(() => {
|
|
80
|
+
console.log('Clicked!')
|
|
81
|
+
})
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### `useIsomorphicLayoutEffect`
|
|
85
|
+
|
|
86
|
+
Safe layout effect for SSR and browser.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { useIsomorphicLayoutEffect } from 'tona-hooks'
|
|
90
|
+
|
|
91
|
+
useIsomorphicLayoutEffect(() => {
|
|
92
|
+
// DOM measurements
|
|
93
|
+
}, [])
|
|
94
|
+
```
|
|
12
95
|
|
|
13
|
-
|
|
96
|
+
### `useLocalStorage`
|
|
97
|
+
|
|
98
|
+
Persist state to localStorage.
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { useLocalStorage } from 'tona-hooks'
|
|
102
|
+
|
|
103
|
+
const [value, setValue] = useLocalStorage('key', 'defaultValue')
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### `useQueryDOM`
|
|
107
|
+
|
|
108
|
+
Query and observe DOM elements.
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
14
111
|
import { useQueryDOM } from 'tona-hooks'
|
|
112
|
+
|
|
113
|
+
const element = useQueryDOM('#my-element')
|
|
15
114
|
```
|
|
115
|
+
|
|
116
|
+
### `useRafState`
|
|
117
|
+
|
|
118
|
+
State updates synced with requestAnimationFrame.
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { useRafState } from 'tona-hooks'
|
|
122
|
+
|
|
123
|
+
const [position, setPosition] = useRafState({ x: 0, y: 0 })
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### `useScroll`
|
|
127
|
+
|
|
128
|
+
Track scroll position of an element.
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
import { useScroll } from 'tona-hooks'
|
|
132
|
+
|
|
133
|
+
const [x, y] = useScroll(ref)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### `useUnmount`
|
|
137
|
+
|
|
138
|
+
Run cleanup on component unmount.
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import { useUnmount } from 'tona-hooks'
|
|
142
|
+
|
|
143
|
+
useUnmount(() => {
|
|
144
|
+
console.log('Component unmounted')
|
|
145
|
+
})
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### `useWindowScroll`
|
|
149
|
+
|
|
150
|
+
Track window scroll position.
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
import { useWindowScroll } from 'tona-hooks'
|
|
154
|
+
|
|
155
|
+
const [x, y] = useWindowScroll()
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Peer Dependencies
|
|
159
|
+
|
|
160
|
+
```json
|
|
161
|
+
{
|
|
162
|
+
"preact": ">=10.0.0"
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Related
|
|
167
|
+
|
|
168
|
+
- [tona](https://github.com/guangzan/tona/tree/main/packages/core) - Core framework
|
|
169
|
+
- [tona-ui](https://github.com/guangzan/tona/tree/main/packages/ui) - UI components
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# tona-hooks
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="../../assets/tona.png" alt="Tona" width="100" />
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
用于博客园主题开发的 React Hooks 集合。
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/tona-hooks"><img src="https://img.shields.io/npm/v/tona-hooks?style=flat-square" alt="npm version"></a>
|
|
13
|
+
<a href="LICENSE"><img src="https://img.shields.io/npm/l/tona-hooks?style=flat-square" alt="license"></a>
|
|
14
|
+
<a href="https://preactjs.com"><img src="https://img.shields.io/badge/Preact->=10.0.0-673AB8?style=flat-square&logo=preact" alt="Preact"></a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
[English](./README.md) | **中文**
|
|
18
|
+
|
|
19
|
+
## 特性
|
|
20
|
+
|
|
21
|
+
- **Preact 兼容** - 为 Preact 构建,兼容 React
|
|
22
|
+
- **博客园优化** - 专为博客园环境设计的 Hooks
|
|
23
|
+
- **TypeScript 支持** - 包含完整的类型定义
|
|
24
|
+
- **轻量级** - 可摇树优化,占用空间小
|
|
25
|
+
|
|
26
|
+
## 安装
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install tona-hooks
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm add tona-hooks
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
yarn add tona-hooks
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 使用
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { useQueryDOM, useLocalStorage, useScroll } from 'tona-hooks'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## 可用的 Hooks
|
|
47
|
+
|
|
48
|
+
### `useAjaxComplete`
|
|
49
|
+
|
|
50
|
+
监听 AJAX 请求完成。
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { useAjaxComplete } from 'tona-hooks'
|
|
54
|
+
|
|
55
|
+
useAjaxComplete((event, xhr, settings) => {
|
|
56
|
+
console.log('AJAX completed:', settings.url)
|
|
57
|
+
})
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### `useEffectOnce`
|
|
61
|
+
|
|
62
|
+
仅在挂载时运行一次 effect。
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { useEffectOnce } from 'tona-hooks'
|
|
66
|
+
|
|
67
|
+
useEffectOnce(() => {
|
|
68
|
+
console.log('Component mounted')
|
|
69
|
+
})
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### `useEventCallback`
|
|
73
|
+
|
|
74
|
+
创建稳定的回调引用。
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { useEventCallback } from 'tona-hooks'
|
|
78
|
+
|
|
79
|
+
const handleClick = useEventCallback(() => {
|
|
80
|
+
console.log('Clicked!')
|
|
81
|
+
})
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### `useIsomorphicLayoutEffect`
|
|
85
|
+
|
|
86
|
+
适用于 SSR 和浏览器的安全 layout effect。
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { useIsomorphicLayoutEffect } from 'tona-hooks'
|
|
90
|
+
|
|
91
|
+
useIsomorphicLayoutEffect(() => {
|
|
92
|
+
// DOM 测量
|
|
93
|
+
}, [])
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### `useLocalStorage`
|
|
97
|
+
|
|
98
|
+
将状态持久化到 localStorage。
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
import { useLocalStorage } from 'tona-hooks'
|
|
102
|
+
|
|
103
|
+
const [value, setValue] = useLocalStorage('key', 'defaultValue')
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### `useQueryDOM`
|
|
107
|
+
|
|
108
|
+
查询和观察 DOM 元素。
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { useQueryDOM } from 'tona-hooks'
|
|
112
|
+
|
|
113
|
+
const element = useQueryDOM('#my-element')
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### `useRafState`
|
|
117
|
+
|
|
118
|
+
与 requestAnimationFrame 同步的状态更新。
|
|
119
|
+
|
|
120
|
+
```typescript
|
|
121
|
+
import { useRafState } from 'tona-hooks'
|
|
122
|
+
|
|
123
|
+
const [position, setPosition] = useRafState({ x: 0, y: 0 })
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### `useScroll`
|
|
127
|
+
|
|
128
|
+
跟踪元素的滚动位置。
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
import { useScroll } from 'tona-hooks'
|
|
132
|
+
|
|
133
|
+
const [x, y] = useScroll(ref)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### `useUnmount`
|
|
137
|
+
|
|
138
|
+
在组件卸载时运行清理。
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import { useUnmount } from 'tona-hooks'
|
|
142
|
+
|
|
143
|
+
useUnmount(() => {
|
|
144
|
+
console.log('Component unmounted')
|
|
145
|
+
})
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### `useWindowScroll`
|
|
149
|
+
|
|
150
|
+
跟踪窗口滚动位置。
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
import { useWindowScroll } from 'tona-hooks'
|
|
154
|
+
|
|
155
|
+
const [x, y] = useWindowScroll()
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## 对等依赖
|
|
159
|
+
|
|
160
|
+
```json
|
|
161
|
+
{
|
|
162
|
+
"preact": ">=10.0.0"
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## 相关
|
|
167
|
+
|
|
168
|
+
- [tona](https://github.com/guangzan/tona/tree/main/packages/core) - 核心框架
|
|
169
|
+
- [tona-ui](https://github.com/guangzan/tona/tree/main/packages/ui) - UI 组件
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Dispatch, EffectCallback, useEffect } from "preact/hooks";
|
|
2
|
-
import { SetStateAction } from "preact/compat";
|
|
2
|
+
import { Dispatch as Dispatch$1, SetStateAction } from "preact/compat";
|
|
3
3
|
import { RefObject } from "preact";
|
|
4
4
|
|
|
5
5
|
//#region src/use-ajax-complete.d.ts
|
|
6
|
-
|
|
7
6
|
/**
|
|
8
7
|
* 通用的 Ajax 完成监听 Hook
|
|
9
8
|
* @param config 配置对象
|
|
@@ -27,6 +26,16 @@ declare function useEventCallback<Args extends unknown[], R>(fn: ((...args: Args
|
|
|
27
26
|
//#region src/use-isomorphic-layout-effect.d.ts
|
|
28
27
|
declare const useIsomorphicLayoutEffect: typeof useEffect;
|
|
29
28
|
//#endregion
|
|
29
|
+
//#region src/use-local-storage.d.ts
|
|
30
|
+
type parserOptions<T> = {
|
|
31
|
+
raw: true;
|
|
32
|
+
} | {
|
|
33
|
+
raw: false;
|
|
34
|
+
serializer: (value: T) => string;
|
|
35
|
+
deserializer: (value: string) => T;
|
|
36
|
+
};
|
|
37
|
+
declare const useLocalStorage: <T>(key: string, initialValue?: T, options?: parserOptions<T>) => [T | undefined, Dispatch$1<SetStateAction<T | undefined>>, () => void];
|
|
38
|
+
//#endregion
|
|
30
39
|
//#region src/use-query-dom.d.ts
|
|
31
40
|
interface UseQueryDomOptions<T> {
|
|
32
41
|
selector: string;
|
|
@@ -68,4 +77,4 @@ interface State {
|
|
|
68
77
|
}
|
|
69
78
|
declare const useWindowScroll: () => State;
|
|
70
79
|
//#endregion
|
|
71
|
-
export { useAjaxComplete, useEffectOnce, useEventCallback, useIsomorphicLayoutEffect, useQueryDOM, useRafState, useScroll, useUnmount, useWindowScroll };
|
|
80
|
+
export { useAjaxComplete, useEffectOnce, useEventCallback, useIsomorphicLayoutEffect, useLocalStorage, useQueryDOM, useRafState, useScroll, useUnmount, useWindowScroll };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "preact/hooks";
|
|
2
|
-
import { useCallback as useCallback$1, useRef as useRef$1 } from "preact/compat";
|
|
3
|
-
|
|
2
|
+
import { useCallback as useCallback$1, useLayoutEffect as useLayoutEffect$1, useRef as useRef$1, useState as useState$1 } from "preact/compat";
|
|
4
3
|
//#region src/use-ajax-complete.ts
|
|
5
4
|
/**
|
|
6
5
|
* 通用的 Ajax 完成监听 Hook
|
|
@@ -27,17 +26,14 @@ function useAjaxComplete(config) {
|
|
|
27
26
|
};
|
|
28
27
|
}, [config]);
|
|
29
28
|
}
|
|
30
|
-
|
|
31
29
|
//#endregion
|
|
32
30
|
//#region src/use-effect-once.ts
|
|
33
31
|
const useEffectOnce = (effect) => {
|
|
34
32
|
useEffect(effect, []);
|
|
35
33
|
};
|
|
36
|
-
|
|
37
34
|
//#endregion
|
|
38
35
|
//#region src/use-isomorphic-layout-effect.ts
|
|
39
36
|
const useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
|
|
40
|
-
|
|
41
37
|
//#endregion
|
|
42
38
|
//#region src/use-event-callback.ts
|
|
43
39
|
function useEventCallback(fn) {
|
|
@@ -49,7 +45,65 @@ function useEventCallback(fn) {
|
|
|
49
45
|
}, [fn]);
|
|
50
46
|
return useCallback$1((...args) => ref.current?.(...args), [ref]);
|
|
51
47
|
}
|
|
52
|
-
|
|
48
|
+
//#endregion
|
|
49
|
+
//#region src/misc/util.ts
|
|
50
|
+
const noop = () => {};
|
|
51
|
+
function on(obj, ...args) {
|
|
52
|
+
if (obj?.addEventListener) obj.addEventListener(...args);
|
|
53
|
+
}
|
|
54
|
+
function off(obj, ...args) {
|
|
55
|
+
if (obj?.removeEventListener) obj.removeEventListener(...args);
|
|
56
|
+
}
|
|
57
|
+
const isBrowser = typeof window !== "undefined";
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region src/use-local-storage.ts
|
|
60
|
+
const useLocalStorage = (key, initialValue, options) => {
|
|
61
|
+
if (!isBrowser) return [
|
|
62
|
+
initialValue,
|
|
63
|
+
noop,
|
|
64
|
+
noop
|
|
65
|
+
];
|
|
66
|
+
if (!key) throw new Error("useLocalStorage key may not be falsy");
|
|
67
|
+
const deserializer = options ? options.raw ? (value) => value : options.deserializer : JSON.parse;
|
|
68
|
+
const initializer = useRef$1((key) => {
|
|
69
|
+
try {
|
|
70
|
+
const serializer = options ? options.raw ? String : options.serializer : JSON.stringify;
|
|
71
|
+
const localStorageValue = localStorage.getItem(key);
|
|
72
|
+
if (localStorageValue !== null) return deserializer(localStorageValue);
|
|
73
|
+
else {
|
|
74
|
+
initialValue && localStorage.setItem(key, serializer(initialValue));
|
|
75
|
+
return initialValue;
|
|
76
|
+
}
|
|
77
|
+
} catch {
|
|
78
|
+
return initialValue;
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
const [state, setState] = useState$1(() => initializer.current(key));
|
|
82
|
+
useLayoutEffect$1(() => setState(initializer.current(key)), [key]);
|
|
83
|
+
return [
|
|
84
|
+
state,
|
|
85
|
+
useCallback$1((valOrFunc) => {
|
|
86
|
+
try {
|
|
87
|
+
const newState = typeof valOrFunc === "function" ? valOrFunc(state) : valOrFunc;
|
|
88
|
+
if (typeof newState === "undefined") return;
|
|
89
|
+
let value;
|
|
90
|
+
if (options) if (options.raw) if (typeof newState === "string") value = newState;
|
|
91
|
+
else value = JSON.stringify(newState);
|
|
92
|
+
else if (options.serializer) value = options.serializer(newState);
|
|
93
|
+
else value = JSON.stringify(newState);
|
|
94
|
+
else value = JSON.stringify(newState);
|
|
95
|
+
localStorage.setItem(key, value);
|
|
96
|
+
setState(deserializer(value));
|
|
97
|
+
} catch {}
|
|
98
|
+
}, [key, setState]),
|
|
99
|
+
useCallback$1(() => {
|
|
100
|
+
try {
|
|
101
|
+
localStorage.removeItem(key);
|
|
102
|
+
setState(void 0);
|
|
103
|
+
} catch {}
|
|
104
|
+
}, [key, setState])
|
|
105
|
+
];
|
|
106
|
+
};
|
|
53
107
|
//#endregion
|
|
54
108
|
//#region src/use-query-dom.ts
|
|
55
109
|
function useQueryDOM({ selector, observe = false, queryFn, ajaxUrl }) {
|
|
@@ -150,7 +204,6 @@ function useQueryDOM({ selector, observe = false, queryFn, ajaxUrl }) {
|
|
|
150
204
|
isPending
|
|
151
205
|
};
|
|
152
206
|
}
|
|
153
|
-
|
|
154
207
|
//#endregion
|
|
155
208
|
//#region src/use-unmount.ts
|
|
156
209
|
const useUnmount = (fn) => {
|
|
@@ -158,7 +211,6 @@ const useUnmount = (fn) => {
|
|
|
158
211
|
fnRef.current = fn;
|
|
159
212
|
useEffectOnce(() => () => fnRef.current());
|
|
160
213
|
};
|
|
161
|
-
|
|
162
214
|
//#endregion
|
|
163
215
|
//#region src/use-raf-state.ts
|
|
164
216
|
const useRafState = (initialState) => {
|
|
@@ -175,21 +227,9 @@ const useRafState = (initialState) => {
|
|
|
175
227
|
});
|
|
176
228
|
return [state, setRafState];
|
|
177
229
|
};
|
|
178
|
-
|
|
179
|
-
//#endregion
|
|
180
|
-
//#region src/misc/util.ts
|
|
181
|
-
function on(obj, ...args) {
|
|
182
|
-
if (obj?.addEventListener) obj.addEventListener(...args);
|
|
183
|
-
}
|
|
184
|
-
function off(obj, ...args) {
|
|
185
|
-
if (obj?.removeEventListener) obj.removeEventListener(...args);
|
|
186
|
-
}
|
|
187
|
-
const isBrowser = typeof window !== "undefined";
|
|
188
|
-
|
|
189
230
|
//#endregion
|
|
190
231
|
//#region src/use-scroll.ts
|
|
191
232
|
const useScroll = (ref) => {
|
|
192
|
-
if (typeof ref !== "object" || typeof ref.current === "undefined") console.error("`useScroll` expects a single ref argument.");
|
|
193
233
|
const [state, setState] = useRafState({
|
|
194
234
|
x: 0,
|
|
195
235
|
y: 0
|
|
@@ -211,7 +251,6 @@ const useScroll = (ref) => {
|
|
|
211
251
|
}, [ref, setState]);
|
|
212
252
|
return state;
|
|
213
253
|
};
|
|
214
|
-
|
|
215
254
|
//#endregion
|
|
216
255
|
//#region src/use-window-scroll.ts
|
|
217
256
|
const useWindowScroll = () => {
|
|
@@ -221,12 +260,12 @@ const useWindowScroll = () => {
|
|
|
221
260
|
}));
|
|
222
261
|
useEffect(() => {
|
|
223
262
|
const handler = () => {
|
|
224
|
-
setState((state
|
|
263
|
+
setState((state) => {
|
|
225
264
|
const { pageXOffset, pageYOffset } = window;
|
|
226
|
-
return state
|
|
265
|
+
return state.x !== pageXOffset || state.y !== pageYOffset ? {
|
|
227
266
|
x: pageXOffset,
|
|
228
267
|
y: pageYOffset
|
|
229
|
-
} : state
|
|
268
|
+
} : state;
|
|
230
269
|
});
|
|
231
270
|
};
|
|
232
271
|
handler();
|
|
@@ -240,6 +279,5 @@ const useWindowScroll = () => {
|
|
|
240
279
|
}, [setState]);
|
|
241
280
|
return state;
|
|
242
281
|
};
|
|
243
|
-
|
|
244
282
|
//#endregion
|
|
245
|
-
export { useAjaxComplete, useEffectOnce, useEventCallback, useIsomorphicLayoutEffect, useQueryDOM, useRafState, useScroll, useUnmount, useWindowScroll };
|
|
283
|
+
export { useAjaxComplete, useEffectOnce, useEventCallback, useIsomorphicLayoutEffect, useLocalStorage, useQueryDOM, useRafState, useScroll, useUnmount, useWindowScroll };
|
package/package.json
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tona-hooks",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.22",
|
|
4
4
|
"description": "",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"博客园"
|
|
7
|
+
],
|
|
8
|
+
"homepage": "https://github.com/guangzan/tona/tree/main/packages/hooks#readme",
|
|
9
|
+
"bugs": {
|
|
10
|
+
"url": "https://github.com/guangzan/tona/issues"
|
|
11
|
+
},
|
|
12
|
+
"license": "MIT",
|
|
5
13
|
"author": {
|
|
6
14
|
"name": "guangzan",
|
|
7
|
-
"
|
|
8
|
-
"
|
|
15
|
+
"email": "guangzan1999@outlook.com",
|
|
16
|
+
"url": "https://www.cnblogs.com/guangzan"
|
|
9
17
|
},
|
|
10
|
-
"license": "MIT",
|
|
11
|
-
"homepage": "https://github.com/guangzan/tona/tree/main/packages/hooks#readme",
|
|
12
18
|
"repository": {
|
|
13
19
|
"type": "git",
|
|
14
20
|
"url": "git+https://github.com/guangzan/tona.git",
|
|
15
21
|
"directory": "packages/hooks"
|
|
16
22
|
},
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
},
|
|
20
|
-
"keywords": [
|
|
21
|
-
"博客园"
|
|
23
|
+
"files": [
|
|
24
|
+
"dist"
|
|
22
25
|
],
|
|
23
26
|
"type": "module",
|
|
27
|
+
"main": "./dist/index.js",
|
|
28
|
+
"module": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
24
30
|
"exports": {
|
|
25
31
|
".": {
|
|
26
32
|
"types": "./dist/index.d.ts",
|
|
27
33
|
"import": "./dist/index.js"
|
|
28
34
|
}
|
|
29
35
|
},
|
|
30
|
-
"main": "./dist/index.js",
|
|
31
|
-
"module": "./dist/index.js",
|
|
32
|
-
"types": "./dist/index.d.ts",
|
|
33
|
-
"files": [
|
|
34
|
-
"dist"
|
|
35
|
-
],
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"
|
|
37
|
+
"vite-plus": "latest"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"preact": "^10.
|
|
40
|
+
"preact": "^10.29.0"
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
|
-
"dev": "
|
|
44
|
-
"build": "
|
|
43
|
+
"dev": "vp pack --watch",
|
|
44
|
+
"build": "vp pack"
|
|
45
45
|
}
|
|
46
46
|
}
|