@ox0/hooks 0.2.0 → 0.2.2
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/LICENSE +21 -0
- package/README.md +225 -0
- package/dist/index.js +107 -104
- package/dist/use-controllable-state.d.ts +8 -0
- package/dist/use-controllable-state.d.ts.map +1 -1
- package/dist/use-controllable-state.test.d.ts +2 -0
- package/dist/use-controllable-state.test.d.ts.map +1 -0
- package/dist/use-debounced-value.d.ts.map +1 -1
- package/dist/use-debounced-value.test.d.ts +2 -0
- package/dist/use-debounced-value.test.d.ts.map +1 -0
- package/dist/use-deferred-presence.d.ts.map +1 -1
- package/dist/use-disclosure.test.d.ts +2 -0
- package/dist/use-disclosure.test.d.ts.map +1 -0
- package/dist/use-long-press.d.ts.map +1 -1
- package/dist/use-media-query.test.d.ts +2 -0
- package/dist/use-media-query.test.d.ts.map +1 -0
- package/dist/use-previous.d.ts.map +1 -1
- package/dist/use-stored-state.d.ts +1 -1
- package/dist/use-stored-state.d.ts.map +1 -1
- package/dist/use-stored-state.test.d.ts +2 -0
- package/dist/use-stored-state.test.d.ts.map +1 -0
- package/package.json +6 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Erik Sturcke
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# @ox0/hooks
|
|
2
|
+
|
|
3
|
+
Shared React hooks for ox0 applications. Every hook is SSR-safe unless noted.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @ox0/hooks
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Hooks
|
|
12
|
+
|
|
13
|
+
### State and control
|
|
14
|
+
|
|
15
|
+
#### `useControllableState<T>(options)`
|
|
16
|
+
|
|
17
|
+
Controlled/uncontrolled state bridge. Pass `value` + `onChange` for controlled mode; omit `value`
|
|
18
|
+
for uncontrolled. When uncontrolled, internal state resets to `defaultValue` whenever `defaultValue`
|
|
19
|
+
changes — pass stable primitives to avoid surprise resets.
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
const [val, setVal] = useControllableState({ defaultValue: "initial", value, onChange })
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
#### `useDisclosure(initialOpen?)`
|
|
26
|
+
|
|
27
|
+
Boolean open/close state. Returns `{ isOpen, onOpen, onClose, onToggle }` with stable callbacks.
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
const { isOpen, onOpen, onClose } = useDisclosure()
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
### Persistence
|
|
36
|
+
|
|
37
|
+
All storage hooks require a `<StorageProvider scope={userId ?? null}>` ancestor. The scope string
|
|
38
|
+
prefixes every key so different users sharing a browser do not mix data. Pass `scope={null}` to
|
|
39
|
+
opt out of scoping.
|
|
40
|
+
|
|
41
|
+
```tsx
|
|
42
|
+
import { StorageProvider } from "@ox0/hooks"
|
|
43
|
+
|
|
44
|
+
function App() {
|
|
45
|
+
return <StorageProvider scope={currentUserId}>{children}</StorageProvider>
|
|
46
|
+
}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
#### `usePersistentState(key, parser, options)`
|
|
50
|
+
|
|
51
|
+
`localStorage`, tab-private. Changes are not visible in other open tabs.
|
|
52
|
+
|
|
53
|
+
#### `usePersistentSharedState(key, parser, options)`
|
|
54
|
+
|
|
55
|
+
`localStorage`, shared across tabs. Changes broadcast via `BroadcastChannel` and the `storage`
|
|
56
|
+
event. All tabs with the same key stay in sync.
|
|
57
|
+
|
|
58
|
+
#### `useSessionState(key, parser, options)`
|
|
59
|
+
|
|
60
|
+
`sessionStorage`, tab-private.
|
|
61
|
+
|
|
62
|
+
#### `useSessionSharedState(key, parser, options)`
|
|
63
|
+
|
|
64
|
+
`sessionStorage`, shared within the tab (multiple hook instances on the same key sync via
|
|
65
|
+
in-tab pub/sub).
|
|
66
|
+
|
|
67
|
+
**Shared options:**
|
|
68
|
+
|
|
69
|
+
```ts
|
|
70
|
+
type StoredStateOptions<T> = {
|
|
71
|
+
defaultValue: T
|
|
72
|
+
version?: number // @default 1
|
|
73
|
+
migrate?: (value: unknown, fromVersion: number) => T
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Pass any object with a `.parse(unknown): T` method as the `parser` (Zod schemas work directly).
|
|
78
|
+
Use `version` + `migrate` to transform stored data when the shape changes:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
const [theme, setTheme] = usePersistentSharedState("ui:theme", ThemeSchema, {
|
|
82
|
+
defaultValue: "system",
|
|
83
|
+
version: 2,
|
|
84
|
+
migrate: (old, from) => (from === 1 ? "system" : "system"),
|
|
85
|
+
})
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
### Interaction
|
|
91
|
+
|
|
92
|
+
#### `usePress(props)` — re-export from React Aria
|
|
93
|
+
|
|
94
|
+
Cross-device press normalization for mouse, touch, keyboard (Space/Enter), and virtual pointer
|
|
95
|
+
(screen reader). Handles iOS text-selection conflicts and scroll-gesture cancellation. Prefer this
|
|
96
|
+
over raw `onClick` for custom interactive elements.
|
|
97
|
+
|
|
98
|
+
#### `useLongPress(options)`
|
|
99
|
+
|
|
100
|
+
Returns pointer event handlers that fire `onLongPress` after the pointer has been held for
|
|
101
|
+
`delayMs` (default 500ms) without moving beyond `moveThresholdPx` (default 8px). Cancels on
|
|
102
|
+
pointer up or excessive movement; suppresses the subsequent click.
|
|
103
|
+
|
|
104
|
+
#### `useKeyDown(key, callback, options?)`
|
|
105
|
+
|
|
106
|
+
Attaches a `keydown` listener to `window`. Modifier options: `ctrl`, `meta`, `shift`, `alt`.
|
|
107
|
+
Pass `enabled: false` to disable without removing the hook call.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
### DOM and browser
|
|
112
|
+
|
|
113
|
+
#### `useContainerSize<T extends HTMLElement>()`
|
|
114
|
+
|
|
115
|
+
Measures element content size via `ResizeObserver`. Returns `[ref, { width, height }]`. Attach
|
|
116
|
+
the ref to the element to observe.
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
const [ref, { width }] = useContainerSize<HTMLDivElement>()
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### `useEventListener(type, listener, target?)`
|
|
123
|
+
|
|
124
|
+
Attaches a typed event listener to `window` (default), a `Document`, `HTMLElement`, or a ref.
|
|
125
|
+
The listener ref is always up to date — no stale-closure issues.
|
|
126
|
+
|
|
127
|
+
#### `useHover<T extends HTMLElement>()`
|
|
128
|
+
|
|
129
|
+
Returns `[ref, isHovered]`. Uses `pointerenter`/`pointerleave` events.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
### Viewport and layout
|
|
134
|
+
|
|
135
|
+
#### `useBreakpoint()`
|
|
136
|
+
|
|
137
|
+
Tracks the current responsive breakpoint. Returns
|
|
138
|
+
`{ breakpoint, isMobile, isTablet, isDesktop, isMobileOrTablet, isTabletOrDesktop }`.
|
|
139
|
+
|
|
140
|
+
Breakpoints: mobile ≤ 767px, tablet ≤ 1023px, desktop > 1023px.
|
|
141
|
+
|
|
142
|
+
#### `useWindowSize()`
|
|
143
|
+
|
|
144
|
+
Tracks `{ width, height }` from `window.innerWidth`/`innerHeight`.
|
|
145
|
+
|
|
146
|
+
#### `useViewport()`
|
|
147
|
+
|
|
148
|
+
Tracks `{ visualViewportHeight, keyboardOpen }`. `keyboardOpen` is true when the on-screen
|
|
149
|
+
keyboard reduces the visual viewport by more than 150px — useful for mobile layouts.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
### Media queries and preferences
|
|
154
|
+
|
|
155
|
+
#### `useMediaQuery(query)`
|
|
156
|
+
|
|
157
|
+
Returns `true` when the CSS media query matches. Updates on change.
|
|
158
|
+
|
|
159
|
+
#### `usePointerCoarse()`
|
|
160
|
+
|
|
161
|
+
Returns `true` when the primary pointer is coarse (touch screen). Shorthand for
|
|
162
|
+
`useMediaQuery("(pointer: coarse)")`.
|
|
163
|
+
|
|
164
|
+
#### `usePrefersReducedMotion()`
|
|
165
|
+
|
|
166
|
+
Returns `true` when the user has requested reduced motion.
|
|
167
|
+
|
|
168
|
+
#### `useNavigatorOnline()`
|
|
169
|
+
|
|
170
|
+
Returns `true` when the browser reports a network connection. Updates on `online`/`offline` events.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
### OS and environment
|
|
175
|
+
|
|
176
|
+
#### `useOS(override?)`
|
|
177
|
+
|
|
178
|
+
Detects the runtime OS: `"mac" | "windows" | "linux" | "mobile"`. Useful for keyboard shortcut
|
|
179
|
+
labels. Pass `override` to force a value in tests or demos.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
### Timing
|
|
184
|
+
|
|
185
|
+
#### `useDebouncedValue<T>(value, delay?)`
|
|
186
|
+
|
|
187
|
+
Returns a debounced copy of `value` that only updates after `delay` ms (default 200ms) of no
|
|
188
|
+
changes.
|
|
189
|
+
|
|
190
|
+
#### `useInterval(callback, delay)`
|
|
191
|
+
|
|
192
|
+
Calls `callback` every `delay` ms. Pass `delay = null` to pause. Callback ref is always current.
|
|
193
|
+
|
|
194
|
+
#### `useTimeout(callback, delay)`
|
|
195
|
+
|
|
196
|
+
Calls `callback` once after `delay` ms. Pass `delay = null` to disable. Callback ref is always
|
|
197
|
+
current.
|
|
198
|
+
|
|
199
|
+
#### `useNow(options?)`
|
|
200
|
+
|
|
201
|
+
Returns the current `Date.now()` value, updating every `update` ms (default 1000ms). Pass
|
|
202
|
+
`update: false` to get a stable snapshot.
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
### Utilities
|
|
207
|
+
|
|
208
|
+
#### `usePrevious<T>(value)`
|
|
209
|
+
|
|
210
|
+
Returns the value from the previous render. Returns `undefined` on the first render.
|
|
211
|
+
|
|
212
|
+
#### `useCopyToClipboard(resetMs?)`
|
|
213
|
+
|
|
214
|
+
Returns `{ copy: (text: string) => Promise<void>, copied: boolean }`. `copied` resets to `false`
|
|
215
|
+
after `resetMs` ms (default 2000ms).
|
|
216
|
+
|
|
217
|
+
#### `useBeforeUnloadWarning(enabled)`
|
|
218
|
+
|
|
219
|
+
Shows the browser's native "leave page?" dialog when `enabled` is `true`. Use for unsaved-changes
|
|
220
|
+
guards.
|
|
221
|
+
|
|
222
|
+
#### `useDeferredPresence(options)`
|
|
223
|
+
|
|
224
|
+
Manages show/hide lifecycle with entry delay, minimum visible time, and exit duration. Returns
|
|
225
|
+
`"hidden" | "visible" | "exiting"`. Useful for tooltips, toasts, and animated presence.
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as __WEBPACK_EXTERNAL_MODULE__react_aria_interactions_8422cce9__ from "@react-aria/interactions";
|
|
1
|
+
import { createContext, createElement, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
3
2
|
function useBeforeUnloadWarning(enabled) {
|
|
4
|
-
|
|
5
|
-
if (!enabled || "
|
|
3
|
+
useEffect(()=>{
|
|
4
|
+
if (!enabled || "u" < typeof window) return;
|
|
6
5
|
const handle = (event)=>{
|
|
7
6
|
event.preventDefault();
|
|
8
7
|
event.returnValue = "";
|
|
@@ -16,7 +15,7 @@ function useBeforeUnloadWarning(enabled) {
|
|
|
16
15
|
const MOBILE_MAX = 767;
|
|
17
16
|
const TABLET_MAX = 1023;
|
|
18
17
|
function getBreakpoint() {
|
|
19
|
-
if ("
|
|
18
|
+
if ("u" < typeof window) return "desktop";
|
|
20
19
|
if (window.matchMedia(`(max-width: ${MOBILE_MAX}px)`).matches) return "mobile";
|
|
21
20
|
if (window.matchMedia(`(max-width: ${TABLET_MAX}px)`).matches) return "tablet";
|
|
22
21
|
return "desktop";
|
|
@@ -32,9 +31,9 @@ function toState(breakpoint) {
|
|
|
32
31
|
};
|
|
33
32
|
}
|
|
34
33
|
function useBreakpoint() {
|
|
35
|
-
const [state, setState] =
|
|
36
|
-
|
|
37
|
-
if ("
|
|
34
|
+
const [state, setState] = useState(()=>toState(getBreakpoint()));
|
|
35
|
+
useEffect(()=>{
|
|
36
|
+
if ("u" < typeof window) return;
|
|
38
37
|
const mobileQuery = window.matchMedia(`(max-width: ${MOBILE_MAX}px)`);
|
|
39
38
|
const tabletQuery = window.matchMedia(`(max-width: ${TABLET_MAX}px)`);
|
|
40
39
|
const handleChange = ()=>{
|
|
@@ -54,12 +53,12 @@ function useBreakpoint() {
|
|
|
54
53
|
return state;
|
|
55
54
|
}
|
|
56
55
|
function useContainerSize() {
|
|
57
|
-
const ref =
|
|
58
|
-
const [size, setSize] =
|
|
56
|
+
const ref = useRef(null);
|
|
57
|
+
const [size, setSize] = useState({
|
|
59
58
|
width: 0,
|
|
60
59
|
height: 0
|
|
61
60
|
});
|
|
62
|
-
|
|
61
|
+
useEffect(()=>{
|
|
63
62
|
const el = ref.current;
|
|
64
63
|
if (!el) return;
|
|
65
64
|
const observer = new ResizeObserver((entries)=>{
|
|
@@ -84,10 +83,10 @@ function useContainerSize() {
|
|
|
84
83
|
}
|
|
85
84
|
function useControllableState(options) {
|
|
86
85
|
const { defaultValue, onChange, value } = options;
|
|
87
|
-
const [uncontrolledValue, setUncontrolledValue] =
|
|
86
|
+
const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
|
|
88
87
|
const isControlled = void 0 !== value;
|
|
89
88
|
const currentValue = void 0 !== value ? value : uncontrolledValue;
|
|
90
|
-
|
|
89
|
+
useEffect(()=>{
|
|
91
90
|
if (!isControlled) setUncontrolledValue(defaultValue);
|
|
92
91
|
}, [
|
|
93
92
|
defaultValue,
|
|
@@ -103,12 +102,12 @@ function useControllableState(options) {
|
|
|
103
102
|
];
|
|
104
103
|
}
|
|
105
104
|
function useCopyToClipboard(resetMs = 2000) {
|
|
106
|
-
const [copied, setCopied] =
|
|
107
|
-
const timerRef =
|
|
108
|
-
|
|
105
|
+
const [copied, setCopied] = useState(false);
|
|
106
|
+
const timerRef = useRef(null);
|
|
107
|
+
useEffect(()=>()=>{
|
|
109
108
|
if (null !== timerRef.current) clearTimeout(timerRef.current);
|
|
110
109
|
}, []);
|
|
111
|
-
const copy =
|
|
110
|
+
const copy = useCallback(async (text)=>{
|
|
112
111
|
try {
|
|
113
112
|
await navigator.clipboard.writeText(text);
|
|
114
113
|
setCopied(true);
|
|
@@ -124,8 +123,8 @@ function useCopyToClipboard(resetMs = 2000) {
|
|
|
124
123
|
};
|
|
125
124
|
}
|
|
126
125
|
function useDebouncedValue(value, delay = 200) {
|
|
127
|
-
const [debouncedValue, setDebouncedValue] =
|
|
128
|
-
|
|
126
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
127
|
+
useEffect(()=>{
|
|
129
128
|
const timeoutId = window.setTimeout(()=>{
|
|
130
129
|
setDebouncedValue(value);
|
|
131
130
|
}, delay);
|
|
@@ -139,21 +138,18 @@ function useDebouncedValue(value, delay = 200) {
|
|
|
139
138
|
return debouncedValue;
|
|
140
139
|
}
|
|
141
140
|
function useDeferredPresence(isPresent, { delayMs, exitMs, minimumVisibleMs }) {
|
|
142
|
-
const [state, setState] =
|
|
141
|
+
const [state, setState] = useState({
|
|
143
142
|
phase: "hidden"
|
|
144
143
|
});
|
|
145
|
-
const timerRef =
|
|
146
|
-
|
|
144
|
+
const timerRef = useRef(void 0);
|
|
145
|
+
useEffect(()=>{
|
|
147
146
|
clearTimeout(timerRef.current);
|
|
148
147
|
if (isPresent) {
|
|
149
148
|
if ("visible" === state.phase) return;
|
|
150
|
-
if ("exiting" === state.phase) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
});
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
149
|
+
if ("exiting" === state.phase) return void setState({
|
|
150
|
+
phase: "visible",
|
|
151
|
+
shownAt: state.shownAt
|
|
152
|
+
});
|
|
157
153
|
timerRef.current = window.setTimeout(()=>{
|
|
158
154
|
setState({
|
|
159
155
|
phase: "visible",
|
|
@@ -183,14 +179,14 @@ function useDeferredPresence(isPresent, { delayMs, exitMs, minimumVisibleMs }) {
|
|
|
183
179
|
return state.phase;
|
|
184
180
|
}
|
|
185
181
|
function useDisclosure(initialOpen = false) {
|
|
186
|
-
const [isOpen, setIsOpen] =
|
|
187
|
-
const onClose =
|
|
182
|
+
const [isOpen, setIsOpen] = useState(initialOpen);
|
|
183
|
+
const onClose = useCallback(()=>{
|
|
188
184
|
setIsOpen(false);
|
|
189
185
|
}, []);
|
|
190
|
-
const onOpen =
|
|
186
|
+
const onOpen = useCallback(()=>{
|
|
191
187
|
setIsOpen(true);
|
|
192
188
|
}, []);
|
|
193
|
-
const onToggle =
|
|
189
|
+
const onToggle = useCallback(()=>{
|
|
194
190
|
setIsOpen((value)=>!value);
|
|
195
191
|
}, []);
|
|
196
192
|
return {
|
|
@@ -201,13 +197,13 @@ function useDisclosure(initialOpen = false) {
|
|
|
201
197
|
};
|
|
202
198
|
}
|
|
203
199
|
function useEventListener(type, listener, target) {
|
|
204
|
-
const listenerRef =
|
|
205
|
-
|
|
200
|
+
const listenerRef = useRef(listener);
|
|
201
|
+
useEffect(()=>{
|
|
206
202
|
listenerRef.current = listener;
|
|
207
203
|
}, [
|
|
208
204
|
listener
|
|
209
205
|
]);
|
|
210
|
-
|
|
206
|
+
useEffect(()=>{
|
|
211
207
|
const el = void 0 === target ? window : target && "current" in target ? target.current : target;
|
|
212
208
|
if (!el) return;
|
|
213
209
|
const handler = (e)=>listenerRef.current(e);
|
|
@@ -219,9 +215,9 @@ function useEventListener(type, listener, target) {
|
|
|
219
215
|
]);
|
|
220
216
|
}
|
|
221
217
|
function useHover() {
|
|
222
|
-
const ref =
|
|
223
|
-
const [hovered, setHovered] =
|
|
224
|
-
|
|
218
|
+
const ref = useRef(null);
|
|
219
|
+
const [hovered, setHovered] = useState(false);
|
|
220
|
+
useEffect(()=>{
|
|
225
221
|
const el = ref.current;
|
|
226
222
|
if (!el) return;
|
|
227
223
|
const enter = ()=>setHovered(true);
|
|
@@ -239,13 +235,13 @@ function useHover() {
|
|
|
239
235
|
];
|
|
240
236
|
}
|
|
241
237
|
function useInterval(callback, delay) {
|
|
242
|
-
const callbackRef =
|
|
243
|
-
|
|
238
|
+
const callbackRef = useRef(callback);
|
|
239
|
+
useEffect(()=>{
|
|
244
240
|
callbackRef.current = callback;
|
|
245
241
|
}, [
|
|
246
242
|
callback
|
|
247
243
|
]);
|
|
248
|
-
|
|
244
|
+
useEffect(()=>{
|
|
249
245
|
if (null === delay) return;
|
|
250
246
|
const id = window.setInterval(()=>callbackRef.current(), delay);
|
|
251
247
|
return ()=>window.clearInterval(id);
|
|
@@ -254,13 +250,13 @@ function useInterval(callback, delay) {
|
|
|
254
250
|
]);
|
|
255
251
|
}
|
|
256
252
|
function useKeyDown(key, callback, { ctrl = false, meta = false, shift = false, alt = false, enabled = true } = {}) {
|
|
257
|
-
const callbackRef =
|
|
258
|
-
|
|
253
|
+
const callbackRef = useRef(callback);
|
|
254
|
+
useEffect(()=>{
|
|
259
255
|
callbackRef.current = callback;
|
|
260
256
|
}, [
|
|
261
257
|
callback
|
|
262
258
|
]);
|
|
263
|
-
|
|
259
|
+
useEffect(()=>{
|
|
264
260
|
if (!enabled) return;
|
|
265
261
|
const handler = (e)=>{
|
|
266
262
|
if (e.key !== key) return;
|
|
@@ -284,8 +280,12 @@ function useKeyDown(key, callback, { ctrl = false, meta = false, shift = false,
|
|
|
284
280
|
const instanceId = `${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
285
281
|
const tabSubscribers = new Map();
|
|
286
282
|
function tabSubscribe(key, fn) {
|
|
287
|
-
|
|
288
|
-
|
|
283
|
+
let tabSet = tabSubscribers.get(key);
|
|
284
|
+
if (!tabSet) {
|
|
285
|
+
tabSet = new Set();
|
|
286
|
+
tabSubscribers.set(key, tabSet);
|
|
287
|
+
}
|
|
288
|
+
tabSet.add(fn);
|
|
289
289
|
return ()=>{
|
|
290
290
|
const set = tabSubscribers.get(key);
|
|
291
291
|
set?.delete(fn);
|
|
@@ -298,7 +298,7 @@ function tabNotify(key, value) {
|
|
|
298
298
|
const crossTabSubscribers = new Map();
|
|
299
299
|
let broadcastChannel = null;
|
|
300
300
|
function getChannel() {
|
|
301
|
-
if ("
|
|
301
|
+
if ("u" < typeof window || "u" < typeof BroadcastChannel) return null;
|
|
302
302
|
if (!broadcastChannel) {
|
|
303
303
|
broadcastChannel = new BroadcastChannel("ox0:storage");
|
|
304
304
|
broadcastChannel.addEventListener("message", (e)=>{
|
|
@@ -308,8 +308,12 @@ function getChannel() {
|
|
|
308
308
|
return broadcastChannel;
|
|
309
309
|
}
|
|
310
310
|
function crossTabSubscribe(key, fn) {
|
|
311
|
-
|
|
312
|
-
|
|
311
|
+
let crossTabSet = crossTabSubscribers.get(key);
|
|
312
|
+
if (!crossTabSet) {
|
|
313
|
+
crossTabSet = new Set();
|
|
314
|
+
crossTabSubscribers.set(key, crossTabSet);
|
|
315
|
+
}
|
|
316
|
+
crossTabSet.add(fn);
|
|
313
317
|
getChannel();
|
|
314
318
|
return ()=>{
|
|
315
319
|
const set = crossTabSubscribers.get(key);
|
|
@@ -318,7 +322,7 @@ function crossTabSubscribe(key, fn) {
|
|
|
318
322
|
};
|
|
319
323
|
}
|
|
320
324
|
function getTabId() {
|
|
321
|
-
if ("
|
|
325
|
+
if ("u" < typeof sessionStorage) return instanceId;
|
|
322
326
|
const existing = sessionStorage.getItem("ox0:tab-id");
|
|
323
327
|
if (existing) return existing;
|
|
324
328
|
const next = `${Date.now()}-${Math.random().toString(16).slice(2)}`;
|
|
@@ -326,7 +330,7 @@ function getTabId() {
|
|
|
326
330
|
return next;
|
|
327
331
|
}
|
|
328
332
|
function getStorage(kind) {
|
|
329
|
-
if ("
|
|
333
|
+
if ("u" < typeof window) return null;
|
|
330
334
|
return "persistent" === kind ? window.localStorage : window.sessionStorage;
|
|
331
335
|
}
|
|
332
336
|
function makeStorageKey(key, kind, shared, scope) {
|
|
@@ -346,7 +350,7 @@ function readSafe(raw, parser, defaultValue, version, migrate) {
|
|
|
346
350
|
migrated: false
|
|
347
351
|
};
|
|
348
352
|
if (parsed.v !== version) return migrate ? {
|
|
349
|
-
value: migrate(parsed.value, parsed.v),
|
|
353
|
+
value: parser.parse(migrate(parsed.value, parsed.v)),
|
|
350
354
|
migrated: true
|
|
351
355
|
} : {
|
|
352
356
|
value: defaultValue,
|
|
@@ -374,49 +378,49 @@ function writeStorage(storage, key, value, version) {
|
|
|
374
378
|
} catch {}
|
|
375
379
|
return raw;
|
|
376
380
|
}
|
|
377
|
-
const StorageScopeContext =
|
|
381
|
+
const StorageScopeContext = createContext(void 0);
|
|
378
382
|
function StorageProvider({ scope, children }) {
|
|
379
|
-
return
|
|
383
|
+
return createElement(StorageScopeContext.Provider, {
|
|
380
384
|
value: scope
|
|
381
385
|
}, children);
|
|
382
386
|
}
|
|
383
387
|
function useStorageScope() {
|
|
384
|
-
const scope =
|
|
388
|
+
const scope = useContext(StorageScopeContext);
|
|
385
389
|
if (void 0 === scope) throw new Error("useStoredState: no StorageProvider found. Wrap your app with <StorageProvider scope={userId ?? null}>.");
|
|
386
390
|
return scope;
|
|
387
391
|
}
|
|
388
392
|
function useStoredState(kind, key, parser, { defaultValue, version = 1, migrate }, shared) {
|
|
389
393
|
const scope = useStorageScope();
|
|
390
394
|
const storage = getStorage(kind);
|
|
391
|
-
const storageKey =
|
|
395
|
+
const storageKey = useMemo(()=>makeStorageKey(key, kind, shared, scope), [
|
|
392
396
|
key,
|
|
393
397
|
kind,
|
|
394
398
|
shared,
|
|
395
399
|
scope
|
|
396
400
|
]);
|
|
397
|
-
const parserRef =
|
|
398
|
-
const defaultValueRef =
|
|
399
|
-
const versionRef =
|
|
400
|
-
const migrateRef =
|
|
401
|
-
|
|
401
|
+
const parserRef = useRef(parser);
|
|
402
|
+
const defaultValueRef = useRef(defaultValue);
|
|
403
|
+
const versionRef = useRef(version);
|
|
404
|
+
const migrateRef = useRef(migrate);
|
|
405
|
+
useEffect(()=>{
|
|
402
406
|
parserRef.current = parser;
|
|
403
407
|
defaultValueRef.current = defaultValue;
|
|
404
408
|
versionRef.current = version;
|
|
405
409
|
migrateRef.current = migrate;
|
|
406
410
|
});
|
|
407
|
-
const [value, setValueState] =
|
|
411
|
+
const [value, setValueState] = useState(()=>{
|
|
408
412
|
const raw = storage?.getItem(storageKey) ?? null;
|
|
409
413
|
const result = readSafe(raw, parser, defaultValue, version, migrate);
|
|
410
414
|
if (result.migrated) writeStorage(storage, storageKey, result.value, version);
|
|
411
415
|
return result.value;
|
|
412
416
|
});
|
|
413
|
-
const valueRef =
|
|
414
|
-
|
|
417
|
+
const valueRef = useRef(value);
|
|
418
|
+
useEffect(()=>{
|
|
415
419
|
valueRef.current = value;
|
|
416
420
|
}, [
|
|
417
421
|
value
|
|
418
422
|
]);
|
|
419
|
-
|
|
423
|
+
useEffect(()=>{
|
|
420
424
|
const raw = storage?.getItem(storageKey) ?? null;
|
|
421
425
|
const result = readSafe(raw, parserRef.current, defaultValueRef.current, versionRef.current, migrateRef.current);
|
|
422
426
|
setValueState((prev)=>Object.is(prev, result.value) ? prev : result.value);
|
|
@@ -425,12 +429,12 @@ function useStoredState(kind, key, parser, { defaultValue, version = 1, migrate
|
|
|
425
429
|
storage,
|
|
426
430
|
storageKey
|
|
427
431
|
]);
|
|
428
|
-
|
|
432
|
+
useEffect(()=>tabSubscribe(storageKey, (next)=>{
|
|
429
433
|
setValueState((prev)=>Object.is(prev, next) ? prev : next);
|
|
430
434
|
}), [
|
|
431
435
|
storageKey
|
|
432
436
|
]);
|
|
433
|
-
|
|
437
|
+
useEffect(()=>{
|
|
434
438
|
if (!shared) return;
|
|
435
439
|
return crossTabSubscribe(storageKey, (msg)=>{
|
|
436
440
|
if (msg.storage !== kind || msg.sourceId === instanceId) return;
|
|
@@ -445,8 +449,8 @@ function useStoredState(kind, key, parser, { defaultValue, version = 1, migrate
|
|
|
445
449
|
storage,
|
|
446
450
|
storageKey
|
|
447
451
|
]);
|
|
448
|
-
|
|
449
|
-
if (!shared || "persistent" !== kind || "
|
|
452
|
+
useEffect(()=>{
|
|
453
|
+
if (!shared || "persistent" !== kind || "u" < typeof window) return;
|
|
450
454
|
const handler = (event)=>{
|
|
451
455
|
if (event.key !== storageKey) return;
|
|
452
456
|
const result = readSafe(event.newValue, parserRef.current, defaultValueRef.current, versionRef.current, migrateRef.current);
|
|
@@ -462,7 +466,7 @@ function useStoredState(kind, key, parser, { defaultValue, version = 1, migrate
|
|
|
462
466
|
storage,
|
|
463
467
|
storageKey
|
|
464
468
|
]);
|
|
465
|
-
const setValue =
|
|
469
|
+
const setValue = useCallback((next)=>{
|
|
466
470
|
const resolved = "function" == typeof next ? next(valueRef.current) : next;
|
|
467
471
|
if (Object.is(valueRef.current, resolved)) return;
|
|
468
472
|
valueRef.current = resolved;
|
|
@@ -499,10 +503,10 @@ function useSessionSharedState(key, parser, options) {
|
|
|
499
503
|
return useStoredState("session", key, parser, options, true);
|
|
500
504
|
}
|
|
501
505
|
function useLongPress({ delayMs = 500, moveThresholdPx = 8, disabled = false, onLongPress }) {
|
|
502
|
-
const timerRef =
|
|
503
|
-
const pointerIdRef =
|
|
504
|
-
const startRef =
|
|
505
|
-
const triggeredRef =
|
|
506
|
+
const timerRef = useRef(null);
|
|
507
|
+
const pointerIdRef = useRef(null);
|
|
508
|
+
const startRef = useRef(null);
|
|
509
|
+
const triggeredRef = useRef(false);
|
|
506
510
|
const clearTimer = ()=>{
|
|
507
511
|
if (null == timerRef.current) return;
|
|
508
512
|
window.clearTimeout(timerRef.current);
|
|
@@ -513,7 +517,7 @@ function useLongPress({ delayMs = 500, moveThresholdPx = 8, disabled = false, on
|
|
|
513
517
|
pointerIdRef.current = null;
|
|
514
518
|
startRef.current = null;
|
|
515
519
|
};
|
|
516
|
-
|
|
520
|
+
useEffect(()=>{
|
|
517
521
|
if (disabled) {
|
|
518
522
|
triggeredRef.current = false;
|
|
519
523
|
reset();
|
|
@@ -521,7 +525,7 @@ function useLongPress({ delayMs = 500, moveThresholdPx = 8, disabled = false, on
|
|
|
521
525
|
}, [
|
|
522
526
|
disabled
|
|
523
527
|
]);
|
|
524
|
-
|
|
528
|
+
useEffect(()=>()=>clearTimer(), []);
|
|
525
529
|
return {
|
|
526
530
|
onPointerDown (event) {
|
|
527
531
|
if (disabled || 0 !== event.button) return;
|
|
@@ -563,10 +567,10 @@ function useLongPress({ delayMs = 500, moveThresholdPx = 8, disabled = false, on
|
|
|
563
567
|
};
|
|
564
568
|
}
|
|
565
569
|
function useMediaQuery(query) {
|
|
566
|
-
const getMatches = ()=>"
|
|
567
|
-
const [matches, setMatches] =
|
|
568
|
-
|
|
569
|
-
if ("
|
|
570
|
+
const getMatches = ()=>"u" > typeof window && window.matchMedia(query).matches;
|
|
571
|
+
const [matches, setMatches] = useState(getMatches);
|
|
572
|
+
useEffect(()=>{
|
|
573
|
+
if ("u" < typeof window) return;
|
|
570
574
|
const mediaQuery = window.matchMedia(query);
|
|
571
575
|
const update = ()=>{
|
|
572
576
|
setMatches(mediaQuery.matches);
|
|
@@ -582,9 +586,9 @@ function useMediaQuery(query) {
|
|
|
582
586
|
return matches;
|
|
583
587
|
}
|
|
584
588
|
function useNavigatorOnline() {
|
|
585
|
-
const [isOnline, setIsOnline] =
|
|
586
|
-
|
|
587
|
-
if ("
|
|
589
|
+
const [isOnline, setIsOnline] = useState(()=>"u" < typeof navigator ? true : navigator.onLine);
|
|
590
|
+
useEffect(()=>{
|
|
591
|
+
if ("u" < typeof window) return;
|
|
588
592
|
const sync = ()=>setIsOnline(navigator.onLine);
|
|
589
593
|
window.addEventListener("online", sync);
|
|
590
594
|
window.addEventListener("offline", sync);
|
|
@@ -596,8 +600,8 @@ function useNavigatorOnline() {
|
|
|
596
600
|
return isOnline;
|
|
597
601
|
}
|
|
598
602
|
function useNow({ update = 1000 } = {}) {
|
|
599
|
-
const [now, setNow] =
|
|
600
|
-
|
|
603
|
+
const [now, setNow] = useState(()=>Date.now());
|
|
604
|
+
useEffect(()=>{
|
|
601
605
|
if (false === update) return;
|
|
602
606
|
const id = window.setInterval(()=>setNow(Date.now()), update);
|
|
603
607
|
return ()=>window.clearInterval(id);
|
|
@@ -607,7 +611,7 @@ function useNow({ update = 1000 } = {}) {
|
|
|
607
611
|
return now;
|
|
608
612
|
}
|
|
609
613
|
function detectOS() {
|
|
610
|
-
if ("
|
|
614
|
+
if ("u" < typeof navigator) return "windows";
|
|
611
615
|
const ua = navigator.userAgent.toLowerCase();
|
|
612
616
|
const platform = (navigator.platform ?? "").toLowerCase();
|
|
613
617
|
const combined = `${ua} ${platform}`;
|
|
@@ -618,7 +622,7 @@ function detectOS() {
|
|
|
618
622
|
return "windows";
|
|
619
623
|
}
|
|
620
624
|
function useOS(override) {
|
|
621
|
-
return
|
|
625
|
+
return useMemo(()=>override ?? detectOS(), [
|
|
622
626
|
override
|
|
623
627
|
]);
|
|
624
628
|
}
|
|
@@ -629,8 +633,8 @@ function usePrefersReducedMotion() {
|
|
|
629
633
|
return useMediaQuery("(prefers-reduced-motion: reduce)");
|
|
630
634
|
}
|
|
631
635
|
function usePrevious(value) {
|
|
632
|
-
const ref =
|
|
633
|
-
|
|
636
|
+
const ref = useRef(void 0);
|
|
637
|
+
useEffect(()=>{
|
|
634
638
|
ref.current = value;
|
|
635
639
|
}, [
|
|
636
640
|
value
|
|
@@ -638,13 +642,13 @@ function usePrevious(value) {
|
|
|
638
642
|
return ref.current;
|
|
639
643
|
}
|
|
640
644
|
function useTimeout(callback, delay) {
|
|
641
|
-
const callbackRef =
|
|
642
|
-
|
|
645
|
+
const callbackRef = useRef(callback);
|
|
646
|
+
useEffect(()=>{
|
|
643
647
|
callbackRef.current = callback;
|
|
644
648
|
}, [
|
|
645
649
|
callback
|
|
646
650
|
]);
|
|
647
|
-
|
|
651
|
+
useEffect(()=>{
|
|
648
652
|
if (null === delay) return;
|
|
649
653
|
const id = window.setTimeout(()=>callbackRef.current(), delay);
|
|
650
654
|
return ()=>window.clearTimeout(id);
|
|
@@ -654,7 +658,7 @@ function useTimeout(callback, delay) {
|
|
|
654
658
|
}
|
|
655
659
|
const KEYBOARD_OPEN_DELTA = 150;
|
|
656
660
|
function getViewportState() {
|
|
657
|
-
if ("
|
|
661
|
+
if ("u" < typeof window) return {
|
|
658
662
|
visualViewportHeight: 0,
|
|
659
663
|
keyboardOpen: false
|
|
660
664
|
};
|
|
@@ -666,9 +670,9 @@ function getViewportState() {
|
|
|
666
670
|
};
|
|
667
671
|
}
|
|
668
672
|
function useViewport() {
|
|
669
|
-
const [state, setState] =
|
|
670
|
-
|
|
671
|
-
if ("
|
|
673
|
+
const [state, setState] = useState(()=>getViewportState());
|
|
674
|
+
useEffect(()=>{
|
|
675
|
+
if ("u" < typeof window) return;
|
|
672
676
|
const target = window.visualViewport ?? window;
|
|
673
677
|
const handleChange = ()=>{
|
|
674
678
|
setState((prev)=>{
|
|
@@ -687,7 +691,7 @@ function useViewport() {
|
|
|
687
691
|
return state;
|
|
688
692
|
}
|
|
689
693
|
function getWindowSize() {
|
|
690
|
-
if ("
|
|
694
|
+
if ("u" < typeof window) return {
|
|
691
695
|
width: 0,
|
|
692
696
|
height: 0
|
|
693
697
|
};
|
|
@@ -697,9 +701,9 @@ function getWindowSize() {
|
|
|
697
701
|
};
|
|
698
702
|
}
|
|
699
703
|
function useWindowSize() {
|
|
700
|
-
const [size, setSize] =
|
|
701
|
-
|
|
702
|
-
if ("
|
|
704
|
+
const [size, setSize] = useState(getWindowSize);
|
|
705
|
+
useEffect(()=>{
|
|
706
|
+
if ("u" < typeof window) return;
|
|
703
707
|
const handleResize = ()=>{
|
|
704
708
|
setSize((prev)=>{
|
|
705
709
|
const next = getWindowSize();
|
|
@@ -712,6 +716,5 @@ function useWindowSize() {
|
|
|
712
716
|
}, []);
|
|
713
717
|
return size;
|
|
714
718
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
export { StorageProvider, useBeforeUnloadWarning, useBreakpoint, useContainerSize, useControllableState, useCopyToClipboard, useDebouncedValue, useDeferredPresence, useDisclosure, useEventListener, useHover, useInterval, useKeyDown, useLongPress, useMediaQuery, useNavigatorOnline, useNow, useOS, usePersistentSharedState, usePersistentState, usePointerCoarse, usePrefersReducedMotion, usePrevious, useSessionSharedState, useSessionState, useTimeout, useViewport, useWindowSize, __webpack_exports__isFocusVisible as isFocusVisible, __webpack_exports__usePress as usePress };
|
|
719
|
+
export { isFocusVisible, usePress } from "@react-aria/interactions";
|
|
720
|
+
export { StorageProvider, useBeforeUnloadWarning, useBreakpoint, useContainerSize, useControllableState, useCopyToClipboard, useDebouncedValue, useDeferredPresence, useDisclosure, useEventListener, useHover, useInterval, useKeyDown, useLongPress, useMediaQuery, useNavigatorOnline, useNow, useOS, usePersistentSharedState, usePersistentState, usePointerCoarse, usePrefersReducedMotion, usePrevious, useSessionSharedState, useSessionState, useTimeout, useViewport, useWindowSize };
|
|
@@ -3,5 +3,13 @@ export interface UseControllableStateOptions<TValue> {
|
|
|
3
3
|
readonly onChange?: (value: TValue) => void;
|
|
4
4
|
readonly value?: TValue;
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* Controlled/uncontrolled state bridge.
|
|
8
|
+
*
|
|
9
|
+
* Design decision: in uncontrolled mode, internal state resets to `defaultValue` whenever
|
|
10
|
+
* `defaultValue` changes. This is intentional — it supports controlled→uncontrolled transitions
|
|
11
|
+
* (e.g. when a parent stops passing `value`). Pass a stable primitive as `defaultValue` to avoid
|
|
12
|
+
* surprise resets.
|
|
13
|
+
*/
|
|
6
14
|
export declare function useControllableState<TValue>(options: UseControllableStateOptions<TValue>): [TValue, (nextValue: TValue) => void];
|
|
7
15
|
//# sourceMappingURL=use-controllable-state.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-controllable-state.d.ts","sourceRoot":"","sources":["../src/use-controllable-state.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,2BAA2B,CAAC,MAAM;IACjD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EACzC,OAAO,EAAE,2BAA2B,CAAC,MAAM,CAAC,GAC3C,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"use-controllable-state.d.ts","sourceRoot":"","sources":["../src/use-controllable-state.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,2BAA2B,CAAC,MAAM;IACjD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IAC3C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CACxB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EACzC,OAAO,EAAE,2BAA2B,CAAC,MAAM,CAAC,GAC3C,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC,CAqBvC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-controllable-state.test.d.ts","sourceRoot":"","sources":["../src/use-controllable-state.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-debounced-value.d.ts","sourceRoot":"","sources":["../src/use-debounced-value.ts"],"names":[],"mappings":"AAEA,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"use-debounced-value.d.ts","sourceRoot":"","sources":["../src/use-debounced-value.ts"],"names":[],"mappings":"AAEA,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,SAAM,GAAG,MAAM,CAe5E"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-debounced-value.test.d.ts","sourceRoot":"","sources":["../src/use-debounced-value.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-deferred-presence.d.ts","sourceRoot":"","sources":["../src/use-deferred-presence.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAA;AAIpE,MAAM,WAAW,uBAAuB;IACtC,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAA;IACd,wEAAwE;IACxE,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,OAAO,EAClB,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAAE,uBAAuB,GAC7D,qBAAqB,
|
|
1
|
+
{"version":3,"file":"use-deferred-presence.d.ts","sourceRoot":"","sources":["../src/use-deferred-presence.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAA;AAIpE,MAAM,WAAW,uBAAuB;IACtC,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,yCAAyC;IACzC,MAAM,EAAE,MAAM,CAAA;IACd,wEAAwE;IACxE,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,OAAO,EAClB,EAAE,OAAO,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAAE,uBAAuB,GAC7D,qBAAqB,CA+BvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-disclosure.test.d.ts","sourceRoot":"","sources":["../src/use-disclosure.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-long-press.d.ts","sourceRoot":"","sources":["../src/use-long-press.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,IAAI,eAAe,EAAE,YAAY,IAAI,iBAAiB,EAAE,MAAM,OAAO,CAAA;AAG7F,MAAM,WAAW,mBAAmB;IAClC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6EAA6E;IAC7E,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,EAAE,MAAM,IAAI,CAAA;CACxB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAC3B,OAAa,EACb,eAAmB,EACnB,QAAgB,EAChB,WAAW,GACZ,EAAE,mBAAmB;
|
|
1
|
+
{"version":3,"file":"use-long-press.d.ts","sourceRoot":"","sources":["../src/use-long-press.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,IAAI,eAAe,EAAE,YAAY,IAAI,iBAAiB,EAAE,MAAM,OAAO,CAAA;AAG7F,MAAM,WAAW,mBAAmB;IAClC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6EAA6E;IAC7E,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,WAAW,EAAE,MAAM,IAAI,CAAA;CACxB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAC3B,OAAa,EACb,eAAmB,EACnB,QAAgB,EAChB,WAAW,GACZ,EAAE,mBAAmB;IA8BlB,aAAa,QAAQ,iBAAiB,CAAC,WAAW,CAAC;IAcnD,aAAa,QAAQ,iBAAiB,CAAC,WAAW,CAAC;IAMnD,WAAW,QAAQ,iBAAiB,CAAC,WAAW,CAAC;IAIjD,eAAe,QAAQ,iBAAiB,CAAC,WAAW,CAAC;IAIrD,cAAc,QAAQ,eAAe,CAAC,WAAW,CAAC;EAQrD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-media-query.test.d.ts","sourceRoot":"","sources":["../src/use-media-query.test.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-previous.d.ts","sourceRoot":"","sources":["../src/use-previous.ts"],"names":[],"mappings":"AAEA,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"use-previous.d.ts","sourceRoot":"","sources":["../src/use-previous.ts"],"names":[],"mappings":"AAEA,wBAAgB,WAAW,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS,CAOtD"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
|
-
/** Anything with a `.parse` method — Zod schemas
|
|
2
|
+
/** Anything with a `.parse` method that throws on invalid input — `@ox0/schema` and Zod schemas fit. */
|
|
3
3
|
export type Parser<T> = {
|
|
4
4
|
parse: (value: unknown) => T;
|
|
5
5
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-stored-state.d.ts","sourceRoot":"","sources":["../src/use-stored-state.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,
|
|
1
|
+
{"version":3,"file":"use-stored-state.d.ts","sourceRoot":"","sources":["../src/use-stored-state.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,wGAAwG;AACxG,MAAM,MAAM,MAAM,CAAC,CAAC,IAAI;IAAE,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC,CAAA;CAAE,CAAA;AAExD,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI;IAClC,YAAY,EAAE,CAAC,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,KAAK,CAAC,CAAA;CACrD,CAAA;AA2HD,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,QAAQ,EAAE,SAAS,CAAA;CACpB,sGAEA;AAuID,iCAAiC;AACjC,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,uCAzHO,IAAI,EA4H1C;AAED,wCAAwC;AACxC,wBAAgB,wBAAwB,CAAC,CAAC,EACxC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,uCAlIO,IAAI,EAqI1C;AAED,mCAAmC;AACnC,wBAAgB,eAAe,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,uCAxI1D,IAAI,EA0I1C;AAED,yCAAyC;AACzC,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,EACjB,OAAO,EAAE,kBAAkB,CAAC,CAAC,CAAC,uCAhJO,IAAI,EAmJ1C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-stored-state.test.d.ts","sourceRoot":"","sources":["../src/use-stored-state.test.tsx"],"names":[],"mappings":""}
|