carbon-components-angular
Version:
Next generation components
362 lines (357 loc) • 17.9 kB
JavaScript
import * as i0 from '@angular/core';
import { EventEmitter, Component, HostBinding, Input, Output, ViewChild, 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';
/**
* Get started with importing the module:
*
* ```typescript
* import { SearchModule } from 'carbon-components-angular';
* ```
*
* [See demo](../../?path=/story/components-search--basic)
*/
class Search {
/**
* Creates an instance of `Search`.
* @param i18n The i18n translations.
*/
constructor(elementRef, i18n) {
this.elementRef = elementRef;
this.i18n = i18n;
/**
* @deprecated since v5 - Use `cdsLayer` directive instead
* `light` or `dark` search theme.
*/
this.theme = "dark";
/**
* Size of the search field.
*/
this.size = "md";
/**
* Set to `true` for a disabled search input.
*/
this.disabled = false;
/**
* Set to `true` for a toolbar search component.
*/
this.toolbar = false;
/**
* Set to `true` to make the search component expandable.
* `expandable` would override `toolbar` property behaviours.
*/
this.expandable = false;
/**
* Set to `true` for a loading search component.
*/
this.skeleton = false;
/**
* Set to `true` to expand the toolbar search component.
*/
this.active = false;
/**
* Specifies whether the search component is used in the table toolbar.
*/
this.tableSearch = false;
/**
* The unique id for the search component.
*/
this.id = `search-${Search.searchCount}`;
/**
* Sets the value attribute on the `input` element.
*/
this.value = "";
/**
* Sets the autocomplete attribute on the `input` element.
* For reference: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#Values
*/
this.autocomplete = "on";
/**
* Sets the text inside the `label` tag.
*/
this.label = this.i18n.get().SEARCH.LABEL;
/**
* Sets the placeholder attribute on the `input` element.
*/
this.placeholder = this.i18n.get().SEARCH.PLACEHOLDER;
/**
* Used to set the `title` attribute of the clear button.
*/
this.clearButtonTitle = this.i18n.get().SEARCH.CLEAR_BUTTON;
/**
* Title for the search trigger
*/
this.searchTitle = "";
/**
* Experimental: enable fluid state
*/
this.fluid = false;
/**
* Emits an event when value is changed.
*/
this.valueChange = new EventEmitter();
this.open = new EventEmitter();
/**
* Emits an event when the clear button is clicked.
*/
this.clear = new EventEmitter();
/**
* Emits an event on enter.
*/
this.search = new EventEmitter();
/**
* Sets `true` when composing text via IME.
*/
this.isComposing = false;
/**
* Called when search input is blurred. Needed to properly implement `ControlValueAccessor`.
*/
this.onTouched = () => { };
/**
* Method set in `registerOnChange` to propagate changes back to the form.
*/
this.propagateChange = (_) => { };
Search.searchCount++;
}
get containerClass() {
return !(this.toolbar || this.expandable);
}
get fluidSkeletonClass() {
return this.skeleton && this.fluid;
}
/**
* 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 search input is touched.
*/
registerOnTouched(fn) {
this.onTouched = fn;
}
/**
* Called when text is written in the input.
* @param search The input text.
*/
onSearch(search) {
if (this.isComposing) { // check for IME use
return;
}
this.value = search;
this.doValueChange();
}
/**
* Called on enter.
*/
onEnter() {
this.search.emit(this.value);
}
/**
* Called when clear button is clicked.
*/
clearSearch() {
this.value = "";
this.doValueChange();
this.clear.emit();
}
doValueChange() {
this.propagateChange(this.value);
this.valueChange.emit(this.value);
}
openSearch() {
this.active = true;
this.open.emit(this.active);
setTimeout(() => this.inputRef.nativeElement.focus());
}
keyDown(event) {
if (this.toolbar || this.expandable) {
if (event.key === "Escape") {
if (this.value === "") {
this.active = false;
this.open.emit(this.active);
}
}
else if (event.key === "Enter") {
this.openSearch();
}
}
if (event.key === "Escape") {
if (this.value !== "") {
this.clearSearch();
}
}
}
focusOut(event) {
this.onTouched();
if ((this.expandable || this.toolbar) &&
this.inputRef &&
this.inputRef.nativeElement.value === "" &&
!this.elementRef.nativeElement.contains(event.relatedTarget)) {
this.active = false;
this.open.emit(this.active);
}
}
focusIn(event) {
this.onTouched();
// set input focus if search icon get focus from tab key press event.
if ((this.expandable || this.toolbar) &&
this.inputRef && !event.relatedTarget &&
!this.elementRef.nativeElement.contains(event.relatedTarget)) {
this.openSearch();
}
}
/**
* Called when using IME composition.
*/
compositionStart(event) {
this.isComposing = true;
}
/**
* Called when IME composition finishes.
*/
compositionEnd(event) {
this.isComposing = false;
this.onSearch(this.value + event.data);
}
}
/**
* Variable used for creating unique ids for search components.
*/
Search.searchCount = 0;
Search.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: Search, deps: [{ token: i0.ElementRef }, { token: i1.I18n }], target: i0.ɵɵFactoryTarget.Component });
Search.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: Search, selector: "cds-search, ibm-search", inputs: { theme: "theme", size: "size", disabled: "disabled", toolbar: "toolbar", expandable: "expandable", skeleton: "skeleton", active: "active", tableSearch: "tableSearch", name: "name", id: "id", required: "required", value: "value", autocomplete: "autocomplete", label: "label", placeholder: "placeholder", clearButtonTitle: "clearButtonTitle", searchTitle: "searchTitle", ariaLabel: "ariaLabel", fluid: "fluid" }, outputs: { valueChange: "valueChange", open: "open", clear: "clear", search: "search" }, host: { listeners: { "keydown": "keyDown($event)", "focusout": "focusOut($event)", "focusin": "focusIn($event)", "compositionstart": "compositionStart($event)", "compositionend": "compositionEnd($event)" }, properties: { "class.cds--form-item": "this.containerClass", "class.cds--text-input--fluid__skeleton": "this.fluidSkeletonClass" } }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: Search,
multi: true
}
], viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true }], ngImport: i0, template: "<div\n\tclass=\"cds--search\"\n\t[ngClass]=\"{\n\t\t'cds--search--sm': size === 'sm',\n\t\t'cds--search--md': size === 'md',\n\t\t'cds--search--lg': size === 'lg',\n\t\t'cds--search--light': theme === 'light',\n\t\t'cds--skeleton': skeleton && !fluid,\n\t\t'cds--search--expandable': expandable && !tableSearch,\n\t\t'cds--search--expanded': expandable && !tableSearch && active,\n\t\t'cds--toolbar-search': toolbar && !expandable,\n\t\t'cds--toolbar-search--active': toolbar && !expandable && active,\n\t\t'cds--toolbar-search-container-persistent': tableSearch && !expandable,\n\t\t'cds--toolbar-search-container-expandable': tableSearch && expandable,\n\t\t'cds--toolbar-search-container-active': tableSearch && expandable && active,\n\t\t'cds--search--fluid': fluid,\n\t\t'cds--search--disabled': disabled\n\t}\"\n\trole=\"search\"\n\t[attr.aria-label]=\"ariaLabel\"\n\t(click)=\"openSearch()\">\n\t<label\n\t\tclass=\"cds--label\"\n\t\t[for]=\"id\"\n\t\t[ngClass]=\"{ 'cds--skeleton': skeleton && fluid }\">\n\t\t{{ !skeleton ? label : ''}}\n\t</label>\n\n\t<div *ngIf=\"skeleton; else enableInput\" class=\"cds--text-input cds--skeleton\"></div>\n\t<ng-template #enableInput>\n\t\t<input\n\t\t\t#input\n\t\t\tclass=\"cds--search-input\"\n\t\t\t[type]=\"tableSearch || !toolbar ? 'text' : 'search'\"\n\t\t\t[id]=\"id\"\n\t\t\t[value]=\"value\"\n\t\t\t[autocomplete]=\"autocomplete\"\n\t\t\t[placeholder]=\"placeholder\"\n\t\t\t[disabled]=\"disabled\"\n\t\t\t[required]=\"required\"\n\t\t\t(input)=\"onSearch($event.target.value)\"\n\t\t\t(keyup.enter)=\"onEnter()\"/>\n\t\t<button\n\t\t\t*ngIf=\"!tableSearch && toolbar\"\n\t\t\tclass=\"cds--toolbar-search__btn\"\n\t\t\t(click)=\"openSearch()\"\n\t\t\taria-label=\"Open search\">\n\t\t\t<svg cdsIcon=\"search\" size=\"16\" class=\"cds--search-magnifier-icon\"></svg>\n\t\t</button>\n\t\t<svg\n\t\t\tcdsIcon=\"search\"\n\t\t\t*ngIf=\"tableSearch || !toolbar\"\n\t\t\tclass=\"cds--search-magnifier-icon\"\n\t\t\tsize=\"16\">\n\t\t</svg>\n\t</ng-template>\n\n\t<button\n\t\t*ngIf=\"tableSearch || !toolbar\"\n\t\tclass=\"cds--search-close\"\n\t\t[ngClass]=\"{\n\t\t\t'cds--search-close--hidden': !value || value.length === 0\n\t\t}\"\n\t\t[title]=\"clearButtonTitle\"\n\t\t(click)=\"clearSearch()\">\n\t\t<span class=\"cds--visually-hidden\">{{ clearButtonTitle }}</span>\n\t\t<svg cdsIcon=\"close\" size=\"16\"></svg>\n\t</button>\n</div>\n", 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: i3.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: Search, decorators: [{
type: Component,
args: [{ selector: "cds-search, ibm-search", providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: Search,
multi: true
}
], template: "<div\n\tclass=\"cds--search\"\n\t[ngClass]=\"{\n\t\t'cds--search--sm': size === 'sm',\n\t\t'cds--search--md': size === 'md',\n\t\t'cds--search--lg': size === 'lg',\n\t\t'cds--search--light': theme === 'light',\n\t\t'cds--skeleton': skeleton && !fluid,\n\t\t'cds--search--expandable': expandable && !tableSearch,\n\t\t'cds--search--expanded': expandable && !tableSearch && active,\n\t\t'cds--toolbar-search': toolbar && !expandable,\n\t\t'cds--toolbar-search--active': toolbar && !expandable && active,\n\t\t'cds--toolbar-search-container-persistent': tableSearch && !expandable,\n\t\t'cds--toolbar-search-container-expandable': tableSearch && expandable,\n\t\t'cds--toolbar-search-container-active': tableSearch && expandable && active,\n\t\t'cds--search--fluid': fluid,\n\t\t'cds--search--disabled': disabled\n\t}\"\n\trole=\"search\"\n\t[attr.aria-label]=\"ariaLabel\"\n\t(click)=\"openSearch()\">\n\t<label\n\t\tclass=\"cds--label\"\n\t\t[for]=\"id\"\n\t\t[ngClass]=\"{ 'cds--skeleton': skeleton && fluid }\">\n\t\t{{ !skeleton ? label : ''}}\n\t</label>\n\n\t<div *ngIf=\"skeleton; else enableInput\" class=\"cds--text-input cds--skeleton\"></div>\n\t<ng-template #enableInput>\n\t\t<input\n\t\t\t#input\n\t\t\tclass=\"cds--search-input\"\n\t\t\t[type]=\"tableSearch || !toolbar ? 'text' : 'search'\"\n\t\t\t[id]=\"id\"\n\t\t\t[value]=\"value\"\n\t\t\t[autocomplete]=\"autocomplete\"\n\t\t\t[placeholder]=\"placeholder\"\n\t\t\t[disabled]=\"disabled\"\n\t\t\t[required]=\"required\"\n\t\t\t(input)=\"onSearch($event.target.value)\"\n\t\t\t(keyup.enter)=\"onEnter()\"/>\n\t\t<button\n\t\t\t*ngIf=\"!tableSearch && toolbar\"\n\t\t\tclass=\"cds--toolbar-search__btn\"\n\t\t\t(click)=\"openSearch()\"\n\t\t\taria-label=\"Open search\">\n\t\t\t<svg cdsIcon=\"search\" size=\"16\" class=\"cds--search-magnifier-icon\"></svg>\n\t\t</button>\n\t\t<svg\n\t\t\tcdsIcon=\"search\"\n\t\t\t*ngIf=\"tableSearch || !toolbar\"\n\t\t\tclass=\"cds--search-magnifier-icon\"\n\t\t\tsize=\"16\">\n\t\t</svg>\n\t</ng-template>\n\n\t<button\n\t\t*ngIf=\"tableSearch || !toolbar\"\n\t\tclass=\"cds--search-close\"\n\t\t[ngClass]=\"{\n\t\t\t'cds--search-close--hidden': !value || value.length === 0\n\t\t}\"\n\t\t[title]=\"clearButtonTitle\"\n\t\t(click)=\"clearSearch()\">\n\t\t<span class=\"cds--visually-hidden\">{{ clearButtonTitle }}</span>\n\t\t<svg cdsIcon=\"close\" size=\"16\"></svg>\n\t</button>\n</div>\n" }]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.I18n }]; }, propDecorators: { containerClass: [{
type: HostBinding,
args: ["class.cds--form-item"]
}], fluidSkeletonClass: [{
type: HostBinding,
args: ["class.cds--text-input--fluid__skeleton"]
}], theme: [{
type: Input
}], size: [{
type: Input
}], disabled: [{
type: Input
}], toolbar: [{
type: Input
}], expandable: [{
type: Input
}], skeleton: [{
type: Input
}], active: [{
type: Input
}], tableSearch: [{
type: Input
}], name: [{
type: Input
}], id: [{
type: Input
}], required: [{
type: Input
}], value: [{
type: Input
}], autocomplete: [{
type: Input
}], label: [{
type: Input
}], placeholder: [{
type: Input
}], clearButtonTitle: [{
type: Input
}], searchTitle: [{
type: Input
}], ariaLabel: [{
type: Input
}], fluid: [{
type: Input
}], valueChange: [{
type: Output
}], open: [{
type: Output
}], clear: [{
type: Output
}], search: [{
type: Output
}], inputRef: [{
type: ViewChild,
args: ["input"]
}], keyDown: [{
type: HostListener,
args: ["keydown", ["$event"]]
}], focusOut: [{
type: HostListener,
args: ["focusout", ["$event"]]
}], focusIn: [{
type: HostListener,
args: ["focusin", ["$event"]]
}], compositionStart: [{
type: HostListener,
args: ["compositionstart", ["$event"]]
}], compositionEnd: [{
type: HostListener,
args: ["compositionend", ["$event"]]
}] } });
// modules
class SearchModule {
}
SearchModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SearchModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
SearchModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: SearchModule, declarations: [Search], imports: [FormsModule,
CommonModule,
I18nModule,
IconModule], exports: [Search] });
SearchModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SearchModule, imports: [FormsModule,
CommonModule,
I18nModule,
IconModule] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: SearchModule, decorators: [{
type: NgModule,
args: [{
declarations: [
Search
],
exports: [
Search
],
imports: [
FormsModule,
CommonModule,
I18nModule,
IconModule
]
}]
}] });
/**
* Generated bundle index. Do not edit.
*/
export { Search, SearchModule };
//# sourceMappingURL=carbon-components-angular-search.mjs.map