Skip to content

Commit

Permalink
feat: add prefixed property to hex-input (#92)
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan authored Nov 5, 2022
1 parent f6a5d4c commit 45cdc57
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 12 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,12 @@ hex-color-picker::part(hue-pointer) {
`<hex-input>` renders an unstyled `<input>` element inside a slot and exposes it for styling using
`part`. You can also pass your own `<input>` element as a child if you want to fully configure it.

| Property | Default | Description |
| -------- | ------- | -------------------------------------------- |
| `alpha` | `false` | Allows `#rgba` and `#rrggbbaa` color formats |
In addition to `color` property, `<hex-input>` supports the following boolean properties:

| Property | Default | Description |
| ---------- | ------- | -------------------------------------------- |
| `alpha` | `false` | Allows `#rgba` and `#rrggbbaa` color formats |
| `prefixed` | `false` | Enables `#` prefix displaying |

## Base classes

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
},
{
"path": "hex-input.js",
"limit": "1 KB"
"limit": "1.1 KB"
}
],
"sideEffects": [
Expand Down
2 changes: 2 additions & 0 deletions src/hex-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { HexInputBase } from './lib/entrypoints/hex-input.js';
* @attr {string} color - Selected color in HEX format.
* @prop {boolean} alpha - When true, `#rgba` and `#rrggbbaa` color formats are allowed.
* @attr {boolean} alpha - Allows `#rgba` and `#rrggbbaa` color formats.
* @prop {boolean} prefixed - When true, `#` prefix is displayed in the input.
* @attr {boolean} prefixed - Enables `#` prefix displaying.
*
* @fires color-changed - Event fired when color is changed.
*
Expand Down
40 changes: 34 additions & 6 deletions src/lib/entrypoints/hex-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ const escape = (hex: string, alpha: boolean) =>
const $alpha = Symbol('alpha');
const $color = Symbol('color');
const $saved = Symbol('saved');
const $input = Symbol('saved');
const $input = Symbol('input');
const $prefix = Symbol('prefix');
const $update = Symbol('update');

export interface HexInputBase {
Expand All @@ -30,13 +31,15 @@ export interface HexInputBase {

export class HexInputBase extends HTMLElement {
static get observedAttributes(): string[] {
return ['alpha', 'color'];
return ['alpha', 'color', 'prefixed'];
}

private declare [$color]: string;

private declare [$alpha]: boolean;

private declare [$prefix]: boolean;

private declare [$saved]: string;

private declare [$input]: HTMLInputElement;
Expand Down Expand Up @@ -67,6 +70,16 @@ export class HexInputBase extends HTMLElement {
}
}

get prefixed(): boolean {
return this[$prefix];
}

set prefixed(prefixed: boolean) {
this[$prefix] = prefixed;
this.toggleAttribute('prefixed', prefixed);
this[$update](this.color);
}

connectedCallback(): void {
const root = this.attachShadow({ mode: 'open' });
root.appendChild(template.content.cloneNode(true));
Expand Down Expand Up @@ -99,6 +112,14 @@ export class HexInputBase extends HTMLElement {
this.alpha = this.hasAttribute('alpha');
}

if (this.hasOwnProperty('prefixed')) {
const value = this.prefixed;
delete this['prefixed' as keyof this];
this.prefixed = value;
} else {
this.prefixed = this.hasAttribute('prefixed');
}

if (this.hasOwnProperty('color')) {
const value = this.color;
delete this['color' as keyof this];
Expand Down Expand Up @@ -139,17 +160,24 @@ export class HexInputBase extends HTMLElement {
this.color = newVal;
}

const hasBooleanAttr = newVal != null;
if (attr === 'alpha') {
const hasAlpha = newVal != null;
if (this.alpha !== hasAlpha) {
this.alpha = hasAlpha;
if (this.alpha !== hasBooleanAttr) {
this.alpha = hasBooleanAttr;
}
}

if (attr === 'prefixed') {
if (this.prefixed !== hasBooleanAttr) {
this.prefixed = hasBooleanAttr;
}
}
}

private [$update](hex: string): void {
if (this[$input]) {
this[$input].value = hex == null || hex == '' ? '' : escape(hex, this.alpha);
this[$input].value =
hex == null || hex == '' ? '' : (this.prefixed ? '#' : '') + escape(hex, this.alpha);
}
}
}
60 changes: 58 additions & 2 deletions src/test/hex-input.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@ describe('hex-input', () => {
}

describe('lazy upgrade', () => {
it('should work with color property set before upgrade', async () => {
it('should work with all properties set before upgrade', async () => {
const element = document.createElement('hex-input');
document.body.appendChild(element);
element.alpha = true;
element.prefixed = true;
element.color = '#123';
await import('../hex-input');
expect(element.color).to.equal('#123');
expect(element.alpha).to.be.true;
expect(element.prefixed).to.be.true;
target = getTarget(element);
expect(target.value).to.equal('123');
expect(target.value).to.equal('#123');
document.body.removeChild(element);
});
});
Expand Down Expand Up @@ -334,4 +336,58 @@ describe('hex-input', () => {
});
});
});

describe('prefixed', () => {
describe('property', () => {
beforeEach(async () => {
input = await fixture(html`<hex-input></hex-input>`);
input.prefixed = true;
input.color = '#112233';
target = getTarget(input);
});

it('should set prefixed attribute when prefixed property is set', () => {
expect(input.hasAttribute('prefixed')).to.be.true;
});

it('should set # to the input when prefixed property is set', () => {
expect(target.value).to.equal('#112233');
});

it('should remove prefixed attribute when prefixed property is set to false', () => {
input.prefixed = false;
expect(input.hasAttribute('prefixed')).to.be.false;
});

it('should remove # from the input when prefixed property is set to false', () => {
input.prefixed = false;
expect(target.value).to.equal('112233');
});
});

describe('attribute', () => {
beforeEach(async () => {
input = await fixture(html`<hex-input color="#112233" prefixed></hex-input>`);
target = getTarget(input);
});

it('should set prefixed to true when prefixed attribute is set', () => {
expect(input.prefixed).to.be.true;
});

it('should set # to the input when prefixed attribute is set', () => {
expect(target.value).to.equal('#112233');
});

it('should set prefixed to false when prefixed attribute is removed', () => {
input.removeAttribute('prefixed');
expect(input.prefixed).to.be.false;
});

it('should remove # from the input when prefixed attribute is removed', () => {
input.removeAttribute('prefixed');
expect(target.value).to.equal('112233');
});
});
});
});

0 comments on commit 45cdc57

Please sign in to comment.