UNPKG

element-vir

Version:

Heroic. Reactive. Declarative. Type safe. Web components without compromise.

52 lines (51 loc) 2.07 kB
import { getObjectTypedKeys } from '@augment-vir/common'; /** * Which of an element's two property maps a value is being written to. * * @category Internal */ export var ElementPropertyType; (function (ElementPropertyType) { ElementPropertyType["Input"] = "input"; ElementPropertyType["State"] = "state"; })(ElementPropertyType || (ElementPropertyType = {})); const collidingPropertyDescriptions = { [ElementPropertyType.Input]: 'a state', [ElementPropertyType.State]: 'an input', }; export function createPropertyCollisionError({ propertyKey, propertyType, tagName, }) { const lowerCasedTagName = tagName.toLowerCase(); return new Error(`Cannot set ${propertyType} '${String(propertyKey)}' on '${lowerCasedTagName}'. '${lowerCasedTagName}' already has ${collidingPropertyDescriptions[propertyType]} property with the same name.`); } export function assignInputs(element, inputs) { const instanceState = element.instanceState; const newInputKeys = getObjectTypedKeys(inputs); /** Validate every key first so that a collision leaves the element untouched. */ newInputKeys.forEach((newInputKey) => { if (instanceState && Object.hasOwn(instanceState, newInputKey)) { throw createPropertyCollisionError({ propertyKey: newInputKey, propertyType: ElementPropertyType.Input, tagName: element.tagName, }); } }); newInputKeys.forEach((newInputKey) => { if ('instanceInputs' in element) { element.instanceInputs[newInputKey] = inputs[newInputKey]; } else { element[newInputKey] = inputs[newInputKey]; } }); /** Wipe out all inputs that weren't set to undefined (as expected) */ if ('instanceInputs' in element) { getObjectTypedKeys(element.instanceInputs).forEach((existingKey) => { if (!(existingKey in inputs)) { element.instanceInputs[existingKey] = undefined; } }); } }