@ficusjs/core
Advanced tools
+5
-0
@@ -7,2 +7,7 @@ # Changelog | ||
| ## [3.0.0] - 2022-11-10 | ||
| ### Breaking | ||
| - Add default prop named `key` | ||
| ## [2.1.1] - 2022-11-07 | ||
@@ -9,0 +14,0 @@ |
@@ -1,2 +0,2 @@ | ||
| function toKebabCase(e){return e.replace(/([A-Z])/g,"-$1").toLowerCase()}function elementRenderer(e,t){for(;t.firstChild;)t.removeChild(t.firstChild);let s;if("string"==typeof e)s=document.createElement("div"),s.innerHTML=e;else{if(!e.nodeName)throw new Error(`Unable to render ${e}. Have you included a renderer function?`);s=e}s&&t.appendChild(s)}function createCustomElement(e,t){const s=function(e){if(!e)return[];const t=[];return Object.keys(e).forEach((s=>{(null==e[s].observed||e[s].observed)&&t.push(toKebabCase(s))})),t}(t.props);globalThis.customElements.get(e)||globalThis.customElements.define(e,class extends globalThis.HTMLElement{static get observedAttributes(){return s}get componentTagName(){return e}connectedCallback(){null==this.connectedCallbackCount&&(this.connectedCallbackCount=0),this.connectedCallbackCount=this.connectedCallbackCount+1,this._checkInit(),this._preprocess()}disconnectedCallback(){"function"==typeof this.removed&&(this.removed(),this.isRemovedCalled=!0)}attributeChangedCallback(){null!=this.connectedCallbackCount&&(this._checkInit(),this._preprocess(),"function"==typeof this.propsDidUpdate&&this.isMountedCalled&&this.propsDidUpdate())}get initialised(){return this._props&&this._computed&&this.templateRenderer}_checkInit(){this.initialised||this._init(t)}_init(t){this.ficusCustomElement=e,this._props=t.props||{},this._computed=t.computed||{},this.computedCache={},this.status="render",this.connectedCallbackCount=0,this.props=this._processProps(),this.root=this._processRoot(t.root),this.slots=this._processSlots(),this.render=t.render||null,this.templateRenderer=t.renderer||elementRenderer,this.template=null,this.created=t.created||null,this.mounted=t.mounted||null,this.updated=t.updated||null,this.removed=t.removed||null,this.propsDidUpdate=t.propsDidUpdate||null,this.isCreatedCalled=!1,this.isMountedCalled=!1,this.isRemovedCalled=!1,this.emit=(e,t)=>{!function(e,t,s={}){const o=Object.assign({},{bubbles:!0,cancelable:!0,composed:!1},s),n=new CustomEvent(t,{bubbles:o.bubbles,cancelable:o.cancelable,composed:o.composed,detail:o.detail});e.dispatchEvent(n)}(this,e,{detail:t})},this._processMethodsAndComputedProps(t),this._processInstanceProps(this._props),"function"!=typeof this.created||this.isCreatedCalled||(this.created(),this.isCreatedCalled=!0)}_processProps(){const e={};return Object.keys(this._props).forEach((t=>{const s={},o=this._props[t],n=this._getAttribute(t);let r=null;if(null!=o.default&&(r=o.default),o.required&&null==n)null!=r?(console.info(`No biggie, the required prop '${t}' has no value set, so the default has been set`),s[t]=r):(s[t]=null,console.error(`The required prop '${t}' has no value set`));else switch(o.type){case String:default:s[t]=n||r;break;case Number:s[t]=null!=n?parseFloat(n):null!=r?r:0;break;case Boolean:s[t]=null!=n?"true"===n.toString():null!=r&&r;break;case Object:try{s[t]=null!=n?JSON.parse(n):null!=r?r:void 0}catch(e){s[t]=null!=r?r:void 0,console.error(`An object prop parse issue occurred with prop ${t} and value ${n}`)}}e[t]=s[t],this._instanceProps&&this._instanceProps[t]&&(e[t]=this._instanceProps[t])})),e}_processMethodsAndComputedProps(e){const t=this,s=Object.keys(e);s.length&&s.forEach((s=>{t[s]||"function"!=typeof e[s]||(t[s]=e[s].bind(t)),"computed"===s&&this._processComputed(e[s])}))}_processRoot(e){switch(e){case"standard":default:return this;case"shadow":return this.attachShadow({mode:"open"});case"shadow:closed":return this.attachShadow({mode:"closed"})}}_processComputed(e){const t=this,s=Object.keys(e);s.length&&s.forEach((s=>{t[s]?console.warn(`Computed property '${s}' already exists on the component instance`):Object.defineProperty(t,s,{get:()=>(t.computedCache[s]||(t.computedCache[s]=e[s].bind(t)()),t.computedCache[s])})}))}_processRender(){const e=this.render?this.render():void 0;e&&(this.template=e,this._updateRender())}_processSlots(){const e=this.childNodes,t={default:[]};return e.length>0&&[...e].forEach((e=>{const s=e.getAttribute?e.getAttribute("slot"):null;s?t[s]=e:t.default.push(e)})),t}_getAttribute(e){try{return this.getAttribute(toKebabCase(e))}catch(e){return console.error("A get prop error occurred",e),""}}_processInstanceProps(e){const t=this,s=Object.keys(e);e&&s.forEach((e=>{let s;t[e]&&(s=t[e],delete t[e]),Object.defineProperty(t,e,{get(){return this._instanceProps&&this._instanceProps[e]?this._instanceProps[e]:this.getAttribute(toKebabCase(e))},set(t){return this._instanceProps||(this._instanceProps={}),this._instanceProps[e]=t,this.setAttribute(toKebabCase(e),"object"==typeof t?JSON.stringify(t):t.toString()),!0},enumerable:!0}),s&&(t[e]=s)}))}_preprocess(){this.computedCache={},this.props=this._processProps(),this._processRender()}_updateRender(){var e;this.template&&("object"!=typeof(e=this.template)&&"function"!=typeof e||"function"!=typeof e.then?(this.templateRenderer(this.template,this.root),this._callLifecycleMethods()):this.template.then((e=>{this.templateRenderer(e,this.root),this._callLifecycleMethods()})).catch((e=>console.error("A component render error occurred",e))))}_callLifecycleMethods(){"function"!=typeof this.mounted||this.isMountedCalled||this.mounted(),this.isMountedCalled=!0,"function"==typeof this.updated&&this.isMountedCalled&&this.updated()}})}export{createCustomElement}; | ||
| function toKebabCase(e){return e.replace(/([A-Z])/g,"-$1").toLowerCase()}function elementRenderer(e,t){for(;t.firstChild;)t.removeChild(t.firstChild);let s;if("string"==typeof e)s=document.createElement("div"),s.innerHTML=e;else{if(!e.nodeName)throw new Error(`Unable to render ${e}. Have you included a renderer function?`);s=e}s&&t.appendChild(s)}function createCustomElement(e,t){const s={type:String};t.props.key&&console.warn("Prop 'key' is a default property on the component instance, you cannot override it.");const o=function(e){if(!e)return[];const t=[];return Object.keys(e).forEach((s=>{(null==e[s].observed||e[s].observed)&&t.push(toKebabCase(s))})),t}({...t.props,key:s});globalThis.customElements.get(e)||globalThis.customElements.define(e,class extends globalThis.HTMLElement{static get observedAttributes(){return o}get componentTagName(){return e}connectedCallback(){null==this.connectedCallbackCount&&(this.connectedCallbackCount=0),this.connectedCallbackCount=this.connectedCallbackCount+1,this._checkInit(),this._preprocess()}disconnectedCallback(){"function"==typeof this.removed&&(this.removed(),this.isRemovedCalled=!0)}attributeChangedCallback(){null!=this.connectedCallbackCount&&(this._checkInit(),this._preprocess(),"function"==typeof this.propsDidUpdate&&this.isMountedCalled&&this.propsDidUpdate())}get initialised(){return this._props&&this._computed&&this.templateRenderer}_checkInit(){this.initialised||this._init(t)}_init(t){this.ficusCustomElement=e,this._props={...t.props||{},key:s},this._computed=t.computed||{},this.computedCache={},this.status="render",this.connectedCallbackCount=0,this.props=this._processProps(),this.root=this._processRoot(t.root),this.slots=this._processSlots(),this.render=t.render||null,this.templateRenderer=t.renderer||elementRenderer,this.template=null,this.created=t.created||null,this.mounted=t.mounted||null,this.updated=t.updated||null,this.removed=t.removed||null,this.propsDidUpdate=t.propsDidUpdate||null,this.isCreatedCalled=!1,this.isMountedCalled=!1,this.isRemovedCalled=!1,this.emit=(e,t)=>{!function(e,t,s={}){const o=Object.assign({},{bubbles:!0,cancelable:!0,composed:!1},s),n=new CustomEvent(t,{bubbles:o.bubbles,cancelable:o.cancelable,composed:o.composed,detail:o.detail});e.dispatchEvent(n)}(this,e,{detail:t})},this._processMethodsAndComputedProps(t),this._processInstanceProps(this._props),"function"!=typeof this.created||this.isCreatedCalled||(this.created(),this.isCreatedCalled=!0)}_processProps(){const e={};return Object.keys(this._props).forEach((t=>{const s={},o=this._props[t],n=this._getAttribute(t);let r=null;if(null!=o.default&&(r=o.default),o.required&&null==n)null!=r?(console.info(`No biggie, the required prop '${t}' has no value set, so the default has been set`),s[t]=r):(s[t]=null,console.error(`The required prop '${t}' has no value set`));else switch(o.type){case String:default:s[t]=n||r;break;case Number:s[t]=null!=n?parseFloat(n):null!=r?r:0;break;case Boolean:s[t]=null!=n?"true"===n.toString():null!=r&&r;break;case Object:try{s[t]=null!=n?JSON.parse(n):null!=r?r:void 0}catch(e){s[t]=null!=r?r:void 0,console.error(`An object prop parse issue occurred with prop ${t} and value ${n}`)}}e[t]=s[t],this._instanceProps&&this._instanceProps[t]&&(e[t]=this._instanceProps[t])})),e}_processMethodsAndComputedProps(e){const t=this,s=Object.keys(e);s.length&&s.forEach((s=>{t[s]||"function"!=typeof e[s]||(t[s]=e[s].bind(t)),"computed"===s&&this._processComputed(e[s])}))}_processRoot(e){switch(e){case"standard":default:return this;case"shadow":return this.attachShadow({mode:"open"});case"shadow:closed":return this.attachShadow({mode:"closed"})}}_processComputed(e){const t=this,s=Object.keys(e);s.length&&s.forEach((s=>{t[s]?console.warn(`Computed property '${s}' already exists on the component instance`):Object.defineProperty(t,s,{get:()=>(t.computedCache[s]||(t.computedCache[s]=e[s].bind(t)()),t.computedCache[s])})}))}_processRender(){const e=this.render?this.render():void 0;e&&(this.template=e,this._updateRender())}_processSlots(){const e=this.childNodes,t={default:[]};return e.length>0&&[...e].forEach((e=>{const s=e.getAttribute?e.getAttribute("slot"):null;s?t[s]=e:t.default.push(e)})),t}_getAttribute(e){try{return this.getAttribute(toKebabCase(e))}catch(e){return console.error("A get prop error occurred",e),""}}_processInstanceProps(e){const t=this,s=Object.keys(e);e&&s.forEach((e=>{let s;t[e]&&(s=t[e],delete t[e]),Object.defineProperty(t,e,{get(){return this._instanceProps&&this._instanceProps[e]?this._instanceProps[e]:this.getAttribute(toKebabCase(e))},set(t){return this._instanceProps||(this._instanceProps={}),this._instanceProps[e]=t,this.setAttribute(toKebabCase(e),"object"==typeof t?JSON.stringify(t):t.toString()),!0},enumerable:!0}),s&&(t[e]=s)}))}_preprocess(){this.computedCache={},this.props=this._processProps(),this._processRender()}_updateRender(){var e;this.template&&("object"!=typeof(e=this.template)&&"function"!=typeof e||"function"!=typeof e.then?(this.templateRenderer(this.template,this.root),this._callLifecycleMethods()):this.template.then((e=>{this.templateRenderer(e,this.root),this._callLifecycleMethods()})).catch((e=>console.error("A component render error occurred",e))))}_callLifecycleMethods(){"function"!=typeof this.mounted||this.isMountedCalled||this.mounted(),this.isMountedCalled=!0,"function"==typeof this.updated&&this.isMountedCalled&&this.updated()}})}export{createCustomElement}; | ||
| //# sourceMappingURL=custom-element.mjs.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"custom-element.mjs","sources":["../src/util/to-kebab-case.mjs","../src/util/element-renderer.mjs","../src/custom-element.mjs","../src/util/collate-observed-attrs.mjs","../src/util/emit.mjs","../src/util/is-promise.mjs"],"sourcesContent":["export function toKebabCase (str) {\n return str.replace(/([A-Z])/g, '-$1').toLowerCase()\n}\n","export function elementRenderer (what, where) {\n // remove any existing elements\n while (where.firstChild) where.removeChild(where.firstChild)\n\n let element\n if (typeof what === 'string') {\n // create a new in-memory element\n element = document.createElement('div')\n element.innerHTML = what\n } else if (what.nodeName) {\n element = what\n } else {\n throw new Error(`Unable to render ${what}. Have you included a renderer function?`)\n }\n\n // add the element to the DOM\n if (element) where.appendChild(element)\n}\n","import { collateObservedAttrs } from './util/collate-observed-attrs.mjs'\nimport { toKebabCase } from './util/to-kebab-case.mjs'\nimport { isPromise } from './util/is-promise.mjs'\nimport { emit } from './util/emit.mjs'\nimport { elementRenderer } from './util/element-renderer.mjs'\n\nexport function createCustomElement (tagName, props) {\n const observedAttrs = collateObservedAttrs(props.props)\n\n globalThis.customElements.get(tagName) ||\n globalThis.customElements.define(\n tagName,\n class FicusComponent extends globalThis.HTMLElement {\n // standard HTMLElement props and lifecycle hooks\n\n static get observedAttributes () {\n return observedAttrs\n }\n\n get componentTagName () {\n return tagName\n }\n\n connectedCallback () {\n if (this.connectedCallbackCount == null) this.connectedCallbackCount = 0\n this.connectedCallbackCount = this.connectedCallbackCount + 1\n this._checkInit()\n this._preprocess()\n }\n\n disconnectedCallback () {\n if (typeof this.removed === 'function') {\n this.removed()\n this.isRemovedCalled = true\n }\n }\n\n attributeChangedCallback () {\n if (this.connectedCallbackCount == null) return\n this._checkInit()\n this._preprocess()\n if (typeof this.propsDidUpdate === 'function' && this.isMountedCalled) {\n this.propsDidUpdate()\n }\n }\n\n // custom props and private methods\n\n get initialised () {\n return this._props && this._computed && this.templateRenderer\n }\n\n _checkInit () {\n if (!this.initialised) {\n this._init(props)\n }\n }\n\n _init (options) {\n // metadata for devtools\n this.ficusCustomElement = tagName\n\n // It's handy to access what was passed through originally, so we'll store in private props\n this._props = options.props || {}\n this._computed = options.computed || {}\n\n // create a cache for the computed functions\n this.computedCache = {}\n\n // A status enum to set during operations\n this.status = 'render'\n this.connectedCallbackCount = 0\n\n // Run passed props through the props processor\n this.props = this._processProps()\n\n // Determine what our root is. It can be a pointer for `this` or a shadow root\n this.root = this._processRoot(options.root)\n\n // do we have child nodes, if so create them as slots\n this.slots = this._processSlots()\n\n // Pull out a render method if there is one defined\n this.render = options.render || null\n\n // set the default template renderer\n this.templateRenderer = options.renderer || elementRenderer\n\n // Create a template instance we can call with each render\n this.template = null\n\n // Find lifecycle handlers\n this.created = options.created || null\n this.mounted = options.mounted || null\n this.updated = options.updated || null\n this.removed = options.removed || null\n this.propsDidUpdate = options.propsDidUpdate || null\n this.isCreatedCalled = false // ensure callback is only called once\n this.isMountedCalled = false // ensure callback is only called once\n this.isRemovedCalled = false // ensure callback is only called once\n\n // event handlers - the ability to emit an event from the component\n this.emit = (eventName, data) => {\n emit(this, eventName, { detail: data })\n }\n\n // Allow methods and computed properties to be added to this instance\n this._processMethodsAndComputedProps(options)\n\n // create instance properties\n this._processInstanceProps(this._props)\n\n // fire the created method\n if (typeof this.created === 'function' && !this.isCreatedCalled) {\n this.created()\n this.isCreatedCalled = true\n }\n }\n\n _processProps () {\n const response = {}\n\n Object.keys(this._props).forEach(key => {\n const instanceResponse = {}\n const instance = this._props[key]\n const attributeValue = this._getAttribute(key)\n let defaultValue = null\n\n if (instance.default != null) {\n defaultValue = instance.default\n }\n\n // If there's a required attribute with no value we need to do generate the most useful feedback\n if (instance.required && attributeValue == null) {\n // If there's a default value, this is less severe, so set a warning and return out\n if (defaultValue != null) {\n console.info(`No biggie, the required prop '${key}' has no value set, so the default has been set`)\n instanceResponse[key] = defaultValue\n } else {\n // If there's no default, this is an error. We'll set the data to be null too\n instanceResponse[key] = null\n console.error(`The required prop '${key}' has no value set`)\n }\n } else {\n // We're all good here, so let's process the data\n // Make sure the data matches the declared type\n switch (instance.type) {\n case String:\n // eslint-disable-next-line default-case-last,no-fallthrough\n default:\n instanceResponse[key] = attributeValue || defaultValue\n break\n case Number:\n instanceResponse[key] = attributeValue != null ? parseFloat(attributeValue) : defaultValue != null ? defaultValue : 0\n break\n case Boolean:\n instanceResponse[key] = attributeValue != null ? attributeValue.toString() === 'true' : defaultValue != null ? defaultValue : false\n break\n case Object:\n try {\n instanceResponse[key] = attributeValue != null ? JSON.parse(attributeValue) : defaultValue != null ? defaultValue : undefined\n } catch (ex) {\n instanceResponse[key] = defaultValue != null ? defaultValue : undefined\n console.error(`An object prop parse issue occurred with prop ${key} and value ${attributeValue}`)\n }\n break\n }\n }\n\n // Set this data in the main response object\n response[key] = instanceResponse[key]\n\n // Override the props data if we have an instanceProp\n if (this._instanceProps && this._instanceProps[key]) {\n response[key] = this._instanceProps[key]\n }\n })\n\n return response\n }\n\n _processMethodsAndComputedProps (props) {\n const self = this\n const keys = Object.keys(props)\n if (!keys.length) return\n // Run through and bind to the component instance\n keys.forEach(key => {\n if (!self[key] && typeof props[key] === 'function') {\n self[key] = props[key].bind(self)\n }\n if (key === 'computed') {\n this._processComputed(props[key])\n }\n })\n }\n\n _processRoot (key) {\n switch (key) {\n case 'standard':\n // eslint-disable-next-line default-case-last,no-fallthrough\n default:\n return this\n case 'shadow':\n return this.attachShadow({ mode: 'open' })\n case 'shadow:closed':\n return this.attachShadow({ mode: 'closed' })\n }\n }\n\n _processComputed (obj) {\n const self = this\n const keys = Object.keys(obj)\n\n // Bail out if there's not any getters\n if (!keys.length) return\n\n // Run through and create a real getter\n keys.forEach(key => {\n if (self[key]) {\n console.warn(`Computed property '${key}' already exists on the component instance`)\n return\n }\n Object.defineProperty(self, key, {\n get () {\n // check the computed cache first\n if (!self.computedCache[key]) {\n self.computedCache[key] = obj[key].bind(self)()\n }\n return self.computedCache[key]\n }\n })\n })\n }\n\n _processRender () {\n // Check if there's a render method and get the result if it does exist\n const template = this.render ? this.render() : undefined\n\n // Nothing to render so bail out\n if (!template) return\n\n // Set the template for rendering\n this.template = template\n\n // Render the template\n this._updateRender()\n }\n\n _processSlots () {\n const children = this.childNodes\n const slots = {\n default: []\n }\n if (children.length > 0) {\n [...children].forEach(child => {\n const to = child.getAttribute ? child.getAttribute('slot') : null\n if (!to) {\n slots.default.push(child)\n } else {\n slots[to] = child\n }\n })\n }\n return slots\n }\n\n _getAttribute (key) {\n try {\n return this.getAttribute(toKebabCase(key))\n } catch (ex) {\n console.error('A get prop error occurred', ex)\n return ''\n }\n }\n\n _processInstanceProps (props) {\n const self = this\n const keys = Object.keys(props)\n // set instance properties for any defined props\n if (props) {\n keys.forEach(key => {\n let existingPropValue\n if (self[key]) {\n existingPropValue = self[key]\n delete self[key]\n }\n Object.defineProperty(self, key, {\n get () {\n if (this._instanceProps && this._instanceProps[key]) {\n return this._instanceProps[key]\n }\n return this.getAttribute(toKebabCase(key))\n },\n set (newValue) {\n if (!this._instanceProps) {\n this._instanceProps = {}\n }\n this._instanceProps[key] = newValue\n\n // set the HTML attribute value\n this.setAttribute(toKebabCase(key), typeof newValue === 'object' ? JSON.stringify(newValue) : newValue.toString())\n\n return true\n },\n enumerable: true\n })\n if (existingPropValue) self[key] = existingPropValue\n })\n }\n }\n\n _preprocess () {\n this.computedCache = {}\n this.props = this._processProps()\n this._processRender()\n }\n\n _updateRender () {\n if (this.template) {\n // is this an async render?\n if (isPromise(this.template)) {\n this.template\n .then(template => {\n this.templateRenderer(template, this.root)\n this._callLifecycleMethods()\n })\n .catch(e => console.error('A component render error occurred', e))\n } else {\n this.templateRenderer(this.template, this.root)\n this._callLifecycleMethods()\n }\n }\n }\n\n _callLifecycleMethods () {\n if (typeof this.mounted === 'function' && !this.isMountedCalled) {\n this.mounted()\n this.isMountedCalled = true\n } else {\n this.isMountedCalled = true\n }\n if (typeof this.updated === 'function' && this.isMountedCalled) {\n this.updated()\n }\n }\n })\n}\n","import { toKebabCase } from './to-kebab-case.mjs'\n\nexport function collateObservedAttrs (props) {\n if (!props) return []\n const oa = []\n const opk = Object.keys(props)\n opk.forEach(k => {\n if (props[k].observed != null && !props[k].observed) return\n oa.push(toKebabCase(k))\n })\n return oa\n}\n","/* global CustomEvent */\n\nexport function emit (elem, name, opts = {}) {\n const defs = {\n bubbles: true,\n cancelable: true,\n composed: false\n }\n const eventOptions = Object.assign({}, defs, opts)\n const e = new CustomEvent(name, {\n bubbles: eventOptions.bubbles,\n cancelable: eventOptions.cancelable,\n composed: eventOptions.composed,\n detail: eventOptions.detail\n })\n return elem.dispatchEvent(e)\n}\n","export function isPromise (obj) {\n return (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'\n}\n"],"names":["toKebabCase","str","replace","toLowerCase","elementRenderer","what","where","firstChild","removeChild","element","document","createElement","innerHTML","nodeName","Error","appendChild","createCustomElement","tagName","props","observedAttrs","oa","Object","keys","forEach","k","observed","push","collateObservedAttrs","globalThis","customElements","get","define","HTMLElement","observedAttributes","componentTagName","connectedCallback","this","connectedCallbackCount","_checkInit","_preprocess","disconnectedCallback","removed","isRemovedCalled","attributeChangedCallback","propsDidUpdate","isMountedCalled","initialised","_props","_computed","templateRenderer","_init","options","ficusCustomElement","computed","computedCache","status","_processProps","root","_processRoot","slots","_processSlots","render","renderer","template","created","mounted","updated","isCreatedCalled","emit","eventName","data","elem","name","opts","eventOptions","assign","bubbles","cancelable","composed","e","CustomEvent","detail","dispatchEvent","_processMethodsAndComputedProps","_processInstanceProps","response","key","instanceResponse","instance","attributeValue","_getAttribute","defaultValue","default","required","console","info","error","type","String","Number","parseFloat","Boolean","toString","JSON","parse","undefined","ex","_instanceProps","self","length","bind","_processComputed","attachShadow","mode","obj","warn","defineProperty","_processRender","_updateRender","children","childNodes","child","to","getAttribute","existingPropValue","set","newValue","setAttribute","stringify","enumerable","then","_callLifecycleMethods","catch"],"mappings":"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"} | ||
| {"version":3,"file":"custom-element.mjs","sources":["../src/util/to-kebab-case.mjs","../src/util/element-renderer.mjs","../src/custom-element.mjs","../src/util/collate-observed-attrs.mjs","../src/util/emit.mjs","../src/util/is-promise.mjs"],"sourcesContent":["export function toKebabCase (str) {\n return str.replace(/([A-Z])/g, '-$1').toLowerCase()\n}\n","export function elementRenderer (what, where) {\n // remove any existing elements\n while (where.firstChild) where.removeChild(where.firstChild)\n\n let element\n if (typeof what === 'string') {\n // create a new in-memory element\n element = document.createElement('div')\n element.innerHTML = what\n } else if (what.nodeName) {\n element = what\n } else {\n throw new Error(`Unable to render ${what}. Have you included a renderer function?`)\n }\n\n // add the element to the DOM\n if (element) where.appendChild(element)\n}\n","import { collateObservedAttrs } from './util/collate-observed-attrs.mjs'\nimport { toKebabCase } from './util/to-kebab-case.mjs'\nimport { isPromise } from './util/is-promise.mjs'\nimport { emit } from './util/emit.mjs'\nimport { elementRenderer } from './util/element-renderer.mjs'\n\nexport function createCustomElement (tagName, props) {\n const key = {\n type: String\n }\n if (props.props['key']) {\n console.warn(`Prop 'key' is a default property on the component instance, you cannot override it.`)\n }\n const observedAttrs = collateObservedAttrs({ ...props.props, key })\n\n globalThis.customElements.get(tagName) ||\n globalThis.customElements.define(\n tagName,\n class FicusComponent extends globalThis.HTMLElement {\n // standard HTMLElement props and lifecycle hooks\n\n static get observedAttributes () {\n return observedAttrs\n }\n\n get componentTagName () {\n return tagName\n }\n\n connectedCallback () {\n if (this.connectedCallbackCount == null) this.connectedCallbackCount = 0\n this.connectedCallbackCount = this.connectedCallbackCount + 1\n this._checkInit()\n this._preprocess()\n }\n\n disconnectedCallback () {\n if (typeof this.removed === 'function') {\n this.removed()\n this.isRemovedCalled = true\n }\n }\n\n attributeChangedCallback () {\n if (this.connectedCallbackCount == null) return\n this._checkInit()\n this._preprocess()\n if (typeof this.propsDidUpdate === 'function' && this.isMountedCalled) {\n this.propsDidUpdate()\n }\n }\n\n // custom props and private methods\n\n get initialised () {\n return this._props && this._computed && this.templateRenderer\n }\n\n _checkInit () {\n if (!this.initialised) {\n this._init(props)\n }\n }\n\n _init (options) {\n // metadata for devtools\n this.ficusCustomElement = tagName\n\n // It's handy to access what was passed through originally, so we'll store in private props\n this._props = { ...(options.props || {}), key }\n this._computed = options.computed || {}\n\n // create a cache for the computed functions\n this.computedCache = {}\n\n // A status enum to set during operations\n this.status = 'render'\n this.connectedCallbackCount = 0\n\n // Run passed props through the props processor\n this.props = this._processProps()\n\n // Determine what our root is. It can be a pointer for `this` or a shadow root\n this.root = this._processRoot(options.root)\n\n // do we have child nodes, if so create them as slots\n this.slots = this._processSlots()\n\n // Pull out a render method if there is one defined\n this.render = options.render || null\n\n // set the default template renderer\n this.templateRenderer = options.renderer || elementRenderer\n\n // Create a template instance we can call with each render\n this.template = null\n\n // Find lifecycle handlers\n this.created = options.created || null\n this.mounted = options.mounted || null\n this.updated = options.updated || null\n this.removed = options.removed || null\n this.propsDidUpdate = options.propsDidUpdate || null\n this.isCreatedCalled = false // ensure callback is only called once\n this.isMountedCalled = false // ensure callback is only called once\n this.isRemovedCalled = false // ensure callback is only called once\n\n // event handlers - the ability to emit an event from the component\n this.emit = (eventName, data) => {\n emit(this, eventName, { detail: data })\n }\n\n // Allow methods and computed properties to be added to this instance\n this._processMethodsAndComputedProps(options)\n\n // create instance properties\n this._processInstanceProps(this._props)\n\n // fire the created method\n if (typeof this.created === 'function' && !this.isCreatedCalled) {\n this.created()\n this.isCreatedCalled = true\n }\n }\n\n _processProps () {\n const response = {}\n\n Object.keys(this._props).forEach(key => {\n const instanceResponse = {}\n const instance = this._props[key]\n const attributeValue = this._getAttribute(key)\n let defaultValue = null\n\n if (instance.default != null) {\n defaultValue = instance.default\n }\n\n // If there's a required attribute with no value we need to do generate the most useful feedback\n if (instance.required && attributeValue == null) {\n // If there's a default value, this is less severe, so set a warning and return out\n if (defaultValue != null) {\n console.info(`No biggie, the required prop '${key}' has no value set, so the default has been set`)\n instanceResponse[key] = defaultValue\n } else {\n // If there's no default, this is an error. We'll set the data to be null too\n instanceResponse[key] = null\n console.error(`The required prop '${key}' has no value set`)\n }\n } else {\n // We're all good here, so let's process the data\n // Make sure the data matches the declared type\n switch (instance.type) {\n case String:\n // eslint-disable-next-line default-case-last,no-fallthrough\n default:\n instanceResponse[key] = attributeValue || defaultValue\n break\n case Number:\n instanceResponse[key] = attributeValue != null ? parseFloat(attributeValue) : defaultValue != null ? defaultValue : 0\n break\n case Boolean:\n instanceResponse[key] = attributeValue != null ? attributeValue.toString() === 'true' : defaultValue != null ? defaultValue : false\n break\n case Object:\n try {\n instanceResponse[key] = attributeValue != null ? JSON.parse(attributeValue) : defaultValue != null ? defaultValue : undefined\n } catch (ex) {\n instanceResponse[key] = defaultValue != null ? defaultValue : undefined\n console.error(`An object prop parse issue occurred with prop ${key} and value ${attributeValue}`)\n }\n break\n }\n }\n\n // Set this data in the main response object\n response[key] = instanceResponse[key]\n\n // Override the props data if we have an instanceProp\n if (this._instanceProps && this._instanceProps[key]) {\n response[key] = this._instanceProps[key]\n }\n })\n\n return response\n }\n\n _processMethodsAndComputedProps (props) {\n const self = this\n const keys = Object.keys(props)\n if (!keys.length) return\n // Run through and bind to the component instance\n keys.forEach(key => {\n if (!self[key] && typeof props[key] === 'function') {\n self[key] = props[key].bind(self)\n }\n if (key === 'computed') {\n this._processComputed(props[key])\n }\n })\n }\n\n _processRoot (key) {\n switch (key) {\n case 'standard':\n // eslint-disable-next-line default-case-last,no-fallthrough\n default:\n return this\n case 'shadow':\n return this.attachShadow({ mode: 'open' })\n case 'shadow:closed':\n return this.attachShadow({ mode: 'closed' })\n }\n }\n\n _processComputed (obj) {\n const self = this\n const keys = Object.keys(obj)\n\n // Bail out if there's not any getters\n if (!keys.length) return\n\n // Run through and create a real getter\n keys.forEach(key => {\n if (self[key]) {\n console.warn(`Computed property '${key}' already exists on the component instance`)\n return\n }\n Object.defineProperty(self, key, {\n get () {\n // check the computed cache first\n if (!self.computedCache[key]) {\n self.computedCache[key] = obj[key].bind(self)()\n }\n return self.computedCache[key]\n }\n })\n })\n }\n\n _processRender () {\n // Check if there's a render method and get the result if it does exist\n const template = this.render ? this.render() : undefined\n\n // Nothing to render so bail out\n if (!template) return\n\n // Set the template for rendering\n this.template = template\n\n // Render the template\n this._updateRender()\n }\n\n _processSlots () {\n const children = this.childNodes\n const slots = {\n default: []\n }\n if (children.length > 0) {\n [...children].forEach(child => {\n const to = child.getAttribute ? child.getAttribute('slot') : null\n if (!to) {\n slots.default.push(child)\n } else {\n slots[to] = child\n }\n })\n }\n return slots\n }\n\n _getAttribute (key) {\n try {\n return this.getAttribute(toKebabCase(key))\n } catch (ex) {\n console.error('A get prop error occurred', ex)\n return ''\n }\n }\n\n _processInstanceProps (props) {\n const self = this\n const keys = Object.keys(props)\n // set instance properties for any defined props\n if (props) {\n keys.forEach(key => {\n let existingPropValue\n if (self[key]) {\n existingPropValue = self[key]\n delete self[key]\n }\n Object.defineProperty(self, key, {\n get () {\n if (this._instanceProps && this._instanceProps[key]) {\n return this._instanceProps[key]\n }\n return this.getAttribute(toKebabCase(key))\n },\n set (newValue) {\n if (!this._instanceProps) {\n this._instanceProps = {}\n }\n this._instanceProps[key] = newValue\n\n // set the HTML attribute value\n this.setAttribute(toKebabCase(key), typeof newValue === 'object' ? JSON.stringify(newValue) : newValue.toString())\n\n return true\n },\n enumerable: true\n })\n if (existingPropValue) self[key] = existingPropValue\n })\n }\n }\n\n _preprocess () {\n this.computedCache = {}\n this.props = this._processProps()\n this._processRender()\n }\n\n _updateRender () {\n if (this.template) {\n // is this an async render?\n if (isPromise(this.template)) {\n this.template\n .then(template => {\n this.templateRenderer(template, this.root)\n this._callLifecycleMethods()\n })\n .catch(e => console.error('A component render error occurred', e))\n } else {\n this.templateRenderer(this.template, this.root)\n this._callLifecycleMethods()\n }\n }\n }\n\n _callLifecycleMethods () {\n if (typeof this.mounted === 'function' && !this.isMountedCalled) {\n this.mounted()\n this.isMountedCalled = true\n } else {\n this.isMountedCalled = true\n }\n if (typeof this.updated === 'function' && this.isMountedCalled) {\n this.updated()\n }\n }\n })\n}\n","import { toKebabCase } from './to-kebab-case.mjs'\n\nexport function collateObservedAttrs (props) {\n if (!props) return []\n const oa = []\n const opk = Object.keys(props)\n opk.forEach(k => {\n if (props[k].observed != null && !props[k].observed) return\n oa.push(toKebabCase(k))\n })\n return oa\n}\n","/* global CustomEvent */\n\nexport function emit (elem, name, opts = {}) {\n const defs = {\n bubbles: true,\n cancelable: true,\n composed: false\n }\n const eventOptions = Object.assign({}, defs, opts)\n const e = new CustomEvent(name, {\n bubbles: eventOptions.bubbles,\n cancelable: eventOptions.cancelable,\n composed: eventOptions.composed,\n detail: eventOptions.detail\n })\n return elem.dispatchEvent(e)\n}\n","export function isPromise (obj) {\n return (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'\n}\n"],"names":["toKebabCase","str","replace","toLowerCase","elementRenderer","what","where","firstChild","removeChild","element","document","createElement","innerHTML","nodeName","Error","appendChild","createCustomElement","tagName","props","key","type","String","console","warn","observedAttrs","oa","Object","keys","forEach","k","observed","push","collateObservedAttrs","globalThis","customElements","get","define","HTMLElement","observedAttributes","componentTagName","connectedCallback","this","connectedCallbackCount","_checkInit","_preprocess","disconnectedCallback","removed","isRemovedCalled","attributeChangedCallback","propsDidUpdate","isMountedCalled","initialised","_props","_computed","templateRenderer","_init","options","ficusCustomElement","computed","computedCache","status","_processProps","root","_processRoot","slots","_processSlots","render","renderer","template","created","mounted","updated","isCreatedCalled","emit","eventName","data","elem","name","opts","eventOptions","assign","bubbles","cancelable","composed","e","CustomEvent","detail","dispatchEvent","_processMethodsAndComputedProps","_processInstanceProps","response","instanceResponse","instance","attributeValue","_getAttribute","defaultValue","default","required","info","error","Number","parseFloat","Boolean","toString","JSON","parse","undefined","ex","_instanceProps","self","length","bind","_processComputed","attachShadow","mode","obj","defineProperty","_processRender","_updateRender","children","childNodes","child","to","getAttribute","existingPropValue","set","newValue","setAttribute","stringify","enumerable","then","_callLifecycleMethods","catch"],"mappings":"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"} |
+1
-1
@@ -1,2 +0,2 @@ | ||
| function toKebabCase(e){return e.replace(/([A-Z])/g,"-$1").toLowerCase()}function elementRenderer(e,t){for(;t.firstChild;)t.removeChild(t.firstChild);let s;if("string"==typeof e)s=document.createElement("div"),s.innerHTML=e;else{if(!e.nodeName)throw new Error(`Unable to render ${e}. Have you included a renderer function?`);s=e}s&&t.appendChild(s)}function createCustomElement(e,t){const s=function(e){if(!e)return[];const t=[];return Object.keys(e).forEach((s=>{(null==e[s].observed||e[s].observed)&&t.push(toKebabCase(s))})),t}(t.props);globalThis.customElements.get(e)||globalThis.customElements.define(e,class extends globalThis.HTMLElement{static get observedAttributes(){return s}get componentTagName(){return e}connectedCallback(){null==this.connectedCallbackCount&&(this.connectedCallbackCount=0),this.connectedCallbackCount=this.connectedCallbackCount+1,this._checkInit(),this._preprocess()}disconnectedCallback(){"function"==typeof this.removed&&(this.removed(),this.isRemovedCalled=!0)}attributeChangedCallback(){null!=this.connectedCallbackCount&&(this._checkInit(),this._preprocess(),"function"==typeof this.propsDidUpdate&&this.isMountedCalled&&this.propsDidUpdate())}get initialised(){return this._props&&this._computed&&this.templateRenderer}_checkInit(){this.initialised||this._init(t)}_init(t){this.ficusCustomElement=e,this._props=t.props||{},this._computed=t.computed||{},this.computedCache={},this.status="render",this.connectedCallbackCount=0,this.props=this._processProps(),this.root=this._processRoot(t.root),this.slots=this._processSlots(),this.render=t.render||null,this.templateRenderer=t.renderer||elementRenderer,this.template=null,this.created=t.created||null,this.mounted=t.mounted||null,this.updated=t.updated||null,this.removed=t.removed||null,this.propsDidUpdate=t.propsDidUpdate||null,this.isCreatedCalled=!1,this.isMountedCalled=!1,this.isRemovedCalled=!1,this.emit=(e,t)=>{!function(e,t,s={}){const o=Object.assign({},{bubbles:!0,cancelable:!0,composed:!1},s),n=new CustomEvent(t,{bubbles:o.bubbles,cancelable:o.cancelable,composed:o.composed,detail:o.detail});e.dispatchEvent(n)}(this,e,{detail:t})},this._processMethodsAndComputedProps(t),this._processInstanceProps(this._props),"function"!=typeof this.created||this.isCreatedCalled||(this.created(),this.isCreatedCalled=!0)}_processProps(){const e={};return Object.keys(this._props).forEach((t=>{const s={},o=this._props[t],n=this._getAttribute(t);let r=null;if(null!=o.default&&(r=o.default),o.required&&null==n)null!=r?(console.info(`No biggie, the required prop '${t}' has no value set, so the default has been set`),s[t]=r):(s[t]=null,console.error(`The required prop '${t}' has no value set`));else switch(o.type){case String:default:s[t]=n||r;break;case Number:s[t]=null!=n?parseFloat(n):null!=r?r:0;break;case Boolean:s[t]=null!=n?"true"===n.toString():null!=r&&r;break;case Object:try{s[t]=null!=n?JSON.parse(n):null!=r?r:void 0}catch(e){s[t]=null!=r?r:void 0,console.error(`An object prop parse issue occurred with prop ${t} and value ${n}`)}}e[t]=s[t],this._instanceProps&&this._instanceProps[t]&&(e[t]=this._instanceProps[t])})),e}_processMethodsAndComputedProps(e){const t=this,s=Object.keys(e);s.length&&s.forEach((s=>{t[s]||"function"!=typeof e[s]||(t[s]=e[s].bind(t)),"computed"===s&&this._processComputed(e[s])}))}_processRoot(e){switch(e){case"standard":default:return this;case"shadow":return this.attachShadow({mode:"open"});case"shadow:closed":return this.attachShadow({mode:"closed"})}}_processComputed(e){const t=this,s=Object.keys(e);s.length&&s.forEach((s=>{t[s]?console.warn(`Computed property '${s}' already exists on the component instance`):Object.defineProperty(t,s,{get:()=>(t.computedCache[s]||(t.computedCache[s]=e[s].bind(t)()),t.computedCache[s])})}))}_processRender(){const e=this.render?this.render():void 0;e&&(this.template=e,this._updateRender())}_processSlots(){const e=this.childNodes,t={default:[]};return e.length>0&&[...e].forEach((e=>{const s=e.getAttribute?e.getAttribute("slot"):null;s?t[s]=e:t.default.push(e)})),t}_getAttribute(e){try{return this.getAttribute(toKebabCase(e))}catch(e){return console.error("A get prop error occurred",e),""}}_processInstanceProps(e){const t=this,s=Object.keys(e);e&&s.forEach((e=>{let s;t[e]&&(s=t[e],delete t[e]),Object.defineProperty(t,e,{get(){return this._instanceProps&&this._instanceProps[e]?this._instanceProps[e]:this.getAttribute(toKebabCase(e))},set(t){return this._instanceProps||(this._instanceProps={}),this._instanceProps[e]=t,this.setAttribute(toKebabCase(e),"object"==typeof t?JSON.stringify(t):t.toString()),!0},enumerable:!0}),s&&(t[e]=s)}))}_preprocess(){this.computedCache={},this.props=this._processProps(),this._processRender()}_updateRender(){var e;this.template&&("object"!=typeof(e=this.template)&&"function"!=typeof e||"function"!=typeof e.then?(this.templateRenderer(this.template,this.root),this._callLifecycleMethods()):this.template.then((e=>{this.templateRenderer(e,this.root),this._callLifecycleMethods()})).catch((e=>console.error("A component render error occurred",e))))}_callLifecycleMethods(){"function"!=typeof this.mounted||this.isMountedCalled||this.mounted(),this.isMountedCalled=!0,"function"==typeof this.updated&&this.isMountedCalled&&this.updated()}})}function use(e,{...t}){if(e.create&&"function"==typeof e.create)return e.create({...t,use:use})}export{createCustomElement,use}; | ||
| function toKebabCase(e){return e.replace(/([A-Z])/g,"-$1").toLowerCase()}function elementRenderer(e,t){for(;t.firstChild;)t.removeChild(t.firstChild);let s;if("string"==typeof e)s=document.createElement("div"),s.innerHTML=e;else{if(!e.nodeName)throw new Error(`Unable to render ${e}. Have you included a renderer function?`);s=e}s&&t.appendChild(s)}function createCustomElement(e,t){const s={type:String};t.props.key&&console.warn("Prop 'key' is a default property on the component instance, you cannot override it.");const o=function(e){if(!e)return[];const t=[];return Object.keys(e).forEach((s=>{(null==e[s].observed||e[s].observed)&&t.push(toKebabCase(s))})),t}({...t.props,key:s});globalThis.customElements.get(e)||globalThis.customElements.define(e,class extends globalThis.HTMLElement{static get observedAttributes(){return o}get componentTagName(){return e}connectedCallback(){null==this.connectedCallbackCount&&(this.connectedCallbackCount=0),this.connectedCallbackCount=this.connectedCallbackCount+1,this._checkInit(),this._preprocess()}disconnectedCallback(){"function"==typeof this.removed&&(this.removed(),this.isRemovedCalled=!0)}attributeChangedCallback(){null!=this.connectedCallbackCount&&(this._checkInit(),this._preprocess(),"function"==typeof this.propsDidUpdate&&this.isMountedCalled&&this.propsDidUpdate())}get initialised(){return this._props&&this._computed&&this.templateRenderer}_checkInit(){this.initialised||this._init(t)}_init(t){this.ficusCustomElement=e,this._props={...t.props||{},key:s},this._computed=t.computed||{},this.computedCache={},this.status="render",this.connectedCallbackCount=0,this.props=this._processProps(),this.root=this._processRoot(t.root),this.slots=this._processSlots(),this.render=t.render||null,this.templateRenderer=t.renderer||elementRenderer,this.template=null,this.created=t.created||null,this.mounted=t.mounted||null,this.updated=t.updated||null,this.removed=t.removed||null,this.propsDidUpdate=t.propsDidUpdate||null,this.isCreatedCalled=!1,this.isMountedCalled=!1,this.isRemovedCalled=!1,this.emit=(e,t)=>{!function(e,t,s={}){const o=Object.assign({},{bubbles:!0,cancelable:!0,composed:!1},s),n=new CustomEvent(t,{bubbles:o.bubbles,cancelable:o.cancelable,composed:o.composed,detail:o.detail});e.dispatchEvent(n)}(this,e,{detail:t})},this._processMethodsAndComputedProps(t),this._processInstanceProps(this._props),"function"!=typeof this.created||this.isCreatedCalled||(this.created(),this.isCreatedCalled=!0)}_processProps(){const e={};return Object.keys(this._props).forEach((t=>{const s={},o=this._props[t],n=this._getAttribute(t);let r=null;if(null!=o.default&&(r=o.default),o.required&&null==n)null!=r?(console.info(`No biggie, the required prop '${t}' has no value set, so the default has been set`),s[t]=r):(s[t]=null,console.error(`The required prop '${t}' has no value set`));else switch(o.type){case String:default:s[t]=n||r;break;case Number:s[t]=null!=n?parseFloat(n):null!=r?r:0;break;case Boolean:s[t]=null!=n?"true"===n.toString():null!=r&&r;break;case Object:try{s[t]=null!=n?JSON.parse(n):null!=r?r:void 0}catch(e){s[t]=null!=r?r:void 0,console.error(`An object prop parse issue occurred with prop ${t} and value ${n}`)}}e[t]=s[t],this._instanceProps&&this._instanceProps[t]&&(e[t]=this._instanceProps[t])})),e}_processMethodsAndComputedProps(e){const t=this,s=Object.keys(e);s.length&&s.forEach((s=>{t[s]||"function"!=typeof e[s]||(t[s]=e[s].bind(t)),"computed"===s&&this._processComputed(e[s])}))}_processRoot(e){switch(e){case"standard":default:return this;case"shadow":return this.attachShadow({mode:"open"});case"shadow:closed":return this.attachShadow({mode:"closed"})}}_processComputed(e){const t=this,s=Object.keys(e);s.length&&s.forEach((s=>{t[s]?console.warn(`Computed property '${s}' already exists on the component instance`):Object.defineProperty(t,s,{get:()=>(t.computedCache[s]||(t.computedCache[s]=e[s].bind(t)()),t.computedCache[s])})}))}_processRender(){const e=this.render?this.render():void 0;e&&(this.template=e,this._updateRender())}_processSlots(){const e=this.childNodes,t={default:[]};return e.length>0&&[...e].forEach((e=>{const s=e.getAttribute?e.getAttribute("slot"):null;s?t[s]=e:t.default.push(e)})),t}_getAttribute(e){try{return this.getAttribute(toKebabCase(e))}catch(e){return console.error("A get prop error occurred",e),""}}_processInstanceProps(e){const t=this,s=Object.keys(e);e&&s.forEach((e=>{let s;t[e]&&(s=t[e],delete t[e]),Object.defineProperty(t,e,{get(){return this._instanceProps&&this._instanceProps[e]?this._instanceProps[e]:this.getAttribute(toKebabCase(e))},set(t){return this._instanceProps||(this._instanceProps={}),this._instanceProps[e]=t,this.setAttribute(toKebabCase(e),"object"==typeof t?JSON.stringify(t):t.toString()),!0},enumerable:!0}),s&&(t[e]=s)}))}_preprocess(){this.computedCache={},this.props=this._processProps(),this._processRender()}_updateRender(){var e;this.template&&("object"!=typeof(e=this.template)&&"function"!=typeof e||"function"!=typeof e.then?(this.templateRenderer(this.template,this.root),this._callLifecycleMethods()):this.template.then((e=>{this.templateRenderer(e,this.root),this._callLifecycleMethods()})).catch((e=>console.error("A component render error occurred",e))))}_callLifecycleMethods(){"function"!=typeof this.mounted||this.isMountedCalled||this.mounted(),this.isMountedCalled=!0,"function"==typeof this.updated&&this.isMountedCalled&&this.updated()}})}function use(e,{...t}){if(e.create&&"function"==typeof e.create)return e.create({...t,use:use})}export{createCustomElement,use}; | ||
| //# sourceMappingURL=index.mjs.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.mjs","sources":["../src/util/to-kebab-case.mjs","../src/util/element-renderer.mjs","../src/custom-element.mjs","../src/util/collate-observed-attrs.mjs","../src/util/emit.mjs","../src/util/is-promise.mjs","../src/module.mjs"],"sourcesContent":["export function toKebabCase (str) {\n return str.replace(/([A-Z])/g, '-$1').toLowerCase()\n}\n","export function elementRenderer (what, where) {\n // remove any existing elements\n while (where.firstChild) where.removeChild(where.firstChild)\n\n let element\n if (typeof what === 'string') {\n // create a new in-memory element\n element = document.createElement('div')\n element.innerHTML = what\n } else if (what.nodeName) {\n element = what\n } else {\n throw new Error(`Unable to render ${what}. Have you included a renderer function?`)\n }\n\n // add the element to the DOM\n if (element) where.appendChild(element)\n}\n","import { collateObservedAttrs } from './util/collate-observed-attrs.mjs'\nimport { toKebabCase } from './util/to-kebab-case.mjs'\nimport { isPromise } from './util/is-promise.mjs'\nimport { emit } from './util/emit.mjs'\nimport { elementRenderer } from './util/element-renderer.mjs'\n\nexport function createCustomElement (tagName, props) {\n const observedAttrs = collateObservedAttrs(props.props)\n\n globalThis.customElements.get(tagName) ||\n globalThis.customElements.define(\n tagName,\n class FicusComponent extends globalThis.HTMLElement {\n // standard HTMLElement props and lifecycle hooks\n\n static get observedAttributes () {\n return observedAttrs\n }\n\n get componentTagName () {\n return tagName\n }\n\n connectedCallback () {\n if (this.connectedCallbackCount == null) this.connectedCallbackCount = 0\n this.connectedCallbackCount = this.connectedCallbackCount + 1\n this._checkInit()\n this._preprocess()\n }\n\n disconnectedCallback () {\n if (typeof this.removed === 'function') {\n this.removed()\n this.isRemovedCalled = true\n }\n }\n\n attributeChangedCallback () {\n if (this.connectedCallbackCount == null) return\n this._checkInit()\n this._preprocess()\n if (typeof this.propsDidUpdate === 'function' && this.isMountedCalled) {\n this.propsDidUpdate()\n }\n }\n\n // custom props and private methods\n\n get initialised () {\n return this._props && this._computed && this.templateRenderer\n }\n\n _checkInit () {\n if (!this.initialised) {\n this._init(props)\n }\n }\n\n _init (options) {\n // metadata for devtools\n this.ficusCustomElement = tagName\n\n // It's handy to access what was passed through originally, so we'll store in private props\n this._props = options.props || {}\n this._computed = options.computed || {}\n\n // create a cache for the computed functions\n this.computedCache = {}\n\n // A status enum to set during operations\n this.status = 'render'\n this.connectedCallbackCount = 0\n\n // Run passed props through the props processor\n this.props = this._processProps()\n\n // Determine what our root is. It can be a pointer for `this` or a shadow root\n this.root = this._processRoot(options.root)\n\n // do we have child nodes, if so create them as slots\n this.slots = this._processSlots()\n\n // Pull out a render method if there is one defined\n this.render = options.render || null\n\n // set the default template renderer\n this.templateRenderer = options.renderer || elementRenderer\n\n // Create a template instance we can call with each render\n this.template = null\n\n // Find lifecycle handlers\n this.created = options.created || null\n this.mounted = options.mounted || null\n this.updated = options.updated || null\n this.removed = options.removed || null\n this.propsDidUpdate = options.propsDidUpdate || null\n this.isCreatedCalled = false // ensure callback is only called once\n this.isMountedCalled = false // ensure callback is only called once\n this.isRemovedCalled = false // ensure callback is only called once\n\n // event handlers - the ability to emit an event from the component\n this.emit = (eventName, data) => {\n emit(this, eventName, { detail: data })\n }\n\n // Allow methods and computed properties to be added to this instance\n this._processMethodsAndComputedProps(options)\n\n // create instance properties\n this._processInstanceProps(this._props)\n\n // fire the created method\n if (typeof this.created === 'function' && !this.isCreatedCalled) {\n this.created()\n this.isCreatedCalled = true\n }\n }\n\n _processProps () {\n const response = {}\n\n Object.keys(this._props).forEach(key => {\n const instanceResponse = {}\n const instance = this._props[key]\n const attributeValue = this._getAttribute(key)\n let defaultValue = null\n\n if (instance.default != null) {\n defaultValue = instance.default\n }\n\n // If there's a required attribute with no value we need to do generate the most useful feedback\n if (instance.required && attributeValue == null) {\n // If there's a default value, this is less severe, so set a warning and return out\n if (defaultValue != null) {\n console.info(`No biggie, the required prop '${key}' has no value set, so the default has been set`)\n instanceResponse[key] = defaultValue\n } else {\n // If there's no default, this is an error. We'll set the data to be null too\n instanceResponse[key] = null\n console.error(`The required prop '${key}' has no value set`)\n }\n } else {\n // We're all good here, so let's process the data\n // Make sure the data matches the declared type\n switch (instance.type) {\n case String:\n // eslint-disable-next-line default-case-last,no-fallthrough\n default:\n instanceResponse[key] = attributeValue || defaultValue\n break\n case Number:\n instanceResponse[key] = attributeValue != null ? parseFloat(attributeValue) : defaultValue != null ? defaultValue : 0\n break\n case Boolean:\n instanceResponse[key] = attributeValue != null ? attributeValue.toString() === 'true' : defaultValue != null ? defaultValue : false\n break\n case Object:\n try {\n instanceResponse[key] = attributeValue != null ? JSON.parse(attributeValue) : defaultValue != null ? defaultValue : undefined\n } catch (ex) {\n instanceResponse[key] = defaultValue != null ? defaultValue : undefined\n console.error(`An object prop parse issue occurred with prop ${key} and value ${attributeValue}`)\n }\n break\n }\n }\n\n // Set this data in the main response object\n response[key] = instanceResponse[key]\n\n // Override the props data if we have an instanceProp\n if (this._instanceProps && this._instanceProps[key]) {\n response[key] = this._instanceProps[key]\n }\n })\n\n return response\n }\n\n _processMethodsAndComputedProps (props) {\n const self = this\n const keys = Object.keys(props)\n if (!keys.length) return\n // Run through and bind to the component instance\n keys.forEach(key => {\n if (!self[key] && typeof props[key] === 'function') {\n self[key] = props[key].bind(self)\n }\n if (key === 'computed') {\n this._processComputed(props[key])\n }\n })\n }\n\n _processRoot (key) {\n switch (key) {\n case 'standard':\n // eslint-disable-next-line default-case-last,no-fallthrough\n default:\n return this\n case 'shadow':\n return this.attachShadow({ mode: 'open' })\n case 'shadow:closed':\n return this.attachShadow({ mode: 'closed' })\n }\n }\n\n _processComputed (obj) {\n const self = this\n const keys = Object.keys(obj)\n\n // Bail out if there's not any getters\n if (!keys.length) return\n\n // Run through and create a real getter\n keys.forEach(key => {\n if (self[key]) {\n console.warn(`Computed property '${key}' already exists on the component instance`)\n return\n }\n Object.defineProperty(self, key, {\n get () {\n // check the computed cache first\n if (!self.computedCache[key]) {\n self.computedCache[key] = obj[key].bind(self)()\n }\n return self.computedCache[key]\n }\n })\n })\n }\n\n _processRender () {\n // Check if there's a render method and get the result if it does exist\n const template = this.render ? this.render() : undefined\n\n // Nothing to render so bail out\n if (!template) return\n\n // Set the template for rendering\n this.template = template\n\n // Render the template\n this._updateRender()\n }\n\n _processSlots () {\n const children = this.childNodes\n const slots = {\n default: []\n }\n if (children.length > 0) {\n [...children].forEach(child => {\n const to = child.getAttribute ? child.getAttribute('slot') : null\n if (!to) {\n slots.default.push(child)\n } else {\n slots[to] = child\n }\n })\n }\n return slots\n }\n\n _getAttribute (key) {\n try {\n return this.getAttribute(toKebabCase(key))\n } catch (ex) {\n console.error('A get prop error occurred', ex)\n return ''\n }\n }\n\n _processInstanceProps (props) {\n const self = this\n const keys = Object.keys(props)\n // set instance properties for any defined props\n if (props) {\n keys.forEach(key => {\n let existingPropValue\n if (self[key]) {\n existingPropValue = self[key]\n delete self[key]\n }\n Object.defineProperty(self, key, {\n get () {\n if (this._instanceProps && this._instanceProps[key]) {\n return this._instanceProps[key]\n }\n return this.getAttribute(toKebabCase(key))\n },\n set (newValue) {\n if (!this._instanceProps) {\n this._instanceProps = {}\n }\n this._instanceProps[key] = newValue\n\n // set the HTML attribute value\n this.setAttribute(toKebabCase(key), typeof newValue === 'object' ? JSON.stringify(newValue) : newValue.toString())\n\n return true\n },\n enumerable: true\n })\n if (existingPropValue) self[key] = existingPropValue\n })\n }\n }\n\n _preprocess () {\n this.computedCache = {}\n this.props = this._processProps()\n this._processRender()\n }\n\n _updateRender () {\n if (this.template) {\n // is this an async render?\n if (isPromise(this.template)) {\n this.template\n .then(template => {\n this.templateRenderer(template, this.root)\n this._callLifecycleMethods()\n })\n .catch(e => console.error('A component render error occurred', e))\n } else {\n this.templateRenderer(this.template, this.root)\n this._callLifecycleMethods()\n }\n }\n }\n\n _callLifecycleMethods () {\n if (typeof this.mounted === 'function' && !this.isMountedCalled) {\n this.mounted()\n this.isMountedCalled = true\n } else {\n this.isMountedCalled = true\n }\n if (typeof this.updated === 'function' && this.isMountedCalled) {\n this.updated()\n }\n }\n })\n}\n","import { toKebabCase } from './to-kebab-case.mjs'\n\nexport function collateObservedAttrs (props) {\n if (!props) return []\n const oa = []\n const opk = Object.keys(props)\n opk.forEach(k => {\n if (props[k].observed != null && !props[k].observed) return\n oa.push(toKebabCase(k))\n })\n return oa\n}\n","/* global CustomEvent */\n\nexport function emit (elem, name, opts = {}) {\n const defs = {\n bubbles: true,\n cancelable: true,\n composed: false\n }\n const eventOptions = Object.assign({}, defs, opts)\n const e = new CustomEvent(name, {\n bubbles: eventOptions.bubbles,\n cancelable: eventOptions.cancelable,\n composed: eventOptions.composed,\n detail: eventOptions.detail\n })\n return elem.dispatchEvent(e)\n}\n","export function isPromise (obj) {\n return (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'\n}\n","/**\n * Function to use another FicusJS module\n * @param {object} module\n * @param {function} renderer\n * @param {*} args\n * @returns {*}\n */\nexport function use (module, { ...args }) {\n if (module.create && typeof module.create === 'function') {\n return module.create({\n ...args,\n use\n })\n }\n}\n"],"names":["toKebabCase","str","replace","toLowerCase","elementRenderer","what","where","firstChild","removeChild","element","document","createElement","innerHTML","nodeName","Error","appendChild","createCustomElement","tagName","props","observedAttrs","oa","Object","keys","forEach","k","observed","push","collateObservedAttrs","globalThis","customElements","get","define","HTMLElement","observedAttributes","componentTagName","connectedCallback","this","connectedCallbackCount","_checkInit","_preprocess","disconnectedCallback","removed","isRemovedCalled","attributeChangedCallback","propsDidUpdate","isMountedCalled","initialised","_props","_computed","templateRenderer","_init","options","ficusCustomElement","computed","computedCache","status","_processProps","root","_processRoot","slots","_processSlots","render","renderer","template","created","mounted","updated","isCreatedCalled","emit","eventName","data","elem","name","opts","eventOptions","assign","bubbles","cancelable","composed","e","CustomEvent","detail","dispatchEvent","_processMethodsAndComputedProps","_processInstanceProps","response","key","instanceResponse","instance","attributeValue","_getAttribute","defaultValue","default","required","console","info","error","type","String","Number","parseFloat","Boolean","toString","JSON","parse","undefined","ex","_instanceProps","self","length","bind","_processComputed","attachShadow","mode","obj","warn","defineProperty","_processRender","_updateRender","children","childNodes","child","to","getAttribute","existingPropValue","set","newValue","setAttribute","stringify","enumerable","then","_callLifecycleMethods","catch","use","module","args","create"],"mappings":"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"} | ||
| {"version":3,"file":"index.mjs","sources":["../src/util/to-kebab-case.mjs","../src/util/element-renderer.mjs","../src/custom-element.mjs","../src/util/collate-observed-attrs.mjs","../src/util/emit.mjs","../src/util/is-promise.mjs","../src/module.mjs"],"sourcesContent":["export function toKebabCase (str) {\n return str.replace(/([A-Z])/g, '-$1').toLowerCase()\n}\n","export function elementRenderer (what, where) {\n // remove any existing elements\n while (where.firstChild) where.removeChild(where.firstChild)\n\n let element\n if (typeof what === 'string') {\n // create a new in-memory element\n element = document.createElement('div')\n element.innerHTML = what\n } else if (what.nodeName) {\n element = what\n } else {\n throw new Error(`Unable to render ${what}. Have you included a renderer function?`)\n }\n\n // add the element to the DOM\n if (element) where.appendChild(element)\n}\n","import { collateObservedAttrs } from './util/collate-observed-attrs.mjs'\nimport { toKebabCase } from './util/to-kebab-case.mjs'\nimport { isPromise } from './util/is-promise.mjs'\nimport { emit } from './util/emit.mjs'\nimport { elementRenderer } from './util/element-renderer.mjs'\n\nexport function createCustomElement (tagName, props) {\n const key = {\n type: String\n }\n if (props.props['key']) {\n console.warn(`Prop 'key' is a default property on the component instance, you cannot override it.`)\n }\n const observedAttrs = collateObservedAttrs({ ...props.props, key })\n\n globalThis.customElements.get(tagName) ||\n globalThis.customElements.define(\n tagName,\n class FicusComponent extends globalThis.HTMLElement {\n // standard HTMLElement props and lifecycle hooks\n\n static get observedAttributes () {\n return observedAttrs\n }\n\n get componentTagName () {\n return tagName\n }\n\n connectedCallback () {\n if (this.connectedCallbackCount == null) this.connectedCallbackCount = 0\n this.connectedCallbackCount = this.connectedCallbackCount + 1\n this._checkInit()\n this._preprocess()\n }\n\n disconnectedCallback () {\n if (typeof this.removed === 'function') {\n this.removed()\n this.isRemovedCalled = true\n }\n }\n\n attributeChangedCallback () {\n if (this.connectedCallbackCount == null) return\n this._checkInit()\n this._preprocess()\n if (typeof this.propsDidUpdate === 'function' && this.isMountedCalled) {\n this.propsDidUpdate()\n }\n }\n\n // custom props and private methods\n\n get initialised () {\n return this._props && this._computed && this.templateRenderer\n }\n\n _checkInit () {\n if (!this.initialised) {\n this._init(props)\n }\n }\n\n _init (options) {\n // metadata for devtools\n this.ficusCustomElement = tagName\n\n // It's handy to access what was passed through originally, so we'll store in private props\n this._props = { ...(options.props || {}), key }\n this._computed = options.computed || {}\n\n // create a cache for the computed functions\n this.computedCache = {}\n\n // A status enum to set during operations\n this.status = 'render'\n this.connectedCallbackCount = 0\n\n // Run passed props through the props processor\n this.props = this._processProps()\n\n // Determine what our root is. It can be a pointer for `this` or a shadow root\n this.root = this._processRoot(options.root)\n\n // do we have child nodes, if so create them as slots\n this.slots = this._processSlots()\n\n // Pull out a render method if there is one defined\n this.render = options.render || null\n\n // set the default template renderer\n this.templateRenderer = options.renderer || elementRenderer\n\n // Create a template instance we can call with each render\n this.template = null\n\n // Find lifecycle handlers\n this.created = options.created || null\n this.mounted = options.mounted || null\n this.updated = options.updated || null\n this.removed = options.removed || null\n this.propsDidUpdate = options.propsDidUpdate || null\n this.isCreatedCalled = false // ensure callback is only called once\n this.isMountedCalled = false // ensure callback is only called once\n this.isRemovedCalled = false // ensure callback is only called once\n\n // event handlers - the ability to emit an event from the component\n this.emit = (eventName, data) => {\n emit(this, eventName, { detail: data })\n }\n\n // Allow methods and computed properties to be added to this instance\n this._processMethodsAndComputedProps(options)\n\n // create instance properties\n this._processInstanceProps(this._props)\n\n // fire the created method\n if (typeof this.created === 'function' && !this.isCreatedCalled) {\n this.created()\n this.isCreatedCalled = true\n }\n }\n\n _processProps () {\n const response = {}\n\n Object.keys(this._props).forEach(key => {\n const instanceResponse = {}\n const instance = this._props[key]\n const attributeValue = this._getAttribute(key)\n let defaultValue = null\n\n if (instance.default != null) {\n defaultValue = instance.default\n }\n\n // If there's a required attribute with no value we need to do generate the most useful feedback\n if (instance.required && attributeValue == null) {\n // If there's a default value, this is less severe, so set a warning and return out\n if (defaultValue != null) {\n console.info(`No biggie, the required prop '${key}' has no value set, so the default has been set`)\n instanceResponse[key] = defaultValue\n } else {\n // If there's no default, this is an error. We'll set the data to be null too\n instanceResponse[key] = null\n console.error(`The required prop '${key}' has no value set`)\n }\n } else {\n // We're all good here, so let's process the data\n // Make sure the data matches the declared type\n switch (instance.type) {\n case String:\n // eslint-disable-next-line default-case-last,no-fallthrough\n default:\n instanceResponse[key] = attributeValue || defaultValue\n break\n case Number:\n instanceResponse[key] = attributeValue != null ? parseFloat(attributeValue) : defaultValue != null ? defaultValue : 0\n break\n case Boolean:\n instanceResponse[key] = attributeValue != null ? attributeValue.toString() === 'true' : defaultValue != null ? defaultValue : false\n break\n case Object:\n try {\n instanceResponse[key] = attributeValue != null ? JSON.parse(attributeValue) : defaultValue != null ? defaultValue : undefined\n } catch (ex) {\n instanceResponse[key] = defaultValue != null ? defaultValue : undefined\n console.error(`An object prop parse issue occurred with prop ${key} and value ${attributeValue}`)\n }\n break\n }\n }\n\n // Set this data in the main response object\n response[key] = instanceResponse[key]\n\n // Override the props data if we have an instanceProp\n if (this._instanceProps && this._instanceProps[key]) {\n response[key] = this._instanceProps[key]\n }\n })\n\n return response\n }\n\n _processMethodsAndComputedProps (props) {\n const self = this\n const keys = Object.keys(props)\n if (!keys.length) return\n // Run through and bind to the component instance\n keys.forEach(key => {\n if (!self[key] && typeof props[key] === 'function') {\n self[key] = props[key].bind(self)\n }\n if (key === 'computed') {\n this._processComputed(props[key])\n }\n })\n }\n\n _processRoot (key) {\n switch (key) {\n case 'standard':\n // eslint-disable-next-line default-case-last,no-fallthrough\n default:\n return this\n case 'shadow':\n return this.attachShadow({ mode: 'open' })\n case 'shadow:closed':\n return this.attachShadow({ mode: 'closed' })\n }\n }\n\n _processComputed (obj) {\n const self = this\n const keys = Object.keys(obj)\n\n // Bail out if there's not any getters\n if (!keys.length) return\n\n // Run through and create a real getter\n keys.forEach(key => {\n if (self[key]) {\n console.warn(`Computed property '${key}' already exists on the component instance`)\n return\n }\n Object.defineProperty(self, key, {\n get () {\n // check the computed cache first\n if (!self.computedCache[key]) {\n self.computedCache[key] = obj[key].bind(self)()\n }\n return self.computedCache[key]\n }\n })\n })\n }\n\n _processRender () {\n // Check if there's a render method and get the result if it does exist\n const template = this.render ? this.render() : undefined\n\n // Nothing to render so bail out\n if (!template) return\n\n // Set the template for rendering\n this.template = template\n\n // Render the template\n this._updateRender()\n }\n\n _processSlots () {\n const children = this.childNodes\n const slots = {\n default: []\n }\n if (children.length > 0) {\n [...children].forEach(child => {\n const to = child.getAttribute ? child.getAttribute('slot') : null\n if (!to) {\n slots.default.push(child)\n } else {\n slots[to] = child\n }\n })\n }\n return slots\n }\n\n _getAttribute (key) {\n try {\n return this.getAttribute(toKebabCase(key))\n } catch (ex) {\n console.error('A get prop error occurred', ex)\n return ''\n }\n }\n\n _processInstanceProps (props) {\n const self = this\n const keys = Object.keys(props)\n // set instance properties for any defined props\n if (props) {\n keys.forEach(key => {\n let existingPropValue\n if (self[key]) {\n existingPropValue = self[key]\n delete self[key]\n }\n Object.defineProperty(self, key, {\n get () {\n if (this._instanceProps && this._instanceProps[key]) {\n return this._instanceProps[key]\n }\n return this.getAttribute(toKebabCase(key))\n },\n set (newValue) {\n if (!this._instanceProps) {\n this._instanceProps = {}\n }\n this._instanceProps[key] = newValue\n\n // set the HTML attribute value\n this.setAttribute(toKebabCase(key), typeof newValue === 'object' ? JSON.stringify(newValue) : newValue.toString())\n\n return true\n },\n enumerable: true\n })\n if (existingPropValue) self[key] = existingPropValue\n })\n }\n }\n\n _preprocess () {\n this.computedCache = {}\n this.props = this._processProps()\n this._processRender()\n }\n\n _updateRender () {\n if (this.template) {\n // is this an async render?\n if (isPromise(this.template)) {\n this.template\n .then(template => {\n this.templateRenderer(template, this.root)\n this._callLifecycleMethods()\n })\n .catch(e => console.error('A component render error occurred', e))\n } else {\n this.templateRenderer(this.template, this.root)\n this._callLifecycleMethods()\n }\n }\n }\n\n _callLifecycleMethods () {\n if (typeof this.mounted === 'function' && !this.isMountedCalled) {\n this.mounted()\n this.isMountedCalled = true\n } else {\n this.isMountedCalled = true\n }\n if (typeof this.updated === 'function' && this.isMountedCalled) {\n this.updated()\n }\n }\n })\n}\n","import { toKebabCase } from './to-kebab-case.mjs'\n\nexport function collateObservedAttrs (props) {\n if (!props) return []\n const oa = []\n const opk = Object.keys(props)\n opk.forEach(k => {\n if (props[k].observed != null && !props[k].observed) return\n oa.push(toKebabCase(k))\n })\n return oa\n}\n","/* global CustomEvent */\n\nexport function emit (elem, name, opts = {}) {\n const defs = {\n bubbles: true,\n cancelable: true,\n composed: false\n }\n const eventOptions = Object.assign({}, defs, opts)\n const e = new CustomEvent(name, {\n bubbles: eventOptions.bubbles,\n cancelable: eventOptions.cancelable,\n composed: eventOptions.composed,\n detail: eventOptions.detail\n })\n return elem.dispatchEvent(e)\n}\n","export function isPromise (obj) {\n return (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'\n}\n","/**\n * Function to use another FicusJS module\n * @param {object} module\n * @param {function} renderer\n * @param {*} args\n * @returns {*}\n */\nexport function use (module, { ...args }) {\n if (module.create && typeof module.create === 'function') {\n return module.create({\n ...args,\n use\n })\n }\n}\n"],"names":["toKebabCase","str","replace","toLowerCase","elementRenderer","what","where","firstChild","removeChild","element","document","createElement","innerHTML","nodeName","Error","appendChild","createCustomElement","tagName","props","key","type","String","console","warn","observedAttrs","oa","Object","keys","forEach","k","observed","push","collateObservedAttrs","globalThis","customElements","get","define","HTMLElement","observedAttributes","componentTagName","connectedCallback","this","connectedCallbackCount","_checkInit","_preprocess","disconnectedCallback","removed","isRemovedCalled","attributeChangedCallback","propsDidUpdate","isMountedCalled","initialised","_props","_computed","templateRenderer","_init","options","ficusCustomElement","computed","computedCache","status","_processProps","root","_processRoot","slots","_processSlots","render","renderer","template","created","mounted","updated","isCreatedCalled","emit","eventName","data","elem","name","opts","eventOptions","assign","bubbles","cancelable","composed","e","CustomEvent","detail","dispatchEvent","_processMethodsAndComputedProps","_processInstanceProps","response","instanceResponse","instance","attributeValue","_getAttribute","defaultValue","default","required","info","error","Number","parseFloat","Boolean","toString","JSON","parse","undefined","ex","_instanceProps","self","length","bind","_processComputed","attachShadow","mode","obj","defineProperty","_processRender","_updateRender","children","childNodes","child","to","getAttribute","existingPropValue","set","newValue","setAttribute","stringify","enumerable","then","_callLifecycleMethods","catch","use","module","args","create"],"mappings":"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"} |
+3
-3
| { | ||
| "name": "@ficusjs/core", | ||
| "version": "2.1.1", | ||
| "version": "3.0.0", | ||
| "description": "Core functions for FicusJS", | ||
@@ -50,3 +50,3 @@ "type": "module", | ||
| "c8": "7.12.0", | ||
| "cypress": "10.11.0", | ||
| "cypress": "11.0.1", | ||
| "http-server": "14.1.1", | ||
@@ -60,3 +60,3 @@ "jsdom": "20.0.2", | ||
| "rollup-plugin-terser": "7.0.2", | ||
| "sinon": "14.0.1", | ||
| "sinon": "14.0.2", | ||
| "standard": "16.0.4", | ||
@@ -63,0 +63,0 @@ "start-server-and-test": "1.14.0" |
@@ -8,3 +8,9 @@ import { collateObservedAttrs } from './util/collate-observed-attrs.mjs' | ||
| export function createCustomElement (tagName, props) { | ||
| const observedAttrs = collateObservedAttrs(props.props) | ||
| const key = { | ||
| type: String | ||
| } | ||
| if (props.props['key']) { | ||
| console.warn(`Prop 'key' is a default property on the component instance, you cannot override it.`) | ||
| } | ||
| const observedAttrs = collateObservedAttrs({ ...props.props, key }) | ||
@@ -65,3 +71,3 @@ globalThis.customElements.get(tagName) || | ||
| // It's handy to access what was passed through originally, so we'll store in private props | ||
| this._props = options.props || {} | ||
| this._props = { ...(options.props || {}), key } | ||
| this._computed = options.computed || {} | ||
@@ -68,0 +74,0 @@ |
73352
1.69%469
1.52%