@tanstack/react-router 1.45.15 → 1.46.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.
@@ -48,173 +48,214 @@ export type TrailingSlashOption = 'always' | 'never' | 'preserve';
48
48
  export interface RouterOptions<TRouteTree extends AnyRoute, TTrailingSlashOption extends TrailingSlashOption, TDehydrated extends Record<string, any> = Record<string, any>, TSerializedError extends Record<string, any> = Record<string, any>> {
49
49
  /**
50
50
  * The history object that will be used to manage the browser history.
51
+ *
51
52
  * If not provided, a new createBrowserHistory instance will be created and used.
53
+ *
52
54
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#history-property)
53
55
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/history-types)
54
56
  */
55
57
  history?: RouterHistory;
56
58
  /**
57
59
  * A function that will be used to stringify search params when generating links.
58
- * Defaults to `defaultStringifySearch`.
60
+ *
61
+ * @default defaultStringifySearch
59
62
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#stringifysearch-method)
60
63
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/custom-search-param-serialization)
61
64
  */
62
65
  stringifySearch?: SearchSerializer;
63
66
  /**
64
67
  * A function that will be used to parse search params when parsing the current location.
65
- * Defaults to `defaultParseSearch`.
68
+ *
69
+ * @default defaultParseSearch
66
70
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#parsesearch-method)
67
71
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/custom-search-param-serialization)
68
72
  */
69
73
  parseSearch?: SearchParser;
70
74
  /**
71
- * Defaults to `false`
72
75
  * If `false`, routes will not be preloaded by default in any way.
76
+ *
73
77
  * If `'intent'`, routes will be preloaded by default when the user hovers over a link or a `touchstart` event is detected on a `<Link>`.
78
+ *
79
+ * If `'viewport'`, routes will be preloaded by default when they are within the viewport.
80
+ *
81
+ * @default false
74
82
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultpreload-property)
75
83
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/preloading)
76
84
  */
77
- defaultPreload?: false | 'intent';
85
+ defaultPreload?: false | 'intent' | 'viewport';
78
86
  /**
79
- * Defaults to 50
80
87
  * The delay in milliseconds that a route must be hovered over or touched before it is preloaded.
88
+ *
89
+ * @default 50
81
90
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultpreloaddelay-property)
82
91
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/preloading#preload-delay)
83
92
  */
84
93
  defaultPreloadDelay?: number;
85
94
  /**
86
- * Defaults to `Outlet`
87
95
  * The default `component` a route should use if no component is provided.
96
+ *
97
+ * @default Outlet
88
98
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultcomponent-property)
89
99
  */
90
100
  defaultComponent?: RouteComponent;
91
101
  /**
92
- * Defaults to `ErrorComponent`
93
102
  * The default `errorComponent` a route should use if no error component is provided.
103
+ *
104
+ * @default ErrorComponent
94
105
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaulterrorcomponent-property)
95
106
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#handling-errors-with-routeoptionserrorcomponent)
96
107
  */
97
108
  defaultErrorComponent?: ErrorRouteComponent;
98
109
  /**
99
110
  * The default `pendingComponent` a route should use if no pending component is provided.
111
+ *
100
112
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultpendingcomponent-property)
101
113
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#showing-a-pending-component)
102
114
  */
103
115
  defaultPendingComponent?: RouteComponent;
104
116
  /**
105
- * Defaults to `1000`
106
117
  * The default `pendingMs` a route should use if no pendingMs is provided.
118
+ *
119
+ * @default 1000
107
120
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultpendingms-property)
108
121
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#avoiding-pending-component-flash)
109
122
  */
110
123
  defaultPendingMs?: number;
111
124
  /**
112
- * Defaults to `500`
113
125
  * The default `pendingMinMs` a route should use if no pendingMinMs is provided.
126
+ *
127
+ * @default 500
114
128
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultpendingminms-property)
115
129
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#avoiding-pending-component-flash)
116
130
  */
117
131
  defaultPendingMinMs?: number;
118
132
  /**
119
- * Defaults to `0`
120
- * The default `staleTime` a route should use if no staleTime is
133
+ * The default `staleTime` a route should use if no staleTime is provided. This is the time in milliseconds that a route will be considered fresh.
134
+ *
135
+ * @default 0
121
136
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultstaletime-property)
122
137
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#key-options)
123
138
  */
124
139
  defaultStaleTime?: number;
125
140
  /**
126
- * Defaults to `30_000` ms (30 seconds)
127
141
  * The default `preloadStaleTime` a route should use if no preloadStaleTime is provided.
142
+ *
143
+ * @default 30_000 `(30 seconds)`
128
144
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultpreloadstaletime-property)
129
145
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/preloading)
130
146
  */
131
147
  defaultPreloadStaleTime?: number;
132
148
  /**
133
149
  * Defaults to `routerOptions.defaultGcTime`, which defaults to 30 minutes.
150
+ *
134
151
  * The default `defaultPreloadGcTime` a route should use if no preloadGcTime is provided.
152
+ *
135
153
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultpreloadgctime-property)
136
154
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/preloading)
137
155
  */
138
156
  defaultPreloadGcTime?: number;
139
157
  /**
140
158
  * The default `onCatch` handler for errors caught by the Router ErrorBoundary
159
+ *
141
160
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultoncatch-property)
142
161
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#handling-errors-with-routeoptionsoncatch)
143
162
  */
144
163
  defaultOnCatch?: (error: Error, errorInfo: React.ErrorInfo) => void;
164
+ /**
165
+ * If set to `true`, all navigation actions will wrapped in `document.startViewTransition()`.
166
+ */
145
167
  defaultViewTransition?: boolean;
146
168
  /**
147
169
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/not-found-errors#the-notfoundmode-option)
148
170
  */
149
171
  notFoundMode?: 'root' | 'fuzzy';
150
172
  /**
151
- * Defaults to 30 minutes.
152
173
  * The default `gcTime` a route should use if no
174
+ *
175
+ * @default 1_800_000 `(30 minutes)`
153
176
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultgctime-property)
154
177
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#key-options)
155
178
  */
156
179
  defaultGcTime?: number;
157
180
  /**
158
- * Defaults to `false`
159
181
  * If `true`, all routes will be matched as case-sensitive.
182
+ *
183
+ * @default false
160
184
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#casesensitive-property)
161
185
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/route-trees#case-sensitivity)
162
186
  */
163
187
  caseSensitive?: boolean;
164
188
  /**
165
- * Required
189
+ * __Required*__
190
+ *
166
191
  * The route tree that will be used to configure the router instance.
192
+ *
167
193
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#routetree-property)
168
194
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/route-trees)
169
195
  */
170
196
  routeTree?: TRouteTree;
171
197
  /**
172
- * Defaults to `/`
173
198
  * The basepath for then entire router. This is useful for mounting a router instance at a subpath.
199
+ *
200
+ * @default '/'
174
201
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#basepath-property)
175
202
  */
176
203
  basepath?: string;
177
204
  /**
178
- * Optional or required if the root route was created with [`createRootRouteWithContext()`](https://tanstack.com/router/latest/docs/framework/react/api/router/createRootRouteWithContextFunction).
179
205
  * The root context that will be provided to all routes in the route tree.
206
+ *
180
207
  * This can be used to provide a context to all routes in the tree without having to provide it to each route individually.
208
+ *
209
+ * Optional or required if the root route was created with [`createRootRouteWithContext()`](https://tanstack.com/router/latest/docs/framework/react/api/router/createRootRouteWithContextFunction).
210
+ *
181
211
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#context-property)
182
212
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/router-context)
183
213
  */
184
214
  context?: InferRouterContext<TRouteTree>;
185
215
  /**
186
216
  * A function that will be called when the router is dehydrated.
217
+ *
187
218
  * The return value of this function will be serialized and stored in the router's dehydrated state.
219
+ *
188
220
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#dehydrate-method)
189
221
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/external-data-loading#critical-dehydrationhydration)
190
222
  */
191
223
  dehydrate?: () => TDehydrated;
192
224
  /**
193
225
  * A function that will be called when the router is hydrated.
226
+ *
194
227
  * The return value of this function will be serialized and stored in the router's dehydrated state.
228
+ *
195
229
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#hydrate-method)
196
230
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/external-data-loading#critical-dehydrationhydration)
197
231
  */
198
232
  hydrate?: (dehydrated: TDehydrated) => void;
199
233
  /**
200
234
  * An array of route masks that will be used to mask routes in the route tree.
235
+ *
201
236
  * Route masking is when you display a route at a different path than the one it is configured to match, like a modal popup that when shared will unmask to the modal's content instead of the modal's context.
237
+ *
202
238
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#routemasks-property)
203
239
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/route-masking)
204
240
  */
205
241
  routeMasks?: Array<RouteMask<TRouteTree>>;
206
242
  /**
207
- * Defaults to `false`
208
243
  * If `true`, route masks will, by default, be removed when the page is reloaded.
244
+ *
209
245
  * This can be overridden on a per-mask basis by setting the `unmaskOnReload` option on the mask, or on a per-navigation basis by setting the `unmaskOnReload` option in the `Navigate` options.
246
+ *
247
+ * @default false
210
248
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#unmaskonreload-property)
211
249
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/route-masking#unmasking-on-page-reload)
212
250
  */
213
251
  unmaskOnReload?: boolean;
214
252
  /**
215
253
  * A component that will be used to wrap the entire router.
254
+ *
216
255
  * This is useful for providing a context to the entire router.
256
+ *
217
257
  * Only non-DOM-rendering components like providers should be used, anything else will cause a hydration error.
258
+ *
218
259
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#wrap-property)
219
260
  */
220
261
  Wrap?: (props: {
@@ -222,48 +263,60 @@ export interface RouterOptions<TRouteTree extends AnyRoute, TTrailingSlashOption
222
263
  }) => React.JSX.Element;
223
264
  /**
224
265
  * A component that will be used to wrap the inner contents of the router.
266
+ *
225
267
  * This is useful for providing a context to the inner contents of the router where you also need access to the router context and hooks.
268
+ *
226
269
  * Only non-DOM-rendering components like providers should be used, anything else will cause a hydration error.
270
+ *
227
271
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#innerwrap-property)
228
272
  */
229
273
  InnerWrap?: (props: {
230
274
  children: any;
231
275
  }) => React.JSX.Element;
232
276
  /**
233
- * @deprecated
234
277
  * Use `notFoundComponent` instead.
278
+ *
279
+ * @deprecated
235
280
  * See https://tanstack.com/router/v1/docs/guide/not-found-errors#migrating-from-notfoundroute for more info.
236
281
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#notfoundroute-property)
237
282
  */
238
283
  notFoundRoute?: AnyRoute;
239
284
  /**
240
- * Defaults to `NotFound`
241
285
  * The default `notFoundComponent` a route should use if no notFound component is provided.
286
+ *
287
+ * @default NotFound
242
288
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#defaultnotfoundcomponent-property)
243
289
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/not-found-errors#default-router-wide-not-found-handling)
244
290
  */
245
291
  defaultNotFoundComponent?: NotFoundRouteComponent;
246
292
  /**
247
293
  * The transformer that will be used when sending data between the server and the client during SSR.
294
+ *
248
295
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#transformer-property)
249
296
  * @link [Guide](https://tanstack.com/router/latest/docs/framework/react/guide/ssr#data-transformers)
250
297
  */
251
298
  transformer?: RouterTransformer;
252
299
  /**
253
300
  * The serializer object that will be used to determine how errors are serialized and deserialized between the server and the client.
301
+ *
254
302
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#errorserializer-property)
255
303
  */
256
304
  errorSerializer?: RouterErrorSerializer<TSerializedError>;
257
305
  /**
258
- * Defaults to `never`
259
306
  * Configures how trailing slashes are treated.
260
- * `'always'` will add a trailing slash if not present, `'never'` will remove the trailing slash if present and `'preserve'` will not modify the trailing slash.
307
+ *
308
+ * - `'always'` will add a trailing slash if not present
309
+ * - `'never'` will remove the trailing slash if present
310
+ * - `'preserve'` will not modify the trailing slash.
311
+ *
312
+ * @default 'never'
261
313
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#trailingslash-property)
262
314
  */
263
315
  trailingSlash?: TTrailingSlashOption;
264
316
  /**
265
- * Defaults to `typeof document !== 'undefined'`
266
317
  * While usually automatic, sometimes it can be useful to force the router into a server-side state, e.g. when using the router in a non-browser environment that has access to a global.document object.
318
+ *
319
+ * @default typeof document !== 'undefined'
267
320
  * @link [API Docs](https://tanstack.com/router/latest/docs/framework/react/api/router/RouterOptionsType#isserver property)
268
321
  */
269
322
  isServer?: boolean;
@@ -175,6 +175,38 @@ function usePrevious(value) {
175
175
  }
176
176
  return ref.current.prev;
177
177
  }
