@levi-gemcommerce/analytics 1.0.0-dev.27 → 1.0.0-dev.29
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/dist/esm/index.js +5 -1371
- package/dist/esm/index.mjs +5 -1371
- package/dist/umd/index.js +1 -34
- package/package.json +3 -1
package/dist/esm/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client"
|
|
2
2
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
3
|
-
import { Text, Box, InlineStack, Icon, InlineGrid, Tooltip as Tooltip$1, Button, BlockStack, Checkbox, RadioButton, Popover, ActionList, Link
|
|
3
|
+
import { Text, Box, InlineStack, Icon, InlineGrid, Tooltip as Tooltip$1, Button, BlockStack, Checkbox, RadioButton, Popover, ActionList, Link, SkeletonDisplayText, List, Card, SkeletonBodyText, TextField, Collapsible, useBreakpoints, Select, Scrollable, OptionList, DatePicker, ButtonGroup, Divider } from '@shopify/polaris';
|
|
4
4
|
import * as React from 'react';
|
|
5
5
|
import React__default, { useMemo, useCallback, useState, useEffect, forwardRef, Fragment as Fragment$1, useRef, useImperativeHandle, createContext, useContext, createElement, useLayoutEffect, memo, Component } from 'react';
|
|
6
6
|
import dayjs from 'dayjs';
|
|
@@ -12,6 +12,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
12
12
|
import { create } from 'zustand';
|
|
13
13
|
import { useQuery } from '@tanstack/react-query';
|
|
14
14
|
import { PolarisVizProvider, LineChart, DonutChart } from '@shopify/polaris-viz';
|
|
15
|
+
import { useSearchParams } from '@remix-run/react';
|
|
15
16
|
import { unstable_batchedUpdates, createPortal } from 'react-dom';
|
|
16
17
|
import { t as t$1 } from 'i18next';
|
|
17
18
|
|
|
@@ -955,7 +956,7 @@ const GTextLink = ({ linkAction, isDisabled, disabledFocus, children }) => {
|
|
|
955
956
|
if (!linkAction || isDisabled) {
|
|
956
957
|
return jsx(Fragment, { children: children });
|
|
957
958
|
}
|
|
958
|
-
return (jsx("span", { className: cls('GTextLink', { 'GTextLink--disabled-focus': disabledFocus }), children: jsx(Link
|
|
959
|
+
return (jsx("span", { className: cls('GTextLink', { 'GTextLink--disabled-focus': disabledFocus }), children: jsx(Link, { ...linkAction, children: jsx(Fragment, { children: children }) }) }));
|
|
959
960
|
};
|
|
960
961
|
|
|
961
962
|
const GSkeletonDisplayText = (props) => {
|
|
@@ -1049,7 +1050,7 @@ const GViewBySelector = ({ activatorText, selected, options, minWidth, maxWidth,
|
|
|
1049
1050
|
};
|
|
1050
1051
|
|
|
1051
1052
|
const ChoiceHelpText = ({ item }) => {
|
|
1052
|
-
return (jsxs(Text, { as: "p", variant: "bodyMd", children: [item.description, item.inlineAction && (jsx(Link
|
|
1053
|
+
return (jsxs(Text, { as: "p", variant: "bodyMd", children: [item.description, item.inlineAction && (jsx(Link, { monochrome: true, onClick: () => {
|
|
1053
1054
|
if (item.inlineAction?.onAction) {
|
|
1054
1055
|
item.inlineAction?.onAction();
|
|
1055
1056
|
}
|
|
@@ -3239,1373 +3240,6 @@ const useFunnelChartStore = create()((set, get) => ({
|
|
|
3239
3240
|
const MAX_FUNNEL_ADDITIONAL_LEVEL = 3;
|
|
3240
3241
|
const FINAL_FUNNEL_FIXED_LEVEL = 3;
|
|
3241
3242
|
|
|
3242
|
-
/**
|
|
3243
|
-
* @remix-run/router v1.21.0
|
|
3244
|
-
*
|
|
3245
|
-
* Copyright (c) Remix Software Inc.
|
|
3246
|
-
*
|
|
3247
|
-
* This source code is licensed under the MIT license found in the
|
|
3248
|
-
* LICENSE.md file in the root directory of this source tree.
|
|
3249
|
-
*
|
|
3250
|
-
* @license MIT
|
|
3251
|
-
*/
|
|
3252
|
-
function _extends$2() {
|
|
3253
|
-
_extends$2 = Object.assign ? Object.assign.bind() : function (target) {
|
|
3254
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
3255
|
-
var source = arguments[i];
|
|
3256
|
-
for (var key in source) {
|
|
3257
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
3258
|
-
target[key] = source[key];
|
|
3259
|
-
}
|
|
3260
|
-
}
|
|
3261
|
-
}
|
|
3262
|
-
return target;
|
|
3263
|
-
};
|
|
3264
|
-
return _extends$2.apply(this, arguments);
|
|
3265
|
-
}
|
|
3266
|
-
|
|
3267
|
-
////////////////////////////////////////////////////////////////////////////////
|
|
3268
|
-
//#region Types and Constants
|
|
3269
|
-
////////////////////////////////////////////////////////////////////////////////
|
|
3270
|
-
/**
|
|
3271
|
-
* Actions represent the type of change to a location value.
|
|
3272
|
-
*/
|
|
3273
|
-
var Action;
|
|
3274
|
-
(function (Action) {
|
|
3275
|
-
/**
|
|
3276
|
-
* A POP indicates a change to an arbitrary index in the history stack, such
|
|
3277
|
-
* as a back or forward navigation. It does not describe the direction of the
|
|
3278
|
-
* navigation, only that the current index changed.
|
|
3279
|
-
*
|
|
3280
|
-
* Note: This is the default action for newly created history objects.
|
|
3281
|
-
*/
|
|
3282
|
-
Action["Pop"] = "POP";
|
|
3283
|
-
/**
|
|
3284
|
-
* A PUSH indicates a new entry being added to the history stack, such as when
|
|
3285
|
-
* a link is clicked and a new page loads. When this happens, all subsequent
|
|
3286
|
-
* entries in the stack are lost.
|
|
3287
|
-
*/
|
|
3288
|
-
Action["Push"] = "PUSH";
|
|
3289
|
-
/**
|
|
3290
|
-
* A REPLACE indicates the entry at the current index in the history stack
|
|
3291
|
-
* being replaced by a new one.
|
|
3292
|
-
*/
|
|
3293
|
-
Action["Replace"] = "REPLACE";
|
|
3294
|
-
})(Action || (Action = {}));
|
|
3295
|
-
function invariant(value, message) {
|
|
3296
|
-
if (value === false || value === null || typeof value === "undefined") {
|
|
3297
|
-
throw new Error(message);
|
|
3298
|
-
}
|
|
3299
|
-
}
|
|
3300
|
-
function warning(cond, message) {
|
|
3301
|
-
if (!cond) {
|
|
3302
|
-
// eslint-disable-next-line no-console
|
|
3303
|
-
if (typeof console !== "undefined") console.warn(message);
|
|
3304
|
-
try {
|
|
3305
|
-
// Welcome to debugging history!
|
|
3306
|
-
//
|
|
3307
|
-
// This error is thrown as a convenience, so you can more easily
|
|
3308
|
-
// find the source for a warning that appears in the console by
|
|
3309
|
-
// enabling "pause on exceptions" in your JavaScript debugger.
|
|
3310
|
-
throw new Error(message);
|
|
3311
|
-
// eslint-disable-next-line no-empty
|
|
3312
|
-
} catch (e) {}
|
|
3313
|
-
}
|
|
3314
|
-
}
|
|
3315
|
-
/**
|
|
3316
|
-
* Creates a string URL path from the given pathname, search, and hash components.
|
|
3317
|
-
*/
|
|
3318
|
-
function createPath(_ref) {
|
|
3319
|
-
let {
|
|
3320
|
-
pathname = "/",
|
|
3321
|
-
search = "",
|
|
3322
|
-
hash = ""
|
|
3323
|
-
} = _ref;
|
|
3324
|
-
if (search && search !== "?") pathname += search.charAt(0) === "?" ? search : "?" + search;
|
|
3325
|
-
if (hash && hash !== "#") pathname += hash.charAt(0) === "#" ? hash : "#" + hash;
|
|
3326
|
-
return pathname;
|
|
3327
|
-
}
|
|
3328
|
-
/**
|
|
3329
|
-
* Parses a string URL path into its separate pathname, search, and hash components.
|
|
3330
|
-
*/
|
|
3331
|
-
function parsePath(path) {
|
|
3332
|
-
let parsedPath = {};
|
|
3333
|
-
if (path) {
|
|
3334
|
-
let hashIndex = path.indexOf("#");
|
|
3335
|
-
if (hashIndex >= 0) {
|
|
3336
|
-
parsedPath.hash = path.substr(hashIndex);
|
|
3337
|
-
path = path.substr(0, hashIndex);
|
|
3338
|
-
}
|
|
3339
|
-
let searchIndex = path.indexOf("?");
|
|
3340
|
-
if (searchIndex >= 0) {
|
|
3341
|
-
parsedPath.search = path.substr(searchIndex);
|
|
3342
|
-
path = path.substr(0, searchIndex);
|
|
3343
|
-
}
|
|
3344
|
-
if (path) {
|
|
3345
|
-
parsedPath.pathname = path;
|
|
3346
|
-
}
|
|
3347
|
-
}
|
|
3348
|
-
return parsedPath;
|
|
3349
|
-
}
|
|
3350
|
-
//#endregion
|
|
3351
|
-
|
|
3352
|
-
var ResultType;
|
|
3353
|
-
(function (ResultType) {
|
|
3354
|
-
ResultType["data"] = "data";
|
|
3355
|
-
ResultType["deferred"] = "deferred";
|
|
3356
|
-
ResultType["redirect"] = "redirect";
|
|
3357
|
-
ResultType["error"] = "error";
|
|
3358
|
-
})(ResultType || (ResultType = {}));
|
|
3359
|
-
/**
|
|
3360
|
-
* Performs pattern matching on a URL pathname and returns information about
|
|
3361
|
-
* the match.
|
|
3362
|
-
*
|
|
3363
|
-
* @see https://reactrouter.com/v6/utils/match-path
|
|
3364
|
-
*/
|
|
3365
|
-
function matchPath(pattern, pathname) {
|
|
3366
|
-
if (typeof pattern === "string") {
|
|
3367
|
-
pattern = {
|
|
3368
|
-
path: pattern,
|
|
3369
|
-
caseSensitive: false,
|
|
3370
|
-
end: true
|
|
3371
|
-
};
|
|
3372
|
-
}
|
|
3373
|
-
let [matcher, compiledParams] = compilePath(pattern.path, pattern.caseSensitive, pattern.end);
|
|
3374
|
-
let match = pathname.match(matcher);
|
|
3375
|
-
if (!match) return null;
|
|
3376
|
-
let matchedPathname = match[0];
|
|
3377
|
-
let pathnameBase = matchedPathname.replace(/(.)\/+$/, "$1");
|
|
3378
|
-
let captureGroups = match.slice(1);
|
|
3379
|
-
let params = compiledParams.reduce((memo, _ref, index) => {
|
|
3380
|
-
let {
|
|
3381
|
-
paramName,
|
|
3382
|
-
isOptional
|
|
3383
|
-
} = _ref;
|
|
3384
|
-
// We need to compute the pathnameBase here using the raw splat value
|
|
3385
|
-
// instead of using params["*"] later because it will be decoded then
|
|
3386
|
-
if (paramName === "*") {
|
|
3387
|
-
let splatValue = captureGroups[index] || "";
|
|
3388
|
-
pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\/+$/, "$1");
|
|
3389
|
-
}
|
|
3390
|
-
const value = captureGroups[index];
|
|
3391
|
-
if (isOptional && !value) {
|
|
3392
|
-
memo[paramName] = undefined;
|
|
3393
|
-
} else {
|
|
3394
|
-
memo[paramName] = (value || "").replace(/%2F/g, "/");
|
|
3395
|
-
}
|
|
3396
|
-
return memo;
|
|
3397
|
-
}, {});
|
|
3398
|
-
return {
|
|
3399
|
-
params,
|
|
3400
|
-
pathname: matchedPathname,
|
|
3401
|
-
pathnameBase,
|
|
3402
|
-
pattern
|
|
3403
|
-
};
|
|
3404
|
-
}
|
|
3405
|
-
function compilePath(path, caseSensitive, end) {
|
|
3406
|
-
if (caseSensitive === void 0) {
|
|
3407
|
-
caseSensitive = false;
|
|
3408
|
-
}
|
|
3409
|
-
if (end === void 0) {
|
|
3410
|
-
end = true;
|
|
3411
|
-
}
|
|
3412
|
-
warning(path === "*" || !path.endsWith("*") || path.endsWith("/*"), "Route path \"" + path + "\" will be treated as if it were " + ("\"" + path.replace(/\*$/, "/*") + "\" because the `*` character must ") + "always follow a `/` in the pattern. To get rid of this warning, " + ("please change the route path to \"" + path.replace(/\*$/, "/*") + "\"."));
|
|
3413
|
-
let params = [];
|
|
3414
|
-
let regexpSource = "^" + path.replace(/\/*\*?$/, "") // Ignore trailing / and /*, we'll handle it below
|
|
3415
|
-
.replace(/^\/*/, "/") // Make sure it has a leading /
|
|
3416
|
-
.replace(/[\\.*+^${}|()[\]]/g, "\\$&") // Escape special regex chars
|
|
3417
|
-
.replace(/\/:([\w-]+)(\?)?/g, (_, paramName, isOptional) => {
|
|
3418
|
-
params.push({
|
|
3419
|
-
paramName,
|
|
3420
|
-
isOptional: isOptional != null
|
|
3421
|
-
});
|
|
3422
|
-
return isOptional ? "/?([^\\/]+)?" : "/([^\\/]+)";
|
|
3423
|
-
});
|
|
3424
|
-
if (path.endsWith("*")) {
|
|
3425
|
-
params.push({
|
|
3426
|
-
paramName: "*"
|
|
3427
|
-
});
|
|
3428
|
-
regexpSource += path === "*" || path === "/*" ? "(.*)$" // Already matched the initial /, just match the rest
|
|
3429
|
-
: "(?:\\/(.+)|\\/*)$"; // Don't include the / in params["*"]
|
|
3430
|
-
} else if (end) {
|
|
3431
|
-
// When matching to the end, ignore trailing slashes
|
|
3432
|
-
regexpSource += "\\/*$";
|
|
3433
|
-
} else if (path !== "" && path !== "/") {
|
|
3434
|
-
// If our path is non-empty and contains anything beyond an initial slash,
|
|
3435
|
-
// then we have _some_ form of path in our regex, so we should expect to
|
|
3436
|
-
// match only if we find the end of this path segment. Look for an optional
|
|
3437
|
-
// non-captured trailing slash (to match a portion of the URL) or the end
|
|
3438
|
-
// of the path (if we've matched to the end). We used to do this with a
|
|
3439
|
-
// word boundary but that gives false positives on routes like
|
|
3440
|
-
// /user-preferences since `-` counts as a word boundary.
|
|
3441
|
-
regexpSource += "(?:(?=\\/|$))";
|
|
3442
|
-
} else ;
|
|
3443
|
-
let matcher = new RegExp(regexpSource, caseSensitive ? undefined : "i");
|
|
3444
|
-
return [matcher, params];
|
|
3445
|
-
}
|
|
3446
|
-
/**
|
|
3447
|
-
* @private
|
|
3448
|
-
*/
|
|
3449
|
-
function stripBasename(pathname, basename) {
|
|
3450
|
-
if (basename === "/") return pathname;
|
|
3451
|
-
if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {
|
|
3452
|
-
return null;
|
|
3453
|
-
}
|
|
3454
|
-
// We want to leave trailing slash behavior in the user's control, so if they
|
|
3455
|
-
// specify a basename with a trailing slash, we should support it
|
|
3456
|
-
let startIndex = basename.endsWith("/") ? basename.length - 1 : basename.length;
|
|
3457
|
-
let nextChar = pathname.charAt(startIndex);
|
|
3458
|
-
if (nextChar && nextChar !== "/") {
|
|
3459
|
-
// pathname does not start with basename/
|
|
3460
|
-
return null;
|
|
3461
|
-
}
|
|
3462
|
-
return pathname.slice(startIndex) || "/";
|
|
3463
|
-
}
|
|
3464
|
-
/**
|
|
3465
|
-
* Returns a resolved path object relative to the given pathname.
|
|
3466
|
-
*
|
|
3467
|
-
* @see https://reactrouter.com/v6/utils/resolve-path
|
|
3468
|
-
*/
|
|
3469
|
-
function resolvePath(to, fromPathname) {
|
|
3470
|
-
if (fromPathname === void 0) {
|
|
3471
|
-
fromPathname = "/";
|
|
3472
|
-
}
|
|
3473
|
-
let {
|
|
3474
|
-
pathname: toPathname,
|
|
3475
|
-
search = "",
|
|
3476
|
-
hash = ""
|
|
3477
|
-
} = typeof to === "string" ? parsePath(to) : to;
|
|
3478
|
-
let pathname = toPathname ? toPathname.startsWith("/") ? toPathname : resolvePathname(toPathname, fromPathname) : fromPathname;
|
|
3479
|
-
return {
|
|
3480
|
-
pathname,
|
|
3481
|
-
search: normalizeSearch(search),
|
|
3482
|
-
hash: normalizeHash(hash)
|
|
3483
|
-
};
|
|
3484
|
-
}
|
|
3485
|
-
function resolvePathname(relativePath, fromPathname) {
|
|
3486
|
-
let segments = fromPathname.replace(/\/+$/, "").split("/");
|
|
3487
|
-
let relativeSegments = relativePath.split("/");
|
|
3488
|
-
relativeSegments.forEach(segment => {
|
|
3489
|
-
if (segment === "..") {
|
|
3490
|
-
// Keep the root "" segment so the pathname starts at /
|
|
3491
|
-
if (segments.length > 1) segments.pop();
|
|
3492
|
-
} else if (segment !== ".") {
|
|
3493
|
-
segments.push(segment);
|
|
3494
|
-
}
|
|
3495
|
-
});
|
|
3496
|
-
return segments.length > 1 ? segments.join("/") : "/";
|
|
3497
|
-
}
|
|
3498
|
-
function getInvalidPathError(char, field, dest, path) {
|
|
3499
|
-
return "Cannot include a '" + char + "' character in a manually specified " + ("`to." + field + "` field [" + JSON.stringify(path) + "]. Please separate it out to the ") + ("`to." + dest + "` field. Alternatively you may provide the full path as ") + "a string in <Link to=\"...\"> and the router will parse it for you.";
|
|
3500
|
-
}
|
|
3501
|
-
/**
|
|
3502
|
-
* @private
|
|
3503
|
-
*
|
|
3504
|
-
* When processing relative navigation we want to ignore ancestor routes that
|
|
3505
|
-
* do not contribute to the path, such that index/pathless layout routes don't
|
|
3506
|
-
* interfere.
|
|
3507
|
-
*
|
|
3508
|
-
* For example, when moving a route element into an index route and/or a
|
|
3509
|
-
* pathless layout route, relative link behavior contained within should stay
|
|
3510
|
-
* the same. Both of the following examples should link back to the root:
|
|
3511
|
-
*
|
|
3512
|
-
* <Route path="/">
|
|
3513
|
-
* <Route path="accounts" element={<Link to=".."}>
|
|
3514
|
-
* </Route>
|
|
3515
|
-
*
|
|
3516
|
-
* <Route path="/">
|
|
3517
|
-
* <Route path="accounts">
|
|
3518
|
-
* <Route element={<AccountsLayout />}> // <-- Does not contribute
|
|
3519
|
-
* <Route index element={<Link to=".."} /> // <-- Does not contribute
|
|
3520
|
-
* </Route
|
|
3521
|
-
* </Route>
|
|
3522
|
-
* </Route>
|
|
3523
|
-
*/
|
|
3524
|
-
function getPathContributingMatches(matches) {
|
|
3525
|
-
return matches.filter((match, index) => index === 0 || match.route.path && match.route.path.length > 0);
|
|
3526
|
-
}
|
|
3527
|
-
// Return the array of pathnames for the current route matches - used to
|
|
3528
|
-
// generate the routePathnames input for resolveTo()
|
|
3529
|
-
function getResolveToMatches(matches, v7_relativeSplatPath) {
|
|
3530
|
-
let pathMatches = getPathContributingMatches(matches);
|
|
3531
|
-
// When v7_relativeSplatPath is enabled, use the full pathname for the leaf
|
|
3532
|
-
// match so we include splat values for "." links. See:
|
|
3533
|
-
// https://github.com/remix-run/react-router/issues/11052#issuecomment-1836589329
|
|
3534
|
-
if (v7_relativeSplatPath) {
|
|
3535
|
-
return pathMatches.map((match, idx) => idx === pathMatches.length - 1 ? match.pathname : match.pathnameBase);
|
|
3536
|
-
}
|
|
3537
|
-
return pathMatches.map(match => match.pathnameBase);
|
|
3538
|
-
}
|
|
3539
|
-
/**
|
|
3540
|
-
* @private
|
|
3541
|
-
*/
|
|
3542
|
-
function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) {
|
|
3543
|
-
if (isPathRelative === void 0) {
|
|
3544
|
-
isPathRelative = false;
|
|
3545
|
-
}
|
|
3546
|
-
let to;
|
|
3547
|
-
if (typeof toArg === "string") {
|
|
3548
|
-
to = parsePath(toArg);
|
|
3549
|
-
} else {
|
|
3550
|
-
to = _extends$2({}, toArg);
|
|
3551
|
-
invariant(!to.pathname || !to.pathname.includes("?"), getInvalidPathError("?", "pathname", "search", to));
|
|
3552
|
-
invariant(!to.pathname || !to.pathname.includes("#"), getInvalidPathError("#", "pathname", "hash", to));
|
|
3553
|
-
invariant(!to.search || !to.search.includes("#"), getInvalidPathError("#", "search", "hash", to));
|
|
3554
|
-
}
|
|
3555
|
-
let isEmptyPath = toArg === "" || to.pathname === "";
|
|
3556
|
-
let toPathname = isEmptyPath ? "/" : to.pathname;
|
|
3557
|
-
let from;
|
|
3558
|
-
// Routing is relative to the current pathname if explicitly requested.
|
|
3559
|
-
//
|
|
3560
|
-
// If a pathname is explicitly provided in `to`, it should be relative to the
|
|
3561
|
-
// route context. This is explained in `Note on `<Link to>` values` in our
|
|
3562
|
-
// migration guide from v5 as a means of disambiguation between `to` values
|
|
3563
|
-
// that begin with `/` and those that do not. However, this is problematic for
|
|
3564
|
-
// `to` values that do not provide a pathname. `to` can simply be a search or
|
|
3565
|
-
// hash string, in which case we should assume that the navigation is relative
|
|
3566
|
-
// to the current location's pathname and *not* the route pathname.
|
|
3567
|
-
if (toPathname == null) {
|
|
3568
|
-
from = locationPathname;
|
|
3569
|
-
} else {
|
|
3570
|
-
let routePathnameIndex = routePathnames.length - 1;
|
|
3571
|
-
// With relative="route" (the default), each leading .. segment means
|
|
3572
|
-
// "go up one route" instead of "go up one URL segment". This is a key
|
|
3573
|
-
// difference from how <a href> works and a major reason we call this a
|
|
3574
|
-
// "to" value instead of a "href".
|
|
3575
|
-
if (!isPathRelative && toPathname.startsWith("..")) {
|
|
3576
|
-
let toSegments = toPathname.split("/");
|
|
3577
|
-
while (toSegments[0] === "..") {
|
|
3578
|
-
toSegments.shift();
|
|
3579
|
-
routePathnameIndex -= 1;
|
|
3580
|
-
}
|
|
3581
|
-
to.pathname = toSegments.join("/");
|
|
3582
|
-
}
|
|
3583
|
-
from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : "/";
|
|
3584
|
-
}
|
|
3585
|
-
let path = resolvePath(to, from);
|
|
3586
|
-
// Ensure the pathname has a trailing slash if the original "to" had one
|
|
3587
|
-
let hasExplicitTrailingSlash = toPathname && toPathname !== "/" && toPathname.endsWith("/");
|
|
3588
|
-
// Or if this was a link to the current path which has a trailing slash
|
|
3589
|
-
let hasCurrentTrailingSlash = (isEmptyPath || toPathname === ".") && locationPathname.endsWith("/");
|
|
3590
|
-
if (!path.pathname.endsWith("/") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) {
|
|
3591
|
-
path.pathname += "/";
|
|
3592
|
-
}
|
|
3593
|
-
return path;
|
|
3594
|
-
}
|
|
3595
|
-
/**
|
|
3596
|
-
* @private
|
|
3597
|
-
*/
|
|
3598
|
-
const joinPaths = paths => paths.join("/").replace(/\/\/+/g, "/");
|
|
3599
|
-
/**
|
|
3600
|
-
* @private
|
|
3601
|
-
*/
|
|
3602
|
-
const normalizeSearch = search => !search || search === "?" ? "" : search.startsWith("?") ? search : "?" + search;
|
|
3603
|
-
/**
|
|
3604
|
-
* @private
|
|
3605
|
-
*/
|
|
3606
|
-
const normalizeHash = hash => !hash || hash === "#" ? "" : hash.startsWith("#") ? hash : "#" + hash;
|
|
3607
|
-
|
|
3608
|
-
const validMutationMethodsArr = ["post", "put", "patch", "delete"];
|
|
3609
|
-
new Set(validMutationMethodsArr);
|
|
3610
|
-
const validRequestMethodsArr = ["get", ...validMutationMethodsArr];
|
|
3611
|
-
new Set(validRequestMethodsArr);
|
|
3612
|
-
|
|
3613
|
-
/**
|
|
3614
|
-
* React Router v6.28.1
|
|
3615
|
-
*
|
|
3616
|
-
* Copyright (c) Remix Software Inc.
|
|
3617
|
-
*
|
|
3618
|
-
* This source code is licensed under the MIT license found in the
|
|
3619
|
-
* LICENSE.md file in the root directory of this source tree.
|
|
3620
|
-
*
|
|
3621
|
-
* @license MIT
|
|
3622
|
-
*/
|
|
3623
|
-
|
|
3624
|
-
function _extends$1() {
|
|
3625
|
-
_extends$1 = Object.assign ? Object.assign.bind() : function (target) {
|
|
3626
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
3627
|
-
var source = arguments[i];
|
|
3628
|
-
for (var key in source) {
|
|
3629
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
3630
|
-
target[key] = source[key];
|
|
3631
|
-
}
|
|
3632
|
-
}
|
|
3633
|
-
}
|
|
3634
|
-
return target;
|
|
3635
|
-
};
|
|
3636
|
-
return _extends$1.apply(this, arguments);
|
|
3637
|
-
}
|
|
3638
|
-
|
|
3639
|
-
// Create react-specific types from the agnostic types in @remix-run/router to
|
|
3640
|
-
// export from react-router
|
|
3641
|
-
const DataRouterContext = /*#__PURE__*/React.createContext(null);
|
|
3642
|
-
if (process.env.NODE_ENV !== "production") {
|
|
3643
|
-
DataRouterContext.displayName = "DataRouter";
|
|
3644
|
-
}
|
|
3645
|
-
const DataRouterStateContext = /*#__PURE__*/React.createContext(null);
|
|
3646
|
-
if (process.env.NODE_ENV !== "production") {
|
|
3647
|
-
DataRouterStateContext.displayName = "DataRouterState";
|
|
3648
|
-
}
|
|
3649
|
-
const AwaitContext = /*#__PURE__*/React.createContext(null);
|
|
3650
|
-
if (process.env.NODE_ENV !== "production") {
|
|
3651
|
-
AwaitContext.displayName = "Await";
|
|
3652
|
-
}
|
|
3653
|
-
|
|
3654
|
-
/**
|
|
3655
|
-
* A Navigator is a "location changer"; it's how you get to different locations.
|
|
3656
|
-
*
|
|
3657
|
-
* Every history instance conforms to the Navigator interface, but the
|
|
3658
|
-
* distinction is useful primarily when it comes to the low-level `<Router>` API
|
|
3659
|
-
* where both the location and a navigator must be provided separately in order
|
|
3660
|
-
* to avoid "tearing" that may occur in a suspense-enabled app if the action
|
|
3661
|
-
* and/or location were to be read directly from the history instance.
|
|
3662
|
-
*/
|
|
3663
|
-
|
|
3664
|
-
const NavigationContext = /*#__PURE__*/React.createContext(null);
|
|
3665
|
-
if (process.env.NODE_ENV !== "production") {
|
|
3666
|
-
NavigationContext.displayName = "Navigation";
|
|
3667
|
-
}
|
|
3668
|
-
const LocationContext = /*#__PURE__*/React.createContext(null);
|
|
3669
|
-
if (process.env.NODE_ENV !== "production") {
|
|
3670
|
-
LocationContext.displayName = "Location";
|
|
3671
|
-
}
|
|
3672
|
-
const RouteContext = /*#__PURE__*/React.createContext({
|
|
3673
|
-
outlet: null,
|
|
3674
|
-
matches: [],
|
|
3675
|
-
isDataRoute: false
|
|
3676
|
-
});
|
|
3677
|
-
if (process.env.NODE_ENV !== "production") {
|
|
3678
|
-
RouteContext.displayName = "Route";
|
|
3679
|
-
}
|
|
3680
|
-
const RouteErrorContext = /*#__PURE__*/React.createContext(null);
|
|
3681
|
-
if (process.env.NODE_ENV !== "production") {
|
|
3682
|
-
RouteErrorContext.displayName = "RouteError";
|
|
3683
|
-
}
|
|
3684
|
-
|
|
3685
|
-
/**
|
|
3686
|
-
* Returns the full href for the given "to" value. This is useful for building
|
|
3687
|
-
* custom links that are also accessible and preserve right-click behavior.
|
|
3688
|
-
*
|
|
3689
|
-
* @see https://reactrouter.com/v6/hooks/use-href
|
|
3690
|
-
*/
|
|
3691
|
-
function useHref(to, _temp) {
|
|
3692
|
-
let {
|
|
3693
|
-
relative
|
|
3694
|
-
} = _temp === void 0 ? {} : _temp;
|
|
3695
|
-
!useInRouterContext() ? process.env.NODE_ENV !== "production" ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
|
|
3696
|
-
// router loaded. We can help them understand how to avoid that.
|
|
3697
|
-
"useHref() may be used only in the context of a <Router> component.") : invariant(false) : void 0;
|
|
3698
|
-
let {
|
|
3699
|
-
basename,
|
|
3700
|
-
navigator
|
|
3701
|
-
} = React.useContext(NavigationContext);
|
|
3702
|
-
let {
|
|
3703
|
-
hash,
|
|
3704
|
-
pathname,
|
|
3705
|
-
search
|
|
3706
|
-
} = useResolvedPath(to, {
|
|
3707
|
-
relative
|
|
3708
|
-
});
|
|
3709
|
-
let joinedPathname = pathname;
|
|
3710
|
-
|
|
3711
|
-
// If we're operating within a basename, prepend it to the pathname prior
|
|
3712
|
-
// to creating the href. If this is a root navigation, then just use the raw
|
|
3713
|
-
// basename which allows the basename to have full control over the presence
|
|
3714
|
-
// of a trailing slash on root links
|
|
3715
|
-
if (basename !== "/") {
|
|
3716
|
-
joinedPathname = pathname === "/" ? basename : joinPaths([basename, pathname]);
|
|
3717
|
-
}
|
|
3718
|
-
return navigator.createHref({
|
|
3719
|
-
pathname: joinedPathname,
|
|
3720
|
-
search,
|
|
3721
|
-
hash
|
|
3722
|
-
});
|
|
3723
|
-
}
|
|
3724
|
-
|
|
3725
|
-
/**
|
|
3726
|
-
* Returns true if this component is a descendant of a `<Router>`.
|
|
3727
|
-
*
|
|
3728
|
-
* @see https://reactrouter.com/v6/hooks/use-in-router-context
|
|
3729
|
-
*/
|
|
3730
|
-
function useInRouterContext() {
|
|
3731
|
-
return React.useContext(LocationContext) != null;
|
|
3732
|
-
}
|
|
3733
|
-
|
|
3734
|
-
/**
|
|
3735
|
-
* Returns the current location object, which represents the current URL in web
|
|
3736
|
-
* browsers.
|
|
3737
|
-
*
|
|
3738
|
-
* Note: If you're using this it may mean you're doing some of your own
|
|
3739
|
-
* "routing" in your app, and we'd like to know what your use case is. We may
|
|
3740
|
-
* be able to provide something higher-level to better suit your needs.
|
|
3741
|
-
*
|
|
3742
|
-
* @see https://reactrouter.com/v6/hooks/use-location
|
|
3743
|
-
*/
|
|
3744
|
-
function useLocation() {
|
|
3745
|
-
!useInRouterContext() ? process.env.NODE_ENV !== "production" ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
|
|
3746
|
-
// router loaded. We can help them understand how to avoid that.
|
|
3747
|
-
"useLocation() may be used only in the context of a <Router> component.") : invariant(false) : void 0;
|
|
3748
|
-
return React.useContext(LocationContext).location;
|
|
3749
|
-
}
|
|
3750
|
-
|
|
3751
|
-
/**
|
|
3752
|
-
* The interface for the navigate() function returned from useNavigate().
|
|
3753
|
-
*/
|
|
3754
|
-
|
|
3755
|
-
const navigateEffectWarning = "You should call navigate() in a React.useEffect(), not when " + "your component is first rendered.";
|
|
3756
|
-
|
|
3757
|
-
// Mute warnings for calls to useNavigate in SSR environments
|
|
3758
|
-
function useIsomorphicLayoutEffect$1(cb) {
|
|
3759
|
-
let isStatic = React.useContext(NavigationContext).static;
|
|
3760
|
-
if (!isStatic) {
|
|
3761
|
-
// We should be able to get rid of this once react 18.3 is released
|
|
3762
|
-
// See: https://github.com/facebook/react/pull/26395
|
|
3763
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
3764
|
-
React.useLayoutEffect(cb);
|
|
3765
|
-
}
|
|
3766
|
-
}
|
|
3767
|
-
|
|
3768
|
-
/**
|
|
3769
|
-
* Returns an imperative method for changing the location. Used by `<Link>`s, but
|
|
3770
|
-
* may also be used by other elements to change the location.
|
|
3771
|
-
*
|
|
3772
|
-
* @see https://reactrouter.com/v6/hooks/use-navigate
|
|
3773
|
-
*/
|
|
3774
|
-
function useNavigate() {
|
|
3775
|
-
let {
|
|
3776
|
-
isDataRoute
|
|
3777
|
-
} = React.useContext(RouteContext);
|
|
3778
|
-
// Conditional usage is OK here because the usage of a data router is static
|
|
3779
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
3780
|
-
return isDataRoute ? useNavigateStable() : useNavigateUnstable();
|
|
3781
|
-
}
|
|
3782
|
-
function useNavigateUnstable() {
|
|
3783
|
-
!useInRouterContext() ? process.env.NODE_ENV !== "production" ? invariant(false, // TODO: This error is probably because they somehow have 2 versions of the
|
|
3784
|
-
// router loaded. We can help them understand how to avoid that.
|
|
3785
|
-
"useNavigate() may be used only in the context of a <Router> component.") : invariant(false) : void 0;
|
|
3786
|
-
let dataRouterContext = React.useContext(DataRouterContext);
|
|
3787
|
-
let {
|
|
3788
|
-
basename,
|
|
3789
|
-
future,
|
|
3790
|
-
navigator
|
|
3791
|
-
} = React.useContext(NavigationContext);
|
|
3792
|
-
let {
|
|
3793
|
-
matches
|
|
3794
|
-
} = React.useContext(RouteContext);
|
|
3795
|
-
let {
|
|
3796
|
-
pathname: locationPathname
|
|
3797
|
-
} = useLocation();
|
|
3798
|
-
let routePathnamesJson = JSON.stringify(getResolveToMatches(matches, future.v7_relativeSplatPath));
|
|
3799
|
-
let activeRef = React.useRef(false);
|
|
3800
|
-
useIsomorphicLayoutEffect$1(() => {
|
|
3801
|
-
activeRef.current = true;
|
|
3802
|
-
});
|
|
3803
|
-
let navigate = React.useCallback(function (to, options) {
|
|
3804
|
-
if (options === void 0) {
|
|
3805
|
-
options = {};
|
|
3806
|
-
}
|
|
3807
|
-
process.env.NODE_ENV !== "production" ? warning(activeRef.current, navigateEffectWarning) : void 0;
|
|
3808
|
-
|
|
3809
|
-
// Short circuit here since if this happens on first render the navigate
|
|
3810
|
-
// is useless because we haven't wired up our history listener yet
|
|
3811
|
-
if (!activeRef.current) return;
|
|
3812
|
-
if (typeof to === "number") {
|
|
3813
|
-
navigator.go(to);
|
|
3814
|
-
return;
|
|
3815
|
-
}
|
|
3816
|
-
let path = resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, options.relative === "path");
|
|
3817
|
-
|
|
3818
|
-
// If we're operating within a basename, prepend it to the pathname prior
|
|
3819
|
-
// to handing off to history (but only if we're not in a data router,
|
|
3820
|
-
// otherwise it'll prepend the basename inside of the router).
|
|
3821
|
-
// If this is a root navigation, then we navigate to the raw basename
|
|
3822
|
-
// which allows the basename to have full control over the presence of a
|
|
3823
|
-
// trailing slash on root links
|
|
3824
|
-
if (dataRouterContext == null && basename !== "/") {
|
|
3825
|
-
path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]);
|
|
3826
|
-
}
|
|
3827
|
-
(!!options.replace ? navigator.replace : navigator.push)(path, options.state, options);
|
|
3828
|
-
}, [basename, navigator, routePathnamesJson, locationPathname, dataRouterContext]);
|
|
3829
|
-
return navigate;
|
|
3830
|
-
}
|
|
3831
|
-
|
|
3832
|
-
/**
|
|
3833
|
-
* Resolves the pathname of the given `to` value against the current location.
|
|
3834
|
-
*
|
|
3835
|
-
* @see https://reactrouter.com/v6/hooks/use-resolved-path
|
|
3836
|
-
*/
|
|
3837
|
-
function useResolvedPath(to, _temp2) {
|
|
3838
|
-
let {
|
|
3839
|
-
relative
|
|
3840
|
-
} = _temp2 === void 0 ? {} : _temp2;
|
|
3841
|
-
let {
|
|
3842
|
-
future
|
|
3843
|
-
} = React.useContext(NavigationContext);
|
|
3844
|
-
let {
|
|
3845
|
-
matches
|
|
3846
|
-
} = React.useContext(RouteContext);
|
|
3847
|
-
let {
|
|
3848
|
-
pathname: locationPathname
|
|
3849
|
-
} = useLocation();
|
|
3850
|
-
let routePathnamesJson = JSON.stringify(getResolveToMatches(matches, future.v7_relativeSplatPath));
|
|
3851
|
-
return React.useMemo(() => resolveTo(to, JSON.parse(routePathnamesJson), locationPathname, relative === "path"), [to, routePathnamesJson, locationPathname, relative]);
|
|
3852
|
-
}
|
|
3853
|
-
var DataRouterHook$1 = /*#__PURE__*/function (DataRouterHook) {
|
|
3854
|
-
DataRouterHook["UseBlocker"] = "useBlocker";
|
|
3855
|
-
DataRouterHook["UseRevalidator"] = "useRevalidator";
|
|
3856
|
-
DataRouterHook["UseNavigateStable"] = "useNavigate";
|
|
3857
|
-
return DataRouterHook;
|
|
3858
|
-
}(DataRouterHook$1 || {});
|
|
3859
|
-
var DataRouterStateHook$1 = /*#__PURE__*/function (DataRouterStateHook) {
|
|
3860
|
-
DataRouterStateHook["UseBlocker"] = "useBlocker";
|
|
3861
|
-
DataRouterStateHook["UseLoaderData"] = "useLoaderData";
|
|
3862
|
-
DataRouterStateHook["UseActionData"] = "useActionData";
|
|
3863
|
-
DataRouterStateHook["UseRouteError"] = "useRouteError";
|
|
3864
|
-
DataRouterStateHook["UseNavigation"] = "useNavigation";
|
|
3865
|
-
DataRouterStateHook["UseRouteLoaderData"] = "useRouteLoaderData";
|
|
3866
|
-
DataRouterStateHook["UseMatches"] = "useMatches";
|
|
3867
|
-
DataRouterStateHook["UseRevalidator"] = "useRevalidator";
|
|
3868
|
-
DataRouterStateHook["UseNavigateStable"] = "useNavigate";
|
|
3869
|
-
DataRouterStateHook["UseRouteId"] = "useRouteId";
|
|
3870
|
-
return DataRouterStateHook;
|
|
3871
|
-
}(DataRouterStateHook$1 || {});
|
|
3872
|
-
function getDataRouterConsoleError$1(hookName) {
|
|
3873
|
-
return hookName + " must be used within a data router. See https://reactrouter.com/v6/routers/picking-a-router.";
|
|
3874
|
-
}
|
|
3875
|
-
function useDataRouterContext$1(hookName) {
|
|
3876
|
-
let ctx = React.useContext(DataRouterContext);
|
|
3877
|
-
!ctx ? process.env.NODE_ENV !== "production" ? invariant(false, getDataRouterConsoleError$1(hookName)) : invariant(false) : void 0;
|
|
3878
|
-
return ctx;
|
|
3879
|
-
}
|
|
3880
|
-
function useRouteContext(hookName) {
|
|
3881
|
-
let route = React.useContext(RouteContext);
|
|
3882
|
-
!route ? process.env.NODE_ENV !== "production" ? invariant(false, getDataRouterConsoleError$1(hookName)) : invariant(false) : void 0;
|
|
3883
|
-
return route;
|
|
3884
|
-
}
|
|
3885
|
-
|
|
3886
|
-
// Internal version with hookName-aware debugging
|
|
3887
|
-
function useCurrentRouteId(hookName) {
|
|
3888
|
-
let route = useRouteContext(hookName);
|
|
3889
|
-
let thisRoute = route.matches[route.matches.length - 1];
|
|
3890
|
-
!thisRoute.route.id ? process.env.NODE_ENV !== "production" ? invariant(false, hookName + " can only be used on routes that contain a unique \"id\"") : invariant(false) : void 0;
|
|
3891
|
-
return thisRoute.route.id;
|
|
3892
|
-
}
|
|
3893
|
-
|
|
3894
|
-
/**
|
|
3895
|
-
* Returns the ID for the nearest contextual route
|
|
3896
|
-
*/
|
|
3897
|
-
function useRouteId() {
|
|
3898
|
-
return useCurrentRouteId(DataRouterStateHook$1.UseRouteId);
|
|
3899
|
-
}
|
|
3900
|
-
|
|
3901
|
-
/**
|
|
3902
|
-
* Stable version of useNavigate that is used when we are in the context of
|
|
3903
|
-
* a RouterProvider.
|
|
3904
|
-
*/
|
|
3905
|
-
function useNavigateStable() {
|
|
3906
|
-
let {
|
|
3907
|
-
router
|
|
3908
|
-
} = useDataRouterContext$1(DataRouterHook$1.UseNavigateStable);
|
|
3909
|
-
let id = useCurrentRouteId(DataRouterStateHook$1.UseNavigateStable);
|
|
3910
|
-
let activeRef = React.useRef(false);
|
|
3911
|
-
useIsomorphicLayoutEffect$1(() => {
|
|
3912
|
-
activeRef.current = true;
|
|
3913
|
-
});
|
|
3914
|
-
let navigate = React.useCallback(function (to, options) {
|
|
3915
|
-
if (options === void 0) {
|
|
3916
|
-
options = {};
|
|
3917
|
-
}
|
|
3918
|
-
process.env.NODE_ENV !== "production" ? warning(activeRef.current, navigateEffectWarning) : void 0;
|
|
3919
|
-
|
|
3920
|
-
// Short circuit here since if this happens on first render the navigate
|
|
3921
|
-
// is useless because we haven't wired up our router subscriber yet
|
|
3922
|
-
if (!activeRef.current) return;
|
|
3923
|
-
if (typeof to === "number") {
|
|
3924
|
-
router.navigate(to);
|
|
3925
|
-
} else {
|
|
3926
|
-
router.navigate(to, _extends$1({
|
|
3927
|
-
fromRouteId: id
|
|
3928
|
-
}, options));
|
|
3929
|
-
}
|
|
3930
|
-
}, [router, id]);
|
|
3931
|
-
return navigate;
|
|
3932
|
-
}
|
|
3933
|
-
new Promise(() => {});
|
|
3934
|
-
|
|
3935
|
-
/**
|
|
3936
|
-
* React Router DOM v6.28.1
|
|
3937
|
-
*
|
|
3938
|
-
* Copyright (c) Remix Software Inc.
|
|
3939
|
-
*
|
|
3940
|
-
* This source code is licensed under the MIT license found in the
|
|
3941
|
-
* LICENSE.md file in the root directory of this source tree.
|
|
3942
|
-
*
|
|
3943
|
-
* @license MIT
|
|
3944
|
-
*/
|
|
3945
|
-
|
|
3946
|
-
function _extends() {
|
|
3947
|
-
_extends = Object.assign ? Object.assign.bind() : function (target) {
|
|
3948
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
3949
|
-
var source = arguments[i];
|
|
3950
|
-
for (var key in source) {
|
|
3951
|
-
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
|
3952
|
-
target[key] = source[key];
|
|
3953
|
-
}
|
|
3954
|
-
}
|
|
3955
|
-
}
|
|
3956
|
-
return target;
|
|
3957
|
-
};
|
|
3958
|
-
return _extends.apply(this, arguments);
|
|
3959
|
-
}
|
|
3960
|
-
function _objectWithoutPropertiesLoose(source, excluded) {
|
|
3961
|
-
if (source == null) return {};
|
|
3962
|
-
var target = {};
|
|
3963
|
-
var sourceKeys = Object.keys(source);
|
|
3964
|
-
var key, i;
|
|
3965
|
-
for (i = 0; i < sourceKeys.length; i++) {
|
|
3966
|
-
key = sourceKeys[i];
|
|
3967
|
-
if (excluded.indexOf(key) >= 0) continue;
|
|
3968
|
-
target[key] = source[key];
|
|
3969
|
-
}
|
|
3970
|
-
return target;
|
|
3971
|
-
}
|
|
3972
|
-
|
|
3973
|
-
const defaultMethod = "get";
|
|
3974
|
-
const defaultEncType = "application/x-www-form-urlencoded";
|
|
3975
|
-
function isHtmlElement(object) {
|
|
3976
|
-
return object != null && typeof object.tagName === "string";
|
|
3977
|
-
}
|
|
3978
|
-
function isButtonElement(object) {
|
|
3979
|
-
return isHtmlElement(object) && object.tagName.toLowerCase() === "button";
|
|
3980
|
-
}
|
|
3981
|
-
function isFormElement(object) {
|
|
3982
|
-
return isHtmlElement(object) && object.tagName.toLowerCase() === "form";
|
|
3983
|
-
}
|
|
3984
|
-
function isInputElement(object) {
|
|
3985
|
-
return isHtmlElement(object) && object.tagName.toLowerCase() === "input";
|
|
3986
|
-
}
|
|
3987
|
-
function isModifiedEvent(event) {
|
|
3988
|
-
return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey);
|
|
3989
|
-
}
|
|
3990
|
-
function shouldProcessLinkClick(event, target) {
|
|
3991
|
-
return event.button === 0 && (
|
|
3992
|
-
// Ignore everything but left clicks
|
|
3993
|
-
!target || target === "_self") &&
|
|
3994
|
-
// Let browser handle "target=_blank" etc.
|
|
3995
|
-
!isModifiedEvent(event) // Ignore clicks with modifier keys
|
|
3996
|
-
;
|
|
3997
|
-
}
|
|
3998
|
-
/**
|
|
3999
|
-
* Creates a URLSearchParams object using the given initializer.
|
|
4000
|
-
*
|
|
4001
|
-
* This is identical to `new URLSearchParams(init)` except it also
|
|
4002
|
-
* supports arrays as values in the object form of the initializer
|
|
4003
|
-
* instead of just strings. This is convenient when you need multiple
|
|
4004
|
-
* values for a given key, but don't want to use an array initializer.
|
|
4005
|
-
*
|
|
4006
|
-
* For example, instead of:
|
|
4007
|
-
*
|
|
4008
|
-
* let searchParams = new URLSearchParams([
|
|
4009
|
-
* ['sort', 'name'],
|
|
4010
|
-
* ['sort', 'price']
|
|
4011
|
-
* ]);
|
|
4012
|
-
*
|
|
4013
|
-
* you can do:
|
|
4014
|
-
*
|
|
4015
|
-
* let searchParams = createSearchParams({
|
|
4016
|
-
* sort: ['name', 'price']
|
|
4017
|
-
* });
|
|
4018
|
-
*/
|
|
4019
|
-
function createSearchParams(init) {
|
|
4020
|
-
if (init === void 0) {
|
|
4021
|
-
init = "";
|
|
4022
|
-
}
|
|
4023
|
-
return new URLSearchParams(typeof init === "string" || Array.isArray(init) || init instanceof URLSearchParams ? init : Object.keys(init).reduce((memo, key) => {
|
|
4024
|
-
let value = init[key];
|
|
4025
|
-
return memo.concat(Array.isArray(value) ? value.map(v => [key, v]) : [[key, value]]);
|
|
4026
|
-
}, []));
|
|
4027
|
-
}
|
|
4028
|
-
function getSearchParamsForLocation(locationSearch, defaultSearchParams) {
|
|
4029
|
-
let searchParams = createSearchParams(locationSearch);
|
|
4030
|
-
if (defaultSearchParams) {
|
|
4031
|
-
// Use `defaultSearchParams.forEach(...)` here instead of iterating of
|
|
4032
|
-
// `defaultSearchParams.keys()` to work-around a bug in Firefox related to
|
|
4033
|
-
// web extensions. Relevant Bugzilla tickets:
|
|
4034
|
-
// https://bugzilla.mozilla.org/show_bug.cgi?id=1414602
|
|
4035
|
-
// https://bugzilla.mozilla.org/show_bug.cgi?id=1023984
|
|
4036
|
-
defaultSearchParams.forEach((_, key) => {
|
|
4037
|
-
if (!searchParams.has(key)) {
|
|
4038
|
-
defaultSearchParams.getAll(key).forEach(value => {
|
|
4039
|
-
searchParams.append(key, value);
|
|
4040
|
-
});
|
|
4041
|
-
}
|
|
4042
|
-
});
|
|
4043
|
-
}
|
|
4044
|
-
return searchParams;
|
|
4045
|
-
}
|
|
4046
|
-
// One-time check for submitter support
|
|
4047
|
-
let _formDataSupportsSubmitter = null;
|
|
4048
|
-
function isFormDataSubmitterSupported() {
|
|
4049
|
-
if (_formDataSupportsSubmitter === null) {
|
|
4050
|
-
try {
|
|
4051
|
-
new FormData(document.createElement("form"),
|
|
4052
|
-
// @ts-expect-error if FormData supports the submitter parameter, this will throw
|
|
4053
|
-
0);
|
|
4054
|
-
_formDataSupportsSubmitter = false;
|
|
4055
|
-
} catch (e) {
|
|
4056
|
-
_formDataSupportsSubmitter = true;
|
|
4057
|
-
}
|
|
4058
|
-
}
|
|
4059
|
-
return _formDataSupportsSubmitter;
|
|
4060
|
-
}
|
|
4061
|
-
const supportedFormEncTypes = new Set(["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"]);
|
|
4062
|
-
function getFormEncType(encType) {
|
|
4063
|
-
if (encType != null && !supportedFormEncTypes.has(encType)) {
|
|
4064
|
-
process.env.NODE_ENV !== "production" ? warning(false, "\"" + encType + "\" is not a valid `encType` for `<Form>`/`<fetcher.Form>` " + ("and will default to \"" + defaultEncType + "\"")) : void 0;
|
|
4065
|
-
return null;
|
|
4066
|
-
}
|
|
4067
|
-
return encType;
|
|
4068
|
-
}
|
|
4069
|
-
function getFormSubmissionInfo(target, basename) {
|
|
4070
|
-
let method;
|
|
4071
|
-
let action;
|
|
4072
|
-
let encType;
|
|
4073
|
-
let formData;
|
|
4074
|
-
let body;
|
|
4075
|
-
if (isFormElement(target)) {
|
|
4076
|
-
// When grabbing the action from the element, it will have had the basename
|
|
4077
|
-
// prefixed to ensure non-JS scenarios work, so strip it since we'll
|
|
4078
|
-
// re-prefix in the router
|
|
4079
|
-
let attr = target.getAttribute("action");
|
|
4080
|
-
action = attr ? stripBasename(attr, basename) : null;
|
|
4081
|
-
method = target.getAttribute("method") || defaultMethod;
|
|
4082
|
-
encType = getFormEncType(target.getAttribute("enctype")) || defaultEncType;
|
|
4083
|
-
formData = new FormData(target);
|
|
4084
|
-
} else if (isButtonElement(target) || isInputElement(target) && (target.type === "submit" || target.type === "image")) {
|
|
4085
|
-
let form = target.form;
|
|
4086
|
-
if (form == null) {
|
|
4087
|
-
throw new Error("Cannot submit a <button> or <input type=\"submit\"> without a <form>");
|
|
4088
|
-
}
|
|
4089
|
-
// <button>/<input type="submit"> may override attributes of <form>
|
|
4090
|
-
// When grabbing the action from the element, it will have had the basename
|
|
4091
|
-
// prefixed to ensure non-JS scenarios work, so strip it since we'll
|
|
4092
|
-
// re-prefix in the router
|
|
4093
|
-
let attr = target.getAttribute("formaction") || form.getAttribute("action");
|
|
4094
|
-
action = attr ? stripBasename(attr, basename) : null;
|
|
4095
|
-
method = target.getAttribute("formmethod") || form.getAttribute("method") || defaultMethod;
|
|
4096
|
-
encType = getFormEncType(target.getAttribute("formenctype")) || getFormEncType(form.getAttribute("enctype")) || defaultEncType;
|
|
4097
|
-
// Build a FormData object populated from a form and submitter
|
|
4098
|
-
formData = new FormData(form, target);
|
|
4099
|
-
// If this browser doesn't support the `FormData(el, submitter)` format,
|
|
4100
|
-
// then tack on the submitter value at the end. This is a lightweight
|
|
4101
|
-
// solution that is not 100% spec compliant. For complete support in older
|
|
4102
|
-
// browsers, consider using the `formdata-submitter-polyfill` package
|
|
4103
|
-
if (!isFormDataSubmitterSupported()) {
|
|
4104
|
-
let {
|
|
4105
|
-
name,
|
|
4106
|
-
type,
|
|
4107
|
-
value
|
|
4108
|
-
} = target;
|
|
4109
|
-
if (type === "image") {
|
|
4110
|
-
let prefix = name ? name + "." : "";
|
|
4111
|
-
formData.append(prefix + "x", "0");
|
|
4112
|
-
formData.append(prefix + "y", "0");
|
|
4113
|
-
} else if (name) {
|
|
4114
|
-
formData.append(name, value);
|
|
4115
|
-
}
|
|
4116
|
-
}
|
|
4117
|
-
} else if (isHtmlElement(target)) {
|
|
4118
|
-
throw new Error("Cannot submit element that is not <form>, <button>, or " + "<input type=\"submit|image\">");
|
|
4119
|
-
} else {
|
|
4120
|
-
method = defaultMethod;
|
|
4121
|
-
action = null;
|
|
4122
|
-
encType = defaultEncType;
|
|
4123
|
-
body = target;
|
|
4124
|
-
}
|
|
4125
|
-
// Send body for <Form encType="text/plain" so we encode it into text
|
|
4126
|
-
if (formData && encType === "text/plain") {
|
|
4127
|
-
body = formData;
|
|
4128
|
-
formData = undefined;
|
|
4129
|
-
}
|
|
4130
|
-
return {
|
|
4131
|
-
action,
|
|
4132
|
-
method: method.toLowerCase(),
|
|
4133
|
-
encType,
|
|
4134
|
-
formData,
|
|
4135
|
-
body
|
|
4136
|
-
};
|
|
4137
|
-
}
|
|
4138
|
-
|
|
4139
|
-
const _excluded = ["onClick", "relative", "reloadDocument", "replace", "state", "target", "to", "preventScrollReset", "viewTransition"],
|
|
4140
|
-
_excluded2 = ["aria-current", "caseSensitive", "className", "end", "style", "to", "viewTransition", "children"],
|
|
4141
|
-
_excluded3 = ["fetcherKey", "navigate", "reloadDocument", "replace", "state", "method", "action", "onSubmit", "relative", "preventScrollReset", "viewTransition"];
|
|
4142
|
-
// HEY YOU! DON'T TOUCH THIS VARIABLE!
|
|
4143
|
-
//
|
|
4144
|
-
// It is replaced with the proper version at build time via a babel plugin in
|
|
4145
|
-
// the rollup config.
|
|
4146
|
-
//
|
|
4147
|
-
// Export a global property onto the window for React Router detection by the
|
|
4148
|
-
// Core Web Vitals Technology Report. This way they can configure the `wappalyzer`
|
|
4149
|
-
// to detect and properly classify live websites as being built with React Router:
|
|
4150
|
-
// https://github.com/HTTPArchive/wappalyzer/blob/main/src/technologies/r.json
|
|
4151
|
-
const REACT_ROUTER_VERSION = "6";
|
|
4152
|
-
try {
|
|
4153
|
-
window.__reactRouterVersion = REACT_ROUTER_VERSION;
|
|
4154
|
-
} catch (e) {
|
|
4155
|
-
// no-op
|
|
4156
|
-
}
|
|
4157
|
-
const ViewTransitionContext = /*#__PURE__*/React.createContext({
|
|
4158
|
-
isTransitioning: false
|
|
4159
|
-
});
|
|
4160
|
-
if (process.env.NODE_ENV !== "production") {
|
|
4161
|
-
ViewTransitionContext.displayName = "ViewTransition";
|
|
4162
|
-
}
|
|
4163
|
-
const FetchersContext = /*#__PURE__*/React.createContext(new Map());
|
|
4164
|
-
if (process.env.NODE_ENV !== "production") {
|
|
4165
|
-
FetchersContext.displayName = "Fetchers";
|
|
4166
|
-
}
|
|
4167
|
-
if (process.env.NODE_ENV !== "production") ;
|
|
4168
|
-
const isBrowser$1 = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined";
|
|
4169
|
-
const ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
|
|
4170
|
-
/**
|
|
4171
|
-
* The public API for rendering a history-aware `<a>`.
|
|
4172
|
-
*/
|
|
4173
|
-
const Link = /*#__PURE__*/React.forwardRef(function LinkWithRef(_ref7, ref) {
|
|
4174
|
-
let {
|
|
4175
|
-
onClick,
|
|
4176
|
-
relative,
|
|
4177
|
-
reloadDocument,
|
|
4178
|
-
replace,
|
|
4179
|
-
state,
|
|
4180
|
-
target,
|
|
4181
|
-
to,
|
|
4182
|
-
preventScrollReset,
|
|
4183
|
-
viewTransition
|
|
4184
|
-
} = _ref7,
|
|
4185
|
-
rest = _objectWithoutPropertiesLoose(_ref7, _excluded);
|
|
4186
|
-
let {
|
|
4187
|
-
basename
|
|
4188
|
-
} = React.useContext(NavigationContext);
|
|
4189
|
-
// Rendered into <a href> for absolute URLs
|
|
4190
|
-
let absoluteHref;
|
|
4191
|
-
let isExternal = false;
|
|
4192
|
-
if (typeof to === "string" && ABSOLUTE_URL_REGEX.test(to)) {
|
|
4193
|
-
// Render the absolute href server- and client-side
|
|
4194
|
-
absoluteHref = to;
|
|
4195
|
-
// Only check for external origins client-side
|
|
4196
|
-
if (isBrowser$1) {
|
|
4197
|
-
try {
|
|
4198
|
-
let currentUrl = new URL(window.location.href);
|
|
4199
|
-
let targetUrl = to.startsWith("//") ? new URL(currentUrl.protocol + to) : new URL(to);
|
|
4200
|
-
let path = stripBasename(targetUrl.pathname, basename);
|
|
4201
|
-
if (targetUrl.origin === currentUrl.origin && path != null) {
|
|
4202
|
-
// Strip the protocol/origin/basename for same-origin absolute URLs
|
|
4203
|
-
to = path + targetUrl.search + targetUrl.hash;
|
|
4204
|
-
} else {
|
|
4205
|
-
isExternal = true;
|
|
4206
|
-
}
|
|
4207
|
-
} catch (e) {
|
|
4208
|
-
// We can't do external URL detection without a valid URL
|
|
4209
|
-
process.env.NODE_ENV !== "production" ? warning(false, "<Link to=\"" + to + "\"> contains an invalid URL which will probably break " + "when clicked - please update to a valid URL path.") : void 0;
|
|
4210
|
-
}
|
|
4211
|
-
}
|
|
4212
|
-
}
|
|
4213
|
-
// Rendered into <a href> for relative URLs
|
|
4214
|
-
let href = useHref(to, {
|
|
4215
|
-
relative
|
|
4216
|
-
});
|
|
4217
|
-
let internalOnClick = useLinkClickHandler(to, {
|
|
4218
|
-
replace,
|
|
4219
|
-
state,
|
|
4220
|
-
target,
|
|
4221
|
-
preventScrollReset,
|
|
4222
|
-
relative,
|
|
4223
|
-
viewTransition
|
|
4224
|
-
});
|
|
4225
|
-
function handleClick(event) {
|
|
4226
|
-
if (onClick) onClick(event);
|
|
4227
|
-
if (!event.defaultPrevented) {
|
|
4228
|
-
internalOnClick(event);
|
|
4229
|
-
}
|
|
4230
|
-
}
|
|
4231
|
-
return (
|
|
4232
|
-
/*#__PURE__*/
|
|
4233
|
-
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
|
4234
|
-
React.createElement("a", _extends({}, rest, {
|
|
4235
|
-
href: absoluteHref || href,
|
|
4236
|
-
onClick: isExternal || reloadDocument ? onClick : handleClick,
|
|
4237
|
-
ref: ref,
|
|
4238
|
-
target: target
|
|
4239
|
-
}))
|
|
4240
|
-
);
|
|
4241
|
-
});
|
|
4242
|
-
if (process.env.NODE_ENV !== "production") {
|
|
4243
|
-
Link.displayName = "Link";
|
|
4244
|
-
}
|
|
4245
|
-
/**
|
|
4246
|
-
* A `<Link>` wrapper that knows if it's "active" or not.
|
|
4247
|
-
*/
|
|
4248
|
-
const NavLink = /*#__PURE__*/React.forwardRef(function NavLinkWithRef(_ref8, ref) {
|
|
4249
|
-
let {
|
|
4250
|
-
"aria-current": ariaCurrentProp = "page",
|
|
4251
|
-
caseSensitive = false,
|
|
4252
|
-
className: classNameProp = "",
|
|
4253
|
-
end = false,
|
|
4254
|
-
style: styleProp,
|
|
4255
|
-
to,
|
|
4256
|
-
viewTransition,
|
|
4257
|
-
children
|
|
4258
|
-
} = _ref8,
|
|
4259
|
-
rest = _objectWithoutPropertiesLoose(_ref8, _excluded2);
|
|
4260
|
-
let path = useResolvedPath(to, {
|
|
4261
|
-
relative: rest.relative
|
|
4262
|
-
});
|
|
4263
|
-
let location = useLocation();
|
|
4264
|
-
let routerState = React.useContext(DataRouterStateContext);
|
|
4265
|
-
let {
|
|
4266
|
-
navigator,
|
|
4267
|
-
basename
|
|
4268
|
-
} = React.useContext(NavigationContext);
|
|
4269
|
-
let isTransitioning = routerState != null &&
|
|
4270
|
-
// Conditional usage is OK here because the usage of a data router is static
|
|
4271
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
4272
|
-
useViewTransitionState(path) && viewTransition === true;
|
|
4273
|
-
let toPathname = navigator.encodeLocation ? navigator.encodeLocation(path).pathname : path.pathname;
|
|
4274
|
-
let locationPathname = location.pathname;
|
|
4275
|
-
let nextLocationPathname = routerState && routerState.navigation && routerState.navigation.location ? routerState.navigation.location.pathname : null;
|
|
4276
|
-
if (!caseSensitive) {
|
|
4277
|
-
locationPathname = locationPathname.toLowerCase();
|
|
4278
|
-
nextLocationPathname = nextLocationPathname ? nextLocationPathname.toLowerCase() : null;
|
|
4279
|
-
toPathname = toPathname.toLowerCase();
|
|
4280
|
-
}
|
|
4281
|
-
if (nextLocationPathname && basename) {
|
|
4282
|
-
nextLocationPathname = stripBasename(nextLocationPathname, basename) || nextLocationPathname;
|
|
4283
|
-
}
|
|
4284
|
-
// If the `to` has a trailing slash, look at that exact spot. Otherwise,
|
|
4285
|
-
// we're looking for a slash _after_ what's in `to`. For example:
|
|
4286
|
-
//
|
|
4287
|
-
// <NavLink to="/users"> and <NavLink to="/users/">
|
|
4288
|
-
// both want to look for a / at index 6 to match URL `/users/matt`
|
|
4289
|
-
const endSlashPosition = toPathname !== "/" && toPathname.endsWith("/") ? toPathname.length - 1 : toPathname.length;
|
|
4290
|
-
let isActive = locationPathname === toPathname || !end && locationPathname.startsWith(toPathname) && locationPathname.charAt(endSlashPosition) === "/";
|
|
4291
|
-
let isPending = nextLocationPathname != null && (nextLocationPathname === toPathname || !end && nextLocationPathname.startsWith(toPathname) && nextLocationPathname.charAt(toPathname.length) === "/");
|
|
4292
|
-
let renderProps = {
|
|
4293
|
-
isActive,
|
|
4294
|
-
isPending,
|
|
4295
|
-
isTransitioning
|
|
4296
|
-
};
|
|
4297
|
-
let ariaCurrent = isActive ? ariaCurrentProp : undefined;
|
|
4298
|
-
let className;
|
|
4299
|
-
if (typeof classNameProp === "function") {
|
|
4300
|
-
className = classNameProp(renderProps);
|
|
4301
|
-
} else {
|
|
4302
|
-
// If the className prop is not a function, we use a default `active`
|
|
4303
|
-
// class for <NavLink />s that are active. In v5 `active` was the default
|
|
4304
|
-
// value for `activeClassName`, but we are removing that API and can still
|
|
4305
|
-
// use the old default behavior for a cleaner upgrade path and keep the
|
|
4306
|
-
// simple styling rules working as they currently do.
|
|
4307
|
-
className = [classNameProp, isActive ? "active" : null, isPending ? "pending" : null, isTransitioning ? "transitioning" : null].filter(Boolean).join(" ");
|
|
4308
|
-
}
|
|
4309
|
-
let style = typeof styleProp === "function" ? styleProp(renderProps) : styleProp;
|
|
4310
|
-
return /*#__PURE__*/React.createElement(Link, _extends({}, rest, {
|
|
4311
|
-
"aria-current": ariaCurrent,
|
|
4312
|
-
className: className,
|
|
4313
|
-
ref: ref,
|
|
4314
|
-
style: style,
|
|
4315
|
-
to: to,
|
|
4316
|
-
viewTransition: viewTransition
|
|
4317
|
-
}), typeof children === "function" ? children(renderProps) : children);
|
|
4318
|
-
});
|
|
4319
|
-
if (process.env.NODE_ENV !== "production") {
|
|
4320
|
-
NavLink.displayName = "NavLink";
|
|
4321
|
-
}
|
|
4322
|
-
/**
|
|
4323
|
-
* A `@remix-run/router`-aware `<form>`. It behaves like a normal form except
|
|
4324
|
-
* that the interaction with the server is with `fetch` instead of new document
|
|
4325
|
-
* requests, allowing components to add nicer UX to the page as the form is
|
|
4326
|
-
* submitted and returns with data.
|
|
4327
|
-
*/
|
|
4328
|
-
const Form = /*#__PURE__*/React.forwardRef((_ref9, forwardedRef) => {
|
|
4329
|
-
let {
|
|
4330
|
-
fetcherKey,
|
|
4331
|
-
navigate,
|
|
4332
|
-
reloadDocument,
|
|
4333
|
-
replace,
|
|
4334
|
-
state,
|
|
4335
|
-
method = defaultMethod,
|
|
4336
|
-
action,
|
|
4337
|
-
onSubmit,
|
|
4338
|
-
relative,
|
|
4339
|
-
preventScrollReset,
|
|
4340
|
-
viewTransition
|
|
4341
|
-
} = _ref9,
|
|
4342
|
-
props = _objectWithoutPropertiesLoose(_ref9, _excluded3);
|
|
4343
|
-
let submit = useSubmit();
|
|
4344
|
-
let formAction = useFormAction(action, {
|
|
4345
|
-
relative
|
|
4346
|
-
});
|
|
4347
|
-
let formMethod = method.toLowerCase() === "get" ? "get" : "post";
|
|
4348
|
-
let submitHandler = event => {
|
|
4349
|
-
onSubmit && onSubmit(event);
|
|
4350
|
-
if (event.defaultPrevented) return;
|
|
4351
|
-
event.preventDefault();
|
|
4352
|
-
let submitter = event.nativeEvent.submitter;
|
|
4353
|
-
let submitMethod = (submitter == null ? void 0 : submitter.getAttribute("formmethod")) || method;
|
|
4354
|
-
submit(submitter || event.currentTarget, {
|
|
4355
|
-
fetcherKey,
|
|
4356
|
-
method: submitMethod,
|
|
4357
|
-
navigate,
|
|
4358
|
-
replace,
|
|
4359
|
-
state,
|
|
4360
|
-
relative,
|
|
4361
|
-
preventScrollReset,
|
|
4362
|
-
viewTransition
|
|
4363
|
-
});
|
|
4364
|
-
};
|
|
4365
|
-
return /*#__PURE__*/React.createElement("form", _extends({
|
|
4366
|
-
ref: forwardedRef,
|
|
4367
|
-
method: formMethod,
|
|
4368
|
-
action: formAction,
|
|
4369
|
-
onSubmit: reloadDocument ? onSubmit : submitHandler
|
|
4370
|
-
}, props));
|
|
4371
|
-
});
|
|
4372
|
-
if (process.env.NODE_ENV !== "production") {
|
|
4373
|
-
Form.displayName = "Form";
|
|
4374
|
-
}
|
|
4375
|
-
if (process.env.NODE_ENV !== "production") ;
|
|
4376
|
-
//#endregion
|
|
4377
|
-
////////////////////////////////////////////////////////////////////////////////
|
|
4378
|
-
//#region Hooks
|
|
4379
|
-
////////////////////////////////////////////////////////////////////////////////
|
|
4380
|
-
var DataRouterHook;
|
|
4381
|
-
(function (DataRouterHook) {
|
|
4382
|
-
DataRouterHook["UseScrollRestoration"] = "useScrollRestoration";
|
|
4383
|
-
DataRouterHook["UseSubmit"] = "useSubmit";
|
|
4384
|
-
DataRouterHook["UseSubmitFetcher"] = "useSubmitFetcher";
|
|
4385
|
-
DataRouterHook["UseFetcher"] = "useFetcher";
|
|
4386
|
-
DataRouterHook["useViewTransitionState"] = "useViewTransitionState";
|
|
4387
|
-
})(DataRouterHook || (DataRouterHook = {}));
|
|
4388
|
-
var DataRouterStateHook;
|
|
4389
|
-
(function (DataRouterStateHook) {
|
|
4390
|
-
DataRouterStateHook["UseFetcher"] = "useFetcher";
|
|
4391
|
-
DataRouterStateHook["UseFetchers"] = "useFetchers";
|
|
4392
|
-
DataRouterStateHook["UseScrollRestoration"] = "useScrollRestoration";
|
|
4393
|
-
})(DataRouterStateHook || (DataRouterStateHook = {}));
|
|
4394
|
-
// Internal hooks
|
|
4395
|
-
function getDataRouterConsoleError(hookName) {
|
|
4396
|
-
return hookName + " must be used within a data router. See https://reactrouter.com/v6/routers/picking-a-router.";
|
|
4397
|
-
}
|
|
4398
|
-
function useDataRouterContext(hookName) {
|
|
4399
|
-
let ctx = React.useContext(DataRouterContext);
|
|
4400
|
-
!ctx ? process.env.NODE_ENV !== "production" ? invariant(false, getDataRouterConsoleError(hookName)) : invariant(false) : void 0;
|
|
4401
|
-
return ctx;
|
|
4402
|
-
}
|
|
4403
|
-
// External hooks
|
|
4404
|
-
/**
|
|
4405
|
-
* Handles the click behavior for router `<Link>` components. This is useful if
|
|
4406
|
-
* you need to create custom `<Link>` components with the same click behavior we
|
|
4407
|
-
* use in our exported `<Link>`.
|
|
4408
|
-
*/
|
|
4409
|
-
function useLinkClickHandler(to, _temp) {
|
|
4410
|
-
let {
|
|
4411
|
-
target,
|
|
4412
|
-
replace: replaceProp,
|
|
4413
|
-
state,
|
|
4414
|
-
preventScrollReset,
|
|
4415
|
-
relative,
|
|
4416
|
-
viewTransition
|
|
4417
|
-
} = _temp === void 0 ? {} : _temp;
|
|
4418
|
-
let navigate = useNavigate();
|
|
4419
|
-
let location = useLocation();
|
|
4420
|
-
let path = useResolvedPath(to, {
|
|
4421
|
-
relative
|
|
4422
|
-
});
|
|
4423
|
-
return React.useCallback(event => {
|
|
4424
|
-
if (shouldProcessLinkClick(event, target)) {
|
|
4425
|
-
event.preventDefault();
|
|
4426
|
-
// If the URL hasn't changed, a regular <a> will do a replace instead of
|
|
4427
|
-
// a push, so do the same here unless the replace prop is explicitly set
|
|
4428
|
-
let replace = replaceProp !== undefined ? replaceProp : createPath(location) === createPath(path);
|
|
4429
|
-
navigate(to, {
|
|
4430
|
-
replace,
|
|
4431
|
-
state,
|
|
4432
|
-
preventScrollReset,
|
|
4433
|
-
relative,
|
|
4434
|
-
viewTransition
|
|
4435
|
-
});
|
|
4436
|
-
}
|
|
4437
|
-
}, [location, navigate, path, replaceProp, state, target, to, preventScrollReset, relative, viewTransition]);
|
|
4438
|
-
}
|
|
4439
|
-
/**
|
|
4440
|
-
* A convenient wrapper for reading and writing search parameters via the
|
|
4441
|
-
* URLSearchParams interface.
|
|
4442
|
-
*/
|
|
4443
|
-
function useSearchParams(defaultInit) {
|
|
4444
|
-
process.env.NODE_ENV !== "production" ? warning(typeof URLSearchParams !== "undefined", "You cannot use the `useSearchParams` hook in a browser that does not " + "support the URLSearchParams API. If you need to support Internet " + "Explorer 11, we recommend you load a polyfill such as " + "https://github.com/ungap/url-search-params.") : void 0;
|
|
4445
|
-
let defaultSearchParamsRef = React.useRef(createSearchParams(defaultInit));
|
|
4446
|
-
let hasSetSearchParamsRef = React.useRef(false);
|
|
4447
|
-
let location = useLocation();
|
|
4448
|
-
let searchParams = React.useMemo(() =>
|
|
4449
|
-
// Only merge in the defaults if we haven't yet called setSearchParams.
|
|
4450
|
-
// Once we call that we want those to take precedence, otherwise you can't
|
|
4451
|
-
// remove a param with setSearchParams({}) if it has an initial value
|
|
4452
|
-
getSearchParamsForLocation(location.search, hasSetSearchParamsRef.current ? null : defaultSearchParamsRef.current), [location.search]);
|
|
4453
|
-
let navigate = useNavigate();
|
|
4454
|
-
let setSearchParams = React.useCallback((nextInit, navigateOptions) => {
|
|
4455
|
-
const newSearchParams = createSearchParams(typeof nextInit === "function" ? nextInit(searchParams) : nextInit);
|
|
4456
|
-
hasSetSearchParamsRef.current = true;
|
|
4457
|
-
navigate("?" + newSearchParams, navigateOptions);
|
|
4458
|
-
}, [navigate, searchParams]);
|
|
4459
|
-
return [searchParams, setSearchParams];
|
|
4460
|
-
}
|
|
4461
|
-
function validateClientSideSubmission() {
|
|
4462
|
-
if (typeof document === "undefined") {
|
|
4463
|
-
throw new Error("You are calling submit during the server render. " + "Try calling submit within a `useEffect` or callback instead.");
|
|
4464
|
-
}
|
|
4465
|
-
}
|
|
4466
|
-
let fetcherId = 0;
|
|
4467
|
-
let getUniqueFetcherId = () => "__" + String(++fetcherId) + "__";
|
|
4468
|
-
/**
|
|
4469
|
-
* Returns a function that may be used to programmatically submit a form (or
|
|
4470
|
-
* some arbitrary data) to the server.
|
|
4471
|
-
*/
|
|
4472
|
-
function useSubmit() {
|
|
4473
|
-
let {
|
|
4474
|
-
router
|
|
4475
|
-
} = useDataRouterContext(DataRouterHook.UseSubmit);
|
|
4476
|
-
let {
|
|
4477
|
-
basename
|
|
4478
|
-
} = React.useContext(NavigationContext);
|
|
4479
|
-
let currentRouteId = useRouteId();
|
|
4480
|
-
return React.useCallback(function (target, options) {
|
|
4481
|
-
if (options === void 0) {
|
|
4482
|
-
options = {};
|
|
4483
|
-
}
|
|
4484
|
-
validateClientSideSubmission();
|
|
4485
|
-
let {
|
|
4486
|
-
action,
|
|
4487
|
-
method,
|
|
4488
|
-
encType,
|
|
4489
|
-
formData,
|
|
4490
|
-
body
|
|
4491
|
-
} = getFormSubmissionInfo(target, basename);
|
|
4492
|
-
if (options.navigate === false) {
|
|
4493
|
-
let key = options.fetcherKey || getUniqueFetcherId();
|
|
4494
|
-
router.fetch(key, currentRouteId, options.action || action, {
|
|
4495
|
-
preventScrollReset: options.preventScrollReset,
|
|
4496
|
-
formData,
|
|
4497
|
-
body,
|
|
4498
|
-
formMethod: options.method || method,
|
|
4499
|
-
formEncType: options.encType || encType,
|
|
4500
|
-
flushSync: options.flushSync
|
|
4501
|
-
});
|
|
4502
|
-
} else {
|
|
4503
|
-
router.navigate(options.action || action, {
|
|
4504
|
-
preventScrollReset: options.preventScrollReset,
|
|
4505
|
-
formData,
|
|
4506
|
-
body,
|
|
4507
|
-
formMethod: options.method || method,
|
|
4508
|
-
formEncType: options.encType || encType,
|
|
4509
|
-
replace: options.replace,
|
|
4510
|
-
state: options.state,
|
|
4511
|
-
fromRouteId: currentRouteId,
|
|
4512
|
-
flushSync: options.flushSync,
|
|
4513
|
-
viewTransition: options.viewTransition
|
|
4514
|
-
});
|
|
4515
|
-
}
|
|
4516
|
-
}, [router, basename, currentRouteId]);
|
|
4517
|
-
}
|
|
4518
|
-
// v7: Eventually we should deprecate this entirely in favor of using the
|
|
4519
|
-
// router method directly?
|
|
4520
|
-
function useFormAction(action, _temp2) {
|
|
4521
|
-
let {
|
|
4522
|
-
relative
|
|
4523
|
-
} = _temp2 === void 0 ? {} : _temp2;
|
|
4524
|
-
let {
|
|
4525
|
-
basename
|
|
4526
|
-
} = React.useContext(NavigationContext);
|
|
4527
|
-
let routeContext = React.useContext(RouteContext);
|
|
4528
|
-
!routeContext ? process.env.NODE_ENV !== "production" ? invariant(false, "useFormAction must be used inside a RouteContext") : invariant(false) : void 0;
|
|
4529
|
-
let [match] = routeContext.matches.slice(-1);
|
|
4530
|
-
// Shallow clone path so we can modify it below, otherwise we modify the
|
|
4531
|
-
// object referenced by useMemo inside useResolvedPath
|
|
4532
|
-
let path = _extends({}, useResolvedPath(action ? action : ".", {
|
|
4533
|
-
relative
|
|
4534
|
-
}));
|
|
4535
|
-
// If no action was specified, browsers will persist current search params
|
|
4536
|
-
// when determining the path, so match that behavior
|
|
4537
|
-
// https://github.com/remix-run/remix/issues/927
|
|
4538
|
-
let location = useLocation();
|
|
4539
|
-
if (action == null) {
|
|
4540
|
-
// Safe to write to this directly here since if action was undefined, we
|
|
4541
|
-
// would have called useResolvedPath(".") which will never include a search
|
|
4542
|
-
path.search = location.search;
|
|
4543
|
-
// When grabbing search params from the URL, remove any included ?index param
|
|
4544
|
-
// since it might not apply to our contextual route. We add it back based
|
|
4545
|
-
// on match.route.index below
|
|
4546
|
-
let params = new URLSearchParams(path.search);
|
|
4547
|
-
let indexValues = params.getAll("index");
|
|
4548
|
-
let hasNakedIndexParam = indexValues.some(v => v === "");
|
|
4549
|
-
if (hasNakedIndexParam) {
|
|
4550
|
-
params.delete("index");
|
|
4551
|
-
indexValues.filter(v => v).forEach(v => params.append("index", v));
|
|
4552
|
-
let qs = params.toString();
|
|
4553
|
-
path.search = qs ? "?" + qs : "";
|
|
4554
|
-
}
|
|
4555
|
-
}
|
|
4556
|
-
if ((!action || action === ".") && match.route.index) {
|
|
4557
|
-
path.search = path.search ? path.search.replace(/^\?/, "?index&") : "?index";
|
|
4558
|
-
}
|
|
4559
|
-
// If we're operating within a basename, prepend it to the pathname prior
|
|
4560
|
-
// to creating the form action. If this is a root navigation, then just use
|
|
4561
|
-
// the raw basename which allows the basename to have full control over the
|
|
4562
|
-
// presence of a trailing slash on root actions
|
|
4563
|
-
if (basename !== "/") {
|
|
4564
|
-
path.pathname = path.pathname === "/" ? basename : joinPaths([basename, path.pathname]);
|
|
4565
|
-
}
|
|
4566
|
-
return createPath(path);
|
|
4567
|
-
}
|
|
4568
|
-
/**
|
|
4569
|
-
* Return a boolean indicating if there is an active view transition to the
|
|
4570
|
-
* given href. You can use this value to render CSS classes or viewTransitionName
|
|
4571
|
-
* styles onto your elements
|
|
4572
|
-
*
|
|
4573
|
-
* @param href The destination href
|
|
4574
|
-
* @param [opts.relative] Relative routing type ("route" | "path")
|
|
4575
|
-
*/
|
|
4576
|
-
function useViewTransitionState(to, opts) {
|
|
4577
|
-
if (opts === void 0) {
|
|
4578
|
-
opts = {};
|
|
4579
|
-
}
|
|
4580
|
-
let vtContext = React.useContext(ViewTransitionContext);
|
|
4581
|
-
!(vtContext != null) ? process.env.NODE_ENV !== "production" ? invariant(false, "`useViewTransitionState` must be used within `react-router-dom`'s `RouterProvider`. " + "Did you accidentally import `RouterProvider` from `react-router`?") : invariant(false) : void 0;
|
|
4582
|
-
let {
|
|
4583
|
-
basename
|
|
4584
|
-
} = useDataRouterContext(DataRouterHook.useViewTransitionState);
|
|
4585
|
-
let path = useResolvedPath(to, {
|
|
4586
|
-
relative: opts.relative
|
|
4587
|
-
});
|
|
4588
|
-
if (!vtContext.isTransitioning) {
|
|
4589
|
-
return false;
|
|
4590
|
-
}
|
|
4591
|
-
let currentPath = stripBasename(vtContext.currentLocation.pathname, basename) || vtContext.currentLocation.pathname;
|
|
4592
|
-
let nextPath = stripBasename(vtContext.nextLocation.pathname, basename) || vtContext.nextLocation.pathname;
|
|
4593
|
-
// Transition is active if we're going to or coming from the indicated
|
|
4594
|
-
// destination. This ensures that other PUSH navigations that reverse
|
|
4595
|
-
// an indicated transition apply. I.e., on the list view you have:
|
|
4596
|
-
//
|
|
4597
|
-
// <NavLink to="/details/1" viewTransition>
|
|
4598
|
-
//
|
|
4599
|
-
// If you click the breadcrumb back to the list view:
|
|
4600
|
-
//
|
|
4601
|
-
// <NavLink to="/list" viewTransition>
|
|
4602
|
-
//
|
|
4603
|
-
// We should apply the transition because it's indicated as active going
|
|
4604
|
-
// from /list -> /details/1 and therefore should be active on the reverse
|
|
4605
|
-
// (even though this isn't strictly a POP reverse)
|
|
4606
|
-
return matchPath(path.pathname, nextPath) != null || matchPath(path.pathname, currentPath) != null;
|
|
4607
|
-
}
|
|
4608
|
-
|
|
4609
3243
|
const usePathAnalysisFunnel = ({ pathAnalytics, pathAnalysisCacheKey, dataFirstLevels, }) => {
|
|
4610
3244
|
const [searchParams] = useSearchParams();
|
|
4611
3245
|
const setFirstLevelLocationPath = usePathAnalysisStore((state) => state.setFirstLevelLocationPath);
|
|
@@ -4916,7 +3550,7 @@ const usePathAnalysisChart = () => {
|
|
|
4916
3550
|
return [
|
|
4917
3551
|
{
|
|
4918
3552
|
value: Number(totalAddedToCart ?? 0),
|
|
4919
|
-
key: METRICS_COLUMNS[IPAMetricKey.PAGE_ADDED_TO_CART]
|
|
3553
|
+
key: METRICS_COLUMNS[IPAMetricKey.PAGE_ADDED_TO_CART]?.label ?? t('Added to cart'),
|
|
4920
3554
|
labelTooltip: PA_METRIC_TOOLTIP[IPAMetricKey.PAGE_CART_ADDITION],
|
|
4921
3555
|
},
|
|
4922
3556
|
{
|