UNPKG

standards-ui

Version:

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

202 lines (173 loc) 6.84 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: ds-fieldset.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-fieldset.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>/** * @file ds-fieldset.js * @summary A custom Web Component that wraps a native `&lt;fieldset>` element. * @description * The `ds-fieldset` component provides a styled and functional fieldset element * for grouping related form controls together. It creates a visual and semantic * grouping that improves form organization and accessibility. * * - The content inside `&lt;ds-fieldset>...&lt;/ds-fieldset>` is rendered via the default slot as the fieldset content. * - Should contain a `&lt;ds-legend>` or native `&lt;legend>` as the first child for accessibility. * - Supports ARIA attributes: `aria-label`, `aria-describedby` for accessibility. * - Uses `part="fieldset"` for styling via Shadow DOM. * - Warns in the console if no accessible name (legend or `aria-label`) is provided. * - No custom events are fired. * * @element ds-fieldset * * @slot - Renders form controls and other content within the fieldset. * * @attr {string} aria-label - Accessible label for the fieldset element (overrides legend). * @attr {string} aria-describedby - Reference to element(s) describing the fieldset. * * @note Uses `part="fieldset"` for styling via Shadow DOM. * @note Warns if no accessible name (legend or `aria-label`) is provided. * @note Should contain a `&lt;ds-legend>` or `&lt;legend>` as the first child for correct semantics and accessibility. * * @example * &lt;!-- Basic fieldset --> * &lt;ds-fieldset> * &lt;ds-legend>Personal Information&lt;/ds-legend> * &lt;ds-label for="first-name">First Name&lt;/ds-label> * &lt;ds-text-input id="first-name" name="firstName">&lt;/ds-text-input> * &lt;ds-label for="last-name">Last Name&lt;/ds-label> * &lt;ds-text-input id="last-name" name="lastName">&lt;/ds-text-input> * &lt;/ds-fieldset> * * @example * &lt;!-- Fieldset with radio buttons --> * &lt;ds-fieldset> * &lt;ds-legend>Gender&lt;/ds-legend> * &lt;ds-radio name="gender" value="male" id="male">Male&lt;/ds-radio> * &lt;ds-radio name="gender" value="female" id="female">Female&lt;/ds-radio> * &lt;ds-radio name="gender" value="other" id="other">Other&lt;/ds-radio> * &lt;/ds-fieldset> * * @example * &lt;!-- Fieldset with checkboxes --> * &lt;ds-fieldset> * &lt;ds-legend>Interests&lt;/ds-legend> * &lt;ds-checkbox name="interests" value="sports" id="sports">Sports&lt;/ds-checkbox> * &lt;ds-checkbox name="interests" value="music" id="music">Music&lt;/ds-checkbox> * &lt;ds-checkbox name="interests" value="reading" id="reading">Reading&lt;/ds-checkbox> * &lt;/ds-fieldset> */ import BaseComponent from './base-component.js'; class DsFieldset extends BaseComponent { constructor() { // ARIA config for ds-fieldset 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: block; } .wrapper { width: 100%; } &lt;/style> &lt;div class="wrapper"> &lt;fieldset part="fieldset"> &lt;slot>&lt;/slot> &lt;/fieldset> &lt;/div> `; super({ template: template.innerHTML, targetSelector: 'fieldset', ariaConfig, events: [], observedAttributes: [] }); this.fieldset = this.shadowRoot.querySelector('fieldset'); } static get observedAttributes() { return ['aria-label', 'aria-describedby']; } attributeChangedCallback(name, oldValue, newValue) { super.attributeChangedCallback(name, oldValue, newValue); if (oldValue === newValue) return; } // ARIA property accessors get ariaLabel() { const value = this.fieldset.getAttribute('aria-label'); return value === null ? null : value; } set ariaLabel(val) { if (val === null || val === undefined) { this.fieldset.removeAttribute('aria-label'); } else { this.fieldset.setAttribute('aria-label', val); } } get ariaDescribedBy() { const value = this.fieldset.getAttribute('aria-describedby'); return value === null ? null : value; } set ariaDescribedBy(val) { if (val === null || val === undefined) { this.fieldset.removeAttribute('aria-describedby'); } else { this.fieldset.setAttribute('aria-describedby', val); } } // Override validateARIA for fieldset-specific checks validateARIA() { const errors = super.validateARIA ? super.validateARIA() : []; // Accessible name check: must have a legend or aria-label const legend = this.fieldset.querySelector('legend,ds-legend'); const ariaLabel = this.fieldset.getAttribute('aria-label'); if (!legend &amp;&amp; !ariaLabel) { errors.push('Fieldset has no accessible name (legend or aria-label required)'); } return errors; } } // Register the custom element if (!customElements.get('ds-fieldset')) { customElements.define('ds-fieldset', DsFieldset); } // Export for use in other modules export default DsFieldset;</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>