import { className } from 'lib/css' import { FC } from 'preact/compat' import { MutableRef, useCallback, useEffect } from 'preact/hooks' import Icon from 'ui/components/layout/icon' import { useGeneratedId, useOptionButton, useSeamlyOptions, } from 'ui/hooks/seamly-hooks' import useClickOutside from 'ui/hooks/use-click-outside' import { focusElement } from 'ui/utils/general-utils' export type FramePosition = { vertical: 'top' | 'bottom' horizontal: 'left' | 'right' } type OptionsFrameProps = { className?: string onCancel?: () => void headingText: string description?: string descriptionId?: string cancelButtonText?: string cancelButtonRef?: MutableRef disableButtonFocusing?: boolean position: FramePosition } const OptionsFrame: FC = ({ className: givenClassName, children, onCancel, headingText, description, descriptionId, cancelButtonText, cancelButtonRef, disableButtonFocusing, position = { horizontal: 'left', vertical: 'top', }, }) => { const mainHeadingId = useGeneratedId() // @todo Lift this from the "options frame" into something reusable // when you're not using options const { hideOption } = useSeamlyOptions() const { focusButton } = useOptionButton() const closePanel = useCallback(() => { hideOption() if (!disableButtonFocusing) { focusButton() } }, [disableButtonFocusing, focusButton, hideOption]) const onCancelHandler = useCallback(() => { if (onCancel) { onCancel() } closePanel() }, [closePanel, onCancel]) const container = useClickOutside(onCancelHandler) useEffect(() => { focusElement(container.current) }, [container]) return (

{headingText}

{description ? (

{description}

) : null}
{children}
) } export default OptionsFrame