@v4fire/client
Version:
V4Fire client core library
141 lines (114 loc) • 3.54 kB
text/typescript
/*!
* 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;
}
}