UNPKG

carbon-components-angular

Version:
497 lines (492 loc) 17.5 kB
import * as i0 from '@angular/core'; import { EventEmitter, TemplateRef, Component, HostBinding, Input, Output, HostListener, NgModule } from '@angular/core'; import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms'; import * as i1 from 'carbon-components-angular/i18n'; import { I18nModule } from 'carbon-components-angular/i18n'; import * as i2 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i3 from 'carbon-components-angular/icon'; import { IconModule } from 'carbon-components-angular/icon'; /** * Used to emit changes performed on number input components. */ class NumberChange { } /** * Get started with importing the module: * * ```typescript * import { NumberModule } from 'carbon-components-angular'; * ``` * * [See demo](../../?path=/story/components-number--basic) */ class NumberComponent { /** * Creates an instance of `Number`. */ constructor(i18n) { this.i18n = i18n; this.containerClass = true; /** * @deprecated since v5 - Use `cdsLayer` directive instead * `light` or `dark` number input theme. */ this.theme = "dark"; /** * Set to `true` for a disabled number input. */ this.disabled = false; /** * Set to `true` for a loading number component. */ this.skeleton = false; /** * Set to `true` for an invalid number component. */ this.invalid = false; /** * The unique id for the number component. */ this.id = `number-${NumberComponent.numberCount}`; /** * Sets the placeholder attribute on the `input` element. */ this.placeholder = ""; /** * Number input field render size */ this.size = "md"; /** * Sets the min attribute on the `input` element. */ this.min = null; /** * Sets the max attribute on the `input` element. */ this.max = null; /** * Sets the amount the number controls increment and decrement by. */ this.step = 1; /** * Set to `true` to show a warning (contents set by warningText) */ this.warn = false; /** * Emits event notifying other classes when a change in state occurs in the input. */ this.change = new EventEmitter(); this._value = 0; this._decrementLabel = this.i18n.getOverridable("NUMBER.DECREMENT"); this._incrementLabel = this.i18n.getOverridable("NUMBER.INCREMENT"); /** * Called when number input is blurred. Needed to properly implement `ControlValueAccessor`. */ this.onTouched = () => { }; /** * Method set in `registerOnChange` to propagate changes back to the form. */ this.propagateChange = (_) => { }; NumberComponent.numberCount++; } /** * Sets the value attribute on the `input` element. */ set value(v) { if (v === "" || v === null) { this._value = null; return; } this._value = Number(v); } get value() { return this._value; } set decrementLabel(value) { this._decrementLabel.override(value); } get decrementLabel() { return this._decrementLabel.value; } set incrementLabel(value) { this._incrementLabel.override(value); } get incrementLabel() { return this._incrementLabel.value; } /** * This is the initial value set to the component * @param value The input value. */ writeValue(value) { this.value = value; } /** * Sets a method in order to propagate changes back to the form. */ registerOnChange(fn) { this.propagateChange = fn; } /** * Registers a callback to be triggered when the control has been touched. * @param fn Callback to be triggered when the number input is touched. */ registerOnTouched(fn) { this.onTouched = fn; } focusOut() { this.onTouched(); } /** * Sets the disabled state through the model */ setDisabledState(isDisabled) { this.disabled = isDisabled; } /** * Adds `step` to the current `value`. */ onIncrement() { if (this.max === null || this.value + this.step <= this.max) { this.value += this.step; this.value = parseFloat(this.value.toPrecision(this.precision)); this.emitChangeEvent(); } } /** * Subtracts `step` to the current `value`. */ onDecrement() { if (this.min === null || this.value - this.step >= this.min) { this.value -= this.step; this.value = parseFloat(this.value.toPrecision(this.precision)); this.emitChangeEvent(); } } getDecrementLabel() { return this._decrementLabel.subject; } getIncrementLabel() { return this._incrementLabel.subject; } /** * Creates a class of `NumberChange` to emit the change in the `Number`. */ emitChangeEvent() { let event = new NumberChange(); event.source = this; event.value = this.value; this.change.emit(event); this.propagateChange(this.value); } onNumberInputChange(event) { this.value = event.target.value; this.emitChangeEvent(); } isTemplate(value) { return value instanceof TemplateRef; } } /** * Variable used for creating unique ids for number input components. */ NumberComponent.numberCount = 0; NumberComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NumberComponent, deps: [{ token: i1.I18n }], target: i0.ɵɵFactoryTarget.Component }); NumberComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: NumberComponent, selector: "cds-number, ibm-number", inputs: { theme: "theme", disabled: "disabled", skeleton: "skeleton", invalid: "invalid", id: "id", placeholder: "placeholder", size: "size", required: "required", value: "value", min: "min", max: "max", label: "label", helperText: "helperText", invalidText: "invalidText", step: "step", precision: "precision", warn: "warn", warnText: "warnText", ariaLabel: "ariaLabel", decrementLabel: "decrementLabel", incrementLabel: "incrementLabel" }, outputs: { change: "change" }, host: { listeners: { "focusout": "focusOut()" }, properties: { "class.cds--form-item": "this.containerClass" } }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: NumberComponent, multi: true } ], ngImport: i0, template: ` <div data-numberinput [attr.data-invalid]="(invalid ? true : null)" class="cds--number" [ngClass]="{ 'cds--number--light': theme === 'light', 'cds--number--nolabel': !label, 'cds--number--helpertext': helperText, 'cds--skeleton' : skeleton, 'cds--number--sm': size === 'sm', 'cds--number--md': size === 'md', 'cds--number--lg': size === 'lg' }"> <label *ngIf="skeleton && label" class="cds--label cds--skeleton"></label> <label *ngIf="!skeleton && label" [for]="id" class="cds--label" [ngClass]="{'cds--label--disabled': disabled}"> <ng-container *ngIf="!isTemplate(label)">{{label}}</ng-container> <ng-template *ngIf="isTemplate(label)" [ngTemplateOutlet]="label"></ng-template> </label> <div class="cds--number__input-wrapper" [ngClass]="{ 'cds--number__input-wrapper--warning': warn }"> <input type="number" [id]="id" [value]="value" [attr.min]="min" [attr.max]="max" [attr.step]="step" [disabled]="disabled" [required]="required" [attr.aria-label]="ariaLabel" [attr.data-invalid]="invalid ? invalid : null" [placeholder]="placeholder" (change)="onNumberInputChange($event)"/> <svg *ngIf="!skeleton && invalid" cdsIcon="warning--filled" size="16" class="cds--number__invalid"> </svg> <svg *ngIf="!skeleton && !invalid && warn" cdsIcon="warning--alt--filled" size="16" class="cds--number__invalid cds--number__invalid--warning"> </svg> <div *ngIf="!skeleton" class="cds--number__controls"> <button class="cds--number__control-btn down-icon" type="button" [attr.disabled]="disabled ? true : null" aria-live="polite" aria-atomic="true" [attr.aria-label]="getDecrementLabel() | async" (click)="onDecrement()"> <svg cdsIcon="subtract" size="16"></svg> </button> <div class="cds--number__rule-divider"></div> <button class="cds--number__control-btn up-icon" type="button" [attr.disabled]="disabled ? true : null" aria-live="polite" aria-atomic="true" [attr.aria-label]="getIncrementLabel() | async" (click)="onIncrement()"> <svg cdsIcon="add" size="16"></svg> </button> <div class="cds--number__rule-divider"></div> </div> </div> <div *ngIf="helperText && !invalid && !warn" class="cds--form__helper-text" [ngClass]="{ 'cds--form__helper-text--disabled': disabled }"> <ng-container *ngIf="!isTemplate(helperText)">{{helperText}}</ng-container> <ng-template *ngIf="isTemplate(helperText)" [ngTemplateOutlet]="helperText"></ng-template> </div> <div *ngIf="invalid" class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(invalidText)">{{invalidText}}</ng-container> <ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="invalidText"></ng-template> </div> <div *ngIf="!invalid && warn" class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(warnText)">{{warnText}}</ng-container> <ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template> </div> </div> `, isInline: true, dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i3.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }, { kind: "pipe", type: i2.AsyncPipe, name: "async" }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NumberComponent, decorators: [{ type: Component, args: [{ selector: "cds-number, ibm-number", template: ` <div data-numberinput [attr.data-invalid]="(invalid ? true : null)" class="cds--number" [ngClass]="{ 'cds--number--light': theme === 'light', 'cds--number--nolabel': !label, 'cds--number--helpertext': helperText, 'cds--skeleton' : skeleton, 'cds--number--sm': size === 'sm', 'cds--number--md': size === 'md', 'cds--number--lg': size === 'lg' }"> <label *ngIf="skeleton && label" class="cds--label cds--skeleton"></label> <label *ngIf="!skeleton && label" [for]="id" class="cds--label" [ngClass]="{'cds--label--disabled': disabled}"> <ng-container *ngIf="!isTemplate(label)">{{label}}</ng-container> <ng-template *ngIf="isTemplate(label)" [ngTemplateOutlet]="label"></ng-template> </label> <div class="cds--number__input-wrapper" [ngClass]="{ 'cds--number__input-wrapper--warning': warn }"> <input type="number" [id]="id" [value]="value" [attr.min]="min" [attr.max]="max" [attr.step]="step" [disabled]="disabled" [required]="required" [attr.aria-label]="ariaLabel" [attr.data-invalid]="invalid ? invalid : null" [placeholder]="placeholder" (change)="onNumberInputChange($event)"/> <svg *ngIf="!skeleton && invalid" cdsIcon="warning--filled" size="16" class="cds--number__invalid"> </svg> <svg *ngIf="!skeleton && !invalid && warn" cdsIcon="warning--alt--filled" size="16" class="cds--number__invalid cds--number__invalid--warning"> </svg> <div *ngIf="!skeleton" class="cds--number__controls"> <button class="cds--number__control-btn down-icon" type="button" [attr.disabled]="disabled ? true : null" aria-live="polite" aria-atomic="true" [attr.aria-label]="getDecrementLabel() | async" (click)="onDecrement()"> <svg cdsIcon="subtract" size="16"></svg> </button> <div class="cds--number__rule-divider"></div> <button class="cds--number__control-btn up-icon" type="button" [attr.disabled]="disabled ? true : null" aria-live="polite" aria-atomic="true" [attr.aria-label]="getIncrementLabel() | async" (click)="onIncrement()"> <svg cdsIcon="add" size="16"></svg> </button> <div class="cds--number__rule-divider"></div> </div> </div> <div *ngIf="helperText && !invalid && !warn" class="cds--form__helper-text" [ngClass]="{ 'cds--form__helper-text--disabled': disabled }"> <ng-container *ngIf="!isTemplate(helperText)">{{helperText}}</ng-container> <ng-template *ngIf="isTemplate(helperText)" [ngTemplateOutlet]="helperText"></ng-template> </div> <div *ngIf="invalid" class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(invalidText)">{{invalidText}}</ng-container> <ng-template *ngIf="isTemplate(invalidText)" [ngTemplateOutlet]="invalidText"></ng-template> </div> <div *ngIf="!invalid && warn" class="cds--form-requirement"> <ng-container *ngIf="!isTemplate(warnText)">{{warnText}}</ng-container> <ng-template *ngIf="isTemplate(warnText)" [ngTemplateOutlet]="warnText"></ng-template> </div> </div> `, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: NumberComponent, multi: true } ] }] }], ctorParameters: function () { return [{ type: i1.I18n }]; }, propDecorators: { containerClass: [{ type: HostBinding, args: ["class.cds--form-item"] }], theme: [{ type: Input }], disabled: [{ type: Input }], skeleton: [{ type: Input }], invalid: [{ type: Input }], id: [{ type: Input }], placeholder: [{ type: Input }], size: [{ type: Input }], required: [{ type: Input }], value: [{ type: Input }], min: [{ type: Input }], max: [{ type: Input }], label: [{ type: Input }], helperText: [{ type: Input }], invalidText: [{ type: Input }], step: [{ type: Input }], precision: [{ type: Input }], warn: [{ type: Input }], warnText: [{ type: Input }], ariaLabel: [{ type: Input }], change: [{ type: Output }], decrementLabel: [{ type: Input }], incrementLabel: [{ type: Input }], focusOut: [{ type: HostListener, args: ["focusout"] }] } }); // modules class NumberModule { } NumberModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NumberModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); NumberModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: NumberModule, declarations: [NumberComponent], imports: [FormsModule, CommonModule, I18nModule, IconModule], exports: [NumberComponent] }); NumberModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NumberModule, imports: [FormsModule, CommonModule, I18nModule, IconModule] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: NumberModule, decorators: [{ type: NgModule, args: [{ declarations: [ NumberComponent ], exports: [ NumberComponent ], imports: [ FormsModule, CommonModule, I18nModule, IconModule ] }] }] }); /** * Generated bundle index. Do not edit. */ export { NumberComponent as Number, NumberChange, NumberComponent, NumberModule }; //# sourceMappingURL=carbon-components-angular-number-input.mjs.map