178
+ function useIntersectionObserver(ref, intersectionObserverOptions = {}, options = {}, callback) {
179
+ const isIntersectionObserverAvailable = React__namespace.useRef(
180
+ typeof IntersectionObserver === "function"
181
+ );
182
+ const observerRef = React__namespace.useRef(null);
183
+ React__namespace.useEffect(() => {
184
+ if (!ref.current || !isIntersectionObserverAvailable.current || options.disabled) {
185
+ return;
186
+ }
187
+ observerRef.current = new IntersectionObserver(([entry]) => {
188
+ callback(entry);
189
+ }, intersectionObserverOptions);
190
+ observerRef.current.observe(ref.current);
191
+ return () => {
192
+ var _a;
193
+ (_a = observerRef.current) == null ? void 0 : _a.disconnect();
194
+ };
195
+ }, [intersectionObserverOptions, options, ref, callback]);
196
+ return observerRef.current;
197
+ }
198
+ function useForwardedRef(ref) {
199
+ const innerRef = React__namespace.useRef(null);
200
+ React__namespace.useEffect(() => {
201
+ if (!ref) return;
202
+ if (typeof ref === "function") {
203
+ ref(innerRef.current);
204
+ } else {
205
+ ref.current = innerRef.current;
206
+ }
207
+ });
208
+ return innerRef;
209
+ }
178
210
  exports.createControlledPromise = createControlledPromise;
