UNPKG

ngx-color

Version:

A Collection of Color Pickers from Sketch, Photoshop, Chrome & more

1,148 lines (1,137 loc) 57.4 kB
import * as i1 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i0 from '@angular/core'; import { Component, ChangeDetectionStrategy, Input, NgModule, inject, ElementRef, Directive, Output, HostListener, EventEmitter, isDevMode, forwardRef } from '@angular/core'; import { Subject, Subscription, fromEvent } from 'rxjs'; import { distinctUntilChanged, debounceTime, tap } from 'rxjs/operators'; import { TinyColor } from '@ctrl/tinycolor'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; const checkboardCache = {}; function render(c1, c2, size) { if (typeof document === 'undefined') { return null; } const canvas = document.createElement('canvas'); canvas.width = size * 2; canvas.height = size * 2; const ctx = canvas.getContext('2d'); if (!ctx) { return null; } // If no context can be found, return early. ctx.fillStyle = c1; ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = c2; ctx.fillRect(0, 0, size, size); ctx.translate(size, size); ctx.fillRect(0, 0, size, size); return canvas.toDataURL(); } function getCheckerboard(c1, c2, size) { const key = `${c1}-${c2}-${size}`; if (checkboardCache[key]) { return checkboardCache[key]; } const checkboard = render(c1, c2, size); if (!checkboard) { return null; } checkboardCache[key] = checkboard; return checkboard; } class CheckboardComponent { white = 'transparent'; size = 8; grey = 'rgba(0,0,0,.08)'; boxShadow; borderRadius; gridStyles; ngOnInit() { const background = getCheckerboard(this.white, this.grey, this.size); this.gridStyles = { borderRadius: this.borderRadius, boxShadow: this.boxShadow, background: `url(${background}) center left`, }; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: CheckboardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.3", type: CheckboardComponent, isStandalone: false, selector: "color-checkboard", inputs: { white: "white", size: "size", grey: "grey", boxShadow: "boxShadow", borderRadius: "borderRadius" }, ngImport: i0, template: `<div class="grid" [ngStyle]="gridStyles"></div>`, isInline: true, styles: [".grid{inset:0;position:absolute}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: CheckboardComponent, decorators: [{ type: Component, args: [{ selector: 'color-checkboard', template: `<div class="grid" [ngStyle]="gridStyles"></div>`, preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, styles: [".grid{inset:0;position:absolute}\n"] }] }], propDecorators: { white: [{ type: Input }], size: [{ type: Input }], grey: [{ type: Input }], boxShadow: [{ type: Input }], borderRadius: [{ type: Input }] } }); class CheckboardModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: CheckboardModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.3", ngImport: i0, type: CheckboardModule, declarations: [CheckboardComponent], imports: [CommonModule], exports: [CheckboardComponent] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: CheckboardModule, imports: [CommonModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: CheckboardModule, decorators: [{ type: NgModule, args: [{ declarations: [CheckboardComponent], exports: [CheckboardComponent], imports: [CommonModule], }] }] }); class CoordinatesDirective { el = inject(ElementRef); coordinatesChange = new Subject(); mousechange = new Subject(); mouseListening = false; sub; mousemove($event, x, y, isTouch = false) { if (this.mouseListening) { $event.preventDefault(); this.mousechange.next({ $event, x, y, isTouch }); } } mouseup() { this.mouseListening = false; } mousedown($event, x, y, isTouch = false) { $event.preventDefault(); this.mouseListening = true; this.mousechange.next({ $event, x, y, isTouch }); } ngOnInit() { this.sub = this.mousechange .pipe( // limit times it is updated for the same area distinctUntilChanged((p, q) => p.x === q.x && p.y === q.y)) .subscribe(n => this.handleChange(n.x, n.y, n.$event, n.isTouch)); } ngOnDestroy() { this.sub?.unsubscribe(); } handleChange(x, y, $event, isTouch) { const containerWidth = this.el.nativeElement.clientWidth; const containerHeight = this.el.nativeElement.clientHeight; const left = x - (this.el.nativeElement.getBoundingClientRect().left + window.pageXOffset); let top = y - this.el.nativeElement.getBoundingClientRect().top; if (!isTouch) { top = top - window.pageYOffset; } this.coordinatesChange.next({ x, y, top, left, containerWidth, containerHeight, $event, }); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: CoordinatesDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.3", type: CoordinatesDirective, isStandalone: false, selector: "[ngx-color-coordinates]", outputs: { coordinatesChange: "coordinatesChange" }, host: { listeners: { "window:mousemove": "mousemove($event,$event.pageX,$event.pageY)", "window:touchmove": "mousemove($event,$event.touches[0].clientX,$event.touches[0].clientY,true)", "window:mouseup": "mouseup()", "window:touchend": "mouseup()", "mousedown": "mousedown($event,$event.pageX,$event.pageY)", "touchstart": "mousedown($event,$event.touches[0].clientX,$event.touches[0].clientY,true)" } }, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: CoordinatesDirective, decorators: [{ type: Directive, args: [{ selector: '[ngx-color-coordinates]', standalone: false, }] }], propDecorators: { coordinatesChange: [{ type: Output }], mousemove: [{ type: HostListener, args: ['window:mousemove', ['$event', '$event.pageX', '$event.pageY']] }, { type: HostListener, args: ['window:touchmove', [ '$event', '$event.touches[0].clientX', '$event.touches[0].clientY', 'true', ]] }], mouseup: [{ type: HostListener, args: ['window:mouseup'] }, { type: HostListener, args: ['window:touchend'] }], mousedown: [{ type: HostListener, args: ['mousedown', ['$event', '$event.pageX', '$event.pageY']] }, { type: HostListener, args: ['touchstart', [ '$event', '$event.touches[0].clientX', '$event.touches[0].clientY', 'true', ]] }] } }); class CoordinatesModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: CoordinatesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.3", ngImport: i0, type: CoordinatesModule, declarations: [CoordinatesDirective], exports: [CoordinatesDirective] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: CoordinatesModule }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: CoordinatesModule, decorators: [{ type: NgModule, args: [{ declarations: [CoordinatesDirective], exports: [CoordinatesDirective], }] }] }); class AlphaComponent { hsl; rgb; pointer; shadow; radius; direction = 'horizontal'; onChange = new EventEmitter(); gradient; pointerLeft; pointerTop; ngOnChanges() { if (this.direction === 'vertical') { this.pointerLeft = 0; this.pointerTop = this.rgb.a * 100; this.gradient = { background: `linear-gradient(to bottom, rgba(${this.rgb.r},${this.rgb.g},${this.rgb.b}, 0) 0%, rgba(${this.rgb.r},${this.rgb.g},${this.rgb.b}, 1) 100%)`, }; } else { this.gradient = { background: `linear-gradient(to right, rgba(${this.rgb.r},${this.rgb.g},${this.rgb.b}, 0) 0%, rgba(${this.rgb.r},${this.rgb.g},${this.rgb.b}, 1) 100%)`, }; this.pointerLeft = this.rgb.a * 100; } } handleChange({ top, left, containerHeight, containerWidth, $event }) { let data; if (this.direction === 'vertical') { let a; if (top < 0) { a = 0; } else if (top > containerHeight) { a = 1; } else { a = Math.round((top * 100) / containerHeight) / 100; } if (this.hsl.a !== a) { data = { h: this.hsl.h, s: this.hsl.s, l: this.hsl.l, a, source: 'rgb', }; } } else { let a; if (left < 0) { a = 0; } else if (left > containerWidth) { a = 1; } else { a = Math.round((left * 100) / containerWidth) / 100; } if (this.hsl.a !== a) { data = { h: this.hsl.h, s: this.hsl.s, l: this.hsl.l, a, source: 'rgb', }; } } if (!data) { return; } this.onChange.emit({ data, $event }); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: AlphaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.3", type: AlphaComponent, isStandalone: false, selector: "color-alpha", inputs: { hsl: "hsl", rgb: "rgb", pointer: "pointer", shadow: "shadow", radius: "radius", direction: "direction" }, outputs: { onChange: "onChange" }, usesOnChanges: true, ngImport: i0, template: ` <div class="alpha" [style.border-radius]="radius"> <div class="alpha-checkboard"> <color-checkboard></color-checkboard> </div> <div class="alpha-gradient" [ngStyle]="gradient" [style.box-shadow]="shadow" [style.border-radius]="radius" ></div> <div ngx-color-coordinates (coordinatesChange)="handleChange($event)" class="alpha-container color-alpha-{{ direction }}" > <div class="alpha-pointer" [style.left.%]="pointerLeft" [style.top.%]="pointerTop"> <div class="alpha-slider" [ngStyle]="pointer"></div> </div> </div> </div> `, isInline: true, styles: [".alpha{position:absolute;inset:0}.alpha-checkboard{position:absolute;inset:0;overflow:hidden}.alpha-gradient{position:absolute;inset:0}.alpha-container{position:relative;height:100%;margin:0 3px}.alpha-pointer{position:absolute}.alpha-slider{width:4px;border-radius:1px;height:8px;box-shadow:0 0 2px #0009;background:#fff;margin-top:1px;transform:translate(-2px)}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: CheckboardComponent, selector: "color-checkboard", inputs: ["white", "size", "grey", "boxShadow", "borderRadius"] }, { kind: "directive", type: CoordinatesDirective, selector: "[ngx-color-coordinates]", outputs: ["coordinatesChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: AlphaComponent, decorators: [{ type: Component, args: [{ selector: 'color-alpha', template: ` <div class="alpha" [style.border-radius]="radius"> <div class="alpha-checkboard"> <color-checkboard></color-checkboard> </div> <div class="alpha-gradient" [ngStyle]="gradient" [style.box-shadow]="shadow" [style.border-radius]="radius" ></div> <div ngx-color-coordinates (coordinatesChange)="handleChange($event)" class="alpha-container color-alpha-{{ direction }}" > <div class="alpha-pointer" [style.left.%]="pointerLeft" [style.top.%]="pointerTop"> <div class="alpha-slider" [ngStyle]="pointer"></div> </div> </div> </div> `, changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, standalone: false, styles: [".alpha{position:absolute;inset:0}.alpha-checkboard{position:absolute;inset:0;overflow:hidden}.alpha-gradient{position:absolute;inset:0}.alpha-container{position:relative;height:100%;margin:0 3px}.alpha-pointer{position:absolute}.alpha-slider{width:4px;border-radius:1px;height:8px;box-shadow:0 0 2px #0009;background:#fff;margin-top:1px;transform:translate(-2px)}\n"] }] }], propDecorators: { hsl: [{ type: Input }], rgb: [{ type: Input }], pointer: [{ type: Input }], shadow: [{ type: Input }], radius: [{ type: Input }], direction: [{ type: Input }], onChange: [{ type: Output }] } }); class AlphaModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: AlphaModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.3", ngImport: i0, type: AlphaModule, declarations: [AlphaComponent], imports: [CommonModule, CheckboardModule, CoordinatesModule], exports: [AlphaComponent] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: AlphaModule, imports: [CommonModule, CheckboardModule, CoordinatesModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: AlphaModule, decorators: [{ type: NgModule, args: [{ declarations: [AlphaComponent], exports: [AlphaComponent], imports: [CommonModule, CheckboardModule, CoordinatesModule], }] }] }); function simpleCheckForValidColor(data) { const keysToCheck = ['r', 'g', 'b', 'a', 'h', 's', 'l', 'v']; let checked = 0; let passed = 0; keysToCheck.forEach(letter => { if (!data[letter]) { return; } checked += 1; if (!isNaN(data[letter])) { passed += 1; } if (letter === 's' || letter === 'l') { const percentPatt = /^\d+%$/; if (percentPatt.test(data[letter])) { passed += 1; } } }); return checked === passed ? data : false; } function toState(data, oldHue, disableAlpha) { const color = data.hex ? new TinyColor(data.hex) : new TinyColor(data); if (disableAlpha) { color.setAlpha(1); } const hsl = color.toHsl(); const hsv = color.toHsv(); const rgb = color.toRgb(); const hex = color.toHex(); if (hsl.s === 0) { hsl.h = oldHue || 0; hsv.h = oldHue || 0; } const transparent = hex === '000000' && rgb.a === 0; return { hsl, hex: transparent ? 'transparent' : color.toHexString(), rgb, hsv, oldHue: data.h || oldHue || hsl.h, source: data.source, }; } function isValidHex(hex) { return new TinyColor(hex).isValid; } function getContrastingColor(data) { if (!data) { return '#fff'; } const col = toState(data); if (col.hex === 'transparent') { return 'rgba(0,0,0,0.4)'; } const yiq = (col.rgb.r * 299 + col.rgb.g * 587 + col.rgb.b * 114) / 1000; return yiq >= 128 ? '#000' : '#fff'; } var ColorMode; (function (ColorMode) { ColorMode["HEX"] = "hex"; ColorMode["HSL"] = "hsl"; ColorMode["HSV"] = "hsv"; ColorMode["RGB"] = "rgb"; })(ColorMode || (ColorMode = {})); class ColorWrap { className; /** * Descriptors the return color format if the component is used with two-way binding */ mode = ColorMode.HEX; color = { h: 250, s: 0.5, l: 0.2, a: 1, }; colorChange = new EventEmitter(); onChange = new EventEmitter(); onChangeComplete = new EventEmitter(); onSwatchHover = new EventEmitter(); oldHue; hsl; hsv; rgb; hex; source; currentColor; changes; disableAlpha; _onChangeCompleteSubscription = new Subscription(); _onSwatchHoverSubscription = new Subscription(); ngOnInit() { this.changes = this.onChange .pipe(debounceTime(100), tap(event => { this.onChangeComplete.emit(event); switch (this.mode) { case ColorMode.HEX: this.colorChange.emit(event.color.hex); break; case ColorMode.HSL: this.colorChange.emit(event.color.hsl); break; case ColorMode.HSV: this.colorChange.emit(event.color.hsv); break; case ColorMode.RGB: this.colorChange.emit(event.color.rgb); break; default: const msg = `The mode '${this.mode}' is not supported`; if (isDevMode()) { throw new Error(msg); } else { console.warn(msg); } break; } })) .subscribe(); this.setState(toState(this.color, 0)); this.currentColor = this.hex; } ngOnChanges() { this.setState(toState(this.color, this.oldHue)); } ngOnDestroy() { this.changes?.unsubscribe(); this._onChangeCompleteSubscription?.unsubscribe(); this._onSwatchHoverSubscription?.unsubscribe(); } setState(data) { this.oldHue = data.oldHue; this.hsl = data.hsl; this.hsv = data.hsv; this.rgb = data.rgb; this.hex = data.hex; this.source = data.source; this.afterValidChange(); } handleChange(data, $event) { const isValidColor = simpleCheckForValidColor(data); if (isValidColor) { const color = toState(data, data.h || this.oldHue, this.disableAlpha); this.setState(color); this.onChange.emit({ color, $event }); this.afterValidChange(); } } /** hook for components after a complete change */ afterValidChange() { } handleSwatchHover(data, $event) { const isValidColor = simpleCheckForValidColor(data); if (isValidColor) { const color = toState(data, data.h || this.oldHue); this.setState(color); this.onSwatchHover.emit({ color, $event }); } } registerOnChange(fn) { this._onChangeCompleteSubscription.add(this.onChangeComplete.pipe(tap(event => fn(event.color.hex))).subscribe()); } registerOnTouched(fn) { this._onSwatchHoverSubscription.add(this.onSwatchHover.pipe(tap(() => fn())).subscribe()); } setDisabledState(isDisabled) { } writeValue(hex) { this.color = hex; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ColorWrap, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.3", type: ColorWrap, isStandalone: false, selector: "color-wrap", inputs: { className: "className", mode: "mode", color: "color" }, outputs: { colorChange: "colorChange", onChange: "onChange", onChangeComplete: "onChangeComplete", onSwatchHover: "onSwatchHover" }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ColorWrap), multi: true, }, ], usesOnChanges: true, ngImport: i0, template: ``, isInline: true }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ColorWrap, decorators: [{ type: Component, args: [{ // create seletor base for test override property selector: 'color-wrap', template: ``, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => ColorWrap), multi: true, }, ], standalone: false, }] }], propDecorators: { className: [{ type: Input }], mode: [{ type: Input }], color: [{ type: Input }], colorChange: [{ type: Output }], onChange: [{ type: Output }], onChangeComplete: [{ type: Output }], onSwatchHover: [{ type: Output }] } }); class ColorWrapModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ColorWrapModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.3", ngImport: i0, type: ColorWrapModule, declarations: [ColorWrap], imports: [CommonModule], exports: [ColorWrap] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ColorWrapModule, imports: [CommonModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: ColorWrapModule, decorators: [{ type: NgModule, args: [{ declarations: [ColorWrap], exports: [ColorWrap], imports: [CommonModule], }] }] }); let nextUniqueId = 0; class EditableInputComponent { style; label; value; arrowOffset; dragLabel; dragMax; placeholder = ''; onChange = new EventEmitter(); currentValue; blurValue; wrapStyle; inputStyle; labelStyle; focus = false; mousemove; mouseup; uniqueId = `editableInput-${++nextUniqueId}`; ngOnInit() { this.wrapStyle = this.style && this.style.wrap ? this.style.wrap : {}; this.inputStyle = this.style && this.style.input ? this.style.input : {}; this.labelStyle = this.style && this.style.label ? this.style.label : {}; if (this.dragLabel) { this.labelStyle.cursor = 'ew-resize'; } } handleFocus($event) { this.focus = true; } handleFocusOut($event) { this.focus = false; this.currentValue = this.blurValue; } handleKeydown($event) { // In case `e.target.value` is a percentage remove the `%` character // and update accordingly with a percentage // https://github.com/casesandberg/react-color/issues/383 const stringValue = String($event.target.value); const isPercentage = stringValue.indexOf('%') > -1; const num = Number(stringValue.replace(/%/g, '')); if (isNaN(num)) { return; } const amount = this.arrowOffset || 1; // Up if ($event.keyCode === 38) { if (this.label) { this.onChange.emit({ data: { [this.label]: num + amount }, $event, }); } else { this.onChange.emit({ data: num + amount, $event }); } if (isPercentage) { this.currentValue = `${num + amount}%`; } else { this.currentValue = num + amount; } } // Down if ($event.keyCode === 40) { if (this.label) { this.onChange.emit({ data: { [this.label]: num - amount }, $event, }); } else { this.onChange.emit({ data: num - amount, $event }); } if (isPercentage) { this.currentValue = `${num - amount}%`; } else { this.currentValue = num - amount; } } } handleKeyup($event) { if ($event.keyCode === 40 || $event.keyCode === 38) { return; } if (`${this.currentValue}` === $event.target.value) { return; } if (this.label) { this.onChange.emit({ data: { [this.label]: $event.target.value }, $event, }); } else { this.onChange.emit({ data: $event.target.value, $event }); } } ngOnChanges() { if (!this.focus) { this.currentValue = String(this.value).toUpperCase(); this.blurValue = String(this.value).toUpperCase(); } else { this.blurValue = String(this.value).toUpperCase(); } } ngOnDestroy() { this.unsubscribe(); } subscribe() { this.mousemove = fromEvent(document, 'mousemove').subscribe((ev) => this.handleDrag(ev)); this.mouseup = fromEvent(document, 'mouseup').subscribe(() => this.unsubscribe()); } unsubscribe() { this.mousemove?.unsubscribe(); this.mouseup?.unsubscribe(); } handleMousedown($event) { if (this.dragLabel) { $event.preventDefault(); this.handleDrag($event); this.subscribe(); } } handleDrag($event) { if (this.dragLabel) { const newValue = Math.round(this.value + $event.movementX); if (newValue >= 0 && newValue <= this.dragMax) { this.onChange.emit({ data: { [this.label]: newValue }, $event }); } } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: EditableInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.3", type: EditableInputComponent, isStandalone: false, selector: "color-editable-input", inputs: { style: "style", label: "label", value: "value", arrowOffset: "arrowOffset", dragLabel: "dragLabel", dragMax: "dragMax", placeholder: "placeholder" }, outputs: { onChange: "onChange" }, usesOnChanges: true, ngImport: i0, template: ` <div class="wrap" [ngStyle]="wrapStyle"> <input [ngStyle]="inputStyle" spellCheck="false" [value]="currentValue" [placeholder]="placeholder" (keydown)="handleKeydown($event)" (keyup)="handleKeyup($event)" (focus)="handleFocus($event)" (focusout)="handleFocusOut($event)" [attr.aria-labelledby]="uniqueId" /> @if (label) { <span [id]="uniqueId" [ngStyle]="labelStyle" (mousedown)="handleMousedown($event)"> {{ label }} </span> } </div> `, isInline: true, styles: [":host{display:flex}.wrap{position:relative}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: EditableInputComponent, decorators: [{ type: Component, args: [{ selector: 'color-editable-input', template: ` <div class="wrap" [ngStyle]="wrapStyle"> <input [ngStyle]="inputStyle" spellCheck="false" [value]="currentValue" [placeholder]="placeholder" (keydown)="handleKeydown($event)" (keyup)="handleKeyup($event)" (focus)="handleFocus($event)" (focusout)="handleFocusOut($event)" [attr.aria-labelledby]="uniqueId" /> @if (label) { <span [id]="uniqueId" [ngStyle]="labelStyle" (mousedown)="handleMousedown($event)"> {{ label }} </span> } </div> `, changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, styles: [":host{display:flex}.wrap{position:relative}\n"] }] }], propDecorators: { style: [{ type: Input }], label: [{ type: Input }], value: [{ type: Input }], arrowOffset: [{ type: Input }], dragLabel: [{ type: Input }], dragMax: [{ type: Input }], placeholder: [{ type: Input }], onChange: [{ type: Output }] } }); class EditableInputModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: EditableInputModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.3", ngImport: i0, type: EditableInputModule, declarations: [EditableInputComponent], imports: [CommonModule], exports: [EditableInputComponent] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: EditableInputModule, imports: [CommonModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: EditableInputModule, decorators: [{ type: NgModule, args: [{ declarations: [EditableInputComponent], exports: [EditableInputComponent], imports: [CommonModule], }] }] }); class HueComponent { hsl; pointer; radius; shadow; hidePointer = false; direction = 'horizontal'; onChange = new EventEmitter(); left = '0px'; top = ''; ngOnChanges() { if (this.direction === 'horizontal') { this.left = `${(this.hsl.h * 100) / 360}%`; } else { this.top = `${-((this.hsl.h * 100) / 360) + 100}%`; } } handleChange({ top, left, containerHeight, containerWidth, $event }) { let data; if (this.direction === 'vertical') { let h; if (top < 0) { h = 359; } else if (top > containerHeight) { h = 0; } else { const percent = -((top * 100) / containerHeight) + 100; h = (360 * percent) / 100; } if (this.hsl.h !== h) { data = { h, s: this.hsl.s, l: this.hsl.l, a: this.hsl.a, source: 'rgb', }; } } else { let h; if (left < 0) { h = 0; } else if (left > containerWidth) { h = 359; } else { const percent = (left * 100) / containerWidth; h = (360 * percent) / 100; } if (this.hsl.h !== h) { data = { h, s: this.hsl.s, l: this.hsl.l, a: this.hsl.a, source: 'rgb', }; } } if (!data) { return; } this.onChange.emit({ data, $event }); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: HueComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.3", type: HueComponent, isStandalone: false, selector: "color-hue", inputs: { hsl: "hsl", pointer: "pointer", radius: "radius", shadow: "shadow", hidePointer: "hidePointer", direction: "direction" }, outputs: { onChange: "onChange" }, usesOnChanges: true, ngImport: i0, template: ` <div class="color-hue color-hue-{{ direction }}" [style.border-radius.px]="radius" [style.box-shadow]="shadow" > <div ngx-color-coordinates (coordinatesChange)="handleChange($event)" class="color-hue-container" > @if (!hidePointer) { <div class="color-hue-pointer" [style.left]="left" [style.top]="top"> <div class="color-hue-slider" [ngStyle]="pointer"></div> </div> } </div> </div> `, isInline: true, styles: [".color-hue{position:absolute;inset:0}.color-hue-container{margin:0 2px;position:relative;height:100%}.color-hue-pointer{position:absolute}.color-hue-slider{margin-top:1px;width:4px;border-radius:1px;height:8px;box-shadow:0 0 2px #0009;background:#fff;transform:translate(-2px)}.color-hue-horizontal{background:linear-gradient(to right,red,#ff0 17%,#0f0 33%,#0ff,#00f 67%,#f0f 83%,red)}.color-hue-vertical{background:linear-gradient(to top,red,#ff0 17%,#0f0 33%,#0ff,#00f 67%,#f0f 83%,red)}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: CoordinatesDirective, selector: "[ngx-color-coordinates]", outputs: ["coordinatesChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: HueComponent, decorators: [{ type: Component, args: [{ selector: 'color-hue', template: ` <div class="color-hue color-hue-{{ direction }}" [style.border-radius.px]="radius" [style.box-shadow]="shadow" > <div ngx-color-coordinates (coordinatesChange)="handleChange($event)" class="color-hue-container" > @if (!hidePointer) { <div class="color-hue-pointer" [style.left]="left" [style.top]="top"> <div class="color-hue-slider" [ngStyle]="pointer"></div> </div> } </div> </div> `, preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, styles: [".color-hue{position:absolute;inset:0}.color-hue-container{margin:0 2px;position:relative;height:100%}.color-hue-pointer{position:absolute}.color-hue-slider{margin-top:1px;width:4px;border-radius:1px;height:8px;box-shadow:0 0 2px #0009;background:#fff;transform:translate(-2px)}.color-hue-horizontal{background:linear-gradient(to right,red,#ff0 17%,#0f0 33%,#0ff,#00f 67%,#f0f 83%,red)}.color-hue-vertical{background:linear-gradient(to top,red,#ff0 17%,#0f0 33%,#0ff,#00f 67%,#f0f 83%,red)}\n"] }] }], propDecorators: { hsl: [{ type: Input }], pointer: [{ type: Input }], radius: [{ type: Input }], shadow: [{ type: Input }], hidePointer: [{ type: Input }], direction: [{ type: Input }], onChange: [{ type: Output }] } }); class HueModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: HueModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.3", ngImport: i0, type: HueModule, declarations: [HueComponent], imports: [CommonModule, CoordinatesModule], exports: [HueComponent] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: HueModule, imports: [CommonModule, CoordinatesModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: HueModule, decorators: [{ type: NgModule, args: [{ declarations: [HueComponent], exports: [HueComponent], imports: [CommonModule, CoordinatesModule], }] }] }); class RaisedComponent { zDepth = 1; radius = 1; background = '#fff'; static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: RaisedComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.3", type: RaisedComponent, isStandalone: false, selector: "color-raised", inputs: { zDepth: "zDepth", radius: "radius", background: "background" }, ngImport: i0, template: ` <div class="raised-wrap"> <div class="raised-bg zDepth-{{ zDepth }}" [style.background]="background"></div> <div class="raised-content"> <ng-content></ng-content> </div> </div> `, isInline: true, styles: [".raised-wrap{position:relative;display:inline-block}.raised-bg{position:absolute;inset:0}.raised-content{position:relative}.zDepth-0{box-shadow:none}.zDepth-1{box-shadow:0 2px 10px #0000001f,0 2px 5px #00000029}.zDepth-2{box-shadow:0 6px 20px #00000030,0 8px 17px #0003}.zDepth-3{box-shadow:0 17px 50px #00000030,0 12px 15px #0000003d}.zDepth-4{box-shadow:0 25px 55px #00000036,0 16px 28px #00000038}.zDepth-5{box-shadow:0 40px 77px #00000038,0 27px 24px #0003}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: RaisedComponent, decorators: [{ type: Component, args: [{ selector: 'color-raised', template: ` <div class="raised-wrap"> <div class="raised-bg zDepth-{{ zDepth }}" [style.background]="background"></div> <div class="raised-content"> <ng-content></ng-content> </div> </div> `, preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, styles: [".raised-wrap{position:relative;display:inline-block}.raised-bg{position:absolute;inset:0}.raised-content{position:relative}.zDepth-0{box-shadow:none}.zDepth-1{box-shadow:0 2px 10px #0000001f,0 2px 5px #00000029}.zDepth-2{box-shadow:0 6px 20px #00000030,0 8px 17px #0003}.zDepth-3{box-shadow:0 17px 50px #00000030,0 12px 15px #0000003d}.zDepth-4{box-shadow:0 25px 55px #00000036,0 16px 28px #00000038}.zDepth-5{box-shadow:0 40px 77px #00000038,0 27px 24px #0003}\n"] }] }], propDecorators: { zDepth: [{ type: Input }], radius: [{ type: Input }], background: [{ type: Input }] } }); class RaisedModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: RaisedModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.3", ngImport: i0, type: RaisedModule, declarations: [RaisedComponent], imports: [CommonModule], exports: [RaisedComponent] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: RaisedModule, imports: [CommonModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: RaisedModule, decorators: [{ type: NgModule, args: [{ declarations: [RaisedComponent], exports: [RaisedComponent], imports: [CommonModule], }] }] }); class SaturationComponent { hsl; hsv; radius; pointer; circle; onChange = new EventEmitter(); background; pointerTop; pointerLeft; ngOnChanges() { this.background = `hsl(${this.hsl.h}, 100%, 50%)`; this.pointerTop = -(this.hsv.v * 100) + 1 + 100 + '%'; this.pointerLeft = this.hsv.s * 100 + '%'; } handleChange({ top, left, containerHeight, containerWidth, $event }) { if (left < 0) { left = 0; } else if (left > containerWidth) { left = containerWidth; } else if (top < 0) { top = 0; } else if (top > containerHeight) { top = containerHeight; } const saturation = left / containerWidth; let bright = -(top / containerHeight) + 1; bright = bright > 0 ? bright : 0; bright = bright > 1 ? 1 : bright; const data = { h: this.hsl.h, s: saturation, v: bright, a: this.hsl.a, source: 'hsva', }; this.onChange.emit({ data, $event }); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: SaturationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.3", type: SaturationComponent, isStandalone: false, selector: "color-saturation", inputs: { hsl: "hsl", hsv: "hsv", radius: "radius", pointer: "pointer", circle: "circle" }, outputs: { onChange: "onChange" }, usesOnChanges: true, ngImport: i0, template: ` <div class="color-saturation" ngx-color-coordinates (coordinatesChange)="handleChange($event)" [style.background]="background" > <div class="saturation-white"> <div class="saturation-black"></div> <div class="saturation-pointer" [ngStyle]="pointer" [style.top]="pointerTop" [style.left]="pointerLeft" > <div class="saturation-circle" [ngStyle]="circle"></div> </div> </div> </div> `, isInline: true, styles: [".saturation-white{background:linear-gradient(to right,#fff,#fff0);position:absolute;inset:0}.saturation-black{background:linear-gradient(to top,#000,#0000);position:absolute;inset:0}.color-saturation{position:absolute;inset:0}.saturation-pointer{position:absolute;cursor:default}.saturation-circle{width:4px;height:4px;box-shadow:0 0 0 1.5px #fff,inset 0 0 1px 1px #0000004d,0 0 1px 2px #0006;border-radius:50%;cursor:hand;transform:translate(-2px,-4px)}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: CoordinatesDirective, selector: "[ngx-color-coordinates]", outputs: ["coordinatesChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: SaturationComponent, decorators: [{ type: Component, args: [{ selector: 'color-saturation', template: ` <div class="color-saturation" ngx-color-coordinates (coordinatesChange)="handleChange($event)" [style.background]="background" > <div class="saturation-white"> <div class="saturation-black"></div> <div class="saturation-pointer" [ngStyle]="pointer" [style.top]="pointerTop" [style.left]="pointerLeft" > <div class="saturation-circle" [ngStyle]="circle"></div> </div> </div> </div> `, preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, styles: [".saturation-white{background:linear-gradient(to right,#fff,#fff0);position:absolute;inset:0}.saturation-black{background:linear-gradient(to top,#000,#0000);position:absolute;inset:0}.color-saturation{position:absolute;inset:0}.saturation-pointer{position:absolute;cursor:default}.saturation-circle{width:4px;height:4px;box-shadow:0 0 0 1.5px #fff,inset 0 0 1px 1px #0000004d,0 0 1px 2px #0006;border-radius:50%;cursor:hand;transform:translate(-2px,-4px)}\n"] }] }], propDecorators: { hsl: [{ type: Input }], hsv: [{ type: Input }], radius: [{ type: Input }], pointer: [{ type: Input }], circle: [{ type: Input }], onChange: [{ type: Output }] } }); class SaturationModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: SaturationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.3", ngImport: i0, type: SaturationModule, declarations: [SaturationComponent], imports: [CommonModule, CoordinatesModule], exports: [SaturationComponent] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: SaturationModule, imports: [CommonModule, CoordinatesModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: SaturationModule, decorators: [{ type: NgModule, args: [{ declarations: [SaturationComponent], exports: [SaturationComponent], imports: [CommonModule, CoordinatesModule], }] }] }); class SwatchComponent { color; style = {}; focusStyle = {}; focus; onClick = new EventEmitter(); onHover = new EventEmitter(); divStyles = {}; focusStyles = {}; inFocus = false; ngOnInit() { this.divStyles = { background: this.color, ...this.style, }; } currentStyles() { this.focusStyles = { ...this.divStyles, ...this.focusStyle, }; return this.focus || this.inFocus ? this.focusStyles : this.divStyles; } handleFocusOut() { this.inFocus = false; } handleFocus() { this.inFocus = true; } handleHover(hex, $event) { this.onHover.emit({ hex, $event }); } handleClick(hex, $event) { this.onClick.emit({ hex, $event }); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: SwatchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.1.3", type: SwatchComponent, isStandalone: false, selector: "color-swatch", inputs: { color: "color", style: "style", focusStyle: "focusStyle", focus: "focus" }, outputs: { onClick: "onClick", onHover: "onHover" }, ngImport: i0, template: ` <div class="swatch" [ngStyle]="currentStyles()" [attr.title]="color" (click)="handleClick(color, $event)" (keydown.enter)="handleClick(color, $event)" (focus)="handleFocus()" (blur)="handleFocusOut()" (mouseover)="handleHover(color, $event)" tabindex="0" > <ng-content></ng-content> @if (color === 'transparent') { <color-checkboard boxShadow="inset 0 0 0 1px rgba(0,0,0,0.1)"></color-checkboard> } </div> `, isInline: true, styles: [".swatch{outline:none;height:100%;width:100%;cursor:pointer;position:relative}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: CheckboardComponent, selector: "color-checkboard", inputs: ["white", "size", "grey", "boxShadow", "borderRadius"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: SwatchComponent, decorators: [{ type: Component, args: [{ selector: 'color-swatch', template: ` <div class="swatch" [ngStyle]="currentStyles()" [attr.title]="color" (click)="handleClick(color, $event)" (keydown.enter)="handleClick(color, $event)" (focus)="handleFocus()" (blur)="handleFocusOut()" (mouseover)="handleHover(color, $event)" tabindex="0" > <ng-content></ng-content> @if (color === 'transparent') { <color-checkboard boxShadow="inset 0 0 0 1px rgba(0,0,0,0.1)"></color-checkboard> } </div> `, changeDetection: ChangeDete