import React, { forwardRef } from "react"; import { ChevronDownIcon } from "@navikt/aksel-icons"; import { useId } from "../utils-external"; import { cl, composeEventHandlers } from "../utils/helpers"; import { useControllableState } from "../utils/hooks"; import { useI18n } from "../utils/i18n/i18n.hooks"; import AnimateHeight from "./AnimateHeight"; import DataCell from "./DataCell"; import Row, { RowProps } from "./Row"; import { isElementInteractiveTarget } from "./Table.utils"; export interface ExpandableRowProps extends Omit< RowProps, "content" | "onRowClick" > { /** * Content of the expanded row */ content: React.ReactNode; /** * Placement of toggle button * @default "left" */ togglePlacement?: "left" | "right"; /** * Opens component if 'true', closes if 'false' * Using this prop removes automatic control of open-state */ open?: boolean; /** * Opened state default * @default false */ defaultOpen?: boolean; /** * Change handler for open */ onOpenChange?: (open: boolean) => void; /** * Disable expansion. shadeOnHover will not be visible. * @default false */ expansionDisabled?: boolean; /** * Makes the whole row clickable * @default false */ expandOnRowClick?: boolean; /** * The width of the expanded row's internal cell * @default 999 */ colSpan?: number; /** * Optional left, right-gutter for content * @default Same as `togglePlacement` */ contentGutter?: "left" | "right" | "none"; } export type ExpandableRowType = React.ForwardRefExoticComponent< ExpandableRowProps & React.RefAttributes >; export const ExpandableRow: ExpandableRowType = forwardRef( ( { className, children, content, togglePlacement = "left", defaultOpen = false, open, onOpenChange, expansionDisabled = false, expandOnRowClick = false, colSpan = 999, contentGutter, onClick, ...rest }, ref, ) => { const [_open, _setOpen] = useControllableState({ defaultValue: defaultOpen, value: open, onChange: onOpenChange, }); const translate = useI18n("global"); const id = useId(); const expansionHandler = (event: React.MouseEvent) => { _setOpen((oldOpen) => !oldOpen); event.stopPropagation(); }; const handleRowClick = (event: React.MouseEvent) => { expandOnRowClick && !expansionDisabled && !isElementInteractiveTarget(event.target as HTMLElement) && expansionHandler(event); }; return ( <> {togglePlacement === "right" && children} null} > {!expansionDisabled && ( )} {togglePlacement === "left" && children} {content} ); }, ); export default ExpandableRow;