UNPKG

vira

Version:

A simple and highly versatile design system using element-vir.

62 lines (61 loc) 2.27 kB
import { asyncProp } from 'element-vir'; /** * Create a dynamic element loader. This should go in your element state. This makes deferring * element importing convenient and allows parts of your app to be placed in separate bundles. Make * sure to also use {@link renderDynamicElement} to use the output of this loader. * * @category Util * @see {@link renderDynamicElement} * @see [example usage](https://github.com/electrovir/vira/blob/dev/packages/vira-book/src/element-book/entries/dynamic-elements.book.ts) */ export function createDynamicElementLoader(loaders) { return asyncProp({ async updateCallback(elementKey, previousResolvedValue) { if (previousResolvedValue && elementKey in previousResolvedValue.cache) { return { cache: previousResolvedValue.cache, element: previousResolvedValue.cache[elementKey], key: elementKey, }; } const imported = await loaders[elementKey](); return { cache: { ...previousResolvedValue?.cache, [elementKey]: imported, }, element: imported, key: elementKey, }; }, }); } /** * Renders the current state of a dynamic element loader. This should go in your render function. * Make sure to also use {@link createDynamicElementLoader} to create a dynamic loader in your * element's state. * * @category Util * @see {@link createDynamicElementLoader} * @see [example usage](https://github.com/electrovir/vira/blob/dev/packages/vira-book/src/element-book/entries/dynamic-elements.book.ts) */ export function renderDynamicElement(asyncProp, { ready, loading, error, key, }) { if (key) { asyncProp.update(key); } if (asyncProp.value instanceof Error) { return error(asyncProp.value); } else if (asyncProp.value instanceof Promise) { return loading(asyncProp.value.then((value) => { return { [value.key]: value.element, }; })); } else { return ready({ [asyncProp.value.key]: asyncProp.value.element, }); } }