@visa/nova-angular
Version:
Visa Product Design System Nova Angular library
1,199 lines (1,184 loc) • 624 kB
JavaScript
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
import * as i2$1 from '@angular/cdk/a11y';
import { A11yModule } from '@angular/cdk/a11y';
import * as i1 from '@angular/common';
import { isPlatformBrowser, DOCUMENT, CommonModule } from '@angular/common';
import * as i0 from '@angular/core';
import { EventEmitter, Directive, Output, HostListener, Input, HostBinding, Injectable, signal, PLATFORM_ID, Inject, Component, ContentChild, ContentChildren, forwardRef, inject, Optional, computed, ViewChild, ElementRef, Host, NgModule, APP_ID } from '@angular/core';
import * as i2 from '@angular/forms';
import { NG_VALUE_ACCESSOR, FormsModule, ReactiveFormsModule } from '@angular/forms';
import * as i1$1 from '@angular/router';
import { NavigationEnd, RouterModule } from '@angular/router';
import { filter } from 'rxjs';
import { SafeSubscriber } from 'rxjs/internal/Subscriber';
import { coerceBooleanProperty, coerceNumberProperty } from '@angular/cdk/coercion';
import { offset, flip, shift, arrow, autoUpdate, computePosition } from '@floating-ui/dom';
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
const A_LOWERCASE_KEY = 'a';
const DOWN_ARROW_KEY = 'ArrowDown';
const END_KEY = 'End';
const ESCAPE_KEY = 'Escape';
const HOME_KEY = 'Home';
const LEFT_ARROW_KEY = 'ArrowLeft';
const PAGE_DOWN_KEY = 'PageDown';
const PAGE_UP_KEY = 'PageUp';
const RIGHT_ARROW_KEY = 'ArrowRight';
const SPACE_KEY = ' ';
const SPACE_CODE = 'Space';
const TAB_KEY = 'Tab';
const UP_ARROW_KEY = 'ArrowUp';
const ALT_KEY = 'Alt';
const SHIFT_KEY = 'Shift';
const ENTER_KEY = 'Enter';
const BACKSPACE_KEY = 'Backspace';
const DELETE_KEY = 'Delete';
const CTRL_KEY = 'Control';
const META_KEY = 'Meta'; // command key on macs
// Internet Explorer (tested on release 9 and 11) and Firefox 36 and earlier use "Del" instead of "Delete" for the Del key.
// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values
const DEL_KEY = 'Del';
const SpacingProperties = {
INHERIT: 'inherit',
NORMAL: 'normal',
AUTO: 'auto'
};
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
class BaseInteractiveDirective {
constructor(el) {
this.el = el;
this.listeners = [];
/**
* Emits event when host interactive element is blurred.
*/
this.blurred = new EventEmitter();
/**
* Emits event when host interactive element is focused.
*/
this.focused = new EventEmitter();
/**
* Emits event when host interactive element is clicked.
*/
this.clicked = new EventEmitter();
}
ngOnDestroy() {
this.listeners = [];
}
hostBlur(event) {
this.blurred.emit(event);
}
hostFocus(event) {
this.focused.emit(event);
}
hostClick(event) {
this.clicked.emit(event);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BaseInteractiveDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: BaseInteractiveDirective, isStandalone: true, selector: "[v-interactive]", outputs: { blurred: "blurred", focused: "focused", clicked: "clicked" }, host: { listeners: { "blur": "hostBlur($event)", "focus": "hostFocus($event)", "click": "hostClick($event)" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BaseInteractiveDirective, decorators: [{
type: Directive,
args: [{
selector: '[v-interactive]',
standalone: true
}]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { blurred: [{
type: Output
}], hostBlur: [{
type: HostListener,
args: ['blur', ['$event']]
}], focused: [{
type: Output
}], hostFocus: [{
type: HostListener,
args: ['focus', ['$event']]
}], clicked: [{
type: Output
}], hostClick: [{
type: HostListener,
args: ['click', ['$event']]
}] } });
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
class DropdownItemDirective extends BaseInteractiveDirective {
constructor(el) {
super(el);
this.el = el;
this.buttonItem = false;
this.cssClasses = '';
/**
* Provides custom class(es) for custom styling.
* @default .v-listbox-item.v-dropdown-item
* @default .v-listbox-item.v-dropdown-item.v-button.v-button-tertiary.v-justify-content-start when the host element is a button.
*/
this.class = ''; // override the standard class attr with a new one.
this.cssClasses = 'v-listbox-item v-dropdown-item';
if (this.el.nativeElement.tagName.toLowerCase() === 'button') {
this.buttonItem = true;
this.cssClasses = 'v-listbox-item v-dropdown-item v-button v-button-tertiary v-justify-content-start';
}
}
get hostClasses() {
return [this.class, this.cssClasses].join(' ');
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DropdownItemDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: DropdownItemDirective, isStandalone: true, selector: "[v-dropdown-item]", inputs: { class: "class" }, host: { properties: { "class": "this.hostClasses" } }, usesInheritance: true, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DropdownItemDirective, decorators: [{
type: Directive,
args: [{
standalone: true,
selector: '[v-dropdown-item]'
}]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { class: [{
type: Input
}], hostClasses: [{
type: HostBinding,
args: ['class']
}] } });
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
/**
* This unique ID generator service is primarily used internally by the library but can be leveraged directly for custom implementations.
*/
class UUIDService {
constructor() {
/**
* Object to store generated IDs.
*/
this.UUIDs = {};
}
/** @ignore */
_getRandomId() {
return (Math.floor(Math.random() * 10).toString() +
Math.floor(Math.random() * 10).toString() +
Math.floor(Math.random() * 10).toString() +
Math.floor(Math.random() * 10).toString() +
Math.floor(Math.random() * 10).toString() +
Math.floor(Math.random() * 10).toString());
}
/**
* The getUUID method generates a random ID. <br>
* Works in tandem with <code>checkUUID</code> until a unique ID is generated.
* @param name Optional string to start the ID.
* @returns string
*/
getUUID(prefix) {
prefix = prefix ? prefix : '';
const uuid = '' + prefix + this._getRandomId();
return this.checkUUID(uuid, prefix);
}
/**
* The checkUUID method verifies that the ID has not already been generated by the getUUID method. <br>
* Works in tandem with <code>getUUID</code> until a unique ID is generated.
* @param uuid ID to check.
* @param name Optional string to start the ID.
* @returns uuid
*/
checkUUID(uuid, prefix) {
if (this.UUIDs[uuid]) {
return this.getUUID(prefix);
}
this.UUIDs[uuid] = 1;
return uuid;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UUIDService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UUIDService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UUIDService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}] });
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
/**
* This service is used internally by the library and can optionally be used directly. <br />
* It’s required for SSR integration but not necessary for functions behind Angular's renderer.
*/
class AppReadyService {
constructor(appRef, document, platformId) {
this.appRef = appRef;
this.document = document;
this.platformId = platformId;
/**
* Signal to indicate if the application is stable.
*/
this.appStable = signal(false);
/** @ignore */
this._browserAndDomReady = false;
this.appRef.isStable.subscribe((isStable) => {
this.appStable.set(isStable);
});
}
/**
* The checkDocumentExists method checks and returns the document object if applicable.
*/
checkDocumentExists() {
if (this.document) {
return this.document;
}
else
return false;
}
/**
* The checkIsPlatformBrowser method checks if the platform is a browser (as opposed to server).
* @returns boolean
*/
checkIsPlatformBrowser() {
return isPlatformBrowser(this.platformId);
}
/**
* The isBrowserAndDomAvailable method checks for both the document and the browser platform.
* @returns boolean
*/
isBrowserAndDomAvailable() {
if (this._browserAndDomReady)
return true; // prevent calling the functions every time
this._browserAndDomReady = this.checkDocumentExists() && this.checkIsPlatformBrowser();
return this._browserAndDomReady;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AppReadyService, deps: [{ token: i0.ApplicationRef }, { token: DOCUMENT }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AppReadyService, providedIn: 'root' }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: AppReadyService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], ctorParameters: () => [{ type: i0.ApplicationRef }, { type: Document, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [PLATFORM_ID]
}] }] });
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
const BadgeType = {
DEFAULT: 'default',
NEUTRAL: 'neutral',
CRITICAL: 'critical',
NEGATIVE: 'negative',
STABLE: 'stable',
WARNING: 'warning',
SUBTLE: 'subtle',
NUMBER: 'number',
ACTIVE: 'active'
};
class BadgeDirective {
/**
* Sets badge type.
* @default 'default' | BadgeType.DEFAULT
* @options 'default' | BadgeType.DEFAULT | <br> 'neutral' | BadgeType.NEUTRAL | <br> 'critical' | BadgeType.CRITICAL | <br> 'stable' | BadgeType.STABLE | <br> 'warning' | BadgeType.WARNING | <br> 'subtle' | BadgeType.SUBTLE | <br> 'number' | BadgeType.NUMBER
*/
get badgeType() {
return this._badgeType;
}
set badgeType(value) {
this._badgeType = value;
}
/**
* Provides custom class(es) for custom styling.
* @default .v-badge
*/
get class() {
return [
this._class,
this.badgeType && this.badgeType != 'default'
? this.badgeType === BadgeType.NEGATIVE
? 'v-badge-critical'
: `v-badge-${this.badgeType}`
: '',
this.number ? 'v-badge-number' : '',
this.noBackground ? 'v-badge-clear' : '',
this.icon ? 'v-badge-icon' : ''
].join(' ');
}
set class(value) {
this._class = value;
}
get hostClass() {
return this.class;
}
get hostId() {
return this.id;
}
constructor(uuidService) {
this.uuidService = uuidService;
this._badgeType = BadgeType.DEFAULT;
this._class = 'v-badge';
/**
* Sets custom id.
* @default uuidService.getUUID('v-badge-')
* @builtin true
*/
this.id = this.uuidService.getUUID('v-badge-');
this._number = false;
this._icon = false;
this._noBackground = false;
}
/**
* Sets badge to number variant when true. <br />
* Using this flag rather than <code>badgeType="number"</code> allows for number badges with other badge types.
* @default false
*/
get number() {
return this._number;
}
set number(value) {
this._number = coerceBooleanProperty(value);
}
/**
* Whether or not badge contains an icon.
* @default false
*/
get icon() {
return this._icon;
}
set icon(value) {
this._icon = coerceBooleanProperty(value);
}
/**
* Removes background color from badge when true.
*/
get noBackground() {
return this._noBackground;
}
set noBackground(value) {
this._noBackground = coerceBooleanProperty(value);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BadgeDirective, deps: [{ token: UUIDService }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: BadgeDirective, isStandalone: true, selector: "[v-badge]", inputs: { badgeType: "badgeType", class: "class", id: "id", number: "number", icon: "icon", noBackground: "noBackground" }, host: { properties: { "class": "this.hostClass", "attr.id": "this.hostId" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: BadgeDirective, decorators: [{
type: Directive,
args: [{
standalone: true,
selector: '[v-badge]'
}]
}], ctorParameters: () => [{ type: UUIDService }], propDecorators: { badgeType: [{
type: Input
}], class: [{
type: Input
}], hostClass: [{
type: HostBinding,
args: ['class']
}], id: [{
type: Input
}], hostId: [{
type: HostBinding,
args: ['attr.id']
}], number: [{
type: Input
}], icon: [{
type: Input
}], noBackground: [{
type: Input
}] } });
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
class IconToggleDefaultTemplateDirective {
get hostClasses() {
return [this.class].join(' ');
}
constructor(el) {
this.el = el;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: IconToggleDefaultTemplateDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: IconToggleDefaultTemplateDirective, isStandalone: true, selector: "[v-toggle-default-template]", inputs: { class: "class" }, host: { properties: { "class": "this.hostClasses" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: IconToggleDefaultTemplateDirective, decorators: [{
type: Directive,
args: [{
standalone: true,
selector: '[v-toggle-default-template]'
}]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { class: [{
type: Input
}], hostClasses: [{
type: HostBinding,
args: ['class']
}] } });
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
class IconToggleRotatedTemplateDirective {
get hostClasses() {
return [this.class].join(' ');
}
constructor(el) {
this.el = el;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: IconToggleRotatedTemplateDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: IconToggleRotatedTemplateDirective, isStandalone: true, selector: "[v-toggle-rotated-template]", inputs: { class: "class" }, host: { properties: { "class": "this.hostClasses" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: IconToggleRotatedTemplateDirective, decorators: [{
type: Directive,
args: [{
standalone: true,
selector: '[v-toggle-rotated-template]'
}]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { class: [{
type: Input
}], hostClasses: [{
type: HostBinding,
args: ['class']
}] } });
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
class IconToggleComponent {
constructor(el) {
this.el = el;
this._floatingUIToggle = false;
this._selectToggle = false;
this._accordionToggle = false;
this._class = '';
this._rotated = false;
/** @ignore */
this.alignment = 'center';
// don't allow this component to be styled with colors
// "pass" the colors to the child svg
/** @ignore */
this.color = 'inherit';
/** @ignore */
this.pointerEvents = 'none';
} // used for tabs
/**
* Provides custom class(es) for custom styling.
* @default .v-accordion-toggle-icon
*/
get class() {
return [this._class, 'v-icon', 'v-icon-tiny', this._accordionToggle ? 'v-accordion-toggle-icon' : ''].join(' ');
}
set class(value) {
this._class = value;
}
get hostClass() {
return this.class;
}
/**
* Shows the rotated template when true and the default template when false.
* @default false
**/
get rotated() {
return this._rotated;
}
set rotated(value) {
this._rotated = value;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: IconToggleComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: IconToggleComponent, isStandalone: true, selector: "v-icon-visa-toggle", inputs: { class: "class", rotated: "rotated", alignment: "alignment", color: "color", pointerEvents: "pointerEvents" }, host: { properties: { "class": "this.hostClass", "style.align-items": "this.alignment", "style.justify-content": "this.alignment", "style.--v-icon-primary": "this.color", "style.--v-icon-secondary": "this.color", "style.pointer-events": "this.pointerEvents" } }, queries: [{ propertyName: "defaultTemplate", first: true, predicate: IconToggleDefaultTemplateDirective, descendants: true }, { propertyName: "rotatedTemplate", first: true, predicate: IconToggleRotatedTemplateDirective, descendants: true }], ngImport: i0, template: "<!--\n * Copyright (c) 2025 Visa, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n -->\n<ng-container *ngIf=\"!rotated; else rotatedTemplate\">\n <ng-content select=\"[v-toggle-default-template]\"></ng-content>\n</ng-container>\n\n<ng-template #rotatedTemplate>\n <ng-content select=\"[v-toggle-rotated-template]\"></ng-content>\n</ng-template>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: IconToggleComponent, decorators: [{
type: Component,
args: [{ standalone: true, imports: [CommonModule], selector: 'v-icon-visa-toggle', template: "<!--\n * Copyright (c) 2025 Visa, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n -->\n<ng-container *ngIf=\"!rotated; else rotatedTemplate\">\n <ng-content select=\"[v-toggle-default-template]\"></ng-content>\n</ng-container>\n\n<ng-template #rotatedTemplate>\n <ng-content select=\"[v-toggle-rotated-template]\"></ng-content>\n</ng-template>\n" }]
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { defaultTemplate: [{
type: ContentChild,
args: [IconToggleDefaultTemplateDirective]
}], rotatedTemplate: [{
type: ContentChild,
args: [IconToggleRotatedTemplateDirective]
}], class: [{
type: Input
}], hostClass: [{
type: HostBinding,
args: ['class']
}], rotated: [{
type: Input
}], alignment: [{
type: HostBinding,
args: ['style.align-items']
}, {
type: HostBinding,
args: ['style.justify-content']
}, {
type: Input
}], color: [{
type: HostBinding,
args: ['style.--v-icon-primary']
}, {
type: HostBinding,
args: ['style.--v-icon-secondary']
}, {
type: Input
}], pointerEvents: [{
type: HostBinding,
args: ['style.pointer-events']
}, {
type: Input
}] } });
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
const IconSize = {
TINY: 'tiny',
LOW: 'low',
HIGH: 'high'
};
const IconLibrary = {
VISA: 'visa',
GENERIC: 'generic',
};
const IconToggle = {
EXPANDED: 'chevron-up',
COLLAPSED: 'chevron-down',
};
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
/**
* <code>IconComponent</code> is intended <i>only</i> for use with icons used with an icon sprite. <br />
* <strong>Standalone icons from @visa/nova-icons-angular is recommended over using the <code>IconComponent</code>.</strong>. <br />
* Icon component for displaying icons from VPDS' [Icon Library](https://design.visa.com/icons). <br />
*/
class IconComponent {
/**
* Provides custom class(es) for custom styling.
* @default .v-icon.v-icon-<iconSize>.v-icon-<library>
*/
get class() {
return [
this._class,
'v-icon',
'v-icon-' + this.iconSize,
'v-icon-' + this.library,
this.isBadgeEllipse ? 'v-badge-ellipse' : '',
this.rtl ? 'v-icon-rtl' : ''
].join(' ');
}
set class(value) {
this._class = value;
}
get hostClass() {
return this.class;
}
/**
* Flips icon from right to left when true and <code>dir="rtl" is present on a parent element.
* @default false
*/
get rtl() {
return this._rtl;
}
set rtl(value) {
this._rtl = coerceBooleanProperty(value);
}
/**
* Sets icon resolution/size.
* @default 'tiny' / IconSize.TINY
* @options 'tiny' | IconSize.TINY | <br> 'low' | IconSize.LOW | <br> 'high' | IconSize.HIGH
*/
// default of tiny chosen because it is the default for majority of buttons
get iconSize() {
return this._iconSize;
}
set iconSize(value) {
this._iconSize = value;
this.setIcon();
}
/**
* Tells icon which library to reference.
* @default 'visa' / IconLibrary.VISA
* @options 'visa' | IconLibrary.VISA | <br> 'generic' | IconLibrary.GENERIC
*/
get library() {
return this._library;
}
set library(value) {
this._library = value;
}
/**
* Name of icon to display. <br />
* Should refer to an icon in VPDS' [Icon Library](https://design.visa.com/icons).
*/
get icon() {
return this._icon;
}
set icon(value) {
this._icon = value;
this.setIcon();
}
/**
* Sets icon to badge-ellipse variant when true. <br />
* Intended for use in badges with an indicator.
* @default false
*/
get isBadgeEllipse() {
return this._isBadgeEllipse;
}
set isBadgeEllipse(value) {
this._isBadgeEllipse = coerceBooleanProperty(value);
}
get hostStyleFill() {
if (this.isBadgeEllipse) {
return 'var(--v-badge-ellipse-color)';
}
}
get hostStyleIconHeight() {
if (this.isBadgeEllipse) {
return `var(--size-scalable-${this.customHeight})`;
}
}
get hostStyleIconWidth() {
if (this.isBadgeEllipse) {
return `var(--size-scalable-${this.customWidth})`;
}
}
/**
* Set CSS variable <code>--v-icon-height</code> which customizes icon height.
* @default '--size-scalable-8'
*/
get customHeight() {
return this._customHeight;
}
set customHeight(value) {
this._customHeight = value;
}
/**
* Set CSS variable <code>--v-icon-width</code> which customizes icon width.
* @default '--size-scalable-8'
*/
get customWidth() {
return this._customWidth;
}
set customWidth(value) {
this._customWidth = value;
}
/**
* Name of <strong>custom</strong> icon reference. <br />
* Should refer to an icon within an icon sprite in your application. <br />
* The href will reference the string provided directly. No library or iconSize will be added.
*/
get customIcon() {
return this._customIcon;
}
set customIcon(value) {
this._customIcon = value;
this.setIcon();
}
get hostViewBox() {
return `0 0 ${this._computedSize} ${this._computedSize}`;
}
get hostHeight() {
return `${this._computedSize}`;
}
get hostWidth() {
return `${this._computedSize}`;
}
get hostFocusable() {
return 'false';
}
get hostAriaHidden() {
return 'true';
}
constructor() {
this._computedSize = 24;
this._class = '';
this._rtl = false;
this._iconSize = IconSize.TINY;
this._library = IconLibrary.VISA;
this._isBadgeEllipse = false;
this._customHeight = '8';
this._customWidth = '8';
}
ngOnInit() {
this.setIcon();
}
setIcon() {
this._computedSize = this.iconSize === IconSize.LOW ? 24 : this.iconSize === IconSize.HIGH ? 48 : 16;
this._iconRef = this.customIcon
? this.customIcon
: this.icon
? `${this.library}-${this.icon}-${this.iconSize}`
: '';
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: IconComponent, isStandalone: true, selector: "[v-icon]", inputs: { class: "class", rtl: "rtl", iconSize: "iconSize", library: "library", icon: "icon", isBadgeEllipse: "isBadgeEllipse", customHeight: "customHeight", customWidth: "customWidth", customIcon: "customIcon" }, host: { properties: { "class": "this.hostClass", "style.--v-icon-primary": "this.hostStyleFill", "style.--v-icon-secondary": "this.hostStyleFill", "style.--v-icon-height": "this.hostStyleIconHeight", "style.--v-icon-width": "this.hostStyleIconWidth", "attr.viewBox": "this.hostViewBox", "attr.height": "this.hostHeight", "attr.width": "this.hostWidth", "attr.focusable": "this.hostFocusable", "attr.aria-hidden": "this.hostAriaHidden" } }, ngImport: i0, template: "<!--\n * Copyright (c) 2025 Visa, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n -->\n<svg:use *ngIf=\"_iconRef\" [attr.href]=\"'#' + _iconRef\" [attr.xlink:href]=\"'#' + _iconRef\"></svg:use>\n<svg:circle *ngIf=\"isBadgeEllipse\" cx=\"8\" cy=\"8\" r=\"8\" style=\"fill: var(--v-badge-ellipse-color)\"></svg:circle>\n<ng-content></ng-content>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: IconComponent, decorators: [{
type: Component,
args: [{ standalone: true, imports: [CommonModule], selector: '[v-icon]', template: "<!--\n * Copyright (c) 2025 Visa, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n -->\n<svg:use *ngIf=\"_iconRef\" [attr.href]=\"'#' + _iconRef\" [attr.xlink:href]=\"'#' + _iconRef\"></svg:use>\n<svg:circle *ngIf=\"isBadgeEllipse\" cx=\"8\" cy=\"8\" r=\"8\" style=\"fill: var(--v-badge-ellipse-color)\"></svg:circle>\n<ng-content></ng-content>\n" }]
}], ctorParameters: () => [], propDecorators: { class: [{
type: Input
}], hostClass: [{
type: HostBinding,
args: ['class']
}], rtl: [{
type: Input
}], iconSize: [{
type: Input
}], library: [{
type: Input
}], icon: [{
type: Input
}], isBadgeEllipse: [{
type: Input
}], hostStyleFill: [{
type: HostBinding,
args: ['style.--v-icon-primary']
}, {
type: HostBinding,
args: ['style.--v-icon-secondary']
}], hostStyleIconHeight: [{
type: HostBinding,
args: ['style.--v-icon-height']
}], hostStyleIconWidth: [{
type: HostBinding,
args: ['style.--v-icon-width']
}], customHeight: [{
type: Input
}], customWidth: [{
type: Input
}], customIcon: [{
type: Input
}], hostViewBox: [{
type: HostBinding,
args: ['attr.viewBox']
}], hostHeight: [{
type: HostBinding,
args: ['attr.height']
}], hostWidth: [{
type: HostBinding,
args: ['attr.width']
}], hostFocusable: [{
type: HostBinding,
args: ['attr.focusable']
}], hostAriaHidden: [{
type: HostBinding,
args: ['attr.aria-hidden']
}] } });
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
class IconToggleDirective {
/**
* Provides custom class(es) for custom styling.
* @default .v-accordion-toggle-icon
*/
get class() {
return [this._class].join(' ');
}
set class(value) {
this._class = value;
}
get hostClass() {
return this.class;
}
/**
* Icon to show when item is expanded / shown. <br>
* Will render this icon when no <code>icon</code> or <code>customIcon</code> is provided to <code>v-icon</code>. <br>
* Should refer to an icon in VPDS' [Icon Library](https://design.visa.com/icons).
* @default 'chevron-down' / IconToggle.EXPANDED <br>
* @builtin true
*/
get expandedIcon() {
return this._expandedIcon;
}
set expandedIcon(value) {
this._expandedIcon = value;
this._expandedSet = true;
}
/**
* Icon to show when item is collapsed / hidden. <br>
* Will render this icon when no <code>icon</code> or <code>customIcon</code> is provided to <code>v-icon</code>. <br>
* Should refer to an icon in VPDS' [Icon Library](https://design.visa.com/icons).
* @default 'chevron-right' / IconToggle.COLLAPSED <br>
* @builtin true
*/
get collapsedIcon() {
return this._collapsedIcon;
}
set collapsedIcon(value) {
this._collapsedIcon = value;
this._collapsedSet = true;
}
constructor(icon) {
this.icon = icon;
this._expanded = false;
this._iconSet = false;
this._expandedSet = false;
this._collapsedSet = false;
this._class = '';
this._expandedIcon = IconToggle.EXPANDED;
this._collapsedIcon = IconToggle.COLLAPSED;
} // used in floating-ui or accordion service
ngOnInit() {
if (this.icon && (this.icon.icon || this.icon.customIcon)) {
this._iconSet = true;
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: IconToggleDirective, deps: [{ token: IconComponent }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: IconToggleDirective, isStandalone: true, selector: "[v-icon-toggle]", inputs: { class: "class", expandedIcon: "expandedIcon", collapsedIcon: "collapsedIcon" }, host: { properties: { "class": "this.hostClass" } }, ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: IconToggleDirective, decorators: [{
type: Directive,
args: [{
standalone: true,
// tslint:disable-next-line:directive-selector
selector: '[v-icon-toggle]'
}]
}], ctorParameters: () => [{ type: IconComponent }], propDecorators: { class: [{
type: Input
}], hostClass: [{
type: HostBinding,
args: ['class']
}], expandedIcon: [{
type: Input
}], collapsedIcon: [{
type: Input
}] } });
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
const ButtonSize = {
SMALL: 'small',
MEDIUM: 'medium',
LARGE: 'large'
};
const ButtonColor = {
PRIMARY: 'primary',
SECONDARY: 'secondary',
TERTIARY: 'tertiary'
};
/**
* Copyright (c) 2025 Visa, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/
class ButtonDirective extends BaseInteractiveDirective {
get hostId() {
return this.id;
}
get hostType() {
return this.type;
}
/**
* Provides custom class(es) for custom styling.
* @default .v-button.v-button-<buttonColor>.v-button-<buttonSize>
*/
get class() {
return [
this._class,
'v-button',
this.buttonColor !== ButtonColor.PRIMARY ? 'v-button-' + this.buttonColor : '',
this.buttonSize !== ButtonSize.MEDIUM ? 'v-button-' + this.buttonSize : '',
this.subtle ? 'v-button-subtle' : '',
this.destructive ? 'v-button-destructive' : ''
].join(' ');
}
set class(value) {
this._class = value;
}
get hostClass() {
return this.class;
}
/**
* Sets button size.
* @default 'medium' / ButtonSize.MEDIUM
* @options 'small' | ButtonSize.SMALL | <br> 'medium' | ButtonSize.MEDIUM | <br> 'large' | ButtonSize.LARGE
*/
get buttonSize() {
return this._buttonSize;
}
set buttonSize(value) {
this._buttonSize = value;
this._buttonSizeSetByUser = true;
}
/**
* Sets button color scheme.
* @default 'primary' / ButtonColor.PRIMARY
* @options 'primary' | ButtonSize.PRIMARY | <br> 'secondary' | ButtonSize.SECONDARY | <br> 'tertiary' | ButtonSize.TERTIARY
*/
get buttonColor() {
return this._buttonColor;
}
set buttonColor(value) {
this._buttonColor = value;
this._buttonColorSetByUser = true;
}
/**
* Sets button to subtle variant when true.
* @default false
*/
get subtle() {
return this._subtle;
}
set subtle(value) {
this._subtle = coerceBooleanProperty(value);
}
/**
* Sets button to destructive variant when true.
* @default false
*/
get destructive() {
return this._destructive;
}
set destructive(value) {
this._destructive = coerceBooleanProperty(value);
}
/**
* Disables button when true.
* @default false
*/
get disabled() {
return this._disabled;
}
set disabled(value) {
this._disabled = coerceBooleanProperty(value);
this.disabledChange.emit(this.disabled);
}
/**
* Aria attribute pointing to id of descriptive element. <br />
* If the button has a badge, the <code>aria-describedby</code> will be set to the badge's id by default.
* @default false
*/
get ariaDescribedby() {
return this._ariaDescribedby;
}
set ariaDescribedby(value) {
this._ariaDescribedby = value;
}
get hostAriaDescribedby() {
if (this.ariaDescribedby !== null) {
return this.ariaDescribedby;
}
}
constructor(el) {
super(el);
this._roleSetByUser = false; // prevents parent component from overriding if role if role is given directly by user
this._buttonColorSetByUser = false; // prevents parent component from overriding if buttonColor if buttonColor is given directly by user
this._buttonSizeSetByUser = false; // prevents parent component from overriding if buttonSize if buttonSize is given directly by user
/**
* Sets custom type.
* @default 'button'
*/
this.type = 'button';
this._class = '';
this._buttonSize = ButtonSize.MEDIUM;
this._buttonColor = ButtonColor.PRIMARY;
this._subtle = false;
this._destructive = false;
this._disabled = false;
/**
* Emits a boolean value indicating the new disabled state when the disabled state changes.
*/
this.disabledChange = new EventEmitter();
this._ariaDescribedby = null;
this._roleSetByTab = false;
this._isInNavOrNested = false;
this._ariaSelected = null;
this._ariaCurrent = null;
this._ariaExpanded = null;
this._ariaDisabled = false;
this._ariaControls = null;
/** Below needed for combobox */
this._inCombobox = false;
} // used in accordion service
ngAfterContentInit() {
if (this.badge) {
this.ariaDescribedby = this.badge.id;