@devjuliovilla/jv-ui 1.7.1 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -2
- package/fesm2022/devjuliovilla-jv-ui.mjs +2520 -876
- package/fesm2022/devjuliovilla-jv-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/styles/jv-theme.css +135 -135
- package/types/devjuliovilla-jv-ui.d.ts +309 -24
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { input, computed, Component, forwardRef, inject, output,
|
|
2
|
+
import { input, computed, Component, forwardRef, inject, output, Directive, Injectable, signal, InjectionToken, makeEnvironmentProviders, ENVIRONMENT_INITIALIZER, effect, contentChildren, HostListener, viewChild, viewChildren, afterNextRender, Renderer2, ElementRef } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/forms';
|
|
4
4
|
import { NG_VALUE_ACCESSOR, FormBuilder, Validators, ReactiveFormsModule, FormsModule } from '@angular/forms';
|
|
5
|
-
import { CommonModule, DOCUMENT } from '@angular/common';
|
|
5
|
+
import { CommonModule, DOCUMENT, NgTemplateOutlet } from '@angular/common';
|
|
6
6
|
import { Router, RouterLink } from '@angular/router';
|
|
7
7
|
|
|
8
8
|
// This file is auto-generated by tools/generate-icons.mjs
|
|
@@ -18658,116 +18658,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
18658
18658
|
`, styles: [".jv-divider{width:100%;height:1px;background:var(--jv-color-border)}.jv-divider--vertical{width:1px;height:100%;min-height:1.5rem}\n"] }]
|
|
18659
18659
|
}], propDecorators: { vertical: [{ type: i0.Input, args: [{ isSignal: true, alias: "vertical", required: false }] }] } });
|
|
18660
18660
|
|
|
18661
|
-
class
|
|
18662
|
-
|
|
18663
|
-
|
|
18664
|
-
|
|
18665
|
-
|
|
18666
|
-
}
|
|
18667
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvBadgeComponent, decorators: [{
|
|
18668
|
-
type: Component,
|
|
18669
|
-
args: [{ selector: 'jv-badge', standalone: true, template: `<span class="jv-badge" [class]="badgeClass()"><ng-content></ng-content></span>`, styles: [".jv-badge{display:inline-flex;align-items:center;justify-content:center;min-height:1.75rem;padding:0 var(--jv-spacing-sm);border-radius:999px;font-size:.8rem;font-weight:700;line-height:1;white-space:nowrap}.jv-badge--primary{background:color-mix(in srgb,var(--jv-color-primary) 14%,var(--jv-color-surface));color:var(--jv-color-primary)}.jv-badge--secondary,.jv-badge--neutral{background:var(--jv-color-surface-muted);color:var(--jv-color-foreground)}.jv-badge--success{background:color-mix(in srgb,var(--jv-color-success) 16%,var(--jv-color-surface));color:var(--jv-color-success)}.jv-badge--warning{background:color-mix(in srgb,var(--jv-color-warning) 20%,var(--jv-color-surface));color:#8a4b00}.jv-badge--danger{background:color-mix(in srgb,var(--jv-color-danger) 16%,var(--jv-color-surface));color:var(--jv-color-danger)}.jv-badge--info{background:color-mix(in srgb,var(--jv-color-info) 16%,var(--jv-color-surface));color:var(--jv-color-info)}\n"] }]
|
|
18670
|
-
}], propDecorators: { tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }] } });
|
|
18671
|
-
|
|
18672
|
-
class JvLoaderService {
|
|
18673
|
-
counter = signal(0, ...(ngDevMode ? [{ debugName: "counter" }] : /* istanbul ignore next */ []));
|
|
18674
|
-
visible = signal(false, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
18675
|
-
message = signal('Loading', ...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
18676
|
-
delayMs = 300;
|
|
18677
|
-
showTimeout = null;
|
|
18678
|
-
activeCount = this.counter.asReadonly();
|
|
18679
|
-
isVisible = this.visible.asReadonly();
|
|
18680
|
-
liveMessage = this.message.asReadonly();
|
|
18681
|
-
show(message = 'Loading') {
|
|
18682
|
-
this.message.set(message);
|
|
18683
|
-
this.counter.update((count) => count + 1);
|
|
18684
|
-
if (this.counter() === 1) {
|
|
18685
|
-
this.scheduleVisibility();
|
|
18686
|
-
}
|
|
18687
|
-
}
|
|
18688
|
-
hide() {
|
|
18689
|
-
this.counter.update((count) => Math.max(0, count - 1));
|
|
18690
|
-
if (this.counter() === 0) {
|
|
18691
|
-
this.clearTimer();
|
|
18692
|
-
this.visible.set(false);
|
|
18693
|
-
}
|
|
18694
|
-
}
|
|
18695
|
-
scheduleVisibility() {
|
|
18696
|
-
this.clearTimer();
|
|
18697
|
-
this.showTimeout = setTimeout(() => {
|
|
18698
|
-
if (this.counter() > 0) {
|
|
18699
|
-
this.visible.set(true);
|
|
18700
|
-
}
|
|
18701
|
-
this.showTimeout = null;
|
|
18702
|
-
}, this.delayMs);
|
|
18703
|
-
}
|
|
18704
|
-
clearTimer() {
|
|
18705
|
-
if (this.showTimeout) {
|
|
18706
|
-
clearTimeout(this.showTimeout);
|
|
18707
|
-
this.showTimeout = null;
|
|
18708
|
-
}
|
|
18709
|
-
}
|
|
18710
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvLoaderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
18711
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvLoaderService, providedIn: 'root' });
|
|
18712
|
-
}
|
|
18713
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvLoaderService, decorators: [{
|
|
18714
|
-
type: Injectable,
|
|
18715
|
-
args: [{ providedIn: 'root' }]
|
|
18716
|
-
}] });
|
|
18717
|
-
|
|
18718
|
-
class JvLoaderComponent {
|
|
18719
|
-
document = inject(DOCUMENT);
|
|
18720
|
-
loaderService = inject(JvLoaderService);
|
|
18721
|
-
constructor() {
|
|
18722
|
-
effect(() => {
|
|
18723
|
-
const locked = this.loaderService.isVisible();
|
|
18724
|
-
const body = this.document.body;
|
|
18725
|
-
const root = this.document.documentElement;
|
|
18726
|
-
body.style.overflow = locked ? 'hidden' : '';
|
|
18727
|
-
root.style.overflow = locked ? 'hidden' : '';
|
|
18728
|
-
});
|
|
18729
|
-
}
|
|
18730
|
-
handleWheel(event) {
|
|
18731
|
-
if (this.loaderService.isVisible()) {
|
|
18732
|
-
event.preventDefault();
|
|
18733
|
-
}
|
|
18734
|
-
}
|
|
18735
|
-
handleTouchMove(event) {
|
|
18736
|
-
if (this.loaderService.isVisible()) {
|
|
18737
|
-
event.preventDefault();
|
|
18738
|
-
}
|
|
18661
|
+
class JvAccordionPanelDirective {
|
|
18662
|
+
templateRef;
|
|
18663
|
+
id = input.required({ ...(ngDevMode ? { debugName: "id" } : /* istanbul ignore next */ {}), alias: 'jvAccordionPanel' });
|
|
18664
|
+
constructor(templateRef) {
|
|
18665
|
+
this.templateRef = templateRef;
|
|
18739
18666
|
}
|
|
18740
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type:
|
|
18741
|
-
static
|
|
18742
|
-
@if (loaderService.isVisible()) {
|
|
18743
|
-
<div class="jv-loader-backdrop" aria-live="polite" aria-atomic="true">
|
|
18744
|
-
<div class="jv-loader-panel" role="status">
|
|
18745
|
-
<span class="spinner" aria-hidden="true"></span>
|
|
18746
|
-
<span>{{ loaderService.liveMessage() }}</span>
|
|
18747
|
-
</div>
|
|
18748
|
-
</div>
|
|
18749
|
-
}
|
|
18750
|
-
`, isInline: true, styles: [".jv-loader-backdrop{position:fixed;inset:0;z-index:1050;display:grid;place-items:center;background:#0f172a2e;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.jv-loader-panel{display:inline-flex;align-items:center;gap:var(--jv-spacing-sm);padding:var(--jv-spacing-md) var(--jv-spacing-lg);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-lg);background:var(--jv-color-surface);box-shadow:var(--jv-shadow-lg);color:var(--jv-color-foreground)}.spinner{width:1rem;height:1rem;border:2px solid currentColor;border-right-color:transparent;border-radius:999px;animation:jv-loader-spin .8s linear infinite}@keyframes jv-loader-spin{to{transform:rotate(360deg)}}\n"] });
|
|
18667
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvAccordionPanelDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
18668
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.17", type: JvAccordionPanelDirective, isStandalone: true, selector: "ng-template[jvAccordionPanel]", inputs: { id: { classPropertyName: "id", publicName: "jvAccordionPanel", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
|
|
18751
18669
|
}
|
|
18752
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type:
|
|
18753
|
-
type:
|
|
18754
|
-
args: [{
|
|
18755
|
-
|
|
18756
|
-
|
|
18757
|
-
|
|
18758
|
-
|
|
18759
|
-
<span>{{ loaderService.liveMessage() }}</span>
|
|
18760
|
-
</div>
|
|
18761
|
-
</div>
|
|
18762
|
-
}
|
|
18763
|
-
`, styles: [".jv-loader-backdrop{position:fixed;inset:0;z-index:1050;display:grid;place-items:center;background:#0f172a2e;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.jv-loader-panel{display:inline-flex;align-items:center;gap:var(--jv-spacing-sm);padding:var(--jv-spacing-md) var(--jv-spacing-lg);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-lg);background:var(--jv-color-surface);box-shadow:var(--jv-shadow-lg);color:var(--jv-color-foreground)}.spinner{width:1rem;height:1rem;border:2px solid currentColor;border-right-color:transparent;border-radius:999px;animation:jv-loader-spin .8s linear infinite}@keyframes jv-loader-spin{to{transform:rotate(360deg)}}\n"] }]
|
|
18764
|
-
}], ctorParameters: () => [], propDecorators: { handleWheel: [{
|
|
18765
|
-
type: HostListener,
|
|
18766
|
-
args: ['document:wheel', ['$event']]
|
|
18767
|
-
}], handleTouchMove: [{
|
|
18768
|
-
type: HostListener,
|
|
18769
|
-
args: ['document:touchmove', ['$event']]
|
|
18770
|
-
}] } });
|
|
18670
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvAccordionPanelDirective, decorators: [{
|
|
18671
|
+
type: Directive,
|
|
18672
|
+
args: [{
|
|
18673
|
+
selector: 'ng-template[jvAccordionPanel]',
|
|
18674
|
+
standalone: true,
|
|
18675
|
+
}]
|
|
18676
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "jvAccordionPanel", required: true }] }] } });
|
|
18771
18677
|
|
|
18772
18678
|
class JvAnnouncementService {
|
|
18773
18679
|
document = inject(DOCUMENT);
|
|
@@ -18885,6 +18791,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
18885
18791
|
args: [{ providedIn: 'root' }]
|
|
18886
18792
|
}] });
|
|
18887
18793
|
|
|
18794
|
+
const JV_UI_CONFIG = new InjectionToken('JV_UI_CONFIG');
|
|
18795
|
+
const JV_UI_CONFIG_DEFAULTS = new InjectionToken('JV_UI_CONFIG_DEFAULTS', {
|
|
18796
|
+
providedIn: 'root',
|
|
18797
|
+
factory: () => JV_UI_DEFAULT_CONFIG,
|
|
18798
|
+
});
|
|
18799
|
+
function provideJvUi(config = {}) {
|
|
18800
|
+
const configProvider = {
|
|
18801
|
+
provide: JV_UI_CONFIG,
|
|
18802
|
+
useValue: config,
|
|
18803
|
+
multi: true,
|
|
18804
|
+
};
|
|
18805
|
+
return makeEnvironmentProviders([
|
|
18806
|
+
configProvider,
|
|
18807
|
+
{
|
|
18808
|
+
provide: ENVIRONMENT_INITIALIZER,
|
|
18809
|
+
multi: true,
|
|
18810
|
+
useValue: () => {
|
|
18811
|
+
inject(JvThemeService).initialize();
|
|
18812
|
+
inject(JvTranslationService).initialize();
|
|
18813
|
+
},
|
|
18814
|
+
},
|
|
18815
|
+
]);
|
|
18816
|
+
}
|
|
18817
|
+
|
|
18818
|
+
class JvUiConfigService {
|
|
18819
|
+
defaults = inject(JV_UI_CONFIG_DEFAULTS);
|
|
18820
|
+
configLayers = inject(JV_UI_CONFIG, { optional: true }) ?? [];
|
|
18821
|
+
get snapshot() {
|
|
18822
|
+
return this.configLayers.reduce((merged, layer) => ({ ...merged, ...layer }), { ...this.defaults });
|
|
18823
|
+
}
|
|
18824
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvUiConfigService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
18825
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvUiConfigService, providedIn: 'root' });
|
|
18826
|
+
}
|
|
18827
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvUiConfigService, decorators: [{
|
|
18828
|
+
type: Injectable,
|
|
18829
|
+
args: [{ providedIn: 'root' }]
|
|
18830
|
+
}] });
|
|
18831
|
+
|
|
18888
18832
|
const ES = {
|
|
18889
18833
|
'list.emptyMessage': 'No hay elementos',
|
|
18890
18834
|
'grid.emptyMessage': 'No hay registros',
|
|
@@ -18919,6 +18863,26 @@ const ES = {
|
|
|
18919
18863
|
'pagination.nextPage': 'Página siguiente',
|
|
18920
18864
|
'pagination.lastPage': 'Última página',
|
|
18921
18865
|
'pagination.itemsPerPage': 'Registros por página',
|
|
18866
|
+
'datePicker.placeholder': 'Seleccione una fecha',
|
|
18867
|
+
'datePicker.dialogTitle': 'Seleccionar fecha',
|
|
18868
|
+
'datePicker.clear': 'Limpiar fecha',
|
|
18869
|
+
'datePicker.close': 'Cerrar',
|
|
18870
|
+
'datePicker.prevMonth': 'Mes anterior',
|
|
18871
|
+
'datePicker.nextMonth': 'Mes siguiente',
|
|
18872
|
+
'datePicker.selectionCleared': 'Seleccion de fecha limpiada',
|
|
18873
|
+
'modalSelector.placeholder': 'Seleccione una opcion',
|
|
18874
|
+
'modalSelector.searchPlaceholder': 'Buscar',
|
|
18875
|
+
'modalSelector.emptyMessage': 'No se encontraron resultados',
|
|
18876
|
+
'modalSelector.clear': 'Limpiar seleccion',
|
|
18877
|
+
'modalSelector.close': 'Cerrar',
|
|
18878
|
+
'modalSelector.results': '{count} resultados',
|
|
18879
|
+
'modalSelector.selected': '{label} seleccionado',
|
|
18880
|
+
'modalSelector.selectionCleared': 'Seleccion limpiada',
|
|
18881
|
+
'dialog.confirmTitle': 'Confirmar',
|
|
18882
|
+
'dialog.confirm': 'Aceptar',
|
|
18883
|
+
'dialog.cancel': 'Cancelar',
|
|
18884
|
+
'common.expanded': 'Expandido',
|
|
18885
|
+
'common.collapsed': 'Colapsado',
|
|
18922
18886
|
};
|
|
18923
18887
|
|
|
18924
18888
|
const EN = {
|
|
@@ -18955,6 +18919,26 @@ const EN = {
|
|
|
18955
18919
|
'pagination.nextPage': 'Next page',
|
|
18956
18920
|
'pagination.lastPage': 'Last page',
|
|
18957
18921
|
'pagination.itemsPerPage': 'Items per page',
|
|
18922
|
+
'datePicker.placeholder': 'Select a date',
|
|
18923
|
+
'datePicker.dialogTitle': 'Select date',
|
|
18924
|
+
'datePicker.clear': 'Clear date',
|
|
18925
|
+
'datePicker.close': 'Close',
|
|
18926
|
+
'datePicker.prevMonth': 'Previous month',
|
|
18927
|
+
'datePicker.nextMonth': 'Next month',
|
|
18928
|
+
'datePicker.selectionCleared': 'Date selection cleared',
|
|
18929
|
+
'modalSelector.placeholder': 'Select an option',
|
|
18930
|
+
'modalSelector.searchPlaceholder': 'Search',
|
|
18931
|
+
'modalSelector.emptyMessage': 'No results found',
|
|
18932
|
+
'modalSelector.clear': 'Clear selection',
|
|
18933
|
+
'modalSelector.close': 'Close',
|
|
18934
|
+
'modalSelector.results': '{count} results',
|
|
18935
|
+
'modalSelector.selected': '{label} selected',
|
|
18936
|
+
'modalSelector.selectionCleared': 'Selection cleared',
|
|
18937
|
+
'dialog.confirmTitle': 'Confirm',
|
|
18938
|
+
'dialog.confirm': 'Confirm',
|
|
18939
|
+
'dialog.cancel': 'Cancel',
|
|
18940
|
+
'common.expanded': 'Expanded',
|
|
18941
|
+
'common.collapsed': 'Collapsed',
|
|
18958
18942
|
};
|
|
18959
18943
|
|
|
18960
18944
|
const JV_LOCALE_DICTIONARIES = {
|
|
@@ -18999,96 +18983,415 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
18999
18983
|
args: [{ providedIn: 'root' }]
|
|
19000
18984
|
}] });
|
|
19001
18985
|
|
|
19002
|
-
|
|
19003
|
-
|
|
19004
|
-
providedIn: 'root',
|
|
19005
|
-
factory: () => JV_UI_DEFAULT_CONFIG,
|
|
19006
|
-
});
|
|
19007
|
-
function provideJvUi(config = {}) {
|
|
19008
|
-
const configProvider = {
|
|
19009
|
-
provide: JV_UI_CONFIG,
|
|
19010
|
-
useValue: config,
|
|
19011
|
-
multi: true,
|
|
19012
|
-
};
|
|
19013
|
-
return makeEnvironmentProviders([
|
|
19014
|
-
configProvider,
|
|
19015
|
-
{
|
|
19016
|
-
provide: ENVIRONMENT_INITIALIZER,
|
|
19017
|
-
multi: true,
|
|
19018
|
-
useValue: () => {
|
|
19019
|
-
inject(JvThemeService).initialize();
|
|
19020
|
-
inject(JvTranslationService).initialize();
|
|
19021
|
-
},
|
|
19022
|
-
},
|
|
19023
|
-
]);
|
|
19024
|
-
}
|
|
19025
|
-
|
|
19026
|
-
class JvUiConfigService {
|
|
19027
|
-
defaults = inject(JV_UI_CONFIG_DEFAULTS);
|
|
19028
|
-
configLayers = inject(JV_UI_CONFIG, { optional: true }) ?? [];
|
|
19029
|
-
get snapshot() {
|
|
19030
|
-
return this.configLayers.reduce((merged, layer) => ({ ...merged, ...layer }), { ...this.defaults });
|
|
19031
|
-
}
|
|
19032
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvUiConfigService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
19033
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvUiConfigService, providedIn: 'root' });
|
|
19034
|
-
}
|
|
19035
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvUiConfigService, decorators: [{
|
|
19036
|
-
type: Injectable,
|
|
19037
|
-
args: [{ providedIn: 'root' }]
|
|
19038
|
-
}] });
|
|
19039
|
-
|
|
19040
|
-
class JvToastService {
|
|
18986
|
+
let collapsiblePanelSequence = 0;
|
|
18987
|
+
class JvCollapsiblePanelComponent {
|
|
19041
18988
|
announcementService = inject(JvAnnouncementService);
|
|
19042
|
-
|
|
19043
|
-
|
|
19044
|
-
|
|
19045
|
-
|
|
19046
|
-
|
|
19047
|
-
|
|
19048
|
-
|
|
19049
|
-
|
|
19050
|
-
|
|
19051
|
-
|
|
19052
|
-
|
|
19053
|
-
|
|
19054
|
-
|
|
19055
|
-
|
|
19056
|
-
|
|
19057
|
-
|
|
19058
|
-
|
|
19059
|
-
|
|
19060
|
-
|
|
18989
|
+
translation = inject(JvTranslationService);
|
|
18990
|
+
internalOpen = signal(false, ...(ngDevMode ? [{ debugName: "internalOpen" }] : /* istanbul ignore next */ []));
|
|
18991
|
+
bodyVisible = signal(false, ...(ngDevMode ? [{ debugName: "bodyVisible" }] : /* istanbul ignore next */ []));
|
|
18992
|
+
title = input.required(...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
18993
|
+
subtitle = input('', ...(ngDevMode ? [{ debugName: "subtitle" }] : /* istanbul ignore next */ []));
|
|
18994
|
+
icon = input(null, ...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
18995
|
+
open = input(undefined, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
18996
|
+
defaultOpen = input(false, ...(ngDevMode ? [{ debugName: "defaultOpen" }] : /* istanbul ignore next */ []));
|
|
18997
|
+
keepMounted = input(true, ...(ngDevMode ? [{ debugName: "keepMounted" }] : /* istanbul ignore next */ []));
|
|
18998
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
18999
|
+
showIndicator = input(true, ...(ngDevMode ? [{ debugName: "showIndicator" }] : /* istanbul ignore next */ []));
|
|
19000
|
+
variant = input('bordered', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
19001
|
+
openChange = output();
|
|
19002
|
+
triggerId = `jv-collapsible-trigger-${++collapsiblePanelSequence}`;
|
|
19003
|
+
contentId = `jv-collapsible-content-${collapsiblePanelSequence}`;
|
|
19004
|
+
resolvedOpen = computed(() => this.open() ?? this.internalOpen(), ...(ngDevMode ? [{ debugName: "resolvedOpen" }] : /* istanbul ignore next */ []));
|
|
19005
|
+
panelClass = computed(() => `jv-collapsible-panel--${this.variant()}`, ...(ngDevMode ? [{ debugName: "panelClass" }] : /* istanbul ignore next */ []));
|
|
19006
|
+
shouldRenderBody = computed(() => this.keepMounted() || this.bodyVisible(), ...(ngDevMode ? [{ debugName: "shouldRenderBody" }] : /* istanbul ignore next */ []));
|
|
19007
|
+
triggerAriaLabel = computed(() => {
|
|
19008
|
+
const parts = [this.title()];
|
|
19009
|
+
if (this.subtitle()) {
|
|
19010
|
+
parts.push(this.subtitle());
|
|
19061
19011
|
}
|
|
19062
|
-
|
|
19012
|
+
parts.push(this.translation.translate(this.resolvedOpen() ? 'common.expanded' : 'common.collapsed'));
|
|
19013
|
+
return parts.join('. ');
|
|
19014
|
+
}, ...(ngDevMode ? [{ debugName: "triggerAriaLabel" }] : /* istanbul ignore next */ []));
|
|
19015
|
+
constructor() {
|
|
19016
|
+
this.internalOpen.set(this.defaultOpen());
|
|
19017
|
+
this.bodyVisible.set(this.defaultOpen());
|
|
19018
|
+
effect(() => {
|
|
19019
|
+
const open = this.resolvedOpen();
|
|
19020
|
+
const keepMounted = this.keepMounted();
|
|
19021
|
+
if (keepMounted || open) {
|
|
19022
|
+
this.bodyVisible.set(true);
|
|
19023
|
+
}
|
|
19024
|
+
});
|
|
19063
19025
|
}
|
|
19064
|
-
|
|
19065
|
-
this.
|
|
19026
|
+
toggle() {
|
|
19027
|
+
if (this.disabled()) {
|
|
19028
|
+
return;
|
|
19029
|
+
}
|
|
19030
|
+
const nextOpen = !this.resolvedOpen();
|
|
19031
|
+
if (this.open() === undefined) {
|
|
19032
|
+
this.internalOpen.set(nextOpen);
|
|
19033
|
+
}
|
|
19034
|
+
if (nextOpen) {
|
|
19035
|
+
this.bodyVisible.set(true);
|
|
19036
|
+
}
|
|
19037
|
+
this.announcementService.announce(`${this.title()}. ${this.translation.translate(nextOpen ? 'common.expanded' : 'common.collapsed')}`, 'polite');
|
|
19038
|
+
this.openChange.emit(nextOpen);
|
|
19066
19039
|
}
|
|
19067
|
-
|
|
19068
|
-
this.
|
|
19040
|
+
handleBodyTransitionEnd(event) {
|
|
19041
|
+
if (event.propertyName !== 'grid-template-rows' || this.keepMounted() || this.resolvedOpen()) {
|
|
19042
|
+
return;
|
|
19043
|
+
}
|
|
19044
|
+
this.bodyVisible.set(false);
|
|
19069
19045
|
}
|
|
19070
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type:
|
|
19071
|
-
static
|
|
19046
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvCollapsiblePanelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
19047
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvCollapsiblePanelComponent, isStandalone: true, selector: "jv-collapsible-panel", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, defaultOpen: { classPropertyName: "defaultOpen", publicName: "defaultOpen", isSignal: true, isRequired: false, transformFunction: null }, keepMounted: { classPropertyName: "keepMounted", publicName: "keepMounted", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, showIndicator: { classPropertyName: "showIndicator", publicName: "showIndicator", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openChange: "openChange" }, ngImport: i0, template: `
|
|
19048
|
+
<section class="jv-collapsible-panel" [class]="panelClass()">
|
|
19049
|
+
<button
|
|
19050
|
+
type="button"
|
|
19051
|
+
class="jv-collapsible-trigger"
|
|
19052
|
+
[id]="triggerId"
|
|
19053
|
+
[disabled]="disabled()"
|
|
19054
|
+
[attr.aria-expanded]="resolvedOpen() ? 'true' : 'false'"
|
|
19055
|
+
[attr.aria-controls]="contentId"
|
|
19056
|
+
[attr.aria-label]="triggerAriaLabel()"
|
|
19057
|
+
(click)="toggle()"
|
|
19058
|
+
>
|
|
19059
|
+
<span class="jv-collapsible-main">
|
|
19060
|
+
@if (icon()) {
|
|
19061
|
+
<jv-icon [name]="icon()!" [size]="18" />
|
|
19062
|
+
}
|
|
19063
|
+
|
|
19064
|
+
<span class="jv-collapsible-copy">
|
|
19065
|
+
<span class="jv-collapsible-title">{{ title() }}</span>
|
|
19066
|
+
@if (subtitle()) {
|
|
19067
|
+
<span class="jv-collapsible-subtitle">{{ subtitle() }}</span>
|
|
19068
|
+
}
|
|
19069
|
+
</span>
|
|
19070
|
+
</span>
|
|
19071
|
+
|
|
19072
|
+
@if (showIndicator()) {
|
|
19073
|
+
<jv-icon class="jv-collapsible-indicator" [class.jv-collapsible-indicator--open]="resolvedOpen()" name="chevron-down" [size]="18" />
|
|
19074
|
+
}
|
|
19075
|
+
</button>
|
|
19076
|
+
|
|
19077
|
+
@if (shouldRenderBody()) {
|
|
19078
|
+
<div
|
|
19079
|
+
class="jv-collapsible-body"
|
|
19080
|
+
[class.jv-collapsible-body--open]="resolvedOpen()"
|
|
19081
|
+
[id]="contentId"
|
|
19082
|
+
role="region"
|
|
19083
|
+
[attr.aria-labelledby]="triggerId"
|
|
19084
|
+
[attr.aria-hidden]="resolvedOpen() ? null : 'true'"
|
|
19085
|
+
[attr.inert]="resolvedOpen() ? null : ''"
|
|
19086
|
+
(transitionend)="handleBodyTransitionEnd($event)"
|
|
19087
|
+
>
|
|
19088
|
+
<div class="jv-collapsible-content">
|
|
19089
|
+
<ng-content />
|
|
19090
|
+
</div>
|
|
19091
|
+
</div>
|
|
19092
|
+
}
|
|
19093
|
+
</section>
|
|
19094
|
+
`, isInline: true, styles: [".jv-collapsible-panel{border-radius:var(--jv-radius-lg);background:var(--jv-color-surface)}.jv-collapsible-panel--bordered{border:1px solid var(--jv-color-border)}.jv-collapsible-panel--filled{border:1px solid transparent;background:var(--jv-color-surface-muted)}.jv-collapsible-panel--minimal{border-bottom:1px solid var(--jv-color-border);border-radius:0}.jv-collapsible-trigger{width:100%;display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-md);padding:var(--jv-spacing-md) var(--jv-spacing-lg);border:0;border-radius:inherit;background:transparent;color:var(--jv-color-foreground);text-align:left;font:inherit;cursor:pointer}.jv-collapsible-trigger:disabled{opacity:.6;cursor:not-allowed}.jv-collapsible-trigger:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:-2px}.jv-collapsible-main{min-width:0;display:inline-flex;align-items:flex-start;gap:var(--jv-spacing-sm)}.jv-collapsible-copy{min-width:0;display:grid;gap:.25rem}.jv-collapsible-title{font-weight:600}.jv-collapsible-subtitle{color:var(--jv-color-foreground-muted);font-size:.875rem}.jv-collapsible-indicator{flex-shrink:0;transition:transform .18s ease}.jv-collapsible-indicator--open{transform:rotate(180deg)}.jv-collapsible-body{display:grid;grid-template-rows:0fr;opacity:0;transition:grid-template-rows .18s ease,opacity .18s ease}.jv-collapsible-body--open{grid-template-rows:1fr;opacity:1}.jv-collapsible-content{min-height:0;overflow:hidden;padding:0 var(--jv-spacing-lg) var(--jv-spacing-lg)}\n"], dependencies: [{ kind: "component", type: JvIconComponent, selector: "jv-icon", inputs: ["name", "size", "strokeWidth", "decorative", "ariaLabel"] }] });
|
|
19072
19095
|
}
|
|
19073
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type:
|
|
19074
|
-
type:
|
|
19075
|
-
args: [{
|
|
19076
|
-
|
|
19096
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvCollapsiblePanelComponent, decorators: [{
|
|
19097
|
+
type: Component,
|
|
19098
|
+
args: [{ selector: 'jv-collapsible-panel', standalone: true, imports: [JvIconComponent], template: `
|
|
19099
|
+
<section class="jv-collapsible-panel" [class]="panelClass()">
|
|
19100
|
+
<button
|
|
19101
|
+
type="button"
|
|
19102
|
+
class="jv-collapsible-trigger"
|
|
19103
|
+
[id]="triggerId"
|
|
19104
|
+
[disabled]="disabled()"
|
|
19105
|
+
[attr.aria-expanded]="resolvedOpen() ? 'true' : 'false'"
|
|
19106
|
+
[attr.aria-controls]="contentId"
|
|
19107
|
+
[attr.aria-label]="triggerAriaLabel()"
|
|
19108
|
+
(click)="toggle()"
|
|
19109
|
+
>
|
|
19110
|
+
<span class="jv-collapsible-main">
|
|
19111
|
+
@if (icon()) {
|
|
19112
|
+
<jv-icon [name]="icon()!" [size]="18" />
|
|
19113
|
+
}
|
|
19077
19114
|
|
|
19078
|
-
class
|
|
19079
|
-
|
|
19080
|
-
|
|
19081
|
-
|
|
19082
|
-
|
|
19083
|
-
|
|
19084
|
-
|
|
19085
|
-
|
|
19086
|
-
|
|
19087
|
-
|
|
19088
|
-
|
|
19089
|
-
|
|
19090
|
-
|
|
19091
|
-
|
|
19115
|
+
<span class="jv-collapsible-copy">
|
|
19116
|
+
<span class="jv-collapsible-title">{{ title() }}</span>
|
|
19117
|
+
@if (subtitle()) {
|
|
19118
|
+
<span class="jv-collapsible-subtitle">{{ subtitle() }}</span>
|
|
19119
|
+
}
|
|
19120
|
+
</span>
|
|
19121
|
+
</span>
|
|
19122
|
+
|
|
19123
|
+
@if (showIndicator()) {
|
|
19124
|
+
<jv-icon class="jv-collapsible-indicator" [class.jv-collapsible-indicator--open]="resolvedOpen()" name="chevron-down" [size]="18" />
|
|
19125
|
+
}
|
|
19126
|
+
</button>
|
|
19127
|
+
|
|
19128
|
+
@if (shouldRenderBody()) {
|
|
19129
|
+
<div
|
|
19130
|
+
class="jv-collapsible-body"
|
|
19131
|
+
[class.jv-collapsible-body--open]="resolvedOpen()"
|
|
19132
|
+
[id]="contentId"
|
|
19133
|
+
role="region"
|
|
19134
|
+
[attr.aria-labelledby]="triggerId"
|
|
19135
|
+
[attr.aria-hidden]="resolvedOpen() ? null : 'true'"
|
|
19136
|
+
[attr.inert]="resolvedOpen() ? null : ''"
|
|
19137
|
+
(transitionend)="handleBodyTransitionEnd($event)"
|
|
19138
|
+
>
|
|
19139
|
+
<div class="jv-collapsible-content">
|
|
19140
|
+
<ng-content />
|
|
19141
|
+
</div>
|
|
19142
|
+
</div>
|
|
19143
|
+
}
|
|
19144
|
+
</section>
|
|
19145
|
+
`, styles: [".jv-collapsible-panel{border-radius:var(--jv-radius-lg);background:var(--jv-color-surface)}.jv-collapsible-panel--bordered{border:1px solid var(--jv-color-border)}.jv-collapsible-panel--filled{border:1px solid transparent;background:var(--jv-color-surface-muted)}.jv-collapsible-panel--minimal{border-bottom:1px solid var(--jv-color-border);border-radius:0}.jv-collapsible-trigger{width:100%;display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-md);padding:var(--jv-spacing-md) var(--jv-spacing-lg);border:0;border-radius:inherit;background:transparent;color:var(--jv-color-foreground);text-align:left;font:inherit;cursor:pointer}.jv-collapsible-trigger:disabled{opacity:.6;cursor:not-allowed}.jv-collapsible-trigger:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:-2px}.jv-collapsible-main{min-width:0;display:inline-flex;align-items:flex-start;gap:var(--jv-spacing-sm)}.jv-collapsible-copy{min-width:0;display:grid;gap:.25rem}.jv-collapsible-title{font-weight:600}.jv-collapsible-subtitle{color:var(--jv-color-foreground-muted);font-size:.875rem}.jv-collapsible-indicator{flex-shrink:0;transition:transform .18s ease}.jv-collapsible-indicator--open{transform:rotate(180deg)}.jv-collapsible-body{display:grid;grid-template-rows:0fr;opacity:0;transition:grid-template-rows .18s ease,opacity .18s ease}.jv-collapsible-body--open{grid-template-rows:1fr;opacity:1}.jv-collapsible-content{min-height:0;overflow:hidden;padding:0 var(--jv-spacing-lg) var(--jv-spacing-lg)}\n"] }]
|
|
19146
|
+
}], ctorParameters: () => [], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], defaultOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultOpen", required: false }] }], keepMounted: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepMounted", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showIndicator: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIndicator", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], openChange: [{ type: i0.Output, args: ["openChange"] }] } });
|
|
19147
|
+
|
|
19148
|
+
class JvAccordionComponent {
|
|
19149
|
+
panelTemplates = contentChildren(JvAccordionPanelDirective, ...(ngDevMode ? [{ debugName: "panelTemplates" }] : /* istanbul ignore next */ []));
|
|
19150
|
+
internalOpenItemIds = signal([], ...(ngDevMode ? [{ debugName: "internalOpenItemIds" }] : /* istanbul ignore next */ []));
|
|
19151
|
+
items = input([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
19152
|
+
openItemIds = input(undefined, ...(ngDevMode ? [{ debugName: "openItemIds" }] : /* istanbul ignore next */ []));
|
|
19153
|
+
defaultOpenItemIds = input([], ...(ngDevMode ? [{ debugName: "defaultOpenItemIds" }] : /* istanbul ignore next */ []));
|
|
19154
|
+
multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple" }] : /* istanbul ignore next */ []));
|
|
19155
|
+
keepMounted = input(true, ...(ngDevMode ? [{ debugName: "keepMounted" }] : /* istanbul ignore next */ []));
|
|
19156
|
+
showIndicator = input(true, ...(ngDevMode ? [{ debugName: "showIndicator" }] : /* istanbul ignore next */ []));
|
|
19157
|
+
variant = input('bordered', ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
19158
|
+
openItemIdsChange = output();
|
|
19159
|
+
resolvedOpenItemIds = computed(() => {
|
|
19160
|
+
const allItemIds = new Set(this.items().map((item) => item.id));
|
|
19161
|
+
const candidateIds = this.openItemIds() ?? this.internalOpenItemIds();
|
|
19162
|
+
const filteredIds = candidateIds.filter((id) => allItemIds.has(id));
|
|
19163
|
+
return this.multiple() ? filteredIds : filteredIds.slice(0, 1);
|
|
19164
|
+
}, ...(ngDevMode ? [{ debugName: "resolvedOpenItemIds" }] : /* istanbul ignore next */ []));
|
|
19165
|
+
constructor() {
|
|
19166
|
+
this.internalOpenItemIds.set(this.defaultOpenItemIds());
|
|
19167
|
+
}
|
|
19168
|
+
isItemOpen(itemId) {
|
|
19169
|
+
return this.resolvedOpenItemIds().includes(itemId);
|
|
19170
|
+
}
|
|
19171
|
+
handleItemOpenChange(itemId, nextOpen) {
|
|
19172
|
+
const currentIds = this.resolvedOpenItemIds();
|
|
19173
|
+
let nextIds = currentIds;
|
|
19174
|
+
if (nextOpen) {
|
|
19175
|
+
nextIds = this.multiple() ? [...new Set([...currentIds, itemId])] : [itemId];
|
|
19176
|
+
}
|
|
19177
|
+
else {
|
|
19178
|
+
nextIds = currentIds.filter((id) => id !== itemId);
|
|
19179
|
+
}
|
|
19180
|
+
if (this.openItemIds() === undefined) {
|
|
19181
|
+
this.internalOpenItemIds.set(nextIds);
|
|
19182
|
+
}
|
|
19183
|
+
this.openItemIdsChange.emit(nextIds);
|
|
19184
|
+
}
|
|
19185
|
+
panelTemplate(itemId) {
|
|
19186
|
+
return this.panelTemplates().find((panel) => panel.id() === itemId)?.templateRef ?? null;
|
|
19187
|
+
}
|
|
19188
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvAccordionComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
19189
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvAccordionComponent, isStandalone: true, selector: "jv-accordion", inputs: { items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, openItemIds: { classPropertyName: "openItemIds", publicName: "openItemIds", isSignal: true, isRequired: false, transformFunction: null }, defaultOpenItemIds: { classPropertyName: "defaultOpenItemIds", publicName: "defaultOpenItemIds", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, keepMounted: { classPropertyName: "keepMounted", publicName: "keepMounted", isSignal: true, isRequired: false, transformFunction: null }, showIndicator: { classPropertyName: "showIndicator", publicName: "showIndicator", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { openItemIdsChange: "openItemIdsChange" }, queries: [{ propertyName: "panelTemplates", predicate: JvAccordionPanelDirective, isSignal: true }], ngImport: i0, template: `
|
|
19190
|
+
<div class="jv-accordion">
|
|
19191
|
+
@for (item of items(); track item.id) {
|
|
19192
|
+
<jv-collapsible-panel
|
|
19193
|
+
[title]="item.title"
|
|
19194
|
+
[subtitle]="item.subtitle ?? ''"
|
|
19195
|
+
[icon]="item.icon ?? null"
|
|
19196
|
+
[open]="isItemOpen(item.id)"
|
|
19197
|
+
[keepMounted]="keepMounted()"
|
|
19198
|
+
[disabled]="item.disabled ?? false"
|
|
19199
|
+
[showIndicator]="showIndicator()"
|
|
19200
|
+
[variant]="variant()"
|
|
19201
|
+
(openChange)="handleItemOpenChange(item.id, $event)"
|
|
19202
|
+
>
|
|
19203
|
+
<ng-container [ngTemplateOutlet]="panelTemplate(item.id) ?? null" />
|
|
19204
|
+
</jv-collapsible-panel>
|
|
19205
|
+
}
|
|
19206
|
+
</div>
|
|
19207
|
+
`, isInline: true, styles: [".jv-accordion{display:grid;gap:var(--jv-spacing-sm)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: JvCollapsiblePanelComponent, selector: "jv-collapsible-panel", inputs: ["title", "subtitle", "icon", "open", "defaultOpen", "keepMounted", "disabled", "showIndicator", "variant"], outputs: ["openChange"] }] });
|
|
19208
|
+
}
|
|
19209
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvAccordionComponent, decorators: [{
|
|
19210
|
+
type: Component,
|
|
19211
|
+
args: [{ selector: 'jv-accordion', standalone: true, imports: [NgTemplateOutlet, JvCollapsiblePanelComponent], template: `
|
|
19212
|
+
<div class="jv-accordion">
|
|
19213
|
+
@for (item of items(); track item.id) {
|
|
19214
|
+
<jv-collapsible-panel
|
|
19215
|
+
[title]="item.title"
|
|
19216
|
+
[subtitle]="item.subtitle ?? ''"
|
|
19217
|
+
[icon]="item.icon ?? null"
|
|
19218
|
+
[open]="isItemOpen(item.id)"
|
|
19219
|
+
[keepMounted]="keepMounted()"
|
|
19220
|
+
[disabled]="item.disabled ?? false"
|
|
19221
|
+
[showIndicator]="showIndicator()"
|
|
19222
|
+
[variant]="variant()"
|
|
19223
|
+
(openChange)="handleItemOpenChange(item.id, $event)"
|
|
19224
|
+
>
|
|
19225
|
+
<ng-container [ngTemplateOutlet]="panelTemplate(item.id) ?? null" />
|
|
19226
|
+
</jv-collapsible-panel>
|
|
19227
|
+
}
|
|
19228
|
+
</div>
|
|
19229
|
+
`, styles: [".jv-accordion{display:grid;gap:var(--jv-spacing-sm)}\n"] }]
|
|
19230
|
+
}], ctorParameters: () => [], propDecorators: { panelTemplates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => JvAccordionPanelDirective), { isSignal: true }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], openItemIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "openItemIds", required: false }] }], defaultOpenItemIds: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultOpenItemIds", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], keepMounted: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepMounted", required: false }] }], showIndicator: [{ type: i0.Input, args: [{ isSignal: true, alias: "showIndicator", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], openItemIdsChange: [{ type: i0.Output, args: ["openItemIdsChange"] }] } });
|
|
19231
|
+
|
|
19232
|
+
class JvBadgeComponent {
|
|
19233
|
+
tone = input('primary', ...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
|
|
19234
|
+
badgeClass = computed(() => `jv-badge--${this.tone()}`, ...(ngDevMode ? [{ debugName: "badgeClass" }] : /* istanbul ignore next */ []));
|
|
19235
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
19236
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.17", type: JvBadgeComponent, isStandalone: true, selector: "jv-badge", inputs: { tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `<span class="jv-badge" [class]="badgeClass()"><ng-content></ng-content></span>`, isInline: true, styles: [".jv-badge{display:inline-flex;align-items:center;justify-content:center;min-height:1.75rem;padding:0 var(--jv-spacing-sm);border-radius:999px;font-size:.8rem;font-weight:700;line-height:1;white-space:nowrap}.jv-badge--primary{background:color-mix(in srgb,var(--jv-color-primary) 14%,var(--jv-color-surface));color:var(--jv-color-primary)}.jv-badge--secondary,.jv-badge--neutral{background:var(--jv-color-surface-muted);color:var(--jv-color-foreground)}.jv-badge--success{background:color-mix(in srgb,var(--jv-color-success) 16%,var(--jv-color-surface));color:var(--jv-color-success)}.jv-badge--warning{background:color-mix(in srgb,var(--jv-color-warning) 20%,var(--jv-color-surface));color:#8a4b00}.jv-badge--danger{background:color-mix(in srgb,var(--jv-color-danger) 16%,var(--jv-color-surface));color:var(--jv-color-danger)}.jv-badge--info{background:color-mix(in srgb,var(--jv-color-info) 16%,var(--jv-color-surface));color:var(--jv-color-info)}\n"] });
|
|
19237
|
+
}
|
|
19238
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvBadgeComponent, decorators: [{
|
|
19239
|
+
type: Component,
|
|
19240
|
+
args: [{ selector: 'jv-badge', standalone: true, template: `<span class="jv-badge" [class]="badgeClass()"><ng-content></ng-content></span>`, styles: [".jv-badge{display:inline-flex;align-items:center;justify-content:center;min-height:1.75rem;padding:0 var(--jv-spacing-sm);border-radius:999px;font-size:.8rem;font-weight:700;line-height:1;white-space:nowrap}.jv-badge--primary{background:color-mix(in srgb,var(--jv-color-primary) 14%,var(--jv-color-surface));color:var(--jv-color-primary)}.jv-badge--secondary,.jv-badge--neutral{background:var(--jv-color-surface-muted);color:var(--jv-color-foreground)}.jv-badge--success{background:color-mix(in srgb,var(--jv-color-success) 16%,var(--jv-color-surface));color:var(--jv-color-success)}.jv-badge--warning{background:color-mix(in srgb,var(--jv-color-warning) 20%,var(--jv-color-surface));color:#8a4b00}.jv-badge--danger{background:color-mix(in srgb,var(--jv-color-danger) 16%,var(--jv-color-surface));color:var(--jv-color-danger)}.jv-badge--info{background:color-mix(in srgb,var(--jv-color-info) 16%,var(--jv-color-surface));color:var(--jv-color-info)}\n"] }]
|
|
19241
|
+
}], propDecorators: { tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }] } });
|
|
19242
|
+
|
|
19243
|
+
class JvLoaderService {
|
|
19244
|
+
counter = signal(0, ...(ngDevMode ? [{ debugName: "counter" }] : /* istanbul ignore next */ []));
|
|
19245
|
+
visible = signal(false, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
19246
|
+
message = signal('Loading', ...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
19247
|
+
delayMs = 300;
|
|
19248
|
+
showTimeout = null;
|
|
19249
|
+
activeCount = this.counter.asReadonly();
|
|
19250
|
+
isVisible = this.visible.asReadonly();
|
|
19251
|
+
liveMessage = this.message.asReadonly();
|
|
19252
|
+
show(message = 'Loading') {
|
|
19253
|
+
this.message.set(message);
|
|
19254
|
+
this.counter.update((count) => count + 1);
|
|
19255
|
+
if (this.counter() === 1) {
|
|
19256
|
+
this.scheduleVisibility();
|
|
19257
|
+
}
|
|
19258
|
+
}
|
|
19259
|
+
hide() {
|
|
19260
|
+
this.counter.update((count) => Math.max(0, count - 1));
|
|
19261
|
+
if (this.counter() === 0) {
|
|
19262
|
+
this.clearTimer();
|
|
19263
|
+
this.visible.set(false);
|
|
19264
|
+
}
|
|
19265
|
+
}
|
|
19266
|
+
scheduleVisibility() {
|
|
19267
|
+
this.clearTimer();
|
|
19268
|
+
this.showTimeout = setTimeout(() => {
|
|
19269
|
+
if (this.counter() > 0) {
|
|
19270
|
+
this.visible.set(true);
|
|
19271
|
+
}
|
|
19272
|
+
this.showTimeout = null;
|
|
19273
|
+
}, this.delayMs);
|
|
19274
|
+
}
|
|
19275
|
+
clearTimer() {
|
|
19276
|
+
if (this.showTimeout) {
|
|
19277
|
+
clearTimeout(this.showTimeout);
|
|
19278
|
+
this.showTimeout = null;
|
|
19279
|
+
}
|
|
19280
|
+
}
|
|
19281
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvLoaderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
19282
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvLoaderService, providedIn: 'root' });
|
|
19283
|
+
}
|
|
19284
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvLoaderService, decorators: [{
|
|
19285
|
+
type: Injectable,
|
|
19286
|
+
args: [{ providedIn: 'root' }]
|
|
19287
|
+
}] });
|
|
19288
|
+
|
|
19289
|
+
class JvLoaderComponent {
|
|
19290
|
+
document = inject(DOCUMENT);
|
|
19291
|
+
loaderService = inject(JvLoaderService);
|
|
19292
|
+
constructor() {
|
|
19293
|
+
effect(() => {
|
|
19294
|
+
const locked = this.loaderService.isVisible();
|
|
19295
|
+
const body = this.document.body;
|
|
19296
|
+
const root = this.document.documentElement;
|
|
19297
|
+
body.style.overflow = locked ? 'hidden' : '';
|
|
19298
|
+
root.style.overflow = locked ? 'hidden' : '';
|
|
19299
|
+
});
|
|
19300
|
+
}
|
|
19301
|
+
handleWheel(event) {
|
|
19302
|
+
if (this.loaderService.isVisible()) {
|
|
19303
|
+
event.preventDefault();
|
|
19304
|
+
}
|
|
19305
|
+
}
|
|
19306
|
+
handleTouchMove(event) {
|
|
19307
|
+
if (this.loaderService.isVisible()) {
|
|
19308
|
+
event.preventDefault();
|
|
19309
|
+
}
|
|
19310
|
+
}
|
|
19311
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
19312
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvLoaderComponent, isStandalone: true, selector: "jv-loader", host: { listeners: { "document:wheel": "handleWheel($event)", "document:touchmove": "handleTouchMove($event)" } }, ngImport: i0, template: `
|
|
19313
|
+
@if (loaderService.isVisible()) {
|
|
19314
|
+
<div class="jv-loader-backdrop" aria-live="polite" aria-atomic="true">
|
|
19315
|
+
<div class="jv-loader-panel" role="status">
|
|
19316
|
+
<span class="spinner" aria-hidden="true"></span>
|
|
19317
|
+
<span>{{ loaderService.liveMessage() }}</span>
|
|
19318
|
+
</div>
|
|
19319
|
+
</div>
|
|
19320
|
+
}
|
|
19321
|
+
`, isInline: true, styles: [".jv-loader-backdrop{position:fixed;inset:0;z-index:1050;display:grid;place-items:center;background:#0f172a2e;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.jv-loader-panel{display:inline-flex;align-items:center;gap:var(--jv-spacing-sm);padding:var(--jv-spacing-md) var(--jv-spacing-lg);width:min(35vw,calc(100vw - 2rem));height:min(35vh,calc(100vh - 2rem));max-width:calc(100vw - 2rem);max-height:calc(100vh - 2rem);justify-content:center;border:1px solid #d6dce5;border-radius:var(--jv-radius-lg);background:#f8fafc;box-shadow:var(--jv-shadow-lg);color:#111827;text-align:center;forced-color-adjust:none}.spinner{width:1.25rem;height:1.25rem;border:2px solid currentColor;border-right-color:transparent;border-radius:999px;animation:jv-loader-spin .8s linear infinite}@media(forced-colors:active){.jv-loader-panel{border-color:#d6dce5;background:#f8fafc;color:#111827}}@keyframes jv-loader-spin{to{transform:rotate(360deg)}}\n"] });
|
|
19322
|
+
}
|
|
19323
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvLoaderComponent, decorators: [{
|
|
19324
|
+
type: Component,
|
|
19325
|
+
args: [{ selector: 'jv-loader', standalone: true, template: `
|
|
19326
|
+
@if (loaderService.isVisible()) {
|
|
19327
|
+
<div class="jv-loader-backdrop" aria-live="polite" aria-atomic="true">
|
|
19328
|
+
<div class="jv-loader-panel" role="status">
|
|
19329
|
+
<span class="spinner" aria-hidden="true"></span>
|
|
19330
|
+
<span>{{ loaderService.liveMessage() }}</span>
|
|
19331
|
+
</div>
|
|
19332
|
+
</div>
|
|
19333
|
+
}
|
|
19334
|
+
`, styles: [".jv-loader-backdrop{position:fixed;inset:0;z-index:1050;display:grid;place-items:center;background:#0f172a2e;-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.jv-loader-panel{display:inline-flex;align-items:center;gap:var(--jv-spacing-sm);padding:var(--jv-spacing-md) var(--jv-spacing-lg);width:min(35vw,calc(100vw - 2rem));height:min(35vh,calc(100vh - 2rem));max-width:calc(100vw - 2rem);max-height:calc(100vh - 2rem);justify-content:center;border:1px solid #d6dce5;border-radius:var(--jv-radius-lg);background:#f8fafc;box-shadow:var(--jv-shadow-lg);color:#111827;text-align:center;forced-color-adjust:none}.spinner{width:1.25rem;height:1.25rem;border:2px solid currentColor;border-right-color:transparent;border-radius:999px;animation:jv-loader-spin .8s linear infinite}@media(forced-colors:active){.jv-loader-panel{border-color:#d6dce5;background:#f8fafc;color:#111827}}@keyframes jv-loader-spin{to{transform:rotate(360deg)}}\n"] }]
|
|
19335
|
+
}], ctorParameters: () => [], propDecorators: { handleWheel: [{
|
|
19336
|
+
type: HostListener,
|
|
19337
|
+
args: ['document:wheel', ['$event']]
|
|
19338
|
+
}], handleTouchMove: [{
|
|
19339
|
+
type: HostListener,
|
|
19340
|
+
args: ['document:touchmove', ['$event']]
|
|
19341
|
+
}] } });
|
|
19342
|
+
|
|
19343
|
+
class JvToastService {
|
|
19344
|
+
announcementService = inject(JvAnnouncementService);
|
|
19345
|
+
config = inject(JvUiConfigService);
|
|
19346
|
+
items = signal([], ...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
19347
|
+
positionOverride = signal(null, ...(ngDevMode ? [{ debugName: "positionOverride" }] : /* istanbul ignore next */ []));
|
|
19348
|
+
nextId = 0;
|
|
19349
|
+
toasts = computed(() => this.items(), ...(ngDevMode ? [{ debugName: "toasts" }] : /* istanbul ignore next */ []));
|
|
19350
|
+
position = computed(() => this.positionOverride() ?? this.config.snapshot.toastPosition, ...(ngDevMode ? [{ debugName: "position" }] : /* istanbul ignore next */ []));
|
|
19351
|
+
show(message, tone = 'info', options = {}) {
|
|
19352
|
+
const id = ++this.nextId;
|
|
19353
|
+
const toast = {
|
|
19354
|
+
id,
|
|
19355
|
+
title: options.title,
|
|
19356
|
+
message,
|
|
19357
|
+
tone,
|
|
19358
|
+
duration: options.duration ?? 4000,
|
|
19359
|
+
};
|
|
19360
|
+
this.items.update((current) => [...current, toast]);
|
|
19361
|
+
this.announcementService.announce(toast.title ? `${toast.title}. ${toast.message}` : toast.message, toast.tone === 'danger' ? 'assertive' : 'polite');
|
|
19362
|
+
if (toast.duration > 0) {
|
|
19363
|
+
setTimeout(() => this.dismiss(id), toast.duration);
|
|
19364
|
+
}
|
|
19365
|
+
return id;
|
|
19366
|
+
}
|
|
19367
|
+
dismiss(id) {
|
|
19368
|
+
this.items.update((current) => current.filter((item) => item.id !== id));
|
|
19369
|
+
}
|
|
19370
|
+
setPosition(position) {
|
|
19371
|
+
this.positionOverride.set(position);
|
|
19372
|
+
}
|
|
19373
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvToastService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
19374
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvToastService, providedIn: 'root' });
|
|
19375
|
+
}
|
|
19376
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvToastService, decorators: [{
|
|
19377
|
+
type: Injectable,
|
|
19378
|
+
args: [{ providedIn: 'root' }]
|
|
19379
|
+
}] });
|
|
19380
|
+
|
|
19381
|
+
class JvToastComponent {
|
|
19382
|
+
toastService = inject(JvToastService);
|
|
19383
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvToastComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
19384
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvToastComponent, isStandalone: true, selector: "jv-toast", ngImport: i0, template: `
|
|
19385
|
+
@if (toastService.toasts().length > 0) {
|
|
19386
|
+
<div class="jv-toast-viewport" [class]="'is-' + toastService.position()" aria-live="polite" aria-atomic="false">
|
|
19387
|
+
@for (toast of toastService.toasts(); track toast.id) {
|
|
19388
|
+
<article class="jv-toast-item" [class]="'jv-toast--' + toast.tone" [attr.role]="toast.tone === 'danger' ? 'alert' : 'status'" aria-atomic="true">
|
|
19389
|
+
<div class="jv-toast-copy">
|
|
19390
|
+
@if (toast.title) {
|
|
19391
|
+
<strong>{{ toast.title }}</strong>
|
|
19392
|
+
}
|
|
19393
|
+
<p>{{ toast.message }}</p>
|
|
19394
|
+
</div>
|
|
19092
19395
|
|
|
19093
19396
|
<button type="button" class="jv-toast-close" (click)="toastService.dismiss(toast.id)" aria-label="Dismiss notification">
|
|
19094
19397
|
<jv-icon name="x" [size]="16" />
|
|
@@ -19099,43 +19402,844 @@ class JvToastComponent {
|
|
|
19099
19402
|
}
|
|
19100
19403
|
`, isInline: true, styles: [".jv-toast-viewport{position:fixed;z-index:1100;display:grid;gap:var(--jv-spacing-sm);width:min(360px,calc(100vw - 2rem))}.is-top-left{top:1rem;left:1rem}.is-top-center{top:1rem;left:50%;transform:translate(-50%)}.is-top-right{top:1rem;right:1rem}.is-bottom-left{bottom:1rem;left:1rem}.is-bottom-center{bottom:1rem;left:50%;transform:translate(-50%)}.is-bottom-right{bottom:1rem;right:1rem}.jv-toast-item{display:grid;grid-template-columns:1fr auto;gap:var(--jv-spacing-sm);padding:var(--jv-spacing-md);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md);background:var(--jv-color-surface);box-shadow:var(--jv-shadow-lg)}.jv-toast-copy strong,.jv-toast-copy p{margin:0}.jv-toast-copy{display:grid;gap:.25rem}.jv-toast-copy p{color:var(--jv-color-foreground-muted)}.jv-toast-close{display:inline-grid;place-items:center;width:2rem;height:2rem;border:0;border-radius:999px;background:transparent;color:inherit}.jv-toast--success{border-color:color-mix(in srgb,var(--jv-color-success) 35%,var(--jv-color-border))}.jv-toast--warning{border-color:color-mix(in srgb,var(--jv-color-warning) 35%,var(--jv-color-border))}.jv-toast--danger{border-color:color-mix(in srgb,var(--jv-color-danger) 35%,var(--jv-color-border))}.jv-toast--info,.jv-toast--primary{border-color:color-mix(in srgb,var(--jv-color-primary) 35%,var(--jv-color-border))}\n"], dependencies: [{ kind: "component", type: JvIconComponent, selector: "jv-icon", inputs: ["name", "size", "strokeWidth", "decorative", "ariaLabel"] }] });
|
|
19101
19404
|
}
|
|
19102
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvToastComponent, decorators: [{
|
|
19405
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvToastComponent, decorators: [{
|
|
19406
|
+
type: Component,
|
|
19407
|
+
args: [{ selector: 'jv-toast', standalone: true, imports: [JvIconComponent], template: `
|
|
19408
|
+
@if (toastService.toasts().length > 0) {
|
|
19409
|
+
<div class="jv-toast-viewport" [class]="'is-' + toastService.position()" aria-live="polite" aria-atomic="false">
|
|
19410
|
+
@for (toast of toastService.toasts(); track toast.id) {
|
|
19411
|
+
<article class="jv-toast-item" [class]="'jv-toast--' + toast.tone" [attr.role]="toast.tone === 'danger' ? 'alert' : 'status'" aria-atomic="true">
|
|
19412
|
+
<div class="jv-toast-copy">
|
|
19413
|
+
@if (toast.title) {
|
|
19414
|
+
<strong>{{ toast.title }}</strong>
|
|
19415
|
+
}
|
|
19416
|
+
<p>{{ toast.message }}</p>
|
|
19417
|
+
</div>
|
|
19418
|
+
|
|
19419
|
+
<button type="button" class="jv-toast-close" (click)="toastService.dismiss(toast.id)" aria-label="Dismiss notification">
|
|
19420
|
+
<jv-icon name="x" [size]="16" />
|
|
19421
|
+
</button>
|
|
19422
|
+
</article>
|
|
19423
|
+
}
|
|
19424
|
+
</div>
|
|
19425
|
+
}
|
|
19426
|
+
`, styles: [".jv-toast-viewport{position:fixed;z-index:1100;display:grid;gap:var(--jv-spacing-sm);width:min(360px,calc(100vw - 2rem))}.is-top-left{top:1rem;left:1rem}.is-top-center{top:1rem;left:50%;transform:translate(-50%)}.is-top-right{top:1rem;right:1rem}.is-bottom-left{bottom:1rem;left:1rem}.is-bottom-center{bottom:1rem;left:50%;transform:translate(-50%)}.is-bottom-right{bottom:1rem;right:1rem}.jv-toast-item{display:grid;grid-template-columns:1fr auto;gap:var(--jv-spacing-sm);padding:var(--jv-spacing-md);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md);background:var(--jv-color-surface);box-shadow:var(--jv-shadow-lg)}.jv-toast-copy strong,.jv-toast-copy p{margin:0}.jv-toast-copy{display:grid;gap:.25rem}.jv-toast-copy p{color:var(--jv-color-foreground-muted)}.jv-toast-close{display:inline-grid;place-items:center;width:2rem;height:2rem;border:0;border-radius:999px;background:transparent;color:inherit}.jv-toast--success{border-color:color-mix(in srgb,var(--jv-color-success) 35%,var(--jv-color-border))}.jv-toast--warning{border-color:color-mix(in srgb,var(--jv-color-warning) 35%,var(--jv-color-border))}.jv-toast--danger{border-color:color-mix(in srgb,var(--jv-color-danger) 35%,var(--jv-color-border))}.jv-toast--info,.jv-toast--primary{border-color:color-mix(in srgb,var(--jv-color-primary) 35%,var(--jv-color-border))}\n"] }]
|
|
19427
|
+
}] });
|
|
19428
|
+
|
|
19429
|
+
class JvCodeComponent {
|
|
19430
|
+
code = input.required(...(ngDevMode ? [{ debugName: "code" }] : /* istanbul ignore next */ []));
|
|
19431
|
+
language = input('', ...(ngDevMode ? [{ debugName: "language" }] : /* istanbul ignore next */ []));
|
|
19432
|
+
title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
19433
|
+
font = input('jetbrains-mono', ...(ngDevMode ? [{ debugName: "font" }] : /* istanbul ignore next */ []));
|
|
19434
|
+
editable = input(false, ...(ngDevMode ? [{ debugName: "editable" }] : /* istanbul ignore next */ []));
|
|
19435
|
+
width = input('100%', ...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
|
|
19436
|
+
height = input('auto', ...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
|
|
19437
|
+
codeChange = output();
|
|
19438
|
+
fontFamily = computed(() => {
|
|
19439
|
+
switch (this.font()) {
|
|
19440
|
+
case 'fira-code':
|
|
19441
|
+
return `'Fira Code', 'JetBrains Mono', 'Cascadia Code', 'Consolas', monospace`;
|
|
19442
|
+
case 'cascadia':
|
|
19443
|
+
return `'Cascadia Code', 'JetBrains Mono', 'Fira Code', 'Consolas', monospace`;
|
|
19444
|
+
case 'consolas':
|
|
19445
|
+
return `'Consolas', 'Cascadia Code', 'JetBrains Mono', 'Fira Code', monospace`;
|
|
19446
|
+
case 'system':
|
|
19447
|
+
return `ui-monospace, 'SFMono-Regular', 'Cascadia Code', 'JetBrains Mono', 'Fira Code', 'Consolas', monospace`;
|
|
19448
|
+
default:
|
|
19449
|
+
return `'JetBrains Mono', 'Fira Code', 'Cascadia Code', 'Consolas', monospace`;
|
|
19450
|
+
}
|
|
19451
|
+
}, ...(ngDevMode ? [{ debugName: "fontFamily" }] : /* istanbul ignore next */ []));
|
|
19452
|
+
languageLabel() {
|
|
19453
|
+
return this.language().trim();
|
|
19454
|
+
}
|
|
19455
|
+
handleInput(event) {
|
|
19456
|
+
this.codeChange.emit(event.target.value);
|
|
19457
|
+
}
|
|
19458
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvCodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
19459
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvCodeComponent, isStandalone: true, selector: "jv-code", inputs: { code: { classPropertyName: "code", publicName: "code", isSignal: true, isRequired: true, transformFunction: null }, language: { classPropertyName: "language", publicName: "language", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, font: { classPropertyName: "font", publicName: "font", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { codeChange: "codeChange" }, ngImport: i0, template: `
|
|
19460
|
+
<section
|
|
19461
|
+
class="jv-code"
|
|
19462
|
+
[style.--jv-code-font-family]="fontFamily()"
|
|
19463
|
+
[style.width]="width()"
|
|
19464
|
+
role="region"
|
|
19465
|
+
[attr.aria-label]="title() || languageLabel() || 'Code block'"
|
|
19466
|
+
>
|
|
19467
|
+
@if (title() || languageLabel()) {
|
|
19468
|
+
<header class="jv-code-header">
|
|
19469
|
+
@if (title()) {
|
|
19470
|
+
<span class="jv-code-title">{{ title() }}</span>
|
|
19471
|
+
}
|
|
19472
|
+
|
|
19473
|
+
@if (languageLabel()) {
|
|
19474
|
+
<span class="jv-code-language">{{ languageLabel() }}</span>
|
|
19475
|
+
}
|
|
19476
|
+
</header>
|
|
19477
|
+
}
|
|
19478
|
+
|
|
19479
|
+
@if (editable()) {
|
|
19480
|
+
<div class="jv-code-body">
|
|
19481
|
+
<textarea
|
|
19482
|
+
class="jv-code-editor"
|
|
19483
|
+
[value]="code()"
|
|
19484
|
+
[style.height]="height()"
|
|
19485
|
+
spellcheck="false"
|
|
19486
|
+
(input)="handleInput($event)"
|
|
19487
|
+
></textarea>
|
|
19488
|
+
</div>
|
|
19489
|
+
} @else {
|
|
19490
|
+
<div class="jv-code-scroll">
|
|
19491
|
+
<pre class="jv-code-pre" [style.min-height]="height() === 'auto' ? null : height()"><code>{{ code() }}</code></pre>
|
|
19492
|
+
</div>
|
|
19493
|
+
}
|
|
19494
|
+
</section>
|
|
19495
|
+
`, isInline: true, styles: [".jv-code{display:grid;gap:0;border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-lg);background:color-mix(in srgb,var(--jv-color-surface-muted) 60%,#0f172a 40%);color:#e5eefb;overflow:hidden}.jv-code-body{min-width:0}.jv-code-header{display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-sm);padding:var(--jv-spacing-sm) var(--jv-spacing-md);border-bottom:1px solid rgba(148,163,184,.22);background:#0f172ae0}.jv-code-title{font-size:.875rem;font-weight:600;color:#f8fafc}.jv-code-language{display:inline-flex;align-items:center;min-height:1.75rem;padding:0 .65rem;border:1px solid rgba(125,211,252,.28);border-radius:999px;background:#0ea5e924;color:#c4f1ff;font-size:.75rem;text-transform:uppercase;letter-spacing:.06em}.jv-code-scroll{overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;scrollbar-color:transparent transparent}.jv-code-scroll:hover,.jv-code-scroll:focus-within{scrollbar-color:rgba(148,163,184,.7) transparent}.jv-code-scroll::-webkit-scrollbar{height:.45rem}.jv-code-scroll::-webkit-scrollbar-track{background:transparent}.jv-code-scroll::-webkit-scrollbar-thumb{border-radius:999px;background:transparent}.jv-code-scroll:hover::-webkit-scrollbar-thumb,.jv-code-scroll:focus-within::-webkit-scrollbar-thumb{background:#94a3b8b8}.jv-code-pre{margin:0;min-width:max-content;padding:var(--jv-spacing-md);font-family:var(--jv-code-font-family, \"JetBrains Mono\", \"Fira Code\", \"Cascadia Code\", \"Consolas\", monospace);font-size:.875rem;line-height:1.6;white-space:pre}.jv-code-editor{display:block;width:100%;min-width:100%;min-height:12rem;padding:var(--jv-spacing-md);border:0;background:transparent;color:inherit;font-family:var(--jv-code-font-family, \"JetBrains Mono\", \"Fira Code\", \"Cascadia Code\", \"Consolas\", monospace);font-size:.875rem;line-height:1.6;white-space:pre;overflow:auto;resize:both;box-sizing:border-box}.jv-code-editor:focus{outline:2px solid color-mix(in srgb,#7dd3fc 70%,transparent);outline-offset:-2px}code{font:inherit}\n"] });
|
|
19496
|
+
}
|
|
19497
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvCodeComponent, decorators: [{
|
|
19498
|
+
type: Component,
|
|
19499
|
+
args: [{ selector: 'jv-code', standalone: true, template: `
|
|
19500
|
+
<section
|
|
19501
|
+
class="jv-code"
|
|
19502
|
+
[style.--jv-code-font-family]="fontFamily()"
|
|
19503
|
+
[style.width]="width()"
|
|
19504
|
+
role="region"
|
|
19505
|
+
[attr.aria-label]="title() || languageLabel() || 'Code block'"
|
|
19506
|
+
>
|
|
19507
|
+
@if (title() || languageLabel()) {
|
|
19508
|
+
<header class="jv-code-header">
|
|
19509
|
+
@if (title()) {
|
|
19510
|
+
<span class="jv-code-title">{{ title() }}</span>
|
|
19511
|
+
}
|
|
19512
|
+
|
|
19513
|
+
@if (languageLabel()) {
|
|
19514
|
+
<span class="jv-code-language">{{ languageLabel() }}</span>
|
|
19515
|
+
}
|
|
19516
|
+
</header>
|
|
19517
|
+
}
|
|
19518
|
+
|
|
19519
|
+
@if (editable()) {
|
|
19520
|
+
<div class="jv-code-body">
|
|
19521
|
+
<textarea
|
|
19522
|
+
class="jv-code-editor"
|
|
19523
|
+
[value]="code()"
|
|
19524
|
+
[style.height]="height()"
|
|
19525
|
+
spellcheck="false"
|
|
19526
|
+
(input)="handleInput($event)"
|
|
19527
|
+
></textarea>
|
|
19528
|
+
</div>
|
|
19529
|
+
} @else {
|
|
19530
|
+
<div class="jv-code-scroll">
|
|
19531
|
+
<pre class="jv-code-pre" [style.min-height]="height() === 'auto' ? null : height()"><code>{{ code() }}</code></pre>
|
|
19532
|
+
</div>
|
|
19533
|
+
}
|
|
19534
|
+
</section>
|
|
19535
|
+
`, styles: [".jv-code{display:grid;gap:0;border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-lg);background:color-mix(in srgb,var(--jv-color-surface-muted) 60%,#0f172a 40%);color:#e5eefb;overflow:hidden}.jv-code-body{min-width:0}.jv-code-header{display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-sm);padding:var(--jv-spacing-sm) var(--jv-spacing-md);border-bottom:1px solid rgba(148,163,184,.22);background:#0f172ae0}.jv-code-title{font-size:.875rem;font-weight:600;color:#f8fafc}.jv-code-language{display:inline-flex;align-items:center;min-height:1.75rem;padding:0 .65rem;border:1px solid rgba(125,211,252,.28);border-radius:999px;background:#0ea5e924;color:#c4f1ff;font-size:.75rem;text-transform:uppercase;letter-spacing:.06em}.jv-code-scroll{overflow-x:auto;overflow-y:hidden;scrollbar-width:thin;scrollbar-color:transparent transparent}.jv-code-scroll:hover,.jv-code-scroll:focus-within{scrollbar-color:rgba(148,163,184,.7) transparent}.jv-code-scroll::-webkit-scrollbar{height:.45rem}.jv-code-scroll::-webkit-scrollbar-track{background:transparent}.jv-code-scroll::-webkit-scrollbar-thumb{border-radius:999px;background:transparent}.jv-code-scroll:hover::-webkit-scrollbar-thumb,.jv-code-scroll:focus-within::-webkit-scrollbar-thumb{background:#94a3b8b8}.jv-code-pre{margin:0;min-width:max-content;padding:var(--jv-spacing-md);font-family:var(--jv-code-font-family, \"JetBrains Mono\", \"Fira Code\", \"Cascadia Code\", \"Consolas\", monospace);font-size:.875rem;line-height:1.6;white-space:pre}.jv-code-editor{display:block;width:100%;min-width:100%;min-height:12rem;padding:var(--jv-spacing-md);border:0;background:transparent;color:inherit;font-family:var(--jv-code-font-family, \"JetBrains Mono\", \"Fira Code\", \"Cascadia Code\", \"Consolas\", monospace);font-size:.875rem;line-height:1.6;white-space:pre;overflow:auto;resize:both;box-sizing:border-box}.jv-code-editor:focus{outline:2px solid color-mix(in srgb,#7dd3fc 70%,transparent);outline-offset:-2px}code{font:inherit}\n"] }]
|
|
19536
|
+
}], propDecorators: { code: [{ type: i0.Input, args: [{ isSignal: true, alias: "code", required: true }] }], language: [{ type: i0.Input, args: [{ isSignal: true, alias: "language", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], font: [{ type: i0.Input, args: [{ isSignal: true, alias: "font", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], codeChange: [{ type: i0.Output, args: ["codeChange"] }] } });
|
|
19537
|
+
|
|
19538
|
+
class JvDialogComponent {
|
|
19539
|
+
document = inject(DOCUMENT);
|
|
19540
|
+
panelRef = viewChild('panel', ...(ngDevMode ? [{ debugName: "panelRef" }] : /* istanbul ignore next */ []));
|
|
19541
|
+
open = input(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
19542
|
+
title = input('Dialog', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
19543
|
+
closed = output();
|
|
19544
|
+
titleId = `jv-dialog-title-${Math.random().toString(36).slice(2, 8)}`;
|
|
19545
|
+
descriptionId = `jv-dialog-description-${Math.random().toString(36).slice(2, 8)}`;
|
|
19546
|
+
constructor() {
|
|
19547
|
+
effect(() => {
|
|
19548
|
+
if (this.open()) {
|
|
19549
|
+
queueMicrotask(() => this.focusInitialElement());
|
|
19550
|
+
}
|
|
19551
|
+
});
|
|
19552
|
+
}
|
|
19553
|
+
handleDocumentKeydown(event) {
|
|
19554
|
+
if (!this.open()) {
|
|
19555
|
+
return;
|
|
19556
|
+
}
|
|
19557
|
+
if (event.key === 'Escape') {
|
|
19558
|
+
event.preventDefault();
|
|
19559
|
+
this.closed.emit();
|
|
19560
|
+
return;
|
|
19561
|
+
}
|
|
19562
|
+
if (event.key === 'Tab') {
|
|
19563
|
+
this.trapFocus(event);
|
|
19564
|
+
}
|
|
19565
|
+
}
|
|
19566
|
+
focusInitialElement() {
|
|
19567
|
+
const panel = this.panelRef()?.nativeElement;
|
|
19568
|
+
if (!panel) {
|
|
19569
|
+
return;
|
|
19570
|
+
}
|
|
19571
|
+
const firstFocusable = this.getFocusableElements()[0];
|
|
19572
|
+
(firstFocusable ?? panel).focus();
|
|
19573
|
+
}
|
|
19574
|
+
backdropClose() {
|
|
19575
|
+
this.closed.emit();
|
|
19576
|
+
}
|
|
19577
|
+
trapFocus(event) {
|
|
19578
|
+
const focusable = this.getFocusableElements();
|
|
19579
|
+
const panel = this.panelRef()?.nativeElement;
|
|
19580
|
+
if (!panel || focusable.length === 0) {
|
|
19581
|
+
panel?.focus();
|
|
19582
|
+
event.preventDefault();
|
|
19583
|
+
return;
|
|
19584
|
+
}
|
|
19585
|
+
const first = focusable[0];
|
|
19586
|
+
const last = focusable[focusable.length - 1];
|
|
19587
|
+
const active = this.document.activeElement;
|
|
19588
|
+
if (event.shiftKey && active === first) {
|
|
19589
|
+
last.focus();
|
|
19590
|
+
event.preventDefault();
|
|
19591
|
+
}
|
|
19592
|
+
else if (!event.shiftKey && active === last) {
|
|
19593
|
+
first.focus();
|
|
19594
|
+
event.preventDefault();
|
|
19595
|
+
}
|
|
19596
|
+
}
|
|
19597
|
+
getFocusableElements() {
|
|
19598
|
+
const panel = this.panelRef()?.nativeElement;
|
|
19599
|
+
if (!panel) {
|
|
19600
|
+
return [];
|
|
19601
|
+
}
|
|
19602
|
+
return Array.from(panel.querySelectorAll('button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'));
|
|
19603
|
+
}
|
|
19604
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
19605
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvDialogComponent, isStandalone: true, selector: "jv-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, host: { listeners: { "document:keydown": "handleDocumentKeydown($event)" } }, viewQueries: [{ propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
19606
|
+
@if (open()) {
|
|
19607
|
+
<div class="jv-dialog-backdrop" (click)="backdropClose()">
|
|
19608
|
+
<div class="jv-dialog-panel" role="dialog" aria-modal="true" tabindex="-1" [attr.aria-labelledby]="titleId" [attr.aria-describedby]="descriptionId" (click)="$event.stopPropagation()" #panel>
|
|
19609
|
+
<header class="jv-dialog-header">
|
|
19610
|
+
<h2 [id]="titleId">{{ title() }}</h2>
|
|
19611
|
+
</header>
|
|
19612
|
+
|
|
19613
|
+
<div class="jv-dialog-body" [id]="descriptionId">
|
|
19614
|
+
<ng-content></ng-content>
|
|
19615
|
+
</div>
|
|
19616
|
+
|
|
19617
|
+
<footer class="jv-dialog-footer">
|
|
19618
|
+
<ng-content select="[dialog-actions]"></ng-content>
|
|
19619
|
+
</footer>
|
|
19620
|
+
</div>
|
|
19621
|
+
</div>
|
|
19622
|
+
}
|
|
19623
|
+
`, isInline: true, styles: [".jv-dialog-backdrop{position:fixed;inset:0;z-index:1200;display:grid;place-items:center;padding:1rem;background:#0f172a80}.jv-dialog-panel{width:min(32rem,100%);max-height:calc(100vh - 2rem);overflow:auto;padding:var(--jv-spacing-lg);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-lg);background:var(--jv-color-surface);box-shadow:var(--jv-shadow-lg)}.jv-dialog-header,.jv-dialog-body,.jv-dialog-footer{display:grid;gap:var(--jv-spacing-sm)}.jv-dialog-footer{margin-top:var(--jv-spacing-lg)}h2,p{margin:0}\n"] });
|
|
19624
|
+
}
|
|
19625
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvDialogComponent, decorators: [{
|
|
19626
|
+
type: Component,
|
|
19627
|
+
args: [{ selector: 'jv-dialog', standalone: true, template: `
|
|
19628
|
+
@if (open()) {
|
|
19629
|
+
<div class="jv-dialog-backdrop" (click)="backdropClose()">
|
|
19630
|
+
<div class="jv-dialog-panel" role="dialog" aria-modal="true" tabindex="-1" [attr.aria-labelledby]="titleId" [attr.aria-describedby]="descriptionId" (click)="$event.stopPropagation()" #panel>
|
|
19631
|
+
<header class="jv-dialog-header">
|
|
19632
|
+
<h2 [id]="titleId">{{ title() }}</h2>
|
|
19633
|
+
</header>
|
|
19634
|
+
|
|
19635
|
+
<div class="jv-dialog-body" [id]="descriptionId">
|
|
19636
|
+
<ng-content></ng-content>
|
|
19637
|
+
</div>
|
|
19638
|
+
|
|
19639
|
+
<footer class="jv-dialog-footer">
|
|
19640
|
+
<ng-content select="[dialog-actions]"></ng-content>
|
|
19641
|
+
</footer>
|
|
19642
|
+
</div>
|
|
19643
|
+
</div>
|
|
19644
|
+
}
|
|
19645
|
+
`, styles: [".jv-dialog-backdrop{position:fixed;inset:0;z-index:1200;display:grid;place-items:center;padding:1rem;background:#0f172a80}.jv-dialog-panel{width:min(32rem,100%);max-height:calc(100vh - 2rem);overflow:auto;padding:var(--jv-spacing-lg);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-lg);background:var(--jv-color-surface);box-shadow:var(--jv-shadow-lg)}.jv-dialog-header,.jv-dialog-body,.jv-dialog-footer{display:grid;gap:var(--jv-spacing-sm)}.jv-dialog-footer{margin-top:var(--jv-spacing-lg)}h2,p{margin:0}\n"] }]
|
|
19646
|
+
}], ctorParameters: () => [], propDecorators: { panelRef: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], handleDocumentKeydown: [{
|
|
19647
|
+
type: HostListener,
|
|
19648
|
+
args: ['document:keydown', ['$event']]
|
|
19649
|
+
}] } });
|
|
19650
|
+
|
|
19651
|
+
let selectIdSequence = 0;
|
|
19652
|
+
class JvSelectComponent {
|
|
19653
|
+
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
19654
|
+
placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
19655
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
19656
|
+
invalid = input(false, ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
|
|
19657
|
+
describedBy = input('', ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
|
|
19658
|
+
inputId = input(`jv-select-${++selectIdSequence}`, ...(ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []));
|
|
19659
|
+
modelValue = input('', ...(ngDevMode ? [{ debugName: "modelValue" }] : /* istanbul ignore next */ []));
|
|
19660
|
+
selectionChange = output();
|
|
19661
|
+
value = '';
|
|
19662
|
+
disabled = false;
|
|
19663
|
+
onChange = () => undefined;
|
|
19664
|
+
onTouched = () => undefined;
|
|
19665
|
+
currentValue = computed(() => this.modelValue() || this.value, ...(ngDevMode ? [{ debugName: "currentValue" }] : /* istanbul ignore next */ []));
|
|
19666
|
+
writeValue(value) {
|
|
19667
|
+
this.value = value ?? '';
|
|
19668
|
+
}
|
|
19669
|
+
registerOnChange(fn) {
|
|
19670
|
+
this.onChange = fn;
|
|
19671
|
+
}
|
|
19672
|
+
registerOnTouched(fn) {
|
|
19673
|
+
this.onTouched = fn;
|
|
19674
|
+
}
|
|
19675
|
+
setDisabledState(isDisabled) {
|
|
19676
|
+
this.disabled = isDisabled;
|
|
19677
|
+
}
|
|
19678
|
+
handleChange(event) {
|
|
19679
|
+
const nextValue = event.target.value;
|
|
19680
|
+
this.value = nextValue;
|
|
19681
|
+
this.onChange(nextValue);
|
|
19682
|
+
this.selectionChange.emit(nextValue);
|
|
19683
|
+
}
|
|
19684
|
+
handleBlur() {
|
|
19685
|
+
this.onTouched();
|
|
19686
|
+
}
|
|
19687
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
19688
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvSelectComponent, isStandalone: true, selector: "jv-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, describedBy: { classPropertyName: "describedBy", publicName: "describedBy", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, modelValue: { classPropertyName: "modelValue", publicName: "modelValue", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, providers: [
|
|
19689
|
+
{
|
|
19690
|
+
provide: NG_VALUE_ACCESSOR,
|
|
19691
|
+
useExisting: forwardRef(() => JvSelectComponent),
|
|
19692
|
+
multi: true,
|
|
19693
|
+
},
|
|
19694
|
+
], ngImport: i0, template: `
|
|
19695
|
+
<select
|
|
19696
|
+
class="jv-select"
|
|
19697
|
+
[class.is-invalid]="invalid()"
|
|
19698
|
+
[id]="inputId()"
|
|
19699
|
+
[disabled]="disabled"
|
|
19700
|
+
[required]="required()"
|
|
19701
|
+
[attr.aria-invalid]="invalid() ? 'true' : null"
|
|
19702
|
+
[attr.aria-describedby]="describedBy() || null"
|
|
19703
|
+
[value]="currentValue()"
|
|
19704
|
+
(change)="handleChange($event)"
|
|
19705
|
+
(blur)="handleBlur()"
|
|
19706
|
+
>
|
|
19707
|
+
@if (placeholder()) {
|
|
19708
|
+
<option value="" [disabled]="required()">{{ placeholder() }}</option>
|
|
19709
|
+
}
|
|
19710
|
+
|
|
19711
|
+
@for (option of options(); track option.label + ':' + option.value) {
|
|
19712
|
+
<option [value]="option.value" [disabled]="option.disabled ?? false">{{ option.label }}</option>
|
|
19713
|
+
}
|
|
19714
|
+
</select>
|
|
19715
|
+
`, isInline: true, styles: [".jv-select{width:100%;min-height:var(--jv-density-control-height);padding:0 var(--jv-spacing-md);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md);background:var(--jv-color-surface);color:var(--jv-color-foreground)}.jv-select.is-invalid{border-color:var(--jv-color-danger)}\n"] });
|
|
19716
|
+
}
|
|
19717
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvSelectComponent, decorators: [{
|
|
19718
|
+
type: Component,
|
|
19719
|
+
args: [{ selector: 'jv-select', standalone: true, providers: [
|
|
19720
|
+
{
|
|
19721
|
+
provide: NG_VALUE_ACCESSOR,
|
|
19722
|
+
useExisting: forwardRef(() => JvSelectComponent),
|
|
19723
|
+
multi: true,
|
|
19724
|
+
},
|
|
19725
|
+
], template: `
|
|
19726
|
+
<select
|
|
19727
|
+
class="jv-select"
|
|
19728
|
+
[class.is-invalid]="invalid()"
|
|
19729
|
+
[id]="inputId()"
|
|
19730
|
+
[disabled]="disabled"
|
|
19731
|
+
[required]="required()"
|
|
19732
|
+
[attr.aria-invalid]="invalid() ? 'true' : null"
|
|
19733
|
+
[attr.aria-describedby]="describedBy() || null"
|
|
19734
|
+
[value]="currentValue()"
|
|
19735
|
+
(change)="handleChange($event)"
|
|
19736
|
+
(blur)="handleBlur()"
|
|
19737
|
+
>
|
|
19738
|
+
@if (placeholder()) {
|
|
19739
|
+
<option value="" [disabled]="required()">{{ placeholder() }}</option>
|
|
19740
|
+
}
|
|
19741
|
+
|
|
19742
|
+
@for (option of options(); track option.label + ':' + option.value) {
|
|
19743
|
+
<option [value]="option.value" [disabled]="option.disabled ?? false">{{ option.label }}</option>
|
|
19744
|
+
}
|
|
19745
|
+
</select>
|
|
19746
|
+
`, styles: [".jv-select{width:100%;min-height:var(--jv-density-control-height);padding:0 var(--jv-spacing-md);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md);background:var(--jv-color-surface);color:var(--jv-color-foreground)}.jv-select.is-invalid{border-color:var(--jv-color-danger)}\n"] }]
|
|
19747
|
+
}], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], describedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "describedBy", required: false }] }], inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], modelValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "modelValue", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }] } });
|
|
19748
|
+
|
|
19749
|
+
let datePickerIdSequence = 0;
|
|
19750
|
+
class JvDatePickerComponent {
|
|
19751
|
+
translation = inject(JvTranslationService);
|
|
19752
|
+
announcementService = inject(JvAnnouncementService);
|
|
19753
|
+
instanceId = ++datePickerIdSequence;
|
|
19754
|
+
calendarRootRef = viewChild('calendarRoot', ...(ngDevMode ? [{ debugName: "calendarRootRef" }] : /* istanbul ignore next */ []));
|
|
19755
|
+
triggerButtonRef = viewChild('triggerButton', ...(ngDevMode ? [{ debugName: "triggerButtonRef" }] : /* istanbul ignore next */ []));
|
|
19756
|
+
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
19757
|
+
placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
19758
|
+
dialogTitle = input('', ...(ngDevMode ? [{ debugName: "dialogTitle" }] : /* istanbul ignore next */ []));
|
|
19759
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
19760
|
+
invalid = input(false, ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
|
|
19761
|
+
hint = input('', ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
19762
|
+
error = input('', ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
|
|
19763
|
+
describedBy = input('', ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
|
|
19764
|
+
inputId = input(`jv-date-picker-${this.instanceId}`, ...(ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []));
|
|
19765
|
+
valueInput = input(undefined, { ...(ngDevMode ? { debugName: "valueInput" } : /* istanbul ignore next */ {}), alias: 'value' });
|
|
19766
|
+
selectionChange = output();
|
|
19767
|
+
dialogOpen = signal(false, ...(ngDevMode ? [{ debugName: "dialogOpen" }] : /* istanbul ignore next */ []));
|
|
19768
|
+
visibleMonth = signal(firstOfMonth(new Date()), ...(ngDevMode ? [{ debugName: "visibleMonth" }] : /* istanbul ignore next */ []));
|
|
19769
|
+
focusedDate = signal(startOfDay(new Date()), ...(ngDevMode ? [{ debugName: "focusedDate" }] : /* istanbul ignore next */ []));
|
|
19770
|
+
dialogId = `jv-date-picker-dialog-${this.instanceId}`;
|
|
19771
|
+
value = null;
|
|
19772
|
+
disabled = false;
|
|
19773
|
+
resolvedDialogTitle = computed(() => this.dialogTitle() || this.translation.translate('datePicker.dialogTitle'), ...(ngDevMode ? [{ debugName: "resolvedDialogTitle" }] : /* istanbul ignore next */ []));
|
|
19774
|
+
currentValue = computed(() => this.valueInput() !== undefined ? this.valueInput() : this.value, ...(ngDevMode ? [{ debugName: "currentValue" }] : /* istanbul ignore next */ []));
|
|
19775
|
+
triggerAriaLabel = computed(() => {
|
|
19776
|
+
const name = this.label() || this.resolvedDialogTitle();
|
|
19777
|
+
return `${name}. ${this.displayValue()}`;
|
|
19778
|
+
}, ...(ngDevMode ? [{ debugName: "triggerAriaLabel" }] : /* istanbul ignore next */ []));
|
|
19779
|
+
displayValue = computed(() => {
|
|
19780
|
+
const value = this.currentValue();
|
|
19781
|
+
if (!value) {
|
|
19782
|
+
return this.placeholder() || this.translation.translate('datePicker.placeholder');
|
|
19783
|
+
}
|
|
19784
|
+
return new Intl.DateTimeFormat(this.translation.locale(), {
|
|
19785
|
+
day: '2-digit',
|
|
19786
|
+
month: '2-digit',
|
|
19787
|
+
year: 'numeric',
|
|
19788
|
+
}).format(value);
|
|
19789
|
+
}, ...(ngDevMode ? [{ debugName: "displayValue" }] : /* istanbul ignore next */ []));
|
|
19790
|
+
monthOptions = computed(() => {
|
|
19791
|
+
const formatter = new Intl.DateTimeFormat(this.translation.locale(), { month: 'long' });
|
|
19792
|
+
return Array.from({ length: 12 }, (_, month) => ({
|
|
19793
|
+
label: capitalize(formatter.format(new Date(2026, month, 1))),
|
|
19794
|
+
value: String(month),
|
|
19795
|
+
}));
|
|
19796
|
+
}, ...(ngDevMode ? [{ debugName: "monthOptions" }] : /* istanbul ignore next */ []));
|
|
19797
|
+
yearOptions = computed(() => {
|
|
19798
|
+
return Array.from({ length: 201 }, (_, index) => {
|
|
19799
|
+
const year = 1900 + index;
|
|
19800
|
+
return { label: String(year), value: String(year) };
|
|
19801
|
+
});
|
|
19802
|
+
}, ...(ngDevMode ? [{ debugName: "yearOptions" }] : /* istanbul ignore next */ []));
|
|
19803
|
+
weekdayLabels = computed(() => {
|
|
19804
|
+
const startDay = this.firstDayOfWeek();
|
|
19805
|
+
const formatter = new Intl.DateTimeFormat(this.translation.locale(), { weekday: 'short' });
|
|
19806
|
+
return Array.from({ length: 7 }, (_, index) => capitalize(formatter.format(addDays(new Date(2026, 5, 7), startDay + index))));
|
|
19807
|
+
}, ...(ngDevMode ? [{ debugName: "weekdayLabels" }] : /* istanbul ignore next */ []));
|
|
19808
|
+
calendarCells = computed(() => {
|
|
19809
|
+
const month = this.visibleMonth();
|
|
19810
|
+
const firstDay = firstOfMonth(month);
|
|
19811
|
+
const daysInCurrentMonth = daysInMonth(month.getFullYear(), month.getMonth());
|
|
19812
|
+
const startOffset = (firstDay.getDay() - this.firstDayOfWeek() + 7) % 7;
|
|
19813
|
+
const gridStart = addDays(firstDay, -startOffset);
|
|
19814
|
+
return Array.from({ length: 42 }, (_, index) => {
|
|
19815
|
+
const date = addDays(gridStart, index);
|
|
19816
|
+
return {
|
|
19817
|
+
date,
|
|
19818
|
+
currentMonth: date.getMonth() === month.getMonth(),
|
|
19819
|
+
isToday: sameDate(date, new Date()),
|
|
19820
|
+
};
|
|
19821
|
+
}).slice(0, Math.ceil((startOffset + daysInCurrentMonth) / 7) * 7);
|
|
19822
|
+
}, ...(ngDevMode ? [{ debugName: "calendarCells" }] : /* istanbul ignore next */ []));
|
|
19823
|
+
onChange = () => undefined;
|
|
19824
|
+
onTouched = () => undefined;
|
|
19825
|
+
writeValue(value) {
|
|
19826
|
+
this.value = value ? startOfDay(value) : null;
|
|
19827
|
+
}
|
|
19828
|
+
registerOnChange(fn) {
|
|
19829
|
+
this.onChange = fn;
|
|
19830
|
+
}
|
|
19831
|
+
registerOnTouched(fn) {
|
|
19832
|
+
this.onTouched = fn;
|
|
19833
|
+
}
|
|
19834
|
+
setDisabledState(isDisabled) {
|
|
19835
|
+
this.disabled = isDisabled;
|
|
19836
|
+
}
|
|
19837
|
+
openDialog() {
|
|
19838
|
+
if (this.disabled) {
|
|
19839
|
+
return;
|
|
19840
|
+
}
|
|
19841
|
+
const baseDate = this.currentValue() ?? startOfDay(new Date());
|
|
19842
|
+
this.visibleMonth.set(firstOfMonth(baseDate));
|
|
19843
|
+
this.focusedDate.set(baseDate);
|
|
19844
|
+
this.dialogOpen.set(true);
|
|
19845
|
+
queueMicrotask(() => this.focusDateButton(baseDate));
|
|
19846
|
+
}
|
|
19847
|
+
closeDialog() {
|
|
19848
|
+
this.dialogOpen.set(false);
|
|
19849
|
+
this.handleBlur();
|
|
19850
|
+
queueMicrotask(() => this.triggerButtonRef()?.nativeElement.focus());
|
|
19851
|
+
}
|
|
19852
|
+
clearSelection() {
|
|
19853
|
+
this.updateValue(null);
|
|
19854
|
+
this.announcementService.announce(this.translation.translate('datePicker.selectionCleared'), 'polite');
|
|
19855
|
+
this.closeDialog();
|
|
19856
|
+
}
|
|
19857
|
+
shiftMonth(offset) {
|
|
19858
|
+
const month = this.visibleMonth();
|
|
19859
|
+
const nextMonth = firstOfMonth(new Date(month.getFullYear(), month.getMonth() + offset, 1));
|
|
19860
|
+
this.visibleMonth.set(nextMonth);
|
|
19861
|
+
this.focusDateWithinVisibleMonth(this.focusedDate());
|
|
19862
|
+
}
|
|
19863
|
+
handleMonthChange(value) {
|
|
19864
|
+
const month = Number(value);
|
|
19865
|
+
const current = this.visibleMonth();
|
|
19866
|
+
this.visibleMonth.set(firstOfMonth(new Date(current.getFullYear(), month, 1)));
|
|
19867
|
+
this.focusDateWithinVisibleMonth(this.focusedDate());
|
|
19868
|
+
}
|
|
19869
|
+
handleYearChange(value) {
|
|
19870
|
+
const year = Number(value);
|
|
19871
|
+
const current = this.visibleMonth();
|
|
19872
|
+
this.visibleMonth.set(firstOfMonth(new Date(year, current.getMonth(), 1)));
|
|
19873
|
+
this.focusDateWithinVisibleMonth(this.focusedDate());
|
|
19874
|
+
}
|
|
19875
|
+
selectDate(date) {
|
|
19876
|
+
const nextValue = startOfDay(date);
|
|
19877
|
+
this.updateValue(nextValue);
|
|
19878
|
+
this.announcementService.announce(this.displayDateForAnnouncement(nextValue), 'polite');
|
|
19879
|
+
this.closeDialog();
|
|
19880
|
+
}
|
|
19881
|
+
handleDayKeydown(event, date) {
|
|
19882
|
+
let nextDate = null;
|
|
19883
|
+
switch (event.key) {
|
|
19884
|
+
case 'ArrowRight':
|
|
19885
|
+
nextDate = addDays(date, 1);
|
|
19886
|
+
break;
|
|
19887
|
+
case 'ArrowLeft':
|
|
19888
|
+
nextDate = addDays(date, -1);
|
|
19889
|
+
break;
|
|
19890
|
+
case 'ArrowDown':
|
|
19891
|
+
nextDate = addDays(date, 7);
|
|
19892
|
+
break;
|
|
19893
|
+
case 'ArrowUp':
|
|
19894
|
+
nextDate = addDays(date, -7);
|
|
19895
|
+
break;
|
|
19896
|
+
case 'Home':
|
|
19897
|
+
nextDate = addDays(date, -((date.getDay() - this.firstDayOfWeek() + 7) % 7));
|
|
19898
|
+
break;
|
|
19899
|
+
case 'End':
|
|
19900
|
+
nextDate = addDays(date, 6 - ((date.getDay() - this.firstDayOfWeek() + 7) % 7));
|
|
19901
|
+
break;
|
|
19902
|
+
case 'Enter':
|
|
19903
|
+
case ' ':
|
|
19904
|
+
event.preventDefault();
|
|
19905
|
+
this.selectDate(date);
|
|
19906
|
+
return;
|
|
19907
|
+
}
|
|
19908
|
+
if (!nextDate) {
|
|
19909
|
+
return;
|
|
19910
|
+
}
|
|
19911
|
+
event.preventDefault();
|
|
19912
|
+
this.focusedDate.set(nextDate);
|
|
19913
|
+
this.visibleMonth.set(firstOfMonth(nextDate));
|
|
19914
|
+
queueMicrotask(() => this.focusDateButton(nextDate));
|
|
19915
|
+
}
|
|
19916
|
+
isSelected(date) {
|
|
19917
|
+
return sameDate(date, this.currentValue());
|
|
19918
|
+
}
|
|
19919
|
+
isFocusedDate(date) {
|
|
19920
|
+
return sameDate(date, this.focusedDate());
|
|
19921
|
+
}
|
|
19922
|
+
isoDate(date) {
|
|
19923
|
+
const year = date.getFullYear();
|
|
19924
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
19925
|
+
const day = String(date.getDate()).padStart(2, '0');
|
|
19926
|
+
return `${year}-${month}-${day}`;
|
|
19927
|
+
}
|
|
19928
|
+
handleBlur() {
|
|
19929
|
+
this.onTouched();
|
|
19930
|
+
}
|
|
19931
|
+
updateValue(value) {
|
|
19932
|
+
this.value = value;
|
|
19933
|
+
this.onChange(value);
|
|
19934
|
+
this.selectionChange.emit(value);
|
|
19935
|
+
}
|
|
19936
|
+
focusDateWithinVisibleMonth(date) {
|
|
19937
|
+
const month = this.visibleMonth();
|
|
19938
|
+
const nextDate = startOfDay(new Date(month.getFullYear(), month.getMonth(), Math.min(date.getDate(), daysInMonth(month.getFullYear(), month.getMonth()))));
|
|
19939
|
+
this.focusedDate.set(nextDate);
|
|
19940
|
+
queueMicrotask(() => this.focusDateButton(nextDate));
|
|
19941
|
+
}
|
|
19942
|
+
focusDateButton(date) {
|
|
19943
|
+
const root = this.calendarRootRef()?.nativeElement;
|
|
19944
|
+
root?.querySelector(`[data-jv-date="${this.isoDate(date)}"]`)?.focus();
|
|
19945
|
+
}
|
|
19946
|
+
firstDayOfWeek() {
|
|
19947
|
+
return this.translation.locale() === 'es' ? 1 : 0;
|
|
19948
|
+
}
|
|
19949
|
+
displayDateForAnnouncement(date) {
|
|
19950
|
+
return new Intl.DateTimeFormat(this.translation.locale(), {
|
|
19951
|
+
weekday: 'long',
|
|
19952
|
+
day: 'numeric',
|
|
19953
|
+
month: 'long',
|
|
19954
|
+
year: 'numeric',
|
|
19955
|
+
}).format(date);
|
|
19956
|
+
}
|
|
19957
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvDatePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
19958
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvDatePickerComponent, isStandalone: true, selector: "jv-date-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, dialogTitle: { classPropertyName: "dialogTitle", publicName: "dialogTitle", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, describedBy: { classPropertyName: "describedBy", publicName: "describedBy", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, valueInput: { classPropertyName: "valueInput", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, providers: [
|
|
19959
|
+
{
|
|
19960
|
+
provide: NG_VALUE_ACCESSOR,
|
|
19961
|
+
useExisting: forwardRef(() => JvDatePickerComponent),
|
|
19962
|
+
multi: true,
|
|
19963
|
+
},
|
|
19964
|
+
], viewQueries: [{ propertyName: "calendarRootRef", first: true, predicate: ["calendarRoot"], descendants: true, isSignal: true }, { propertyName: "triggerButtonRef", first: true, predicate: ["triggerButton"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
19965
|
+
<jv-form-container
|
|
19966
|
+
[label]="label()"
|
|
19967
|
+
[inputId]="inputId()"
|
|
19968
|
+
[required]="required()"
|
|
19969
|
+
[invalid]="invalid()"
|
|
19970
|
+
[hint]="hint()"
|
|
19971
|
+
[error]="error()"
|
|
19972
|
+
>
|
|
19973
|
+
<button
|
|
19974
|
+
#triggerButton
|
|
19975
|
+
type="button"
|
|
19976
|
+
class="jv-date-picker-trigger"
|
|
19977
|
+
[class.is-invalid]="invalid()"
|
|
19978
|
+
[id]="inputId()"
|
|
19979
|
+
[disabled]="disabled"
|
|
19980
|
+
[attr.aria-haspopup]="'dialog'"
|
|
19981
|
+
[attr.aria-expanded]="dialogOpen() ? 'true' : 'false'"
|
|
19982
|
+
[attr.aria-controls]="dialogId"
|
|
19983
|
+
[attr.aria-invalid]="invalid() ? 'true' : null"
|
|
19984
|
+
[attr.aria-describedby]="describedBy() || null"
|
|
19985
|
+
[attr.aria-label]="triggerAriaLabel()"
|
|
19986
|
+
[attr.title]="displayValue()"
|
|
19987
|
+
(click)="openDialog()"
|
|
19988
|
+
(blur)="handleBlur()"
|
|
19989
|
+
>
|
|
19990
|
+
<span [class.jv-date-picker-placeholder]="!currentValue()">{{ displayValue() }}</span>
|
|
19991
|
+
<jv-icon name="calendar-days" [size]="18" />
|
|
19992
|
+
</button>
|
|
19993
|
+
</jv-form-container>
|
|
19994
|
+
|
|
19995
|
+
<jv-dialog [open]="dialogOpen()" [title]="resolvedDialogTitle()" (closed)="closeDialog()">
|
|
19996
|
+
<div #calendarRoot [id]="dialogId" class="jv-date-picker-dialog">
|
|
19997
|
+
<div class="jv-date-picker-toolbar">
|
|
19998
|
+
<jv-icon-button icon="chevron-left" variant="ghost" [ariaLabel]="translation.translate('datePicker.prevMonth')" (click)="shiftMonth(-1)" />
|
|
19999
|
+
|
|
20000
|
+
<div class="jv-date-picker-selects">
|
|
20001
|
+
<jv-select [options]="monthOptions()" [modelValue]="visibleMonth().getMonth().toString()" (selectionChange)="handleMonthChange($event)" />
|
|
20002
|
+
<jv-select [options]="yearOptions()" [modelValue]="visibleMonth().getFullYear().toString()" (selectionChange)="handleYearChange($event)" />
|
|
20003
|
+
</div>
|
|
20004
|
+
|
|
20005
|
+
<jv-icon-button icon="chevron-right" variant="ghost" [ariaLabel]="translation.translate('datePicker.nextMonth')" (click)="shiftMonth(1)" />
|
|
20006
|
+
</div>
|
|
20007
|
+
|
|
20008
|
+
<div class="jv-date-picker-weekdays" aria-hidden="true">
|
|
20009
|
+
@for (weekday of weekdayLabels(); track weekday) {
|
|
20010
|
+
<span>{{ weekday }}</span>
|
|
20011
|
+
}
|
|
20012
|
+
</div>
|
|
20013
|
+
|
|
20014
|
+
<div class="jv-date-picker-grid" role="grid" [attr.aria-label]="resolvedDialogTitle()">
|
|
20015
|
+
@for (cell of calendarCells(); track isoDate(cell.date)) {
|
|
20016
|
+
<button
|
|
20017
|
+
type="button"
|
|
20018
|
+
class="jv-date-picker-day"
|
|
20019
|
+
[class.jv-date-picker-day--outside]="!cell.currentMonth"
|
|
20020
|
+
[class.jv-date-picker-day--today]="cell.isToday"
|
|
20021
|
+
[class.jv-date-picker-day--selected]="isSelected(cell.date)"
|
|
20022
|
+
[attr.data-jv-date]="isoDate(cell.date)"
|
|
20023
|
+
[attr.tabindex]="isFocusedDate(cell.date) ? 0 : -1"
|
|
20024
|
+
[attr.aria-selected]="isSelected(cell.date) ? 'true' : 'false'"
|
|
20025
|
+
(click)="selectDate(cell.date)"
|
|
20026
|
+
(keydown)="handleDayKeydown($event, cell.date)"
|
|
20027
|
+
>
|
|
20028
|
+
{{ cell.date.getDate() }}
|
|
20029
|
+
</button>
|
|
20030
|
+
}
|
|
20031
|
+
</div>
|
|
20032
|
+
</div>
|
|
20033
|
+
|
|
20034
|
+
<div dialog-actions class="jv-date-picker-actions">
|
|
20035
|
+
@if (currentValue()) {
|
|
20036
|
+
<jv-button variant="ghost" (click)="clearSelection()">{{ translation.translate('datePicker.clear') }}</jv-button>
|
|
20037
|
+
}
|
|
20038
|
+
<jv-button variant="outline" (click)="closeDialog()">{{ translation.translate('datePicker.close') }}</jv-button>
|
|
20039
|
+
</div>
|
|
20040
|
+
</jv-dialog>
|
|
20041
|
+
`, isInline: true, styles: [".jv-date-picker-trigger{width:100%;min-height:var(--jv-density-control-height);display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-sm);padding:0 var(--jv-spacing-md);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md);background:var(--jv-color-surface);color:var(--jv-color-foreground);text-align:left;font:inherit;cursor:pointer}.jv-date-picker-trigger.is-invalid{border-color:var(--jv-color-danger)}.jv-date-picker-trigger:disabled{opacity:.7;cursor:not-allowed}.jv-date-picker-trigger:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:1px}.jv-date-picker-placeholder{color:var(--jv-color-foreground-muted)}.jv-date-picker-dialog,.jv-date-picker-actions{display:grid;gap:var(--jv-spacing-md)}.jv-date-picker-toolbar,.jv-date-picker-selects,.jv-date-picker-weekdays,.jv-date-picker-grid{display:grid;gap:var(--jv-spacing-sm)}.jv-date-picker-toolbar{grid-template-columns:auto 1fr auto;align-items:center}.jv-date-picker-selects{grid-template-columns:1fr 1fr}.jv-date-picker-weekdays,.jv-date-picker-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.jv-date-picker-weekdays span{text-align:center;font-size:.8125rem;font-weight:600;color:var(--jv-color-foreground-muted)}.jv-date-picker-day{min-height:2.5rem;border:1px solid transparent;border-radius:var(--jv-radius-md);background:transparent;color:var(--jv-color-foreground);font:inherit;cursor:pointer;transition:background-color .16s ease,border-color .16s ease,color .16s ease}.jv-date-picker-day:hover,.jv-date-picker-day:focus-visible{background:var(--jv-color-surface-muted)}.jv-date-picker-day:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:1px}.jv-date-picker-day--outside{color:var(--jv-color-foreground-muted)}.jv-date-picker-day--today{border-color:var(--jv-color-primary)}.jv-date-picker-day--selected{background:var(--jv-color-primary);color:#fff}\n"], dependencies: [{ kind: "component", type: JvButtonComponent, selector: "jv-button", inputs: ["type", "variant", "icon", "iconPosition", "loading", "disabled"] }, { kind: "component", type: JvDialogComponent, selector: "jv-dialog", inputs: ["open", "title"], outputs: ["closed"] }, { kind: "component", type: JvFormContainerComponent, selector: "jv-form-container", inputs: ["label", "hint", "error", "inputId", "hintId", "errorId", "required", "invalid"] }, { kind: "component", type: JvIconButtonComponent, selector: "jv-icon-button", inputs: ["icon", "ariaLabel", "variant", "disabled"] }, { kind: "component", type: JvIconComponent, selector: "jv-icon", inputs: ["name", "size", "strokeWidth", "decorative", "ariaLabel"] }, { kind: "component", type: JvSelectComponent, selector: "jv-select", inputs: ["options", "placeholder", "required", "invalid", "describedBy", "inputId", "modelValue"], outputs: ["selectionChange"] }] });
|
|
20042
|
+
}
|
|
20043
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvDatePickerComponent, decorators: [{
|
|
20044
|
+
type: Component,
|
|
20045
|
+
args: [{ selector: 'jv-date-picker', standalone: true, imports: [JvButtonComponent, JvDialogComponent, JvFormContainerComponent, JvIconButtonComponent, JvIconComponent, JvSelectComponent], providers: [
|
|
20046
|
+
{
|
|
20047
|
+
provide: NG_VALUE_ACCESSOR,
|
|
20048
|
+
useExisting: forwardRef(() => JvDatePickerComponent),
|
|
20049
|
+
multi: true,
|
|
20050
|
+
},
|
|
20051
|
+
], template: `
|
|
20052
|
+
<jv-form-container
|
|
20053
|
+
[label]="label()"
|
|
20054
|
+
[inputId]="inputId()"
|
|
20055
|
+
[required]="required()"
|
|
20056
|
+
[invalid]="invalid()"
|
|
20057
|
+
[hint]="hint()"
|
|
20058
|
+
[error]="error()"
|
|
20059
|
+
>
|
|
20060
|
+
<button
|
|
20061
|
+
#triggerButton
|
|
20062
|
+
type="button"
|
|
20063
|
+
class="jv-date-picker-trigger"
|
|
20064
|
+
[class.is-invalid]="invalid()"
|
|
20065
|
+
[id]="inputId()"
|
|
20066
|
+
[disabled]="disabled"
|
|
20067
|
+
[attr.aria-haspopup]="'dialog'"
|
|
20068
|
+
[attr.aria-expanded]="dialogOpen() ? 'true' : 'false'"
|
|
20069
|
+
[attr.aria-controls]="dialogId"
|
|
20070
|
+
[attr.aria-invalid]="invalid() ? 'true' : null"
|
|
20071
|
+
[attr.aria-describedby]="describedBy() || null"
|
|
20072
|
+
[attr.aria-label]="triggerAriaLabel()"
|
|
20073
|
+
[attr.title]="displayValue()"
|
|
20074
|
+
(click)="openDialog()"
|
|
20075
|
+
(blur)="handleBlur()"
|
|
20076
|
+
>
|
|
20077
|
+
<span [class.jv-date-picker-placeholder]="!currentValue()">{{ displayValue() }}</span>
|
|
20078
|
+
<jv-icon name="calendar-days" [size]="18" />
|
|
20079
|
+
</button>
|
|
20080
|
+
</jv-form-container>
|
|
20081
|
+
|
|
20082
|
+
<jv-dialog [open]="dialogOpen()" [title]="resolvedDialogTitle()" (closed)="closeDialog()">
|
|
20083
|
+
<div #calendarRoot [id]="dialogId" class="jv-date-picker-dialog">
|
|
20084
|
+
<div class="jv-date-picker-toolbar">
|
|
20085
|
+
<jv-icon-button icon="chevron-left" variant="ghost" [ariaLabel]="translation.translate('datePicker.prevMonth')" (click)="shiftMonth(-1)" />
|
|
20086
|
+
|
|
20087
|
+
<div class="jv-date-picker-selects">
|
|
20088
|
+
<jv-select [options]="monthOptions()" [modelValue]="visibleMonth().getMonth().toString()" (selectionChange)="handleMonthChange($event)" />
|
|
20089
|
+
<jv-select [options]="yearOptions()" [modelValue]="visibleMonth().getFullYear().toString()" (selectionChange)="handleYearChange($event)" />
|
|
20090
|
+
</div>
|
|
20091
|
+
|
|
20092
|
+
<jv-icon-button icon="chevron-right" variant="ghost" [ariaLabel]="translation.translate('datePicker.nextMonth')" (click)="shiftMonth(1)" />
|
|
20093
|
+
</div>
|
|
20094
|
+
|
|
20095
|
+
<div class="jv-date-picker-weekdays" aria-hidden="true">
|
|
20096
|
+
@for (weekday of weekdayLabels(); track weekday) {
|
|
20097
|
+
<span>{{ weekday }}</span>
|
|
20098
|
+
}
|
|
20099
|
+
</div>
|
|
20100
|
+
|
|
20101
|
+
<div class="jv-date-picker-grid" role="grid" [attr.aria-label]="resolvedDialogTitle()">
|
|
20102
|
+
@for (cell of calendarCells(); track isoDate(cell.date)) {
|
|
20103
|
+
<button
|
|
20104
|
+
type="button"
|
|
20105
|
+
class="jv-date-picker-day"
|
|
20106
|
+
[class.jv-date-picker-day--outside]="!cell.currentMonth"
|
|
20107
|
+
[class.jv-date-picker-day--today]="cell.isToday"
|
|
20108
|
+
[class.jv-date-picker-day--selected]="isSelected(cell.date)"
|
|
20109
|
+
[attr.data-jv-date]="isoDate(cell.date)"
|
|
20110
|
+
[attr.tabindex]="isFocusedDate(cell.date) ? 0 : -1"
|
|
20111
|
+
[attr.aria-selected]="isSelected(cell.date) ? 'true' : 'false'"
|
|
20112
|
+
(click)="selectDate(cell.date)"
|
|
20113
|
+
(keydown)="handleDayKeydown($event, cell.date)"
|
|
20114
|
+
>
|
|
20115
|
+
{{ cell.date.getDate() }}
|
|
20116
|
+
</button>
|
|
20117
|
+
}
|
|
20118
|
+
</div>
|
|
20119
|
+
</div>
|
|
20120
|
+
|
|
20121
|
+
<div dialog-actions class="jv-date-picker-actions">
|
|
20122
|
+
@if (currentValue()) {
|
|
20123
|
+
<jv-button variant="ghost" (click)="clearSelection()">{{ translation.translate('datePicker.clear') }}</jv-button>
|
|
20124
|
+
}
|
|
20125
|
+
<jv-button variant="outline" (click)="closeDialog()">{{ translation.translate('datePicker.close') }}</jv-button>
|
|
20126
|
+
</div>
|
|
20127
|
+
</jv-dialog>
|
|
20128
|
+
`, styles: [".jv-date-picker-trigger{width:100%;min-height:var(--jv-density-control-height);display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-sm);padding:0 var(--jv-spacing-md);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md);background:var(--jv-color-surface);color:var(--jv-color-foreground);text-align:left;font:inherit;cursor:pointer}.jv-date-picker-trigger.is-invalid{border-color:var(--jv-color-danger)}.jv-date-picker-trigger:disabled{opacity:.7;cursor:not-allowed}.jv-date-picker-trigger:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:1px}.jv-date-picker-placeholder{color:var(--jv-color-foreground-muted)}.jv-date-picker-dialog,.jv-date-picker-actions{display:grid;gap:var(--jv-spacing-md)}.jv-date-picker-toolbar,.jv-date-picker-selects,.jv-date-picker-weekdays,.jv-date-picker-grid{display:grid;gap:var(--jv-spacing-sm)}.jv-date-picker-toolbar{grid-template-columns:auto 1fr auto;align-items:center}.jv-date-picker-selects{grid-template-columns:1fr 1fr}.jv-date-picker-weekdays,.jv-date-picker-grid{grid-template-columns:repeat(7,minmax(0,1fr))}.jv-date-picker-weekdays span{text-align:center;font-size:.8125rem;font-weight:600;color:var(--jv-color-foreground-muted)}.jv-date-picker-day{min-height:2.5rem;border:1px solid transparent;border-radius:var(--jv-radius-md);background:transparent;color:var(--jv-color-foreground);font:inherit;cursor:pointer;transition:background-color .16s ease,border-color .16s ease,color .16s ease}.jv-date-picker-day:hover,.jv-date-picker-day:focus-visible{background:var(--jv-color-surface-muted)}.jv-date-picker-day:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:1px}.jv-date-picker-day--outside{color:var(--jv-color-foreground-muted)}.jv-date-picker-day--today{border-color:var(--jv-color-primary)}.jv-date-picker-day--selected{background:var(--jv-color-primary);color:#fff}\n"] }]
|
|
20129
|
+
}], propDecorators: { calendarRootRef: [{ type: i0.ViewChild, args: ['calendarRoot', { isSignal: true }] }], triggerButtonRef: [{ type: i0.ViewChild, args: ['triggerButton', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], dialogTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "dialogTitle", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], describedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "describedBy", required: false }] }], inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], valueInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }] } });
|
|
20130
|
+
function daysInMonth(year, month) {
|
|
20131
|
+
return new Date(year, month + 1, 0).getDate();
|
|
20132
|
+
}
|
|
20133
|
+
function firstOfMonth(date) {
|
|
20134
|
+
return new Date(date.getFullYear(), date.getMonth(), 1);
|
|
20135
|
+
}
|
|
20136
|
+
function startOfDay(date) {
|
|
20137
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
20138
|
+
}
|
|
20139
|
+
function addDays(date, amount) {
|
|
20140
|
+
return startOfDay(new Date(date.getFullYear(), date.getMonth(), date.getDate() + amount));
|
|
20141
|
+
}
|
|
20142
|
+
function sameDate(left, right) {
|
|
20143
|
+
if (!left || !right) {
|
|
20144
|
+
return false;
|
|
20145
|
+
}
|
|
20146
|
+
return left.getFullYear() === right.getFullYear() && left.getMonth() === right.getMonth() && left.getDate() === right.getDate();
|
|
20147
|
+
}
|
|
20148
|
+
function capitalize(value) {
|
|
20149
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
20150
|
+
}
|
|
20151
|
+
|
|
20152
|
+
class JvListComponent {
|
|
20153
|
+
role = input('list', ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
|
|
20154
|
+
ariaRole = input(null, ...(ngDevMode ? [{ debugName: "ariaRole" }] : /* istanbul ignore next */ []));
|
|
20155
|
+
variant = input(null, ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
20156
|
+
ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
20157
|
+
variantClass = computed(() => {
|
|
20158
|
+
const v = this.variant();
|
|
20159
|
+
return v ? `jv-list--${v}` : '';
|
|
20160
|
+
}, ...(ngDevMode ? [{ debugName: "variantClass" }] : /* istanbul ignore next */ []));
|
|
20161
|
+
resolvedRole = computed(() => this.ariaRole() ?? (this.role() === 'navigation' ? 'list' : null), ...(ngDevMode ? [{ debugName: "resolvedRole" }] : /* istanbul ignore next */ []));
|
|
20162
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20163
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.17", type: JvListComponent, isStandalone: true, selector: "jv-list", inputs: { role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, ariaRole: { classPropertyName: "ariaRole", publicName: "ariaRole", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
20164
|
+
<ul
|
|
20165
|
+
class="jv-list"
|
|
20166
|
+
[class]="variantClass()"
|
|
20167
|
+
[attr.role]="resolvedRole()"
|
|
20168
|
+
[attr.aria-label]="ariaLabel()"
|
|
20169
|
+
>
|
|
20170
|
+
<ng-content />
|
|
20171
|
+
</ul>
|
|
20172
|
+
`, isInline: true, styles: [".jv-list{display:block;list-style:none;margin:0;padding:0}.jv-list>:not(:last-child){border-bottom:1px solid var(--jv-color-border)}.jv-list--bordered{border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md)}\n"] });
|
|
20173
|
+
}
|
|
20174
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvListComponent, decorators: [{
|
|
19103
20175
|
type: Component,
|
|
19104
|
-
args: [{ selector: 'jv-
|
|
19105
|
-
|
|
19106
|
-
|
|
19107
|
-
|
|
19108
|
-
|
|
19109
|
-
|
|
19110
|
-
|
|
19111
|
-
|
|
19112
|
-
|
|
19113
|
-
|
|
19114
|
-
|
|
19115
|
-
|
|
19116
|
-
<button type="button" class="jv-toast-close" (click)="toastService.dismiss(toast.id)" aria-label="Dismiss notification">
|
|
19117
|
-
<jv-icon name="x" [size]="16" />
|
|
19118
|
-
</button>
|
|
19119
|
-
</article>
|
|
19120
|
-
}
|
|
19121
|
-
</div>
|
|
19122
|
-
}
|
|
19123
|
-
`, styles: [".jv-toast-viewport{position:fixed;z-index:1100;display:grid;gap:var(--jv-spacing-sm);width:min(360px,calc(100vw - 2rem))}.is-top-left{top:1rem;left:1rem}.is-top-center{top:1rem;left:50%;transform:translate(-50%)}.is-top-right{top:1rem;right:1rem}.is-bottom-left{bottom:1rem;left:1rem}.is-bottom-center{bottom:1rem;left:50%;transform:translate(-50%)}.is-bottom-right{bottom:1rem;right:1rem}.jv-toast-item{display:grid;grid-template-columns:1fr auto;gap:var(--jv-spacing-sm);padding:var(--jv-spacing-md);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md);background:var(--jv-color-surface);box-shadow:var(--jv-shadow-lg)}.jv-toast-copy strong,.jv-toast-copy p{margin:0}.jv-toast-copy{display:grid;gap:.25rem}.jv-toast-copy p{color:var(--jv-color-foreground-muted)}.jv-toast-close{display:inline-grid;place-items:center;width:2rem;height:2rem;border:0;border-radius:999px;background:transparent;color:inherit}.jv-toast--success{border-color:color-mix(in srgb,var(--jv-color-success) 35%,var(--jv-color-border))}.jv-toast--warning{border-color:color-mix(in srgb,var(--jv-color-warning) 35%,var(--jv-color-border))}.jv-toast--danger{border-color:color-mix(in srgb,var(--jv-color-danger) 35%,var(--jv-color-border))}.jv-toast--info,.jv-toast--primary{border-color:color-mix(in srgb,var(--jv-color-primary) 35%,var(--jv-color-border))}\n"] }]
|
|
19124
|
-
}] });
|
|
20176
|
+
args: [{ selector: 'jv-list', standalone: true, template: `
|
|
20177
|
+
<ul
|
|
20178
|
+
class="jv-list"
|
|
20179
|
+
[class]="variantClass()"
|
|
20180
|
+
[attr.role]="resolvedRole()"
|
|
20181
|
+
[attr.aria-label]="ariaLabel()"
|
|
20182
|
+
>
|
|
20183
|
+
<ng-content />
|
|
20184
|
+
</ul>
|
|
20185
|
+
`, styles: [".jv-list{display:block;list-style:none;margin:0;padding:0}.jv-list>:not(:last-child){border-bottom:1px solid var(--jv-color-border)}.jv-list--bordered{border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md)}\n"] }]
|
|
20186
|
+
}], propDecorators: { role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], ariaRole: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaRole", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
|
|
19125
20187
|
|
|
19126
|
-
let
|
|
19127
|
-
class
|
|
19128
|
-
|
|
20188
|
+
let modalSelectorIdSequence = 0;
|
|
20189
|
+
class JvModalSelectorComponent {
|
|
20190
|
+
announcementService = inject(JvAnnouncementService);
|
|
20191
|
+
translation = inject(JvTranslationService);
|
|
20192
|
+
instanceId = ++modalSelectorIdSequence;
|
|
20193
|
+
triggerButtonRef = viewChild('triggerButton', ...(ngDevMode ? [{ debugName: "triggerButtonRef" }] : /* istanbul ignore next */ []));
|
|
20194
|
+
optionElements = viewChildren('optionElement', ...(ngDevMode ? [{ debugName: "optionElements" }] : /* istanbul ignore next */ []));
|
|
20195
|
+
options = input([], ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
19129
20196
|
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
19130
|
-
|
|
20197
|
+
placeholder = input('', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
20198
|
+
dialogTitle = input('', ...(ngDevMode ? [{ debugName: "dialogTitle" }] : /* istanbul ignore next */ []));
|
|
20199
|
+
dialogSubtitle = input('', ...(ngDevMode ? [{ debugName: "dialogSubtitle" }] : /* istanbul ignore next */ []));
|
|
20200
|
+
searchPlaceholder = input('', ...(ngDevMode ? [{ debugName: "searchPlaceholder" }] : /* istanbul ignore next */ []));
|
|
20201
|
+
emptyMessage = input('', ...(ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []));
|
|
20202
|
+
clearLabel = input('', ...(ngDevMode ? [{ debugName: "clearLabel" }] : /* istanbul ignore next */ []));
|
|
20203
|
+
closeLabel = input('', ...(ngDevMode ? [{ debugName: "closeLabel" }] : /* istanbul ignore next */ []));
|
|
20204
|
+
showSearch = input(true, ...(ngDevMode ? [{ debugName: "showSearch" }] : /* istanbul ignore next */ []));
|
|
20205
|
+
required = input(false, ...(ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []));
|
|
20206
|
+
invalid = input(false, ...(ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []));
|
|
20207
|
+
hint = input('', ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
|
|
20208
|
+
error = input('', ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
|
|
19131
20209
|
describedBy = input('', ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
|
|
19132
|
-
inputId = input(`jv-
|
|
19133
|
-
|
|
20210
|
+
inputId = input(`jv-modal-selector-${this.instanceId}`, ...(ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []));
|
|
20211
|
+
valueInput = input(undefined, { ...(ngDevMode ? { debugName: "valueInput" } : /* istanbul ignore next */ {}), alias: 'value' });
|
|
20212
|
+
selectionChange = output();
|
|
20213
|
+
dialogOpen = signal(false, ...(ngDevMode ? [{ debugName: "dialogOpen" }] : /* istanbul ignore next */ []));
|
|
20214
|
+
searchQuery = signal('', ...(ngDevMode ? [{ debugName: "searchQuery" }] : /* istanbul ignore next */ []));
|
|
20215
|
+
dialogId = `jv-modal-selector-dialog-${this.instanceId}`;
|
|
20216
|
+
searchInputId = `jv-modal-selector-search-${this.instanceId}`;
|
|
20217
|
+
value = null;
|
|
19134
20218
|
disabled = false;
|
|
20219
|
+
resolvedDialogTitle = computed(() => this.dialogTitle() || this.label() || this.translation.translate('modalSelector.placeholder'), ...(ngDevMode ? [{ debugName: "resolvedDialogTitle" }] : /* istanbul ignore next */ []));
|
|
20220
|
+
currentValue = computed(() => (this.valueInput() !== undefined ? this.valueInput() : this.value), ...(ngDevMode ? [{ debugName: "currentValue" }] : /* istanbul ignore next */ []));
|
|
20221
|
+
selectedOption = computed(() => this.options().find((option) => Object.is(option.value, this.currentValue())) ?? null, ...(ngDevMode ? [{ debugName: "selectedOption" }] : /* istanbul ignore next */ []));
|
|
20222
|
+
resolvedPlaceholder = computed(() => this.placeholder() || this.translation.translate('modalSelector.placeholder'), ...(ngDevMode ? [{ debugName: "resolvedPlaceholder" }] : /* istanbul ignore next */ []));
|
|
20223
|
+
triggerAriaLabel = computed(() => {
|
|
20224
|
+
const name = this.label() || this.resolvedDialogTitle();
|
|
20225
|
+
const value = this.selectedOption()?.label ?? this.resolvedPlaceholder();
|
|
20226
|
+
return `${name}. ${value}`;
|
|
20227
|
+
}, ...(ngDevMode ? [{ debugName: "triggerAriaLabel" }] : /* istanbul ignore next */ []));
|
|
20228
|
+
resultsLabel = computed(() => this.translation.translate('modalSelector.results', { count: this.filteredOptions().length }), ...(ngDevMode ? [{ debugName: "resultsLabel" }] : /* istanbul ignore next */ []));
|
|
20229
|
+
filteredOptions = computed(() => {
|
|
20230
|
+
const query = this.searchQuery().trim().toLocaleLowerCase();
|
|
20231
|
+
if (!query) {
|
|
20232
|
+
return this.options();
|
|
20233
|
+
}
|
|
20234
|
+
return this.options().filter((option) => {
|
|
20235
|
+
const haystack = [option.label, option.description ?? '', ...(option.keywords ?? [])].join(' ').toLocaleLowerCase();
|
|
20236
|
+
return haystack.includes(query);
|
|
20237
|
+
});
|
|
20238
|
+
}, ...(ngDevMode ? [{ debugName: "filteredOptions" }] : /* istanbul ignore next */ []));
|
|
19135
20239
|
onChange = () => undefined;
|
|
19136
20240
|
onTouched = () => undefined;
|
|
19137
20241
|
writeValue(value) {
|
|
19138
|
-
this.value = value ??
|
|
20242
|
+
this.value = value ?? null;
|
|
19139
20243
|
}
|
|
19140
20244
|
registerOnChange(fn) {
|
|
19141
20245
|
this.onChange = fn;
|
|
@@ -19146,77 +20250,312 @@ class JvRadioComponent {
|
|
|
19146
20250
|
setDisabledState(isDisabled) {
|
|
19147
20251
|
this.disabled = isDisabled;
|
|
19148
20252
|
}
|
|
19149
|
-
|
|
19150
|
-
|
|
19151
|
-
|
|
19152
|
-
|
|
20253
|
+
openDialog() {
|
|
20254
|
+
if (this.disabled) {
|
|
20255
|
+
return;
|
|
20256
|
+
}
|
|
20257
|
+
this.searchQuery.set('');
|
|
20258
|
+
this.dialogOpen.set(true);
|
|
20259
|
+
}
|
|
20260
|
+
closeDialog() {
|
|
20261
|
+
this.dialogOpen.set(false);
|
|
20262
|
+
this.handleBlur();
|
|
20263
|
+
queueMicrotask(() => this.triggerButtonRef()?.nativeElement.focus());
|
|
20264
|
+
}
|
|
20265
|
+
clearSelection() {
|
|
20266
|
+
this.updateValue(null);
|
|
20267
|
+
this.announcementService.announce(this.translation.translate('modalSelector.selectionCleared'), 'polite');
|
|
20268
|
+
this.closeDialog();
|
|
20269
|
+
}
|
|
20270
|
+
selectOption(option) {
|
|
20271
|
+
if (option.disabled) {
|
|
20272
|
+
return;
|
|
20273
|
+
}
|
|
20274
|
+
this.updateValue(option.value);
|
|
20275
|
+
this.announcementService.announce(this.translation.translate('modalSelector.selected', { label: option.label }), 'polite');
|
|
20276
|
+
this.closeDialog();
|
|
20277
|
+
}
|
|
20278
|
+
isSelected(option) {
|
|
20279
|
+
return Object.is(option.value, this.currentValue());
|
|
20280
|
+
}
|
|
20281
|
+
getOptionTabIndex(option, index) {
|
|
20282
|
+
if (option.disabled) {
|
|
20283
|
+
return -1;
|
|
20284
|
+
}
|
|
20285
|
+
const selected = this.filteredOptions().find((item) => this.isSelected(item) && !item.disabled);
|
|
20286
|
+
if (selected) {
|
|
20287
|
+
return this.isSelected(option) ? 0 : -1;
|
|
20288
|
+
}
|
|
20289
|
+
const firstEnabledIndex = this.filteredOptions().findIndex((item) => !item.disabled);
|
|
20290
|
+
return index === firstEnabledIndex ? 0 : -1;
|
|
20291
|
+
}
|
|
20292
|
+
optionId(index) {
|
|
20293
|
+
return `jv-modal-selector-option-${this.instanceId}-${index}`;
|
|
20294
|
+
}
|
|
20295
|
+
handleOptionKeydown(event, index, option) {
|
|
20296
|
+
switch (event.key) {
|
|
20297
|
+
case 'ArrowDown':
|
|
20298
|
+
event.preventDefault();
|
|
20299
|
+
this.focusRelativeOption(index, 1);
|
|
20300
|
+
break;
|
|
20301
|
+
case 'ArrowUp':
|
|
20302
|
+
event.preventDefault();
|
|
20303
|
+
this.focusRelativeOption(index, -1);
|
|
20304
|
+
break;
|
|
20305
|
+
case 'Home':
|
|
20306
|
+
event.preventDefault();
|
|
20307
|
+
this.focusOptionByIndex(0);
|
|
20308
|
+
break;
|
|
20309
|
+
case 'End':
|
|
20310
|
+
event.preventDefault();
|
|
20311
|
+
this.focusOptionByIndex(this.filteredOptions().length - 1);
|
|
20312
|
+
break;
|
|
20313
|
+
case 'Enter':
|
|
20314
|
+
case ' ':
|
|
20315
|
+
event.preventDefault();
|
|
20316
|
+
this.selectOption(option);
|
|
20317
|
+
break;
|
|
20318
|
+
}
|
|
19153
20319
|
}
|
|
19154
20320
|
handleBlur() {
|
|
19155
20321
|
this.onTouched();
|
|
19156
20322
|
}
|
|
19157
|
-
|
|
19158
|
-
|
|
20323
|
+
updateValue(value) {
|
|
20324
|
+
this.value = value;
|
|
20325
|
+
this.onChange(value);
|
|
20326
|
+
this.selectionChange.emit(value);
|
|
20327
|
+
}
|
|
20328
|
+
focusRelativeOption(startIndex, direction) {
|
|
20329
|
+
const options = this.filteredOptions();
|
|
20330
|
+
for (let offset = 1; offset <= options.length; offset++) {
|
|
20331
|
+
const candidateIndex = (startIndex + direction * offset + options.length) % options.length;
|
|
20332
|
+
if (!options[candidateIndex]?.disabled) {
|
|
20333
|
+
this.focusOptionByIndex(candidateIndex);
|
|
20334
|
+
return;
|
|
20335
|
+
}
|
|
20336
|
+
}
|
|
20337
|
+
}
|
|
20338
|
+
focusOptionByIndex(index) {
|
|
20339
|
+
const optionElements = this.optionElements();
|
|
20340
|
+
optionElements?.[index]?.nativeElement.focus();
|
|
20341
|
+
}
|
|
20342
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvModalSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20343
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvModalSelectorComponent, isStandalone: true, selector: "jv-modal-selector", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, dialogTitle: { classPropertyName: "dialogTitle", publicName: "dialogTitle", isSignal: true, isRequired: false, transformFunction: null }, dialogSubtitle: { classPropertyName: "dialogSubtitle", publicName: "dialogSubtitle", isSignal: true, isRequired: false, transformFunction: null }, searchPlaceholder: { classPropertyName: "searchPlaceholder", publicName: "searchPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null }, showSearch: { classPropertyName: "showSearch", publicName: "showSearch", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, describedBy: { classPropertyName: "describedBy", publicName: "describedBy", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null }, valueInput: { classPropertyName: "valueInput", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectionChange: "selectionChange" }, providers: [
|
|
19159
20344
|
{
|
|
19160
20345
|
provide: NG_VALUE_ACCESSOR,
|
|
19161
|
-
useExisting: forwardRef(() =>
|
|
20346
|
+
useExisting: forwardRef(() => JvModalSelectorComponent),
|
|
19162
20347
|
multi: true,
|
|
19163
20348
|
},
|
|
19164
|
-
], ngImport: i0, template: `
|
|
19165
|
-
<
|
|
19166
|
-
|
|
19167
|
-
|
|
19168
|
-
|
|
19169
|
-
|
|
19170
|
-
|
|
19171
|
-
|
|
19172
|
-
|
|
19173
|
-
|
|
19174
|
-
|
|
19175
|
-
|
|
19176
|
-
|
|
19177
|
-
|
|
19178
|
-
|
|
20349
|
+
], viewQueries: [{ propertyName: "triggerButtonRef", first: true, predicate: ["triggerButton"], descendants: true, isSignal: true }, { propertyName: "optionElements", predicate: ["optionElement"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
20350
|
+
<jv-form-container
|
|
20351
|
+
[label]="label()"
|
|
20352
|
+
[inputId]="inputId()"
|
|
20353
|
+
[required]="required()"
|
|
20354
|
+
[invalid]="invalid()"
|
|
20355
|
+
[hint]="hint()"
|
|
20356
|
+
[error]="error()"
|
|
20357
|
+
>
|
|
20358
|
+
<button
|
|
20359
|
+
#triggerButton
|
|
20360
|
+
type="button"
|
|
20361
|
+
class="jv-modal-selector-trigger"
|
|
20362
|
+
[class.is-invalid]="invalid()"
|
|
20363
|
+
[id]="inputId()"
|
|
20364
|
+
[disabled]="disabled"
|
|
20365
|
+
[attr.aria-haspopup]="'dialog'"
|
|
20366
|
+
[attr.aria-expanded]="dialogOpen() ? 'true' : 'false'"
|
|
20367
|
+
[attr.aria-controls]="dialogId"
|
|
20368
|
+
[attr.aria-invalid]="invalid() ? 'true' : null"
|
|
20369
|
+
[attr.aria-describedby]="describedBy() || null"
|
|
20370
|
+
[attr.aria-label]="triggerAriaLabel()"
|
|
20371
|
+
(click)="openDialog()"
|
|
20372
|
+
(blur)="handleBlur()"
|
|
20373
|
+
>
|
|
20374
|
+
<span class="jv-modal-selector-trigger-copy">
|
|
20375
|
+
<span [class.jv-modal-selector-trigger-placeholder]="!selectedOption()">
|
|
20376
|
+
{{ selectedOption()?.label ?? resolvedPlaceholder() }}
|
|
20377
|
+
</span>
|
|
20378
|
+
</span>
|
|
20379
|
+
<jv-icon name="chevrons-up-down" [size]="18" />
|
|
20380
|
+
</button>
|
|
20381
|
+
</jv-form-container>
|
|
20382
|
+
|
|
20383
|
+
<jv-dialog [open]="dialogOpen()" [title]="resolvedDialogTitle()" (closed)="closeDialog()">
|
|
20384
|
+
<div [id]="dialogId" class="jv-modal-selector-dialog">
|
|
20385
|
+
@if (dialogSubtitle()) {
|
|
20386
|
+
<p class="jv-modal-selector-subtitle">{{ dialogSubtitle() }}</p>
|
|
20387
|
+
}
|
|
20388
|
+
|
|
20389
|
+
@if (showSearch()) {
|
|
20390
|
+
<jv-input
|
|
20391
|
+
type="search"
|
|
20392
|
+
[inputId]="searchInputId"
|
|
20393
|
+
[placeholder]="searchPlaceholder() || translation.translate('modalSelector.searchPlaceholder')"
|
|
20394
|
+
[ngModel]="searchQuery()"
|
|
20395
|
+
(ngModelChange)="searchQuery.set($event)"
|
|
20396
|
+
/>
|
|
20397
|
+
}
|
|
20398
|
+
|
|
20399
|
+
<p class="jv-modal-selector-results" aria-live="polite">{{ resultsLabel() }}</p>
|
|
20400
|
+
|
|
20401
|
+
@if (filteredOptions().length > 0) {
|
|
20402
|
+
<jv-list variant="bordered" [ariaRole]="'listbox'" [ariaLabel]="resolvedDialogTitle()">
|
|
20403
|
+
@for (option of filteredOptions(); track option.value; let index = $index) {
|
|
20404
|
+
<li role="presentation">
|
|
20405
|
+
<div
|
|
20406
|
+
#optionElement
|
|
20407
|
+
class="jv-modal-selector-option"
|
|
20408
|
+
[class.jv-modal-selector-option--selected]="isSelected(option)"
|
|
20409
|
+
[class.jv-modal-selector-option--disabled]="option.disabled ?? false"
|
|
20410
|
+
[id]="optionId(index)"
|
|
20411
|
+
role="option"
|
|
20412
|
+
[attr.aria-selected]="isSelected(option) ? 'true' : 'false'"
|
|
20413
|
+
[attr.tabindex]="getOptionTabIndex(option, index)"
|
|
20414
|
+
(click)="selectOption(option)"
|
|
20415
|
+
(keydown)="handleOptionKeydown($event, index, option)"
|
|
20416
|
+
>
|
|
20417
|
+
<div class="jv-modal-selector-option-copy">
|
|
20418
|
+
<span class="jv-modal-selector-option-label">{{ option.label }}</span>
|
|
20419
|
+
@if (option.description) {
|
|
20420
|
+
<span class="jv-modal-selector-option-description">{{ option.description }}</span>
|
|
20421
|
+
}
|
|
20422
|
+
</div>
|
|
20423
|
+
@if (isSelected(option)) {
|
|
20424
|
+
<jv-icon name="check" [size]="16" />
|
|
20425
|
+
}
|
|
20426
|
+
</div>
|
|
20427
|
+
</li>
|
|
20428
|
+
}
|
|
20429
|
+
</jv-list>
|
|
20430
|
+
} @else {
|
|
20431
|
+
<div class="jv-modal-selector-empty" aria-live="polite">{{ emptyMessage() || translation.translate('modalSelector.emptyMessage') }}</div>
|
|
20432
|
+
}
|
|
20433
|
+
</div>
|
|
20434
|
+
|
|
20435
|
+
<div dialog-actions class="jv-modal-selector-actions">
|
|
20436
|
+
@if (selectedOption()) {
|
|
20437
|
+
<jv-button variant="ghost" (click)="clearSelection()">{{ clearLabel() || translation.translate('modalSelector.clear') }}</jv-button>
|
|
20438
|
+
}
|
|
20439
|
+
<jv-button variant="outline" (click)="closeDialog()">{{ closeLabel() || translation.translate('modalSelector.close') }}</jv-button>
|
|
20440
|
+
</div>
|
|
20441
|
+
</jv-dialog>
|
|
20442
|
+
`, isInline: true, styles: [".jv-modal-selector-trigger{width:100%;min-height:var(--jv-density-control-height);display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-sm);padding:0 var(--jv-spacing-md);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md);background:var(--jv-color-surface);color:var(--jv-color-foreground);text-align:left;font:inherit;cursor:pointer}.jv-modal-selector-trigger.is-invalid{border-color:var(--jv-color-danger)}.jv-modal-selector-trigger:disabled{opacity:.7;cursor:not-allowed}.jv-modal-selector-trigger:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:1px}.jv-modal-selector-trigger-copy{min-width:0;flex:1}.jv-modal-selector-trigger-placeholder{color:var(--jv-color-foreground-muted)}.jv-modal-selector-dialog,.jv-modal-selector-actions{display:grid;gap:var(--jv-spacing-md)}.jv-modal-selector-subtitle,.jv-modal-selector-results,.jv-modal-selector-option-description,.jv-modal-selector-empty{margin:0;color:var(--jv-color-foreground-muted)}.jv-modal-selector-empty{padding:var(--jv-spacing-md);border:1px dashed var(--jv-color-border);border-radius:var(--jv-radius-md);text-align:center}.jv-modal-selector-option{display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-md);padding:var(--jv-spacing-md);background:var(--jv-color-surface);cursor:pointer;outline:none;transition:background-color .16s ease}.jv-modal-selector-option:hover,.jv-modal-selector-option:focus-visible{background:var(--jv-color-surface-muted)}.jv-modal-selector-option:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:-2px}.jv-modal-selector-option--selected{background:color-mix(in srgb,var(--jv-color-primary) 8%,var(--jv-color-surface))}.jv-modal-selector-option--disabled{opacity:.55;cursor:not-allowed;pointer-events:none}.jv-modal-selector-option-copy{min-width:0;display:grid;gap:.25rem}.jv-modal-selector-option-label{font-weight:600;color:var(--jv-color-foreground)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: JvButtonComponent, selector: "jv-button", inputs: ["type", "variant", "icon", "iconPosition", "loading", "disabled"] }, { kind: "component", type: JvDialogComponent, selector: "jv-dialog", inputs: ["open", "title"], outputs: ["closed"] }, { kind: "component", type: JvFormContainerComponent, selector: "jv-form-container", inputs: ["label", "hint", "error", "inputId", "hintId", "errorId", "required", "invalid"] }, { kind: "component", type: JvIconComponent, selector: "jv-icon", inputs: ["name", "size", "strokeWidth", "decorative", "ariaLabel"] }, { kind: "component", type: JvInputComponent, selector: "jv-input", inputs: ["type", "placeholder", "required", "invalid", "describedBy", "inputId"] }, { kind: "component", type: JvListComponent, selector: "jv-list", inputs: ["role", "ariaRole", "variant", "ariaLabel"] }] });
|
|
19179
20443
|
}
|
|
19180
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type:
|
|
20444
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvModalSelectorComponent, decorators: [{
|
|
19181
20445
|
type: Component,
|
|
19182
|
-
args: [{ selector: 'jv-
|
|
20446
|
+
args: [{ selector: 'jv-modal-selector', standalone: true, imports: [FormsModule, JvButtonComponent, JvDialogComponent, JvFormContainerComponent, JvIconComponent, JvInputComponent, JvListComponent], providers: [
|
|
19183
20447
|
{
|
|
19184
20448
|
provide: NG_VALUE_ACCESSOR,
|
|
19185
|
-
useExisting: forwardRef(() =>
|
|
20449
|
+
useExisting: forwardRef(() => JvModalSelectorComponent),
|
|
19186
20450
|
multi: true,
|
|
19187
20451
|
},
|
|
19188
|
-
], template: `
|
|
19189
|
-
<
|
|
19190
|
-
|
|
19191
|
-
|
|
19192
|
-
|
|
19193
|
-
|
|
19194
|
-
|
|
19195
|
-
|
|
19196
|
-
|
|
19197
|
-
|
|
19198
|
-
|
|
19199
|
-
|
|
19200
|
-
|
|
19201
|
-
|
|
19202
|
-
|
|
19203
|
-
|
|
20452
|
+
], template: `
|
|
20453
|
+
<jv-form-container
|
|
20454
|
+
[label]="label()"
|
|
20455
|
+
[inputId]="inputId()"
|
|
20456
|
+
[required]="required()"
|
|
20457
|
+
[invalid]="invalid()"
|
|
20458
|
+
[hint]="hint()"
|
|
20459
|
+
[error]="error()"
|
|
20460
|
+
>
|
|
20461
|
+
<button
|
|
20462
|
+
#triggerButton
|
|
20463
|
+
type="button"
|
|
20464
|
+
class="jv-modal-selector-trigger"
|
|
20465
|
+
[class.is-invalid]="invalid()"
|
|
20466
|
+
[id]="inputId()"
|
|
20467
|
+
[disabled]="disabled"
|
|
20468
|
+
[attr.aria-haspopup]="'dialog'"
|
|
20469
|
+
[attr.aria-expanded]="dialogOpen() ? 'true' : 'false'"
|
|
20470
|
+
[attr.aria-controls]="dialogId"
|
|
20471
|
+
[attr.aria-invalid]="invalid() ? 'true' : null"
|
|
20472
|
+
[attr.aria-describedby]="describedBy() || null"
|
|
20473
|
+
[attr.aria-label]="triggerAriaLabel()"
|
|
20474
|
+
(click)="openDialog()"
|
|
20475
|
+
(blur)="handleBlur()"
|
|
20476
|
+
>
|
|
20477
|
+
<span class="jv-modal-selector-trigger-copy">
|
|
20478
|
+
<span [class.jv-modal-selector-trigger-placeholder]="!selectedOption()">
|
|
20479
|
+
{{ selectedOption()?.label ?? resolvedPlaceholder() }}
|
|
20480
|
+
</span>
|
|
20481
|
+
</span>
|
|
20482
|
+
<jv-icon name="chevrons-up-down" [size]="18" />
|
|
20483
|
+
</button>
|
|
20484
|
+
</jv-form-container>
|
|
19204
20485
|
|
|
19205
|
-
|
|
19206
|
-
|
|
19207
|
-
|
|
19208
|
-
|
|
19209
|
-
|
|
19210
|
-
|
|
20486
|
+
<jv-dialog [open]="dialogOpen()" [title]="resolvedDialogTitle()" (closed)="closeDialog()">
|
|
20487
|
+
<div [id]="dialogId" class="jv-modal-selector-dialog">
|
|
20488
|
+
@if (dialogSubtitle()) {
|
|
20489
|
+
<p class="jv-modal-selector-subtitle">{{ dialogSubtitle() }}</p>
|
|
20490
|
+
}
|
|
20491
|
+
|
|
20492
|
+
@if (showSearch()) {
|
|
20493
|
+
<jv-input
|
|
20494
|
+
type="search"
|
|
20495
|
+
[inputId]="searchInputId"
|
|
20496
|
+
[placeholder]="searchPlaceholder() || translation.translate('modalSelector.searchPlaceholder')"
|
|
20497
|
+
[ngModel]="searchQuery()"
|
|
20498
|
+
(ngModelChange)="searchQuery.set($event)"
|
|
20499
|
+
/>
|
|
20500
|
+
}
|
|
20501
|
+
|
|
20502
|
+
<p class="jv-modal-selector-results" aria-live="polite">{{ resultsLabel() }}</p>
|
|
20503
|
+
|
|
20504
|
+
@if (filteredOptions().length > 0) {
|
|
20505
|
+
<jv-list variant="bordered" [ariaRole]="'listbox'" [ariaLabel]="resolvedDialogTitle()">
|
|
20506
|
+
@for (option of filteredOptions(); track option.value; let index = $index) {
|
|
20507
|
+
<li role="presentation">
|
|
20508
|
+
<div
|
|
20509
|
+
#optionElement
|
|
20510
|
+
class="jv-modal-selector-option"
|
|
20511
|
+
[class.jv-modal-selector-option--selected]="isSelected(option)"
|
|
20512
|
+
[class.jv-modal-selector-option--disabled]="option.disabled ?? false"
|
|
20513
|
+
[id]="optionId(index)"
|
|
20514
|
+
role="option"
|
|
20515
|
+
[attr.aria-selected]="isSelected(option) ? 'true' : 'false'"
|
|
20516
|
+
[attr.tabindex]="getOptionTabIndex(option, index)"
|
|
20517
|
+
(click)="selectOption(option)"
|
|
20518
|
+
(keydown)="handleOptionKeydown($event, index, option)"
|
|
20519
|
+
>
|
|
20520
|
+
<div class="jv-modal-selector-option-copy">
|
|
20521
|
+
<span class="jv-modal-selector-option-label">{{ option.label }}</span>
|
|
20522
|
+
@if (option.description) {
|
|
20523
|
+
<span class="jv-modal-selector-option-description">{{ option.description }}</span>
|
|
20524
|
+
}
|
|
20525
|
+
</div>
|
|
20526
|
+
@if (isSelected(option)) {
|
|
20527
|
+
<jv-icon name="check" [size]="16" />
|
|
20528
|
+
}
|
|
20529
|
+
</div>
|
|
20530
|
+
</li>
|
|
20531
|
+
}
|
|
20532
|
+
</jv-list>
|
|
20533
|
+
} @else {
|
|
20534
|
+
<div class="jv-modal-selector-empty" aria-live="polite">{{ emptyMessage() || translation.translate('modalSelector.emptyMessage') }}</div>
|
|
20535
|
+
}
|
|
20536
|
+
</div>
|
|
20537
|
+
|
|
20538
|
+
<div dialog-actions class="jv-modal-selector-actions">
|
|
20539
|
+
@if (selectedOption()) {
|
|
20540
|
+
<jv-button variant="ghost" (click)="clearSelection()">{{ clearLabel() || translation.translate('modalSelector.clear') }}</jv-button>
|
|
20541
|
+
}
|
|
20542
|
+
<jv-button variant="outline" (click)="closeDialog()">{{ closeLabel() || translation.translate('modalSelector.close') }}</jv-button>
|
|
20543
|
+
</div>
|
|
20544
|
+
</jv-dialog>
|
|
20545
|
+
`, styles: [".jv-modal-selector-trigger{width:100%;min-height:var(--jv-density-control-height);display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-sm);padding:0 var(--jv-spacing-md);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md);background:var(--jv-color-surface);color:var(--jv-color-foreground);text-align:left;font:inherit;cursor:pointer}.jv-modal-selector-trigger.is-invalid{border-color:var(--jv-color-danger)}.jv-modal-selector-trigger:disabled{opacity:.7;cursor:not-allowed}.jv-modal-selector-trigger:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:1px}.jv-modal-selector-trigger-copy{min-width:0;flex:1}.jv-modal-selector-trigger-placeholder{color:var(--jv-color-foreground-muted)}.jv-modal-selector-dialog,.jv-modal-selector-actions{display:grid;gap:var(--jv-spacing-md)}.jv-modal-selector-subtitle,.jv-modal-selector-results,.jv-modal-selector-option-description,.jv-modal-selector-empty{margin:0;color:var(--jv-color-foreground-muted)}.jv-modal-selector-empty{padding:var(--jv-spacing-md);border:1px dashed var(--jv-color-border);border-radius:var(--jv-radius-md);text-align:center}.jv-modal-selector-option{display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-md);padding:var(--jv-spacing-md);background:var(--jv-color-surface);cursor:pointer;outline:none;transition:background-color .16s ease}.jv-modal-selector-option:hover,.jv-modal-selector-option:focus-visible{background:var(--jv-color-surface-muted)}.jv-modal-selector-option:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:-2px}.jv-modal-selector-option--selected{background:color-mix(in srgb,var(--jv-color-primary) 8%,var(--jv-color-surface))}.jv-modal-selector-option--disabled{opacity:.55;cursor:not-allowed;pointer-events:none}.jv-modal-selector-option-copy{min-width:0;display:grid;gap:.25rem}.jv-modal-selector-option-label{font-weight:600;color:var(--jv-color-foreground)}\n"] }]
|
|
20546
|
+
}], propDecorators: { triggerButtonRef: [{ type: i0.ViewChild, args: ['triggerButton', { isSignal: true }] }], optionElements: [{ type: i0.ViewChildren, args: ['optionElement', { isSignal: true }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], dialogTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "dialogTitle", required: false }] }], dialogSubtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "dialogSubtitle", required: false }] }], searchPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "searchPlaceholder", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], showSearch: [{ type: i0.Input, args: [{ isSignal: true, alias: "showSearch", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], describedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "describedBy", required: false }] }], inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], valueInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }] } });
|
|
20547
|
+
|
|
20548
|
+
let radioIdSequence = 0;
|
|
20549
|
+
class JvRadioComponent {
|
|
20550
|
+
name = input.required(...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
20551
|
+
label = input('', ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
20552
|
+
radioValue = input.required(...(ngDevMode ? [{ debugName: "radioValue" }] : /* istanbul ignore next */ []));
|
|
19211
20553
|
describedBy = input('', ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
|
|
19212
|
-
inputId = input(`jv-
|
|
19213
|
-
modelValue = input('', ...(ngDevMode ? [{ debugName: "modelValue" }] : /* istanbul ignore next */ []));
|
|
19214
|
-
selectionChange = output();
|
|
20554
|
+
inputId = input(`jv-radio-${++radioIdSequence}`, ...(ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []));
|
|
19215
20555
|
value = '';
|
|
19216
20556
|
disabled = false;
|
|
19217
20557
|
onChange = () => undefined;
|
|
19218
20558
|
onTouched = () => undefined;
|
|
19219
|
-
currentValue = computed(() => this.modelValue() || this.value, ...(ngDevMode ? [{ debugName: "currentValue" }] : /* istanbul ignore next */ []));
|
|
19220
20559
|
writeValue(value) {
|
|
19221
20560
|
this.value = value ?? '';
|
|
19222
20561
|
}
|
|
@@ -19229,76 +20568,61 @@ class JvSelectComponent {
|
|
|
19229
20568
|
setDisabledState(isDisabled) {
|
|
19230
20569
|
this.disabled = isDisabled;
|
|
19231
20570
|
}
|
|
19232
|
-
handleChange(
|
|
19233
|
-
const nextValue =
|
|
20571
|
+
handleChange() {
|
|
20572
|
+
const nextValue = this.radioValue();
|
|
19234
20573
|
this.value = nextValue;
|
|
19235
20574
|
this.onChange(nextValue);
|
|
19236
|
-
this.selectionChange.emit(nextValue);
|
|
19237
20575
|
}
|
|
19238
20576
|
handleBlur() {
|
|
19239
20577
|
this.onTouched();
|
|
19240
20578
|
}
|
|
19241
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type:
|
|
19242
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
20579
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvRadioComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20580
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.17", type: JvRadioComponent, isStandalone: true, selector: "jv-radio", inputs: { name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, radioValue: { classPropertyName: "radioValue", publicName: "radioValue", isSignal: true, isRequired: true, transformFunction: null }, describedBy: { classPropertyName: "describedBy", publicName: "describedBy", isSignal: true, isRequired: false, transformFunction: null }, inputId: { classPropertyName: "inputId", publicName: "inputId", isSignal: true, isRequired: false, transformFunction: null } }, providers: [
|
|
19243
20581
|
{
|
|
19244
20582
|
provide: NG_VALUE_ACCESSOR,
|
|
19245
|
-
useExisting: forwardRef(() =>
|
|
20583
|
+
useExisting: forwardRef(() => JvRadioComponent),
|
|
19246
20584
|
multi: true,
|
|
19247
20585
|
},
|
|
19248
20586
|
], ngImport: i0, template: `
|
|
19249
|
-
<
|
|
19250
|
-
|
|
19251
|
-
|
|
19252
|
-
|
|
19253
|
-
|
|
19254
|
-
|
|
19255
|
-
|
|
19256
|
-
|
|
19257
|
-
|
|
19258
|
-
|
|
19259
|
-
|
|
19260
|
-
|
|
19261
|
-
|
|
19262
|
-
|
|
19263
|
-
}
|
|
19264
|
-
|
|
19265
|
-
@for (option of options(); track option.label + ':' + option.value) {
|
|
19266
|
-
<option [value]="option.value" [disabled]="option.disabled ?? false">{{ option.label }}</option>
|
|
19267
|
-
}
|
|
19268
|
-
</select>
|
|
19269
|
-
`, isInline: true, styles: [".jv-select{width:100%;min-height:var(--jv-density-control-height);padding:0 var(--jv-spacing-md);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md);background:var(--jv-color-surface);color:var(--jv-color-foreground)}.jv-select.is-invalid{border-color:var(--jv-color-danger)}\n"] });
|
|
20587
|
+
<label class="jv-radio" [class.is-disabled]="disabled">
|
|
20588
|
+
<input
|
|
20589
|
+
type="radio"
|
|
20590
|
+
[id]="inputId()"
|
|
20591
|
+
[name]="name()"
|
|
20592
|
+
[checked]="value === radioValue()"
|
|
20593
|
+
[disabled]="disabled"
|
|
20594
|
+
[attr.aria-describedby]="describedBy() || null"
|
|
20595
|
+
(change)="handleChange()"
|
|
20596
|
+
(blur)="handleBlur()"
|
|
20597
|
+
/>
|
|
20598
|
+
<span>{{ label() }}</span>
|
|
20599
|
+
</label>
|
|
20600
|
+
`, isInline: true, styles: [".jv-radio{display:inline-flex;align-items:center;gap:var(--jv-spacing-sm);min-height:var(--jv-density-control-height);color:var(--jv-color-foreground)}.jv-radio.is-disabled{opacity:.7}\n"] });
|
|
19270
20601
|
}
|
|
19271
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type:
|
|
20602
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvRadioComponent, decorators: [{
|
|
19272
20603
|
type: Component,
|
|
19273
|
-
args: [{ selector: 'jv-
|
|
20604
|
+
args: [{ selector: 'jv-radio', standalone: true, providers: [
|
|
19274
20605
|
{
|
|
19275
20606
|
provide: NG_VALUE_ACCESSOR,
|
|
19276
|
-
useExisting: forwardRef(() =>
|
|
20607
|
+
useExisting: forwardRef(() => JvRadioComponent),
|
|
19277
20608
|
multi: true,
|
|
19278
20609
|
},
|
|
19279
|
-
], template: `
|
|
19280
|
-
<
|
|
19281
|
-
|
|
19282
|
-
|
|
19283
|
-
|
|
19284
|
-
|
|
19285
|
-
|
|
19286
|
-
|
|
19287
|
-
|
|
19288
|
-
|
|
19289
|
-
|
|
19290
|
-
|
|
19291
|
-
|
|
19292
|
-
|
|
19293
|
-
|
|
19294
|
-
|
|
19295
|
-
|
|
19296
|
-
@for (option of options(); track option.label + ':' + option.value) {
|
|
19297
|
-
<option [value]="option.value" [disabled]="option.disabled ?? false">{{ option.label }}</option>
|
|
19298
|
-
}
|
|
19299
|
-
</select>
|
|
19300
|
-
`, styles: [".jv-select{width:100%;min-height:var(--jv-density-control-height);padding:0 var(--jv-spacing-md);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md);background:var(--jv-color-surface);color:var(--jv-color-foreground)}.jv-select.is-invalid{border-color:var(--jv-color-danger)}\n"] }]
|
|
19301
|
-
}], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], describedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "describedBy", required: false }] }], inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }], modelValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "modelValue", required: false }] }], selectionChange: [{ type: i0.Output, args: ["selectionChange"] }] } });
|
|
20610
|
+
], template: `
|
|
20611
|
+
<label class="jv-radio" [class.is-disabled]="disabled">
|
|
20612
|
+
<input
|
|
20613
|
+
type="radio"
|
|
20614
|
+
[id]="inputId()"
|
|
20615
|
+
[name]="name()"
|
|
20616
|
+
[checked]="value === radioValue()"
|
|
20617
|
+
[disabled]="disabled"
|
|
20618
|
+
[attr.aria-describedby]="describedBy() || null"
|
|
20619
|
+
(change)="handleChange()"
|
|
20620
|
+
(blur)="handleBlur()"
|
|
20621
|
+
/>
|
|
20622
|
+
<span>{{ label() }}</span>
|
|
20623
|
+
</label>
|
|
20624
|
+
`, styles: [".jv-radio{display:inline-flex;align-items:center;gap:var(--jv-spacing-sm);min-height:var(--jv-density-control-height);color:var(--jv-color-foreground)}.jv-radio.is-disabled{opacity:.7}\n"] }]
|
|
20625
|
+
}], propDecorators: { name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], radioValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "radioValue", required: true }] }], describedBy: [{ type: i0.Input, args: [{ isSignal: true, alias: "describedBy", required: false }] }], inputId: [{ type: i0.Input, args: [{ isSignal: true, alias: "inputId", required: false }] }] } });
|
|
19302
20626
|
|
|
19303
20627
|
let switchIdSequence = 0;
|
|
19304
20628
|
class JvSwitchComponent {
|
|
@@ -19478,6 +20802,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
19478
20802
|
|
|
19479
20803
|
class JvDialogService {
|
|
19480
20804
|
announcementService = inject(JvAnnouncementService);
|
|
20805
|
+
translation = inject(JvTranslationService);
|
|
19481
20806
|
document = inject(DOCUMENT);
|
|
19482
20807
|
activeDialogSignal = signal(null, ...(ngDevMode ? [{ debugName: "activeDialogSignal" }] : /* istanbul ignore next */ []));
|
|
19483
20808
|
nextId = 0;
|
|
@@ -19487,15 +20812,16 @@ class JvDialogService {
|
|
|
19487
20812
|
confirm(options) {
|
|
19488
20813
|
const id = ++this.nextId;
|
|
19489
20814
|
this.restoreTarget = this.document.activeElement instanceof HTMLElement ? this.document.activeElement : null;
|
|
20815
|
+
const title = options.title ?? this.translation.translate('dialog.confirmTitle');
|
|
19490
20816
|
this.activeDialogSignal.set({
|
|
19491
20817
|
id,
|
|
19492
|
-
title
|
|
20818
|
+
title,
|
|
19493
20819
|
message: options.message,
|
|
19494
|
-
confirmLabel: options.confirmLabel ?? '
|
|
19495
|
-
cancelLabel: options.cancelLabel ?? '
|
|
20820
|
+
confirmLabel: options.confirmLabel ?? this.translation.translate('dialog.confirm'),
|
|
20821
|
+
cancelLabel: options.cancelLabel ?? this.translation.translate('dialog.cancel'),
|
|
19496
20822
|
tone: options.tone ?? 'primary',
|
|
19497
20823
|
});
|
|
19498
|
-
this.announcementService.announce(`${
|
|
20824
|
+
this.announcementService.announce(`${title}. ${options.message}`, 'assertive');
|
|
19499
20825
|
return new Promise((resolve) => {
|
|
19500
20826
|
this.resolver = resolve;
|
|
19501
20827
|
});
|
|
@@ -19515,127 +20841,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
19515
20841
|
args: [{ providedIn: 'root' }]
|
|
19516
20842
|
}] });
|
|
19517
20843
|
|
|
19518
|
-
class JvDialogComponent {
|
|
19519
|
-
document = inject(DOCUMENT);
|
|
19520
|
-
panelRef = viewChild('panel', ...(ngDevMode ? [{ debugName: "panelRef" }] : /* istanbul ignore next */ []));
|
|
19521
|
-
open = input(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
|
|
19522
|
-
title = input('Dialog', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
19523
|
-
closed = output();
|
|
19524
|
-
titleId = `jv-dialog-title-${Math.random().toString(36).slice(2, 8)}`;
|
|
19525
|
-
descriptionId = `jv-dialog-description-${Math.random().toString(36).slice(2, 8)}`;
|
|
19526
|
-
constructor() {
|
|
19527
|
-
effect(() => {
|
|
19528
|
-
if (this.open()) {
|
|
19529
|
-
queueMicrotask(() => this.focusInitialElement());
|
|
19530
|
-
}
|
|
19531
|
-
});
|
|
19532
|
-
}
|
|
19533
|
-
handleDocumentKeydown(event) {
|
|
19534
|
-
if (!this.open()) {
|
|
19535
|
-
return;
|
|
19536
|
-
}
|
|
19537
|
-
if (event.key === 'Escape') {
|
|
19538
|
-
event.preventDefault();
|
|
19539
|
-
this.closed.emit();
|
|
19540
|
-
return;
|
|
19541
|
-
}
|
|
19542
|
-
if (event.key === 'Tab') {
|
|
19543
|
-
this.trapFocus(event);
|
|
19544
|
-
}
|
|
19545
|
-
}
|
|
19546
|
-
focusInitialElement() {
|
|
19547
|
-
const panel = this.panelRef()?.nativeElement;
|
|
19548
|
-
if (!panel) {
|
|
19549
|
-
return;
|
|
19550
|
-
}
|
|
19551
|
-
const firstFocusable = this.getFocusableElements()[0];
|
|
19552
|
-
(firstFocusable ?? panel).focus();
|
|
19553
|
-
}
|
|
19554
|
-
backdropClose() {
|
|
19555
|
-
this.closed.emit();
|
|
19556
|
-
}
|
|
19557
|
-
trapFocus(event) {
|
|
19558
|
-
const focusable = this.getFocusableElements();
|
|
19559
|
-
const panel = this.panelRef()?.nativeElement;
|
|
19560
|
-
if (!panel || focusable.length === 0) {
|
|
19561
|
-
panel?.focus();
|
|
19562
|
-
event.preventDefault();
|
|
19563
|
-
return;
|
|
19564
|
-
}
|
|
19565
|
-
const first = focusable[0];
|
|
19566
|
-
const last = focusable[focusable.length - 1];
|
|
19567
|
-
const active = this.document.activeElement;
|
|
19568
|
-
if (event.shiftKey && active === first) {
|
|
19569
|
-
last.focus();
|
|
19570
|
-
event.preventDefault();
|
|
19571
|
-
}
|
|
19572
|
-
else if (!event.shiftKey && active === last) {
|
|
19573
|
-
first.focus();
|
|
19574
|
-
event.preventDefault();
|
|
19575
|
-
}
|
|
19576
|
-
}
|
|
19577
|
-
getFocusableElements() {
|
|
19578
|
-
const panel = this.panelRef()?.nativeElement;
|
|
19579
|
-
if (!panel) {
|
|
19580
|
-
return [];
|
|
19581
|
-
}
|
|
19582
|
-
return Array.from(panel.querySelectorAll('button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'));
|
|
19583
|
-
}
|
|
19584
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
19585
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvDialogComponent, isStandalone: true, selector: "jv-dialog", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, host: { listeners: { "document:keydown": "handleDocumentKeydown($event)" } }, viewQueries: [{ propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
19586
|
-
@if (open()) {
|
|
19587
|
-
<div class="jv-dialog-backdrop" (click)="backdropClose()">
|
|
19588
|
-
<div class="jv-dialog-panel" role="dialog" aria-modal="true" tabindex="-1" [attr.aria-labelledby]="titleId" [attr.aria-describedby]="descriptionId" (click)="$event.stopPropagation()" #panel>
|
|
19589
|
-
<header class="jv-dialog-header">
|
|
19590
|
-
<h2 [id]="titleId">{{ title() }}</h2>
|
|
19591
|
-
</header>
|
|
19592
|
-
|
|
19593
|
-
<div class="jv-dialog-body" [id]="descriptionId">
|
|
19594
|
-
<ng-content></ng-content>
|
|
19595
|
-
</div>
|
|
19596
|
-
|
|
19597
|
-
<footer class="jv-dialog-footer">
|
|
19598
|
-
<ng-content select="[dialog-actions]"></ng-content>
|
|
19599
|
-
</footer>
|
|
19600
|
-
</div>
|
|
19601
|
-
</div>
|
|
19602
|
-
}
|
|
19603
|
-
`, isInline: true, styles: [".jv-dialog-backdrop{position:fixed;inset:0;z-index:1200;display:grid;place-items:center;padding:1rem;background:#0f172a80}.jv-dialog-panel{width:min(32rem,100%);max-height:calc(100vh - 2rem);overflow:auto;padding:var(--jv-spacing-lg);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-lg);background:var(--jv-color-surface);box-shadow:var(--jv-shadow-lg)}.jv-dialog-header,.jv-dialog-body,.jv-dialog-footer{display:grid;gap:var(--jv-spacing-sm)}.jv-dialog-footer{margin-top:var(--jv-spacing-lg)}h2,p{margin:0}\n"] });
|
|
19604
|
-
}
|
|
19605
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvDialogComponent, decorators: [{
|
|
19606
|
-
type: Component,
|
|
19607
|
-
args: [{ selector: 'jv-dialog', standalone: true, template: `
|
|
19608
|
-
@if (open()) {
|
|
19609
|
-
<div class="jv-dialog-backdrop" (click)="backdropClose()">
|
|
19610
|
-
<div class="jv-dialog-panel" role="dialog" aria-modal="true" tabindex="-1" [attr.aria-labelledby]="titleId" [attr.aria-describedby]="descriptionId" (click)="$event.stopPropagation()" #panel>
|
|
19611
|
-
<header class="jv-dialog-header">
|
|
19612
|
-
<h2 [id]="titleId">{{ title() }}</h2>
|
|
19613
|
-
</header>
|
|
19614
|
-
|
|
19615
|
-
<div class="jv-dialog-body" [id]="descriptionId">
|
|
19616
|
-
<ng-content></ng-content>
|
|
19617
|
-
</div>
|
|
19618
|
-
|
|
19619
|
-
<footer class="jv-dialog-footer">
|
|
19620
|
-
<ng-content select="[dialog-actions]"></ng-content>
|
|
19621
|
-
</footer>
|
|
19622
|
-
</div>
|
|
19623
|
-
</div>
|
|
19624
|
-
}
|
|
19625
|
-
`, styles: [".jv-dialog-backdrop{position:fixed;inset:0;z-index:1200;display:grid;place-items:center;padding:1rem;background:#0f172a80}.jv-dialog-panel{width:min(32rem,100%);max-height:calc(100vh - 2rem);overflow:auto;padding:var(--jv-spacing-lg);border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-lg);background:var(--jv-color-surface);box-shadow:var(--jv-shadow-lg)}.jv-dialog-header,.jv-dialog-body,.jv-dialog-footer{display:grid;gap:var(--jv-spacing-sm)}.jv-dialog-footer{margin-top:var(--jv-spacing-lg)}h2,p{margin:0}\n"] }]
|
|
19626
|
-
}], ctorParameters: () => [], propDecorators: { panelRef: [{ type: i0.ViewChild, args: ['panel', { isSignal: true }] }], open: [{ type: i0.Input, args: [{ isSignal: true, alias: "open", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], handleDocumentKeydown: [{
|
|
19627
|
-
type: HostListener,
|
|
19628
|
-
args: ['document:keydown', ['$event']]
|
|
19629
|
-
}] } });
|
|
19630
|
-
|
|
19631
20844
|
class JvConfirmDialogComponent {
|
|
19632
20845
|
dialogService = inject(JvDialogService);
|
|
20846
|
+
translation = inject(JvTranslationService);
|
|
19633
20847
|
activeDialog = this.dialogService.activeDialog;
|
|
19634
20848
|
isOpen = computed(() => this.activeDialog() !== null, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
19635
|
-
dialogTitle = computed(() => this.activeDialog()?.title ?? '
|
|
20849
|
+
dialogTitle = computed(() => this.activeDialog()?.title ?? this.translation.translate('dialog.confirmTitle'), ...(ngDevMode ? [{ debugName: "dialogTitle" }] : /* istanbul ignore next */ []));
|
|
19636
20850
|
dialogMessage = computed(() => this.activeDialog()?.message ?? '', ...(ngDevMode ? [{ debugName: "dialogMessage" }] : /* istanbul ignore next */ []));
|
|
19637
|
-
cancelLabel = computed(() => this.activeDialog()?.cancelLabel ?? '
|
|
19638
|
-
confirmLabel = computed(() => this.activeDialog()?.confirmLabel ?? '
|
|
20851
|
+
cancelLabel = computed(() => this.activeDialog()?.cancelLabel ?? this.translation.translate('dialog.cancel'), ...(ngDevMode ? [{ debugName: "cancelLabel" }] : /* istanbul ignore next */ []));
|
|
20852
|
+
confirmLabel = computed(() => this.activeDialog()?.confirmLabel ?? this.translation.translate('dialog.confirm'), ...(ngDevMode ? [{ debugName: "confirmLabel" }] : /* istanbul ignore next */ []));
|
|
19639
20853
|
confirmVariant = computed(() => {
|
|
19640
20854
|
const tone = this.activeDialog()?.tone ?? 'primary';
|
|
19641
20855
|
return tone === 'info' ? 'primary' : tone;
|
|
@@ -19650,8 +20864,8 @@ class JvConfirmDialogComponent {
|
|
|
19650
20864
|
<p>{{ dialogMessage() }}</p>
|
|
19651
20865
|
|
|
19652
20866
|
<div dialog-actions class="actions">
|
|
19653
|
-
<jv-button variant="ghost" (click)="dialogService.resolve(false)">{{ cancelLabel() }}</jv-button>
|
|
19654
20867
|
<jv-button [variant]="confirmVariant()" (click)="dialogService.resolve(true)">{{ confirmLabel() }}</jv-button>
|
|
20868
|
+
<jv-button variant="ghost" (click)="dialogService.resolve(false)">{{ cancelLabel() }}</jv-button>
|
|
19655
20869
|
</div>
|
|
19656
20870
|
</jv-dialog>
|
|
19657
20871
|
`, isInline: true, styles: [".actions{display:flex;justify-content:flex-end;gap:var(--jv-spacing-sm);flex-wrap:wrap}p{margin:0;color:var(--jv-color-foreground-muted)}\n"], dependencies: [{ kind: "component", type: JvButtonComponent, selector: "jv-button", inputs: ["type", "variant", "icon", "iconPosition", "loading", "disabled"] }, { kind: "component", type: JvDialogComponent, selector: "jv-dialog", inputs: ["open", "title"], outputs: ["closed"] }] });
|
|
@@ -19667,8 +20881,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
19667
20881
|
<p>{{ dialogMessage() }}</p>
|
|
19668
20882
|
|
|
19669
20883
|
<div dialog-actions class="actions">
|
|
19670
|
-
<jv-button variant="ghost" (click)="dialogService.resolve(false)">{{ cancelLabel() }}</jv-button>
|
|
19671
20884
|
<jv-button [variant]="confirmVariant()" (click)="dialogService.resolve(true)">{{ confirmLabel() }}</jv-button>
|
|
20885
|
+
<jv-button variant="ghost" (click)="dialogService.resolve(false)">{{ cancelLabel() }}</jv-button>
|
|
19672
20886
|
</div>
|
|
19673
20887
|
</jv-dialog>
|
|
19674
20888
|
`, styles: [".actions{display:flex;justify-content:flex-end;gap:var(--jv-spacing-sm);flex-wrap:wrap}p{margin:0;color:var(--jv-color-foreground-muted)}\n"] }]
|
|
@@ -19784,321 +20998,321 @@ class JvSidebarComponent {
|
|
|
19784
20998
|
target?.scrollIntoView({ block: 'start', behavior: 'smooth' });
|
|
19785
20999
|
}
|
|
19786
21000
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvSidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
19787
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvSidebarComponent, isStandalone: true, selector: "jv-sidebar", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, brandIcon: { classPropertyName: "brandIcon", publicName: "brandIcon", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, mobileOpen: { classPropertyName: "mobileOpen", publicName: "mobileOpen", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, currentTheme: { classPropertyName: "currentTheme", publicName: "currentTheme", isSignal: true, isRequired: false, transformFunction: null }, themeOptions: { classPropertyName: "themeOptions", publicName: "themeOptions", isSignal: true, isRequired: false, transformFunction: null }, topbarActions: { classPropertyName: "topbarActions", publicName: "topbarActions", isSignal: true, isRequired: false, transformFunction: null }, showThemeSelector: { classPropertyName: "showThemeSelector", publicName: "showThemeSelector", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapseToggle: "collapseToggle", mobileClose: "mobileClose", themeChange: "themeChange", actionClick: "actionClick" }, ngImport: i0, template: `
|
|
19788
|
-
@if (mobileOpen()) {
|
|
19789
|
-
<div class="jv-sidebar-backdrop" (click)="mobileClose.emit()"></div>
|
|
19790
|
-
}
|
|
19791
|
-
|
|
19792
|
-
<aside
|
|
19793
|
-
class="jv-sidebar"
|
|
19794
|
-
[class.is-collapsed]="collapsed()"
|
|
19795
|
-
[class.is-mobile-open]="mobileOpen()"
|
|
19796
|
-
>
|
|
19797
|
-
<div class="jv-sidebar-brand">
|
|
19798
|
-
<div class="brand-mark">
|
|
19799
|
-
<jv-icon [name]="brandIcon()" [size]="18" />
|
|
19800
|
-
</div>
|
|
19801
|
-
|
|
19802
|
-
@if (!collapsed()) {
|
|
19803
|
-
<div class="brand-copy">
|
|
19804
|
-
<strong>{{ title() }}</strong>
|
|
19805
|
-
@if (subtitle()) {
|
|
19806
|
-
<span>{{ subtitle() }}</span>
|
|
19807
|
-
}
|
|
19808
|
-
</div>
|
|
19809
|
-
}
|
|
19810
|
-
</div>
|
|
19811
|
-
|
|
19812
|
-
<nav class="jv-sidebar-nav" [attr.aria-label]="ariaLabel()">
|
|
19813
|
-
<ul class="jv-sidebar-list">
|
|
19814
|
-
@for (item of normalizedItems(); track item.id) {
|
|
19815
|
-
<li class="jv-sidebar-item">
|
|
19816
|
-
@if (item.children.length > 0) {
|
|
19817
|
-
<button
|
|
19818
|
-
type="button"
|
|
19819
|
-
class="jv-sidebar-link"
|
|
19820
|
-
[class.is-active]="item.active"
|
|
19821
|
-
[attr.aria-label]="item.label"
|
|
19822
|
-
[attr.aria-expanded]="isExpanded(item.id) ? 'true' : 'false'"
|
|
19823
|
-
[attr.aria-controls]="'jv-sidebar-section-' + item.id"
|
|
19824
|
-
[attr.title]="item.label"
|
|
19825
|
-
(click)="toggleSection(item.id)"
|
|
19826
|
-
>
|
|
19827
|
-
<span class="jv-sidebar-link-main">
|
|
19828
|
-
@if (item.icon) {
|
|
19829
|
-
<jv-icon [name]="item.icon" [size]="18" />
|
|
19830
|
-
}
|
|
19831
|
-
|
|
19832
|
-
@if (!collapsed()) {
|
|
19833
|
-
<span>{{ item.label }}</span>
|
|
19834
|
-
}
|
|
19835
|
-
</span>
|
|
19836
|
-
|
|
19837
|
-
@if (!collapsed()) {
|
|
19838
|
-
<jv-icon [name]="isExpanded(item.id) ? 'chevron-up' : 'chevron-down'" [size]="16" />
|
|
19839
|
-
}
|
|
19840
|
-
</button>
|
|
19841
|
-
} @else {
|
|
19842
|
-
@if (isHashLink(item.href)) {
|
|
19843
|
-
<button
|
|
19844
|
-
type="button"
|
|
19845
|
-
class="jv-sidebar-link"
|
|
19846
|
-
[class.is-active]="item.active"
|
|
19847
|
-
[attr.aria-label]="item.label"
|
|
19848
|
-
[attr.aria-current]="item.active ? 'page' : null"
|
|
19849
|
-
[attr.title]="item.label"
|
|
19850
|
-
(click)="navigateTo(item.href); mobileClose.emit()"
|
|
19851
|
-
>
|
|
19852
|
-
<span class="jv-sidebar-link-main">
|
|
19853
|
-
@if (item.icon) {
|
|
19854
|
-
<jv-icon [name]="item.icon" [size]="18" />
|
|
19855
|
-
}
|
|
19856
|
-
|
|
19857
|
-
@if (!collapsed()) {
|
|
19858
|
-
<span>{{ item.label }}</span>
|
|
19859
|
-
}
|
|
19860
|
-
</span>
|
|
19861
|
-
</button>
|
|
19862
|
-
} @else {
|
|
19863
|
-
<a
|
|
19864
|
-
class="jv-sidebar-link"
|
|
19865
|
-
[class.is-active]="item.active"
|
|
19866
|
-
[attr.aria-label]="item.label"
|
|
19867
|
-
[attr.aria-current]="item.active ? 'page' : null"
|
|
19868
|
-
[routerLink]="item.href"
|
|
19869
|
-
[attr.title]="item.label"
|
|
19870
|
-
(click)="mobileClose.emit()"
|
|
19871
|
-
>
|
|
19872
|
-
<span class="jv-sidebar-link-main">
|
|
19873
|
-
@if (item.icon) {
|
|
19874
|
-
<jv-icon [name]="item.icon" [size]="18" />
|
|
19875
|
-
}
|
|
19876
|
-
|
|
19877
|
-
@if (!collapsed()) {
|
|
19878
|
-
<span>{{ item.label }}</span>
|
|
19879
|
-
}
|
|
19880
|
-
</span>
|
|
19881
|
-
</a>
|
|
19882
|
-
}
|
|
19883
|
-
}
|
|
19884
|
-
|
|
19885
|
-
@if (!collapsed() && item.children.length > 0 && isExpanded(item.id)) {
|
|
19886
|
-
<div class="jv-sidebar-children" [id]="'jv-sidebar-section-' + item.id">
|
|
19887
|
-
@for (child of item.children; track child.id) {
|
|
19888
|
-
@if (isHashLink(child.href)) {
|
|
19889
|
-
<button type="button" class="jv-sidebar-child-link" [class.is-active]="child.active" [attr.aria-label]="child.label" [attr.aria-current]="child.active ? 'page' : null" [attr.title]="child.label" (click)="navigateTo(child.href)">
|
|
19890
|
-
{{ child.label }}
|
|
19891
|
-
</button>
|
|
19892
|
-
} @else {
|
|
19893
|
-
<a class="jv-sidebar-child-link" [class.is-active]="child.active" [attr.aria-label]="child.label" [attr.aria-current]="child.active ? 'page' : null" [routerLink]="child.href" [attr.title]="child.label" (click)="mobileClose.emit()">
|
|
19894
|
-
{{ child.label }}
|
|
19895
|
-
</a>
|
|
19896
|
-
}
|
|
19897
|
-
}
|
|
19898
|
-
</div>
|
|
19899
|
-
}
|
|
19900
|
-
</li>
|
|
19901
|
-
}
|
|
19902
|
-
</ul>
|
|
19903
|
-
</nav>
|
|
19904
|
-
|
|
19905
|
-
<div class="jv-sidebar-footer">
|
|
19906
|
-
<button type="button" class="jv-sidebar-toggle" (click)="collapseToggle.emit()">
|
|
19907
|
-
<jv-icon [name]="collapsed() ? 'menu' : 'panel-left-close'" [size]="18" />
|
|
19908
|
-
@if (!collapsed()) {
|
|
19909
|
-
<span>Collapse</span>
|
|
19910
|
-
}
|
|
19911
|
-
</button>
|
|
19912
|
-
|
|
19913
|
-
<div class="jv-sidebar-mobile-extras">
|
|
19914
|
-
@if (showThemeSelector()) {
|
|
19915
|
-
<div class="theme-group" aria-label="Theme selector">
|
|
19916
|
-
@for (option of themeOptions(); track option.value) {
|
|
19917
|
-
<button
|
|
19918
|
-
type="button"
|
|
19919
|
-
class="theme-pill"
|
|
19920
|
-
[class.is-active]="currentTheme() === option.value"
|
|
19921
|
-
(click)="themeChange.emit(option.value)"
|
|
19922
|
-
>
|
|
19923
|
-
@if (option.icon) {
|
|
19924
|
-
<jv-icon [name]="option.icon" [size]="16" />
|
|
19925
|
-
}
|
|
19926
|
-
<span>{{ option.label }}</span>
|
|
19927
|
-
</button>
|
|
19928
|
-
}
|
|
19929
|
-
</div>
|
|
19930
|
-
}
|
|
19931
|
-
|
|
19932
|
-
<div class="mobile-actions">
|
|
19933
|
-
@for (action of topbarActions(); track action.id) {
|
|
19934
|
-
<button type="button" class="icon-button" [attr.aria-label]="action.label" (click)="actionClick.emit(action.id); mobileClose.emit()">
|
|
19935
|
-
<jv-icon [name]="action.icon" [size]="18" />
|
|
19936
|
-
</button>
|
|
19937
|
-
}
|
|
19938
|
-
</div>
|
|
19939
|
-
</div>
|
|
19940
|
-
</div>
|
|
19941
|
-
</aside>
|
|
19942
|
-
`, isInline: true, styles: [".jv-sidebar-backdrop{display:none}.jv-sidebar{display:grid;grid-template-rows:auto 1fr auto;gap:var(--jv-spacing-lg);width:280px;min-width:280px;height:100vh;padding:var(--jv-spacing-lg);overflow-y:auto;border-right:1px solid var(--jv-color-border);background:var(--jv-color-surface);scrollbar-width:none;-ms-overflow-style:none}.jv-sidebar::-webkit-scrollbar{width:0;height:0;display:none}.jv-sidebar.is-collapsed{width:96px;min-width:96px;padding-inline:var(--jv-spacing-md)}.jv-sidebar-footer{display:grid;gap:var(--jv-spacing-md)}.jv-sidebar-mobile-extras{display:none}.jv-sidebar-brand,.jv-sidebar-link,.jv-sidebar-toggle{display:flex;align-items:center;gap:var(--jv-spacing-sm)}.brand-mark{display:inline-grid;place-items:center;width:
|
|
19943
|
-
}
|
|
19944
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvSidebarComponent, decorators: [{
|
|
19945
|
-
type: Component,
|
|
19946
|
-
args: [{ selector: 'jv-sidebar', standalone: true, imports: [JvIconComponent, RouterLink], template: `
|
|
19947
|
-
@if (mobileOpen()) {
|
|
19948
|
-
<div class="jv-sidebar-backdrop" (click)="mobileClose.emit()"></div>
|
|
19949
|
-
}
|
|
19950
|
-
|
|
19951
|
-
<aside
|
|
19952
|
-
class="jv-sidebar"
|
|
19953
|
-
[class.is-collapsed]="collapsed()"
|
|
19954
|
-
[class.is-mobile-open]="mobileOpen()"
|
|
19955
|
-
>
|
|
19956
|
-
<div class="jv-sidebar-brand">
|
|
19957
|
-
<div class="brand-mark">
|
|
19958
|
-
<jv-icon [name]="brandIcon()" [size]="18" />
|
|
19959
|
-
</div>
|
|
19960
|
-
|
|
19961
|
-
@if (!collapsed()) {
|
|
19962
|
-
<div class="brand-copy">
|
|
19963
|
-
<strong>{{ title() }}</strong>
|
|
19964
|
-
@if (subtitle()) {
|
|
19965
|
-
<span>{{ subtitle() }}</span>
|
|
19966
|
-
}
|
|
19967
|
-
</div>
|
|
19968
|
-
}
|
|
19969
|
-
</div>
|
|
19970
|
-
|
|
19971
|
-
<nav class="jv-sidebar-nav" [attr.aria-label]="ariaLabel()">
|
|
19972
|
-
<ul class="jv-sidebar-list">
|
|
19973
|
-
@for (item of normalizedItems(); track item.id) {
|
|
19974
|
-
<li class="jv-sidebar-item">
|
|
19975
|
-
@if (item.children.length > 0) {
|
|
19976
|
-
<button
|
|
19977
|
-
type="button"
|
|
19978
|
-
class="jv-sidebar-link"
|
|
19979
|
-
[class.is-active]="item.active"
|
|
19980
|
-
[attr.aria-label]="item.label"
|
|
19981
|
-
[attr.aria-expanded]="isExpanded(item.id) ? 'true' : 'false'"
|
|
19982
|
-
[attr.aria-controls]="'jv-sidebar-section-' + item.id"
|
|
19983
|
-
[attr.title]="item.label"
|
|
19984
|
-
(click)="toggleSection(item.id)"
|
|
19985
|
-
>
|
|
19986
|
-
<span class="jv-sidebar-link-main">
|
|
19987
|
-
@if (item.icon) {
|
|
19988
|
-
<jv-icon [name]="item.icon" [size]="18" />
|
|
19989
|
-
}
|
|
19990
|
-
|
|
19991
|
-
@if (!collapsed()) {
|
|
19992
|
-
<span>{{ item.label }}</span>
|
|
19993
|
-
}
|
|
19994
|
-
</span>
|
|
19995
|
-
|
|
19996
|
-
@if (!collapsed()) {
|
|
19997
|
-
<jv-icon [name]="isExpanded(item.id) ? 'chevron-up' : 'chevron-down'" [size]="16" />
|
|
19998
|
-
}
|
|
19999
|
-
</button>
|
|
20000
|
-
} @else {
|
|
20001
|
-
@if (isHashLink(item.href)) {
|
|
20002
|
-
<button
|
|
20003
|
-
type="button"
|
|
20004
|
-
class="jv-sidebar-link"
|
|
20005
|
-
[class.is-active]="item.active"
|
|
20006
|
-
[attr.aria-label]="item.label"
|
|
20007
|
-
[attr.aria-current]="item.active ? 'page' : null"
|
|
20008
|
-
[attr.title]="item.label"
|
|
20009
|
-
(click)="navigateTo(item.href); mobileClose.emit()"
|
|
20010
|
-
>
|
|
20011
|
-
<span class="jv-sidebar-link-main">
|
|
20012
|
-
@if (item.icon) {
|
|
20013
|
-
<jv-icon [name]="item.icon" [size]="18" />
|
|
20014
|
-
}
|
|
20015
|
-
|
|
20016
|
-
@if (!collapsed()) {
|
|
20017
|
-
<span>{{ item.label }}</span>
|
|
20018
|
-
}
|
|
20019
|
-
</span>
|
|
20020
|
-
</button>
|
|
20021
|
-
} @else {
|
|
20022
|
-
<a
|
|
20023
|
-
class="jv-sidebar-link"
|
|
20024
|
-
[class.is-active]="item.active"
|
|
20025
|
-
[attr.aria-label]="item.label"
|
|
20026
|
-
[attr.aria-current]="item.active ? 'page' : null"
|
|
20027
|
-
[routerLink]="item.href"
|
|
20028
|
-
[attr.title]="item.label"
|
|
20029
|
-
(click)="mobileClose.emit()"
|
|
20030
|
-
>
|
|
20031
|
-
<span class="jv-sidebar-link-main">
|
|
20032
|
-
@if (item.icon) {
|
|
20033
|
-
<jv-icon [name]="item.icon" [size]="18" />
|
|
20034
|
-
}
|
|
20035
|
-
|
|
20036
|
-
@if (!collapsed()) {
|
|
20037
|
-
<span>{{ item.label }}</span>
|
|
20038
|
-
}
|
|
20039
|
-
</span>
|
|
20040
|
-
</a>
|
|
20041
|
-
}
|
|
20042
|
-
}
|
|
20043
|
-
|
|
20044
|
-
@if (!collapsed() && item.children.length > 0 && isExpanded(item.id)) {
|
|
20045
|
-
<div class="jv-sidebar-children" [id]="'jv-sidebar-section-' + item.id">
|
|
20046
|
-
@for (child of item.children; track child.id) {
|
|
20047
|
-
@if (isHashLink(child.href)) {
|
|
20048
|
-
<button type="button" class="jv-sidebar-child-link" [class.is-active]="child.active" [attr.aria-label]="child.label" [attr.aria-current]="child.active ? 'page' : null" [attr.title]="child.label" (click)="navigateTo(child.href)">
|
|
20049
|
-
{{ child.label }}
|
|
20050
|
-
</button>
|
|
20051
|
-
} @else {
|
|
20052
|
-
<a class="jv-sidebar-child-link" [class.is-active]="child.active" [attr.aria-label]="child.label" [attr.aria-current]="child.active ? 'page' : null" [routerLink]="child.href" [attr.title]="child.label" (click)="mobileClose.emit()">
|
|
20053
|
-
{{ child.label }}
|
|
20054
|
-
</a>
|
|
20055
|
-
}
|
|
20056
|
-
}
|
|
20057
|
-
</div>
|
|
20058
|
-
}
|
|
20059
|
-
</li>
|
|
20060
|
-
}
|
|
20061
|
-
</ul>
|
|
20062
|
-
</nav>
|
|
20063
|
-
|
|
20064
|
-
<div class="jv-sidebar-footer">
|
|
20065
|
-
<button type="button" class="jv-sidebar-toggle" (click)="collapseToggle.emit()">
|
|
20066
|
-
<jv-icon [name]="collapsed() ? 'menu' : 'panel-left-close'" [size]="18" />
|
|
20067
|
-
@if (!collapsed()) {
|
|
20068
|
-
<span>Collapse</span>
|
|
20069
|
-
}
|
|
20070
|
-
</button>
|
|
20071
|
-
|
|
20072
|
-
<div class="jv-sidebar-mobile-extras">
|
|
20073
|
-
@if (showThemeSelector()) {
|
|
20074
|
-
<div class="theme-group" aria-label="Theme selector">
|
|
20075
|
-
@for (option of themeOptions(); track option.value) {
|
|
20076
|
-
<button
|
|
20077
|
-
type="button"
|
|
20078
|
-
class="theme-pill"
|
|
20079
|
-
[class.is-active]="currentTheme() === option.value"
|
|
20080
|
-
(click)="themeChange.emit(option.value)"
|
|
20081
|
-
>
|
|
20082
|
-
@if (option.icon) {
|
|
20083
|
-
<jv-icon [name]="option.icon" [size]="16" />
|
|
20084
|
-
}
|
|
20085
|
-
<span>{{ option.label }}</span>
|
|
20086
|
-
</button>
|
|
20087
|
-
}
|
|
20088
|
-
</div>
|
|
20089
|
-
}
|
|
20090
|
-
|
|
20091
|
-
<div class="mobile-actions">
|
|
20092
|
-
@for (action of topbarActions(); track action.id) {
|
|
20093
|
-
<button type="button" class="icon-button" [attr.aria-label]="action.label" (click)="actionClick.emit(action.id); mobileClose.emit()">
|
|
20094
|
-
<jv-icon [name]="action.icon" [size]="18" />
|
|
20095
|
-
</button>
|
|
20096
|
-
}
|
|
20097
|
-
</div>
|
|
20098
|
-
</div>
|
|
20099
|
-
</div>
|
|
20100
|
-
</aside>
|
|
20101
|
-
`, styles: [".jv-sidebar-backdrop{display:none}.jv-sidebar{display:grid;grid-template-rows:auto 1fr auto;gap:var(--jv-spacing-lg);width:280px;min-width:280px;height:100vh;padding:var(--jv-spacing-lg);overflow-y:auto;border-right:1px solid var(--jv-color-border);background:var(--jv-color-surface);scrollbar-width:none;-ms-overflow-style:none}.jv-sidebar::-webkit-scrollbar{width:0;height:0;display:none}.jv-sidebar.is-collapsed{width:96px;min-width:96px;padding-inline:var(--jv-spacing-md)}.jv-sidebar-footer{display:grid;gap:var(--jv-spacing-md)}.jv-sidebar-mobile-extras{display:none}.jv-sidebar-brand,.jv-sidebar-link,.jv-sidebar-toggle{display:flex;align-items:center;gap:var(--jv-spacing-sm)}.brand-mark{display:inline-grid;place-items:center;width:
|
|
21001
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvSidebarComponent, isStandalone: true, selector: "jv-sidebar", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, brandIcon: { classPropertyName: "brandIcon", publicName: "brandIcon", isSignal: true, isRequired: false, transformFunction: null }, items: { classPropertyName: "items", publicName: "items", isSignal: true, isRequired: false, transformFunction: null }, collapsed: { classPropertyName: "collapsed", publicName: "collapsed", isSignal: true, isRequired: false, transformFunction: null }, mobileOpen: { classPropertyName: "mobileOpen", publicName: "mobileOpen", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, currentTheme: { classPropertyName: "currentTheme", publicName: "currentTheme", isSignal: true, isRequired: false, transformFunction: null }, themeOptions: { classPropertyName: "themeOptions", publicName: "themeOptions", isSignal: true, isRequired: false, transformFunction: null }, topbarActions: { classPropertyName: "topbarActions", publicName: "topbarActions", isSignal: true, isRequired: false, transformFunction: null }, showThemeSelector: { classPropertyName: "showThemeSelector", publicName: "showThemeSelector", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { collapseToggle: "collapseToggle", mobileClose: "mobileClose", themeChange: "themeChange", actionClick: "actionClick" }, ngImport: i0, template: `
|
|
21002
|
+
@if (mobileOpen()) {
|
|
21003
|
+
<div class="jv-sidebar-backdrop" (click)="mobileClose.emit()"></div>
|
|
21004
|
+
}
|
|
21005
|
+
|
|
21006
|
+
<aside
|
|
21007
|
+
class="jv-sidebar"
|
|
21008
|
+
[class.is-collapsed]="collapsed()"
|
|
21009
|
+
[class.is-mobile-open]="mobileOpen()"
|
|
21010
|
+
>
|
|
21011
|
+
<div class="jv-sidebar-brand">
|
|
21012
|
+
<div class="brand-mark">
|
|
21013
|
+
<jv-icon [name]="brandIcon()" [size]="18" />
|
|
21014
|
+
</div>
|
|
21015
|
+
|
|
21016
|
+
@if (!collapsed()) {
|
|
21017
|
+
<div class="brand-copy">
|
|
21018
|
+
<strong>{{ title() }}</strong>
|
|
21019
|
+
@if (subtitle()) {
|
|
21020
|
+
<span>{{ subtitle() }}</span>
|
|
21021
|
+
}
|
|
21022
|
+
</div>
|
|
21023
|
+
}
|
|
21024
|
+
</div>
|
|
21025
|
+
|
|
21026
|
+
<nav class="jv-sidebar-nav" [attr.aria-label]="ariaLabel()">
|
|
21027
|
+
<ul class="jv-sidebar-list">
|
|
21028
|
+
@for (item of normalizedItems(); track item.id) {
|
|
21029
|
+
<li class="jv-sidebar-item">
|
|
21030
|
+
@if (item.children.length > 0) {
|
|
21031
|
+
<button
|
|
21032
|
+
type="button"
|
|
21033
|
+
class="jv-sidebar-link"
|
|
21034
|
+
[class.is-active]="item.active"
|
|
21035
|
+
[attr.aria-label]="item.label"
|
|
21036
|
+
[attr.aria-expanded]="isExpanded(item.id) ? 'true' : 'false'"
|
|
21037
|
+
[attr.aria-controls]="'jv-sidebar-section-' + item.id"
|
|
21038
|
+
[attr.title]="item.label"
|
|
21039
|
+
(click)="toggleSection(item.id)"
|
|
21040
|
+
>
|
|
21041
|
+
<span class="jv-sidebar-link-main">
|
|
21042
|
+
@if (item.icon) {
|
|
21043
|
+
<jv-icon [name]="item.icon" [size]="18" />
|
|
21044
|
+
}
|
|
21045
|
+
|
|
21046
|
+
@if (!collapsed()) {
|
|
21047
|
+
<span>{{ item.label }}</span>
|
|
21048
|
+
}
|
|
21049
|
+
</span>
|
|
21050
|
+
|
|
21051
|
+
@if (!collapsed()) {
|
|
21052
|
+
<jv-icon [name]="isExpanded(item.id) ? 'chevron-up' : 'chevron-down'" [size]="16" />
|
|
21053
|
+
}
|
|
21054
|
+
</button>
|
|
21055
|
+
} @else {
|
|
21056
|
+
@if (isHashLink(item.href)) {
|
|
21057
|
+
<button
|
|
21058
|
+
type="button"
|
|
21059
|
+
class="jv-sidebar-link"
|
|
21060
|
+
[class.is-active]="item.active"
|
|
21061
|
+
[attr.aria-label]="item.label"
|
|
21062
|
+
[attr.aria-current]="item.active ? 'page' : null"
|
|
21063
|
+
[attr.title]="item.label"
|
|
21064
|
+
(click)="navigateTo(item.href); mobileClose.emit()"
|
|
21065
|
+
>
|
|
21066
|
+
<span class="jv-sidebar-link-main">
|
|
21067
|
+
@if (item.icon) {
|
|
21068
|
+
<jv-icon [name]="item.icon" [size]="18" />
|
|
21069
|
+
}
|
|
21070
|
+
|
|
21071
|
+
@if (!collapsed()) {
|
|
21072
|
+
<span>{{ item.label }}</span>
|
|
21073
|
+
}
|
|
21074
|
+
</span>
|
|
21075
|
+
</button>
|
|
21076
|
+
} @else {
|
|
21077
|
+
<a
|
|
21078
|
+
class="jv-sidebar-link"
|
|
21079
|
+
[class.is-active]="item.active"
|
|
21080
|
+
[attr.aria-label]="item.label"
|
|
21081
|
+
[attr.aria-current]="item.active ? 'page' : null"
|
|
21082
|
+
[routerLink]="item.href"
|
|
21083
|
+
[attr.title]="item.label"
|
|
21084
|
+
(click)="mobileClose.emit()"
|
|
21085
|
+
>
|
|
21086
|
+
<span class="jv-sidebar-link-main">
|
|
21087
|
+
@if (item.icon) {
|
|
21088
|
+
<jv-icon [name]="item.icon" [size]="18" />
|
|
21089
|
+
}
|
|
21090
|
+
|
|
21091
|
+
@if (!collapsed()) {
|
|
21092
|
+
<span>{{ item.label }}</span>
|
|
21093
|
+
}
|
|
21094
|
+
</span>
|
|
21095
|
+
</a>
|
|
21096
|
+
}
|
|
21097
|
+
}
|
|
21098
|
+
|
|
21099
|
+
@if (!collapsed() && item.children.length > 0 && isExpanded(item.id)) {
|
|
21100
|
+
<div class="jv-sidebar-children" [id]="'jv-sidebar-section-' + item.id">
|
|
21101
|
+
@for (child of item.children; track child.id) {
|
|
21102
|
+
@if (isHashLink(child.href)) {
|
|
21103
|
+
<button type="button" class="jv-sidebar-child-link" [class.is-active]="child.active" [attr.aria-label]="child.label" [attr.aria-current]="child.active ? 'page' : null" [attr.title]="child.label" (click)="navigateTo(child.href)">
|
|
21104
|
+
{{ child.label }}
|
|
21105
|
+
</button>
|
|
21106
|
+
} @else {
|
|
21107
|
+
<a class="jv-sidebar-child-link" [class.is-active]="child.active" [attr.aria-label]="child.label" [attr.aria-current]="child.active ? 'page' : null" [routerLink]="child.href" [attr.title]="child.label" (click)="mobileClose.emit()">
|
|
21108
|
+
{{ child.label }}
|
|
21109
|
+
</a>
|
|
21110
|
+
}
|
|
21111
|
+
}
|
|
21112
|
+
</div>
|
|
21113
|
+
}
|
|
21114
|
+
</li>
|
|
21115
|
+
}
|
|
21116
|
+
</ul>
|
|
21117
|
+
</nav>
|
|
21118
|
+
|
|
21119
|
+
<div class="jv-sidebar-footer">
|
|
21120
|
+
<button type="button" class="jv-sidebar-toggle" (click)="collapseToggle.emit()">
|
|
21121
|
+
<jv-icon [name]="collapsed() ? 'menu' : 'panel-left-close'" [size]="18" />
|
|
21122
|
+
@if (!collapsed()) {
|
|
21123
|
+
<span>Collapse</span>
|
|
21124
|
+
}
|
|
21125
|
+
</button>
|
|
21126
|
+
|
|
21127
|
+
<div class="jv-sidebar-mobile-extras">
|
|
21128
|
+
@if (showThemeSelector()) {
|
|
21129
|
+
<div class="theme-group" aria-label="Theme selector">
|
|
21130
|
+
@for (option of themeOptions(); track option.value) {
|
|
21131
|
+
<button
|
|
21132
|
+
type="button"
|
|
21133
|
+
class="theme-pill"
|
|
21134
|
+
[class.is-active]="currentTheme() === option.value"
|
|
21135
|
+
(click)="themeChange.emit(option.value)"
|
|
21136
|
+
>
|
|
21137
|
+
@if (option.icon) {
|
|
21138
|
+
<jv-icon [name]="option.icon" [size]="16" />
|
|
21139
|
+
}
|
|
21140
|
+
<span>{{ option.label }}</span>
|
|
21141
|
+
</button>
|
|
21142
|
+
}
|
|
21143
|
+
</div>
|
|
21144
|
+
}
|
|
21145
|
+
|
|
21146
|
+
<div class="mobile-actions">
|
|
21147
|
+
@for (action of topbarActions(); track action.id) {
|
|
21148
|
+
<button type="button" class="icon-button" [attr.aria-label]="action.label" (click)="actionClick.emit(action.id); mobileClose.emit()">
|
|
21149
|
+
<jv-icon [name]="action.icon" [size]="18" />
|
|
21150
|
+
</button>
|
|
21151
|
+
}
|
|
21152
|
+
</div>
|
|
21153
|
+
</div>
|
|
21154
|
+
</div>
|
|
21155
|
+
</aside>
|
|
21156
|
+
`, isInline: true, styles: [".jv-sidebar-backdrop{display:none}.jv-sidebar{display:grid;grid-template-rows:auto 1fr auto;gap:var(--jv-spacing-lg);width:280px;min-width:280px;height:100vh;padding:var(--jv-spacing-lg);overflow-y:auto;border-right:1px solid var(--jv-color-border);background:var(--jv-color-surface);scrollbar-width:none;-ms-overflow-style:none}.jv-sidebar::-webkit-scrollbar{width:0;height:0;display:none}.jv-sidebar.is-collapsed{width:96px;min-width:96px;padding-inline:var(--jv-spacing-md)}.jv-sidebar-footer{display:grid;gap:var(--jv-spacing-md)}.jv-sidebar-mobile-extras{display:none}.jv-sidebar-brand,.jv-sidebar-link,.jv-sidebar-toggle{display:flex;align-items:center;gap:var(--jv-spacing-sm)}.brand-mark{display:inline-grid;place-items:center;width:var(--jv-density-control-height);height:var(--jv-density-control-height);border-radius:var(--jv-radius-md);background:color-mix(in srgb,var(--jv-color-primary) 16%,var(--jv-color-surface));color:var(--jv-color-primary);flex:0 0 auto}.brand-copy{display:grid;gap:.1rem}.brand-copy span{color:var(--jv-color-foreground-muted);font-size:.875rem}.jv-sidebar-item{display:grid;gap:var(--jv-spacing-xs);list-style:none}.jv-sidebar-list{display:grid;gap:var(--jv-spacing-xs);margin:0;padding:0}.jv-sidebar-nav{display:grid;gap:var(--jv-spacing-xs);align-content:start}.jv-sidebar-link,.jv-sidebar-child-link,.jv-sidebar-toggle{width:100%;display:flex;align-items:center;justify-content:space-between;min-height:var(--jv-density-control-height);padding:0 var(--jv-spacing-md);border:1px solid transparent;border-radius:var(--jv-radius-md);background:transparent;color:var(--jv-color-foreground-muted);text-decoration:none;cursor:pointer}.jv-sidebar-link-main{display:inline-flex;align-items:center;gap:var(--jv-spacing-sm)}.jv-sidebar-link:hover,.jv-sidebar-child-link:hover,.jv-sidebar-toggle:hover{background:var(--jv-color-surface-muted);color:var(--jv-color-foreground)}.jv-sidebar-link.is-active,.jv-sidebar-child-link.is-active{border-color:color-mix(in srgb,var(--jv-color-primary) 25%,var(--jv-color-border));background:color-mix(in srgb,var(--jv-color-primary) 12%,var(--jv-color-surface));color:var(--jv-color-foreground)}.jv-sidebar-children{display:grid;gap:var(--jv-spacing-xs);margin-left:var(--jv-spacing-xl);padding-left:var(--jv-spacing-sm);border-left:1px solid var(--jv-color-border)}.jv-sidebar-child-link{display:flex;align-items:center;min-height:calc(var(--jv-density-control-height) - .25rem);font-size:.9rem}.jv-sidebar-toggle{width:100%;background:var(--jv-color-surface-muted);cursor:pointer}@media(max-width:900px){.jv-sidebar-backdrop{display:block;position:fixed;inset:0;z-index:99;background:#0006}.jv-sidebar{position:fixed;top:0;left:0;z-index:100;width:280px;min-width:280px;height:100vh;border-right:1px solid var(--jv-color-border);border-bottom:none;box-shadow:var(--jv-shadow-lg);transform:translate(-100%);visibility:hidden;transition:transform .24s cubic-bezier(.4,0,.2,1),visibility .24s}.jv-sidebar.is-mobile-open{transform:translate(0);visibility:visible}.jv-sidebar.is-collapsed{width:280px;min-width:280px}.jv-sidebar-mobile-extras{display:flex;flex-direction:column;gap:var(--jv-spacing-md);padding-top:var(--jv-spacing-md);border-top:1px solid var(--jv-color-border)}.jv-sidebar-mobile-extras .theme-group{display:flex;flex-wrap:wrap;gap:var(--jv-spacing-xs)}.jv-sidebar-mobile-extras .theme-pill{display:inline-flex;align-items:center;gap:var(--jv-spacing-xs);min-height:var(--jv-density-control-height);padding:0 var(--jv-spacing-md);border:1px solid var(--jv-color-border);border-radius:999px;background:var(--jv-color-surface-muted);color:var(--jv-color-foreground);cursor:pointer;font:inherit}.jv-sidebar-mobile-extras .theme-pill.is-active{border-color:var(--jv-color-primary);background:color-mix(in srgb,var(--jv-color-primary) 14%,var(--jv-color-surface))}.jv-sidebar-mobile-extras .mobile-actions{display:flex;gap:var(--jv-spacing-sm)}.jv-sidebar-mobile-extras .icon-button{display:inline-grid;place-items:center;width:var(--jv-density-control-height);height:var(--jv-density-control-height);border:1px solid var(--jv-color-border);border-radius:999px;background:var(--jv-color-surface-muted);color:var(--jv-color-foreground);cursor:pointer}}\n"], dependencies: [{ kind: "component", type: JvIconComponent, selector: "jv-icon", inputs: ["name", "size", "strokeWidth", "decorative", "ariaLabel"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
|
|
21157
|
+
}
|
|
21158
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvSidebarComponent, decorators: [{
|
|
21159
|
+
type: Component,
|
|
21160
|
+
args: [{ selector: 'jv-sidebar', standalone: true, imports: [JvIconComponent, RouterLink], template: `
|
|
21161
|
+
@if (mobileOpen()) {
|
|
21162
|
+
<div class="jv-sidebar-backdrop" (click)="mobileClose.emit()"></div>
|
|
21163
|
+
}
|
|
21164
|
+
|
|
21165
|
+
<aside
|
|
21166
|
+
class="jv-sidebar"
|
|
21167
|
+
[class.is-collapsed]="collapsed()"
|
|
21168
|
+
[class.is-mobile-open]="mobileOpen()"
|
|
21169
|
+
>
|
|
21170
|
+
<div class="jv-sidebar-brand">
|
|
21171
|
+
<div class="brand-mark">
|
|
21172
|
+
<jv-icon [name]="brandIcon()" [size]="18" />
|
|
21173
|
+
</div>
|
|
21174
|
+
|
|
21175
|
+
@if (!collapsed()) {
|
|
21176
|
+
<div class="brand-copy">
|
|
21177
|
+
<strong>{{ title() }}</strong>
|
|
21178
|
+
@if (subtitle()) {
|
|
21179
|
+
<span>{{ subtitle() }}</span>
|
|
21180
|
+
}
|
|
21181
|
+
</div>
|
|
21182
|
+
}
|
|
21183
|
+
</div>
|
|
21184
|
+
|
|
21185
|
+
<nav class="jv-sidebar-nav" [attr.aria-label]="ariaLabel()">
|
|
21186
|
+
<ul class="jv-sidebar-list">
|
|
21187
|
+
@for (item of normalizedItems(); track item.id) {
|
|
21188
|
+
<li class="jv-sidebar-item">
|
|
21189
|
+
@if (item.children.length > 0) {
|
|
21190
|
+
<button
|
|
21191
|
+
type="button"
|
|
21192
|
+
class="jv-sidebar-link"
|
|
21193
|
+
[class.is-active]="item.active"
|
|
21194
|
+
[attr.aria-label]="item.label"
|
|
21195
|
+
[attr.aria-expanded]="isExpanded(item.id) ? 'true' : 'false'"
|
|
21196
|
+
[attr.aria-controls]="'jv-sidebar-section-' + item.id"
|
|
21197
|
+
[attr.title]="item.label"
|
|
21198
|
+
(click)="toggleSection(item.id)"
|
|
21199
|
+
>
|
|
21200
|
+
<span class="jv-sidebar-link-main">
|
|
21201
|
+
@if (item.icon) {
|
|
21202
|
+
<jv-icon [name]="item.icon" [size]="18" />
|
|
21203
|
+
}
|
|
21204
|
+
|
|
21205
|
+
@if (!collapsed()) {
|
|
21206
|
+
<span>{{ item.label }}</span>
|
|
21207
|
+
}
|
|
21208
|
+
</span>
|
|
21209
|
+
|
|
21210
|
+
@if (!collapsed()) {
|
|
21211
|
+
<jv-icon [name]="isExpanded(item.id) ? 'chevron-up' : 'chevron-down'" [size]="16" />
|
|
21212
|
+
}
|
|
21213
|
+
</button>
|
|
21214
|
+
} @else {
|
|
21215
|
+
@if (isHashLink(item.href)) {
|
|
21216
|
+
<button
|
|
21217
|
+
type="button"
|
|
21218
|
+
class="jv-sidebar-link"
|
|
21219
|
+
[class.is-active]="item.active"
|
|
21220
|
+
[attr.aria-label]="item.label"
|
|
21221
|
+
[attr.aria-current]="item.active ? 'page' : null"
|
|
21222
|
+
[attr.title]="item.label"
|
|
21223
|
+
(click)="navigateTo(item.href); mobileClose.emit()"
|
|
21224
|
+
>
|
|
21225
|
+
<span class="jv-sidebar-link-main">
|
|
21226
|
+
@if (item.icon) {
|
|
21227
|
+
<jv-icon [name]="item.icon" [size]="18" />
|
|
21228
|
+
}
|
|
21229
|
+
|
|
21230
|
+
@if (!collapsed()) {
|
|
21231
|
+
<span>{{ item.label }}</span>
|
|
21232
|
+
}
|
|
21233
|
+
</span>
|
|
21234
|
+
</button>
|
|
21235
|
+
} @else {
|
|
21236
|
+
<a
|
|
21237
|
+
class="jv-sidebar-link"
|
|
21238
|
+
[class.is-active]="item.active"
|
|
21239
|
+
[attr.aria-label]="item.label"
|
|
21240
|
+
[attr.aria-current]="item.active ? 'page' : null"
|
|
21241
|
+
[routerLink]="item.href"
|
|
21242
|
+
[attr.title]="item.label"
|
|
21243
|
+
(click)="mobileClose.emit()"
|
|
21244
|
+
>
|
|
21245
|
+
<span class="jv-sidebar-link-main">
|
|
21246
|
+
@if (item.icon) {
|
|
21247
|
+
<jv-icon [name]="item.icon" [size]="18" />
|
|
21248
|
+
}
|
|
21249
|
+
|
|
21250
|
+
@if (!collapsed()) {
|
|
21251
|
+
<span>{{ item.label }}</span>
|
|
21252
|
+
}
|
|
21253
|
+
</span>
|
|
21254
|
+
</a>
|
|
21255
|
+
}
|
|
21256
|
+
}
|
|
21257
|
+
|
|
21258
|
+
@if (!collapsed() && item.children.length > 0 && isExpanded(item.id)) {
|
|
21259
|
+
<div class="jv-sidebar-children" [id]="'jv-sidebar-section-' + item.id">
|
|
21260
|
+
@for (child of item.children; track child.id) {
|
|
21261
|
+
@if (isHashLink(child.href)) {
|
|
21262
|
+
<button type="button" class="jv-sidebar-child-link" [class.is-active]="child.active" [attr.aria-label]="child.label" [attr.aria-current]="child.active ? 'page' : null" [attr.title]="child.label" (click)="navigateTo(child.href)">
|
|
21263
|
+
{{ child.label }}
|
|
21264
|
+
</button>
|
|
21265
|
+
} @else {
|
|
21266
|
+
<a class="jv-sidebar-child-link" [class.is-active]="child.active" [attr.aria-label]="child.label" [attr.aria-current]="child.active ? 'page' : null" [routerLink]="child.href" [attr.title]="child.label" (click)="mobileClose.emit()">
|
|
21267
|
+
{{ child.label }}
|
|
21268
|
+
</a>
|
|
21269
|
+
}
|
|
21270
|
+
}
|
|
21271
|
+
</div>
|
|
21272
|
+
}
|
|
21273
|
+
</li>
|
|
21274
|
+
}
|
|
21275
|
+
</ul>
|
|
21276
|
+
</nav>
|
|
21277
|
+
|
|
21278
|
+
<div class="jv-sidebar-footer">
|
|
21279
|
+
<button type="button" class="jv-sidebar-toggle" (click)="collapseToggle.emit()">
|
|
21280
|
+
<jv-icon [name]="collapsed() ? 'menu' : 'panel-left-close'" [size]="18" />
|
|
21281
|
+
@if (!collapsed()) {
|
|
21282
|
+
<span>Collapse</span>
|
|
21283
|
+
}
|
|
21284
|
+
</button>
|
|
21285
|
+
|
|
21286
|
+
<div class="jv-sidebar-mobile-extras">
|
|
21287
|
+
@if (showThemeSelector()) {
|
|
21288
|
+
<div class="theme-group" aria-label="Theme selector">
|
|
21289
|
+
@for (option of themeOptions(); track option.value) {
|
|
21290
|
+
<button
|
|
21291
|
+
type="button"
|
|
21292
|
+
class="theme-pill"
|
|
21293
|
+
[class.is-active]="currentTheme() === option.value"
|
|
21294
|
+
(click)="themeChange.emit(option.value)"
|
|
21295
|
+
>
|
|
21296
|
+
@if (option.icon) {
|
|
21297
|
+
<jv-icon [name]="option.icon" [size]="16" />
|
|
21298
|
+
}
|
|
21299
|
+
<span>{{ option.label }}</span>
|
|
21300
|
+
</button>
|
|
21301
|
+
}
|
|
21302
|
+
</div>
|
|
21303
|
+
}
|
|
21304
|
+
|
|
21305
|
+
<div class="mobile-actions">
|
|
21306
|
+
@for (action of topbarActions(); track action.id) {
|
|
21307
|
+
<button type="button" class="icon-button" [attr.aria-label]="action.label" (click)="actionClick.emit(action.id); mobileClose.emit()">
|
|
21308
|
+
<jv-icon [name]="action.icon" [size]="18" />
|
|
21309
|
+
</button>
|
|
21310
|
+
}
|
|
21311
|
+
</div>
|
|
21312
|
+
</div>
|
|
21313
|
+
</div>
|
|
21314
|
+
</aside>
|
|
21315
|
+
`, styles: [".jv-sidebar-backdrop{display:none}.jv-sidebar{display:grid;grid-template-rows:auto 1fr auto;gap:var(--jv-spacing-lg);width:280px;min-width:280px;height:100vh;padding:var(--jv-spacing-lg);overflow-y:auto;border-right:1px solid var(--jv-color-border);background:var(--jv-color-surface);scrollbar-width:none;-ms-overflow-style:none}.jv-sidebar::-webkit-scrollbar{width:0;height:0;display:none}.jv-sidebar.is-collapsed{width:96px;min-width:96px;padding-inline:var(--jv-spacing-md)}.jv-sidebar-footer{display:grid;gap:var(--jv-spacing-md)}.jv-sidebar-mobile-extras{display:none}.jv-sidebar-brand,.jv-sidebar-link,.jv-sidebar-toggle{display:flex;align-items:center;gap:var(--jv-spacing-sm)}.brand-mark{display:inline-grid;place-items:center;width:var(--jv-density-control-height);height:var(--jv-density-control-height);border-radius:var(--jv-radius-md);background:color-mix(in srgb,var(--jv-color-primary) 16%,var(--jv-color-surface));color:var(--jv-color-primary);flex:0 0 auto}.brand-copy{display:grid;gap:.1rem}.brand-copy span{color:var(--jv-color-foreground-muted);font-size:.875rem}.jv-sidebar-item{display:grid;gap:var(--jv-spacing-xs);list-style:none}.jv-sidebar-list{display:grid;gap:var(--jv-spacing-xs);margin:0;padding:0}.jv-sidebar-nav{display:grid;gap:var(--jv-spacing-xs);align-content:start}.jv-sidebar-link,.jv-sidebar-child-link,.jv-sidebar-toggle{width:100%;display:flex;align-items:center;justify-content:space-between;min-height:var(--jv-density-control-height);padding:0 var(--jv-spacing-md);border:1px solid transparent;border-radius:var(--jv-radius-md);background:transparent;color:var(--jv-color-foreground-muted);text-decoration:none;cursor:pointer}.jv-sidebar-link-main{display:inline-flex;align-items:center;gap:var(--jv-spacing-sm)}.jv-sidebar-link:hover,.jv-sidebar-child-link:hover,.jv-sidebar-toggle:hover{background:var(--jv-color-surface-muted);color:var(--jv-color-foreground)}.jv-sidebar-link.is-active,.jv-sidebar-child-link.is-active{border-color:color-mix(in srgb,var(--jv-color-primary) 25%,var(--jv-color-border));background:color-mix(in srgb,var(--jv-color-primary) 12%,var(--jv-color-surface));color:var(--jv-color-foreground)}.jv-sidebar-children{display:grid;gap:var(--jv-spacing-xs);margin-left:var(--jv-spacing-xl);padding-left:var(--jv-spacing-sm);border-left:1px solid var(--jv-color-border)}.jv-sidebar-child-link{display:flex;align-items:center;min-height:calc(var(--jv-density-control-height) - .25rem);font-size:.9rem}.jv-sidebar-toggle{width:100%;background:var(--jv-color-surface-muted);cursor:pointer}@media(max-width:900px){.jv-sidebar-backdrop{display:block;position:fixed;inset:0;z-index:99;background:#0006}.jv-sidebar{position:fixed;top:0;left:0;z-index:100;width:280px;min-width:280px;height:100vh;border-right:1px solid var(--jv-color-border);border-bottom:none;box-shadow:var(--jv-shadow-lg);transform:translate(-100%);visibility:hidden;transition:transform .24s cubic-bezier(.4,0,.2,1),visibility .24s}.jv-sidebar.is-mobile-open{transform:translate(0);visibility:visible}.jv-sidebar.is-collapsed{width:280px;min-width:280px}.jv-sidebar-mobile-extras{display:flex;flex-direction:column;gap:var(--jv-spacing-md);padding-top:var(--jv-spacing-md);border-top:1px solid var(--jv-color-border)}.jv-sidebar-mobile-extras .theme-group{display:flex;flex-wrap:wrap;gap:var(--jv-spacing-xs)}.jv-sidebar-mobile-extras .theme-pill{display:inline-flex;align-items:center;gap:var(--jv-spacing-xs);min-height:var(--jv-density-control-height);padding:0 var(--jv-spacing-md);border:1px solid var(--jv-color-border);border-radius:999px;background:var(--jv-color-surface-muted);color:var(--jv-color-foreground);cursor:pointer;font:inherit}.jv-sidebar-mobile-extras .theme-pill.is-active{border-color:var(--jv-color-primary);background:color-mix(in srgb,var(--jv-color-primary) 14%,var(--jv-color-surface))}.jv-sidebar-mobile-extras .mobile-actions{display:flex;gap:var(--jv-spacing-sm)}.jv-sidebar-mobile-extras .icon-button{display:inline-grid;place-items:center;width:var(--jv-density-control-height);height:var(--jv-density-control-height);border:1px solid var(--jv-color-border);border-radius:999px;background:var(--jv-color-surface-muted);color:var(--jv-color-foreground);cursor:pointer}}\n"] }]
|
|
20102
21316
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], brandIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandIcon", required: false }] }], items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: false }] }], collapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "collapsed", required: false }] }], mobileOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobileOpen", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], currentTheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentTheme", required: false }] }], themeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeOptions", required: false }] }], topbarActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "topbarActions", required: false }] }], showThemeSelector: [{ type: i0.Input, args: [{ isSignal: true, alias: "showThemeSelector", required: false }] }], collapseToggle: [{ type: i0.Output, args: ["collapseToggle"] }], mobileClose: [{ type: i0.Output, args: ["mobileClose"] }], themeChange: [{ type: i0.Output, args: ["themeChange"] }], actionClick: [{ type: i0.Output, args: ["actionClick"] }] } });
|
|
20103
21317
|
|
|
20104
21318
|
class JvTopbarComponent {
|
|
@@ -20229,88 +21443,88 @@ class JvDashboardShellComponent {
|
|
|
20229
21443
|
themeChange = output();
|
|
20230
21444
|
topbarActionClick = output();
|
|
20231
21445
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvDashboardShellComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20232
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.17", type: JvDashboardShellComponent, isStandalone: true, selector: "jv-dashboard-shell", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, sidebarSubtitle: { classPropertyName: "sidebarSubtitle", publicName: "sidebarSubtitle", isSignal: true, isRequired: false, transformFunction: null }, brandIcon: { classPropertyName: "brandIcon", publicName: "brandIcon", isSignal: true, isRequired: false, transformFunction: null }, navItems: { classPropertyName: "navItems", publicName: "navItems", isSignal: true, isRequired: false, transformFunction: null }, sidebarCollapsed: { classPropertyName: "sidebarCollapsed", publicName: "sidebarCollapsed", isSignal: true, isRequired: false, transformFunction: null }, mobileSidebarOpen: { classPropertyName: "mobileSidebarOpen", publicName: "mobileSidebarOpen", isSignal: true, isRequired: false, transformFunction: null }, topbarTitle: { classPropertyName: "topbarTitle", publicName: "topbarTitle", isSignal: true, isRequired: false, transformFunction: null }, topbarSubtitle: { classPropertyName: "topbarSubtitle", publicName: "topbarSubtitle", isSignal: true, isRequired: false, transformFunction: null }, currentTheme: { classPropertyName: "currentTheme", publicName: "currentTheme", isSignal: true, isRequired: false, transformFunction: null }, themeOptions: { classPropertyName: "themeOptions", publicName: "themeOptions", isSignal: true, isRequired: false, transformFunction: null }, topbarActions: { classPropertyName: "topbarActions", publicName: "topbarActions", isSignal: true, isRequired: false, transformFunction: null }, showThemeSelector: { classPropertyName: "showThemeSelector", publicName: "showThemeSelector", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { menuClick: "menuClick", mobileClose: "mobileClose", sidebarCollapseToggle: "sidebarCollapseToggle", themeChange: "themeChange", topbarActionClick: "topbarActionClick" }, ngImport: i0, template: `
|
|
20233
|
-
<div class="jv-dashboard-shell" [class.is-sidebar-collapsed]="sidebarCollapsed()">
|
|
20234
|
-
<jv-sidebar
|
|
20235
|
-
[title]="title()"
|
|
20236
|
-
[subtitle]="sidebarSubtitle()"
|
|
20237
|
-
[brandIcon]="brandIcon()"
|
|
20238
|
-
[items]="navItems()"
|
|
20239
|
-
[collapsed]="sidebarCollapsed()"
|
|
20240
|
-
[mobileOpen]="mobileSidebarOpen()"
|
|
20241
|
-
[currentTheme]="currentTheme()"
|
|
20242
|
-
[themeOptions]="themeOptions()"
|
|
20243
|
-
[topbarActions]="topbarActions()"
|
|
20244
|
-
[showThemeSelector]="showThemeSelector()"
|
|
20245
|
-
(collapseToggle)="sidebarCollapseToggle.emit()"
|
|
20246
|
-
(mobileClose)="mobileClose.emit()"
|
|
20247
|
-
(themeChange)="themeChange.emit($event)"
|
|
20248
|
-
(actionClick)="topbarActionClick.emit($event)"
|
|
20249
|
-
/>
|
|
20250
|
-
|
|
20251
|
-
<div class="jv-dashboard-main">
|
|
20252
|
-
<jv-topbar
|
|
20253
|
-
[title]="topbarTitle()"
|
|
20254
|
-
[subtitle]="topbarSubtitle()"
|
|
20255
|
-
[currentTheme]="currentTheme()"
|
|
20256
|
-
[themeOptions]="themeOptions()"
|
|
20257
|
-
[actions]="topbarActions()"
|
|
20258
|
-
[showThemeSelector]="showThemeSelector()"
|
|
20259
|
-
(menuClick)="menuClick.emit()"
|
|
20260
|
-
(themeChange)="themeChange.emit($event)"
|
|
20261
|
-
(actionClick)="topbarActionClick.emit($event)"
|
|
20262
|
-
>
|
|
20263
|
-
<ng-content select="[topbar-actions]" topbar-actions></ng-content>
|
|
20264
|
-
</jv-topbar>
|
|
20265
|
-
|
|
20266
|
-
<main class="jv-dashboard-content">
|
|
20267
|
-
<ng-content></ng-content>
|
|
20268
|
-
</main>
|
|
20269
|
-
</div>
|
|
20270
|
-
</div>
|
|
21446
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.17", type: JvDashboardShellComponent, isStandalone: true, selector: "jv-dashboard-shell", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, sidebarSubtitle: { classPropertyName: "sidebarSubtitle", publicName: "sidebarSubtitle", isSignal: true, isRequired: false, transformFunction: null }, brandIcon: { classPropertyName: "brandIcon", publicName: "brandIcon", isSignal: true, isRequired: false, transformFunction: null }, navItems: { classPropertyName: "navItems", publicName: "navItems", isSignal: true, isRequired: false, transformFunction: null }, sidebarCollapsed: { classPropertyName: "sidebarCollapsed", publicName: "sidebarCollapsed", isSignal: true, isRequired: false, transformFunction: null }, mobileSidebarOpen: { classPropertyName: "mobileSidebarOpen", publicName: "mobileSidebarOpen", isSignal: true, isRequired: false, transformFunction: null }, topbarTitle: { classPropertyName: "topbarTitle", publicName: "topbarTitle", isSignal: true, isRequired: false, transformFunction: null }, topbarSubtitle: { classPropertyName: "topbarSubtitle", publicName: "topbarSubtitle", isSignal: true, isRequired: false, transformFunction: null }, currentTheme: { classPropertyName: "currentTheme", publicName: "currentTheme", isSignal: true, isRequired: false, transformFunction: null }, themeOptions: { classPropertyName: "themeOptions", publicName: "themeOptions", isSignal: true, isRequired: false, transformFunction: null }, topbarActions: { classPropertyName: "topbarActions", publicName: "topbarActions", isSignal: true, isRequired: false, transformFunction: null }, showThemeSelector: { classPropertyName: "showThemeSelector", publicName: "showThemeSelector", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { menuClick: "menuClick", mobileClose: "mobileClose", sidebarCollapseToggle: "sidebarCollapseToggle", themeChange: "themeChange", topbarActionClick: "topbarActionClick" }, ngImport: i0, template: `
|
|
21447
|
+
<div class="jv-dashboard-shell" [class.is-sidebar-collapsed]="sidebarCollapsed()">
|
|
21448
|
+
<jv-sidebar
|
|
21449
|
+
[title]="title()"
|
|
21450
|
+
[subtitle]="sidebarSubtitle()"
|
|
21451
|
+
[brandIcon]="brandIcon()"
|
|
21452
|
+
[items]="navItems()"
|
|
21453
|
+
[collapsed]="sidebarCollapsed()"
|
|
21454
|
+
[mobileOpen]="mobileSidebarOpen()"
|
|
21455
|
+
[currentTheme]="currentTheme()"
|
|
21456
|
+
[themeOptions]="themeOptions()"
|
|
21457
|
+
[topbarActions]="topbarActions()"
|
|
21458
|
+
[showThemeSelector]="showThemeSelector()"
|
|
21459
|
+
(collapseToggle)="sidebarCollapseToggle.emit()"
|
|
21460
|
+
(mobileClose)="mobileClose.emit()"
|
|
21461
|
+
(themeChange)="themeChange.emit($event)"
|
|
21462
|
+
(actionClick)="topbarActionClick.emit($event)"
|
|
21463
|
+
/>
|
|
21464
|
+
|
|
21465
|
+
<div class="jv-dashboard-main">
|
|
21466
|
+
<jv-topbar
|
|
21467
|
+
[title]="topbarTitle()"
|
|
21468
|
+
[subtitle]="topbarSubtitle()"
|
|
21469
|
+
[currentTheme]="currentTheme()"
|
|
21470
|
+
[themeOptions]="themeOptions()"
|
|
21471
|
+
[actions]="topbarActions()"
|
|
21472
|
+
[showThemeSelector]="showThemeSelector()"
|
|
21473
|
+
(menuClick)="menuClick.emit()"
|
|
21474
|
+
(themeChange)="themeChange.emit($event)"
|
|
21475
|
+
(actionClick)="topbarActionClick.emit($event)"
|
|
21476
|
+
>
|
|
21477
|
+
<ng-content select="[topbar-actions]" topbar-actions></ng-content>
|
|
21478
|
+
</jv-topbar>
|
|
21479
|
+
|
|
21480
|
+
<main class="jv-dashboard-content">
|
|
21481
|
+
<ng-content></ng-content>
|
|
21482
|
+
</main>
|
|
21483
|
+
</div>
|
|
21484
|
+
</div>
|
|
20271
21485
|
`, isInline: true, styles: [":host{display:block;height:100dvh;overflow:hidden}.jv-dashboard-shell{display:grid;height:100%;grid-template-columns:auto 1fr;background:var(--jv-color-background);overflow:hidden}.jv-dashboard-main{display:grid;grid-template-rows:auto 1fr;min-width:0;min-height:0;overflow:hidden}.jv-dashboard-content{overflow:auto;min-width:0;min-height:0;padding:var(--jv-spacing-xl);scrollbar-width:none;-ms-overflow-style:none}.jv-dashboard-content::-webkit-scrollbar{width:0;height:0;display:none}@media(max-width:900px){.jv-dashboard-shell{grid-template-columns:1fr}.jv-dashboard-content{padding:var(--jv-spacing-lg)}}\n"], dependencies: [{ kind: "component", type: JvSidebarComponent, selector: "jv-sidebar", inputs: ["title", "subtitle", "brandIcon", "items", "collapsed", "mobileOpen", "ariaLabel", "currentTheme", "themeOptions", "topbarActions", "showThemeSelector"], outputs: ["collapseToggle", "mobileClose", "themeChange", "actionClick"] }, { kind: "component", type: JvTopbarComponent, selector: "jv-topbar", inputs: ["title", "subtitle", "currentTheme", "themeOptions", "actions", "showThemeSelector"], outputs: ["menuClick", "themeChange", "actionClick"] }] });
|
|
20272
21486
|
}
|
|
20273
21487
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvDashboardShellComponent, decorators: [{
|
|
20274
21488
|
type: Component,
|
|
20275
|
-
args: [{ selector: 'jv-dashboard-shell', standalone: true, imports: [JvSidebarComponent, JvTopbarComponent], template: `
|
|
20276
|
-
<div class="jv-dashboard-shell" [class.is-sidebar-collapsed]="sidebarCollapsed()">
|
|
20277
|
-
<jv-sidebar
|
|
20278
|
-
[title]="title()"
|
|
20279
|
-
[subtitle]="sidebarSubtitle()"
|
|
20280
|
-
[brandIcon]="brandIcon()"
|
|
20281
|
-
[items]="navItems()"
|
|
20282
|
-
[collapsed]="sidebarCollapsed()"
|
|
20283
|
-
[mobileOpen]="mobileSidebarOpen()"
|
|
20284
|
-
[currentTheme]="currentTheme()"
|
|
20285
|
-
[themeOptions]="themeOptions()"
|
|
20286
|
-
[topbarActions]="topbarActions()"
|
|
20287
|
-
[showThemeSelector]="showThemeSelector()"
|
|
20288
|
-
(collapseToggle)="sidebarCollapseToggle.emit()"
|
|
20289
|
-
(mobileClose)="mobileClose.emit()"
|
|
20290
|
-
(themeChange)="themeChange.emit($event)"
|
|
20291
|
-
(actionClick)="topbarActionClick.emit($event)"
|
|
20292
|
-
/>
|
|
20293
|
-
|
|
20294
|
-
<div class="jv-dashboard-main">
|
|
20295
|
-
<jv-topbar
|
|
20296
|
-
[title]="topbarTitle()"
|
|
20297
|
-
[subtitle]="topbarSubtitle()"
|
|
20298
|
-
[currentTheme]="currentTheme()"
|
|
20299
|
-
[themeOptions]="themeOptions()"
|
|
20300
|
-
[actions]="topbarActions()"
|
|
20301
|
-
[showThemeSelector]="showThemeSelector()"
|
|
20302
|
-
(menuClick)="menuClick.emit()"
|
|
20303
|
-
(themeChange)="themeChange.emit($event)"
|
|
20304
|
-
(actionClick)="topbarActionClick.emit($event)"
|
|
20305
|
-
>
|
|
20306
|
-
<ng-content select="[topbar-actions]" topbar-actions></ng-content>
|
|
20307
|
-
</jv-topbar>
|
|
20308
|
-
|
|
20309
|
-
<main class="jv-dashboard-content">
|
|
20310
|
-
<ng-content></ng-content>
|
|
20311
|
-
</main>
|
|
20312
|
-
</div>
|
|
20313
|
-
</div>
|
|
21489
|
+
args: [{ selector: 'jv-dashboard-shell', standalone: true, imports: [JvSidebarComponent, JvTopbarComponent], template: `
|
|
21490
|
+
<div class="jv-dashboard-shell" [class.is-sidebar-collapsed]="sidebarCollapsed()">
|
|
21491
|
+
<jv-sidebar
|
|
21492
|
+
[title]="title()"
|
|
21493
|
+
[subtitle]="sidebarSubtitle()"
|
|
21494
|
+
[brandIcon]="brandIcon()"
|
|
21495
|
+
[items]="navItems()"
|
|
21496
|
+
[collapsed]="sidebarCollapsed()"
|
|
21497
|
+
[mobileOpen]="mobileSidebarOpen()"
|
|
21498
|
+
[currentTheme]="currentTheme()"
|
|
21499
|
+
[themeOptions]="themeOptions()"
|
|
21500
|
+
[topbarActions]="topbarActions()"
|
|
21501
|
+
[showThemeSelector]="showThemeSelector()"
|
|
21502
|
+
(collapseToggle)="sidebarCollapseToggle.emit()"
|
|
21503
|
+
(mobileClose)="mobileClose.emit()"
|
|
21504
|
+
(themeChange)="themeChange.emit($event)"
|
|
21505
|
+
(actionClick)="topbarActionClick.emit($event)"
|
|
21506
|
+
/>
|
|
21507
|
+
|
|
21508
|
+
<div class="jv-dashboard-main">
|
|
21509
|
+
<jv-topbar
|
|
21510
|
+
[title]="topbarTitle()"
|
|
21511
|
+
[subtitle]="topbarSubtitle()"
|
|
21512
|
+
[currentTheme]="currentTheme()"
|
|
21513
|
+
[themeOptions]="themeOptions()"
|
|
21514
|
+
[actions]="topbarActions()"
|
|
21515
|
+
[showThemeSelector]="showThemeSelector()"
|
|
21516
|
+
(menuClick)="menuClick.emit()"
|
|
21517
|
+
(themeChange)="themeChange.emit($event)"
|
|
21518
|
+
(actionClick)="topbarActionClick.emit($event)"
|
|
21519
|
+
>
|
|
21520
|
+
<ng-content select="[topbar-actions]" topbar-actions></ng-content>
|
|
21521
|
+
</jv-topbar>
|
|
21522
|
+
|
|
21523
|
+
<main class="jv-dashboard-content">
|
|
21524
|
+
<ng-content></ng-content>
|
|
21525
|
+
</main>
|
|
21526
|
+
</div>
|
|
21527
|
+
</div>
|
|
20314
21528
|
`, styles: [":host{display:block;height:100dvh;overflow:hidden}.jv-dashboard-shell{display:grid;height:100%;grid-template-columns:auto 1fr;background:var(--jv-color-background);overflow:hidden}.jv-dashboard-main{display:grid;grid-template-rows:auto 1fr;min-width:0;min-height:0;overflow:hidden}.jv-dashboard-content{overflow:auto;min-width:0;min-height:0;padding:var(--jv-spacing-xl);scrollbar-width:none;-ms-overflow-style:none}.jv-dashboard-content::-webkit-scrollbar{width:0;height:0;display:none}@media(max-width:900px){.jv-dashboard-shell{grid-template-columns:1fr}.jv-dashboard-content{padding:var(--jv-spacing-lg)}}\n"] }]
|
|
20315
21529
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], sidebarSubtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarSubtitle", required: false }] }], brandIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandIcon", required: false }] }], navItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "navItems", required: false }] }], sidebarCollapsed: [{ type: i0.Input, args: [{ isSignal: true, alias: "sidebarCollapsed", required: false }] }], mobileSidebarOpen: [{ type: i0.Input, args: [{ isSignal: true, alias: "mobileSidebarOpen", required: false }] }], topbarTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "topbarTitle", required: false }] }], topbarSubtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "topbarSubtitle", required: false }] }], currentTheme: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentTheme", required: false }] }], themeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "themeOptions", required: false }] }], topbarActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "topbarActions", required: false }] }], showThemeSelector: [{ type: i0.Input, args: [{ isSignal: true, alias: "showThemeSelector", required: false }] }], menuClick: [{ type: i0.Output, args: ["menuClick"] }], mobileClose: [{ type: i0.Output, args: ["mobileClose"] }], sidebarCollapseToggle: [{ type: i0.Output, args: ["sidebarCollapseToggle"] }], themeChange: [{ type: i0.Output, args: ["themeChange"] }], topbarActionClick: [{ type: i0.Output, args: ["topbarActionClick"] }] } });
|
|
20316
21530
|
|
|
@@ -20379,40 +21593,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
20379
21593
|
`, styles: [".jv-page{display:grid;gap:var(--jv-spacing-lg);min-width:0}.jv-page-header{display:grid;gap:var(--jv-spacing-sm)}.jv-page-content{min-width:0}.eyebrow{margin:0;color:var(--jv-color-primary);font-size:.75rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase}h1,.description{margin:0}.description{color:var(--jv-color-foreground-muted);max-width:72ch}\n"] }]
|
|
20380
21594
|
}], propDecorators: { eyebrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "eyebrow", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], breadcrumbs: [{ type: i0.Input, args: [{ isSignal: true, alias: "breadcrumbs", required: false }] }] } });
|
|
20381
21595
|
|
|
20382
|
-
class JvListComponent {
|
|
20383
|
-
role = input('list', ...(ngDevMode ? [{ debugName: "role" }] : /* istanbul ignore next */ []));
|
|
20384
|
-
variant = input(null, ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
20385
|
-
ariaLabel = input('', ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
20386
|
-
variantClass = computed(() => {
|
|
20387
|
-
const v = this.variant();
|
|
20388
|
-
return v ? `jv-list--${v}` : '';
|
|
20389
|
-
}, ...(ngDevMode ? [{ debugName: "variantClass" }] : /* istanbul ignore next */ []));
|
|
20390
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
20391
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.17", type: JvListComponent, isStandalone: true, selector: "jv-list", inputs: { role: { classPropertyName: "role", publicName: "role", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
20392
|
-
<ul
|
|
20393
|
-
class="jv-list"
|
|
20394
|
-
[class]="variantClass()"
|
|
20395
|
-
[attr.role]="role() === 'navigation' ? 'list' : null"
|
|
20396
|
-
[attr.aria-label]="ariaLabel()"
|
|
20397
|
-
>
|
|
20398
|
-
<ng-content />
|
|
20399
|
-
</ul>
|
|
20400
|
-
`, isInline: true, styles: [".jv-list{display:block;list-style:none;margin:0;padding:0}.jv-list>:not(:last-child){border-bottom:1px solid var(--jv-color-border)}.jv-list--bordered{border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md)}\n"] });
|
|
20401
|
-
}
|
|
20402
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvListComponent, decorators: [{
|
|
20403
|
-
type: Component,
|
|
20404
|
-
args: [{ selector: 'jv-list', standalone: true, template: `
|
|
20405
|
-
<ul
|
|
20406
|
-
class="jv-list"
|
|
20407
|
-
[class]="variantClass()"
|
|
20408
|
-
[attr.role]="role() === 'navigation' ? 'list' : null"
|
|
20409
|
-
[attr.aria-label]="ariaLabel()"
|
|
20410
|
-
>
|
|
20411
|
-
<ng-content />
|
|
20412
|
-
</ul>
|
|
20413
|
-
`, styles: [".jv-list{display:block;list-style:none;margin:0;padding:0}.jv-list>:not(:last-child){border-bottom:1px solid var(--jv-color-border)}.jv-list--bordered{border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md)}\n"] }]
|
|
20414
|
-
}], propDecorators: { role: [{ type: i0.Input, args: [{ isSignal: true, alias: "role", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }] } });
|
|
20415
|
-
|
|
20416
21596
|
class JvListItemComponent {
|
|
20417
21597
|
title = input.required(...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
20418
21598
|
description = input('', ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
|
|
@@ -20481,6 +21661,470 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
20481
21661
|
`, styles: [":host{display:block}.jv-list-item{display:flex;align-items:center;gap:var(--jv-spacing-md);padding:var(--jv-spacing-md);background:var(--jv-color-surface);cursor:default;outline:none;transition:background-color .16s ease}.jv-list-item:hover{background:var(--jv-color-surface-muted)}.jv-list-item:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:-2px}.jv-list-item--disabled{opacity:.5;cursor:not-allowed;pointer-events:none}.jv-list-item--active{background:color-mix(in srgb,var(--jv-color-primary) 10%,var(--jv-color-surface));border-left:3px solid var(--jv-color-primary);padding-left:calc(var(--jv-spacing-md) - 3px)}.jv-list-item-text{flex:1;display:flex;flex-direction:column;gap:.125rem;min-width:0}.jv-list-item-title{font-weight:600;font-size:var(--jv-density-font-size);color:var(--jv-color-foreground);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.jv-list-item-description{font-size:.85rem;color:var(--jv-color-foreground-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.jv-list-item-meta{display:flex;align-items:center;gap:var(--jv-spacing-sm);flex-shrink:0}.jv-list-item-leading{flex-shrink:0;color:var(--jv-color-foreground-muted)}\n"] }]
|
|
20482
21662
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], leadingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "leadingIcon", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }], activated: [{ type: i0.Output, args: ["activated"] }] } });
|
|
20483
21663
|
|
|
21664
|
+
class JvTabPanelDirective {
|
|
21665
|
+
templateRef;
|
|
21666
|
+
id = input.required({ ...(ngDevMode ? { debugName: "id" } : /* istanbul ignore next */ {}), alias: 'jvTabPanel' });
|
|
21667
|
+
constructor(templateRef) {
|
|
21668
|
+
this.templateRef = templateRef;
|
|
21669
|
+
}
|
|
21670
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvTabPanelDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
|
|
21671
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.17", type: JvTabPanelDirective, isStandalone: true, selector: "ng-template[jvTabPanel]", inputs: { id: { classPropertyName: "id", publicName: "jvTabPanel", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 });
|
|
21672
|
+
}
|
|
21673
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvTabPanelDirective, decorators: [{
|
|
21674
|
+
type: Directive,
|
|
21675
|
+
args: [{
|
|
21676
|
+
selector: 'ng-template[jvTabPanel]',
|
|
21677
|
+
standalone: true,
|
|
21678
|
+
}]
|
|
21679
|
+
}], ctorParameters: () => [{ type: i0.TemplateRef }], propDecorators: { id: [{ type: i0.Input, args: [{ isSignal: true, alias: "jvTabPanel", required: true }] }] } });
|
|
21680
|
+
|
|
21681
|
+
let tabsSequence = 0;
|
|
21682
|
+
class JvTabsComponent {
|
|
21683
|
+
instanceId = ++tabsSequence;
|
|
21684
|
+
panelTemplates = contentChildren(JvTabPanelDirective, ...(ngDevMode ? [{ debugName: "panelTemplates" }] : /* istanbul ignore next */ []));
|
|
21685
|
+
tabListRef = viewChild('tabList', ...(ngDevMode ? [{ debugName: "tabListRef" }] : /* istanbul ignore next */ []));
|
|
21686
|
+
tabs = input([], ...(ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []));
|
|
21687
|
+
activeTabId = input(null, ...(ngDevMode ? [{ debugName: "activeTabId" }] : /* istanbul ignore next */ []));
|
|
21688
|
+
keepMounted = input(true, ...(ngDevMode ? [{ debugName: "keepMounted" }] : /* istanbul ignore next */ []));
|
|
21689
|
+
activeTabChange = output();
|
|
21690
|
+
showScrollLeft = signal(false, ...(ngDevMode ? [{ debugName: "showScrollLeft" }] : /* istanbul ignore next */ []));
|
|
21691
|
+
showScrollRight = signal(false, ...(ngDevMode ? [{ debugName: "showScrollRight" }] : /* istanbul ignore next */ []));
|
|
21692
|
+
resolvedActiveTabId = computed(() => {
|
|
21693
|
+
const enabledTabs = this.tabs().filter((tab) => !tab.disabled);
|
|
21694
|
+
const requestedId = this.activeTabId();
|
|
21695
|
+
if (requestedId && enabledTabs.some((tab) => tab.id === requestedId)) {
|
|
21696
|
+
return requestedId;
|
|
21697
|
+
}
|
|
21698
|
+
return enabledTabs[0]?.id ?? null;
|
|
21699
|
+
}, ...(ngDevMode ? [{ debugName: "resolvedActiveTabId" }] : /* istanbul ignore next */ []));
|
|
21700
|
+
constructor() {
|
|
21701
|
+
afterNextRender(() => this.updateScrollControls());
|
|
21702
|
+
effect(() => {
|
|
21703
|
+
this.tabs();
|
|
21704
|
+
this.panelTemplates();
|
|
21705
|
+
this.activeTabId();
|
|
21706
|
+
queueMicrotask(() => {
|
|
21707
|
+
this.ensureActiveTabVisible();
|
|
21708
|
+
this.updateScrollControls();
|
|
21709
|
+
});
|
|
21710
|
+
});
|
|
21711
|
+
}
|
|
21712
|
+
ngAfterViewInit() {
|
|
21713
|
+
this.updateScrollControls();
|
|
21714
|
+
}
|
|
21715
|
+
handleWindowResize() {
|
|
21716
|
+
this.updateScrollControls();
|
|
21717
|
+
}
|
|
21718
|
+
isActive(tabId) {
|
|
21719
|
+
return this.resolvedActiveTabId() === tabId;
|
|
21720
|
+
}
|
|
21721
|
+
getTabIndex(tabId, disabled) {
|
|
21722
|
+
if (disabled) {
|
|
21723
|
+
return -1;
|
|
21724
|
+
}
|
|
21725
|
+
return this.isActive(tabId) ? 0 : -1;
|
|
21726
|
+
}
|
|
21727
|
+
activateTab(tabId) {
|
|
21728
|
+
const tab = this.tabs().find((item) => item.id === tabId);
|
|
21729
|
+
if (!tab || tab.disabled || this.resolvedActiveTabId() === tabId) {
|
|
21730
|
+
return;
|
|
21731
|
+
}
|
|
21732
|
+
this.activeTabChange.emit(tabId);
|
|
21733
|
+
queueMicrotask(() => this.focusTabButton(tabId));
|
|
21734
|
+
}
|
|
21735
|
+
handleKeydown(event, currentTabId) {
|
|
21736
|
+
const enabledTabs = this.tabs().filter((tab) => !tab.disabled);
|
|
21737
|
+
if (enabledTabs.length === 0) {
|
|
21738
|
+
return;
|
|
21739
|
+
}
|
|
21740
|
+
const currentIndex = Math.max(0, enabledTabs.findIndex((tab) => tab.id === currentTabId));
|
|
21741
|
+
switch (event.key) {
|
|
21742
|
+
case 'ArrowRight':
|
|
21743
|
+
event.preventDefault();
|
|
21744
|
+
this.activateAndFocus(enabledTabs[(currentIndex + 1) % enabledTabs.length].id);
|
|
21745
|
+
break;
|
|
21746
|
+
case 'ArrowLeft':
|
|
21747
|
+
event.preventDefault();
|
|
21748
|
+
this.activateAndFocus(enabledTabs[(currentIndex - 1 + enabledTabs.length) % enabledTabs.length].id);
|
|
21749
|
+
break;
|
|
21750
|
+
case 'Home':
|
|
21751
|
+
event.preventDefault();
|
|
21752
|
+
this.activateAndFocus(enabledTabs[0].id);
|
|
21753
|
+
break;
|
|
21754
|
+
case 'End':
|
|
21755
|
+
event.preventDefault();
|
|
21756
|
+
this.activateAndFocus(enabledTabs[enabledTabs.length - 1].id);
|
|
21757
|
+
break;
|
|
21758
|
+
}
|
|
21759
|
+
}
|
|
21760
|
+
scrollTabs(direction) {
|
|
21761
|
+
const tabList = this.tabListRef()?.nativeElement;
|
|
21762
|
+
if (!tabList) {
|
|
21763
|
+
return;
|
|
21764
|
+
}
|
|
21765
|
+
tabList.scrollBy({
|
|
21766
|
+
left: direction * Math.max(tabList.clientWidth * 0.75, 180),
|
|
21767
|
+
behavior: 'smooth',
|
|
21768
|
+
});
|
|
21769
|
+
}
|
|
21770
|
+
updateScrollControls() {
|
|
21771
|
+
const tabList = this.tabListRef()?.nativeElement;
|
|
21772
|
+
if (!tabList) {
|
|
21773
|
+
return;
|
|
21774
|
+
}
|
|
21775
|
+
const maxScrollLeft = Math.max(tabList.scrollWidth - tabList.clientWidth, 0);
|
|
21776
|
+
this.showScrollLeft.set(tabList.scrollLeft > 1);
|
|
21777
|
+
this.showScrollRight.set(tabList.scrollLeft < maxScrollLeft - 1);
|
|
21778
|
+
}
|
|
21779
|
+
panelTemplate(tabId) {
|
|
21780
|
+
return this.panelTemplates().find((panel) => panel.id() === tabId)?.templateRef ?? null;
|
|
21781
|
+
}
|
|
21782
|
+
tabButtonId(tabId) {
|
|
21783
|
+
return `jv-tab-${this.instanceId}-${tabId}`;
|
|
21784
|
+
}
|
|
21785
|
+
panelId(tabId) {
|
|
21786
|
+
return `jv-tab-panel-${this.instanceId}-${tabId}`;
|
|
21787
|
+
}
|
|
21788
|
+
activateAndFocus(tabId) {
|
|
21789
|
+
if (this.resolvedActiveTabId() !== tabId) {
|
|
21790
|
+
this.activeTabChange.emit(tabId);
|
|
21791
|
+
}
|
|
21792
|
+
queueMicrotask(() => this.focusTabButton(tabId));
|
|
21793
|
+
}
|
|
21794
|
+
ensureActiveTabVisible() {
|
|
21795
|
+
const activeTabId = this.resolvedActiveTabId();
|
|
21796
|
+
if (!activeTabId) {
|
|
21797
|
+
return;
|
|
21798
|
+
}
|
|
21799
|
+
const button = this.getTabButton(activeTabId);
|
|
21800
|
+
if (button && typeof button.scrollIntoView === 'function') {
|
|
21801
|
+
button.scrollIntoView({ inline: 'nearest', block: 'nearest' });
|
|
21802
|
+
}
|
|
21803
|
+
}
|
|
21804
|
+
focusTabButton(tabId) {
|
|
21805
|
+
this.getTabButton(tabId)?.focus();
|
|
21806
|
+
}
|
|
21807
|
+
getTabButton(tabId) {
|
|
21808
|
+
const tabList = this.tabListRef()?.nativeElement;
|
|
21809
|
+
if (!tabList) {
|
|
21810
|
+
return null;
|
|
21811
|
+
}
|
|
21812
|
+
return (Array.from(tabList.querySelectorAll('[data-jv-tab-id]')).find((button) => button.dataset['jvTabId'] === tabId) ?? null);
|
|
21813
|
+
}
|
|
21814
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvTabsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
21815
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvTabsComponent, isStandalone: true, selector: "jv-tabs", inputs: { tabs: { classPropertyName: "tabs", publicName: "tabs", isSignal: true, isRequired: false, transformFunction: null }, activeTabId: { classPropertyName: "activeTabId", publicName: "activeTabId", isSignal: true, isRequired: false, transformFunction: null }, keepMounted: { classPropertyName: "keepMounted", publicName: "keepMounted", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { activeTabChange: "activeTabChange" }, host: { listeners: { "window:resize": "handleWindowResize()" } }, queries: [{ propertyName: "panelTemplates", predicate: JvTabPanelDirective, isSignal: true }], viewQueries: [{ propertyName: "tabListRef", first: true, predicate: ["tabList"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
21816
|
+
<div class="jv-tabs">
|
|
21817
|
+
<div class="jv-tabs-header">
|
|
21818
|
+
<div class="jv-tabs-scroll" #tabList role="tablist" aria-orientation="horizontal" (scroll)="updateScrollControls()">
|
|
21819
|
+
@for (tab of tabs(); track tab.id) {
|
|
21820
|
+
<button
|
|
21821
|
+
type="button"
|
|
21822
|
+
class="jv-tab"
|
|
21823
|
+
[class.jv-tab--active]="isActive(tab.id)"
|
|
21824
|
+
[class.jv-tab--disabled]="tab.disabled ?? false"
|
|
21825
|
+
[id]="tabButtonId(tab.id)"
|
|
21826
|
+
[attr.data-jv-tab-id]="tab.id"
|
|
21827
|
+
role="tab"
|
|
21828
|
+
[attr.aria-selected]="isActive(tab.id) ? 'true' : 'false'"
|
|
21829
|
+
[attr.aria-controls]="panelId(tab.id)"
|
|
21830
|
+
[attr.tabindex]="getTabIndex(tab.id, tab.disabled ?? false)"
|
|
21831
|
+
[disabled]="tab.disabled ?? false"
|
|
21832
|
+
(click)="activateTab(tab.id)"
|
|
21833
|
+
(keydown)="handleKeydown($event, tab.id)"
|
|
21834
|
+
>
|
|
21835
|
+
@if (tab.icon) {
|
|
21836
|
+
<jv-icon [name]="tab.icon" [size]="16" />
|
|
21837
|
+
}
|
|
21838
|
+
<span>{{ tab.label }}</span>
|
|
21839
|
+
</button>
|
|
21840
|
+
}
|
|
21841
|
+
</div>
|
|
21842
|
+
|
|
21843
|
+
@if (showScrollLeft() || showScrollRight()) {
|
|
21844
|
+
<div class="jv-tabs-controls" aria-hidden="true">
|
|
21845
|
+
<button type="button" class="jv-tabs-scroll-button" [disabled]="!showScrollLeft()" (click)="scrollTabs(-1)">
|
|
21846
|
+
<jv-icon name="chevron-left" [size]="16" />
|
|
21847
|
+
</button>
|
|
21848
|
+
<button type="button" class="jv-tabs-scroll-button" [disabled]="!showScrollRight()" (click)="scrollTabs(1)">
|
|
21849
|
+
<jv-icon name="chevron-right" [size]="16" />
|
|
21850
|
+
</button>
|
|
21851
|
+
</div>
|
|
21852
|
+
}
|
|
21853
|
+
</div>
|
|
21854
|
+
|
|
21855
|
+
<div class="jv-tabs-panels">
|
|
21856
|
+
@if (keepMounted()) {
|
|
21857
|
+
@for (tab of tabs(); track tab.id) {
|
|
21858
|
+
<div
|
|
21859
|
+
class="jv-tab-panel"
|
|
21860
|
+
[class.jv-tab-panel--hidden]="!isActive(tab.id)"
|
|
21861
|
+
[id]="panelId(tab.id)"
|
|
21862
|
+
role="tabpanel"
|
|
21863
|
+
[attr.aria-labelledby]="tabButtonId(tab.id)"
|
|
21864
|
+
[attr.tabindex]="isActive(tab.id) ? 0 : null"
|
|
21865
|
+
[hidden]="!isActive(tab.id)"
|
|
21866
|
+
>
|
|
21867
|
+
<ng-container [ngTemplateOutlet]="panelTemplate(tab.id) ?? null" />
|
|
21868
|
+
</div>
|
|
21869
|
+
}
|
|
21870
|
+
} @else if (resolvedActiveTabId(); as activeId) {
|
|
21871
|
+
<div
|
|
21872
|
+
class="jv-tab-panel"
|
|
21873
|
+
[id]="panelId(activeId)"
|
|
21874
|
+
role="tabpanel"
|
|
21875
|
+
[attr.aria-labelledby]="tabButtonId(activeId)"
|
|
21876
|
+
tabindex="0"
|
|
21877
|
+
>
|
|
21878
|
+
<ng-container [ngTemplateOutlet]="panelTemplate(activeId) ?? null" />
|
|
21879
|
+
</div>
|
|
21880
|
+
}
|
|
21881
|
+
</div>
|
|
21882
|
+
</div>
|
|
21883
|
+
`, isInline: true, styles: [".jv-tabs{display:grid;gap:var(--jv-spacing-md)}.jv-tabs-header{display:flex;align-items:center;gap:var(--jv-spacing-sm);min-width:0}.jv-tabs-scroll{flex:1;min-width:0;display:flex;align-items:stretch;gap:var(--jv-spacing-xs);overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none;border-bottom:1px solid var(--jv-color-border);scroll-behavior:smooth}.jv-tabs-scroll::-webkit-scrollbar{display:none}.jv-tab{position:relative;display:inline-flex;align-items:center;gap:var(--jv-spacing-xs);flex:0 0 auto;min-height:var(--jv-density-control-height);padding:0 var(--jv-spacing-md);border:0;border-bottom:2px solid transparent;background:transparent;color:var(--jv-color-foreground-muted);font:inherit;font-weight:600;white-space:nowrap;cursor:pointer;transition:color .16s ease,border-color .16s ease,background-color .16s ease}.jv-tab:hover:not(:disabled){color:var(--jv-color-foreground);background:color-mix(in srgb,var(--jv-color-primary) 6%,transparent)}.jv-tab:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:-2px;border-radius:var(--jv-radius-sm) var(--jv-radius-sm) 0 0}.jv-tab--active{color:var(--jv-color-primary);border-bottom-color:var(--jv-color-primary)}.jv-tab--disabled{opacity:.5;cursor:not-allowed}.jv-tabs-controls{display:inline-flex;align-items:center;gap:var(--jv-spacing-xs)}.jv-tabs-scroll-button{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md);background:var(--jv-color-surface);color:var(--jv-color-foreground);cursor:pointer}.jv-tabs-scroll-button:disabled{opacity:.4;cursor:default}.jv-tab-panel{outline:none}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: JvIconComponent, selector: "jv-icon", inputs: ["name", "size", "strokeWidth", "decorative", "ariaLabel"] }] });
|
|
21884
|
+
}
|
|
21885
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvTabsComponent, decorators: [{
|
|
21886
|
+
type: Component,
|
|
21887
|
+
args: [{ selector: 'jv-tabs', standalone: true, imports: [NgTemplateOutlet, JvIconComponent], template: `
|
|
21888
|
+
<div class="jv-tabs">
|
|
21889
|
+
<div class="jv-tabs-header">
|
|
21890
|
+
<div class="jv-tabs-scroll" #tabList role="tablist" aria-orientation="horizontal" (scroll)="updateScrollControls()">
|
|
21891
|
+
@for (tab of tabs(); track tab.id) {
|
|
21892
|
+
<button
|
|
21893
|
+
type="button"
|
|
21894
|
+
class="jv-tab"
|
|
21895
|
+
[class.jv-tab--active]="isActive(tab.id)"
|
|
21896
|
+
[class.jv-tab--disabled]="tab.disabled ?? false"
|
|
21897
|
+
[id]="tabButtonId(tab.id)"
|
|
21898
|
+
[attr.data-jv-tab-id]="tab.id"
|
|
21899
|
+
role="tab"
|
|
21900
|
+
[attr.aria-selected]="isActive(tab.id) ? 'true' : 'false'"
|
|
21901
|
+
[attr.aria-controls]="panelId(tab.id)"
|
|
21902
|
+
[attr.tabindex]="getTabIndex(tab.id, tab.disabled ?? false)"
|
|
21903
|
+
[disabled]="tab.disabled ?? false"
|
|
21904
|
+
(click)="activateTab(tab.id)"
|
|
21905
|
+
(keydown)="handleKeydown($event, tab.id)"
|
|
21906
|
+
>
|
|
21907
|
+
@if (tab.icon) {
|
|
21908
|
+
<jv-icon [name]="tab.icon" [size]="16" />
|
|
21909
|
+
}
|
|
21910
|
+
<span>{{ tab.label }}</span>
|
|
21911
|
+
</button>
|
|
21912
|
+
}
|
|
21913
|
+
</div>
|
|
21914
|
+
|
|
21915
|
+
@if (showScrollLeft() || showScrollRight()) {
|
|
21916
|
+
<div class="jv-tabs-controls" aria-hidden="true">
|
|
21917
|
+
<button type="button" class="jv-tabs-scroll-button" [disabled]="!showScrollLeft()" (click)="scrollTabs(-1)">
|
|
21918
|
+
<jv-icon name="chevron-left" [size]="16" />
|
|
21919
|
+
</button>
|
|
21920
|
+
<button type="button" class="jv-tabs-scroll-button" [disabled]="!showScrollRight()" (click)="scrollTabs(1)">
|
|
21921
|
+
<jv-icon name="chevron-right" [size]="16" />
|
|
21922
|
+
</button>
|
|
21923
|
+
</div>
|
|
21924
|
+
}
|
|
21925
|
+
</div>
|
|
21926
|
+
|
|
21927
|
+
<div class="jv-tabs-panels">
|
|
21928
|
+
@if (keepMounted()) {
|
|
21929
|
+
@for (tab of tabs(); track tab.id) {
|
|
21930
|
+
<div
|
|
21931
|
+
class="jv-tab-panel"
|
|
21932
|
+
[class.jv-tab-panel--hidden]="!isActive(tab.id)"
|
|
21933
|
+
[id]="panelId(tab.id)"
|
|
21934
|
+
role="tabpanel"
|
|
21935
|
+
[attr.aria-labelledby]="tabButtonId(tab.id)"
|
|
21936
|
+
[attr.tabindex]="isActive(tab.id) ? 0 : null"
|
|
21937
|
+
[hidden]="!isActive(tab.id)"
|
|
21938
|
+
>
|
|
21939
|
+
<ng-container [ngTemplateOutlet]="panelTemplate(tab.id) ?? null" />
|
|
21940
|
+
</div>
|
|
21941
|
+
}
|
|
21942
|
+
} @else if (resolvedActiveTabId(); as activeId) {
|
|
21943
|
+
<div
|
|
21944
|
+
class="jv-tab-panel"
|
|
21945
|
+
[id]="panelId(activeId)"
|
|
21946
|
+
role="tabpanel"
|
|
21947
|
+
[attr.aria-labelledby]="tabButtonId(activeId)"
|
|
21948
|
+
tabindex="0"
|
|
21949
|
+
>
|
|
21950
|
+
<ng-container [ngTemplateOutlet]="panelTemplate(activeId) ?? null" />
|
|
21951
|
+
</div>
|
|
21952
|
+
}
|
|
21953
|
+
</div>
|
|
21954
|
+
</div>
|
|
21955
|
+
`, styles: [".jv-tabs{display:grid;gap:var(--jv-spacing-md)}.jv-tabs-header{display:flex;align-items:center;gap:var(--jv-spacing-sm);min-width:0}.jv-tabs-scroll{flex:1;min-width:0;display:flex;align-items:stretch;gap:var(--jv-spacing-xs);overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none;border-bottom:1px solid var(--jv-color-border);scroll-behavior:smooth}.jv-tabs-scroll::-webkit-scrollbar{display:none}.jv-tab{position:relative;display:inline-flex;align-items:center;gap:var(--jv-spacing-xs);flex:0 0 auto;min-height:var(--jv-density-control-height);padding:0 var(--jv-spacing-md);border:0;border-bottom:2px solid transparent;background:transparent;color:var(--jv-color-foreground-muted);font:inherit;font-weight:600;white-space:nowrap;cursor:pointer;transition:color .16s ease,border-color .16s ease,background-color .16s ease}.jv-tab:hover:not(:disabled){color:var(--jv-color-foreground);background:color-mix(in srgb,var(--jv-color-primary) 6%,transparent)}.jv-tab:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:-2px;border-radius:var(--jv-radius-sm) var(--jv-radius-sm) 0 0}.jv-tab--active{color:var(--jv-color-primary);border-bottom-color:var(--jv-color-primary)}.jv-tab--disabled{opacity:.5;cursor:not-allowed}.jv-tabs-controls{display:inline-flex;align-items:center;gap:var(--jv-spacing-xs)}.jv-tabs-scroll-button{display:inline-flex;align-items:center;justify-content:center;width:2rem;height:2rem;border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-md);background:var(--jv-color-surface);color:var(--jv-color-foreground);cursor:pointer}.jv-tabs-scroll-button:disabled{opacity:.4;cursor:default}.jv-tab-panel{outline:none}\n"] }]
|
|
21956
|
+
}], ctorParameters: () => [], propDecorators: { panelTemplates: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => JvTabPanelDirective), { isSignal: true }] }], tabListRef: [{ type: i0.ViewChild, args: ['tabList', { isSignal: true }] }], tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: false }] }], activeTabId: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTabId", required: false }] }], keepMounted: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepMounted", required: false }] }], activeTabChange: [{ type: i0.Output, args: ["activeTabChange"] }], handleWindowResize: [{
|
|
21957
|
+
type: HostListener,
|
|
21958
|
+
args: ['window:resize']
|
|
21959
|
+
}] } });
|
|
21960
|
+
|
|
21961
|
+
let tooltipSequence = 0;
|
|
21962
|
+
class JvTooltipDirective {
|
|
21963
|
+
document = inject(DOCUMENT);
|
|
21964
|
+
renderer = inject(Renderer2);
|
|
21965
|
+
hostRef = inject((ElementRef));
|
|
21966
|
+
tooltipElement = null;
|
|
21967
|
+
showTimeout = null;
|
|
21968
|
+
hideTimeout = null;
|
|
21969
|
+
tooltipId = `jv-tooltip-${++tooltipSequence}`;
|
|
21970
|
+
text = input.required({ ...(ngDevMode ? { debugName: "text" } : /* istanbul ignore next */ {}), alias: 'jvTooltip' });
|
|
21971
|
+
position = input('top', { ...(ngDevMode ? { debugName: "position" } : /* istanbul ignore next */ {}), alias: 'jvTooltipPosition' });
|
|
21972
|
+
show() {
|
|
21973
|
+
if (!this.text().trim()) {
|
|
21974
|
+
return;
|
|
21975
|
+
}
|
|
21976
|
+
this.clearHideTimeout();
|
|
21977
|
+
if (this.tooltipElement) {
|
|
21978
|
+
return;
|
|
21979
|
+
}
|
|
21980
|
+
this.showTimeout = setTimeout(() => {
|
|
21981
|
+
this.renderTooltip();
|
|
21982
|
+
this.positionTooltip();
|
|
21983
|
+
this.renderer.setAttribute(this.anchorElement(), 'aria-describedby', this.tooltipId);
|
|
21984
|
+
}, 120);
|
|
21985
|
+
}
|
|
21986
|
+
hide() {
|
|
21987
|
+
this.clearShowTimeout();
|
|
21988
|
+
if (!this.tooltipElement) {
|
|
21989
|
+
return;
|
|
21990
|
+
}
|
|
21991
|
+
this.hideTimeout = setTimeout(() => this.destroyTooltip(), 80);
|
|
21992
|
+
}
|
|
21993
|
+
handleDocumentKeydown(event) {
|
|
21994
|
+
if (event.key === 'Escape') {
|
|
21995
|
+
this.destroyTooltip();
|
|
21996
|
+
}
|
|
21997
|
+
}
|
|
21998
|
+
handleViewportChange() {
|
|
21999
|
+
if (this.tooltipElement) {
|
|
22000
|
+
this.positionTooltip();
|
|
22001
|
+
}
|
|
22002
|
+
}
|
|
22003
|
+
ngOnDestroy() {
|
|
22004
|
+
this.clearShowTimeout();
|
|
22005
|
+
this.clearHideTimeout();
|
|
22006
|
+
this.destroyTooltip();
|
|
22007
|
+
}
|
|
22008
|
+
renderTooltip() {
|
|
22009
|
+
if (this.tooltipElement) {
|
|
22010
|
+
return;
|
|
22011
|
+
}
|
|
22012
|
+
const tooltip = this.renderer.createElement('div');
|
|
22013
|
+
tooltip.textContent = this.text();
|
|
22014
|
+
this.renderer.setAttribute(tooltip, 'id', this.tooltipId);
|
|
22015
|
+
this.renderer.setAttribute(tooltip, 'role', 'tooltip');
|
|
22016
|
+
this.renderer.setStyle(tooltip, 'position', 'fixed');
|
|
22017
|
+
this.renderer.setStyle(tooltip, 'z-index', '1400');
|
|
22018
|
+
this.renderer.setStyle(tooltip, 'max-width', '18rem');
|
|
22019
|
+
this.renderer.setStyle(tooltip, 'padding', '0.5rem 0.75rem');
|
|
22020
|
+
this.renderer.setStyle(tooltip, 'border-radius', '0.5rem');
|
|
22021
|
+
this.renderer.setStyle(tooltip, 'background', 'rgb(15 23 42)');
|
|
22022
|
+
this.renderer.setStyle(tooltip, 'color', '#ffffff');
|
|
22023
|
+
this.renderer.setStyle(tooltip, 'font-size', '0.8125rem');
|
|
22024
|
+
this.renderer.setStyle(tooltip, 'line-height', '1.4');
|
|
22025
|
+
this.renderer.setStyle(tooltip, 'box-shadow', 'var(--jv-shadow-md)');
|
|
22026
|
+
this.renderer.setStyle(tooltip, 'pointer-events', 'none');
|
|
22027
|
+
this.renderer.setStyle(tooltip, 'opacity', '0');
|
|
22028
|
+
this.renderer.setStyle(tooltip, 'transition', 'opacity 120ms ease');
|
|
22029
|
+
this.renderer.appendChild(this.document.body, tooltip);
|
|
22030
|
+
this.tooltipElement = tooltip;
|
|
22031
|
+
requestAnimationFrame(() => {
|
|
22032
|
+
if (this.tooltipElement) {
|
|
22033
|
+
this.renderer.setStyle(this.tooltipElement, 'opacity', '1');
|
|
22034
|
+
}
|
|
22035
|
+
});
|
|
22036
|
+
}
|
|
22037
|
+
positionTooltip() {
|
|
22038
|
+
const tooltip = this.tooltipElement;
|
|
22039
|
+
if (!tooltip) {
|
|
22040
|
+
return;
|
|
22041
|
+
}
|
|
22042
|
+
const hostRect = this.anchorElement().getBoundingClientRect();
|
|
22043
|
+
const tooltipRect = tooltip.getBoundingClientRect();
|
|
22044
|
+
const gap = 8;
|
|
22045
|
+
let top = hostRect.top - tooltipRect.height - gap;
|
|
22046
|
+
let left = hostRect.left + hostRect.width / 2 - tooltipRect.width / 2;
|
|
22047
|
+
switch (this.position()) {
|
|
22048
|
+
case 'right':
|
|
22049
|
+
top = hostRect.top + hostRect.height / 2 - tooltipRect.height / 2;
|
|
22050
|
+
left = hostRect.right + gap;
|
|
22051
|
+
break;
|
|
22052
|
+
case 'bottom':
|
|
22053
|
+
top = hostRect.bottom + gap;
|
|
22054
|
+
left = hostRect.left + hostRect.width / 2 - tooltipRect.width / 2;
|
|
22055
|
+
break;
|
|
22056
|
+
case 'left':
|
|
22057
|
+
top = hostRect.top + hostRect.height / 2 - tooltipRect.height / 2;
|
|
22058
|
+
left = hostRect.left - tooltipRect.width - gap;
|
|
22059
|
+
break;
|
|
22060
|
+
}
|
|
22061
|
+
this.renderer.setStyle(tooltip, 'top', `${Math.round(top)}px`);
|
|
22062
|
+
this.renderer.setStyle(tooltip, 'left', `${Math.round(left)}px`);
|
|
22063
|
+
}
|
|
22064
|
+
destroyTooltip() {
|
|
22065
|
+
this.clearHideTimeout();
|
|
22066
|
+
this.clearShowTimeout();
|
|
22067
|
+
if (!this.tooltipElement) {
|
|
22068
|
+
return;
|
|
22069
|
+
}
|
|
22070
|
+
this.renderer.removeAttribute(this.anchorElement(), 'aria-describedby');
|
|
22071
|
+
this.renderer.removeChild(this.document.body, this.tooltipElement);
|
|
22072
|
+
this.tooltipElement = null;
|
|
22073
|
+
}
|
|
22074
|
+
anchorElement() {
|
|
22075
|
+
const host = this.hostRef.nativeElement;
|
|
22076
|
+
if (isInteractiveElement(host)) {
|
|
22077
|
+
return host;
|
|
22078
|
+
}
|
|
22079
|
+
return host.querySelector('button, a, input, select, textarea, [tabindex]:not([tabindex="-1"])') ?? host;
|
|
22080
|
+
}
|
|
22081
|
+
clearShowTimeout() {
|
|
22082
|
+
if (this.showTimeout) {
|
|
22083
|
+
clearTimeout(this.showTimeout);
|
|
22084
|
+
this.showTimeout = null;
|
|
22085
|
+
}
|
|
22086
|
+
}
|
|
22087
|
+
clearHideTimeout() {
|
|
22088
|
+
if (this.hideTimeout) {
|
|
22089
|
+
clearTimeout(this.hideTimeout);
|
|
22090
|
+
this.hideTimeout = null;
|
|
22091
|
+
}
|
|
22092
|
+
}
|
|
22093
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvTooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
22094
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.17", type: JvTooltipDirective, isStandalone: true, selector: "[jvTooltip]", inputs: { text: { classPropertyName: "text", publicName: "jvTooltip", isSignal: true, isRequired: true, transformFunction: null }, position: { classPropertyName: "position", publicName: "jvTooltipPosition", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "mouseenter": "show()", "focusin": "show()", "mouseleave": "hide()", "blur": "hide()", "document:keydown": "handleDocumentKeydown($event)", "window:scroll": "handleViewportChange()", "window:resize": "handleViewportChange()" } }, ngImport: i0 });
|
|
22095
|
+
}
|
|
22096
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvTooltipDirective, decorators: [{
|
|
22097
|
+
type: Directive,
|
|
22098
|
+
args: [{
|
|
22099
|
+
selector: '[jvTooltip]',
|
|
22100
|
+
standalone: true,
|
|
22101
|
+
}]
|
|
22102
|
+
}], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "jvTooltip", required: true }] }], position: [{ type: i0.Input, args: [{ isSignal: true, alias: "jvTooltipPosition", required: false }] }], show: [{
|
|
22103
|
+
type: HostListener,
|
|
22104
|
+
args: ['mouseenter']
|
|
22105
|
+
}, {
|
|
22106
|
+
type: HostListener,
|
|
22107
|
+
args: ['focusin']
|
|
22108
|
+
}], hide: [{
|
|
22109
|
+
type: HostListener,
|
|
22110
|
+
args: ['mouseleave']
|
|
22111
|
+
}, {
|
|
22112
|
+
type: HostListener,
|
|
22113
|
+
args: ['blur']
|
|
22114
|
+
}], handleDocumentKeydown: [{
|
|
22115
|
+
type: HostListener,
|
|
22116
|
+
args: ['document:keydown', ['$event']]
|
|
22117
|
+
}], handleViewportChange: [{
|
|
22118
|
+
type: HostListener,
|
|
22119
|
+
args: ['window:scroll']
|
|
22120
|
+
}, {
|
|
22121
|
+
type: HostListener,
|
|
22122
|
+
args: ['window:resize']
|
|
22123
|
+
}] } });
|
|
22124
|
+
function isInteractiveElement(element) {
|
|
22125
|
+
return ['BUTTON', 'A', 'INPUT', 'SELECT', 'TEXTAREA'].includes(element.tagName) || element.tabIndex >= 0;
|
|
22126
|
+
}
|
|
22127
|
+
|
|
20484
22128
|
const JV_GRID_DEFAULT_OPTIONS = {
|
|
20485
22129
|
searchable: true,
|
|
20486
22130
|
sortable: true,
|
|
@@ -21880,5 +23524,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
|
|
|
21880
23524
|
* Generated bundle index. Do not edit.
|
|
21881
23525
|
*/
|
|
21882
23526
|
|
|
21883
|
-
export { EN, ES, JV_DEFAULT_LOCALE, JV_FALLBACK_ICON_NAME, JV_GRID_DEFAULT_OPTIONS, JV_LOCALE_DICTIONARIES, JV_LUCIDE_ICON_REGISTRY, JV_UI_CONFIG, JV_UI_CONFIG_DEFAULTS, JV_UI_DEFAULT_CONFIG, JvAlertComponent, JvAnnouncementService, JvBadgeComponent, JvBreadcrumbComponent, JvButtonComponent, JvButtonGroupComponent, JvCardComponent, JvChangePasswordPageComponent, JvCheckboxComponent, JvConfirmDialogComponent, JvDashboardShellComponent, JvDialogComponent, JvDialogService, JvDividerComponent, JvForgotPasswordPageComponent, JvFormContainerComponent, JvGridComponent, JvIconButtonComponent, JvIconComponent, JvInputComponent, JvListComponent, JvListItemComponent, JvLoaderComponent, JvLoaderService, JvLoginPageComponent, JvPageComponent, JvPaginationComponent, JvRadioComponent, JvSectionComponent, JvSelectComponent, JvSidebarComponent, JvSwitchComponent, JvTextareaComponent, JvThemeService, JvToastComponent, JvToastService, JvTopbarComponent, JvTranslationService, provideJvUi };
|
|
23527
|
+
export { EN, ES, JV_DEFAULT_LOCALE, JV_FALLBACK_ICON_NAME, JV_GRID_DEFAULT_OPTIONS, JV_LOCALE_DICTIONARIES, JV_LUCIDE_ICON_REGISTRY, JV_UI_CONFIG, JV_UI_CONFIG_DEFAULTS, JV_UI_DEFAULT_CONFIG, JvAccordionComponent, JvAccordionPanelDirective, JvAlertComponent, JvAnnouncementService, JvBadgeComponent, JvBreadcrumbComponent, JvButtonComponent, JvButtonGroupComponent, JvCardComponent, JvChangePasswordPageComponent, JvCheckboxComponent, JvCodeComponent, JvCollapsiblePanelComponent, JvConfirmDialogComponent, JvDashboardShellComponent, JvDatePickerComponent, JvDialogComponent, JvDialogService, JvDividerComponent, JvForgotPasswordPageComponent, JvFormContainerComponent, JvGridComponent, JvIconButtonComponent, JvIconComponent, JvInputComponent, JvListComponent, JvListItemComponent, JvLoaderComponent, JvLoaderService, JvLoginPageComponent, JvModalSelectorComponent, JvPageComponent, JvPaginationComponent, JvRadioComponent, JvSectionComponent, JvSelectComponent, JvSidebarComponent, JvSwitchComponent, JvTabPanelDirective, JvTabsComponent, JvTextareaComponent, JvThemeService, JvToastComponent, JvToastService, JvTooltipDirective, JvTopbarComponent, JvTranslationService, provideJvUi };
|
|
21884
23528
|
//# sourceMappingURL=devjuliovilla-jv-ui.mjs.map
|