@aweebit/react-essentials 0.5.3 → 0.6.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.md +290 -0
- package/dist/hooks/index.d.ts +5 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +5 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/useEventListener.d.ts +69 -10
- package/dist/hooks/useEventListener.d.ts.map +1 -1
- package/dist/hooks/useEventListener.js +16 -12
- package/dist/hooks/useEventListener.js.map +1 -1
- package/dist/hooks/useForceUpdate.d.ts +3 -4
- package/dist/hooks/useForceUpdate.d.ts.map +1 -1
- package/dist/hooks/useForceUpdate.js +4 -4
- package/dist/hooks/useForceUpdate.js.map +1 -1
- package/dist/hooks/useReducerWithDeps.d.ts +13 -10
- package/dist/hooks/useReducerWithDeps.d.ts.map +1 -1
- package/dist/hooks/useReducerWithDeps.js +10 -11
- package/dist/hooks/useReducerWithDeps.js.map +1 -1
- package/dist/hooks/useStateWithDeps.d.ts +6 -7
- package/dist/hooks/useStateWithDeps.d.ts.map +1 -1
- package/dist/hooks/useStateWithDeps.js +8 -9
- package/dist/hooks/useStateWithDeps.js.map +1 -1
- package/dist/index.d.ts +2 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/misc/createSafeContext.d.ts +52 -0
- package/dist/misc/createSafeContext.d.ts.map +1 -0
- package/dist/misc/createSafeContext.js +46 -0
- package/dist/misc/createSafeContext.js.map +1 -0
- package/dist/misc/index.d.ts +2 -0
- package/dist/misc/index.d.ts.map +1 -0
- package/dist/misc/index.js +2 -0
- package/dist/misc/index.js.map +1 -0
- package/dist/utils.d.ts +7 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/{utils/index.js → utils.js} +2 -2
- package/dist/utils.js.map +1 -0
- package/package.json +25 -15
- package/src/hooks/index.ts +4 -0
- package/src/hooks/useEventListener.ts +170 -0
- package/{lib → src}/hooks/useForceUpdate.ts +8 -6
- package/{lib → src}/hooks/useReducerWithDeps.ts +23 -17
- package/{lib → src}/hooks/useStateWithDeps.ts +8 -9
- package/src/index.ts +2 -0
- package/src/misc/createSafeContext.ts +83 -0
- package/src/misc/index.ts +1 -0
- package/src/utils.ts +25 -0
- package/dist/utils/index.d.ts +0 -4
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/lib/hooks/useEventListener.ts +0 -95
- package/lib/index.ts +0 -4
- package/lib/utils/index.ts +0 -16
package/README.md
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# @aweebit/react-essentials
|
|
2
|
+
|
|
3
|
+
## RestrictedContext
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
type RestrictedContext<T> =
|
|
7
|
+
Context<T> extends Provider<T>
|
|
8
|
+
? {
|
|
9
|
+
Provider: Provider<T>;
|
|
10
|
+
displayName: string;
|
|
11
|
+
} & Provider<T>
|
|
12
|
+
: {
|
|
13
|
+
Provider: Provider<T>;
|
|
14
|
+
displayName: string;
|
|
15
|
+
};
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Defined in: [misc/createSafeContext.ts:17](https://github.com/aweebit/react-essentials/blob/v0.6.0/src/misc/createSafeContext.ts#L17)
|
|
19
|
+
|
|
20
|
+
A React context with a required `displayName` and the obsolete `Consumer`
|
|
21
|
+
property purposefully omitted so that it is impossible to pass the context
|
|
22
|
+
as an argument to `useContext` or `use` (the hook produced with
|
|
23
|
+
[`createSafeContext`](#createsafecontext) should be used instead)
|
|
24
|
+
|
|
25
|
+
### Type Parameters
|
|
26
|
+
|
|
27
|
+
| Type Parameter |
|
|
28
|
+
| -------------- |
|
|
29
|
+
| `T` |
|
|
30
|
+
|
|
31
|
+
### See
|
|
32
|
+
|
|
33
|
+
[`createSafeContext`](#createsafecontext)
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## SafeContext
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
type SafeContext<DisplayName, T> = {
|
|
41
|
+
[K in `${DisplayName}Context`]: RestrictedContext<T>;
|
|
42
|
+
} & { [K in `use${DisplayName}`]: () => T };
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Defined in: [misc/createSafeContext.ts:25](https://github.com/aweebit/react-essentials/blob/v0.6.0/src/misc/createSafeContext.ts#L25)
|
|
46
|
+
|
|
47
|
+
### Type Parameters
|
|
48
|
+
|
|
49
|
+
| Type Parameter |
|
|
50
|
+
| -------------------------------- |
|
|
51
|
+
| `DisplayName` _extends_ `string` |
|
|
52
|
+
| `T` |
|
|
53
|
+
|
|
54
|
+
### See
|
|
55
|
+
|
|
56
|
+
[`createSafeContext`](#createsafecontext)
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## useEventListener()
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
function useEventListener<T>(eventName, handler, element?, options?): void;
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Defined in: [hooks/useEventListener.ts:120](https://github.com/aweebit/react-essentials/blob/v0.6.0/src/hooks/useEventListener.ts#L120)
|
|
67
|
+
|
|
68
|
+
Adds `handler` as a listener for the event `eventName` of `element` with the
|
|
69
|
+
provided `options` applied
|
|
70
|
+
|
|
71
|
+
If `element` is `undefined`, `window` is used instead.
|
|
72
|
+
|
|
73
|
+
If `element` is `null`, no event listener is added.
|
|
74
|
+
|
|
75
|
+
### Example
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
useEventListener('resize', () => {
|
|
79
|
+
console.log(window.innerWidth, window.innerHeight);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
useEventListener(
|
|
83
|
+
'visibilitychange',
|
|
84
|
+
() => console.log(document.visibilityState),
|
|
85
|
+
document,
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const buttonRef = useRef<HTMLButtonElement>(null);
|
|
89
|
+
useEventListener('click', () => console.log('click'), buttonRef.current);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Type Parameters
|
|
93
|
+
|
|
94
|
+
| Type Parameter |
|
|
95
|
+
| --------------------------- |
|
|
96
|
+
| `T` _extends_ `EventTarget` |
|
|
97
|
+
|
|
98
|
+
### Parameters
|
|
99
|
+
|
|
100
|
+
| Parameter | Type |
|
|
101
|
+
| ----------- | -------------------------------------- |
|
|
102
|
+
| `eventName` | `string` |
|
|
103
|
+
| `handler` | (`this`, `event`) => `void` |
|
|
104
|
+
| `element?` | `null` \| `T` |
|
|
105
|
+
| `options?` | `boolean` \| `AddEventListenerOptions` |
|
|
106
|
+
|
|
107
|
+
### Returns
|
|
108
|
+
|
|
109
|
+
`void`
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## useForceUpdate()
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
function useForceUpdate(callback?): [() => void, bigint];
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Defined in: [hooks/useForceUpdate.ts:32](https://github.com/aweebit/react-essentials/blob/v0.6.0/src/hooks/useForceUpdate.ts#L32)
|
|
120
|
+
|
|
121
|
+
Enables you to imperatively trigger re-rendering of components
|
|
122
|
+
|
|
123
|
+
This hook is designed in the most general way possible in order to cover all
|
|
124
|
+
imaginable use cases.
|
|
125
|
+
|
|
126
|
+
### Parameters
|
|
127
|
+
|
|
128
|
+
| Parameter | Type | Description |
|
|
129
|
+
| ----------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
130
|
+
| `callback?` | () => `void` | An optional callback function to call during renders that were triggered with `forceUpdate()` Can be used for conditionally calling state setters when state needs to be reset. That is legal and better than using effects (see [You Might Not Need an Effect \> Adjusting some state when a prop changes](https://react.dev/learn/-might-not-need-an-effect#adjusting-some-state-when-a-prop-changes)), but can often be avoided by using [`useStateWithDeps`](#usestatewithdeps) or [`useReducerWithDeps`](#usereducerwithdeps). Important: the callback function is called once per render, not once per `forceUpdate` call! If React batches `forceUpdate` calls, then it will only be called once. |
|
|
131
|
+
|
|
132
|
+
### Returns
|
|
133
|
+
|
|
134
|
+
\[() => `void`, `bigint`\]
|
|
135
|
+
|
|
136
|
+
An array with the following two elements:
|
|
137
|
+
|
|
138
|
+
1. A `forceUpdate` function that triggers a re-render
|
|
139
|
+
2. The number of times `forceUpdate` has been called so far
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## useReducerWithDeps()
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
function useReducerWithDeps<S, A>(
|
|
147
|
+
reducer,
|
|
148
|
+
initialState,
|
|
149
|
+
deps,
|
|
150
|
+
): [S, ActionDispatch<A>];
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Defined in: [hooks/useReducerWithDeps.ts:49](https://github.com/aweebit/react-essentials/blob/v0.6.0/src/hooks/useReducerWithDeps.ts#L49)
|
|
154
|
+
|
|
155
|
+
`useReducer` hook with an additional dependency array `deps` that resets the
|
|
156
|
+
state to `initialState` when dependencies change
|
|
157
|
+
|
|
158
|
+
### On linter support
|
|
159
|
+
|
|
160
|
+
The `react-hooks/exhaustive-deps` ESLint rule doesn't support hooks where
|
|
161
|
+
the dependency array parameter is at any other position than the second.
|
|
162
|
+
However, as we would like to keep the hook as compatible with `useReducer` as
|
|
163
|
+
possible, we don't want to artificially change the parameter's position.
|
|
164
|
+
Therefore, there will be no warnings about missing dependencies.
|
|
165
|
+
Because of that, additional caution is advised!
|
|
166
|
+
Be sure to check no dependencies are missing from the `deps` array.
|
|
167
|
+
|
|
168
|
+
Related issue: [https://github.com/facebook/react/issues/25443](https://github.com/facebook/react/issues/25443).
|
|
169
|
+
|
|
170
|
+
Unlike `eslint-plugin-react-hooks` maintained by React's team, the unofficial
|
|
171
|
+
`useExhaustiveDependencies` rule provided for Biome by Biome's team
|
|
172
|
+
does actually have support for dependency arrays at other positions, see
|
|
173
|
+
[useExhaustiveDependencies \> Options \> Validating dependencies](https://biomejs.dev/linter/rules/use-exhaustive-dependencies/#validating-dependencies).
|
|
174
|
+
|
|
175
|
+
### Type Parameters
|
|
176
|
+
|
|
177
|
+
| Type Parameter |
|
|
178
|
+
| ---------------------------- |
|
|
179
|
+
| `S` |
|
|
180
|
+
| `A` _extends_ `AnyActionArg` |
|
|
181
|
+
|
|
182
|
+
### Parameters
|
|
183
|
+
|
|
184
|
+
| Parameter | Type | Description |
|
|
185
|
+
| -------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
186
|
+
| `reducer` | (`prevState`, ...`args`) => `S` | The reducer function that specifies how the state gets updated |
|
|
187
|
+
| `initialState` | `S` \| (`previousState?`) => `S` | The value to which the state is set when the component is mounted or dependencies change It can also be a function that returns a state value. If the state is reset due to a change of dependencies, this function will be passed the previous state as its argument (will be `undefined` in the first call upon mount). |
|
|
188
|
+
| `deps` | `DependencyList` | Dependencies that reset the state to `initialState` |
|
|
189
|
+
|
|
190
|
+
### Returns
|
|
191
|
+
|
|
192
|
+
\[`S`, `ActionDispatch`\<`A`\>\]
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## useStateWithDeps()
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
function useStateWithDeps<S>(
|
|
200
|
+
initialState,
|
|
201
|
+
deps,
|
|
202
|
+
): [S, Dispatch<SetStateAction<S>>];
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Defined in: [hooks/useStateWithDeps.ts:31](https://github.com/aweebit/react-essentials/blob/v0.6.0/src/hooks/useStateWithDeps.ts#L31)
|
|
206
|
+
|
|
207
|
+
`useState` hook with an additional dependency array `deps` that resets the
|
|
208
|
+
state to `initialState` when dependencies change
|
|
209
|
+
|
|
210
|
+
### Type Parameters
|
|
211
|
+
|
|
212
|
+
| Type Parameter |
|
|
213
|
+
| -------------- |
|
|
214
|
+
| `S` |
|
|
215
|
+
|
|
216
|
+
### Parameters
|
|
217
|
+
|
|
218
|
+
| Parameter | Type | Description |
|
|
219
|
+
| -------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
220
|
+
| `initialState` | `S` \| (`previousState?`) => `S` | The value to which the state is set when the component is mounted or dependencies change It can also be a function that returns a state value. If the state is reset due to a change of dependencies, this function will be passed the previous state as its argument (will be `undefined` in the first call upon mount). |
|
|
221
|
+
| `deps` | `DependencyList` | Dependencies that reset the state to `initialState` |
|
|
222
|
+
|
|
223
|
+
### Returns
|
|
224
|
+
|
|
225
|
+
\[`S`, `Dispatch`\<`SetStateAction`\<`S`\>\>\]
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## createSafeContext()
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
function createSafeContext<T>(): <DisplayName>(
|
|
233
|
+
displayName,
|
|
234
|
+
) => SafeContext<DisplayName, T>;
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Defined in: [misc/createSafeContext.ts:56](https://github.com/aweebit/react-essentials/blob/v0.6.0/src/misc/createSafeContext.ts#L56)
|
|
238
|
+
|
|
239
|
+
For a given type `T`, returns a function that produces both a context of that
|
|
240
|
+
type and a hook that returns the current context value if one was provided,
|
|
241
|
+
or throws an error otherwise
|
|
242
|
+
|
|
243
|
+
### Example
|
|
244
|
+
|
|
245
|
+
```tsx
|
|
246
|
+
const { ItemsContext, useItems } = createSafeContext<string[]>()('Items');
|
|
247
|
+
|
|
248
|
+
const Parent = () => (
|
|
249
|
+
<ItemsContext value={['compass', 'newspaper', 'banana']}>
|
|
250
|
+
<Child />
|
|
251
|
+
</ItemsContext>
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
const Child = () => useItems().join(', ');
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Type Parameters
|
|
258
|
+
|
|
259
|
+
| Type Parameter | Default type |
|
|
260
|
+
| -------------- | ------------ |
|
|
261
|
+
| `T` | `never` |
|
|
262
|
+
|
|
263
|
+
### Returns
|
|
264
|
+
|
|
265
|
+
A function that accepts a single string argument `displayName` (e.g.
|
|
266
|
+
`"Items"`) and returns an object with the following properties:
|
|
267
|
+
|
|
268
|
+
- `` `${displayName}Context` `` (e.g. `ItemsContext`): the context
|
|
269
|
+
- `` `use${displayName}` `` (e.g. `useItems`): a hook that returns the
|
|
270
|
+
current context value if one was provided, or throws an error otherwise
|
|
271
|
+
|
|
272
|
+
```ts
|
|
273
|
+
<DisplayName>(displayName): SafeContext<DisplayName, T>;
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
#### Type Parameters
|
|
277
|
+
|
|
278
|
+
| Type Parameter |
|
|
279
|
+
| -------------------------------- |
|
|
280
|
+
| `DisplayName` _extends_ `string` |
|
|
281
|
+
|
|
282
|
+
#### Parameters
|
|
283
|
+
|
|
284
|
+
| Parameter | Type |
|
|
285
|
+
| ------------- | ------------------------------------------------------------------------------------------------ |
|
|
286
|
+
| `displayName` | \[`T`\] _extends_ \[`never`\] ? `never` : `ArgumentFallback`\<`DisplayName`, `never`, `string`\> |
|
|
287
|
+
|
|
288
|
+
#### Returns
|
|
289
|
+
|
|
290
|
+
[`SafeContext`](#safecontext)\<`DisplayName`, `T`\>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC"}
|
|
@@ -5,16 +5,75 @@
|
|
|
5
5
|
* @copyright 2020 Julien CARON
|
|
6
6
|
*/
|
|
7
7
|
/**
|
|
8
|
-
* Adds `handler` as a listener for the event `eventName` of `element`
|
|
9
|
-
*
|
|
8
|
+
* Adds `handler` as a listener for the event `eventName` of `element` with the
|
|
9
|
+
* provided `options` applied
|
|
10
10
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
11
|
+
* If `element` is `undefined`, `window` is used instead.
|
|
12
|
+
*
|
|
13
|
+
* If `element` is `null`, no event listener is added.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* useEventListener('resize', () => {
|
|
18
|
+
* console.log(window.innerWidth, window.innerHeight);
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* useEventListener(
|
|
22
|
+
* 'visibilitychange',
|
|
23
|
+
* () => console.log(document.visibilityState),
|
|
24
|
+
* document
|
|
25
|
+
* );
|
|
26
|
+
*
|
|
27
|
+
* const buttonRef = useRef<HTMLButtonElement>(null);
|
|
28
|
+
* useEventListener("click", () => console.log("click"), buttonRef.current);
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @ignore
|
|
32
|
+
*/
|
|
33
|
+
export declare function useEventListener<K extends keyof HTMLElementEventMap, T extends HTMLElement>(eventName: K, handler: (this: NoInfer<T>, event: HTMLElementEventMap[K]) => void, element: T | null, options?: boolean | AddEventListenerOptions): void;
|
|
34
|
+
/**
|
|
35
|
+
* @see {@linkcode useEventListener}
|
|
36
|
+
* @ignore
|
|
37
|
+
*/
|
|
38
|
+
export declare function useEventListener<K extends keyof SVGElementEventMap, T extends SVGElement>(eventName: K, handler: (this: NoInfer<T>, event: SVGElementEventMap[K]) => void, element: T | null, options?: boolean | AddEventListenerOptions): void;
|
|
39
|
+
/**
|
|
40
|
+
* @see {@linkcode useEventListener}
|
|
41
|
+
* @ignore
|
|
42
|
+
*/
|
|
43
|
+
export declare function useEventListener<K extends keyof MathMLElementEventMap, T extends MathMLElement>(eventName: K, handler: (this: NoInfer<T>, event: MathMLElementEventMap[K]) => void, element: T | null, options?: boolean | AddEventListenerOptions): void;
|
|
44
|
+
/**
|
|
45
|
+
* @see {@linkcode useEventListener}
|
|
46
|
+
* @ignore
|
|
47
|
+
*/
|
|
48
|
+
export declare function useEventListener<K extends keyof DocumentEventMap>(eventName: K, handler: (this: Document, event: DocumentEventMap[K]) => void, element: Document, options?: boolean | AddEventListenerOptions): void;
|
|
49
|
+
/**
|
|
50
|
+
* @see {@linkcode useEventListener}
|
|
51
|
+
* @ignore
|
|
52
|
+
*/
|
|
53
|
+
export declare function useEventListener<K extends keyof WindowEventMap>(eventName: K, handler: (this: Window, event: WindowEventMap[K]) => void, element?: Window, options?: boolean | AddEventListenerOptions): void;
|
|
54
|
+
/**
|
|
55
|
+
* Adds `handler` as a listener for the event `eventName` of `element` with the
|
|
56
|
+
* provided `options` applied
|
|
57
|
+
*
|
|
58
|
+
* If `element` is `undefined`, `window` is used instead.
|
|
59
|
+
*
|
|
60
|
+
* If `element` is `null`, no event listener is added.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```tsx
|
|
64
|
+
* useEventListener('resize', () => {
|
|
65
|
+
* console.log(window.innerWidth, window.innerHeight);
|
|
66
|
+
* });
|
|
67
|
+
*
|
|
68
|
+
* useEventListener(
|
|
69
|
+
* 'visibilitychange',
|
|
70
|
+
* () => console.log(document.visibilityState),
|
|
71
|
+
* document
|
|
72
|
+
* );
|
|
73
|
+
*
|
|
74
|
+
* const buttonRef = useRef<HTMLButtonElement>(null);
|
|
75
|
+
* useEventListener("click", () => console.log("click"), buttonRef.current);
|
|
76
|
+
* ```
|
|
13
77
|
*/
|
|
14
|
-
declare function useEventListener<
|
|
15
|
-
declare function useEventListener<K extends keyof HTMLElementEventMap, T extends HTMLElement>(eventName: K, handler: (this: T, event: HTMLElementEventMap[K]) => void, element: T, options?: boolean | AddEventListenerOptions): void;
|
|
16
|
-
declare function useEventListener<K extends keyof DocumentEventMap>(eventName: K, handler: (this: Document, event: DocumentEventMap[K]) => void, element: Document, options?: boolean | AddEventListenerOptions): void;
|
|
17
|
-
declare function useEventListener<K extends keyof WindowEventMap>(eventName: K, handler: (this: Window, event: WindowEventMap[K]) => void, element?: Window, options?: boolean | AddEventListenerOptions): void;
|
|
18
|
-
declare function useEventListener(eventName: string, handler: (this: EventTarget, event: Event) => void, element?: EventTarget, options?: boolean | AddEventListenerOptions): void;
|
|
19
|
-
export default useEventListener;
|
|
78
|
+
export declare function useEventListener<T extends EventTarget>(eventName: string, handler: (this: NoInfer<T>, event: Event) => void, element?: T | null, options?: boolean | AddEventListenerOptions): void;
|
|
20
79
|
//# sourceMappingURL=useEventListener.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEventListener.d.ts","sourceRoot":"","sources":["../../
|
|
1
|
+
{"version":3,"file":"useEventListener.d.ts","sourceRoot":"","sources":["../../src/hooks/useEventListener.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,gBAAgB,CAC9B,CAAC,SAAS,MAAM,mBAAmB,EACnC,CAAC,SAAS,WAAW,EAErB,SAAS,EAAE,CAAC,EACZ,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAAK,IAAI,EAClE,OAAO,EAAE,CAAC,GAAG,IAAI,EACjB,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,IAAI,CAAC;AAER;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,CAAC,SAAS,MAAM,kBAAkB,EAClC,CAAC,SAAS,UAAU,EAEpB,SAAS,EAAE,CAAC,EACZ,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAAK,IAAI,EACjE,OAAO,EAAE,CAAC,GAAG,IAAI,EACjB,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,IAAI,CAAC;AAER;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,CAAC,SAAS,MAAM,qBAAqB,EACrC,CAAC,SAAS,aAAa,EAEvB,SAAS,EAAE,CAAC,EACZ,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC,CAAC,KAAK,IAAI,EACpE,OAAO,EAAE,CAAC,GAAG,IAAI,EACjB,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,IAAI,CAAC;AAER;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,gBAAgB,EAC/D,SAAS,EAAE,CAAC,EACZ,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,EAC7D,OAAO,EAAE,QAAQ,EACjB,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,IAAI,CAAC;AAER;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,cAAc,EAC7D,SAAS,EAAE,CAAC,EACZ,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,IAAI,EACzD,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,IAAI,CAAC;AAER;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,WAAW,EACpD,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,EACjD,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,EAClB,OAAO,CAAC,EAAE,OAAO,GAAG,uBAAuB,GAC1C,IAAI,CAAC"}
|
|
@@ -4,26 +4,30 @@
|
|
|
4
4
|
* @license MIT
|
|
5
5
|
* @copyright 2020 Julien CARON
|
|
6
6
|
*/
|
|
7
|
-
import { useEffect,
|
|
8
|
-
function useEventListener(eventName, handler, element, options) {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
import { useEffect, useMemo, useRef } from 'react';
|
|
8
|
+
export function useEventListener(eventName, handler, element, options) {
|
|
9
|
+
const handlerRef = useRef(handler);
|
|
10
|
+
handlerRef.current = handler;
|
|
11
|
+
const { capture = false, once = false, passive, signal, } = typeof options === 'boolean' ? { capture: options } : (options ?? {});
|
|
12
|
+
const memoizedOptions = useMemo(() => options,
|
|
13
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
14
|
+
[capture, once, passive, signal]);
|
|
14
15
|
useEffect(() => {
|
|
16
|
+
if (element === null) {
|
|
17
|
+
// No element has been attached to the ref yet
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
15
20
|
// Define the listening target
|
|
16
21
|
const targetElement = element ?? window;
|
|
17
22
|
// Create event listener that calls handler function stored in ref
|
|
18
23
|
const listener = function (event) {
|
|
19
|
-
|
|
24
|
+
handlerRef.current.call(this, event);
|
|
20
25
|
};
|
|
21
|
-
targetElement.addEventListener(eventName, listener,
|
|
26
|
+
targetElement.addEventListener(eventName, listener, memoizedOptions);
|
|
22
27
|
// Remove event listener on cleanup
|
|
23
28
|
return () => {
|
|
24
|
-
targetElement.removeEventListener(eventName, listener,
|
|
29
|
+
targetElement.removeEventListener(eventName, listener, memoizedOptions);
|
|
25
30
|
};
|
|
26
|
-
}, [eventName, element,
|
|
31
|
+
}, [eventName, element, memoizedOptions]);
|
|
27
32
|
}
|
|
28
|
-
export default useEventListener;
|
|
29
33
|
//# sourceMappingURL=useEventListener.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useEventListener.js","sourceRoot":"","sources":["../../
|
|
1
|
+
{"version":3,"file":"useEventListener.js","sourceRoot":"","sources":["../../src/hooks/useEventListener.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAuHnD,MAAM,UAAU,gBAAgB,CAC9B,SAAiB,EACjB,OAAkD,EAClD,OAA4B,EAC5B,OAA2C;IAE3C,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;IAE7B,MAAM,EACJ,OAAO,GAAG,KAAK,EACf,IAAI,GAAG,KAAK,EACZ,OAAO,EACP,MAAM,GACP,GAAG,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAE1E,MAAM,eAAe,GAAG,OAAO,CAC7B,GAAG,EAAE,CAAC,OAAO;IACb,uDAAuD;IACvD,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CACjC,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,8CAA8C;YAC9C,OAAO;QACT,CAAC;QAED,8BAA8B;QAC9B,MAAM,aAAa,GAAG,OAAO,IAAI,MAAM,CAAC;QAExC,kEAAkE;QAClE,MAAM,QAAQ,GAAmB,UAAU,KAAK;YAC9C,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvC,CAAC,CAAC;QAEF,aAAa,CAAC,gBAAgB,CAAC,SAAS,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;QAErE,mCAAmC;QACnC,OAAO,GAAG,EAAE;YACV,aAAa,CAAC,mBAAmB,CAAC,SAAS,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;QAC1E,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC;AAC5C,CAAC"}
|
|
@@ -10,9 +10,8 @@
|
|
|
10
10
|
* Can be used for conditionally calling state setters when state needs to be
|
|
11
11
|
* reset. That is legal and better than using effects (see
|
|
12
12
|
* {@link https://react.dev/learn/-might-not-need-an-effect#adjusting-some-state-when-a-prop-changes You Might Not Need an Effect > Adjusting some state when a prop changes}),
|
|
13
|
-
* but can often be avoided by using
|
|
14
|
-
*
|
|
15
|
-
* [`useReducerWithDeps`]({@link ./useReducerWithDeps.ts}).
|
|
13
|
+
* but can often be avoided by using {@linkcode useStateWithDeps} or
|
|
14
|
+
* {@linkcode useReducerWithDeps}.
|
|
16
15
|
*
|
|
17
16
|
* Important: the callback function is called once per render, not once per
|
|
18
17
|
* `forceUpdate` call! If React batches `forceUpdate` calls, then it will only
|
|
@@ -23,5 +22,5 @@
|
|
|
23
22
|
* 1. A `forceUpdate` function that triggers a re-render
|
|
24
23
|
* 2. The number of times `forceUpdate` has been called so far
|
|
25
24
|
*/
|
|
26
|
-
export
|
|
25
|
+
export declare function useForceUpdate(callback?: () => void): [() => void, bigint];
|
|
27
26
|
//# sourceMappingURL=useForceUpdate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useForceUpdate.d.ts","sourceRoot":"","sources":["../../
|
|
1
|
+
{"version":3,"file":"useForceUpdate.d.ts","sourceRoot":"","sources":["../../src/hooks/useForceUpdate.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE,MAAM,CAAC,CAU1E"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { useReducer, useRef } from 'react';
|
|
2
|
+
/* eslint-enable */
|
|
2
3
|
/**
|
|
3
4
|
* Enables you to imperatively trigger re-rendering of components
|
|
4
5
|
*
|
|
@@ -11,9 +12,8 @@ import { useReducer, useRef } from 'react';
|
|
|
11
12
|
* Can be used for conditionally calling state setters when state needs to be
|
|
12
13
|
* reset. That is legal and better than using effects (see
|
|
13
14
|
* {@link https://react.dev/learn/-might-not-need-an-effect#adjusting-some-state-when-a-prop-changes You Might Not Need an Effect > Adjusting some state when a prop changes}),
|
|
14
|
-
* but can often be avoided by using
|
|
15
|
-
*
|
|
16
|
-
* [`useReducerWithDeps`]({@link ./useReducerWithDeps.ts}).
|
|
15
|
+
* but can often be avoided by using {@linkcode useStateWithDeps} or
|
|
16
|
+
* {@linkcode useReducerWithDeps}.
|
|
17
17
|
*
|
|
18
18
|
* Important: the callback function is called once per render, not once per
|
|
19
19
|
* `forceUpdate` call! If React batches `forceUpdate` calls, then it will only
|
|
@@ -24,7 +24,7 @@ import { useReducer, useRef } from 'react';
|
|
|
24
24
|
* 1. A `forceUpdate` function that triggers a re-render
|
|
25
25
|
* 2. The number of times `forceUpdate` has been called so far
|
|
26
26
|
*/
|
|
27
|
-
export
|
|
27
|
+
export function useForceUpdate(callback) {
|
|
28
28
|
// It is very unlikely that the number of updates will exceed
|
|
29
29
|
// Number.MAX_SAFE_INTEGER, but not impossible. That is why we use bigints.
|
|
30
30
|
const [counter, forceUpdate] = useReducer((prev) => prev + 1n, 0n);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useForceUpdate.js","sourceRoot":"","sources":["../../
|
|
1
|
+
{"version":3,"file":"useForceUpdate.js","sourceRoot":"","sources":["../../src/hooks/useForceUpdate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAK3C,mBAAmB;AAEnB;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,cAAc,CAAC,QAAqB;IAClD,6DAA6D;IAC7D,2EAA2E;IAC3E,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;IACnE,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,OAAO,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC;QACnC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;QAC7B,QAAQ,EAAE,EAAE,CAAC;IACf,CAAC;IACD,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type DependencyList } from 'react';
|
|
2
|
+
/** @ignore */
|
|
3
|
+
export type AnyActionArg = [] | [any];
|
|
4
|
+
/** @ignore */
|
|
5
|
+
export type ActionDispatch<ActionArg extends AnyActionArg> = (...args: ActionArg) => void;
|
|
2
6
|
/**
|
|
3
|
-
* `useReducer` hook with an additional dependency array that resets the
|
|
4
|
-
* to
|
|
5
|
-
* change
|
|
7
|
+
* `useReducer` hook with an additional dependency array `deps` that resets the
|
|
8
|
+
* state to `initialState` when dependencies change
|
|
6
9
|
*
|
|
7
10
|
* ### On linter support
|
|
8
11
|
*
|
|
@@ -11,7 +14,7 @@ import { type ActionDispatch, type AnyActionArg, type DependencyList } from 'rea
|
|
|
11
14
|
* However, as we would like to keep the hook as compatible with `useReducer` as
|
|
12
15
|
* possible, we don't want to artificially change the parameter's position.
|
|
13
16
|
* Therefore, there will be no warnings about missing dependencies.
|
|
14
|
-
* Because of that,
|
|
17
|
+
* Because of that, additional caution is advised!
|
|
15
18
|
* Be sure to check no dependencies are missing from the `deps` array.
|
|
16
19
|
*
|
|
17
20
|
* Related issue: {@link https://github.com/facebook/react/issues/25443}.
|
|
@@ -19,18 +22,18 @@ import { type ActionDispatch, type AnyActionArg, type DependencyList } from 'rea
|
|
|
19
22
|
* Unlike `eslint-plugin-react-hooks` maintained by React's team, the unofficial
|
|
20
23
|
* `useExhaustiveDependencies` rule provided for Biome by Biome's team
|
|
21
24
|
* does actually have support for dependency arrays at other positions, see
|
|
22
|
-
* {@link https://biomejs.dev/linter/rules/use-exhaustive-dependencies/#validating-dependencies}.
|
|
25
|
+
* {@link https://biomejs.dev/linter/rules/use-exhaustive-dependencies/#validating-dependencies useExhaustiveDependencies > Options > Validating dependencies}.
|
|
23
26
|
*
|
|
24
27
|
* @param reducer The reducer function that specifies how the state gets updated
|
|
25
28
|
*
|
|
26
|
-
* @param initialState The
|
|
27
|
-
*
|
|
29
|
+
* @param initialState The value to which the state is set when the component is
|
|
30
|
+
* mounted or dependencies change
|
|
28
31
|
*
|
|
29
|
-
* It can also be a function
|
|
32
|
+
* It can also be a function that returns a state value. If the state is reset
|
|
30
33
|
* due to a change of dependencies, this function will be passed the previous
|
|
31
34
|
* state as its argument (will be `undefined` in the first call upon mount).
|
|
32
35
|
*
|
|
33
36
|
* @param deps Dependencies that reset the state to `initialState`
|
|
34
37
|
*/
|
|
35
|
-
export
|
|
38
|
+
export declare function useReducerWithDeps<S, A extends AnyActionArg>(reducer: (prevState: S, ...args: A) => S, initialState: S | ((previousState?: S) => S), deps: DependencyList): [S, ActionDispatch<A>];
|
|
36
39
|
//# sourceMappingURL=useReducerWithDeps.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useReducerWithDeps.d.ts","sourceRoot":"","sources":["../../
|
|
1
|
+
{"version":3,"file":"useReducerWithDeps.d.ts","sourceRoot":"","sources":["../../src/hooks/useReducerWithDeps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,cAAc,EAAuB,MAAM,OAAO,CAAC;AAOjE,cAAc;AAEd,MAAM,MAAM,YAAY,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;AAEtC,cAAc;AACd,MAAM,MAAM,cAAc,CAAC,SAAS,SAAS,YAAY,IAAI,CAC3D,GAAG,IAAI,EAAE,SAAS,KACf,IAAI,CAAC;AAEV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,CAAC,SAAS,YAAY,EAC1D,OAAO,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,EACxC,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAC5C,IAAI,EAAE,cAAc,GACnB,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,CAYxB"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { useCallback, useRef
|
|
2
|
-
import useStateWithDeps from './useStateWithDeps.js';
|
|
1
|
+
import { useCallback, useRef } from 'react';
|
|
2
|
+
import { useStateWithDeps } from './useStateWithDeps.js';
|
|
3
3
|
/**
|
|
4
|
-
* `useReducer` hook with an additional dependency array that resets the
|
|
5
|
-
* to
|
|
6
|
-
* change
|
|
4
|
+
* `useReducer` hook with an additional dependency array `deps` that resets the
|
|
5
|
+
* state to `initialState` when dependencies change
|
|
7
6
|
*
|
|
8
7
|
* ### On linter support
|
|
9
8
|
*
|
|
@@ -12,7 +11,7 @@ import useStateWithDeps from './useStateWithDeps.js';
|
|
|
12
11
|
* However, as we would like to keep the hook as compatible with `useReducer` as
|
|
13
12
|
* possible, we don't want to artificially change the parameter's position.
|
|
14
13
|
* Therefore, there will be no warnings about missing dependencies.
|
|
15
|
-
* Because of that,
|
|
14
|
+
* Because of that, additional caution is advised!
|
|
16
15
|
* Be sure to check no dependencies are missing from the `deps` array.
|
|
17
16
|
*
|
|
18
17
|
* Related issue: {@link https://github.com/facebook/react/issues/25443}.
|
|
@@ -20,20 +19,20 @@ import useStateWithDeps from './useStateWithDeps.js';
|
|
|
20
19
|
* Unlike `eslint-plugin-react-hooks` maintained by React's team, the unofficial
|
|
21
20
|
* `useExhaustiveDependencies` rule provided for Biome by Biome's team
|
|
22
21
|
* does actually have support for dependency arrays at other positions, see
|
|
23
|
-
* {@link https://biomejs.dev/linter/rules/use-exhaustive-dependencies/#validating-dependencies}.
|
|
22
|
+
* {@link https://biomejs.dev/linter/rules/use-exhaustive-dependencies/#validating-dependencies useExhaustiveDependencies > Options > Validating dependencies}.
|
|
24
23
|
*
|
|
25
24
|
* @param reducer The reducer function that specifies how the state gets updated
|
|
26
25
|
*
|
|
27
|
-
* @param initialState The
|
|
28
|
-
*
|
|
26
|
+
* @param initialState The value to which the state is set when the component is
|
|
27
|
+
* mounted or dependencies change
|
|
29
28
|
*
|
|
30
|
-
* It can also be a function
|
|
29
|
+
* It can also be a function that returns a state value. If the state is reset
|
|
31
30
|
* due to a change of dependencies, this function will be passed the previous
|
|
32
31
|
* state as its argument (will be `undefined` in the first call upon mount).
|
|
33
32
|
*
|
|
34
33
|
* @param deps Dependencies that reset the state to `initialState`
|
|
35
34
|
*/
|
|
36
|
-
export
|
|
35
|
+
export function useReducerWithDeps(reducer, initialState, deps) {
|
|
37
36
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
38
37
|
const [state, setState] = useStateWithDeps(initialState, deps);
|
|
39
38
|
// Only the initially provided reducer is used
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useReducerWithDeps.js","sourceRoot":"","sources":["../../
|
|
1
|
+
{"version":3,"file":"useReducerWithDeps.js","sourceRoot":"","sources":["../../src/hooks/useReducerWithDeps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,WAAW,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAezD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAwC,EACxC,YAA4C,EAC5C,IAAoB;IAEpB,uDAAuD;IACvD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAE/D,8CAA8C;IAC9C,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnC,MAAM,QAAQ,GAAG,WAAW,CAAC,SAAS,QAAQ,CAAC,GAAG,IAAO;QACvD,QAAQ,CAAC,CAAC,aAAa,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,kDAAkD;IAE1D,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AAC3B,CAAC"}
|