UNPKG

@roxi/routify

Version:

103 lines (91 loc) 3.5 kB
import { get } from 'svelte/store' import { RouteFragment } from '../Route/RouteFragment.js' import { RenderContext } from './RenderContext.js' import { normalizeWrapper } from './utils/normalizeDecorator.js' import { getNearestScrollLock } from '../plugins/scroller/utils.js' /** * check if fragments have the same node and all a params are in b. * @param {RouteFragment} f fragment * @returns {(c: RenderContext) => boolean} */ export const contextHasMatchingFragmentAndParams = f => c => f.node === c.node && Object.entries(f.params).every(([key, value]) => c.fragment.params[key] === value) /** * same as node.pagesWithIndex, except includes dynamic pages * @param {RNodeRuntime} node */ export const nodeIsIndexed = node => !node.meta.fallback && !node.name.startsWith('_') && node.meta?.order !== false /** @param {RNodeRuntime} node*/ export const fetchIndexNode = node => node.navigableChildren.find(node => node.meta.isDefault) // TODO addFolderDecorator should always be synchronous /** * * @param {Decorator<any>[]} decorators * @param {RenderContext | RouterContext} context * @returns {void | Promise<void>} */ export const addFolderDecorator = (decorators, context) => { const folderDecorator = context['node']?.children.find(node => node.meta.isDecorator) const push = () => { const options = folderDecorator.module['decorator'] || {} decorators.push({ component: folderDecorator.module['default'], recursive: options.recursive ?? folderDecorator.meta.recursive ?? true, order: folderDecorator.meta.order || 0, shouldRender: options.shouldRender ?? folderDecorator.meta.shouldRender ?? (() => true), props: options.props || {}, }) } if (folderDecorator) { if (folderDecorator.module) return push() console.warn(`Dynamic import of "${folderDecorator.id}" may cause issues.`) return folderDecorator.loadModule().then(push) } } /** * * @param {Decorator<any>[]} decorators * @param {RenderContext | RouterContext} context * @returns {void | Promise<void>} */ export const addFolderWrapper = (decorators, context) => { const inlineWrapper = context['node']?.children.find( node => node.meta.isInlineWrapper, ) const push = () => decorators.push(normalizeWrapper(inlineWrapper.module.default)) if (inlineWrapper) { if (!inlineWrapper.module) { console.warn(`Dynamic import of "${inlineWrapper.id}" may cause issues.`) return inlineWrapper.loadModule().then(push) } else push() } } export function findNearestInlineContext(context) { return context ? context.isInline ? context : findNearestInlineContext(context.parentContext) : null } /** * * @param {RenderContext} renderContext * @param {HTMLElement} scrollTarget * @param {ScrollContext} scrollContext */ export const defaultScrollLock = (renderContext, scrollTarget, scrollContext) => [ !renderContext.isInline && get(findNearestInlineContext(renderContext)?.elem)?.parent, getNearestScrollLock(scrollContext.elem), ] /** * @param {RenderContext[]} childContexts * @param {RouteFragment} fragment * @returns {RenderContext} */ export const findActiveChildContext = (childContexts, fragment) => childContexts.find(contextHasMatchingFragmentAndParams(fragment)) || childContexts.find(s => s.node === fragment?.node)