UNPKG

@insightphp/inertia-view

Version:

View abstraction layer for building architectured Inertia applications.

91 lines (70 loc) 2.45 kB
import type { ComponentDef, ComponentMap } from "./contracts"; import { resolveCommonBasePath } from "./utils"; export class InertiaViewComponentManager { /** * Map of resolved components. */ resolvedComponents: Record<string, ComponentDef> = {} /** * Registers view components for given namespace. */ addComponents<T>( components: Record<string, ComponentDef>, namespace: string = 'app' ): InertiaViewComponentManager { const paths = Object.keys(components) if (paths.length <= 0) { // TODO: Ignore when runnning on vitest. console.warn(`No components have been found when registering namespace [${namespace}].`) return this } const base = resolveCommonBasePath(paths) Object.keys(components).forEach(fileName => { const path = fileName.replace(base, '') const name = this.resolveComponentName(path.replace(/\//g, '-'), namespace) this.resolvedComponents[name] = components[fileName] as any }) return this } getResolvedComponents(): Record<string, ComponentDef> { return this.resolvedComponents } /** * Retrieve registered component with given name. */ getComponentWithName(name: string): ComponentDef { if (! Object.keys(this.resolvedComponents).includes(name)) { throw new Error(`The Component with name [${name}] is not registered.`) } return this.resolvedComponents[name] } /** * Resolve component name from file name. * * @param fileName * @param prefix */ resolveComponentName(fileName: string, prefix: string|null = null): string { const parts = fileName.split('/'); const camelCase = parts[parts.length - 1].replace('.vue', '') const kebabCase = camelCase.replace(/\B([A-Z])(?=[a-z])/g, '-$1') .replace(/\B([a-z0-9])([A-Z])/g, '$1-$2') .toLowerCase() if (prefix) { return `${prefix}-${kebabCase}` } return kebabCase } } const ComponentManager = new InertiaViewComponentManager() export { ComponentManager } export function registerComponents(components: ComponentMap|Array<ComponentMap>, namespace: string = 'app') { if (Array.isArray(components)) { components.forEach(map => ComponentManager.addComponents(map, namespace)) } else { ComponentManager.addComponents(components, namespace) } } export function resolveNamedComponent(name: string): ComponentDef { return ComponentManager.getComponentWithName(name) }