123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- import {Children, Fragment, useState} from 'react';
- import Button from 'sentry/components/button';
- import {t, tn} from 'sentry/locale';
- type CollapseButtonRenderProps = {
- onCollapse: () => void;
- };
- type ExpandButtonRenderProps = {
- numberOfHiddenItems: number;
- onExpand: () => void;
- };
- type Props = {
- collapseButton?: (props: CollapseButtonRenderProps) => React.ReactNode;
- expandButton?: (props: ExpandButtonRenderProps) => React.ReactNode;
- maxVisibleItems?: number;
- };
- /**
- * This component is used to show first X items and collapse the rest
- */
- const Collapsible: React.FC<Props> = ({
- collapseButton,
- expandButton,
- maxVisibleItems = 5,
- children,
- }) => {
- const [isCollapsed, setCollapsed] = useState(true);
- const handleCollapseToggle = () => setCollapsed(!isCollapsed);
- const items = Children.toArray(children);
- const canCollapse = items.length > maxVisibleItems;
- if (!canCollapse) {
- return <Fragment>{children}</Fragment>;
- }
- const visibleItems = isCollapsed ? items.slice(0, maxVisibleItems) : items;
- const numberOfHiddenItems = items.length - visibleItems.length;
- const showDefault =
- (numberOfHiddenItems > 0 && !expandButton) ||
- (numberOfHiddenItems === 0 && !collapseButton);
- return (
- <Fragment>
- {visibleItems}
- {showDefault && (
- <Button priority="link" onClick={handleCollapseToggle}>
- {isCollapsed
- ? tn('Show %s hidden item', 'Show %s hidden items', numberOfHiddenItems)
- : t('Collapse')}
- </Button>
- )}
- {numberOfHiddenItems > 0 &&
- expandButton?.({onExpand: handleCollapseToggle, numberOfHiddenItems})}
- {numberOfHiddenItems === 0 && collapseButton?.({onCollapse: handleCollapseToggle})}
- </Fragment>
- );
- };
- export default Collapsible;
|