UNPKG

@engie-group/fluid-design-system-angular

Version:
839 lines (821 loc) 388 kB
import * as i0 from '@angular/core'; import { inject, TemplateRef, Directive, Input, booleanAttribute, input, computed, ViewEncapsulation, ChangeDetectionStrategy, Component, ElementRef, ContentChildren, HostBinding, ContentChild, DestroyRef, EventEmitter, contentChild, signal, effect, Output, ViewChild, forwardRef, ChangeDetectorRef, HostListener, ViewChildren, Inject, output, contentChildren, Pipe, Attribute, Optional, model, Self, Host, Injectable } from '@angular/core'; import * as i1 from '@angular/common'; import { NgTemplateOutlet, CommonModule, DOCUMENT } from '@angular/common'; import { ICON_ENGIE_PREFIX } from '@engie-group/fluid-types'; export * from '@engie-group/fluid-types'; import * as i2 from '@angular/forms'; import { NgModel, NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms'; import { Subject, merge, fromEvent, takeUntil, race, BehaviorSubject } from 'rxjs'; import { trigger, state, transition, style, animate } from '@angular/animations'; import { njSemanticMotionEasingLinearOutSlowIn } from '@engie-group/fluid-design-tokens'; import { ComponentPortal, DomPortalOutlet, TemplatePortal } from '@angular/cdk/portal'; import * as i1$1 from '@angular/cdk/overlay'; import * as i1$2 from '@angular/cdk/dialog'; import * as i1$3 from '@angular/platform-browser'; const ThemeComponentsVariantsArray = [ 'grey', 'brand', 'teal', 'pink', 'orange', 'red', 'green', 'ultramarine', 'yellow', 'purple', 'blue', 'lime' ]; class CustomIconDirective { constructor() { this.templateRef = inject(TemplateRef); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: CustomIconDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.13", type: CustomIconDirective, isStandalone: true, selector: "[njCustomIcon]", ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: CustomIconDirective, decorators: [{ type: Directive, args: [{ selector: '[njCustomIcon]', standalone: true }] }] }); class EngieTemplateDirective { constructor() { this.templateRef = inject(TemplateRef); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: EngieTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.13", type: EngieTemplateDirective, isStandalone: true, selector: "[njTemplate]", inputs: { selector: ["njTemplate", "selector"] }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: EngieTemplateDirective, decorators: [{ type: Directive, args: [{ selector: '[njTemplate]', standalone: true }] }], propDecorators: { selector: [{ type: Input, args: ['njTemplate'] }] } }); class HeadingDirective { get classes() { return { 'nj-heading': true, 'nj-heading--not-invertible': this.isNotInvertible, [`nj-heading--${this.scale}`]: !!this.scale, [`nj-heading--${this.variant}`]: !!this.variant }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: HeadingDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "20.3.13", type: HeadingDirective, isStandalone: true, selector: "[njHeading]", inputs: { scale: "scale", variant: "variant", isNotInvertible: ["isNotInvertible", "isNotInvertible", booleanAttribute] }, host: { properties: { "class": "classes" } }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: HeadingDirective, decorators: [{ type: Directive, args: [{ selector: '[njHeading]', standalone: true, host: { '[class]': 'classes' } }] }], propDecorators: { scale: [{ type: Input }], variant: [{ type: Input }], isNotInvertible: [{ type: Input, args: [{ transform: booleanAttribute }] }] } }); class TextDirective { get classes() { return { 'nj-text': true, 'nj-text--not-invertible': this.isNotInvertible, 'nj-text--monospace': this.isMono, [`nj-text--${this.scale}`]: !!this.scale, [`nj-text--${this.variant}`]: !!this.variant }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: TextDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "20.3.13", type: TextDirective, isStandalone: true, selector: "[njText]", inputs: { scale: "scale", variant: "variant", isNotInvertible: ["isNotInvertible", "isNotInvertible", booleanAttribute], isMono: ["isMono", "isMono", booleanAttribute] }, host: { properties: { "class.nj-text": "true", "class.nj-text--not-invertible": "isNotInvertible", "class.nj-text--monospace": "isMono", "class": "classes" } }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: TextDirective, decorators: [{ type: Directive, args: [{ selector: '[njText]', standalone: true, host: { '[class.nj-text]': 'true', '[class.nj-text--not-invertible]': 'isNotInvertible', '[class.nj-text--monospace]': 'isMono', '[class]': 'classes' } }] }], propDecorators: { scale: [{ type: Input }], variant: [{ type: Input }], isNotInvertible: [{ type: Input, args: [{ transform: booleanAttribute }] }], isMono: [{ type: Input, args: [{ transform: booleanAttribute }] }] } }); class IconComponent { constructor() { this.ICON_MATERIAL_CLASS = 'nj-icon-material'; /** * Icon name */ this.name = input.required(...(ngDevMode ? [{ debugName: "name" }] : [])); /** * Icon size */ this.scale = input(...(ngDevMode ? [undefined, { debugName: "scale" }] : [])); /** * Icon variant theme */ this.variant = input(...(ngDevMode ? [undefined, { debugName: "variant" }] : [])); /** * Icon style */ this.iconStyle = input(...(ngDevMode ? [undefined, { debugName: "iconStyle" }] : [])); /** * Text alternative for assistive technologies. * When provided, removes `aria-hidden` and exposes the icon to screen readers. */ this.ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel", alias: 'aria-label' }] : [{ alias: 'aria-label' }])); this.classes = computed(() => { const base = this.ICON_MATERIAL_CLASS; const scale = this.scale(); const variant = this.variant(); const iconStyle = this.iconStyle(); const name = this.name(); const isEngie = name.startsWith(ICON_ENGIE_PREFIX); return { [base]: true, [`${base}--${scale === 'inherit' ? 'size-inherit' : scale}`]: !!scale && scale !== 'md', [`${base}--${variant === 'inherit' ? 'color-inherit' : variant}`]: !!variant && variant !== 'primary', [`${base}--${iconStyle}`]: !!iconStyle && iconStyle !== 'filled' && !isEngie, [`${base}--engie`]: isEngie }; }, ...(ngDevMode ? [{ debugName: "classes" }] : [])); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: IconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.13", type: IconComponent, isStandalone: true, selector: "nj-icon", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, scale: { classPropertyName: "scale", publicName: "scale", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, iconStyle: { classPropertyName: "iconStyle", publicName: "iconStyle", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "aria-label", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()", "attr.aria-hidden": "ariaLabel() ? null : \"true\"", "attr.role": "ariaLabel() ? \"img\" : null" } }, ngImport: i0, template: "{{ name() }}\n", styles: [":host,nj-icon{display:inline-flex}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: IconComponent, decorators: [{ type: Component, args: [{ selector: 'nj-icon', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes()', '[attr.aria-hidden]': 'ariaLabel() ? null : "true"', '[attr.role]': 'ariaLabel() ? "img" : null' }, template: "{{ name() }}\n", styles: [":host,nj-icon{display:inline-flex}\n"] }] }], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], scale: [{ type: i0.Input, args: [{ isSignal: true, alias: "scale", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], iconStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "iconStyle", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "aria-label", required: false }] }] } }); class AccordionItemComponent { constructor() { this.element = inject(ElementRef); this.accordion = inject(AccordionComponent); } get classes() { const classes = ['nj-accordion-item']; if (this.scale && this.scale !== 'md') { classes.push(`nj-accordion-item--${this.scale}`); } if (this.hasLeadingToggleIcon) { classes.push('nj-accordion-item--leading-toggle'); } return classes; } ngAfterContentInit() { this.templateDirectives?.forEach((templateDirective) => { if (templateDirective?.selector === 'icon') { this.iconTemplate = templateDirective.templateRef; } if (templateDirective?.selector === 'header') { this.headerTemplate = templateDirective.templateRef; } }); } handleClick(event) { if (this.name && !this.element.nativeElement.open) { event.preventDefault(); this.accordion.collapseAllItems(this.name); this.expand(); } } /** * Expand the accordion item programmatically */ expand() { if (this.element) { this.element.nativeElement.open = true; } } /** * Collapse the accordion item programmatically */ collapse() { if (this.element) { this.element.nativeElement.open = false; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AccordionItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.13", type: AccordionItemComponent, isStandalone: true, selector: "details[nj-accordion-item]", inputs: { scale: "scale", hasLeadingToggleIcon: ["hasLeadingToggleIcon", "hasLeadingToggleIcon", booleanAttribute], useAlternativeToggleIcon: ["useAlternativeToggleIcon", "useAlternativeToggleIcon", booleanAttribute], name: "name", label: "label" }, host: { listeners: { "click": "handleClick($event)" }, properties: { "class": "classes" } }, queries: [{ propertyName: "templateDirectives", predicate: EngieTemplateDirective }], ngImport: i0, template: "@if (label || headerTemplate) {\n <summary>\n @if (iconTemplate) {\n <ng-container [ngTemplateOutlet]=\"iconTemplate\"></ng-container>\n }\n <span class=\"nj-accordion-item__label\">\n @if (label) {\n {{ label }}\n } @else {\n <ng-template [ngTemplateOutlet]=\"headerTemplate\"></ng-template>\n }\n </span>\n @if (!useAlternativeToggleIcon) {\n <nj-icon name=\"expand_more\" class=\"nj-accordion-item__toggle\" variant=\"inherit\" scale=\"inherit\"></nj-icon>\n } @else {\n <nj-icon\n name=\"add\"\n class=\"nj-accordion-item__toggle nj-accordion-item__toggle--closed\"\n variant=\"inherit\"\n scale=\"inherit\"\n ></nj-icon>\n <nj-icon\n name=\"remove\"\n class=\"nj-accordion-item__toggle nj-accordion-item__toggle--opened\"\n variant=\"inherit\"\n scale=\"inherit\"\n ></nj-icon>\n }\n </summary>\n}\n<p class=\"nj-accordion-item__content\">\n <ng-content></ng-content>\n</p>\n", styles: ["details[nj-accordion-item][open] nj-icon.nj-accordion-item__toggle.nj-accordion-item__toggle--opened{display:inline-flex}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "nj-icon", inputs: ["name", "scale", "variant", "iconStyle", "aria-label"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AccordionItemComponent, decorators: [{ type: Component, args: [{ selector: 'details[nj-accordion-item]', encapsulation: ViewEncapsulation.None, imports: [IconComponent, NgTemplateOutlet], host: { '[class]': 'classes', '(click)': 'handleClick($event)' }, template: "@if (label || headerTemplate) {\n <summary>\n @if (iconTemplate) {\n <ng-container [ngTemplateOutlet]=\"iconTemplate\"></ng-container>\n }\n <span class=\"nj-accordion-item__label\">\n @if (label) {\n {{ label }}\n } @else {\n <ng-template [ngTemplateOutlet]=\"headerTemplate\"></ng-template>\n }\n </span>\n @if (!useAlternativeToggleIcon) {\n <nj-icon name=\"expand_more\" class=\"nj-accordion-item__toggle\" variant=\"inherit\" scale=\"inherit\"></nj-icon>\n } @else {\n <nj-icon\n name=\"add\"\n class=\"nj-accordion-item__toggle nj-accordion-item__toggle--closed\"\n variant=\"inherit\"\n scale=\"inherit\"\n ></nj-icon>\n <nj-icon\n name=\"remove\"\n class=\"nj-accordion-item__toggle nj-accordion-item__toggle--opened\"\n variant=\"inherit\"\n scale=\"inherit\"\n ></nj-icon>\n }\n </summary>\n}\n<p class=\"nj-accordion-item__content\">\n <ng-content></ng-content>\n</p>\n", styles: ["details[nj-accordion-item][open] nj-icon.nj-accordion-item__toggle.nj-accordion-item__toggle--opened{display:inline-flex}\n"] }] }], propDecorators: { scale: [{ type: Input }], hasLeadingToggleIcon: [{ type: Input, args: [{ transform: booleanAttribute }] }], useAlternativeToggleIcon: [{ type: Input, args: [{ transform: booleanAttribute }] }], name: [{ type: Input }], label: [{ type: Input }], templateDirectives: [{ type: ContentChildren, args: [EngieTemplateDirective] }] } }); class AccordionComponent { get classes() { const classes = ['nj-accordion']; if (this.noBorder) { classes.push('nj-accordion--no-border'); } if (this.separated) { classes.push('nj-accordion--separated'); } return classes; } /** * Expand all children items programmatically */ expandAllItems() { const openedGroup = new Set(); this.accordions?.forEach((accordion) => { // Firefox doesn't currently support grouping accordion items with `name` property. // So we replicate the behavior here to have it on all browsers. // // As explained in the MDN documentation, when the `name` property is set, only the first details // element with the `open` property should be opened. if (!accordion.name || !openedGroup.has(accordion.name)) { accordion.expand(); } else { accordion.collapse(); } if (accordion.name) { openedGroup.add(accordion.name); } }); } /** * Collapse all children items programmatically */ collapseAllItems(name) { this.accordions?.forEach((accordion) => { if (name && accordion.name !== name) { return; } accordion.collapse(); }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AccordionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "20.3.13", type: AccordionComponent, isStandalone: true, selector: "nj-accordion", inputs: { noBorder: ["noBorder", "noBorder", booleanAttribute], separated: ["separated", "separated", booleanAttribute] }, host: { properties: { "class": "classes" } }, queries: [{ propertyName: "accordions", predicate: AccordionItemComponent }], ngImport: i0, template: "<ng-content></ng-content>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AccordionComponent, decorators: [{ type: Component, args: [{ selector: 'nj-accordion', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { '[class]': 'classes' }, template: "<ng-content></ng-content>\n" }] }], propDecorators: { noBorder: [{ type: Input, args: [{ transform: booleanAttribute }] }], separated: [{ type: Input, args: [{ transform: booleanAttribute }] }], accordions: [{ type: ContentChildren, args: [AccordionItemComponent] }] } }); class AccordionActionsComponent { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AccordionActionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.13", type: AccordionActionsComponent, isStandalone: true, selector: "nj-accordion-actions", host: { classAttribute: "nj-accordion__actions" }, ngImport: i0, template: "<ng-content></ng-content>\n", changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AccordionActionsComponent, decorators: [{ type: Component, args: [{ selector: 'nj-accordion-actions', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, host: { class: 'nj-accordion__actions' }, template: "<ng-content></ng-content>\n" }] }] }); class AccordionActionDirective { constructor() { this.accordion = inject(AccordionComponent); } handleClicked() { if (this.type === 'expand') { this.accordion?.expandAllItems(); } if (this.type === 'collapse') { this.accordion?.collapseAllItems(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AccordionActionDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.13", type: AccordionActionDirective, isStandalone: true, selector: "[njAccordionAction]", inputs: { type: ["njAccordionAction", "type"] }, host: { listeners: { "click": "handleClicked()" }, properties: { "attr.data-accordion-expand": "type === 'expand'", "attr.data-accordion-collapse": "type === 'collapse'" }, classAttribute: "njAccordionAction" }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: AccordionActionDirective, decorators: [{ type: Directive, args: [{ selector: '[njAccordionAction]', standalone: true, host: { class: 'njAccordionAction', '[attr.data-accordion-expand]': "type === 'expand'", '[attr.data-accordion-collapse]': "type === 'collapse'", '(click)': 'handleClicked()' } }] }], propDecorators: { type: [{ type: Input, args: ['njAccordionAction'] }] } }); const selectAnimations = { transformList: trigger('transformList', [ state('void', style({ transform: 'scaleY(0.8)', opacity: 0 })), state('*', style({ opacity: 1, transform: 'scaleY(1)' })), transition('void => *', animate(`120ms ${njSemanticMotionEasingLinearOutSlowIn}`)), transition('* => void', animate(`100ms 25ms ${njSemanticMotionEasingLinearOutSlowIn}`, style({ opacity: 0 }))) ]) }; // Ignore https://angular.io/guide/angular-compiler-options#strictmetadataemit // @dynamic class Utils { static { this.MAX_UID = 1000000; } static isUndefinedOrNull(value) { return typeof value === 'undefined' || value === null; } static normalizeString(text) { return text.normalize('NFD').replace(/[\u0300-\u036f]/g, ''); } static normalizeAndSearchInText(text, search) { if (Utils.isUndefinedOrNull(text) || Utils.isUndefinedOrNull(search)) { return false; } const normalizedText = Utils.normalizeString(text); let normalizedSearch = Utils.escapeRegExp(Utils.normalizeString(search)); const regExp = new RegExp(normalizedSearch, 'gi'); return normalizedText.search(regExp) !== -1; } static escapeRegExp(string) { return string.replace(/[-\\^$*+?.()|[\]{}]/g, '\\$&'); } static getUID(prefix) { do { // eslint-disable-next-line no-bitwise prefix += ~~(Math.random() * Utils.MAX_UID); // "~~" acts like a faster Math.floor() here } while (document.getElementById(prefix)); return prefix; } } class FormFieldDirective { constructor(el) { this.el = el; this.class = 'nj-form-item__field'; this.setPlaceholder(); } setPlaceholder() { if (this.tagName.toLowerCase() === 'select') { return; } const placeholder = this.el?.nativeElement?.placeholder; this.el.nativeElement.placeholder = Utils.isUndefinedOrNull(placeholder) || placeholder?.trim() === '' ? ' ' // Placeholder must be " " because of webkit browser behavior with floating labels : placeholder; } get type() { return this.el?.nativeElement?.type; } set type(value) { if (this.el?.nativeElement) { this.el.nativeElement.type = value; } } get tagName() { return this.el?.nativeElement?.tagName; } get element() { return this.el?.nativeElement; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: FormFieldDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.13", type: FormFieldDirective, isStandalone: true, selector: "input[njFormField], textarea[njFormField], select[njFormField], nj-select[njFormField], div[njFormField]", host: { properties: { "class": "this.class" } }, exportAs: ["njFormField"], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: FormFieldDirective, decorators: [{ type: Directive, args: [{ selector: 'input[njFormField], textarea[njFormField], select[njFormField], nj-select[njFormField], div[njFormField]', exportAs: 'njFormField', standalone: true }] }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { class: [{ type: HostBinding, args: ['class'] }] } }); class IconButtonIconDirective { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: IconButtonIconDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.13", type: IconButtonIconDirective, isStandalone: true, selector: "[njIconButtonIcon]", host: { classAttribute: "nj-icon-btn__icon" }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: IconButtonIconDirective, decorators: [{ type: Directive, args: [{ selector: '[njIconButtonIcon]', standalone: true, host: { class: 'nj-icon-btn__icon' } }] }] }); const rootClassName = 'nj-icon-btn'; class IconButtonComponent { constructor() { /** * Whether button has custom icon */ this.hasCustomIcon = false; } ngAfterContentInit() { if (this.template?.selector === 'icon') { this.iconTemplateRef = this.template.templateRef; } } get classes() { const classes = [rootClassName]; if (this.variant) { classes.push(`${rootClassName}--${this.variant}`); } const scale = this.scale ?? this.size; if (scale) { classes.push(`${rootClassName}--${scale}`); } return classes; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: IconButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.13", type: IconButtonComponent, isStandalone: true, selector: "button[nj-icon-button]", inputs: { variant: "variant", size: "size", scale: "scale", hasCustomIcon: "hasCustomIcon", icon: "icon", altLabel: "altLabel" }, host: { properties: { "class": "classes" } }, queries: [{ propertyName: "template", first: true, predicate: EngieTemplateDirective, descendants: true }], ngImport: i0, template: "@if (altLabel) {\n <span class=\"nj-sr-only\">{{ altLabel }}</span>\n}\n@if (icon) {\n <nj-icon njIconButtonIcon [name]=\"icon\"></nj-icon>\n} @else if (iconTemplateRef) {\n <ng-container [ngTemplateOutlet]=\"iconTemplateRef\"></ng-container>\n}\n", dependencies: [{ kind: "component", type: IconComponent, selector: "nj-icon", inputs: ["name", "scale", "variant", "iconStyle", "aria-label"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: IconButtonIconDirective, selector: "[njIconButtonIcon]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: IconButtonComponent, decorators: [{ type: Component, args: [{ selector: 'button[nj-icon-button]', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [IconComponent, CommonModule, IconButtonIconDirective], host: { '[class]': 'classes' }, template: "@if (altLabel) {\n <span class=\"nj-sr-only\">{{ altLabel }}</span>\n}\n@if (icon) {\n <nj-icon njIconButtonIcon [name]=\"icon\"></nj-icon>\n} @else if (iconTemplateRef) {\n <ng-container [ngTemplateOutlet]=\"iconTemplateRef\"></ng-container>\n}\n" }] }], propDecorators: { variant: [{ type: Input }], size: [{ type: Input }], scale: [{ type: Input }], hasCustomIcon: [{ type: Input }], icon: [{ type: Input }], altLabel: [{ type: Input }], template: [{ type: ContentChild, args: [EngieTemplateDirective] }] } }); class FormItemComponent { constructor() { this.destroyRef = inject(DestroyRef); this.formItemClassName = 'nj-form-item'; /** * @ignore */ this.isVisible = false; /** * @ignore */ this.passwordNotice = ''; /** * @ignore */ this.passwordButtonLabel = ''; /** * @ignore */ this.isMultiline = false; /** * Form item size * * @deprecated Use `scale` instead. This property will be removed in future releases. */ this.size = 'medium'; /** * Whether the form-item label is floating */ this.isFloatingLabel = true; /** * Whether the form-item's icon (or custom icon) is clickable */ this.isIconClickable = true; /** * Additional form-item css classes */ this.additionalClass = ''; /** * Outputs icon click */ this.iconClick = new EventEmitter(); /** * Outputs icon keydown */ this.iconKeydown = new EventEmitter(); /** * Outputs icon click */ this.wrapperClick = new EventEmitter(); /** * Outputs clear icon click */ this.clearIconClick = new EventEmitter(); this.formField = contentChild(FormFieldDirective, ...(ngDevMode ? [{ debugName: "formField" }] : [])); this.formFieldNgModel = contentChild(FormFieldDirective, ...(ngDevMode ? [{ debugName: "formFieldNgModel", read: NgModel }] : [{ read: NgModel }])); this.formFieldValue = signal('', ...(ngDevMode ? [{ debugName: "formFieldValue" }] : [])); this.hasValue = computed(() => !!this.formFieldValue(), ...(ngDevMode ? [{ debugName: "hasValue" }] : [])); this.cleanInputListener = null; this.formFieldValueChangeEffect = effect(() => { const value = this.formFieldValue(); const formField = this.formField(); if (formField?.element && formField.element.value !== value) { formField.element.value = value; } }, ...(ngDevMode ? [{ debugName: "formFieldValueChangeEffect" }] : [])); this.handleFormFieldInputEffect = effect(() => { this.cleanInputListener?.(); const input = this.formField()?.element; if (!input) { return; } this.formFieldValue.set(input.value); const onInput = () => { this.formFieldValue.set(input.value); }; //Fixme: Necessary for clearable to works with autocomplete. // Blocking for FLuid 6 release, will be reworked with form-item component redesign this.formFieldNgModel()?.control.registerOnChange(onInput.bind(this)); input.addEventListener('input', onInput); this.cleanInputListener = () => { input.removeEventListener('input', onInput); this.cleanInputListener = null; }; this.destroyRef.onDestroy(() => this.cleanInputListener?.()); }, ...(ngDevMode ? [{ debugName: "handleFormFieldInputEffect" }] : [])); } /** * Whether form-item is in success state */ set hasSuccess(value) { this._hasSuccess = value; this.setAriaAttributes(); } get hasSuccess() { return !!this._hasSuccess; } /** * Whether form-item is in error state */ set hasError(value) { this._hasError = value; this.setAriaAttributes(); } get hasError() { return !!this._hasError; } /** * Whether the form-item has a hint substring */ set hasHint(value) { this._hasHint = value; this.setAriaAttributes(); } get hasHint() { return !!this._hasHint; } ngAfterContentInit() { const tagName = this.formField()?.tagName?.toLowerCase(); this.isPassword = this.formField()?.type === 'password'; this.isMultiline = tagName === 'textarea'; this.passwordButtonLabel = this.passwordButtonLabelShow ?? ''; this.setAriaAttributes(); if (this.isRequired) { this.formField()?.element.setAttribute('required', 'required'); } } /** * @ignore */ iconClickHandler(event) { if (!this.isIconClickable) { return; } this.iconClick.emit(event); } /** * @ignore */ iconKeydownHandler(event) { event?.preventDefault(); if (!this.isIconClickable) { return; } this.iconKeydown.emit(event); } /** * @ignore */ toggleVisibility() { const formField = this.formField(); if (this.isVisible) { if (formField) { formField.type = 'password'; } this.passwordNotice = this.passwordNoticeIsHidden ?? ''; this.passwordButtonLabel = this.passwordButtonLabelShow ?? ''; } else { if (formField) { formField.type = 'text'; } this.passwordNotice = this.passwordNoticeIsVisible ?? ''; this.passwordButtonLabel = this.passwordButtonLabelHide ?? ''; } this.isVisible = !this.isVisible; } /** * @ignore */ getSubscriptId() { return `${this.inputId}-subscript`; } /** * @ignore */ setAriaAttributes() { const formField = this.formField(); if (formField?.element) { if (this.hasError) { formField.element.setAttribute('aria-invalid', 'true'); } if (this.hasError || this.hasSuccess || this.hasHint) { formField.element.setAttribute('aria-describedby', this.getSubscriptId()); } } } /** * @ignore */ isCustomSelect() { const type = this.formField()?.type; return !!this.isSelect && type === 'text'; } /** * @ignore */ getFormItemSizeClass() { let sizeModifier; switch (this.size) { case 'small': sizeModifier = 'sm'; break; case 'large': sizeModifier = 'lg'; break; case 'xlarge': sizeModifier = 'xl'; break; default: break; } const scale = this.scale ?? sizeModifier; return scale ? `${this.formItemClassName}--${scale}` : ''; } clearInput(event) { const formField = this.formField(); if (formField?.element) { this.formFieldValue.set(''); } this.clearIconClick.emit(event); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: FormItemComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.13", type: FormItemComponent, isStandalone: true, selector: "nj-form-item", inputs: { inputId: "inputId", size: "size", scale: "scale", isFloatingLabel: "isFloatingLabel", isDisabled: "isDisabled", isRequired: "isRequired", clearable: "clearable", hasSuccess: "hasSuccess", hasError: "hasError", hasHint: "hasHint", hasCustomIcon: "hasCustomIcon", isIconClickable: "isIconClickable", iconName: "iconName", additionalClass: "additionalClass", passwordButtonLabelShow: "passwordButtonLabelShow", passwordButtonLabelHide: "passwordButtonLabelHide", passwordNoticeIsVisible: "passwordNoticeIsVisible", passwordNoticeIsHidden: "passwordNoticeIsHidden", isSelect: "isSelect" }, outputs: { iconClick: "iconClick", iconKeydown: "iconKeydown", wrapperClick: "wrapperClick", clearIconClick: "clearIconClick" }, queries: [{ propertyName: "formField", first: true, predicate: FormFieldDirective, descendants: true, isSignal: true }, { propertyName: "formFieldNgModel", first: true, predicate: FormFieldDirective, descendants: true, read: NgModel, isSignal: true }], ngImport: i0, template: "<div\n class=\"nj-form-item\"\n [class.nj-form-item--static]=\"!isFloatingLabel\"\n [class.nj-form-item--disabled]=\"isDisabled\"\n [class.nj-form-item--error]=\"hasError\"\n [class.nj-form-item--success]=\"hasSuccess\"\n [class.nj-form-item--password]=\"isPassword\"\n [class.nj-form-item--select]=\"isSelect\"\n [class.nj-form-item--visible]=\"isVisible\"\n [class.nj-form-item--textarea]=\"isMultiline\"\n [ngClass]=\"[getFormItemSizeClass(), additionalClass]\"\n>\n <div class=\"nj-form-item__field-wrapper\" (click)=\"wrapperClick.emit($event)\">\n <ng-content select=\"[njFormField]\"></ng-content>\n <label class=\"nj-form-item__label\" [attr.for]=\"inputId\" [attr.aria-hidden]=\"isCustomSelect() ? 'true' : null\">\n <ng-content select=\"[njFormLabel]\"></ng-content>\n @if (isRequired) {\n <span class=\"nj-form-item__required-asterisk\">*</span>\n }\n </label>\n <ng-content select=\"[njFormAdditionalContent]\"></ng-content>\n @let hasIcon =\n isPassword || (!isMultiline && (iconName || hasCustomIcon)) || (clearable && hasValue() && !isDisabled);\n @if (hasIcon) {\n <div class=\"nj-form-item__trailing\">\n @if (clearable && hasValue() && !isDisabled) {\n <button\n nj-icon-button\n class=\"nj-form-item__clear-button\"\n scale=\"sm\"\n variant=\"tertiary\"\n [altLabel]=\"passwordButtonLabel\"\n (click)=\"clearInput($event)\"\n icon=\"cancel\"\n [attr.aria-pressed]=\"isVisible\"\n ></button>\n }\n @if (isPassword) {\n <button\n nj-icon-button\n class=\"nj-form-item__password-button\"\n scale=\"sm\"\n variant=\"tertiary\"\n [altLabel]=\"passwordButtonLabel\"\n [icon]=\"iconName || 'visibility'\"\n (click)=\"toggleVisibility()\"\n [attr.aria-pressed]=\"isVisible\"\n ></button>\n <p class=\"nj-sr-only\" aria-live=\"polite\" aria-atomic=\"true\">{{ passwordNotice }}</p>\n } @else if (!isMultiline && !hasCustomIcon && iconName) {\n <nj-icon\n class=\"nj-form-item__icon\"\n [name]=\"iconName\"\n (click)=\"iconClickHandler($event)\"\n (keydown)=\"iconKeydownHandler($event)\"\n >\n </nj-icon>\n } @else if (!isMultiline && hasCustomIcon) {\n <div\n class=\"nj-form-item__icon\"\n [attr.tabindex]=\"isIconClickable ? 0 : null\"\n (click)=\"iconClickHandler($event)\"\n (keydown)=\"iconKeydownHandler($event)\"\n >\n <ng-content select=\"[njFormCustomIcon]\"></ng-content>\n </div>\n }\n </div>\n }\n </div>\n @if (hasError || hasSuccess || hasHint) {\n <div class=\"nj-form-item__subscript\" [attr.id]=\"getSubscriptId()\">\n @if (hasError) {\n <nj-icon class=\"nj-form-item__subscript-icon\" name=\"warning\"></nj-icon>\n } @else if (hasSuccess) {\n <nj-icon class=\"nj-form-item__subscript-icon\" name=\"check\"></nj-icon>\n }\n <ng-content select=\"[njFormSubscript]\"></ng-content>\n </div>\n }\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: IconComponent, selector: "nj-icon", inputs: ["name", "scale", "variant", "iconStyle", "aria-label"] }, { kind: "component", type: IconButtonComponent, selector: "button[nj-icon-button]", inputs: ["variant", "size", "scale", "hasCustomIcon", "icon", "altLabel"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.13", ngImport: i0, type: FormItemComponent, decorators: [{ type: Component, args: [{ selector: 'nj-form-item', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [IconComponent, IconButtonComponent, CommonModule], template: "<div\n class=\"nj-form-item\"\n [class.nj-form-item--static]=\"!isFloatingLabel\"\n [class.nj-form-item--disabled]=\"isDisabled\"\n [class.nj-form-item--error]=\"hasError\"\n [class.nj-form-item--success]=\"hasSuccess\"\n [class.nj-form-item--password]=\"isPassword\"\n [class.nj-form-item--select]=\"isSelect\"\n [class.nj-form-item--visible]=\"isVisible\"\n [class.nj-form-item--textarea]=\"isMultiline\"\n [ngClass]=\"[getFormItemSizeClass(), additionalClass]\"\n>\n <div class=\"nj-form-item__field-wrapper\" (click)=\"wrapperClick.emit($event)\">\n <ng-content select=\"[njFormField]\"></ng-content>\n <label class=\"nj-form-item__label\" [attr.for]=\"inputId\" [attr.aria-hidden]=\"isCustomSelect() ? 'true' : null\">\n <ng-content select=\"[njFormLabel]\"></ng-content>\n @if (isRequired) {\n <span class=\"nj-form-item__required-asterisk\">*</span>\n }\n </label>\n <ng-content select=\"[njFormAdditionalContent]\"></ng-content>\n @let hasIcon =\n isPassword || (!isMultiline && (iconName || hasCustomIcon)) || (clearable && hasValue() && !isDisabled);\n @if (hasIcon) {\n <div class=\"nj-form-item__trailing\">\n @if (clearable && hasValue() && !isDisabled) {\n <button\n nj-icon-button\n class=\"nj-form-item__clear-button\"\n scale=\"sm\"\n variant=\"tertiary\"\n [altLabel]=\"passwordButtonLabel\"\n (click)=\"clearInput($event)\"\n icon=\"cancel\"\n [attr.aria-pressed]=\"isVisible\"\n ></button>\n }\n @if (isPassword) {\n <button\n nj-icon-button\n class=\"nj-form-item__password-button\"\n scale=\"sm\"\n variant=\"tertiary\"\n [altLabel]=\"passwordButtonLabel\"\n [icon]=\"iconName || 'visibility'\"\n (click)=\"toggleVisibility()\"\n [attr.aria-pressed]=\"isVisible\"\n ></button>\n <p class=\"nj-sr-only\" aria-live=\"polite\" aria-atomic=\"true\">{{ passwordNotice }}</p>\n } @else if (!isMultiline && !hasCustomIcon && iconName) {\n <nj-icon\n class=\"nj-form-item__icon\"\n [name]=\"iconName\"\n (click)=\"iconClickHandler($event)\"\n (keydown)=\"iconKeydownHandler($event)\"\n >\n </nj-icon>\n } @else if (!isMultiline && hasCustomIcon) {\n <div\n class=\"nj-form-item__icon\"\n [attr.tabindex]=\"isIconClickable ? 0 : null\"\n (click)=\"iconClickHandler($event)\"\n (keydown)=\"iconKeydownHandler($event)\"\n >\n <ng-content select=\"[njFormCustomIcon]\"></ng-content>\n </div>\n }\n </div>\n }\n </div>\n @if (hasError || hasSuccess || hasHint) {\n <div class=\"nj-form-item__subscript\" [attr.id]=\"getSubscriptId()\">\n @if (hasError) {\n <nj-icon class=\"nj-form-item__subscript-icon\" name=\"warning\"></nj-icon>\n } @else if (hasSuccess) {\n <nj-icon class=\"nj-form-item__subscript-icon\" name=\"check\"></nj-icon>\n }\n <ng-content select=\"[njFormSubscript]\"></ng-content>\n </div>\n }\n</div>\n", styles: [":host{display:block}\n"] }] }], propDecorators: { inputId: [{ type: Input }], size: [{ type: Input }], scale: [{ type: Input }], isFloatingLabel: [{ type: Input }], isDisabled: [{ type: Input }], isRequired: [{ type: Input }], clearable: [{ type: Input }], hasSuccess: [{ type: Input }], hasError: [{ type: Input }], hasHint: [{ type: Input }], hasCustomIcon: [{ type: Input }], isIconClickable: [{ type: Input }], iconName: [{ type: Input }], additionalClass: [{ type: Input }], passwordButtonLabelShow: [{ type: Input }], passwordButtonLabelHide: [{ type: Input }], passwordNoticeIsVisible: [{ type: Input }], passwordNoticeIsHidden: [{ type: Input }], isSelect: [{ type: Input }], iconClick: [{ type: Output }], iconKeydown: [{ type: Output }], wrapperClick: [{ type: Output }], clearIconClick: [{ type: Output }], formField: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FormFieldDirective), { isSignal: true }] }], formFieldNgModel: [{ type: i0.ContentChild, args: [i0.forwardRef(() => FormFieldDirective), { ...{ read: NgModel }, isSignal: true }] }] } }); class HighlightDirective { constructor(el) { this.el = el; /** * Whether to escape accents or no */ this.escapeAccents = true; /** * Whether to take into account case or no */ this.caseSensitive = false; this.OPENING_TAG = '<mark class="nj-highlight">'; this.CLOSING_TAG = '</mark>'; } ngOnChanges(changes) { this.highlightText(); } highlightText() { if (Utils.isUndefinedOrNull(this.content) || Utils.isUndefinedOrNull(this.el?.nativeElement)) { return; } const regexFlags = this.caseSensitive ? 'g' : 'gi'; let innerHtml; if (Utils.isUndefinedOrNull(this.textToHighlight)) { innerHtml = this.content; } else { if (this.escapeAccents) { const escapedText = Utils.escapeRegExp(Utils.normalizeString(this.textToHighlight)); const regExp = new RegExp(escapedText, regexFlags); const matches = Utils.normalizeString(this.content).matchAll(regExp); let finalText = this.content; let buffer = 0; if (!Utils.isUndefinedOrNull(matches)) { for (const match of matches) { const updatedIndex = buffer + (match.index ?? 0); const textBeforeOccurrence = finalText.slice(0, updatedIndex); const occurrence = finalText.slice(updatedIndex, updatedIndex + this.textToHighlight.length); const textAfterOccurrence = finalText.slice(updatedIndex + this.textToHighlight.length, finalText.length); finalText = `${textBeforeOccurrence}${this.OPENING_TAG}${occurrence}${this.CLOSING_TAG}${textAfterOccurrence}`; buffer = buffer + this.OPENING_TAG.length + this.CLOSING_TAG.length; } } innerHtml = finalText;