Newer
Older
iuav-ui / src / components / input / checkbox.ts
import { LitElement, html, css } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
import { unsafeHTML } from 'lit/directives/unsafe-html.js';

@customElement('iu-checkbox')
export class Checkbox extends LitElement {
  static override styles = css`
    :host {
      display: inline-flex;
      align-items: start;
      cursor: pointer;
      user-select: none;
      margin-bottom: var(--iu-spacing-5);
    }

    .checkbox {
      width: 18px;
      height: 18px;
      border: 1px solid var(--iu-color-grey-300);
      border-radius: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      flex-shrink: 0;
      position: relative;
    }

    .checkbox::after{
        content: '';
        background-image: url("data:image/svg+xml,%3Csvg fill='none' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 9'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='m4.022 7.313-2.67-2.67-.703.711 3.375 3.375 7.328-7.374-.704-.71-6.626 6.668Z' fill='%23fff'/%3E%3C/svg%3E");
        position: absolute;
        background-size: contain;
        background-repeat: no-repeat;
        top: 50%;
        left: 50%;
        transform: translateX(-50%) translateY(-50%);
        width: 14px;
        height: 11px;
    }

    .checkbox[aria-checked="true"] {
      background: var(--iu-color-black);
      border-color: var(--iu-color-black);
    }

    .checkbox[aria-checked="true"]::after {
    }

    .label {
      margin-left: 14px;
      font: var(--iu-fs-1);
      color: var(--iu-color-black);
      a{
        color: var(--iu-color-black)
      }
    }

    /* Focus styles */
    :host(:focus-within) .checkbox {
      outline: 0;
    }
  `;

  @property({ type: Boolean, reflect: true }) checked = false;
  @property({ type: String }) label = ''; // Optional label
  @property({ type: String }) name = ''; // For form compatibility

  private toggleChecked() {
    this.checked = !this.checked;
    this.dispatchEvent(new CustomEvent('change', { detail: { checked: this.checked }, bubbles: true, composed: true }));
  }

  private handleKeyDown(event: KeyboardEvent) {
    if (event.key === ' ' || event.key === 'Enter') {
      event.preventDefault();
      this.toggleChecked();
    }
  }

  override render() {
    return html`
      <div
        class="checkbox"
        role="checkbox"
        tabindex="0"
        aria-checked="${this.checked}"
        @click="${this.toggleChecked}"
        @keydown="${this.handleKeyDown}"
      ></div>
        ${this.label ? html`<span class="label" @click="${this.toggleChecked}">${unsafeHTML(this.label)}</span>` : ''}
        <input type="checkbox" name="${this.name}" .checked="${this.checked}" hidden />
    `;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'iu-checkbox': Checkbox;
  }
}