@forgeroute/ui 0.3.0 → 0.3.1

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from "@angular/core";
2
- import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, ElementRef, HostBinding, HostListener, Injectable, InjectionToken, Injector, Input, Renderer2, afterNextRender, computed, effect, forwardRef, inject, input, linkedSignal, model, output, signal, untracked, viewChild } from "@angular/core";
2
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, Directive, ElementRef, HostBinding, HostListener, Injectable, InjectionToken, Injector, Input, Renderer2, afterNextRender, computed, effect, forwardRef, inject, input, linkedSignal, model, output, signal, untracked, viewChild } from "@angular/core";
3
3
  import { HttpClient, HttpErrorResponse, HttpParams } from "@angular/common/http";
4
4
  import { takeUntilDestroyed, toObservable } from "@angular/core/rxjs-interop";
5
5
  import { catchError, debounceTime, distinctUntilChanged, skip, switchMap } from "rxjs/operators";
@@ -1200,7 +1200,7 @@ var ColumnFilterComponent = class ColumnFilterComponent {
1200
1200
  </div>
1201
1201
  `,
1202
1202
  isInline: true,
1203
- styles: [":host{display:inline-block;position:relative}.cf-wrapper{position:relative}.cf-trigger{display:inline-flex;align-items:center;gap:4px;background:none;border:none;cursor:pointer;color:#94a3b8;padding:2px 4px;border-radius:4px;font-family:inherit;font-size:.75rem;transition:color .15s}.cf-trigger:hover{color:#1e293b}.cf-trigger.cf-active{color:#3b82f6}.cf-trigger:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}@media(max-width:640px),(pointer:coarse){.cf-trigger{position:relative}.cf-trigger:after{content:\"\";position:absolute;top:50%;left:50%;width:44px;height:44px;transform:translate(-50%,-50%)}}.cf-active-label{font-size:.75rem;font-weight:500;color:#3b82f6}.cf-trigger--chip{min-height:44px;padding:0 14px;gap:6px;border:1px solid #e2e8f0;border-radius:999px;background:#fff;color:#334155;font-size:.8125rem;font-weight:500}.cf-trigger--chip.cf-active{border-color:#bfdbfe;background:#eff6ff}.cf-trigger--chip:after{display:none}.cf-chip-label{white-space:nowrap}.cf-dropdown{position:fixed;display:flex;flex-direction:column;max-height:calc(100vh - 16px);z-index:9999;background:#fff;border:1px solid #e2e8f0;border-radius:12px;box-shadow:0 4px 6px #0000000a,0 12px 28px #0000001a;min-width:220px;animation:cf-drop .16s cubic-bezier(.16,1,.3,1)}.cf-header{display:flex;align-items:center;justify-content:space-between;padding:12px 12px 10px 16px;border-bottom:1px solid #f1f5f9}.cf-header-label{font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:#64748b}.cf-close{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:6px;background:none;border:none;cursor:pointer;color:#94a3b8;flex-shrink:0;transition:background .13s,color .13s}.cf-close:hover{background:#f1f5f9;color:#1e293b}.cf-options{padding:6px 8px;overflow-y:auto;min-height:0}.cf-option{display:flex;align-items:center;gap:10px;width:100%;padding:10px;background:none;border:none;border-bottom:1px solid #e2e8f0;cursor:pointer;font-size:.875rem;color:#1e293b;font-family:inherit;text-align:left;border-radius:0;transition:background .12s}.cf-option:last-child{border-bottom:none}.cf-option:hover{background:#f8fafc}.cf-option.cf-selected{background:#eff6ff;color:#1d4ed8;font-weight:500}.cf-option:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.cf-checkbox{flex-shrink:0;width:16px;height:16px;border-radius:4px;border:1.5px solid #d1d5db;display:flex;align-items:center;justify-content:center;background:#fff;transition:background .12s,border-color .12s}.cf-checkbox.cf-checkbox--checked{background:#3b82f6;border-color:#3b82f6;color:#fff}.cf-count{margin-left:auto;font-size:.7rem;font-weight:600;line-height:1;background:#f1f5f9;color:#64748b;border-radius:999px;padding:2px 7px;min-width:22px;text-align:center}.cf-option.cf-selected .cf-count{background:#dbeafe;color:#2563eb}.cf-footer{display:flex;gap:8px;padding:10px 12px 12px;border-top:1px solid #f1f5f9}.cf-clear{flex:1;padding:8px;border-radius:8px;border:1px solid #e2e8f0;background:#fff;font-size:.8125rem;color:#64748b;cursor:pointer;font-family:inherit;font-weight:500;transition:background .12s,color .12s}.cf-clear:hover{background:#f8fafc;color:#1e293b}.cf-apply{flex:1;padding:8px;border-radius:8px;border:none;background:#0f172a;color:#fff;font-size:.8125rem;cursor:pointer;font-family:inherit;font-weight:600;transition:background .12s}.cf-apply:hover{background:#1e293b}@keyframes cf-drop{0%{opacity:0;transform:translateY(-4px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}@media(max-width:1024px){.cf-trigger{padding:6px 8px}.cf-option{padding:11px 10px;min-height:40px}.cf-clear,.cf-apply{padding:10px}}@media(max-width:640px){.cf-dropdown{min-width:200px;max-width:calc(100vw - 16px)}.cf-option{padding:12px 10px;min-height:44px}.cf-clear,.cf-apply{padding:11px}}\n"],
1203
+ styles: [":host{display:inline-block;position:relative}.cf-wrapper{position:relative}.cf-trigger{display:inline-flex;align-items:center;gap:4px;background:none;border:none;cursor:pointer;color:#94a3b8;padding:2px 4px;border-radius:4px;font-family:inherit;font-size:.75rem;transition:color .15s}.cf-trigger:hover{color:#1e293b}.cf-trigger.cf-active{color:#3b82f6}.cf-trigger:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}@media(max-width:640px),(pointer:coarse){.cf-trigger{position:relative}.cf-trigger:after{content:\"\";position:absolute;top:50%;left:50%;width:44px;height:44px;transform:translate(-50%,-50%)}}.cf-active-label{font-size:.75rem;font-weight:500;color:#3b82f6}.cf-trigger--chip{min-height:44px;padding:0 14px;gap:6px;border:1px solid #e2e8f0;border-radius:999px;background:#fff;color:#334155;font-size:.8125rem;font-weight:500}.cf-trigger--chip.cf-active{border-color:#bfdbfe;background:#eff6ff}.cf-trigger--chip:after{display:none}.cf-chip-label{white-space:nowrap}.cf-dropdown{position:fixed;display:flex;flex-direction:column;max-height:calc(100vh - 16px);z-index:9999;background:#fff;border:1px solid #e2e8f0;border-radius:12px;box-shadow:0 4px 6px #0000000a,0 12px 28px #0000001a;min-width:220px;animation:cf-drop .16s cubic-bezier(.16,1,.3,1)}.cf-header{display:flex;align-items:center;justify-content:space-between;padding:12px 12px 10px 16px;border-bottom:1px solid #f1f5f9}.cf-header-label{font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:#64748b}.cf-close{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:6px;background:none;border:none;cursor:pointer;color:#94a3b8;flex-shrink:0;transition:background .13s,color .13s}.cf-close:hover{background:#f1f5f9;color:#1e293b}@media(max-width:640px),(pointer:coarse){.cf-close{position:relative}.cf-close:after{content:\"\";position:absolute;inset:-10px}}.cf-options{padding:6px 8px;overflow-y:auto;min-height:0}.cf-option{display:flex;align-items:center;gap:10px;width:100%;padding:10px;background:none;border:none;border-bottom:1px solid #e2e8f0;cursor:pointer;font-size:.875rem;color:#1e293b;font-family:inherit;text-align:left;border-radius:0;transition:background .12s}.cf-option:last-child{border-bottom:none}.cf-option:hover{background:#f8fafc}.cf-option.cf-selected{background:#eff6ff;color:#1d4ed8;font-weight:500}.cf-option:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.cf-checkbox{flex-shrink:0;width:16px;height:16px;border-radius:4px;border:1.5px solid #d1d5db;display:flex;align-items:center;justify-content:center;background:#fff;transition:background .12s,border-color .12s}.cf-checkbox.cf-checkbox--checked{background:#3b82f6;border-color:#3b82f6;color:#fff}.cf-count{margin-left:auto;font-size:.7rem;font-weight:600;line-height:1;background:#f1f5f9;color:#64748b;border-radius:999px;padding:2px 7px;min-width:22px;text-align:center}.cf-option.cf-selected .cf-count{background:#dbeafe;color:#2563eb}.cf-footer{display:flex;gap:8px;padding:10px 12px 12px;border-top:1px solid #f1f5f9}.cf-clear{flex:1;padding:8px;border-radius:8px;border:1px solid #e2e8f0;background:#fff;font-size:.8125rem;color:#64748b;cursor:pointer;font-family:inherit;font-weight:500;transition:background .12s,color .12s}.cf-clear:hover{background:#f8fafc;color:#1e293b}.cf-apply{flex:1;padding:8px;border-radius:8px;border:none;background:#0f172a;color:#fff;font-size:.8125rem;cursor:pointer;font-family:inherit;font-weight:600;transition:background .12s}.cf-apply:hover{background:#1e293b}@keyframes cf-drop{0%{opacity:0;transform:translateY(-4px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}@media(max-width:1024px){.cf-trigger{padding:6px 8px}.cf-option{padding:11px 10px;min-height:40px}.cf-clear,.cf-apply{padding:10px}}@media(max-width:640px){.cf-dropdown{min-width:200px;max-width:calc(100vw - 16px)}.cf-option{padding:12px 10px;min-height:44px}.cf-clear,.cf-apply{padding:11px}}\n"],
1204
1204
  changeDetection: i0.ChangeDetectionStrategy.OnPush
1205
1205
  });
1206
1206
  }
@@ -1290,7 +1290,7 @@ i0.ɵɵngDeclareClassMetadata({
1290
1290
  }
1291
1291
  </div>
1292
1292
  `,
1293
- styles: [":host{display:inline-block;position:relative}.cf-wrapper{position:relative}.cf-trigger{display:inline-flex;align-items:center;gap:4px;background:none;border:none;cursor:pointer;color:#94a3b8;padding:2px 4px;border-radius:4px;font-family:inherit;font-size:.75rem;transition:color .15s}.cf-trigger:hover{color:#1e293b}.cf-trigger.cf-active{color:#3b82f6}.cf-trigger:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}@media(max-width:640px),(pointer:coarse){.cf-trigger{position:relative}.cf-trigger:after{content:\"\";position:absolute;top:50%;left:50%;width:44px;height:44px;transform:translate(-50%,-50%)}}.cf-active-label{font-size:.75rem;font-weight:500;color:#3b82f6}.cf-trigger--chip{min-height:44px;padding:0 14px;gap:6px;border:1px solid #e2e8f0;border-radius:999px;background:#fff;color:#334155;font-size:.8125rem;font-weight:500}.cf-trigger--chip.cf-active{border-color:#bfdbfe;background:#eff6ff}.cf-trigger--chip:after{display:none}.cf-chip-label{white-space:nowrap}.cf-dropdown{position:fixed;display:flex;flex-direction:column;max-height:calc(100vh - 16px);z-index:9999;background:#fff;border:1px solid #e2e8f0;border-radius:12px;box-shadow:0 4px 6px #0000000a,0 12px 28px #0000001a;min-width:220px;animation:cf-drop .16s cubic-bezier(.16,1,.3,1)}.cf-header{display:flex;align-items:center;justify-content:space-between;padding:12px 12px 10px 16px;border-bottom:1px solid #f1f5f9}.cf-header-label{font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:#64748b}.cf-close{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:6px;background:none;border:none;cursor:pointer;color:#94a3b8;flex-shrink:0;transition:background .13s,color .13s}.cf-close:hover{background:#f1f5f9;color:#1e293b}.cf-options{padding:6px 8px;overflow-y:auto;min-height:0}.cf-option{display:flex;align-items:center;gap:10px;width:100%;padding:10px;background:none;border:none;border-bottom:1px solid #e2e8f0;cursor:pointer;font-size:.875rem;color:#1e293b;font-family:inherit;text-align:left;border-radius:0;transition:background .12s}.cf-option:last-child{border-bottom:none}.cf-option:hover{background:#f8fafc}.cf-option.cf-selected{background:#eff6ff;color:#1d4ed8;font-weight:500}.cf-option:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.cf-checkbox{flex-shrink:0;width:16px;height:16px;border-radius:4px;border:1.5px solid #d1d5db;display:flex;align-items:center;justify-content:center;background:#fff;transition:background .12s,border-color .12s}.cf-checkbox.cf-checkbox--checked{background:#3b82f6;border-color:#3b82f6;color:#fff}.cf-count{margin-left:auto;font-size:.7rem;font-weight:600;line-height:1;background:#f1f5f9;color:#64748b;border-radius:999px;padding:2px 7px;min-width:22px;text-align:center}.cf-option.cf-selected .cf-count{background:#dbeafe;color:#2563eb}.cf-footer{display:flex;gap:8px;padding:10px 12px 12px;border-top:1px solid #f1f5f9}.cf-clear{flex:1;padding:8px;border-radius:8px;border:1px solid #e2e8f0;background:#fff;font-size:.8125rem;color:#64748b;cursor:pointer;font-family:inherit;font-weight:500;transition:background .12s,color .12s}.cf-clear:hover{background:#f8fafc;color:#1e293b}.cf-apply{flex:1;padding:8px;border-radius:8px;border:none;background:#0f172a;color:#fff;font-size:.8125rem;cursor:pointer;font-family:inherit;font-weight:600;transition:background .12s}.cf-apply:hover{background:#1e293b}@keyframes cf-drop{0%{opacity:0;transform:translateY(-4px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}@media(max-width:1024px){.cf-trigger{padding:6px 8px}.cf-option{padding:11px 10px;min-height:40px}.cf-clear,.cf-apply{padding:10px}}@media(max-width:640px){.cf-dropdown{min-width:200px;max-width:calc(100vw - 16px)}.cf-option{padding:12px 10px;min-height:44px}.cf-clear,.cf-apply{padding:11px}}\n"]
1293
+ styles: [":host{display:inline-block;position:relative}.cf-wrapper{position:relative}.cf-trigger{display:inline-flex;align-items:center;gap:4px;background:none;border:none;cursor:pointer;color:#94a3b8;padding:2px 4px;border-radius:4px;font-family:inherit;font-size:.75rem;transition:color .15s}.cf-trigger:hover{color:#1e293b}.cf-trigger.cf-active{color:#3b82f6}.cf-trigger:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}@media(max-width:640px),(pointer:coarse){.cf-trigger{position:relative}.cf-trigger:after{content:\"\";position:absolute;top:50%;left:50%;width:44px;height:44px;transform:translate(-50%,-50%)}}.cf-active-label{font-size:.75rem;font-weight:500;color:#3b82f6}.cf-trigger--chip{min-height:44px;padding:0 14px;gap:6px;border:1px solid #e2e8f0;border-radius:999px;background:#fff;color:#334155;font-size:.8125rem;font-weight:500}.cf-trigger--chip.cf-active{border-color:#bfdbfe;background:#eff6ff}.cf-trigger--chip:after{display:none}.cf-chip-label{white-space:nowrap}.cf-dropdown{position:fixed;display:flex;flex-direction:column;max-height:calc(100vh - 16px);z-index:9999;background:#fff;border:1px solid #e2e8f0;border-radius:12px;box-shadow:0 4px 6px #0000000a,0 12px 28px #0000001a;min-width:220px;animation:cf-drop .16s cubic-bezier(.16,1,.3,1)}.cf-header{display:flex;align-items:center;justify-content:space-between;padding:12px 12px 10px 16px;border-bottom:1px solid #f1f5f9}.cf-header-label{font-size:.7rem;font-weight:700;text-transform:uppercase;letter-spacing:.07em;color:#64748b}.cf-close{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:6px;background:none;border:none;cursor:pointer;color:#94a3b8;flex-shrink:0;transition:background .13s,color .13s}.cf-close:hover{background:#f1f5f9;color:#1e293b}@media(max-width:640px),(pointer:coarse){.cf-close{position:relative}.cf-close:after{content:\"\";position:absolute;inset:-10px}}.cf-options{padding:6px 8px;overflow-y:auto;min-height:0}.cf-option{display:flex;align-items:center;gap:10px;width:100%;padding:10px;background:none;border:none;border-bottom:1px solid #e2e8f0;cursor:pointer;font-size:.875rem;color:#1e293b;font-family:inherit;text-align:left;border-radius:0;transition:background .12s}.cf-option:last-child{border-bottom:none}.cf-option:hover{background:#f8fafc}.cf-option.cf-selected{background:#eff6ff;color:#1d4ed8;font-weight:500}.cf-option:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}.cf-checkbox{flex-shrink:0;width:16px;height:16px;border-radius:4px;border:1.5px solid #d1d5db;display:flex;align-items:center;justify-content:center;background:#fff;transition:background .12s,border-color .12s}.cf-checkbox.cf-checkbox--checked{background:#3b82f6;border-color:#3b82f6;color:#fff}.cf-count{margin-left:auto;font-size:.7rem;font-weight:600;line-height:1;background:#f1f5f9;color:#64748b;border-radius:999px;padding:2px 7px;min-width:22px;text-align:center}.cf-option.cf-selected .cf-count{background:#dbeafe;color:#2563eb}.cf-footer{display:flex;gap:8px;padding:10px 12px 12px;border-top:1px solid #f1f5f9}.cf-clear{flex:1;padding:8px;border-radius:8px;border:1px solid #e2e8f0;background:#fff;font-size:.8125rem;color:#64748b;cursor:pointer;font-family:inherit;font-weight:500;transition:background .12s,color .12s}.cf-clear:hover{background:#f8fafc;color:#1e293b}.cf-apply{flex:1;padding:8px;border-radius:8px;border:none;background:#0f172a;color:#fff;font-size:.8125rem;cursor:pointer;font-family:inherit;font-weight:600;transition:background .12s}.cf-apply:hover{background:#1e293b}@keyframes cf-drop{0%{opacity:0;transform:translateY(-4px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}@media(max-width:1024px){.cf-trigger{padding:6px 8px}.cf-option{padding:11px 10px;min-height:40px}.cf-clear,.cf-apply{padding:10px}}@media(max-width:640px){.cf-dropdown{min-width:200px;max-width:calc(100vw - 16px)}.cf-option{padding:12px 10px;min-height:44px}.cf-clear,.cf-apply{padding:11px}}\n"]
1294
1294
  }]
1295
1295
  }],
1296
1296
  ctorParameters: () => [],
@@ -2143,7 +2143,7 @@ var ModalComponent = class ModalComponent {
2143
2143
  }
2144
2144
  `,
2145
2145
  isInline: true,
2146
- styles: [".m-backdrop{position:fixed;inset:0;background:#02081773;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);z-index:200;animation:m-fade .18s ease}.m-modal:focus{outline:none}.m-modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:#fff;border-radius:16px;border:1px solid rgba(0,0,0,.07);z-index:201;width:calc(100% - 32px);box-shadow:0 4px 6px #0000000a,0 16px 32px #0000001f,0 48px 96px #0000001a;max-height:calc(100vh - 48px);display:flex;flex-direction:column;animation:m-scale .22s cubic-bezier(.16,1,.3,1)}.m-header{display:flex;align-items:flex-start;justify-content:space-between;padding:20px 24px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0;border-radius:16px 16px 0 0;flex-shrink:0}.m-header-text{display:flex;flex-direction:column;gap:3px;flex:1;min-width:0}.m-title{font-size:1.125rem;font-weight:700;color:#0f172a;margin:0;letter-spacing:-.02em;line-height:1.3}.m-description{font-size:.8125rem;color:#64748b;margin:0;line-height:1.4}.m-close{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:8px;border:none;background:none;cursor:pointer;color:#94a3b8;flex-shrink:0;margin-left:12px;transition:background .13s,color .13s}.m-close:hover{background:#f1f5f9;color:#1e293b}.m-close:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.m-body{padding:20px 24px;overflow-y:auto;flex:1;min-height:0;font-size:.9rem;color:#475569;line-height:1.65}.m-footer{padding:14px 24px 18px;background:#f8fafc;border-top:1px solid #e2e8f0;border-radius:0 0 16px 16px;flex-shrink:0;display:flex;align-items:center;justify-content:space-between;gap:8px}.m-footer:not(:has(*)){display:none}.m-footer-left{display:flex;align-items:center;gap:8px}.m-footer-right{display:flex;align-items:center;gap:8px;margin-left:auto}@media(max-width:480px){.m-modal{top:auto;bottom:var(--ui-kb, 0px);left:0;right:0;transform:none;width:100vw;max-width:none!important;max-height:min(85dvh,var(--ui-vvh, 100dvh));border-radius:20px 20px 0 0;animation:m-up .24s cubic-bezier(.16,1,.3,1)}.m-footer{border-radius:0;flex-direction:column-reverse;align-items:stretch;padding-bottom:max(18px,env(safe-area-inset-bottom))}}@keyframes m-fade{0%{opacity:0}to{opacity:1}}@keyframes m-scale{0%{opacity:0;transform:translate(-50%,-48%) scale(.96)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}@keyframes m-up{0%{transform:translateY(100%)}to{transform:translateY(0)}}\n"],
2146
+ styles: [".m-backdrop{position:fixed;inset:0;background:#02081773;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);z-index:200;animation:m-fade .18s ease}.m-modal:focus{outline:none}.m-modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:#fff;border-radius:16px;border:1px solid rgba(0,0,0,.07);z-index:201;width:calc(100% - 32px);box-shadow:0 4px 6px #0000000a,0 16px 32px #0000001f,0 48px 96px #0000001a;max-height:calc(100vh - 48px);display:flex;flex-direction:column;animation:m-scale .22s cubic-bezier(.16,1,.3,1)}.m-header{display:flex;align-items:flex-start;justify-content:space-between;padding:20px 24px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0;border-radius:16px 16px 0 0;flex-shrink:0}.m-header-text{display:flex;flex-direction:column;gap:3px;flex:1;min-width:0}.m-title{font-size:1.125rem;font-weight:700;color:#0f172a;margin:0;letter-spacing:-.02em;line-height:1.3}.m-description{font-size:.8125rem;color:#64748b;margin:0;line-height:1.4}.m-close{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:8px;border:none;background:none;cursor:pointer;color:#94a3b8;flex-shrink:0;margin-left:12px;transition:background .13s,color .13s}.m-close:hover{background:#f1f5f9;color:#1e293b}.m-close:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.m-body{padding:20px 24px;overflow-y:auto;flex:1;min-height:0;font-size:.9rem;color:#475569;line-height:1.65}.m-footer{padding:14px 24px 18px;background:#f8fafc;border-top:1px solid #e2e8f0;border-radius:0 0 16px 16px;flex-shrink:0;display:flex;align-items:center;justify-content:space-between;gap:8px}.m-footer:not(:has(*)){display:none}.m-footer-left{display:flex;align-items:center;gap:8px}.m-footer-right{display:flex;align-items:center;gap:8px;margin-left:auto}@media(max-width:480px){.m-modal{top:auto;bottom:var(--ui-kb, 0px);left:0;right:0;transform:none;width:100vw;max-width:none!important;max-height:min(85dvh,var(--ui-vvh, 100dvh));border-radius:20px 20px 0 0;animation:m-up .24s cubic-bezier(.16,1,.3,1)}.m-footer{border-radius:0;flex-direction:column-reverse;align-items:stretch;padding-bottom:max(18px,env(safe-area-inset-bottom))}}@media(pointer:coarse),(max-width:480px){.m-close{position:relative}.m-close:after{content:\"\";position:absolute;inset:-7px}}@keyframes m-fade{0%{opacity:0}to{opacity:1}}@keyframes m-scale{0%{opacity:0;transform:translate(-50%,-48%) scale(.96)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}@keyframes m-up{0%{transform:translateY(100%)}to{transform:translateY(0)}}\n"],
2147
2147
  changeDetection: i0.ChangeDetectionStrategy.OnPush
2148
2148
  });
2149
2149
  }
@@ -2187,7 +2187,7 @@ i0.ɵɵngDeclareClassMetadata({
2187
2187
  </div>
2188
2188
  }
2189
2189
  `,
2190
- styles: [".m-backdrop{position:fixed;inset:0;background:#02081773;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);z-index:200;animation:m-fade .18s ease}.m-modal:focus{outline:none}.m-modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:#fff;border-radius:16px;border:1px solid rgba(0,0,0,.07);z-index:201;width:calc(100% - 32px);box-shadow:0 4px 6px #0000000a,0 16px 32px #0000001f,0 48px 96px #0000001a;max-height:calc(100vh - 48px);display:flex;flex-direction:column;animation:m-scale .22s cubic-bezier(.16,1,.3,1)}.m-header{display:flex;align-items:flex-start;justify-content:space-between;padding:20px 24px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0;border-radius:16px 16px 0 0;flex-shrink:0}.m-header-text{display:flex;flex-direction:column;gap:3px;flex:1;min-width:0}.m-title{font-size:1.125rem;font-weight:700;color:#0f172a;margin:0;letter-spacing:-.02em;line-height:1.3}.m-description{font-size:.8125rem;color:#64748b;margin:0;line-height:1.4}.m-close{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:8px;border:none;background:none;cursor:pointer;color:#94a3b8;flex-shrink:0;margin-left:12px;transition:background .13s,color .13s}.m-close:hover{background:#f1f5f9;color:#1e293b}.m-close:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.m-body{padding:20px 24px;overflow-y:auto;flex:1;min-height:0;font-size:.9rem;color:#475569;line-height:1.65}.m-footer{padding:14px 24px 18px;background:#f8fafc;border-top:1px solid #e2e8f0;border-radius:0 0 16px 16px;flex-shrink:0;display:flex;align-items:center;justify-content:space-between;gap:8px}.m-footer:not(:has(*)){display:none}.m-footer-left{display:flex;align-items:center;gap:8px}.m-footer-right{display:flex;align-items:center;gap:8px;margin-left:auto}@media(max-width:480px){.m-modal{top:auto;bottom:var(--ui-kb, 0px);left:0;right:0;transform:none;width:100vw;max-width:none!important;max-height:min(85dvh,var(--ui-vvh, 100dvh));border-radius:20px 20px 0 0;animation:m-up .24s cubic-bezier(.16,1,.3,1)}.m-footer{border-radius:0;flex-direction:column-reverse;align-items:stretch;padding-bottom:max(18px,env(safe-area-inset-bottom))}}@keyframes m-fade{0%{opacity:0}to{opacity:1}}@keyframes m-scale{0%{opacity:0;transform:translate(-50%,-48%) scale(.96)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}@keyframes m-up{0%{transform:translateY(100%)}to{transform:translateY(0)}}\n"]
2190
+ styles: [".m-backdrop{position:fixed;inset:0;background:#02081773;backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px);z-index:200;animation:m-fade .18s ease}.m-modal:focus{outline:none}.m-modal{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);background:#fff;border-radius:16px;border:1px solid rgba(0,0,0,.07);z-index:201;width:calc(100% - 32px);box-shadow:0 4px 6px #0000000a,0 16px 32px #0000001f,0 48px 96px #0000001a;max-height:calc(100vh - 48px);display:flex;flex-direction:column;animation:m-scale .22s cubic-bezier(.16,1,.3,1)}.m-header{display:flex;align-items:flex-start;justify-content:space-between;padding:20px 24px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0;border-radius:16px 16px 0 0;flex-shrink:0}.m-header-text{display:flex;flex-direction:column;gap:3px;flex:1;min-width:0}.m-title{font-size:1.125rem;font-weight:700;color:#0f172a;margin:0;letter-spacing:-.02em;line-height:1.3}.m-description{font-size:.8125rem;color:#64748b;margin:0;line-height:1.4}.m-close{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:8px;border:none;background:none;cursor:pointer;color:#94a3b8;flex-shrink:0;margin-left:12px;transition:background .13s,color .13s}.m-close:hover{background:#f1f5f9;color:#1e293b}.m-close:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.m-body{padding:20px 24px;overflow-y:auto;flex:1;min-height:0;font-size:.9rem;color:#475569;line-height:1.65}.m-footer{padding:14px 24px 18px;background:#f8fafc;border-top:1px solid #e2e8f0;border-radius:0 0 16px 16px;flex-shrink:0;display:flex;align-items:center;justify-content:space-between;gap:8px}.m-footer:not(:has(*)){display:none}.m-footer-left{display:flex;align-items:center;gap:8px}.m-footer-right{display:flex;align-items:center;gap:8px;margin-left:auto}@media(max-width:480px){.m-modal{top:auto;bottom:var(--ui-kb, 0px);left:0;right:0;transform:none;width:100vw;max-width:none!important;max-height:min(85dvh,var(--ui-vvh, 100dvh));border-radius:20px 20px 0 0;animation:m-up .24s cubic-bezier(.16,1,.3,1)}.m-footer{border-radius:0;flex-direction:column-reverse;align-items:stretch;padding-bottom:max(18px,env(safe-area-inset-bottom))}}@media(pointer:coarse),(max-width:480px){.m-close{position:relative}.m-close:after{content:\"\";position:absolute;inset:-7px}}@keyframes m-fade{0%{opacity:0}to{opacity:1}}@keyframes m-scale{0%{opacity:0;transform:translate(-50%,-48%) scale(.96)}to{opacity:1;transform:translate(-50%,-50%) scale(1)}}@keyframes m-up{0%{transform:translateY(100%)}to{transform:translateY(0)}}\n"]
2191
2191
  }]
2192
2192
  }],
2193
2193
  ctorParameters: () => [],
@@ -2238,12 +2238,120 @@ i0.ɵɵngDeclareClassMetadata({
2238
2238
  }]
2239
2239
  }
2240
2240
  });
