@trackunit/react-components 0.1.13 → 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$7, 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) }) })) })));
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$7 = tw.span `
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$6, Object.assign({ id: id || "", htmlFor: htmlFor || "", className: className, "data-testid": dataTestId, "$disabled": disabled, "$isInvalid": isInvalid }, { children: children })));
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$6 = tw.label `
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$5, 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 }))] }))) : (
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$5 = tw.div `
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$4, 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 })] })));
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$4 = tw.div `
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$3, 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: () => {
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$3 = tw.div `
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$2, Object.assign({ className: className }, { children: jsx(SkeletonLines, { height: 16, width: 150 }) })));
1757
+ return (jsx(Root$3, Object.assign({ className: className }, { children: jsx(SkeletonLines, { height: 16, width: 150 }) })));
1758
1758
  }
1759
- return (jsxs(Root$2, 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,
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$2 = tw.div `
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trackunit/react-components",
3
- "version": "0.1.13",
3
+ "version": "0.1.14",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "dependencies": {
@@ -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
+ };
@@ -34,6 +34,10 @@ export interface ButtonCommonProps extends CommonProps {
34
34
  * The link to be used for the button.
35
35
  */
36
36
  to?: string;
37
+ /**
38
+ * The id of the button.
39
+ */
40
+ id?: string;
37
41
  title?: string;
38
42
  tabIndex?: number;
39
43
  role?: string;
@@ -33,6 +33,7 @@ export * from "./RadioGroup";
33
33
  export * from "./Search";
34
34
  export * from "./SectionHeader";
35
35
  export * from "./Select";
36
+ export * from "./Sidebar/Sidebar";
36
37
  export * from "./SkeletonLines";
37
38
  export * from "./Spacer";
38
39
  export * from "./Spinner";