/** @jsxImportSource react */ import { Widget, VDOM, getContent } from "../../ui/Widget"; import { HtmlElement, HtmlElementInstance } from "../HtmlElement"; import { Field, getFieldTooltip, FieldInstance } from "./Field"; import { tooltipParentWillReceiveProps, tooltipMouseMove, tooltipMouseLeave, tooltipParentDidMount, } from "../overlay/tooltip-ops"; import { stopPropagation, preventDefault } from "../../util/eventCallbacks"; import DropdownIcon from "../icons/drop-down"; import ClearIcon from "../icons/clear"; import { Localization } from "../../ui/Localization"; import { isString } from "../../util/isString"; import { isDefined } from "../../util/isDefined"; import { KeyCode } from "../../util/KeyCode"; import { autoFocus } from "../autoFocus"; import type { RenderingContext } from "../../ui/RenderingContext"; import type { Instance } from "../../ui/Instance"; import { FieldConfig } from "./Field"; import { Prop, StringProp, BooleanProp } from "../../ui/Prop"; export interface SelectConfig extends FieldConfig { value?: Prop; emptyValue?: unknown; enabled?: BooleanProp; placeholder?: StringProp; hideClear?: boolean; showClear?: boolean; alwaysShowClear?: boolean; baseClass?: string; multiple?: boolean; convertValues?: boolean; nullString?: string; /** Custom validation function. */ onValidate?: | string | ((value: number | string, instance: Instance, validationParams: Record) => unknown); } export class Select extends Field { declare public baseClass: string; declare public hideClear?: boolean; declare public showClear: boolean; declare public alwaysShowClear: boolean; declare public multiple: boolean; declare public convertValues: boolean; declare public nullString: string; declareData(...args: Record[]): void { super.declareData( { value: undefined, disabled: undefined, enabled: undefined, required: undefined, placeholder: undefined, icon: undefined, }, ...args, ); } init(): void { if (isDefined(this.hideClear)) this.showClear = !this.hideClear; if (this.alwaysShowClear) this.showClear = true; super.init(); } renderInput(context: RenderingContext, instance: FieldInstance; multiple: boolean; select: (value: string) => void; label?: React.ReactNode; help?: React.ReactNode; icon?: React.ReactNode; children?: React.ReactNode; } interface SelectComponentState { visited: boolean; focus: boolean; } class SelectComponent extends VDOM.Component { select: HTMLSelectElement | null = null; constructor(props: SelectComponentProps) { super(props); this.state = { visited: false, focus: false, }; } render(): React.ReactNode { let { multiple, select, instance, label, help, icon: iconVDOM } = this.props; let { data, widget, state } = instance; let { CSS, baseClass } = widget; let icon = iconVDOM &&
{iconVDOM}
; let insideButton, readOnly = data.disabled || data.readOnly; if ( widget.showClear && !readOnly && !this.props.multiple && (widget.alwaysShowClear || !data.required) && data.placeholder && !data.empty ) { insideButton = (
this.onClearClick(e)} className={CSS.element(baseClass, "clear")} >
); } else { insideButton = (
); } let placeholder; if (data.placeholder) { placeholder = ( ); } return (
{insideButton} {icon} {label} {help}
); } onBlur(): void { this.props.instance.setState({ visited: true }); if (this.state.focus) this.setState({ focus: false, }); } onFocus(): void { let { instance } = this.props; let { widget } = instance; if (widget.trackFocus) { this.setState({ focus: true, }); } } onClearClick(e: React.MouseEvent): void { e.preventDefault(); e.stopPropagation(); let { instance } = this.props; let { widget } = instance; instance.set("value", widget.emptyValue); } onKeyDown(e: React.KeyboardEvent): void { switch (e.keyCode) { case KeyCode.up: case KeyCode.down: e.stopPropagation(); break; } } componentDidMount(): void { const { select } = this.props; if (this.select) { select(this.select.value); tooltipParentDidMount(this.select, ...getFieldTooltip(this.props.instance)); autoFocus(this.select, this); } } componentDidUpdate(): void { if (this.select) { autoFocus(this.select, this); } } UNSAFE_componentWillReceiveProps(props: SelectComponentProps): void { if (this.select) { tooltipParentWillReceiveProps(this.select, ...getFieldTooltip(props.instance)); } } } export class Option extends HtmlElement { declareData(...args: Record[]): void { super.declareData( { value: undefined, disabled: undefined, enabled: undefined, selected: undefined, text: undefined, }, ...args, ); } prepareData(context: RenderingContext, instance: HtmlElementInstance): void { super.prepareData(context, instance); const { data } = instance; if (!data.empty) data.value = data.value.toString(); } render(context: RenderingContext, instance: HtmlElementInstance, key: string): React.ReactNode { const { data } = instance; return ( ); } } Widget.alias("option", Option);