179
211
  exports.deepEqual = deepEqual;
180
212
  exports.escapeJSON = escapeJSON;
@@ -185,6 +217,8 @@ exports.last = last;
185
217
  exports.pick = pick;
186
218
  exports.replaceEqualDeep = replaceEqualDeep;
187
219
  exports.shallow = shallow;
220
+ exports.useForwardedRef = useForwardedRef;
221
+ exports.useIntersectionObserver = useIntersectionObserver;
188
222
  exports.useLayoutEffect = useLayoutEffect;
189
223
  exports.usePrevious = usePrevious;
190
224
  exports.useStableCallback = useStableCallback;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.cjs","sources":["../../src/utils.ts"],"sourcesContent":["import * as React from 'react'\n\nexport type NoInfer<T> = [T][T extends any ? 0 : never]\nexport type IsAny<TValue, TYesResult, TNoResult = TValue> = 1 extends 0 & TValue\n ? TYesResult\n : TNoResult\nexport type PickAsRequired<TValue, TKey extends keyof TValue> = Omit<\n TValue,\n TKey\n> &\n Required<Pick<TValue, TKey>>\n\nexport type PickRequired<T> = {\n [K in keyof T as undefined extends T[K] ? never : K]: T[K]\n}\n\n// from https://stackoverflow.com/a/76458160\nexport type WithoutEmpty<T> = T extends any ? ({} extends T ? never : T) : never\n\n// export type Expand<T> = T\nexport type Expand<T> = T extends object\n ? T extends infer O\n ? O extends Function\n ? O\n : { [K in keyof O]: O[K] }\n : never\n : T\n\nexport type DeepPartial<T> = T extends object\n ? {\n [P in keyof T]?: DeepPartial<T[P]>\n }\n : T\n\nexport type MakeDifferenceOptional<TLeft, TRight> = Omit<\n TRight,\n keyof TLeft\n> & {\n [K in keyof TLeft & keyof TRight]?: TRight[K]\n}\n\n// from https://stackoverflow.com/a/53955431\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type IsUnion<T, U extends T = T> = (\n T extends any ? (U extends T ? false : true) : never\n) extends false\n ? false\n : true\n\nexport type Assign<TLeft, TRight> = keyof TLeft extends never\n ? TRight\n : keyof TRight extends never\n ? TLeft\n : keyof TLeft & keyof TRight extends never\n ? TLeft & TRight\n : Omit<TLeft, keyof TRight> & TRight\n\nexport type Timeout = ReturnType<typeof setTimeout>\n\nexport type Updater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev?: TPrevious) => TResult)\n\nexport type NonNullableUpdater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev: TPrevious) => TResult)\n\nexport type MergeUnionObjects<TUnion> = TUnion extends MergeUnionPrimitive\n ? never\n : TUnion\n\nexport type MergeUnionObject<TUnion> =\n MergeUnionObjects<TUnion> extends infer TObj\n ? {\n [TKey in TObj extends any ? keyof TObj : never]?: TObj extends any\n ? TKey extends keyof TObj\n ? TObj[TKey]\n : never\n : never\n }\n : never\n\nexport type MergeUnionPrimitive =\n | ReadonlyArray<any>\n | number\n | string\n | bigint\n | boolean\n | symbol\n\nexport type MergeUnionPrimitives<TUnion> = TUnion extends MergeUnionPrimitive\n ? TUnion\n : TUnion extends object\n ? never\n : TUnion\n\nexport type MergeUnion<TUnion> =\n | MergeUnionPrimitives<TUnion>\n | MergeUnionObject<TUnion>\n\nexport function last<T>(arr: Array<T>) {\n return arr[arr.length - 1]\n}\n\nfunction isFunction(d: any): d is Function {\n return typeof d === 'function'\n}\n\nexport function functionalUpdate<TResult>(\n updater: Updater<TResult> | NonNullableUpdater<TResult>,\n previous: TResult,\n): TResult {\n if (isFunction(updater)) {\n return updater(previous)\n }\n\n return updater\n}\n\nexport function pick<TValue, TKey extends keyof TValue>(\n parent: TValue,\n keys: Array<TKey>,\n): Pick<TValue, TKey> {\n return keys.reduce((obj: any, key: TKey) => {\n obj[key] = parent[key]\n return obj\n }, {} as any)\n}\n\n/**\n * This function returns `prev` if `_next` is deeply equal.\n * If not, it will replace any deeply equal children of `b` with those of `a`.\n * This can be used for structural sharing between immutable JSON values for example.\n * Do not use this with signals\n */\nexport function replaceEqualDeep<T>(prev: any, _next: T): T {\n if (prev === _next) {\n return prev\n }\n\n const next = _next as any\n\n const array = isPlainArray(prev) && isPlainArray(next)\n\n if (array || (isPlainObject(prev) && isPlainObject(next))) {\n const prevItems = array ? prev : Object.keys(prev)\n const prevSize = prevItems.length\n const nextItems = array ? next : Object.keys(next)\n const nextSize = nextItems.length\n const copy: any = array ? [] : {}\n\n let equalItems = 0\n\n for (let i = 0; i < nextSize; i++) {\n const key = array ? i : (nextItems[i] as any)\n if (\n ((!array && prevItems.includes(key)) || array) &&\n prev[key] === undefined &&\n next[key] === undefined\n ) {\n copy[key] = undefined\n equalItems++\n } else {\n copy[key] = replaceEqualDeep(prev[key], next[key])\n if (copy[key] === prev[key] && prev[key] !== undefined) {\n equalItems++\n }\n }\n }\n\n return prevSize === nextSize && equalItems === prevSize ? prev : copy\n }\n\n return next\n}\n\n// Copied from: https://github.com/jonschlinkert/is-plain-object\nexport function isPlainObject(o: any) {\n if (!hasObjectPrototype(o)) {\n return false\n }\n\n // If has modified constructor\n const ctor = o.constructor\n if (typeof ctor === 'undefined') {\n return true\n }\n\n // If has modified prototype\n const prot = ctor.prototype\n if (!hasObjectPrototype(prot)) {\n return false\n }\n\n // If constructor does not have an Object-specific method\n if (!prot.hasOwnProperty('isPrototypeOf')) {\n return false\n }\n\n // Most likely a plain Object\n return true\n}\n\nfunction hasObjectPrototype(o: any) {\n return Object.prototype.toString.call(o) === '[object Object]'\n}\n\nexport function isPlainArray(value: unknown): value is Array<unknown> {\n return Array.isArray(value) && value.length === Object.keys(value).length\n}\n\nexport function deepEqual(a: any, b: any, partial: boolean = false): boolean {\n if (a === b) {\n return true\n }\n\n if (typeof a !== typeof b) {\n return false\n }\n\n if (isPlainObject(a) && isPlainObject(b)) {\n const aKeys = Object.keys(a).filter((key) => a[key] !== undefined)\n const bKeys = Object.keys(b).filter((key) => b[key] !== undefined)\n\n if (!partial && aKeys.length !== bKeys.length) {\n return false\n }\n\n return !bKeys.some(\n (key) => !(key in a) || !deepEqual(a[key], b[key], partial),\n )\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false\n }\n return !a.some((item, index) => !deepEqual(item, b[index], partial))\n }\n\n return false\n}\n\nexport function useStableCallback<T extends (...args: Array<any>) => any>(\n fn: T,\n): T {\n const fnRef = React.useRef(fn)\n fnRef.current = fn\n\n const ref = React.useRef((...args: Array<any>) => fnRef.current(...args))\n return ref.current as T\n}\n\nexport function shallow<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n const keysA = Object.keys(objA)\n if (keysA.length !== Object.keys(objB).length) {\n return false\n }\n\n for (const item of keysA) {\n if (\n !Object.prototype.hasOwnProperty.call(objB, item) ||\n !Object.is(objA[item as keyof T], objB[item as keyof T])\n ) {\n return false\n }\n }\n return true\n}\n\nexport type StringLiteral<T> = T extends string\n ? string extends T\n ? string\n : T\n : never\n\nexport type StrictOrFrom<\n TFrom,\n TStrict extends boolean = true,\n> = TStrict extends false\n ? {\n from?: never\n strict: TStrict\n }\n : {\n from: StringLiteral<TFrom> | TFrom\n strict?: TStrict\n }\n\nexport const useLayoutEffect =\n typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect\n\n/**\n *\n * @deprecated use `jsesc` instead\n */\nexport function escapeJSON(jsonString: string) {\n return jsonString\n .replace(/\\\\/g, '\\\\\\\\') // Escape backslashes\n .replace(/'/g, \"\\\\'\") // Escape single quotes\n .replace(/\"/g, '\\\\\"') // Escape double quotes\n}\n\nexport type ControlledPromise<T> = Promise<T> & {\n resolve: (value: T) => void\n reject: (value: any) => void\n status: 'pending' | 'resolved' | 'rejected'\n value?: T\n}\n\nexport function createControlledPromise<T>(onResolve?: (value: T) => void) {\n let resolveLoadPromise!: (value: T) => void\n let rejectLoadPromise!: (value: any) => void\n\n const controlledPromise = new Promise<T>((resolve, reject) => {\n resolveLoadPromise = resolve\n rejectLoadPromise = reject\n }) as ControlledPromise<T>\n\n controlledPromise.status = 'pending'\n\n controlledPromise.resolve = (value: T) => {\n controlledPromise.status = 'resolved'\n controlledPromise.value = value\n resolveLoadPromise(value)\n onResolve?.(value)\n }\n\n controlledPromise.reject = (e) => {\n controlledPromise.status = 'rejected'\n rejectLoadPromise(e)\n }\n\n return controlledPromise\n}\n\n/**\n * Taken from https://www.developerway.com/posts/implementing-advanced-use-previous-hook#part3\n */\nexport function usePrevious<T>(value: T): T | null {\n // initialise the ref with previous and current values\n const ref = React.useRef<{ value: T; prev: T | null }>({\n value: value,\n prev: null,\n })\n\n const current = ref.current.value\n\n // if the value passed into hook doesn't match what we store as \"current\"\n // move the \"current\" to the \"previous\"\n // and store the passed value as \"current\"\n if (value !== current) {\n ref.current = {\n value: value,\n prev: current,\n }\n }\n\n // return the previous value only\n return ref.current.prev\n}\n"],"names":["React"],"mappings":"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"}