2241
+ var UiFieldValidity = class {};
2242
+ function issueToErrors(issue) {
2243
+ return issue ? { [issue.key]: issue.value ?? true } : null;
2244
+ }
2245
+ function requiredIssue(label) {
2246
+ return {
2247
+ key: "required",
2248
+ message: `${label.trim() || "This field"} is required.`
2249
+ };
2250
+ }
2251
+ function maxLengthIssue(text, max) {
2252
+ if (max == null || max < 0 || text.length <= max) return null;
2253
+ return {
2254
+ key: "maxlength",
2255
+ message: `Too long (max ${max} characters).`,
2256
+ value: {
2257
+ requiredLength: max,
2258
+ actualLength: text.length
2259
+ }
2260
+ };
2261
+ }
2262
+ function createFieldReveal(showErrors) {
2263
+ const touched = signal(false, ...ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []);
2264
+ let previous = false;
2265
+ effect(() => {
2266
+ const show = showErrors();
2267
+ if (previous && !show) touched.set(false);
2268
+ previous = show;
2269
+ });
2270
+ return {
2271
+ touched,
2272
+ revealed: computed(() => touched() || showErrors())
2273
+ };
2274
+ }
2275
+ const MONTHS = [
2276
+ "Jan",
2277
+ "Feb",
2278
+ "Mar",
2279
+ "Apr",
2280
+ "May",
2281
+ "Jun",
2282
+ "Jul",
2283
+ "Aug",
2284
+ "Sep",
2285
+ "Oct",
2286
+ "Nov",
2287
+ "Dec"
2288
+ ];
2289
+ function parseIso(value, withTime) {
2290
+ if (typeof value !== "string") return null;
2291
+ const m = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::(\d{2})(?:\.\d+)?)?)?$/.exec(value.trim());
2292
+ if (!m) return null;
2293
+ if (m[6] !== void 0 && Number(m[6]) > 59) return null;
2294
+ if (withTime && m[4] === void 0) return null;
2295
+ if (!withTime && m[4] !== void 0) return null;
2296
+ const y = Number(m[1]), mo = Number(m[2]), d = Number(m[3]);
2297
+ const h = m[4] === void 0 ? 0 : Number(m[4]);
2298
+ const mi = m[5] === void 0 ? 0 : Number(m[5]);
2299
+ if (mo < 1 || mo > 12 || d < 1 || d > new Date(Date.UTC(y, mo, 0)).getUTCDate()) return null;
2300
+ if (h > 23 || mi > 59) return null;
2301
+ return {
2302
+ y,
2303
+ mo,
2304
+ d,
2305
+ h,
2306
+ mi
2307
+ };
2308
+ }
2309
+ function formatIsoDate(value) {
2310
+ const p = parseIso(value, false);
2311
+ return p ? `${MONTHS[p.mo - 1]} ${p.d}, ${p.y}` : typeof value === "string" ? value : "";
2312
+ }
2313
+ function formatIsoDateTime(value) {
2314
+ const p = parseIso(value, true);
2315
+ if (!p) return typeof value === "string" ? value : "";
2316
+ const hour = p.h % 12 === 0 ? 12 : p.h % 12;
2317
+ return `${MONTHS[p.mo - 1]} ${p.d}, ${p.y}, ${hour}:${String(p.mi).padStart(2, "0")} ${p.h < 12 ? "AM" : "PM"}`;
2318
+ }
2319
+ function isoKey(p) {
2320
+ return (((p.y * 100 + p.mo) * 100 + p.d) * 100 + p.h) * 100 + p.mi;
2321
+ }
2322
+ function parseTime(value) {
2323
+ if (typeof value !== "string") return null;
2324
+ const m = /^(\d{2}):(\d{2})(?::(\d{2})(?:\.\d+)?)?$/.exec(value.trim());
2325
+ if (!m) return null;
2326
+ if (m[3] !== void 0 && Number(m[3]) > 59) return null;
2327
+ const h = Number(m[1]), mi = Number(m[2]);
2328
+ return h > 23 || mi > 59 ? null : h * 60 + mi;
2329
+ }
2330
+ function formatTime(value) {
2331
+ const t = parseTime(value);
2332
+ if (t == null) return typeof value === "string" ? value : "";
2333
+ const h = Math.floor(t / 60), mi = t % 60;
2334
+ return `${h % 12 === 0 ? 12 : h % 12}:${String(mi).padStart(2, "0")} ${h < 12 ? "AM" : "PM"}`;
2335
+ }
2241
2336
  var CheckboxComponent = class CheckboxComponent {
2242
2337
  constructor() {
2243
2338
  this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
2244
2339
  this.ariaLabel = input("", ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
2245
2340
  this.indeterminate = input(false, ...ngDevMode ? [{ debugName: "indeterminate" }] : /* istanbul ignore next */ []);
2246
2341
  this.checked = model(false, ...ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []);
2342
+ this.required = input(false, ...ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []);
2343
+ this.requiredMessage = input("", ...ngDevMode ? [{ debugName: "requiredMessage" }] : /* istanbul ignore next */ []);
2344
+ this.hint = input("", ...ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []);
2345
+ this.error = input("", ...ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []);
2346
+ this.showErrors = input(false, ...ngDevMode ? [{ debugName: "showErrors" }] : /* istanbul ignore next */ []);
2347
+ this._descId = `cb-${Math.random().toString(36).slice(2, 8)}-desc`;
2348
+ this._reveal = createFieldReveal(this.showErrors);
2349
+ this._issue = computed(() => this._check(this.checked()), ...ngDevMode ? [{ debugName: "_issue" }] : /* istanbul ignore next */ []);
2350
+ this.invalid = computed(() => !!this.error() || !!this._issue(), ...ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []);
2351
+ this.errorMessage = computed(() => this._issue()?.message ?? "", ...ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []);
2352
+ this.invalidChange = output();
2353
+ this._activeError = computed(() => this.error() || (this._reveal.revealed() ? this.errorMessage() : ""), ...ngDevMode ? [{ debugName: "_activeError" }] : /* istanbul ignore next */ []);
2354
+ this._onValidatorChange = () => {};
2247
2355
  this._disabledInput = input(false, {
2248
2356
  ...ngDevMode ? { debugName: "_disabledInput" } : /* istanbul ignore next */ {},
2249
2357
  alias: "disabled"
@@ -2252,6 +2360,26 @@ var CheckboxComponent = class CheckboxComponent {
2252
2360
  this.disabled = computed(() => this._disabledInput() || this._cvaDisabled(), ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
2253
2361
  this.onChange = (_) => {};
2254
2362
  this.onTouched = () => {};
2363
+ effect(() => {
2364
+ this.invalidChange.emit(this.invalid());
2365
+ });
2366
+ }
2367
+ ngOnChanges() {
2368
+ this._onValidatorChange();
2369
+ }
2370
+ validate(control) {
2371
+ return issueToErrors(this._check(!!control.value));
2372
+ }
2373
+ registerOnValidatorChange(fn) {
2374
+ this._onValidatorChange = fn;
2375
+ }
2376
+ _check(checked) {
2377
+ if (this.disabled() || !this.required() || checked) return null;
2378
+ const rm = this.requiredMessage();
2379
+ return rm ? {
2380
+ key: "required",
2381
+ message: rm
2382
+ } : requiredIssue(this.label());
2255
2383
  }
2256
2384
  writeValue(val) {
2257
2385
  this.checked.set(!!val);
@@ -2271,6 +2399,7 @@ var CheckboxComponent = class CheckboxComponent {
2271
2399
  this.checked.set(val);
2272
2400
  this.onChange(val);
2273
2401
  this.onTouched();
2402
+ this._reveal.touched.set(true);
2274
2403
  }
2275
2404
  static {
2276
2405
  this.ɵfac = i0.ɵɵngDeclareFactory({
@@ -2318,6 +2447,41 @@ var CheckboxComponent = class CheckboxComponent {
2318
2447
  isRequired: false,
2319
2448
  transformFunction: null
2320
2449
  },
2450
+ required: {
2451
+ classPropertyName: "required",
2452
+ publicName: "required",
2453
+ isSignal: true,
2454
+ isRequired: false,
2455
+ transformFunction: null
2456
+ },
2457
+ requiredMessage: {
2458
+ classPropertyName: "requiredMessage",
2459
+ publicName: "requiredMessage",
2460
+ isSignal: true,
2461
+ isRequired: false,
2462
+ transformFunction: null
2463
+ },
2464
+ hint: {
2465
+ classPropertyName: "hint",
2466
+ publicName: "hint",
2467
+ isSignal: true,
2468
+ isRequired: false,
2469
+ transformFunction: null
2470
+ },
2471
+ error: {
2472
+ classPropertyName: "error",
2473
+ publicName: "error",
2474
+ isSignal: true,
2475
+ isRequired: false,
2476
+ transformFunction: null
2477
+ },
2478
+ showErrors: {
2479
+ classPropertyName: "showErrors",
2480
+ publicName: "showErrors",
2481
+ isSignal: true,
2482
+ isRequired: false,
2483
+ transformFunction: null
2484
+ },
2321
2485
  _disabledInput: {
2322
2486
  classPropertyName: "_disabledInput",
2323
2487
  publicName: "disabled",
@@ -2326,14 +2490,30 @@ var CheckboxComponent = class CheckboxComponent {
2326
2490
  transformFunction: null
2327
2491
  }
2328
2492
  },
2329
- outputs: { checked: "checkedChange" },
2330
- providers: [{
2331
- provide: NG_VALUE_ACCESSOR,
2332
- useExisting: forwardRef(() => CheckboxComponent),
2333
- multi: true
2334
- }],
2493
+ outputs: {
2494
+ checked: "checkedChange",
2495
+ invalidChange: "invalidChange"
2496
+ },
2497
+ providers: [
2498
+ {
2499
+ provide: NG_VALUE_ACCESSOR,
2500
+ useExisting: forwardRef(() => CheckboxComponent),
2501
+ multi: true
2502
+ },
2503
+ {
2504
+ provide: NG_VALIDATORS,
2505
+ useExisting: forwardRef(() => CheckboxComponent),
2506
+ multi: true
2507
+ },
2508
+ {
2509
+ provide: UiFieldValidity,
2510
+ useExisting: forwardRef(() => CheckboxComponent)
2511
+ }
2512
+ ],
2513
+ usesOnChanges: true,
2335
2514
  ngImport: i0,
2336
2515
  template: `
2516
+ <div class="cb-field" [class.cb-error]="_activeError()">
2337
2517
  <label class="cb-wrap" [class.cb-disabled]="disabled()">
2338
2518
  <span class="cb-box" [class.cb-checked]="checked()" [class.cb-indeterminate]="indeterminate() && !checked()" [class.cb-disabled]="disabled()">
2339
2519
  @if (checked()) {
@@ -2353,6 +2533,9 @@ var CheckboxComponent = class CheckboxComponent {
2353
2533
  [disabled]="disabled()"
2354
2534
  [attr.aria-label]="ariaLabel() || null"
2355
2535
  [attr.aria-checked]="indeterminate() && !checked() ? 'mixed' : null"
2536
+ [attr.aria-required]="required() ? 'true' : null"
2537
+ [attr.aria-invalid]="_activeError() ? 'true' : null"
2538
+ [attr.aria-describedby]="(_activeError() || hint()) ? _descId : null"
2356
2539
  (change)="onToggle($event)"
2357
2540
  />
2358
2541
  @if (label()) {
@@ -2360,9 +2543,15 @@ var CheckboxComponent = class CheckboxComponent {
2360
2543
  }
2361
2544
  <ng-content />
2362
2545
  </label>
2546
+ @if (_activeError()) {
2547
+ <p class="cb-desc cb-desc-error" [id]="_descId" role="alert">{{ _activeError() }}</p>
2548
+ } @else if (hint()) {
2549
+ <p class="cb-desc" [id]="_descId">{{ hint() }}</p>
2550
+ }
2551
+ </div>
2363
2552
  `,
2364
2553
  isInline: true,
2365
- styles: [".cb-wrap{display:inline-flex;align-items:center;gap:9px;cursor:pointer;-webkit-user-select:none;user-select:none}.cb-wrap.cb-disabled{cursor:not-allowed;opacity:.5}.cb-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.cb-wrap:has(.cb-hidden:focus-visible) .cb-box{outline:2px solid #3b82f6;outline-offset:2px}.cb-box{flex-shrink:0;width:20px;height:20px;border:2px solid #cbd5e1;border-radius:5px;background:#fff;display:flex;align-items:center;justify-content:center;transition:background .12s,border-color .12s}.cb-box.cb-checked,.cb-box.cb-indeterminate{background:#3b82f6;border-color:#3b82f6}.cb-wrap:hover .cb-box:not(.cb-checked):not(.cb-disabled){border-color:#3b82f6}@media(max-width:640px),(pointer:coarse){.cb-box{position:relative}.cb-box:after{content:\"\";position:absolute;inset:-12px}}.cb-label{font-size:.875rem;color:#334155;line-height:1.4}\n"],
2554
+ styles: [".cb-field{display:inline-flex;flex-direction:column;gap:4px}.cb-desc{margin:0 0 0 29px;font-size:.75rem;line-height:1.4;color:#64748b}.cb-desc-error{color:#ef4444}.cb-error .cb-box:not(.cb-checked){border-color:#ef4444}.cb-wrap{display:inline-flex;align-items:center;gap:9px;cursor:pointer;-webkit-user-select:none;user-select:none}.cb-wrap.cb-disabled{cursor:not-allowed;opacity:.5}.cb-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.cb-wrap:has(.cb-hidden:focus-visible) .cb-box{outline:2px solid #3b82f6;outline-offset:2px}@media(pointer:coarse),(max-width:480px){.cb-wrap{position:relative}.cb-hidden{width:44px;height:44px;margin:0;clip:auto;overflow:visible;left:-12px;top:50%;transform:translateY(-50%);opacity:0;cursor:pointer;z-index:1}.cb-wrap.cb-disabled .cb-hidden{cursor:not-allowed}}.cb-box{flex-shrink:0;width:20px;height:20px;border:2px solid #cbd5e1;border-radius:5px;background:#fff;display:flex;align-items:center;justify-content:center;transition:background .12s,border-color .12s}.cb-box.cb-checked,.cb-box.cb-indeterminate{background:#3b82f6;border-color:#3b82f6}.cb-wrap:hover .cb-box:not(.cb-checked):not(.cb-disabled){border-color:#3b82f6}@media(max-width:640px),(pointer:coarse){.cb-box{position:relative}.cb-box:after{content:\"\";position:absolute;inset:-12px}}.cb-label{font-size:.875rem;color:#334155;line-height:1.4}\n"],
2366
2555
  changeDetection: i0.ChangeDetectionStrategy.OnPush
2367
2556
  });
2368
2557
  }
@@ -2378,12 +2567,24 @@ i0.ɵɵngDeclareClassMetadata({
2378
2567
  selector: "ui-checkbox",
2379
2568
  standalone: true,
2380
2569
  changeDetection: ChangeDetectionStrategy.OnPush,
2381
- providers: [{
2382
- provide: NG_VALUE_ACCESSOR,
2383
- useExisting: forwardRef(() => CheckboxComponent),
2384
- multi: true
2385
- }],
2570
+ providers: [
2571
+ {
2572
+ provide: NG_VALUE_ACCESSOR,
2573
+ useExisting: forwardRef(() => CheckboxComponent),
2574
+ multi: true
2575
+ },
2576
+ {
2577
+ provide: NG_VALIDATORS,
2578
+ useExisting: forwardRef(() => CheckboxComponent),
2579
+ multi: true
2580
+ },
2581
+ {
2582
+ provide: UiFieldValidity,
2583
+ useExisting: forwardRef(() => CheckboxComponent)
2584
+ }
2585
+ ],
2386
2586
  template: `
2587
+ <div class="cb-field" [class.cb-error]="_activeError()">
2387
2588
  <label class="cb-wrap" [class.cb-disabled]="disabled()">
2388
2589
  <span class="cb-box" [class.cb-checked]="checked()" [class.cb-indeterminate]="indeterminate() && !checked()" [class.cb-disabled]="disabled()">
2389
2590
  @if (checked()) {
@@ -2403,6 +2604,9 @@ i0.ɵɵngDeclareClassMetadata({
2403
2604
  [disabled]="disabled()"
2404
2605
  [attr.aria-label]="ariaLabel() || null"
2405
2606
  [attr.aria-checked]="indeterminate() && !checked() ? 'mixed' : null"
2607
+ [attr.aria-required]="required() ? 'true' : null"
2608
+ [attr.aria-invalid]="_activeError() ? 'true' : null"
2609
+ [attr.aria-describedby]="(_activeError() || hint()) ? _descId : null"
2406
2610
  (change)="onToggle($event)"
2407
2611
  />
2408
2612
  @if (label()) {
@@ -2410,10 +2614,17 @@ i0.ɵɵngDeclareClassMetadata({
2410
2614
  }
2411
2615
  <ng-content />
2412
2616
  </label>
2617
+ @if (_activeError()) {
2618
+ <p class="cb-desc cb-desc-error" [id]="_descId" role="alert">{{ _activeError() }}</p>
2619
+ } @else if (hint()) {
2620
+ <p class="cb-desc" [id]="_descId">{{ hint() }}</p>
2621
+ }
2622
+ </div>
2413
2623
  `,
2414
- styles: [".cb-wrap{display:inline-flex;align-items:center;gap:9px;cursor:pointer;-webkit-user-select:none;user-select:none}.cb-wrap.cb-disabled{cursor:not-allowed;opacity:.5}.cb-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.cb-wrap:has(.cb-hidden:focus-visible) .cb-box{outline:2px solid #3b82f6;outline-offset:2px}.cb-box{flex-shrink:0;width:20px;height:20px;border:2px solid #cbd5e1;border-radius:5px;background:#fff;display:flex;align-items:center;justify-content:center;transition:background .12s,border-color .12s}.cb-box.cb-checked,.cb-box.cb-indeterminate{background:#3b82f6;border-color:#3b82f6}.cb-wrap:hover .cb-box:not(.cb-checked):not(.cb-disabled){border-color:#3b82f6}@media(max-width:640px),(pointer:coarse){.cb-box{position:relative}.cb-box:after{content:\"\";position:absolute;inset:-12px}}.cb-label{font-size:.875rem;color:#334155;line-height:1.4}\n"]
2624
+ styles: [".cb-field{display:inline-flex;flex-direction:column;gap:4px}.cb-desc{margin:0 0 0 29px;font-size:.75rem;line-height:1.4;color:#64748b}.cb-desc-error{color:#ef4444}.cb-error .cb-box:not(.cb-checked){border-color:#ef4444}.cb-wrap{display:inline-flex;align-items:center;gap:9px;cursor:pointer;-webkit-user-select:none;user-select:none}.cb-wrap.cb-disabled{cursor:not-allowed;opacity:.5}.cb-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.cb-wrap:has(.cb-hidden:focus-visible) .cb-box{outline:2px solid #3b82f6;outline-offset:2px}@media(pointer:coarse),(max-width:480px){.cb-wrap{position:relative}.cb-hidden{width:44px;height:44px;margin:0;clip:auto;overflow:visible;left:-12px;top:50%;transform:translateY(-50%);opacity:0;cursor:pointer;z-index:1}.cb-wrap.cb-disabled .cb-hidden{cursor:not-allowed}}.cb-box{flex-shrink:0;width:20px;height:20px;border:2px solid #cbd5e1;border-radius:5px;background:#fff;display:flex;align-items:center;justify-content:center;transition:background .12s,border-color .12s}.cb-box.cb-checked,.cb-box.cb-indeterminate{background:#3b82f6;border-color:#3b82f6}.cb-wrap:hover .cb-box:not(.cb-checked):not(.cb-disabled){border-color:#3b82f6}@media(max-width:640px),(pointer:coarse){.cb-box{position:relative}.cb-box:after{content:\"\";position:absolute;inset:-12px}}.cb-label{font-size:.875rem;color:#334155;line-height:1.4}\n"]
2415
2625
  }]
2416
2626
  }],
2627
+ ctorParameters: () => [],
2417
2628
  propDecorators: {
2418
2629
  label: [{
2419
2630
  type: i0.Input,
@@ -2450,6 +2661,50 @@ i0.ɵɵngDeclareClassMetadata({
2450
2661
  type: i0.Output,
2451
2662
  args: ["checkedChange"]
2452
2663
  }],
2664
+ required: [{
2665
+ type: i0.Input,
2666
+ args: [{
2667
+ isSignal: true,
2668
+ alias: "required",
2669
+ required: false
2670
+ }]
2671
+ }],
2672
+ requiredMessage: [{
2673
+ type: i0.Input,
2674
+ args: [{
2675
+ isSignal: true,
2676
+ alias: "requiredMessage",
2677
+ required: false
2678
+ }]
2679
+ }],
2680
+ hint: [{
2681
+ type: i0.Input,
2682
+ args: [{
2683
+ isSignal: true,
2684
+ alias: "hint",
2685
+ required: false
2686
+ }]
2687
+ }],
2688
+ error: [{
2689
+ type: i0.Input,
2690
+ args: [{
2691
+ isSignal: true,
2692
+ alias: "error",
2693
+ required: false
2694
+ }]
2695
+ }],
2696
+ showErrors: [{
2697
+ type: i0.Input,
2698
+ args: [{
2699
+ isSignal: true,
2700
+ alias: "showErrors",
2701
+ required: false
2702
+ }]
2703
+ }],
2704
+ invalidChange: [{
2705
+ type: i0.Output,
2706
+ args: ["invalidChange"]
2707
+ }],
2453
2708
  _disabledInput: [{
2454
2709
  type: i0.Input,
2455
2710
  args: [{
@@ -2742,85 +2997,6 @@ i0.ɵɵngDeclareClassMetadata({
2742
2997
  }]
2743
2998
  }
2744
2999
  });
2745
- var UiFieldValidity = class {};
2746
- function issueToErrors(issue) {
2747
- return issue ? { [issue.key]: issue.value ?? true } : null;
2748
- }
2749
- function requiredIssue(label) {
2750
- return {
2751
- key: "required",
2752
- message: `${label.trim() || "This field"} is required.`
2753
- };
2754
- }
2755
- function maxLengthIssue(text, max) {
2756
- if (max == null || max < 0 || text.length <= max) return null;
2757
- return {
2758
- key: "maxlength",
2759
- message: `Too long (max ${max} characters).`,
2760
- value: {
2761
- requiredLength: max,
2762
- actualLength: text.length
2763
- }
2764
- };
2765
- }
2766
- function createFieldReveal(showErrors) {
2767
- const touched = signal(false, ...ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []);
2768
- let previous = false;
2769
- effect(() => {
2770
- const show = showErrors();
2771
- if (previous && !show) touched.set(false);
2772
- previous = show;
2773
- });
2774
- return {
2775
- touched,
2776
- revealed: computed(() => touched() || showErrors())
2777
- };
2778
- }
2779
- const MONTHS = [
2780
- "Jan",
2781
- "Feb",
2782
- "Mar",
2783
- "Apr",
2784
- "May",
2785
- "Jun",
2786
- "Jul",
2787
- "Aug",
2788
- "Sep",
2789
- "Oct",
2790
- "Nov",
2791
- "Dec"
2792
- ];
2793
- function parseIso(value, withTime) {
2794
- const m = /^(\d{4})-(\d{2})-(\d{2})(?:[T ](\d{2}):(\d{2})(?::\d{2}(?:\.\d+)?)?)?$/.exec(value.trim());
2795
- if (!m) return null;
2796
- if (withTime && m[4] === void 0) return null;
2797
- if (!withTime && m[4] !== void 0) return null;
2798
- const y = Number(m[1]), mo = Number(m[2]), d = Number(m[3]);
2799
- const h = m[4] === void 0 ? 0 : Number(m[4]);
2800
- const mi = m[5] === void 0 ? 0 : Number(m[5]);
2801
- if (mo < 1 || mo > 12 || d < 1 || d > new Date(Date.UTC(y, mo, 0)).getUTCDate()) return null;
2802
- if (h > 23 || mi > 59) return null;
2803
- return {
2804
- y,
2805
- mo,
2806
- d,
2807
- h,
2808
- mi
2809
- };
2810
- }
2811
- function formatIsoDate(value) {
2812
- const p = parseIso(value, false);
2813
- return p ? `${MONTHS[p.mo - 1]} ${p.d}, ${p.y}` : value;
2814
- }
2815
- function formatIsoDateTime(value) {
2816
- const p = parseIso(value, true);
2817
- if (!p) return value;
2818
- const hour = p.h % 12 === 0 ? 12 : p.h % 12;
2819
- return `${MONTHS[p.mo - 1]} ${p.d}, ${p.y}, ${hour}:${String(p.mi).padStart(2, "0")} ${p.h < 12 ? "AM" : "PM"}`;
2820
- }
2821
- function isoKey(p) {
2822
- return (((p.y * 100 + p.mo) * 100 + p.d) * 100 + p.h) * 100 + p.mi;
2823
- }
2824
3000
  var TextInputComponent = class TextInputComponent {
2825
3001
  static {
2826
3002
  this._EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
@@ -3399,7 +3575,7 @@ var TableToolbarComponent = class TableToolbarComponent {
3399
3575
  this.additionalDropdownButtons = computed(() => this._allowedButtons().filter((b) => !b.variant && !b.hidden && b.type !== "import" && b.type !== "export").sort((a, b) => a.label.localeCompare(b.label, void 0, { sensitivity: "base" })), ...ngDevMode ? [{ debugName: "additionalDropdownButtons" }] : /* istanbul ignore next */ []);
3400
3576
  this.showSavedViewsItem = computed(() => this.showSavedViews() && (!this.readOnly() || this.savedViews().length > 0), ...ngDevMode ? [{ debugName: "showSavedViewsItem" }] : /* istanbul ignore next */ []);
3401
3577
  this.hasMoreItems = computed(() => !!this.exportDropdownButton() || !!this.importButton() || !this.readOnly() || this.showSavedViewsItem() || this.additionalDropdownButtons().length > 0, ...ngDevMode ? [{ debugName: "hasMoreItems" }] : /* istanbul ignore next */ []);
3402
- this.configurableColumns = computed(() => this.columns().filter((c) => c.key !== this.lockedColumn()), ...ngDevMode ? [{ debugName: "configurableColumns" }] : /* istanbul ignore next */ []);
3578
+ this.configurableColumns = computed(() => this.columns().filter((c) => c.key !== this.lockedColumn() && c.cellType !== "actions"), ...ngDevMode ? [{ debugName: "configurableColumns" }] : /* istanbul ignore next */ []);
3403
3579
  this.hiddenCount = computed(() => this.configurableColumns().filter((c) => !this.visibleColumns().includes(c.key)).length, ...ngDevMode ? [{ debugName: "hiddenCount" }] : /* istanbul ignore next */ []);
3404
3580
  this.activeViewName = computed(() => this.savedViews().find((v) => v.id === this.activeViewId())?.name ?? "", ...ngDevMode ? [{ debugName: "activeViewName" }] : /* istanbul ignore next */ []);
3405
3581
  this.sortedViews = computed(() => {
@@ -3416,7 +3592,7 @@ var TableToolbarComponent = class TableToolbarComponent {
3416
3592
  this._pendingCols.update((cols) => cols.includes(key) ? cols.filter((k) => k !== key) : [...cols, key]);
3417
3593
  }
3418
3594
  applyColumns() {
3419
- this.visibleColumnsChange.emit(this._pendingCols());
3595
+ this.visibleColumnsChange.emit(this._pendingCols().filter((k) => !this.columns().some((c) => c.key === k && c.cellType === "actions")));
3420
3596
  this.colModalOpen.set(false);
3421
3597
  }
3422
3598
  closeColModal() {
@@ -3757,9 +3933,14 @@ var TableToolbarComponent = class TableToolbarComponent {
3757
3933
  "ariaLabel",
3758
3934
  "indeterminate",
3759
3935
  "checked",
3936
+ "required",
3937
+ "requiredMessage",
3938
+ "hint",
3939
+ "error",
3940
+ "showErrors",
3760
3941
  "disabled"
3761
3942
  ],
3762
- outputs: ["checkedChange"]
3943
+ outputs: ["checkedChange", "invalidChange"]
3763
3944
  },
3764
3945
  {
3765
3946
  kind: "component",
@@ -4073,6 +4254,35 @@ i0.ɵɵngDeclareClassMetadata({
4073
4254
  }]
4074
4255
  }
4075
4256
  });
4257
+ function needsEscape(value) {
4258
+ return value.includes(",") || value.includes("\\\\") || value.endsWith("\\");
4259
+ }
4260
+ function encodeFilterValue(value) {
4261
+ return needsEscape(value) ? value.replace(/\\/g, "\\\\").replace(/,/g, "\\,") : value;
4262
+ }
4263
+ function encodeFilterValues(values) {
4264
+ return values.map(encodeFilterValue).join(",");
4265
+ }
4266
+ function decodeFilterValues(raw) {
4267
+ const out = [];
4268
+ let current = "";
4269
+ for (let i = 0; i < raw.length; i++) {
4270
+ const ch = raw[i];
4271
+ if (ch === "\\" && (raw[i + 1] === "," || raw[i + 1] === "\\")) {
4272
+ current += raw[i + 1];
4273
+ i++;
4274
+ continue;
4275
+ }
4276
+ if (ch === ",") {
4277
+ out.push(current);
4278
+ current = "";
4279
+ continue;
4280
+ }
4281
+ current += ch;
4282
+ }
4283
+ out.push(current);
4284
+ return out.map((v) => v.trim()).filter(Boolean);
4285
+ }
4076
4286
  function getEligibleOptions(options, selectedItems, field) {
4077
4287
  if (selectedItems.length === 0) return options;
4078
4288
  return options.filter((opt) => !selectedItems.every((item) => String(item[field] ?? "") === opt.value));
@@ -4349,16 +4559,180 @@ i0.ɵɵngDeclareClassMetadata({
4349
4559
  }]
4350
4560
  }
4351
4561
  });
4562
+ let nextTooltipId = 0;
4563
+ var TooltipDirective = class TooltipDirective {
4564
+ constructor() {
4565
+ this.uiTooltip = input("", ...ngDevMode ? [{ debugName: "uiTooltip" }] : /* istanbul ignore next */ []);
4566
+ this.tooltipPosition = input("top", ...ngDevMode ? [{ debugName: "tooltipPosition" }] : /* istanbul ignore next */ []);
4567
+ this.host = inject(ElementRef).nativeElement;
4568
+ this.doc = inject(DOCUMENT);
4569
+ this.bubble = null;
4570
+ this.id = `ui-tooltip-${nextTooltipId++}`;
4571
+ inject(DestroyRef).onDestroy(() => this.hide());
4572
+ }
4573
+ show() {
4574
+ const text = this.uiTooltip();
4575
+ if (!text || this.bubble) return;
4576
+ const el = this.doc.createElement("div");
4577
+ el.id = this.id;
4578
+ el.setAttribute("role", "tooltip");
4579
+ el.textContent = text;
4580
+ Object.assign(el.style, {
4581
+ position: "fixed",
4582
+ zIndex: "10000",
4583
+ maxWidth: "280px",
4584
+ padding: "6px 10px",
4585
+ background: "#0f172a",
4586
+ color: "#fff",
4587
+ fontSize: "0.75rem",
4588
+ lineHeight: "1.4",
4589
+ borderRadius: "6px",
4590
+ boxShadow: "0 4px 12px rgba(15,23,42,.25)",
4591
+ whiteSpace: "pre-line",
4592
+ pointerEvents: "none",
4593
+ visibility: "hidden"
4594
+ });
4595
+ this.doc.body.appendChild(el);
4596
+ this.bubble = el;
4597
+ this.host.setAttribute("aria-describedby", this.id);
4598
+ const r = this.host.getBoundingClientRect();
4599
+ const b = el.getBoundingClientRect();
4600
+ const gap = 6;
4601
+ let top = this.tooltipPosition() === "top" ? r.top - b.height - gap : r.bottom + gap;
4602
+ if (top < 4) top = r.bottom + gap;
4603
+ else if (top + b.height > window.innerHeight - 4) top = r.top - b.height - gap;
4604
+ const left = Math.min(Math.max(4, r.left + r.width / 2 - b.width / 2), window.innerWidth - b.width - 4);
4605
+ el.style.top = `${top}px`;
4606
+ el.style.left = `${left}px`;
4607
+ el.style.visibility = "visible";
4608
+ }
4609
+ hide() {
4610
+ this.bubble?.remove();
4611
+ this.bubble = null;
4612
+ this.host.removeAttribute("aria-describedby");
4613
+ }
4614
+ static {
4615
+ this.ɵfac = i0.ɵɵngDeclareFactory({
4616
+ minVersion: "12.0.0",
4617
+ version: "22.2.2",
4618
+ ngImport: i0,
4619
+ type: TooltipDirective,
4620
+ deps: [],
4621
+ target: i0.ɵɵFactoryTarget.Directive
4622
+ });
4623
+ }
4624
+ static {
4625
+ this.ɵdir = i0.ɵɵngDeclareDirective({
4626
+ minVersion: "17.1.0",
4627
+ version: "22.2.2",
4628
+ type: TooltipDirective,
4629
+ isStandalone: true,
4630
+ selector: "[uiTooltip]",
4631
+ inputs: {
4632
+ uiTooltip: {
4633
+ classPropertyName: "uiTooltip",
4634
+ publicName: "uiTooltip",
4635
+ isSignal: true,
4636
+ isRequired: false,
4637
+ transformFunction: null
4638
+ },
4639
+ tooltipPosition: {
4640
+ classPropertyName: "tooltipPosition",
4641
+ publicName: "tooltipPosition",
4642
+ isSignal: true,
4643
+ isRequired: false,
4644
+ transformFunction: null
4645
+ }
4646
+ },
4647
+ host: { listeners: {
4648
+ "mouseenter": "show()",
4649
+ "mouseleave": "hide()",
4650
+ "focusin": "show()",
4651
+ "focusout": "hide()",
4652
+ "keydown.escape": "hide()",
4653
+ "click": "hide()"
4654
+ } },
4655
+ ngImport: i0
4656
+ });
4657
+ }
4658
+ };
4659
+ i0.ɵɵngDeclareClassMetadata({
4660
+ minVersion: "12.0.0",
4661
+ version: "22.2.2",
4662
+ ngImport: i0,
4663
+ type: TooltipDirective,
4664
+ decorators: [{
4665
+ type: Directive,
4666
+ args: [{
4667
+ selector: "[uiTooltip]",
4668
+ standalone: true,
4669
+ host: {
4670
+ "(mouseenter)": "show()",
4671
+ "(mouseleave)": "hide()",
4672
+ "(focusin)": "show()",
4673
+ "(focusout)": "hide()",
4674
+ "(keydown.escape)": "hide()",
4675
+ "(click)": "hide()"
4676
+ }
4677
+ }]
4678
+ }],
4679
+ ctorParameters: () => [],
4680
+ propDecorators: {
4681
+ uiTooltip: [{
4682
+ type: i0.Input,
4683
+ args: [{
4684
+ isSignal: true,
4685
+ alias: "uiTooltip",
4686
+ required: false
4687
+ }]
4688
+ }],
4689
+ tooltipPosition: [{
4690
+ type: i0.Input,
4691
+ args: [{
4692
+ isSignal: true,
4693
+ alias: "tooltipPosition",
4694
+ required: false
4695
+ }]
4696
+ }]
4697
+ }
4698
+ });
4699
+ const PROGRESS_STEP_THRESHOLDS = [
4700
+ {
4701
+ at: 25,
4702
+ variant: "amber"
4703
+ },
4704
+ {
4705
+ at: 50,
4706
+ variant: "blue"
4707
+ },
4708
+ {
4709
+ at: 75,
4710
+ variant: "lime"
4711
+ },
4712
+ {
4713
+ at: 100,
4714
+ variant: "green"
4715
+ }
4716
+ ];
4352
4717
  var ProgressBarComponent = class ProgressBarComponent {
4353
4718
  constructor() {
4354
4719
  this.value = input(0, ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
4355
4720
  this.max = input(100, ...ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []);
4356
4721
  this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
4357
4722
  this.variant = input("blue", ...ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []);
4723
+ this.thresholds = input(null, ...ngDevMode ? [{ debugName: "thresholds" }] : /* istanbul ignore next */ []);
4724
+ this.autoColor = input(false, ...ngDevMode ? [{ debugName: "autoColor" }] : /* istanbul ignore next */ []);
4358
4725
  this.tooltip = input("", ...ngDevMode ? [{ debugName: "tooltip" }] : /* istanbul ignore next */ []);
4359
4726
  this.ariaLabel = input("", ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
4360
4727
  this.clampedValue = computed(() => Math.min(Math.max(this.value(), 0), this.max()), ...ngDevMode ? [{ debugName: "clampedValue" }] : /* istanbul ignore next */ []);
4361
4728
  this.percent = computed(() => this.max() > 0 ? Math.round(this.clampedValue() / this.max() * 100) : 0, ...ngDevMode ? [{ debugName: "percent" }] : /* istanbul ignore next */ []);
4729
+ this.effectiveVariant = computed(() => {
4730
+ const list = this.thresholds() ?? (this.autoColor() ? PROGRESS_STEP_THRESHOLDS : null);
4731
+ if (!list?.length || this.max() <= 0) return this.variant();
4732
+ const exact = this.clampedValue() / this.max() * 100;
4733
+ const hit = list.filter((t) => t.at <= exact).sort((a, b) => b.at - a.at)[0];
4734
+ return hit ? hit.variant : this.variant();
4735
+ }, ...ngDevMode ? [{ debugName: "effectiveVariant" }] : /* istanbul ignore next */ []);
4362
4736
  }
4363
4737
  static {
4364
4738
  this.ɵfac = i0.ɵɵngDeclareFactory({
@@ -4406,6 +4780,20 @@ var ProgressBarComponent = class ProgressBarComponent {
4406
4780
  isRequired: false,
4407
4781
  transformFunction: null
4408
4782
  },
4783
+ thresholds: {
4784
+ classPropertyName: "thresholds",
4785
+ publicName: "thresholds",
4786
+ isSignal: true,
4787
+ isRequired: false,
4788
+ transformFunction: null
4789
+ },
4790
+ autoColor: {
4791
+ classPropertyName: "autoColor",
4792
+ publicName: "autoColor",
4793
+ isSignal: true,
4794
+ isRequired: false,
4795
+ transformFunction: null
4796
+ },
4409
4797
  tooltip: {
4410
4798
  classPropertyName: "tooltip",
4411
4799
  publicName: "tooltip",
@@ -4429,13 +4817,20 @@ var ProgressBarComponent = class ProgressBarComponent {
4429
4817
  [attr.aria-valuemax]="max()"
4430
4818
  [attr.aria-valuenow]="clampedValue()"
4431
4819
  [attr.aria-label]="ariaLabel() || label() || null"
4432
- [attr.title]="tooltip() || null">
4433
- <div class="pb-track"><div class="pb-fill" [class]="'pb-fill pb-' + variant()" [style.width.%]="percent()"></div></div>
4820
+ [uiTooltip]="tooltip()"
4821
+ [attr.tabindex]="tooltip() ? 0 : null">
4822
+ <div class="pb-track"><div class="pb-fill" [class]="'pb-fill pb-' + effectiveVariant()" [style.width.%]="percent()"></div></div>
4434
4823
  @if (label()) { <span class="pb-label">{{ label() }}</span> }
4435
4824
  </div>
4436
4825
  `,
4437
4826
  isInline: true,
4438
- styles: [":host{display:block}.pb{display:flex;align-items:center;gap:8px;min-width:100px}.pb-track{flex:1;height:6px;background:#e2e8f0;border-radius:3px;overflow:hidden}.pb-fill{height:100%;border-radius:3px;transition:width .3s}.pb-blue{background:#3b82f6}.pb-green{background:#16a34a}.pb-amber{background:#f59e0b}.pb-red{background:#ef4444}.pb-slate{background:#94a3b8}.pb-label{font-size:.75rem;font-weight:500;color:#64748b;white-space:nowrap}\n"],
4827
+ styles: [":host{display:block}.pb{display:flex;align-items:center;gap:8px;min-width:100px}.pb-track{flex:1;height:6px;background:#e2e8f0;border-radius:3px;overflow:hidden}.pb-fill{height:100%;border-radius:3px;transition:width .3s}.pb-blue{background:#3b82f6}.pb-green{background:#16a34a}.pb-amber{background:#f59e0b}.pb-red{background:#ef4444}.pb-slate{background:#94a3b8}.pb-lime{background:#84cc16}.pb-label{font-size:.75rem;font-weight:500;color:#64748b;white-space:nowrap}\n"],
4828
+ dependencies: [{
4829
+ kind: "directive",
4830
+ type: TooltipDirective,
4831
+ selector: "[uiTooltip]",
4832
+ inputs: ["uiTooltip", "tooltipPosition"]
4833
+ }],
4439
4834
  changeDetection: i0.ChangeDetectionStrategy.OnPush
4440
4835
  });
4441
4836
  }
@@ -4450,6 +4845,7 @@ i0.ɵɵngDeclareClassMetadata({
4450
4845
  args: [{
4451
4846
  selector: "ui-progress-bar",
4452
4847
  standalone: true,
4848
+ imports: [TooltipDirective],
4453
4849
  changeDetection: ChangeDetectionStrategy.OnPush,
4454
4850
  template: `
4455
4851
  <div class="pb"
@@ -4458,12 +4854,13 @@ i0.ɵɵngDeclareClassMetadata({
4458
4854
  [attr.aria-valuemax]="max()"
4459
4855
  [attr.aria-valuenow]="clampedValue()"
4460
4856
  [attr.aria-label]="ariaLabel() || label() || null"
4461
- [attr.title]="tooltip() || null">
4462
- <div class="pb-track"><div class="pb-fill" [class]="'pb-fill pb-' + variant()" [style.width.%]="percent()"></div></div>
4857
+ [uiTooltip]="tooltip()"
4858
+ [attr.tabindex]="tooltip() ? 0 : null">
4859
+ <div class="pb-track"><div class="pb-fill" [class]="'pb-fill pb-' + effectiveVariant()" [style.width.%]="percent()"></div></div>
4463
4860
  @if (label()) { <span class="pb-label">{{ label() }}</span> }
4464
4861
  </div>
4465
4862
  `,
4466
- styles: [":host{display:block}.pb{display:flex;align-items:center;gap:8px;min-width:100px}.pb-track{flex:1;height:6px;background:#e2e8f0;border-radius:3px;overflow:hidden}.pb-fill{height:100%;border-radius:3px;transition:width .3s}.pb-blue{background:#3b82f6}.pb-green{background:#16a34a}.pb-amber{background:#f59e0b}.pb-red{background:#ef4444}.pb-slate{background:#94a3b8}.pb-label{font-size:.75rem;font-weight:500;color:#64748b;white-space:nowrap}\n"]
4863
+ styles: [":host{display:block}.pb{display:flex;align-items:center;gap:8px;min-width:100px}.pb-track{flex:1;height:6px;background:#e2e8f0;border-radius:3px;overflow:hidden}.pb-fill{height:100%;border-radius:3px;transition:width .3s}.pb-blue{background:#3b82f6}.pb-green{background:#16a34a}.pb-amber{background:#f59e0b}.pb-red{background:#ef4444}.pb-slate{background:#94a3b8}.pb-lime{background:#84cc16}.pb-label{font-size:.75rem;font-weight:500;color:#64748b;white-space:nowrap}\n"]
4467
4864
  }]
4468
4865
  }],
4469
4866
  propDecorators: {
@@ -4499,6 +4896,22 @@ i0.ɵɵngDeclareClassMetadata({
4499
4896
  required: false
4500
4897
  }]
4501
4898
  }],
4899
+ thresholds: [{
4900
+ type: i0.Input,
4901
+ args: [{
4902
+ isSignal: true,
4903
+ alias: "thresholds",
4904
+ required: false
4905
+ }]
4906
+ }],
4907
+ autoColor: [{
4908
+ type: i0.Input,
4909
+ args: [{
4910
+ isSignal: true,
4911
+ alias: "autoColor",
4912
+ required: false
4913
+ }]
4914
+ }],
4502
4915
  tooltip: [{
4503
4916
  type: i0.Input,
4504
4917
  args: [{
@@ -6724,6 +7137,10 @@ var DataTableComponent = class DataTableComponent {
6724
7137
  }
6725
7138
  return null;
6726
7139
  }
7140
+ _configurableKeys(keys) {
7141
+ const actionKeys = new Set(this.columns().filter((c) => c.cellType === "actions").map((c) => c.key));
7142
+ return (keys ?? []).filter((k) => !actionKeys.has(k));
7143
+ }
6727
7144
  _rowClickable() {
6728
7145
  const listeners = this.rowClick.listeners;
6729
7146
  return listeners === void 0 ? true : (listeners?.length ?? 0) > 0;
@@ -6732,11 +7149,11 @@ var DataTableComponent = class DataTableComponent {
6732
7149
  const opts = this._getOptionsForField(def.field);
6733
7150
  return def.exclude?.length ? opts.filter((o) => !this._isBulkExcluded(def, o.value)) : opts;
6734
7151
  }
6735
- _canBulkMove(def, current, target) {
7152
+ _canBulkMove(def, current, target, row) {
6736
7153
  const cur = String(current ?? "");
6737
7154
  if (cur === String(target)) return false;
6738
- if (!def.allowedFrom) return true;
6739
- return !!def.allowedFrom[target]?.includes(cur);
7155
+ if (def.allowedFrom && !def.allowedFrom[target]?.includes(cur)) return false;
7156
+ return !def.canChange || row === void 0 || def.canChange(row, String(target));
6740
7157
  }
6741
7158
  _isBulkExcluded(def, value) {
6742
7159
  if (!def.exclude?.length) return false;
@@ -6752,12 +7169,16 @@ var DataTableComponent = class DataTableComponent {
6752
7169
  const raw = col.nameFn ? col.nameFn(item) : col.render ? col.render(item) : item[col.key];
6753
7170
  return raw == null ? "" : String(raw).trim();
6754
7171
  }
6755
- selectRowLabel(item) {
7172
+ rowAccessibleName(item) {
6756
7173
  const name = this.rowName(item);
7174
+ return name ? `${name}${this._rowNameSuffix().get(item) ?? ""}` : "";
7175
+ }
7176
+ selectRowLabel(item) {
7177
+ const name = this.rowAccessibleName(item);
6757
7178
  return name ? `Select ${name}` : "Select row";
6758
7179
  }
6759
7180
  rowActionsLabel(item) {
6760
- const name = this.rowName(item);
7181
+ const name = this.rowAccessibleName(item);
6761
7182
  return name ? `Row actions for ${name}` : "Row actions";
6762
7183
  }
6763
7184
  toggleSelectAll() {
@@ -6989,7 +7410,7 @@ var DataTableComponent = class DataTableComponent {
6989
7410
  }
6990
7411
  if (action.startsWith("change-") && targetValue !== void 0) {
6991
7412
  const field = action.slice(7);
6992
- const eligible = selected.filter((item) => def ? this._canBulkMove(def, item[field], targetValue) : String(item[field] ?? "") !== String(targetValue));
7413
+ const eligible = selected.filter((item) => def ? this._canBulkMove(def, item[field], targetValue, item) : String(item[field] ?? "") !== String(targetValue));
6993
7414
  return {
6994
7415
  eligibleIds: eligible.map((i) => i.id),
6995
7416
  skippedCount: selected.length - eligible.length
@@ -7116,6 +7537,7 @@ var DataTableComponent = class DataTableComponent {
7116
7537
  }, ...ngDevMode ? [{ debugName: "_effectiveTabs" }] : /* istanbul ignore next */ []);
7117
7538
  this._error = signal(null, ...ngDevMode ? [{ debugName: "_error" }] : /* istanbul ignore next */ []);
7118
7539
  this._search = signal("", ...ngDevMode ? [{ debugName: "_search" }] : /* istanbul ignore next */ []);
7540
+ this._searchParam = computed(() => this._search().toLowerCase(), ...ngDevMode ? [{ debugName: "_searchParam" }] : /* istanbul ignore next */ []);
7119
7541
  this._page = signal(1, ...ngDevMode ? [{ debugName: "_page" }] : /* istanbul ignore next */ []);
7120
7542
  this._sortField = signal(null, ...ngDevMode ? [{ debugName: "_sortField" }] : /* istanbul ignore next */ []);
7121
7543
  this._sortDir = signal("asc", ...ngDevMode ? [{ debugName: "_sortDir" }] : /* istanbul ignore next */ []);
@@ -7131,7 +7553,7 @@ var DataTableComponent = class DataTableComponent {
7131
7553
  const vis = this._visibleColumns();
7132
7554
  const cols = this.columns();
7133
7555
  const numericKeys = this._numericKeys();
7134
- const base = vis.length ? cols.filter((c) => vis.includes(c.key)) : cols.filter((c) => c.defaultVisible !== false);
7556
+ const base = vis.length ? cols.filter((c) => c.cellType === "actions" || vis.includes(c.key)) : cols.filter((c) => c.defaultVisible !== false);
7135
7557
  const dates = [];
7136
7558
  const status = [];
7137
7559
  const regular = [];
@@ -7190,7 +7612,7 @@ var DataTableComponent = class DataTableComponent {
7190
7612
  this._exportParams = computed(() => {
7191
7613
  const params = { ...this._extraParams() };
7192
7614
  if (this._search()) {
7193
- params["search"] = this._search();
7615
+ params["search"] = this._searchParam();
7194
7616
  if (this._searchFields()) params["searchFields"] = this._searchFields();
7195
7617
  }
7196
7618
  if (this._activeTab()) params["filter"] = this._activeTab();
@@ -7199,7 +7621,7 @@ var DataTableComponent = class DataTableComponent {
7199
7621
  params["direction"] = this._sortDir();
7200
7622
  }
7201
7623
  const cf = this._colFilterValues();
7202
- for (const [key, vals] of Object.entries(cf)) if (vals.length > 0) params[key] = vals.join(",");
7624
+ for (const [key, vals] of Object.entries(cf)) if (vals.length > 0) params[key] = encodeFilterValues(vals);
7203
7625
  return params;
7204
7626
  }, ...ngDevMode ? [{ debugName: "_exportParams" }] : /* istanbul ignore next */ []);
7205
7627
  this._effectiveButtons = computed(() => {
@@ -7237,6 +7659,7 @@ var DataTableComponent = class DataTableComponent {
7237
7659
  const exclude = typeof entry === "string" ? [] : entry.exclude ?? [];
7238
7660
  const col = this.columns().find((c) => c.key === key);
7239
7661
  const allowedFrom = typeof entry === "string" ? void 0 : entry.allowedFrom;
7662
+ const canChange = typeof entry === "string" ? void 0 : entry.canChange;
7240
7663
  return {
7241
7664
  type: `change-${key}`,
7242
7665
  label: `Change ${col?.label ?? key}`,
@@ -7244,6 +7667,7 @@ var DataTableComponent = class DataTableComponent {
7244
7667
  field: key,
7245
7668
  ...exclude.length ? { exclude } : {},
7246
7669
  ...allowedFrom ? { allowedFrom } : {},
7670
+ ...canChange ? { canChange } : {},
7247
7671
  ...confirm ? { confirm } : {}
7248
7672
  };
7249
7673
  }).filter((def) => !def.field || !def.exclude?.length || this._bulkOptionsFor(def).length > 0), ...ngDevMode ? [{ debugName: "_bulkDefs" }] : /* istanbul ignore next */ []);
@@ -7261,8 +7685,8 @@ var DataTableComponent = class DataTableComponent {
7261
7685
  const allOpts = this._bulkOptionsFor(def);
7262
7686
  const selected = this._items().filter((i) => this._selectedIds().has(i["id"]));
7263
7687
  const eligible = getEligibleOptions(allOpts, selected, def.field);
7264
- if (!def.allowedFrom) return eligible;
7265
- return eligible.filter((o) => selected.some((i) => this._canBulkMove(def, i[def.field], o.value)));
7688
+ if (!def.allowedFrom && !def.canChange) return eligible;
7689
+ return eligible.filter((o) => selected.some((i) => this._canBulkMove(def, i[def.field], o.value, i)));
7266
7690
  }, ...ngDevMode ? [{ debugName: "_eligibleBulkOptions" }] : /* istanbul ignore next */ []);
7267
7691
  this._allSelected = computed(() => {
7268
7692
  const items = this._items();
@@ -7270,6 +7694,22 @@ var DataTableComponent = class DataTableComponent {
7270
7694
  return items.length > 0 && items.every((item) => sel.has(item["id"]));
7271
7695
  }, ...ngDevMode ? [{ debugName: "_allSelected" }] : /* istanbul ignore next */ []);
7272
7696
  this._someSelected = computed(() => this._selectedIds().size > 0 && !this._allSelected(), ...ngDevMode ? [{ debugName: "_someSelected" }] : /* istanbul ignore next */ []);
7697
+ this._rowNameSuffix = computed(() => {
7698
+ const items = this._items();
7699
+ const names = items.map((item) => this.rowName(item));
7700
+ const total = /* @__PURE__ */ new Map();
7701
+ for (const n of names) if (n) total.set(n, (total.get(n) ?? 0) + 1);
7702
+ const seen = /* @__PURE__ */ new Map();
7703
+ const out = /* @__PURE__ */ new Map();
7704
+ items.forEach((item, index) => {
7705
+ const n = names[index];
7706
+ if (!n || (total.get(n) ?? 0) < 2) return;
7707
+ const k = (seen.get(n) ?? 0) + 1;
7708
+ seen.set(n, k);
7709
+ out.set(item, ` (${k} of ${total.get(n)})`);
7710
+ });
7711
+ return out;
7712
+ }, ...ngDevMode ? [{ debugName: "_rowNameSuffix" }] : /* istanbul ignore next */ []);
7273
7713
  this._confirmingBulk = false;
7274
7714
  this._rowDeleteTarget = signal(null, ...ngDevMode ? [{ debugName: "_rowDeleteTarget" }] : /* istanbul ignore next */ []);
7275
7715
  this._rowDeleting = signal(false, ...ngDevMode ? [{ debugName: "_rowDeleting" }] : /* istanbul ignore next */ []);
@@ -7334,14 +7774,14 @@ var DataTableComponent = class DataTableComponent {
7334
7774
  this._error.set(null);
7335
7775
  let params = new HttpParams({ fromObject: this._extraParams() }).set("page", this._page() - 1).set("size", this.pageSize());
7336
7776
  if (this._search()) {
7337
- params = params.set("search", this._search());
7777
+ params = params.set("search", this._searchParam());
7338
7778
  const searchFields = this._searchFields();
7339
7779
  if (searchFields) params = params.set("searchFields", searchFields);
7340
7780
  }
7341
7781
  if (this._sortField()) params = params.set("sort", this._sortField()).set("direction", this._sortDir());
7342
7782
  if (this._activeTab()) params = params.set("filter", this._activeTab());
7343
7783
  const cf = this._colFilterValues();
7344
- for (const [key, vals] of Object.entries(cf)) if (vals.length > 0) params = params.set(key, vals.join(","));
7784
+ for (const [key, vals] of Object.entries(cf)) if (vals.length > 0) params = params.set(key, encodeFilterValues(vals));
7345
7785
  return this.http.get(`${this.config.baseUrl}${this.endpoint()}`, { params }).pipe(catchError(() => {
7346
7786
  this._error.set("Something went wrong. Please try again.");
7347
7787
  return of(null);
@@ -7367,7 +7807,7 @@ var DataTableComponent = class DataTableComponent {
7367
7807
  _countParams() {
7368
7808
  const params = { ...this._extraParams() };
7369
7809
  if (this._search()) {
7370
- params["search"] = this._search();
7810
+ params["search"] = this._searchParam();
7371
7811
  if (this._searchFields()) params["searchFields"] = this._searchFields();
7372
7812
  }
7373
7813
  return params;
@@ -7547,13 +7987,13 @@ var DataTableComponent = class DataTableComponent {
7547
7987
  }
7548
7988
  getState() {
7549
7989
  const columnFilters = {};
7550
- for (const [key, vals] of Object.entries(this._colFilterValues())) if (vals.length > 0) columnFilters[key] = vals.join(",");
7990
+ for (const [key, vals] of Object.entries(this._colFilterValues())) if (vals.length > 0) columnFilters[key] = encodeFilterValues(vals);
7551
7991
  return {
7552
7992
  columnFilters,
7553
7993
  quickFilter: this._activeTab() || null,
7554
7994
  sortField: this._sortField() || null,
7555
7995
  sortDir: this._sortField() ? this._sortDir() : null,
7556
- visibleColumns: this._visibleColumns().length ? [...this._visibleColumns()] : []
7996
+ visibleColumns: this._configurableKeys(this._visibleColumns())
7557
7997
  };
7558
7998
  }
7559
7999
  applyView(view) {
@@ -7566,7 +8006,7 @@ var DataTableComponent = class DataTableComponent {
7566
8006
  this._sortField.set(null);
7567
8007
  this._sortDir.set("asc");
7568
8008
  }
7569
- this._visibleColumns.set(view.visibleColumns?.length ? view.visibleColumns : []);
8009
+ this._visibleColumns.set(this._configurableKeys(view.visibleColumns));
7570
8010
  if (view.columnFilters && typeof view.columnFilters === "object") this._colFilterValues.set(this._restorableColumnFilters(view.columnFilters));
7571
8011
  this.resetToFirstPage();
7572
8012
  }
@@ -7577,7 +8017,7 @@ var DataTableComponent = class DataTableComponent {
7577
8017
  for (const [key, raw] of Object.entries(saved)) {
7578
8018
  if (!keys.has(key) || typeof raw !== "string") continue;
7579
8019
  const known = Object.keys(counts[key] ?? {});
7580
- let vals = raw.split(",").map((v) => v.trim()).filter(Boolean);
8020
+ let vals = decodeFilterValues(raw);
7581
8021
  if (known.length > 0) vals = vals.filter((v) => known.includes(v));
7582
8022
  if (vals.length > 0) out[key] = vals;
7583
8023
  }
@@ -7630,7 +8070,7 @@ var DataTableComponent = class DataTableComponent {
7630
8070
  _rowActions(col, item) {
7631
8071
  const actions = col.actionsFn?.(item) ?? [];
7632
8072
  if (this._canEdit()) return actions;
7633
- const visible = actions.filter((a) => a.type === "view");
8073
+ const visible = actions.filter((a) => a.type === "view" || a.allowReadOnly === true && a.type !== "delete");
7634
8074
  return visible.length === actions.length ? actions : visible;
7635
8075
  }
7636
8076
  async onTableRowAction(type, col, item) {
@@ -7731,6 +8171,15 @@ var DataTableComponent = class DataTableComponent {
7731
8171
  return "";
7732
8172
  }
7733
8173
  }
8174
+ imagePosition(col, item) {
8175
+ try {
8176
+ const p = col.imagePositionFn?.(item);
8177
+ const clamp = (n) => typeof n === "number" && Number.isFinite(n) ? Math.min(100, Math.max(0, n)) : 50;
8178
+ return `${clamp(p?.x)}% ${clamp(p?.y)}%`;
8179
+ } catch {
8180
+ return "50% 50%";
8181
+ }
8182
+ }
7734
8183
  imageClass(col, small) {
7735
8184
  const size = small ? "sm" : col.imageSize ?? "md";
7736
8185
  return `dt-img-${col.imageShape ?? "circle"}-${size}`;
@@ -8051,7 +8500,7 @@ var DataTableComponent = class DataTableComponent {
8051
8500
  [readOnly]="!_canEdit()"
8052
8501
  [tableButtons]="_toolbarButtons()"
8053
8502
  [hideMoreActions]="_emptyUnfiltered() && !_keepMoreActions()"
8054
- (visibleColumnsChange)="_visibleColumns.set($event)"
8503
+ (visibleColumnsChange)="_visibleColumns.set(_configurableKeys($event))"
8055
8504
  (saveViewClick)="onSaveViewClick($event)"
8056
8505
  (loadViewClick)="onLoadViewClick($event)"
8057
8506
  (deleteViewClick)="onDeleteViewClick($event)"
@@ -8096,7 +8545,7 @@ var DataTableComponent = class DataTableComponent {
8096
8545
  @let imgClass = imageClass(col, !!small);
8097
8546
  @if (imgUrl && !_failedImages().has(imgUrl)) {
8098
8547
  <img [class]="imgClass + ' dt-img'" [src]="imgUrl" [attr.alt]="imageAlt(col, item)"
8099
- loading="lazy" decoding="async" (error)="onImageError(imgUrl)" />
8548
+ [style.object-position]="imagePosition(col, item)" loading="lazy" decoding="async" (error)="onImageError(imgUrl)" />
8100
8549
  } @else {
8101
8550
  <span [class]="imgClass + ' dt-img-ph'" aria-hidden="true">
8102
8551
  @if (col.imagePlaceholder === 'person') {
@@ -8127,6 +8576,9 @@ var DataTableComponent = class DataTableComponent {
8127
8576
  <th
8128
8577
  scope="col"
8129
8578
  [style.text-align]="col.headerAlign ?? (col.cellType === 'number' ? 'right' : 'center')"
8579
+ [style.width]="col.width ?? null"
8580
+ [style.min-width]="col.width ?? null"
8581
+ [style.max-width]="col.width ?? null"
8130
8582
  [attr.aria-sort]="_isSortable(col) ? sortAriaLabel(col.key) : null"
8131
8583
  [class.dt-th-sorted]="_sortField() === col.key"
8132
8584
  [class.dt-th-actions]="col.cellType === 'actions'">
@@ -8227,6 +8679,10 @@ var DataTableComponent = class DataTableComponent {
8227
8679
  @for (col of visibleCols(); track col.key) {
8228
8680
  <td
8229
8681
  [style.text-align]="resolveCellAlign(col, item)"
8682
+ [style.width]="col.width ?? null"
8683
+ [style.min-width]="col.width ?? null"
8684
+ [style.max-width]="col.width ?? null"
8685
+ [class.dt-td-width]="!!col.width && col.cellType !== 'actions'"
8230
8686
  [class.dt-td-actions]="col.cellType === 'actions'">
8231
8687
 
8232
8688
  @switch (col.cellType) {
@@ -8274,7 +8730,7 @@ var DataTableComponent = class DataTableComponent {
8274
8730
  @let pCfg = col.progressFn ? col.progressFn(item) : null;
8275
8731
  @if (pCfg) {
8276
8732
  <ui-progress-bar [value]="pCfg.value" [max]="pCfg.max" [label]="pCfg.label ?? ''"
8277
- [variant]="pCfg.variant ?? 'blue'" [tooltip]="pCfg.tooltip ?? ''" />
8733
+ [variant]="pCfg.variant ?? 'blue'" [thresholds]="pCfg.thresholds ?? null" [autoColor]="pCfg.autoColor ?? false" [tooltip]="pCfg.tooltip ?? ''" />
8278
8734
  } @else { <span class="dt-none">—</span> }
8279
8735
  }
8280
8736
 
@@ -8564,7 +9020,7 @@ var DataTableComponent = class DataTableComponent {
8564
9020
  </div>
8565
9021
  `,
8566
9022
  isInline: true,
8567
- styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0}.dt-host{display:flex;flex-direction:column;height:100%;min-height:0}.dt-header{display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap;justify-content:space-between;position:relative;z-index:10}.dt-header-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap;flex:1;min-width:0}.dt-header-right{display:flex;align-items:center;gap:8px;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end}.dt-sk-shimmer{position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-shimmer:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}@keyframes dt-shimmer{to{transform:translate(200%)}}.dt-sk-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px}.dt-sk-toolbar-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.dt-sk-toolbar-right{display:flex;align-items:center;gap:8px;flex-shrink:0}.dt-sk-search{display:flex;align-items:center;gap:10px;width:380px;height:36px;padding:0 12px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc;box-sizing:border-box}.dt-sk-search-icon{width:16px;height:16px;border-radius:50%;flex-shrink:0}.dt-sk-search-text{flex:1;height:11px;border-radius:4px}.dt-sk-tab-strip{display:flex;gap:2px;padding:3px;background:#f1f5f9;border-radius:8px}.dt-sk-tab{height:28px;width:70px;border-radius:6px}.dt-sk-icon-btn{width:32px;height:32px;border-radius:6px}.dt-skeleton{border:1px solid #e2e8f0;border-radius:10px;overflow:hidden}.dt-sk-header{display:flex;gap:24px;padding:12px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.dt-sk-row{display:flex;gap:24px;padding:13px 16px;border-bottom:1px solid #f1f5f9}.dt-sk-row:last-child{border-bottom:none}.dt-sk-cell{flex:1;height:13px;border-radius:4px;position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-cell:first-child{max-width:100px}.dt-sk-cell:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}.dt-sk-head{height:10px}.dt-table-wrap{flex:1;min-height:0;overflow:auto;border:1px solid #e2e8f0;border-radius:10px 10px 0 0}.dt-sk-reload-row td{padding:10px 14px;border-bottom:1px solid #f1f5f9}table{width:100%;border-collapse:collapse;font-size:.875rem}thead tr{background:#f8fafc;border-bottom:1px solid #e2e8f0}thead{position:sticky;top:0;z-index:2}th{padding:10px 14px;font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;border-right:1px solid #e2e8f0;text-align:center;background:#f8fafc}th:last-child{border-right:none}th.dt-th-sorted{background:#f1f5f9}th.dt-th-actions{width:48px}.dt-th-inner{display:flex;align-items:center;justify-content:center;gap:4px}.dt-sort-btn{display:inline-flex;align-items:center;gap:4px;background:none;border:none;cursor:pointer;font-size:inherit;font-weight:inherit;color:inherit;font-family:inherit;padding:0;text-transform:inherit;letter-spacing:inherit}.dt-sort-btn:hover{color:#1e293b}.dt-sort-btn:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:2px}.dt-sort-icon{transition:transform .15s}.dt-sort-desc{transform:rotate(180deg)}.dt-sort-inactive{opacity:.4}tbody tr{border-bottom:1px solid #f1f5f9;background:#fff;transition:background .1s}tbody tr:last-child{border-bottom:none}tbody tr:hover{background:#f8fafc}.dt-row-clickable{cursor:pointer}.dt-row-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}td{padding:10px 14px;color:#334155;vertical-align:middle;white-space:nowrap;border-right:1px solid #f1f5f9}td:last-child{border-right:none}.dt-td-actions{text-align:center;padding:6px 8px}.dt-img{display:inline-block;vertical-align:middle;object-fit:cover;border:1px solid #e2e8f0;background:#f1f5f9;flex-shrink:0}.dt-img-ph{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;color:#94a3b8;background:#f1f5f9;border:1px solid #e2e8f0;flex-shrink:0}.dt-img-ph svg{width:55%;height:55%}.dt-img-circle-md{width:40px;height:40px;border-radius:50%}.dt-img-circle-sm{width:28px;height:28px;border-radius:50%}.dt-img-rounded-md{width:48px;height:32px;border-radius:6px}.dt-img-rounded-sm{width:36px;height:24px;border-radius:5px}.dt-avatar-name{display:flex;align-items:center;gap:8px}.dt-name-text{font-weight:500;color:#1e293b}.dt-overdue{color:#dc2626;font-weight:500}.dt-none{color:#94a3b8}.dt-tags{display:flex;align-items:center;gap:4px}.dt-tags-more{font-size:.75rem;font-weight:600;color:#475569;background:#f1f5f9;border-radius:999px;padding:2px 7px;cursor:default;-webkit-user-select:none;user-select:none;border:1px solid #e2e8f0}.dt-tags-more:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:999px}.dt-tag-tooltip{position:fixed;z-index:9999;pointer-events:none;background:#1e293b;border-radius:10px;padding:8px 10px;display:flex;flex-direction:column;gap:5px;box-shadow:0 4px 6px #0000000f,0 10px 24px #00000024;transform:translate(-50%) translateY(-100%);animation:dt-tip-in .12s ease;max-width:220px}@keyframes dt-tip-in{0%{opacity:0;transform:translate(-50%) translateY(calc(-100% + 4px))}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.dt-actions-cell{display:flex;align-items:center;justify-content:center}.dt-bulk-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;align-self:flex-start;padding:10px 14px;margin-bottom:8px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px}.dt-bulk-count{font-size:.875rem;font-weight:600;color:#1e40af;white-space:nowrap;flex-shrink:0}.dt-bulk-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;flex:1;min-width:0}.dt-bulk-actions ui-select{max-width:180px;min-width:120px}.dt-bulk-hint{font-size:.8125rem;line-height:1.35;color:#475569}.dt-card-cb{display:flex;align-items:center;padding:0 0 6px}.dt-card-selected{background:#eff6ff!important;border-color:#bfdbfe!important}.dt-th-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #e2e8f0;background:#f8fafc}.dt-td-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #f1f5f9}.dt-row-selected{background:#eff6ff!important}.dt-row-selected:hover{background:#dbeafe!important}.dt-state-cell{padding:0!important;border:none!important;background:#fff!important}@media(max-width:1024px){th{padding:10px 12px}td{padding:11px 12px}.dt-sort-btn{padding:4px 0}.dt-td-actions{padding:6px}.dt-bulk-bar{align-self:stretch}}@media(max-width:768px){th{padding:9px 10px;font-size:.8125rem}td{padding:10px;font-size:.8125rem}.dt-sk-search{width:100%}}@media(max-width:640px){.dt-header{flex-direction:column;align-items:stretch}.dt-header-left,.dt-header-right{width:100%}.dt-table-wrap{display:none}.dt-sk-search{width:100%}.dt-sk-toolbar{flex-direction:column;align-items:stretch;gap:8px}.dt-sk-toolbar-right{align-self:flex-end}.dt-bulk-bar{align-self:stretch;padding:10px 12px;row-gap:8px}.dt-bulk-count{flex:1}.dt-bulk-actions{width:100%}.dt-bulk-hint{flex-basis:100%}.dt-bulk-actions ui-select{max-width:100%;flex:1}}.dt-confirm-msg{margin:0;font-size:.9375rem;color:#334155;line-height:1.5;overflow-wrap:anywhere;word-break:break-word;white-space:pre-line}.dt-confirm-details{margin:10px 0 0;padding-left:20px;font-size:.875rem;color:#64748b;line-height:1.5;overflow-wrap:anywhere;word-break:break-word}.dt-confirm-details li+li{margin-top:4px}ui-pagination{flex-shrink:0}.dt-phone-controls{display:flex;flex-direction:column;gap:8px;margin-bottom:8px;flex-shrink:0}.dt-phone-sort{display:flex;align-items:center;gap:8px}.dt-phone-sort-label{font-size:.8125rem;font-weight:600;color:#64748b;flex-shrink:0}.dt-phone-sort-select{flex:1;min-width:0;min-height:44px;box-sizing:border-box;padding:0 12px;font-family:inherit;font-size:1rem;color:#1e293b;background:#fff;border:1px solid #e2e8f0;border-radius:8px}.dt-phone-filters{display:flex;flex-wrap:wrap;gap:8px}.dt-card-list{display:none;flex-direction:column;gap:8px;flex:1;min-height:0;overflow-y:auto}@media(max-width:640px){.dt-card-list{display:flex;padding-bottom:8px}}.dt-card{background:#fff;border:1px solid #e2e8f0;border-radius:10px;contain:layout style;padding:14px 16px;display:flex;flex-direction:column;gap:10px;transition:background .1s}.dt-card:has(.mm-dropdown){position:relative;z-index:1}.dt-card-clickable{cursor:pointer}.dt-card-clickable:active{background:#f8fafc}.dt-card-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.dt-card-header{display:flex;align-items:center;gap:10px}.dt-card-title{display:flex;align-items:center;gap:10px;flex:1;min-width:0}.dt-card-name{min-width:0;font-weight:600;color:#1e293b;font-size:.9375rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dt-card-name-plain{flex:1}.dt-card-actions{margin-left:auto;flex-shrink:0}.dt-card-badges{display:flex;flex-wrap:wrap;gap:6px}.dt-card-tags{display:flex;flex-wrap:wrap;gap:4px}.dt-card-details{display:flex;flex-direction:column;gap:5px}.dt-card-detail-row{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font-size:.8125rem}.dt-card-detail-label{color:#64748b;flex-shrink:0}.dt-card-detail-value{color:#334155;font-weight:500;text-align:right;min-width:0;overflow-wrap:anywhere;word-break:break-word}.dt-card-sk{gap:12px}.dt-card-sk-header{display:flex;align-items:center;gap:10px}.dt-card-sk-badges{display:flex;gap:6px}.dt-card-sk-rows{display:flex;flex-direction:column;gap:8px}\n"],
9023
+ styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0}.dt-host{display:flex;flex-direction:column;height:100%;min-height:0}.dt-header{display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap;justify-content:space-between;position:relative;z-index:10}.dt-header-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap;flex:1;min-width:0}.dt-header-right{display:flex;align-items:center;gap:8px;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end}.dt-sk-shimmer{position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-shimmer:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}@keyframes dt-shimmer{to{transform:translate(200%)}}.dt-sk-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px}.dt-sk-toolbar-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.dt-sk-toolbar-right{display:flex;align-items:center;gap:8px;flex-shrink:0}.dt-sk-search{display:flex;align-items:center;gap:10px;width:380px;height:36px;padding:0 12px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc;box-sizing:border-box}.dt-sk-search-icon{width:16px;height:16px;border-radius:50%;flex-shrink:0}.dt-sk-search-text{flex:1;height:11px;border-radius:4px}.dt-sk-tab-strip{display:flex;gap:2px;padding:3px;background:#f1f5f9;border-radius:8px}.dt-sk-tab{height:28px;width:70px;border-radius:6px}.dt-sk-icon-btn{width:32px;height:32px;border-radius:6px}.dt-skeleton{border:1px solid #e2e8f0;border-radius:10px;overflow:hidden}.dt-sk-header{display:flex;gap:24px;padding:12px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.dt-sk-row{display:flex;gap:24px;padding:13px 16px;border-bottom:1px solid #f1f5f9}.dt-sk-row:last-child{border-bottom:none}.dt-sk-cell{flex:1;height:13px;border-radius:4px;position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-cell:first-child{max-width:100px}.dt-sk-cell:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}.dt-sk-head{height:10px}.dt-table-wrap{flex:1;min-height:0;overflow:auto;border:1px solid #e2e8f0;border-radius:10px 10px 0 0}.dt-sk-reload-row td{padding:10px 14px;border-bottom:1px solid #f1f5f9}table{width:100%;border-collapse:collapse;font-size:.875rem}thead tr{background:#f8fafc;border-bottom:1px solid #e2e8f0}thead{position:sticky;top:0;z-index:2}th{padding:10px 14px;font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;border-right:1px solid #e2e8f0;text-align:center;background:#f8fafc}th:last-child{border-right:none}th.dt-th-sorted{background:#f1f5f9}th.dt-th-actions{width:48px}.dt-th-inner{display:flex;align-items:center;justify-content:center;gap:4px}.dt-sort-btn{display:inline-flex;align-items:center;gap:4px;background:none;border:none;cursor:pointer;font-size:inherit;font-weight:inherit;color:inherit;font-family:inherit;padding:0;text-transform:inherit;letter-spacing:inherit}.dt-sort-btn:hover{color:#1e293b}.dt-sort-btn:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:2px}@media(pointer:coarse){.dt-sort-btn{position:relative}.dt-sort-btn:after{content:\"\";position:absolute;left:-4px;right:-4px;top:50%;height:44px;transform:translateY(-50%)}}.dt-sort-icon{transition:transform .15s}.dt-sort-desc{transform:rotate(180deg)}.dt-sort-inactive{opacity:.4}tbody tr{border-bottom:1px solid #f1f5f9;background:#fff;transition:background .1s}tbody tr:last-child{border-bottom:none}tbody tr:hover{background:#f8fafc}.dt-row-clickable{cursor:pointer}.dt-row-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}td{padding:10px 14px;color:#334155;vertical-align:middle;white-space:nowrap;border-right:1px solid #f1f5f9}td:last-child{border-right:none}.dt-td-actions{text-align:center;padding:6px 8px}.dt-td-width{overflow:hidden;text-overflow:ellipsis}.dt-img{display:inline-block;vertical-align:middle;object-fit:cover;border:1px solid #e2e8f0;background:#f1f5f9;flex-shrink:0}.dt-img-ph{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;color:#94a3b8;background:#f1f5f9;border:1px solid #e2e8f0;flex-shrink:0}.dt-img-ph svg{width:55%;height:55%}.dt-img-circle-md{width:40px;height:40px;border-radius:50%}.dt-img-circle-sm{width:28px;height:28px;border-radius:50%}.dt-img-rounded-md{width:48px;height:32px;border-radius:6px}.dt-img-rounded-sm{width:36px;height:24px;border-radius:5px}.dt-avatar-name{display:flex;align-items:center;gap:8px}.dt-name-text{color:#1e293b}.dt-overdue{color:#dc2626;font-weight:500}.dt-none{color:#94a3b8}.dt-tags{display:flex;align-items:center;gap:4px}.dt-tags-more{font-size:.75rem;font-weight:600;color:#475569;background:#f1f5f9;border-radius:999px;padding:2px 7px;cursor:default;-webkit-user-select:none;user-select:none;border:1px solid #e2e8f0}.dt-tags-more:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:999px}.dt-tag-tooltip{position:fixed;z-index:9999;pointer-events:none;background:#1e293b;border-radius:10px;padding:8px 10px;display:flex;flex-direction:column;gap:5px;box-shadow:0 4px 6px #0000000f,0 10px 24px #00000024;transform:translate(-50%) translateY(-100%);animation:dt-tip-in .12s ease;max-width:220px}@keyframes dt-tip-in{0%{opacity:0;transform:translate(-50%) translateY(calc(-100% + 4px))}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.dt-actions-cell{display:flex;align-items:center;justify-content:center}.dt-bulk-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;align-self:flex-start;padding:10px 14px;margin-bottom:8px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px}.dt-bulk-count{font-size:.875rem;font-weight:600;color:#1e40af;white-space:nowrap;flex-shrink:0}.dt-bulk-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;flex:1;min-width:0}.dt-bulk-actions ui-select{max-width:180px;min-width:120px}.dt-bulk-hint{font-size:.8125rem;line-height:1.35;color:#475569}.dt-card-cb{display:flex;align-items:center;padding:0 0 6px}.dt-card-selected{background:#eff6ff!important;border-color:#bfdbfe!important}.dt-th-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #e2e8f0;background:#f8fafc}.dt-td-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #f1f5f9}.dt-row-selected{background:#eff6ff!important}.dt-row-selected:hover{background:#dbeafe!important}.dt-state-cell{padding:0!important;border:none!important;background:#fff!important}@media(max-width:1024px){th{padding:10px 12px}td{padding:11px 12px}.dt-sort-btn{padding:4px 0}.dt-td-actions{padding:6px}.dt-bulk-bar{align-self:stretch}}@media(max-width:768px){th{padding:9px 10px;font-size:.8125rem}td{padding:10px;font-size:.8125rem}.dt-sk-search{width:100%}}@media(max-width:640px){.dt-header{flex-direction:column;align-items:stretch}.dt-header-left,.dt-header-right{width:100%}.dt-table-wrap{display:none}.dt-sk-search{width:100%}.dt-sk-toolbar{flex-direction:column;align-items:stretch;gap:8px}.dt-sk-toolbar-right{align-self:flex-end}.dt-bulk-bar{align-self:stretch;padding:10px 12px;row-gap:8px}.dt-bulk-count{flex:1}.dt-bulk-actions{width:100%}.dt-bulk-hint{flex-basis:100%}.dt-bulk-actions ui-select{max-width:100%;flex:1}}.dt-confirm-msg{margin:0;font-size:.9375rem;color:#334155;line-height:1.5;overflow-wrap:anywhere;word-break:break-word;white-space:pre-line}.dt-confirm-details{margin:10px 0 0;padding-left:20px;font-size:.875rem;color:#64748b;line-height:1.5;overflow-wrap:anywhere;word-break:break-word}.dt-confirm-details li+li{margin-top:4px}ui-pagination{flex-shrink:0}.dt-phone-controls{display:flex;flex-direction:column;gap:8px;margin-bottom:8px;flex-shrink:0}.dt-phone-sort{display:flex;align-items:center;gap:8px}.dt-phone-sort-label{font-size:.8125rem;font-weight:600;color:#64748b;flex-shrink:0}.dt-phone-sort-select{flex:1;min-width:0;min-height:44px;box-sizing:border-box;padding:0 12px;font-family:inherit;font-size:1rem;color:#1e293b;background:#fff;border:1px solid #e2e8f0;border-radius:8px}.dt-phone-filters{display:flex;flex-wrap:wrap;gap:8px}.dt-card-list{display:none;flex-direction:column;gap:8px;flex:1;min-height:0;overflow-y:auto}@media(max-width:640px){.dt-card-list{display:flex;padding-bottom:8px}}.dt-card{background:#fff;border:1px solid #e2e8f0;border-radius:10px;contain:layout style;padding:14px 16px;display:flex;flex-direction:column;gap:10px;transition:background .1s}.dt-card:has(.mm-dropdown){position:relative;z-index:1}.dt-card-clickable{cursor:pointer}.dt-card-clickable:active{background:#f8fafc}.dt-card-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.dt-card-header{display:flex;align-items:center;gap:10px}.dt-card-title{display:flex;align-items:center;gap:10px;flex:1;min-width:0}.dt-card-name{min-width:0;font-weight:600;color:#1e293b;font-size:.9375rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dt-card-name-plain{flex:1}.dt-card-actions{margin-left:auto;flex-shrink:0}.dt-card-badges{display:flex;flex-wrap:wrap;gap:6px}.dt-card-tags{display:flex;flex-wrap:wrap;gap:4px}.dt-card-details{display:flex;flex-direction:column;gap:5px}.dt-card-detail-row{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font-size:.8125rem}.dt-card-detail-label{color:#64748b;flex-shrink:0}.dt-card-detail-value{color:#334155;font-weight:500;text-align:right;min-width:0;overflow-wrap:anywhere;word-break:break-word}.dt-card-sk{gap:12px}.dt-card-sk-header{display:flex;align-items:center;gap:10px}.dt-card-sk-badges{display:flex;gap:6px}.dt-card-sk-rows{display:flex;flex-direction:column;gap:8px}\n"],
8568
9024
  dependencies: [
8569
9025
  {
8570
9026
  kind: "directive",
@@ -8730,6 +9186,8 @@ var DataTableComponent = class DataTableComponent {
8730
9186
  "max",
8731
9187
  "label",
8732
9188
  "variant",
9189
+ "thresholds",
9190
+ "autoColor",
8733
9191
  "tooltip",
8734
9192
  "ariaLabel"
8735
9193
  ]
@@ -8763,9 +9221,14 @@ var DataTableComponent = class DataTableComponent {
8763
9221
  "ariaLabel",
8764
9222
  "indeterminate",
8765
9223
  "checked",
9224
+ "required",
9225
+ "requiredMessage",
9226
+ "hint",
9227
+ "error",
9228
+ "showErrors",
8766
9229
  "disabled"
8767
9230
  ],
8768
- outputs: ["checkedChange"]
9231
+ outputs: ["checkedChange", "invalidChange"]
8769
9232
  },
8770
9233
  {
8771
9234
  kind: "component",
@@ -8947,7 +9410,7 @@ i0.ɵɵngDeclareClassMetadata({
8947
9410
  [readOnly]="!_canEdit()"
8948
9411
  [tableButtons]="_toolbarButtons()"
8949
9412
  [hideMoreActions]="_emptyUnfiltered() && !_keepMoreActions()"
8950
- (visibleColumnsChange)="_visibleColumns.set($event)"
9413
+ (visibleColumnsChange)="_visibleColumns.set(_configurableKeys($event))"
8951
9414
  (saveViewClick)="onSaveViewClick($event)"
8952
9415
  (loadViewClick)="onLoadViewClick($event)"
8953
9416
  (deleteViewClick)="onDeleteViewClick($event)"
@@ -8992,7 +9455,7 @@ i0.ɵɵngDeclareClassMetadata({
8992
9455
  @let imgClass = imageClass(col, !!small);
8993
9456
  @if (imgUrl && !_failedImages().has(imgUrl)) {
8994
9457
  <img [class]="imgClass + ' dt-img'" [src]="imgUrl" [attr.alt]="imageAlt(col, item)"
8995
- loading="lazy" decoding="async" (error)="onImageError(imgUrl)" />
9458
+ [style.object-position]="imagePosition(col, item)" loading="lazy" decoding="async" (error)="onImageError(imgUrl)" />
8996
9459
  } @else {
8997
9460
  <span [class]="imgClass + ' dt-img-ph'" aria-hidden="true">
8998
9461
  @if (col.imagePlaceholder === 'person') {
@@ -9023,6 +9486,9 @@ i0.ɵɵngDeclareClassMetadata({
9023
9486
  <th
9024
9487
  scope="col"
9025
9488
  [style.text-align]="col.headerAlign ?? (col.cellType === 'number' ? 'right' : 'center')"
9489
+ [style.width]="col.width ?? null"
9490
+ [style.min-width]="col.width ?? null"
9491
+ [style.max-width]="col.width ?? null"
9026
9492
  [attr.aria-sort]="_isSortable(col) ? sortAriaLabel(col.key) : null"
9027
9493
  [class.dt-th-sorted]="_sortField() === col.key"
9028
9494
  [class.dt-th-actions]="col.cellType === 'actions'">
@@ -9123,6 +9589,10 @@ i0.ɵɵngDeclareClassMetadata({
9123
9589
  @for (col of visibleCols(); track col.key) {
9124
9590
  <td
9125
9591
  [style.text-align]="resolveCellAlign(col, item)"
9592
+ [style.width]="col.width ?? null"
9593
+ [style.min-width]="col.width ?? null"
9594
+ [style.max-width]="col.width ?? null"
9595
+ [class.dt-td-width]="!!col.width && col.cellType !== 'actions'"
9126
9596
  [class.dt-td-actions]="col.cellType === 'actions'">
9127
9597
 
9128
9598
  @switch (col.cellType) {
@@ -9170,7 +9640,7 @@ i0.ɵɵngDeclareClassMetadata({
9170
9640
  @let pCfg = col.progressFn ? col.progressFn(item) : null;
9171
9641
  @if (pCfg) {
9172
9642
  <ui-progress-bar [value]="pCfg.value" [max]="pCfg.max" [label]="pCfg.label ?? ''"
9173
- [variant]="pCfg.variant ?? 'blue'" [tooltip]="pCfg.tooltip ?? ''" />
9643
+ [variant]="pCfg.variant ?? 'blue'" [thresholds]="pCfg.thresholds ?? null" [autoColor]="pCfg.autoColor ?? false" [tooltip]="pCfg.tooltip ?? ''" />
9174
9644
  } @else { <span class="dt-none">—</span> }
9175
9645
  }
9176
9646
 
@@ -9459,7 +9929,7 @@ i0.ɵɵngDeclareClassMetadata({
9459
9929
  }
9460
9930
  </div>
9461
9931
  `,
9462
- styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0}.dt-host{display:flex;flex-direction:column;height:100%;min-height:0}.dt-header{display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap;justify-content:space-between;position:relative;z-index:10}.dt-header-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap;flex:1;min-width:0}.dt-header-right{display:flex;align-items:center;gap:8px;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end}.dt-sk-shimmer{position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-shimmer:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}@keyframes dt-shimmer{to{transform:translate(200%)}}.dt-sk-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px}.dt-sk-toolbar-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.dt-sk-toolbar-right{display:flex;align-items:center;gap:8px;flex-shrink:0}.dt-sk-search{display:flex;align-items:center;gap:10px;width:380px;height:36px;padding:0 12px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc;box-sizing:border-box}.dt-sk-search-icon{width:16px;height:16px;border-radius:50%;flex-shrink:0}.dt-sk-search-text{flex:1;height:11px;border-radius:4px}.dt-sk-tab-strip{display:flex;gap:2px;padding:3px;background:#f1f5f9;border-radius:8px}.dt-sk-tab{height:28px;width:70px;border-radius:6px}.dt-sk-icon-btn{width:32px;height:32px;border-radius:6px}.dt-skeleton{border:1px solid #e2e8f0;border-radius:10px;overflow:hidden}.dt-sk-header{display:flex;gap:24px;padding:12px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.dt-sk-row{display:flex;gap:24px;padding:13px 16px;border-bottom:1px solid #f1f5f9}.dt-sk-row:last-child{border-bottom:none}.dt-sk-cell{flex:1;height:13px;border-radius:4px;position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-cell:first-child{max-width:100px}.dt-sk-cell:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}.dt-sk-head{height:10px}.dt-table-wrap{flex:1;min-height:0;overflow:auto;border:1px solid #e2e8f0;border-radius:10px 10px 0 0}.dt-sk-reload-row td{padding:10px 14px;border-bottom:1px solid #f1f5f9}table{width:100%;border-collapse:collapse;font-size:.875rem}thead tr{background:#f8fafc;border-bottom:1px solid #e2e8f0}thead{position:sticky;top:0;z-index:2}th{padding:10px 14px;font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;border-right:1px solid #e2e8f0;text-align:center;background:#f8fafc}th:last-child{border-right:none}th.dt-th-sorted{background:#f1f5f9}th.dt-th-actions{width:48px}.dt-th-inner{display:flex;align-items:center;justify-content:center;gap:4px}.dt-sort-btn{display:inline-flex;align-items:center;gap:4px;background:none;border:none;cursor:pointer;font-size:inherit;font-weight:inherit;color:inherit;font-family:inherit;padding:0;text-transform:inherit;letter-spacing:inherit}.dt-sort-btn:hover{color:#1e293b}.dt-sort-btn:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:2px}.dt-sort-icon{transition:transform .15s}.dt-sort-desc{transform:rotate(180deg)}.dt-sort-inactive{opacity:.4}tbody tr{border-bottom:1px solid #f1f5f9;background:#fff;transition:background .1s}tbody tr:last-child{border-bottom:none}tbody tr:hover{background:#f8fafc}.dt-row-clickable{cursor:pointer}.dt-row-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}td{padding:10px 14px;color:#334155;vertical-align:middle;white-space:nowrap;border-right:1px solid #f1f5f9}td:last-child{border-right:none}.dt-td-actions{text-align:center;padding:6px 8px}.dt-img{display:inline-block;vertical-align:middle;object-fit:cover;border:1px solid #e2e8f0;background:#f1f5f9;flex-shrink:0}.dt-img-ph{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;color:#94a3b8;background:#f1f5f9;border:1px solid #e2e8f0;flex-shrink:0}.dt-img-ph svg{width:55%;height:55%}.dt-img-circle-md{width:40px;height:40px;border-radius:50%}.dt-img-circle-sm{width:28px;height:28px;border-radius:50%}.dt-img-rounded-md{width:48px;height:32px;border-radius:6px}.dt-img-rounded-sm{width:36px;height:24px;border-radius:5px}.dt-avatar-name{display:flex;align-items:center;gap:8px}.dt-name-text{font-weight:500;color:#1e293b}.dt-overdue{color:#dc2626;font-weight:500}.dt-none{color:#94a3b8}.dt-tags{display:flex;align-items:center;gap:4px}.dt-tags-more{font-size:.75rem;font-weight:600;color:#475569;background:#f1f5f9;border-radius:999px;padding:2px 7px;cursor:default;-webkit-user-select:none;user-select:none;border:1px solid #e2e8f0}.dt-tags-more:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:999px}.dt-tag-tooltip{position:fixed;z-index:9999;pointer-events:none;background:#1e293b;border-radius:10px;padding:8px 10px;display:flex;flex-direction:column;gap:5px;box-shadow:0 4px 6px #0000000f,0 10px 24px #00000024;transform:translate(-50%) translateY(-100%);animation:dt-tip-in .12s ease;max-width:220px}@keyframes dt-tip-in{0%{opacity:0;transform:translate(-50%) translateY(calc(-100% + 4px))}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.dt-actions-cell{display:flex;align-items:center;justify-content:center}.dt-bulk-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;align-self:flex-start;padding:10px 14px;margin-bottom:8px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px}.dt-bulk-count{font-size:.875rem;font-weight:600;color:#1e40af;white-space:nowrap;flex-shrink:0}.dt-bulk-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;flex:1;min-width:0}.dt-bulk-actions ui-select{max-width:180px;min-width:120px}.dt-bulk-hint{font-size:.8125rem;line-height:1.35;color:#475569}.dt-card-cb{display:flex;align-items:center;padding:0 0 6px}.dt-card-selected{background:#eff6ff!important;border-color:#bfdbfe!important}.dt-th-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #e2e8f0;background:#f8fafc}.dt-td-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #f1f5f9}.dt-row-selected{background:#eff6ff!important}.dt-row-selected:hover{background:#dbeafe!important}.dt-state-cell{padding:0!important;border:none!important;background:#fff!important}@media(max-width:1024px){th{padding:10px 12px}td{padding:11px 12px}.dt-sort-btn{padding:4px 0}.dt-td-actions{padding:6px}.dt-bulk-bar{align-self:stretch}}@media(max-width:768px){th{padding:9px 10px;font-size:.8125rem}td{padding:10px;font-size:.8125rem}.dt-sk-search{width:100%}}@media(max-width:640px){.dt-header{flex-direction:column;align-items:stretch}.dt-header-left,.dt-header-right{width:100%}.dt-table-wrap{display:none}.dt-sk-search{width:100%}.dt-sk-toolbar{flex-direction:column;align-items:stretch;gap:8px}.dt-sk-toolbar-right{align-self:flex-end}.dt-bulk-bar{align-self:stretch;padding:10px 12px;row-gap:8px}.dt-bulk-count{flex:1}.dt-bulk-actions{width:100%}.dt-bulk-hint{flex-basis:100%}.dt-bulk-actions ui-select{max-width:100%;flex:1}}.dt-confirm-msg{margin:0;font-size:.9375rem;color:#334155;line-height:1.5;overflow-wrap:anywhere;word-break:break-word;white-space:pre-line}.dt-confirm-details{margin:10px 0 0;padding-left:20px;font-size:.875rem;color:#64748b;line-height:1.5;overflow-wrap:anywhere;word-break:break-word}.dt-confirm-details li+li{margin-top:4px}ui-pagination{flex-shrink:0}.dt-phone-controls{display:flex;flex-direction:column;gap:8px;margin-bottom:8px;flex-shrink:0}.dt-phone-sort{display:flex;align-items:center;gap:8px}.dt-phone-sort-label{font-size:.8125rem;font-weight:600;color:#64748b;flex-shrink:0}.dt-phone-sort-select{flex:1;min-width:0;min-height:44px;box-sizing:border-box;padding:0 12px;font-family:inherit;font-size:1rem;color:#1e293b;background:#fff;border:1px solid #e2e8f0;border-radius:8px}.dt-phone-filters{display:flex;flex-wrap:wrap;gap:8px}.dt-card-list{display:none;flex-direction:column;gap:8px;flex:1;min-height:0;overflow-y:auto}@media(max-width:640px){.dt-card-list{display:flex;padding-bottom:8px}}.dt-card{background:#fff;border:1px solid #e2e8f0;border-radius:10px;contain:layout style;padding:14px 16px;display:flex;flex-direction:column;gap:10px;transition:background .1s}.dt-card:has(.mm-dropdown){position:relative;z-index:1}.dt-card-clickable{cursor:pointer}.dt-card-clickable:active{background:#f8fafc}.dt-card-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.dt-card-header{display:flex;align-items:center;gap:10px}.dt-card-title{display:flex;align-items:center;gap:10px;flex:1;min-width:0}.dt-card-name{min-width:0;font-weight:600;color:#1e293b;font-size:.9375rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dt-card-name-plain{flex:1}.dt-card-actions{margin-left:auto;flex-shrink:0}.dt-card-badges{display:flex;flex-wrap:wrap;gap:6px}.dt-card-tags{display:flex;flex-wrap:wrap;gap:4px}.dt-card-details{display:flex;flex-direction:column;gap:5px}.dt-card-detail-row{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font-size:.8125rem}.dt-card-detail-label{color:#64748b;flex-shrink:0}.dt-card-detail-value{color:#334155;font-weight:500;text-align:right;min-width:0;overflow-wrap:anywhere;word-break:break-word}.dt-card-sk{gap:12px}.dt-card-sk-header{display:flex;align-items:center;gap:10px}.dt-card-sk-badges{display:flex;gap:6px}.dt-card-sk-rows{display:flex;flex-direction:column;gap:8px}\n"]
9932
+ styles: [":host{display:flex;flex-direction:column;flex:1;min-height:0}.dt-host{display:flex;flex-direction:column;height:100%;min-height:0}.dt-header{display:flex;align-items:center;gap:12px;margin-bottom:16px;flex-wrap:wrap;justify-content:space-between;position:relative;z-index:10}.dt-header-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap;flex:1;min-width:0}.dt-header-right{display:flex;align-items:center;gap:8px;flex-shrink:0;flex-wrap:wrap;justify-content:flex-end}.dt-sk-shimmer{position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-shimmer:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}@keyframes dt-shimmer{to{transform:translate(200%)}}.dt-sk-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px}.dt-sk-toolbar-left{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.dt-sk-toolbar-right{display:flex;align-items:center;gap:8px;flex-shrink:0}.dt-sk-search{display:flex;align-items:center;gap:10px;width:380px;height:36px;padding:0 12px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc;box-sizing:border-box}.dt-sk-search-icon{width:16px;height:16px;border-radius:50%;flex-shrink:0}.dt-sk-search-text{flex:1;height:11px;border-radius:4px}.dt-sk-tab-strip{display:flex;gap:2px;padding:3px;background:#f1f5f9;border-radius:8px}.dt-sk-tab{height:28px;width:70px;border-radius:6px}.dt-sk-icon-btn{width:32px;height:32px;border-radius:6px}.dt-skeleton{border:1px solid #e2e8f0;border-radius:10px;overflow:hidden}.dt-sk-header{display:flex;gap:24px;padding:12px 16px;background:#f8fafc;border-bottom:1px solid #e2e8f0}.dt-sk-row{display:flex;gap:24px;padding:13px 16px;border-bottom:1px solid #f1f5f9}.dt-sk-row:last-child{border-bottom:none}.dt-sk-cell{flex:1;height:13px;border-radius:4px;position:relative;overflow:hidden;background:#f1f5f9}.dt-sk-cell:first-child{max-width:100px}.dt-sk-cell:after{content:\"\";position:absolute;inset:0;background:linear-gradient(90deg,transparent 25%,rgba(255,255,255,.65) 50%,transparent 75%);transform:translate(-100%);animation:dt-shimmer 1.4s ease-in-out infinite}.dt-sk-head{height:10px}.dt-table-wrap{flex:1;min-height:0;overflow:auto;border:1px solid #e2e8f0;border-radius:10px 10px 0 0}.dt-sk-reload-row td{padding:10px 14px;border-bottom:1px solid #f1f5f9}table{width:100%;border-collapse:collapse;font-size:.875rem}thead tr{background:#f8fafc;border-bottom:1px solid #e2e8f0}thead{position:sticky;top:0;z-index:2}th{padding:10px 14px;font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.04em;white-space:nowrap;border-right:1px solid #e2e8f0;text-align:center;background:#f8fafc}th:last-child{border-right:none}th.dt-th-sorted{background:#f1f5f9}th.dt-th-actions{width:48px}.dt-th-inner{display:flex;align-items:center;justify-content:center;gap:4px}.dt-sort-btn{display:inline-flex;align-items:center;gap:4px;background:none;border:none;cursor:pointer;font-size:inherit;font-weight:inherit;color:inherit;font-family:inherit;padding:0;text-transform:inherit;letter-spacing:inherit}.dt-sort-btn:hover{color:#1e293b}.dt-sort-btn:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:2px}@media(pointer:coarse){.dt-sort-btn{position:relative}.dt-sort-btn:after{content:\"\";position:absolute;left:-4px;right:-4px;top:50%;height:44px;transform:translateY(-50%)}}.dt-sort-icon{transition:transform .15s}.dt-sort-desc{transform:rotate(180deg)}.dt-sort-inactive{opacity:.4}tbody tr{border-bottom:1px solid #f1f5f9;background:#fff;transition:background .1s}tbody tr:last-child{border-bottom:none}tbody tr:hover{background:#f8fafc}.dt-row-clickable{cursor:pointer}.dt-row-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:-2px}td{padding:10px 14px;color:#334155;vertical-align:middle;white-space:nowrap;border-right:1px solid #f1f5f9}td:last-child{border-right:none}.dt-td-actions{text-align:center;padding:6px 8px}.dt-td-width{overflow:hidden;text-overflow:ellipsis}.dt-img{display:inline-block;vertical-align:middle;object-fit:cover;border:1px solid #e2e8f0;background:#f1f5f9;flex-shrink:0}.dt-img-ph{display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;color:#94a3b8;background:#f1f5f9;border:1px solid #e2e8f0;flex-shrink:0}.dt-img-ph svg{width:55%;height:55%}.dt-img-circle-md{width:40px;height:40px;border-radius:50%}.dt-img-circle-sm{width:28px;height:28px;border-radius:50%}.dt-img-rounded-md{width:48px;height:32px;border-radius:6px}.dt-img-rounded-sm{width:36px;height:24px;border-radius:5px}.dt-avatar-name{display:flex;align-items:center;gap:8px}.dt-name-text{color:#1e293b}.dt-overdue{color:#dc2626;font-weight:500}.dt-none{color:#94a3b8}.dt-tags{display:flex;align-items:center;gap:4px}.dt-tags-more{font-size:.75rem;font-weight:600;color:#475569;background:#f1f5f9;border-radius:999px;padding:2px 7px;cursor:default;-webkit-user-select:none;user-select:none;border:1px solid #e2e8f0}.dt-tags-more:focus-visible{outline:2px solid #60a5fa;outline-offset:2px;border-radius:999px}.dt-tag-tooltip{position:fixed;z-index:9999;pointer-events:none;background:#1e293b;border-radius:10px;padding:8px 10px;display:flex;flex-direction:column;gap:5px;box-shadow:0 4px 6px #0000000f,0 10px 24px #00000024;transform:translate(-50%) translateY(-100%);animation:dt-tip-in .12s ease;max-width:220px}@keyframes dt-tip-in{0%{opacity:0;transform:translate(-50%) translateY(calc(-100% + 4px))}to{opacity:1;transform:translate(-50%) translateY(-100%)}}.dt-actions-cell{display:flex;align-items:center;justify-content:center}.dt-bulk-bar{display:flex;align-items:center;gap:10px;flex-wrap:wrap;align-self:flex-start;padding:10px 14px;margin-bottom:8px;background:#eff6ff;border:1px solid #bfdbfe;border-radius:8px}.dt-bulk-count{font-size:.875rem;font-weight:600;color:#1e40af;white-space:nowrap;flex-shrink:0}.dt-bulk-actions{display:flex;align-items:center;gap:8px;flex-wrap:wrap;flex:1;min-width:0}.dt-bulk-actions ui-select{max-width:180px;min-width:120px}.dt-bulk-hint{font-size:.8125rem;line-height:1.35;color:#475569}.dt-card-cb{display:flex;align-items:center;padding:0 0 6px}.dt-card-selected{background:#eff6ff!important;border-color:#bfdbfe!important}.dt-th-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #e2e8f0;background:#f8fafc}.dt-td-cb{width:44px;padding:0 10px!important;text-align:center!important;border-right:1px solid #f1f5f9}.dt-row-selected{background:#eff6ff!important}.dt-row-selected:hover{background:#dbeafe!important}.dt-state-cell{padding:0!important;border:none!important;background:#fff!important}@media(max-width:1024px){th{padding:10px 12px}td{padding:11px 12px}.dt-sort-btn{padding:4px 0}.dt-td-actions{padding:6px}.dt-bulk-bar{align-self:stretch}}@media(max-width:768px){th{padding:9px 10px;font-size:.8125rem}td{padding:10px;font-size:.8125rem}.dt-sk-search{width:100%}}@media(max-width:640px){.dt-header{flex-direction:column;align-items:stretch}.dt-header-left,.dt-header-right{width:100%}.dt-table-wrap{display:none}.dt-sk-search{width:100%}.dt-sk-toolbar{flex-direction:column;align-items:stretch;gap:8px}.dt-sk-toolbar-right{align-self:flex-end}.dt-bulk-bar{align-self:stretch;padding:10px 12px;row-gap:8px}.dt-bulk-count{flex:1}.dt-bulk-actions{width:100%}.dt-bulk-hint{flex-basis:100%}.dt-bulk-actions ui-select{max-width:100%;flex:1}}.dt-confirm-msg{margin:0;font-size:.9375rem;color:#334155;line-height:1.5;overflow-wrap:anywhere;word-break:break-word;white-space:pre-line}.dt-confirm-details{margin:10px 0 0;padding-left:20px;font-size:.875rem;color:#64748b;line-height:1.5;overflow-wrap:anywhere;word-break:break-word}.dt-confirm-details li+li{margin-top:4px}ui-pagination{flex-shrink:0}.dt-phone-controls{display:flex;flex-direction:column;gap:8px;margin-bottom:8px;flex-shrink:0}.dt-phone-sort{display:flex;align-items:center;gap:8px}.dt-phone-sort-label{font-size:.8125rem;font-weight:600;color:#64748b;flex-shrink:0}.dt-phone-sort-select{flex:1;min-width:0;min-height:44px;box-sizing:border-box;padding:0 12px;font-family:inherit;font-size:1rem;color:#1e293b;background:#fff;border:1px solid #e2e8f0;border-radius:8px}.dt-phone-filters{display:flex;flex-wrap:wrap;gap:8px}.dt-card-list{display:none;flex-direction:column;gap:8px;flex:1;min-height:0;overflow-y:auto}@media(max-width:640px){.dt-card-list{display:flex;padding-bottom:8px}}.dt-card{background:#fff;border:1px solid #e2e8f0;border-radius:10px;contain:layout style;padding:14px 16px;display:flex;flex-direction:column;gap:10px;transition:background .1s}.dt-card:has(.mm-dropdown){position:relative;z-index:1}.dt-card-clickable{cursor:pointer}.dt-card-clickable:active{background:#f8fafc}.dt-card-clickable:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.dt-card-header{display:flex;align-items:center;gap:10px}.dt-card-title{display:flex;align-items:center;gap:10px;flex:1;min-width:0}.dt-card-name{min-width:0;font-weight:600;color:#1e293b;font-size:.9375rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dt-card-name-plain{flex:1}.dt-card-actions{margin-left:auto;flex-shrink:0}.dt-card-badges{display:flex;flex-wrap:wrap;gap:6px}.dt-card-tags{display:flex;flex-wrap:wrap;gap:4px}.dt-card-details{display:flex;flex-direction:column;gap:5px}.dt-card-detail-row{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font-size:.8125rem}.dt-card-detail-label{color:#64748b;flex-shrink:0}.dt-card-detail-value{color:#334155;font-weight:500;text-align:right;min-width:0;overflow-wrap:anywhere;word-break:break-word}.dt-card-sk{gap:12px}.dt-card-sk-header{display:flex;align-items:center;gap:10px}.dt-card-sk-badges{display:flex;gap:6px}.dt-card-sk-rows{display:flex;flex-direction:column;gap:8px}\n"]
9463
9933
  }]
9464
9934
  }],
9465
9935
  ctorParameters: () => [],
@@ -9939,7 +10409,7 @@ var SidePanelComponent = class SidePanelComponent {
9939
10409
  }
9940
10410
  `,
9941
10411
  isInline: true,
9942
- styles: [".sp-backdrop{position:fixed;inset:0;background:#0000004d;z-index:90;animation:sp-fade .2s ease}.sp-panel{position:fixed;top:0;right:0;bottom:var(--ui-kb, 0px);width:480px;max-width:100vw;max-height:var(--ui-vvh, 100dvh);background:#fff;z-index:100;box-shadow:-4px 0 20px #0000001a;display:flex;flex-direction:column;animation:sp-slide .25s ease}.sp-panel:focus{outline:none}.sp-wide{width:620px}.sp-extra-wide{width:760px}.sp-header{display:flex;justify-content:space-between;align-items:center;padding:24px 24px 20px;gap:12px;flex-shrink:0;background:linear-gradient(135deg,#1e293b,#334155)}.sp-header-text{flex:1;min-width:0}.sp-title{font-size:1.125rem;font-weight:700;color:#fff;margin:0}.sp-subtitle{font-size:.8125rem;color:#94a3b8;margin:4px 0 0}.sp-close{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:36px;height:36px;border-radius:8px;border:1px solid rgba(255,255,255,.2);background:#ffffff1a;cursor:pointer;color:#cbd5e1;transition:background .15s,border-color .15s}.sp-close:hover{background:#fff3;border-color:#ffffff4d;color:#fff}.sp-close:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.sp-body{padding:20px 24px 24px;flex:1;overflow-y:auto;overflow-x:hidden}.sp-footer{display:flex;align-items:center;justify-content:space-between;flex-shrink:0;padding:14px 24px calc(14px + env(safe-area-inset-bottom,0px));border-top:1px solid #e2e8f0;background:#f8fafc}.sp-btn{display:inline-flex;align-items:center;gap:7px;padding:8px 18px;border-radius:7px;font-size:.875rem;font-weight:500;font-family:inherit;cursor:pointer;white-space:nowrap;transition:background .1s,border-color .1s,opacity .1s}.sp-btn:disabled{opacity:.5;cursor:default}.sp-btn:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.sp-btn-cancel{background:#fff;border:1px solid #e2e8f0;color:#475569}.sp-btn-cancel:hover:not(:disabled){background:#f8fafc;border-color:#cbd5e1}.sp-btn-primary{background:#3b82f6;border:1px solid #3b82f6;color:#fff}.sp-btn-primary:hover:not(:disabled){background:#2563eb;border-color:#2563eb}.sp-btn-danger{background:#dc2626;border:1px solid #dc2626;color:#fff}.sp-btn-danger:hover:not(:disabled){background:#b91c1c;border-color:#b91c1c}.sp-btn-warning{background:#d97706;border:1px solid #d97706;color:#fff}.sp-btn-warning:hover:not(:disabled){background:#b45309;border-color:#b45309}.sp-spinner{display:inline-block;width:13px;height:13px;border-radius:50%;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:sp-spin .55s linear infinite;flex-shrink:0}@media(max-width:768px){.sp-panel,.sp-wide,.sp-extra-wide{width:100vw}}@media(max-width:480px){.sp-panel,.sp-wide,.sp-extra-wide{inset:auto 0 0;width:100vw;max-height:min(90dvh,var(--ui-vvh, 100dvh));border-radius:16px 16px 0 0;box-shadow:0 -4px 24px #00000026;animation:sp-up .25s ease}.sp-header{padding:16px 16px 14px}.sp-body{padding:16px}.sp-footer{padding:12px 16px calc(12px + env(safe-area-inset-bottom,0px))}}@keyframes sp-slide{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes sp-up{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes sp-fade{0%{opacity:0}to{opacity:1}}@keyframes sp-spin{to{transform:rotate(360deg)}}\n"],
10412
+ styles: [".sp-backdrop{position:fixed;inset:0;background:#0000004d;z-index:90;animation:sp-fade .2s ease}.sp-panel{position:fixed;top:0;right:0;bottom:var(--ui-kb, 0px);width:480px;max-width:100vw;max-height:var(--ui-vvh, 100dvh);background:#fff;z-index:100;box-shadow:-4px 0 20px #0000001a;display:flex;flex-direction:column;animation:sp-slide .25s ease}.sp-panel:focus{outline:none}.sp-wide{width:620px}.sp-extra-wide{width:760px}.sp-header{display:flex;justify-content:space-between;align-items:center;padding:24px 24px 20px;gap:12px;flex-shrink:0;background:linear-gradient(135deg,#1e293b,#334155)}.sp-header-text{flex:1;min-width:0}.sp-title{font-size:1.125rem;font-weight:700;color:#fff;margin:0}.sp-subtitle{font-size:.8125rem;color:#94a3b8;margin:4px 0 0}.sp-close{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:36px;height:36px;border-radius:8px;border:1px solid rgba(255,255,255,.2);background:#ffffff1a;cursor:pointer;color:#cbd5e1;transition:background .15s,border-color .15s}.sp-close:hover{background:#fff3;border-color:#ffffff4d;color:#fff}.sp-close:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.sp-body{padding:20px 24px 24px;flex:1;overflow-y:auto;overflow-x:hidden}.sp-footer{display:flex;align-items:center;justify-content:space-between;flex-shrink:0;padding:14px 24px calc(14px + env(safe-area-inset-bottom,0px));border-top:1px solid #e2e8f0;background:#f8fafc}.sp-btn{display:inline-flex;align-items:center;gap:7px;padding:8px 18px;border-radius:7px;font-size:.875rem;font-weight:500;font-family:inherit;cursor:pointer;white-space:nowrap;transition:background .1s,border-color .1s,opacity .1s}.sp-btn:disabled{opacity:.5;cursor:default}.sp-btn:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.sp-btn-cancel{background:#fff;border:1px solid #e2e8f0;color:#475569}.sp-btn-cancel:hover:not(:disabled){background:#f8fafc;border-color:#cbd5e1}.sp-btn-primary{background:#3b82f6;border:1px solid #3b82f6;color:#fff}.sp-btn-primary:hover:not(:disabled){background:#2563eb;border-color:#2563eb}.sp-btn-danger{background:#dc2626;border:1px solid #dc2626;color:#fff}.sp-btn-danger:hover:not(:disabled){background:#b91c1c;border-color:#b91c1c}.sp-btn-warning{background:#d97706;border:1px solid #d97706;color:#fff}.sp-btn-warning:hover:not(:disabled){background:#b45309;border-color:#b45309}.sp-spinner{display:inline-block;width:13px;height:13px;border-radius:50%;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:sp-spin .55s linear infinite;flex-shrink:0}@media(max-width:768px){.sp-panel,.sp-wide,.sp-extra-wide{width:100vw}}@media(max-width:480px){.sp-panel,.sp-wide,.sp-extra-wide{inset:auto 0 0;width:100vw;max-height:min(90dvh,var(--ui-vvh, 100dvh));border-radius:16px 16px 0 0;box-shadow:0 -4px 24px #00000026;animation:sp-up .25s ease}.sp-header{padding:16px 16px 14px}.sp-body{padding:16px}.sp-footer{padding:12px 16px calc(12px + env(safe-area-inset-bottom,0px))}}@media(pointer:coarse),(max-width:480px){.sp-close{position:relative}.sp-close:after{content:\"\";position:absolute;inset:-5px}.sp-btn{min-height:44px;justify-content:center}}@keyframes sp-slide{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes sp-up{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes sp-fade{0%{opacity:0}to{opacity:1}}@keyframes sp-spin{to{transform:rotate(360deg)}}\n"],
9943
10413
  changeDetection: i0.ChangeDetectionStrategy.OnPush
9944
10414
  });
9945
10415
  }
@@ -10021,7 +10491,7 @@ i0.ɵɵngDeclareClassMetadata({
10021
10491
  </aside>
10022
10492
  }
10023
10493
  `,
10024
- styles: [".sp-backdrop{position:fixed;inset:0;background:#0000004d;z-index:90;animation:sp-fade .2s ease}.sp-panel{position:fixed;top:0;right:0;bottom:var(--ui-kb, 0px);width:480px;max-width:100vw;max-height:var(--ui-vvh, 100dvh);background:#fff;z-index:100;box-shadow:-4px 0 20px #0000001a;display:flex;flex-direction:column;animation:sp-slide .25s ease}.sp-panel:focus{outline:none}.sp-wide{width:620px}.sp-extra-wide{width:760px}.sp-header{display:flex;justify-content:space-between;align-items:center;padding:24px 24px 20px;gap:12px;flex-shrink:0;background:linear-gradient(135deg,#1e293b,#334155)}.sp-header-text{flex:1;min-width:0}.sp-title{font-size:1.125rem;font-weight:700;color:#fff;margin:0}.sp-subtitle{font-size:.8125rem;color:#94a3b8;margin:4px 0 0}.sp-close{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:36px;height:36px;border-radius:8px;border:1px solid rgba(255,255,255,.2);background:#ffffff1a;cursor:pointer;color:#cbd5e1;transition:background .15s,border-color .15s}.sp-close:hover{background:#fff3;border-color:#ffffff4d;color:#fff}.sp-close:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.sp-body{padding:20px 24px 24px;flex:1;overflow-y:auto;overflow-x:hidden}.sp-footer{display:flex;align-items:center;justify-content:space-between;flex-shrink:0;padding:14px 24px calc(14px + env(safe-area-inset-bottom,0px));border-top:1px solid #e2e8f0;background:#f8fafc}.sp-btn{display:inline-flex;align-items:center;gap:7px;padding:8px 18px;border-radius:7px;font-size:.875rem;font-weight:500;font-family:inherit;cursor:pointer;white-space:nowrap;transition:background .1s,border-color .1s,opacity .1s}.sp-btn:disabled{opacity:.5;cursor:default}.sp-btn:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.sp-btn-cancel{background:#fff;border:1px solid #e2e8f0;color:#475569}.sp-btn-cancel:hover:not(:disabled){background:#f8fafc;border-color:#cbd5e1}.sp-btn-primary{background:#3b82f6;border:1px solid #3b82f6;color:#fff}.sp-btn-primary:hover:not(:disabled){background:#2563eb;border-color:#2563eb}.sp-btn-danger{background:#dc2626;border:1px solid #dc2626;color:#fff}.sp-btn-danger:hover:not(:disabled){background:#b91c1c;border-color:#b91c1c}.sp-btn-warning{background:#d97706;border:1px solid #d97706;color:#fff}.sp-btn-warning:hover:not(:disabled){background:#b45309;border-color:#b45309}.sp-spinner{display:inline-block;width:13px;height:13px;border-radius:50%;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:sp-spin .55s linear infinite;flex-shrink:0}@media(max-width:768px){.sp-panel,.sp-wide,.sp-extra-wide{width:100vw}}@media(max-width:480px){.sp-panel,.sp-wide,.sp-extra-wide{inset:auto 0 0;width:100vw;max-height:min(90dvh,var(--ui-vvh, 100dvh));border-radius:16px 16px 0 0;box-shadow:0 -4px 24px #00000026;animation:sp-up .25s ease}.sp-header{padding:16px 16px 14px}.sp-body{padding:16px}.sp-footer{padding:12px 16px calc(12px + env(safe-area-inset-bottom,0px))}}@keyframes sp-slide{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes sp-up{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes sp-fade{0%{opacity:0}to{opacity:1}}@keyframes sp-spin{to{transform:rotate(360deg)}}\n"]
10494
+ styles: [".sp-backdrop{position:fixed;inset:0;background:#0000004d;z-index:90;animation:sp-fade .2s ease}.sp-panel{position:fixed;top:0;right:0;bottom:var(--ui-kb, 0px);width:480px;max-width:100vw;max-height:var(--ui-vvh, 100dvh);background:#fff;z-index:100;box-shadow:-4px 0 20px #0000001a;display:flex;flex-direction:column;animation:sp-slide .25s ease}.sp-panel:focus{outline:none}.sp-wide{width:620px}.sp-extra-wide{width:760px}.sp-header{display:flex;justify-content:space-between;align-items:center;padding:24px 24px 20px;gap:12px;flex-shrink:0;background:linear-gradient(135deg,#1e293b,#334155)}.sp-header-text{flex:1;min-width:0}.sp-title{font-size:1.125rem;font-weight:700;color:#fff;margin:0}.sp-subtitle{font-size:.8125rem;color:#94a3b8;margin:4px 0 0}.sp-close{display:flex;align-items:center;justify-content:center;flex-shrink:0;width:36px;height:36px;border-radius:8px;border:1px solid rgba(255,255,255,.2);background:#ffffff1a;cursor:pointer;color:#cbd5e1;transition:background .15s,border-color .15s}.sp-close:hover{background:#fff3;border-color:#ffffff4d;color:#fff}.sp-close:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.sp-body{padding:20px 24px 24px;flex:1;overflow-y:auto;overflow-x:hidden}.sp-footer{display:flex;align-items:center;justify-content:space-between;flex-shrink:0;padding:14px 24px calc(14px + env(safe-area-inset-bottom,0px));border-top:1px solid #e2e8f0;background:#f8fafc}.sp-btn{display:inline-flex;align-items:center;gap:7px;padding:8px 18px;border-radius:7px;font-size:.875rem;font-weight:500;font-family:inherit;cursor:pointer;white-space:nowrap;transition:background .1s,border-color .1s,opacity .1s}.sp-btn:disabled{opacity:.5;cursor:default}.sp-btn:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.sp-btn-cancel{background:#fff;border:1px solid #e2e8f0;color:#475569}.sp-btn-cancel:hover:not(:disabled){background:#f8fafc;border-color:#cbd5e1}.sp-btn-primary{background:#3b82f6;border:1px solid #3b82f6;color:#fff}.sp-btn-primary:hover:not(:disabled){background:#2563eb;border-color:#2563eb}.sp-btn-danger{background:#dc2626;border:1px solid #dc2626;color:#fff}.sp-btn-danger:hover:not(:disabled){background:#b91c1c;border-color:#b91c1c}.sp-btn-warning{background:#d97706;border:1px solid #d97706;color:#fff}.sp-btn-warning:hover:not(:disabled){background:#b45309;border-color:#b45309}.sp-spinner{display:inline-block;width:13px;height:13px;border-radius:50%;border:2px solid rgba(255,255,255,.35);border-top-color:#fff;animation:sp-spin .55s linear infinite;flex-shrink:0}@media(max-width:768px){.sp-panel,.sp-wide,.sp-extra-wide{width:100vw}}@media(max-width:480px){.sp-panel,.sp-wide,.sp-extra-wide{inset:auto 0 0;width:100vw;max-height:min(90dvh,var(--ui-vvh, 100dvh));border-radius:16px 16px 0 0;box-shadow:0 -4px 24px #00000026;animation:sp-up .25s ease}.sp-header{padding:16px 16px 14px}.sp-body{padding:16px}.sp-footer{padding:12px 16px calc(12px + env(safe-area-inset-bottom,0px))}}@media(pointer:coarse),(max-width:480px){.sp-close{position:relative}.sp-close:after{content:\"\";position:absolute;inset:-5px}.sp-btn{min-height:44px;justify-content:center}}@keyframes sp-slide{0%{transform:translate(100%)}to{transform:translate(0)}}@keyframes sp-up{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes sp-fade{0%{opacity:0}to{opacity:1}}@keyframes sp-spin{to{transform:rotate(360deg)}}\n"]
10025
10495
  }]
10026
10496
  }],
10027
10497
  ctorParameters: () => [],
@@ -10116,30 +10586,120 @@ i0.ɵɵngDeclareClassMetadata({
10116
10586
  }]
10117
10587
  }
10118
10588
  });
10119
- var ToggleBadgeComponent = class ToggleBadgeComponent {
10589
+ const KEY_STEP = 2;
10590
+ const KEY_STEP_BIG = 10;
10591
+ const clamp = (n) => Math.min(100, Math.max(0, Math.round(n)));
10592
+ var ImageRepositionComponent = class ImageRepositionComponent {
10120
10593
  constructor() {
10121
- this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
10122
- this.active = input(false, ...ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []);
10123
- this.toggle = output();
10594
+ this.hintId = `ui-image-reposition-hint-${ImageRepositionComponent.nextId++}`;
10595
+ this.host = inject(ElementRef).nativeElement;
10596
+ this.src = input(null, ...ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []);
10597
+ this.alt = input("", ...ngDevMode ? [{ debugName: "alt" }] : /* istanbul ignore next */ []);
10598
+ this.shape = input("circle", ...ngDevMode ? [{ debugName: "shape" }] : /* istanbul ignore next */ []);
10599
+ this.label = input("Photo position", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
10600
+ this.x = model(50, ...ngDevMode ? [{ debugName: "x" }] : /* istanbul ignore next */ []);
10601
+ this.y = model(50, ...ngDevMode ? [{ debugName: "y" }] : /* istanbul ignore next */ []);
10602
+ this.dragging = signal(false, ...ngDevMode ? [{ debugName: "dragging" }] : /* istanbul ignore next */ []);
10603
+ this.natural = null;
10604
+ this.start = null;
10605
+ }
10606
+ static {
10607
+ this.nextId = 0;
10608
+ }
10609
+ onLoad(e) {
10610
+ const img = e.target;
10611
+ this.natural = {
10612
+ w: img.naturalWidth,
10613
+ h: img.naturalHeight
10614
+ };
10615
+ }
10616
+ overflow(frame) {
10617
+ if (!this.natural || !this.natural.w || !this.natural.h) return {
10618
+ x: 0,
10619
+ y: 0
10620
+ };
10621
+ const scale = Math.max(frame.width / this.natural.w, frame.height / this.natural.h);
10622
+ return {
10623
+ x: Math.max(0, this.natural.w * scale - frame.width),
10624
+ y: Math.max(0, this.natural.h * scale - frame.height)
10625
+ };
10626
+ }
10627
+ onPointerDown(e) {
10628
+ if (!this.src() || e.pointerType === "mouse" && e.button !== 0) return;
10629
+ e.currentTarget.setPointerCapture?.(e.pointerId);
10630
+ this.start = {
10631
+ px: e.clientX,
10632
+ py: e.clientY,
10633
+ x: this.x(),
10634
+ y: this.y()
10635
+ };
10636
+ this.dragging.set(true);
10637
+ }
10638
+ onPointerMove(e) {
10639
+ if (!this.start) return;
10640
+ const frame = e.currentTarget.getBoundingClientRect();
10641
+ const o = this.overflow(frame);
10642
+ if (o.x > 0) this.x.set(clamp(this.start.x - (e.clientX - this.start.px) / o.x * 100));
10643
+ if (o.y > 0) this.y.set(clamp(this.start.y - (e.clientY - this.start.py) / o.y * 100));
10644
+ }
10645
+ endDrag(e) {
10646
+ if (!this.start) return;
10647
+ e.currentTarget.releasePointerCapture?.(e.pointerId);
10648
+ this.start = null;
10649
+ this.dragging.set(false);
10650
+ }
10651
+ onKeydown(e) {
10652
+ if (!this.src()) return;
10653
+ const step = e.shiftKey ? KEY_STEP_BIG : KEY_STEP;
10654
+ const frame = this.host.querySelector(".ir-frame").getBoundingClientRect();
10655
+ const o = this.overflow(frame);
10656
+ let handled = true;
10657
+ if (e.key === "ArrowLeft" && o.x > 0) this.x.set(clamp(this.x() + step));
10658
+ else if (e.key === "ArrowRight" && o.x > 0) this.x.set(clamp(this.x() - step));
10659
+ else if (e.key === "ArrowUp" && o.y > 0) this.y.set(clamp(this.y() + step));
10660
+ else if (e.key === "ArrowDown" && o.y > 0) this.y.set(clamp(this.y() - step));
10661
+ else handled = e.key.startsWith("Arrow");
10662
+ if (handled) e.preventDefault();
10124
10663
  }
10125
10664
  static {
10126
10665
  this.ɵfac = i0.ɵɵngDeclareFactory({
10127
10666
  minVersion: "12.0.0",
10128
10667
  version: "22.2.2",
10129
10668
  ngImport: i0,
10130
- type: ToggleBadgeComponent,
10669
+ type: ImageRepositionComponent,
10131
10670
  deps: [],
10132
10671
  target: i0.ɵɵFactoryTarget.Component
10133
10672
  });
10134
10673
  }
10135
10674
  static {
10136
10675
  this.ɵcmp = i0.ɵɵngDeclareComponent({
10137
- minVersion: "17.1.0",
10676
+ minVersion: "17.0.0",
10138
10677
  version: "22.2.2",
10139
- type: ToggleBadgeComponent,
10678
+ type: ImageRepositionComponent,
10140
10679
  isStandalone: true,
10141
- selector: "ui-toggle-badge",
10680
+ selector: "ui-image-reposition",
10142
10681
  inputs: {
10682
+ src: {
10683
+ classPropertyName: "src",
10684
+ publicName: "src",
10685
+ isSignal: true,
10686
+ isRequired: false,
10687
+ transformFunction: null
10688
+ },
10689
+ alt: {
10690
+ classPropertyName: "alt",
10691
+ publicName: "alt",
10692
+ isSignal: true,
10693
+ isRequired: false,
10694
+ transformFunction: null
10695
+ },
10696
+ shape: {
10697
+ classPropertyName: "shape",
10698
+ publicName: "shape",
10699
+ isSignal: true,
10700
+ isRequired: false,
10701
+ transformFunction: null
10702
+ },
10143
10703
  label: {
10144
10704
  classPropertyName: "label",
10145
10705
  publicName: "label",
@@ -10147,24 +10707,41 @@ var ToggleBadgeComponent = class ToggleBadgeComponent {
10147
10707
  isRequired: false,
10148
10708
  transformFunction: null
10149
10709
  },
10150
- active: {
10151
- classPropertyName: "active",
10152
- publicName: "active",
10710
+ x: {
10711
+ classPropertyName: "x",
10712
+ publicName: "x",
10713
+ isSignal: true,
10714
+ isRequired: false,
10715
+ transformFunction: null
10716
+ },
10717
+ y: {
10718
+ classPropertyName: "y",
10719
+ publicName: "y",
10153
10720
  isSignal: true,
10154
10721
  isRequired: false,
10155
10722
  transformFunction: null
10156
10723
  }
10157
10724
  },
10158
- outputs: { toggle: "toggle" },
10725
+ outputs: {
10726
+ x: "xChange",
10727
+ y: "yChange"
10728
+ },
10159
10729
  ngImport: i0,
10160
10730
  template: `
10161
- <button class="toggle-badge" [class.active]="active()" (click)="toggle.emit()">
10162
- <ng-content />
10163
- {{ label() }}
10164
- </button>
10731
+ <div class="ir-frame" [class.ir-circle]="shape() === 'circle'" [class.ir-dragging]="dragging()"
10732
+ role="group" tabindex="0" data-testid="image-reposition-frame"
10733
+ [attr.aria-label]="label()" [attr.aria-describedby]="hintId"
10734
+ (pointerdown)="onPointerDown($event)" (pointermove)="onPointerMove($event)"
10735
+ (pointerup)="endDrag($event)" (pointercancel)="endDrag($event)" (keydown)="onKeydown($event)">
10736
+ @if (src()) {
10737
+ <img class="ir-img" [src]="src()" [attr.alt]="alt()" draggable="false"
10738
+ [style.object-position]="x() + '% ' + y() + '%'" (load)="onLoad($event)" />
10739
+ }
10740
+ </div>
10741
+ <span class="ir-hint" [id]="hintId">Drag the photo, or use the arrow keys, to center it in the frame.</span>
10165
10742
  `,
10166
10743
  isInline: true,
10167
- styles: [".toggle-badge{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:999px;border:1px solid #e2e8f0;background:#fff;font-size:.75rem;font-weight:500;color:#64748b;cursor:pointer;font-family:inherit;transition:all .15s ease;line-height:1}.toggle-badge:hover{background:#f8fafc;border-color:#94a3b8}.toggle-badge.active{background:#1e293b;color:#fff;border-color:#1e293b}.toggle-badge:focus-visible{outline:2px solid #60a5fa;outline-offset:2px}\n"],
10744
+ styles: [":host{display:inline-flex;flex-direction:column;gap:6px;max-width:100%}.ir-frame{width:160px;height:160px;border-radius:12px;overflow:hidden;border:1px solid #e2e8f0;background:#f1f5f9;cursor:grab;touch-action:none;-webkit-user-select:none;user-select:none;box-sizing:border-box;flex-shrink:0}.ir-frame:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.ir-circle{border-radius:50%}.ir-dragging{cursor:grabbing}.ir-img{display:block;width:100%;height:100%;object-fit:cover;pointer-events:none}.ir-hint{font-size:.75rem;color:#64748b}\n"],
10168
10745
  changeDetection: i0.ChangeDetectionStrategy.OnPush
10169
10746
  });
10170
10747
  }
@@ -10173,51 +10750,188 @@ i0.ɵɵngDeclareClassMetadata({
10173
10750
  minVersion: "12.0.0",
10174
10751
  version: "22.2.2",
10175
10752
  ngImport: i0,
10176
- type: ToggleBadgeComponent,
10753
+ type: ImageRepositionComponent,
10177
10754
  decorators: [{
10178
10755
  type: Component,
10179
10756
  args: [{
10180
- selector: "ui-toggle-badge",
10757
+ selector: "ui-image-reposition",
10181
10758
  standalone: true,
10182
10759
  changeDetection: ChangeDetectionStrategy.OnPush,
10183
10760
  template: `
10184
- <button class="toggle-badge" [class.active]="active()" (click)="toggle.emit()">
10185
- <ng-content />
10186
- {{ label() }}
10187
- </button>
10761
+ <div class="ir-frame" [class.ir-circle]="shape() === 'circle'" [class.ir-dragging]="dragging()"
10762
+ role="group" tabindex="0" data-testid="image-reposition-frame"
10763
+ [attr.aria-label]="label()" [attr.aria-describedby]="hintId"
10764
+ (pointerdown)="onPointerDown($event)" (pointermove)="onPointerMove($event)"
10765
+ (pointerup)="endDrag($event)" (pointercancel)="endDrag($event)" (keydown)="onKeydown($event)">
10766
+ @if (src()) {
10767
+ <img class="ir-img" [src]="src()" [attr.alt]="alt()" draggable="false"
10768
+ [style.object-position]="x() + '% ' + y() + '%'" (load)="onLoad($event)" />
10769
+ }
10770
+ </div>
10771
+ <span class="ir-hint" [id]="hintId">Drag the photo, or use the arrow keys, to center it in the frame.</span>
10188
10772
  `,
10189
- styles: [".toggle-badge{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:999px;border:1px solid #e2e8f0;background:#fff;font-size:.75rem;font-weight:500;color:#64748b;cursor:pointer;font-family:inherit;transition:all .15s ease;line-height:1}.toggle-badge:hover{background:#f8fafc;border-color:#94a3b8}.toggle-badge.active{background:#1e293b;color:#fff;border-color:#1e293b}.toggle-badge:focus-visible{outline:2px solid #60a5fa;outline-offset:2px}\n"]
10773
+ styles: [":host{display:inline-flex;flex-direction:column;gap:6px;max-width:100%}.ir-frame{width:160px;height:160px;border-radius:12px;overflow:hidden;border:1px solid #e2e8f0;background:#f1f5f9;cursor:grab;touch-action:none;-webkit-user-select:none;user-select:none;box-sizing:border-box;flex-shrink:0}.ir-frame:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.ir-circle{border-radius:50%}.ir-dragging{cursor:grabbing}.ir-img{display:block;width:100%;height:100%;object-fit:cover;pointer-events:none}.ir-hint{font-size:.75rem;color:#64748b}\n"]
10190
10774
  }]
10191
10775
  }],
10192
10776
  propDecorators: {
10193
- label: [{
10777
+ src: [{
10194
10778
  type: i0.Input,
10195
10779
  args: [{
10196
10780
  isSignal: true,
10197
- alias: "label",
10781
+ alias: "src",
10198
10782
  required: false
10199
10783
  }]
10200
10784
  }],
10201
- active: [{
10785
+ alt: [{
10202
10786
  type: i0.Input,
10203
10787
  args: [{
10204
10788
  isSignal: true,
10205
- alias: "active",
10789
+ alias: "alt",
10206
10790
  required: false
10207
10791
  }]
10208
10792
  }],
10209
- toggle: [{
10210
- type: i0.Output,
10211
- args: ["toggle"]
10212
- }]
10213
- }
10214
- });
10215
- var PillTabsComponent = class PillTabsComponent {
10216
- constructor() {
10217
- this.host = inject(ElementRef);
10218
- this.tabs = input([], ...ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []);
10219
- this.activeKey = input("", ...ngDevMode ? [{ debugName: "activeKey" }] : /* istanbul ignore next */ []);
10220
- this.ariaLabel = input(null, ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
10793
+ shape: [{
10794
+ type: i0.Input,
10795
+ args: [{
10796
+ isSignal: true,
10797
+ alias: "shape",
10798
+ required: false
10799
+ }]
10800
+ }],
10801
+ label: [{
10802
+ type: i0.Input,
10803
+ args: [{
10804
+ isSignal: true,
10805
+ alias: "label",
10806
+ required: false
10807
+ }]
10808
+ }],
10809
+ x: [{
10810
+ type: i0.Input,
10811
+ args: [{
10812
+ isSignal: true,
10813
+ alias: "x",
10814
+ required: false
10815
+ }]
10816
+ }, {
10817
+ type: i0.Output,
10818
+ args: ["xChange"]
10819
+ }],
10820
+ y: [{
10821
+ type: i0.Input,
10822
+ args: [{
10823
+ isSignal: true,
10824
+ alias: "y",
10825
+ required: false
10826
+ }]
10827
+ }, {
10828
+ type: i0.Output,
10829
+ args: ["yChange"]
10830
+ }]
10831
+ }
10832
+ });
10833
+ var ToggleBadgeComponent = class ToggleBadgeComponent {
10834
+ constructor() {
10835
+ this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
10836
+ this.active = input(false, ...ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []);
10837
+ this.toggle = output();
10838
+ }
10839
+ static {
10840
+ this.ɵfac = i0.ɵɵngDeclareFactory({
10841
+ minVersion: "12.0.0",
10842
+ version: "22.2.2",
10843
+ ngImport: i0,
10844
+ type: ToggleBadgeComponent,
10845
+ deps: [],
10846
+ target: i0.ɵɵFactoryTarget.Component
10847
+ });
10848
+ }
10849
+ static {
10850
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
10851
+ minVersion: "17.1.0",
10852
+ version: "22.2.2",
10853
+ type: ToggleBadgeComponent,
10854
+ isStandalone: true,
10855
+ selector: "ui-toggle-badge",
10856
+ inputs: {
10857
+ label: {
10858
+ classPropertyName: "label",
10859
+ publicName: "label",
10860
+ isSignal: true,
10861
+ isRequired: false,
10862
+ transformFunction: null
10863
+ },
10864
+ active: {
10865
+ classPropertyName: "active",
10866
+ publicName: "active",
10867
+ isSignal: true,
10868
+ isRequired: false,
10869
+ transformFunction: null
10870
+ }
10871
+ },
10872
+ outputs: { toggle: "toggle" },
10873
+ ngImport: i0,
10874
+ template: `
10875
+ <button class="toggle-badge" [class.active]="active()" (click)="toggle.emit()">
10876
+ <ng-content />
10877
+ {{ label() }}
10878
+ </button>
10879
+ `,
10880
+ isInline: true,
10881
+ styles: [".toggle-badge{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:999px;border:1px solid #e2e8f0;background:#fff;font-size:.75rem;font-weight:500;color:#64748b;cursor:pointer;font-family:inherit;transition:all .15s ease;line-height:1}.toggle-badge:hover{background:#f8fafc;border-color:#94a3b8}.toggle-badge.active{background:#1e293b;color:#fff;border-color:#1e293b}.toggle-badge:focus-visible{outline:2px solid #60a5fa;outline-offset:2px}\n"],
10882
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
10883
+ });
10884
+ }
10885
+ };
10886
+ i0.ɵɵngDeclareClassMetadata({
10887
+ minVersion: "12.0.0",
10888
+ version: "22.2.2",
10889
+ ngImport: i0,
10890
+ type: ToggleBadgeComponent,
10891
+ decorators: [{
10892
+ type: Component,
10893
+ args: [{
10894
+ selector: "ui-toggle-badge",
10895
+ standalone: true,
10896
+ changeDetection: ChangeDetectionStrategy.OnPush,
10897
+ template: `
10898
+ <button class="toggle-badge" [class.active]="active()" (click)="toggle.emit()">
10899
+ <ng-content />
10900
+ {{ label() }}
10901
+ </button>
10902
+ `,
10903
+ styles: [".toggle-badge{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:999px;border:1px solid #e2e8f0;background:#fff;font-size:.75rem;font-weight:500;color:#64748b;cursor:pointer;font-family:inherit;transition:all .15s ease;line-height:1}.toggle-badge:hover{background:#f8fafc;border-color:#94a3b8}.toggle-badge.active{background:#1e293b;color:#fff;border-color:#1e293b}.toggle-badge:focus-visible{outline:2px solid #60a5fa;outline-offset:2px}\n"]
10904
+ }]
10905
+ }],
10906
+ propDecorators: {
10907
+ label: [{
10908
+ type: i0.Input,
10909
+ args: [{
10910
+ isSignal: true,
10911
+ alias: "label",
10912
+ required: false
10913
+ }]
10914
+ }],
10915
+ active: [{
10916
+ type: i0.Input,
10917
+ args: [{
10918
+ isSignal: true,
10919
+ alias: "active",
10920
+ required: false
10921
+ }]
10922
+ }],
10923
+ toggle: [{
10924
+ type: i0.Output,
10925
+ args: ["toggle"]
10926
+ }]
10927
+ }
10928
+ });
10929
+ var PillTabsComponent = class PillTabsComponent {
10930
+ constructor() {
10931
+ this.host = inject(ElementRef);
10932
+ this.tabs = input([], ...ngDevMode ? [{ debugName: "tabs" }] : /* istanbul ignore next */ []);
10933
+ this.activeKey = input("", ...ngDevMode ? [{ debugName: "activeKey" }] : /* istanbul ignore next */ []);
10934
+ this.ariaLabel = input(null, ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
10221
10935
  this.name = input("pill-tabs-" + Math.random().toString(36).slice(2), ...ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []);
10222
10936
  this.tabChange = output();
10223
10937
  this.canScrollStart = signal(false, ...ngDevMode ? [{ debugName: "canScrollStart" }] : /* istanbul ignore next */ []);
@@ -10348,7 +11062,7 @@ var PillTabsComponent = class PillTabsComponent {
10348
11062
  </div>
10349
11063
  `,
10350
11064
  isInline: true,
10351
- styles: [".pill-wrap{position:relative}.pill-fade{position:absolute;top:0;bottom:0;width:28px;pointer-events:none;opacity:0;transition:opacity .15s}.pill-fade.visible{opacity:1}.pill-fade--start{left:0;background:linear-gradient(to right,var(--ui-pill-tabs-fade, #fff),transparent)}.pill-fade--end{right:0;background:linear-gradient(to left,var(--ui-pill-tabs-fade, #fff),transparent)}.pill-tabs{display:flex;gap:8px;flex-wrap:wrap}@media(max-width:768px){.pill-tabs{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:2px;scrollbar-width:none}.pill-tabs::-webkit-scrollbar{display:none}}.pill-tab{position:relative;display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border-radius:999px;border:1px solid #e2e8f0;background:#fff;font-size:.8125rem;font-weight:500;color:#64748b;cursor:pointer;transition:all .15s;font-family:inherit}.pill-tab:hover:not(.disabled):not(.active){background:#f8fafc;border-color:#94a3b8}.pill-tab:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.pill-tab .pill-count{background:#e2e8f0;color:#475569;font-size:.7rem;font-weight:600;padding:1px 6px;border-radius:999px;line-height:1.4}.pill-tab.active{background:#1e293b;color:#fff;border-color:#1e293b}.pill-tab.active .pill-count{background:#fff3;color:#fff}.pill-tab.active:hover{background:#1e293b;color:#fff}.pill-tab.disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.pill-tab .pill-info-icon{flex-shrink:0;opacity:.7}.pill-tab:hover .pill-info-icon,.pill-tab:focus-visible .pill-info-icon{opacity:1}.pill-tab .pill-info-tip{position:absolute;left:0;top:calc(100% + 8px);z-index:20;width:max-content;max-width:280px;padding:8px 12px;border-radius:8px;background:#1e293b;color:#fff;font-size:.75rem;font-weight:400;line-height:1.45;text-align:left;white-space:normal;box-shadow:0 4px 12px #0f172a40;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .12s,visibility .12s}.pill-tab:hover .pill-info-tip,.pill-tab:focus-visible .pill-info-tip{opacity:1;visibility:visible}\n"],
11065
+ styles: [".pill-wrap{position:relative}.pill-fade{position:absolute;top:0;bottom:0;width:28px;pointer-events:none;opacity:0;transition:opacity .15s}.pill-fade.visible{opacity:1}.pill-fade--start{left:0;background:linear-gradient(to right,var(--ui-pill-tabs-fade, #fff),transparent)}.pill-fade--end{right:0;background:linear-gradient(to left,var(--ui-pill-tabs-fade, #fff),transparent)}.pill-tabs{display:flex;gap:8px;flex-wrap:wrap}@media(max-width:768px){.pill-tabs{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:2px;scrollbar-width:none}.pill-tabs::-webkit-scrollbar{display:none}}.pill-tab{position:relative;display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border-radius:999px;border:1px solid #e2e8f0;background:#fff;font-size:.8125rem;font-weight:500;color:#64748b;cursor:pointer;transition:all .15s;font-family:inherit}.pill-tab:hover:not(.disabled):not(.active){background:#f8fafc;border-color:#94a3b8}.pill-tab:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.pill-tab .pill-count{background:#e2e8f0;color:#475569;font-size:.7rem;font-weight:600;padding:1px 6px;border-radius:999px;line-height:1.4}.pill-tab.active{background:#1e293b;color:#fff;border-color:#1e293b}.pill-tab.active .pill-count{background:#fff3;color:#fff}.pill-tab.active:hover{background:#1e293b;color:#fff}.pill-tab.disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.pill-tab .pill-info-icon{flex-shrink:0;opacity:.7}.pill-tab:hover .pill-info-icon,.pill-tab:focus-visible .pill-info-icon{opacity:1}.pill-tab .pill-info-tip{position:absolute;left:0;top:calc(100% + 8px);z-index:20;width:max-content;max-width:280px;padding:8px 12px;border-radius:8px;background:#1e293b;color:#fff;font-size:.75rem;font-weight:400;line-height:1.45;text-align:left;white-space:normal;box-shadow:0 4px 12px #0f172a40;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .12s,visibility .12s}.pill-tab:hover .pill-info-tip,.pill-tab:focus-visible .pill-info-tip{opacity:1;visibility:visible}@media(pointer:coarse),(max-width:480px){.pill-tab{min-height:44px}}\n"],
10352
11066
  changeDetection: i0.ChangeDetectionStrategy.OnPush
10353
11067
  });
10354
11068
  }
@@ -10394,7 +11108,7 @@ i0.ɵɵngDeclareClassMetadata({
10394
11108
  <span class="pill-fade pill-fade--end" [class.visible]="canScrollEnd()" aria-hidden="true" data-testid="pill-fade-end"></span>
10395
11109
  </div>
10396
11110
  `,
10397
- styles: [".pill-wrap{position:relative}.pill-fade{position:absolute;top:0;bottom:0;width:28px;pointer-events:none;opacity:0;transition:opacity .15s}.pill-fade.visible{opacity:1}.pill-fade--start{left:0;background:linear-gradient(to right,var(--ui-pill-tabs-fade, #fff),transparent)}.pill-fade--end{right:0;background:linear-gradient(to left,var(--ui-pill-tabs-fade, #fff),transparent)}.pill-tabs{display:flex;gap:8px;flex-wrap:wrap}@media(max-width:768px){.pill-tabs{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:2px;scrollbar-width:none}.pill-tabs::-webkit-scrollbar{display:none}}.pill-tab{position:relative;display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border-radius:999px;border:1px solid #e2e8f0;background:#fff;font-size:.8125rem;font-weight:500;color:#64748b;cursor:pointer;transition:all .15s;font-family:inherit}.pill-tab:hover:not(.disabled):not(.active){background:#f8fafc;border-color:#94a3b8}.pill-tab:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.pill-tab .pill-count{background:#e2e8f0;color:#475569;font-size:.7rem;font-weight:600;padding:1px 6px;border-radius:999px;line-height:1.4}.pill-tab.active{background:#1e293b;color:#fff;border-color:#1e293b}.pill-tab.active .pill-count{background:#fff3;color:#fff}.pill-tab.active:hover{background:#1e293b;color:#fff}.pill-tab.disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.pill-tab .pill-info-icon{flex-shrink:0;opacity:.7}.pill-tab:hover .pill-info-icon,.pill-tab:focus-visible .pill-info-icon{opacity:1}.pill-tab .pill-info-tip{position:absolute;left:0;top:calc(100% + 8px);z-index:20;width:max-content;max-width:280px;padding:8px 12px;border-radius:8px;background:#1e293b;color:#fff;font-size:.75rem;font-weight:400;line-height:1.45;text-align:left;white-space:normal;box-shadow:0 4px 12px #0f172a40;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .12s,visibility .12s}.pill-tab:hover .pill-info-tip,.pill-tab:focus-visible .pill-info-tip{opacity:1;visibility:visible}\n"]
11111
+ styles: [".pill-wrap{position:relative}.pill-fade{position:absolute;top:0;bottom:0;width:28px;pointer-events:none;opacity:0;transition:opacity .15s}.pill-fade.visible{opacity:1}.pill-fade--start{left:0;background:linear-gradient(to right,var(--ui-pill-tabs-fade, #fff),transparent)}.pill-fade--end{right:0;background:linear-gradient(to left,var(--ui-pill-tabs-fade, #fff),transparent)}.pill-tabs{display:flex;gap:8px;flex-wrap:wrap}@media(max-width:768px){.pill-tabs{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;padding-bottom:2px;scrollbar-width:none}.pill-tabs::-webkit-scrollbar{display:none}}.pill-tab{position:relative;display:inline-flex;align-items:center;gap:6px;padding:7px 16px;border-radius:999px;border:1px solid #e2e8f0;background:#fff;font-size:.8125rem;font-weight:500;color:#64748b;cursor:pointer;transition:all .15s;font-family:inherit}.pill-tab:hover:not(.disabled):not(.active){background:#f8fafc;border-color:#94a3b8}.pill-tab:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.pill-tab .pill-count{background:#e2e8f0;color:#475569;font-size:.7rem;font-weight:600;padding:1px 6px;border-radius:999px;line-height:1.4}.pill-tab.active{background:#1e293b;color:#fff;border-color:#1e293b}.pill-tab.active .pill-count{background:#fff3;color:#fff}.pill-tab.active:hover{background:#1e293b;color:#fff}.pill-tab.disabled{opacity:.4;cursor:not-allowed;pointer-events:none}.pill-tab .pill-info-icon{flex-shrink:0;opacity:.7}.pill-tab:hover .pill-info-icon,.pill-tab:focus-visible .pill-info-icon{opacity:1}.pill-tab .pill-info-tip{position:absolute;left:0;top:calc(100% + 8px);z-index:20;width:max-content;max-width:280px;padding:8px 12px;border-radius:8px;background:#1e293b;color:#fff;font-size:.75rem;font-weight:400;line-height:1.45;text-align:left;white-space:normal;box-shadow:0 4px 12px #0f172a40;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .12s,visibility .12s}.pill-tab:hover .pill-info-tip,.pill-tab:focus-visible .pill-info-tip{opacity:1;visibility:visible}@media(pointer:coarse),(max-width:480px){.pill-tab{min-height:44px}}\n"]
10398
11112
  }]
10399
11113
  }],
10400
11114
  ctorParameters: () => [],
@@ -10933,7 +11647,7 @@ var ContactPickerComponent = class ContactPickerComponent {
10933
11647
  </div>
10934
11648
  `,
10935
11649
  isInline: true,
10936
- styles: [".picker-wrapper{position:relative;overflow:visible}.picker-label{display:block;font-size:.8125rem;font-weight:600;color:#374151;margin-bottom:6px}.picker-req{color:#ef4444}.picker-hint{margin:6px 0 0;font-size:.75rem;line-height:1.4;color:#64748b}.picker-input{width:100%;padding:9px 12px;border:1px solid #e2e8f0;border-radius:8px;font-size:.875rem;color:#1e293b;font-family:inherit;outline:none;box-sizing:border-box}.picker-input::placeholder{color:#94a3b8}.picker-input:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61f}.picker-input:focus-visible{outline:2px solid transparent}@media(max-width:480px){.picker-input{font-size:1rem}}.picker-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.picker-dropdown{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:9999;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 6px 16px #0000001a;max-height:240px;overflow-y:auto}@media(pointer:coarse),(max-width:480px){.picker-input{min-height:44px}.picker-dropdown{max-height:min(240px,40vh);overscroll-behavior:contain}.picker-option{min-height:44px;justify-content:center;box-sizing:border-box}.picker-option--check{min-height:44px}.chip-remove{position:relative}.chip-remove:after{content:\"\";position:absolute;inset:-13px}}.picker-option{display:flex;flex-direction:column;gap:2px;width:100%;padding:10px 12px;border:none;background:none;text-align:left;cursor:pointer;font-family:inherit}.picker-option:hover,.picker-option.picker-option--active{background:#f8fafc}.picker-option:first-child{border-radius:8px 8px 0 0}.picker-option:last-child{border-radius:0 0 8px 8px}.picker-option--check{flex-direction:row;align-items:center;gap:10px}.picker-option--check .option-body{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}.picker-option--check .option-name,.picker-option--check .option-detail{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.option-check{display:flex;pointer-events:none}.option-name{font-size:.875rem;font-weight:600;color:#1e293b;overflow-wrap:anywhere}.option-detail{font-size:.75rem;color:#94a3b8;overflow-wrap:anywhere}.picker-loading,.picker-empty{padding:12px;font-size:.8125rem;color:#94a3b8;text-align:center}.selected-input{display:flex;align-items:center;justify-content:space-between;padding:9px 12px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc;font-size:.875rem;font-weight:600;color:#1e293b;gap:8px;overflow-wrap:anywhere;min-width:0}.selected-input:focus{outline:none}.selected-input:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.clear-btn{width:18px;height:18px;border:none;background:#e2e8f0;border-radius:50%;cursor:pointer;font-size:.75rem;color:#64748b;display:flex;align-items:center;justify-content:center;position:relative;flex-shrink:0}.clear-btn:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.clear-btn:hover{background:#cbd5e1;color:#1e293b}.clear-btn:after{content:\"\";position:absolute;inset:-13px}.recipient-details{margin-top:16px}.details-label{display:block;font-size:.6875rem;font-weight:600;color:#94a3b8;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px}.details-card{border:1px solid #e2e8f0;border-radius:8px;overflow:hidden}.detail-row{display:flex;justify-content:space-between;align-items:center;padding:10px 14px;border-bottom:1px solid #f1f5f9}.detail-row.last{border-bottom:none}.detail-row:nth-child(2n){background:#f8fafc}.detail-key{font-size:.8125rem;color:#94a3b8;font-weight:500}.detail-val{font-size:.875rem;color:#1e293b;font-weight:600}.multi-chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}.multi-chip{display:inline-flex;align-items:center;gap:4px;padding:4px 8px 4px 10px;background:#dbeafe;border-radius:20px;font-size:.8125rem;font-weight:500;color:#1e40af}.chip-remove{width:18px;height:18px;border:none;background:#1e40af26;border-radius:50%;cursor:pointer;font-size:.875rem;line-height:1;color:#1e40af;display:flex;align-items:center;justify-content:center;flex-shrink:0}.chip-remove:hover{background:#1e40af4d}.chip-remove:focus-visible{outline:2px solid #1e40af;outline-offset:2px}@media(forced-colors:active){.picker-input:focus{outline:2px solid Highlight;outline-offset:1px}.picker-option--active{outline:2px solid Highlight;outline-offset:-2px}}\n"],
11650
+ styles: [".picker-wrapper{position:relative;overflow:visible}.picker-label{display:block;font-size:.8125rem;font-weight:600;color:#374151;margin-bottom:6px}.picker-req{color:#ef4444}.picker-hint{margin:6px 0 0;font-size:.75rem;line-height:1.4;color:#64748b}.picker-input{width:100%;padding:9px 12px;border:1px solid #e2e8f0;border-radius:8px;font-size:.875rem;color:#1e293b;font-family:inherit;outline:none;box-sizing:border-box}.picker-input::placeholder{color:#94a3b8}.picker-input:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61f}.picker-input:focus-visible{outline:2px solid transparent}@media(max-width:480px){.picker-input{font-size:1rem}}.picker-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.picker-dropdown{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:9999;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 6px 16px #0000001a;max-height:240px;overflow-y:auto}@media(pointer:coarse),(max-width:480px){.picker-input{min-height:44px}.picker-dropdown{max-height:min(240px,40vh);overscroll-behavior:contain}.picker-option{min-height:44px;justify-content:center;box-sizing:border-box}.picker-option--check{min-height:44px}.chip-remove{position:relative}.chip-remove:after{content:\"\";position:absolute;inset:-13px}}@media(max-width:480px){:host-context(.m-body) .picker-dropdown{position:static;margin-top:4px;max-height:min(240px,calc(var(--ui-vvh, 100dvh) * .3))}}.picker-option{display:flex;flex-direction:column;gap:2px;width:100%;padding:10px 12px;border:none;background:none;text-align:left;cursor:pointer;font-family:inherit}.picker-option:hover,.picker-option.picker-option--active{background:#f8fafc}.picker-option:first-child{border-radius:8px 8px 0 0}.picker-option:last-child{border-radius:0 0 8px 8px}.picker-option--check{flex-direction:row;align-items:center;gap:10px}.picker-option--check .option-body{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}.picker-option--check .option-name,.picker-option--check .option-detail{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.option-check{display:flex;pointer-events:none}.option-name{font-size:.875rem;font-weight:600;color:#1e293b;overflow-wrap:anywhere}.option-detail{font-size:.75rem;color:#94a3b8;overflow-wrap:anywhere}.picker-loading,.picker-empty{padding:12px;font-size:.8125rem;color:#94a3b8;text-align:center}.selected-input{display:flex;align-items:center;justify-content:space-between;padding:9px 12px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc;font-size:.875rem;font-weight:600;color:#1e293b;gap:8px;overflow-wrap:anywhere;min-width:0}.selected-input:focus{outline:none}.selected-input:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.clear-btn{width:18px;height:18px;border:none;background:#e2e8f0;border-radius:50%;cursor:pointer;font-size:.75rem;color:#64748b;display:flex;align-items:center;justify-content:center;position:relative;flex-shrink:0}.clear-btn:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.clear-btn:hover{background:#cbd5e1;color:#1e293b}.clear-btn:after{content:\"\";position:absolute;inset:-13px}.recipient-details{margin-top:16px}.details-label{display:block;font-size:.6875rem;font-weight:600;color:#94a3b8;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px}.details-card{border:1px solid #e2e8f0;border-radius:8px;overflow:hidden}.detail-row{display:flex;justify-content:space-between;align-items:center;padding:10px 14px;border-bottom:1px solid #f1f5f9}.detail-row.last{border-bottom:none}.detail-row:nth-child(2n){background:#f8fafc}.detail-key{font-size:.8125rem;color:#94a3b8;font-weight:500}.detail-val{font-size:.875rem;color:#1e293b;font-weight:600}.multi-chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}.multi-chip{display:inline-flex;align-items:center;gap:4px;padding:4px 8px 4px 10px;background:#dbeafe;border-radius:20px;font-size:.8125rem;font-weight:500;color:#1e40af}.chip-remove{width:18px;height:18px;border:none;background:#1e40af26;border-radius:50%;cursor:pointer;font-size:.875rem;line-height:1;color:#1e40af;display:flex;align-items:center;justify-content:center;flex-shrink:0}.chip-remove:hover{background:#1e40af4d}.chip-remove:focus-visible{outline:2px solid #1e40af;outline-offset:2px}@media(forced-colors:active){.picker-input:focus{outline:2px solid Highlight;outline-offset:1px}.picker-option--active{outline:2px solid Highlight;outline-offset:-2px}}\n"],
10937
11651
  dependencies: [
10938
11652
  {
10939
11653
  kind: "ngmodule",
@@ -10971,9 +11685,14 @@ var ContactPickerComponent = class ContactPickerComponent {
10971
11685
  "ariaLabel",
10972
11686
  "indeterminate",
10973
11687
  "checked",
11688
+ "required",
11689
+ "requiredMessage",
11690
+ "hint",
11691
+ "error",
11692
+ "showErrors",
10974
11693
  "disabled"
10975
11694
  ],
10976
- outputs: ["checkedChange"]
11695
+ outputs: ["checkedChange", "invalidChange"]
10977
11696
  }
10978
11697
  ],
10979
11698
  changeDetection: i0.ChangeDetectionStrategy.OnPush
@@ -11156,7 +11875,7 @@ i0.ɵɵngDeclareClassMetadata({
11156
11875
  }
11157
11876
  </div>
11158
11877
  `,
11159
- styles: [".picker-wrapper{position:relative;overflow:visible}.picker-label{display:block;font-size:.8125rem;font-weight:600;color:#374151;margin-bottom:6px}.picker-req{color:#ef4444}.picker-hint{margin:6px 0 0;font-size:.75rem;line-height:1.4;color:#64748b}.picker-input{width:100%;padding:9px 12px;border:1px solid #e2e8f0;border-radius:8px;font-size:.875rem;color:#1e293b;font-family:inherit;outline:none;box-sizing:border-box}.picker-input::placeholder{color:#94a3b8}.picker-input:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61f}.picker-input:focus-visible{outline:2px solid transparent}@media(max-width:480px){.picker-input{font-size:1rem}}.picker-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.picker-dropdown{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:9999;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 6px 16px #0000001a;max-height:240px;overflow-y:auto}@media(pointer:coarse),(max-width:480px){.picker-input{min-height:44px}.picker-dropdown{max-height:min(240px,40vh);overscroll-behavior:contain}.picker-option{min-height:44px;justify-content:center;box-sizing:border-box}.picker-option--check{min-height:44px}.chip-remove{position:relative}.chip-remove:after{content:\"\";position:absolute;inset:-13px}}.picker-option{display:flex;flex-direction:column;gap:2px;width:100%;padding:10px 12px;border:none;background:none;text-align:left;cursor:pointer;font-family:inherit}.picker-option:hover,.picker-option.picker-option--active{background:#f8fafc}.picker-option:first-child{border-radius:8px 8px 0 0}.picker-option:last-child{border-radius:0 0 8px 8px}.picker-option--check{flex-direction:row;align-items:center;gap:10px}.picker-option--check .option-body{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}.picker-option--check .option-name,.picker-option--check .option-detail{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.option-check{display:flex;pointer-events:none}.option-name{font-size:.875rem;font-weight:600;color:#1e293b;overflow-wrap:anywhere}.option-detail{font-size:.75rem;color:#94a3b8;overflow-wrap:anywhere}.picker-loading,.picker-empty{padding:12px;font-size:.8125rem;color:#94a3b8;text-align:center}.selected-input{display:flex;align-items:center;justify-content:space-between;padding:9px 12px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc;font-size:.875rem;font-weight:600;color:#1e293b;gap:8px;overflow-wrap:anywhere;min-width:0}.selected-input:focus{outline:none}.selected-input:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.clear-btn{width:18px;height:18px;border:none;background:#e2e8f0;border-radius:50%;cursor:pointer;font-size:.75rem;color:#64748b;display:flex;align-items:center;justify-content:center;position:relative;flex-shrink:0}.clear-btn:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.clear-btn:hover{background:#cbd5e1;color:#1e293b}.clear-btn:after{content:\"\";position:absolute;inset:-13px}.recipient-details{margin-top:16px}.details-label{display:block;font-size:.6875rem;font-weight:600;color:#94a3b8;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px}.details-card{border:1px solid #e2e8f0;border-radius:8px;overflow:hidden}.detail-row{display:flex;justify-content:space-between;align-items:center;padding:10px 14px;border-bottom:1px solid #f1f5f9}.detail-row.last{border-bottom:none}.detail-row:nth-child(2n){background:#f8fafc}.detail-key{font-size:.8125rem;color:#94a3b8;font-weight:500}.detail-val{font-size:.875rem;color:#1e293b;font-weight:600}.multi-chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}.multi-chip{display:inline-flex;align-items:center;gap:4px;padding:4px 8px 4px 10px;background:#dbeafe;border-radius:20px;font-size:.8125rem;font-weight:500;color:#1e40af}.chip-remove{width:18px;height:18px;border:none;background:#1e40af26;border-radius:50%;cursor:pointer;font-size:.875rem;line-height:1;color:#1e40af;display:flex;align-items:center;justify-content:center;flex-shrink:0}.chip-remove:hover{background:#1e40af4d}.chip-remove:focus-visible{outline:2px solid #1e40af;outline-offset:2px}@media(forced-colors:active){.picker-input:focus{outline:2px solid Highlight;outline-offset:1px}.picker-option--active{outline:2px solid Highlight;outline-offset:-2px}}\n"]
11878
+ styles: [".picker-wrapper{position:relative;overflow:visible}.picker-label{display:block;font-size:.8125rem;font-weight:600;color:#374151;margin-bottom:6px}.picker-req{color:#ef4444}.picker-hint{margin:6px 0 0;font-size:.75rem;line-height:1.4;color:#64748b}.picker-input{width:100%;padding:9px 12px;border:1px solid #e2e8f0;border-radius:8px;font-size:.875rem;color:#1e293b;font-family:inherit;outline:none;box-sizing:border-box}.picker-input::placeholder{color:#94a3b8}.picker-input:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61f}.picker-input:focus-visible{outline:2px solid transparent}@media(max-width:480px){.picker-input{font-size:1rem}}.picker-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.picker-dropdown{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:9999;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 6px 16px #0000001a;max-height:240px;overflow-y:auto}@media(pointer:coarse),(max-width:480px){.picker-input{min-height:44px}.picker-dropdown{max-height:min(240px,40vh);overscroll-behavior:contain}.picker-option{min-height:44px;justify-content:center;box-sizing:border-box}.picker-option--check{min-height:44px}.chip-remove{position:relative}.chip-remove:after{content:\"\";position:absolute;inset:-13px}}@media(max-width:480px){:host-context(.m-body) .picker-dropdown{position:static;margin-top:4px;max-height:min(240px,calc(var(--ui-vvh, 100dvh) * .3))}}.picker-option{display:flex;flex-direction:column;gap:2px;width:100%;padding:10px 12px;border:none;background:none;text-align:left;cursor:pointer;font-family:inherit}.picker-option:hover,.picker-option.picker-option--active{background:#f8fafc}.picker-option:first-child{border-radius:8px 8px 0 0}.picker-option:last-child{border-radius:0 0 8px 8px}.picker-option--check{flex-direction:row;align-items:center;gap:10px}.picker-option--check .option-body{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}.picker-option--check .option-name,.picker-option--check .option-detail{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.option-check{display:flex;pointer-events:none}.option-name{font-size:.875rem;font-weight:600;color:#1e293b;overflow-wrap:anywhere}.option-detail{font-size:.75rem;color:#94a3b8;overflow-wrap:anywhere}.picker-loading,.picker-empty{padding:12px;font-size:.8125rem;color:#94a3b8;text-align:center}.selected-input{display:flex;align-items:center;justify-content:space-between;padding:9px 12px;border:1px solid #e2e8f0;border-radius:8px;background:#f8fafc;font-size:.875rem;font-weight:600;color:#1e293b;gap:8px;overflow-wrap:anywhere;min-width:0}.selected-input:focus{outline:none}.selected-input:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.clear-btn{width:18px;height:18px;border:none;background:#e2e8f0;border-radius:50%;cursor:pointer;font-size:.75rem;color:#64748b;display:flex;align-items:center;justify-content:center;position:relative;flex-shrink:0}.clear-btn:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.clear-btn:hover{background:#cbd5e1;color:#1e293b}.clear-btn:after{content:\"\";position:absolute;inset:-13px}.recipient-details{margin-top:16px}.details-label{display:block;font-size:.6875rem;font-weight:600;color:#94a3b8;text-transform:uppercase;letter-spacing:.05em;margin-bottom:8px}.details-card{border:1px solid #e2e8f0;border-radius:8px;overflow:hidden}.detail-row{display:flex;justify-content:space-between;align-items:center;padding:10px 14px;border-bottom:1px solid #f1f5f9}.detail-row.last{border-bottom:none}.detail-row:nth-child(2n){background:#f8fafc}.detail-key{font-size:.8125rem;color:#94a3b8;font-weight:500}.detail-val{font-size:.875rem;color:#1e293b;font-weight:600}.multi-chips{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}.multi-chip{display:inline-flex;align-items:center;gap:4px;padding:4px 8px 4px 10px;background:#dbeafe;border-radius:20px;font-size:.8125rem;font-weight:500;color:#1e40af}.chip-remove{width:18px;height:18px;border:none;background:#1e40af26;border-radius:50%;cursor:pointer;font-size:.875rem;line-height:1;color:#1e40af;display:flex;align-items:center;justify-content:center;flex-shrink:0}.chip-remove:hover{background:#1e40af4d}.chip-remove:focus-visible{outline:2px solid #1e40af;outline-offset:2px}@media(forced-colors:active){.picker-input:focus{outline:2px solid Highlight;outline-offset:1px}.picker-option--active{outline:2px solid Highlight;outline-offset:-2px}}\n"]
11160
11879
  }]
11161
11880
  }],
11162
11881
  ctorParameters: () => [],
@@ -13151,6 +13870,11 @@ function getErrorMessage(error, fallbackContext, action) {
13151
13870
  if (typeof error === "string") return error;
13152
13871
  return `${failed} Please try again.`;
13153
13872
  }
13873
+ function serverMessage(err) {
13874
+ if (!(err instanceof HttpErrorResponse)) return "";
13875
+ const m = err.error?.message;
13876
+ return typeof m === "string" ? m.trim() : "";
13877
+ }
13154
13878
  var TextareaInputComponent = class TextareaInputComponent {
13155
13879
  constructor() {
13156
13880
  this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
@@ -13170,6 +13894,7 @@ var TextareaInputComponent = class TextareaInputComponent {
13170
13894
  this._cvaDisabled = signal(false, ...ngDevMode ? [{ debugName: "_cvaDisabled" }] : /* istanbul ignore next */ []);
13171
13895
  this.disabled = computed(() => this._disabledInput() || this._cvaDisabled(), ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
13172
13896
  this._value = signal("", ...ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []);
13897
+ this._unlabelledHint = computed(() => !this.label() && !!this.hint(), ...ngDevMode ? [{ debugName: "_unlabelledHint" }] : /* istanbul ignore next */ []);
13173
13898
  this._reveal = createFieldReveal(this.showErrors);
13174
13899
  this._issue = computed(() => this._check(this._value()), ...ngDevMode ? [{ debugName: "_issue" }] : /* istanbul ignore next */ []);
13175
13900
  this.invalid = computed(() => !!this.error() || !!this._issue(), ...ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []);
@@ -13357,10 +14082,13 @@ var TextareaInputComponent = class TextareaInputComponent {
13357
14082
  [attr.required]="required() || null"
13358
14083
  [attr.aria-label]="ariaLabel() || null"
13359
14084
  [attr.aria-invalid]="_activeError() ? 'true' : null"
13360
- [attr.aria-describedby]="_activeError() ? _inputId + '-desc' : null"
14085
+ [attr.aria-describedby]="_activeError() ? _inputId + '-desc' : (_unlabelledHint() ? _inputId + '-hint' : null)"
13361
14086
  (input)="onInput($event)"
13362
14087
  (blur)="onBlur()"
13363
14088
  ></textarea>
14089
+ @if (!_activeError() && _unlabelledHint()) {
14090
+ <p class="ta-desc" [id]="_inputId + '-hint'">{{ hint() }}</p>
14091
+ }
13364
14092
  @if (_activeError()) {
13365
14093
  <p class="ta-desc ta-desc-error" [id]="_inputId + '-desc'" role="alert">{{ _activeError() }}</p>
13366
14094
  }
@@ -13420,10 +14148,13 @@ i0.ɵɵngDeclareClassMetadata({
13420
14148
  [attr.required]="required() || null"
13421
14149
  [attr.aria-label]="ariaLabel() || null"
13422
14150
  [attr.aria-invalid]="_activeError() ? 'true' : null"
13423
- [attr.aria-describedby]="_activeError() ? _inputId + '-desc' : null"
14151
+ [attr.aria-describedby]="_activeError() ? _inputId + '-desc' : (_unlabelledHint() ? _inputId + '-hint' : null)"
13424
14152
  (input)="onInput($event)"
13425
14153
  (blur)="onBlur()"
13426
14154
  ></textarea>
14155
+ @if (!_activeError() && _unlabelledHint()) {
14156
+ <p class="ta-desc" [id]="_inputId + '-hint'">{{ hint() }}</p>
14157
+ }
13427
14158
  @if (_activeError()) {
13428
14159
  <p class="ta-desc ta-desc-error" [id]="_inputId + '-desc'" role="alert">{{ _activeError() }}</p>
13429
14160
  }
@@ -14097,7 +14828,7 @@ var ChipComponent = class ChipComponent {
14097
14828
  </button>
14098
14829
  `,
14099
14830
  isInline: true,
14100
- styles: [":host{display:contents}.chip{display:inline-flex;align-items:center;gap:5px;border-radius:999px;border:1.5px solid #d1d5db;background:#f9fafb;color:#374151;font-weight:500;font-family:inherit;cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;transition:background .15s,border-color .15s,color .15s}.chip:hover:not(:disabled){border-color:#3b82f6;color:#3b82f6;background:#eff6ff}.chip:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.chip:disabled{opacity:.5;cursor:default}.chip--sm{padding:2px 10px;font-size:.75rem}.chip--lg{padding:6px 16px;font-size:.875rem}.chip--sm.chip--dismissible{padding-right:6px}.chip--lg.chip--dismissible{padding-right:10px}@media(pointer:coarse){.chip{min-height:44px}.chip--sm{min-height:40px;padding:6px 14px}.chip--lg{padding-left:18px;padding-right:18px}.chip--sm.chip--dismissible{padding-right:8px}.chip--lg.chip--dismissible{padding-right:12px}.chip-dismiss{width:24px;height:24px}}.chip--active{background:#3b82f6;border-color:#3b82f6;color:#fff}.chip--active:hover:not(:disabled){background:#2563eb;border-color:#2563eb;color:#fff}.chip-dismiss{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;border-radius:50%;background:#0000001f;flex-shrink:0;transition:background .15s}.chip-dismiss:hover{background:#00000040}.chip--active .chip-dismiss{background:#ffffff4d}.chip--active .chip-dismiss:hover{background:#ffffff80}\n"],
14831
+ styles: [":host{display:contents}.chip{display:inline-flex;align-items:center;gap:5px;border-radius:999px;border:1.5px solid #d1d5db;background:#f9fafb;color:#374151;font-weight:500;font-family:inherit;cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;transition:background .15s,border-color .15s,color .15s}.chip:hover:not(:disabled){border-color:#3b82f6;color:#3b82f6;background:#eff6ff}.chip:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.chip:disabled{opacity:.5;cursor:default}.chip--sm{padding:2px 10px;font-size:.75rem}.chip--lg{padding:6px 16px;font-size:.875rem}.chip--sm.chip--dismissible{padding-right:6px}.chip--lg.chip--dismissible{padding-right:10px}.chip--active{background:#3b82f6;border-color:#3b82f6;color:#fff}.chip--active:hover:not(:disabled){background:#2563eb;border-color:#2563eb;color:#fff}.chip-dismiss{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;border-radius:50%;background:#0000001f;flex-shrink:0;transition:background .15s}.chip-dismiss:hover{background:#00000040}.chip--active .chip-dismiss{background:#ffffff4d}.chip--active .chip-dismiss:hover{background:#ffffff80}@media(pointer:coarse){.chip{min-height:44px}.chip--sm{min-height:40px;padding:6px 14px}.chip--lg{padding-left:18px;padding-right:18px}.chip--sm.chip--dismissible{padding-right:8px}.chip--lg.chip--dismissible{padding-right:12px}.chip-dismiss{width:24px;height:24px;position:relative}.chip-dismiss:after{content:\"\";position:absolute;inset:-10px}}@media(max-width:480px)and (pointer:fine){.chip-dismiss{position:relative}.chip-dismiss:after{content:\"\";position:absolute;inset:-15px}}\n"],
14101
14832
  changeDetection: i0.ChangeDetectionStrategy.OnPush
14102
14833
  });
14103
14834
  }
@@ -14146,7 +14877,7 @@ i0.ɵɵngDeclareClassMetadata({
14146
14877
  }
14147
14878
  </button>
14148
14879
  `,
14149
- styles: [":host{display:contents}.chip{display:inline-flex;align-items:center;gap:5px;border-radius:999px;border:1.5px solid #d1d5db;background:#f9fafb;color:#374151;font-weight:500;font-family:inherit;cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;transition:background .15s,border-color .15s,color .15s}.chip:hover:not(:disabled){border-color:#3b82f6;color:#3b82f6;background:#eff6ff}.chip:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.chip:disabled{opacity:.5;cursor:default}.chip--sm{padding:2px 10px;font-size:.75rem}.chip--lg{padding:6px 16px;font-size:.875rem}.chip--sm.chip--dismissible{padding-right:6px}.chip--lg.chip--dismissible{padding-right:10px}@media(pointer:coarse){.chip{min-height:44px}.chip--sm{min-height:40px;padding:6px 14px}.chip--lg{padding-left:18px;padding-right:18px}.chip--sm.chip--dismissible{padding-right:8px}.chip--lg.chip--dismissible{padding-right:12px}.chip-dismiss{width:24px;height:24px}}.chip--active{background:#3b82f6;border-color:#3b82f6;color:#fff}.chip--active:hover:not(:disabled){background:#2563eb;border-color:#2563eb;color:#fff}.chip-dismiss{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;border-radius:50%;background:#0000001f;flex-shrink:0;transition:background .15s}.chip-dismiss:hover{background:#00000040}.chip--active .chip-dismiss{background:#ffffff4d}.chip--active .chip-dismiss:hover{background:#ffffff80}\n"]
14880
+ styles: [":host{display:contents}.chip{display:inline-flex;align-items:center;gap:5px;border-radius:999px;border:1.5px solid #d1d5db;background:#f9fafb;color:#374151;font-weight:500;font-family:inherit;cursor:pointer;-webkit-user-select:none;user-select:none;white-space:nowrap;transition:background .15s,border-color .15s,color .15s}.chip:hover:not(:disabled){border-color:#3b82f6;color:#3b82f6;background:#eff6ff}.chip:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}.chip:disabled{opacity:.5;cursor:default}.chip--sm{padding:2px 10px;font-size:.75rem}.chip--lg{padding:6px 16px;font-size:.875rem}.chip--sm.chip--dismissible{padding-right:6px}.chip--lg.chip--dismissible{padding-right:10px}.chip--active{background:#3b82f6;border-color:#3b82f6;color:#fff}.chip--active:hover:not(:disabled){background:#2563eb;border-color:#2563eb;color:#fff}.chip-dismiss{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;border-radius:50%;background:#0000001f;flex-shrink:0;transition:background .15s}.chip-dismiss:hover{background:#00000040}.chip--active .chip-dismiss{background:#ffffff4d}.chip--active .chip-dismiss:hover{background:#ffffff80}@media(pointer:coarse){.chip{min-height:44px}.chip--sm{min-height:40px;padding:6px 14px}.chip--lg{padding-left:18px;padding-right:18px}.chip--sm.chip--dismissible{padding-right:8px}.chip--lg.chip--dismissible{padding-right:12px}.chip-dismiss{width:24px;height:24px;position:relative}.chip-dismiss:after{content:\"\";position:absolute;inset:-10px}}@media(max-width:480px)and (pointer:fine){.chip-dismiss{position:relative}.chip-dismiss:after{content:\"\";position:absolute;inset:-15px}}\n"]
14150
14881
  }]
14151
14882
  }],
14152
14883
  propDecorators: {
@@ -14990,6 +15721,8 @@ var SendEmailComponent = class SendEmailComponent {
14990
15721
  this._suggestedSubject = "";
14991
15722
  this.previewHtml = messagePreviewHtml;
14992
15723
  this.docsRemovedNote = "";
15724
+ this.MAX_SUBJECT = 255;
15725
+ this.MAX_BODY = 1e4;
14993
15726
  effect(() => {
14994
15727
  this.contactName();
14995
15728
  this.contactEmail();
@@ -15058,7 +15791,17 @@ var SendEmailComponent = class SendEmailComponent {
15058
15791
  this.documentsInvalid = bad;
15059
15792
  this.notifyValid();
15060
15793
  }
15794
+ get bodyLengthError() {
15795
+ return this.resolvedBody.length > this.MAX_BODY ? `Message is too long (${this.resolvedBody.length.toLocaleString("en-US")} of ${this.MAX_BODY.toLocaleString("en-US")} characters).` : "";
15796
+ }
15797
+ get subjectLengthError() {
15798
+ return this.resolvedSubject.length > this.MAX_SUBJECT ? `Subject is too long (${this.resolvedSubject.length.toLocaleString("en-US")} of ${this.MAX_SUBJECT} characters).` : "";
15799
+ }
15800
+ get sendLengthError() {
15801
+ return this.subjectLengthError || (this.mode === "compose" ? "" : this.bodyLengthError);
15802
+ }
15061
15803
  get canSend() {
15804
+ if (this.bodyLengthError || this.subjectLengthError) return false;
15062
15805
  if (this.ccError || this.documents() && this.documentsInvalid) return false;
15063
15806
  const hasContent = !!this.subject.trim() && !!this.body.trim() && this.unresolvedVars.length === 0 && !hasLeftoverTags(this.resolvedSubject) && !hasLeftoverTags(this.resolvedBody);
15064
15807
  if (this.showSchedule) return hasContent && !!this.scheduledAt && new Date(this.scheduledAt).getTime() > Date.now();
@@ -15286,7 +16029,7 @@ var SendEmailComponent = class SendEmailComponent {
15286
16029
  this.cdr.markForCheck();
15287
16030
  },
15288
16031
  error: (err) => {
15289
- this.toast.error(custom || docs ? getErrorMessage(err, "email", "send") : "Failed to send email");
16032
+ this.toast.error(custom || docs ? getErrorMessage(err, "email", "send") : serverMessage(err) || "Failed to send email");
15290
16033
  this.loading = false;
15291
16034
  this.cdr.markForCheck();
15292
16035
  }
@@ -15477,6 +16220,7 @@ var SendEmailComponent = class SendEmailComponent {
15477
16220
  label="Subject"
15478
16221
  [required]="true"
15479
16222
  placeholder="Email subject..."
16223
+ [maxlength]="MAX_SUBJECT"
15480
16224
  [(ngModel)]="subject"
15481
16225
  (ngModelChange)="notifyValid()" />
15482
16226
  <ui-textarea-input
@@ -15485,7 +16229,7 @@ var SendEmailComponent = class SendEmailComponent {
15485
16229
  placeholder="Write your message..."
15486
16230
  [rows]="8"
15487
16231
  [(ngModel)]="body"
15488
- [error]="composeTagError"
16232
+ [error]="composeTagError || bodyLengthError"
15489
16233
  (ngModelChange)="notifyValid()" />
15490
16234
 
15491
16235
  @if (!hasDocuments && attachmentsAndScheduling()) {
@@ -15598,6 +16342,9 @@ var SendEmailComponent = class SendEmailComponent {
15598
16342
  </div>
15599
16343
  }
15600
16344
 
16345
+ <!-- Why Send is disabled for length, in every mode (compose shows the message error inline on the editor itself). -->
16346
+ <ui-error errorId="sm-length-error" [message]="sendLengthError" />
16347
+
15601
16348
  @if (showReceiptOption() === true) {
15602
16349
  <ui-checkbox
15603
16350
  class="sm-receipt-option"
@@ -15654,6 +16401,12 @@ var SendEmailComponent = class SendEmailComponent {
15654
16401
  selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",
15655
16402
  inputs: ["required"]
15656
16403
  },
16404
+ {
16405
+ kind: "directive",
16406
+ type: i1.MaxLengthValidator,
16407
+ selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]",
16408
+ inputs: ["maxlength"]
16409
+ },
15657
16410
  {
15658
16411
  kind: "directive",
15659
16412
  type: i1.NgModel,
@@ -15696,9 +16449,14 @@ var SendEmailComponent = class SendEmailComponent {
15696
16449
  "ariaLabel",
15697
16450
  "indeterminate",
15698
16451
  "checked",
16452
+ "required",
16453
+ "requiredMessage",
16454
+ "hint",
16455
+ "error",
16456
+ "showErrors",
15699
16457
  "disabled"
15700
16458
  ],
15701
- outputs: ["checkedChange"]
16459
+ outputs: ["checkedChange", "invalidChange"]
15702
16460
  },
15703
16461
  {
15704
16462
  kind: "component",
@@ -15822,6 +16580,12 @@ var SendEmailComponent = class SendEmailComponent {
15822
16580
  "initialDocuments"
15823
16581
  ],
15824
16582
  outputs: ["valueChange", "invalidChange"]
16583
+ },
16584
+ {
16585
+ kind: "component",
16586
+ type: ErrorComponent,
16587
+ selector: "ui-error",
16588
+ inputs: ["message", "errorId"]
15825
16589
  }
15826
16590
  ],
15827
16591
  changeDetection: i0.ChangeDetectionStrategy.OnPush
@@ -15850,7 +16614,8 @@ i0.ɵɵngDeclareClassMetadata({
15850
16614
  TextareaInputComponent,
15851
16615
  DatetimeInputComponent,
15852
16616
  FormSectionComponent,
15853
- DocumentSendOptionsComponent
16617
+ DocumentSendOptionsComponent,
16618
+ ErrorComponent
15854
16619
  ],
15855
16620
  template: `
15856
16621
  <!-- Missing email guard -->
@@ -15900,6 +16665,7 @@ i0.ɵɵngDeclareClassMetadata({
15900
16665
  label="Subject"
15901
16666
  [required]="true"
15902
16667
  placeholder="Email subject..."
16668
+ [maxlength]="MAX_SUBJECT"
15903
16669
  [(ngModel)]="subject"
15904
16670
  (ngModelChange)="notifyValid()" />
15905
16671
  <ui-textarea-input
@@ -15908,7 +16674,7 @@ i0.ɵɵngDeclareClassMetadata({
15908
16674
  placeholder="Write your message..."
15909
16675
  [rows]="8"
15910
16676
  [(ngModel)]="body"
15911
- [error]="composeTagError"
16677
+ [error]="composeTagError || bodyLengthError"
15912
16678
  (ngModelChange)="notifyValid()" />
15913
16679
 
15914
16680
  @if (!hasDocuments && attachmentsAndScheduling()) {
@@ -16021,6 +16787,9 @@ i0.ɵɵngDeclareClassMetadata({
16021
16787
  </div>
16022
16788
  }
16023
16789
 
16790
+ <!-- Why Send is disabled for length, in every mode (compose shows the message error inline on the editor itself). -->
16791
+ <ui-error errorId="sm-length-error" [message]="sendLengthError" />
16792
+
16024
16793
  @if (showReceiptOption() === true) {
16025
16794
  <ui-checkbox
16026
16795
  class="sm-receipt-option"
@@ -16523,7 +17292,7 @@ var SendTextComponent = class SendTextComponent {
16523
17292
  this.cdr.detectChanges();
16524
17293
  },
16525
17294
  error: (err) => {
16526
- this.toast.error(custom || docs ? getErrorMessage(err, "text message", "send") : "Failed to send text message");
17295
+ this.toast.error(custom || docs ? getErrorMessage(err, "text message", "send") : serverMessage(err) || "Failed to send text message");
16527
17296
  this.loading = false;
16528
17297
  this.cdr.detectChanges();
16529
17298
  }
@@ -16899,9 +17668,14 @@ var SendTextComponent = class SendTextComponent {
16899
17668
  "ariaLabel",
16900
17669
  "indeterminate",
16901
17670
  "checked",
17671
+ "required",
17672
+ "requiredMessage",
17673
+ "hint",
17674
+ "error",
17675
+ "showErrors",
16902
17676
  "disabled"
16903
17677
  ],
16904
- outputs: ["checkedChange"]
17678
+ outputs: ["checkedChange", "invalidChange"]
16905
17679
  },
16906
17680
  {
16907
17681
  kind: "component",
@@ -19420,11 +20194,13 @@ i0.ɵɵngDeclareClassMetadata({
19420
20194
  var TimeInputComponent = class TimeInputComponent {
19421
20195
  constructor() {
19422
20196
  this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
20197
+ this.ariaLabel = input("", ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
19423
20198
  this.required = input(false, ...ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []);
19424
20199
  this.min = input("", ...ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []);
19425
20200
  this.max = input("", ...ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []);
19426
20201
  this.hint = input("", ...ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []);
19427
20202
  this.error = input("", ...ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []);
20203
+ this.showErrors = input(false, ...ngDevMode ? [{ debugName: "showErrors" }] : /* istanbul ignore next */ []);
19428
20204
  this._disabledInput = input(false, {
19429
20205
  ...ngDevMode ? { debugName: "_disabledInput" } : /* istanbul ignore next */ {},
19430
20206
  alias: "disabled"
@@ -19433,8 +20209,28 @@ var TimeInputComponent = class TimeInputComponent {
19433
20209
  this.disabled = computed(() => this._disabledInput() || this._cvaDisabled(), ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
19434
20210
  this._value = signal("", ...ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []);
19435
20211
  this._inputId = `tmi-${Math.random().toString(36).slice(2, 8)}`;
20212
+ this._reveal = createFieldReveal(this.showErrors);
20213
+ this._issue = computed(() => this._check(this._value()), ...ngDevMode ? [{ debugName: "_issue" }] : /* istanbul ignore next */ []);
20214
+ this.invalid = computed(() => !!this.error() || !!this._issue(), ...ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []);
20215
+ this.errorMessage = computed(() => this._issue()?.message ?? "", ...ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []);
20216
+ this.invalidChange = output();
20217
+ this._activeError = computed(() => this.error() || (this._reveal.revealed() ? this.errorMessage() : ""), ...ngDevMode ? [{ debugName: "_activeError" }] : /* istanbul ignore next */ []);
20218
+ this._onValidatorChange = () => {};
19436
20219
  this._onChange = (_) => {};
19437
20220
  this._onTouched = () => {};
20221
+ effect(() => {
20222
+ this.invalidChange.emit(this.invalid());
20223
+ });
20224
+ }
20225
+ ngOnChanges() {
20226
+ this._onValidatorChange();
20227
+ }
20228
+ validate(control) {
20229
+ const v = control.value;
20230
+ return issueToErrors(this._check(v == null ? "" : String(v)));
20231
+ }
20232
+ registerOnValidatorChange(fn) {
20233
+ this._onValidatorChange = fn;
19438
20234
  }
19439
20235
  writeValue(val) {
19440
20236
  this._value.set(val ?? "");
@@ -19455,6 +20251,40 @@ var TimeInputComponent = class TimeInputComponent {
19455
20251
  }
19456
20252
  onBlur() {
19457
20253
  this._onTouched();
20254
+ this._reveal.touched.set(true);
20255
+ }
20256
+ _check(value) {
20257
+ if (this.disabled()) return null;
20258
+ const text = value.trim();
20259
+ if (!text) return this.required() ? requiredIssue(this.label() || this.ariaLabel()) : null;
20260
+ const t = parseTime(text);
20261
+ if (t == null) return {
20262
+ key: "time",
20263
+ message: "Please enter a valid time."
20264
+ };
20265
+ let min = this.min() ? parseTime(this.min()) : null;
20266
+ let max = this.max() ? parseTime(this.max()) : null;
20267
+ if (min != null && max != null && max < min) {
20268
+ min = null;
20269
+ max = null;
20270
+ }
20271
+ if (min != null && t < min) return {
20272
+ key: "min",
20273
+ message: `Must be at or after ${formatTime(this.min())}`,
20274
+ value: {
20275
+ min: this.min(),
20276
+ actual: text
20277
+ }
20278
+ };
20279
+ if (max != null && t > max) return {
20280
+ key: "max",
20281
+ message: `Must be at or before ${formatTime(this.max())}`,
20282
+ value: {
20283
+ max: this.max(),
20284
+ actual: text
20285
+ }
20286
+ };
20287
+ return null;
19458
20288
  }
19459
20289
  static {
19460
20290
  this.ɵfac = i0.ɵɵngDeclareFactory({
@@ -19481,6 +20311,13 @@ var TimeInputComponent = class TimeInputComponent {
19481
20311
  isRequired: false,
19482
20312
  transformFunction: null
19483
20313
  },
20314
+ ariaLabel: {
20315
+ classPropertyName: "ariaLabel",
20316
+ publicName: "ariaLabel",
20317
+ isSignal: true,
20318
+ isRequired: false,
20319
+ transformFunction: null
20320
+ },
19484
20321
  required: {
19485
20322
  classPropertyName: "required",
19486
20323
  publicName: "required",
@@ -19516,6 +20353,13 @@ var TimeInputComponent = class TimeInputComponent {
19516
20353
  isRequired: false,
19517
20354
  transformFunction: null
19518
20355
  },
20356
+ showErrors: {
20357
+ classPropertyName: "showErrors",
20358
+ publicName: "showErrors",
20359
+ isSignal: true,
20360
+ isRequired: false,
20361
+ transformFunction: null
20362
+ },
19519
20363
  _disabledInput: {
19520
20364
  classPropertyName: "_disabledInput",
19521
20365
  publicName: "disabled",
@@ -19524,14 +20368,27 @@ var TimeInputComponent = class TimeInputComponent {
19524
20368
  transformFunction: null
19525
20369
  }
19526
20370
  },
19527
- providers: [{
19528
- provide: NG_VALUE_ACCESSOR,
19529
- useExisting: forwardRef(() => TimeInputComponent),
19530
- multi: true
19531
- }],
20371
+ outputs: { invalidChange: "invalidChange" },
20372
+ providers: [
20373
+ {
20374
+ provide: NG_VALUE_ACCESSOR,
20375
+ useExisting: forwardRef(() => TimeInputComponent),
20376
+ multi: true
20377
+ },
20378
+ {
20379
+ provide: NG_VALIDATORS,
20380
+ useExisting: forwardRef(() => TimeInputComponent),
20381
+ multi: true
20382
+ },
20383
+ {
20384
+ provide: UiFieldValidity,
20385
+ useExisting: forwardRef(() => TimeInputComponent)
20386
+ }
20387
+ ],
20388
+ usesOnChanges: true,
19532
20389
  ngImport: i0,
19533
20390
  template: `
19534
- <div class="tmi-field" [class.tmi-error]="error()" [class.tmi-disabled]="disabled()">
20391
+ <div class="tmi-field" [class.tmi-error]="_activeError()" [class.tmi-disabled]="disabled()">
19535
20392
  @if (label()) {
19536
20393
  <label class="tmi-label" [for]="_inputId">
19537
20394
  {{ label() }}
@@ -19547,13 +20404,15 @@ var TimeInputComponent = class TimeInputComponent {
19547
20404
  [attr.min]="min() || null"
19548
20405
  [attr.max]="max() || null"
19549
20406
  [attr.required]="required() || null"
19550
- [attr.aria-invalid]="error() ? 'true' : null"
19551
- [attr.aria-describedby]="(error() || hint()) ? _inputId + '-desc' : null"
20407
+ [attr.aria-label]="ariaLabel() || label() || null"
20408
+ [attr.aria-required]="required() ? 'true' : null"
20409
+ [attr.aria-invalid]="_activeError() ? 'true' : null"
20410
+ [attr.aria-describedby]="(_activeError() || hint()) ? _inputId + '-desc' : null"
19552
20411
  (change)="onChange($event)"
19553
20412
  (blur)="onBlur()"
19554
20413
  />
19555
- @if (error()) {
19556
- <p class="tmi-desc tmi-desc-error" [id]="_inputId + '-desc'" role="alert">{{ error() }}</p>
20414
+ @if (_activeError()) {
20415
+ <p class="tmi-desc tmi-desc-error" [id]="_inputId + '-desc'" role="alert">{{ _activeError() }}</p>
19557
20416
  } @else if (hint()) {
19558
20417
  <p class="tmi-desc" [id]="_inputId + '-desc'">{{ hint() }}</p>
19559
20418
  }
@@ -19576,14 +20435,25 @@ i0.ɵɵngDeclareClassMetadata({
19576
20435
  selector: "ui-time-input",
19577
20436
  standalone: true,
19578
20437
  changeDetection: ChangeDetectionStrategy.OnPush,
19579
- providers: [{
19580
- provide: NG_VALUE_ACCESSOR,
19581
- useExisting: forwardRef(() => TimeInputComponent),
19582
- multi: true
19583
- }],
19584
- template: `
19585
- <div class="tmi-field" [class.tmi-error]="error()" [class.tmi-disabled]="disabled()">
19586
- @if (label()) {
20438
+ providers: [
20439
+ {
20440
+ provide: NG_VALUE_ACCESSOR,
20441
+ useExisting: forwardRef(() => TimeInputComponent),
20442
+ multi: true
20443
+ },
20444
+ {
20445
+ provide: NG_VALIDATORS,
20446
+ useExisting: forwardRef(() => TimeInputComponent),
20447
+ multi: true
20448
+ },
20449
+ {
20450
+ provide: UiFieldValidity,
20451
+ useExisting: forwardRef(() => TimeInputComponent)
20452
+ }
20453
+ ],
20454
+ template: `
20455
+ <div class="tmi-field" [class.tmi-error]="_activeError()" [class.tmi-disabled]="disabled()">
20456
+ @if (label()) {
19587
20457
  <label class="tmi-label" [for]="_inputId">
19588
20458
  {{ label() }}
19589
20459
  @if (required()) { <span class="tmi-required" aria-hidden="true">*</span> }
@@ -19598,13 +20468,15 @@ i0.ɵɵngDeclareClassMetadata({
19598
20468
  [attr.min]="min() || null"
19599
20469
  [attr.max]="max() || null"
19600
20470
  [attr.required]="required() || null"
19601
- [attr.aria-invalid]="error() ? 'true' : null"
19602
- [attr.aria-describedby]="(error() || hint()) ? _inputId + '-desc' : null"
20471
+ [attr.aria-label]="ariaLabel() || label() || null"
20472
+ [attr.aria-required]="required() ? 'true' : null"
20473
+ [attr.aria-invalid]="_activeError() ? 'true' : null"
20474
+ [attr.aria-describedby]="(_activeError() || hint()) ? _inputId + '-desc' : null"
19603
20475
  (change)="onChange($event)"
19604
20476
  (blur)="onBlur()"
19605
20477
  />
19606
- @if (error()) {
19607
- <p class="tmi-desc tmi-desc-error" [id]="_inputId + '-desc'" role="alert">{{ error() }}</p>
20478
+ @if (_activeError()) {
20479
+ <p class="tmi-desc tmi-desc-error" [id]="_inputId + '-desc'" role="alert">{{ _activeError() }}</p>
19608
20480
  } @else if (hint()) {
19609
20481
  <p class="tmi-desc" [id]="_inputId + '-desc'">{{ hint() }}</p>
19610
20482
  }
@@ -19613,6 +20485,7 @@ i0.ɵɵngDeclareClassMetadata({
19613
20485
  styles: [":host{display:block}.tmi-field{display:flex;flex-direction:column;gap:6px}.tmi-label{font-size:.8125rem;font-weight:600;color:#374151;line-height:1}.tmi-required{color:#ef4444;margin-left:2px}.tmi-input{width:100%;box-sizing:border-box;padding:8px 12px;font-size:.875rem;font-family:inherit;color:#1e293b;background:#fff;border:1px solid #e2e8f0;border-radius:8px;outline:none;transition:border-color .15s,box-shadow .15s;appearance:none}.tmi-input:focus{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61f}.tmi-error .tmi-input{border-color:#ef4444}.tmi-error .tmi-input:focus{box-shadow:0 0 0 3px #ef44441f}.tmi-disabled .tmi-input{opacity:.5;cursor:not-allowed}.tmi-desc{margin:0;font-size:.75rem;line-height:1.4;color:#64748b}.tmi-desc-error{color:#ef4444}@media(max-width:480px){.tmi-input{font-size:1rem}}@media(pointer:coarse),(max-width:480px){.tmi-input{min-height:44px}}\n"]
19614
20486
  }]
19615
20487
  }],
20488
+ ctorParameters: () => [],
19616
20489
  propDecorators: {
19617
20490
  label: [{
19618
20491
  type: i0.Input,
@@ -19622,6 +20495,14 @@ i0.ɵɵngDeclareClassMetadata({
19622
20495
  required: false
19623
20496
  }]
19624
20497
  }],
20498
+ ariaLabel: [{
20499
+ type: i0.Input,
20500
+ args: [{
20501
+ isSignal: true,
20502
+ alias: "ariaLabel",
20503
+ required: false
20504
+ }]
20505
+ }],
19625
20506
  required: [{
19626
20507
  type: i0.Input,
19627
20508
  args: [{
@@ -19662,6 +20543,14 @@ i0.ɵɵngDeclareClassMetadata({
19662
20543
  required: false
19663
20544
  }]
19664
20545
  }],
20546
+ showErrors: [{
20547
+ type: i0.Input,
20548
+ args: [{
20549
+ isSignal: true,
20550
+ alias: "showErrors",
20551
+ required: false
20552
+ }]
20553
+ }],
19665
20554
  _disabledInput: [{
19666
20555
  type: i0.Input,
19667
20556
  args: [{
@@ -19669,6 +20558,10 @@ i0.ɵɵngDeclareClassMetadata({
19669
20558
  alias: "disabled",
19670
20559
  required: false
19671
20560
  }]
20561
+ }],
20562
+ invalidChange: [{
20563
+ type: i0.Output,
20564
+ args: ["invalidChange"]
19672
20565
  }]
19673
20566
  }
19674
20567
  });
@@ -19924,9 +20817,14 @@ var MultiSelectComponent = class MultiSelectComponent {
19924
20817
  "ariaLabel",
19925
20818
  "indeterminate",
19926
20819
  "checked",
20820
+ "required",
20821
+ "requiredMessage",
20822
+ "hint",
20823
+ "error",
20824
+ "showErrors",
19927
20825
  "disabled"
19928
20826
  ],
19929
- outputs: ["checkedChange"]
20827
+ outputs: ["checkedChange", "invalidChange"]
19930
20828
  }],
19931
20829
  changeDetection: i0.ChangeDetectionStrategy.OnPush
19932
20830
  });
@@ -20235,9 +21133,14 @@ var DiscountSelectorComponent = class DiscountSelectorComponent {
20235
21133
  "ariaLabel",
20236
21134
  "indeterminate",
20237
21135
  "checked",
21136
+ "required",
21137
+ "requiredMessage",
21138
+ "hint",
21139
+ "error",
21140
+ "showErrors",
20238
21141
  "disabled"
20239
21142
  ],
20240
- outputs: ["checkedChange"]
21143
+ outputs: ["checkedChange", "invalidChange"]
20241
21144
  }],
20242
21145
  changeDetection: i0.ChangeDetectionStrategy.OnPush
20243
21146
  });
@@ -23292,9 +24195,12 @@ var ImagePreviewComponent = class ImagePreviewComponent {
23292
24195
  this.size = input("md", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
23293
24196
  this.placeholder = input("image", ...ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []);
23294
24197
  this.loading = input("lazy", ...ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []);
24198
+ this.positionX = input(50, ...ngDevMode ? [{ debugName: "positionX" }] : /* istanbul ignore next */ []);
24199
+ this.positionY = input(50, ...ngDevMode ? [{ debugName: "positionY" }] : /* istanbul ignore next */ []);
23295
24200
  this.retryKey = input(null, ...ngDevMode ? [{ debugName: "retryKey" }] : /* istanbul ignore next */ []);
23296
24201
  this._failed = signal(false, ...ngDevMode ? [{ debugName: "_failed" }] : /* istanbul ignore next */ []);
23297
24202
  this._url = computed(() => this.src()?.trim() || null, ...ngDevMode ? [{ debugName: "_url" }] : /* istanbul ignore next */ []);
24203
+ this._objectPosition = computed(() => `${this.positionX() ?? 50}% ${this.positionY() ?? 50}%`, ...ngDevMode ? [{ debugName: "_objectPosition" }] : /* istanbul ignore next */ []);
23298
24204
  this._cls = computed(() => `ip-${this.shape()}-${this.size()}`, ...ngDevMode ? [{ debugName: "_cls" }] : /* istanbul ignore next */ []);
23299
24205
  effect(() => {
23300
24206
  this.src();
@@ -23368,6 +24274,20 @@ var ImagePreviewComponent = class ImagePreviewComponent {
23368
24274
  isRequired: false,
23369
24275
  transformFunction: null
23370
24276
  },
24277
+ positionX: {
24278
+ classPropertyName: "positionX",
24279
+ publicName: "positionX",
24280
+ isSignal: true,
24281
+ isRequired: false,
24282
+ transformFunction: null
24283
+ },
24284
+ positionY: {
24285
+ classPropertyName: "positionY",
24286
+ publicName: "positionY",
24287
+ isSignal: true,
24288
+ isRequired: false,
24289
+ transformFunction: null
24290
+ },
23371
24291
  retryKey: {
23372
24292
  classPropertyName: "retryKey",
23373
24293
  publicName: "retryKey",
@@ -23379,7 +24299,7 @@ var ImagePreviewComponent = class ImagePreviewComponent {
23379
24299
  ngImport: i0,
23380
24300
  template: `
23381
24301
  @if (_url() && !_failed()) {
23382
- <img class="ip-img" [class]="_cls()" [src]="_url()" [attr.alt]="alt()" [attr.loading]="loading()" decoding="async" (error)="_onError()" />
24302
+ <img class="ip-img" [class]="_cls()" [src]="_url()" [attr.alt]="alt()" [attr.loading]="loading()" [style.object-position]="_objectPosition()" decoding="async" (error)="_onError()" />
23383
24303
  } @else {
23384
24304
  <span class="ip-img ip-ph" [class]="_cls()" aria-hidden="true">
23385
24305
  @if (placeholder() === 'person') {
@@ -23409,7 +24329,7 @@ i0.ɵɵngDeclareClassMetadata({
23409
24329
  changeDetection: ChangeDetectionStrategy.OnPush,
23410
24330
  template: `
23411
24331
  @if (_url() && !_failed()) {
23412
- <img class="ip-img" [class]="_cls()" [src]="_url()" [attr.alt]="alt()" [attr.loading]="loading()" decoding="async" (error)="_onError()" />
24332
+ <img class="ip-img" [class]="_cls()" [src]="_url()" [attr.alt]="alt()" [attr.loading]="loading()" [style.object-position]="_objectPosition()" decoding="async" (error)="_onError()" />
23413
24333
  } @else {
23414
24334
  <span class="ip-img ip-ph" [class]="_cls()" aria-hidden="true">
23415
24335
  @if (placeholder() === 'person') {
@@ -23473,6 +24393,22 @@ i0.ɵɵngDeclareClassMetadata({
23473
24393
  required: false
23474
24394
  }]
23475
24395
  }],
24396
+ positionX: [{
24397
+ type: i0.Input,
24398
+ args: [{
24399
+ isSignal: true,
24400
+ alias: "positionX",
24401
+ required: false
24402
+ }]
24403
+ }],
24404
+ positionY: [{
24405
+ type: i0.Input,
24406
+ args: [{
24407
+ isSignal: true,
24408
+ alias: "positionY",
24409
+ required: false
24410
+ }]
24411
+ }],
23476
24412
  retryKey: [{
23477
24413
  type: i0.Input,
23478
24414
  args: [{
@@ -25099,7 +26035,7 @@ var RichTextEditorComponent = class RichTextEditorComponent {
25099
26035
  </div>
25100
26036
  `,
25101
26037
  isInline: true,
25102
- styles: [":host{display:block}.rte-field{display:flex;flex-direction:column;gap:6px}.rte-label{font-size:.8125rem;font-weight:600;color:#374151;line-height:1}.rte-required{color:#ef4444;margin-left:2px}.rte-hint-inline{font-size:.75rem;color:#94a3b8;font-weight:400;margin-left:4px}.rte-box{border:1px solid #e2e8f0;border-radius:8px;background:#fff;transition:border-color .15s,box-shadow .15s}.rte-box:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61f}.rte-error .rte-box{border-color:#ef4444}.rte-error .rte-box:focus-within{box-shadow:0 0 0 3px #ef44441f}.rte-disabled .rte-box{opacity:.5;cursor:not-allowed}.rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:2px;padding:6px 8px;background:#f8fafc;border-bottom:1px solid #e2e8f0;border-radius:8px 8px 0 0}.rte-divider{width:1px;height:20px;background:#cbd5e1;margin:0 4px}.rte-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:4px;background:none;color:#64748b;cursor:pointer;transition:background .15s,color .15s}.rte-btn svg{width:16px;height:16px}.rte-btn:hover:not(:disabled){background:#e2e8f0;color:#1e293b}.rte-btn:focus-visible,.rte-btn:focus-within{outline:2px solid #3b82f6;outline-offset:1px}.rte-btn.active{background:#dbeafe;color:#2563eb}.rte-btn:disabled,.rte-btn-disabled{cursor:not-allowed;opacity:.5}.rte-menu-wrap{position:relative;display:inline-flex}.rte-menu-btn{width:auto;padding:0 6px;gap:3px}.rte-menu-btn .rte-chevron{width:10px;height:10px;color:#94a3b8;flex-shrink:0}.rte-dropdown{position:absolute;top:calc(100% + 4px);left:0;z-index:100;background:#fff;border:1px solid #e2e8f0;border-radius:6px;box-shadow:0 4px 12px #0000001f;padding:4px;overflow-y:auto;max-height:260px}.rte-font-panel{min-width:180px}.rte-item{display:block;width:100%;text-align:left;padding:5px 10px;font-size:12px;color:#374151;border:none;background:none;border-radius:4px;cursor:pointer;white-space:nowrap}.rte-item:hover{background:#f1f5f9}.rte-item.selected{background:#dbeafe;color:#2563eb;font-weight:600}.rte-group-label{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:#94a3b8;padding:6px 10px 2px}.di-h1{font-size:18px;font-weight:700}.di-h2{font-size:15px;font-weight:600}.di-h3{font-size:13px;font-weight:600}.rte-color{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}.rte-editor{padding:12px;outline:none;overflow-y:auto;box-sizing:border-box;font-size:.875rem;line-height:1.6;color:#1e293b;background:#fff;border-radius:0 0 8px 8px;word-break:break-word}.rte-editor[data-empty=true]:before{content:attr(data-placeholder);color:#94a3b8;pointer-events:none;float:left;height:0}.rte-editor ul,.rte-editor ol{padding-left:1.5em;margin:.25em 0}.rte-editor li{margin:.15em 0}.rte-editor h1{font-size:1.75em;font-weight:700;margin:.5em 0 .25em}.rte-editor h2{font-size:1.4em;font-weight:600;margin:.5em 0 .25em}.rte-editor h3{font-size:1.15em;font-weight:600;margin:.5em 0 .25em}.rte-editor a{color:#2563eb;text-decoration:underline}.rte-desc{margin:0;font-size:.75rem;line-height:1.4;color:#64748b}.rte-desc-error{color:#ef4444}@media(max-width:480px){.rte-editor{font-size:1rem}}\n"],
26038
+ styles: [":host{display:block}.rte-field{display:flex;flex-direction:column;gap:6px}.rte-label{font-size:.8125rem;font-weight:600;color:#374151;line-height:1}.rte-required{color:#ef4444;margin-left:2px}.rte-hint-inline{font-size:.75rem;color:#94a3b8;font-weight:400;margin-left:4px}.rte-box{border:1px solid #e2e8f0;border-radius:8px;background:#fff;transition:border-color .15s,box-shadow .15s}.rte-box:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61f}.rte-error .rte-box{border-color:#ef4444}.rte-error .rte-box:focus-within{box-shadow:0 0 0 3px #ef44441f}.rte-disabled .rte-box{opacity:.5;cursor:not-allowed}.rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:2px;padding:6px 8px;background:#f8fafc;border-bottom:1px solid #e2e8f0;border-radius:8px 8px 0 0}.rte-divider{width:1px;height:20px;background:#cbd5e1;margin:0 4px}.rte-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:4px;background:none;color:#64748b;cursor:pointer;transition:background .15s,color .15s}.rte-btn svg{width:16px;height:16px}.rte-btn:hover:not(:disabled){background:#e2e8f0;color:#1e293b}.rte-btn:focus-visible,.rte-btn:focus-within{outline:2px solid #3b82f6;outline-offset:1px}.rte-btn.active{background:#dbeafe;color:#2563eb}.rte-btn:disabled,.rte-btn-disabled{cursor:not-allowed;opacity:.5}.rte-menu-wrap{position:relative;display:inline-flex}.rte-menu-btn{width:auto;padding:0 6px;gap:3px}.rte-menu-btn .rte-chevron{width:10px;height:10px;color:#94a3b8;flex-shrink:0}.rte-dropdown{position:absolute;top:calc(100% + 4px);left:0;z-index:100;background:#fff;border:1px solid #e2e8f0;border-radius:6px;box-shadow:0 4px 12px #0000001f;padding:4px;overflow-y:auto;max-height:260px}.rte-font-panel{min-width:180px}.rte-item{display:block;width:100%;text-align:left;padding:5px 10px;font-size:12px;color:#374151;border:none;background:none;border-radius:4px;cursor:pointer;white-space:nowrap}.rte-item:hover{background:#f1f5f9}.rte-item.selected{background:#dbeafe;color:#2563eb;font-weight:600}.rte-group-label{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:#94a3b8;padding:6px 10px 2px}.di-h1{font-size:18px;font-weight:700}.di-h2{font-size:15px;font-weight:600}.di-h3{font-size:13px;font-weight:600}.rte-color{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}.rte-editor{padding:12px;outline:none;overflow-y:auto;box-sizing:border-box;font-size:.875rem;line-height:1.6;color:#1e293b;background:#fff;border-radius:0 0 8px 8px;word-break:break-word}.rte-editor[data-empty=true]:before{content:attr(data-placeholder);color:#94a3b8;pointer-events:none;float:left;height:0}.rte-editor ul,.rte-editor ol{padding-left:1.5em;margin:.25em 0}.rte-editor li{margin:.15em 0}.rte-editor h1{font-size:1.75em;font-weight:700;margin:.5em 0 .25em}.rte-editor h2{font-size:1.4em;font-weight:600;margin:.5em 0 .25em}.rte-editor h3{font-size:1.15em;font-weight:600;margin:.5em 0 .25em}.rte-editor a{color:#2563eb;text-decoration:underline}.rte-desc{margin:0;font-size:.75rem;line-height:1.4;color:#64748b}.rte-desc-error{color:#ef4444}@media(max-width:480px){.rte-editor{font-size:1rem}}@media(pointer:coarse),(max-width:480px){.rte-btn{width:44px;height:44px}.rte-menu-btn{width:auto;min-width:44px}.rte-divider{height:28px}}\n"],
25103
26039
  changeDetection: i0.ChangeDetectionStrategy.OnPush
25104
26040
  });
25105
26041
  }
@@ -25336,7 +26272,7 @@ i0.ɵɵngDeclareClassMetadata({
25336
26272
  }
25337
26273
  </div>
25338
26274
  `,
25339
- styles: [":host{display:block}.rte-field{display:flex;flex-direction:column;gap:6px}.rte-label{font-size:.8125rem;font-weight:600;color:#374151;line-height:1}.rte-required{color:#ef4444;margin-left:2px}.rte-hint-inline{font-size:.75rem;color:#94a3b8;font-weight:400;margin-left:4px}.rte-box{border:1px solid #e2e8f0;border-radius:8px;background:#fff;transition:border-color .15s,box-shadow .15s}.rte-box:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61f}.rte-error .rte-box{border-color:#ef4444}.rte-error .rte-box:focus-within{box-shadow:0 0 0 3px #ef44441f}.rte-disabled .rte-box{opacity:.5;cursor:not-allowed}.rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:2px;padding:6px 8px;background:#f8fafc;border-bottom:1px solid #e2e8f0;border-radius:8px 8px 0 0}.rte-divider{width:1px;height:20px;background:#cbd5e1;margin:0 4px}.rte-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:4px;background:none;color:#64748b;cursor:pointer;transition:background .15s,color .15s}.rte-btn svg{width:16px;height:16px}.rte-btn:hover:not(:disabled){background:#e2e8f0;color:#1e293b}.rte-btn:focus-visible,.rte-btn:focus-within{outline:2px solid #3b82f6;outline-offset:1px}.rte-btn.active{background:#dbeafe;color:#2563eb}.rte-btn:disabled,.rte-btn-disabled{cursor:not-allowed;opacity:.5}.rte-menu-wrap{position:relative;display:inline-flex}.rte-menu-btn{width:auto;padding:0 6px;gap:3px}.rte-menu-btn .rte-chevron{width:10px;height:10px;color:#94a3b8;flex-shrink:0}.rte-dropdown{position:absolute;top:calc(100% + 4px);left:0;z-index:100;background:#fff;border:1px solid #e2e8f0;border-radius:6px;box-shadow:0 4px 12px #0000001f;padding:4px;overflow-y:auto;max-height:260px}.rte-font-panel{min-width:180px}.rte-item{display:block;width:100%;text-align:left;padding:5px 10px;font-size:12px;color:#374151;border:none;background:none;border-radius:4px;cursor:pointer;white-space:nowrap}.rte-item:hover{background:#f1f5f9}.rte-item.selected{background:#dbeafe;color:#2563eb;font-weight:600}.rte-group-label{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:#94a3b8;padding:6px 10px 2px}.di-h1{font-size:18px;font-weight:700}.di-h2{font-size:15px;font-weight:600}.di-h3{font-size:13px;font-weight:600}.rte-color{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}.rte-editor{padding:12px;outline:none;overflow-y:auto;box-sizing:border-box;font-size:.875rem;line-height:1.6;color:#1e293b;background:#fff;border-radius:0 0 8px 8px;word-break:break-word}.rte-editor[data-empty=true]:before{content:attr(data-placeholder);color:#94a3b8;pointer-events:none;float:left;height:0}.rte-editor ul,.rte-editor ol{padding-left:1.5em;margin:.25em 0}.rte-editor li{margin:.15em 0}.rte-editor h1{font-size:1.75em;font-weight:700;margin:.5em 0 .25em}.rte-editor h2{font-size:1.4em;font-weight:600;margin:.5em 0 .25em}.rte-editor h3{font-size:1.15em;font-weight:600;margin:.5em 0 .25em}.rte-editor a{color:#2563eb;text-decoration:underline}.rte-desc{margin:0;font-size:.75rem;line-height:1.4;color:#64748b}.rte-desc-error{color:#ef4444}@media(max-width:480px){.rte-editor{font-size:1rem}}\n"]
26275
+ styles: [":host{display:block}.rte-field{display:flex;flex-direction:column;gap:6px}.rte-label{font-size:.8125rem;font-weight:600;color:#374151;line-height:1}.rte-required{color:#ef4444;margin-left:2px}.rte-hint-inline{font-size:.75rem;color:#94a3b8;font-weight:400;margin-left:4px}.rte-box{border:1px solid #e2e8f0;border-radius:8px;background:#fff;transition:border-color .15s,box-shadow .15s}.rte-box:focus-within{border-color:#3b82f6;box-shadow:0 0 0 3px #3b82f61f}.rte-error .rte-box{border-color:#ef4444}.rte-error .rte-box:focus-within{box-shadow:0 0 0 3px #ef44441f}.rte-disabled .rte-box{opacity:.5;cursor:not-allowed}.rte-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:2px;padding:6px 8px;background:#f8fafc;border-bottom:1px solid #e2e8f0;border-radius:8px 8px 0 0}.rte-divider{width:1px;height:20px;background:#cbd5e1;margin:0 4px}.rte-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:4px;background:none;color:#64748b;cursor:pointer;transition:background .15s,color .15s}.rte-btn svg{width:16px;height:16px}.rte-btn:hover:not(:disabled){background:#e2e8f0;color:#1e293b}.rte-btn:focus-visible,.rte-btn:focus-within{outline:2px solid #3b82f6;outline-offset:1px}.rte-btn.active{background:#dbeafe;color:#2563eb}.rte-btn:disabled,.rte-btn-disabled{cursor:not-allowed;opacity:.5}.rte-menu-wrap{position:relative;display:inline-flex}.rte-menu-btn{width:auto;padding:0 6px;gap:3px}.rte-menu-btn .rte-chevron{width:10px;height:10px;color:#94a3b8;flex-shrink:0}.rte-dropdown{position:absolute;top:calc(100% + 4px);left:0;z-index:100;background:#fff;border:1px solid #e2e8f0;border-radius:6px;box-shadow:0 4px 12px #0000001f;padding:4px;overflow-y:auto;max-height:260px}.rte-font-panel{min-width:180px}.rte-item{display:block;width:100%;text-align:left;padding:5px 10px;font-size:12px;color:#374151;border:none;background:none;border-radius:4px;cursor:pointer;white-space:nowrap}.rte-item:hover{background:#f1f5f9}.rte-item.selected{background:#dbeafe;color:#2563eb;font-weight:600}.rte-group-label{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:#94a3b8;padding:6px 10px 2px}.di-h1{font-size:18px;font-weight:700}.di-h2{font-size:15px;font-weight:600}.di-h3{font-size:13px;font-weight:600}.rte-color{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}.rte-editor{padding:12px;outline:none;overflow-y:auto;box-sizing:border-box;font-size:.875rem;line-height:1.6;color:#1e293b;background:#fff;border-radius:0 0 8px 8px;word-break:break-word}.rte-editor[data-empty=true]:before{content:attr(data-placeholder);color:#94a3b8;pointer-events:none;float:left;height:0}.rte-editor ul,.rte-editor ol{padding-left:1.5em;margin:.25em 0}.rte-editor li{margin:.15em 0}.rte-editor h1{font-size:1.75em;font-weight:700;margin:.5em 0 .25em}.rte-editor h2{font-size:1.4em;font-weight:600;margin:.5em 0 .25em}.rte-editor h3{font-size:1.15em;font-weight:600;margin:.5em 0 .25em}.rte-editor a{color:#2563eb;text-decoration:underline}.rte-desc{margin:0;font-size:.75rem;line-height:1.4;color:#64748b}.rte-desc-error{color:#ef4444}@media(max-width:480px){.rte-editor{font-size:1rem}}@media(pointer:coarse),(max-width:480px){.rte-btn{width:44px;height:44px}.rte-menu-btn{width:auto;min-width:44px}.rte-divider{height:28px}}\n"]
25340
26276
  }]
25341
26277
  }],
25342
26278
  ctorParameters: () => [],
@@ -25435,6 +26371,1085 @@ i0.ɵɵngDeclareClassMetadata({
25435
26371
  }]
25436
26372
  }
25437
26373
  });
25438
- export { AlertComponent, AppShellComponent, AvatarComponent, BADGE_VARIANT_STYLES, BadgeComponent, BulkMessagePanelComponent, ButtonComponent, CheckboxComponent, ChipComponent, ChipGroupComponent, ColumnFilterComponent, ComboboxComponent, ConfirmOutletComponent, ConfirmService, ContactPickerComponent, DEFAULT_DOCUMENT_SUBJECT, DOCUMENT_PURPOSE_OPTIONS, DROPDOWN_GROUP, DataTableComponent, DateInputComponent, DateRangePickerComponent, DatetimeInputComponent, DiscountSelectorComponent, DocumentSendOptionsComponent, DropdownComponent, EmptyStateComponent, ErrorComponent, ErrorStateComponent, FORGEROUTE_CONFIG, FileInputComponent, FormRowComponent, FormSectionComponent, HintComponent, ImagePreviewComponent, ImportExportComponent, KpiCardComponent, ListItemComponent, MAX_CC, ModalComponent, MoreMenuComponent, MultiSelectComponent, PaginationComponent, PanelInfoListComponent, PillTabsComponent, ProgressBarComponent, QrCodeComponent, QuickFilterTabsComponent, RICH_TEXT_OPTIONS, RichTextEditorComponent, SEMANTIC_BADGE_MAP, SearchInputComponent, SelectComponent, SendMessagePanelComponent, SidePanelComponent, SkeletonComponent, TableToolbarComponent, TemplatePickerComponent, TextInputComponent, TextareaInputComponent, TimeInputComponent, ToastComponent, ToastService, ToggleBadgeComponent, US_STATES, UiFieldValidity, VideoPickerComponent, appShellGroupsStorageKey, autoVariant, builtInActionIcon, createFieldReveal, errorContextInterceptor, formatIsoDate, formatIsoDateTime, getEligibleIds, getEligibleOptions, getErrorMessage, humanReadableMessage, isoKey, issueToErrors, maxLengthIssue, messagePreviewHtml, parseCcList, parseIso, pluralize, requiredIssue, resolvePreset, suggestDocumentSubject };
26374
+ var RadioComponent = class RadioComponent {
26375
+ constructor() {
26376
+ this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
26377
+ this.description = input("", ...ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []);
26378
+ this.ariaLabel = input("", ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
26379
+ this.value = input("", ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
26380
+ this.name = input("", ...ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []);
26381
+ this.checked = input(false, ...ngDevMode ? [{ debugName: "checked" }] : /* istanbul ignore next */ []);
26382
+ this.invalid = input(false, ...ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []);
26383
+ this.describedBy = input("", ...ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []);
26384
+ this._disabledInput = input(false, {
26385
+ ...ngDevMode ? { debugName: "_disabledInput" } : /* istanbul ignore next */ {},
26386
+ alias: "disabled"
26387
+ });
26388
+ this.disabled = this._disabledInput;
26389
+ this._labelId = `rd-${Math.random().toString(36).slice(2, 8)}-label`;
26390
+ this._labelledBy = computed(() => this.label() && this.description() && !this.ariaLabel() ? this._labelId : null, ...ngDevMode ? [{ debugName: "_labelledBy" }] : /* istanbul ignore next */ []);
26391
+ this._descriptionId = `rd-${Math.random().toString(36).slice(2, 8)}-desc`;
26392
+ this._describedByIds = computed(() => {
26393
+ return [this.describedBy(), this.description() ? this._descriptionId : ""].filter(Boolean).join(" ") || null;
26394
+ }, ...ngDevMode ? [{ debugName: "_describedByIds" }] : /* istanbul ignore next */ []);
26395
+ this.selected = output();
26396
+ }
26397
+ onChange(event) {
26398
+ if (event.target.checked) this.selected.emit(this.value());
26399
+ }
26400
+ static {
26401
+ this.ɵfac = i0.ɵɵngDeclareFactory({
26402
+ minVersion: "12.0.0",
26403
+ version: "22.2.2",
26404
+ ngImport: i0,
26405
+ type: RadioComponent,
26406
+ deps: [],
26407
+ target: i0.ɵɵFactoryTarget.Component
26408
+ });
26409
+ }
26410
+ static {
26411
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
26412
+ minVersion: "17.0.0",
26413
+ version: "22.2.2",
26414
+ type: RadioComponent,
26415
+ isStandalone: true,
26416
+ selector: "ui-radio",
26417
+ inputs: {
26418
+ label: {
26419
+ classPropertyName: "label",
26420
+ publicName: "label",
26421
+ isSignal: true,
26422
+ isRequired: false,
26423
+ transformFunction: null
26424
+ },
26425
+ description: {
26426
+ classPropertyName: "description",
26427
+ publicName: "description",
26428
+ isSignal: true,
26429
+ isRequired: false,
26430
+ transformFunction: null
26431
+ },
26432
+ ariaLabel: {
26433
+ classPropertyName: "ariaLabel",
26434
+ publicName: "ariaLabel",
26435
+ isSignal: true,
26436
+ isRequired: false,
26437
+ transformFunction: null
26438
+ },
26439
+ value: {
26440
+ classPropertyName: "value",
26441
+ publicName: "value",
26442
+ isSignal: true,
26443
+ isRequired: false,
26444
+ transformFunction: null
26445
+ },
26446
+ name: {
26447
+ classPropertyName: "name",
26448
+ publicName: "name",
26449
+ isSignal: true,
26450
+ isRequired: false,
26451
+ transformFunction: null
26452
+ },
26453
+ checked: {
26454
+ classPropertyName: "checked",
26455
+ publicName: "checked",
26456
+ isSignal: true,
26457
+ isRequired: false,
26458
+ transformFunction: null
26459
+ },
26460
+ invalid: {
26461
+ classPropertyName: "invalid",
26462
+ publicName: "invalid",
26463
+ isSignal: true,
26464
+ isRequired: false,
26465
+ transformFunction: null
26466
+ },
26467
+ describedBy: {
26468
+ classPropertyName: "describedBy",
26469
+ publicName: "describedBy",
26470
+ isSignal: true,
26471
+ isRequired: false,
26472
+ transformFunction: null
26473
+ },
26474
+ _disabledInput: {
26475
+ classPropertyName: "_disabledInput",
26476
+ publicName: "disabled",
26477
+ isSignal: true,
26478
+ isRequired: false,
26479
+ transformFunction: null
26480
+ }
26481
+ },
26482
+ outputs: { selected: "selected" },
26483
+ ngImport: i0,
26484
+ template: `
26485
+ <label class="rd-wrap" [class.rd-disabled]="disabled()">
26486
+ <span class="rd-dot" [class.rd-checked]="checked()" [class.rd-invalid]="invalid()" [class.rd-disabled]="disabled()">
26487
+ @if (checked()) { <span class="rd-core"></span> }
26488
+ </span>
26489
+ <input
26490
+ type="radio"
26491
+ class="rd-hidden"
26492
+ [name]="name()"
26493
+ [value]="value()"
26494
+ [checked]="checked()"
26495
+ [disabled]="disabled()"
26496
+ [attr.aria-label]="ariaLabel() || null"
26497
+ [attr.aria-labelledby]="_labelledBy()"
26498
+ [attr.aria-invalid]="invalid() ? 'true' : null"
26499
+ [attr.aria-describedby]="_describedByIds()"
26500
+ (change)="onChange($event)"
26501
+ />
26502
+ <span class="rd-text">
26503
+ @if (label()) { <span class="rd-label" [id]="_labelId">{{ label() }}</span> }
26504
+ @if (description()) { <span class="rd-description" [id]="_descriptionId">{{ description() }}</span> }
26505
+ <ng-content />
26506
+ </span>
26507
+ </label>
26508
+ `,
26509
+ isInline: true,
26510
+ styles: [":host{display:block}.rd-wrap{display:inline-flex;align-items:flex-start;gap:9px;cursor:pointer;-webkit-user-select:none;user-select:none}.rd-wrap.rd-disabled{cursor:not-allowed;opacity:.5}.rd-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.rd-wrap:has(.rd-hidden:focus-visible) .rd-dot{outline:2px solid #3b82f6;outline-offset:2px}@media(pointer:coarse),(max-width:480px){.rd-wrap{position:relative}.rd-hidden{width:44px;height:44px;margin:0;clip:auto;overflow:visible;left:-12px;top:-2px;opacity:0;cursor:pointer;z-index:1}.rd-wrap.rd-disabled .rd-hidden{cursor:not-allowed}}.rd-dot{flex-shrink:0;width:20px;height:20px;box-sizing:border-box;border:2px solid #cbd5e1;border-radius:50%;background:#fff;display:flex;align-items:center;justify-content:center;transition:background .12s,border-color .12s}.rd-dot.rd-checked{background:#3b82f6;border-color:#3b82f6}.rd-dot.rd-invalid:not(.rd-checked){border-color:#ef4444}.rd-wrap:hover .rd-dot:not(.rd-checked):not(.rd-disabled){border-color:#3b82f6}.rd-core{width:8px;height:8px;border-radius:50%;background:#fff}@media(max-width:640px),(pointer:coarse){.rd-dot{position:relative}.rd-dot:after{content:\"\";position:absolute;inset:-12px}}.rd-text{display:flex;flex-direction:column;gap:2px}.rd-label{font-size:.875rem;color:#334155;line-height:1.4}.rd-description{font-size:.75rem;color:#64748b;line-height:1.4}\n"],
26511
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
26512
+ });
26513
+ }
26514
+ };
26515
+ i0.ɵɵngDeclareClassMetadata({
26516
+ minVersion: "12.0.0",
26517
+ version: "22.2.2",
26518
+ ngImport: i0,
26519
+ type: RadioComponent,
26520
+ decorators: [{
26521
+ type: Component,
26522
+ args: [{
26523
+ selector: "ui-radio",
26524
+ standalone: true,
26525
+ changeDetection: ChangeDetectionStrategy.OnPush,
26526
+ template: `
26527
+ <label class="rd-wrap" [class.rd-disabled]="disabled()">
26528
+ <span class="rd-dot" [class.rd-checked]="checked()" [class.rd-invalid]="invalid()" [class.rd-disabled]="disabled()">
26529
+ @if (checked()) { <span class="rd-core"></span> }
26530
+ </span>
26531
+ <input
26532
+ type="radio"
26533
+ class="rd-hidden"
26534
+ [name]="name()"
26535
+ [value]="value()"
26536
+ [checked]="checked()"
26537
+ [disabled]="disabled()"
26538
+ [attr.aria-label]="ariaLabel() || null"
26539
+ [attr.aria-labelledby]="_labelledBy()"
26540
+ [attr.aria-invalid]="invalid() ? 'true' : null"
26541
+ [attr.aria-describedby]="_describedByIds()"
26542
+ (change)="onChange($event)"
26543
+ />
26544
+ <span class="rd-text">
26545
+ @if (label()) { <span class="rd-label" [id]="_labelId">{{ label() }}</span> }
26546
+ @if (description()) { <span class="rd-description" [id]="_descriptionId">{{ description() }}</span> }
26547
+ <ng-content />
26548
+ </span>
26549
+ </label>
26550
+ `,
26551
+ styles: [":host{display:block}.rd-wrap{display:inline-flex;align-items:flex-start;gap:9px;cursor:pointer;-webkit-user-select:none;user-select:none}.rd-wrap.rd-disabled{cursor:not-allowed;opacity:.5}.rd-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.rd-wrap:has(.rd-hidden:focus-visible) .rd-dot{outline:2px solid #3b82f6;outline-offset:2px}@media(pointer:coarse),(max-width:480px){.rd-wrap{position:relative}.rd-hidden{width:44px;height:44px;margin:0;clip:auto;overflow:visible;left:-12px;top:-2px;opacity:0;cursor:pointer;z-index:1}.rd-wrap.rd-disabled .rd-hidden{cursor:not-allowed}}.rd-dot{flex-shrink:0;width:20px;height:20px;box-sizing:border-box;border:2px solid #cbd5e1;border-radius:50%;background:#fff;display:flex;align-items:center;justify-content:center;transition:background .12s,border-color .12s}.rd-dot.rd-checked{background:#3b82f6;border-color:#3b82f6}.rd-dot.rd-invalid:not(.rd-checked){border-color:#ef4444}.rd-wrap:hover .rd-dot:not(.rd-checked):not(.rd-disabled){border-color:#3b82f6}.rd-core{width:8px;height:8px;border-radius:50%;background:#fff}@media(max-width:640px),(pointer:coarse){.rd-dot{position:relative}.rd-dot:after{content:\"\";position:absolute;inset:-12px}}.rd-text{display:flex;flex-direction:column;gap:2px}.rd-label{font-size:.875rem;color:#334155;line-height:1.4}.rd-description{font-size:.75rem;color:#64748b;line-height:1.4}\n"]
26552
+ }]
26553
+ }],
26554
+ propDecorators: {
26555
+ label: [{
26556
+ type: i0.Input,
26557
+ args: [{
26558
+ isSignal: true,
26559
+ alias: "label",
26560
+ required: false
26561
+ }]
26562
+ }],
26563
+ description: [{
26564
+ type: i0.Input,
26565
+ args: [{
26566
+ isSignal: true,
26567
+ alias: "description",
26568
+ required: false
26569
+ }]
26570
+ }],
26571
+ ariaLabel: [{
26572
+ type: i0.Input,
26573
+ args: [{
26574
+ isSignal: true,
26575
+ alias: "ariaLabel",
26576
+ required: false
26577
+ }]
26578
+ }],
26579
+ value: [{
26580
+ type: i0.Input,
26581
+ args: [{
26582
+ isSignal: true,
26583
+ alias: "value",
26584
+ required: false
26585
+ }]
26586
+ }],
26587
+ name: [{
26588
+ type: i0.Input,
26589
+ args: [{
26590
+ isSignal: true,
26591
+ alias: "name",
26592
+ required: false
26593
+ }]
26594
+ }],
26595
+ checked: [{
26596
+ type: i0.Input,
26597
+ args: [{
26598
+ isSignal: true,
26599
+ alias: "checked",
26600
+ required: false
26601
+ }]
26602
+ }],
26603
+ invalid: [{
26604
+ type: i0.Input,
26605
+ args: [{
26606
+ isSignal: true,
26607
+ alias: "invalid",
26608
+ required: false
26609
+ }]
26610
+ }],
26611
+ describedBy: [{
26612
+ type: i0.Input,
26613
+ args: [{
26614
+ isSignal: true,
26615
+ alias: "describedBy",
26616
+ required: false
26617
+ }]
26618
+ }],
26619
+ _disabledInput: [{
26620
+ type: i0.Input,
26621
+ args: [{
26622
+ isSignal: true,
26623
+ alias: "disabled",
26624
+ required: false
26625
+ }]
26626
+ }],
26627
+ selected: [{
26628
+ type: i0.Output,
26629
+ args: ["selected"]
26630
+ }]
26631
+ }
26632
+ });
26633
+ var RadioGroupComponent = class RadioGroupComponent {
26634
+ get _name() {
26635
+ return this.name() || this._generatedName;
26636
+ }
26637
+ constructor() {
26638
+ this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
26639
+ this.options = input([], ...ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []);
26640
+ this.required = input(false, ...ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []);
26641
+ this.hint = input("", ...ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []);
26642
+ this.error = input("", ...ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []);
26643
+ this.showErrors = input(false, ...ngDevMode ? [{ debugName: "showErrors" }] : /* istanbul ignore next */ []);
26644
+ this.orientation = input("vertical", ...ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []);
26645
+ this.name = input("", ...ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []);
26646
+ this._disabledInput = input(false, {
26647
+ ...ngDevMode ? { debugName: "_disabledInput" } : /* istanbul ignore next */ {},
26648
+ alias: "disabled"
26649
+ });
26650
+ this._cvaDisabled = signal(false, ...ngDevMode ? [{ debugName: "_cvaDisabled" }] : /* istanbul ignore next */ []);
26651
+ this.disabled = computed(() => this._disabledInput() || this._cvaDisabled(), ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
26652
+ this._generatedName = `rg-${Math.random().toString(36).slice(2, 8)}`;
26653
+ this._descId = `${this._generatedName}-desc`;
26654
+ this._value = signal("", ...ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []);
26655
+ this._reveal = createFieldReveal(this.showErrors);
26656
+ this._issue = computed(() => this._check(this._value()), ...ngDevMode ? [{ debugName: "_issue" }] : /* istanbul ignore next */ []);
26657
+ this.invalid = computed(() => !!this.error() || !!this._issue(), ...ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []);
26658
+ this.errorMessage = computed(() => this._issue()?.message ?? "", ...ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []);
26659
+ this.invalidChange = output();
26660
+ this._activeError = computed(() => this.error() || (this._reveal.revealed() ? this.errorMessage() : ""), ...ngDevMode ? [{ debugName: "_activeError" }] : /* istanbul ignore next */ []);
26661
+ this._onValidatorChange = () => {};
26662
+ this._onChange = (_) => {};
26663
+ this._onTouched = () => {};
26664
+ effect(() => {
26665
+ this.invalidChange.emit(this.invalid());
26666
+ });
26667
+ }
26668
+ ngOnChanges() {
26669
+ this._onValidatorChange();
26670
+ }
26671
+ validate(control) {
26672
+ const v = control.value;
26673
+ return issueToErrors(this._check(v == null ? "" : String(v)));
26674
+ }
26675
+ registerOnValidatorChange(fn) {
26676
+ this._onValidatorChange = fn;
26677
+ }
26678
+ writeValue(val) {
26679
+ this._value.set(val ?? "");
26680
+ }
26681
+ registerOnChange(fn) {
26682
+ this._onChange = fn;
26683
+ }
26684
+ registerOnTouched(fn) {
26685
+ this._onTouched = fn;
26686
+ }
26687
+ setDisabledState(d) {
26688
+ this._cvaDisabled.set(d);
26689
+ }
26690
+ onSelect(value) {
26691
+ this._value.set(value);
26692
+ this._onChange(value);
26693
+ }
26694
+ onFocusOut(event) {
26695
+ const next = event.relatedTarget;
26696
+ if (next && event.currentTarget.contains(next)) return;
26697
+ this._onTouched();
26698
+ this._reveal.touched.set(true);
26699
+ }
26700
+ _check(value) {
26701
+ if (this.disabled()) return null;
26702
+ if (!value) return this.required() ? requiredIssue(this.label()) : null;
26703
+ const opts = this.options();
26704
+ if (opts.length > 0 && !opts.some((o) => o.value === value)) return {
26705
+ key: "option",
26706
+ message: "Select a valid option."
26707
+ };
26708
+ return null;
26709
+ }
26710
+ static {
26711
+ this.ɵfac = i0.ɵɵngDeclareFactory({
26712
+ minVersion: "12.0.0",
26713
+ version: "22.2.2",
26714
+ ngImport: i0,
26715
+ type: RadioGroupComponent,
26716
+ deps: [],
26717
+ target: i0.ɵɵFactoryTarget.Component
26718
+ });
26719
+ }
26720
+ static {
26721
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
26722
+ minVersion: "17.0.0",
26723
+ version: "22.2.2",
26724
+ type: RadioGroupComponent,
26725
+ isStandalone: true,
26726
+ selector: "ui-radio-group",
26727
+ inputs: {
26728
+ label: {
26729
+ classPropertyName: "label",
26730
+ publicName: "label",
26731
+ isSignal: true,
26732
+ isRequired: false,
26733
+ transformFunction: null
26734
+ },
26735
+ options: {
26736
+ classPropertyName: "options",
26737
+ publicName: "options",
26738
+ isSignal: true,
26739
+ isRequired: false,
26740
+ transformFunction: null
26741
+ },
26742
+ required: {
26743
+ classPropertyName: "required",
26744
+ publicName: "required",
26745
+ isSignal: true,
26746
+ isRequired: false,
26747
+ transformFunction: null
26748
+ },
26749
+ hint: {
26750
+ classPropertyName: "hint",
26751
+ publicName: "hint",
26752
+ isSignal: true,
26753
+ isRequired: false,
26754
+ transformFunction: null
26755
+ },
26756
+ error: {
26757
+ classPropertyName: "error",
26758
+ publicName: "error",
26759
+ isSignal: true,
26760
+ isRequired: false,
26761
+ transformFunction: null
26762
+ },
26763
+ showErrors: {
26764
+ classPropertyName: "showErrors",
26765
+ publicName: "showErrors",
26766
+ isSignal: true,
26767
+ isRequired: false,
26768
+ transformFunction: null
26769
+ },
26770
+ orientation: {
26771
+ classPropertyName: "orientation",
26772
+ publicName: "orientation",
26773
+ isSignal: true,
26774
+ isRequired: false,
26775
+ transformFunction: null
26776
+ },
26777
+ name: {
26778
+ classPropertyName: "name",
26779
+ publicName: "name",
26780
+ isSignal: true,
26781
+ isRequired: false,
26782
+ transformFunction: null
26783
+ },
26784
+ _disabledInput: {
26785
+ classPropertyName: "_disabledInput",
26786
+ publicName: "disabled",
26787
+ isSignal: true,
26788
+ isRequired: false,
26789
+ transformFunction: null
26790
+ }
26791
+ },
26792
+ outputs: { invalidChange: "invalidChange" },
26793
+ providers: [
26794
+ {
26795
+ provide: NG_VALUE_ACCESSOR,
26796
+ useExisting: forwardRef(() => RadioGroupComponent),
26797
+ multi: true
26798
+ },
26799
+ {
26800
+ provide: NG_VALIDATORS,
26801
+ useExisting: forwardRef(() => RadioGroupComponent),
26802
+ multi: true
26803
+ },
26804
+ {
26805
+ provide: UiFieldValidity,
26806
+ useExisting: forwardRef(() => RadioGroupComponent)
26807
+ }
26808
+ ],
26809
+ usesOnChanges: true,
26810
+ ngImport: i0,
26811
+ template: `
26812
+ <fieldset
26813
+ class="rg-field"
26814
+ role="radiogroup"
26815
+ [class.rg-error]="_activeError()"
26816
+ [class.rg-disabled]="disabled()"
26817
+ [disabled]="disabled()"
26818
+ [attr.aria-required]="required() ? 'true' : null"
26819
+ [attr.aria-invalid]="_activeError() ? 'true' : null"
26820
+ [attr.aria-describedby]="(_activeError() || hint()) ? _descId : null"
26821
+ (focusout)="onFocusOut($event)">
26822
+ @if (label()) {
26823
+ <legend class="rg-label">
26824
+ {{ label() }}
26825
+ @if (required()) { <span class="rg-required" aria-hidden="true">*</span> }
26826
+ </legend>
26827
+ }
26828
+ <div class="rg-options" [class.rg-horizontal]="orientation() === 'horizontal'">
26829
+ @for (opt of options(); track opt.value) {
26830
+ <ui-radio
26831
+ [name]="_name"
26832
+ [value]="opt.value"
26833
+ [label]="opt.label"
26834
+ [description]="opt.description ?? ''"
26835
+ [checked]="_value() === opt.value"
26836
+ [disabled]="disabled() || !!opt.disabled"
26837
+ [invalid]="!!_activeError()"
26838
+ [describedBy]="(_activeError() || hint()) ? _descId : ''"
26839
+ (selected)="onSelect($event)" />
26840
+ }
26841
+ </div>
26842
+ @if (_activeError()) {
26843
+ <p class="rg-desc rg-desc-error" [id]="_descId" role="alert">{{ _activeError() }}</p>
26844
+ } @else if (hint()) {
26845
+ <p class="rg-desc" [id]="_descId">{{ hint() }}</p>
26846
+ }
26847
+ </fieldset>
26848
+ `,
26849
+ isInline: true,
26850
+ styles: [":host{display:block}.rg-field{display:flex;flex-direction:column;gap:6px;border:0;margin:0;padding:0;min-width:0}.rg-label{padding:0;margin-bottom:6px;font-size:.8125rem;font-weight:600;color:#374151;line-height:1}.rg-required{color:#ef4444;margin-left:2px}.rg-options{display:flex;flex-direction:column;gap:10px}.rg-options.rg-horizontal{flex-direction:row;flex-wrap:wrap;gap:8px 20px}.rg-disabled{cursor:not-allowed}.rg-desc{margin:0;font-size:.75rem;line-height:1.4;color:#64748b}.rg-desc-error{color:#ef4444}@media(pointer:coarse),(max-width:480px){.rg-options{gap:4px}}\n"],
26851
+ dependencies: [{
26852
+ kind: "component",
26853
+ type: RadioComponent,
26854
+ selector: "ui-radio",
26855
+ inputs: [
26856
+ "label",
26857
+ "description",
26858
+ "ariaLabel",
26859
+ "value",
26860
+ "name",
26861
+ "checked",
26862
+ "invalid",
26863
+ "describedBy",
26864
+ "disabled"
26865
+ ],
26866
+ outputs: ["selected"]
26867
+ }],
26868
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
26869
+ });
26870
+ }
26871
+ };
26872
+ i0.ɵɵngDeclareClassMetadata({
26873
+ minVersion: "12.0.0",
26874
+ version: "22.2.2",
26875
+ ngImport: i0,
26876
+ type: RadioGroupComponent,
26877
+ decorators: [{
26878
+ type: Component,
26879
+ args: [{
26880
+ selector: "ui-radio-group",
26881
+ standalone: true,
26882
+ imports: [RadioComponent],
26883
+ changeDetection: ChangeDetectionStrategy.OnPush,
26884
+ providers: [
26885
+ {
26886
+ provide: NG_VALUE_ACCESSOR,
26887
+ useExisting: forwardRef(() => RadioGroupComponent),
26888
+ multi: true
26889
+ },
26890
+ {
26891
+ provide: NG_VALIDATORS,
26892
+ useExisting: forwardRef(() => RadioGroupComponent),
26893
+ multi: true
26894
+ },
26895
+ {
26896
+ provide: UiFieldValidity,
26897
+ useExisting: forwardRef(() => RadioGroupComponent)
26898
+ }
26899
+ ],
26900
+ template: `
26901
+ <fieldset
26902
+ class="rg-field"
26903
+ role="radiogroup"
26904
+ [class.rg-error]="_activeError()"
26905
+ [class.rg-disabled]="disabled()"
26906
+ [disabled]="disabled()"
26907
+ [attr.aria-required]="required() ? 'true' : null"
26908
+ [attr.aria-invalid]="_activeError() ? 'true' : null"
26909
+ [attr.aria-describedby]="(_activeError() || hint()) ? _descId : null"
26910
+ (focusout)="onFocusOut($event)">
26911
+ @if (label()) {
26912
+ <legend class="rg-label">
26913
+ {{ label() }}
26914
+ @if (required()) { <span class="rg-required" aria-hidden="true">*</span> }
26915
+ </legend>
26916
+ }
26917
+ <div class="rg-options" [class.rg-horizontal]="orientation() === 'horizontal'">
26918
+ @for (opt of options(); track opt.value) {
26919
+ <ui-radio
26920
+ [name]="_name"
26921
+ [value]="opt.value"
26922
+ [label]="opt.label"
26923
+ [description]="opt.description ?? ''"
26924
+ [checked]="_value() === opt.value"
26925
+ [disabled]="disabled() || !!opt.disabled"
26926
+ [invalid]="!!_activeError()"
26927
+ [describedBy]="(_activeError() || hint()) ? _descId : ''"
26928
+ (selected)="onSelect($event)" />
26929
+ }
26930
+ </div>
26931
+ @if (_activeError()) {
26932
+ <p class="rg-desc rg-desc-error" [id]="_descId" role="alert">{{ _activeError() }}</p>
26933
+ } @else if (hint()) {
26934
+ <p class="rg-desc" [id]="_descId">{{ hint() }}</p>
26935
+ }
26936
+ </fieldset>
26937
+ `,
26938
+ styles: [":host{display:block}.rg-field{display:flex;flex-direction:column;gap:6px;border:0;margin:0;padding:0;min-width:0}.rg-label{padding:0;margin-bottom:6px;font-size:.8125rem;font-weight:600;color:#374151;line-height:1}.rg-required{color:#ef4444;margin-left:2px}.rg-options{display:flex;flex-direction:column;gap:10px}.rg-options.rg-horizontal{flex-direction:row;flex-wrap:wrap;gap:8px 20px}.rg-disabled{cursor:not-allowed}.rg-desc{margin:0;font-size:.75rem;line-height:1.4;color:#64748b}.rg-desc-error{color:#ef4444}@media(pointer:coarse),(max-width:480px){.rg-options{gap:4px}}\n"]
26939
+ }]
26940
+ }],
26941
+ ctorParameters: () => [],
26942
+ propDecorators: {
26943
+ label: [{
26944
+ type: i0.Input,
26945
+ args: [{
26946
+ isSignal: true,
26947
+ alias: "label",
26948
+ required: false
26949
+ }]
26950
+ }],
26951
+ options: [{
26952
+ type: i0.Input,
26953
+ args: [{
26954
+ isSignal: true,
26955
+ alias: "options",
26956
+ required: false
26957
+ }]
26958
+ }],
26959
+ required: [{
26960
+ type: i0.Input,
26961
+ args: [{
26962
+ isSignal: true,
26963
+ alias: "required",
26964
+ required: false
26965
+ }]
26966
+ }],
26967
+ hint: [{
26968
+ type: i0.Input,
26969
+ args: [{
26970
+ isSignal: true,
26971
+ alias: "hint",
26972
+ required: false
26973
+ }]
26974
+ }],
26975
+ error: [{
26976
+ type: i0.Input,
26977
+ args: [{
26978
+ isSignal: true,
26979
+ alias: "error",
26980
+ required: false
26981
+ }]
26982
+ }],
26983
+ showErrors: [{
26984
+ type: i0.Input,
26985
+ args: [{
26986
+ isSignal: true,
26987
+ alias: "showErrors",
26988
+ required: false
26989
+ }]
26990
+ }],
26991
+ orientation: [{
26992
+ type: i0.Input,
26993
+ args: [{
26994
+ isSignal: true,
26995
+ alias: "orientation",
26996
+ required: false
26997
+ }]
26998
+ }],
26999
+ name: [{
27000
+ type: i0.Input,
27001
+ args: [{
27002
+ isSignal: true,
27003
+ alias: "name",
27004
+ required: false
27005
+ }]
27006
+ }],
27007
+ _disabledInput: [{
27008
+ type: i0.Input,
27009
+ args: [{
27010
+ isSignal: true,
27011
+ alias: "disabled",
27012
+ required: false
27013
+ }]
27014
+ }],
27015
+ invalidChange: [{
27016
+ type: i0.Output,
27017
+ args: ["invalidChange"]
27018
+ }]
27019
+ }
27020
+ });
27021
+ var DetailCardComponent = class DetailCardComponent {
27022
+ constructor() {
27023
+ this.title = input("", ...ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []);
27024
+ this.headingLevel = input(null, ...ngDevMode ? [{ debugName: "headingLevel" }] : /* istanbul ignore next */ []);
27025
+ this.titleId = input("", ...ngDevMode ? [{ debugName: "titleId" }] : /* istanbul ignore next */ []);
27026
+ this.subtitle = input("", ...ngDevMode ? [{ debugName: "subtitle" }] : /* istanbul ignore next */ []);
27027
+ this.showHeader = input(true, ...ngDevMode ? [{ debugName: "showHeader" }] : /* istanbul ignore next */ []);
27028
+ this.collapsible = input(true, ...ngDevMode ? [{ debugName: "collapsible" }] : /* istanbul ignore next */ []);
27029
+ this.expanded = model(true, ...ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []);
27030
+ this.showEdit = input(false, ...ngDevMode ? [{ debugName: "showEdit" }] : /* istanbul ignore next */ []);
27031
+ this.editLabel = input("Edit", ...ngDevMode ? [{ debugName: "editLabel" }] : /* istanbul ignore next */ []);
27032
+ this.editClick = output();
27033
+ }
27034
+ isOpen() {
27035
+ return !(this.showHeader() && this.collapsible()) || this.expanded();
27036
+ }
27037
+ toggle() {
27038
+ this.expanded.set(!this.expanded());
27039
+ }
27040
+ onHeaderClick(event) {
27041
+ if (!this.showHeader() || !this.collapsible()) return;
27042
+ if (event.target?.closest("button, a, input, select, textarea, label, [role=\"button\"], [role=\"link\"], [tabindex]:not([tabindex=\"-1\"])")?.closest(".dc-header")) return;
27043
+ this.toggle();
27044
+ }
27045
+ static {
27046
+ this.ɵfac = i0.ɵɵngDeclareFactory({
27047
+ minVersion: "12.0.0",
27048
+ version: "22.2.2",
27049
+ ngImport: i0,
27050
+ type: DetailCardComponent,
27051
+ deps: [],
27052
+ target: i0.ɵɵFactoryTarget.Component
27053
+ });
27054
+ }
27055
+ static {
27056
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
27057
+ minVersion: "17.0.0",
27058
+ version: "22.2.2",
27059
+ type: DetailCardComponent,
27060
+ isStandalone: true,
27061
+ selector: "ui-detail-card",
27062
+ inputs: {
27063
+ title: {
27064
+ classPropertyName: "title",
27065
+ publicName: "title",
27066
+ isSignal: true,
27067
+ isRequired: false,
27068
+ transformFunction: null
27069
+ },
27070
+ headingLevel: {
27071
+ classPropertyName: "headingLevel",
27072
+ publicName: "headingLevel",
27073
+ isSignal: true,
27074
+ isRequired: false,
27075
+ transformFunction: null
27076
+ },
27077
+ titleId: {
27078
+ classPropertyName: "titleId",
27079
+ publicName: "titleId",
27080
+ isSignal: true,
27081
+ isRequired: false,
27082
+ transformFunction: null
27083
+ },
27084
+ subtitle: {
27085
+ classPropertyName: "subtitle",
27086
+ publicName: "subtitle",
27087
+ isSignal: true,
27088
+ isRequired: false,
27089
+ transformFunction: null
27090
+ },
27091
+ showHeader: {
27092
+ classPropertyName: "showHeader",
27093
+ publicName: "showHeader",
27094
+ isSignal: true,
27095
+ isRequired: false,
27096
+ transformFunction: null
27097
+ },
27098
+ collapsible: {
27099
+ classPropertyName: "collapsible",
27100
+ publicName: "collapsible",
27101
+ isSignal: true,
27102
+ isRequired: false,
27103
+ transformFunction: null
27104
+ },
27105
+ expanded: {
27106
+ classPropertyName: "expanded",
27107
+ publicName: "expanded",
27108
+ isSignal: true,
27109
+ isRequired: false,
27110
+ transformFunction: null
27111
+ },
27112
+ showEdit: {
27113
+ classPropertyName: "showEdit",
27114
+ publicName: "showEdit",
27115
+ isSignal: true,
27116
+ isRequired: false,
27117
+ transformFunction: null
27118
+ },
27119
+ editLabel: {
27120
+ classPropertyName: "editLabel",
27121
+ publicName: "editLabel",
27122
+ isSignal: true,
27123
+ isRequired: false,
27124
+ transformFunction: null
27125
+ }
27126
+ },
27127
+ outputs: {
27128
+ expanded: "expandedChange",
27129
+ editClick: "editClick"
27130
+ },
27131
+ host: {
27132
+ attributes: { "role": "group" },
27133
+ properties: {
27134
+ "attr.aria-labelledby": "showHeader() && title() && titleId() ? titleId() : null",
27135
+ "attr.aria-label": "showHeader() && title() && !titleId() ? title() : null"
27136
+ }
27137
+ },
27138
+ ngImport: i0,
27139
+ template: `
27140
+ <div class="dc">
27141
+ @if (showHeader()) {
27142
+ <div class="dc-header" [class.collapsible]="collapsible()" [class.open]="isOpen()" (click)="onHeaderClick($event)">
27143
+ @if (collapsible()) {
27144
+ <ui-button class="dc-chevron" variant="icon" size="sm"
27145
+ [ariaLabel]="title() || 'Toggle section'"
27146
+ [ariaExpanded]="isOpen()"
27147
+ (click)="$event.stopPropagation(); toggle()">
27148
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"
27149
+ stroke-linecap="round" stroke-linejoin="round" [class.rotated]="!isOpen()" aria-hidden="true">
27150
+ <path d="M6 9l6 6 6-6"/>
27151
+ </svg>
27152
+ </ui-button>
27153
+ }
27154
+ <ng-content select="[card-header-leading]" />
27155
+ <div class="dc-header-text">
27156
+ @if (title()) { <span class="dc-title" [attr.id]="titleId() || null" [attr.role]="headingLevel() ? 'heading' : null" [attr.aria-level]="headingLevel() || null">{{ title() }}</span> }
27157
+ @if (subtitle()) { <span class="dc-subtitle">{{ subtitle() }}</span> }
27158
+ <ng-content select="[card-header]" />
27159
+ </div>
27160
+ @if (showEdit()) {
27161
+ <ui-button class="dc-edit" variant="secondary" size="xs" (click)="$event.stopPropagation(); editClick.emit()">
27162
+ <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
27163
+ <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
27164
+ <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
27165
+ </svg>
27166
+ {{ editLabel() }}
27167
+ </ui-button>
27168
+ }
27169
+ <ng-content select="[card-header-action]" />
27170
+ </div>
27171
+ }
27172
+ <div class="dc-body-wrap" [class.collapsed]="!isOpen()" [attr.inert]="isOpen() ? null : ''" [attr.aria-hidden]="isOpen() ? null : 'true'">
27173
+ <div class="dc-body">
27174
+ <ng-content />
27175
+ </div>
27176
+ </div>
27177
+ </div>
27178
+ `,
27179
+ isInline: true,
27180
+ styles: [":host{display:block;margin-bottom:16px}:host(:last-child){margin-bottom:0}.dc{background:#fff;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden}.dc-header{display:flex;align-items:center;flex-wrap:wrap;gap:8px 10px;padding:14px 18px}.dc-header.open{border-bottom:1px solid #f1f5f9}.dc-header.collapsible{cursor:pointer;-webkit-user-select:none;user-select:none}@media(hover:hover){.dc-header.collapsible:hover{background:#f8fafc}}.dc-chevron{flex-shrink:0;color:#94a3b8}.dc-chevron svg{transition:transform .2s}.dc-chevron svg.rotated{transform:rotate(-90deg)}.dc-header-text{display:flex;flex-direction:column;gap:2px;flex:1 1 160px;min-width:0;word-break:break-word;overflow-wrap:anywhere}.dc-title{font-size:.8125rem;font-weight:800;letter-spacing:.07em;color:#1e293b;line-height:1.3;text-transform:uppercase}.dc-subtitle{font-size:.75rem;color:#94a3b8}.dc-edit{flex-shrink:0;margin-left:auto}.dc-edit ::ng-deep button{font-size:.8rem;font-weight:500;color:#64748b;background:none;border:1px solid #e2e8f0;border-radius:6px;padding:4px 10px;gap:5px}.dc-edit ::ng-deep button:hover{background:#f1f5f9;color:#1e293b}.dc-body-wrap{display:grid;grid-template-rows:1fr;transition:grid-template-rows .25s ease}.dc-body-wrap.collapsed{grid-template-rows:0fr}.dc-body{padding:0;min-height:0;overflow:hidden}@media(max-width:480px){.dc-header{padding:12px 14px}.dc-edit{margin-left:0}}@media(prefers-reduced-motion:reduce){.dc-body-wrap,.dc-chevron svg{transition:none}}\n"],
27181
+ dependencies: [{
27182
+ kind: "component",
27183
+ type: ButtonComponent,
27184
+ selector: "ui-button",
27185
+ inputs: [
27186
+ "variant",
27187
+ "color",
27188
+ "active",
27189
+ "size",
27190
+ "type",
27191
+ "disabled",
27192
+ "loading",
27193
+ "fullWidth",
27194
+ "ariaLabel",
27195
+ "ariaExpanded",
27196
+ "ariaPressed",
27197
+ "modal-footer-left",
27198
+ "modal-footer-right"
27199
+ ]
27200
+ }],
27201
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
27202
+ });
27203
+ }
27204
+ };
27205
+ i0.ɵɵngDeclareClassMetadata({
27206
+ minVersion: "12.0.0",
27207
+ version: "22.2.2",
27208
+ ngImport: i0,
27209
+ type: DetailCardComponent,
27210
+ decorators: [{
27211
+ type: Component,
27212
+ args: [{
27213
+ selector: "ui-detail-card",
27214
+ standalone: true,
27215
+ changeDetection: ChangeDetectionStrategy.OnPush,
27216
+ imports: [ButtonComponent],
27217
+ host: {
27218
+ "role": "group",
27219
+ "[attr.aria-labelledby]": "showHeader() && title() && titleId() ? titleId() : null",
27220
+ "[attr.aria-label]": "showHeader() && title() && !titleId() ? title() : null"
27221
+ },
27222
+ template: `
27223
+ <div class="dc">
27224
+ @if (showHeader()) {
27225
+ <div class="dc-header" [class.collapsible]="collapsible()" [class.open]="isOpen()" (click)="onHeaderClick($event)">
27226
+ @if (collapsible()) {
27227
+ <ui-button class="dc-chevron" variant="icon" size="sm"
27228
+ [ariaLabel]="title() || 'Toggle section'"
27229
+ [ariaExpanded]="isOpen()"
27230
+ (click)="$event.stopPropagation(); toggle()">
27231
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"
27232
+ stroke-linecap="round" stroke-linejoin="round" [class.rotated]="!isOpen()" aria-hidden="true">
27233
+ <path d="M6 9l6 6 6-6"/>
27234
+ </svg>
27235
+ </ui-button>
27236
+ }
27237
+ <ng-content select="[card-header-leading]" />
27238
+ <div class="dc-header-text">
27239
+ @if (title()) { <span class="dc-title" [attr.id]="titleId() || null" [attr.role]="headingLevel() ? 'heading' : null" [attr.aria-level]="headingLevel() || null">{{ title() }}</span> }
27240
+ @if (subtitle()) { <span class="dc-subtitle">{{ subtitle() }}</span> }
27241
+ <ng-content select="[card-header]" />
27242
+ </div>
27243
+ @if (showEdit()) {
27244
+ <ui-button class="dc-edit" variant="secondary" size="xs" (click)="$event.stopPropagation(); editClick.emit()">
27245
+ <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
27246
+ <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/>
27247
+ <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/>
27248
+ </svg>
27249
+ {{ editLabel() }}
27250
+ </ui-button>
27251
+ }
27252
+ <ng-content select="[card-header-action]" />
27253
+ </div>
27254
+ }
27255
+ <div class="dc-body-wrap" [class.collapsed]="!isOpen()" [attr.inert]="isOpen() ? null : ''" [attr.aria-hidden]="isOpen() ? null : 'true'">
27256
+ <div class="dc-body">
27257
+ <ng-content />
27258
+ </div>
27259
+ </div>
27260
+ </div>
27261
+ `,
27262
+ styles: [":host{display:block;margin-bottom:16px}:host(:last-child){margin-bottom:0}.dc{background:#fff;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden}.dc-header{display:flex;align-items:center;flex-wrap:wrap;gap:8px 10px;padding:14px 18px}.dc-header.open{border-bottom:1px solid #f1f5f9}.dc-header.collapsible{cursor:pointer;-webkit-user-select:none;user-select:none}@media(hover:hover){.dc-header.collapsible:hover{background:#f8fafc}}.dc-chevron{flex-shrink:0;color:#94a3b8}.dc-chevron svg{transition:transform .2s}.dc-chevron svg.rotated{transform:rotate(-90deg)}.dc-header-text{display:flex;flex-direction:column;gap:2px;flex:1 1 160px;min-width:0;word-break:break-word;overflow-wrap:anywhere}.dc-title{font-size:.8125rem;font-weight:800;letter-spacing:.07em;color:#1e293b;line-height:1.3;text-transform:uppercase}.dc-subtitle{font-size:.75rem;color:#94a3b8}.dc-edit{flex-shrink:0;margin-left:auto}.dc-edit ::ng-deep button{font-size:.8rem;font-weight:500;color:#64748b;background:none;border:1px solid #e2e8f0;border-radius:6px;padding:4px 10px;gap:5px}.dc-edit ::ng-deep button:hover{background:#f1f5f9;color:#1e293b}.dc-body-wrap{display:grid;grid-template-rows:1fr;transition:grid-template-rows .25s ease}.dc-body-wrap.collapsed{grid-template-rows:0fr}.dc-body{padding:0;min-height:0;overflow:hidden}@media(max-width:480px){.dc-header{padding:12px 14px}.dc-edit{margin-left:0}}@media(prefers-reduced-motion:reduce){.dc-body-wrap,.dc-chevron svg{transition:none}}\n"]
27263
+ }]
27264
+ }],
27265
+ propDecorators: {
27266
+ title: [{
27267
+ type: i0.Input,
27268
+ args: [{
27269
+ isSignal: true,
27270
+ alias: "title",
27271
+ required: false
27272
+ }]
27273
+ }],
27274
+ headingLevel: [{
27275
+ type: i0.Input,
27276
+ args: [{
27277
+ isSignal: true,
27278
+ alias: "headingLevel",
27279
+ required: false
27280
+ }]
27281
+ }],
27282
+ titleId: [{
27283
+ type: i0.Input,
27284
+ args: [{
27285
+ isSignal: true,
27286
+ alias: "titleId",
27287
+ required: false
27288
+ }]
27289
+ }],
27290
+ subtitle: [{
27291
+ type: i0.Input,
27292
+ args: [{
27293
+ isSignal: true,
27294
+ alias: "subtitle",
27295
+ required: false
27296
+ }]
27297
+ }],
27298
+ showHeader: [{
27299
+ type: i0.Input,
27300
+ args: [{
27301
+ isSignal: true,
27302
+ alias: "showHeader",
27303
+ required: false
27304
+ }]
27305
+ }],
27306
+ collapsible: [{
27307
+ type: i0.Input,
27308
+ args: [{
27309
+ isSignal: true,
27310
+ alias: "collapsible",
27311
+ required: false
27312
+ }]
27313
+ }],
27314
+ expanded: [{
27315
+ type: i0.Input,
27316
+ args: [{
27317
+ isSignal: true,
27318
+ alias: "expanded",
27319
+ required: false
27320
+ }]
27321
+ }, {
27322
+ type: i0.Output,
27323
+ args: ["expandedChange"]
27324
+ }],
27325
+ showEdit: [{
27326
+ type: i0.Input,
27327
+ args: [{
27328
+ isSignal: true,
27329
+ alias: "showEdit",
27330
+ required: false
27331
+ }]
27332
+ }],
27333
+ editLabel: [{
27334
+ type: i0.Input,
27335
+ args: [{
27336
+ isSignal: true,
27337
+ alias: "editLabel",
27338
+ required: false
27339
+ }]
27340
+ }],
27341
+ editClick: [{
27342
+ type: i0.Output,
27343
+ args: ["editClick"]
27344
+ }]
27345
+ }
27346
+ });
27347
+ const SPACE_PX = {
27348
+ none: 0,
27349
+ sm: 8,
27350
+ md: 16,
27351
+ lg: 24
27352
+ };
27353
+ var DividerComponent = class DividerComponent {
27354
+ constructor() {
27355
+ this.spaceAbove = input("none", ...ngDevMode ? [{ debugName: "spaceAbove" }] : /* istanbul ignore next */ []);
27356
+ this.spaceBelow = input("md", ...ngDevMode ? [{ debugName: "spaceBelow" }] : /* istanbul ignore next */ []);
27357
+ this.decorative = input(false, ...ngDevMode ? [{ debugName: "decorative" }] : /* istanbul ignore next */ []);
27358
+ this.above = computed(() => SPACE_PX[this.spaceAbove()] ?? 0, ...ngDevMode ? [{ debugName: "above" }] : /* istanbul ignore next */ []);
27359
+ this.below = computed(() => SPACE_PX[this.spaceBelow()] ?? 0, ...ngDevMode ? [{ debugName: "below" }] : /* istanbul ignore next */ []);
27360
+ }
27361
+ static {
27362
+ this.ɵfac = i0.ɵɵngDeclareFactory({
27363
+ minVersion: "12.0.0",
27364
+ version: "22.2.2",
27365
+ ngImport: i0,
27366
+ type: DividerComponent,
27367
+ deps: [],
27368
+ target: i0.ɵɵFactoryTarget.Component
27369
+ });
27370
+ }
27371
+ static {
27372
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
27373
+ minVersion: "17.1.0",
27374
+ version: "22.2.2",
27375
+ type: DividerComponent,
27376
+ isStandalone: true,
27377
+ selector: "ui-divider",
27378
+ inputs: {
27379
+ spaceAbove: {
27380
+ classPropertyName: "spaceAbove",
27381
+ publicName: "spaceAbove",
27382
+ isSignal: true,
27383
+ isRequired: false,
27384
+ transformFunction: null
27385
+ },
27386
+ spaceBelow: {
27387
+ classPropertyName: "spaceBelow",
27388
+ publicName: "spaceBelow",
27389
+ isSignal: true,
27390
+ isRequired: false,
27391
+ transformFunction: null
27392
+ },
27393
+ decorative: {
27394
+ classPropertyName: "decorative",
27395
+ publicName: "decorative",
27396
+ isSignal: true,
27397
+ isRequired: false,
27398
+ transformFunction: null
27399
+ }
27400
+ },
27401
+ ngImport: i0,
27402
+ template: `<hr class="ui-divider" [style.margin-top.px]="above()" [style.margin-bottom.px]="below()"
27403
+ [attr.aria-hidden]="decorative() ? 'true' : null" [attr.role]="decorative() ? 'presentation' : null" />`,
27404
+ isInline: true,
27405
+ styles: [":host{display:block}.ui-divider{display:block;width:100%;height:0;border:0;border-top:1px solid #e2e8f0;padding:0}\n"],
27406
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
27407
+ });
27408
+ }
27409
+ };
27410
+ i0.ɵɵngDeclareClassMetadata({
27411
+ minVersion: "12.0.0",
27412
+ version: "22.2.2",
27413
+ ngImport: i0,
27414
+ type: DividerComponent,
27415
+ decorators: [{
27416
+ type: Component,
27417
+ args: [{
27418
+ selector: "ui-divider",
27419
+ standalone: true,
27420
+ changeDetection: ChangeDetectionStrategy.OnPush,
27421
+ template: `<hr class="ui-divider" [style.margin-top.px]="above()" [style.margin-bottom.px]="below()"
27422
+ [attr.aria-hidden]="decorative() ? 'true' : null" [attr.role]="decorative() ? 'presentation' : null" />`,
27423
+ styles: [":host{display:block}.ui-divider{display:block;width:100%;height:0;border:0;border-top:1px solid #e2e8f0;padding:0}\n"]
27424
+ }]
27425
+ }],
27426
+ propDecorators: {
27427
+ spaceAbove: [{
27428
+ type: i0.Input,
27429
+ args: [{
27430
+ isSignal: true,
27431
+ alias: "spaceAbove",
27432
+ required: false
27433
+ }]
27434
+ }],
27435
+ spaceBelow: [{
27436
+ type: i0.Input,
27437
+ args: [{
27438
+ isSignal: true,
27439
+ alias: "spaceBelow",
27440
+ required: false
27441
+ }]
27442
+ }],
27443
+ decorative: [{
27444
+ type: i0.Input,
27445
+ args: [{
27446
+ isSignal: true,
27447
+ alias: "decorative",
27448
+ required: false
27449
+ }]
27450
+ }]
27451
+ }
27452
+ });
27453
+ export { AlertComponent, AppShellComponent, AvatarComponent, BADGE_VARIANT_STYLES, BadgeComponent, BulkMessagePanelComponent, ButtonComponent, CheckboxComponent, ChipComponent, ChipGroupComponent, ColumnFilterComponent, ComboboxComponent, ConfirmOutletComponent, ConfirmService, ContactPickerComponent, DEFAULT_DOCUMENT_SUBJECT, DOCUMENT_PURPOSE_OPTIONS, DROPDOWN_GROUP, DataTableComponent, DateInputComponent, DateRangePickerComponent, DatetimeInputComponent, DetailCardComponent, DiscountSelectorComponent, DividerComponent, DocumentSendOptionsComponent, DropdownComponent, EmptyStateComponent, ErrorComponent, ErrorStateComponent, FORGEROUTE_CONFIG, FileInputComponent, FormRowComponent, FormSectionComponent, HintComponent, ImagePreviewComponent, ImageRepositionComponent, ImportExportComponent, KpiCardComponent, ListItemComponent, MAX_CC, ModalComponent, MoreMenuComponent, MultiSelectComponent, PROGRESS_STEP_THRESHOLDS, PaginationComponent, PanelInfoListComponent, PillTabsComponent, ProgressBarComponent, QrCodeComponent, QuickFilterTabsComponent, RICH_TEXT_OPTIONS, RadioComponent, RadioGroupComponent, RichTextEditorComponent, SEMANTIC_BADGE_MAP, SearchInputComponent, SelectComponent, SendMessagePanelComponent, SidePanelComponent, SkeletonComponent, TableToolbarComponent, TemplatePickerComponent, TextInputComponent, TextareaInputComponent, TimeInputComponent, ToastComponent, ToastService, ToggleBadgeComponent, TooltipDirective, US_STATES, UiFieldValidity, VideoPickerComponent, appShellGroupsStorageKey, autoVariant, builtInActionIcon, createFieldReveal, decodeFilterValues, encodeFilterValue, encodeFilterValues, errorContextInterceptor, formatIsoDate, formatIsoDateTime, formatTime, getEligibleIds, getEligibleOptions, getErrorMessage, humanReadableMessage, isoKey, issueToErrors, maxLengthIssue, messagePreviewHtml, parseCcList, parseIso, parseTime, pluralize, requiredIssue, resolvePreset, suggestDocumentSubject };
25439
27454
 
25440
27455
  //# sourceMappingURL=forgeroute-ui.mjs.map