import { FloatingFocusManager, autoUpdate, flip, offset, safePolygon, shift, useDismiss, useFloating, useFocus, useHover, useInteractions, } from "@floating-ui/react"; import React, { useState } from "react"; import { cl } from "../../utils/helpers"; import { useMergeRefs } from "../../utils/hooks"; import { useI18n } from "../../utils/i18n/i18n.hooks"; import { usePeriodContext } from "../hooks/usePeriodContext"; import { useRowContext } from "../hooks/useRowContext"; import { useTimelineContext } from "../hooks/useTimelineContext"; import { ariaLabel, getConditionalClasses } from "../utils/period"; import type { PeriodProps } from "./types"; interface TimelineClickablePeriodProps extends PeriodProps { onSelectPeriod?: ( e: React.MouseEvent | React.KeyboardEvent, ) => void; isActive?: boolean; periodRef: React.ForwardedRef; /** * Default orientation of popover * @default "top" */ placement?: "top" | "bottom"; } const ClickablePeriod = React.memo( ({ onSelectPeriod, start, end, status, cropped, direction, left, width, icon, children, isActive, statusLabel, restProps, periodRef, }: TimelineClickablePeriodProps) => { const [open, setOpen] = useState(false); const { index } = useRowContext(); const { firstFocus } = usePeriodContext(); const { initiate, addFocusable } = useTimelineContext(); const translate = useI18n("Timeline"); const { context, placement, refs, floatingStyles } = useFloating({ placement: restProps?.placement ?? "top", open, onOpenChange: (_open) => setOpen(_open), whileElementsMounted: autoUpdate, middleware: [ offset(8), shift(), flip({ padding: 5, fallbackPlacements: ["bottom", "top"] }), ], }); const hover = useHover(context, { handleClose: safePolygon(), restMs: 25, delay: { open: 1000 }, move: false, }); const focus = useFocus(context); const dismiss = useDismiss(context); const { getFloatingProps, getReferenceProps } = useInteractions([ hover, focus, dismiss, ]); const mergedRef = useMergeRefs(refs.setReference, periodRef); const label = ariaLabel(start, end, status, statusLabel, translate); return ( <> {children && open && (
{children}
)} ); }, ); export default ClickablePeriod;