import { FieldSchema } from '@ephox/boulder'; import { Fun, Optional } from '@ephox/katamari'; import * as Behaviour from '../../api/behaviour/Behaviour'; import { Coupling } from '../../api/behaviour/Coupling'; import { Focusing } from '../../api/behaviour/Focusing'; import { Keying } from '../../api/behaviour/Keying'; import { Toggling } from '../../api/behaviour/Toggling'; import type { AlloyComponent } from '../../api/component/ComponentApi'; import * as SketchBehaviours from '../../api/component/SketchBehaviours'; import * as AlloyTriggers from '../../api/events/AlloyTriggers'; import { Button } from '../../api/ui/Button'; import * as Fields from '../../data/Fields'; import * as SketcherFields from '../../data/SketcherFields'; import * as InternalSink from '../../parts/InternalSink'; import * as PartType from '../../parts/PartType'; import * as AnchorLayouts from '../../positioning/mode/AnchorLayouts'; import type { ButtonSpec } from '../types/ButtonTypes'; import type { SplitDropdownDetail } from '../types/SplitDropdownTypes'; import type { TieredMenuSpec } from '../types/TieredMenuTypes'; const schema = Fun.constant([ FieldSchema.required('toggleClass'), FieldSchema.required('fetch'), Fields.onStrictHandler('onExecute'), FieldSchema.defaulted('getHotspot', Optional.some), FieldSchema.defaulted('getAnchorOverrides', Fun.constant({ })), AnchorLayouts.schema(), Fields.onStrictHandler('onItemExecute'), FieldSchema.option('lazySink'), FieldSchema.required('dom'), Fields.onHandler('onOpen'), SketchBehaviours.field('splitDropdownBehaviours', [ Coupling, Keying, Focusing ]), FieldSchema.defaulted('matchWidth', false), FieldSchema.defaulted('useMinWidth', false), FieldSchema.defaulted('eventOrder', {}), FieldSchema.option('role'), FieldSchema.option('listRole') ].concat( SketcherFields.sandboxFields() )); const arrowPart = PartType.required({ factory: Button, schema: [ FieldSchema.required('dom') ], name: 'arrow', defaults: () => { return { buttonBehaviours: Behaviour.derive([ // TODO: Remove all traces of revoking Focusing.revoke() ]) }; }, overrides: (detail) => { return { dom: { tag: 'span', attributes: { role: 'presentation' } }, action: (arrow: AlloyComponent) => { arrow.getSystem().getByUid(detail.uid).each(AlloyTriggers.emitExecute); }, buttonBehaviours: Behaviour.derive([ Toggling.config({ toggleOnExecute: false, toggleClass: detail.toggleClass }) ]) }; } }); const buttonPart = PartType.required({ factory: Button, schema: [ FieldSchema.required('dom') ], name: 'button', defaults: () => { return { buttonBehaviours: Behaviour.derive([ // TODO: Remove all traces of revoking Focusing.revoke() ]) }; }, overrides: (detail) => { return { dom: { tag: 'span', attributes: { role: 'presentation' } }, action: (btn: AlloyComponent) => { btn.getSystem().getByUid(detail.uid).each((splitDropdown) => { detail.onExecute(splitDropdown, btn); }); } }; } }); const parts: () => PartType.PartTypeAdt[] = Fun.constant([ arrowPart, buttonPart, PartType.optional({ factory: { sketch: (spec) => { return { uid: spec.uid, dom: { tag: 'span', styles: { display: 'none' }, attributes: { 'aria-hidden': 'true' }, innerHtml: spec.text } }; } }, schema: [ FieldSchema.required('text') ], name: 'aria-descriptor' }), PartType.external({ schema: [ Fields.tieredMenuMarkers() ], name: 'menu', defaults: (detail) => { return { onExecute: (tmenu: AlloyComponent, item: AlloyComponent) => { // CAUTION: This won't work if the splitDropdown and the tmenu aren't // in the same mothership. It is just a default, though. tmenu.getSystem().getByUid(detail.uid).each((splitDropdown) => { detail.onItemExecute(splitDropdown, tmenu, item); }); } }; } }), InternalSink.partType() ]); const name = Fun.constant('SplitDropdown'); export { name, schema, parts };