process.env.NODE_ENV = "production"; import preact from "preact"; import { observable } from "mobx"; import { observer } from "./observer"; import { css } from "typesafecss"; import { LengthOrPercentage, LengthOrPercentageOrAuto } from "typesafecss/cssTypes"; @observer export class DropdownCustom extends preact.Component<{ class?: string; optionClass?: string; title?: string; value: T; onChange: (value: T, index: number) => void; maxWidth?: LengthOrPercentage; options: { value: T; label: (isOpen: boolean) => preact.ComponentChild; }[]; }> { synced = observable({ isOpen: false, tempIndexSelected: null as null | number, }); onUnmount: (() => void)[] = []; componentDidMount(): void { const handler = (e: MouseEvent) => { if (!this.synced.isOpen) return; let el = e.target as HTMLElement | null; while (el) { if (el === this.base) return; el = el.parentElement; } this.synced.isOpen = false; }; window.addEventListener("click", handler); this.onUnmount.push(() => window.removeEventListener("click", handler)); } componentDidUnmount(): void { for (let f of this.onUnmount) f(); } render() { const { options, value, title, onChange } = this.props; let selectedIndex = options.findIndex(o => o.value === value); if (selectedIndex === -1) selectedIndex = 0; let selectedItem = options[selectedIndex] || { value: undefined, label: () => { } }; let renderOptions = () => { let selIndex = this.synced.tempIndexSelected ?? selectedIndex; return (
{this.synced.isOpen && renderOptions()} ); } }