Skip to content

Commit

Permalink
feat: implement hex-input component
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan committed Aug 28, 2020
1 parent 89cae6f commit 7d037a5
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ node_modules
/test/**/*.js
/test/**/*.js.map
color-picker-*.js
hex-input.js
*.d.ts
*.map
custom-elements.json
82 changes: 82 additions & 0 deletions src/hex-input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { validHex } from './lib/utils/validate.js';

// Escapes all non-hexadecimal characters including "#"
const escape = (hex: string) => hex.replace(/([^0-9A-F]+)/gi, '');

/**
* A color picker custom element that uses HEX format.
*
* @element hex-input
*
* @prop {string} color - Color in HEX format.
* @attr {string} color - Color in HEX format.
*
* @fires color-changed - Event fired when color is changed.
*
* @csspart input - An underlying input element.
*/
export class HexInput extends HTMLElement {
static get observedAttributes(): string[] {
return ['color'];
}

private _color!: string;

private _oldColor!: string;

private _input!: HTMLInputElement;

get color(): string {
return this._color;
}

set color(hex: string) {
this._color = hex;
this._input.value = escape(hex);
}

constructor() {
super();
const input = document.createElement('input');
input.setAttribute('part', 'input');
input.setAttribute('spellcheck', 'false');
input.setAttribute('maxlength', '6');
this.attachShadow({ mode: 'open' }).appendChild(input);
input.addEventListener('input', this);
input.addEventListener('blur', this);
this._input = input;
}

handleEvent(event: Event): void {
const target = event.target as HTMLInputElement;
const { value } = target;
switch (event.type) {
case 'input':
const hex = escape(value);
this._oldColor = this.color;
if (validHex(hex)) {
this.color = hex;
this.dispatchEvent(new CustomEvent('color-changed', { detail: { value: '#' + hex } }));
}
break;
case 'blur':
if (!validHex(value)) {
this.color = this._oldColor;
}
}
}

attributeChangedCallback(_attr: string, _oldVal: string, newVal: string): void {
if (this.color !== newVal) {
this.color = newVal;
}
}
}

customElements.define('hex-input', HexInput);

declare global {
interface HTMLElementTagNameMap {
'hex-input': HexInput;
}
}

0 comments on commit 7d037a5

Please sign in to comment.