From b8e23fad5f16ab534fd270d8080102b63fff6566 Mon Sep 17 00:00:00 2001 From: Eunsun Mota Date: Wed, 6 Nov 2024 22:09:56 -0500 Subject: [PATCH] feat(api): add register static method #21 - `AuroForm.register` is to easily register the element without extra importing - `import '@aurodesignsystem/auro-form'` will still register this element to `` - `import { AuroForm } from '../src/auro-form'` wont register this element until `AuroForm.register` gets called --- components/form/demo/api.js | 4 +- components/form/demo/api.min.js | 87 +++++++++++++++++++++++-- components/form/demo/index.js | 5 +- components/form/demo/index.min.js | 88 ++++++++++++++++++++++++-- components/form/docs/partials/demo.md | 9 +-- components/form/src/auro-form.js | 19 ++++-- components/form/src/index.js | 14 +--- components/form/test/auro-form.test.js | 2 +- index.js | 1 + 9 files changed, 196 insertions(+), 33 deletions(-) diff --git a/components/form/demo/api.js b/components/form/demo/api.js index 0c6115a0..bfeed480 100644 --- a/components/form/demo/api.js +++ b/components/form/demo/api.js @@ -1 +1,3 @@ -import '../src/index.js'; +import { AuroForm } from "../src/auro-form.js" + +AuroForm.register(); diff --git a/components/form/demo/api.min.js b/components/form/demo/api.min.js index 3e50bfb4..3071a5f1 100644 --- a/components/form/demo/api.min.js +++ b/components/form/demo/api.min.js @@ -26,6 +26,76 @@ const t=globalThis,i$1=t.trustedTypes,s=i$1?i$1.createPolicy("lit-html",{createH var styleCss = i$3`*,*:before,*:after{box-sizing:border-box}@media(prefers-reduced-motion: reduce){*,*:before,*:after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important}}*:focus-visible{outline:0}*:focus-visible{outline:0}:focus:not(:focus-visible){outline:3px solid transparent}.testClass{display:inline-block;padding:var(--auro-text-body-size-default);border:1px solid var(--auro-color-border-error-on-light);color:var(--auro-color-border-error-on-light)}:focus-visible{background-color:var(--auro-color-border-error-on-light);color:var(--auro-color-base-white)}`; +// Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license +// See LICENSE in the project root for license information. + +// --------------------------------------------------------------------- + +/* eslint-disable line-comment-position, no-inline-comments, no-confusing-arrow, no-nested-ternary, implicit-arrow-linebreak */ + +class AuroLibraryRuntimeUtils { + + /* eslint-disable jsdoc/require-param */ + + /** + * This will register a new custom element with the browser. + * @param {String} name - The name of the custom element. + * @param {Object} componentClass - The class to register as a custom element. + * @returns {void} + */ + registerComponent(name, componentClass) { + if (!customElements.get(name)) { + customElements.define(name, class extends componentClass {}); + } + } + + /** + * Finds and returns the closest HTML Element based on a selector. + * @returns {void} + */ + closestElement( + selector, // selector like in .closest() + base = this, // extra functionality to skip a parent + __Closest = (el, found = el && el.closest(selector)) => + !el || el === document || el === window + ? null // standard .closest() returns null for non-found selectors also + : found + ? found // found a selector INside this element + : __Closest(el.getRootNode().host) // recursion!! break out to parent DOM + ) { + return __Closest(base); + } + /* eslint-enable jsdoc/require-param */ + + /** + * If the element passed is registered with a different tag name than what is passed in, the tag name is added as an attribute to the element. + * @param {Object} elem - The element to check. + * @param {String} tagName - The name of the Auro component to check for or add as an attribute. + * @returns {void} + */ + handleComponentTagRename(elem, tagName) { + const tag = tagName.toLowerCase(); + const elemTag = elem.tagName.toLowerCase(); + + if (elemTag !== tag) { + elem.setAttribute(tag, true); + } + } + + /** + * Validates if an element is a specific Auro component. + * @param {Object} elem - The element to validate. + * @param {String} tagName - The name of the Auro component to check against. + * @returns {Boolean} - Returns true if the element is the specified Auro component. + */ + elementMatch(elem, tagName) { + const tag = tagName.toLowerCase(); + const elemTag = elem.tagName.toLowerCase(); + + return elemTag === tag || elem.hasAttribute(tag); + } +} + // Copyright (c) 2024 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license // See LICENSE in the project root for license information. @@ -60,6 +130,18 @@ class AuroForm extends r { return [styleCss]; } + /** + * This will register this element with the browser. + * @param {string} [name="auro-form"] - The name of element that you want to register to. + * + * @example + * AuroForm.register("custom-form") // this will register this element to + * + */ + static register(name = "auro-form") { + AuroLibraryRuntimeUtils.prototype.registerComponent(name, AuroForm); + } + // When using auroElement, use the following attribute and function when hiding content from screen readers. // aria-hidden="${this.hideAudible(this.hiddenAudible)}" @@ -75,7 +157,4 @@ class AuroForm extends r { } } -// default internal definition -if (!customElements.get("auro-form")) { - customElements.define("auro-form", AuroForm); -} +AuroForm.register(); diff --git a/components/form/demo/index.js b/components/form/demo/index.js index 0c6115a0..4a9d9856 100644 --- a/components/form/demo/index.js +++ b/components/form/demo/index.js @@ -1 +1,4 @@ -import '../src/index.js'; +import { AuroForm } from '../src/auro-form.js'; + +AuroForm.register(); +AuroForm.register('custom-form'); diff --git a/components/form/demo/index.min.js b/components/form/demo/index.min.js index 3e50bfb4..4970d7a0 100644 --- a/components/form/demo/index.min.js +++ b/components/form/demo/index.min.js @@ -26,6 +26,76 @@ const t=globalThis,i$1=t.trustedTypes,s=i$1?i$1.createPolicy("lit-html",{createH var styleCss = i$3`*,*:before,*:after{box-sizing:border-box}@media(prefers-reduced-motion: reduce){*,*:before,*:after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important}}*:focus-visible{outline:0}*:focus-visible{outline:0}:focus:not(:focus-visible){outline:3px solid transparent}.testClass{display:inline-block;padding:var(--auro-text-body-size-default);border:1px solid var(--auro-color-border-error-on-light);color:var(--auro-color-border-error-on-light)}:focus-visible{background-color:var(--auro-color-border-error-on-light);color:var(--auro-color-base-white)}`; +// Copyright (c) Alaska Air. All right reserved. Licensed under the Apache-2.0 license +// See LICENSE in the project root for license information. + +// --------------------------------------------------------------------- + +/* eslint-disable line-comment-position, no-inline-comments, no-confusing-arrow, no-nested-ternary, implicit-arrow-linebreak */ + +class AuroLibraryRuntimeUtils { + + /* eslint-disable jsdoc/require-param */ + + /** + * This will register a new custom element with the browser. + * @param {String} name - The name of the custom element. + * @param {Object} componentClass - The class to register as a custom element. + * @returns {void} + */ + registerComponent(name, componentClass) { + if (!customElements.get(name)) { + customElements.define(name, class extends componentClass {}); + } + } + + /** + * Finds and returns the closest HTML Element based on a selector. + * @returns {void} + */ + closestElement( + selector, // selector like in .closest() + base = this, // extra functionality to skip a parent + __Closest = (el, found = el && el.closest(selector)) => + !el || el === document || el === window + ? null // standard .closest() returns null for non-found selectors also + : found + ? found // found a selector INside this element + : __Closest(el.getRootNode().host) // recursion!! break out to parent DOM + ) { + return __Closest(base); + } + /* eslint-enable jsdoc/require-param */ + + /** + * If the element passed is registered with a different tag name than what is passed in, the tag name is added as an attribute to the element. + * @param {Object} elem - The element to check. + * @param {String} tagName - The name of the Auro component to check for or add as an attribute. + * @returns {void} + */ + handleComponentTagRename(elem, tagName) { + const tag = tagName.toLowerCase(); + const elemTag = elem.tagName.toLowerCase(); + + if (elemTag !== tag) { + elem.setAttribute(tag, true); + } + } + + /** + * Validates if an element is a specific Auro component. + * @param {Object} elem - The element to validate. + * @param {String} tagName - The name of the Auro component to check against. + * @returns {Boolean} - Returns true if the element is the specified Auro component. + */ + elementMatch(elem, tagName) { + const tag = tagName.toLowerCase(); + const elemTag = elem.tagName.toLowerCase(); + + return elemTag === tag || elem.hasAttribute(tag); + } +} + // Copyright (c) 2024 Alaska Airlines. All right reserved. Licensed under the Apache-2.0 license // See LICENSE in the project root for license information. @@ -60,6 +130,18 @@ class AuroForm extends r { return [styleCss]; } + /** + * This will register this element with the browser. + * @param {string} [name="auro-form"] - The name of element that you want to register to. + * + * @example + * AuroForm.register("custom-form") // this will register this element to + * + */ + static register(name = "auro-form") { + AuroLibraryRuntimeUtils.prototype.registerComponent(name, AuroForm); + } + // When using auroElement, use the following attribute and function when hiding content from screen readers. // aria-hidden="${this.hideAudible(this.hiddenAudible)}" @@ -75,7 +157,5 @@ class AuroForm extends r { } } -// default internal definition -if (!customElements.get("auro-form")) { - customElements.define("auro-form", AuroForm); -} +AuroForm.register(); +AuroForm.register('custom-form'); diff --git a/components/form/docs/partials/demo.md b/components/form/docs/partials/demo.md index 1cb0bf37..9547c642 100644 --- a/components/form/docs/partials/demo.md +++ b/components/form/docs/partials/demo.md @@ -44,13 +44,14 @@ Having a closing statement about your example helps to really complete the thoug ## Recommended Use and Version Control -There are two important parts of every Auro component. The class and the custom clement. The class is exported and then used as part of defining the Web Component. When importing this component as described in the install section, the class is imported and the `auro-form` custom element is defined automatically. +There are two important parts of every Auro component. The class and the custom element. The class is exported and then used as part of defining the Web Component. When importing this component as described in the install section, the class is imported and the `auro-form` custom element is defined automatically. -To protect from versioning conflicts with other instances of the component being loaded, it is recommended to use our `registerComponent(name)` method and pass in a unique name. +To protect from versioning conflicts with other instances of the component being loaded, it is recommended to use our `AuroForm.register(name)` method and pass in a unique name. ```js -import './node_modules/@aurodesignsystem/auro-form'; -registerComponent('custom-form'); +import { AuroForm } from './node_modules/@aurodesignsystem/auro-form/src/auro-form'; + +AuroForm.register('custom-form'); ``` This will create a new custom element that you can use in your HTML that will function identically to the `auro-form` element. diff --git a/components/form/src/auro-form.js b/components/form/src/auro-form.js index 8eb26468..cc58b89b 100644 --- a/components/form/src/auro-form.js +++ b/components/form/src/auro-form.js @@ -14,6 +14,8 @@ import { LitElement, html } from "lit"; // Import touch detection lib import styleCss from "./styles/style-css.js"; +import AuroLibraryRuntimeUtils from '@aurodesignsystem/auro-library/scripts/utils/runtimeUtils.mjs'; + // See https://git.io/JJ6SJ for "How to document your components using JSDoc" /** * The auro-form element provides users a way to ... (it would be great if you fill this out). @@ -44,6 +46,18 @@ export class AuroForm extends LitElement { return [styleCss]; } + /** + * This will register this element with the browser. + * @param {string} [name="auro-form"] - The name of element that you want to register to. + * + * @example + * AuroForm.register("custom-form") // this will register this element to + * + */ + static register(name = "auro-form") { + AuroLibraryRuntimeUtils.prototype.registerComponent(name, AuroForm); + } + // When using auroElement, use the following attribute and function when hiding content from screen readers. // aria-hidden="${this.hideAudible(this.hiddenAudible)}" @@ -58,8 +72,3 @@ export class AuroForm extends LitElement { `; } } - -// default internal definition -if (!customElements.get("auro-form")) { - customElements.define("auro-form", AuroForm); -} diff --git a/components/form/src/index.js b/components/form/src/index.js index 9a58b5b9..5ebb157b 100644 --- a/components/form/src/index.js +++ b/components/form/src/index.js @@ -1,15 +1,3 @@ import { AuroForm } from './auro-form.js'; -/** - * Register Custom Element. - * @param {Object} name - Name to use for custom element. - * @returns {void} - */ -const registerComponent = (name = 'custom-form') => { - // alias definition - if (!customElements.get(name)) { - customElements.define(name, class extends AuroForm {}); - } -}; - -export { registerComponent }; +AuroForm.register(); diff --git a/components/form/test/auro-form.test.js b/components/form/test/auro-form.test.js index dace4dfd..e82de3f1 100644 --- a/components/form/test/auro-form.test.js +++ b/components/form/test/auro-form.test.js @@ -1,5 +1,5 @@ import { fixture, html, expect } from '@open-wc/testing'; -import '../src/auro-form'; +import '../src/index.js'; describe('auro-form', () => { it('sets the CSS class on auro-form > div element', async () => { diff --git a/index.js b/index.js index 3d2e1b30..7e198b90 100644 --- a/index.js +++ b/index.js @@ -4,3 +4,4 @@ import './components/checkbox/src/index.js'; import './components/input/src/index.js'; +import './components/form/src/index.js';