UNPKG

standards-ui

Version:

A foundational design system built with native Web Components. Includes comprehensive TypeScript types, JSDoc documentation, and component examples.

215 lines (188 loc) 6.54 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: ds-option.js</title> <script src="scripts/prettify/prettify.js"> </script> <script src="scripts/prettify/lang-css.js"> </script> <!--[if lt IE 9]> <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script> <![endif]--> <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css"> <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css"> </head> <body> <div id="main"> <h1 class="page-title">Source: ds-option.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>/** * @file ds-option.js * @summary A custom Web Component that wraps a native `&lt;option>` element. * @description * The `ds-option` component provides a styled and functional option element * for use within `&lt;ds-select>` components. It maintains proper option behavior * and can be used as an alternative to native `&lt;option>` elements. * * @element ds-option * @extends BaseComponent * * @attr {string} value - The value of the option when selected. * @attr {boolean} disabled - If present, the option cannot be selected. * @attr {boolean} selected - If present, the option is pre-selected. * * @property {string} value - Gets or sets the value of the option. * @property {boolean} selected - Gets or sets the selected state of the option. * @property {boolean} disabled - Gets or sets the disabled state of the option. * * @fires change - Fired when the option selection changes. * * @slot - Renders the option text content. * * @example * &lt;!-- Basic option --> * &lt;ds-option value="option1">Option 1&lt;/ds-option> * * @example * &lt;!-- Pre-selected option --> * &lt;ds-option value="default" selected>Default Option&lt;/ds-option> * * @example * &lt;!-- Disabled option --> * &lt;ds-option value="disabled" disabled>Disabled Option&lt;/ds-option> * * @example * &lt;!-- Usage within ds-select --> * &lt;ds-select name="category"> * &lt;ds-option value="electronics">Electronics&lt;/ds-option> * &lt;ds-option value="clothing">Clothing&lt;/ds-option> * &lt;ds-option value="books">Books&lt;/ds-option> * &lt;/ds-select> */ import BaseComponent from './base-component.js'; class DsOption extends BaseComponent { constructor() { // ARIA config for ds-option const ariaConfig = { staticAriaAttributes: {}, dynamicAriaAttributes: [ 'aria-label', 'aria-describedby' ], requiredAriaAttributes: [], referenceAttributes: ['aria-describedby'], }; const template = document.createElement('template'); template.innerHTML = ` &lt;style> @import url('/src/styles/styles.css'); :host { display: none; /* Hidden by default, shown when slotted into select */ } &lt;/style> &lt;div> &lt;option part="option"> &lt;slot>&lt;/slot> &lt;/option> &lt;/div> `; super({ template: template.innerHTML, targetSelector: 'option', ariaConfig, events: [], observedAttributes: ['value', 'disabled', 'selected'] }); this.option = this.shadowRoot.querySelector('option'); } static get observedAttributes() { return ['value', 'disabled', 'selected', 'aria-label', 'aria-describedby']; } attributeChangedCallback(name, oldValue, newValue) { super.attributeChangedCallback(name, oldValue, newValue); if (oldValue === newValue) return; switch (name) { case 'value': this.option.value = newValue || ''; break; case 'disabled': this.option.disabled = this.hasAttribute('disabled'); break; case 'selected': this.option.selected = this.hasAttribute('selected'); break; } } get value() { return this.option.value; } set value(val) { this.option.value = val; } get selected() { return this.option.selected; } set selected(val) { this.option.selected = val; } get disabled() { return this.option.disabled; } set disabled(val) { this.option.disabled = val; } // ARIA property accessors get ariaLabel() { const value = this.option.getAttribute('aria-label'); return value === null ? null : value; } set ariaLabel(val) { if (val === null || val === undefined) { this.option.removeAttribute('aria-label'); } else { this.option.setAttribute('aria-label', val); } } get ariaDescribedBy() { const value = this.option.getAttribute('aria-describedby'); return value === null ? null : value; } set ariaDescribedBy(val) { if (val === null || val === undefined) { this.option.removeAttribute('aria-describedby'); } else { this.option.setAttribute('aria-describedby', val); } } // Override validateARIA for option-specific checks validateARIA() { const errors = super.validateARIA ? super.validateARIA() : []; // Accessible name check: must have text or aria-label const optionText = this.textContent.trim(); const ariaLabel = this.option.getAttribute('aria-label'); if (!optionText &amp;&amp; !ariaLabel) { errors.push('Option has no accessible name (text or aria-label required)'); } return errors; } } // Register the custom element if (!customElements.get('ds-option')) { customElements.define('ds-option', DsOption); } // Export for use in other modules export default DsOption;</code></pre> </article> </section> </div> <nav> <h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="BaseComponent.html">BaseComponent</a></li></ul> </nav> <br class="clear"> <footer> Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 4.0.4</a> on Wed Aug 20 2025 19:54:53 GMT-0700 (Pacific Daylight Time) </footer> <script> prettyPrint(); </script> <script src="scripts/linenumber.js"> </script> </body> </html>