All files / packages/sds-components/src/sds/link link.js

100% Statements 37/37
100% Branches 17/17
100% Functions 16/16
100% Lines 37/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101              44x 44x 44x 44x 44x 44x 44x 44x 44x 44x 44x 44x     51x     9x     5x     7x 7x 7x                 47x                   2x     4x     47x     2x 2x     3x     3x 3x 2x         6x 5x       3x     1x     3x 2x         1x 1x                
import { LightningElement, api } from 'lwc';
import { reflectAttribute, normalizeBoolean, normalizeInput } from 'sds/utils';
import 'sds/privateThemeProvider';
 
export default class Link extends LightningElement {
  static shadowSupportMode = 'native';
 
  _href = '#';
  _ariaDisabled;
  _ariaLabel;
  _linkElement;
 
  @api target;
  @api rel;
  @api download;
  @api hreflang;
  @api type;
  @api referrerpolicy;
  @api ping;
 
  @api
  get href() {
    return this._href;
  }
  set href(value) {
    this._href = normalizeInput(value);
  }
 
  @api
  get disabled() {
    return this._disabled;
  }
  set disabled(value) {
    this._disabled = normalizeBoolean(value);
    this._ariaDisabled = this._disabled ? 'true' : 'false';
    reflectAttribute(this, 'disabled', this._disabled);
  }
 
  /**
   * Defines a string value that labels an interactive element.
   *
   * @type {string}
   */
  get ariaLabel() {
    return this._ariaLabel;
  }
 
  /**
   * Set the aria-label using the label value.
   * Reflect the label on the host instead of aria-label to avoid the screen reader duplicate announcement
   *
   * @type {string}
   */
  @api
  get label() {
    return this._label;
  }
  set label(value) {
    this._ariaLabel = value;
  }
 
  get ariaDisabled() {
    return this._ariaDisabled;
  }
 
  get link() {
    this._linkElement = this._linkElement || this.template.querySelector('[part="link"]');
 
    return this._linkElement;
  }
 
  handleSlotChange(e) {
    const nodes = e.target.assignedElements({ flatten: true });
    nodes.find((node) => {
      if (node instanceof HTMLAnchorElement || node instanceof HTMLButtonElement) {
        console.error('Anchor element found in slot. Slotted children cannot be interactive elements.');
      }
    });
  }
 
  handleClick(e) {
    if (this._href === '#' || this._href === 'javascript:void(0)' || this._disabled) {
      e.preventDefault();
    }
  }
 
  handleFocus(e) {
    this.setAttribute('focus', '');
  }
 
  handleBlur(e) {
    this.removeAttribute('focus');
  }
 
  handleKeyDown(e) {
    if (e.key === 'Enter' || e.key === ' ') {
      this.link.click();
    }
  }
}