diff --git a/src/auro-hyperlink.js b/src/auro-hyperlink.js index 30d7415..94d0c1b 100644 --- a/src/auro-hyperlink.js +++ b/src/auro-hyperlink.js @@ -13,21 +13,21 @@ import styleCss from "./style-css.js"; // See https://git.io/JJ6SJ for "How to document your components using JSDoc" /** - * `` is a wrapper components for an HTML `` element containing styling and behavior. + * `` is a component that wraps an HTML `` element, providing additional styling and behavior. * - * @attr {Boolean} download - Specifies that the target will be downloaded when a user clicks on the hyperlink. - * @attr {Boolean} fluid - Modifier for `type="cta"` fluid-width UI option. - * @attr {Boolean} ondark - Specifies dark theme use of hyperlink. - * @attr {Boolean} relative - Add flag to disable auto URL re-write feature. - * @attr {Boolean} secondary - Modifier for `type="cta"` secondary UI option. - * @attr {Boolean} small - Modifier for `type="cta"` small UI option. - * @attr {Boolean} referrerpolicy - Sets `strict-origin-when-cross-origin` to send a full URL when performing a same-origin request, only sends the origin when the protocol security level stays the same (HTTPS→HTTPS), and sends no header to a less secure destination (HTTPS→HTTP). - * @attr {String} rel - Specifies the relationship between the current document and the linked document. - * @attr {String} role - Use for aria roles; currently supports `button` for extended experiences. - * @attr {String} href - Specifies the URL of the page link. - * @attr {String} target - Specifies where to open the linked document. - * @attr {String} type - Enumerable attribute; [`nav`, `cta`] - * @csspart link - Apply CSS to the `a` element + * @attr {Boolean} download - If true, the linked resource will be downloaded when the hyperlink is clicked. + * @attr {Boolean} fluid - If true and `type="cta"`, the hyperlink will have a fluid-width UI. + * @attr {Boolean} ondark - If true, the hyperlink will be styled for use on a dark background. + * @attr {Boolean} relative - If true, the auto URL re-write feature will be disabled. + * @attr {Boolean} secondary - If true and `type="cta"`, the hyperlink will have a secondary UI. + * @attr {Boolean} small - If true and `type="cta"`, the hyperlink will have a small UI. + * @attr {Boolean} referrerpolicy - If true, sets `strict-origin-when-cross-origin` to control the referrer information sent with requests. + * @attr {String} rel - Defines the relationship between the current document and the linked document. + * @attr {String} role - Defines ARIA roles; currently supports `button` for extended experiences. + * @attr {String} href - Defines the URL of the linked page. + * @attr {String} target - Defines where to open the linked document. + * @attr {String} type - Defines the type of hyperlink; accepts `nav` or `cta`. + * @csspart link - Allows styling to be applied to the `a` element. */ // build the component class @@ -44,8 +44,18 @@ export class AuroHyperlink extends ComponentBase { } /** + * Generates an object containing CSS classes based on the properties of the component. + * + * @example + * // Assuming this.safeUri = 'http://example.com', this.role = 'button', this.type = 'cta' + * this.getMarkup(); // Returns { 'hyperlink': true, 'hyperlink--nav': false, 'hyperlink--ondark': false, 'hyperlink--button': true, 'hyperlink--cta': true, 'hyperlink--secondary': false } + * + * @example + * // Assuming this.safeUri = '', this.role = '', this.type = 'nav', this.ondark = true, this.secondary = true + * this.getMarkup(); // Returns { 'hyperlink': false, 'hyperlink--nav': true, 'hyperlink--ondark': true, 'hyperlink--button': false, 'hyperlink--cta': false, 'hyperlink--secondary': true } + * * @private - * @returns {object} Classes object. + * @returns {object} An object containing CSS classes. */ getMarkup() { const classes = { diff --git a/src/component-base.mjs b/src/component-base.mjs index 351d732..8d554e5 100644 --- a/src/component-base.mjs +++ b/src/component-base.mjs @@ -66,32 +66,68 @@ export default class ComponentBase extends LitElement { } /** - * Gets the safe URI. + * Returns a safe URI based on the provided `href` and `relative` parameters. + * If `href` is truthy, it generates a safe URL using the `safeUrl` function. + * Otherwise, it returns an empty string. * - * @private - * @type {string} + * @example + * // Assuming this.href = 'http://example.com' and this.relative = false + * this.safeUri; // Returns 'http://example.com' + * + * @example + * // Assuming this.href = '' or this.href = null + * this.safeUri; // Returns '' + * + * @returns {string} The safe URI or an empty string. */ get safeUri() { return this.href ? this.safeUrl(this.href, this.relative) : ''; } /** - * Checks if the safe URI includes a domain. + * Checks whether the provided URI (if available) includes the 'http' protocol. + * If the URI is truthy, it examines whether it contains 'http'. + * Otherwise, it returns false. + * + * @example + * // Assuming this.href = 'http://example.com' + * this.includesDomain; // Returns true + * + * @example + * // Assuming this.href = '/path/to/file' + * this.includesDomain; // Returns false + * + * @example + * // Assuming this.href = '' or this.href = null + * this.includesDomain; // Returns false * * @private - * @type {boolean} + * @returns {boolean} True if the URI includes 'http', false otherwise. */ get includesDomain() { return this.href ? this.safeUri.includes('http') : false; } /** - * Safely processes a URL. + * Generates a safe URL based on the provided `href` and `relative` parameters. + * If `href` is falsy, it returns `undefined`. + * + * @example + * // Assuming href = 'http://example.com' and relative = false + * this.safeUrl(href, relative); // Returns 'https://example.com' + * + * @example + * // Assuming href = '/path/to/file' and relative = true + * this.safeUrl(href, relative); // Returns '/path/to/file' + * + * @example + * // Assuming href = 'javascript:alert("Hello")' + * this.safeUrl(href, relative); // Returns undefined * * @private - * @param {string} href - The URL to be processed. + * @param {string} href - The original URL. * @param {boolean} relative - Indicates whether the URL is relative. - * @returns {string|undefined} The processed URL or undefined if the URL is invalid or if JavaScript is used. + * @returns {string|undefined} The safe URL or `undefined`. */ safeUrl(href, relative) { if (!href) { @@ -124,11 +160,15 @@ export default class ComponentBase extends LitElement { /** - * Generates an HTML element containing SVG content. + * Generates an HTML element containing an SVG icon based on the provided `svgContent`. + * + * @example + * // Assuming svgContent = '' + * this.generateIconHtml(svgContent); // Returns HTML element containing the SVG icon * * @private - * @param {string} svgContent - The SVG content to be parsed. - * @returns {HTMLElement} The HTML element containing the parsed SVG content. + * @param {string} svgContent - The SVG content to be embedded. + * @returns {Element} The HTML element containing the SVG icon. */ generateIconHtml(svgContent) { const dom = new DOMParser().parseFromString(svgContent, 'text/html'), @@ -140,6 +180,18 @@ export default class ComponentBase extends LitElement { /** * Generates an icon HTML element based on the target attribute. * + * @example + * // Assuming target = '_blank' and this.safeUri = 'http://alaskaair.com' + * this.targetIcon(target); // Returns HTML element containing the new window icon + * + * @example + * // Assuming target = '_blank' and this.safeUri = 'http://external.com' + * this.targetIcon(target); // Returns HTML element containing the external link icon + * + * @example + * // Assuming target = '_self' or this.safeUri = '/relative/path' + * this.targetIcon(target); // Returns undefined + * * @private * @param {string} target - The target attribute of the anchor element. * @returns {HTMLElement|undefined} The HTML element containing the icon, or undefined if no icon is generated. @@ -168,11 +220,19 @@ export default class ComponentBase extends LitElement { } /** - * Gets the state of a tab. + * Returns the state of a tab as a string. + * + * @example + * // Assuming tabisActive = true + * this.getTabState(tabisactive); // Returns 'is-active' + * + * @example + * // Assuming tabisActive = false + * this.getTabState(tabisactive); // Returns '' * * @private * @param {boolean} tabisActive - Indicates whether the tab is active. - * @returns {string} The state of the tab, either "is-active" if active or an empty string if not active. + * @returns {string} 'is-active' if the tab is active, otherwise an empty string. */ getTabState(tabisactive) { return tabisactive === true ? "is-active" : ''; @@ -181,6 +241,22 @@ export default class ComponentBase extends LitElement { /** * Gets the rel attribute value based on target and rel values. * + * @example + * // Assuming target = '_blank', rel = 'nofollow', and this.safeUri = 'http://alaskaair.com' + * this.getReltype(target, rel); // Returns 'nofollow' + * + * @example + * // Assuming target = '_blank', rel = undefined, this.safeUri = 'http://alaskaair.com', and this.includesDomain = true + * this.getReltype(target, rel); // Returns undefined + * + * @example + * // Assuming target = '_blank', rel = undefined, this.safeUri = 'http://external.com', this.includesDomain = true, and this.referrerpolicy = undefined + * this.getReltype(target, rel); // Returns 'noopener noreferrer' + * + * @example + * // Assuming target = '_blank', rel = undefined, this.safeUri = 'http://external.com', this.includesDomain = true, and this.referrerpolicy = 'no-referrer' + * this.getReltype(target, rel); // Returns 'external' + * * @private * @param {string} target - The target attribute of the anchor element. * @param {string} rel - The rel attribute of the anchor element. @@ -210,8 +286,24 @@ export default class ComponentBase extends LitElement { /** * Sets the ARIA pressed state based on user interactions. * + * @example + * // Assuming ariapressed = false and user performs a mousedown event + * this.ariaPressedState(ariapressed); // Returns true + * + * @example + * // Assuming ariapressed = true and user performs a mouseup event + * this.ariaPressedState(ariapressed); // Returns false + * + * @example + * // Assuming ariapressed = false and user performs a keydown event with 'Enter' or 'Space' + * this.ariaPressedState(ariapressed); // Returns true + * + * @example + * // Assuming ariapressed = true and user performs a keyup event + * this.ariaPressedState(ariapressed); // Returns false + * * @private - * @param {boolean} ariaPressed - The initial value of the ARIA pressed state. + * @param {boolean} ariapressed - The initial value of the ARIA pressed state. * @returns {boolean} The updated ARIA pressed state. */ ariaPressedState(ariapressed) { @@ -234,7 +326,7 @@ export default class ComponentBase extends LitElement { } }; - // Add our event listeners + // Add event listeners this.addEventListener('mousedown', ariaToggle); this.addEventListener('mouseup', ariaToggle); this.addEventListener('keydown', ariaToggle); @@ -243,7 +335,7 @@ export default class ComponentBase extends LitElement { return ariapressed; } - // function that renders the HTML and CSS into the scope of the component + // function renders HTML and CSS into the scope of the component render() { return html` ${this.getMarkup()}