1
+ {"version":3,"file":"utils.cjs","sources":["../../src/utils.ts"],"sourcesContent":["import * as React from 'react'\n\nexport type NoInfer<T> = [T][T extends any ? 0 : never]\nexport type IsAny<TValue, TYesResult, TNoResult = TValue> = 1 extends 0 & TValue\n ? TYesResult\n : TNoResult\nexport type PickAsRequired<TValue, TKey extends keyof TValue> = Omit<\n TValue,\n TKey\n> &\n Required<Pick<TValue, TKey>>\n\nexport type PickRequired<T> = {\n [K in keyof T as undefined extends T[K] ? never : K]: T[K]\n}\n\n// from https://stackoverflow.com/a/76458160\nexport type WithoutEmpty<T> = T extends any ? ({} extends T ? never : T) : never\n\n// export type Expand<T> = T\nexport type Expand<T> = T extends object\n ? T extends infer O\n ? O extends Function\n ? O\n : { [K in keyof O]: O[K] }\n : never\n : T\n\nexport type DeepPartial<T> = T extends object\n ? {\n [P in keyof T]?: DeepPartial<T[P]>\n }\n : T\n\nexport type MakeDifferenceOptional<TLeft, TRight> = Omit<\n TRight,\n keyof TLeft\n> & {\n [K in keyof TLeft & keyof TRight]?: TRight[K]\n}\n\n// from https://stackoverflow.com/a/53955431\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport type IsUnion<T, U extends T = T> = (\n T extends any ? (U extends T ? false : true) : never\n) extends false\n ? false\n : true\n\nexport type Assign<TLeft, TRight> = keyof TLeft extends never\n ? TRight\n : keyof TRight extends never\n ? TLeft\n : keyof TLeft & keyof TRight extends never\n ? TLeft & TRight\n : Omit<TLeft, keyof TRight> & TRight\n\nexport type Timeout = ReturnType<typeof setTimeout>\n\nexport type Updater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev?: TPrevious) => TResult)\n\nexport type NonNullableUpdater<TPrevious, TResult = TPrevious> =\n | TResult\n | ((prev: TPrevious) => TResult)\n\nexport type MergeUnionObjects<TUnion> = TUnion extends MergeUnionPrimitive\n ? never\n : TUnion\n\nexport type MergeUnionObject<TUnion> =\n MergeUnionObjects<TUnion> extends infer TObj\n ? {\n [TKey in TObj extends any ? keyof TObj : never]?: TObj extends any\n ? TKey extends keyof TObj\n ? TObj[TKey]\n : never\n : never\n }\n : never\n\nexport type MergeUnionPrimitive =\n | ReadonlyArray<any>\n | number\n | string\n | bigint\n | boolean\n | symbol\n\nexport type MergeUnionPrimitives<TUnion> = TUnion extends MergeUnionPrimitive\n ? TUnion\n : TUnion extends object\n ? never\n : TUnion\n\nexport type MergeUnion<TUnion> =\n | MergeUnionPrimitives<TUnion>\n | MergeUnionObject<TUnion>\n\nexport function last<T>(arr: Array<T>) {\n return arr[arr.length - 1]\n}\n\nfunction isFunction(d: any): d is Function {\n return typeof d === 'function'\n}\n\nexport function functionalUpdate<TResult>(\n updater: Updater<TResult> | NonNullableUpdater<TResult>,\n previous: TResult,\n): TResult {\n if (isFunction(updater)) {\n return updater(previous)\n }\n\n return updater\n}\n\nexport function pick<TValue, TKey extends keyof TValue>(\n parent: TValue,\n keys: Array<TKey>,\n): Pick<TValue, TKey> {\n return keys.reduce((obj: any, key: TKey) => {\n obj[key] = parent[key]\n return obj\n }, {} as any)\n}\n\n/**\n * This function returns `prev` if `_next` is deeply equal.\n * If not, it will replace any deeply equal children of `b` with those of `a`.\n * This can be used for structural sharing between immutable JSON values for example.\n * Do not use this with signals\n */\nexport function replaceEqualDeep<T>(prev: any, _next: T): T {\n if (prev === _next) {\n return prev\n }\n\n const next = _next as any\n\n const array = isPlainArray(prev) && isPlainArray(next)\n\n if (array || (isPlainObject(prev) && isPlainObject(next))) {\n const prevItems = array ? prev : Object.keys(prev)\n const prevSize = prevItems.length\n const nextItems = array ? next : Object.keys(next)\n const nextSize = nextItems.length\n const copy: any = array ? [] : {}\n\n let equalItems = 0\n\n for (let i = 0; i < nextSize; i++) {\n const key = array ? i : (nextItems[i] as any)\n if (\n ((!array && prevItems.includes(key)) || array) &&\n prev[key] === undefined &&\n next[key] === undefined\n ) {\n copy[key] = undefined\n equalItems++\n } else {\n copy[key] = replaceEqualDeep(prev[key], next[key])\n if (copy[key] === prev[key] && prev[key] !== undefined) {\n equalItems++\n }\n }\n }\n\n return prevSize === nextSize && equalItems === prevSize ? prev : copy\n }\n\n return next\n}\n\n// Copied from: https://github.com/jonschlinkert/is-plain-object\nexport function isPlainObject(o: any) {\n if (!hasObjectPrototype(o)) {\n return false\n }\n\n // If has modified constructor\n const ctor = o.constructor\n if (typeof ctor === 'undefined') {\n return true\n }\n\n // If has modified prototype\n const prot = ctor.prototype\n if (!hasObjectPrototype(prot)) {\n return false\n }\n\n // If constructor does not have an Object-specific method\n if (!prot.hasOwnProperty('isPrototypeOf')) {\n return false\n }\n\n // Most likely a plain Object\n return true\n}\n\nfunction hasObjectPrototype(o: any) {\n return Object.prototype.toString.call(o) === '[object Object]'\n}\n\nexport function isPlainArray(value: unknown): value is Array<unknown> {\n return Array.isArray(value) && value.length === Object.keys(value).length\n}\n\nexport function deepEqual(a: any, b: any, partial: boolean = false): boolean {\n if (a === b) {\n return true\n }\n\n if (typeof a !== typeof b) {\n return false\n }\n\n if (isPlainObject(a) && isPlainObject(b)) {\n const aKeys = Object.keys(a).filter((key) => a[key] !== undefined)\n const bKeys = Object.keys(b).filter((key) => b[key] !== undefined)\n\n if (!partial && aKeys.length !== bKeys.length) {\n return false\n }\n\n return !bKeys.some(\n (key) => !(key in a) || !deepEqual(a[key], b[key], partial),\n )\n }\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) {\n return false\n }\n return !a.some((item, index) => !deepEqual(item, b[index], partial))\n }\n\n return false\n}\n\nexport function useStableCallback<T extends (...args: Array<any>) => any>(\n fn: T,\n): T {\n const fnRef = React.useRef(fn)\n fnRef.current = fn\n\n const ref = React.useRef((...args: Array<any>) => fnRef.current(...args))\n return ref.current as T\n}\n\nexport function shallow<T>(objA: T, objB: T) {\n if (Object.is(objA, objB)) {\n return true\n }\n\n if (\n typeof objA !== 'object' ||\n objA === null ||\n typeof objB !== 'object' ||\n objB === null\n ) {\n return false\n }\n\n const keysA = Object.keys(objA)\n if (keysA.length !== Object.keys(objB).length) {\n return false\n }\n\n for (const item of keysA) {\n if (\n !Object.prototype.hasOwnProperty.call(objB, item) ||\n !Object.is(objA[item as keyof T], objB[item as keyof T])\n ) {\n return false\n }\n }\n return true\n}\n\nexport type StringLiteral<T> = T extends string\n ? string extends T\n ? string\n : T\n : never\n\nexport type StrictOrFrom<\n TFrom,\n TStrict extends boolean = true,\n> = TStrict extends false\n ? {\n from?: never\n strict: TStrict\n }\n : {\n from: StringLiteral<TFrom> | TFrom\n strict?: TStrict\n }\n\nexport const useLayoutEffect =\n typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect\n\n/**\n *\n * @deprecated use `jsesc` instead\n */\nexport function escapeJSON(jsonString: string) {\n return jsonString\n .replace(/\\\\/g, '\\\\\\\\') // Escape backslashes\n .replace(/'/g, \"\\\\'\") // Escape single quotes\n .replace(/\"/g, '\\\\\"') // Escape double quotes\n}\n\nexport type ControlledPromise<T> = Promise<T> & {\n resolve: (value: T) => void\n reject: (value: any) => void\n status: 'pending' | 'resolved' | 'rejected'\n value?: T\n}\n\nexport function createControlledPromise<T>(onResolve?: (value: T) => void) {\n let resolveLoadPromise!: (value: T) => void\n let rejectLoadPromise!: (value: any) => void\n\n const controlledPromise = new Promise<T>((resolve, reject) => {\n resolveLoadPromise = resolve\n rejectLoadPromise = reject\n }) as ControlledPromise<T>\n\n controlledPromise.status = 'pending'\n\n controlledPromise.resolve = (value: T) => {\n controlledPromise.status = 'resolved'\n controlledPromise.value = value\n resolveLoadPromise(value)\n onResolve?.(value)\n }\n\n controlledPromise.reject = (e) => {\n controlledPromise.status = 'rejected'\n rejectLoadPromise(e)\n }\n\n return controlledPromise\n}\n\n/**\n * Taken from https://www.developerway.com/posts/implementing-advanced-use-previous-hook#part3\n */\nexport function usePrevious<T>(value: T): T | null {\n // initialise the ref with previous and current values\n const ref = React.useRef<{ value: T; prev: T | null }>({\n value: value,\n prev: null,\n })\n\n const current = ref.current.value\n\n // if the value passed into hook doesn't match what we store as \"current\"\n // move the \"current\" to the \"previous\"\n // and store the passed value as \"current\"\n if (value !== current) {\n ref.current = {\n value: value,\n prev: current,\n }\n }\n\n // return the previous value only\n return ref.current.prev\n}\n\n/**\n * React hook to wrap `IntersectionObserver`.\n *\n * This hook will create an `IntersectionObserver` and observe the ref passed to it.\n *\n * When the intersection changes, the callback will be called with the `IntersectionObserverEntry`.\n *\n * @param ref - The ref to observe\n * @param intersectionObserverOptions - The options to pass to the IntersectionObserver\n * @param options - The options to pass to the hook\n * @param callback - The callback to call when the intersection changes\n * @returns The IntersectionObserver instance\n * @example\n * ```tsx\n * const MyComponent = () => {\n * const ref = React.useRef<HTMLDivElement>(null)\n * useIntersectionObserver(ref, { rootMargin: '10px' }, {}, (entry) => {\n * return <div ref={ref} />\n * })\n * ```\n */\nexport function useIntersectionObserver<T extends Element>(\n ref: React.RefObject<T>,\n intersectionObserverOptions: IntersectionObserverInit = {},\n options: { disabled?: boolean } = {},\n callback: (entry: IntersectionObserverEntry | undefined) => void,\n): IntersectionObserver | null {\n const isIntersectionObserverAvailable = React.useRef(\n typeof IntersectionObserver === 'function',\n )\n\n const observerRef = React.useRef<IntersectionObserver | null>(null)\n\n React.useEffect(() => {\n if (\n !ref.current ||\n !isIntersectionObserverAvailable.current ||\n options.disabled\n ) {\n return\n }\n\n observerRef.current = new IntersectionObserver(([entry]) => {\n callback(entry)\n }, intersectionObserverOptions)\n\n observerRef.current.observe(ref.current)\n\n return () => {\n observerRef.current?.disconnect()\n }\n }, [intersectionObserverOptions, options, ref, callback])\n\n return observerRef.current\n}\n\n/**\n * React hook to take a `React.ForwardedRef` and returns a `ref` that can be used on a DOM element.\n *\n * @param ref - The forwarded ref\n * @returns The inner ref returned by `useRef`\n * @example\n * ```tsx\n * const MyComponent = React.forwardRef((props, ref) => {\n * const innerRef = useForwardedRef(ref)\n * return <div ref={innerRef} />\n * })\n * ```\n */\nexport function useForwardedRef<T>(ref?: React.ForwardedRef<T>) {\n const innerRef = React.useRef<T>(null)\n\n React.useEffect(() => {\n if (!ref) return\n if (typeof ref === 'function') {\n ref(innerRef.current)\n } else {\n ref.current = innerRef.current\n }\n })\n\n return innerRef\n}\n"],"names":["React"],"mappings":";;;;;;;;;;;;;;;;;;;;AAoGO,SAAS,KAAQ,KAAe;AAC9B,SAAA,IAAI,IAAI,SAAS,CAAC;AAC3B;AAEA,SAAS,WAAW,GAAuB;AACzC,SAAO,OAAO,MAAM;AACtB;AAEgB,SAAA,iBACd,SACA,UACS;AACL,MAAA,WAAW,OAAO,GAAG;AACvB,WAAO,QAAQ,QAAQ;AAAA,EACzB;AAEO,SAAA;AACT;AAEgB,SAAA,KACd,QACA,MACoB;AACpB,SAAO,KAAK,OAAO,CAAC,KAAU,QAAc;AACtC,QAAA,GAAG,IAAI,OAAO,GAAG;AACd,WAAA;AAAA,EACT,GAAG,CAAS,CAAA;AACd;AAQgB,SAAA,iBAAoB,MAAW,OAAa;AAC1D,MAAI,SAAS,OAAO;AACX,WAAA;AAAA,EACT;AAEA,QAAM,OAAO;AAEb,QAAM,QAAQ,aAAa,IAAI,KAAK,aAAa,IAAI;AAErD,MAAI,SAAU,cAAc,IAAI,KAAK,cAAc,IAAI,GAAI;AACzD,UAAM,YAAY,QAAQ,OAAO,OAAO,KAAK,IAAI;AACjD,UAAM,WAAW,UAAU;AAC3B,UAAM,YAAY,QAAQ,OAAO,OAAO,KAAK,IAAI;AACjD,UAAM,WAAW,UAAU;AAC3B,UAAM,OAAY,QAAQ,CAAC,IAAI;AAE/B,QAAI,aAAa;AAEjB,aAAS,IAAI,GAAG,IAAI,UAAU,KAAK;AACjC,YAAM,MAAM,QAAQ,IAAK,UAAU,CAAC;AACpC,WACI,CAAC,SAAS,UAAU,SAAS,GAAG,KAAM,UACxC,KAAK,GAAG,MAAM,UACd,KAAK,GAAG,MAAM,QACd;AACA,aAAK,GAAG,IAAI;AACZ;AAAA,MAAA,OACK;AACA,aAAA,GAAG,IAAI,iBAAiB,KAAK,GAAG,GAAG,KAAK,GAAG,CAAC;AAC7C,YAAA,KAAK,GAAG,MAAM,KAAK,GAAG,KAAK,KAAK,GAAG,MAAM,QAAW;AACtD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO,aAAa,YAAY,eAAe,WAAW,OAAO;AAAA,EACnE;AAEO,SAAA;AACT;AAGO,SAAS,cAAc,GAAQ;AAChC,MAAA,CAAC,mBAAmB,CAAC,GAAG;AACnB,WAAA;AAAA,EACT;AAGA,QAAM,OAAO,EAAE;AACX,MAAA,OAAO,SAAS,aAAa;AACxB,WAAA;AAAA,EACT;AAGA,QAAM,OAAO,KAAK;AACd,MAAA,CAAC,mBAAmB,IAAI,GAAG;AACtB,WAAA;AAAA,EACT;AAGA,MAAI,CAAC,KAAK,eAAe,eAAe,GAAG;AAClC,WAAA;AAAA,EACT;AAGO,SAAA;AACT;AAEA,SAAS,mBAAmB,GAAQ;AAClC,SAAO,OAAO,UAAU,SAAS,KAAK,CAAC,MAAM;AAC/C;AAEO,SAAS,aAAa,OAAyC;AAC7D,SAAA,MAAM,QAAQ,KAAK,KAAK,MAAM,WAAW,OAAO,KAAK,KAAK,EAAE;AACrE;AAEO,SAAS,UAAU,GAAQ,GAAQ,UAAmB,OAAgB;AAC3E,MAAI,MAAM,GAAG;AACJ,WAAA;AAAA,EACT;AAEI,MAAA,OAAO,MAAM,OAAO,GAAG;AAClB,WAAA;AAAA,EACT;AAEA,MAAI,cAAc,CAAC,KAAK,cAAc,CAAC,GAAG;AAClC,UAAA,QAAQ,OAAO,KAAK,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE,GAAG,MAAM,MAAS;AAC3D,UAAA,QAAQ,OAAO,KAAK,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE,GAAG,MAAM,MAAS;AAEjE,QAAI,CAAC,WAAW,MAAM,WAAW,MAAM,QAAQ;AACtC,aAAA;AAAA,IACT;AAEA,WAAO,CAAC,MAAM;AAAA,MACZ,CAAC,QAAQ,EAAE,OAAO,MAAM,CAAC,UAAU,EAAE,GAAG,GAAG,EAAE,GAAG,GAAG,OAAO;AAAA,IAAA;AAAA,EAE9D;AAEA,MAAI,MAAM,QAAQ,CAAC,KAAK,MAAM,QAAQ,CAAC,GAAG;AACpC,QAAA,EAAE,WAAW,EAAE,QAAQ;AAClB,aAAA;AAAA,IACT;AACA,WAAO,CAAC,EAAE,KAAK,CAAC,MAAM,UAAU,CAAC,UAAU,MAAM,EAAE,KAAK,GAAG,OAAO,CAAC;AAAA,EACrE;AAEO,SAAA;AACT;AAEO,SAAS,kBACd,IACG;AACG,QAAA,QAAQA,iBAAM,OAAO,EAAE;AAC7B,QAAM,UAAU;AAEV,QAAA,MAAMA,iBAAM,OAAO,IAAI,SAAqB,MAAM,QAAQ,GAAG,IAAI,CAAC;AACxE,SAAO,IAAI;AACb;AAEgB,SAAA,QAAW,MAAS,MAAS;AAC3C,MAAI,OAAO,GAAG,MAAM,IAAI,GAAG;AAClB,WAAA;AAAA,EACT;AAGE,MAAA,OAAO,SAAS,YAChB,SAAS,QACT,OAAO,SAAS,YAChB,SAAS,MACT;AACO,WAAA;AAAA,EACT;AAEM,QAAA,QAAQ,OAAO,KAAK,IAAI;AAC9B,MAAI,MAAM,WAAW,OAAO,KAAK,IAAI,EAAE,QAAQ;AACtC,WAAA;AAAA,EACT;AAEA,aAAW,QAAQ,OAAO;AACxB,QACE,CAAC,OAAO,UAAU,eAAe,KAAK,MAAM,IAAI,KAChD,CAAC,OAAO,GAAG,KAAK,IAAe,GAAG,KAAK,IAAe,CAAC,GACvD;AACO,aAAA;AAAA,IACT;AAAA,EACF;AACO,SAAA;AACT;AAqBO,MAAM,kBACX,OAAO,WAAW,cAAcA,iBAAM,kBAAkBA,iBAAM;AAMzD,SAAS,WAAW,YAAoB;AACtC,SAAA,WACJ,QAAQ,OAAO,MAAM,EACrB,QAAQ,MAAM,KAAK,EACnB,QAAQ,MAAM,KAAK;AACxB;AASO,SAAS,wBAA2B,WAAgC;AACrE,MAAA;AACA,MAAA;AAEJ,QAAM,oBAAoB,IAAI,QAAW,CAAC,SAAS,WAAW;AACvC,yBAAA;AACD,wBAAA;AAAA,EAAA,CACrB;AAED,oBAAkB,SAAS;AAET,oBAAA,UAAU,CAAC,UAAa;AACxC,sBAAkB,SAAS;AAC3B,sBAAkB,QAAQ;AAC1B,uBAAmB,KAAK;AACxB,2CAAY;AAAA,EAAK;AAGD,oBAAA,SAAS,CAAC,MAAM;AAChC,sBAAkB,SAAS;AAC3B,sBAAkB,CAAC;AAAA,EAAA;AAGd,SAAA;AACT;AAKO,SAAS,YAAe,OAAoB;AAE3C,QAAA,MAAMA,iBAAM,OAAqC;AAAA,IACrD;AAAA,IACA,MAAM;AAAA,EAAA,CACP;AAEK,QAAA,UAAU,IAAI,QAAQ;AAK5B,MAAI,UAAU,SAAS;AACrB,QAAI,UAAU;AAAA,MACZ;AAAA,MACA,MAAM;AAAA,IAAA;AAAA,EAEV;AAGA,SAAO,IAAI,QAAQ;AACrB;AAuBgB,SAAA,wBACd,KACA,8BAAwD,IACxD,UAAkC,IAClC,UAC6B;AAC7B,QAAM,kCAAkCA,iBAAM;AAAA,IAC5C,OAAO,yBAAyB;AAAA,EAAA;AAG5B,QAAA,cAAcA,iBAAM,OAAoC,IAAI;AAElEA,mBAAM,UAAU,MAAM;AACpB,QACE,CAAC,IAAI,WACL,CAAC,gCAAgC,WACjC,QAAQ,UACR;AACA;AAAA,IACF;AAEA,gBAAY,UAAU,IAAI,qBAAqB,CAAC,CAAC,KAAK,MAAM;AAC1D,eAAS,KAAK;AAAA,OACb,2BAA2B;AAElB,gBAAA,QAAQ,QAAQ,IAAI,OAAO;AAEvC,WAAO,MAAM;;AACX,wBAAY,YAAZ,mBAAqB;AAAA,IAAW;AAAA,KAEjC,CAAC,6BAA6B,SAAS,KAAK,QAAQ,CAAC;AAExD,SAAO,YAAY;AACrB;AAeO,SAAS,gBAAmB,KAA6B;AACxD,QAAA,WAAWA,iBAAM,OAAU,IAAI;AAErCA,mBAAM,UAAU,MAAM;AACpB,QAAI,CAAC,IAAK;AACN,QAAA,OAAO,QAAQ,YAAY;AAC7B,UAAI,SAAS,OAAO;AAAA,IAAA,OACf;AACL,UAAI,UAAU,SAAS;AAAA,IACzB;AAAA,EAAA,CACD;AAEM,SAAA;AACT;;;;;;;;;;;;;;;;"}
@@ -67,3 +67,41 @@ export declare function createControlledPromise<T>(onResolve?: (value: T) => voi
67
67
  * Taken from https://www.developerway.com/posts/implementing-advanced-use-previous-hook#part3
68
68
  */
69
69
  export declare function usePrevious<T>(value: T): T | null;
70
+ /**
71
+ * React hook to wrap `IntersectionObserver`.
72
+ *
73
+ * This hook will create an `IntersectionObserver` and observe the ref passed to it.
74
+ *
75
+ * When the intersection changes, the callback will be called with the `IntersectionObserverEntry`.
76
+ *
77
+ * @param ref - The ref to observe
78
+ * @param intersectionObserverOptions - The options to pass to the IntersectionObserver
79
+ * @param options - The options to pass to the hook
80
+ * @param callback - The callback to call when the intersection changes
81
+ * @returns The IntersectionObserver instance
82
+ * @example
83
+ * ```tsx
84
+ * const MyComponent = () => {
85
+ * const ref = React.useRef<HTMLDivElement>(null)
86
+ * useIntersectionObserver(ref, { rootMargin: '10px' }, {}, (entry) => {
87
+ * return <div ref={ref} />
88
+ * })
89
+ * ```
90
+ */
91
+ export declare function useIntersectionObserver<T extends Element>(ref: React.RefObject<T>, intersectionObserverOptions: IntersectionObserverInit | undefined, options: {
92
+ disabled?: boolean;
93
+ } | undefined, callback: (entry: IntersectionObserverEntry | undefined) => void): IntersectionObserver | null;
94
+ /**
95
+ * React hook to take a `React.ForwardedRef` and returns a `ref` that can be used on a DOM element.
96
+ *
97
+ * @param ref - The forwarded ref
98
+ * @returns The inner ref returned by `useRef`
99
+ * @example
100
+ * ```tsx
101
+ * const MyComponent = React.forwardRef((props, ref) => {
102
+ * const innerRef = useForwardedRef(ref)
103
+ * return <div ref={innerRef} />
104
+ * })
105
+ * ```
106
+ */
107
+ export declare function useForwardedRef<T>(ref?: React.ForwardedRef<T>): React.RefObject<T>;
@@ -48,7 +48,7 @@ export interface ToSubOptionsProps<in out TRouter extends AnyRouter = Registered
48
48
  export type ParamsReducerFn<in out TRouter extends AnyRouter, in out TParamVariant extends ParamVariant, in out TFrom, in out TTo> = (current: Expand<ResolveFromParams<TRouter, TParamVariant, TFrom>>) => Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>>;
49
49
  type ParamsReducer<TRouter extends AnyRouter, TParamVariant extends ParamVariant, TFrom, TTo> = Expand<ResolveRelativeToParams<TRouter, TParamVariant, TFrom, TTo>> | (ParamsReducerFn<TRouter, TParamVariant, TFrom, TTo> & {});
50
50
  type ParamVariant = 'PATH' | 'SEARCH';
51
- export type ResolveRoute<TRouter extends AnyRouter, TFrom, TTo, TPath = ResolveRelativePath<TFrom, TTo>> = TPath extends string ? string extends TTo ? RouteByPath<TRouter['routeTree'], TPath> : RouteByToPath<TRouter, TPath> : never;
51
+ export type ResolveRoute<TRouter extends AnyRouter, TFrom, TTo, TPath = ResolveRelativePath<TFrom, TTo>> = TPath extends string ? TFrom extends TPath ? RouteByPath<TRouter['routeTree'], TPath> : RouteByToPath<TRouter, TPath> : never;
52
52
  type ResolveFromParamType<TParamVariant extends ParamVariant> = TParamVariant extends 'PATH' ? 'allParams' : 'fullSearchSchema';
53
53
  type ResolveFromAllParams<TRouter extends AnyRouter, TParamVariant extends ParamVariant> = TParamVariant extends 'PATH' ? AllParams<TRouter['routeTree']> : FullSearchSchema<TRouter['routeTree']>;
54
54
  type ResolveFromParams<TRouter extends AnyRouter, TParamVariant extends ParamVariant, TFrom> = string extends TFrom ? ResolveFromAllParams<TRouter, TParamVariant> : RouteByPath<TRouter['routeTree'], TFrom>['types'][ResolveFromParamType<TParamVariant>];
@@ -83,15 +83,37 @@ export interface ActiveOptions {
83
83
  }
84
84
  export type LinkOptions<TRouter extends AnyRouter = RegisteredRouter, TFrom extends string = string, TTo extends string = '', TMaskFrom extends string = TFrom, TMaskTo extends string = ''> = NavigateOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & LinkOptionsProps;
85
85
  export interface LinkOptionsProps {
86
+ /**
87
+ * The standard anchor tag target attribute
88
+ */
86
89
  target?: HTMLAnchorElement['target'];
90
+ /**
91
+ * Configurable options to determine if the link should be considered active or not
92
+ * @default {exact:true,includeHash:true}
93
+ */
87
94
  activeOptions?: ActiveOptions;
88
- preload?: false | 'intent';
95
+ /**
96
+ * The preloading strategy for this link
97
+ * - `false` - No preloading
98
+ * - `'intent'` - Preload the linked route on hover and cache it for this many milliseconds in hopes that the user will eventually navigate there.
99
+ * - `'viewport'` - Preload the linked route when it enters the viewport
100
+ */
101
+ preload?: false | 'intent' | 'viewport';
102
+ /**
103
+ * When a preload strategy is set, this delays the preload by this many milliseconds.
104
+ * If the user exits the link before this delay, the preload will be cancelled.
105
+ */
89
106
  preloadDelay?: number;
107
+ /**
108
+ * Control whether the link should be disabled or not
109
+ * If set to `true`, the link will be rendered without an `href` attribute
110
+ * @default false
111
+ */
90
112
  disabled?: boolean;
91
113
  }
92
114
  export type CheckPath<TRouter extends AnyRouter, TPass, TFail, TFrom, TTo> = string extends ResolveRelativePath<TFrom, TTo> ? TPass : ResolveRelativePath<TFrom, TTo> extends CatchAllPaths ? TPass : ResolveRoute<TRouter, TFrom, TTo> extends never ? TFail : TPass;
93
115
  export type ResolveRelativePath<TFrom, TTo = '.'> = string extends TFrom ? TTo : string extends TTo ? TFrom : TFrom extends string ? TTo extends string ? TTo extends '.' ? TFrom : TTo extends `./` ? Join<[TFrom, '/']> : TTo extends `./${infer TRest}` ? ResolveRelativePath<TFrom, TRest> : TTo extends `/${infer TRest}` ? TTo : Split<TTo> extends ['..', ...infer ToRest] ? Split<TFrom> extends [...infer FromRest, infer FromTail] ? ToRest extends ['/'] ? Join<['/', ...FromRest, '/']> : ResolveRelativePath<Join<FromRest>, Join<ToRest>> : never : Split<TTo> extends ['.', ...infer ToRest] ? ToRest extends ['/'] ? Join<[TFrom, '/']> : ResolveRelativePath<TFrom, Join<ToRest>> : CleanPath<Join<['/', ...Split<TFrom>, ...Split<TTo>]>> : never : never;
94
- export declare function useLinkProps<TRouter extends AnyRouter = RegisteredRouter, TFrom extends RoutePaths<TRouter['routeTree']> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom, TMaskTo extends string = ''>(options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>): React.AnchorHTMLAttributes<HTMLAnchorElement>;
116
+ export declare function useLinkProps<TRouter extends AnyRouter = RegisteredRouter, TFrom extends RoutePaths<TRouter['routeTree']> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom, TMaskTo extends string = ''>(options: UseLinkPropsOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo>, forwardedRef?: React.ForwardedRef<Element>): React.ComponentPropsWithRef<'a'>;
95
117
  export type UseLinkPropsOptions<TRouter extends AnyRouter = RegisteredRouter, TFrom extends RoutePaths<TRouter['routeTree']> | string = string, TTo extends string = '', TMaskFrom extends RoutePaths<TRouter['routeTree']> | string = TFrom, TMaskTo extends string = ''> = ActiveLinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & React.AnchorHTMLAttributes<HTMLAnchorElement>;
96
118
  export type ActiveLinkOptions<TRouter extends AnyRouter = RegisteredRouter, TFrom extends string = string, TTo extends string = '', TMaskFrom extends string = TFrom, TMaskTo extends string = ''> = LinkOptions<TRouter, TFrom, TTo, TMaskFrom, TMaskTo> & ActiveLinkOptionProps;
97
119
  export interface ActiveLinkOptionProps {