@trackunit/react-components 0.1.12 → 0.1.14
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.js
CHANGED
|
@@ -226,12 +226,12 @@ const Icon$1 = ({ name, size = "large", className, dataTestId, color, onClick, f
|
|
|
226
226
|
if (!IconComponent) {
|
|
227
227
|
return null;
|
|
228
228
|
}
|
|
229
|
-
return (jsx(React.Suspense, Object.assign({ fallback: jsx(LoadingDot, { className: iconSizeClassName }) }, { children: jsx(Root$
|
|
229
|
+
return (jsx(React.Suspense, Object.assign({ fallback: jsx(LoadingDot, { className: iconSizeClassName }) }, { children: jsx(Root$8, Object.assign({ "$color": color, onClick: onClick, "data-testid": dataTestId, ref: forwardedRef }, { children: jsx(IconComponent, { "data-testid": dataTestId ? `${dataTestId}-${name}` : name, className: `${iconSizeClassName} ${colorClassNames} ${className !== null && className !== void 0 ? className : ""} ${name} aspect-square`, style: fillColor ? Object.assign(Object.assign({}, style), { fill: fillColor }) : Object.assign({}, style) }) })) })));
|
|
230
230
|
};
|
|
231
231
|
const LoadingDot = tw.span `
|
|
232
232
|
tu-loading-dot
|
|
233
233
|
`;
|
|
234
|
-
const Root$
|
|
234
|
+
const Root$8 = tw.span `
|
|
235
235
|
tu-icon
|
|
236
236
|
${({ $color }) => {
|
|
237
237
|
switch ($color) {
|
|
@@ -783,9 +783,9 @@ const ChartContainer = tw.div `
|
|
|
783
783
|
* @returns {JSX.Element} Label component
|
|
784
784
|
*/
|
|
785
785
|
const Label$2 = ({ id, htmlFor, children, className, dataTestId, disabled, isInvalid, }) => {
|
|
786
|
-
return (jsx(Root$
|
|
786
|
+
return (jsx(Root$7, Object.assign({ id: id || "", htmlFor: htmlFor || "", className: className, "data-testid": dataTestId, "$disabled": disabled, "$isInvalid": isInvalid }, { children: children })));
|
|
787
787
|
};
|
|
788
|
-
const Root$
|
|
788
|
+
const Root$7 = tw.label `
|
|
789
789
|
tu-label
|
|
790
790
|
${({ $disabled }) => $disabled && tws `tu-label--disabled`}
|
|
791
791
|
${({ $isInvalid }) => $isInvalid && tws `tu-label--invalid`}
|
|
@@ -1213,7 +1213,7 @@ const Drawer = ({ open, onClose = () => { }, children, disableOverlay = false, p
|
|
|
1213
1213
|
window.removeEventListener("keyup", onKeyPress);
|
|
1214
1214
|
};
|
|
1215
1215
|
}, [open, onClose]);
|
|
1216
|
-
return (jsx(FloatingFocusManager, Object.assign({ context: context }, { children: open ? (jsxs(Root$
|
|
1216
|
+
return (jsx(FloatingFocusManager, Object.assign({ context: context }, { children: open ? (jsxs(Root$6, Object.assign({ id: "drawer" }, { children: [!disableOverlay && jsx(Overlay, { "aria-hidden": open, "$open": open, onClick: onClose, id: "drawer__overlay" }), jsx(StyledCard$1, Object.assign({ "aria-hidden": open, "data-testId": dataTestId, "$open": open, "$position": position, id: "drawer__card", className: className }, { children: children }))] }))) : (
|
|
1217
1217
|
// eslint-disable-next-line react/jsx-no-useless-fragment
|
|
1218
1218
|
jsx(Fragment, {})) })));
|
|
1219
1219
|
};
|
|
@@ -1235,7 +1235,7 @@ const StyledCard$1 = twx(Card) `
|
|
|
1235
1235
|
${({ $open }) => $open && tws `tu-drawer__card--open`}
|
|
1236
1236
|
${({ $position }) => getPositionStyles($position)}
|
|
1237
1237
|
`;
|
|
1238
|
-
const Root$
|
|
1238
|
+
const Root$6 = tw.div `
|
|
1239
1239
|
tu-drawer
|
|
1240
1240
|
`;
|
|
1241
1241
|
const Overlay = tw.div `
|
|
@@ -1346,9 +1346,9 @@ const Ping = tw.span `
|
|
|
1346
1346
|
*/
|
|
1347
1347
|
const LegendItem = ({ className, label, disabled, selected, onClick, color, dataTestId }) => {
|
|
1348
1348
|
const handleOnClick = onClick && !disabled ? () => onClick() : undefined;
|
|
1349
|
-
return (jsxs(Root$
|
|
1349
|
+
return (jsxs(Root$5, Object.assign({ "data-testid": dataTestId, "$disabled": disabled, className: className, "$selected": selected, onClick: handleOnClick }, { children: [jsx(Indicator, { style: { backgroundColor: color }, "$selected": selected }), label && jsx("p", { children: label })] })));
|
|
1350
1350
|
};
|
|
1351
|
-
const Root$
|
|
1351
|
+
const Root$5 = tw.div `
|
|
1352
1352
|
inline-flex
|
|
1353
1353
|
items-center
|
|
1354
1354
|
transition-all
|
|
@@ -1441,11 +1441,11 @@ const MoreMenu = ({ className, dataTestId, dotsDirection = "horizontal", menuPla
|
|
|
1441
1441
|
useClickOutside(actionMenuRef, () => {
|
|
1442
1442
|
setActionMenuIsOpen(false);
|
|
1443
1443
|
});
|
|
1444
|
-
return (jsx(Root$
|
|
1444
|
+
return (jsx(Root$4, Object.assign({ ref: actionMenuRef, className: className, "data-testid": dataTestId }, { children: jsx(Popover, Object.assign({ render: () => children, placement: menuPlacement }, { children: jsx(IconButton, Object.assign({}, iconButtonProps, { icon: jsx(Icon$1, Object.assign({ name: dotsName }, iconProps)), onClick: () => {
|
|
1445
1445
|
setActionMenuIsOpen(!actionMenuIsOpen);
|
|
1446
1446
|
} })) })) })));
|
|
1447
1447
|
};
|
|
1448
|
-
const Root$
|
|
1448
|
+
const Root$4 = tw.div `
|
|
1449
1449
|
tu-more-menu
|
|
1450
1450
|
${({ variant }) => (variant === "primary" ? tws `tu-more-menu--primary` : "")}
|
|
1451
1451
|
`;
|
|
@@ -1619,7 +1619,7 @@ const IconContainer = tw.div `
|
|
|
1619
1619
|
* @returns {JSX.Element} PageHeader component
|
|
1620
1620
|
*/
|
|
1621
1621
|
const PageHeader = ({ className, dataTestId, action, showLoading, description, link, title, tag, backTo, children, }) => {
|
|
1622
|
-
return (jsxs(StyledPageHeader, Object.assign({ className: className, "data-testid": dataTestId }, { children: [jsxs(HeadingAndAccessoriesContainer, Object.assign({ "data-testid": `${dataTestId}-heading-container` }, { children: [jsxs(HeadingContainer, { children: [backTo && (jsx(IconButton, { to: backTo, color: "tertiary", variant: "transparent", size: "small", icon: jsx(Icon$1, { name: "ArrowLeftIcon" }) })), jsx(Heading, Object.assign({ "data-testid": `${dataTestId}-heading` }, { children: title })), description && (jsx(StyledTip, Object.assign({ link: isValidHttpUrl(link) ? link : undefined, dataTestId: `${dataTestId}-tip`, iconProps: { name: "QuestionMarkCircleIcon" }, renderAs: link ? "a" : "span" }, { children: description })))] }), tag && jsx(Tag, Object.assign({ dataTestId: dataTestId }, { children: tag })), showLoading && jsx(Spinner, { dataTestId: `${dataTestId}-spinner`, centered: true }), action] })), jsx(ChildContainer, { children: children })] })));
|
|
1622
|
+
return (jsxs(StyledPageHeader, Object.assign({ className: className, "data-testid": dataTestId }, { children: [jsxs(HeadingAndAccessoriesContainer, Object.assign({ "data-testid": `${dataTestId}-heading-container` }, { children: [jsxs(HeadingContainer, { children: [backTo && (jsx(IconButton, { to: backTo, color: "tertiary", variant: "transparent", size: "small", icon: jsx(Icon$1, { name: "ArrowLeftIcon" }) })), jsx(Heading, Object.assign({ "data-testid": `${dataTestId}-heading` }, { children: title })), description && (jsx(StyledTip, Object.assign({ link: isValidHttpUrl(link) ? link : undefined, dataTestId: `${dataTestId}-tip`, iconProps: { name: "QuestionMarkCircleIcon" }, renderAs: link ? "a" : "span" }, { children: description })))] }), tag && jsx(Tag, Object.assign({ dataTestId: dataTestId }, { children: tag })), showLoading && jsx(Spinner, { dataTestId: `${dataTestId}-spinner`, centered: true }), action] })), jsx(ChildContainer$1, { children: children })] })));
|
|
1623
1623
|
};
|
|
1624
1624
|
function isValidHttpUrl(link) {
|
|
1625
1625
|
if (!link) {
|
|
@@ -1646,7 +1646,7 @@ const HeadingContainer = tw.div `
|
|
|
1646
1646
|
const Heading = tw.h1 `
|
|
1647
1647
|
tu-page-header__heading
|
|
1648
1648
|
`;
|
|
1649
|
-
const ChildContainer = tw.div `
|
|
1649
|
+
const ChildContainer$1 = tw.div `
|
|
1650
1650
|
tu-page-header__child-container
|
|
1651
1651
|
`;
|
|
1652
1652
|
const StyledTip = twx(Tip) `
|
|
@@ -1754,15 +1754,15 @@ const Pagination = ({ gotoPage, previousPage, nextPage, pageCount, pageIndex, ca
|
|
|
1754
1754
|
handlePageChange("manual");
|
|
1755
1755
|
}, [handlePageChange]);
|
|
1756
1756
|
if (loading) {
|
|
1757
|
-
return (jsx(Root$
|
|
1757
|
+
return (jsx(Root$3, Object.assign({ className: className }, { children: jsx(SkeletonLines, { height: 16, width: 150 }) })));
|
|
1758
1758
|
}
|
|
1759
|
-
return (jsxs(Root$
|
|
1759
|
+
return (jsxs(Root$3, Object.assign({ "data-testid": dataTestId, className: className }, { children: [jsx(IconButton, { onClick: () => handlePageChange("prev"), disabled: cursorBase ? false : page !== undefined && page <= 0, "data-testid": "prev-page", icon: jsx(Icon$1, { name: "ChevronLeftIcon", size: "small" }), size: "small", color: "secondary", variant: "transparent" }), !cursorBase && (jsxs(Fragment, { children: [jsx(Text$1, { children: getTranslatedPage() }), jsx(PageInput, { type: "number", min: 1,
|
|
1760
1760
|
// max={amountOfPages}
|
|
1761
1761
|
value: pageInputValue, onFocus: handleOnFocus, onBlur: handleOnBlur, onChange: handleOnChange, onKeyPress: handleOnKeyPress, "data-testid": "page-input" }), jsx(TextStyled, Object.assign({ dataTestId: "page-count" }, { children: pageCount !== null && pageCount !== undefined && getTranslatedCount(pageCount) }))] })), jsx(IconButton, { onClick: () => handlePageChange("next"), disabled: cursorBase
|
|
1762
1762
|
? false
|
|
1763
1763
|
: page !== undefined && pageCount !== undefined && pageCount !== null && page >= pageCount - 1, "data-testid": "next-page", icon: jsx(Icon$1, { name: "ChevronRightIcon", size: "small" }), size: "small", color: "secondary", variant: "transparent" })] })));
|
|
1764
1764
|
};
|
|
1765
|
-
const Root$
|
|
1765
|
+
const Root$3 = tw.div `
|
|
1766
1766
|
tu-pagination
|
|
1767
1767
|
`;
|
|
1768
1768
|
const TextStyled = twx(Text$1) `
|
|
@@ -2451,6 +2451,107 @@ const SelectContainer = tw.div `
|
|
|
2451
2451
|
`;
|
|
2452
2452
|
Select.displayName = "Select";
|
|
2453
2453
|
|
|
2454
|
+
/**
|
|
2455
|
+
* A hook used to detect what children are overflowing a container.
|
|
2456
|
+
*
|
|
2457
|
+
* @param {OverflowItemsOptions} root0 The options for the hook.
|
|
2458
|
+
* @param {OverflowItemsOptions.threshold} root0.threshold The threshold for the intersection observer.
|
|
2459
|
+
* @returns {object} The overflow items and the ref to the container.
|
|
2460
|
+
*/
|
|
2461
|
+
const useOverflowItems = ({ threshold = 1, childUniqueIdentifierAttribute = "id", children, }) => {
|
|
2462
|
+
const [itemOverflowMap, setItemOverflowMap] = useState({});
|
|
2463
|
+
const overflowContainerRef = useRef(null); // TODO: Handle other elements than div
|
|
2464
|
+
const observerRef = useRef(null);
|
|
2465
|
+
const handleIntersection = useCallback(entries => {
|
|
2466
|
+
const updatedEntries = {};
|
|
2467
|
+
entries.forEach(entry => {
|
|
2468
|
+
const targetElementId = entry.target[childUniqueIdentifierAttribute];
|
|
2469
|
+
if (targetElementId) {
|
|
2470
|
+
updatedEntries[targetElementId] = entry.isIntersecting ? false : true;
|
|
2471
|
+
}
|
|
2472
|
+
});
|
|
2473
|
+
setItemOverflowMap(prev => (Object.assign(Object.assign({}, prev), updatedEntries)));
|
|
2474
|
+
}, [childUniqueIdentifierAttribute]);
|
|
2475
|
+
const observe = useCallback(() => {
|
|
2476
|
+
const node = overflowContainerRef.current;
|
|
2477
|
+
if (node && node.children) {
|
|
2478
|
+
const root = overflowContainerRef.current;
|
|
2479
|
+
const options = { root, threshold };
|
|
2480
|
+
const observer = new IntersectionObserver(handleIntersection, options);
|
|
2481
|
+
Array.from(node.children).forEach(child => {
|
|
2482
|
+
observer.observe(child);
|
|
2483
|
+
});
|
|
2484
|
+
observer.observe(node);
|
|
2485
|
+
observerRef.current = observer;
|
|
2486
|
+
}
|
|
2487
|
+
}, [handleIntersection, threshold]);
|
|
2488
|
+
const unobserve = useCallback(() => {
|
|
2489
|
+
const currentObserver = observerRef.current;
|
|
2490
|
+
currentObserver === null || currentObserver === void 0 ? void 0 : currentObserver.disconnect();
|
|
2491
|
+
observerRef.current = null;
|
|
2492
|
+
}, []);
|
|
2493
|
+
const initializeObserver = useCallback(() => {
|
|
2494
|
+
unobserve();
|
|
2495
|
+
observe();
|
|
2496
|
+
}, [observe, unobserve]);
|
|
2497
|
+
useEffect(() => {
|
|
2498
|
+
initializeObserver();
|
|
2499
|
+
return () => {
|
|
2500
|
+
unobserve();
|
|
2501
|
+
};
|
|
2502
|
+
}, [initializeObserver, unobserve, children]);
|
|
2503
|
+
return { overflowContainerRef, itemOverflowMap };
|
|
2504
|
+
};
|
|
2505
|
+
|
|
2506
|
+
/**
|
|
2507
|
+
* The sidebar components is used to render a responsive sidebar.
|
|
2508
|
+
* - The sidebar will be rendered horizontally until a given breakpoint where it will be stacked vertically.
|
|
2509
|
+
* - The sidebar hides items that does not fit in the sidebar and show them in a more menu.
|
|
2510
|
+
* - **_The sidebar is just a wrapper. You are responsible for styling the children._**
|
|
2511
|
+
*
|
|
2512
|
+
* When using this component make sure to add `setupIntersectionObserver();` to your jest.setup.ts file.
|
|
2513
|
+
*
|
|
2514
|
+
* @param {SidebarProps} props - The props for the Sidebar component
|
|
2515
|
+
* @returns {JSX.Element} Sidebar component
|
|
2516
|
+
*/
|
|
2517
|
+
const Sidebar = ({ childContainerClassName, children, breakpoint = "lg", className, dataTestId = "sidebar", moreMenuProps, overflowThreshold, }) => {
|
|
2518
|
+
const { overflowContainerRef, itemOverflowMap } = useOverflowItems({
|
|
2519
|
+
children,
|
|
2520
|
+
childUniqueIdentifierAttribute: "id",
|
|
2521
|
+
threshold: overflowThreshold !== null && overflowThreshold !== void 0 ? overflowThreshold : 0.8,
|
|
2522
|
+
});
|
|
2523
|
+
const overflowItemCount = Object.values(itemOverflowMap).filter(isOverflowing => isOverflowing).length;
|
|
2524
|
+
const itemVisibilityClassName = (id) => {
|
|
2525
|
+
if (itemOverflowMap[id]) {
|
|
2526
|
+
return tws `invisible`;
|
|
2527
|
+
}
|
|
2528
|
+
return tws `visible`;
|
|
2529
|
+
};
|
|
2530
|
+
return (jsxs(Root$2, Object.assign({ className: className, "data-testid": dataTestId }, { children: [jsx(ChildContainer, Object.assign({ "$breakpoint": breakpoint, ref: overflowContainerRef, className: childContainerClassName, "data-testid": `${dataTestId}-child-container` }, { children: React__default.Children.map(children, child => {
|
|
2531
|
+
return React__default.cloneElement(child, {
|
|
2532
|
+
className: `${child.props.className} ${itemVisibilityClassName(child.props.id)}`,
|
|
2533
|
+
});
|
|
2534
|
+
}) })), overflowItemCount > 0 ? (jsx(MoreMenu, Object.assign({ menuPlacement: "bottom-end" }, moreMenuProps, { className: `${(moreMenuProps === null || moreMenuProps === void 0 ? void 0 : moreMenuProps.className) || ""} !p-0`, dataTestId: `${dataTestId}-more-menu` }, { children: jsx(MenuList, Object.assign({}, moreMenuProps, { dataTestId: `${dataTestId}-menu-list` }, { children: React__default.Children.map(children, child => {
|
|
2535
|
+
return itemOverflowMap[child.props.id] ? child : null;
|
|
2536
|
+
}) })) }))) : null] })));
|
|
2537
|
+
};
|
|
2538
|
+
const Root$2 = tw.div `
|
|
2539
|
+
tu-sidebar
|
|
2540
|
+
`;
|
|
2541
|
+
const breakpointClasses = {
|
|
2542
|
+
xs: tws `tu-sidebar__child-container--xs`,
|
|
2543
|
+
sm: tws `tu-sidebar__child-container--sm`,
|
|
2544
|
+
md: tws `tu-sidebar__child-container--md`,
|
|
2545
|
+
lg: tws `tu-sidebar__child-container--lg`,
|
|
2546
|
+
xl: tws `tu-sidebar__child-container--xl`,
|
|
2547
|
+
"2xl": tws `tu-sidebar__child-container--2xl`,
|
|
2548
|
+
"3xl": tws `tu-sidebar__child-container--3xl`,
|
|
2549
|
+
};
|
|
2550
|
+
const ChildContainer = tw.div `
|
|
2551
|
+
tu-sidebar__child-container
|
|
2552
|
+
${({ $breakpoint }) => breakpointClasses[$breakpoint]}
|
|
2553
|
+
`;
|
|
2554
|
+
|
|
2454
2555
|
/**
|
|
2455
2556
|
* The TextArea is a base component, and should not be used very often.
|
|
2456
2557
|
* For most cases the TextAreaField is the correct component.
|
|
@@ -2961,4 +3062,4 @@ const Layout = tw.div `
|
|
|
2961
3062
|
tu-layout-TwoColumnLayout
|
|
2962
3063
|
`;
|
|
2963
3064
|
|
|
2964
|
-
export { ActionButton, Alert, Badge, BaseInput, Button, Card, CardBody, CardFooter, CardHeader, Chart, Checkbox, Collapse, ContentGridArea, CopyableText, CreatableSelect, DateField, DateInput, DayPicker, DayPickerPopover, DayRangePicker, DensityContainer, Drawer, ExternalLink, FilterListMapLayout, FormGroup, FullWidthRepeatingLayout, GridArea, Heading$1 as Heading, Icon$1 as Icon, IconButton, Indicator$1 as Indicator, IntrinsicallyResponsiveGrid, Label$2 as Label, LegendItem, MenuItem, MenuList, MinTopFullContentLayout, Modal, ModalBackdrop, MoreMenu, MultiSelectMenuItem, NavGridArea, NumberField, NumberInput, PageHeader, Pagination, PieChart, Popover, PopoverList, PopoverListItem, PopoverTitle, Prompt, ROLE_CARD, RadioGroup, RadioItem, Search, SectionHeader, Select, SelectPrefix, SingleSelectMenuItem, SkeletonLines, Spacer, Spinner, StarButton, Tag, Text$1 as Text, TextArea, TextAreaField, TextField, TextInput, Timeline, TimelineElement, Tip, TitleGridArea, TitleNavContentLayout, Toggle, Tooltip, TwoColumnLayout, ValueBar, docs, getOrderedOptions, getValueBarColorByValue, isMultiValue, useContainerProps, useCustomComponents, useDebounce, useLocalStorage, useModal, usePrompt, useTimeout };
|
|
3065
|
+
export { ActionButton, Alert, Badge, BaseInput, Button, Card, CardBody, CardFooter, CardHeader, Chart, Checkbox, Collapse, ContentGridArea, CopyableText, CreatableSelect, DateField, DateInput, DayPicker, DayPickerPopover, DayRangePicker, DensityContainer, Drawer, ExternalLink, FilterListMapLayout, FormGroup, FullWidthRepeatingLayout, GridArea, Heading$1 as Heading, Icon$1 as Icon, IconButton, Indicator$1 as Indicator, IntrinsicallyResponsiveGrid, Label$2 as Label, LegendItem, MenuItem, MenuList, MinTopFullContentLayout, Modal, ModalBackdrop, MoreMenu, MultiSelectMenuItem, NavGridArea, NumberField, NumberInput, PageHeader, Pagination, PieChart, Popover, PopoverList, PopoverListItem, PopoverTitle, Prompt, ROLE_CARD, RadioGroup, RadioItem, Search, SectionHeader, Select, SelectPrefix, Sidebar, SingleSelectMenuItem, SkeletonLines, Spacer, Spinner, StarButton, Tag, Text$1 as Text, TextArea, TextAreaField, TextField, TextInput, Timeline, TimelineElement, Tip, TitleGridArea, TitleNavContentLayout, Toggle, Tooltip, TwoColumnLayout, ValueBar, docs, getOrderedOptions, getValueBarColorByValue, isMultiValue, useContainerProps, useCustomComponents, useDebounce, useLocalStorage, useModal, usePrompt, useTimeout };
|
package/package.json
CHANGED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { CommonProps } from "../../common/CommonProps";
|
|
3
|
+
import { MenuList, MoreMenu } from "../Menu";
|
|
4
|
+
export interface SidebarItemProps extends CommonProps {
|
|
5
|
+
/**
|
|
6
|
+
* The id prop is used to identify the sidebar item in the dom.
|
|
7
|
+
* This is needed as it is used for the intersection observer to determine which items are visible and which are not.
|
|
8
|
+
*/
|
|
9
|
+
id: string;
|
|
10
|
+
}
|
|
11
|
+
export declare type Breakpoints = "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl";
|
|
12
|
+
export interface SidebarProps extends CommonProps {
|
|
13
|
+
/**
|
|
14
|
+
* The breakpoint at which the menu will go from Horizontal to vertical stacked
|
|
15
|
+
*
|
|
16
|
+
* @default "lg"
|
|
17
|
+
*/
|
|
18
|
+
breakpoint?: Breakpoints;
|
|
19
|
+
/**
|
|
20
|
+
* The overflowThreshold is used to determine when an item is considered to be overflowing.
|
|
21
|
+
*/
|
|
22
|
+
overflowThreshold?: number;
|
|
23
|
+
/**
|
|
24
|
+
* The child elements of the sidebar.
|
|
25
|
+
* Usually this will be a list of SidebarItems, bottons or links.
|
|
26
|
+
*
|
|
27
|
+
* **For the overflow functionality to take effect use _"min-w-[*]"_ or _"flex-shrink-0"_ on the elements.**
|
|
28
|
+
*/
|
|
29
|
+
children: React.ReactElement<SidebarItemProps>[] | React.ReactElement<SidebarItemProps>;
|
|
30
|
+
/**
|
|
31
|
+
* The childContainerClassName is applied to the element that contains the children.
|
|
32
|
+
* This can be used to change gap or similar styling.
|
|
33
|
+
*/
|
|
34
|
+
childContainerClassName?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Pass custom props to the MoreMenu component used to render overflow items
|
|
37
|
+
*/
|
|
38
|
+
moreMenuProps?: Omit<React.ComponentProps<typeof MoreMenu>, "children">;
|
|
39
|
+
/**
|
|
40
|
+
* Pass custom props to the MenuList component used to render overflow items
|
|
41
|
+
*/
|
|
42
|
+
menuListProps?: Omit<React.ComponentProps<typeof MenuList>, "children">;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The sidebar components is used to render a responsive sidebar.
|
|
46
|
+
* - The sidebar will be rendered horizontally until a given breakpoint where it will be stacked vertically.
|
|
47
|
+
* - The sidebar hides items that does not fit in the sidebar and show them in a more menu.
|
|
48
|
+
* - **_The sidebar is just a wrapper. You are responsible for styling the children._**
|
|
49
|
+
*
|
|
50
|
+
* When using this component make sure to add `setupIntersectionObserver();` to your jest.setup.ts file.
|
|
51
|
+
*
|
|
52
|
+
* @param {SidebarProps} props - The props for the Sidebar component
|
|
53
|
+
* @returns {JSX.Element} Sidebar component
|
|
54
|
+
*/
|
|
55
|
+
export declare const Sidebar: ({ childContainerClassName, children, breakpoint, className, dataTestId, moreMenuProps, overflowThreshold, }: SidebarProps) => JSX.Element;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { HTMLAttributes } from "react";
|
|
2
|
+
import { SidebarItemProps } from "./Sidebar";
|
|
3
|
+
export interface OverflowItemsOptions {
|
|
4
|
+
/**
|
|
5
|
+
* If the child elements of the container are not available at the time of the hook initialization,
|
|
6
|
+
* you can pass the children as a prop, and the hook will initialize the observer when the children are available.
|
|
7
|
+
*/
|
|
8
|
+
children?: React.ReactElement<SidebarItemProps>[] | React.ReactElement<SidebarItemProps>;
|
|
9
|
+
/**
|
|
10
|
+
* The threshold for the intersection observer.
|
|
11
|
+
* Learn more: https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API#creating_an_intersection_observer
|
|
12
|
+
*
|
|
13
|
+
* @default 1
|
|
14
|
+
*/
|
|
15
|
+
threshold?: number | number[];
|
|
16
|
+
/**
|
|
17
|
+
* The unique identifier attribute for the child elements.
|
|
18
|
+
* The identifier is the value that will be returned in the visibleItemsIds array.
|
|
19
|
+
*
|
|
20
|
+
* **ATTENTION: The identifier must be a HTMLAttribute that is available in the DOM, you cannot use react key.**
|
|
21
|
+
*
|
|
22
|
+
* @default "id"
|
|
23
|
+
*/
|
|
24
|
+
childUniqueIdentifierAttribute?: keyof HTMLAttributes<HTMLElement> | `data-${string}`;
|
|
25
|
+
}
|
|
26
|
+
export declare type OverflowMap = {
|
|
27
|
+
[key: string]: boolean;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* A hook used to detect what children are overflowing a container.
|
|
31
|
+
*
|
|
32
|
+
* @param {OverflowItemsOptions} root0 The options for the hook.
|
|
33
|
+
* @param {OverflowItemsOptions.threshold} root0.threshold The threshold for the intersection observer.
|
|
34
|
+
* @returns {object} The overflow items and the ref to the container.
|
|
35
|
+
*/
|
|
36
|
+
export declare const useOverflowItems: ({ threshold, childUniqueIdentifierAttribute, children, }: OverflowItemsOptions) => {
|
|
37
|
+
overflowContainerRef: import("react").MutableRefObject<HTMLDivElement | null>;
|
|
38
|
+
itemOverflowMap: OverflowMap;
|
|
39
|
+
};
|