@trackunit/react-components 0.1.119 → 0.1.126
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/051071830dacb5a2.svg +36 -0
- package/143a6e982b3d1ec9.svg +59 -0
- package/8df3d27593b5fba4.svg +70 -0
- package/building_error.cjs +181 -0
- package/building_error.js +159 -0
- package/index.cjs +533 -338
- package/index.js +531 -341
- package/package.json +4 -3
- package/road_block.cjs +244 -0
- package/road_block.js +222 -0
- package/src/components/EmptyState/EmptyState.d.ts +29 -0
- package/src/components/EmptyState/EmptyState.variants.d.ts +2 -0
- package/src/components/EmptyState/images/index.d.ts +4 -0
- package/src/components/Menu/MenuItem/MenuItem.d.ts +0 -8
- package/src/components/Menu/MenuItem/MenuItem.variants.d.ts +12 -0
- package/src/components/Menu/MenuList/MenuList.d.ts +2 -9
- package/src/components/Menu/MenuList/MenuList.variants.d.ts +4 -0
- package/src/components/Menu/MoreMenu/MoreMenu.variants.d.ts +1 -0
- package/src/components/Modal/Modal.variants.d.ts +5 -0
- package/src/components/Text/Text.variants.d.ts +9 -0
- package/src/components/index.d.ts +1 -0
- package/src/hooks/index.d.ts +2 -2
- package/src/hooks/localStorage/initLocalStorageState.d.ts +9 -0
- package/src/hooks/localStorage/types.d.ts +27 -0
- package/src/hooks/localStorage/useLocalStorage.d.ts +10 -0
- package/src/hooks/localStorage/useLocalStorageEffect.d.ts +11 -0
- package/src/hooks/localStorage/useLocalStorageReducer.d.ts +13 -0
- package/src/hooks/localStorage/validateState.d.ts +13 -0
- package/src/index.d.ts +1 -0
- package/wall_construction.cjs +308 -0
- package/wall_construction.js +286 -0
- package/src/hooks/useLocalStorage.d.ts +0 -9
- package/src/hooks/useLocalStorageReducer.d.ts +0 -7
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import React__default, { useRef, useCallback, useEffect, useState, useLayoutEffect, useMemo, createContext, forwardRef, useContext, isValidElement, cloneElement, Children, useReducer,
|
|
4
|
-
import { tw, tws
|
|
3
|
+
import React__default, { useRef, useCallback, useEffect, useState, useLayoutEffect, useMemo, createContext, forwardRef, useContext, isValidElement, cloneElement, memo, Children, useReducer, Component } from 'react';
|
|
4
|
+
import { tw, tws } from '@trackunit/tailwind-styled-components';
|
|
5
5
|
import { cvaMerge } from '@trackunit/css-class-variance-utilities';
|
|
6
6
|
import { HeroIconsArray, heroIconLookup, TrackunitSolidIconsArray, TrackunitOutlineIconsArray, trackunitIconLookup } from '@trackunit/ui-icons';
|
|
7
7
|
import * as ReactDOM from 'react-dom';
|
|
@@ -59,6 +59,16 @@ function __rest$1(s, e) {
|
|
|
59
59
|
t[p[i]] = s[p[i]];
|
|
60
60
|
}
|
|
61
61
|
return t;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
65
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
66
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
67
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
68
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
69
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
70
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
71
|
+
});
|
|
62
72
|
}
|
|
63
73
|
|
|
64
74
|
const cvaSpinner = cvaMerge([
|
|
@@ -417,6 +427,53 @@ const StarButton = ({ starred, onClick }) => {
|
|
|
417
427
|
return (jsx("div", { onClick: onClick, "data-test-id": "starred-filter", children: jsx(Icon, { name: "StarIcon", color: starred ? "primary" : "neutral", type: starred ? "solid" : "outline", size: "medium" }) }));
|
|
418
428
|
};
|
|
419
429
|
|
|
430
|
+
const cvaText = cvaMerge(["m-0", "relative", "text-sm", "font-normal"], {
|
|
431
|
+
variants: {
|
|
432
|
+
align: {
|
|
433
|
+
left: "text-left",
|
|
434
|
+
right: "text-right",
|
|
435
|
+
center: "text-center",
|
|
436
|
+
},
|
|
437
|
+
italic: {
|
|
438
|
+
true: "italic",
|
|
439
|
+
false: "",
|
|
440
|
+
},
|
|
441
|
+
uppercase: {
|
|
442
|
+
true: "uppercase",
|
|
443
|
+
false: "",
|
|
444
|
+
},
|
|
445
|
+
underline: {
|
|
446
|
+
true: [
|
|
447
|
+
"underline",
|
|
448
|
+
"after:bg-inherit",
|
|
449
|
+
"after:content-none",
|
|
450
|
+
"after:absolute",
|
|
451
|
+
"after:w-full",
|
|
452
|
+
"after:h-0.5",
|
|
453
|
+
"after:bottom-0",
|
|
454
|
+
"after:left-0",
|
|
455
|
+
],
|
|
456
|
+
false: "",
|
|
457
|
+
},
|
|
458
|
+
weight: {
|
|
459
|
+
normal: "font-normal",
|
|
460
|
+
bold: "font-medium",
|
|
461
|
+
thick: "font-semibold",
|
|
462
|
+
},
|
|
463
|
+
size: {
|
|
464
|
+
small: "text-xs",
|
|
465
|
+
medium: "text-sm",
|
|
466
|
+
large: "text-base",
|
|
467
|
+
},
|
|
468
|
+
color: {
|
|
469
|
+
default: "text-black",
|
|
470
|
+
subtleInverted: "text-neutral-300",
|
|
471
|
+
subtle: "text-neutral-600",
|
|
472
|
+
inverted: "text-white",
|
|
473
|
+
},
|
|
474
|
+
},
|
|
475
|
+
});
|
|
476
|
+
|
|
420
477
|
/**
|
|
421
478
|
* The Text component is used to apply Trackunit default typography styles to text.
|
|
422
479
|
*
|
|
@@ -428,49 +485,10 @@ const StarButton = ({ starred, onClick }) => {
|
|
|
428
485
|
* @returns {JSX.Element} Text component
|
|
429
486
|
*/
|
|
430
487
|
const Text = ({ children, type = "p", size = "medium", align = "left", weight = "normal", underline = false, inverted = false, subtle = false, italicize = false, uppercase = false, className, dataTestId, }) => {
|
|
431
|
-
|
|
432
|
-
};
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
small: tws `tu-text--small`,
|
|
436
|
-
large: tws `tu-text--large`,
|
|
437
|
-
medium: null,
|
|
438
|
-
default: null,
|
|
439
|
-
};
|
|
440
|
-
return sizes[$size];
|
|
441
|
-
};
|
|
442
|
-
const getTextWeight = () => ({ $weight }) => {
|
|
443
|
-
const weights = {
|
|
444
|
-
thick: tws `tu-text--medium`,
|
|
445
|
-
bold: tws `tu-text--semibold`,
|
|
446
|
-
normal: null,
|
|
447
|
-
default: null,
|
|
448
|
-
};
|
|
449
|
-
return weights[$weight];
|
|
450
|
-
};
|
|
451
|
-
const getFontColor = () => ({ $inverted, $subtle }) => {
|
|
452
|
-
const subtle = $inverted ? tws `tu-text--subtle-inverted` : tws `tu-text--subtle`;
|
|
453
|
-
const inverted = $inverted ? tws `tu-text--inverted` : null;
|
|
454
|
-
return $subtle ? subtle : inverted;
|
|
455
|
-
};
|
|
456
|
-
const getTextAlignment = () => ({ $align }) => {
|
|
457
|
-
const alignments = {
|
|
458
|
-
left: tws `tu-text--align-left`,
|
|
459
|
-
center: tws `tu-text--align-center`,
|
|
460
|
-
right: tws `tu-text--align-right`,
|
|
461
|
-
};
|
|
462
|
-
return alignments[$align];
|
|
463
|
-
};
|
|
464
|
-
const StyledText = tw.text `
|
|
465
|
-
tu-text
|
|
466
|
-
${getFontColor()}
|
|
467
|
-
${p => (p.$italicize ? tws `tu-text--italic` : "")}
|
|
468
|
-
${p => (p.$uppercase ? tws `tu-text--uppercase` : "")}
|
|
469
|
-
${getTextAlignment()}
|
|
470
|
-
${p => (p.$underline ? tws `tu-text--underline` : "")}
|
|
471
|
-
${getTextSize()}
|
|
472
|
-
${getTextWeight()}
|
|
473
|
-
`;
|
|
488
|
+
const color = inverted && subtle ? "subtleInverted" : inverted ? "inverted" : subtle ? "subtle" : "default";
|
|
489
|
+
return (jsx(StyledText, { "$as": type, className: cvaText({ color, uppercase, align, italic: italicize, size, underline, weight, className }), "data-testid": dataTestId, children: children }));
|
|
490
|
+
};
|
|
491
|
+
const StyledText = tw.text ``;
|
|
474
492
|
|
|
475
493
|
const cvaAlert = cvaMerge(["flex", "relative", "p-4", "rounded"], {
|
|
476
494
|
variants: {
|
|
@@ -1065,6 +1083,14 @@ var useCopyToClipboard$1 = useCopyToClipboard;
|
|
|
1065
1083
|
var useIsomorphicLayoutEffect$1 = isBrowser ? useLayoutEffect : useEffect;
|
|
1066
1084
|
var useIsomorphicLayoutEffect$2 = useIsomorphicLayoutEffect$1;
|
|
1067
1085
|
|
|
1086
|
+
function usePrevious(state) {
|
|
1087
|
+
var ref = useRef();
|
|
1088
|
+
useEffect(function () {
|
|
1089
|
+
ref.current = state;
|
|
1090
|
+
});
|
|
1091
|
+
return ref.current;
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1068
1094
|
var defaultState = {
|
|
1069
1095
|
x: 0,
|
|
1070
1096
|
y: 0,
|
|
@@ -14545,7 +14571,7 @@ function Month(props) {
|
|
|
14545
14571
|
}
|
|
14546
14572
|
|
|
14547
14573
|
/** Render the container with the months according to the number of months to display. */
|
|
14548
|
-
function Root
|
|
14574
|
+
function Root(_a) {
|
|
14549
14575
|
var initialProps = _a.initialProps;
|
|
14550
14576
|
var dayPicker = useDayPicker();
|
|
14551
14577
|
var focusContext = useFocusContext();
|
|
@@ -14688,7 +14714,7 @@ function RootProvider(props) {
|
|
|
14688
14714
|
*/
|
|
14689
14715
|
function DayPicker$1(props) {
|
|
14690
14716
|
return (React__default.createElement(RootProvider, __assign({}, props),
|
|
14691
|
-
React__default.createElement(Root
|
|
14717
|
+
React__default.createElement(Root, { initialProps: props })));
|
|
14692
14718
|
}
|
|
14693
14719
|
|
|
14694
14720
|
const localeLookup = {
|
|
@@ -18777,6 +18803,93 @@ const Drawer = ({ open, onClose = () => { }, children, disableOverlay = false, p
|
|
|
18777
18803
|
jsx(Fragment, {})) }));
|
|
18778
18804
|
};
|
|
18779
18805
|
|
|
18806
|
+
const cvaSkeletonLine = cvaMerge([
|
|
18807
|
+
"rounded-md",
|
|
18808
|
+
"h-3",
|
|
18809
|
+
"opacity-20",
|
|
18810
|
+
"animate-pulse",
|
|
18811
|
+
"bg-black/50",
|
|
18812
|
+
"bg-auto",
|
|
18813
|
+
"bg-gradient-to-r",
|
|
18814
|
+
"from-black/0",
|
|
18815
|
+
"via-black/50",
|
|
18816
|
+
"to-black/20",
|
|
18817
|
+
]);
|
|
18818
|
+
|
|
18819
|
+
/**
|
|
18820
|
+
* Display placeholder lines before the data gets loaded to reduce load-time frustration.
|
|
18821
|
+
*/
|
|
18822
|
+
const SkeletonLines = memo(({ margin = "10px 0", lines = 1, height, width = "100%", className, dataTestId }) => {
|
|
18823
|
+
const skeletonLines = [];
|
|
18824
|
+
const getWidth = (index) => {
|
|
18825
|
+
if (width instanceof Array) {
|
|
18826
|
+
return width[index] || "100%";
|
|
18827
|
+
}
|
|
18828
|
+
return width;
|
|
18829
|
+
};
|
|
18830
|
+
const getHeight = (index) => {
|
|
18831
|
+
if (height instanceof Array) {
|
|
18832
|
+
return height[index] || "auto";
|
|
18833
|
+
}
|
|
18834
|
+
return height;
|
|
18835
|
+
};
|
|
18836
|
+
for (let i = 0; i < lines; i++) {
|
|
18837
|
+
skeletonLines.push(jsx("div", { "data-testid": dataTestId !== null && dataTestId !== void 0 ? dataTestId : "skeleton-lines", "data-type": "loading-skeleton-line", className: cvaSkeletonLine({ className }), style: { height: getHeight(i), width: getWidth(i), margin: lines > 1 ? margin : "" }, children: lines > 1 && jsx(Fragment, { children: "\u00A0" }) }, i));
|
|
18838
|
+
}
|
|
18839
|
+
// eslint-disable-next-line react/jsx-no-useless-fragment
|
|
18840
|
+
return jsx(Fragment, { children: skeletonLines });
|
|
18841
|
+
});
|
|
18842
|
+
|
|
18843
|
+
const containerStyles = cvaMerge(["flex flex-col items-center gap-5 p-12 text-center justify-center h-full"]);
|
|
18844
|
+
const textStyles = cvaMerge(["flex flex-col items-center gap-2"]);
|
|
18845
|
+
|
|
18846
|
+
var WorkerWithSign = "8df3d27593b5fba4.svg";
|
|
18847
|
+
|
|
18848
|
+
/**
|
|
18849
|
+
* Component representing an empty state.
|
|
18850
|
+
* Use this component when there is no data to display or when an error occurs.
|
|
18851
|
+
*
|
|
18852
|
+
*
|
|
18853
|
+
* @param {EmptyStateProps} props props
|
|
18854
|
+
* @returns {JSX.Element} component
|
|
18855
|
+
* @example
|
|
18856
|
+
* <EmptyState
|
|
18857
|
+
* title="No results found"
|
|
18858
|
+
* description="Try changing your search criteria"
|
|
18859
|
+
* altText="No results found"
|
|
18860
|
+
* image="BUILDING_ERROR"
|
|
18861
|
+
* />
|
|
18862
|
+
*/
|
|
18863
|
+
const EmptyState = ({ title, description, altText, image, customImageSrc, action, loading, dataTestId, className, }) => {
|
|
18864
|
+
const [imageSource, setImageSource] = useState(WorkerWithSign);
|
|
18865
|
+
useEffect(() => {
|
|
18866
|
+
const lazyLoadImage = () => __awaiter(void 0, void 0, void 0, function* () {
|
|
18867
|
+
let importedImage = null;
|
|
18868
|
+
switch (image) {
|
|
18869
|
+
case "WORKER_WITH_SIGN":
|
|
18870
|
+
importedImage = WorkerWithSign;
|
|
18871
|
+
break;
|
|
18872
|
+
case "ROAD_BLOCK":
|
|
18873
|
+
importedImage = (yield import('./road_block.js')).default;
|
|
18874
|
+
break;
|
|
18875
|
+
case "BUILDING_ERROR":
|
|
18876
|
+
importedImage = (yield import('./building_error.js')).default;
|
|
18877
|
+
break;
|
|
18878
|
+
case "WALL_CONSTRUCTION":
|
|
18879
|
+
importedImage = (yield import('./wall_construction.js')).default;
|
|
18880
|
+
break;
|
|
18881
|
+
default:
|
|
18882
|
+
importedImage = WorkerWithSign;
|
|
18883
|
+
}
|
|
18884
|
+
setImageSource(importedImage);
|
|
18885
|
+
});
|
|
18886
|
+
if (!customImageSrc && image) {
|
|
18887
|
+
lazyLoadImage();
|
|
18888
|
+
}
|
|
18889
|
+
}, [customImageSrc, image]);
|
|
18890
|
+
return (jsx("div", { className: `${containerStyles()} ${className}`, "data-testid": dataTestId !== null && dataTestId !== void 0 ? dataTestId : "empty-state", children: loading ? (jsxs(Fragment, { children: [jsx(Spinner, { dataTestId: "spinner", size: "large", centering: "centered" }), jsx(SkeletonLines, { dataTestId: "skeleton-lines", width: 50 })] })) : (jsxs(Fragment, { children: [jsx("img", { src: customImageSrc ? customImageSrc : imageSource, alt: altText }), jsxs("div", { className: textStyles(), children: [jsx(Heading, { variant: "secondary", children: title }), jsx(Text, { align: "center", children: description })] }), action] })) }));
|
|
18891
|
+
};
|
|
18892
|
+
|
|
18780
18893
|
/**
|
|
18781
18894
|
* The external link component is used to link to an external page outside the Trackunit Manager.
|
|
18782
18895
|
*
|
|
@@ -18888,6 +19001,68 @@ const Indicator = (_a) => {
|
|
|
18888
19001
|
return (jsxs("div", Object.assign({ className: cvaIndicator({ className }), "data-testid": dataTestId }, rest, { title: !withLabel ? label : undefined, children: [jsxs("div", { className: cvaIndicatorIconBackground({ color, background: withBackground ? "visible" : "hidden" }), "data-testid": dataTestId ? `${dataTestId}-background` : "indicator-background", children: [ping && (jsx("div", { className: cvaIndicatorPing({ color }), "data-testid": dataTestId ? `${dataTestId}-ping` : "indicator-ping" })), icon] }), label !== undefined && withLabel && (jsx("div", { className: cvaIndicatorLabel(), "data-testid": dataTestId ? `${dataTestId}-label` : "indicator-label", children: label }))] })));
|
|
18889
19002
|
};
|
|
18890
19003
|
|
|
19004
|
+
const cvaMenuItem = cvaMerge([
|
|
19005
|
+
"py-2",
|
|
19006
|
+
"pl-2",
|
|
19007
|
+
"pr-3",
|
|
19008
|
+
"w-full",
|
|
19009
|
+
"h-auto",
|
|
19010
|
+
"cursor-pointer",
|
|
19011
|
+
"flex",
|
|
19012
|
+
"flex-row",
|
|
19013
|
+
"items-center",
|
|
19014
|
+
"gap-x-2",
|
|
19015
|
+
"select-none",
|
|
19016
|
+
"rounded",
|
|
19017
|
+
"hover:bg-slate-100",
|
|
19018
|
+
], {
|
|
19019
|
+
variants: {
|
|
19020
|
+
selected: {
|
|
19021
|
+
true: "bg-primary-100 hover:bg-primary-200",
|
|
19022
|
+
false: "",
|
|
19023
|
+
},
|
|
19024
|
+
disabled: {
|
|
19025
|
+
true: "!bg-slate-100 pointer-events-none",
|
|
19026
|
+
false: "",
|
|
19027
|
+
},
|
|
19028
|
+
focused: {
|
|
19029
|
+
true: "bg-slate-100",
|
|
19030
|
+
false: "",
|
|
19031
|
+
},
|
|
19032
|
+
},
|
|
19033
|
+
compoundVariants: [
|
|
19034
|
+
{
|
|
19035
|
+
focused: true,
|
|
19036
|
+
selected: true,
|
|
19037
|
+
className: "bg-primary-200",
|
|
19038
|
+
},
|
|
19039
|
+
],
|
|
19040
|
+
});
|
|
19041
|
+
const cvaMenuItemLabel = cvaMerge([
|
|
19042
|
+
"flex-grow",
|
|
19043
|
+
"text-gray-700",
|
|
19044
|
+
"text-ellipsis",
|
|
19045
|
+
"truncate",
|
|
19046
|
+
"group-hover:text-gray-900",
|
|
19047
|
+
"group-active:text-gray-700",
|
|
19048
|
+
]);
|
|
19049
|
+
const cvaMenuItemSuffix = cvaMerge(["self-center", "flex-grow-0", "text-slate-400"], {
|
|
19050
|
+
variants: {
|
|
19051
|
+
selected: {
|
|
19052
|
+
true: "text-primary-600 hover:text-primary-700",
|
|
19053
|
+
false: "",
|
|
19054
|
+
},
|
|
19055
|
+
},
|
|
19056
|
+
});
|
|
19057
|
+
const cvaMenuItemPrefix = cvaMerge(["self-center", "flex-grow-0", "text-slate-400", "group-hover:text-slate-600"], {
|
|
19058
|
+
variants: {
|
|
19059
|
+
selected: {
|
|
19060
|
+
true: "text-primary-600 hover:text-primary-700",
|
|
19061
|
+
false: "",
|
|
19062
|
+
},
|
|
19063
|
+
},
|
|
19064
|
+
});
|
|
19065
|
+
|
|
18891
19066
|
/**
|
|
18892
19067
|
* The MenuItem component is used to display a menu, primarily meant to be used in a list form.
|
|
18893
19068
|
*
|
|
@@ -18895,30 +19070,32 @@ const Indicator = (_a) => {
|
|
|
18895
19070
|
* @returns {JSX.Element} MenuItem component
|
|
18896
19071
|
*/
|
|
18897
19072
|
const MenuItem = ({ className, dataTestId, label, children, selected, focused, prefix, suffix, disabled, onClick, }) => {
|
|
18898
|
-
const containerProps = useContainerProps({ className, dataTestId });
|
|
18899
|
-
return (jsxs(
|
|
19073
|
+
const containerProps = useContainerProps({ className, dataTestId: dataTestId || "menu-item" });
|
|
19074
|
+
return (jsxs("div", Object.assign({}, containerProps, { className: cvaMenuItem({
|
|
19075
|
+
selected,
|
|
19076
|
+
focused,
|
|
19077
|
+
disabled,
|
|
19078
|
+
className: containerProps.className,
|
|
19079
|
+
}), onClick: e => {
|
|
18900
19080
|
e.stopPropagation();
|
|
18901
19081
|
onClick && onClick(e);
|
|
18902
|
-
},
|
|
19082
|
+
}, tabIndex: 0, children: [prefix && (jsx("div", { className: cvaMenuItemPrefix({ selected }), "data-testid": dataTestId && `${dataTestId}-prefix`, children: prefix })), children && typeof children !== "string" ? (children) : (jsx("div", { className: cvaMenuItemLabel(), "data-testid": dataTestId && `${dataTestId}-label`, children: children !== null && children !== void 0 ? children : label })), suffix && (jsx("div", { className: cvaMenuItemSuffix({ selected }), "data-testid": dataTestId && `${dataTestId}-suffix`, children: suffix }))] })));
|
|
18903
19083
|
};
|
|
18904
|
-
const Container$1 = tw.div `
|
|
18905
|
-
group tu-menu-item
|
|
18906
|
-
${({ $selected }) => ($selected ? tws `tu-menu-item--selected ` : "tu-menu-item--unselected")}
|
|
18907
|
-
${({ $focused }) => ($focused ? tws `tu-menu-item--focused ` : "")}
|
|
18908
|
-
${({ $disabled }) => ($disabled ? tws `tu-menu-item--disabled ` : "")}
|
|
18909
19084
|
|
|
18910
|
-
|
|
18911
|
-
|
|
18912
|
-
|
|
18913
|
-
|
|
18914
|
-
|
|
18915
|
-
|
|
18916
|
-
|
|
18917
|
-
|
|
18918
|
-
|
|
18919
|
-
|
|
18920
|
-
|
|
18921
|
-
|
|
19085
|
+
const cvaMenuList = cvaMerge(["shadow-md", "rounded-lg", "z-20", "bg-white", "p-1", "border", "border-slate-300", "gap-1", "grid"], {
|
|
19086
|
+
variants: {
|
|
19087
|
+
stickyHeader: {
|
|
19088
|
+
true: "grid grid-rows-min-fr !p-0",
|
|
19089
|
+
false: "",
|
|
19090
|
+
},
|
|
19091
|
+
},
|
|
19092
|
+
});
|
|
19093
|
+
const cvaMenuListDivider = cvaMerge([
|
|
19094
|
+
"file:w-full",
|
|
19095
|
+
"selection:col-span-full",
|
|
19096
|
+
"selection:h-px",
|
|
19097
|
+
"selection:bg-slate-200",
|
|
19098
|
+
]);
|
|
18922
19099
|
|
|
18923
19100
|
/**
|
|
18924
19101
|
* The MenuList component is used for menus and selects.
|
|
@@ -18930,211 +19107,62 @@ const MenuList = (_a) => {
|
|
|
18930
19107
|
var { dataTestId, className, children, withStickyHeader = false, showDivider = false } = _a; __rest$1(_a, ["dataTestId", "className", "children", "withStickyHeader", "showDivider"]);
|
|
18931
19108
|
const childrenArr = Children.toArray(children);
|
|
18932
19109
|
const isLastItem = (index) => index === childrenArr.length - 1;
|
|
18933
|
-
return (jsx(
|
|
18934
|
-
};
|
|
18935
|
-
const Container = tw.div `
|
|
18936
|
-
tu-menu-list
|
|
18937
|
-
${props => props.$withStickyHeader && tws `tu-menu-list--sticky-header`}
|
|
18938
|
-
`;
|
|
18939
|
-
const Divider = tw.hr `
|
|
18940
|
-
tu-menu-list__divider
|
|
18941
|
-
`;
|
|
18942
|
-
|
|
18943
|
-
/**
|
|
18944
|
-
* Custom hook to handle click outside events.
|
|
18945
|
-
*
|
|
18946
|
-
* @param {RefObject<HTMLElement> | Array<RefObject<HTMLElement>>} el - The reference(s) to the element(s) to watch for click outside events.
|
|
18947
|
-
* @param {Object | Function} [options={}] - Configuration options or the click event handler if options are not provided.
|
|
18948
|
-
* @param {boolean} [options.active=true] - Whether the click outside event listener should be active.
|
|
18949
|
-
* @param {Function} [onClick] - The event handler for the click outside event.
|
|
18950
|
-
*/
|
|
18951
|
-
const useClickOutside = (el, options = {}, onClick) => {
|
|
18952
|
-
const els = Array.isArray(el) ? el : [el];
|
|
18953
|
-
let active = true;
|
|
18954
|
-
if (!onClick && typeof options === "function") {
|
|
18955
|
-
onClick = options;
|
|
18956
|
-
}
|
|
18957
|
-
else if (typeof options === "object") {
|
|
18958
|
-
active = options.active !== undefined ? options.active : active;
|
|
18959
|
-
}
|
|
18960
|
-
const handler = (ev) => {
|
|
18961
|
-
const target = ev.target;
|
|
18962
|
-
if (els.every(ref => !ref.current || !ref.current.contains(target))) {
|
|
18963
|
-
onClick && onClick(ev);
|
|
18964
|
-
}
|
|
18965
|
-
};
|
|
18966
|
-
const cleanup = () => window.removeEventListener("click", handler);
|
|
18967
|
-
useEffect(() => {
|
|
18968
|
-
if (active) {
|
|
18969
|
-
window.addEventListener("click", handler);
|
|
18970
|
-
}
|
|
18971
|
-
else {
|
|
18972
|
-
cleanup();
|
|
18973
|
-
}
|
|
18974
|
-
return cleanup;
|
|
18975
|
-
});
|
|
19110
|
+
return (jsx("div", { "data-testid": dataTestId, className: cvaMenuList({ stickyHeader: withStickyHeader, className }), tabIndex: 0, role: "list", children: Children.map(childrenArr, (menuItem, index) => (jsxs(Fragment, { children: [menuItem, showDivider && !isLastItem(index) && jsx("hr", { className: cvaMenuListDivider() })] }))) }));
|
|
18976
19111
|
};
|
|
18977
19112
|
|
|
18978
19113
|
/**
|
|
18979
|
-
*
|
|
19114
|
+
* Validates the state object using a Zod schema.
|
|
18980
19115
|
*
|
|
18981
|
-
* @
|
|
18982
|
-
* @param {
|
|
18983
|
-
* @
|
|
18984
|
-
* @returns {any} The latest value received
|
|
19116
|
+
* @template State - The type of the state.
|
|
19117
|
+
* @param {ValidateStateOptions<State>} params - The parameters for the validateState function.
|
|
19118
|
+
* @returns {boolean} - `true` if the state is valid according to the schema, `false` otherwise.
|
|
18985
19119
|
*/
|
|
18986
|
-
|
|
18987
|
-
|
|
18988
|
-
|
|
18989
|
-
|
|
18990
|
-
|
|
18991
|
-
useEffect(() => {
|
|
18992
|
-
let handler;
|
|
18993
|
-
if ((direction === "in" && !debouncedValue && value) ||
|
|
18994
|
-
(direction === "out" && debouncedValue && !value) ||
|
|
18995
|
-
direction === "both" ||
|
|
18996
|
-
!direction) {
|
|
18997
|
-
handler = setTimeout(() => {
|
|
18998
|
-
setDebouncedValue(value);
|
|
18999
|
-
}, delay);
|
|
19120
|
+
const validateState = ({ state, schema, onValidationFailed, onValidationSuccessful, }) => {
|
|
19121
|
+
try {
|
|
19122
|
+
schema.parse(state);
|
|
19123
|
+
if (onValidationSuccessful) {
|
|
19124
|
+
onValidationSuccessful();
|
|
19000
19125
|
}
|
|
19001
|
-
|
|
19002
|
-
|
|
19126
|
+
return true;
|
|
19127
|
+
}
|
|
19128
|
+
catch (error) {
|
|
19129
|
+
// eslint-disable-next-line no-console
|
|
19130
|
+
console.error("State validation failed.", error);
|
|
19131
|
+
if (onValidationFailed) {
|
|
19132
|
+
onValidationFailed(error);
|
|
19003
19133
|
}
|
|
19004
|
-
return
|
|
19005
|
-
|
|
19006
|
-
};
|
|
19007
|
-
}, [value, delay, direction, debouncedValue]);
|
|
19008
|
-
return debouncedValue;
|
|
19134
|
+
return false;
|
|
19135
|
+
}
|
|
19009
19136
|
};
|
|
19010
19137
|
|
|
19011
|
-
// Copied from https://github.com/rexxars/use-device-pixel-ratio
|
|
19012
19138
|
/**
|
|
19013
|
-
*
|
|
19014
|
-
* Will emit new values if it changes.
|
|
19139
|
+
* Initializes the state from local storage, parsing and validating it if a Zod schema is provided.
|
|
19015
19140
|
*
|
|
19016
|
-
* @
|
|
19017
|
-
* @
|
|
19141
|
+
* @template State - The type of the state stored in local storage.
|
|
19142
|
+
* @param {Omit<LocalStorageParams<State>, "state">} params - The parameters for initializing the local storage state.
|
|
19143
|
+
* @returns {State} - The initialized state.
|
|
19018
19144
|
*/
|
|
19019
|
-
|
|
19020
|
-
const
|
|
19021
|
-
|
|
19022
|
-
|
|
19023
|
-
|
|
19024
|
-
|
|
19025
|
-
|
|
19026
|
-
|
|
19027
|
-
|
|
19028
|
-
const updateDpr = () => setCurrentDpr(getDevicePixelRatio({ defaultDpr, maxDpr, round }));
|
|
19029
|
-
const mediaMatcher = window.matchMedia(`screen and (resolution: ${currentDpr}dppx)`);
|
|
19030
|
-
// Safari 13.1 does not have `addEventListener`, but does have `addListener`
|
|
19031
|
-
if (mediaMatcher.addEventListener) {
|
|
19032
|
-
mediaMatcher.addEventListener("change", updateDpr);
|
|
19033
|
-
}
|
|
19034
|
-
else {
|
|
19035
|
-
mediaMatcher.addListener(updateDpr);
|
|
19036
|
-
}
|
|
19037
|
-
return () => {
|
|
19038
|
-
if (mediaMatcher.removeEventListener) {
|
|
19039
|
-
mediaMatcher.removeEventListener("change", updateDpr);
|
|
19145
|
+
const initLocalStorageState = ({ key, defaultState, schema, }) => {
|
|
19146
|
+
const localStorageItem = localStorage.getItem(key);
|
|
19147
|
+
if (localStorageItem) {
|
|
19148
|
+
try {
|
|
19149
|
+
const parsedState = JSON.parse(localStorageItem);
|
|
19150
|
+
if (schema) {
|
|
19151
|
+
if (validateState({ state: parsedState, schema })) {
|
|
19152
|
+
return parsedState;
|
|
19153
|
+
}
|
|
19040
19154
|
}
|
|
19041
19155
|
else {
|
|
19042
|
-
|
|
19156
|
+
return parsedState;
|
|
19043
19157
|
}
|
|
19044
|
-
};
|
|
19045
|
-
}, [currentDpr, defaultDpr, maxDpr, round]);
|
|
19046
|
-
return currentDpr;
|
|
19047
|
-
}
|
|
19048
|
-
/**
|
|
19049
|
-
* Returns the current device pixel ratio (DPR) given the passed options
|
|
19050
|
-
*
|
|
19051
|
-
* @param { DevicePixelRatioOptions } options the options object
|
|
19052
|
-
* @returns { number } current device pixel ratio
|
|
19053
|
-
*/
|
|
19054
|
-
function getDevicePixelRatio(options) {
|
|
19055
|
-
const { defaultDpr = 1, maxDpr = 3, round = true } = options || {};
|
|
19056
|
-
const hasDprProp = typeof window !== "undefined" && typeof window.devicePixelRatio === "number";
|
|
19057
|
-
const dpr = hasDprProp ? window.devicePixelRatio : defaultDpr;
|
|
19058
|
-
const rounded = Math.min(Math.max(1, round ? Math.floor(dpr) : dpr), maxDpr);
|
|
19059
|
-
return rounded;
|
|
19060
|
-
}
|
|
19061
|
-
|
|
19062
|
-
/**
|
|
19063
|
-
* The useHover hook returns a onMouseEnter, onMouseLeave and a boolean indicating whether the element is being hovered.
|
|
19064
|
-
* The boolean will be true if the element is being hovered, and false if it is not.
|
|
19065
|
-
* Can be directionally debounced.
|
|
19066
|
-
*
|
|
19067
|
-
* @param {ConditionalUseHoverProps} param0 The options
|
|
19068
|
-
* @returns {Object} The object containing the onMouseEnter, onMouseLeave and hovering props
|
|
19069
|
-
*/
|
|
19070
|
-
const useHover = ({ debounced = false, delay = 100, direction = "out" } = { debounced: false }) => {
|
|
19071
|
-
const [hovering, setHovering] = useState(false);
|
|
19072
|
-
const debouncedHovering = useDebounce(hovering, delay, direction);
|
|
19073
|
-
const onMouseEnter = () => {
|
|
19074
|
-
setHovering(true);
|
|
19075
|
-
};
|
|
19076
|
-
const onMouseLeave = () => {
|
|
19077
|
-
setHovering(false);
|
|
19078
|
-
};
|
|
19079
|
-
return { onMouseEnter, onMouseLeave, hovering: debounced ? debouncedHovering : hovering };
|
|
19080
|
-
};
|
|
19081
|
-
|
|
19082
|
-
/**
|
|
19083
|
-
* Differentiate between the first and subsequent renders.
|
|
19084
|
-
*
|
|
19085
|
-
* @returns {boolean} Returns true if it is the first render, false otherwise.
|
|
19086
|
-
*/
|
|
19087
|
-
const useIsFirstRender = () => {
|
|
19088
|
-
const renderRef = useRef(true);
|
|
19089
|
-
if (renderRef.current === true) {
|
|
19090
|
-
renderRef.current = false;
|
|
19091
|
-
return true;
|
|
19092
|
-
}
|
|
19093
|
-
return renderRef.current;
|
|
19094
|
-
};
|
|
19095
|
-
|
|
19096
|
-
/**
|
|
19097
|
-
* The useLocalStorage hook works like useState, but saves to localstorage.
|
|
19098
|
-
*
|
|
19099
|
-
* @param {string} key - The key the values is saved under.
|
|
19100
|
-
* @param {string | null | undefined} initialValue - The initial value for the state/local storage item
|
|
19101
|
-
* @returns {string | null | undefined} value
|
|
19102
|
-
*/
|
|
19103
|
-
const useLocalStorage = (key, initialValue) => {
|
|
19104
|
-
if (!key) {
|
|
19105
|
-
throw new Error("useLocalStorage key may not be falsy");
|
|
19106
|
-
}
|
|
19107
|
-
const setLocalStorageItem = useCallback((value) => window.localStorage.setItem(key, typeof value === "object" ? JSON.stringify(value) : `${value}`), [key]);
|
|
19108
|
-
const removeLocalStorageItem = useCallback(() => window.localStorage.removeItem(key), [key]);
|
|
19109
|
-
const [item, setValue] = useState(() => {
|
|
19110
|
-
const value = window.localStorage.getItem(key);
|
|
19111
|
-
if (value !== undefined && value !== null) {
|
|
19112
|
-
const parsedValue = tryParse(value);
|
|
19113
|
-
return parsedValue;
|
|
19114
|
-
}
|
|
19115
|
-
return initialValue !== null && initialValue !== void 0 ? initialValue : null;
|
|
19116
|
-
});
|
|
19117
|
-
useEffect(() => {
|
|
19118
|
-
if (item !== undefined && item !== null) {
|
|
19119
|
-
setLocalStorageItem(item);
|
|
19120
19158
|
}
|
|
19121
|
-
|
|
19122
|
-
|
|
19159
|
+
catch (error) {
|
|
19160
|
+
// eslint-disable-next-line no-console
|
|
19161
|
+
console.error("Failed to parse and validate the state from local storage.", error);
|
|
19123
19162
|
}
|
|
19124
|
-
}, [item, setLocalStorageItem, removeLocalStorageItem, key]);
|
|
19125
|
-
const removeItem = () => {
|
|
19126
|
-
setValue(null);
|
|
19127
|
-
};
|
|
19128
|
-
return [item, setValue, removeItem];
|
|
19129
|
-
};
|
|
19130
|
-
function tryParse(value) {
|
|
19131
|
-
try {
|
|
19132
|
-
return JSON.parse(value);
|
|
19133
19163
|
}
|
|
19134
|
-
|
|
19135
|
-
|
|
19136
|
-
}
|
|
19137
|
-
}
|
|
19164
|
+
return defaultState;
|
|
19165
|
+
};
|
|
19138
19166
|
|
|
19139
19167
|
var lodash = {exports: {}};
|
|
19140
19168
|
|
|
@@ -36338,47 +36366,229 @@ var lodash = {exports: {}};
|
|
|
36338
36366
|
}(lodash, lodash.exports));
|
|
36339
36367
|
|
|
36340
36368
|
/**
|
|
36341
|
-
*
|
|
36369
|
+
* Custom hook for synchronizing a state variable with local storage,
|
|
36370
|
+
* with optional schema validation and callbacks.
|
|
36371
|
+
*
|
|
36372
|
+
* @template State - The type of the state variable.
|
|
36373
|
+
* @param {LocalStorageParams<State> & LocalStorageCallbacks & { state: State }} params - The parameters for the useLocalStorageEffect hook.
|
|
36342
36374
|
*/
|
|
36343
|
-
|
|
36344
|
-
|
|
36345
|
-
const ref = useRef();
|
|
36375
|
+
const useLocalStorageEffect = ({ key, state, defaultState, schema, onValidationFailed, onValidationSuccessful, }) => {
|
|
36376
|
+
const prevState = usePrevious(state);
|
|
36346
36377
|
useEffect(() => {
|
|
36347
|
-
|
|
36378
|
+
if (lodash.exports.isEqual(prevState, state)) {
|
|
36379
|
+
return;
|
|
36380
|
+
}
|
|
36381
|
+
if (schema) {
|
|
36382
|
+
validateState({
|
|
36383
|
+
state,
|
|
36384
|
+
schema,
|
|
36385
|
+
onValidationFailed: error => {
|
|
36386
|
+
// eslint-disable-next-line no-console
|
|
36387
|
+
console.error(`State validation failed. Resetting local storage to default state: ${defaultState}.`, error);
|
|
36388
|
+
localStorage.removeItem(key);
|
|
36389
|
+
onValidationFailed === null || onValidationFailed === void 0 ? void 0 : onValidationFailed(error);
|
|
36390
|
+
},
|
|
36391
|
+
onValidationSuccessful: () => {
|
|
36392
|
+
const stringifiedState = JSON.stringify(state);
|
|
36393
|
+
localStorage.setItem(key, stringifiedState);
|
|
36394
|
+
onValidationSuccessful === null || onValidationSuccessful === void 0 ? void 0 : onValidationSuccessful();
|
|
36395
|
+
},
|
|
36396
|
+
});
|
|
36397
|
+
}
|
|
36398
|
+
else {
|
|
36399
|
+
const stringifiedState = JSON.stringify(state);
|
|
36400
|
+
localStorage.setItem(key, stringifiedState);
|
|
36401
|
+
}
|
|
36402
|
+
}, [state, key, schema, defaultState, prevState, onValidationFailed, onValidationSuccessful]);
|
|
36403
|
+
};
|
|
36404
|
+
|
|
36405
|
+
/**
|
|
36406
|
+
* Works like a normal useState, but saves to local storage and has optional schema validation.
|
|
36407
|
+
*
|
|
36408
|
+
* @template State - The type of the value stored in local storage.
|
|
36409
|
+
* @param {Omit<LocalStorageParams<State>, "state"> & LocalStorageCallbacks} options - The options for useLocalStorage.
|
|
36410
|
+
* @returns {[State, Dispatch<SetStateAction<State>>, () => void]} - A tuple containing the current value, a function to update the value, and a function to remove the value from local storage.
|
|
36411
|
+
*/
|
|
36412
|
+
const useLocalStorage = ({ key, defaultState, schema, onValidationFailed, onValidationSuccessful, }) => {
|
|
36413
|
+
if (!key) {
|
|
36414
|
+
throw new Error("useLocalStorage key may not be falsy");
|
|
36415
|
+
}
|
|
36416
|
+
const [state, setState] = useState(initLocalStorageState({ key, defaultState, schema }));
|
|
36417
|
+
useLocalStorageEffect({ key, state, defaultState, schema, onValidationFailed, onValidationSuccessful });
|
|
36418
|
+
const reset = () => {
|
|
36419
|
+
setState(defaultState);
|
|
36420
|
+
};
|
|
36421
|
+
return [state, setState, reset];
|
|
36422
|
+
};
|
|
36423
|
+
|
|
36424
|
+
/**
|
|
36425
|
+
* Works like a normal useReducer, but saves to local storage and has optional schema validation.
|
|
36426
|
+
*
|
|
36427
|
+
* @template State - The type of the state.
|
|
36428
|
+
* @template Action - The type of the action.
|
|
36429
|
+
* @param {LocalStorageParams<State> & LocalStorageCallbacks} params - The parameters for the useLocalStorageReducer function.
|
|
36430
|
+
* @returns {[State, Dispatch<Action>]} - A tuple containing the state and the dispatch function.
|
|
36431
|
+
*/
|
|
36432
|
+
const useLocalStorageReducer = ({ key, defaultState, reducer, schema, onValidationFailed, onValidationSuccessful, }) => {
|
|
36433
|
+
if (!key) {
|
|
36434
|
+
throw new Error("useLocalStorage key may not be falsy");
|
|
36435
|
+
}
|
|
36436
|
+
const [state, dispatch] = useReducer(reducer, defaultState, () => initLocalStorageState({ key, defaultState, schema }));
|
|
36437
|
+
useLocalStorageEffect({ key, state, defaultState, schema, onValidationFailed, onValidationSuccessful });
|
|
36438
|
+
return [state, dispatch];
|
|
36439
|
+
};
|
|
36440
|
+
|
|
36441
|
+
/**
|
|
36442
|
+
* Custom hook to handle click outside events.
|
|
36443
|
+
*
|
|
36444
|
+
* @param {RefObject<HTMLElement> | Array<RefObject<HTMLElement>>} el - The reference(s) to the element(s) to watch for click outside events.
|
|
36445
|
+
* @param {Object | Function} [options={}] - Configuration options or the click event handler if options are not provided.
|
|
36446
|
+
* @param {boolean} [options.active=true] - Whether the click outside event listener should be active.
|
|
36447
|
+
* @param {Function} [onClick] - The event handler for the click outside event.
|
|
36448
|
+
*/
|
|
36449
|
+
const useClickOutside = (el, options = {}, onClick) => {
|
|
36450
|
+
const els = Array.isArray(el) ? el : [el];
|
|
36451
|
+
let active = true;
|
|
36452
|
+
if (!onClick && typeof options === "function") {
|
|
36453
|
+
onClick = options;
|
|
36454
|
+
}
|
|
36455
|
+
else if (typeof options === "object") {
|
|
36456
|
+
active = options.active !== undefined ? options.active : active;
|
|
36457
|
+
}
|
|
36458
|
+
const handler = (ev) => {
|
|
36459
|
+
const target = ev.target;
|
|
36460
|
+
if (els.every(ref => !ref.current || !ref.current.contains(target))) {
|
|
36461
|
+
onClick && onClick(ev);
|
|
36462
|
+
}
|
|
36463
|
+
};
|
|
36464
|
+
const cleanup = () => window.removeEventListener("click", handler);
|
|
36465
|
+
useEffect(() => {
|
|
36466
|
+
if (active) {
|
|
36467
|
+
window.addEventListener("click", handler);
|
|
36468
|
+
}
|
|
36469
|
+
else {
|
|
36470
|
+
cleanup();
|
|
36471
|
+
}
|
|
36472
|
+
return cleanup;
|
|
36348
36473
|
});
|
|
36349
|
-
|
|
36350
|
-
|
|
36474
|
+
};
|
|
36475
|
+
|
|
36351
36476
|
/**
|
|
36352
|
-
*
|
|
36477
|
+
* The useDebounce hook works like useState, but adds a delay where previous values will be ignored.
|
|
36353
36478
|
*
|
|
36354
|
-
* @param {
|
|
36479
|
+
* @param {any} value The value to set
|
|
36480
|
+
* @param {number} delay The debounce time
|
|
36481
|
+
* @param {"in" | "out" | "both"} direction Considers truthiness of value. If set to "in", the value will only be debounced if it is truthy. If set to "out", the value will only be debounced if it is falsy. If set to "both" or if not defined, the value will be debounced regardless of truthiness.
|
|
36482
|
+
* @returns {any} The latest value received
|
|
36355
36483
|
*/
|
|
36356
|
-
|
|
36357
|
-
|
|
36358
|
-
|
|
36359
|
-
|
|
36360
|
-
|
|
36361
|
-
|
|
36362
|
-
|
|
36363
|
-
|
|
36364
|
-
|
|
36365
|
-
|
|
36366
|
-
|
|
36367
|
-
|
|
36484
|
+
/**
|
|
36485
|
+
*
|
|
36486
|
+
*/
|
|
36487
|
+
const useDebounce = (value, delay = 500, direction) => {
|
|
36488
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
36489
|
+
useEffect(() => {
|
|
36490
|
+
let handler;
|
|
36491
|
+
if ((direction === "in" && !debouncedValue && value) ||
|
|
36492
|
+
(direction === "out" && debouncedValue && !value) ||
|
|
36493
|
+
direction === "both" ||
|
|
36494
|
+
!direction) {
|
|
36495
|
+
handler = setTimeout(() => {
|
|
36496
|
+
setDebouncedValue(value);
|
|
36497
|
+
}, delay);
|
|
36368
36498
|
}
|
|
36369
36499
|
else {
|
|
36370
|
-
|
|
36500
|
+
setDebouncedValue(value);
|
|
36371
36501
|
}
|
|
36372
|
-
|
|
36373
|
-
|
|
36374
|
-
|
|
36502
|
+
return () => {
|
|
36503
|
+
clearTimeout(handler);
|
|
36504
|
+
};
|
|
36505
|
+
}, [value, delay, direction, debouncedValue]);
|
|
36506
|
+
return debouncedValue;
|
|
36507
|
+
};
|
|
36508
|
+
|
|
36509
|
+
// Copied from https://github.com/rexxars/use-device-pixel-ratio
|
|
36510
|
+
/**
|
|
36511
|
+
* Get the device pixel ratio, potentially rounded and capped.
|
|
36512
|
+
* Will emit new values if it changes.
|
|
36513
|
+
*
|
|
36514
|
+
* @param {DevicePixelRatioOptions} options the options object
|
|
36515
|
+
* @returns { number } The current device pixel ratio, or the default if none can be resolved
|
|
36516
|
+
*/
|
|
36517
|
+
function useDevicePixelRatio(options) {
|
|
36518
|
+
const dpr = getDevicePixelRatio(options);
|
|
36519
|
+
const [currentDpr, setCurrentDpr] = useState(dpr);
|
|
36520
|
+
const { defaultDpr, maxDpr, round } = options || {};
|
|
36375
36521
|
useEffect(() => {
|
|
36376
|
-
|
|
36377
|
-
|
|
36378
|
-
|
|
36522
|
+
const canListen = typeof window !== "undefined" && "matchMedia" in window;
|
|
36523
|
+
if (!canListen) {
|
|
36524
|
+
return;
|
|
36379
36525
|
}
|
|
36380
|
-
|
|
36381
|
-
|
|
36526
|
+
const updateDpr = () => setCurrentDpr(getDevicePixelRatio({ defaultDpr, maxDpr, round }));
|
|
36527
|
+
const mediaMatcher = window.matchMedia(`screen and (resolution: ${currentDpr}dppx)`);
|
|
36528
|
+
// Safari 13.1 does not have `addEventListener`, but does have `addListener`
|
|
36529
|
+
if (mediaMatcher.addEventListener) {
|
|
36530
|
+
mediaMatcher.addEventListener("change", updateDpr);
|
|
36531
|
+
}
|
|
36532
|
+
else {
|
|
36533
|
+
mediaMatcher.addListener(updateDpr);
|
|
36534
|
+
}
|
|
36535
|
+
return () => {
|
|
36536
|
+
if (mediaMatcher.removeEventListener) {
|
|
36537
|
+
mediaMatcher.removeEventListener("change", updateDpr);
|
|
36538
|
+
}
|
|
36539
|
+
else {
|
|
36540
|
+
mediaMatcher.removeListener(updateDpr);
|
|
36541
|
+
}
|
|
36542
|
+
};
|
|
36543
|
+
}, [currentDpr, defaultDpr, maxDpr, round]);
|
|
36544
|
+
return currentDpr;
|
|
36545
|
+
}
|
|
36546
|
+
/**
|
|
36547
|
+
* Returns the current device pixel ratio (DPR) given the passed options
|
|
36548
|
+
*
|
|
36549
|
+
* @param { DevicePixelRatioOptions } options the options object
|
|
36550
|
+
* @returns { number } current device pixel ratio
|
|
36551
|
+
*/
|
|
36552
|
+
function getDevicePixelRatio(options) {
|
|
36553
|
+
const { defaultDpr = 1, maxDpr = 3, round = true } = options || {};
|
|
36554
|
+
const hasDprProp = typeof window !== "undefined" && typeof window.devicePixelRatio === "number";
|
|
36555
|
+
const dpr = hasDprProp ? window.devicePixelRatio : defaultDpr;
|
|
36556
|
+
const rounded = Math.min(Math.max(1, round ? Math.floor(dpr) : dpr), maxDpr);
|
|
36557
|
+
return rounded;
|
|
36558
|
+
}
|
|
36559
|
+
|
|
36560
|
+
/**
|
|
36561
|
+
* The useHover hook returns a onMouseEnter, onMouseLeave and a boolean indicating whether the element is being hovered.
|
|
36562
|
+
* The boolean will be true if the element is being hovered, and false if it is not.
|
|
36563
|
+
* Can be directionally debounced.
|
|
36564
|
+
*
|
|
36565
|
+
* @param {ConditionalUseHoverProps} param0 The options
|
|
36566
|
+
* @returns {Object} The object containing the onMouseEnter, onMouseLeave and hovering props
|
|
36567
|
+
*/
|
|
36568
|
+
const useHover = ({ debounced = false, delay = 100, direction = "out" } = { debounced: false }) => {
|
|
36569
|
+
const [hovering, setHovering] = useState(false);
|
|
36570
|
+
const debouncedHovering = useDebounce(hovering, delay, direction);
|
|
36571
|
+
const onMouseEnter = () => {
|
|
36572
|
+
setHovering(true);
|
|
36573
|
+
};
|
|
36574
|
+
const onMouseLeave = () => {
|
|
36575
|
+
setHovering(false);
|
|
36576
|
+
};
|
|
36577
|
+
return { onMouseEnter, onMouseLeave, hovering: debounced ? debouncedHovering : hovering };
|
|
36578
|
+
};
|
|
36579
|
+
|
|
36580
|
+
/**
|
|
36581
|
+
* Differentiate between the first and subsequent renders.
|
|
36582
|
+
*
|
|
36583
|
+
* @returns {boolean} Returns true if it is the first render, false otherwise.
|
|
36584
|
+
*/
|
|
36585
|
+
const useIsFirstRender = () => {
|
|
36586
|
+
const renderRef = useRef(true);
|
|
36587
|
+
if (renderRef.current === true) {
|
|
36588
|
+
renderRef.current = false;
|
|
36589
|
+
return true;
|
|
36590
|
+
}
|
|
36591
|
+
return renderRef.current;
|
|
36382
36592
|
};
|
|
36383
36593
|
|
|
36384
36594
|
/**
|
|
@@ -36450,6 +36660,8 @@ const useTimeout = ({ onTimeout, duration }) => {
|
|
|
36450
36660
|
return [isReady, stopTimeout, startTimeout];
|
|
36451
36661
|
};
|
|
36452
36662
|
|
|
36663
|
+
const cvaMoreMenu = cvaMerge(["p-4"]);
|
|
36664
|
+
|
|
36453
36665
|
/**
|
|
36454
36666
|
* A kebab menu component.
|
|
36455
36667
|
* Advice: fill it with MenuList
|
|
@@ -36471,14 +36683,41 @@ const MoreMenu = ({ className, dataTestId, menuPlacement, iconProps = {
|
|
|
36471
36683
|
useClickOutside(actionMenuRef, () => {
|
|
36472
36684
|
setActionMenuIsOpen(false);
|
|
36473
36685
|
});
|
|
36474
|
-
return (jsx(
|
|
36686
|
+
return (jsx("div", { ref: actionMenuRef, className: cvaMoreMenu({ className }), "data-testid": dataTestId, children: jsxs(Popover, { placement: menuPlacement, children: [jsx(PopoverTrigger, { children: customButton !== null && customButton !== void 0 ? customButton : (jsx(IconButton, Object.assign({}, iconButtonProps, { icon: iconProps.name ? jsx(Icon, Object.assign({}, iconProps, { name: iconProps.name })) : null, onClick: () => {
|
|
36475
36687
|
setActionMenuIsOpen(!actionMenuIsOpen);
|
|
36476
36688
|
} }))) }), jsx(PopoverContent, { children: close => (typeof children === "function" ? children(close) : children) })] }) }));
|
|
36477
36689
|
};
|
|
36478
|
-
|
|
36479
|
-
|
|
36480
|
-
|
|
36481
|
-
|
|
36690
|
+
|
|
36691
|
+
const cvaModalContainer = cvaMerge(["h-full", "w-full", "flex", "items-center"]);
|
|
36692
|
+
const cvaModalCard = cvaMerge([
|
|
36693
|
+
"m-auto",
|
|
36694
|
+
"shadow-2xl",
|
|
36695
|
+
"w-[calc(100%-1rem)]",
|
|
36696
|
+
"max-h-[min(100%-1rem,30%+600px)]",
|
|
36697
|
+
"max-w-[min(100%-1rem,30%+600px)]",
|
|
36698
|
+
]);
|
|
36699
|
+
const cvaModalBackdrop = cvaMerge([
|
|
36700
|
+
"flex",
|
|
36701
|
+
"justify-center",
|
|
36702
|
+
"items-center",
|
|
36703
|
+
"fixed",
|
|
36704
|
+
"top-0",
|
|
36705
|
+
"left-0",
|
|
36706
|
+
"w-full",
|
|
36707
|
+
"h-full",
|
|
36708
|
+
"bg-black/50",
|
|
36709
|
+
"z-20",
|
|
36710
|
+
"invisible",
|
|
36711
|
+
"opacity-0",
|
|
36712
|
+
"transition-all",
|
|
36713
|
+
], {
|
|
36714
|
+
variants: {
|
|
36715
|
+
show: {
|
|
36716
|
+
true: "animate-modal-fade",
|
|
36717
|
+
false: "",
|
|
36718
|
+
},
|
|
36719
|
+
},
|
|
36720
|
+
});
|
|
36482
36721
|
|
|
36483
36722
|
/**
|
|
36484
36723
|
* The Backdrop for the modal.
|
|
@@ -36488,7 +36727,7 @@ const Root = tw.div `
|
|
|
36488
36727
|
*/
|
|
36489
36728
|
const ModalBackdrop = ({ children, isVisible, onClick }) => {
|
|
36490
36729
|
const ref = React.useRef(null);
|
|
36491
|
-
return (jsx(
|
|
36730
|
+
return (jsx("div", { ref: ref, className: cvaModalBackdrop({ show: isVisible }), onMouseDown: e => {
|
|
36492
36731
|
var _a, _b;
|
|
36493
36732
|
// only react on click on backdrop - accessing first child to get around styled element element
|
|
36494
36733
|
if (ref.current !== null) {
|
|
@@ -36498,12 +36737,6 @@ const ModalBackdrop = ({ children, isVisible, onClick }) => {
|
|
|
36498
36737
|
}
|
|
36499
36738
|
}, children: children }));
|
|
36500
36739
|
};
|
|
36501
|
-
const Backdrop = tw.div `
|
|
36502
|
-
tu-modal-backdrop
|
|
36503
|
-
${({ $isVisible }) => {
|
|
36504
|
-
return $isVisible && tws `tu-modal-backdrop--show`;
|
|
36505
|
-
}}
|
|
36506
|
-
`;
|
|
36507
36740
|
|
|
36508
36741
|
/**
|
|
36509
36742
|
* - Modals are used to present critical information or request user input needed to complete a user's workflow.
|
|
@@ -36513,14 +36746,8 @@ const Backdrop = tw.div `
|
|
|
36513
36746
|
const Modal = React.forwardRef(({ isOpen, children, dataTestId, className, role = "", onDismissClick = () => {
|
|
36514
36747
|
return;
|
|
36515
36748
|
}, }, ref) => {
|
|
36516
|
-
return (jsx(ModalBackdrop, { isVisible: isOpen, onClick: onDismissClick, children: isOpen && (jsx(
|
|
36749
|
+
return (jsx(ModalBackdrop, { isVisible: isOpen, onClick: onDismissClick, children: isOpen && (jsx("div", { className: cvaModalContainer(), ref: ref, role: role, children: jsx(Card, { dataTestId: dataTestId, className: cvaModalCard({ className }), children: children }) })) }));
|
|
36517
36750
|
});
|
|
36518
|
-
const StyledCard = twx(Card) `
|
|
36519
|
-
tu-modal__card
|
|
36520
|
-
`;
|
|
36521
|
-
const StyledDiv = tw.div `
|
|
36522
|
-
tu-modal__container
|
|
36523
|
-
`;
|
|
36524
36751
|
|
|
36525
36752
|
var usePortal$1 = {};
|
|
36526
36753
|
|
|
@@ -36932,43 +37159,6 @@ const PageHeader = ({ className, dataTestId, action, showLoading, description, l
|
|
|
36932
37159
|
return (jsxs("div", { className: cvaPageHeader({ className: `${className} tu-page-header` }), "data-testid": dataTestId, children: [jsxs("div", { className: cvaPageHeaderHeadingAccessoriesContainer(), "data-testid": dataTestId && `${dataTestId}-heading-container`, children: [jsxs("div", { className: cvaPageHeaderHeadingContainer(), children: [backTo && (jsx(IconButton, { to: backTo, color: "tertiary", variant: "transparent", size: "small", icon: jsx(Icon, { name: "ArrowLeftIcon" }) })), jsx("h1", { className: cvaPageHeaderHeading(), "data-testid": dataTestId && `${dataTestId}-heading`, children: title }), description && !showLoading && (jsx(Tip, { dataTestId: dataTestId && `${dataTestId}-tip`, iconProps: { name: "QuestionMarkCircleIcon" }, link: link, children: description }))] }), tag && !showLoading && jsx(Tag, { dataTestId: dataTestId, children: tag }), showLoading && jsx(Spinner, { dataTestId: dataTestId && `${dataTestId}-spinner`, centering: "vertically" }), action] }), jsx("div", { className: cvaPageHeaderChildContainer(), children: children })] }));
|
|
36933
37160
|
};
|
|
36934
37161
|
|
|
36935
|
-
const cvaSkeletonLine = cvaMerge([
|
|
36936
|
-
"rounded-md",
|
|
36937
|
-
"h-3",
|
|
36938
|
-
"opacity-20",
|
|
36939
|
-
"animate-pulse",
|
|
36940
|
-
"bg-black/50",
|
|
36941
|
-
"bg-auto",
|
|
36942
|
-
"bg-gradient-to-r",
|
|
36943
|
-
"from-black/0",
|
|
36944
|
-
"via-black/50",
|
|
36945
|
-
"to-black/20",
|
|
36946
|
-
]);
|
|
36947
|
-
|
|
36948
|
-
/**
|
|
36949
|
-
* Display placeholder lines before the data gets loaded to reduce load-time frustration.
|
|
36950
|
-
*/
|
|
36951
|
-
const SkeletonLines = memo(({ margin = "10px 0", lines = 1, height, width = "100%", className, dataTestId }) => {
|
|
36952
|
-
const skeletonLines = [];
|
|
36953
|
-
const getWidth = (index) => {
|
|
36954
|
-
if (width instanceof Array) {
|
|
36955
|
-
return width[index] || "100%";
|
|
36956
|
-
}
|
|
36957
|
-
return width;
|
|
36958
|
-
};
|
|
36959
|
-
const getHeight = (index) => {
|
|
36960
|
-
if (height instanceof Array) {
|
|
36961
|
-
return height[index] || "auto";
|
|
36962
|
-
}
|
|
36963
|
-
return height;
|
|
36964
|
-
};
|
|
36965
|
-
for (let i = 0; i < lines; i++) {
|
|
36966
|
-
skeletonLines.push(jsx("div", { "data-testid": dataTestId !== null && dataTestId !== void 0 ? dataTestId : "skeleton-lines", "data-type": "loading-skeleton-line", className: cvaSkeletonLine({ className }), style: { height: getHeight(i), width: getWidth(i), margin: lines > 1 ? margin : "" }, children: lines > 1 && jsx(Fragment, { children: "\u00A0" }) }, i));
|
|
36967
|
-
}
|
|
36968
|
-
// eslint-disable-next-line react/jsx-no-useless-fragment
|
|
36969
|
-
return jsx(Fragment, { children: skeletonLines });
|
|
36970
|
-
});
|
|
36971
|
-
|
|
36972
37162
|
const cvaPagination = cvaMerge(["flex", "items-center", "gap-1"]);
|
|
36973
37163
|
const cvaPaginationText = cvaMerge("whitespace-nowrap");
|
|
36974
37164
|
|
|
@@ -39034,4 +39224,4 @@ const ContentGridArea = tw.article `
|
|
|
39034
39224
|
tu-layout-area-content
|
|
39035
39225
|
`;
|
|
39036
39226
|
|
|
39037
|
-
export { Alert, Badge, Button$1 as Button, Card, CardBody, CardFooter, CardHeader, Collapse, ContentGridArea, CopyableText, DayPicker, DayPickerPopover, DayRangePicker, DensityContainer, Drawer, ExternalLink, FilterListMapLayout, FullWidthRepeatingLayout, GridArea, Heading, Icon, IconButton, Indicator, IntrinsicallyResponsiveGrid, MenuItem, MenuList, MinTopFullContentLayout, Modal, ModalBackdrop, MoreMenu, NavGridArea, PageHeader, Pagination, Popover, PopoverContent, PopoverTitle, PopoverTrigger, Prompt, ROLE_CARD, SectionHeader, Sidebar, SkeletonLines, Spacer, Spinner, StarButton, Tag, Text, Timeline, TimelineElement, Tip, TitleGridArea, TitleNavContentLayout, Tooltip, ValueBar, cvaButton, cvaButtonSpinner, cvaClickable, cvaIconButtonContainer, cvaIndicator, cvaIndicatorIcon, cvaIndicatorIconBackground, cvaIndicatorLabel, cvaIndicatorPing, docs, getDevicePixelRatio, getValueBarColorByValue, useClickOutside, useContainerProps, useDebounce, useDevicePixelRatio, useHover, useIsFirstRender, useLocalStorage, useLocalStorageReducer, useModal, usePopoverContext, usePrompt, useResize, useTimeout };
|
|
39227
|
+
export { Alert, Badge, Button$1 as Button, Card, CardBody, CardFooter, CardHeader, Collapse, ContentGridArea, CopyableText, DayPicker, DayPickerPopover, DayRangePicker, DensityContainer, Drawer, EmptyState, ExternalLink, FilterListMapLayout, FullWidthRepeatingLayout, GridArea, Heading, Icon, IconButton, Indicator, IntrinsicallyResponsiveGrid, MenuItem, MenuList, MinTopFullContentLayout, Modal, ModalBackdrop, MoreMenu, NavGridArea, PageHeader, Pagination, Popover, PopoverContent, PopoverTitle, PopoverTrigger, Prompt, ROLE_CARD, SectionHeader, Sidebar, SkeletonLines, Spacer, Spinner, StarButton, Tag, Text, Timeline, TimelineElement, Tip, TitleGridArea, TitleNavContentLayout, Tooltip, ValueBar, cvaButton, cvaButtonSpinner, cvaClickable, cvaIconButtonContainer, cvaIndicator, cvaIndicatorIcon, cvaIndicatorIconBackground, cvaIndicatorLabel, cvaIndicatorPing, cvaMenuItem, cvaMenuItemLabel, cvaMenuItemPrefix, cvaMenuItemSuffix, docs, getDevicePixelRatio, getValueBarColorByValue, useClickOutside, useContainerProps, useDebounce, useDevicePixelRatio, useHover, useIsFirstRender, useLocalStorage, useLocalStorageReducer, useModal, usePopoverContext, usePrompt, useResize, useTimeout };
|