@3share/ui-component
Version:
A simple helper Class to save time while creating component registrations and DOM references to internal element using the Adobe's approach with `data-cmp-is="Somecomponent` and the reference with hooks `data-cmp-hook-somecomponent="nameOfElement"`.
116 lines • 3.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Component = void 0;
exports.descriptor = descriptor;
/**
* Abstract class for managing repetitive definitions and initialization tasks in components.
*
* This abstract class provides a standardized structure for managing component initialization
* and DOM element caching.
*
* @public $cmp - The root HTMLElement representing the component.
* @public $elements - An object containing cached DOM elements accessed by their hooks.
*
* @example
* // Component Markup Example
* // HTML:
* // <div data-cmp-is="ClassNameHandler">
* // <button data-cmp-hook-class-name-handler="hookname">Button</button>
* // </div>
* //
* // JavaScript:
* // class MyComponent extends Component {
* // constructor(cmp) {
* // super(cmp);
* // console.log(this.$elements.hookname); // Access the cached DOM node
* // }
* // }
*
* @abstract
*/
class Component {
/**
* Creates an instance of Component.
* @param {Element} cmp The root element of the component.
*/
constructor(cmp) {
var _a;
/**
* The name of the HTML element.
* @private
*/
this.elementName = '';
/**
* The name of the HTML element with dashes.
* @private
*/
this.elementDashName = '';
this.$cmp = cmp;
if (this.$cmp instanceof HTMLElement) {
this.elementName = this.$cmp.dataset['cmpIs']
? (_a = this.$cmp) === null || _a === void 0 ? void 0 : _a.dataset['cmpIs']
: '';
this.elementDashName = this.elementName
.split(/(?=[A-Z])/)
.join('-')
.toLowerCase();
this.initialize();
this.cacheElements();
}
}
/**
* Prevents multiple initializations.
* @private
*/
initialize() {
this.$cmp.removeAttribute('data-cmp-is');
this.$cmp.setAttribute('cmp-initialized', 'true');
}
/**
* Stores the hooked DOM elements and attaches them to the $elements Object.
* @private
*/
cacheElements() {
const hooks = this.$cmp.querySelectorAll(`[data-cmp-hook-${this.elementDashName}]`);
if (hooks.length === 0) {
return;
}
Array.from(hooks).forEach((hook) => {
var _a, _b, _c;
if (!(hook instanceof HTMLElement)) {
return;
}
const capitalized = `${(_a = this.elementName) === null || _a === void 0 ? void 0 : _a.charAt(0).toUpperCase()}${(_b = this.elementName) === null || _b === void 0 ? void 0 : _b.slice(1)}`;
const key = hook.dataset[`${Component.CMP_HOOK}${capitalized}`] || '';
if ((key === null || key === void 0 ? void 0 : key.length) === 0) {
return;
}
// Lazily initialize $elements if a key is found
if (!this.$elements) {
this.$elements = {};
}
if (this.$elements[key]) {
(_c = this.$elements[key]) === null || _c === void 0 ? void 0 : _c.push(hook);
}
else {
this.$elements[key] = [hook];
}
});
}
}
exports.Component = Component;
/**
* The prefix for data attributes used to identify component hooks.
* @private
* @readonly
*/
Component.CMP_HOOK = 'cmpHook';
function descriptor({ selector }) {
return (target) => {
const $cmp = document.querySelectorAll(selector);
Array.from($cmp).forEach((element) => {
const component = new target(element);
});
};
}
//# sourceMappingURL=ui-component.js.map