ngx-input-eip
Version:
Lightweight edit in place text editor.
852 lines (839 loc) • 46.9 kB
JavaScript
import * as i0 from '@angular/core';
import { Directive, Input, EventEmitter, TemplateRef, forwardRef, Component, Output, ViewChild, NgModule } from '@angular/core';
import * as i2 from '@angular/forms';
import { FormGroup, FormControl, Validators, NG_VALUE_ACCESSOR, ReactiveFormsModule } from '@angular/forms';
import { distinctUntilChanged } from 'rxjs/operators';
import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';
const Messages = {
required: 'This field cannot be blank!',
email: `Invalid email!`,
numbersOnly: `Only numbers are allowed!`,
invalid_http_url: `Invalid http url`,
numberOnly: `The value entered is not a number!`,
minlength: (e) => `Minimum length: ${e.requiredLength}, current length: ${e.actualLength}`,
InvalidFormat: (error) => `"${error.value}" is not a valid format. Valid example: "${error.validExample}"`,
pattern: (error) => `"${error.actualValue}" is not a valid format. The format must follow the following regular expression (RegExp): "${error.requiredPattern}"`,
max: (e) => `The value entered is too large! Maximum value: ${e.max}, current value: ${e.actual}`,
maxlength: (e) => `The value entered is too long! Max length: ${e.requiredLength}, current length: ${e.actualLength}`,
};
class ErrorsManager {
static formatErrors(errors, customErrorMessages) {
return new ErrorsManager(errors, customErrorMessages).formatErrors();
}
constructor(errors, customMessages = Messages) {
this.defaultMessages = Messages;
this.messages = {};
this.enableLogging = false;
this.errors = errors;
if (customMessages)
this.mergeMessages(customMessages);
else
this.assignDefaults();
}
assignDefaults() {
this.messages = {};
Object.keys(this.defaultMessages).forEach((key) => {
this.messages[key] = this.defaultMessages[key];
});
}
mergeMessages(messages) {
const keys = [
...Object.keys(this.defaultMessages),
...Object.keys(messages)
];
keys.forEach((key) => {
if (messages[key]) {
this.messages[key] = messages[key];
}
else {
this.messages[key] = this.defaultMessages[key];
}
});
}
formatErrors() {
const result = [
...this.errorMsgFromControl()
];
/**
* TODO write here your custom logic of parsing errors.
*/
return result;
}
warn(...args) {
if (!(this.enableLogging))
return;
console.warn(...args);
}
errorMsgFromControl() {
if (this.errors == undefined || this.errors == null)
return [];
var messages = [];
Object.keys(this.errors).filter((key) => {
if (this.messages.hasOwnProperty(key) && this.messages[key] && this.messages[key] != undefined) {
const field = this.messages[key];
switch (typeof field) {
case 'string':
messages.push(field);
break;
case 'function':
messages.push(field(this.errors[key]));
break;
default:
messages.push(field);
break;
}
return;
}
this.warn(`ReactiveFormsErrors missing error message of "${key}". Parser error with your custom logic.`);
var msg = {};
msg[key] = this.errors[key];
if (!(typeof msg == 'string'))
msg = JSON.stringify(msg);
messages.push(msg);
});
return messages;
}
}
function DefaultErrorsParser(c, customErrorMessages) {
const errors = c.errors;
if (!(errors && Object.keys(errors).length > 0)) {
return [];
}
return ErrorsManager.formatErrors(errors, customErrorMessages);
}
class BaseClass {
}
/**
* Event to trigger (manually) and to listen to when the value of the input changes.
*/
const CustomChangeEvent = 'ngx-autosize';
const InputsDefaults = {
isShort: true,
isMandatory: false,
enableValidations: true,
placeholder: 'Type here...',
label: '',
showLabel: true,
autosave: null,
classes: '',
customValidators: [],
isDisabled: false,
numbersOnly: false,
min: undefined,
max: undefined,
maxLength: undefined,
minLength: undefined,
submitButtonLabel: 'Confirm',
cancelButtonLabel: 'Cancel',
actionbarMode: null,
animateActionbar: true,
allowInvalid: false,
errorsParser: DefaultErrorsParser,
showErrors: true,
customErrorMessages: [],
customErrorsMap: {},
inputStyle: {},
selectOnFocus: true,
};
const selector$1 = 'resizableTextareaContainer';
class ResizableTextareaContainerDirective {
constructor(el, cd) {
this.el = el;
this.cd = cd;
this.enabled = true;
this.defaultHeight = 'auto';
this.element = this.el.nativeElement;
}
ngAfterViewInit() {
this.init();
}
get textarea() {
return this.element.childNodes[0];
}
get container() {
return this.element;
}
get style() {
return this.element.style;
}
get diff() {
return Number(this.style.paddingBottom) + Number(this.style.paddingTop);
}
set height(v) {
if (typeof v == 'number')
v = `${v}px`;
if (!(v && typeof v == 'string' && v.length > 0 && v.indexOf('px') >= 0)) {
this.height = this.defaultHeight;
return;
}
if (this.textarea)
this.textarea.style.height = v;
if (this.container)
this.container.style.minHeight = `${Number(v.replace('px', '')) + 8}px`;
}
get height() {
return this.textarea?.scrollHeight;
}
init() {
this.setInitialHeight();
if (!(this.textarea)) {
// No textarea found, try later.
setTimeout(() => this.init(), 500);
return;
}
this.textarea.addEventListener(`${CustomChangeEvent}`, () => {
this.updateHeight();
});
this.updateHeight();
}
containsText() {
return !!(this.textarea && this.textarea.value.length > 0);
}
setInitialHeight() {
if (this.containsText()) {
this.height = `${this.element.scrollHeight - this.diff}px`;
}
}
updateHeight() {
this.textarea.style.height = '0px';
this.height = `${this.textarea.scrollHeight - this.diff}px`;
this.textarea.dispatchEvent(new CustomEvent('resize'));
// window.scroll({ top: this.textarea!.offsetTop + this.textarea!.offsetHeight });
}
}
ResizableTextareaContainerDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ResizableTextareaContainerDirective, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive });
ResizableTextareaContainerDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.9", type: ResizableTextareaContainerDirective, selector: "[resizableTextareaContainer]", inputs: { enabled: ["resizableTextareaContainer", "enabled"] }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: ResizableTextareaContainerDirective, decorators: [{
type: Directive,
args: [{
selector: `[${selector$1}]`
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { enabled: [{
type: Input,
args: [selector$1]
}] } });
const selector = 'ngx-input-eip';
class NgxInputEipComponent extends BaseClass {
constructor() {
super(...arguments);
this.onSubmit = new EventEmitter();
this.onCancel = new EventEmitter();
/**
* Emit events using this subject.
* The events that will be emitted outside will be filtered.
*/
this.areUnsavedChanges$ = new EventEmitter();
this._areUnsavedChanges = this.areUnsavedChanges$.pipe(distinctUntilChanged());
/**
* This events are listened and emitted from the input.
*/
this.onChange = new EventEmitter();
this.onInput = new EventEmitter();
this.onClick = new EventEmitter();
this.onFocus = new EventEmitter();
this.onResize = new EventEmitter();
this.onDblclick = new EventEmitter();
this.onBlur = new EventEmitter();
this.onKeyDown = new EventEmitter();
this.onKeyPress = new EventEmitter();
this.onKeyUp = new EventEmitter();
/**
* @description
* If the input is `short`, it will appear as a common text input.
* If the input is `long`, it will appear as a textarea.
*/
this.isShort = InputsDefaults['isShort'];
/**
* @description
* If this input is mandatory, it cannot be empty.
* Otherwise its invalid.
*/
this.isMandatory = InputsDefaults['isMandatory'];
/**
* @description
* If this flag is enabled, errors will be shown.
*/
this.enableValidations = InputsDefaults['enableValidations'];
this.inputStyle = InputsDefaults['inputStyle'];
/**
* @description
* The placeholder for the input.
*/
this.placeholder = InputsDefaults['placeholder'];
/**
* @description
* The label for the input.
* Its not mandatory;
* It's possible to pass a custom html-style label too, with `<span label ></span>` attribute.
*/
this.label = InputsDefaults['label'];
/**
* @description
* Show/Hide label.
* This will hide both html-style and text-style labels.
*/
this.showLabel = InputsDefaults['showLabel'];
this.submitButtonLabel = InputsDefaults['submitButtonLabel'];
this.cancelButtonLabel = InputsDefaults['cancelButtonLabel'];
this.avaliableActionbarMode = [null, 'always', 'show', 'overlay'];
this.actionbarMode = InputsDefaults['actionbarMode'];
this.animateActionbar = InputsDefaults['animateActionbar'];
this._autosave = InputsDefaults['autosave'];
this.classes = InputsDefaults['classes'];
/**
* Adding custom user validators.
*/
this.customValidators = InputsDefaults['customValidators'];
this._isDisabled = InputsDefaults['isDisabled'];
/**
* Is a input that allows numbers only?
* If yes:
* - Any non-number character will be removed.
* - Arrow up will increase the value by 1.
* - Arrow down will decrease the value by 1.
* - If the value is empty, it will be set to 0.
* - If the value is not a number, it will be set to 0.
*/
this.numbersOnly = InputsDefaults['numbersOnly'];
/**
* Minimum value for numerical inputs.
*/
this.min = InputsDefaults['min'];
/**
* Maximum value for numerical inputs.
*/
this.max = InputsDefaults['max'];
this.maxLength = InputsDefaults['maxLength'];
this.minLength = InputsDefaults['minLength'];
this.showErrors = InputsDefaults['showErrors'];
this.selectOnFocus = InputsDefaults['selectOnFocus'];
/**
* @description if false and form invalid, changes will not be emitted.
*/
this.allowInvalid = InputsDefaults['allowInvalid'];
this.customErrorMessages = InputsDefaults['customErrorMessages'];
this.customErrorsMap = InputsDefaults['customErrorsMap'];
this.errorsParser = null;
this.form = new FormGroup({
value: new FormControl('', this.validators)
});
this.id = `ngx-input-eip-${Math.random()}`;
this.debugMode = false;
this.emittedValue = '';
this._registerOnTouched = () => { };
this._registerOnChange = () => { };
}
get validActionbarMode() {
return this.avaliableActionbarMode.includes(this.actionbarMode);
}
get defaultActionbarMode() {
return this.isShort ? 'overlay' : 'always';
}
get actionbarClass() {
if (this.autosave)
return 'd-none';
if (this.actionbarMode === null)
return this.defaultActionbarMode;
if (!(this.validActionbarMode)) {
console.warn(`${this.constructor.name}.actionbarClass - Invalid actionbarMode: "${this.actionbarMode}"; Setting default "${this.defaultActionbarMode}". Avaliable options are ${this.avaliableActionbarMode}`);
return this.defaultActionbarMode;
}
return this.actionbarMode;
}
get showActionsBar() {
return !this.autosave;
}
/**
* Ask confirm/deny or save automatically.
*/
set autosave(v) {
this._autosave = v;
}
get autosave() {
return this._autosave == null ? this.isShort : this._autosave;
}
get validators() {
const validators = [
...this.customValidators
];
const addIf = (condition, element) => {
if (!condition)
return;
validators.push(element);
};
addIf(this.isMandatory, Validators.required);
if (this.numbersOnly) {
addIf(this.numbersOnly, Validators.pattern(/^[0-9]*$/));
addIf(!!(this.min != null && this.min && !isNaN(this.min)), Validators.min(this.min));
addIf(!!(this.max != null && this.max && !isNaN(this.max)), Validators.max(this.max));
}
else {
addIf(!!(this.minLength != null && this.minLength && !isNaN(this.minLength)), Validators.minLength(this.minLength));
addIf(!!(this.maxLength != null && this.maxLength && !isNaN(this.maxLength)), Validators.maxLength(this.maxLength));
}
return validators;
}
set isDisabled(v) {
this.setDisabledState(v);
}
get isDisabled() {
return this._isDisabled;
}
get allErrorsMessages() {
if (!this.enableValidations)
return [];
var final = [];
if (this.errorsParser && this.errorsParser != null) {
final = this.errorsParser(this.control);
}
else {
final = DefaultErrorsParser(this.control, (this.customErrorsMap || {}));
}
if (this.customErrorMessages && Array.isArray(this.customErrorMessages))
final = final.concat(this.customErrorMessages);
return final;
}
get stringErrorMessages() {
return this.allErrorsMessages.filter(e => typeof e === 'string');
}
get templateErrorMessages() {
return this.allErrorsMessages.filter(e => e instanceof TemplateRef);
}
get hasErrors() {
return this.allErrorsMessages.length > 0;
}
get value() {
return this.form.value.value;
}
set value(value) {
this.form.patchValue({ value });
}
get control() {
return this.form.get('value');
}
get isLong() {
return !(this.isShort);
}
get invalidForm() {
return this.form.invalid;
}
get showInvalidStatus() {
return this.invalidForm && this.enableValidations && (this.control.touched || this.control.dirty);
}
get isEmpty() {
if (this.value === undefined || this.value === null)
return true;
const value = `${this.value}`.trim();
return !(value.length > 0);
}
get inputStatusClass() {
if (this.showInvalidStatus) {
return 'invalid';
}
if (this.isEmpty) {
return 'empty';
}
return '';
}
set overwriteValue(v) {
this.writeValue(v);
}
get areUnsavedChanges() {
return this.emittedValue !== this.value;
}
get debugJson() {
return {
inputs: {
isShort: this.isShort,
enableValidations: this.enableValidations,
isDisabled: this.isDisabled,
isMandatory: this.isMandatory,
label: this.label,
placeholder: this.placeholder,
autosave: this.autosave,
showLabel: this.showLabel,
numbersOnly: this.numbersOnly,
min: this.min,
max: this.max,
classes: this.classes,
customValidators: this.customValidators,
minLength: this.minLength,
maxLength: this.maxLength,
actionbarMode: this.actionbarMode,
actionbarClass: this.actionbarClass,
allowInvalid: this.allowInvalid,
},
internal: {
value: this.value,
emittedValue: this.emittedValue,
areUnsavedChanges: this.areUnsavedChanges,
showInvalidStatus: this.showInvalidStatus,
control: {
isEmpty: this.isEmpty,
invalid: this.invalidForm,
errors: this.control.errors,
validators: this.validators
},
}
};
}
/**
* CONSTRUCTOR NOT NEEDED HERE
*/
/*****************************************************************
* Angular lifecycle hooks
*****************************************************************/
ngOnInit() {
// super.ngOnInit();
this.validateInputs();
this.onInput.subscribe(ev => this.afterInput(ev));
this.onClick.subscribe(ev => this.afterClick(ev));
this.onFocus.subscribe(ev => this.afterFocus(ev));
this.onKeyDown.subscribe(ev => this.afterKeyDown(ev));
}
ngAfterViewInit() {
// super.ngAfterViewInit();
this.updateValidators();
this.control.valueChanges.subscribe(() => {
this.triggerResize();
});
}
ngOnDestroy() {
// super.ngOnDestroy();
}
/**
* Triggered when any input changes.
*/
ngOnChanges(changes) {
Object.keys(changes).forEach((key) => {
switch (key) {
case 'isMandatory':
case 'enableValidations':
case 'minLength':
case 'maxLength':
case 'min':
case 'max':
case 'numbersOnly':
case 'customValidators':
this.updateValidators();
break;
}
});
setTimeout(() => {
this.triggerResize();
});
this.validateInputs();
}
ngDoCheck(...args) {
// super.ngDoCheck(args);
}
ngAfterContentInit(...args) {
// super.ngAfterContentInit(args);
}
ngAfterContentChecked(...args) {
// super.ngAfterContentChecked(args);
}
ngAfterViewChecked(...args) {
// super.ngAfterViewChecked(args);
}
/*****************************************************************
* Public methods
*****************************************************************/
afterKeyDown(ev) {
var done = () => {
this.valueChanges();
};
if (ev.key === 'Escape') {
// TODO
// cancel but save in localStorage or cookies the element.
// Then show to the user the possibility to restore the element.
if (this.areUnsavedChanges)
return done();
return this.blur();
}
if (ev.key === 'Enter' && this.isShort) {
this.submit();
return done();
}
if (ev.key === 'Tab' && this.isLong) {
return done();
}
if (ev.key == 'Enter' && this.isLong && ev.ctrlKey) {
this.submit();
return done();
}
}
afterInput(ev) {
if (this.numbersOnly && this.value != null && this.value != undefined) {
this.form.patchValue({
value: this.value.toString().replace(/[^0-9|\.|\,]+/gm, '').replace(/[\,]+/gm, '.')
}, { emitEvent: true });
}
this.valueChanges();
}
afterClick(ev) {
ev.stopPropagation();
ev.stopImmediatePropagation();
ev.preventDefault();
}
afterFocus(ev) {
if (this.selectOnFocus && this.input) {
this.input.nativeElement.select();
}
}
focus() {
if (this.input) {
this.input.nativeElement.focus();
}
}
submit() {
var done = () => {
this.onSubmit.emit({
value: this.value,
isValid: this.form.valid,
errors: this.control.errors
});
return this.blur();
};
if (this.autosave) {
this.valueChanges();
return done();
}
this.emitChanges();
done();
this.emitAreUnsavedChanges();
}
cancel() {
if (this.autosave)
return;
this.value = this.emittedValue;
this.blur();
this.emitAreUnsavedChanges();
}
valueChanges() {
this.onChangeTimeout = setTimeout(() => {
this.emitAreUnsavedChanges();
if (this.onChangeTimeout)
clearTimeout(this.onChangeTimeout);
if (this.emittedValue === this.value) {
return; // Nothing changed.
}
if (this.autosave) {
this.emitChanges();
}
}, 200);
}
writeValue(obj) {
let str = ``;
if (typeof obj == 'string')
str = this.formatValue(obj);
else if (typeof obj == 'number')
str = `${obj}`;
this.value = str;
this.emittedValue = str;
}
registerOnChange(fn) {
this._registerOnChange = fn;
}
registerOnTouched(fn) {
this._registerOnTouched = fn;
}
setDisabledState(isDisabled) {
this._isDisabled = !!isDisabled;
var method = this.isDisabled ? 'disable' : 'enable';
this.control[method]();
}
textareaFocus(event) {
this.onFocus.emit(event);
this.triggerResize();
}
triggerResize() {
(this.input?.nativeElement).dispatchEvent(new Event(CustomChangeEvent));
}
/*****************************************************************
* Private/Protected methods
****************************************************************/
emitChanges() {
if (this.hasErrors && !this.allowInvalid)
return;
this._registerOnChange(this.value);
this._registerOnTouched();
this.emittedValue = this.value;
}
formatValue(v) {
if (!(v && typeof v == 'string' && v.length > 0))
return v;
if (this.isLong)
return v;
return v.replace(/\n+/gm, " ");
}
blur() {
this.input?.nativeElement.blur();
}
updateValidators() {
this.control.clearValidators();
this.control.setValidators(this.validators);
this.control.updateValueAndValidity();
}
validateInputs() {
var errors = [];
var warnings = [];
if (this.numbersOnly && this.max && this.min && this.max <= this.min) {
errors.push(`${this.constructor.name} Warning: [max] must be greater than [min]. [max]=${this.max}, [min]=${this.min}`);
this.max = InputsDefaults.max;
this.min = InputsDefaults.min;
}
if (!this.numbersOnly && this.maxLength && this.minLength && this.maxLength <= this.minLength) {
errors.push(`${this.constructor.name} Warning: [maxLength] must be greater than [minLength]. [maxLength]=${this.maxLength}, [minLength]=${this.minLength}`);
this.maxLength = InputsDefaults.maxLength;
this.minLength = InputsDefaults.minLength;
}
for (let msg of warnings) {
console.warn(msg);
}
for (let msg of errors) {
console.error(msg);
}
}
emitAreUnsavedChanges() {
this.areUnsavedChanges$.next(this.areUnsavedChanges);
}
}
NgxInputEipComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NgxInputEipComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
NgxInputEipComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: NgxInputEipComponent, selector: "ngx-input-eip", inputs: { isShort: "isShort", isMandatory: "isMandatory", enableValidations: "enableValidations", inputStyle: "inputStyle", placeholder: "placeholder", label: "label", showLabel: "showLabel", submitButtonLabel: "submitButtonLabel", cancelButtonLabel: "cancelButtonLabel", actionbarMode: "actionbarMode", animateActionbar: "animateActionbar", autosave: "autosave", classes: "classes", customValidators: "customValidators", isDisabled: "isDisabled", numbersOnly: "numbersOnly", min: "min", max: "max", maxLength: "maxLength", minLength: "minLength", showErrors: "showErrors", selectOnFocus: "selectOnFocus", allowInvalid: "allowInvalid", customErrorMessages: "customErrorMessages", customErrorsMap: "customErrorsMap", errorsParser: "errorsParser", overwriteValue: ["value", "overwriteValue"] }, outputs: { onSubmit: "onSubmit", onCancel: "onCancel", _areUnsavedChanges: "areUnsavedChanges", onChange: "onChange", onInput: "onInput", onClick: "onClick", onFocus: "onFocus", onResize: "onResize", onDblclick: "onDblclick", onBlur: "onBlur", onKeyDown: "onKeyDown", onKeyPress: "onKeyPress", onKeyUp: "onKeyUp" }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgxInputEipComponent),
multi: true
}
], viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div [formGroup]=\"form\" class=\"d-flex flex-column\">\n <label [for]=\"id\" *ngIf=\"showLabel\">\n <ng-container *ngIf=\"label\">{{label}}</ng-container>\n <ng-content select=\"[label]\"></ng-content>\n </label>\n\n <div [ngClass]=\"{\n 'show-border': showActionsBar && areUnsavedChanges && this.actionbarClass == 'overlay'\n }\" class=\"border-actionsbar\">\n\n <div class=\"scroll-wrapper\" [resizableTextareaContainer]=\"true\">\n <textarea\n #input\n [rows]=\"1\"\n [id]=\"id\"\n [placeholder]=\"placeholder\"\n formControlName=\"value\"\n class=\"{{inputStatusClass}} {{classes}}\"\n [ngClass]=\"{\n 'is-short': isShort,\n 'is-long': isLong,\n 'active': areUnsavedChanges && !autosave || isEmpty && isShort && isMandatory\n }\"\n\n [ngStyle]=\"inputStyle || {}\"\n\n (resize)=\"onResize.emit($event)\"\n (dblclick)=\"onDblclick.emit($event)\"\n (blur)=\"onBlur.emit($event)\"\n (keypress)=\"onKeyPress.emit($event)\"\n (keyup)=\"onKeyUp.emit($event)\"\n (keydown)=\"onKeyDown.emit($event)\"\n (input)=\"onInput.emit($event)\"\n (change)=\"onChange.emit($event)\"\n (click)=\"onClick.emit($event)\"\n (focus)=\"textareaFocus($event)\"\n ></textarea>\n </div>\n\n <div #customHtmlErrors class=\"errors-container\" [ngClass]=\"{'has-items': showErrors && customHtmlErrors.hasChildNodes()}\" >\n <ng-content select=\"[errors]\" ></ng-content>\n <ng-content select=\"[error]\" ></ng-content>\n </div>\n\n <div class=\"errors-container\" [ngClass]=\"{'has-items': showErrors && hasErrors}\">\n <span *ngFor=\"let error of stringErrorMessages\">{{error}}</span>\n\n <ng-container *ngFor=\"let error of templateErrorMessages\">\n <ng-container *ngTemplateOutlet=\"error\"></ng-container>\n </ng-container>\n </div>\n </div>\n\n\n <ng-content select=\"[after-input]\"></ng-content>\n\n <div *ngIf=\"showActionsBar\" class=\"position-relative\">\n <div class=\"actionsbar {{actionbarClass}}\"\n [ngClass]=\"{'unsavedChanges': areUnsavedChanges, 'has-animation': animateActionbar}\">\n <button [disabled]=\"isDisabled || hasErrors && !allowInvalid\" type=\"button\" (click)=\"submit()\" class=\"confirm\">\n <ng-container *ngIf=\"!submitButtonContainer.hasChildNodes()\">{{submitButtonLabel}}</ng-container>\n\n <span #submitButtonContainer>\n <ng-content select=\"[submitButton]\"></ng-content>\n </span>\n\n </button>\n <button [disabled]=\"isDisabled\" type=\"button\" (click)=\"cancel()\" class=\"cancel\">\n <ng-container *ngIf=\"!cancelButtonContainer.hasChildNodes()\">{{cancelButtonLabel}}</ng-container>\n\n <span #cancelButtonContainer>\n <ng-content select=\"[cancelButton]\"></ng-content>\n </span>\n </button>\n </div>\n </div>\n</div>\n\n<pre *ngIf=\"debugMode\" [innerText]=\"debugJson | json\"></pre>\n", styles: [":host{--active-box-shadow-size: 2px;--error-message-color: red}:host .hidden,:host .hide{visibility:hidden}:host .errors-container{display:flex;flex-direction:column;transition:all 1s;max-height:0px;overflow:hidden}:host .errors-container.has-items{max-height:500px;overflow:auto}:host ::ng-deep .errors-container *{color:var(--error-message-color, red)!important;fill:var(--error-message-color, red)!important;font-size:.75em}:host label{width:-moz-fit-content;width:fit-content}:host *:disabled,:host *.disabled,:host *[disabled]{cursor:not-allowed}:host .border-actionsbar{border:1px solid transparent;display:flex;flex-direction:column}:host .border-actionsbar.show-border{border:1px solid gainsboro;border-radius:5px 5px 5px 0}:host textarea{border:var(--ngx-input-eip-border, 1px solid transparent);outline:var(--ngx-input-eip-outline, none);color:var(--ngx-input-eip-color, rgb(41, 41, 41));background-color:var(--ngx-input-eip-background-color, rgb(255, 255, 255));font-size:var(--ngx-input-eip-font-size, 1em);padding:var(--ngx-input-eip-padding, calc(.2em + var(--active-box-shadow-size)));margin:var(--ngx-input-eip-margin, none);border-radius:var(--ngx-input-eip-border-radius, 5px);box-shadow:inset 0 0 0 var(--active-box-shadow-size) transparent;width:var(--ngx-input-eip-width, 100%);overflow-y:hidden;box-sizing:border-box;resize:none}:host textarea.is-long,:host textarea.is-short.empty{background-color:#091e421f}:host textarea.is-long:hover,:host textarea.is-short.empty:hover{background-color:#091e4214}:host textarea.is-long:hover:not(.focused,:focus,.active,:active,.disabled,:disabled,[disabled]),:host textarea.is-short.empty:hover:not(.focused,:focus,.active,:active,.disabled,:disabled,[disabled]){cursor:pointer}:host textarea.is-long{min-height:60px}:host textarea.focused:not(.disabled):not(:disabled):not([disabled]),:host textarea:focus:not(.disabled):not(:disabled):not([disabled]),:host textarea.active:not(.disabled):not(:disabled):not([disabled]),:host textarea:active:not(.disabled):not(:disabled):not([disabled]){background-color:var(--ngx-input-eip-active-background-input, #fff);box-shadow:inset 0 0 0 var(--active-box-shadow-size) var(--ngx-input-eip-active-box-shadow, #0079bf)}:host .actionsbar{background-color:#fff;display:flex}:host .actionsbar.unsavedChanges,:host .actionsbar.always{padding:var(--ngx-input-eip-padding, calc(.2em + var(--active-box-shadow-size)));opacity:1}:host .actionsbar.show{max-height:0;overflow:hidden}:host .actionsbar.show.has-animation{transition:.5s}:host .actionsbar.show.unsavedChanges{max-height:200px}:host .actionsbar.always{visibility:hidden}:host .actionsbar.always.unsavedChanges{visibility:visible}:host .actionsbar.overlay{position:absolute;top:-1px;margin:0!important;background-color:#fff;border-radius:0 0 5px 5px;border:1px solid gainsboro;border-top:1px solid #fff;z-index:1;display:none}:host .actionsbar.overlay.unsavedChanges{display:block}:host .actionsbar button:first-child{margin-right:10px}:host .actionsbar button.confirm,:host .actionsbar button.cancel{border:none;box-shadow:none;outline:none;border-radius:5px;padding:.3em .6em;transition:background-color .75s}:host .actionsbar button.cancel{background-color:var(--ngx-input-eip-cancel-button-background-color, transparent);color:var(--ngx-input-eip-cancel-button-color, #172b4d)}:host .actionsbar button.cancel:hover{background-color:var(--ngx-input-eip-cancel-button-active-background-color, lightgray)}:host .actionsbar button.confirm{background-color:var(--ngx-input-eip-confirm-button-background-color, #0079bf);color:var(--ngx-input-eip-confirm-button-color, white)}:host .actionsbar button.confirm:hover{background-color:var(--ngx-input-eip-confirm-button-active-background-color, #055a8c)}:host .h1{font-size:2em!important}:host .h2{font-size:1.5em!important}:host .h3{font-size:1.17em!important}:host .h4{font-size:1em!important}:host .h5{font-size:.83em!important}:host .h6{font-size:.67em!important}:host .h1,:host .h2,:host .h3,:host .h4,:host .h5,:host .h6{font-weight:500;line-height:1.2}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: ResizableTextareaContainerDirective, selector: "[resizableTextareaContainer]", inputs: ["resizableTextareaContainer"] }, { kind: "pipe", type: i1.JsonPipe, name: "json" }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NgxInputEipComponent, decorators: [{
type: Component,
args: [{ selector: selector, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => NgxInputEipComponent),
multi: true
}
], template: "<div [formGroup]=\"form\" class=\"d-flex flex-column\">\n <label [for]=\"id\" *ngIf=\"showLabel\">\n <ng-container *ngIf=\"label\">{{label}}</ng-container>\n <ng-content select=\"[label]\"></ng-content>\n </label>\n\n <div [ngClass]=\"{\n 'show-border': showActionsBar && areUnsavedChanges && this.actionbarClass == 'overlay'\n }\" class=\"border-actionsbar\">\n\n <div class=\"scroll-wrapper\" [resizableTextareaContainer]=\"true\">\n <textarea\n #input\n [rows]=\"1\"\n [id]=\"id\"\n [placeholder]=\"placeholder\"\n formControlName=\"value\"\n class=\"{{inputStatusClass}} {{classes}}\"\n [ngClass]=\"{\n 'is-short': isShort,\n 'is-long': isLong,\n 'active': areUnsavedChanges && !autosave || isEmpty && isShort && isMandatory\n }\"\n\n [ngStyle]=\"inputStyle || {}\"\n\n (resize)=\"onResize.emit($event)\"\n (dblclick)=\"onDblclick.emit($event)\"\n (blur)=\"onBlur.emit($event)\"\n (keypress)=\"onKeyPress.emit($event)\"\n (keyup)=\"onKeyUp.emit($event)\"\n (keydown)=\"onKeyDown.emit($event)\"\n (input)=\"onInput.emit($event)\"\n (change)=\"onChange.emit($event)\"\n (click)=\"onClick.emit($event)\"\n (focus)=\"textareaFocus($event)\"\n ></textarea>\n </div>\n\n <div #customHtmlErrors class=\"errors-container\" [ngClass]=\"{'has-items': showErrors && customHtmlErrors.hasChildNodes()}\" >\n <ng-content select=\"[errors]\" ></ng-content>\n <ng-content select=\"[error]\" ></ng-content>\n </div>\n\n <div class=\"errors-container\" [ngClass]=\"{'has-items': showErrors && hasErrors}\">\n <span *ngFor=\"let error of stringErrorMessages\">{{error}}</span>\n\n <ng-container *ngFor=\"let error of templateErrorMessages\">\n <ng-container *ngTemplateOutlet=\"error\"></ng-container>\n </ng-container>\n </div>\n </div>\n\n\n <ng-content select=\"[after-input]\"></ng-content>\n\n <div *ngIf=\"showActionsBar\" class=\"position-relative\">\n <div class=\"actionsbar {{actionbarClass}}\"\n [ngClass]=\"{'unsavedChanges': areUnsavedChanges, 'has-animation': animateActionbar}\">\n <button [disabled]=\"isDisabled || hasErrors && !allowInvalid\" type=\"button\" (click)=\"submit()\" class=\"confirm\">\n <ng-container *ngIf=\"!submitButtonContainer.hasChildNodes()\">{{submitButtonLabel}}</ng-container>\n\n <span #submitButtonContainer>\n <ng-content select=\"[submitButton]\"></ng-content>\n </span>\n\n </button>\n <button [disabled]=\"isDisabled\" type=\"button\" (click)=\"cancel()\" class=\"cancel\">\n <ng-container *ngIf=\"!cancelButtonContainer.hasChildNodes()\">{{cancelButtonLabel}}</ng-container>\n\n <span #cancelButtonContainer>\n <ng-content select=\"[cancelButton]\"></ng-content>\n </span>\n </button>\n </div>\n </div>\n</div>\n\n<pre *ngIf=\"debugMode\" [innerText]=\"debugJson | json\"></pre>\n", styles: [":host{--active-box-shadow-size: 2px;--error-message-color: red}:host .hidden,:host .hide{visibility:hidden}:host .errors-container{display:flex;flex-direction:column;transition:all 1s;max-height:0px;overflow:hidden}:host .errors-container.has-items{max-height:500px;overflow:auto}:host ::ng-deep .errors-container *{color:var(--error-message-color, red)!important;fill:var(--error-message-color, red)!important;font-size:.75em}:host label{width:-moz-fit-content;width:fit-content}:host *:disabled,:host *.disabled,:host *[disabled]{cursor:not-allowed}:host .border-actionsbar{border:1px solid transparent;display:flex;flex-direction:column}:host .border-actionsbar.show-border{border:1px solid gainsboro;border-radius:5px 5px 5px 0}:host textarea{border:var(--ngx-input-eip-border, 1px solid transparent);outline:var(--ngx-input-eip-outline, none);color:var(--ngx-input-eip-color, rgb(41, 41, 41));background-color:var(--ngx-input-eip-background-color, rgb(255, 255, 255));font-size:var(--ngx-input-eip-font-size, 1em);padding:var(--ngx-input-eip-padding, calc(.2em + var(--active-box-shadow-size)));margin:var(--ngx-input-eip-margin, none);border-radius:var(--ngx-input-eip-border-radius, 5px);box-shadow:inset 0 0 0 var(--active-box-shadow-size) transparent;width:var(--ngx-input-eip-width, 100%);overflow-y:hidden;box-sizing:border-box;resize:none}:host textarea.is-long,:host textarea.is-short.empty{background-color:#091e421f}:host textarea.is-long:hover,:host textarea.is-short.empty:hover{background-color:#091e4214}:host textarea.is-long:hover:not(.focused,:focus,.active,:active,.disabled,:disabled,[disabled]),:host textarea.is-short.empty:hover:not(.focused,:focus,.active,:active,.disabled,:disabled,[disabled]){cursor:pointer}:host textarea.is-long{min-height:60px}:host textarea.focused:not(.disabled):not(:disabled):not([disabled]),:host textarea:focus:not(.disabled):not(:disabled):not([disabled]),:host textarea.active:not(.disabled):not(:disabled):not([disabled]),:host textarea:active:not(.disabled):not(:disabled):not([disabled]){background-color:var(--ngx-input-eip-active-background-input, #fff);box-shadow:inset 0 0 0 var(--active-box-shadow-size) var(--ngx-input-eip-active-box-shadow, #0079bf)}:host .actionsbar{background-color:#fff;display:flex}:host .actionsbar.unsavedChanges,:host .actionsbar.always{padding:var(--ngx-input-eip-padding, calc(.2em + var(--active-box-shadow-size)));opacity:1}:host .actionsbar.show{max-height:0;overflow:hidden}:host .actionsbar.show.has-animation{transition:.5s}:host .actionsbar.show.unsavedChanges{max-height:200px}:host .actionsbar.always{visibility:hidden}:host .actionsbar.always.unsavedChanges{visibility:visible}:host .actionsbar.overlay{position:absolute;top:-1px;margin:0!important;background-color:#fff;border-radius:0 0 5px 5px;border:1px solid gainsboro;border-top:1px solid #fff;z-index:1;display:none}:host .actionsbar.overlay.unsavedChanges{display:block}:host .actionsbar button:first-child{margin-right:10px}:host .actionsbar button.confirm,:host .actionsbar button.cancel{border:none;box-shadow:none;outline:none;border-radius:5px;padding:.3em .6em;transition:background-color .75s}:host .actionsbar button.cancel{background-color:var(--ngx-input-eip-cancel-button-background-color, transparent);color:var(--ngx-input-eip-cancel-button-color, #172b4d)}:host .actionsbar button.cancel:hover{background-color:var(--ngx-input-eip-cancel-button-active-background-color, lightgray)}:host .actionsbar button.confirm{background-color:var(--ngx-input-eip-confirm-button-background-color, #0079bf);color:var(--ngx-input-eip-confirm-button-color, white)}:host .actionsbar button.confirm:hover{background-color:var(--ngx-input-eip-confirm-button-active-background-color, #055a8c)}:host .h1{font-size:2em!important}:host .h2{font-size:1.5em!important}:host .h3{font-size:1.17em!important}:host .h4{font-size:1em!important}:host .h5{font-size:.83em!important}:host .h6{font-size:.67em!important}:host .h1,:host .h2,:host .h3,:host .h4,:host .h5,:host .h6{font-weight:500;line-height:1.2}\n"] }]
}], propDecorators: { onSubmit: [{
type: Output
}], onCancel: [{
type: Output
}], _areUnsavedChanges: [{
type: Output,
args: [`areUnsavedChanges`]
}], onChange: [{
type: Output
}], onInput: [{
type: Output
}], onClick: [{
type: Output
}], onFocus: [{
type: Output
}], onResize: [{
type: Output
}], onDblclick: [{
type: Output
}], onBlur: [{
type: Output
}], onKeyDown: [{
type: Output
}], onKeyPress: [{
type: Output
}], onKeyUp: [{
type: Output
}], input: [{
type: ViewChild,
args: ['input']
}], isShort: [{
type: Input
}], isMandatory: [{
type: Input
}], enableValidations: [{
type: Input
}], inputStyle: [{
type: Input
}], placeholder: [{
type: Input
}], label: [{
type: Input
}], showLabel: [{
type: Input
}], submitButtonLabel: [{
type: Input
}], cancelButtonLabel: [{
type: Input
}], actionbarMode: [{
type: Input
}], animateActionbar: [{
type: Input
}], autosave: [{
type: Input
}], classes: [{
type: Input
}], customValidators: [{
type: Input
}], isDisabled: [{
type: Input
}], numbersOnly: [{
type: Input
}], min: [{
type: Input
}], max: [{
type: Input
}], maxLength: [{
type: Input
}], minLength: [{
type: Input
}], showErrors: [{
type: Input
}], selectOnFocus: [{
type: Input
}], allowInvalid: [{
type: Input
}], customErrorMessages: [{
type: Input
}], customErrorsMap: [{
type: Input
}], errorsParser: [{
type: Input
}], overwriteValue: [{
type: Input,
args: ["value"]
}] } });
const declaredExports = [
NgxInputEipComponent,
];
class NgxInputEipModule {
}
NgxInputEipModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NgxInputEipModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
NgxInputEipModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.9", ngImport: i0, type: NgxInputEipModule, declarations: [ResizableTextareaContainerDirective, NgxInputEipComponent], imports: [CommonModule,
ReactiveFormsModule], exports: [NgxInputEipComponent] });
NgxInputEipModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NgxInputEipModule, imports: [CommonModule,
ReactiveFormsModule] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: NgxInputEipModule, decorators: [{
type: NgModule,
args: [{
declarations: [
ResizableTextareaContainerDirective,
...declaredExports,
],
imports: [
CommonModule,
ReactiveFormsModule,
],
exports: [
...declaredExports,
]
}]
}] });
/*
* Public API Surface of ngx-input-eip
*/
/**
* Generated bundle index. Do not edit.
*/
export { NgxInputEipComponent, NgxInputEipModule };
//# sourceMappingURL=ngx-input-eip.mjs.map