@v4fire/client
Version:
V4Fire client core library
112 lines (91 loc) • 2.9 kB
text/typescript
/*!
* V4Fire Client Core
* https://github.com/V4Fire/Client
*
* Released under the MIT license
* https://github.com/V4Fire/Client/blob/master/LICENSE
*/
/**
* [[include:traits/i-items/README.md]]
* @packageDocumentation
*/
import type iBlock from 'super/i-block/i-block';
import type { IterationKey, ItemPropsFn, CreateFromItemFn } from 'traits/i-items/interface';
export * from 'traits/i-items/interface';
export default abstract class iItems {
/**
* Returns a value of the unique key (to optimize re-rendering) of the specified item
*
* @param component
* @param item
* @param i
*/
static getItemKey<T extends iBlock>(
component: T & iItems,
item: object,
i: number
): CanUndef<IterationKey> {
const
{unsafe, itemKey} = component;
let
id;
if (Object.isFunction(itemKey)) {
id = itemKey.call(component, item, i);
} else if (Object.isString(itemKey)) {
const
cacheKey = `[[FN:${itemKey}]]`;
let
compiledFn = <CanUndef<Function>>unsafe.tmp[cacheKey];
if (!Object.isFunction(compiledFn)) {
const
normalize = (str) => str.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
// eslint-disable-next-line no-new-func
compiledFn = Function('item', 'i', `return item['${normalize(itemKey)}']`);
// @ts-ignore (invalid type)
unsafe.tmp[cacheKey] = compiledFn;
}
id = compiledFn.call(component, item, i);
}
if (Object.isPrimitive(id) && !Object.isSymbol(id)) {
return id ?? undefined;
}
return id != null ? String(id) : undefined;
}
/**
* Type: component item
*/
abstract readonly Item: object;
/**
* Type: list of component items
*/
abstract readonly Items: Array<this['Item']>;
/**
* This prop is used to provide a list of items to render by the component
* @prop
*/
abstract items?: this['Items'];
/**
* By design, the specified items are rendered by using other components.
* This prop allows specifying the name of a component that is used to render.
* The prop can be provided as a function. In that case, a value is taken from the result of invoking.
*
* @prop
*/
abstract item?: string | CreateFromItemFn<this['Item'], string>;
/**
* This prop allows specifying props that are passed to a component to render an item.
* The prop can be provided as a function. In that case, a value is taken from the result of invoking.
*
* @prop
*/
abstract itemProps?: Dictionary | ItemPropsFn<this['Item']>;
/**
* To optimize the re-rendering of items, we can specify the unique identifier for each item.
* The prop value can be provided as a string or function. In the string case,
* you are providing the name of a property that stores the identifier.
* If the function case, you should return from the function a value of the identifier.
*
* @prop
*/
abstract itemKey?: string | CreateFromItemFn<this['Item'], IterationKey>;
}