UNPKG

@duoduo-oba/ng-devui

Version:

DevUI components based on Angular

650 lines (644 loc) 22.8 kB
import { forwardRef, EventEmitter, Component, ChangeDetectorRef, ElementRef, Input, Output, ViewChild, NgModule } from '@angular/core'; import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms'; import { fromEvent } from 'rxjs'; import { CommonModule } from '@angular/common'; /** * @fileoverview added by tsickle * Generated from: input-number.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** @type {?} */ const INPUT_NUMBER_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, // tslint:disable-next-line useExisting: forwardRef((/** * @return {?} */ () => InputNumberComponent)), multi: true }; class InputNumberComponent { /** * @param {?} cdr * @param {?} el */ constructor(cdr, el) { this.cdr = cdr; this.el = el; this.max = 100; this.min = 0; this.step = 1; this.disabled = false; this.size = ''; this.autoFocus = false; this.allowEmpty = false; this.placeholder = ''; this.maxLength = 0; this.afterValueChanged = new EventEmitter(); this.whileValueChanging = new EventEmitter(); this.disabledInc = false; this.disabledDec = false; this.onTouchedCallback = (/** * @param {?} v * @return {?} */ (v) => { }); this.onChangeCallback = (/** * @param {?} v * @return {?} */ (v) => { }); } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this.onChangeCallback = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { this.onTouchedCallback = fn; } /** * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { this.disabled = isDisabled; this.toggleDisabled(isDisabled); } /** * @param {?} newValue * @return {?} */ writeValue(newValue) { this.lastEmittedValue = newValue; this.setValue(this.ensureValueInRange(newValue)); } /** * @private * @param {?} value * @return {?} */ valueMustBeValid(value) { return !isNaN(typeof value !== 'number' ? parseFloat(value) : value); } /** * @private * @param {?} min * @param {?} n * @param {?} max * @return {?} */ clamp(min, n, max) { return Math.max(min, Math.min(n, max)); } /** * @private * @param {?} value * @return {?} */ ensureValueInRange(value) { /** @type {?} */ let safeValue; if (this.allowEmpty && (value === null || value === undefined)) { safeValue = value; } else if (!this.valueMustBeValid(value)) { safeValue = this.min; } else { /** @type {?} */ let currentValue = value; if (!value) { currentValue = 0; } safeValue = this.clamp(this.min, currentValue, this.max); } return safeValue; } /** * @private * @param {?} value * @return {?} */ setValue(value) { this.value = value; this.valueInput = value; if (this.disabled) { return; } if (this.allowEmpty && (value === null || value === undefined)) { this.subscribeDecAction(); this.subscribeIncAction(); } else { if (!this.canDecrease()) { this.unsubscribeDecAction(); } else { this.subscribeDecAction(); } if (!this.canIncrease()) { this.unsubscribeIncAction(); } else { this.subscribeIncAction(); } } this.cdr.detectChanges(); } /** * @return {?} */ ngAfterViewInit() { this.registerListeners(); this.subscribeActions(); this.toggleDisabled(this.disabled); this.el.nativeElement.addEventListener('click', this.registerBlurListener.bind(this)); if (this.autoFocus) { this.el.nativeElement.click(); this.inputElement.nativeElement.focus(); } } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { if (changes.hasOwnProperty('min') || changes.hasOwnProperty('max')) { this.checkRangeValues(this.min, this.max); } } /** * @return {?} */ ngOnDestroy() { this.unsubscribeActions(); } /** * @return {?} */ registerListeners() { if (this.incButton && this.incButton.nativeElement) { this.incListener = fromEvent(this.incButton.nativeElement, 'click'); } if (this.decButton && this.decButton.nativeElement) { this.decListener = fromEvent(this.decButton.nativeElement, 'click'); } } /** * @return {?} */ subscribeActions() { this.subscribeIncAction(); this.subscribeDecAction(); } /** * @return {?} */ subscribeIncAction() { if (this.incListener && !this.incAction) { this.incAction = this.incListener.subscribe(this.increaseValue.bind(this)); this.disabledInc = false; } } /** * @return {?} */ subscribeDecAction() { if (this.decListener && !this.decAction) { this.decAction = this.decListener.subscribe(this.decreaseValue.bind(this)); this.disabledDec = false; } } /** * @return {?} */ unsubscribeActions() { this.unsubscribeIncAction(); this.unsubscribeDecAction(); } /** * @return {?} */ unsubscribeIncAction() { if (this.incListener && this.incAction) { this.incAction.unsubscribe(); this.incAction = null; this.disabledInc = true; } } /** * @return {?} */ unsubscribeDecAction() { if (this.incListener && this.decAction) { this.decAction.unsubscribe(); this.decAction = null; this.disabledDec = true; } } /** * @private * @return {?} */ increaseValue() { if (this.canIncrease()) { if (this.allowEmpty && (this.value === null || this.value === undefined)) { this.updateValue(this.min); } else { /** @type {?} */ const decimals = this.getMaxDecimals(this.value); this.updateValue(parseFloat((this.value + this.step).toFixed(decimals))); } } } /** * @private * @return {?} */ decreaseValue() { if (this.canDecrease()) { if (this.allowEmpty && (this.value === null || this.value === undefined)) { this.updateValue(this.min); } else { /** @type {?} */ const decimals = this.getMaxDecimals(this.value); this.updateValue(parseFloat((this.value - this.step).toFixed(decimals))); } } } /** * @private * @return {?} */ canIncrease() { if (this.allowEmpty && (this.value === null || this.value === undefined)) { return (this.min + this.step) <= this.max; } else { return (this.value + this.step) <= this.max; } } /** * @private * @return {?} */ canDecrease() { if (this.allowEmpty && (this.value === null || this.value === undefined)) { return (this.min + this.step) <= this.max; } else { return (this.value - this.step) >= this.min; } } /** * @private * @param {?} disabled * @return {?} */ toggleDisabled(disabled) { if (disabled) { this.unsubscribeActions(); } else { this.subscribeActions(); } } /** * @param {?} event * @return {?} */ ensureValueIsValid(event) { event.stopPropagation(); /** @type {?} */ const newValue = event.target['value']; /** @type {?} */ const parseValue = parseFloat((/** @type {?} */ (newValue))); if (this.allowEmpty && newValue === '') { this.updateValue(this.ensureValueInRange(null)); } else if (!isNaN(parseValue)) { this.updateValue(this.ensureValueInRange(parseValue)); } else { this.updateValue(this.ensureValueInRange(this.value)); } } /** * @private * @param {?} minValue * @param {?} maxValue * @return {?} */ checkRangeValues(minValue, maxValue) { if (maxValue < minValue) { throw new Error(`max value must be greater than or equal to min value`); } } /** * @private * @param {?} value * @return {?} */ getDecimals(value) { /** @type {?} */ const valueString = value.toString(); /** @type {?} */ const integerLength = valueString.indexOf('.') + 1; return integerLength >= 0 ? valueString.length - integerLength : 0; } /** * @private * @param {?} currentValue * @return {?} */ getMaxDecimals(currentValue) { /** @type {?} */ const stepPrecision = this.getDecimals(this.step); /** @type {?} */ const currentValuePrecision = this.getDecimals((/** @type {?} */ (currentValue))); if (!currentValue) { return stepPrecision; } if (this.decimalLimit !== undefined && this.decimalLimit !== null) { return this.decimalLimit; } return Math.max(currentValuePrecision, stepPrecision); } /** * @param {?} event * @return {?} */ protectInput(event) { /** @type {?} */ let value = event.target['value']; /** @type {?} */ const input = String.fromCharCode(event.which); /** @type {?} */ const selectionStart = event.target['selectionStart']; /** @type {?} */ const selectionEnd = event.target['selectionEnd']; value = value.substring(0, selectionStart) + input + value.substring(selectionEnd); if (this.maxLength && value.length > this.maxLength) { event.preventDefault(); return; } if (this.reg && !value.match(new RegExp(this.reg))) { event.preventDefault(); return; } else if (value === '-' || value.match(/^\s*(-|\+)?\d+\.$/) || value.match(/^\s*(-|\+)?\d+\.[0-9]*0$/) || value.match(/^\s*(-|\+)0+$/)) { // indeterminate state return; } else if (value.match(/^\s*(-|\+)?(\d+|(\d*(\.\d*)))$/)) { event.preventDefault(); if (this.decimalLimit !== undefined && this.decimalLimit !== null) { value = parseFloat(value).toFixed(this.decimalLimit); } value = parseFloat((/** @type {?} */ (value))); if (!isNaN(value)) { this.valueInput = value; this.notifyWhileValueChanging(value); // updateValue会使输入游标跳到最后,这里设置输入游标归位 setTimeout((/** * @return {?} */ () => { event.target['setSelectionRange'](selectionStart + 1, selectionStart + 1); }), 0); return; } } else { event.preventDefault(); } } /** * @private * @return {?} */ notifyValueChange() { this.afterValueChanged.emit(this.value); this.onChangeCallback(this.value); } /** * @private * @param {?} value * @return {?} */ notifyWhileValueChanging(value) { this.whileValueChanging.emit(value); } /** * @private * @param {?} value * @return {?} */ updateValue(value) { this.setValue(value); if (this.lastEmittedValue !== value) { this.lastEmittedValue = value; this.notifyValueChange(); } } /** * @param {?} event * @return {?} */ handleBackspace(event) { if (event.key === 'Backspace') { /** @type {?} */ let oldValue = event.target['value']; /** @type {?} */ const selectionStart = event.target['selectionStart']; /** @type {?} */ const selectionEnd = event.target['selectionEnd']; /** @type {?} */ let newValue = oldValue.substring(0, selectionStart - 1) + oldValue.substring(selectionEnd); oldValue = oldValue === '' ? null : this.ensureValueInRange(oldValue); newValue = newValue === '' ? null : this.ensureValueInRange(newValue); if (oldValue !== newValue && newValue !== '-') { this.notifyWhileValueChanging(newValue); } } } /** * @return {?} */ registerBlurListener() { document.addEventListener('click', this.emitBlurEvent.bind(this), { capture: true, once: true, }); } /** * @param {?} event * @return {?} */ emitBlurEvent(event) { if (this.el.nativeElement !== event.target && !this.el.nativeElement.contains(event.target)) { this.el.nativeElement.dispatchEvent(new Event('blur', { bubbles: false })); } } } InputNumberComponent.decorators = [ { type: Component, args: [{ selector: 'd-input-number', template: "<div\r\n class=\"input-control-buttons\"\r\n [ngClass]=\"{\r\n disabled: disabled,\r\n 'devui-input-number-lg': size === 'lg',\r\n 'devui-input-number-sm': size === 'sm'\r\n }\"\r\n>\r\n <span class=\"input-control-button input-control-inc\" [ngClass]=\"{ disabled: disabledInc }\" #incButton>\r\n <svg class=\"devui-svg-icon-arrow\" width=\"15px\" height=\"15px\" viewBox=\"0 0 16 16\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <g id=\"chevron-up\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\r\n <polygon points=\"11.5 12 8 8.23076923 4.5 12 3 10.3846154 8 5 13 10.3846154\"></polygon>\r\n </g>\r\n </svg>\r\n </span>\r\n <span class=\"input-control-button input-control-dec\" [ngClass]=\"{ disabled: disabledDec }\" #decButton>\r\n <svg class=\"devui-svg-icon-arrow\" width=\"15px\" height=\"15px\" viewBox=\"0 0 16 16\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <g id=\"chevron-down\" stroke=\"none\" stroke-width=\"1\" fill-rule=\"evenodd\">\r\n <polygon points=\"4.5 5 8 8.76923077 11.5 5 13 6.61538462 8 12 3 6.61538462\"></polygon>\r\n </g>\r\n </svg>\r\n </span>\r\n</div>\r\n<div\r\n class=\"input-container\"\r\n [ngClass]=\"{\r\n 'devui-input-number-lg': size === 'lg',\r\n 'devui-input-number-sm': size === 'sm'\r\n }\"\r\n>\r\n <input\r\n class=\"input-box\"\r\n [(ngModel)]=\"valueInput\"\r\n [ngClass]=\"{ disabled: disabled }\"\r\n [placeholder]=\"placeholder\"\r\n [attr.readonly]=\"disabled ? '' : null\"\r\n (keypress)=\"protectInput($event)\"\r\n (blur)=\"ensureValueIsValid($event)\"\r\n (keydown)=\"handleBackspace($event)\"\r\n #inputElement\r\n />\r\n</div>\r\n", providers: [INPUT_NUMBER_CONTROL_VALUE_ACCESSOR], styles: [":host{display:inline-block;position:relative;width:80px}:host .disabled{cursor:not-allowed;opacity:.3}:host:hover .input-box:not(.disabled){border:1px solid #344899;padding-right:26px}:host:hover .input-control-buttons:not(.disabled){border-color:#344899;display:-webkit-box;display:flex}:host:focus-within .input-box:not(.disabled){border:1px solid #344899;padding-right:26px}:host:focus-within .input-control-buttons:not(.disabled){border-color:#344899;display:-webkit-box;display:flex}:host .input-box{box-sizing:border-box;padding:5px 10px;font-size:14px;color:#252b3a;vertical-align:middle;border:1px solid #adb0b8;border-radius:2px;outline:0;width:100%;background-color:#fff;line-height:20px;height:32px}:host .input-control-buttons{position:absolute;right:0;width:25px;height:100%;display:none;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column;-webkit-box-pack:center;justify-content:center;-webkit-box-align:center;align-items:center;border:1px solid transparent;border-left-color:#adb0b8;box-sizing:border-box;line-height:100%}:host .input-control-buttons .input-control-button{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;box-sizing:border-box;height:50%;line-height:50%;border-width:0 1px;cursor:pointer;-webkit-transition:-webkit-transform .2s ease-in-out;transition:transform .2s ease-in-out;transition:transform .2s ease-in-out,-webkit-transform .2s ease-in-out;display:-webkit-box;display:flex;-webkit-box-pack:center;justify-content:center;-webkit-box-align:center;align-items:center}:host .input-control-buttons .input-control-button svg>g{fill:#252b3a}:host .input-control-buttons .input-control-button:not(.disabled):hover>svg>g{fill:#344899}.devui-input-number-lg>.input-box{font-size:18px;line-height:24px;height:46px}.devui-input-number-lg ::ng-deep .devui-svg-icon-arrow{width:16px;height:16px}.devui-input-number-sm>.input-box{font-size:12px;line-height:18px;height:30px}.devui-input-number-sm ::ng-deep .devui-svg-icon-arrow{width:13px;height:13px}.input-container{line-height:100%}"] }] } ]; /** @nocollapse */ InputNumberComponent.ctorParameters = () => [ { type: ChangeDetectorRef }, { type: ElementRef } ]; InputNumberComponent.propDecorators = { max: [{ type: Input }], min: [{ type: Input }], step: [{ type: Input }], disabled: [{ type: Input }], size: [{ type: Input }], decimalLimit: [{ type: Input }], autoFocus: [{ type: Input }], allowEmpty: [{ type: Input }], placeholder: [{ type: Input }], maxLength: [{ type: Input }], reg: [{ type: Input }], afterValueChanged: [{ type: Output }], whileValueChanging: [{ type: Output }], incButton: [{ type: ViewChild, args: ['incButton', { static: true },] }], decButton: [{ type: ViewChild, args: ['decButton', { static: true },] }], inputElement: [{ type: ViewChild, args: ['inputElement', { static: true },] }] }; if (false) { /** @type {?} */ InputNumberComponent.prototype.max; /** @type {?} */ InputNumberComponent.prototype.min; /** @type {?} */ InputNumberComponent.prototype.step; /** @type {?} */ InputNumberComponent.prototype.disabled; /** @type {?} */ InputNumberComponent.prototype.size; /** @type {?} */ InputNumberComponent.prototype.decimalLimit; /** @type {?} */ InputNumberComponent.prototype.autoFocus; /** @type {?} */ InputNumberComponent.prototype.allowEmpty; /** @type {?} */ InputNumberComponent.prototype.placeholder; /** @type {?} */ InputNumberComponent.prototype.maxLength; /** @type {?} */ InputNumberComponent.prototype.reg; /** @type {?} */ InputNumberComponent.prototype.afterValueChanged; /** @type {?} */ InputNumberComponent.prototype.whileValueChanging; /** @type {?} */ InputNumberComponent.prototype.incButton; /** @type {?} */ InputNumberComponent.prototype.decButton; /** @type {?} */ InputNumberComponent.prototype.inputElement; /** * @type {?} * @private */ InputNumberComponent.prototype.value; /** * @type {?} * @private */ InputNumberComponent.prototype.incListener; /** * @type {?} * @private */ InputNumberComponent.prototype.decListener; /** * @type {?} * @private */ InputNumberComponent.prototype.incAction; /** * @type {?} * @private */ InputNumberComponent.prototype.decAction; /** @type {?} */ InputNumberComponent.prototype.disabledInc; /** @type {?} */ InputNumberComponent.prototype.disabledDec; /** @type {?} */ InputNumberComponent.prototype.valueInput; /** @type {?} */ InputNumberComponent.prototype.lastEmittedValue; /** * @type {?} * @private */ InputNumberComponent.prototype.onTouchedCallback; /** * @type {?} * @private */ InputNumberComponent.prototype.onChangeCallback; /** * @type {?} * @private */ InputNumberComponent.prototype.cdr; /** * @type {?} * @private */ InputNumberComponent.prototype.el; } /** * @fileoverview added by tsickle * Generated from: input-number.module.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ class InputNumberModule { } InputNumberModule.decorators = [ { type: NgModule, args: [{ imports: [ CommonModule, FormsModule ], exports: [InputNumberComponent], declarations: [InputNumberComponent], providers: [], },] } ]; /** * @fileoverview added by tsickle * Generated from: public-api.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @fileoverview added by tsickle * Generated from: ng-devui-input-number.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ export { InputNumberComponent, InputNumberModule }; //# sourceMappingURL=ng-devui-input-number.js.map