import { Arr, Optional } from '@ephox/katamari'; import * as AlloyParts from '../../parts/AlloyParts'; import * as CustomListSchema from '../../ui/schema/CustomListSchema'; import type { CustomListApis, CustomListDetail, CustomListSketcher, CustomListSpec } from '../../ui/types/CustomListTypes'; import type { NamedConfiguredBehaviour } from '../behaviour/Behaviour'; import { Replacing } from '../behaviour/Replacing'; import type { AlloyComponent } from '../component/ComponentApi'; import * as SketchBehaviours from '../component/SketchBehaviours'; import type { AlloySpec } from '../component/SpecTypes'; import * as Sketcher from './Sketcher'; import type { CompositeSketchFactory } from './UiSketcher'; const factory: CompositeSketchFactory = (detail, components, _spec, _external) => { const setItems = (list: AlloyComponent, items: AlloySpec[]) => { getListContainer(list).fold(() => { // check that the group container existed. It may not have if the components // did not list anything, and shell was false. // eslint-disable-next-line no-console console.error('Custom List was defined to not be a shell, but no item container was specified in components'); throw new Error('Custom List was defined to not be a shell, but no item container was specified in components'); }, (container) => { // Get all the children of container, because they will be items. // And then use the item setGroup api const itemComps = Replacing.contents(container); const numListsRequired = items.length; const numListsToAdd = numListsRequired - itemComps.length; const itemsToAdd = numListsToAdd > 0 ? Arr.range(numListsToAdd, () => detail.makeItem()) : [ ]; const itemsToRemove = itemComps.slice(numListsRequired); Arr.each(itemsToRemove, (item) => Replacing.remove(container, item)); Arr.each(itemsToAdd, (item) => Replacing.append(container, item)); const builtLists = Replacing.contents(container); Arr.each(builtLists, (item, i) => { detail.setupItem(list, item, items[i], i); }); }); }; // In shell mode, the group overrides need to be added to the main container, and there can be no children const extra: { behaviours: Array>; components: AlloySpec[]; } = detail.shell ? { behaviours: [ Replacing.config({ }) ], components: [ ] } : { behaviours: [ ], components }; const getListContainer = (component: AlloyComponent) => detail.shell ? Optional.some(component) : AlloyParts.getPart(component, detail, 'items'); return { uid: detail.uid, dom: detail.dom, components: extra.components, behaviours: SketchBehaviours.augment( detail.listBehaviours, extra.behaviours ), apis: { setItems } }; }; const CustomList: CustomListSketcher = Sketcher.composite({ name: CustomListSchema.name(), configFields: CustomListSchema.schema(), partFields: CustomListSchema.parts(), factory, apis: { setItems: (apis, list, items) => { apis.setItems(list, items); } } }); export { CustomList };