UNPKG

standards-ui

Version:

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

180 lines (153 loc) 5.81 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>JSDoc: Source: ds-card.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-card.js</h1> <section> <article> <pre class="prettyprint source linenums"><code>/** * @file ds-card.js * @summary A custom Web Component for displaying content in a card layout, optionally as a clickable link. * @description * The `ds-card` component displays its content in a styled card. It can be used as a static card or as a clickable card link. * * - The content inside `&lt;ds-card>...&lt;/ds-card>` is rendered via the default slot. * - If the `href` attribute is present, the card renders as a clickable link (`&lt;a>`) with keyboard accessibility (Enter/Space to activate). * - If `href` is not present, the card renders as a static `&lt;div>`. * - The card is always focusable and accessible by keyboard. * - Uses CSS custom properties for background, border, radius, shadow, padding, and text color. * - The card is styled via Shadow DOM; no `part` attribute is exposed. * * @element ds-card * * @slot - The card content (title, description, etc.). * * @attr {string} [href] - If present, the card becomes a clickable link. Opens in a new tab. * * @note When `href` is present, the card is rendered as an accessible link (`role="link"`, keyboard support). * @note When `href` is absent, the card is rendered as a static group (`role="group"`). * @note The card is always focusable (`tabindex=0`). * @note Uses CSS custom properties: `--ds-card-background`, `--ds-card-border-color`, `--ds-card-border-radius`, `--ds-card-shadow`, `--ds-card-padding`, `--ds-card-text-color`. * * @example * &lt;!-- Static card --> * &lt;ds-card> * &lt;h2>Card Title&lt;/h2> * &lt;p>Some description or content.&lt;/p> * &lt;/ds-card> * * @example * &lt;!-- Clickable card link --> * &lt;ds-card href="https://example.com"> * &lt;h2>Go to Example&lt;/h2> * &lt;p>This card acts as a link.&lt;/p> * &lt;/ds-card> */ class DsCard extends HTMLElement { static get observedAttributes() { return ['href']; } constructor() { super(); this.attachShadow({ mode: 'open' }); this._onKeyDown = this._onKeyDown.bind(this); } connectedCallback() { this.render(); if (this.hasAttribute('href')) { this.shadowRoot.querySelector('.card-link').addEventListener('keydown', this._onKeyDown); } } disconnectedCallback() { if (this.hasAttribute('href')) { this.shadowRoot.querySelector('.card-link').removeEventListener('keydown', this._onKeyDown); } } attributeChangedCallback(name, oldValue, newValue) { if (name === 'href' &amp;&amp; oldValue !== newValue) { this.render(); } } _onKeyDown(e) { if ((e.key === 'Enter' || e.key === ' ') &amp;&amp; this.hasAttribute('href')) { e.preventDefault(); this.shadowRoot.querySelector('.card-link').click(); } } render() { const href = this.getAttribute('href'); const isLink = !!href; console.log(href); this.shadowRoot.innerHTML = ` &lt;style> .card-root { display: block; background: var(--ds-card-background, #fff) !important; border: 1px solid var(--ds-card-border-color, #e0e0e0) !important; border-radius: var(--ds-card-border-radius, 12px) !important; box-shadow: var(--ds-card-shadow, 0 2px 8px rgba(0,0,0,0.04)) !important; padding: var(--ds-card-padding, 2rem 2.5rem) !important; min-width: 200px; min-height: 120px; color: var(--ds-card-text-color, #222) !important; transition: box-shadow 0.2s, border 0.2s; outline: none; text-decoration: none !important; cursor: ${isLink ? 'pointer' : 'default'}; text-align: center; } .card-root:focus, .card-root:focus-visible, .card-root:active, .card-root:hover { border: 1px solid var(--ds-color-primary, #007bff) !important; box-shadow: 0 4px 16px rgba(0,123,255,0.08) !important; } ::slotted(h2) { margin: 0 0 0.5rem 0; font-size: 1.3rem; color: var(--ds-color-primary, #007bff) !important; } ::slotted(p), ::slotted(div), ::slotted(span), ::slotted(*) { color: #555 !important; text-decoration: none !important; } &lt;/style> ${isLink ? ` &lt;a class="card-root card-link" href="${href}" tabindex="0" role="link" target="_blank" rel="noopener"> &lt;slot>&lt;/slot> &lt;/a> ` : ` &lt;div class="card-root card-content" role="group" tabindex="0" aria-label="Card"> &lt;slot>&lt;/slot> &lt;/div> `} `; } } if (!customElements.get('ds-card')) { customElements.define('ds-card', DsCard); } export default DsCard;</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>