import { FieldSchema, Objects } from '@ephox/boulder'; import { Arr } from '@ephox/katamari'; import { Value } from '@ephox/sugar'; import type { HtmlSelectDetail, HtmlSelectSketcher, HtmlSelectSpec } from '../../ui/types/HtmlSelectTypes'; import { Focusing } from '../behaviour/Focusing'; import { Representing } from '../behaviour/Representing'; import * as SketchBehaviours from '../component/SketchBehaviours'; import type { SketchSpec } from '../component/SpecTypes'; import * as Sketcher from './Sketcher'; import type { SingleSketchFactory } from './UiSketcher'; const factory: SingleSketchFactory = (detail, _spec): SketchSpec => { const options = Arr.map(detail.options, (option) => ({ dom: { tag: 'option', value: option.value, innerHtml: option.text } })); const initialValues = detail.data.map((v) => Objects.wrap('initialValue', v)).getOr({ }); return { uid: detail.uid, dom: { tag: 'select', classes: detail.selectClasses, attributes: detail.selectAttributes }, components: options, behaviours: SketchBehaviours.augment( detail.selectBehaviours, [ Focusing.config({ }), Representing.config({ store: { mode: 'manual', getValue: (select) => { return Value.get(select.element); }, setValue: (select, newValue) => { const firstOption = Arr.head(detail.options); // This is probably generically useful ... may become a part of Representing. const found = Arr.find(detail.options, (opt) => opt.value === newValue); if (found.isSome()) { Value.set(select.element, newValue); } else if (select.element.dom.selectedIndex === -1 && newValue === '') { /* Sometimes after a redial alloy tries to set a new value, but if no value has been set in the data this used to fail. Now we set the value to the first option in the list if: The index is out of range, indicating that the list of options have changed, or was never set. The user is not trying to set a specific value (which would be user error) */ firstOption.each((value) => Value.set(select.element, value.value) ); } }, ...initialValues } }) ] ) }; }; const HtmlSelect: HtmlSelectSketcher = Sketcher.single({ name: 'HtmlSelect', configFields: [ FieldSchema.required('options'), SketchBehaviours.field('selectBehaviours', [ Focusing, Representing ]), FieldSchema.defaulted('selectClasses', [ ]), FieldSchema.defaulted('selectAttributes', { }), FieldSchema.option('data') ], factory }); export { HtmlSelect };