carbon-components-angular
Version:
Next generation components
277 lines (271 loc) • 11.6 kB
JavaScript
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