import { ReactNode, useMemo } from "react"; import { SizeBuilder } from "./SizeBuilder"; import { ReactWidgetsBinding } from "../modules/react_widgets_binding"; /** Signature for a factory function of a react-node about constraint. */ export type ConstraintsBuilder = (value: T) => ReactNode; export class Constraint { constructor( public min: number, public max: number, public value: T, ) { if (min > max) throw new Error("A min-constraint must be less than a max-constraint."); } } export function ConstraintBuilder({constraints, usememo, builder}: { constraints: Constraint[], usememo?: boolean; builder: ConstraintsBuilder, }) { console.assert( constraints.length != 0, "A constraints of ConstraintBuilder must be one or more." ); return ( { // Find the constraint value that matches the current window size. const value = constraints.find(e => e.min <= width && e.max >= width)?.value; if (value == null) { throw new Error("No constraint value exists for the current window size."); } // Memoize and recycle the builder result based on the value. // Because of due to the widget's characteristic where // the result remains the same if the input value is unchanged. if (usememo ?? ReactWidgetsBinding.instance.optionValueOf("useDefaultMemo")) { return useMemo(() => builder(value), [value]); } return builder(value); }} /> ); }