import { Dropdown as BootstrapDropdown, Tooltip } from "bootstrap"; import { ComponentChildren } from "preact"; import Icon from "./Icon"; import { useEffect, useMemo, useRef, useState, type CSSProperties } from "preact/compat"; import "./FormList.css"; import { CommandNames } from "../../components/app_context"; import { useStaticTooltip } from "./hooks"; import { isMobile } from "../../services/utils"; interface FormListOpts { children: ComponentChildren; onSelect?: (value: string) => void; style?: CSSProperties; fullHeight?: boolean; } export default function FormList({ children, onSelect, style, fullHeight }: FormListOpts) { const wrapperRef = useRef(null); const triggerRef = useRef(null); useEffect(() => { if (!triggerRef.current || !wrapperRef.current) { return; } const $wrapperRef = $(wrapperRef.current); const dropdown = BootstrapDropdown.getOrCreateInstance(triggerRef.current); $wrapperRef.on("hide.bs.dropdown", (e) => e.preventDefault()); return () => { $wrapperRef.off("hide.bs.dropdown"); dropdown.dispose(); } }, [ triggerRef, wrapperRef ]); const builtinStyles = useMemo(() => { const style: CSSProperties = {}; if (fullHeight) { style.height = "100%"; style.overflow = "auto"; } return style; }, [ fullHeight ]); return (
); } export interface FormListBadge { className?: string; text: string; } interface FormListItemOpts { children: ComponentChildren; icon?: string; value?: string; title?: string; active?: boolean; badges?: FormListBadge[]; disabled?: boolean; checked?: boolean | null; selected?: boolean; onClick?: (e: MouseEvent) => void; triggerCommand?: CommandNames; description?: string; className?: string; rtl?: boolean; outsideChildren?: ComponentChildren; } const TOOLTIP_CONFIG: Partial = { placement: "right", fallbackPlacements: [ "right" ] } export function FormListItem({ className, children, icon, value, title, active, badges, disabled, checked, onClick, description, selected, rtl, triggerCommand, outsideChildren }: FormListItemOpts) { const itemRef = useRef(null); if (checked) { icon = "bx bx-check"; } useStaticTooltip(itemRef, TOOLTIP_CONFIG); return (  
{children} {badges && badges.map(({ className, text }) => ( {text} ))} {description &&
{description}
}
{outsideChildren}
); } interface FormListHeaderOpts { text: string; } export function FormListHeader({ text }: FormListHeaderOpts) { return (
  • {text}
  • ) } export function FormDropdownDivider() { return
    ; } export function FormDropdownSubmenu({ icon, title, children }: { icon: string, title: ComponentChildren, children: ComponentChildren }) { const [ openOnMobile, setOpenOnMobile ] = useState(false); return (
  • { e.stopPropagation(); if (isMobile()) { setOpenOnMobile(!openOnMobile); } }} > {title}
      {children}
  • ) }