carbon-components-angular
Version:
Next generation components
555 lines (546 loc) • 20.6 kB
JavaScript
import * as i0 from '@angular/core';
import { Directive, HostBinding, EventEmitter, TemplateRef, Component, Input, Output, ViewChild, HostListener, NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
import * as i1 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i2 from 'carbon-components-angular/icon';
import { IconModule } from 'carbon-components-angular/icon';
class OptGroup {
constructor() {
this.inputClass = "cds--select-optgroup";
}
}
OptGroup.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: OptGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive });
OptGroup.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: OptGroup, selector: "optgroup", host: { properties: { "class": "this.inputClass" } }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: OptGroup, decorators: [{
type: Directive,
args: [{
// tslint:disable-next-line
selector: "optgroup"
}]
}], propDecorators: { inputClass: [{
type: HostBinding,
args: ["class"]
}] } });
class Option {
constructor() {
this.inputClass = "cds--select-option";
}
}
Option.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Option, deps: [], target: i0.ɵɵFactoryTarget.Directive });
Option.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: Option, selector: "option", host: { properties: { "class": "this.inputClass" } }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Option, decorators: [{
type: Directive,
args: [{
// tslint:disable-next-line
selector: "option"
}]
}], propDecorators: { inputClass: [{
type: HostBinding,
args: ["class"]
}] } });
/**
* `cds-select` provides a styled `select` component. Get started with importing the module:
*
* ```typescript
* import { SelectModule } from 'carbon-components-angular';
* ```
*
* ```html
* <cds-select [(ngModel)]="model">
* <option value="default" disabled selected hidden>Choose an option</option>
* <option value="option1">Option 1</option>
* <option value="option2">Option 2</option>
* <option value="option3">Option 3</option>
* </cds-select>
* ```
*
* [See demo](../../?path=/story/components-select--basic)
*/
class Select {
constructor() {
/**
* `inline` or `default` select displays
*/
this.display = "default";
/**
* Set to `true` to show a warning (contents set by warningText)
*/
this.warn = false;
/**
* Sets the unique ID. Defaults to `select-${total count of selects instantiated}`
*/
this.id = `select-${Select.selectCount++}`;
/**
* Number input field render size
*/
this.size = "md";
/**
* Set to true to disable component.
*/
this.disabled = false;
/**
* Set to true for a loading select.
*/
this.skeleton = false;
/**
* Set to `true` for an invalid select component.
*/
this.invalid = false;
/**
* Set to `true` for readonly state.
*/
this.readonly = false;
/**
* @deprecated since v5 - Use `cdsLayer` directive instead
* `light` or `dark` select theme
*/
this.theme = "dark";
/**
* Experimental: enable fluid state
*/
this.fluid = false;
this.valueChange = new EventEmitter();
this.focused = false;
/**
* placeholder declarations. Replaced by the functions provided to `registerOnChange` and `registerOnTouched`
*/
this.onChangeHandler = (_) => { };
this.onTouchedHandler = () => { };
}
set value(v) {
this._value = v;
if (this.select) {
this.select.nativeElement.value = this._value;
}
}
get value() {
return this._value;
}
ngAfterViewInit() {
if (this.value !== undefined &&
this.value !== null &&
this.select &&
this.select.nativeElement.value !== this.value) {
this.select.nativeElement.value = this.value;
}
}
/**
* Receives a value from the model.
*/
writeValue(obj) {
this.value = obj;
}
/**
* Registers a listener that notifies the model when the control updates
*/
registerOnChange(fn) {
this.onChangeHandler = fn;
}
/**
* Registers a listener that notifies the model when the control is blurred
*/
registerOnTouched(fn) {
this.onTouchedHandler = fn;
}
/**
* Sets the disabled state through the model
*/
setDisabledState(isDisabled) {
this.disabled = isDisabled;
}
/**
* Handles the change event from the `select`.
* Sends events to the change handler and emits a `selected` event.
*/
onChange(event) {
this.value = event.target.value;
this.onChangeHandler(event.target.value);
this.valueChange.emit(event.target.value);
}
/**
* Listens for the host blurring, and notifies the model
*/
focusOut() {
this.onTouchedHandler();
}
isTemplate(value) {
return value instanceof TemplateRef;
}
onMouseDown(event) {
/**
* This prevents the select from opening with mouse
*/
if (this.readonly) {
event.preventDefault();
event.target.focus();
}
}
onKeyDown(event) {
const selectAccessKeys = ["ArrowDown", "ArrowUp", "ArrowLeft", "ArrowRight", " "];
/**
* This prevents the select from opening for the above keys
*/
if (this.readonly && selectAccessKeys.includes(event.key)) {
event.preventDefault();
}
}
handleFocus(event) {
this.focused = event.type === "focus";
}
}
/**
* Tracks the total number of selects instantiated. Used to generate unique IDs
*/
Select.selectCount = 0;
Select.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Select, deps: [], target: i0.ɵɵFactoryTarget.Component });
Select.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: Select, selector: "cds-select, ibm-select", inputs: { value: "value", display: "display", label: "label", helperText: "helperText", invalidText: "invalidText", warn: "warn", warnText: "warnText", id: "id", size: "size", disabled: "disabled", skeleton: "skeleton", invalid: "invalid", readonly: "readonly", theme: "theme", ariaLabel: "ariaLabel", fluid: "fluid" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "focusout": "focusOut()" } }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: Select,
multi: true
}
], viewQueries: [{ propertyName: "select", first: true, predicate: ["select"], descendants: true }], ngImport: i0, template: `
<div
[ngClass]="{
'cds--form-item': !skeleton,
'cds--select--fluid': fluid && !skeleton
}">
<ng-container *ngIf="skeleton && !fluid">
<div *ngIf="label" class="cds--label cds--skeleton"></div>
<div class="cds--select cds--skeleton"></div>
</ng-container>
<ng-container *ngIf="skeleton && fluid">
<div class="cds--list-box__wrapper--fluid">
<div class="cds--list-box cds--skeleton">
<div class="cds--list-box__label"></div>
<div class="cds--list-box__field"></div>
</div>
</div>
</ng-container>
<div
*ngIf="!skeleton"
class="cds--select"
[ngClass]="{
'cds--select--inline': display === 'inline',
'cds--select--light': theme === 'light',
'cds--select--invalid': invalid,
'cds--select--warning': warn,
'cds--select--disabled': disabled,
'cds--select--readonly': readonly,
'cds--select--fluid--invalid': fluid && invalid,
'cds--select--fluid--focus': fluid && focused
}">
<label
*ngIf="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 *ngIf="display === 'inline'; else noInline" class="cds--select-input--inline__wrapper">
<ng-container *ngTemplateOutlet="noInline"></ng-container>
</div>
<div
*ngIf="helperText && !invalid && !warn && !skeleton && !fluid"
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>
</div>
<!-- select element: dynamically projected based on 'display' variant -->
<ng-template #noInline>
<div class="cds--select-input__wrapper" [attr.data-invalid]="(invalid ? true : null)">
<select
#select
[attr.id]="id"
[attr.aria-label]="ariaLabel"
[disabled]="disabled"
(change)="onChange($event)"
[attr.aria-invalid]="invalid ? 'true' : null"
[attr.aria-readonly]="readonly ? 'true' : null"
class="cds--select-input"
[ngClass]="{
'cds--select-input--sm': size === 'sm',
'cds--select-input--md': size === 'md',
'cds--select-input--lg': size === 'lg'
}"
(mousedown)="onMouseDown($event)"
(keydown)="onKeyDown($event)"
(focus)="fluid ? handleFocus($event) : null"
(blur)="fluid ? handleFocus($event) : null">
<ng-content></ng-content>
</select>
<svg
focusable="false"
preserveAspectRatio="xMidYMid meet"
style="will-change: transform;"
xmlns="http://www.w3.org/2000/svg"
class="cds--select__arrow"
width="16"
height="16"
viewBox="0 0 16 16"
aria-hidden="true">
<path d="M8 11L3 6 3.7 5.3 8 9.6 12.3 5.3 13 6z"></path>
</svg>
<svg
*ngIf="invalid"
cdsIcon="warning--filled"
size="16"
class="cds--select__invalid-icon">
</svg>
<svg
*ngIf="!invalid && warn"
cdsIcon="warning--alt--filled"
size="16"
class="cds--select__invalid-icon cds--select__invalid-icon--warning">
</svg>
<ng-container *ngIf="fluid">
<hr class="cds--select__divider" />
<div
*ngIf="invalid && invalidText" role="alert" class="cds--form-requirement" aria-live="polite">
<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>
</ng-container>
</div>
<ng-container *ngIf="!fluid">
<div
*ngIf="invalid && invalidText" role="alert" class="cds--form-requirement" aria-live="polite">
<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>
</ng-container>
</ng-template>
`, isInline: true, dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { 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: i2.IconDirective, selector: "[cdsIcon], [ibmIcon]", inputs: ["ibmIcon", "cdsIcon", "size", "title", "ariaLabel", "ariaLabelledBy", "ariaHidden", "isFocusable"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Select, decorators: [{
type: Component,
args: [{
selector: "cds-select, ibm-select",
template: `
<div
[ngClass]="{
'cds--form-item': !skeleton,
'cds--select--fluid': fluid && !skeleton
}">
<ng-container *ngIf="skeleton && !fluid">
<div *ngIf="label" class="cds--label cds--skeleton"></div>
<div class="cds--select cds--skeleton"></div>
</ng-container>
<ng-container *ngIf="skeleton && fluid">
<div class="cds--list-box__wrapper--fluid">
<div class="cds--list-box cds--skeleton">
<div class="cds--list-box__label"></div>
<div class="cds--list-box__field"></div>
</div>
</div>
</ng-container>
<div
*ngIf="!skeleton"
class="cds--select"
[ngClass]="{
'cds--select--inline': display === 'inline',
'cds--select--light': theme === 'light',
'cds--select--invalid': invalid,
'cds--select--warning': warn,
'cds--select--disabled': disabled,
'cds--select--readonly': readonly,
'cds--select--fluid--invalid': fluid && invalid,
'cds--select--fluid--focus': fluid && focused
}">
<label
*ngIf="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 *ngIf="display === 'inline'; else noInline" class="cds--select-input--inline__wrapper">
<ng-container *ngTemplateOutlet="noInline"></ng-container>
</div>
<div
*ngIf="helperText && !invalid && !warn && !skeleton && !fluid"
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>
</div>
<!-- select element: dynamically projected based on 'display' variant -->
<ng-template #noInline>
<div class="cds--select-input__wrapper" [attr.data-invalid]="(invalid ? true : null)">
<select
#select
[attr.id]="id"
[attr.aria-label]="ariaLabel"
[disabled]="disabled"
(change)="onChange($event)"
[attr.aria-invalid]="invalid ? 'true' : null"
[attr.aria-readonly]="readonly ? 'true' : null"
class="cds--select-input"
[ngClass]="{
'cds--select-input--sm': size === 'sm',
'cds--select-input--md': size === 'md',
'cds--select-input--lg': size === 'lg'
}"
(mousedown)="onMouseDown($event)"
(keydown)="onKeyDown($event)"
(focus)="fluid ? handleFocus($event) : null"
(blur)="fluid ? handleFocus($event) : null">
<ng-content></ng-content>
</select>
<svg
focusable="false"
preserveAspectRatio="xMidYMid meet"
style="will-change: transform;"
xmlns="http://www.w3.org/2000/svg"
class="cds--select__arrow"
width="16"
height="16"
viewBox="0 0 16 16"
aria-hidden="true">
<path d="M8 11L3 6 3.7 5.3 8 9.6 12.3 5.3 13 6z"></path>
</svg>
<svg
*ngIf="invalid"
cdsIcon="warning--filled"
size="16"
class="cds--select__invalid-icon">
</svg>
<svg
*ngIf="!invalid && warn"
cdsIcon="warning--alt--filled"
size="16"
class="cds--select__invalid-icon cds--select__invalid-icon--warning">
</svg>
<ng-container *ngIf="fluid">
<hr class="cds--select__divider" />
<div
*ngIf="invalid && invalidText" role="alert" class="cds--form-requirement" aria-live="polite">
<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>
</ng-container>
</div>
<ng-container *ngIf="!fluid">
<div
*ngIf="invalid && invalidText" role="alert" class="cds--form-requirement" aria-live="polite">
<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>
</ng-container>
</ng-template>
`,
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: Select,
multi: true
}
]
}]
}], propDecorators: { value: [{
type: Input
}], display: [{
type: Input
}], label: [{
type: Input
}], helperText: [{
type: Input
}], invalidText: [{
type: Input
}], warn: [{
type: Input
}], warnText: [{
type: Input
}], id: [{
type: Input
}], size: [{
type: Input
}], disabled: [{
type: Input
}], skeleton: [{
type: Input
}], invalid: [{
type: Input
}], readonly: [{
type: Input
}], theme: [{
type: Input
}], ariaLabel: [{
type: Input
}], fluid: [{
type: Input
}], valueChange: [{
type: Output
}], select: [{
type: ViewChild,
args: ["select"]
}], focusOut: [{
type: HostListener,
args: ["focusout"]
}] } });
// modules
class SelectModule {
}
SelectModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SelectModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
SelectModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: SelectModule, declarations: [Select,
Option,
OptGroup], imports: [CommonModule,
FormsModule,
IconModule], exports: [Select,
Option,
OptGroup] });
SelectModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SelectModule, imports: [CommonModule,
FormsModule,
IconModule] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SelectModule, decorators: [{
type: NgModule,
args: [{
declarations: [
Select,
Option,
OptGroup
],
exports: [
Select,
Option,
OptGroup
],
imports: [
CommonModule,
FormsModule,
IconModule
]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { OptGroup, Option, Select, SelectModule };
//# sourceMappingURL=carbon-components-angular-select.mjs.map