@devjuliovilla/jv-ui 1.17.0 → 1.18.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.
@@ -19043,13 +19043,13 @@ class JvSelectComponent {
19043
19043
  inputId = input(`jv-select-${++selectIdSequence}`, ...(ngDevMode ? [{ debugName: "inputId" }] : /* istanbul ignore next */ []));
19044
19044
  modelValue = input('', ...(ngDevMode ? [{ debugName: "modelValue" }] : /* istanbul ignore next */ []));
19045
19045
  selectionChange = output();
19046
- value = '';
19046
+ value = signal('', ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
19047
19047
  disabled = false;
19048
19048
  onChange = () => undefined;
19049
19049
  onTouched = () => undefined;
19050
- currentValue = computed(() => this.modelValue() || this.value, ...(ngDevMode ? [{ debugName: "currentValue" }] : /* istanbul ignore next */ []));
19050
+ currentValue = computed(() => this.modelValue() || this.value(), ...(ngDevMode ? [{ debugName: "currentValue" }] : /* istanbul ignore next */ []));
19051
19051
  writeValue(value) {
19052
- this.value = value ?? '';
19052
+ this.value.set(value ?? '');
19053
19053
  }
19054
19054
  registerOnChange(fn) {
19055
19055
  this.onChange = fn;
@@ -19062,7 +19062,7 @@ class JvSelectComponent {
19062
19062
  }
19063
19063
  handleChange(event) {
19064
19064
  const nextValue = event.target.value;
19065
- this.value = nextValue;
19065
+ this.value.set(nextValue);
19066
19066
  this.onChange(nextValue);
19067
19067
  this.selectionChange.emit(nextValue);
19068
19068
  }
@@ -19912,15 +19912,15 @@ class JvChangePasswordPageComponent {
19912
19912
 
19913
19913
  <form class="auth-form" [formGroup]="form" (ngSubmit)="submit()">
19914
19914
  <jv-form-container label="Current password" inputId="jv-current-password" error="Current password is required" [required]="true" [invalid]="currentInvalid()">
19915
- <jv-input inputId="jv-current-password" type="password" formControlName="currentPassword" [invalid]="currentInvalid()" />
19915
+ <jv-input inputId="jv-current-password" type="password" formControlName="currentPassword" [invalid]="currentInvalid()" [describedBy]="currentInvalid() ? 'jv-current-password-error' : ''" />
19916
19916
  </jv-form-container>
19917
19917
 
19918
19918
  <jv-form-container label="New password" inputId="jv-new-password" error="New password is required" [required]="true" [invalid]="newInvalid()">
19919
- <jv-input inputId="jv-new-password" type="password" formControlName="newPassword" [invalid]="newInvalid()" />
19919
+ <jv-input inputId="jv-new-password" type="password" formControlName="newPassword" [invalid]="newInvalid()" [describedBy]="newInvalid() ? 'jv-new-password-error' : ''" />
19920
19920
  </jv-form-container>
19921
19921
 
19922
19922
  <jv-form-container label="Confirm new password" inputId="jv-confirm-password" error="Passwords must match" [required]="true" [invalid]="confirmInvalid()">
19923
- <jv-input inputId="jv-confirm-password" type="password" formControlName="confirmPassword" [invalid]="confirmInvalid()" />
19923
+ <jv-input inputId="jv-confirm-password" type="password" formControlName="confirmPassword" [invalid]="confirmInvalid()" [describedBy]="confirmInvalid() ? 'jv-confirm-password-error' : ''" />
19924
19924
  </jv-form-container>
19925
19925
 
19926
19926
  <div class="auth-actions">
@@ -19943,15 +19943,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
19943
19943
 
19944
19944
  <form class="auth-form" [formGroup]="form" (ngSubmit)="submit()">
19945
19945
  <jv-form-container label="Current password" inputId="jv-current-password" error="Current password is required" [required]="true" [invalid]="currentInvalid()">
19946
- <jv-input inputId="jv-current-password" type="password" formControlName="currentPassword" [invalid]="currentInvalid()" />
19946
+ <jv-input inputId="jv-current-password" type="password" formControlName="currentPassword" [invalid]="currentInvalid()" [describedBy]="currentInvalid() ? 'jv-current-password-error' : ''" />
19947
19947
  </jv-form-container>
19948
19948
 
19949
19949
  <jv-form-container label="New password" inputId="jv-new-password" error="New password is required" [required]="true" [invalid]="newInvalid()">
19950
- <jv-input inputId="jv-new-password" type="password" formControlName="newPassword" [invalid]="newInvalid()" />
19950
+ <jv-input inputId="jv-new-password" type="password" formControlName="newPassword" [invalid]="newInvalid()" [describedBy]="newInvalid() ? 'jv-new-password-error' : ''" />
19951
19951
  </jv-form-container>
19952
19952
 
19953
19953
  <jv-form-container label="Confirm new password" inputId="jv-confirm-password" error="Passwords must match" [required]="true" [invalid]="confirmInvalid()">
19954
- <jv-input inputId="jv-confirm-password" type="password" formControlName="confirmPassword" [invalid]="confirmInvalid()" />
19954
+ <jv-input inputId="jv-confirm-password" type="password" formControlName="confirmPassword" [invalid]="confirmInvalid()" [describedBy]="confirmInvalid() ? 'jv-confirm-password-error' : ''" />
19955
19955
  </jv-form-container>
19956
19956
 
19957
19957
  <div class="auth-actions">
@@ -19998,7 +19998,7 @@ class JvForgotPasswordPageComponent {
19998
19998
 
19999
19999
  <form class="auth-form" [formGroup]="form" (ngSubmit)="submit()">
20000
20000
  <jv-form-container label="Email" inputId="jv-forgot-email" error="Enter a valid email" [required]="true" [invalid]="emailInvalid()">
20001
- <jv-input inputId="jv-forgot-email" type="email" formControlName="email" [invalid]="emailInvalid()" placeholder="you@example.com" />
20001
+ <jv-input inputId="jv-forgot-email" type="email" formControlName="email" [invalid]="emailInvalid()" [describedBy]="emailInvalid() ? 'jv-forgot-email-error' : ''" placeholder="you@example.com" />
20002
20002
  </jv-form-container>
20003
20003
 
20004
20004
  <div class="auth-actions">
@@ -20021,7 +20021,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
20021
20021
 
20022
20022
  <form class="auth-form" [formGroup]="form" (ngSubmit)="submit()">
20023
20023
  <jv-form-container label="Email" inputId="jv-forgot-email" error="Enter a valid email" [required]="true" [invalid]="emailInvalid()">
20024
- <jv-input inputId="jv-forgot-email" type="email" formControlName="email" [invalid]="emailInvalid()" placeholder="you@example.com" />
20024
+ <jv-input inputId="jv-forgot-email" type="email" formControlName="email" [invalid]="emailInvalid()" [describedBy]="emailInvalid() ? 'jv-forgot-email-error' : ''" placeholder="you@example.com" />
20025
20025
  </jv-form-container>
20026
20026
 
20027
20027
  <div class="auth-actions">
@@ -20150,11 +20150,11 @@ class JvLoginPageComponent {
20150
20150
 
20151
20151
  <form class="auth-form" [formGroup]="form" (ngSubmit)="submit()">
20152
20152
  <jv-form-container label="Email or username" inputId="jv-login-identifier" error="This field is required" [required]="true" [invalid]="identifierInvalid()">
20153
- <jv-input inputId="jv-login-identifier" formControlName="identifier" [invalid]="identifierInvalid()" placeholder="you@example.com" />
20153
+ <jv-input inputId="jv-login-identifier" formControlName="identifier" [invalid]="identifierInvalid()" [describedBy]="identifierInvalid() ? 'jv-login-identifier-error' : ''" placeholder="you@example.com" />
20154
20154
  </jv-form-container>
20155
20155
 
20156
20156
  <jv-form-container label="Password" inputId="jv-login-password" error="Password is required" [required]="true" [invalid]="passwordInvalid()">
20157
- <jv-input inputId="jv-login-password" type="password" formControlName="password" [invalid]="passwordInvalid()" placeholder="Enter your password" />
20157
+ <jv-input inputId="jv-login-password" type="password" formControlName="password" [invalid]="passwordInvalid()" [describedBy]="passwordInvalid() ? 'jv-login-password-error' : ''" placeholder="Enter your password" />
20158
20158
  </jv-form-container>
20159
20159
 
20160
20160
  <div class="auth-inline-row">
@@ -20179,11 +20179,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
20179
20179
 
20180
20180
  <form class="auth-form" [formGroup]="form" (ngSubmit)="submit()">
20181
20181
  <jv-form-container label="Email or username" inputId="jv-login-identifier" error="This field is required" [required]="true" [invalid]="identifierInvalid()">
20182
- <jv-input inputId="jv-login-identifier" formControlName="identifier" [invalid]="identifierInvalid()" placeholder="you@example.com" />
20182
+ <jv-input inputId="jv-login-identifier" formControlName="identifier" [invalid]="identifierInvalid()" [describedBy]="identifierInvalid() ? 'jv-login-identifier-error' : ''" placeholder="you@example.com" />
20183
20183
  </jv-form-container>
20184
20184
 
20185
20185
  <jv-form-container label="Password" inputId="jv-login-password" error="Password is required" [required]="true" [invalid]="passwordInvalid()">
20186
- <jv-input inputId="jv-login-password" type="password" formControlName="password" [invalid]="passwordInvalid()" placeholder="Enter your password" />
20186
+ <jv-input inputId="jv-login-password" type="password" formControlName="password" [invalid]="passwordInvalid()" [describedBy]="passwordInvalid() ? 'jv-login-password-error' : ''" placeholder="Enter your password" />
20187
20187
  </jv-form-container>
20188
20188
 
20189
20189
  <div class="auth-inline-row">
@@ -20820,6 +20820,7 @@ class JvDialogComponent {
20820
20820
  previouslyFocusedElement = null;
20821
20821
  open = input(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
20822
20822
  title = input('Dialog', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
20823
+ description = input('', ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
20823
20824
  closed = output();
20824
20825
  titleId = `jv-dialog-title-${Math.random().toString(36).slice(2, 8)}`;
20825
20826
  descriptionId = `jv-dialog-description-${Math.random().toString(36).slice(2, 8)}`;
@@ -20889,15 +20890,18 @@ class JvDialogComponent {
20889
20890
  return Array.from(panel.querySelectorAll('button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'));
20890
20891
  }
20891
20892
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
20892
- 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: `
20893
+ 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 }, description: { classPropertyName: "description", publicName: "description", 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: `
20893
20894
  @if (open()) {
20894
20895
  <div class="jv-dialog-backdrop" tabindex="-1" (click)="backdropClose()" (keydown.escape)="backdropClose()">
20895
- <div class="jv-dialog-panel" role="dialog" aria-modal="true" tabindex="-1" [attr.aria-labelledby]="titleId" [attr.aria-describedby]="descriptionId" (click)="$event.stopPropagation()" (keydown)="$event.stopPropagation()" #panel>
20896
+ <div class="jv-dialog-panel" role="dialog" aria-modal="true" tabindex="-1" [attr.aria-labelledby]="titleId" [attr.aria-describedby]="description() ? descriptionId : null" (click)="$event.stopPropagation()" (keydown)="$event.stopPropagation()" #panel>
20896
20897
  <header class="jv-dialog-header">
20897
20898
  <h2 [id]="titleId">{{ title() }}</h2>
20899
+ @if (description()) {
20900
+ <p class="jv-dialog-description" [id]="descriptionId">{{ description() }}</p>
20901
+ }
20898
20902
  </header>
20899
20903
 
20900
- <div class="jv-dialog-body" [id]="descriptionId">
20904
+ <div class="jv-dialog-body">
20901
20905
  <ng-content></ng-content>
20902
20906
  </div>
20903
20907
 
@@ -20914,12 +20918,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
20914
20918
  args: [{ selector: 'jv-dialog', standalone: true, template: `
20915
20919
  @if (open()) {
20916
20920
  <div class="jv-dialog-backdrop" tabindex="-1" (click)="backdropClose()" (keydown.escape)="backdropClose()">
20917
- <div class="jv-dialog-panel" role="dialog" aria-modal="true" tabindex="-1" [attr.aria-labelledby]="titleId" [attr.aria-describedby]="descriptionId" (click)="$event.stopPropagation()" (keydown)="$event.stopPropagation()" #panel>
20921
+ <div class="jv-dialog-panel" role="dialog" aria-modal="true" tabindex="-1" [attr.aria-labelledby]="titleId" [attr.aria-describedby]="description() ? descriptionId : null" (click)="$event.stopPropagation()" (keydown)="$event.stopPropagation()" #panel>
20918
20922
  <header class="jv-dialog-header">
20919
20923
  <h2 [id]="titleId">{{ title() }}</h2>
20924
+ @if (description()) {
20925
+ <p class="jv-dialog-description" [id]="descriptionId">{{ description() }}</p>
20926
+ }
20920
20927
  </header>
20921
20928
 
20922
- <div class="jv-dialog-body" [id]="descriptionId">
20929
+ <div class="jv-dialog-body">
20923
20930
  <ng-content></ng-content>
20924
20931
  </div>
20925
20932
 
@@ -20930,7 +20937,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
20930
20937
  </div>
20931
20938
  }
20932
20939
  `, 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"] }]
20933
- }], 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: [{
20940
+ }], 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 }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], handleDocumentKeydown: [{
20934
20941
  type: HostListener,
20935
20942
  args: ['document:keydown', ['$event']]
20936
20943
  }] } });
@@ -20962,6 +20969,9 @@ class JvDatePickerComponent {
20962
20969
  disabled = false;
20963
20970
  resolvedDialogTitle = computed(() => this.dialogTitle() || this.translation.translate('datePicker.dialogTitle'), ...(ngDevMode ? [{ debugName: "resolvedDialogTitle" }] : /* istanbul ignore next */ []));
20964
20971
  currentValue = computed(() => this.valueInput() !== undefined ? this.valueInput() : this.value(), ...(ngDevMode ? [{ debugName: "currentValue" }] : /* istanbul ignore next */ []));
20972
+ resolvedDescribedBy = computed(() => [this.describedBy(), this.invalid() ? (this.error() ? `${this.inputId()}-error` : '') : (this.hint() ? `${this.inputId()}-hint` : '')]
20973
+ .filter(Boolean)
20974
+ .join(' '), ...(ngDevMode ? [{ debugName: "resolvedDescribedBy" }] : /* istanbul ignore next */ []));
20965
20975
  triggerAriaLabel = computed(() => {
20966
20976
  const name = this.label() || this.resolvedDialogTitle();
20967
20977
  return `${name}. ${this.displayValue()}`;
@@ -21167,7 +21177,7 @@ class JvDatePickerComponent {
21167
21177
  [attr.aria-expanded]="dialogOpen() ? 'true' : 'false'"
21168
21178
  [attr.aria-controls]="dialogId"
21169
21179
  [attr.aria-invalid]="invalid() ? 'true' : null"
21170
- [attr.aria-describedby]="describedBy() || null"
21180
+ [attr.aria-describedby]="resolvedDescribedBy() || null"
21171
21181
  [attr.aria-label]="triggerAriaLabel()"
21172
21182
  [attr.title]="displayValue()"
21173
21183
  (click)="openDialog()"
@@ -21224,7 +21234,7 @@ class JvDatePickerComponent {
21224
21234
  <jv-button variant="outline" (click)="closeDialog()">{{ translation.translate('datePicker.close') }}</jv-button>
21225
21235
  </div>
21226
21236
  </jv-dialog>
21227
- `, 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", "ariaLabel", "inputId", "modelValue"], outputs: ["selectionChange"] }] });
21237
+ `, 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", "description"], 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", "ariaLabel", "inputId", "modelValue"], outputs: ["selectionChange"] }] });
21228
21238
  }
21229
21239
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvDatePickerComponent, decorators: [{
21230
21240
  type: Component,
@@ -21254,7 +21264,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
21254
21264
  [attr.aria-expanded]="dialogOpen() ? 'true' : 'false'"
21255
21265
  [attr.aria-controls]="dialogId"
21256
21266
  [attr.aria-invalid]="invalid() ? 'true' : null"
21257
- [attr.aria-describedby]="describedBy() || null"
21267
+ [attr.aria-describedby]="resolvedDescribedBy() || null"
21258
21268
  [attr.aria-label]="triggerAriaLabel()"
21259
21269
  [attr.title]="displayValue()"
21260
21270
  (click)="openDialog()"
@@ -21356,6 +21366,7 @@ class JvFileInputComponent {
21356
21366
  filesRejected = output();
21357
21367
  dragActive = signal(false, ...(ngDevMode ? [{ debugName: "dragActive" }] : /* istanbul ignore next */ []));
21358
21368
  rejectionMessage = signal('', ...(ngDevMode ? [{ debugName: "rejectionMessage" }] : /* istanbul ignore next */ []));
21369
+ rejectionId = `jv-file-input-rejection-${this.instanceId}`;
21359
21370
  internalFiles = signal([], ...(ngDevMode ? [{ debugName: "internalFiles" }] : /* istanbul ignore next */ []));
21360
21371
  currentFiles = computed(() => {
21361
21372
  const externalFiles = this.filesInput();
@@ -21363,6 +21374,13 @@ class JvFileInputComponent {
21363
21374
  }, ...(ngDevMode ? [{ debugName: "currentFiles" }] : /* istanbul ignore next */ []));
21364
21375
  selectionSummary = computed(() => this.translation.translate('fileInput.selectionSummary', { count: this.currentFiles().length, max: this.maxFiles() }), ...(ngDevMode ? [{ debugName: "selectionSummary" }] : /* istanbul ignore next */ []));
21365
21376
  dropzoneAriaLabel = computed(() => `${this.label() || this.translation.translate('fileInput.dropLabel')}. ${this.selectionSummary()}`, ...(ngDevMode ? [{ debugName: "dropzoneAriaLabel" }] : /* istanbul ignore next */ []));
21377
+ resolvedDescribedBy = computed(() => [
21378
+ this.describedBy(),
21379
+ this.invalid() ? (this.error() ? `${this.inputId()}-error` : '') : (this.hint() ? `${this.inputId()}-hint` : ''),
21380
+ this.rejectionMessage() ? this.rejectionId : '',
21381
+ ]
21382
+ .filter(Boolean)
21383
+ .join(' '), ...(ngDevMode ? [{ debugName: "resolvedDescribedBy" }] : /* istanbul ignore next */ []));
21366
21384
  openFileDialog() {
21367
21385
  if (this.disabled())
21368
21386
  return;
@@ -21494,7 +21512,7 @@ class JvFileInputComponent {
21494
21512
  [attr.accept]="accept() || null"
21495
21513
  [attr.multiple]="multiple() ? '' : null"
21496
21514
  [disabled]="disabled()"
21497
- [attr.aria-describedby]="describedBy() || null"
21515
+ [attr.aria-describedby]="resolvedDescribedBy() || null"
21498
21516
  (change)="onNativeInputChange($any($event.target).files)"
21499
21517
  />
21500
21518
 
@@ -21523,7 +21541,7 @@ class JvFileInputComponent {
21523
21541
  </div>
21524
21542
 
21525
21543
  @if (rejectionMessage()) {
21526
- <p class="jv-file-input-rejection" aria-live="polite">{{ rejectionMessage() }}</p>
21544
+ <p class="jv-file-input-rejection" [id]="rejectionId" aria-live="polite">{{ rejectionMessage() }}</p>
21527
21545
  }
21528
21546
 
21529
21547
  @if (currentFiles().length > 0) {
@@ -21569,7 +21587,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
21569
21587
  [attr.accept]="accept() || null"
21570
21588
  [attr.multiple]="multiple() ? '' : null"
21571
21589
  [disabled]="disabled()"
21572
- [attr.aria-describedby]="describedBy() || null"
21590
+ [attr.aria-describedby]="resolvedDescribedBy() || null"
21573
21591
  (change)="onNativeInputChange($any($event.target).files)"
21574
21592
  />
21575
21593
 
@@ -21598,7 +21616,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
21598
21616
  </div>
21599
21617
 
21600
21618
  @if (rejectionMessage()) {
21601
- <p class="jv-file-input-rejection" aria-live="polite">{{ rejectionMessage() }}</p>
21619
+ <p class="jv-file-input-rejection" [id]="rejectionId" aria-live="polite">{{ rejectionMessage() }}</p>
21602
21620
  }
21603
21621
 
21604
21622
  @if (currentFiles().length > 0) {
@@ -21696,10 +21714,13 @@ class JvModalSelectorComponent {
21696
21714
  listboxId = `jv-modal-selector-listbox-${this.instanceId}`;
21697
21715
  resultsId = `jv-modal-selector-results-${this.instanceId}`;
21698
21716
  searchInputId = `jv-modal-selector-search-${this.instanceId}`;
21699
- value = null;
21717
+ value = signal(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
21700
21718
  disabled = false;
21701
21719
  resolvedDialogTitle = computed(() => this.dialogTitle() || this.label() || this.translation.translate('modalSelector.placeholder'), ...(ngDevMode ? [{ debugName: "resolvedDialogTitle" }] : /* istanbul ignore next */ []));
21702
- currentValue = computed(() => (this.valueInput() !== undefined ? this.valueInput() : this.value), ...(ngDevMode ? [{ debugName: "currentValue" }] : /* istanbul ignore next */ []));
21720
+ currentValue = computed(() => (this.valueInput() !== undefined ? this.valueInput() : this.value()), ...(ngDevMode ? [{ debugName: "currentValue" }] : /* istanbul ignore next */ []));
21721
+ resolvedDescribedBy = computed(() => [this.describedBy(), this.invalid() ? (this.error() ? `${this.inputId()}-error` : '') : (this.hint() ? `${this.inputId()}-hint` : '')]
21722
+ .filter(Boolean)
21723
+ .join(' '), ...(ngDevMode ? [{ debugName: "resolvedDescribedBy" }] : /* istanbul ignore next */ []));
21703
21724
  selectedOption = computed(() => this.options().find((option) => Object.is(option.value, this.currentValue())) ?? null, ...(ngDevMode ? [{ debugName: "selectedOption" }] : /* istanbul ignore next */ []));
21704
21725
  resolvedPlaceholder = computed(() => this.placeholder() || this.translation.translate('modalSelector.placeholder'), ...(ngDevMode ? [{ debugName: "resolvedPlaceholder" }] : /* istanbul ignore next */ []));
21705
21726
  triggerAriaLabel = computed(() => {
@@ -21721,7 +21742,7 @@ class JvModalSelectorComponent {
21721
21742
  onChange = () => undefined;
21722
21743
  onTouched = () => undefined;
21723
21744
  writeValue(value) {
21724
- this.value = value ?? null;
21745
+ this.value.set(value ?? null);
21725
21746
  }
21726
21747
  registerOnChange(fn) {
21727
21748
  this.onChange = fn;
@@ -21803,7 +21824,7 @@ class JvModalSelectorComponent {
21803
21824
  this.onTouched();
21804
21825
  }
21805
21826
  updateValue(value) {
21806
- this.value = value;
21827
+ this.value.set(value);
21807
21828
  this.onChange(value);
21808
21829
  this.selectionChange.emit(value);
21809
21830
  }
@@ -21848,7 +21869,7 @@ class JvModalSelectorComponent {
21848
21869
  [attr.aria-expanded]="dialogOpen() ? 'true' : 'false'"
21849
21870
  [attr.aria-controls]="dialogId"
21850
21871
  [attr.aria-invalid]="invalid() ? 'true' : null"
21851
- [attr.aria-describedby]="describedBy() || null"
21872
+ [attr.aria-describedby]="resolvedDescribedBy() || null"
21852
21873
  [attr.aria-label]="triggerAriaLabel()"
21853
21874
  (click)="openDialog()"
21854
21875
  (blur)="handleBlur()"
@@ -21862,12 +21883,8 @@ class JvModalSelectorComponent {
21862
21883
  </button>
21863
21884
  </jv-form-container>
21864
21885
 
21865
- <jv-dialog [open]="dialogOpen()" [title]="resolvedDialogTitle()" (closed)="closeDialog()">
21886
+ <jv-dialog [open]="dialogOpen()" [title]="resolvedDialogTitle()" [description]="dialogSubtitle()" (closed)="closeDialog()">
21866
21887
  <div [id]="dialogId" class="jv-modal-selector-dialog">
21867
- @if (dialogSubtitle()) {
21868
- <p class="jv-modal-selector-subtitle">{{ dialogSubtitle() }}</p>
21869
- }
21870
-
21871
21888
  @if (showSearch()) {
21872
21889
  <jv-input
21873
21890
  type="search"
@@ -21923,7 +21940,7 @@ class JvModalSelectorComponent {
21923
21940
  <jv-button variant="outline" (click)="closeDialog()">{{ closeLabel() || translation.translate('modalSelector.close') }}</jv-button>
21924
21941
  </div>
21925
21942
  </jv-dialog>
21926
- `, 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: ["listId", "role", "ariaRole", "variant", "ariaLabel"] }] });
21943
+ `, 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", "description"], 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: ["listId", "role", "ariaRole", "variant", "ariaLabel"] }] });
21927
21944
  }
21928
21945
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvModalSelectorComponent, decorators: [{
21929
21946
  type: Component,
@@ -21953,7 +21970,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
21953
21970
  [attr.aria-expanded]="dialogOpen() ? 'true' : 'false'"
21954
21971
  [attr.aria-controls]="dialogId"
21955
21972
  [attr.aria-invalid]="invalid() ? 'true' : null"
21956
- [attr.aria-describedby]="describedBy() || null"
21973
+ [attr.aria-describedby]="resolvedDescribedBy() || null"
21957
21974
  [attr.aria-label]="triggerAriaLabel()"
21958
21975
  (click)="openDialog()"
21959
21976
  (blur)="handleBlur()"
@@ -21967,12 +21984,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
21967
21984
  </button>
21968
21985
  </jv-form-container>
21969
21986
 
21970
- <jv-dialog [open]="dialogOpen()" [title]="resolvedDialogTitle()" (closed)="closeDialog()">
21987
+ <jv-dialog [open]="dialogOpen()" [title]="resolvedDialogTitle()" [description]="dialogSubtitle()" (closed)="closeDialog()">
21971
21988
  <div [id]="dialogId" class="jv-modal-selector-dialog">
21972
- @if (dialogSubtitle()) {
21973
- <p class="jv-modal-selector-subtitle">{{ dialogSubtitle() }}</p>
21974
- }
21975
-
21976
21989
  @if (showSearch()) {
21977
21990
  <jv-input
21978
21991
  type="search"
@@ -22473,7 +22486,7 @@ class JvImageGalleryComponent {
22473
22486
  </div>
22474
22487
  </jv-dialog>
22475
22488
  </div>
22476
- `, isInline: true, styles: [".jv-gallery{display:block;width:100%;max-width:100vw}.jv-gallery-strip{display:flex;gap:5px;width:100%;overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;scrollbar-width:none;-ms-overflow-style:none;scroll-snap-type:x proximity;scroll-behavior:smooth;-webkit-overflow-scrolling:touch}.jv-gallery-strip::-webkit-scrollbar{display:none}.jv-gallery-thumb{flex:0 0 auto;width:calc((100vw - 20px)/4);min-width:120px;height:100%;padding:0;border:2px solid transparent;border-radius:var(--jv-radius-sm);background:transparent;cursor:pointer;overflow:hidden;scroll-snap-align:start;transition:border-color .16s ease,opacity .16s ease}.jv-gallery-thumb:hover{opacity:.85}.jv-gallery-thumb--active{border-color:var(--jv-color-primary)}.jv-gallery-thumb:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:1px}.jv-gallery-thumb-image{display:block;width:100%;height:100%;object-fit:cover;pointer-events:none}.jv-gallery-viewer{position:relative;display:flex;align-items:center;justify-content:center;width:100%;height:70vh;min-height:300px;background:#000;border-radius:var(--jv-radius-md);overflow:hidden}.jv-gallery-viewer:focus{outline:none}.jv-gallery-viewer-image{display:block;max-width:100%;max-height:100%;object-fit:contain;-webkit-user-select:none;user-select:none}@keyframes gallery-slide-left{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}@keyframes gallery-slide-right{0%{transform:translate(-100%);opacity:0}to{transform:translate(0);opacity:1}}.jv-gallery-viewer-image--slide-left{animation:gallery-slide-left .28s ease-out}.jv-gallery-viewer-image--slide-right{animation:gallery-slide-right .28s ease-out}.jv-gallery-viewer-nav{position:absolute;top:50%;transform:translateY(-50%);display:inline-flex;align-items:center;justify-content:center;width:3rem;height:3rem;border:none;border-radius:var(--jv-radius-md);background:#00000080;color:#fff;cursor:pointer;transition:background-color .16s ease;z-index:1}.jv-gallery-viewer-nav:hover{background:#000000bf}.jv-gallery-viewer-nav:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:1px}.jv-gallery-viewer-nav--prev{left:var(--jv-spacing-md)}.jv-gallery-viewer-nav--next{right:var(--jv-spacing-md)}.jv-gallery-viewer-counter{position:absolute;bottom:var(--jv-spacing-md);left:50%;transform:translate(-50%);padding:var(--jv-spacing-xs) var(--jv-spacing-sm);border-radius:var(--jv-radius-sm);background:#0009;color:#fff;font-size:.8125rem;font-variant-numeric:tabular-nums;pointer-events:none}@media(max-width:768px){.jv-gallery-thumb{width:calc(100vw - 20px);min-width:200px}.jv-gallery-viewer-nav{width:2.5rem;height:2.5rem}.jv-gallery-viewer-nav--prev{left:var(--jv-spacing-sm)}.jv-gallery-viewer-nav--next{right:var(--jv-spacing-sm)}}@media(prefers-reduced-motion:reduce){.jv-gallery-strip{scroll-behavior:auto}.jv-gallery-viewer-image--slide-left,.jv-gallery-viewer-image--slide-right{animation:none}}\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: JvIconComponent, selector: "jv-icon", inputs: ["name", "size", "strokeWidth", "decorative", "ariaLabel"] }] });
22489
+ `, isInline: true, styles: [".jv-gallery{display:block;width:100%;max-width:100vw}.jv-gallery-strip{display:flex;gap:5px;width:100%;overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;scrollbar-width:none;-ms-overflow-style:none;scroll-snap-type:x proximity;scroll-behavior:smooth;-webkit-overflow-scrolling:touch}.jv-gallery-strip::-webkit-scrollbar{display:none}.jv-gallery-thumb{flex:0 0 auto;width:calc((100vw - 20px)/4);min-width:120px;height:100%;padding:0;border:2px solid transparent;border-radius:var(--jv-radius-sm);background:transparent;cursor:pointer;overflow:hidden;scroll-snap-align:start;transition:border-color .16s ease,opacity .16s ease}.jv-gallery-thumb:hover{opacity:.85}.jv-gallery-thumb--active{border-color:var(--jv-color-primary)}.jv-gallery-thumb:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:1px}.jv-gallery-thumb-image{display:block;width:100%;height:100%;object-fit:cover;pointer-events:none}.jv-gallery-viewer{position:relative;display:flex;align-items:center;justify-content:center;width:100%;height:70vh;min-height:300px;background:#000;border-radius:var(--jv-radius-md);overflow:hidden}.jv-gallery-viewer:focus{outline:none}.jv-gallery-viewer-image{display:block;max-width:100%;max-height:100%;object-fit:contain;-webkit-user-select:none;user-select:none}@keyframes gallery-slide-left{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}@keyframes gallery-slide-right{0%{transform:translate(-100%);opacity:0}to{transform:translate(0);opacity:1}}.jv-gallery-viewer-image--slide-left{animation:gallery-slide-left .28s ease-out}.jv-gallery-viewer-image--slide-right{animation:gallery-slide-right .28s ease-out}.jv-gallery-viewer-nav{position:absolute;top:50%;transform:translateY(-50%);display:inline-flex;align-items:center;justify-content:center;width:3rem;height:3rem;border:none;border-radius:var(--jv-radius-md);background:#00000080;color:#fff;cursor:pointer;transition:background-color .16s ease;z-index:1}.jv-gallery-viewer-nav:hover{background:#000000bf}.jv-gallery-viewer-nav:focus-visible{outline:2px solid var(--jv-color-primary);outline-offset:1px}.jv-gallery-viewer-nav--prev{left:var(--jv-spacing-md)}.jv-gallery-viewer-nav--next{right:var(--jv-spacing-md)}.jv-gallery-viewer-counter{position:absolute;bottom:var(--jv-spacing-md);left:50%;transform:translate(-50%);padding:var(--jv-spacing-xs) var(--jv-spacing-sm);border-radius:var(--jv-radius-sm);background:#0009;color:#fff;font-size:.8125rem;font-variant-numeric:tabular-nums;pointer-events:none}@media(max-width:768px){.jv-gallery-thumb{width:calc(100vw - 20px);min-width:200px}.jv-gallery-viewer-nav{width:2.5rem;height:2.5rem}.jv-gallery-viewer-nav--prev{left:var(--jv-spacing-sm)}.jv-gallery-viewer-nav--next{right:var(--jv-spacing-sm)}}@media(prefers-reduced-motion:reduce){.jv-gallery-strip{scroll-behavior:auto}.jv-gallery-viewer-image--slide-left,.jv-gallery-viewer-image--slide-right{animation:none}}\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", "description"], outputs: ["closed"] }, { kind: "component", type: JvIconComponent, selector: "jv-icon", inputs: ["name", "size", "strokeWidth", "decorative", "ariaLabel"] }] });
22477
22490
  }
22478
22491
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvImageGalleryComponent, decorators: [{
22479
22492
  type: Component,
@@ -22874,16 +22887,15 @@ class JvConfirmDialogComponent {
22874
22887
  <jv-dialog
22875
22888
  [open]="isOpen()"
22876
22889
  [title]="dialogTitle()"
22890
+ [description]="dialogMessage()"
22877
22891
  (closed)="dialogService.resolve(false)"
22878
22892
  >
22879
- <p>{{ dialogMessage() }}</p>
22880
-
22881
22893
  <div dialog-actions class="actions">
22882
22894
  <jv-button [variant]="confirmVariant()" (click)="dialogService.resolve(true)">{{ confirmLabel() }}</jv-button>
22883
22895
  <jv-button variant="ghost" (click)="dialogService.resolve(false)">{{ cancelLabel() }}</jv-button>
22884
22896
  </div>
22885
22897
  </jv-dialog>
22886
- `, 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"] }] });
22898
+ `, 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", "description"], outputs: ["closed"] }] });
22887
22899
  }
22888
22900
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvConfirmDialogComponent, decorators: [{
22889
22901
  type: Component,
@@ -22891,10 +22903,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
22891
22903
  <jv-dialog
22892
22904
  [open]="isOpen()"
22893
22905
  [title]="dialogTitle()"
22906
+ [description]="dialogMessage()"
22894
22907
  (closed)="dialogService.resolve(false)"
22895
22908
  >
22896
- <p>{{ dialogMessage() }}</p>
22897
-
22898
22909
  <div dialog-actions class="actions">
22899
22910
  <jv-button [variant]="confirmVariant()" (click)="dialogService.resolve(true)">{{ confirmLabel() }}</jv-button>
22900
22911
  <jv-button variant="ghost" (click)="dialogService.resolve(false)">{{ cancelLabel() }}</jv-button>
@@ -22909,6 +22920,7 @@ class JvWindowModalComponent {
22909
22920
  open = input(false, ...(ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []));
22910
22921
  title = input('', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
22911
22922
  subtitle = input('', ...(ngDevMode ? [{ debugName: "subtitle" }] : /* istanbul ignore next */ []));
22923
+ description = input('', ...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
22912
22924
  mode = input('floating', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
22913
22925
  size = input('xl', ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
22914
22926
  showCloseButton = input(true, ...(ngDevMode ? [{ debugName: "showCloseButton" }] : /* istanbul ignore next */ []));
@@ -22918,6 +22930,7 @@ class JvWindowModalComponent {
22918
22930
  closed = output();
22919
22931
  close = output();
22920
22932
  resolvedMode = computed(() => (this.size() === 'fullscreen' ? 'fullscreen' : this.mode()), ...(ngDevMode ? [{ debugName: "resolvedMode" }] : /* istanbul ignore next */ []));
22933
+ resolvedDescription = computed(() => this.description() || this.subtitle(), ...(ngDevMode ? [{ debugName: "resolvedDescription" }] : /* istanbul ignore next */ []));
22921
22934
  titleId = `jv-window-modal-title-${Math.random().toString(36).slice(2, 8)}`;
22922
22935
  descriptionId = `jv-window-modal-description-${Math.random().toString(36).slice(2, 8)}`;
22923
22936
  previousFocusedElement = null;
@@ -23006,7 +23019,7 @@ class JvWindowModalComponent {
23006
23019
  return Array.from(panel.querySelectorAll('button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])'));
23007
23020
  }
23008
23021
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.17", ngImport: i0, type: JvWindowModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
23009
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvWindowModalComponent, isStandalone: true, selector: "jv-window-modal", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, showCloseButton: { classPropertyName: "showCloseButton", publicName: "showCloseButton", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdrop: { classPropertyName: "closeOnBackdrop", publicName: "closeOnBackdrop", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", close: "close" }, host: { listeners: { "document:keydown": "handleDocumentKeydown($event)" } }, viewQueries: [{ propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: `
23022
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.17", type: JvWindowModalComponent, isStandalone: true, selector: "jv-window-modal", inputs: { open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, showCloseButton: { classPropertyName: "showCloseButton", publicName: "showCloseButton", isSignal: true, isRequired: false, transformFunction: null }, closeOnBackdrop: { classPropertyName: "closeOnBackdrop", publicName: "closeOnBackdrop", isSignal: true, isRequired: false, transformFunction: null }, closeOnEscape: { classPropertyName: "closeOnEscape", publicName: "closeOnEscape", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed", close: "close" }, host: { listeners: { "document:keydown": "handleDocumentKeydown($event)" } }, viewQueries: [{ propertyName: "panelRef", first: true, predicate: ["panel"], descendants: true, isSignal: true }], ngImport: i0, template: `
23010
23023
  @if (open()) {
23011
23024
  <div class="jv-window-modal-backdrop" tabindex="-1" (click)="backdropClose()" (keydown.escape)="backdropClose()">
23012
23025
  <section
@@ -23019,7 +23032,7 @@ class JvWindowModalComponent {
23019
23032
  aria-modal="true"
23020
23033
  tabindex="-1"
23021
23034
  [attr.aria-labelledby]="title() ? titleId : null"
23022
- [attr.aria-describedby]="descriptionId"
23035
+ [attr.aria-describedby]="resolvedDescription() ? descriptionId : null"
23023
23036
  (click)="$event.stopPropagation()"
23024
23037
  (keydown)="$event.stopPropagation()"
23025
23038
  #panel
@@ -23030,8 +23043,10 @@ class JvWindowModalComponent {
23030
23043
  <h2 [id]="titleId">{{ title() }}</h2>
23031
23044
  }
23032
23045
 
23033
- @if (subtitle()) {
23034
- <p class="jv-window-modal-subtitle">{{ subtitle() }}</p>
23046
+ @if (description()) {
23047
+ <p class="jv-window-modal-description" [id]="descriptionId">{{ description() }}</p>
23048
+ } @else if (subtitle()) {
23049
+ <p class="jv-window-modal-subtitle" [id]="descriptionId">{{ subtitle() }}</p>
23035
23050
  }
23036
23051
  </div>
23037
23052
 
@@ -23044,7 +23059,7 @@ class JvWindowModalComponent {
23044
23059
  </div>
23045
23060
  </header>
23046
23061
 
23047
- <div class="jv-window-modal-body" [id]="descriptionId">
23062
+ <div class="jv-window-modal-body">
23048
23063
  <ng-content></ng-content>
23049
23064
  </div>
23050
23065
 
@@ -23071,7 +23086,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
23071
23086
  aria-modal="true"
23072
23087
  tabindex="-1"
23073
23088
  [attr.aria-labelledby]="title() ? titleId : null"
23074
- [attr.aria-describedby]="descriptionId"
23089
+ [attr.aria-describedby]="resolvedDescription() ? descriptionId : null"
23075
23090
  (click)="$event.stopPropagation()"
23076
23091
  (keydown)="$event.stopPropagation()"
23077
23092
  #panel
@@ -23082,8 +23097,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
23082
23097
  <h2 [id]="titleId">{{ title() }}</h2>
23083
23098
  }
23084
23099
 
23085
- @if (subtitle()) {
23086
- <p class="jv-window-modal-subtitle">{{ subtitle() }}</p>
23100
+ @if (description()) {
23101
+ <p class="jv-window-modal-description" [id]="descriptionId">{{ description() }}</p>
23102
+ } @else if (subtitle()) {
23103
+ <p class="jv-window-modal-subtitle" [id]="descriptionId">{{ subtitle() }}</p>
23087
23104
  }
23088
23105
  </div>
23089
23106
 
@@ -23096,7 +23113,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
23096
23113
  </div>
23097
23114
  </header>
23098
23115
 
23099
- <div class="jv-window-modal-body" [id]="descriptionId">
23116
+ <div class="jv-window-modal-body">
23100
23117
  <ng-content></ng-content>
23101
23118
  </div>
23102
23119
 
@@ -23107,7 +23124,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.17", ngImpo
23107
23124
  </div>
23108
23125
  }
23109
23126
  `, styles: [".jv-window-modal-backdrop{position:fixed;inset:0;z-index:1250;display:flex;align-items:center;justify-content:center;padding:1rem;background:#0f172a94}.jv-window-modal-panel{width:min(100%,72rem);max-width:100%;max-height:calc(100dvh - 2rem);display:grid;grid-template-rows:auto minmax(0,1fr) auto;overflow:hidden;border:1px solid var(--jv-color-border);border-radius:var(--jv-radius-xl, 1.25rem);background:var(--jv-color-surface);color:var(--jv-color-foreground);box-shadow:var(--jv-shadow-lg)}.jv-window-modal-panel--lg{width:min(100%,56rem)}.jv-window-modal-panel--xl{width:min(100%,72rem)}.jv-window-modal-panel--fullscreen{width:min(100%,calc(100vw - 1rem));height:calc(100dvh - 1rem);max-height:calc(100dvh - 1rem)}.jv-window-modal-header,.jv-window-modal-footer{display:flex;align-items:center;justify-content:space-between;gap:var(--jv-spacing-md);padding:var(--jv-spacing-lg);background:var(--jv-color-surface)}.jv-window-modal-header{border-bottom:1px solid var(--jv-color-border)}.jv-window-modal-footer{border-top:1px solid var(--jv-color-border);justify-content:flex-end}.jv-window-modal-footer:empty{display:none}.jv-window-modal-heading{display:grid;gap:.35rem;min-width:0}.jv-window-modal-heading h2,.jv-window-modal-subtitle{margin:0}.jv-window-modal-subtitle{color:var(--jv-color-foreground-muted)}.jv-window-modal-header-actions{display:inline-flex;align-items:center;gap:var(--jv-spacing-sm);flex-shrink:0}.jv-window-modal-body{min-height:0;overflow:auto;padding:var(--jv-spacing-lg);display:grid;gap:var(--jv-spacing-lg);overscroll-behavior:contain}@media(max-width:720px){.jv-window-modal-backdrop{padding:0}.jv-window-modal-panel,.jv-window-modal-panel--fullscreen{width:100vw;height:100dvh;max-height:100dvh;border-radius:0;border-left:none;border-right:none}.jv-window-modal-header,.jv-window-modal-body,.jv-window-modal-footer{padding:var(--jv-spacing-md)}}\n"] }]
23110
- }], 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 }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], showCloseButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCloseButton", required: false }] }], closeOnBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnBackdrop", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], close: [{ type: i0.Output, args: ["close"] }], handleDocumentKeydown: [{
23127
+ }], 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 }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], showCloseButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCloseButton", required: false }] }], closeOnBackdrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnBackdrop", required: false }] }], closeOnEscape: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeOnEscape", required: false }] }], closeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeLabel", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }], close: [{ type: i0.Output, args: ["close"] }], handleDocumentKeydown: [{
23111
23128
  type: HostListener,
23112
23129
  args: ['document:keydown', ['$event']]
23113
23130
  }] } });