@fringeworks/react-utils 0.10.0 → 0.12.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/README.ja.md +118 -43
- package/README.md +118 -43
- package/{_helpers → _internal}/_traverseChildren.cjs +1 -1
- package/{_helpers → _internal}/_traverseChildren.d.cts +1 -1
- package/{_helpers → _internal}/_traverseChildren.d.mts +1 -1
- package/{_helpers → _internal}/_traverseChildren.mjs +1 -1
- package/_internal/_useChangeHandler.cjs +48 -0
- package/_internal/_useChangeHandler.d.cts +18 -0
- package/_internal/_useChangeHandler.d.mts +18 -0
- package/_internal/_useChangeHandler.mjs +47 -0
- package/{_helpers → _internal}/_useExecutionHandler.cjs +13 -12
- package/{_helpers → _internal}/_useExecutionHandler.d.cts +7 -4
- package/{_helpers → _internal}/_useExecutionHandler.d.mts +7 -4
- package/_internal/_useExecutionHandler.mjs +37 -0
- package/hooks/index.cjs +11 -2
- package/hooks/index.d.cts +11 -2
- package/hooks/index.d.mts +11 -2
- package/hooks/index.mjs +9 -3
- package/hooks/useChangeEffect/index.cjs +5 -0
- package/hooks/useChangeEffect/index.d.cts +3 -0
- package/hooks/useChangeEffect/index.d.mts +3 -0
- package/hooks/useChangeEffect/index.mjs +3 -0
- package/hooks/useChangeEffect/types.d.cts +11 -0
- package/hooks/useChangeEffect/types.d.mts +11 -0
- package/hooks/useChangeEffect/useChangeEffect.cjs +37 -0
- package/hooks/useChangeEffect/useChangeEffect.d.cts +27 -0
- package/hooks/useChangeEffect/useChangeEffect.d.mts +27 -0
- package/hooks/useChangeEffect/useChangeEffect.mjs +36 -0
- package/hooks/useChangeLayoutEffect/index.cjs +5 -0
- package/hooks/useChangeLayoutEffect/index.d.cts +2 -0
- package/hooks/useChangeLayoutEffect/index.d.mts +2 -0
- package/hooks/useChangeLayoutEffect/index.mjs +3 -0
- package/hooks/useChangeLayoutEffect/useChangeLayoutEffect.cjs +24 -0
- package/hooks/useChangeLayoutEffect/useChangeLayoutEffect.d.cts +14 -0
- package/hooks/useChangeLayoutEffect/useChangeLayoutEffect.d.mts +14 -0
- package/hooks/useChangeLayoutEffect/useChangeLayoutEffect.mjs +23 -0
- package/hooks/useCombinedRefs/useCombinedRefs.cjs +2 -0
- package/hooks/useCombinedRefs/useCombinedRefs.d.cts +3 -1
- package/hooks/useCombinedRefs/useCombinedRefs.d.mts +3 -1
- package/hooks/useCombinedRefs/useCombinedRefs.mjs +2 -0
- package/hooks/useExecutionAt/index.d.cts +2 -2
- package/hooks/useExecutionAt/index.d.mts +2 -2
- package/hooks/useExecutionAt/types.d.cts +2 -11
- package/hooks/useExecutionAt/types.d.mts +2 -11
- package/hooks/useExecutionAt/useExecutionAt.cjs +2 -3
- package/hooks/useExecutionAt/useExecutionAt.d.cts +2 -3
- package/hooks/useExecutionAt/useExecutionAt.d.mts +2 -3
- package/hooks/useExecutionAt/useExecutionAt.mjs +2 -3
- package/hooks/useExecutionEffect/useExecutionEffect.cjs +8 -6
- package/hooks/useExecutionEffect/useExecutionEffect.d.cts +9 -5
- package/hooks/useExecutionEffect/useExecutionEffect.d.mts +9 -5
- package/hooks/useExecutionEffect/useExecutionEffect.mjs +7 -5
- package/hooks/useExecutionLayoutEffect/useExecutionLayoutEffect.cjs +3 -3
- package/hooks/useExecutionLayoutEffect/useExecutionLayoutEffect.d.cts +4 -2
- package/hooks/useExecutionLayoutEffect/useExecutionLayoutEffect.d.mts +4 -2
- package/hooks/useExecutionLayoutEffect/useExecutionLayoutEffect.mjs +2 -2
- package/hooks/useExecutionMark/index.cjs +5 -0
- package/hooks/useExecutionMark/index.d.cts +3 -0
- package/hooks/useExecutionMark/index.d.mts +3 -0
- package/hooks/useExecutionMark/index.mjs +3 -0
- package/hooks/useExecutionMark/types.cjs +1 -0
- package/hooks/useExecutionMark/types.d.cts +7 -0
- package/hooks/useExecutionMark/types.d.mts +7 -0
- package/hooks/useExecutionMark/types.mjs +1 -0
- package/hooks/useExecutionMark/useExecutionMark.cjs +29 -0
- package/hooks/useExecutionMark/useExecutionMark.d.cts +19 -0
- package/hooks/useExecutionMark/useExecutionMark.d.mts +19 -0
- package/hooks/useExecutionMark/useExecutionMark.mjs +28 -0
- package/index.cjs +7 -1
- package/index.d.cts +9 -5
- package/index.d.mts +9 -5
- package/index.mjs +5 -2
- package/package.json +32 -2
- package/types.d.cts +10 -0
- package/types.d.mts +10 -0
- package/utils/forEachContent/forEachContent.cjs +2 -2
- package/utils/forEachContent/forEachContent.mjs +1 -1
- package/utils/forEachElement/forEachElement.cjs +2 -2
- package/utils/forEachElement/forEachElement.mjs +1 -1
- package/utils/index.d.cts +3 -3
- package/utils/index.d.mts +3 -3
- package/utils/markAt/index.d.cts +1 -2
- package/utils/markAt/index.d.mts +1 -2
- package/utils/markAt/markAt.cjs +2 -2
- package/utils/markAt/markAt.d.cts +4 -4
- package/utils/markAt/markAt.d.mts +4 -4
- package/utils/markAt/markAt.mjs +2 -2
- package/utils/transformContent/transformContent.cjs +2 -2
- package/utils/transformContent/transformContent.mjs +1 -1
- package/utils/transformElement/transformElement.cjs +2 -2
- package/utils/transformElement/transformElement.mjs +1 -1
- package/_helpers/_useExecutionHandler.mjs +0 -36
- package/utils/markAt/types.d.cts +0 -3
- package/utils/markAt/types.d.mts +0 -3
- /package/{utils/markAt → hooks/useChangeEffect}/types.cjs +0 -0
- /package/{utils/markAt → hooks/useChangeEffect}/types.mjs +0 -0
package/README.ja.md
CHANGED
|
@@ -31,20 +31,23 @@ import useLatestRef from '@fringeworks/react-utils/hooks/useLatestRef';
|
|
|
31
31
|
|
|
32
32
|
### hook
|
|
33
33
|
|
|
34
|
-
| hook
|
|
35
|
-
|
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
38
|
-
| `
|
|
39
|
-
| `
|
|
40
|
-
| `
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
34
|
+
| hook | 説明 |
|
|
35
|
+
| ----------------------------------------------- | ------------------------------------------------------------------------ |
|
|
36
|
+
| `useChangeEffect(dependencies, callback)` | `xxxOn` のプロパティで受け取った依存の値が変わったときに、処理を実行する |
|
|
37
|
+
| `useChangeLayoutEffect(dependencies, callback)` | `useChangeEffect` の、画面に表示する前に実行する版 |
|
|
38
|
+
| `useCombinedRefs(...refs)` | 複数の ref にまとめて値を渡す callback ref を返す |
|
|
39
|
+
| `useConstant(factory)` | 初回のレンダリングで作った値を、アンマウントされるまで返し続ける |
|
|
40
|
+
| `useExecutionAt()` | Execution Request プロパティに渡す値と、実行のきっかけになる関数を返す |
|
|
41
|
+
| `useExecutionEffect(request, callback)` | Execution Request プロパティで要求されたときに、処理を実行する |
|
|
42
|
+
| `useExecutionLayoutEffect(request, callback)` | `useExecutionEffect` の、画面に表示する前に実行する版 |
|
|
43
|
+
| `useExecutionMark()` | payload の無い Execution Request と、要求する関数を返す |
|
|
44
|
+
| `useIsHydrated()` | ハイドレーションが終わっているかを返す |
|
|
45
|
+
| `useIsMounted()` | マウントされているかどうかを判定する関数を返す |
|
|
46
|
+
| `useLatestRef(value)` | 最新の値を保持する参照を返す |
|
|
47
|
+
| `usePreviousValue(value, options?)` | 前回の値を返す |
|
|
48
|
+
| `useRerender()` | 再レンダリングだけを起こす関数を返す |
|
|
49
|
+
| `useStableCallback(callback)` | 参照が変わらず、最新のコールバックを呼ぶ関数を返す |
|
|
50
|
+
| `useStableLength(arr)` | 配列の要素数がレンダリングをまたいで変わらないことを確認する |
|
|
48
51
|
|
|
49
52
|
### 関数
|
|
50
53
|
|
|
@@ -61,15 +64,71 @@ import useLatestRef from '@fringeworks/react-utils/hooks/useLatestRef';
|
|
|
61
64
|
| `transformContent(children, callback)` | Fragment を透過し、エレメント・文字列・数値を変換した配列を返す |
|
|
62
65
|
| `transformElement(children, callback)` | Fragment を透過し、エレメントを変換した配列を返す |
|
|
63
66
|
|
|
67
|
+
### `useChangeEffect`
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
useChangeEffect(
|
|
71
|
+
dependencies: ChangeDependencies | undefined,
|
|
72
|
+
callback: () => void,
|
|
73
|
+
): void
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
`xxxOn` のプロパティ(例: `refreshOn`)を受け取る側の hook です。受け取った依存の値(Change Dependencies)が変わったときに、`callback` を実行します。処理は画面に表示した後(`useEffect`)に実行します。
|
|
77
|
+
|
|
78
|
+
測り直しや再計算など、結果が入力だけで決まる操作を、利用者が渡した値の変化に合わせて実行するために使います。回数や payload に意味がある命令は、Execution Request(`useExecutionAt`・`useExecutionEffect`)を使います。
|
|
79
|
+
|
|
80
|
+
- 1段目のプロパティを `Object.is` で比べ、どれかが変わったときに実行します。プロパティが増えた・減った場合も変化とみなします。
|
|
81
|
+
- 比べるのは1段目だけです。プロパティの値がオブジェクトの場合は参照で比べるため、その場で作ったオブジェクト(`{ style }` など)を入れると、毎回変化とみなします。
|
|
82
|
+
- 依存の値そのものは、その場で書いたオブジェクトを渡してかまいません。
|
|
83
|
+
- 初回(マウントしたとき)は実行しません。
|
|
84
|
+
- `dependencies` が `undefined` の場合は、プロパティの無いオブジェクトとして扱います。省略できるプロパティをそのまま渡せます。
|
|
85
|
+
- `callback` は最新のものを呼びます。`callback` の参照が変わっても実行しません。
|
|
86
|
+
- Execution Request(`useExecutionAt` の値)をプロパティに入れると、要求のたびに実行します。
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
// 渡す側
|
|
90
|
+
<WrappedComponent refreshOn={{ className, theme }} />;
|
|
91
|
+
|
|
92
|
+
// 受け取る側
|
|
93
|
+
type Props = { refreshOn?: ChangeDependencies };
|
|
94
|
+
|
|
95
|
+
function WrappedComponent({ refreshOn }: Props) {
|
|
96
|
+
const instance = useConstant(() => createInstance());
|
|
97
|
+
useChangeEffect(refreshOn, () => {
|
|
98
|
+
instance.refresh();
|
|
99
|
+
});
|
|
100
|
+
// ...
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
| 引数 | 型 | 説明 |
|
|
105
|
+
| -------------- | --------------------------------- | ------------------------------------ |
|
|
106
|
+
| `dependencies` | `ChangeDependencies \| undefined` | 受け取った依存の値 |
|
|
107
|
+
| `callback` | `() => void` | 依存の値が変わったときに実行する処理 |
|
|
108
|
+
|
|
109
|
+
### `useChangeLayoutEffect`
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
useChangeLayoutEffect(
|
|
113
|
+
dependencies: ChangeDependencies | undefined,
|
|
114
|
+
callback: () => void,
|
|
115
|
+
): void
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
`useChangeEffect` の、処理を画面に表示する前(`useLayoutEffect`)に実行する版です。測り直しなど、結果を画面に表示する前に反映したい処理に使います。依存の値の扱いと引数は `useChangeEffect` と同じです。
|
|
119
|
+
|
|
64
120
|
### `useCombinedRefs`
|
|
65
121
|
|
|
66
122
|
```ts
|
|
67
|
-
useCombinedRefs<T = unknown>(
|
|
123
|
+
useCombinedRefs<T = unknown>(
|
|
124
|
+
...refs: (Ref<T> | undefined)[]
|
|
125
|
+
): RefCallback<T>
|
|
68
126
|
```
|
|
69
127
|
|
|
70
128
|
渡したすべての ref に同じ値を設定する callback ref を返します。`forwardRef` で受け取った ref と、コンポーネント内の ref を1つのエレメントに渡したい場合に使います。
|
|
71
129
|
|
|
72
130
|
- 返す関数の参照は、渡す ref がすべて変わらない限り変わりません。
|
|
131
|
+
- `null`・`undefined` の ref は無視します。省略できる `ref` のプロパティをそのまま渡せます。
|
|
73
132
|
- 渡す ref の数は、レンダリングをまたいで変えられません。変わった場合はエラーになります。
|
|
74
133
|
- React 19 では、返す callback ref がクリーンアップ関数を返します。callback ref が返したクリーンアップ関数はそのまま呼び、返さなかった callback ref には `null` を渡します。
|
|
75
134
|
|
|
@@ -94,14 +153,12 @@ useConstant<T>(factory: () => T): T
|
|
|
94
153
|
### `useExecutionAt`
|
|
95
154
|
|
|
96
155
|
```ts
|
|
97
|
-
useExecutionAt<P = void>(
|
|
98
|
-
options?: UseExecutionAtOptions<P>,
|
|
99
|
-
): UseExecutionAtResult<P>
|
|
156
|
+
useExecutionAt<P = void>(): UseExecutionAtResult<P>
|
|
100
157
|
```
|
|
101
158
|
|
|
102
159
|
命令的な API を持つ部品をラップしたコンポーネントで、プロパティを通じてそのメソッドを実行するための hook です。Execution Request プロパティ(`undoAt` のように `At` で終わるプロパティ)に渡す値と、実行のきっかけになる関数を返します。
|
|
103
160
|
|
|
104
|
-
- `request.at` は初期状態では `0` で、`execute` を呼ぶたびに増加します。受け取る側は `useExecutionEffect` / `useExecutionLayoutEffect` で処理を実行します。
|
|
161
|
+
- `request.at` は初期状態では `0` で、`execute` を呼ぶたびに増加します。受け取る側は `useExecutionEffect` / `useExecutionLayoutEffect` で処理を実行します。payload が要らない場合は `useExecutionMark` を使います。
|
|
105
162
|
- `execute` の参照は常に同じです。
|
|
106
163
|
|
|
107
164
|
```tsx
|
|
@@ -111,23 +168,21 @@ const [undoAt, undo] = useExecutionAt<string>();
|
|
|
111
168
|
<WrappedImperativeComponent undoAt={undoAt} />
|
|
112
169
|
```
|
|
113
170
|
|
|
114
|
-
| オプション | 型 | 説明 |
|
|
115
|
-
| ----------------- | --- | --------------------------------- |
|
|
116
|
-
| `initialPayload?` | `P` | 初期状態の `request.payload` の値 |
|
|
117
|
-
|
|
118
171
|
### `useExecutionEffect`
|
|
119
172
|
|
|
120
173
|
```ts
|
|
121
174
|
useExecutionEffect<P = void>(
|
|
122
|
-
request: ExecutionRequest<P> | undefined,
|
|
175
|
+
request: ExecutionRequest<P> | ExecutionMark | undefined,
|
|
123
176
|
callback: (payload: P | undefined) => void,
|
|
124
177
|
): void
|
|
125
178
|
```
|
|
126
179
|
|
|
127
|
-
`useExecutionAt` と対になる、受け取る側の hook です。Execution Request プロパティで要求されたときに、要求の `payload` を渡して `callback` を実行します。処理は画面に表示した後(`useEffect`)に実行します。
|
|
180
|
+
`useExecutionAt`・`useExecutionMark` と対になる、受け取る側の hook です。Execution Request プロパティで要求されたときに、要求の `payload` を渡して `callback` を実行します。処理は画面に表示した後(`useEffect`)に実行します。
|
|
128
181
|
|
|
129
|
-
-
|
|
130
|
-
-
|
|
182
|
+
- 印(`request.at`、または `ExecutionMark` の値)が変わったときだけ実行します。`payload` は比べません。
|
|
183
|
+
- マウントしたときに渡されていた要求は実行しません(マウントしたときの印を基準にします)。
|
|
184
|
+
- 印が `0`(まだ要求していない)の場合は実行しません。
|
|
185
|
+
- `ExecutionMark` を受け取った場合、`callback` の `payload` は `undefined` です。印は `markAt()` で作ったものでなくてもかまいません(要求のたびに異なる値であればよい)。
|
|
131
186
|
- 次のレンダリングまでに複数回要求した場合は、最後の要求だけを実行します。
|
|
132
187
|
- `callback` は最新のものを呼びます。`callback` の参照が変わっても実行しません。
|
|
133
188
|
- `request` が `undefined` の場合は、要求なしとして扱います。省略できるプロパティをそのまま渡せます。
|
|
@@ -153,13 +208,32 @@ function WrappedImperativeComponent({ undoAt }: Props) {
|
|
|
153
208
|
|
|
154
209
|
```ts
|
|
155
210
|
useExecutionLayoutEffect<P = void>(
|
|
156
|
-
request: ExecutionRequest<P> | undefined,
|
|
211
|
+
request: ExecutionRequest<P> | ExecutionMark | undefined,
|
|
157
212
|
callback: (payload: P | undefined) => void,
|
|
158
213
|
): void
|
|
159
214
|
```
|
|
160
215
|
|
|
161
216
|
`useExecutionEffect` の、処理を画面に表示する前(`useLayoutEffect`)に実行する版です。スクロールの位置を合わせる、計測し直すなど、結果を画面に表示する前に反映したい処理に使います。要求の扱いと引数は `useExecutionEffect` と同じです。
|
|
162
217
|
|
|
218
|
+
### `useExecutionMark`
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
useExecutionMark(): UseExecutionMarkResult
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
`useExecutionAt` の payload を持たない版です。payload の無い Execution Request(`ExecutionMark`。実体は数値)と、要求する関数を返します。命令的な部品の `focus()`・`reset()` のような、引数の要らないメソッドをプロパティから実行する場合に使います。
|
|
225
|
+
|
|
226
|
+
- 値は初期状態では `0`(まだ要求していない)で、`execute` を呼ぶたびに `markAt()` で作った新しい値になります。
|
|
227
|
+
- `execute` の参照は常に同じです。
|
|
228
|
+
- この hook を使わずに、`ExecutionMark` を自分で作ってもかまいません(ストアや設定に置いた値など)。その場合は、**要求のたびに前回と異なる値にしてください**。同じ値を続けて渡すと、2回目は要求とみなしません。`markAt()` を使うと、呼ぶたびに異なる値になります。
|
|
229
|
+
|
|
230
|
+
```tsx
|
|
231
|
+
const [focusAt, focus] = useExecutionMark();
|
|
232
|
+
|
|
233
|
+
<button onClick={focus}>Focus</button>
|
|
234
|
+
<WrappedImperativeComponent focusAt={focusAt} />
|
|
235
|
+
```
|
|
236
|
+
|
|
163
237
|
### `useIsHydrated`
|
|
164
238
|
|
|
165
239
|
```ts
|
|
@@ -358,10 +432,10 @@ HOC の `displayName` などに使う、コンポーネントの名前を返し
|
|
|
358
432
|
### `markAt`
|
|
359
433
|
|
|
360
434
|
```ts
|
|
361
|
-
markAt():
|
|
435
|
+
markAt(): ExecutionMark
|
|
362
436
|
```
|
|
363
437
|
|
|
364
|
-
呼び出すたびに増加する値を返します。値は `1` から始まり、重複しません。`useExecutionAt`
|
|
438
|
+
呼び出すたびに増加する値を返します。値は `1` から始まり、重複しません。`useExecutionAt` の `request.at` と、`useExecutionMark` の値に使っています。
|
|
365
439
|
|
|
366
440
|
### `setRefCurrent`
|
|
367
441
|
|
|
@@ -401,19 +475,20 @@ const items = transformElement(children, (element, index) => (
|
|
|
401
475
|
|
|
402
476
|
### 型
|
|
403
477
|
|
|
404
|
-
| 型 | 説明
|
|
405
|
-
| ---------------------------- |
|
|
406
|
-
| `AppliedProps<P, Ds>` | `applyDefaultProps` の戻り値の型
|
|
407
|
-
| `
|
|
408
|
-
| `
|
|
409
|
-
| `
|
|
410
|
-
| `
|
|
411
|
-
| `
|
|
412
|
-
| `
|
|
413
|
-
| `
|
|
414
|
-
| `
|
|
415
|
-
| `UseExecutionAtResult<P>` | `useExecutionAt` の戻り値の型
|
|
416
|
-
| `
|
|
478
|
+
| 型 | 説明 |
|
|
479
|
+
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
480
|
+
| `AppliedProps<P, Ds>` | `applyDefaultProps` の戻り値の型 |
|
|
481
|
+
| `ChangeDependencies` | `xxxOn` のプロパティに渡す依存の値(1段目のプロパティを `Object.is` で比べる) |
|
|
482
|
+
| `CSSPropertiesWithVars` | CSS 変数(`--name`)を書ける `CSSProperties` |
|
|
483
|
+
| `ExecutionFunction<P>` | `useExecutionAt` が返す、実行のきっかけになる関数 |
|
|
484
|
+
| `ExecutionRequest<P>` | `useExecutionAt` が返す、Execution Request プロパティに渡す値(`at`・`payload`) |
|
|
485
|
+
| `ExtendableProps` | `extendElement` に渡せるエレメントの props(`className`・`style`) |
|
|
486
|
+
| `LatestRef<T>` | `useLatestRef` が返す参照 |
|
|
487
|
+
| `ExecutionMark` | 実行の印。payload の無い Execution Request で、`markAt` の戻り値と `ExecutionRequest` の `at` の型(実体は数値。要求のたびに異なる値にする) |
|
|
488
|
+
| `SkippedDefaults` | `applyDefaultProps` でスキップされる値(`null`・`undefined`・`false`) |
|
|
489
|
+
| `UseExecutionAtResult<P>` | `useExecutionAt` の戻り値の型 |
|
|
490
|
+
| `UseExecutionMarkResult` | `useExecutionMark` の戻り値の型 |
|
|
491
|
+
| `UsePreviousValueOptions<T>` | `usePreviousValue` のオプション |
|
|
417
492
|
|
|
418
493
|
## ライセンス
|
|
419
494
|
|
package/README.md
CHANGED
|
@@ -31,20 +31,23 @@ import useLatestRef from '@fringeworks/react-utils/hooks/useLatestRef';
|
|
|
31
31
|
|
|
32
32
|
### Hooks
|
|
33
33
|
|
|
34
|
-
| Hook
|
|
35
|
-
|
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
38
|
-
| `
|
|
39
|
-
| `
|
|
40
|
-
| `
|
|
41
|
-
| `
|
|
42
|
-
| `
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
34
|
+
| Hook | Description |
|
|
35
|
+
| ----------------------------------------------- | ------------------------------------------------------------------------------------ |
|
|
36
|
+
| `useChangeEffect(dependencies, callback)` | Runs an operation when the dependency values received through an `xxxOn` prop change |
|
|
37
|
+
| `useChangeLayoutEffect(dependencies, callback)` | A version of `useChangeEffect` that runs before the browser paints |
|
|
38
|
+
| `useCombinedRefs(...refs)` | Returns a callback ref that passes the value to all the given refs |
|
|
39
|
+
| `useConstant(factory)` | Keeps returning the value created on the first render until unmount |
|
|
40
|
+
| `useExecutionAt()` | Returns a value for an Execution Request prop and a function that triggers it |
|
|
41
|
+
| `useExecutionEffect(request, callback)` | Runs an operation when it is requested through an Execution Request prop |
|
|
42
|
+
| `useExecutionLayoutEffect(request, callback)` | A version of `useExecutionEffect` that runs before the browser paints |
|
|
43
|
+
| `useExecutionMark()` | Returns an Execution Request without a payload and a function that makes a request |
|
|
44
|
+
| `useIsHydrated()` | Returns whether hydration has finished |
|
|
45
|
+
| `useIsMounted()` | Returns a function that tells whether the component is mounted |
|
|
46
|
+
| `useLatestRef(value)` | Returns a ref that holds the latest value |
|
|
47
|
+
| `usePreviousValue(value, options?)` | Returns the previous value |
|
|
48
|
+
| `useRerender()` | Returns a function that only triggers a re-render |
|
|
49
|
+
| `useStableCallback(callback)` | Returns a function with a stable reference that calls the latest callback |
|
|
50
|
+
| `useStableLength(arr)` | Ensures that the length of an array does not change across renders |
|
|
48
51
|
|
|
49
52
|
### Functions
|
|
50
53
|
|
|
@@ -61,15 +64,71 @@ import useLatestRef from '@fringeworks/react-utils/hooks/useLatestRef';
|
|
|
61
64
|
| `transformContent(children, callback)` | Maps elements, strings, and numbers to an array, looking through Fragments |
|
|
62
65
|
| `transformElement(children, callback)` | Maps elements to an array, looking through Fragments |
|
|
63
66
|
|
|
67
|
+
### `useChangeEffect`
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
useChangeEffect(
|
|
71
|
+
dependencies: ChangeDependencies | undefined,
|
|
72
|
+
callback: () => void,
|
|
73
|
+
): void
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The receiving hook for `xxxOn` props (such as `refreshOn`). It runs `callback` when the received dependency values (Change Dependencies) change. The operation runs after the browser paints (`useEffect`).
|
|
77
|
+
|
|
78
|
+
Use it to run operations whose result depends only on their inputs, such as measuring or recalculating again, when the values passed by the user change. For commands where the count or the payload matters, use Execution Requests (`useExecutionAt`, `useExecutionEffect`).
|
|
79
|
+
|
|
80
|
+
- It compares the first-level properties with `Object.is` and runs when any of them changes. Added or removed properties also count as a change.
|
|
81
|
+
- Only the first level is compared. Object values are compared by reference, so putting an object created during rendering (such as `{ style }`) counts as a change every time.
|
|
82
|
+
- The dependency object itself may be written inline.
|
|
83
|
+
- It does not run on the first commit (mount).
|
|
84
|
+
- An `undefined` `dependencies` is treated as an object with no properties, so an optional prop can be passed as is.
|
|
85
|
+
- The latest `callback` is called. Changing the reference of `callback` does not run it.
|
|
86
|
+
- Putting an Execution Request (the value of `useExecutionAt`) in a property runs the operation on every request.
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
// Passing side
|
|
90
|
+
<WrappedComponent refreshOn={{ className, theme }} />;
|
|
91
|
+
|
|
92
|
+
// Receiving side
|
|
93
|
+
type Props = { refreshOn?: ChangeDependencies };
|
|
94
|
+
|
|
95
|
+
function WrappedComponent({ refreshOn }: Props) {
|
|
96
|
+
const instance = useConstant(() => createInstance());
|
|
97
|
+
useChangeEffect(refreshOn, () => {
|
|
98
|
+
instance.refresh();
|
|
99
|
+
});
|
|
100
|
+
// ...
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
| Parameter | Type | Description |
|
|
105
|
+
| -------------- | --------------------------------- | ------------------------------------------------------ |
|
|
106
|
+
| `dependencies` | `ChangeDependencies \| undefined` | The received dependency values |
|
|
107
|
+
| `callback` | `() => void` | The operation to run when the dependency values change |
|
|
108
|
+
|
|
109
|
+
### `useChangeLayoutEffect`
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
useChangeLayoutEffect(
|
|
113
|
+
dependencies: ChangeDependencies | undefined,
|
|
114
|
+
callback: () => void,
|
|
115
|
+
): void
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
A version of `useChangeEffect` that runs the operation before the browser paints (`useLayoutEffect`). Use it for operations whose result should be reflected before painting, such as measuring again. Dependency values and parameters are handled the same way as `useChangeEffect`.
|
|
119
|
+
|
|
64
120
|
### `useCombinedRefs`
|
|
65
121
|
|
|
66
122
|
```ts
|
|
67
|
-
useCombinedRefs<T = unknown>(
|
|
123
|
+
useCombinedRefs<T = unknown>(
|
|
124
|
+
...refs: (Ref<T> | undefined)[]
|
|
125
|
+
): RefCallback<T>
|
|
68
126
|
```
|
|
69
127
|
|
|
70
128
|
Returns a callback ref that sets the same value to all the given refs. Use it to pass both a ref received through `forwardRef` and a ref inside the component to a single element.
|
|
71
129
|
|
|
72
130
|
- The returned function keeps the same reference as long as none of the given refs change.
|
|
131
|
+
- `null` / `undefined` refs are ignored, so an optional `ref` prop can be passed as is.
|
|
73
132
|
- The number of refs must not change across renders. An error is thrown if it does.
|
|
74
133
|
- In React 19, the returned callback ref returns a cleanup function. It calls the cleanup functions returned by callback refs as they are, and passes `null` to the callback refs that returned none.
|
|
75
134
|
|
|
@@ -94,14 +153,12 @@ Calls `factory` on the first render and keeps returning the created value until
|
|
|
94
153
|
### `useExecutionAt`
|
|
95
154
|
|
|
96
155
|
```ts
|
|
97
|
-
useExecutionAt<P = void>(
|
|
98
|
-
options?: UseExecutionAtOptions<P>,
|
|
99
|
-
): UseExecutionAtResult<P>
|
|
156
|
+
useExecutionAt<P = void>(): UseExecutionAtResult<P>
|
|
100
157
|
```
|
|
101
158
|
|
|
102
159
|
A hook for components that wrap a part with an imperative API, letting you call its methods through props. It returns a value to pass to an Execution Request prop (a prop ending with `At`, such as `undoAt`) and a function that triggers it.
|
|
103
160
|
|
|
104
|
-
- `request.at` is `0` initially and increases every time `execute` is called. The receiving side runs the operation with `useExecutionEffect` / `useExecutionLayoutEffect`.
|
|
161
|
+
- `request.at` is `0` initially and increases every time `execute` is called. The receiving side runs the operation with `useExecutionEffect` / `useExecutionLayoutEffect`. Use `useExecutionMark` when no payload is needed.
|
|
105
162
|
- `execute` always keeps the same reference.
|
|
106
163
|
|
|
107
164
|
```tsx
|
|
@@ -111,23 +168,21 @@ const [undoAt, undo] = useExecutionAt<string>();
|
|
|
111
168
|
<WrappedImperativeComponent undoAt={undoAt} />
|
|
112
169
|
```
|
|
113
170
|
|
|
114
|
-
| Option | Type | Description |
|
|
115
|
-
| ----------------- | ---- | -------------------------------------- |
|
|
116
|
-
| `initialPayload?` | `P` | The initial value of `request.payload` |
|
|
117
|
-
|
|
118
171
|
### `useExecutionEffect`
|
|
119
172
|
|
|
120
173
|
```ts
|
|
121
174
|
useExecutionEffect<P = void>(
|
|
122
|
-
request: ExecutionRequest<P> | undefined,
|
|
175
|
+
request: ExecutionRequest<P> | ExecutionMark | undefined,
|
|
123
176
|
callback: (payload: P | undefined) => void,
|
|
124
177
|
): void
|
|
125
178
|
```
|
|
126
179
|
|
|
127
|
-
The receiving counterpart of `useExecutionAt`. When an operation is requested through an Execution Request prop, it runs `callback` with the request's `payload`. The operation runs after the browser paints (`useEffect`).
|
|
180
|
+
The receiving counterpart of `useExecutionAt` and `useExecutionMark`. When an operation is requested through an Execution Request prop, it runs `callback` with the request's `payload`. The operation runs after the browser paints (`useEffect`).
|
|
128
181
|
|
|
129
|
-
- It runs only when `request.at` changes. `payload` is not compared.
|
|
130
|
-
-
|
|
182
|
+
- It runs only when the mark (`request.at`, or the value of an `ExecutionMark`) changes. `payload` is not compared.
|
|
183
|
+
- A request that was already passed at mount is not run (the mark at mount is the baseline).
|
|
184
|
+
- It does not run when the mark is `0` (not requested yet).
|
|
185
|
+
- When it receives an `ExecutionMark`, the `payload` passed to `callback` is `undefined`. The mark does not have to be created by `markAt()` (any value that differs on every request works).
|
|
131
186
|
- If multiple requests are made before the next render, only the last one is run.
|
|
132
187
|
- The latest `callback` is called. Changing the reference of `callback` does not run it.
|
|
133
188
|
- An `undefined` `request` is treated as no request, so an optional prop can be passed as is.
|
|
@@ -153,13 +208,32 @@ function WrappedImperativeComponent({ undoAt }: Props) {
|
|
|
153
208
|
|
|
154
209
|
```ts
|
|
155
210
|
useExecutionLayoutEffect<P = void>(
|
|
156
|
-
request: ExecutionRequest<P> | undefined,
|
|
211
|
+
request: ExecutionRequest<P> | ExecutionMark | undefined,
|
|
157
212
|
callback: (payload: P | undefined) => void,
|
|
158
213
|
): void
|
|
159
214
|
```
|
|
160
215
|
|
|
161
216
|
A version of `useExecutionEffect` that runs the operation before the browser paints (`useLayoutEffect`). Use it for operations whose result should be reflected before painting, such as adjusting the scroll position or measuring again. Requests and parameters are handled the same way as `useExecutionEffect`.
|
|
162
217
|
|
|
218
|
+
### `useExecutionMark`
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
useExecutionMark(): UseExecutionMarkResult
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
A version of `useExecutionAt` without a payload. It returns an Execution Request without a payload (`ExecutionMark`, which is a number) and a function that makes a request. Use it to run methods that take no arguments, such as `focus()` or `reset()` of an imperative part, through props.
|
|
225
|
+
|
|
226
|
+
- The value is `0` (not requested yet) initially, and becomes a new value created by `markAt()` every time `execute` is called.
|
|
227
|
+
- `execute` always keeps the same reference.
|
|
228
|
+
- You may create an `ExecutionMark` yourself without this hook (for example, a value in a store or configuration). In that case, **make it different from the previous value on every request**. Passing the same value again is not treated as a new request. `markAt()` returns a different value on every call.
|
|
229
|
+
|
|
230
|
+
```tsx
|
|
231
|
+
const [focusAt, focus] = useExecutionMark();
|
|
232
|
+
|
|
233
|
+
<button onClick={focus}>Focus</button>
|
|
234
|
+
<WrappedImperativeComponent focusAt={focusAt} />
|
|
235
|
+
```
|
|
236
|
+
|
|
163
237
|
### `useIsHydrated`
|
|
164
238
|
|
|
165
239
|
```ts
|
|
@@ -358,10 +432,10 @@ Returns the name of a component, for use in an HOC's `displayName` and the like.
|
|
|
358
432
|
### `markAt`
|
|
359
433
|
|
|
360
434
|
```ts
|
|
361
|
-
markAt():
|
|
435
|
+
markAt(): ExecutionMark
|
|
362
436
|
```
|
|
363
437
|
|
|
364
|
-
Returns a value that increases on every call. Values start from `1` and are never duplicated. `useExecutionAt` uses it for `request.at
|
|
438
|
+
Returns a value that increases on every call. Values start from `1` and are never duplicated. `useExecutionAt` uses it for `request.at`, and `useExecutionMark` uses it for its value.
|
|
365
439
|
|
|
366
440
|
### `setRefCurrent`
|
|
367
441
|
|
|
@@ -401,19 +475,20 @@ const items = transformElement(children, (element, index) => (
|
|
|
401
475
|
|
|
402
476
|
### Types
|
|
403
477
|
|
|
404
|
-
| Type | Description
|
|
405
|
-
| ---------------------------- |
|
|
406
|
-
| `AppliedProps<P, Ds>` | The return type of `applyDefaultProps`
|
|
407
|
-
| `
|
|
408
|
-
| `
|
|
409
|
-
| `
|
|
410
|
-
| `
|
|
411
|
-
| `
|
|
412
|
-
| `
|
|
413
|
-
| `
|
|
414
|
-
| `
|
|
415
|
-
| `UseExecutionAtResult<P>` | The return type of `useExecutionAt`
|
|
416
|
-
| `
|
|
478
|
+
| Type | Description |
|
|
479
|
+
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
480
|
+
| `AppliedProps<P, Ds>` | The return type of `applyDefaultProps` |
|
|
481
|
+
| `ChangeDependencies` | The dependency values passed to an `xxxOn` prop (first-level properties are compared with `Object.is`) |
|
|
482
|
+
| `CSSPropertiesWithVars` | `CSSProperties` that also accepts CSS variables (`--name`) |
|
|
483
|
+
| `ExecutionFunction<P>` | The trigger function returned by `useExecutionAt` |
|
|
484
|
+
| `ExecutionRequest<P>` | The value for an Execution Request prop returned by `useExecutionAt` (`at`, `payload`) |
|
|
485
|
+
| `ExtendableProps` | The props of an element that `extendElement` accepts (`className`, `style`) |
|
|
486
|
+
| `LatestRef<T>` | The ref returned by `useLatestRef` |
|
|
487
|
+
| `ExecutionMark` | An execution mark: an Execution Request without a payload, also the return type of `markAt` and the type of `ExecutionRequest`'s `at` (a number; make it different on every request) |
|
|
488
|
+
| `SkippedDefaults` | Values skipped by `applyDefaultProps` (`null`, `undefined`, `false`) |
|
|
489
|
+
| `UseExecutionAtResult<P>` | The return type of `useExecutionAt` |
|
|
490
|
+
| `UseExecutionMarkResult` | The return type of `useExecutionMark` |
|
|
491
|
+
| `UsePreviousValueOptions<T>` | The options of `usePreviousValue` |
|
|
417
492
|
|
|
418
493
|
## License
|
|
419
494
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
|
|
2
2
|
let react = require("react");
|
|
3
3
|
|
|
4
|
-
//#region src/
|
|
4
|
+
//#region src/_internal/_traverseChildren.ts
|
|
5
5
|
/**
|
|
6
6
|
* ReactElement、string、numberのいずれかであるかを判定する
|
|
7
7
|
* @param child 子要素
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
|
|
2
|
+
const require_hooks_useLatestRef_useLatestRef = require("../hooks/useLatestRef/useLatestRef.cjs");
|
|
3
|
+
require("../hooks/useLatestRef/index.cjs");
|
|
4
|
+
let react = require("react");
|
|
5
|
+
|
|
6
|
+
//#region src/_internal/_useChangeHandler.ts
|
|
7
|
+
/**
|
|
8
|
+
* 依存の値が変わったか(1段目のプロパティを `Object.is` で比べる)
|
|
9
|
+
*
|
|
10
|
+
* undefined はプロパティの無いオブジェクトとして扱う
|
|
11
|
+
*/
|
|
12
|
+
const isChanged = (prev, next) => {
|
|
13
|
+
if (prev === next) return false;
|
|
14
|
+
const a = prev ?? {};
|
|
15
|
+
const b = next ?? {};
|
|
16
|
+
const keys = Object.keys(a);
|
|
17
|
+
if (keys.length !== Object.keys(b).length) return true;
|
|
18
|
+
return keys.some((key) => !Object.prototype.hasOwnProperty.call(b, key) || !Object.is(a[key], b[key]));
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* 依存の値(Change Dependencies)を受け取り、変わっていれば処理を実行する関数を返すフック
|
|
22
|
+
*
|
|
23
|
+
* `useChangeEffect`・`useChangeLayoutEffect` に共通の処理。返す関数を、毎回のコミットでエフェクトから呼ぶ。
|
|
24
|
+
*
|
|
25
|
+
* - 前回の処理の後にコミットした依存の値と比べる。初回のコミットの値が最初の基準になるため、初回は実行しない
|
|
26
|
+
* - 比べるのはエフェクトの中(コミットした値どうし)。破棄されたレンダリングの値とは比べない
|
|
27
|
+
* - 同じ値のままエフェクトが再実行されても(StrictMode など)実行しない
|
|
28
|
+
* - コールバックは最新のものを呼ぶ
|
|
29
|
+
*
|
|
30
|
+
* @param dependencies 依存の値。undefined の場合は依存なし
|
|
31
|
+
* @param callback 依存の値が変わったときに実行する処理
|
|
32
|
+
* @returns エフェクトで呼ぶ関数。参照は常に同じ
|
|
33
|
+
*/
|
|
34
|
+
function useChangeHandler(dependencies, callback) {
|
|
35
|
+
const dependenciesRef = require_hooks_useLatestRef_useLatestRef.default(dependencies);
|
|
36
|
+
const callbackRef = require_hooks_useLatestRef_useLatestRef.default(callback);
|
|
37
|
+
const committedRef = (0, react.useRef)(dependencies);
|
|
38
|
+
return (0, react.useCallback)(() => {
|
|
39
|
+
const next = dependenciesRef.current;
|
|
40
|
+
if (isChanged(committedRef.current, next)) {
|
|
41
|
+
committedRef.current = next;
|
|
42
|
+
callbackRef.current();
|
|
43
|
+
}
|
|
44
|
+
}, [dependenciesRef, callbackRef]);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
exports.default = useChangeHandler;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ChangeDependencies } from "../hooks/useChangeEffect/types.cjs";
|
|
2
|
+
//#region src/_internal/_useChangeHandler.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* 依存の値(Change Dependencies)を受け取り、変わっていれば処理を実行する関数を返すフック
|
|
5
|
+
*
|
|
6
|
+
* `useChangeEffect`・`useChangeLayoutEffect` に共通の処理。返す関数を、毎回のコミットでエフェクトから呼ぶ。
|
|
7
|
+
*
|
|
8
|
+
* - 前回の処理の後にコミットした依存の値と比べる。初回のコミットの値が最初の基準になるため、初回は実行しない
|
|
9
|
+
* - 比べるのはエフェクトの中(コミットした値どうし)。破棄されたレンダリングの値とは比べない
|
|
10
|
+
* - 同じ値のままエフェクトが再実行されても(StrictMode など)実行しない
|
|
11
|
+
* - コールバックは最新のものを呼ぶ
|
|
12
|
+
*
|
|
13
|
+
* @param dependencies 依存の値。undefined の場合は依存なし
|
|
14
|
+
* @param callback 依存の値が変わったときに実行する処理
|
|
15
|
+
* @returns エフェクトで呼ぶ関数。参照は常に同じ
|
|
16
|
+
*/
|
|
17
|
+
declare function useChangeHandler(dependencies: ChangeDependencies | undefined, callback: () => void): () => void;
|
|
18
|
+
export = useChangeHandler;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ChangeDependencies } from "../hooks/useChangeEffect/types.mjs";
|
|
2
|
+
//#region src/_internal/_useChangeHandler.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* 依存の値(Change Dependencies)を受け取り、変わっていれば処理を実行する関数を返すフック
|
|
5
|
+
*
|
|
6
|
+
* `useChangeEffect`・`useChangeLayoutEffect` に共通の処理。返す関数を、毎回のコミットでエフェクトから呼ぶ。
|
|
7
|
+
*
|
|
8
|
+
* - 前回の処理の後にコミットした依存の値と比べる。初回のコミットの値が最初の基準になるため、初回は実行しない
|
|
9
|
+
* - 比べるのはエフェクトの中(コミットした値どうし)。破棄されたレンダリングの値とは比べない
|
|
10
|
+
* - 同じ値のままエフェクトが再実行されても(StrictMode など)実行しない
|
|
11
|
+
* - コールバックは最新のものを呼ぶ
|
|
12
|
+
*
|
|
13
|
+
* @param dependencies 依存の値。undefined の場合は依存なし
|
|
14
|
+
* @param callback 依存の値が変わったときに実行する処理
|
|
15
|
+
* @returns エフェクトで呼ぶ関数。参照は常に同じ
|
|
16
|
+
*/
|
|
17
|
+
export default function useChangeHandler(dependencies: ChangeDependencies | undefined, callback: () => void): () => void;
|
|
18
|
+
//#endregion
|