UNPKG

carbon-components-angular

Version:
277 lines (271 loc) 11.6 kB
import * as i0 from '@angular/core'; import { EventEmitter, Directive, Input, Output, HostBinding, HostListener, Component, ContentChildren, NgModule } from '@angular/core'; import { isFocusInFirstItem, isFocusInLastItem } from 'carbon-components-angular/common'; import * as i1 from '@angular/common'; import { CommonModule } from '@angular/common'; class ContentSwitcherOption { constructor(renderer, hostElement) { this.renderer = renderer; this.hostElement = hostElement; /** * Internal name for the option. * Should be something that identifies the option to the application. * Accessible from the `ContentSwitcher` `selected` emitter */ this.name = "option"; /** * Emits when the option is selected. */ this.selected = new EventEmitter(); this.onClick = new EventEmitter(); this.onFocus = new EventEmitter(); this.switcherClass = "cds--content-switcher-btn"; this.selectedClass = false; this.role = "tab"; this.ariaSelected = false; this.tabindex = "-1"; this._active = false; } /** * Used to activate the option. Only one option may be `active` at a time */ set active(value) { this._active = value; this.selectedClass = value; this.ariaSelected = value; this.tabindex = value ? "0" : "-1"; } get active() { return this._active; } hostClick(event) { this.onClick.emit(event); // skip setting and emitting if the option is already active if (this.active) { return; } this.active = true; this.selected.emit(true); } doFocus(event) { this.onFocus.emit(event); // skip setting and emitting if the option is already active if (this.active) { return; } this.active = true; this.selected.emit(true); } /* * encapsulating the content in a span with cds--content-switcher__label class * to mimic what is done in the react version */ ngOnInit() { const hostNativeElement = this.hostElement.nativeElement; const spanWrapper = this.renderer.createElement("span"); this.renderer.addClass(spanWrapper, "cds--content-switcher__label"); const hostChildren = []; hostNativeElement.childNodes.forEach(node => hostChildren.push(node)); hostChildren.forEach(node => { this.renderer.removeChild(hostNativeElement, node); this.renderer.appendChild(spanWrapper, node); }); this.renderer.appendChild(hostNativeElement, spanWrapper); } } ContentSwitcherOption.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ContentSwitcherOption, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); ContentSwitcherOption.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: ContentSwitcherOption, selector: "[cdsContentOption], [ibmContentOption]", inputs: { active: "active", name: "name" }, outputs: { selected: "selected", onClick: "onClick", onFocus: "onFocus" }, host: { listeners: { "click": "hostClick($event)", "focus": "doFocus($event)" }, properties: { "class": "this.switcherClass", "class.cds--content-switcher--selected": "this.selectedClass", "attr.role": "this.role", "attr.aria-selected": "this.ariaSelected", "attr.tabIndex": "this.tabindex" } }, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ContentSwitcherOption, decorators: [{ type: Directive, args: [{ selector: "[cdsContentOption], [ibmContentOption]" }] }], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.ElementRef }]; }, propDecorators: { active: [{ type: Input }], name: [{ type: Input }], selected: [{ type: Output }], onClick: [{ type: Output }], onFocus: [{ type: Output }], switcherClass: [{ type: HostBinding, args: ["class"] }], selectedClass: [{ type: HostBinding, args: ["class.cds--content-switcher--selected"] }], role: [{ type: HostBinding, args: ["attr.role"] }], ariaSelected: [{ type: HostBinding, args: ["attr.aria-selected"] }], tabindex: [{ type: HostBinding, args: ["attr.tabIndex"] }], hostClick: [{ type: HostListener, args: ["click", ["$event"]] }], doFocus: [{ type: HostListener, args: ["focus", ["$event"]] }] } }); /** * The content switcher can be used for toggling between distinct options. * Similar to tabs, but without an associated content panel. * * Get started with importing the module: * * ```typescript * import { ContentSwitcherModule } from 'carbon-components-angular'; * ``` * * ```html * <cds-content-switcher (selected)="selected($event)"> * <button cdsContentOption>First section</button> * <button cdsContentOption>Second section</button> * <button cdsContentOption>Third section</button> * </cds-content-switcher> * ``` * * [See demo](../../?path=/story/components-content-switcher--basic) */ class ContentSwitcher { constructor(elementRef) { this.elementRef = elementRef; this.ariaLabel = "content switcher"; /** * Set content switcher size */ this.size = "md"; /** * Emits the activated `ContentSwitcherOption` */ this.selected = new EventEmitter(); } ngAfterViewInit() { const firstActive = this.options.find(option => option.active); // delay setting active until the DOM has settled if (!firstActive) { setTimeout(() => this.options.first.active = true); } // subscribe to each item, emit when one is selected, and reset the active states this.options.forEach(option => { option.selected.subscribe((_) => { const active = option; this.options.forEach(option => { if (option !== active) { option.active = false; } }); this.selected.emit(active); }); }); } hostkeys(event) { const buttonList = Array.from(this.elementRef.nativeElement.querySelectorAll("[cdsContentOption], [ibmContentOption]")); switch (event.key) { case "ArrowRight": event.preventDefault(); if (!isFocusInLastItem(event, buttonList)) { const index = buttonList.findIndex(item => item === event.target); buttonList[index + 1].focus(); } else { buttonList[0].focus(); } break; case "ArrowLeft": event.preventDefault(); if (!isFocusInFirstItem(event, buttonList)) { const index = buttonList.findIndex(item => item === event.target); buttonList[index - 1].focus(); } else { buttonList[buttonList.length - 1].focus(); } break; case "Home": event.preventDefault(); buttonList[0].focus(); break; case "End": event.preventDefault(); buttonList[buttonList.length - 1].focus(); break; } } } ContentSwitcher.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ContentSwitcher, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); ContentSwitcher.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: ContentSwitcher, selector: "cds-content-switcher, ibm-content-switcher", inputs: { ariaLabel: "ariaLabel", size: "size" }, outputs: { selected: "selected" }, host: { listeners: { "keydown": "hostkeys($event)" } }, queries: [{ propertyName: "options", predicate: ContentSwitcherOption }], ngImport: i0, template: ` <div [attr.aria-label]="ariaLabel" class="cds--content-switcher" [ngClass]="{ 'cds--content-switcher--sm': size === 'sm', 'cds--content-switcher--md': size === 'md', 'cds--content-switcher--lg': size === 'lg' }" role="tablist"> <ng-content></ng-content> </div> `, isInline: true, dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ContentSwitcher, decorators: [{ type: Component, args: [{ selector: "cds-content-switcher, ibm-content-switcher", template: ` <div [attr.aria-label]="ariaLabel" class="cds--content-switcher" [ngClass]="{ 'cds--content-switcher--sm': size === 'sm', 'cds--content-switcher--md': size === 'md', 'cds--content-switcher--lg': size === 'lg' }" role="tablist"> <ng-content></ng-content> </div> ` }] }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { ariaLabel: [{ type: Input }], size: [{ type: Input }], selected: [{ type: Output }], options: [{ type: ContentChildren, args: [ContentSwitcherOption] }], hostkeys: [{ type: HostListener, args: ["keydown", ["$event"]] }] } }); class ContentSwitcherModule { } ContentSwitcherModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ContentSwitcherModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); ContentSwitcherModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "14.3.0", ngImport: i0, type: ContentSwitcherModule, declarations: [ContentSwitcher, ContentSwitcherOption], imports: [CommonModule], exports: [ContentSwitcher, ContentSwitcherOption] }); ContentSwitcherModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ContentSwitcherModule, imports: [CommonModule] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: ContentSwitcherModule, decorators: [{ type: NgModule, args: [{ declarations: [ ContentSwitcher, ContentSwitcherOption ], exports: [ ContentSwitcher, ContentSwitcherOption ], imports: [CommonModule] }] }] }); /** * Generated bundle index. Do not edit. */ export { ContentSwitcher, ContentSwitcherModule, ContentSwitcherOption }; //# sourceMappingURL=carbon-components-angular-content-switcher.mjs.map