UNPKG

@v4fire/client

Version:

V4Fire client core library

141 lines (114 loc) 3.54 kB
/*! * V4Fire Client Core * https://github.com/V4Fire/Client * * Released under the MIT license * https://github.com/V4Fire/Client/blob/master/LICENSE */ import Friend from 'super/i-block/modules/friend'; import type bVirtualScrollNew from 'base/b-virtual-scroll-new/b-virtual-scroll-new'; import type { VNodeDescriptor, ComponentItem, ItemsProcessor, MountedChild, MountedItem } from 'base/b-virtual-scroll-new/interface'; import { isItem } from 'base/b-virtual-scroll-new/modules/helpers'; import * as vdomRender from 'base/b-virtual-scroll-new/modules/factory/engines/vdom'; /** * A friendly class that provides an API for component production, specifically tailored for the `bVirtualScroll` class. */ export class ComponentFactory extends Friend { override readonly C!: bVirtualScrollNew; /** * Produces component items based on the current state and context. * Returns an array of component items. */ produceComponentItems(): ComponentItem[] { const {ctx} = this; return this.itemsProcessor(ctx.itemsFactory(ctx.getVirtualScrollState(), ctx)); } /** * Produces DOM nodes from an array of component items. * Returns an array of DOM nodes representing the component items. * * @param componentItems - an array of component items */ produceNodes(componentItems: ComponentItem[]): HTMLElement[] { if (componentItems.length === 0) { return []; } const createDescriptor = (item: ComponentItem): VNodeDescriptor => ({ type: item.item, attrs: item.props, children: item.children }); const descriptors = componentItems.map(createDescriptor); return this.callRenderEngine(descriptors); } /** * Augments `ComponentItem` with various properties such as the component node, item index, and child index. * * @param items * @param nodes */ produceMounted(items: ComponentItem[], nodes: HTMLElement[]): Array<MountedChild | MountedItem> { const {ctx} = this, {items: mountedItems, childList} = ctx.getVirtualScrollState(); let itemsCounter = 0; return items.map((item, i) => { if (isItem(item)) { const res = { ...item, node: nodes[i], itemIndex: mountedItems.length + itemsCounter, childIndex: childList.length + i }; itemsCounter++; return res; } return { ...item, node: nodes[i], childIndex: mountedItems.length + i }; }); } /** * Invokes the {@link bVirtualScroll.itemsProcessors} function and returns its result * @param items - the list of items to process. */ protected itemsProcessor(items: ComponentItem[]): ComponentItem[] { const {ctx} = this; const {currentItemsProcessors} = ctx, itemsProcessors = currentItemsProcessors ?? ctx.getItemsProcessors(); if (currentItemsProcessors == null) { ctx.currentItemsProcessors = itemsProcessors; } if (!itemsProcessors) { return items; } if (Object.isFunction(itemsProcessors)) { return itemsProcessors(items, ctx); } Object.forEach<ItemsProcessor>(itemsProcessors, (processor) => { items = processor(items, ctx); }); return items; } /** * Calls the render engine to render the components based on the provided descriptors. * Returns an array of rendered DOM nodes. * * @param descriptors - an array of VNode descriptors. */ protected callRenderEngine(descriptors: VNodeDescriptor[]): HTMLElement[] { const {ctx} = this; ctx.onRenderEngineStart(); const res = vdomRender.render(ctx, descriptors); ctx.onRenderEngineDone(); return res; } }