@trackunit/react-components 0.4.33 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs.js +179 -376
- package/index.esm.js +179 -376
- package/package.json +1 -2
- package/src/components/Menu/MenuDivider/MenuDivider.d.ts +4 -0
- package/src/components/Menu/MenuItem/MenuItem.d.ts +12 -2
- package/src/components/Menu/MenuItem/MenuItem.variants.d.ts +18 -5
- package/src/components/Menu/MenuList/MenuList.d.ts +22 -11
- package/src/components/Menu/MenuList/MenuList.variants.d.ts +2 -0
- package/src/components/Menu/index.d.ts +1 -0
- package/src/components/index.d.ts +0 -2
- package/src/components/Drawer/Drawer.d.ts +0 -37
- package/src/components/Drawer/Drawer.variants.d.ts +0 -20
- package/src/components/Drawer/Overlay.d.ts +0 -14
- package/src/components/Drawer/ToogleButton.d.ts +0 -19
- package/src/components/Drawer/index.d.ts +0 -1
package/index.esm.js
CHANGED
|
@@ -14,7 +14,6 @@ import { Slottable, Slot } from '@radix-ui/react-slot';
|
|
|
14
14
|
import isEqual from 'lodash/isEqual';
|
|
15
15
|
import { Link, useBlocker } from '@tanstack/react-router';
|
|
16
16
|
import { useCopyToClipboard } from 'usehooks-ts';
|
|
17
|
-
import { useSwipeable } from 'react-swipeable';
|
|
18
17
|
import { useFloating, autoUpdate, offset, flip, shift, size, useClick, useDismiss, useHover as useHover$1, useRole, useInteractions, useMergeRefs, FloatingPortal, FloatingFocusManager, arrow, useTransitionStatus, FloatingArrow } from '@floating-ui/react';
|
|
19
18
|
import omit from 'lodash/omit';
|
|
20
19
|
import { twMerge } from 'tailwind-merge';
|
|
@@ -1861,331 +1860,6 @@ const CopyableText = ({ text, alternativeText, dataTestId, className }) => {
|
|
|
1861
1860
|
return (jsx("span", { className: cvaCopyableText({ animating, className }), "data-testid": dataTestId, onAnimationEnd: () => setAnimating(false), onClick: handleOnClick, title: value, children: text }));
|
|
1862
1861
|
};
|
|
1863
1862
|
|
|
1864
|
-
const cvaDialog = cvaMerge([
|
|
1865
|
-
"z-toast",
|
|
1866
|
-
"pointer-events-auto",
|
|
1867
|
-
"absolute",
|
|
1868
|
-
"transform",
|
|
1869
|
-
"flex-col",
|
|
1870
|
-
"bg-neutral-50",
|
|
1871
|
-
"transition-transform",
|
|
1872
|
-
"duration-300",
|
|
1873
|
-
"ease-in-out",
|
|
1874
|
-
"shadow-lg",
|
|
1875
|
-
], {
|
|
1876
|
-
variants: {
|
|
1877
|
-
position: {
|
|
1878
|
-
left: "left-0 top-0 h-full w-fit rounded-r-lg",
|
|
1879
|
-
right: "right-0 top-0 h-full w-fit rounded-l-lg",
|
|
1880
|
-
top: "left-0 top-0 h-fit w-full rounded-b-lg",
|
|
1881
|
-
bottom: "bottom-0 left-0 right-0 h-fit w-full rounded-t-lg",
|
|
1882
|
-
},
|
|
1883
|
-
sidebarMode: {
|
|
1884
|
-
"semi-closed": "translate-y-[calc(100%-2.2rem)]",
|
|
1885
|
-
"1/3": "translate-y-2/3",
|
|
1886
|
-
"2/3": "translate-y-1/3",
|
|
1887
|
-
full: "translate-y-0",
|
|
1888
|
-
"semi-full": "translate-y-5",
|
|
1889
|
-
closed: "translate-y-full",
|
|
1890
|
-
},
|
|
1891
|
-
isLargeScreen: {
|
|
1892
|
-
true: "",
|
|
1893
|
-
false: "bottom-0 left-0 right-0 h-full w-full rounded-t-lg",
|
|
1894
|
-
},
|
|
1895
|
-
open: {
|
|
1896
|
-
true: "",
|
|
1897
|
-
false: "",
|
|
1898
|
-
},
|
|
1899
|
-
},
|
|
1900
|
-
compoundVariants: [
|
|
1901
|
-
{
|
|
1902
|
-
isLargeScreen: false,
|
|
1903
|
-
open: false,
|
|
1904
|
-
className: "translate-y-full",
|
|
1905
|
-
},
|
|
1906
|
-
{
|
|
1907
|
-
isLargeScreen: true,
|
|
1908
|
-
open: true,
|
|
1909
|
-
position: "left",
|
|
1910
|
-
className: "translate-x-0",
|
|
1911
|
-
},
|
|
1912
|
-
{
|
|
1913
|
-
isLargeScreen: true,
|
|
1914
|
-
open: false,
|
|
1915
|
-
position: "left",
|
|
1916
|
-
className: "-translate-x-full",
|
|
1917
|
-
},
|
|
1918
|
-
{
|
|
1919
|
-
isLargeScreen: true,
|
|
1920
|
-
open: true,
|
|
1921
|
-
position: "right",
|
|
1922
|
-
className: "translate-x-0",
|
|
1923
|
-
},
|
|
1924
|
-
{
|
|
1925
|
-
isLargeScreen: true,
|
|
1926
|
-
open: false,
|
|
1927
|
-
position: "right",
|
|
1928
|
-
className: "translate-x-full",
|
|
1929
|
-
},
|
|
1930
|
-
{
|
|
1931
|
-
isLargeScreen: true,
|
|
1932
|
-
open: true,
|
|
1933
|
-
position: "top",
|
|
1934
|
-
className: "translate-y-0",
|
|
1935
|
-
},
|
|
1936
|
-
{
|
|
1937
|
-
isLargeScreen: true,
|
|
1938
|
-
open: false,
|
|
1939
|
-
position: "top",
|
|
1940
|
-
className: "-translate-y-full",
|
|
1941
|
-
},
|
|
1942
|
-
{
|
|
1943
|
-
isLargeScreen: true,
|
|
1944
|
-
open: true,
|
|
1945
|
-
position: "bottom",
|
|
1946
|
-
className: "translate-y-0",
|
|
1947
|
-
},
|
|
1948
|
-
{
|
|
1949
|
-
isLargeScreen: true,
|
|
1950
|
-
open: false,
|
|
1951
|
-
position: "bottom",
|
|
1952
|
-
className: "translate-y-full",
|
|
1953
|
-
},
|
|
1954
|
-
],
|
|
1955
|
-
});
|
|
1956
|
-
const cvaDialogContainer = cvaMerge(["flex", "flex-col", "overflow-hidden", "rounded-[inherit]"], {
|
|
1957
|
-
variants: {
|
|
1958
|
-
sidebarMode: {
|
|
1959
|
-
"semi-closed": "h-auto",
|
|
1960
|
-
"1/3": "h-[34%]",
|
|
1961
|
-
"2/3": "h-[67%]",
|
|
1962
|
-
"semi-full": "h-[calc(100%-1.25rem)]",
|
|
1963
|
-
full: "h-full",
|
|
1964
|
-
closed: "h-auto",
|
|
1965
|
-
},
|
|
1966
|
-
},
|
|
1967
|
-
});
|
|
1968
|
-
const cvaSwipeContainer = cvaMerge(["my-4", "flex", "items-center", "justify-center", "lg:hidden"]);
|
|
1969
|
-
const cvaSwipeIcon = cvaMerge(["block", "h-1", "w-10", "rounded-full", "bg-gray-400"]);
|
|
1970
|
-
const cvaToogleContainer = cvaMerge(["z-8", "absolute"], {
|
|
1971
|
-
variants: {
|
|
1972
|
-
position: {
|
|
1973
|
-
left: "right-[-24px] top-[calc(50%-24px)]",
|
|
1974
|
-
right: "left-[-24px] top-[calc(50%-24px)]",
|
|
1975
|
-
top: "bottom-[-24px] left-[calc(50%-24px)]",
|
|
1976
|
-
bottom: "left-[calc(50%-24px)] top-[-24px]",
|
|
1977
|
-
},
|
|
1978
|
-
},
|
|
1979
|
-
defaultVariants: {
|
|
1980
|
-
position: "left",
|
|
1981
|
-
},
|
|
1982
|
-
});
|
|
1983
|
-
const cvaToogleButton = cvaMerge([
|
|
1984
|
-
"flex",
|
|
1985
|
-
"cursor-pointer",
|
|
1986
|
-
"items-center",
|
|
1987
|
-
"justify-center",
|
|
1988
|
-
"border-gray-300",
|
|
1989
|
-
"bg-neutral-50",
|
|
1990
|
-
"bg-center",
|
|
1991
|
-
"bg-no-repeat",
|
|
1992
|
-
"shadow-md",
|
|
1993
|
-
], {
|
|
1994
|
-
variants: {
|
|
1995
|
-
position: {
|
|
1996
|
-
left: "h-12 w-6 rounded-r-lg",
|
|
1997
|
-
right: "h-12 w-6 rounded-l-lg",
|
|
1998
|
-
top: "h-6 w-12 rounded-b-lg",
|
|
1999
|
-
bottom: "h-6 w-12 rounded-t-lg",
|
|
2000
|
-
},
|
|
2001
|
-
},
|
|
2002
|
-
defaultVariants: {
|
|
2003
|
-
position: "left",
|
|
2004
|
-
},
|
|
2005
|
-
});
|
|
2006
|
-
const cvaOverlayContainer = cvaMerge([
|
|
2007
|
-
"absolute",
|
|
2008
|
-
"flex",
|
|
2009
|
-
"items-center",
|
|
2010
|
-
"justify-center",
|
|
2011
|
-
"inset-0",
|
|
2012
|
-
"bg-black/30",
|
|
2013
|
-
"bg-opacity-50",
|
|
2014
|
-
"transition-opacity",
|
|
2015
|
-
"duration-200",
|
|
2016
|
-
"ease-in-out",
|
|
2017
|
-
"opacity-100",
|
|
2018
|
-
], {
|
|
2019
|
-
variants: {
|
|
2020
|
-
open: {
|
|
2021
|
-
true: "opacity-1 z-popover",
|
|
2022
|
-
false: "z-[-1] opacity-0",
|
|
2023
|
-
},
|
|
2024
|
-
},
|
|
2025
|
-
});
|
|
2026
|
-
|
|
2027
|
-
/**
|
|
2028
|
-
* Overlay Component
|
|
2029
|
-
*
|
|
2030
|
-
* @param {object} props - The Overlay component properties
|
|
2031
|
-
* @param {boolean} props.open - Open status of the Overlay
|
|
2032
|
-
* @param {Function} props.onClose - Callback function when Overlay is closed
|
|
2033
|
-
* @returns {JSX.Element|null} The Overlay component
|
|
2034
|
-
*/
|
|
2035
|
-
const Overlay = ({ open, onClose }) => {
|
|
2036
|
-
useEffect(() => {
|
|
2037
|
-
if (!onClose) {
|
|
2038
|
-
return;
|
|
2039
|
-
}
|
|
2040
|
-
const handleEscape = (event) => {
|
|
2041
|
-
if (event.key === "Escape") {
|
|
2042
|
-
onClose(event);
|
|
2043
|
-
}
|
|
2044
|
-
};
|
|
2045
|
-
if (open) {
|
|
2046
|
-
window.addEventListener("keyup", handleEscape);
|
|
2047
|
-
}
|
|
2048
|
-
return () => {
|
|
2049
|
-
window.removeEventListener("keyup", handleEscape);
|
|
2050
|
-
};
|
|
2051
|
-
}, [open, onClose]);
|
|
2052
|
-
const handleClick = (event) => {
|
|
2053
|
-
if (onClose) {
|
|
2054
|
-
onClose(event);
|
|
2055
|
-
}
|
|
2056
|
-
};
|
|
2057
|
-
return (jsx("div", { "aria-hidden": open, className: cvaOverlayContainer({ open }), "data-testid": "sidebar-overlay", onClick: handleClick }));
|
|
2058
|
-
};
|
|
2059
|
-
|
|
2060
|
-
const getIconName = (open, position) => {
|
|
2061
|
-
switch (position) {
|
|
2062
|
-
case "left":
|
|
2063
|
-
return open ? "ChevronLeft" : "ChevronRight";
|
|
2064
|
-
case "right":
|
|
2065
|
-
return open ? "ChevronRight" : "ChevronLeft";
|
|
2066
|
-
case "top":
|
|
2067
|
-
return open ? "ChevronUp" : "ChevronDown";
|
|
2068
|
-
case "bottom":
|
|
2069
|
-
return open ? "ChevronDown" : "ChevronUp";
|
|
2070
|
-
default:
|
|
2071
|
-
return open ? "ChevronLeft" : "ChevronRight";
|
|
2072
|
-
}
|
|
2073
|
-
};
|
|
2074
|
-
/**
|
|
2075
|
-
* ToggleButton is a React functional component that returns a button with a chevron icon.
|
|
2076
|
-
* The direction of the chevron changes depending on the state of the 'open' prop and
|
|
2077
|
-
* the side the button is positioned ('position' prop).
|
|
2078
|
-
* The button might be disabled based on the 'disableButton' prop.
|
|
2079
|
-
*
|
|
2080
|
-
* @param {object} props - The properties passed to the component
|
|
2081
|
-
* @param {boolean} props.open - Indicates if the button is in "open" state
|
|
2082
|
-
* @param {Function} [props.onToggle] - Optional callback function for when the button is clicked
|
|
2083
|
-
* @param {Position} props.position - The position of the button relative to its container
|
|
2084
|
-
*/
|
|
2085
|
-
const ToogleButton = ({ open, position, onToggle }) => {
|
|
2086
|
-
const name = getIconName(open, position);
|
|
2087
|
-
return (jsx("div", { className: cvaToogleContainer({ position }), children: jsx("button", { className: cvaToogleButton({ position }), "data-testid": "toggle-button", onClick: onToggle, children: jsx(Icon, { name: name }) }) }));
|
|
2088
|
-
};
|
|
2089
|
-
|
|
2090
|
-
/**
|
|
2091
|
-
* MapSidebar is a sidebar component used with Maps.
|
|
2092
|
-
* It provides a slide over sidebar drawer which can be used for displaying map related information or controls.
|
|
2093
|
-
*
|
|
2094
|
-
* @param {DrawerProps} props - The props for the MapSidebar component
|
|
2095
|
-
* @returns {JSX.Element | null} Drawer component
|
|
2096
|
-
*/
|
|
2097
|
-
const Drawer = ({ open = true, onToggle, onClose, disableOverlay, position = "left", children, dataTestId, className, dialogClassName, }) => {
|
|
2098
|
-
const { width } = useResize();
|
|
2099
|
-
const isLargeScreen = width >= 1024;
|
|
2100
|
-
const initialSidebarMode = () => {
|
|
2101
|
-
if (!open) {
|
|
2102
|
-
return "closed";
|
|
2103
|
-
}
|
|
2104
|
-
return isLargeScreen ? "full" : "2/3";
|
|
2105
|
-
};
|
|
2106
|
-
const [sidebarMode, setSidebarMode] = useState(initialSidebarMode);
|
|
2107
|
-
const [isVisible, setIsVisible] = useState(open);
|
|
2108
|
-
const [isAnimationStart, setStartAnimation] = useState(open);
|
|
2109
|
-
useEffect(() => {
|
|
2110
|
-
if (!isLargeScreen && open) {
|
|
2111
|
-
setSidebarMode("2/3");
|
|
2112
|
-
}
|
|
2113
|
-
if (onToggle) {
|
|
2114
|
-
setStartAnimation(open);
|
|
2115
|
-
return;
|
|
2116
|
-
}
|
|
2117
|
-
manageVisibilityAndAnimation(open);
|
|
2118
|
-
}, [onToggle, isLargeScreen, open]);
|
|
2119
|
-
const manageVisibilityAndAnimation = (isOpen) => {
|
|
2120
|
-
if (!isOpen) {
|
|
2121
|
-
setStartAnimation(false);
|
|
2122
|
-
return;
|
|
2123
|
-
}
|
|
2124
|
-
setIsVisible(true);
|
|
2125
|
-
setTimeout(() => {
|
|
2126
|
-
setStartAnimation(true);
|
|
2127
|
-
}, 150);
|
|
2128
|
-
};
|
|
2129
|
-
const handlers = useSwipeable({
|
|
2130
|
-
onSwipedUp: () => !isLargeScreen && handleSwipedUp(),
|
|
2131
|
-
onSwipedDown: () => !isLargeScreen && handleSwipedDown(),
|
|
2132
|
-
trackMouse: true,
|
|
2133
|
-
});
|
|
2134
|
-
const handleSwipedUp = () => {
|
|
2135
|
-
setSidebarMode(prev => {
|
|
2136
|
-
switch (prev) {
|
|
2137
|
-
case "semi-closed":
|
|
2138
|
-
return "1/3";
|
|
2139
|
-
case "1/3":
|
|
2140
|
-
return "2/3";
|
|
2141
|
-
case "2/3":
|
|
2142
|
-
return "semi-full";
|
|
2143
|
-
default:
|
|
2144
|
-
return prev;
|
|
2145
|
-
}
|
|
2146
|
-
});
|
|
2147
|
-
};
|
|
2148
|
-
const handleSwipedDown = () => {
|
|
2149
|
-
setSidebarMode(prev => {
|
|
2150
|
-
switch (prev) {
|
|
2151
|
-
case "semi-full":
|
|
2152
|
-
return "2/3";
|
|
2153
|
-
case "2/3":
|
|
2154
|
-
return "1/3";
|
|
2155
|
-
case "1/3":
|
|
2156
|
-
return onClose ? "closed" : "semi-closed";
|
|
2157
|
-
default:
|
|
2158
|
-
return prev;
|
|
2159
|
-
}
|
|
2160
|
-
});
|
|
2161
|
-
/*
|
|
2162
|
-
* Within a mobile device context, when swiping down,
|
|
2163
|
-
* if the Drawer is open a third and no onToggle function is provided,
|
|
2164
|
-
* the Drawer will automatically be closed using the onClose function.
|
|
2165
|
-
*/
|
|
2166
|
-
if (sidebarMode === "1/3" && !onToggle && onClose) {
|
|
2167
|
-
onClose();
|
|
2168
|
-
}
|
|
2169
|
-
};
|
|
2170
|
-
const handleAnimationEnd = () => {
|
|
2171
|
-
if (!open && !onToggle) {
|
|
2172
|
-
setIsVisible(false);
|
|
2173
|
-
}
|
|
2174
|
-
};
|
|
2175
|
-
if (!isVisible && !onToggle) {
|
|
2176
|
-
return null;
|
|
2177
|
-
}
|
|
2178
|
-
return (jsxs("div", { className: className, "data-testid": dataTestId, children: [!disableOverlay ? jsx(Overlay, { onClose: onClose, open: isAnimationStart }) : null, jsxs("div", { ...handlers, className: cvaDialog({
|
|
2179
|
-
sidebarMode: isLargeScreen ? null : sidebarMode,
|
|
2180
|
-
isLargeScreen,
|
|
2181
|
-
open: isAnimationStart,
|
|
2182
|
-
position: isLargeScreen ? position : undefined,
|
|
2183
|
-
className: dialogClassName,
|
|
2184
|
-
}), "data-testid": dataTestId ? `${dataTestId}-container` : undefined, onTransitionEnd: handleAnimationEnd, children: [isLargeScreen && onToggle ? jsx(ToogleButton, { onToggle: onToggle, open: open, position: position }) : null, jsxs("div", { className: cvaDialogContainer({
|
|
2185
|
-
sidebarMode: isLargeScreen ? "full" : sidebarMode,
|
|
2186
|
-
}), children: [jsx("div", { className: cvaSwipeContainer(), children: jsx("div", { className: cvaSwipeIcon() }) }), children] })] })] }));
|
|
2187
|
-
};
|
|
2188
|
-
|
|
2189
1863
|
const cvaSkeletonLine = cvaMerge([
|
|
2190
1864
|
"rounded-md",
|
|
2191
1865
|
"h-3",
|
|
@@ -3719,7 +3393,7 @@ const PopoverContent = React__default.forwardRef(function PopoverContent({ class
|
|
|
3719
3393
|
var _a;
|
|
3720
3394
|
const { context: floatingContext, customProps, ...context } = usePopoverContext();
|
|
3721
3395
|
const ref = useMergeRefs([context.refs.setFloating, propRef]);
|
|
3722
|
-
return (jsx(FloatingPortal, { id: portalId !== null && portalId !== void 0 ? portalId : "tu-floating-ui", children: context.isOpen ? (jsx(FloatingFocusManager, { closeOnFocusOut: false, context: floatingContext, guards:
|
|
3396
|
+
return (jsx(FloatingPortal, { id: portalId !== null && portalId !== void 0 ? portalId : "tu-floating-ui", 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: {
|
|
3723
3397
|
position: context.strategy,
|
|
3724
3398
|
top: context.y,
|
|
3725
3399
|
left: context.x,
|
|
@@ -4016,6 +3690,36 @@ const KPICard = ({ asChild = false, title, value, loading, unit, iconName, iconB
|
|
|
4016
3690
|
return (jsxs(Comp, { className: cvaKPICardContainer({ className, isClickable: Boolean(asChild || onClick) }), "data-testid": `${dataTestId}-comp`, onClick: onClick, ...rest, children: [tooltipLabel ? (jsx(Tooltip, { className: "w-full", label: tooltipLabel, placement: "bottom", children: jsx(CardContent, {}) })) : (jsx(CardContent, {})), !loading && jsx(Slottable, { children: rest.children })] }));
|
|
4017
3691
|
};
|
|
4018
3692
|
|
|
3693
|
+
const cvaMenuList = cvaMerge([
|
|
3694
|
+
"shadow",
|
|
3695
|
+
"rounded-lg",
|
|
3696
|
+
"z-popover",
|
|
3697
|
+
"bg-white",
|
|
3698
|
+
"border",
|
|
3699
|
+
"border-slate-300",
|
|
3700
|
+
"grid",
|
|
3701
|
+
"min-w-[200px]",
|
|
3702
|
+
"max-w-[300px]",
|
|
3703
|
+
"p-1",
|
|
3704
|
+
], {
|
|
3705
|
+
variants: {
|
|
3706
|
+
stickyHeader: {
|
|
3707
|
+
true: "grid-rows-min-fr grid overflow-y-hidden",
|
|
3708
|
+
false: "",
|
|
3709
|
+
},
|
|
3710
|
+
},
|
|
3711
|
+
});
|
|
3712
|
+
const cvaMenuListDivider = cvaMerge(["mx-[-4px]", "my-1", "min-h-px", "bg-slate-300"]);
|
|
3713
|
+
const cvaMenuListMultiSelect = cvaMerge("hover:!bg-blue-200");
|
|
3714
|
+
const cvaMenuListItem = cvaMerge("max-w-[290px]");
|
|
3715
|
+
|
|
3716
|
+
/**
|
|
3717
|
+
* The MenuDivider component is used to separate items in a menu list.
|
|
3718
|
+
*/
|
|
3719
|
+
const MenuDivider = () => {
|
|
3720
|
+
return jsx("div", { className: cvaMenuListDivider(), "data-testid": "menu-divider" });
|
|
3721
|
+
};
|
|
3722
|
+
|
|
4019
3723
|
/**
|
|
4020
3724
|
* Applies standardized interaction-related styles to an element.
|
|
4021
3725
|
*
|
|
@@ -4068,45 +3772,108 @@ const cvaInteractableItem = cvaMerge("", {
|
|
|
4068
3772
|
},
|
|
4069
3773
|
});
|
|
4070
3774
|
|
|
4071
|
-
|
|
3775
|
+
/**
|
|
3776
|
+
* Extends the cvaInteractableItem variant in order to set the padding, width, height, cursor, and other styles particular to the MenuItem component.
|
|
3777
|
+
* The cvaInteractableItem variant is used to set the standardized styles that change through interaction with the element (background color, hover, focus, and disabled).
|
|
3778
|
+
*/
|
|
3779
|
+
const cvaMenuItem = (props) => {
|
|
3780
|
+
const { size, selected, disabled, focused, className, variant } = props !== null && props !== void 0 ? props : {};
|
|
3781
|
+
return twMerge(cvaMenuItemStyle({ size, variant, selected, disabled }), cvaInteractableItem({ selected, disabled, cursor: "pointer", focused }), className);
|
|
3782
|
+
};
|
|
3783
|
+
const cvaMenuItemStyle = cvaMerge(["py-2", "px-2", "h-auto", "flex", "flex-row", "items-center", "gap-x-2", "select-none", "rounded", "text-sm"], {
|
|
4072
3784
|
variants: {
|
|
4073
3785
|
size: {
|
|
4074
3786
|
small: "py-1",
|
|
4075
3787
|
medium: "py-2",
|
|
4076
3788
|
},
|
|
3789
|
+
variant: {
|
|
3790
|
+
primary: [],
|
|
3791
|
+
danger: [
|
|
3792
|
+
"text-danger-600",
|
|
3793
|
+
"hover:!bg-danger-100",
|
|
3794
|
+
"focus:!bg-danger-200",
|
|
3795
|
+
"hover:!text-danger-700",
|
|
3796
|
+
"focus:!text-danger-800",
|
|
3797
|
+
],
|
|
3798
|
+
},
|
|
3799
|
+
selected: {
|
|
3800
|
+
true: "",
|
|
3801
|
+
false: "",
|
|
3802
|
+
},
|
|
3803
|
+
disabled: {
|
|
3804
|
+
true: "text-black opacity-50",
|
|
3805
|
+
false: "",
|
|
3806
|
+
},
|
|
3807
|
+
},
|
|
3808
|
+
compoundVariants: [
|
|
3809
|
+
{
|
|
3810
|
+
/* danger not multi-select enabled */
|
|
3811
|
+
selected: true,
|
|
3812
|
+
variant: "danger",
|
|
3813
|
+
className: ["!bg-white"],
|
|
3814
|
+
},
|
|
3815
|
+
],
|
|
3816
|
+
defaultVariants: {
|
|
3817
|
+
variant: "primary",
|
|
3818
|
+
selected: false,
|
|
3819
|
+
disabled: false,
|
|
4077
3820
|
},
|
|
4078
3821
|
});
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
const
|
|
3822
|
+
const cvaMenuItemLabel = cvaMerge(["flex-grow", "truncate", "text-black", "font-normal"], {
|
|
3823
|
+
variants: {
|
|
3824
|
+
variant: {
|
|
3825
|
+
primary: [],
|
|
3826
|
+
danger: ["text-danger-600", "hover:text-danger-700", "focus:bg-danger-200", "focus:text-danger-800"],
|
|
3827
|
+
},
|
|
3828
|
+
disabled: {
|
|
3829
|
+
true: "text-black opacity-50",
|
|
3830
|
+
false: "",
|
|
3831
|
+
},
|
|
3832
|
+
},
|
|
3833
|
+
defaultVariants: {
|
|
3834
|
+
variant: "primary",
|
|
3835
|
+
disabled: false,
|
|
3836
|
+
},
|
|
3837
|
+
});
|
|
3838
|
+
const cvaMenuItemPrefix = cvaMerge(["text-secondary-400", "hover:text-secondary-500", "focus:text-secondary-500", "h-min", "leading-[0]"], {
|
|
4096
3839
|
variants: {
|
|
4097
3840
|
selected: {
|
|
4098
|
-
true: "text-
|
|
3841
|
+
true: "text-secondary-600",
|
|
4099
3842
|
false: "",
|
|
4100
3843
|
},
|
|
3844
|
+
variant: {
|
|
3845
|
+
primary: [],
|
|
3846
|
+
danger: ["text-danger-600", "hover:text-danger-700", "focus:bg-danger-200", "focus:text-danger-800"],
|
|
3847
|
+
},
|
|
3848
|
+
disabled: {
|
|
3849
|
+
true: "text-secondary opacity-50",
|
|
3850
|
+
false: "",
|
|
3851
|
+
},
|
|
3852
|
+
},
|
|
3853
|
+
defaultVariants: {
|
|
3854
|
+
variant: "primary",
|
|
3855
|
+
disabled: false,
|
|
4101
3856
|
},
|
|
4102
3857
|
});
|
|
4103
|
-
const
|
|
3858
|
+
const cvaMenuItemSuffix = cvaMerge(["text-secondary-400", "text-sm"], {
|
|
4104
3859
|
variants: {
|
|
4105
3860
|
selected: {
|
|
4106
|
-
true: "text-
|
|
3861
|
+
true: "text-secondary-600",
|
|
3862
|
+
false: "",
|
|
3863
|
+
},
|
|
3864
|
+
variant: {
|
|
3865
|
+
primary: [],
|
|
3866
|
+
danger: ["text-danger-600", "hover:text-danger-700", "focus:bg-danger-200", "focus:text-danger-800"],
|
|
3867
|
+
},
|
|
3868
|
+
disabled: {
|
|
3869
|
+
true: "text-secondary opacity-50",
|
|
4107
3870
|
false: "",
|
|
4108
3871
|
},
|
|
4109
3872
|
},
|
|
3873
|
+
defaultVariants: {
|
|
3874
|
+
variant: "primary",
|
|
3875
|
+
disabled: false,
|
|
3876
|
+
},
|
|
4110
3877
|
});
|
|
4111
3878
|
|
|
4112
3879
|
/**
|
|
@@ -4115,46 +3882,81 @@ const cvaMenuItemPrefix = cvaMerge(["self-center", "flex-grow-0", "text-slate-40
|
|
|
4115
3882
|
* @param {MenuItemProps} props - The props for the MenuItem component
|
|
4116
3883
|
* @returns {JSX.Element} MenuItem component
|
|
4117
3884
|
*/
|
|
4118
|
-
const MenuItem = ({ className, dataTestId, label, size, children, selected, prefix, suffix, disabled, onClick, stopPropagation = true, id, tabIndex, }) => {
|
|
4119
|
-
|
|
3885
|
+
const MenuItem = ({ className, dataTestId, label, size, children, selected, prefix, suffix, disabled, onClick, stopPropagation = true, id, tabIndex, variant = "primary", }) => {
|
|
3886
|
+
/* Handle tab navigation */
|
|
3887
|
+
const handleKeyDown = (e) => {
|
|
3888
|
+
if (e.key === "Enter" && onClick && !disabled) {
|
|
3889
|
+
stopPropagation && e.stopPropagation();
|
|
3890
|
+
// eslint-disable-next-line local-rules/no-typescript-assertion
|
|
3891
|
+
onClick(e);
|
|
3892
|
+
}
|
|
3893
|
+
};
|
|
3894
|
+
return (jsxs("div", { "aria-disabled": disabled, className: cvaMenuItem({
|
|
4120
3895
|
selected,
|
|
4121
3896
|
disabled,
|
|
4122
3897
|
size,
|
|
4123
3898
|
className,
|
|
4124
|
-
|
|
3899
|
+
variant,
|
|
3900
|
+
}), "data-testid": dataTestId ? `${dataTestId}-menu-item` : "menu-item", id: id, onClick: e => {
|
|
4125
3901
|
stopPropagation && e.stopPropagation();
|
|
4126
3902
|
onClick === null || onClick === void 0 ? void 0 : onClick(e);
|
|
4127
|
-
}, role: "menuitem", tabIndex: tabIndex !== null && tabIndex !== void 0 ? tabIndex : 0, children: [prefix ? (jsx("div", { className: cvaMenuItemPrefix({ selected }), "data-testid": dataTestId ? `${dataTestId}-prefix` :
|
|
3903
|
+
}, onKeyDown: handleKeyDown, role: "menuitem", tabIndex: disabled ? -1 : tabIndex !== null && tabIndex !== void 0 ? tabIndex : 0, children: [prefix ? (jsx("div", { className: cvaMenuItemPrefix({ selected, variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-prefix` : "menu-item-prefix", children: prefix })) : null, children && typeof children !== "string" ? (children) : (jsx("div", { className: cvaMenuItemLabel({ variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-label` : "menu-item-label", children: children !== null && children !== void 0 ? children : label })), suffix ? (jsx("div", { className: cvaMenuItemSuffix({ selected, variant, disabled }), "data-testid": dataTestId ? `${dataTestId}-suffix` : "menu-item-suffix", children: suffix })) : null] }));
|
|
4128
3904
|
};
|
|
4129
3905
|
|
|
4130
|
-
const cvaMenuList = cvaMerge(["shadow-md", "rounded-lg", "z-popover", "bg-white", "border", "border-slate-300", "grid"], {
|
|
4131
|
-
variants: {
|
|
4132
|
-
stickyHeader: {
|
|
4133
|
-
true: "grid-rows-min-fr grid overflow-y-hidden",
|
|
4134
|
-
false: "",
|
|
4135
|
-
},
|
|
4136
|
-
},
|
|
4137
|
-
});
|
|
4138
|
-
const cvaMenuListDivider = cvaMerge([
|
|
4139
|
-
"file:w-full",
|
|
4140
|
-
"selection:col-span-full",
|
|
4141
|
-
"selection:h-px",
|
|
4142
|
-
"selection:bg-slate-200",
|
|
4143
|
-
]);
|
|
4144
|
-
|
|
4145
3906
|
/**
|
|
4146
|
-
* The MenuList
|
|
4147
|
-
|
|
3907
|
+
* The MenuList is a popover menu that appears above all other content on the page. The menu offers a list of actions or functions that a user can access by clicking on a trigger.
|
|
3908
|
+
*
|
|
3909
|
+
* **When to use**
|
|
3910
|
+
* - Use the MenuList if you have limited space and need to display overflow actions in a list.
|
|
3911
|
+
* - Use the MenuList for actions that are not essential to completing workflows.
|
|
3912
|
+
* - Don’t use the MenuList to display single or multi-select items within form components. For dropdowns within select components, use SelectDropdown (component not available yet).
|
|
3913
|
+
*
|
|
4148
3914
|
* @param {MenuListProps} props - The props for the MenuList component
|
|
4149
3915
|
* @returns {JSX.Element} MenuList component
|
|
4150
3916
|
*/
|
|
4151
|
-
const MenuList = ({ dataTestId, className, children, withStickyHeader = false,
|
|
3917
|
+
const MenuList = ({ dataTestId, className, children, withStickyHeader = false, isMulti = false, selectedItems: controlledSelectedItems, onSelectionChange, ...args }) => {
|
|
4152
3918
|
const childrenArr = Children.toArray(children);
|
|
4153
|
-
const
|
|
4154
|
-
|
|
3919
|
+
const [internalSelectedItems, setInternalSelectedItems] = useState(controlledSelectedItems !== null && controlledSelectedItems !== void 0 ? controlledSelectedItems : []);
|
|
3920
|
+
const selectedItems = controlledSelectedItems !== null && controlledSelectedItems !== void 0 ? controlledSelectedItems : internalSelectedItems;
|
|
3921
|
+
const handleItemClick = useCallback((id, disabled) => {
|
|
3922
|
+
if (disabled) {
|
|
3923
|
+
return;
|
|
3924
|
+
}
|
|
3925
|
+
const newSelectedItems = isMulti
|
|
3926
|
+
? selectedItems.includes(id)
|
|
3927
|
+
? selectedItems.filter(item => item !== id)
|
|
3928
|
+
: [...selectedItems, id]
|
|
3929
|
+
: [id];
|
|
3930
|
+
if (onSelectionChange) {
|
|
3931
|
+
onSelectionChange(newSelectedItems);
|
|
3932
|
+
}
|
|
3933
|
+
else {
|
|
3934
|
+
setInternalSelectedItems(newSelectedItems);
|
|
3935
|
+
}
|
|
3936
|
+
}, [isMulti, selectedItems, onSelectionChange]);
|
|
3937
|
+
return (jsx("div", { className: cvaMenuList({ stickyHeader: withStickyHeader, className }), "data-testid": dataTestId ? `${dataTestId}-menu-list` : "menu-list", onClick: args.onClick, role: "list", tabIndex: 0, children: childrenArr.map((menuItem, index) => {
|
|
3938
|
+
var _a;
|
|
3939
|
+
if (isValidElement(menuItem)) {
|
|
3940
|
+
const isSelected = selectedItems.includes((_a = menuItem.props.id) !== null && _a !== void 0 ? _a : `${index}`) || menuItem.props.selected;
|
|
3941
|
+
return (jsx("div", { children: cloneElement(menuItem, {
|
|
3942
|
+
...menuItem.props,
|
|
3943
|
+
onClick: (event) => {
|
|
3944
|
+
var _a, _b, _c;
|
|
3945
|
+
(_b = (_a = menuItem.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, event);
|
|
3946
|
+
handleItemClick((_c = menuItem.props.id) !== null && _c !== void 0 ? _c : `${index}`, menuItem.props.disabled);
|
|
3947
|
+
},
|
|
3948
|
+
className: isMulti && isSelected
|
|
3949
|
+
? cvaMenuListMultiSelect({ className: menuItem.props.className })
|
|
3950
|
+
: cvaMenuListItem({ className: menuItem.props.className }),
|
|
3951
|
+
selected: isSelected,
|
|
3952
|
+
suffix: isMulti && isSelected ? (jsx(Icon, { className: "h-5 text-blue-600", name: "Check", size: "medium", type: "solid" })) : null,
|
|
3953
|
+
}) }, index));
|
|
3954
|
+
}
|
|
3955
|
+
return null;
|
|
3956
|
+
}) }));
|
|
4155
3957
|
};
|
|
4156
3958
|
|
|
4157
|
-
const cvaMoreMenu = cvaMerge(["p-
|
|
3959
|
+
const cvaMoreMenu = cvaMerge(["p-0"]);
|
|
4158
3960
|
|
|
4159
3961
|
/**
|
|
4160
3962
|
* A kebab menu component.
|
|
@@ -4172,7 +3974,7 @@ const MoreMenu = ({ className, dataTestId, popoverProps, iconProps = {
|
|
|
4172
3974
|
variant: "secondary",
|
|
4173
3975
|
}, customButton, customPortalId, children, }) => {
|
|
4174
3976
|
const actionMenuRef = useRef(null);
|
|
4175
|
-
return (jsx("div", { className: cvaMoreMenu({ className }), "data-testid": dataTestId, ref: actionMenuRef, children: jsxs(Popover, { ...popoverProps, children: [jsx(PopoverTrigger, { children: customButton !== null && customButton !== void 0 ? customButton : jsx(IconButton, { ...iconButtonProps, icon: jsx(Icon, { name: "EllipsisHorizontal", ...iconProps }) }) }), jsx(PopoverContent, { portalId: customPortalId, children: close => (typeof children === "function" ? children(close) : children) })] }) }));
|
|
3977
|
+
return (jsx("div", { className: cvaMoreMenu({ className }), "data-testid": dataTestId, ref: actionMenuRef, children: jsxs(Popover, { placement: "bottom-end", ...popoverProps, children: [jsx(PopoverTrigger, { children: customButton !== null && customButton !== void 0 ? customButton : (jsx(IconButton, { dataTestId: "more-menu-icon", ...iconButtonProps, icon: jsx(Icon, { name: "EllipsisHorizontal", ...iconProps }) })) }), jsx(PopoverContent, { portalId: customPortalId, children: close => (typeof children === "function" ? children(close) : children) })] }) }));
|
|
4176
3978
|
};
|
|
4177
3979
|
|
|
4178
3980
|
const cvaNotice = cvaMerge(["flex", "items-center"]);
|
|
@@ -4588,7 +4390,7 @@ const Sidebar = ({ childContainerClassName, children, breakpoint = "lg", classNa
|
|
|
4588
4390
|
}) }), overflowItemCount > 0 ? (jsx(MoreMenu, { iconButtonProps: {
|
|
4589
4391
|
circular: false,
|
|
4590
4392
|
variant: "ghost-neutral",
|
|
4591
|
-
},
|
|
4393
|
+
}, ...moreMenuProps, className: moreMenuProps === null || moreMenuProps === void 0 ? void 0 : moreMenuProps.className, dataTestId: dataTestId ? `${dataTestId}-more-menu` : undefined, children: close => (jsx(MenuList, { ...menuListProps, dataTestId: dataTestId, children: React__default.Children.map(children, child => {
|
|
4592
4394
|
return itemOverflowMap[child.props.id]
|
|
4593
4395
|
? React__default.cloneElement(child, {
|
|
4594
4396
|
onClick: () => {
|
|
@@ -4596,6 +4398,7 @@ const Sidebar = ({ childContainerClassName, children, breakpoint = "lg", classNa
|
|
|
4596
4398
|
(_b = (_a = child.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
4597
4399
|
close();
|
|
4598
4400
|
},
|
|
4401
|
+
className: "w-full",
|
|
4599
4402
|
})
|
|
4600
4403
|
: null;
|
|
4601
4404
|
}) })) })) : null] }));
|
|
@@ -5003,4 +4806,4 @@ const cvaClickable = cvaMerge([
|
|
|
5003
4806
|
},
|
|
5004
4807
|
});
|
|
5005
4808
|
|
|
5006
|
-
export { Alert, Badge, Breadcrumb, BreadcrumbContainer, Button, Card, CardBody, CardFooter, CardHeader, Collapse, CompletionStatusIndicator, CopyableText,
|
|
4809
|
+
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, useSelfUpdatingRef, useTimeout, useViewportSize, useWindowActivity };
|