@trackunit/react-components 0.5.19 → 0.5.22
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/index.cjs.js +160 -55
- package/index.esm.js +159 -56
- package/package.json +1 -1
- package/src/components/Collapse/Collapse.d.ts +7 -1
- package/src/components/Collapse/Collapse.variants.d.ts +3 -1
- package/src/components/Popover/PopoverTypes.d.ts +2 -2
- package/src/components/Portal/Portal.d.ts +9 -0
- package/src/components/Portal/shared.d.ts +19 -0
- package/src/components/index.d.ts +1 -0
- package/src/hooks/breakpoint-utils.d.ts +23 -0
- package/src/hooks/index.d.ts +2 -1
- package/src/hooks/useContainerBreakpoints.d.ts +29 -0
- package/src/hooks/useViewportBreakpoints.d.ts +21 -0
- package/src/hooks/useViewportSize.d.ts +0 -32
package/index.cjs.js
CHANGED
|
@@ -993,6 +993,99 @@ const useClickOutside = (el, options = {}, onClick) => {
|
|
|
993
993
|
});
|
|
994
994
|
};
|
|
995
995
|
|
|
996
|
+
/**
|
|
997
|
+
* Maps size keys to their corresponding state property names.
|
|
998
|
+
*/
|
|
999
|
+
const breakpointPropsMap = {
|
|
1000
|
+
xs: "isXs",
|
|
1001
|
+
sm: "isSm",
|
|
1002
|
+
md: "isMd",
|
|
1003
|
+
lg: "isLg",
|
|
1004
|
+
xl: "isXl",
|
|
1005
|
+
"2xl": "is2xl",
|
|
1006
|
+
"3xl": "is3xl",
|
|
1007
|
+
};
|
|
1008
|
+
/**
|
|
1009
|
+
* The default state for sizes, with all values set to false.
|
|
1010
|
+
*/
|
|
1011
|
+
const defaultBreakpointState = {
|
|
1012
|
+
isXs: false,
|
|
1013
|
+
isSm: false,
|
|
1014
|
+
isMd: false,
|
|
1015
|
+
isLg: false,
|
|
1016
|
+
isXl: false,
|
|
1017
|
+
is2xl: false,
|
|
1018
|
+
is3xl: false,
|
|
1019
|
+
};
|
|
1020
|
+
/**
|
|
1021
|
+
* Creates a breakpoint state object based on a width value
|
|
1022
|
+
*/
|
|
1023
|
+
const createBreakpointState = ({ width }) => {
|
|
1024
|
+
return sharedUtils.objectEntries(uiDesignTokens.themeScreenSizeAsNumber).reduce((acc, [size, minWidth]) => ({
|
|
1025
|
+
...acc,
|
|
1026
|
+
[breakpointPropsMap[size]]: width >= minWidth,
|
|
1027
|
+
}), { ...defaultBreakpointState });
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
/**
|
|
1031
|
+
* A custom React hook that provides real-time information about a container's size.
|
|
1032
|
+
*
|
|
1033
|
+
* This hook uses ResizeObserver to monitor changes in the container's width and returns
|
|
1034
|
+
* an object with boolean values indicating which breakpoints are currently active.
|
|
1035
|
+
*
|
|
1036
|
+
* @param {RefObject<HTMLElement>} ref - Reference to the container element to observe
|
|
1037
|
+
* @returns {BreakpointState} An object containing boolean values for each container size breakpoint.
|
|
1038
|
+
* @example
|
|
1039
|
+
* const MyComponent = () => {
|
|
1040
|
+
* const containerRef = useRef<HTMLDivElement>(null);
|
|
1041
|
+
* const containerSize = useContainerBreakpoints(containerRef);
|
|
1042
|
+
*
|
|
1043
|
+
* return (
|
|
1044
|
+
* <div ref={containerRef}>
|
|
1045
|
+
* {containerSize.isLg ? (
|
|
1046
|
+
* <LargeLayout />
|
|
1047
|
+
* ) : containerSize.isMd ? (
|
|
1048
|
+
* <MediumLayout />
|
|
1049
|
+
* ) : (
|
|
1050
|
+
* <SmallLayout />
|
|
1051
|
+
* )}
|
|
1052
|
+
* </div>
|
|
1053
|
+
* );
|
|
1054
|
+
* }
|
|
1055
|
+
*/
|
|
1056
|
+
const useContainerBreakpoints = (ref) => {
|
|
1057
|
+
const [containerSize, setContainerSize] = React.useState(() => defaultBreakpointState);
|
|
1058
|
+
React.useEffect(() => {
|
|
1059
|
+
if (process.env.NODE_ENV === "development" && !ref.current) {
|
|
1060
|
+
// eslint-disable-next-line no-console
|
|
1061
|
+
console.warn("useContainerBreakpoints: The provided ref is not attached to any element. " +
|
|
1062
|
+
"Make sure to pass the ref to an element using the ref prop, like: <div ref={myRef}>", "\nComponent:", ref.current);
|
|
1063
|
+
}
|
|
1064
|
+
}, [ref]);
|
|
1065
|
+
const updateContainerSize = React.useCallback(() => {
|
|
1066
|
+
if (!ref.current) {
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
const width = ref.current.getBoundingClientRect().width;
|
|
1070
|
+
setContainerSize(createBreakpointState({ width }));
|
|
1071
|
+
}, [ref]);
|
|
1072
|
+
React.useEffect(() => {
|
|
1073
|
+
const element = ref.current;
|
|
1074
|
+
if (!element) {
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
// Initial check
|
|
1078
|
+
updateContainerSize();
|
|
1079
|
+
// Set up ResizeObserver
|
|
1080
|
+
const resizeObserver = new ResizeObserver(updateContainerSize);
|
|
1081
|
+
resizeObserver.observe(element);
|
|
1082
|
+
return () => {
|
|
1083
|
+
resizeObserver.disconnect();
|
|
1084
|
+
};
|
|
1085
|
+
}, [updateContainerSize, ref]);
|
|
1086
|
+
return containerSize;
|
|
1087
|
+
};
|
|
1088
|
+
|
|
996
1089
|
/**
|
|
997
1090
|
* Hook for managing timeouts.
|
|
998
1091
|
*
|
|
@@ -1384,61 +1477,32 @@ const useSelfUpdatingRef = (initialState) => {
|
|
|
1384
1477
|
return stateRef;
|
|
1385
1478
|
};
|
|
1386
1479
|
|
|
1387
|
-
/**
|
|
1388
|
-
* Maps viewport size keys to their corresponding state property names.
|
|
1389
|
-
*/
|
|
1390
|
-
const propsMap = {
|
|
1391
|
-
xs: "isXs",
|
|
1392
|
-
sm: "isSm",
|
|
1393
|
-
md: "isMd",
|
|
1394
|
-
lg: "isLg",
|
|
1395
|
-
xl: "isXl",
|
|
1396
|
-
"2xl": "is2xl",
|
|
1397
|
-
"3xl": "is3xl",
|
|
1398
|
-
};
|
|
1399
|
-
/**
|
|
1400
|
-
* The default state for viewport sizes, with all values set to false.
|
|
1401
|
-
*/
|
|
1402
|
-
const defaultState = {
|
|
1403
|
-
isXs: false,
|
|
1404
|
-
isSm: false,
|
|
1405
|
-
isMd: false,
|
|
1406
|
-
isLg: false,
|
|
1407
|
-
isXl: false,
|
|
1408
|
-
is2xl: false,
|
|
1409
|
-
is3xl: false,
|
|
1410
|
-
};
|
|
1411
1480
|
/**
|
|
1412
1481
|
* A custom React hook that provides real-time information about the current viewport size.
|
|
1482
|
+
* ! Consider using `useContainerBreakpoints` instead, and only use this when you need to actually react to the viewport size, not the container size.
|
|
1413
1483
|
*
|
|
1414
1484
|
* This hook listens to changes in the viewport size and returns an object with boolean values
|
|
1415
|
-
* indicating which breakpoints are currently active.
|
|
1416
|
-
* layouts and components that need to adapt to different screen sizes.
|
|
1485
|
+
* indicating which breakpoints are currently active.
|
|
1417
1486
|
*
|
|
1418
|
-
* @returns {
|
|
1487
|
+
* @returns {BreakpointState} An object containing boolean values for each viewport size breakpoint.
|
|
1419
1488
|
* @example
|
|
1420
|
-
*
|
|
1421
|
-
* const viewportSize =
|
|
1489
|
+
* const MyComponent = () => {
|
|
1490
|
+
* const viewportSize = useViewportBreakpoints();
|
|
1422
1491
|
*
|
|
1423
1492
|
* if (viewportSize.isLg) {
|
|
1424
1493
|
* return <LargeScreenLayout />;
|
|
1425
|
-
* } else if (viewportSize.isMd) {
|
|
1426
|
-
* return <MediumScreenLayout />;
|
|
1427
|
-
* } else {
|
|
1428
|
-
* return <SmallScreenLayout />;
|
|
1429
1494
|
* }
|
|
1495
|
+
*
|
|
1496
|
+
* return viewportSize.isMd ? <MediumScreenLayout /> : <SmallLayout />;
|
|
1430
1497
|
* }
|
|
1431
1498
|
*/
|
|
1432
|
-
const
|
|
1433
|
-
const [viewportSize, setViewportSize] = React.useState(() =>
|
|
1499
|
+
const useViewportBreakpoints = () => {
|
|
1500
|
+
const [viewportSize, setViewportSize] = React.useState(() => defaultBreakpointState);
|
|
1434
1501
|
const updateViewportSize = React.useCallback(() => {
|
|
1435
|
-
const newViewportSize = sharedUtils.objectEntries(uiDesignTokens.themeScreenSizeAsNumber).reduce((acc, [size, minWidth]) => {
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
[propsMap[size]]: matches,
|
|
1440
|
-
};
|
|
1441
|
-
}, Object.assign({}, defaultState));
|
|
1502
|
+
const newViewportSize = sharedUtils.objectEntries(uiDesignTokens.themeScreenSizeAsNumber).reduce((acc, [size, minWidth]) => ({
|
|
1503
|
+
...acc,
|
|
1504
|
+
[breakpointPropsMap[size]]: window.matchMedia(`(min-width: ${minWidth}px)`).matches,
|
|
1505
|
+
}), { ...defaultBreakpointState });
|
|
1442
1506
|
setViewportSize(newViewportSize);
|
|
1443
1507
|
}, []);
|
|
1444
1508
|
React.useEffect(() => {
|
|
@@ -1579,7 +1643,7 @@ const Breadcrumb = ({ className, dataTestId, breadcrumbItems, back }) => {
|
|
|
1579
1643
|
* @param {BreadcrumbContainerProps} props - The props for the BreadcrumbContainer component
|
|
1580
1644
|
*/
|
|
1581
1645
|
const BreadcrumbContainer = ({ dataTestId, breadcrumbItems }) => {
|
|
1582
|
-
const { isMd: isMediumScreen, isXs: isSmallScreen } =
|
|
1646
|
+
const { isMd: isMediumScreen, isXs: isSmallScreen } = useViewportBreakpoints();
|
|
1583
1647
|
if (isSmallScreen) {
|
|
1584
1648
|
return jsxRuntime.jsx(BreadcrumbForSmallScreen, { breadcrumbItems: breadcrumbItems, dataTestId: `smallScreen-${dataTestId}` });
|
|
1585
1649
|
}
|
|
@@ -1816,7 +1880,14 @@ const cvaCollapseHeader = cssClassVarianceUtilities.cvaMerge([
|
|
|
1816
1880
|
},
|
|
1817
1881
|
});
|
|
1818
1882
|
const cvaCollapseLabelContainer = cssClassVarianceUtilities.cvaMerge(["flex", "items-center", "gap-2"]);
|
|
1819
|
-
const cvaCollapsible = cssClassVarianceUtilities.cvaMerge(["block", "relative",
|
|
1883
|
+
const cvaCollapsible = cssClassVarianceUtilities.cvaMerge(["block", "relative"], {
|
|
1884
|
+
variants: {
|
|
1885
|
+
extraPadding: {
|
|
1886
|
+
true: "p-4",
|
|
1887
|
+
false: "",
|
|
1888
|
+
},
|
|
1889
|
+
},
|
|
1890
|
+
});
|
|
1820
1891
|
const cvaCollapseAnimated = cssClassVarianceUtilities.cvaMerge(["overflow-y-hidden", "transition-all"], {
|
|
1821
1892
|
variants: {
|
|
1822
1893
|
expanded: {
|
|
@@ -1857,7 +1928,7 @@ const cvaChevronIcon = cssClassVarianceUtilities.cvaMerge(["transition-transform
|
|
|
1857
1928
|
* @param {CollapseProps} props - The props for the Collapse component
|
|
1858
1929
|
* @returns {JSX.Element} Collapse component
|
|
1859
1930
|
*/
|
|
1860
|
-
const Collapse = ({ id, initialExpanded = false, onToggle, label, children, className, headerClassName, headerAddon, dataTestId, }) => {
|
|
1931
|
+
const Collapse = ({ id, initialExpanded = false, onToggle, label, children, className, headerClassName, headerAddon, dataTestId, animate = true, extraPadding = true, }) => {
|
|
1861
1932
|
const LABEL_ID = sharedUtils.uuidv4();
|
|
1862
1933
|
const [expanded, setExpanded] = React__namespace.useState(initialExpanded);
|
|
1863
1934
|
const handleClick = React__namespace.useCallback((e) => {
|
|
@@ -1866,12 +1937,12 @@ const Collapse = ({ id, initialExpanded = false, onToggle, label, children, clas
|
|
|
1866
1937
|
}
|
|
1867
1938
|
setExpanded(!expanded);
|
|
1868
1939
|
}, [expanded, onToggle]);
|
|
1869
|
-
return (jsxRuntime.jsxs("div", { className: cvaCollapse({ className }), "data-testid": dataTestId, children: [jsxRuntime.jsxs("div", { "aria-controls": id, "aria-expanded": expanded, className: cvaCollapseHeader({ expanded, className: headerClassName }), onClick: handleClick, role: "button", children: [jsxRuntime.jsxs("div", { className: cvaCollapseLabelContainer(), children: [jsxRuntime.jsx(Icon, { ariaLabelledBy: LABEL_ID, className: cvaChevronIcon({ expanded }), name: "ChevronRight", size: "small" }), jsxRuntime.jsx(Text, { id: LABEL_ID, type: "span", weight: "bold", children: label })] }), headerAddon ? headerAddon : null] }), jsxRuntime.jsx(Collapsible, { expanded: expanded, id: id, children: children })] }));
|
|
1940
|
+
return (jsxRuntime.jsxs("div", { className: cvaCollapse({ className }), "data-testid": dataTestId, children: [jsxRuntime.jsxs("div", { "aria-controls": id, "aria-expanded": expanded, className: cvaCollapseHeader({ expanded, className: headerClassName }), onClick: handleClick, role: "button", children: [jsxRuntime.jsxs("div", { className: cvaCollapseLabelContainer(), children: [jsxRuntime.jsx(Icon, { ariaLabelledBy: LABEL_ID, className: cvaChevronIcon({ expanded }), name: "ChevronRight", size: "small" }), jsxRuntime.jsx(Text, { id: LABEL_ID, type: "span", weight: "bold", children: label })] }), headerAddon ? headerAddon : null] }), jsxRuntime.jsx(Collapsible, { expanded: expanded, extraPadding: extraPadding, id: id, children: expanded || animate ? children : null })] }));
|
|
1870
1941
|
};
|
|
1871
|
-
const Collapsible = ({ children, expanded, id }) => {
|
|
1942
|
+
const Collapsible = ({ children, expanded, id, extraPadding }) => {
|
|
1872
1943
|
const ref = React.useRef(null);
|
|
1873
1944
|
const { height } = useGeometry(ref);
|
|
1874
|
-
return (jsxRuntime.jsx("div", { className: cvaCollapseAnimated({ expanded }), id: id, style: { height: expanded ? height : "0" }, children: jsxRuntime.jsx("div", { ref: ref, children: jsxRuntime.jsx("div", { className: cvaCollapsible(), children: children }) }) }));
|
|
1945
|
+
return (jsxRuntime.jsx("div", { className: cvaCollapseAnimated({ expanded }), id: id, style: { height: expanded ? height : "0" }, children: jsxRuntime.jsx("div", { ref: ref, children: jsxRuntime.jsx("div", { className: cvaCollapsible({ extraPadding }), children: children }) }) }));
|
|
1875
1946
|
};
|
|
1876
1947
|
|
|
1877
1948
|
/**
|
|
@@ -3356,6 +3427,11 @@ const ExternalLink = ({ rel = "noreferrer", target = "_blank", href, className,
|
|
|
3356
3427
|
|
|
3357
3428
|
const DEFAULT_ACTIVATION = { click: true, hover: false, keyboardHandlers: true };
|
|
3358
3429
|
const PADDING = 16;
|
|
3430
|
+
const DEFAULT_DISMISSAL = {
|
|
3431
|
+
enabled: true,
|
|
3432
|
+
outsidePress: true,
|
|
3433
|
+
ancestorScroll: false,
|
|
3434
|
+
};
|
|
3359
3435
|
/**
|
|
3360
3436
|
* The hook that powers the Popover component.
|
|
3361
3437
|
* It should not be used directly, but rather through the Popover component.
|
|
@@ -3363,7 +3439,7 @@ const PADDING = 16;
|
|
|
3363
3439
|
* @param {PopoverProps} options The options for the popover
|
|
3364
3440
|
* @returns {ReturnType<typeof usePopover>} The data for the popover
|
|
3365
3441
|
*/
|
|
3366
|
-
const usePopover = ({ initialOpen = false, placement = "bottom", isModal, isOpen: controlledIsOpen, activation = DEFAULT_ACTIVATION, dismissal, onOpenStateChange, ...restOptions }) => {
|
|
3442
|
+
const usePopover = ({ initialOpen = false, placement = "bottom", isModal, isOpen: controlledIsOpen, activation = DEFAULT_ACTIVATION, dismissal = DEFAULT_DISMISSAL, onOpenStateChange, ...restOptions }) => {
|
|
3367
3443
|
const [uncontrolledIsOpen, setUncontrolledIsOpen] = React.useState(initialOpen);
|
|
3368
3444
|
const [labelId, setLabelId] = React.useState();
|
|
3369
3445
|
const [descriptionId, setDescriptionId] = React.useState();
|
|
@@ -3392,12 +3468,11 @@ const usePopover = ({ initialOpen = false, placement = "bottom", isModal, isOpen
|
|
|
3392
3468
|
});
|
|
3393
3469
|
const popoverContext = popoverData.context;
|
|
3394
3470
|
const resolvedActivation = typeof activation === "function" ? activation(DEFAULT_ACTIVATION) : activation;
|
|
3471
|
+
const resolvedDismissal = typeof dismissal === "function" ? dismissal(DEFAULT_DISMISSAL) : dismissal;
|
|
3395
3472
|
const clickInteraction = react.useClick(popoverContext, {
|
|
3396
3473
|
enabled: resolvedActivation.click,
|
|
3397
|
-
ignoreMouse: resolvedActivation.hover,
|
|
3398
|
-
keyboardHandlers: false,
|
|
3399
3474
|
});
|
|
3400
|
-
const dismissInteraction = react.useDismiss(popoverContext,
|
|
3475
|
+
const dismissInteraction = react.useDismiss(popoverContext, resolvedDismissal);
|
|
3401
3476
|
const hoverInteraction = react.useHover(popoverContext, {
|
|
3402
3477
|
enabled: resolvedActivation.hover,
|
|
3403
3478
|
});
|
|
@@ -3461,6 +3536,34 @@ const Popover = ({ children, isModal = false, ...restOptions }) => {
|
|
|
3461
3536
|
return (jsxRuntime.jsx(PopoverContext.Provider, { value: popover, children: typeof children === "function" ? children({ isOpen: popover.isOpen, placement: popover.placement }) : children }));
|
|
3462
3537
|
};
|
|
3463
3538
|
|
|
3539
|
+
/** @internal */
|
|
3540
|
+
const PORTAL_CONTAINER = "portal-container";
|
|
3541
|
+
/**
|
|
3542
|
+
* Creates or retrieves the default portal container element
|
|
3543
|
+
*
|
|
3544
|
+
* @internal
|
|
3545
|
+
*/
|
|
3546
|
+
const getDefaultPortalContainer = () => {
|
|
3547
|
+
let container = document.getElementById(PORTAL_CONTAINER);
|
|
3548
|
+
if (!container) {
|
|
3549
|
+
container = document.createElement("div");
|
|
3550
|
+
container.id = PORTAL_CONTAINER;
|
|
3551
|
+
document.body.appendChild(container);
|
|
3552
|
+
}
|
|
3553
|
+
return container;
|
|
3554
|
+
};
|
|
3555
|
+
|
|
3556
|
+
/**
|
|
3557
|
+
* Portals the floating element into a given container element
|
|
3558
|
+
* By default they're portalled into an z-index isolated div in
|
|
3559
|
+
* document body -> div#portal-container.
|
|
3560
|
+
* alongside other portalled elements.
|
|
3561
|
+
*/
|
|
3562
|
+
const Portal = (props) => {
|
|
3563
|
+
var _a;
|
|
3564
|
+
return jsxRuntime.jsx(react.FloatingPortal, { ...props, root: (_a = props.root) !== null && _a !== void 0 ? _a : getDefaultPortalContainer() });
|
|
3565
|
+
};
|
|
3566
|
+
|
|
3464
3567
|
const cvaPopoverContainer = cssClassVarianceUtilities.cvaMerge(["component-popover-border", "z-popover", "animate-fade-in-fast"]);
|
|
3465
3568
|
const cvaPopoverTitleContainer = cssClassVarianceUtilities.cvaMerge(["flex", "items-center", "px-2", "py-1"], {
|
|
3466
3569
|
variants: {
|
|
@@ -3476,7 +3579,7 @@ const PopoverContent = React.forwardRef(function PopoverContent({ className, dat
|
|
|
3476
3579
|
var _a;
|
|
3477
3580
|
const { context: floatingContext, customProps, ...context } = usePopoverContext();
|
|
3478
3581
|
const ref = react.useMergeRefs([context.refs.setFloating, propRef]);
|
|
3479
|
-
return (jsxRuntime.jsx(
|
|
3582
|
+
return (jsxRuntime.jsx(Portal, { id: portalId, children: context.isOpen ? (jsxRuntime.jsx(react.FloatingFocusManager, { closeOnFocusOut: false, context: floatingContext, guards: true, modal: context.isModal, order: ["reference", "content"], returnFocus: true, children: jsxRuntime.jsx("div", { "aria-describedby": context.descriptionId, "aria-labelledby": context.labelId, className: cvaPopoverContainer({ className: className !== null && className !== void 0 ? className : customProps.className }), "data-testid": (_a = dataTestId !== null && dataTestId !== void 0 ? dataTestId : customProps.dataTestId) !== null && _a !== void 0 ? _a : "popover-content", ref: ref, style: {
|
|
3480
3583
|
position: context.strategy,
|
|
3481
3584
|
top: context.y,
|
|
3482
3585
|
left: context.x,
|
|
@@ -3544,7 +3647,7 @@ const cvaTooltipPopoverTail = cssClassVarianceUtilities.cvaMerge("", {
|
|
|
3544
3647
|
},
|
|
3545
3648
|
mode: {
|
|
3546
3649
|
light: "fill-white",
|
|
3547
|
-
dark: "fill-
|
|
3650
|
+
dark: "fill-neutral-700",
|
|
3548
3651
|
},
|
|
3549
3652
|
},
|
|
3550
3653
|
defaultVariants: {
|
|
@@ -4924,6 +5027,7 @@ exports.Popover = Popover;
|
|
|
4924
5027
|
exports.PopoverContent = PopoverContent;
|
|
4925
5028
|
exports.PopoverTitle = PopoverTitle;
|
|
4926
5029
|
exports.PopoverTrigger = PopoverTrigger;
|
|
5030
|
+
exports.Portal = Portal;
|
|
4927
5031
|
exports.Prompt = Prompt;
|
|
4928
5032
|
exports.ROLE_CARD = ROLE_CARD;
|
|
4929
5033
|
exports.SectionHeader = SectionHeader;
|
|
@@ -4970,6 +5074,7 @@ exports.iconColorNames = iconColorNames;
|
|
|
4970
5074
|
exports.iconPalette = iconPalette;
|
|
4971
5075
|
exports.setLocalStorage = setLocalStorage;
|
|
4972
5076
|
exports.useClickOutside = useClickOutside;
|
|
5077
|
+
exports.useContainerBreakpoints = useContainerBreakpoints;
|
|
4973
5078
|
exports.useContinuousTimeout = useContinuousTimeout;
|
|
4974
5079
|
exports.useDebounce = useDebounce;
|
|
4975
5080
|
exports.useDevicePixelRatio = useDevicePixelRatio;
|
|
@@ -4989,5 +5094,5 @@ exports.useResize = useResize;
|
|
|
4989
5094
|
exports.useScrollDetection = useScrollDetection;
|
|
4990
5095
|
exports.useSelfUpdatingRef = useSelfUpdatingRef;
|
|
4991
5096
|
exports.useTimeout = useTimeout;
|
|
4992
|
-
exports.
|
|
5097
|
+
exports.useViewportBreakpoints = useViewportBreakpoints;
|
|
4993
5098
|
exports.useWindowActivity = useWindowActivity;
|
package/index.esm.js
CHANGED
|
@@ -13,7 +13,7 @@ import { cvaMerge } from '@trackunit/css-class-variance-utilities';
|
|
|
13
13
|
import { Slottable, Slot } from '@radix-ui/react-slot';
|
|
14
14
|
import { useDebounceCallback, useCopyToClipboard } from 'usehooks-ts';
|
|
15
15
|
import { Link, useBlocker } from '@tanstack/react-router';
|
|
16
|
-
import { useFloating, autoUpdate, offset, flip, shift, size, useClick, useDismiss, useHover as useHover$1, useRole, useInteractions,
|
|
16
|
+
import { useFloating, autoUpdate, offset, flip, shift, size, useClick, useDismiss, useHover as useHover$1, useRole, useInteractions, FloatingPortal, useMergeRefs, FloatingFocusManager, arrow, useTransitionStatus, FloatingArrow } from '@floating-ui/react';
|
|
17
17
|
import omit from 'lodash/omit';
|
|
18
18
|
import { twMerge } from 'tailwind-merge';
|
|
19
19
|
import { HelmetProvider, Helmet } from 'react-helmet-async';
|
|
@@ -973,6 +973,99 @@ const useClickOutside = (el, options = {}, onClick) => {
|
|
|
973
973
|
});
|
|
974
974
|
};
|
|
975
975
|
|
|
976
|
+
/**
|
|
977
|
+
* Maps size keys to their corresponding state property names.
|
|
978
|
+
*/
|
|
979
|
+
const breakpointPropsMap = {
|
|
980
|
+
xs: "isXs",
|
|
981
|
+
sm: "isSm",
|
|
982
|
+
md: "isMd",
|
|
983
|
+
lg: "isLg",
|
|
984
|
+
xl: "isXl",
|
|
985
|
+
"2xl": "is2xl",
|
|
986
|
+
"3xl": "is3xl",
|
|
987
|
+
};
|
|
988
|
+
/**
|
|
989
|
+
* The default state for sizes, with all values set to false.
|
|
990
|
+
*/
|
|
991
|
+
const defaultBreakpointState = {
|
|
992
|
+
isXs: false,
|
|
993
|
+
isSm: false,
|
|
994
|
+
isMd: false,
|
|
995
|
+
isLg: false,
|
|
996
|
+
isXl: false,
|
|
997
|
+
is2xl: false,
|
|
998
|
+
is3xl: false,
|
|
999
|
+
};
|
|
1000
|
+
/**
|
|
1001
|
+
* Creates a breakpoint state object based on a width value
|
|
1002
|
+
*/
|
|
1003
|
+
const createBreakpointState = ({ width }) => {
|
|
1004
|
+
return objectEntries(themeScreenSizeAsNumber).reduce((acc, [size, minWidth]) => ({
|
|
1005
|
+
...acc,
|
|
1006
|
+
[breakpointPropsMap[size]]: width >= minWidth,
|
|
1007
|
+
}), { ...defaultBreakpointState });
|
|
1008
|
+
};
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* A custom React hook that provides real-time information about a container's size.
|
|
1012
|
+
*
|
|
1013
|
+
* This hook uses ResizeObserver to monitor changes in the container's width and returns
|
|
1014
|
+
* an object with boolean values indicating which breakpoints are currently active.
|
|
1015
|
+
*
|
|
1016
|
+
* @param {RefObject<HTMLElement>} ref - Reference to the container element to observe
|
|
1017
|
+
* @returns {BreakpointState} An object containing boolean values for each container size breakpoint.
|
|
1018
|
+
* @example
|
|
1019
|
+
* const MyComponent = () => {
|
|
1020
|
+
* const containerRef = useRef<HTMLDivElement>(null);
|
|
1021
|
+
* const containerSize = useContainerBreakpoints(containerRef);
|
|
1022
|
+
*
|
|
1023
|
+
* return (
|
|
1024
|
+
* <div ref={containerRef}>
|
|
1025
|
+
* {containerSize.isLg ? (
|
|
1026
|
+
* <LargeLayout />
|
|
1027
|
+
* ) : containerSize.isMd ? (
|
|
1028
|
+
* <MediumLayout />
|
|
1029
|
+
* ) : (
|
|
1030
|
+
* <SmallLayout />
|
|
1031
|
+
* )}
|
|
1032
|
+
* </div>
|
|
1033
|
+
* );
|
|
1034
|
+
* }
|
|
1035
|
+
*/
|
|
1036
|
+
const useContainerBreakpoints = (ref) => {
|
|
1037
|
+
const [containerSize, setContainerSize] = useState(() => defaultBreakpointState);
|
|
1038
|
+
useEffect(() => {
|
|
1039
|
+
if (process.env.NODE_ENV === "development" && !ref.current) {
|
|
1040
|
+
// eslint-disable-next-line no-console
|
|
1041
|
+
console.warn("useContainerBreakpoints: The provided ref is not attached to any element. " +
|
|
1042
|
+
"Make sure to pass the ref to an element using the ref prop, like: <div ref={myRef}>", "\nComponent:", ref.current);
|
|
1043
|
+
}
|
|
1044
|
+
}, [ref]);
|
|
1045
|
+
const updateContainerSize = useCallback(() => {
|
|
1046
|
+
if (!ref.current) {
|
|
1047
|
+
return;
|
|
1048
|
+
}
|
|
1049
|
+
const width = ref.current.getBoundingClientRect().width;
|
|
1050
|
+
setContainerSize(createBreakpointState({ width }));
|
|
1051
|
+
}, [ref]);
|
|
1052
|
+
useEffect(() => {
|
|
1053
|
+
const element = ref.current;
|
|
1054
|
+
if (!element) {
|
|
1055
|
+
return;
|
|
1056
|
+
}
|
|
1057
|
+
// Initial check
|
|
1058
|
+
updateContainerSize();
|
|
1059
|
+
// Set up ResizeObserver
|
|
1060
|
+
const resizeObserver = new ResizeObserver(updateContainerSize);
|
|
1061
|
+
resizeObserver.observe(element);
|
|
1062
|
+
return () => {
|
|
1063
|
+
resizeObserver.disconnect();
|
|
1064
|
+
};
|
|
1065
|
+
}, [updateContainerSize, ref]);
|
|
1066
|
+
return containerSize;
|
|
1067
|
+
};
|
|
1068
|
+
|
|
976
1069
|
/**
|
|
977
1070
|
* Hook for managing timeouts.
|
|
978
1071
|
*
|
|
@@ -1364,61 +1457,32 @@ const useSelfUpdatingRef = (initialState) => {
|
|
|
1364
1457
|
return stateRef;
|
|
1365
1458
|
};
|
|
1366
1459
|
|
|
1367
|
-
/**
|
|
1368
|
-
* Maps viewport size keys to their corresponding state property names.
|
|
1369
|
-
*/
|
|
1370
|
-
const propsMap = {
|
|
1371
|
-
xs: "isXs",
|
|
1372
|
-
sm: "isSm",
|
|
1373
|
-
md: "isMd",
|
|
1374
|
-
lg: "isLg",
|
|
1375
|
-
xl: "isXl",
|
|
1376
|
-
"2xl": "is2xl",
|
|
1377
|
-
"3xl": "is3xl",
|
|
1378
|
-
};
|
|
1379
|
-
/**
|
|
1380
|
-
* The default state for viewport sizes, with all values set to false.
|
|
1381
|
-
*/
|
|
1382
|
-
const defaultState = {
|
|
1383
|
-
isXs: false,
|
|
1384
|
-
isSm: false,
|
|
1385
|
-
isMd: false,
|
|
1386
|
-
isLg: false,
|
|
1387
|
-
isXl: false,
|
|
1388
|
-
is2xl: false,
|
|
1389
|
-
is3xl: false,
|
|
1390
|
-
};
|
|
1391
1460
|
/**
|
|
1392
1461
|
* A custom React hook that provides real-time information about the current viewport size.
|
|
1462
|
+
* ! Consider using `useContainerBreakpoints` instead, and only use this when you need to actually react to the viewport size, not the container size.
|
|
1393
1463
|
*
|
|
1394
1464
|
* This hook listens to changes in the viewport size and returns an object with boolean values
|
|
1395
|
-
* indicating which breakpoints are currently active.
|
|
1396
|
-
* layouts and components that need to adapt to different screen sizes.
|
|
1465
|
+
* indicating which breakpoints are currently active.
|
|
1397
1466
|
*
|
|
1398
|
-
* @returns {
|
|
1467
|
+
* @returns {BreakpointState} An object containing boolean values for each viewport size breakpoint.
|
|
1399
1468
|
* @example
|
|
1400
|
-
*
|
|
1401
|
-
* const viewportSize =
|
|
1469
|
+
* const MyComponent = () => {
|
|
1470
|
+
* const viewportSize = useViewportBreakpoints();
|
|
1402
1471
|
*
|
|
1403
1472
|
* if (viewportSize.isLg) {
|
|
1404
1473
|
* return <LargeScreenLayout />;
|
|
1405
|
-
* } else if (viewportSize.isMd) {
|
|
1406
|
-
* return <MediumScreenLayout />;
|
|
1407
|
-
* } else {
|
|
1408
|
-
* return <SmallScreenLayout />;
|
|
1409
1474
|
* }
|
|
1475
|
+
*
|
|
1476
|
+
* return viewportSize.isMd ? <MediumScreenLayout /> : <SmallLayout />;
|
|
1410
1477
|
* }
|
|
1411
1478
|
*/
|
|
1412
|
-
const
|
|
1413
|
-
const [viewportSize, setViewportSize] = useState(() =>
|
|
1479
|
+
const useViewportBreakpoints = () => {
|
|
1480
|
+
const [viewportSize, setViewportSize] = useState(() => defaultBreakpointState);
|
|
1414
1481
|
const updateViewportSize = useCallback(() => {
|
|
1415
|
-
const newViewportSize = objectEntries(themeScreenSizeAsNumber).reduce((acc, [size, minWidth]) => {
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
[propsMap[size]]: matches,
|
|
1420
|
-
};
|
|
1421
|
-
}, Object.assign({}, defaultState));
|
|
1482
|
+
const newViewportSize = objectEntries(themeScreenSizeAsNumber).reduce((acc, [size, minWidth]) => ({
|
|
1483
|
+
...acc,
|
|
1484
|
+
[breakpointPropsMap[size]]: window.matchMedia(`(min-width: ${minWidth}px)`).matches,
|
|
1485
|
+
}), { ...defaultBreakpointState });
|
|
1422
1486
|
setViewportSize(newViewportSize);
|
|
1423
1487
|
}, []);
|
|
1424
1488
|
useEffect(() => {
|
|
@@ -1559,7 +1623,7 @@ const Breadcrumb = ({ className, dataTestId, breadcrumbItems, back }) => {
|
|
|
1559
1623
|
* @param {BreadcrumbContainerProps} props - The props for the BreadcrumbContainer component
|
|
1560
1624
|
*/
|
|
1561
1625
|
const BreadcrumbContainer = ({ dataTestId, breadcrumbItems }) => {
|
|
1562
|
-
const { isMd: isMediumScreen, isXs: isSmallScreen } =
|
|
1626
|
+
const { isMd: isMediumScreen, isXs: isSmallScreen } = useViewportBreakpoints();
|
|
1563
1627
|
if (isSmallScreen) {
|
|
1564
1628
|
return jsx(BreadcrumbForSmallScreen, { breadcrumbItems: breadcrumbItems, dataTestId: `smallScreen-${dataTestId}` });
|
|
1565
1629
|
}
|
|
@@ -1796,7 +1860,14 @@ const cvaCollapseHeader = cvaMerge([
|
|
|
1796
1860
|
},
|
|
1797
1861
|
});
|
|
1798
1862
|
const cvaCollapseLabelContainer = cvaMerge(["flex", "items-center", "gap-2"]);
|
|
1799
|
-
const cvaCollapsible = cvaMerge(["block", "relative",
|
|
1863
|
+
const cvaCollapsible = cvaMerge(["block", "relative"], {
|
|
1864
|
+
variants: {
|
|
1865
|
+
extraPadding: {
|
|
1866
|
+
true: "p-4",
|
|
1867
|
+
false: "",
|
|
1868
|
+
},
|
|
1869
|
+
},
|
|
1870
|
+
});
|
|
1800
1871
|
const cvaCollapseAnimated = cvaMerge(["overflow-y-hidden", "transition-all"], {
|
|
1801
1872
|
variants: {
|
|
1802
1873
|
expanded: {
|
|
@@ -1837,7 +1908,7 @@ const cvaChevronIcon = cvaMerge(["transition-transform"], {
|
|
|
1837
1908
|
* @param {CollapseProps} props - The props for the Collapse component
|
|
1838
1909
|
* @returns {JSX.Element} Collapse component
|
|
1839
1910
|
*/
|
|
1840
|
-
const Collapse = ({ id, initialExpanded = false, onToggle, label, children, className, headerClassName, headerAddon, dataTestId, }) => {
|
|
1911
|
+
const Collapse = ({ id, initialExpanded = false, onToggle, label, children, className, headerClassName, headerAddon, dataTestId, animate = true, extraPadding = true, }) => {
|
|
1841
1912
|
const LABEL_ID = uuidv4();
|
|
1842
1913
|
const [expanded, setExpanded] = React.useState(initialExpanded);
|
|
1843
1914
|
const handleClick = React.useCallback((e) => {
|
|
@@ -1846,12 +1917,12 @@ const Collapse = ({ id, initialExpanded = false, onToggle, label, children, clas
|
|
|
1846
1917
|
}
|
|
1847
1918
|
setExpanded(!expanded);
|
|
1848
1919
|
}, [expanded, onToggle]);
|
|
1849
|
-
return (jsxs("div", { className: cvaCollapse({ className }), "data-testid": dataTestId, children: [jsxs("div", { "aria-controls": id, "aria-expanded": expanded, className: cvaCollapseHeader({ expanded, className: headerClassName }), onClick: handleClick, role: "button", children: [jsxs("div", { className: cvaCollapseLabelContainer(), children: [jsx(Icon, { ariaLabelledBy: LABEL_ID, className: cvaChevronIcon({ expanded }), name: "ChevronRight", size: "small" }), jsx(Text, { id: LABEL_ID, type: "span", weight: "bold", children: label })] }), headerAddon ? headerAddon : null] }), jsx(Collapsible, { expanded: expanded, id: id, children: children })] }));
|
|
1920
|
+
return (jsxs("div", { className: cvaCollapse({ className }), "data-testid": dataTestId, children: [jsxs("div", { "aria-controls": id, "aria-expanded": expanded, className: cvaCollapseHeader({ expanded, className: headerClassName }), onClick: handleClick, role: "button", children: [jsxs("div", { className: cvaCollapseLabelContainer(), children: [jsx(Icon, { ariaLabelledBy: LABEL_ID, className: cvaChevronIcon({ expanded }), name: "ChevronRight", size: "small" }), jsx(Text, { id: LABEL_ID, type: "span", weight: "bold", children: label })] }), headerAddon ? headerAddon : null] }), jsx(Collapsible, { expanded: expanded, extraPadding: extraPadding, id: id, children: expanded || animate ? children : null })] }));
|
|
1850
1921
|
};
|
|
1851
|
-
const Collapsible = ({ children, expanded, id }) => {
|
|
1922
|
+
const Collapsible = ({ children, expanded, id, extraPadding }) => {
|
|
1852
1923
|
const ref = useRef(null);
|
|
1853
1924
|
const { height } = useGeometry(ref);
|
|
1854
|
-
return (jsx("div", { className: cvaCollapseAnimated({ expanded }), id: id, style: { height: expanded ? height : "0" }, children: jsx("div", { ref: ref, children: jsx("div", { className: cvaCollapsible(), children: children }) }) }));
|
|
1925
|
+
return (jsx("div", { className: cvaCollapseAnimated({ expanded }), id: id, style: { height: expanded ? height : "0" }, children: jsx("div", { ref: ref, children: jsx("div", { className: cvaCollapsible({ extraPadding }), children: children }) }) }));
|
|
1855
1926
|
};
|
|
1856
1927
|
|
|
1857
1928
|
/**
|
|
@@ -3336,6 +3407,11 @@ const ExternalLink = ({ rel = "noreferrer", target = "_blank", href, className,
|
|
|
3336
3407
|
|
|
3337
3408
|
const DEFAULT_ACTIVATION = { click: true, hover: false, keyboardHandlers: true };
|
|
3338
3409
|
const PADDING = 16;
|
|
3410
|
+
const DEFAULT_DISMISSAL = {
|
|
3411
|
+
enabled: true,
|
|
3412
|
+
outsidePress: true,
|
|
3413
|
+
ancestorScroll: false,
|
|
3414
|
+
};
|
|
3339
3415
|
/**
|
|
3340
3416
|
* The hook that powers the Popover component.
|
|
3341
3417
|
* It should not be used directly, but rather through the Popover component.
|
|
@@ -3343,7 +3419,7 @@ const PADDING = 16;
|
|
|
3343
3419
|
* @param {PopoverProps} options The options for the popover
|
|
3344
3420
|
* @returns {ReturnType<typeof usePopover>} The data for the popover
|
|
3345
3421
|
*/
|
|
3346
|
-
const usePopover = ({ initialOpen = false, placement = "bottom", isModal, isOpen: controlledIsOpen, activation = DEFAULT_ACTIVATION, dismissal, onOpenStateChange, ...restOptions }) => {
|
|
3422
|
+
const usePopover = ({ initialOpen = false, placement = "bottom", isModal, isOpen: controlledIsOpen, activation = DEFAULT_ACTIVATION, dismissal = DEFAULT_DISMISSAL, onOpenStateChange, ...restOptions }) => {
|
|
3347
3423
|
const [uncontrolledIsOpen, setUncontrolledIsOpen] = useState(initialOpen);
|
|
3348
3424
|
const [labelId, setLabelId] = useState();
|
|
3349
3425
|
const [descriptionId, setDescriptionId] = useState();
|
|
@@ -3372,12 +3448,11 @@ const usePopover = ({ initialOpen = false, placement = "bottom", isModal, isOpen
|
|
|
3372
3448
|
});
|
|
3373
3449
|
const popoverContext = popoverData.context;
|
|
3374
3450
|
const resolvedActivation = typeof activation === "function" ? activation(DEFAULT_ACTIVATION) : activation;
|
|
3451
|
+
const resolvedDismissal = typeof dismissal === "function" ? dismissal(DEFAULT_DISMISSAL) : dismissal;
|
|
3375
3452
|
const clickInteraction = useClick(popoverContext, {
|
|
3376
3453
|
enabled: resolvedActivation.click,
|
|
3377
|
-
ignoreMouse: resolvedActivation.hover,
|
|
3378
|
-
keyboardHandlers: false,
|
|
3379
3454
|
});
|
|
3380
|
-
const dismissInteraction = useDismiss(popoverContext,
|
|
3455
|
+
const dismissInteraction = useDismiss(popoverContext, resolvedDismissal);
|
|
3381
3456
|
const hoverInteraction = useHover$1(popoverContext, {
|
|
3382
3457
|
enabled: resolvedActivation.hover,
|
|
3383
3458
|
});
|
|
@@ -3441,6 +3516,34 @@ const Popover = ({ children, isModal = false, ...restOptions }) => {
|
|
|
3441
3516
|
return (jsx(PopoverContext.Provider, { value: popover, children: typeof children === "function" ? children({ isOpen: popover.isOpen, placement: popover.placement }) : children }));
|
|
3442
3517
|
};
|
|
3443
3518
|
|
|
3519
|
+
/** @internal */
|
|
3520
|
+
const PORTAL_CONTAINER = "portal-container";
|
|
3521
|
+
/**
|
|
3522
|
+
* Creates or retrieves the default portal container element
|
|
3523
|
+
*
|
|
3524
|
+
* @internal
|
|
3525
|
+
*/
|
|
3526
|
+
const getDefaultPortalContainer = () => {
|
|
3527
|
+
let container = document.getElementById(PORTAL_CONTAINER);
|
|
3528
|
+
if (!container) {
|
|
3529
|
+
container = document.createElement("div");
|
|
3530
|
+
container.id = PORTAL_CONTAINER;
|
|
3531
|
+
document.body.appendChild(container);
|
|
3532
|
+
}
|
|
3533
|
+
return container;
|
|
3534
|
+
};
|
|
3535
|
+
|
|
3536
|
+
/**
|
|
3537
|
+
* Portals the floating element into a given container element
|
|
3538
|
+
* By default they're portalled into an z-index isolated div in
|
|
3539
|
+
* document body -> div#portal-container.
|
|
3540
|
+
* alongside other portalled elements.
|
|
3541
|
+
*/
|
|
3542
|
+
const Portal = (props) => {
|
|
3543
|
+
var _a;
|
|
3544
|
+
return jsx(FloatingPortal, { ...props, root: (_a = props.root) !== null && _a !== void 0 ? _a : getDefaultPortalContainer() });
|
|
3545
|
+
};
|
|
3546
|
+
|
|
3444
3547
|
const cvaPopoverContainer = cvaMerge(["component-popover-border", "z-popover", "animate-fade-in-fast"]);
|
|
3445
3548
|
const cvaPopoverTitleContainer = cvaMerge(["flex", "items-center", "px-2", "py-1"], {
|
|
3446
3549
|
variants: {
|
|
@@ -3456,7 +3559,7 @@ const PopoverContent = React__default.forwardRef(function PopoverContent({ class
|
|
|
3456
3559
|
var _a;
|
|
3457
3560
|
const { context: floatingContext, customProps, ...context } = usePopoverContext();
|
|
3458
3561
|
const ref = useMergeRefs([context.refs.setFloating, propRef]);
|
|
3459
|
-
return (jsx(
|
|
3562
|
+
return (jsx(Portal, { id: portalId, children: context.isOpen ? (jsx(FloatingFocusManager, { closeOnFocusOut: false, context: floatingContext, guards: true, modal: context.isModal, order: ["reference", "content"], returnFocus: true, children: jsx("div", { "aria-describedby": context.descriptionId, "aria-labelledby": context.labelId, className: cvaPopoverContainer({ className: className !== null && className !== void 0 ? className : customProps.className }), "data-testid": (_a = dataTestId !== null && dataTestId !== void 0 ? dataTestId : customProps.dataTestId) !== null && _a !== void 0 ? _a : "popover-content", ref: ref, style: {
|
|
3460
3563
|
position: context.strategy,
|
|
3461
3564
|
top: context.y,
|
|
3462
3565
|
left: context.x,
|
|
@@ -3524,7 +3627,7 @@ const cvaTooltipPopoverTail = cvaMerge("", {
|
|
|
3524
3627
|
},
|
|
3525
3628
|
mode: {
|
|
3526
3629
|
light: "fill-white",
|
|
3527
|
-
dark: "fill-
|
|
3630
|
+
dark: "fill-neutral-700",
|
|
3528
3631
|
},
|
|
3529
3632
|
},
|
|
3530
3633
|
defaultVariants: {
|
|
@@ -4869,4 +4972,4 @@ const cvaClickable = cvaMerge([
|
|
|
4869
4972
|
},
|
|
4870
4973
|
});
|
|
4871
4974
|
|
|
4872
|
-
export { Alert, Badge, Breadcrumb, BreadcrumbContainer, Button, Card, CardBody, CardFooter, CardHeader, Collapse, CompletionStatusIndicator, CopyableText, EmptyState, EmptyValue, ExternalLink, Heading, Icon, IconButton, Indicator, KPICard, MenuDivider, MenuItem, MenuList, MoreMenu, Notice, PackageNameStoryComponent, Page, PageContent, PageHeader, Pagination, Polygon, Popover, PopoverContent, PopoverTitle, PopoverTrigger, Prompt, ROLE_CARD, SectionHeader, Sidebar, SkeletonLines, Spacer, Spinner, StarButton, Tab, TabContent, TabList, Tabs, Tag, Text, Timeline, TimelineElement, ToggleGroup, ToggleItem, Tooltip, ValueBar, VirtualizedList, WidgetBody, cvaButton, cvaButtonPrefixSuffix, cvaButtonSpinner, cvaButtonSpinnerContainer, cvaClickable, cvaIconButton, cvaIndicator, cvaIndicatorIcon, cvaIndicatorIconBackground, cvaIndicatorLabel, cvaIndicatorPing, cvaInteractableItem, cvaMenuItem, cvaMenuItemLabel, cvaMenuItemPrefix, cvaMenuItemStyle, cvaMenuItemSuffix, docs, getDevicePixelRatio, getValueBarColorByValue, iconColorNames, iconPalette, setLocalStorage, useClickOutside, useContinuousTimeout, useDebounce, useDevicePixelRatio, useGeometry, useHover, useIsFirstRender, useIsFullscreen, useIsTextCutOff, useLocalStorage, useLocalStorageReducer, useOptionallyElevatedState, useOverflowItems, usePopoverContext, usePrevious, usePrompt, useResize, useScrollDetection, useSelfUpdatingRef, useTimeout,
|
|
4975
|
+
export { Alert, Badge, Breadcrumb, BreadcrumbContainer, Button, Card, CardBody, CardFooter, CardHeader, Collapse, CompletionStatusIndicator, CopyableText, EmptyState, EmptyValue, ExternalLink, Heading, Icon, IconButton, Indicator, KPICard, MenuDivider, MenuItem, MenuList, MoreMenu, Notice, PackageNameStoryComponent, Page, PageContent, PageHeader, Pagination, Polygon, Popover, PopoverContent, PopoverTitle, PopoverTrigger, Portal, Prompt, ROLE_CARD, SectionHeader, Sidebar, SkeletonLines, Spacer, Spinner, StarButton, Tab, TabContent, TabList, Tabs, Tag, Text, Timeline, TimelineElement, ToggleGroup, ToggleItem, Tooltip, ValueBar, VirtualizedList, WidgetBody, cvaButton, cvaButtonPrefixSuffix, cvaButtonSpinner, cvaButtonSpinnerContainer, cvaClickable, cvaIconButton, cvaIndicator, cvaIndicatorIcon, cvaIndicatorIconBackground, cvaIndicatorLabel, cvaIndicatorPing, cvaInteractableItem, cvaMenuItem, cvaMenuItemLabel, cvaMenuItemPrefix, cvaMenuItemStyle, cvaMenuItemSuffix, docs, getDevicePixelRatio, getValueBarColorByValue, iconColorNames, iconPalette, setLocalStorage, useClickOutside, useContainerBreakpoints, useContinuousTimeout, useDebounce, useDevicePixelRatio, useGeometry, useHover, useIsFirstRender, useIsFullscreen, useIsTextCutOff, useLocalStorage, useLocalStorageReducer, useOptionallyElevatedState, useOverflowItems, usePopoverContext, usePrevious, usePrompt, useResize, useScrollDetection, useSelfUpdatingRef, useTimeout, useViewportBreakpoints, useWindowActivity };
|
package/package.json
CHANGED
|
@@ -26,6 +26,12 @@ export interface CollapseProps extends CommonProps {
|
|
|
26
26
|
* An addon to add to the header. This can be used for a status indicator or similar.
|
|
27
27
|
*/
|
|
28
28
|
headerAddon?: React.ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* Without animation children wont be rendered until expanded, which improves performance
|
|
31
|
+
* for high volume data
|
|
32
|
+
*/
|
|
33
|
+
animate?: boolean;
|
|
34
|
+
extraPadding?: boolean;
|
|
29
35
|
}
|
|
30
36
|
/**
|
|
31
37
|
* The Collapse component is a container for additional information that adds context to various flows. It is used for displaying non-essential information that can be hidden away.
|
|
@@ -44,4 +50,4 @@ export interface CollapseProps extends CommonProps {
|
|
|
44
50
|
* @param {CollapseProps} props - The props for the Collapse component
|
|
45
51
|
* @returns {JSX.Element} Collapse component
|
|
46
52
|
*/
|
|
47
|
-
export declare const Collapse: ({ id, initialExpanded, onToggle, label, children, className, headerClassName, headerAddon, dataTestId, }: CollapseProps) => import("react/jsx-runtime").JSX.Element;
|
|
53
|
+
export declare const Collapse: ({ id, initialExpanded, onToggle, label, children, className, headerClassName, headerAddon, dataTestId, animate, extraPadding, }: CollapseProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,7 +3,9 @@ export declare const cvaCollapseHeader: (props?: ({
|
|
|
3
3
|
expanded?: boolean | null | undefined;
|
|
4
4
|
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
5
5
|
export declare const cvaCollapseLabelContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
6
|
-
export declare const cvaCollapsible: (props?:
|
|
6
|
+
export declare const cvaCollapsible: (props?: ({
|
|
7
|
+
extraPadding?: boolean | null | undefined;
|
|
8
|
+
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
7
9
|
export declare const cvaCollapseAnimated: (props?: ({
|
|
8
10
|
expanded?: boolean | null | undefined;
|
|
9
11
|
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
@@ -5,7 +5,7 @@ export type PopoverActivation = {
|
|
|
5
5
|
hover?: boolean;
|
|
6
6
|
keyboardHandlers?: boolean;
|
|
7
7
|
};
|
|
8
|
-
export type PopoverDismissal = Pick<UseDismissProps, "ancestorScroll" | "enabled" | "outsidePress"
|
|
8
|
+
export type PopoverDismissal = Pick<UseDismissProps, "ancestorScroll" | "enabled" | "outsidePress">;
|
|
9
9
|
export type PopoverPlacement = "top" | "right" | "bottom" | "left" | "top-start" | "top-end" | "right-start" | "right-end" | "bottom-start" | "bottom-end" | "left-start" | "left-end";
|
|
10
10
|
export type Strategy = "absolute" | "fixed";
|
|
11
11
|
export interface PopoverProps extends CommonProps {
|
|
@@ -32,7 +32,7 @@ export interface PopoverProps extends CommonProps {
|
|
|
32
32
|
/**
|
|
33
33
|
* Options for dismissal of the popover
|
|
34
34
|
*/
|
|
35
|
-
dismissal?: PopoverDismissal;
|
|
35
|
+
dismissal?: PopoverDismissal | ((defaultDismissal: PopoverDismissal) => PopoverDismissal);
|
|
36
36
|
/**
|
|
37
37
|
* Callback to be called when the popover open state changes
|
|
38
38
|
*/
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { FloatingPortalProps } from "@floating-ui/react";
|
|
2
|
+
export type PortalProps = FloatingPortalProps;
|
|
3
|
+
/**
|
|
4
|
+
* Portals the floating element into a given container element
|
|
5
|
+
* By default they're portalled into an z-index isolated div in
|
|
6
|
+
* document body -> div#portal-container.
|
|
7
|
+
* alongside other portalled elements.
|
|
8
|
+
*/
|
|
9
|
+
export declare const Portal: (props: FloatingPortalProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { UseFloatingPortalNodeProps } from "@floating-ui/react";
|
|
2
|
+
/** @internal */
|
|
3
|
+
export declare const PORTAL_CONTAINER = "portal-container";
|
|
4
|
+
/**
|
|
5
|
+
* Creates or retrieves the default portal container element
|
|
6
|
+
*
|
|
7
|
+
* @internal
|
|
8
|
+
*/
|
|
9
|
+
export declare const getDefaultPortalContainer: () => HTMLElement;
|
|
10
|
+
/**
|
|
11
|
+
* Hook that creates or retrieves a portal node for floating UI components
|
|
12
|
+
*
|
|
13
|
+
* @param props - The portal node props
|
|
14
|
+
* @param props.root - The root element to attach the portal to
|
|
15
|
+
* @param props.id - The ID for the portal node
|
|
16
|
+
* @returns {HTMLElement | null} The portal node props
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export declare const usePortalNode: (props?: UseFloatingPortalNodeProps) => HTMLElement | null;
|
|
@@ -21,6 +21,7 @@ export * from "./Pagination/Pagination";
|
|
|
21
21
|
export * from "./Polygon/Polygon";
|
|
22
22
|
export * from "./Popover";
|
|
23
23
|
export * from "./Popover/Popover";
|
|
24
|
+
export * from "./Portal/Portal";
|
|
24
25
|
export * from "./Prompt";
|
|
25
26
|
export * from "./SectionHeader";
|
|
26
27
|
export * from "./Sidebar/Sidebar";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { themeScreenSizeAsNumber } from "@trackunit/ui-design-tokens";
|
|
2
|
+
export type BreakpointSize = keyof typeof themeScreenSizeAsNumber;
|
|
3
|
+
/**
|
|
4
|
+
* Represents the state of sizes as boolean values.
|
|
5
|
+
* Each property is true if the width is greater than or equal to the corresponding breakpoint.
|
|
6
|
+
*/
|
|
7
|
+
export type BreakpointState = {
|
|
8
|
+
[K in BreakpointSize as `is${Capitalize<K>}`]: boolean;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Maps size keys to their corresponding state property names.
|
|
12
|
+
*/
|
|
13
|
+
export declare const breakpointPropsMap: Record<BreakpointSize, keyof BreakpointState>;
|
|
14
|
+
/**
|
|
15
|
+
* The default state for sizes, with all values set to false.
|
|
16
|
+
*/
|
|
17
|
+
export declare const defaultBreakpointState: BreakpointState;
|
|
18
|
+
/**
|
|
19
|
+
* Creates a breakpoint state object based on a width value
|
|
20
|
+
*/
|
|
21
|
+
export declare const createBreakpointState: ({ width }: {
|
|
22
|
+
width: number;
|
|
23
|
+
}) => BreakpointState;
|
package/src/hooks/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ export * from "./localStorage/setLocalStorage";
|
|
|
2
2
|
export * from "./localStorage/useLocalStorage";
|
|
3
3
|
export * from "./localStorage/useLocalStorageReducer";
|
|
4
4
|
export * from "./useClickOutside";
|
|
5
|
+
export * from "./useContainerBreakpoints";
|
|
5
6
|
export * from "./useContinuousTimeout";
|
|
6
7
|
export * from "./useDebounce";
|
|
7
8
|
export * from "./useDevicePixelRatio";
|
|
@@ -16,5 +17,5 @@ export * from "./useResize";
|
|
|
16
17
|
export * from "./useScrollDetection";
|
|
17
18
|
export * from "./useSelfUpdatingRef";
|
|
18
19
|
export * from "./useTimeout";
|
|
19
|
-
export * from "./
|
|
20
|
+
export * from "./useViewportBreakpoints";
|
|
20
21
|
export * from "./useWindowActivity";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type RefObject } from "react";
|
|
2
|
+
import { type BreakpointState } from "./breakpoint-utils";
|
|
3
|
+
/**
|
|
4
|
+
* A custom React hook that provides real-time information about a container's size.
|
|
5
|
+
*
|
|
6
|
+
* This hook uses ResizeObserver to monitor changes in the container's width and returns
|
|
7
|
+
* an object with boolean values indicating which breakpoints are currently active.
|
|
8
|
+
*
|
|
9
|
+
* @param {RefObject<HTMLElement>} ref - Reference to the container element to observe
|
|
10
|
+
* @returns {BreakpointState} An object containing boolean values for each container size breakpoint.
|
|
11
|
+
* @example
|
|
12
|
+
* const MyComponent = () => {
|
|
13
|
+
* const containerRef = useRef<HTMLDivElement>(null);
|
|
14
|
+
* const containerSize = useContainerBreakpoints(containerRef);
|
|
15
|
+
*
|
|
16
|
+
* return (
|
|
17
|
+
* <div ref={containerRef}>
|
|
18
|
+
* {containerSize.isLg ? (
|
|
19
|
+
* <LargeLayout />
|
|
20
|
+
* ) : containerSize.isMd ? (
|
|
21
|
+
* <MediumLayout />
|
|
22
|
+
* ) : (
|
|
23
|
+
* <SmallLayout />
|
|
24
|
+
* )}
|
|
25
|
+
* </div>
|
|
26
|
+
* );
|
|
27
|
+
* }
|
|
28
|
+
*/
|
|
29
|
+
export declare const useContainerBreakpoints: (ref: RefObject<HTMLElement>) => BreakpointState;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type BreakpointState } from "./breakpoint-utils";
|
|
2
|
+
/**
|
|
3
|
+
* A custom React hook that provides real-time information about the current viewport size.
|
|
4
|
+
* ! Consider using `useContainerBreakpoints` instead, and only use this when you need to actually react to the viewport size, not the container size.
|
|
5
|
+
*
|
|
6
|
+
* This hook listens to changes in the viewport size and returns an object with boolean values
|
|
7
|
+
* indicating which breakpoints are currently active.
|
|
8
|
+
*
|
|
9
|
+
* @returns {BreakpointState} An object containing boolean values for each viewport size breakpoint.
|
|
10
|
+
* @example
|
|
11
|
+
* const MyComponent = () => {
|
|
12
|
+
* const viewportSize = useViewportBreakpoints();
|
|
13
|
+
*
|
|
14
|
+
* if (viewportSize.isLg) {
|
|
15
|
+
* return <LargeScreenLayout />;
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* return viewportSize.isMd ? <MediumScreenLayout /> : <SmallLayout />;
|
|
19
|
+
* }
|
|
20
|
+
*/
|
|
21
|
+
export declare const useViewportBreakpoints: () => BreakpointState;
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { themeScreenSizeAsNumber } from "@trackunit/ui-design-tokens";
|
|
2
|
-
type ViewportSize = keyof typeof themeScreenSizeAsNumber;
|
|
3
|
-
/**
|
|
4
|
-
* Represents the state of viewport sizes as boolean values.
|
|
5
|
-
* Each property is true if the viewport width is greater than or equal to the corresponding breakpoint.
|
|
6
|
-
*/
|
|
7
|
-
type ViewportSizeState = {
|
|
8
|
-
[K in ViewportSize as `is${Capitalize<K>}`]: boolean;
|
|
9
|
-
};
|
|
10
|
-
/**
|
|
11
|
-
* A custom React hook that provides real-time information about the current viewport size.
|
|
12
|
-
*
|
|
13
|
-
* This hook listens to changes in the viewport size and returns an object with boolean values
|
|
14
|
-
* indicating which breakpoints are currently active. It's useful for creating responsive
|
|
15
|
-
* layouts and components that need to adapt to different screen sizes.
|
|
16
|
-
*
|
|
17
|
-
* @returns {ViewportSizeState} An object containing boolean values for each viewport size breakpoint.
|
|
18
|
-
* @example
|
|
19
|
-
* function MyComponent() {
|
|
20
|
-
* const viewportSize = useViewportSize();
|
|
21
|
-
*
|
|
22
|
-
* if (viewportSize.isLg) {
|
|
23
|
-
* return <LargeScreenLayout />;
|
|
24
|
-
* } else if (viewportSize.isMd) {
|
|
25
|
-
* return <MediumScreenLayout />;
|
|
26
|
-
* } else {
|
|
27
|
-
* return <SmallScreenLayout />;
|
|
28
|
-
* }
|
|
29
|
-
* }
|
|
30
|
-
*/
|
|
31
|
-
export declare const useViewportSize: () => ViewportSizeState;
|
|
32
|
-
export {};
|