UNPKG

primeng

Version:

PrimeNG is a premium UI library for Angular featuring a rich set of 90+ components, a theme designer, various theme alternatives such as Material, Bootstrap, Tailwind, premium templates and professional support. In addition, it integrates with PrimeBlock,

933 lines (917 loc) 46.5 kB
import * as i0 from '@angular/core'; import { Injectable, InjectionToken, inject, model, input, booleanAttribute, numberAttribute, signal, ViewEncapsulation, ChangeDetectionStrategy, Component, contentChild, viewChild, forwardRef, computed, effect, ElementRef, HostListener, NgModule } from '@angular/core'; import { uuid, getWidth, isRTL, findSingle, equals, getAttribute, focus } from '@primeuix/utils'; import { BaseComponent, PARENT_INSTANCE } from 'primeng/basecomponent'; import * as i1 from 'primeng/bind'; import { Bind, BindModule } from 'primeng/bind'; import { style } from '@primeuix/styles/tabs'; import { BaseStyle } from 'primeng/base'; import { isPlatformBrowser, NgTemplateOutlet } from '@angular/common'; import { SharedModule } from 'primeng/api'; import * as i2 from 'primeng/ripple'; import { RippleModule, Ripple } from 'primeng/ripple'; import { ChevronLeft } from '@primeicons/angular/chevron-left'; import { ChevronRight } from '@primeicons/angular/chevron-right'; const classes$4 = { root: 'p-tabs p-component' }; class TabsStyle extends BaseStyle { name = 'tabs'; style = style; classes = classes$4; static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabsStyle, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabsStyle }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabsStyle, decorators: [{ type: Injectable }] }); /** * * Tabs facilitates seamless switching between different views. * * [Live Demo](https://www.primeng.org/tabs/) * * @module tabsstyle * */ var TabsClasses; (function (TabsClasses) { /** * Class name of the root element */ TabsClasses["root"] = "p-tabs"; /** * Class name of the wrapper element */ TabsClasses["list"] = "p-tablist"; /** * Class name of the content element */ TabsClasses["content"] = "p-tablist-content"; /** * Class name of the tab list element */ TabsClasses["tablist"] = "p-tablist-tab-list"; /** * Class name of the tab list element */ TabsClasses["tab"] = "p-tab"; /** * Class name of the inkbar element */ TabsClasses["inkbar"] = "p-tablist-active-bar"; /** * Class name of the navigation buttons */ TabsClasses["button"] = "p-tablist-nav-button"; /** * Class name of the tab panels wrapper */ TabsClasses["tabpanels"] = "p-tabpanels"; /** * Class name of the tab panel element */ TabsClasses["tabpanel"] = "p-tabs-panel"; })(TabsClasses || (TabsClasses = {})); const TABS_INSTANCE = new InjectionToken('TABS_INSTANCE'); /** * Tabs facilitates seamless switching between different views. * @group Components */ class Tabs extends BaseComponent { componentName = 'Tabs'; $pcTabs = inject(TABS_INSTANCE, { optional: true, skipSelf: true }) ?? undefined; bindDirectiveInstance = inject(Bind, { self: true }); onAfterViewChecked() { this.bindDirectiveInstance.setAttrs(this.ptms(['host', 'root'])); } /** * Value of the active tab. * @defaultValue undefined * @group Props */ value = model(undefined, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ [])); /** * Scrolling is enabled by default. This property is no longer needed. * @defaultValue false * @group Props * @deprecated Scrolling is now the default behavior. This property will be removed in a future version. */ scrollable = input(false, { ...(ngDevMode ? { debugName: "scrollable" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * When enabled, tabs are not rendered until activation. * @type boolean * @defaultValue false * @group Props */ lazy = input(false, { ...(ngDevMode ? { debugName: "lazy" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * When enabled, the focused tab is activated. * @type boolean * @defaultValue false * @group Props */ selectOnFocus = input(false, { ...(ngDevMode ? { debugName: "selectOnFocus" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Whether to display navigation buttons in container when scrollable is enabled. * @type boolean * @defaultValue true * @group Props */ showNavigators = input(true, { ...(ngDevMode ? { debugName: "showNavigators" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Tabindex of the tab buttons. * @type number * @defaultValue 0 * @group Props */ tabindex = input(0, { ...(ngDevMode ? { debugName: "tabindex" } : /* istanbul ignore next */ {}), transform: numberAttribute }); /** * Defines the scrolling behavior when the active tab changes. Use 'nearest' to scroll only if the tab is not fully visible, 'center' to always center the active tab, or false to disable auto-scrolling. * @defaultValue 'nearest' * @group Props */ scrollStrategy = input('nearest', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "scrollStrategy" }] : /* istanbul ignore next */ [])); id = signal(uuid('pn_id_'), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ [])); _componentStyle = inject(TabsStyle); updateValue(newValue) { this.value.update(() => newValue); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: Tabs, deps: null, target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.6", type: Tabs, isStandalone: true, selector: "p-tabs", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, scrollable: { classPropertyName: "scrollable", publicName: "scrollable", isSignal: true, isRequired: false, transformFunction: null }, lazy: { classPropertyName: "lazy", publicName: "lazy", isSignal: true, isRequired: false, transformFunction: null }, selectOnFocus: { classPropertyName: "selectOnFocus", publicName: "selectOnFocus", isSignal: true, isRequired: false, transformFunction: null }, showNavigators: { classPropertyName: "showNavigators", publicName: "showNavigators", isSignal: true, isRequired: false, transformFunction: null }, tabindex: { classPropertyName: "tabindex", publicName: "tabindex", isSignal: true, isRequired: false, transformFunction: null }, scrollStrategy: { classPropertyName: "scrollStrategy", publicName: "scrollStrategy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { properties: { "class": "cx(\"root\")", "attr.id": "id()" } }, providers: [TabsStyle, { provide: TABS_INSTANCE, useExisting: Tabs }, { provide: PARENT_INSTANCE, useExisting: Tabs }], usesInheritance: true, hostDirectives: [{ directive: i1.Bind }], ngImport: i0, template: ` <ng-content></ng-content>`, isInline: true, dependencies: [{ kind: "ngmodule", type: BindModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: Tabs, decorators: [{ type: Component, args: [{ selector: 'p-tabs', standalone: true, imports: [BindModule], template: ` <ng-content></ng-content>`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [TabsStyle, { provide: TABS_INSTANCE, useExisting: Tabs }, { provide: PARENT_INSTANCE, useExisting: Tabs }], host: { '[class]': 'cx("root")', '[attr.id]': 'id()' }, hostDirectives: [Bind] }] }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], scrollable: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollable", required: false }] }], lazy: [{ type: i0.Input, args: [{ isSignal: true, alias: "lazy", required: false }] }], selectOnFocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectOnFocus", required: false }] }], showNavigators: [{ type: i0.Input, args: [{ isSignal: true, alias: "showNavigators", required: false }] }], tabindex: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabindex", required: false }] }], scrollStrategy: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollStrategy", required: false }] }] } }); const classes$3 = { root: ({ instance }) => [ 'p-tab', { 'p-tab-active': instance.active(), 'p-disabled': instance.disabled() } ] }; class TabStyle extends BaseStyle { name = 'tab'; classes = classes$3; static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabStyle, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabStyle }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabStyle, decorators: [{ type: Injectable }] }); /** * * Tabs facilitates seamless switching between different views. * * [Live Demo](https://www.primeng.org/tabs/) * * @module tabsstyle * */ var TabClasses; (function (TabClasses) { /** * Class name of the tab list element */ TabClasses["tab"] = "p-tab"; })(TabClasses || (TabClasses = {})); const classes$2 = { root: 'p-tablist', content: 'p-tablist-content', activeBar: 'p-tablist-active-bar', prevButton: 'p-tablist-prev-button p-tablist-nav-button', nextButton: 'p-tablist-next-button p-tablist-nav-button' }; class TabListStyle extends BaseStyle { name = 'tablist'; classes = classes$2; static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabListStyle, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabListStyle }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabListStyle, decorators: [{ type: Injectable }] }); /** * * Tabs facilitates seamless switching between different views. * * [Live Demo](https://www.primeng.org/tabs/) * * @module tabliststyle * */ var TabListClasses; (function (TabListClasses) { /** * Class name of the root element */ TabListClasses["root"] = "p-tablist"; /** * Class name of the content element */ TabListClasses["content"] = "p-tablist-content"; /** * Class name of the activebar element */ TabListClasses["activeBar"] = "p-tablist-active-bar"; /** * Class name of the previous button element */ TabListClasses["prevButton"] = "p-tablist-prev-button"; /** * Class name of the next button element */ TabListClasses["nextButton"] = "p-tablist-next-button"; })(TabListClasses || (TabListClasses = {})); const TABLIST_INSTANCE = new InjectionToken('TABLIST_INSTANCE'); /** * TabList is a helper component for Tabs component. * @group Components */ class TabList extends BaseComponent { componentName = 'TabList'; $pcTabList = inject(TABLIST_INSTANCE, { optional: true, skipSelf: true }) ?? undefined; bindDirectiveInstance = inject(Bind, { self: true }); onAfterViewChecked() { this.bindDirectiveInstance.setAttrs(this.ptms(['host', 'root'])); } /** * A template reference variable that represents the previous icon in a UI component. * @type {TemplateRef<any> | undefined} * @group Templates */ prevIconTemplate = contentChild('previcon', { ...(ngDevMode ? { debugName: "prevIconTemplate" } : /* istanbul ignore next */ {}), descendants: false }); /** * A template reference variable that represents the next icon in a UI component. * @type {TemplateRef<any> | undefined} * @group Templates */ nextIconTemplate = contentChild('nexticon', { ...(ngDevMode ? { debugName: "nextIconTemplate" } : /* istanbul ignore next */ {}), descendants: false }); content = viewChild('content', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "content" }] : /* istanbul ignore next */ [])); prevButton = viewChild('prevButton', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "prevButton" }] : /* istanbul ignore next */ [])); nextButton = viewChild('nextButton', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "nextButton" }] : /* istanbul ignore next */ [])); inkbar = viewChild('inkbar', /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "inkbar" }] : /* istanbul ignore next */ [])); pcTabs = inject(forwardRef(() => Tabs)); isPrevButtonEnabled = signal(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "isPrevButtonEnabled" }] : /* istanbul ignore next */ [])); isNextButtonEnabled = signal(false, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "isNextButtonEnabled" }] : /* istanbul ignore next */ [])); resizeObserver; showNavigators = computed(() => this.pcTabs.showNavigators(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "showNavigators" }] : /* istanbul ignore next */ [])); tabindex = computed(() => this.pcTabs.tabindex(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "tabindex" }] : /* istanbul ignore next */ [])); scrollable = computed(() => this.pcTabs.scrollable(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "scrollable" }] : /* istanbul ignore next */ [])); _componentStyle = inject(TabListStyle); constructor() { super(); effect(() => { this.pcTabs.value(); if (isPlatformBrowser(this.platformId)) { setTimeout(() => { this.updateInkBar(); this.scrollToActiveTab(); }); } }); } get prevButtonAriaLabel() { return this.config?.translation?.aria?.previous; } get nextButtonAriaLabel() { return this.config?.translation?.aria?.next; } onAfterViewInit() { if (this.showNavigators() && isPlatformBrowser(this.platformId)) { this.updateButtonState(); this.bindResizeObserver(); } } onDestroy() { this.unbindResizeObserver(); } onScroll(event) { this.showNavigators() && this.updateButtonState(); event.preventDefault(); } onPrevButtonClick() { const _content = this.content()?.nativeElement; if (!_content) return; const width = getWidth(_content); const pos = Math.abs(_content.scrollLeft) - width; const scrollLeft = pos <= 0 ? 0 : pos; _content.scrollLeft = isRTL(_content) ? -1 * scrollLeft : scrollLeft; } onNextButtonClick() { const _content = this.content()?.nativeElement; if (!_content) return; const width = getWidth(_content) - this.getVisibleButtonWidths(); const pos = _content.scrollLeft + width; const lastPos = _content.scrollWidth - width; const scrollLeft = pos >= lastPos ? lastPos : pos; _content.scrollLeft = isRTL(_content) ? -1 * scrollLeft : scrollLeft; } updateButtonState() { const _content = this.content()?.nativeElement; const _list = this.el?.nativeElement; if (!_content) return; const { scrollWidth, offsetWidth } = _content; const scrollLeft = Math.abs(_content.scrollLeft); const width = getWidth(_content); this.isPrevButtonEnabled.set(scrollLeft !== 0); this.isNextButtonEnabled.set(_list.offsetWidth >= offsetWidth && Math.abs(scrollLeft - scrollWidth + width) > 1); } updateInkBar() { const _content = this.content()?.nativeElement; const _inkbar = this.inkbar()?.nativeElement; if (!_content || !_inkbar) return; const activeTab = findSingle(_content, '[data-pc-name="tab"][data-p-active="true"]'); if (!activeTab) return; _inkbar.style.setProperty('--px-active-bar-width', activeTab.offsetWidth + 'px'); _inkbar.style.setProperty('--px-active-bar-height', activeTab.offsetHeight + 'px'); _inkbar.style.setProperty('--px-active-bar-left', activeTab.offsetLeft + 'px'); _inkbar.style.setProperty('--px-active-bar-top', activeTab.offsetTop + 'px'); } scrollToActiveTab() { const _content = this.content()?.nativeElement; const scrollStrategy = this.pcTabs.scrollStrategy(); if (!_content || scrollStrategy === false) return; const activeTab = findSingle(_content, '[data-pc-name="tab"][data-p-active="true"]'); if (!activeTab) return; const contentWidth = _content.clientWidth; const currentScrollLeft = Math.abs(_content.scrollLeft); const tabLeft = activeTab.offsetLeft; const tabWidth = activeTab.offsetWidth; const tabRight = tabLeft + tabWidth; let targetScrollLeft; if (scrollStrategy === 'center') { targetScrollLeft = tabLeft - (contentWidth - tabWidth) / 2; } else { const padding = contentWidth * 0.1; if (tabLeft < currentScrollLeft + padding) { targetScrollLeft = tabLeft - padding; } else if (tabRight > currentScrollLeft + contentWidth - padding) { targetScrollLeft = tabRight - contentWidth + padding; } else { return; } } const maxScrollLeft = _content.scrollWidth - contentWidth; const clampedScrollLeft = Math.max(0, Math.min(targetScrollLeft, maxScrollLeft)); _content.scrollTo({ left: isRTL(_content) ? -clampedScrollLeft : clampedScrollLeft, behavior: 'smooth' }); } getVisibleButtonWidths() { const _prevBtn = this.prevButton()?.nativeElement; const _nextBtn = this.nextButton()?.nativeElement; return [_prevBtn, _nextBtn].reduce((acc, el) => (el ? acc + getWidth(el) : acc), 0); } bindResizeObserver() { this.resizeObserver = new ResizeObserver(() => this.updateButtonState()); this.resizeObserver.observe(this.el.nativeElement); } unbindResizeObserver() { if (this.resizeObserver) { this.resizeObserver.unobserve(this.el.nativeElement); this.resizeObserver = null; } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabList, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: TabList, isStandalone: true, selector: "p-tablist", host: { properties: { "class": "cx(\"root\")" } }, providers: [TabListStyle, { provide: TABLIST_INSTANCE, useExisting: TabList }, { provide: PARENT_INSTANCE, useExisting: TabList }], queries: [{ propertyName: "prevIconTemplate", first: true, predicate: ["previcon"], isSignal: true }, { propertyName: "nextIconTemplate", first: true, predicate: ["nexticon"], isSignal: true }], viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, isSignal: true }, { propertyName: "prevButton", first: true, predicate: ["prevButton"], descendants: true, isSignal: true }, { propertyName: "nextButton", first: true, predicate: ["nextButton"], descendants: true, isSignal: true }, { propertyName: "inkbar", first: true, predicate: ["inkbar"], descendants: true, isSignal: true }], usesInheritance: true, hostDirectives: [{ directive: i1.Bind }], ngImport: i0, template: ` @if (showNavigators() && isPrevButtonEnabled()) { <button type="button" #prevButton pRipple [pBind]="ptm('prevButton')" [class]="cx('prevButton')" [attr.aria-label]="prevButtonAriaLabel" [attr.tabindex]="tabindex()" [attr.data-pc-group-section]="'navigator'" (click)="onPrevButtonClick()" > @if (prevIconTemplate()) { <ng-container *ngTemplateOutlet="prevIconTemplate()" /> } @else { <svg data-p-icon="chevron-left" /> } </button> } <div #content [pBind]="ptm('content')" [class]="cx('content')" role="tablist" (scroll)="onScroll($event)"> <ng-content /> <span #inkbar [pBind]="ptm('activeBar')" role="presentation" [class]="cx('activeBar')"></span> </div> @if (showNavigators() && isNextButtonEnabled()) { <button type="button" #nextButton pRipple [pBind]="ptm('nextButton')" [class]="cx('nextButton')" [attr.aria-label]="nextButtonAriaLabel" [attr.tabindex]="tabindex()" [attr.data-pc-group-section]="'navigator'" (click)="onNextButtonClick()" > @if (nextIconTemplate()) { <ng-container *ngTemplateOutlet="nextIconTemplate()" /> } @else { <svg data-p-icon="chevron-right" /> } </button> } `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: ChevronLeft, selector: "svg[data-p-icon=\"chevron-left\"]" }, { kind: "component", type: ChevronRight, selector: "svg[data-p-icon=\"chevron-right\"]" }, { kind: "ngmodule", type: RippleModule }, { kind: "directive", type: i2.Ripple, selector: "[pRipple]" }, { kind: "ngmodule", type: SharedModule }, { kind: "ngmodule", type: BindModule }, { kind: "directive", type: i1.Bind, selector: "[pBind]", inputs: ["pBind"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabList, decorators: [{ type: Component, args: [{ selector: 'p-tablist', standalone: true, imports: [NgTemplateOutlet, ChevronLeft, ChevronRight, RippleModule, SharedModule, BindModule], template: ` @if (showNavigators() && isPrevButtonEnabled()) { <button type="button" #prevButton pRipple [pBind]="ptm('prevButton')" [class]="cx('prevButton')" [attr.aria-label]="prevButtonAriaLabel" [attr.tabindex]="tabindex()" [attr.data-pc-group-section]="'navigator'" (click)="onPrevButtonClick()" > @if (prevIconTemplate()) { <ng-container *ngTemplateOutlet="prevIconTemplate()" /> } @else { <svg data-p-icon="chevron-left" /> } </button> } <div #content [pBind]="ptm('content')" [class]="cx('content')" role="tablist" (scroll)="onScroll($event)"> <ng-content /> <span #inkbar [pBind]="ptm('activeBar')" role="presentation" [class]="cx('activeBar')"></span> </div> @if (showNavigators() && isNextButtonEnabled()) { <button type="button" #nextButton pRipple [pBind]="ptm('nextButton')" [class]="cx('nextButton')" [attr.aria-label]="nextButtonAriaLabel" [attr.tabindex]="tabindex()" [attr.data-pc-group-section]="'navigator'" (click)="onNextButtonClick()" > @if (nextIconTemplate()) { <ng-container *ngTemplateOutlet="nextIconTemplate()" /> } @else { <svg data-p-icon="chevron-right" /> } </button> } `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { '[class]': 'cx("root")' }, providers: [TabListStyle, { provide: TABLIST_INSTANCE, useExisting: TabList }, { provide: PARENT_INSTANCE, useExisting: TabList }], hostDirectives: [Bind] }] }], ctorParameters: () => [], propDecorators: { prevIconTemplate: [{ type: i0.ContentChild, args: ['previcon', { ...{ descendants: false }, isSignal: true }] }], nextIconTemplate: [{ type: i0.ContentChild, args: ['nexticon', { ...{ descendants: false }, isSignal: true }] }], content: [{ type: i0.ViewChild, args: ['content', { isSignal: true }] }], prevButton: [{ type: i0.ViewChild, args: ['prevButton', { isSignal: true }] }], nextButton: [{ type: i0.ViewChild, args: ['nextButton', { isSignal: true }] }], inkbar: [{ type: i0.ViewChild, args: ['inkbar', { isSignal: true }] }] } }); const TAB_INSTANCE = new InjectionToken('TAB_INSTANCE'); /** * Defines valid properties in Tab component. * @group Components */ class Tab extends BaseComponent { componentName = 'Tab'; $pcTab = inject(TAB_INSTANCE, { optional: true, skipSelf: true }) ?? undefined; bindDirectiveInstance = inject(Bind, { self: true }); onAfterViewChecked() { this.bindDirectiveInstance.setAttrs(this.ptms(['host', 'root'])); } /** * Value of tab. * @defaultValue undefined * @group Props */ value = model(/* @ts-ignore */ ...(ngDevMode ? [undefined, { debugName: "value" }] : /* istanbul ignore next */ [])); /** * Whether the tab is disabled. * @defaultValue false * @group Props */ disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); pcTabs = inject(forwardRef(() => Tabs)); pcTabList = inject(forwardRef(() => TabList)); el = inject(ElementRef); _componentStyle = inject(TabStyle); ripple = computed(() => this.config.ripple(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "ripple" }] : /* istanbul ignore next */ [])); id = computed(() => `${this.pcTabs.id()}_tab_${this.value()}`, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ [])); ariaControls = computed(() => `${this.pcTabs.id()}_tabpanel_${this.value()}`, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "ariaControls" }] : /* istanbul ignore next */ [])); active = computed(() => equals(this.pcTabs.value(), this.value()), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ [])); tabindex = computed(() => (this.disabled() ? -1 : this.active() ? this.pcTabs.tabindex() : -1), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "tabindex" }] : /* istanbul ignore next */ [])); mutationObserver; onFocus(event) { if (!this.disabled()) { this.pcTabs.selectOnFocus() && this.changeActiveValue(); } } onClick(event) { if (!this.disabled()) { this.changeActiveValue(); } } onKeyDown(event) { switch (event.code) { case 'ArrowRight': this.onArrowRightKey(event); break; case 'ArrowLeft': this.onArrowLeftKey(event); break; case 'Home': this.onHomeKey(event); break; case 'End': this.onEndKey(event); break; case 'PageDown': this.onPageDownKey(event); break; case 'PageUp': this.onPageUpKey(event); break; case 'Enter': case 'NumpadEnter': case 'Space': this.onEnterKey(event); break; default: break; } event.stopPropagation(); } onAfterViewInit() { this.bindMutationObserver(); } onArrowRightKey(event) { const nextTab = this.findNextTab(event.currentTarget); nextTab ? this.changeFocusedTab(nextTab) : this.onHomeKey(event); event.preventDefault(); } onArrowLeftKey(event) { const prevTab = this.findPrevTab(event.currentTarget); prevTab ? this.changeFocusedTab(prevTab) : this.onEndKey(event); event.preventDefault(); } onHomeKey(event) { const firstTab = this.findFirstTab(); this.changeFocusedTab(firstTab); event.preventDefault(); } onEndKey(event) { const lastTab = this.findLastTab(); this.changeFocusedTab(lastTab); event.preventDefault(); } onPageDownKey(event) { this.scrollInView(this.findLastTab()); event.preventDefault(); } onPageUpKey(event) { this.scrollInView(this.findFirstTab()); event.preventDefault(); } onEnterKey(event) { if (!this.disabled()) { this.changeActiveValue(); } event.preventDefault(); } findNextTab(tabElement, selfCheck = false) { const element = selfCheck ? tabElement : tabElement?.nextElementSibling; return element ? (getAttribute(element, 'data-p-disabled') || getAttribute(element, 'data-pc-section') === 'activebar' ? this.findNextTab(element) : element) : null; } findPrevTab(tabElement, selfCheck = false) { const element = selfCheck ? tabElement : tabElement?.previousElementSibling; return element ? (getAttribute(element, 'data-p-disabled') || getAttribute(element, 'data-pc-section') === 'activebar' ? this.findPrevTab(element) : element) : null; } findFirstTab() { return this.findNextTab(this.pcTabList?.content()?.nativeElement?.firstElementChild, true); } findLastTab() { return this.findPrevTab(this.pcTabList?.content()?.nativeElement?.lastElementChild, true); } changeActiveValue() { this.pcTabs.updateValue(this.value()); } changeFocusedTab(element) { if (element) { focus(element); } this.scrollInView(element); } scrollInView(element) { element?.scrollIntoView?.({ block: 'nearest' }); } bindMutationObserver() { if (isPlatformBrowser(this.platformId)) { this.mutationObserver = new MutationObserver((mutations) => { mutations.forEach(() => { if (this.active()) { this.pcTabList?.updateInkBar(); } }); }); this.mutationObserver.observe(this.el.nativeElement, { childList: true, characterData: true, subtree: true }); } } unbindMutationObserver() { this.mutationObserver?.disconnect(); } onDestroy() { if (this.mutationObserver) { this.unbindMutationObserver(); } } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: Tab, deps: null, target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.0.6", type: Tab, isStandalone: true, selector: "p-tab", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { listeners: { "focus": "onFocus($event)", "click": "onClick($event)", "keydown": "onKeyDown($event)" }, properties: { "class": "cx(\"root\")", "attr.id": "id()", "attr.aria-controls": "ariaControls()", "attr.role": "\"tab\"", "attr.aria-selected": "active()", "attr.aria-disabled": "disabled()", "attr.data-p-disabled": "disabled()", "attr.data-p-active": "active()", "attr.tabindex": "tabindex()" } }, providers: [TabStyle, { provide: TAB_INSTANCE, useExisting: Tab }, { provide: PARENT_INSTANCE, useExisting: Tab }], usesInheritance: true, hostDirectives: [{ directive: i2.Ripple }, { directive: i1.Bind }], ngImport: i0, template: ` <ng-content></ng-content>`, isInline: true, dependencies: [{ kind: "ngmodule", type: SharedModule }, { kind: "ngmodule", type: BindModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: Tab, decorators: [{ type: Component, args: [{ selector: 'p-tab', standalone: true, imports: [SharedModule, BindModule], template: ` <ng-content></ng-content>`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { '[class]': 'cx("root")', '[attr.id]': 'id()', '[attr.aria-controls]': 'ariaControls()', '[attr.role]': '"tab"', '[attr.aria-selected]': 'active()', '[attr.aria-disabled]': 'disabled()', '[attr.data-p-disabled]': 'disabled()', '[attr.data-p-active]': 'active()', '[attr.tabindex]': 'tabindex()' }, hostDirectives: [Ripple, Bind], providers: [TabStyle, { provide: TAB_INSTANCE, useExisting: Tab }, { provide: PARENT_INSTANCE, useExisting: Tab }] }] }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], onFocus: [{ type: HostListener, args: ['focus', ['$event']] }], onClick: [{ type: HostListener, args: ['click', ['$event']] }], onKeyDown: [{ type: HostListener, args: ['keydown', ['$event']] }] } }); const classes$1 = { root: ({ instance }) => [ 'p-tabpanel', { 'p-tabpanel-active': instance.active() } ] }; class TabPanelStyle extends BaseStyle { name = 'tabpanel'; classes = classes$1; static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabPanelStyle, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabPanelStyle }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabPanelStyle, decorators: [{ type: Injectable }] }); /** * * Tab is a helper component for Tabs component. * * [Live Demo](https://www.primeng.org/tabs/) * * @module tabstyle * */ var TabPanelClasses; (function (TabPanelClasses) { /** * Class name of the root element */ TabPanelClasses["root"] = "p-tabpanel"; })(TabPanelClasses || (TabPanelClasses = {})); const TABPANEL_INSTANCE = new InjectionToken('TABPANEL_INSTANCE'); /** * TabPanel is a helper component for Tabs component. * @group Components */ class TabPanel extends BaseComponent { componentName = 'TabPanel'; $pcTabPanel = inject(TABPANEL_INSTANCE, { optional: true, skipSelf: true }) ?? undefined; bindDirectiveInstance = inject(Bind, { self: true }); pcTabs = inject(forwardRef(() => Tabs)); onAfterViewChecked() { this.bindDirectiveInstance.setAttrs(this.ptms(['host', 'root'])); } /** * When enabled, tab is not rendered until activation. * @type boolean * @defaultValue false * @group Props */ lazy = input(false, { ...(ngDevMode ? { debugName: "lazy" } : /* istanbul ignore next */ {}), transform: booleanAttribute }); /** * Value of the active tab. * @defaultValue undefined * @group Props */ value = model(undefined, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ [])); /** * Template for initializing complex content when lazy is enabled. * @group Templates */ content = contentChild('content', { ...(ngDevMode ? { debugName: "content" } : /* istanbul ignore next */ {}), descendants: false }); id = computed(() => `${this.pcTabs.id()}_tabpanel_${this.value()}`, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ [])); ariaLabelledby = computed(() => `${this.pcTabs.id()}_tab_${this.value()}`, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "ariaLabelledby" }] : /* istanbul ignore next */ [])); active = computed(() => equals(this.pcTabs.value(), this.value()), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ [])); isLazyEnabled = computed(() => this.pcTabs.lazy() || this.lazy(), /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "isLazyEnabled" }] : /* istanbul ignore next */ [])); hasBeenRendered = false; shouldRender = computed(() => { if (!this.isLazyEnabled() || this.hasBeenRendered) { return true; } if (this.active()) { this.hasBeenRendered = true; return true; } return false; }, /* @ts-ignore */ ...(ngDevMode ? [{ debugName: "shouldRender" }] : /* istanbul ignore next */ [])); _componentStyle = inject(TabPanelStyle); static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabPanel, deps: null, target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: TabPanel, isStandalone: true, selector: "p-tabpanel", inputs: { lazy: { classPropertyName: "lazy", publicName: "lazy", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { properties: { "class": "cx(\"root\")", "attr.id": "id()", "attr.role": "\"tabpanel\"", "attr.aria-labelledby": "ariaLabelledby()", "attr.data-p-active": "active()", "hidden": "!active()" } }, providers: [TabPanelStyle, { provide: TABPANEL_INSTANCE, useExisting: TabPanel }, { provide: PARENT_INSTANCE, useExisting: TabPanel }], queries: [{ propertyName: "content", first: true, predicate: ["content"], isSignal: true }], usesInheritance: true, hostDirectives: [{ directive: i1.Bind }], ngImport: i0, template: ` <ng-template #defaultContent> <ng-content /> </ng-template> @if (shouldRender()) { <ng-container *ngTemplateOutlet="content() ? content() : defaultContent" /> } `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: BindModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabPanel, decorators: [{ type: Component, args: [{ selector: 'p-tabpanel', standalone: true, imports: [NgTemplateOutlet, BindModule], template: ` <ng-template #defaultContent> <ng-content /> </ng-template> @if (shouldRender()) { <ng-container *ngTemplateOutlet="content() ? content() : defaultContent" /> } `, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [TabPanelStyle, { provide: TABPANEL_INSTANCE, useExisting: TabPanel }, { provide: PARENT_INSTANCE, useExisting: TabPanel }], host: { '[class]': 'cx("root")', '[attr.id]': 'id()', '[attr.role]': '"tabpanel"', '[attr.aria-labelledby]': 'ariaLabelledby()', '[attr.data-p-active]': 'active()', '[hidden]': '!active()' }, hostDirectives: [Bind] }] }], propDecorators: { lazy: [{ type: i0.Input, args: [{ isSignal: true, alias: "lazy", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], content: [{ type: i0.ContentChild, args: ['content', { ...{ descendants: false }, isSignal: true }] }] } }); const classes = { root: 'p-tabpanels' }; class TabPanelsStyle extends BaseStyle { name = 'tabpanels'; classes = classes; static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabPanelsStyle, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabPanelsStyle }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabPanelsStyle, decorators: [{ type: Injectable }] }); /** * * Tab is a helper component for Tabs component. * * [Live Demo](https://www.primeng.org/tabs/) * * @module tabpanelstyle * */ var TabPanelsClasses; (function (TabPanelsClasses) { /** * Class name of the root element */ TabPanelsClasses["root"] = "p-tabpanels"; })(TabPanelsClasses || (TabPanelsClasses = {})); const TABPANELS_INSTANCE = new InjectionToken('TABPANELS_INSTANCE'); /** * TabPanels is a helper component for Tabs component. * @group Components */ class TabPanels extends BaseComponent { componentName = 'TabPanels'; $pcTabPanels = inject(TABPANELS_INSTANCE, { optional: true, skipSelf: true }) ?? undefined; bindDirectiveInstance = inject(Bind, { self: true }); _componentStyle = inject(TabPanelsStyle); onAfterViewChecked() { this.bindDirectiveInstance.setAttrs(this.ptms(['host', 'root'])); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabPanels, deps: null, target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: TabPanels, isStandalone: true, selector: "p-tabpanels", host: { properties: { "class": "cx(\"root\")", "attr.role": "\"presentation\"" } }, providers: [TabPanelsStyle, { provide: TABPANELS_INSTANCE, useExisting: TabPanels }, { provide: PARENT_INSTANCE, useExisting: TabPanels }], usesInheritance: true, hostDirectives: [{ directive: i1.Bind }], ngImport: i0, template: ` <ng-content></ng-content>`, isInline: true, dependencies: [{ kind: "ngmodule", type: BindModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabPanels, decorators: [{ type: Component, args: [{ selector: 'p-tabpanels', standalone: true, imports: [BindModule], template: ` <ng-content></ng-content>`, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { '[class]': 'cx("root")', '[attr.role]': '"presentation"' }, providers: [TabPanelsStyle, { provide: TABPANELS_INSTANCE, useExisting: TabPanels }, { provide: PARENT_INSTANCE, useExisting: TabPanels }], hostDirectives: [Bind] }] }] }); class TabsModule { static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.6", ngImport: i0, type: TabsModule, imports: [Tabs, TabPanels, TabPanel, TabList, Tab, BindModule], exports: [Tabs, TabPanels, TabPanel, TabList, Tab, BindModule] }); static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabsModule, imports: [Tabs, TabPanels, TabPanel, TabList, Tab, BindModule, BindModule] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: TabsModule, decorators: [{ type: NgModule, args: [{ imports: [Tabs, TabPanels, TabPanel, TabList, Tab, BindModule], exports: [Tabs, TabPanels, TabPanel, TabList, Tab, BindModule] }] }] }); /** * Generated bundle index. Do not edit. */ export { Tab, TabList, TabPanel, TabPanels, Tabs, TabsClasses, TabsModule, TabsStyle }; //# sourceMappingURL=primeng-tabs.mjs.map