@levi-gemcommerce/analytics 1.0.0-dev.26 → 1.0.0-dev.28

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