File

src/app/components/issue-label/issue-label.component.ts

Description

Renders an issue label.

Metadata

selector app-issue-label
styleUrls ./issue-label.component.scss
templateUrl ./issue-label.component.html

Index

Methods
Inputs

Inputs

label
Type : Label

The label to display. Nullable. Should have properties name and color.

Methods

Public isColorDark
isColorDark(color?: string)

Determines whether the color is light or dark.

Parameters :
Name Type Optional Description
color string Yes

label color - any CSS color string

Returns : boolean
import {Component, Input} from '@angular/core';
import {Label} from 'src/generated/graphql-dgql';

const colorTestCanvas = document.createElement('canvas');
colorTestCanvas.width = colorTestCanvas.height = 1;
const colorTestCtx = colorTestCanvas.getContext('2d');

/**
 * Reads a CSS color into an RGB tuple.
 * Undefined behavior if the string is not a valid color.
 *
 * @param color a CSS color string
 * @return RGB tuple in the 0..255 range
 */
function readCssColor(color: string): [number, number, number] {
  try {
    colorTestCtx.fillStyle = color;
    colorTestCtx.fillRect(0, 0, 1, 1);
    const imageData = colorTestCtx.getImageData(0, 0, 1, 1);
    return [imageData.data[0], imageData.data[1], imageData.data[2]];
  } catch {
    // getImageData may fail in rare cases(?) so we'll simply return garbage
    return [NaN, NaN, NaN];
  }
}

/**
 * Renders an issue label.
 */
@Component({
  selector: 'app-issue-label',
  templateUrl: './issue-label.component.html',
  styleUrls: ['./issue-label.component.scss']
})
export class IssueLabelComponent {
  /** The label to display. Nullable. Should have properties `name` and `color`. */
  @Input() label: Label;

  /**
   * Determines whether the color is light or dark.
   *
   * @param color label color - any CSS color string
   */
  public isColorDark(color?: string): boolean {
    if (!color) {
      return false;
    }

    const [r, g, b] = readCssColor(color);

    // HSP (Hue-Sat-Perceived-brightness) equation from http://alienryderflex.com/hsp.html
    const hsp = Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b));

    // Using the HSP value, determine whether the color is light or dark
    // Compare against gamma-adjusted tipping point
    return hsp > Math.sqrt(0.5) * 255;
  }
}
<span class="inner-label" [ngStyle]="{ backgroundColor: label?.color }" [ngClass]="isColorDark(label?.color) ? 'is-dark-text' : ''">
  {{ label?.name }}
</span>

./issue-label.component.scss

:host {
  display: inline-block;
}

.inner-label {
  display: inline-block;
  color: white;
  border-radius: 4px;
  padding: 1px 2px;
  margin: 1px;
  border: 1px solid rgba(255, 255, 255, 0.3);

  &.is-dark-text {
    color: black;
    border: 1px solid rgba(0, 0, 0, 0.3);
  }
}
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""