@forgeroute/ui 0.4.55 → 0.4.57

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.
@@ -2519,8 +2519,13 @@ var ModalComponent = class ModalComponent {
2519
2519
  this.dialogTestId = input("", ...ngDevMode ? [{ debugName: "dialogTestId" }] : /* istanbul ignore next */ []);
2520
2520
  this.hideClose = input(false, ...ngDevMode ? [{ debugName: "hideClose" }] : /* istanbul ignore next */ []);
2521
2521
  this.closable = input(true, ...ngDevMode ? [{ debugName: "closable" }] : /* istanbul ignore next */ []);
2522
+ this.layout = input("default", ...ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []);
2523
+ this.closeOnBackdrop = input(true, ...ngDevMode ? [{ debugName: "closeOnBackdrop" }] : /* istanbul ignore next */ []);
2524
+ this.closeOnEscape = input(true, ...ngDevMode ? [{ debugName: "closeOnEscape" }] : /* istanbul ignore next */ []);
2525
+ this.busy = input(false, ...ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []);
2522
2526
  this.close = output();
2523
2527
  this.returnFocusTo = input(null, ...ngDevMode ? [{ debugName: "returnFocusTo" }] : /* istanbul ignore next */ []);
2528
+ this.kiosk = computed(() => this.layout() === "kiosk", ...ngDevMode ? [{ debugName: "kiosk" }] : /* istanbul ignore next */ []);
2524
2529
  this.titleId = `m-title-${Math.random().toString(36).slice(2, 8)}`;
2525
2530
  this.el = inject(ElementRef);
2526
2531
  this.ren = inject(Renderer2);
@@ -2563,7 +2568,7 @@ var ModalComponent = class ModalComponent {
2563
2568
  if (!this.open() || !this._overlays.isTop(this)) return;
2564
2569
  if (event.key === "Escape") {
2565
2570
  event.preventDefault();
2566
- if (this.closable()) this.close.emit();
2571
+ this.dismiss("escape");
2567
2572
  return;
2568
2573
  }
2569
2574
  if (event.key === "Tab") {
@@ -2586,6 +2591,12 @@ var ModalComponent = class ModalComponent {
2586
2591
  }
2587
2592
  }
2588
2593
  }
2594
+ dismiss(via) {
2595
+ if (!this.closable() || this.busy()) return;
2596
+ if (via === "backdrop" && !this.closeOnBackdrop()) return;
2597
+ if (via === "escape" && !this.closeOnEscape()) return;
2598
+ this.close.emit();
2599
+ }
2589
2600
  onGuardFocus(which, event) {
2590
2601
  if (!this._overlays.isTop(this)) return;
2591
2602
  redirectFromGuard(which, this.el.nativeElement, this.el.nativeElement.querySelector(".m-modal"), event?.relatedTarget ?? null);
@@ -2606,6 +2617,10 @@ var ModalComponent = class ModalComponent {
2606
2617
  this._stopViewport?.();
2607
2618
  this._stopViewport = null;
2608
2619
  this._overlays.remove(this);
2620
+ if (this._scrollLocked && this.layout() === "kiosk") {
2621
+ restoreFocus(this.returnFocusTo(), this._prevFocus);
2622
+ this._prevFocus = null;
2623
+ }
2609
2624
  if (this._scrollLocked && this._overlays.isEmpty) this.doc.body.style.overflow = "";
2610
2625
  const el = this.el.nativeElement;
2611
2626
  if (el.parentNode === this.doc.body) this.ren.removeChild(this.doc.body, el);
@@ -2684,6 +2699,34 @@ var ModalComponent = class ModalComponent {
2684
2699
  isRequired: false,
2685
2700
  transformFunction: null
2686
2701
  },
2702
+ layout: {
2703
+ classPropertyName: "layout",
2704
+ publicName: "layout",
2705
+ isSignal: true,
2706
+ isRequired: false,
2707
+ transformFunction: null
2708
+ },
2709
+ closeOnBackdrop: {
2710
+ classPropertyName: "closeOnBackdrop",
2711
+ publicName: "closeOnBackdrop",
2712
+ isSignal: true,
2713
+ isRequired: false,
2714
+ transformFunction: null
2715
+ },
2716
+ closeOnEscape: {
2717
+ classPropertyName: "closeOnEscape",
2718
+ publicName: "closeOnEscape",
2719
+ isSignal: true,
2720
+ isRequired: false,
2721
+ transformFunction: null
2722
+ },
2723
+ busy: {
2724
+ classPropertyName: "busy",
2725
+ publicName: "busy",
2726
+ isSignal: true,
2727
+ isRequired: false,
2728
+ transformFunction: null
2729
+ },
2687
2730
  returnFocusTo: {
2688
2731
  classPropertyName: "returnFocusTo",
2689
2732
  publicName: "returnFocusTo",
@@ -2697,8 +2740,8 @@ var ModalComponent = class ModalComponent {
2697
2740
  ngImport: i0,
2698
2741
  template: `
2699
2742
  @if (open()) {
2700
- <div class="m-backdrop" (click)="closable() && close.emit()"></div>
2701
- <div class="m-modal" role="dialog" aria-modal="true" tabindex="-1" [attr.aria-labelledby]="titleId" [attr.data-testid]="dialogTestId() || null" [style.max-width]="maxWidth()">
2743
+ <div class="m-backdrop" [class.m-kiosk-backdrop]="kiosk()" (click)="dismiss('backdrop')"></div>
2744
+ <div class="m-modal" [class.m-kiosk]="kiosk()" role="dialog" aria-modal="true" tabindex="-1" [attr.aria-labelledby]="titleId" [attr.aria-busy]="busy() ? 'true' : null" [attr.data-testid]="dialogTestId() || null" [style.max-width]="maxWidth()">
2702
2745
  <span class="m-focus-guard" data-ui-focus-guard="start" tabindex="0" (focus)="onGuardFocus('start', $event)"></span>
2703
2746
  <div class="m-header">
2704
2747
  <div class="m-header-text">
@@ -2707,8 +2750,9 @@ var ModalComponent = class ModalComponent {
2707
2750
  <p class="m-description">{{ description() }}</p>
2708
2751
  }
2709
2752
  </div>
2753
+ <ng-content select="[modal-header-end]" />
2710
2754
  @if (!hideClose() && closable()) {
2711
- <button class="m-close" type="button" aria-label="Close" (click)="close.emit()">
2755
+ <button class="m-close" type="button" aria-label="Close" [disabled]="busy()" (click)="dismiss('close')">
2712
2756
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
2713
2757
  <line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
2714
2758
  </svg>
@@ -2728,7 +2772,7 @@ var ModalComponent = class ModalComponent {
2728
2772
  }
2729
2773
  `,
2730
2774
  isInline: true,
2731
- 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-focus-guard{position:absolute;width:1px;height:1px;padding:0;margin:-1px;border:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;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);max-height:calc(100dvh - 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}.m-footer-center{display:flex;align-items:center;justify-content:center;gap:8px;flex:1 1 auto;margin:0 8px}.m-footer-center:empty{display:none}@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-wrap:wrap;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)}}@media(prefers-reduced-motion:reduce){.m-backdrop,.m-modal{animation:none}}\n"],
2775
+ 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-close:disabled{opacity:.4;cursor:not-allowed}.m-focus-guard{position:absolute;width:1px;height:1px;padding:0;margin:-1px;border:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;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);max-height:calc(100dvh - 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}.m-footer-center{display:flex;align-items:center;justify-content:center;gap:8px;flex:1 1 auto;margin:0 8px}.m-footer-center:empty{display:none}@media(max-width:480px){.m-modal:not(.m-kiosk){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-wrap:wrap;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}}.m-backdrop.m-kiosk-backdrop{background:#0f172ab8;backdrop-filter:none;-webkit-backdrop-filter:none}.m-modal.m-kiosk{inset:0;transform:none;margin:auto;width:calc(100% - 32px);height:fit-content;max-height:calc(100vh - 32px);max-height:calc(100dvh - 32px);overflow:hidden;animation:m-fade .18s ease;box-shadow:0 25px 60px #00000040}.m-modal.m-kiosk .m-body{overscroll-behavior:contain;-webkit-overflow-scrolling:touch}.m-modal.m-kiosk .m-footer{border-radius:0 0 16px 16px}@media(max-width:480px){.m-modal.m-kiosk{bottom:var(--ui-kb, 0px);max-height:min(calc(100dvh - 32px),var(--ui-vvh, 100dvh));border-radius:16px}.m-modal.m-kiosk .m-footer{flex-wrap:wrap;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)}}@media(prefers-reduced-motion:reduce){.m-backdrop,.m-modal{animation:none}}\n"],
2732
2776
  changeDetection: i0.ChangeDetectionStrategy.OnPush
2733
2777
  });
2734
2778
  }
@@ -2747,8 +2791,8 @@ i0.ɵɵngDeclareClassMetadata({
2747
2791
  host: { "(document:keydown)": "onKeydown($event)" },
2748
2792
  template: `
2749
2793
  @if (open()) {
2750
- <div class="m-backdrop" (click)="closable() && close.emit()"></div>
2751
- <div class="m-modal" role="dialog" aria-modal="true" tabindex="-1" [attr.aria-labelledby]="titleId" [attr.data-testid]="dialogTestId() || null" [style.max-width]="maxWidth()">
2794
+ <div class="m-backdrop" [class.m-kiosk-backdrop]="kiosk()" (click)="dismiss('backdrop')"></div>
2795
+ <div class="m-modal" [class.m-kiosk]="kiosk()" role="dialog" aria-modal="true" tabindex="-1" [attr.aria-labelledby]="titleId" [attr.aria-busy]="busy() ? 'true' : null" [attr.data-testid]="dialogTestId() || null" [style.max-width]="maxWidth()">
2752
2796
  <span class="m-focus-guard" data-ui-focus-guard="start" tabindex="0" (focus)="onGuardFocus('start', $event)"></span>
2753
2797
  <div class="m-header">
2754
2798
  <div class="m-header-text">
@@ -2757,8 +2801,9 @@ i0.ɵɵngDeclareClassMetadata({
2757
2801
  <p class="m-description">{{ description() }}</p>
2758
2802
  }
2759
2803
  </div>
2804
+ <ng-content select="[modal-header-end]" />
2760
2805
  @if (!hideClose() && closable()) {
2761
- <button class="m-close" type="button" aria-label="Close" (click)="close.emit()">
2806
+ <button class="m-close" type="button" aria-label="Close" [disabled]="busy()" (click)="dismiss('close')">
2762
2807
  <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
2763
2808
  <line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
2764
2809
  </svg>
@@ -2777,7 +2822,7 @@ i0.ɵɵngDeclareClassMetadata({
2777
2822
  </div>
2778
2823
  }
2779
2824
  `,
2780
- 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-focus-guard{position:absolute;width:1px;height:1px;padding:0;margin:-1px;border:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;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);max-height:calc(100dvh - 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}.m-footer-center{display:flex;align-items:center;justify-content:center;gap:8px;flex:1 1 auto;margin:0 8px}.m-footer-center:empty{display:none}@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-wrap:wrap;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)}}@media(prefers-reduced-motion:reduce){.m-backdrop,.m-modal{animation:none}}\n"]
2825
+ 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-close:disabled{opacity:.4;cursor:not-allowed}.m-focus-guard{position:absolute;width:1px;height:1px;padding:0;margin:-1px;border:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;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);max-height:calc(100dvh - 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}.m-footer-center{display:flex;align-items:center;justify-content:center;gap:8px;flex:1 1 auto;margin:0 8px}.m-footer-center:empty{display:none}@media(max-width:480px){.m-modal:not(.m-kiosk){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-wrap:wrap;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}}.m-backdrop.m-kiosk-backdrop{background:#0f172ab8;backdrop-filter:none;-webkit-backdrop-filter:none}.m-modal.m-kiosk{inset:0;transform:none;margin:auto;width:calc(100% - 32px);height:fit-content;max-height:calc(100vh - 32px);max-height:calc(100dvh - 32px);overflow:hidden;animation:m-fade .18s ease;box-shadow:0 25px 60px #00000040}.m-modal.m-kiosk .m-body{overscroll-behavior:contain;-webkit-overflow-scrolling:touch}.m-modal.m-kiosk .m-footer{border-radius:0 0 16px 16px}@media(max-width:480px){.m-modal.m-kiosk{bottom:var(--ui-kb, 0px);max-height:min(calc(100dvh - 32px),var(--ui-vvh, 100dvh));border-radius:16px}.m-modal.m-kiosk .m-footer{flex-wrap:wrap;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)}}@media(prefers-reduced-motion:reduce){.m-backdrop,.m-modal{animation:none}}\n"]
2781
2826
  }]
2782
2827
  }],
2783
2828
  ctorParameters: () => [],
@@ -2846,6 +2891,38 @@ i0.ɵɵngDeclareClassMetadata({
2846
2891
  required: false
2847
2892
  }]
2848
2893
  }],
2894
+ layout: [{
2895
+ type: i0.Input,
2896
+ args: [{
2897
+ isSignal: true,
2898
+ alias: "layout",
2899
+ required: false
2900
+ }]
2901
+ }],
2902
+ closeOnBackdrop: [{
2903
+ type: i0.Input,
2904
+ args: [{
2905
+ isSignal: true,
2906
+ alias: "closeOnBackdrop",
2907
+ required: false
2908
+ }]
2909
+ }],
2910
+ closeOnEscape: [{
2911
+ type: i0.Input,
2912
+ args: [{
2913
+ isSignal: true,
2914
+ alias: "closeOnEscape",
2915
+ required: false
2916
+ }]
2917
+ }],
2918
+ busy: [{
2919
+ type: i0.Input,
2920
+ args: [{
2921
+ isSignal: true,
2922
+ alias: "busy",
2923
+ required: false
2924
+ }]
2925
+ }],
2849
2926
  close: [{
2850
2927
  type: i0.Output,
2851
2928
  args: ["close"]
@@ -2990,6 +3067,11 @@ function formatTime(value) {
2990
3067
  const h = Math.floor(t / 60), mi = t % 60;
2991
3068
  return `${h % 12 === 0 ? 12 : h % 12}:${String(mi).padStart(2, "0")} ${h < 12 ? "AM" : "PM"}`;
2992
3069
  }
3070
+ function mergeDescribedBy(own, external) {
3071
+ const ids = `${own ?? ""} ${external ?? ""}`.split(/\s+/).filter(Boolean);
3072
+ const unique = ids.filter((id, i) => ids.indexOf(id) === i);
3073
+ return unique.length ? unique.join(" ") : null;
3074
+ }
2993
3075
  var CheckboxComponent = class CheckboxComponent {
2994
3076
  isSelected(value) {
2995
3077
  return this._selected().includes(value);
@@ -4969,6 +5051,7 @@ var TextInputComponent = class TextInputComponent {
4969
5051
  this.inputmode = input("", ...ngDevMode ? [{ debugName: "inputmode" }] : /* istanbul ignore next */ []);
4970
5052
  this.readonly = input(false, ...ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []);
4971
5053
  this.hint = input("", ...ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []);
5054
+ this.ariaDescribedBy = input("", ...ngDevMode ? [{ debugName: "ariaDescribedBy" }] : /* istanbul ignore next */ []);
4972
5055
  this.error = input("", ...ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []);
4973
5056
  this.phoneFormat = input(false, ...ngDevMode ? [{ debugName: "phoneFormat" }] : /* istanbul ignore next */ []);
4974
5057
  this.min = input(void 0, ...ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []);
@@ -5005,8 +5088,7 @@ var TextInputComponent = class TextInputComponent {
5005
5088
  this._eyeOffPath = iconPath("view-off");
5006
5089
  this._showRequirements = computed(() => this.passwordRequirements() && this.type() === "password" && this._typed(), ...ngDevMode ? [{ debugName: "_showRequirements" }] : /* istanbul ignore next */ []);
5007
5090
  this._describedBy = computed(() => {
5008
- const ids = [this._activeError() || this.hint() ? this._inputId + "-desc" : "", this._showRequirements() ? this._inputId + "-req" : ""].filter(Boolean);
5009
- return ids.length ? ids.join(" ") : null;
5091
+ return mergeDescribedBy([this._activeError() || this.hint() ? this._inputId + "-desc" : "", this._showRequirements() ? this._inputId + "-req" : ""].filter(Boolean).join(" "), this.ariaDescribedBy());
5010
5092
  }, ...ngDevMode ? [{ debugName: "_describedBy" }] : /* istanbul ignore next */ []);
5011
5093
  this._typed = signal(false, ...ngDevMode ? [{ debugName: "_typed" }] : /* istanbul ignore next */ []);
5012
5094
  this._defaultRules = DEFAULT_PASSWORD_RULES;
@@ -5300,6 +5382,13 @@ var TextInputComponent = class TextInputComponent {
5300
5382
  isRequired: false,
5301
5383
  transformFunction: null
5302
5384
  },
5385
+ ariaDescribedBy: {
5386
+ classPropertyName: "ariaDescribedBy",
5387
+ publicName: "ariaDescribedBy",
5388
+ isSignal: true,
5389
+ isRequired: false,
5390
+ transformFunction: null
5391
+ },
5303
5392
  error: {
5304
5393
  classPropertyName: "error",
5305
5394
  publicName: "error",
@@ -5687,6 +5776,14 @@ i0.ɵɵngDeclareClassMetadata({
5687
5776
  required: false
5688
5777
  }]
5689
5778
  }],
5779
+ ariaDescribedBy: [{
5780
+ type: i0.Input,
5781
+ args: [{
5782
+ isSignal: true,
5783
+ alias: "ariaDescribedBy",
5784
+ required: false
5785
+ }]
5786
+ }],
5690
5787
  error: [{
5691
5788
  type: i0.Input,
5692
5789
  args: [{
@@ -6174,6 +6271,10 @@ var TableToolbarComponent = class TableToolbarComponent {
6174
6271
  "dialogTestId",
6175
6272
  "hideClose",
6176
6273
  "closable",
6274
+ "layout",
6275
+ "closeOnBackdrop",
6276
+ "closeOnEscape",
6277
+ "busy",
6177
6278
  "returnFocusTo"
6178
6279
  ],
6179
6280
  outputs: ["close"]
@@ -6259,6 +6360,7 @@ var TableToolbarComponent = class TableToolbarComponent {
6259
6360
  "inputmode",
6260
6361
  "readonly",
6261
6362
  "hint",
6363
+ "ariaDescribedBy",
6262
6364
  "error",
6263
6365
  "phoneFormat",
6264
6366
  "min",
@@ -7330,6 +7432,7 @@ var SelectComponent = class SelectComponent {
7330
7432
  this.valueType = input("string", ...ngDevMode ? [{ debugName: "valueType" }] : /* istanbul ignore next */ []);
7331
7433
  this.required = input(false, ...ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []);
7332
7434
  this.hint = input("", ...ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []);
7435
+ this.ariaDescribedBy = input("", ...ngDevMode ? [{ debugName: "ariaDescribedBy" }] : /* istanbul ignore next */ []);
7333
7436
  this.error = input("", ...ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []);
7334
7437
  this.showErrors = input(false, ...ngDevMode ? [{ debugName: "showErrors" }] : /* istanbul ignore next */ []);
7335
7438
  this.size = input("default", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
@@ -7345,7 +7448,7 @@ var SelectComponent = class SelectComponent {
7345
7448
  return this.options().findIndex((o) => this._norm(String(o.value)) === v);
7346
7449
  }, ...ngDevMode ? [{ debugName: "_selectedIndex" }] : /* istanbul ignore next */ []);
7347
7450
  this._selectedDescription = computed(() => this.options()[this._selectedIndex()]?.description ?? "", ...ngDevMode ? [{ debugName: "_selectedDescription" }] : /* istanbul ignore next */ []);
7348
- this._describedBy = computed(() => [this._activeError() || this.hint() ? this._selectId + "-desc" : "", !this._activeError() && this._selectedDescription() ? this._selectId + "-opt-desc" : ""].filter(Boolean).join(" "), ...ngDevMode ? [{ debugName: "_describedBy" }] : /* istanbul ignore next */ []);
7451
+ this._describedBy = computed(() => mergeDescribedBy([this._activeError() || this.hint() ? this._selectId + "-desc" : "", !this._activeError() && this._selectedDescription() ? this._selectId + "-opt-desc" : ""].filter(Boolean).join(" "), this.ariaDescribedBy()), ...ngDevMode ? [{ debugName: "_describedBy" }] : /* istanbul ignore next */ []);
7349
7452
  this._reveal = createFieldReveal(this.showErrors);
7350
7453
  this._issue = computed(() => this._check(this._value()), ...ngDevMode ? [{ debugName: "_issue" }] : /* istanbul ignore next */ []);
7351
7454
  this.invalid = computed(() => !!this.error() || !!this._issue(), ...ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []);
@@ -7494,6 +7597,13 @@ var SelectComponent = class SelectComponent {
7494
7597
  isRequired: false,
7495
7598
  transformFunction: null
7496
7599
  },
7600
+ ariaDescribedBy: {
7601
+ classPropertyName: "ariaDescribedBy",
7602
+ publicName: "ariaDescribedBy",
7603
+ isSignal: true,
7604
+ isRequired: false,
7605
+ transformFunction: null
7606
+ },
7497
7607
  error: {
7498
7608
  classPropertyName: "error",
7499
7609
  publicName: "error",
@@ -7715,6 +7825,14 @@ i0.ɵɵngDeclareClassMetadata({
7715
7825
  required: false
7716
7826
  }]
7717
7827
  }],
7828
+ ariaDescribedBy: [{
7829
+ type: i0.Input,
7830
+ args: [{
7831
+ isSignal: true,
7832
+ alias: "ariaDescribedBy",
7833
+ required: false
7834
+ }]
7835
+ }],
7718
7836
  error: [{
7719
7837
  type: i0.Input,
7720
7838
  args: [{
@@ -10110,6 +10228,10 @@ var ImportExportComponent = class ImportExportComponent {
10110
10228
  "dialogTestId",
10111
10229
  "hideClose",
10112
10230
  "closable",
10231
+ "layout",
10232
+ "closeOnBackdrop",
10233
+ "closeOnEscape",
10234
+ "busy",
10113
10235
  "returnFocusTo"
10114
10236
  ],
10115
10237
  outputs: ["close"]
@@ -10156,6 +10278,7 @@ var ImportExportComponent = class ImportExportComponent {
10156
10278
  "valueType",
10157
10279
  "required",
10158
10280
  "hint",
10281
+ "ariaDescribedBy",
10159
10282
  "error",
10160
10283
  "showErrors",
10161
10284
  "size",
@@ -10650,6 +10773,10 @@ var ConfirmOutletComponent = class ConfirmOutletComponent {
10650
10773
  "dialogTestId",
10651
10774
  "hideClose",
10652
10775
  "closable",
10776
+ "layout",
10777
+ "closeOnBackdrop",
10778
+ "closeOnEscape",
10779
+ "busy",
10653
10780
  "returnFocusTo"
10654
10781
  ],
10655
10782
  outputs: ["close"]
@@ -11982,7 +12109,7 @@ var DataTableComponent = class DataTableComponent {
11982
12109
  label: "Default"
11983
12110
  }];
11984
12111
  for (const col of this.visibleCols()) {
11985
- if (!this._isSortable(col)) continue;
12112
+ if (!this._isSortable(col) || this._emptyColumnKeys().has(col.key)) continue;
11986
12113
  opts.push({
11987
12114
  value: `${col.key}:asc`,
11988
12115
  label: `${col.label} ↑`
@@ -11999,6 +12126,31 @@ var DataTableComponent = class DataTableComponent {
11999
12126
  cf: this.getColFilter(col)
12000
12127
  })).filter((f) => f.cf !== null), ...ngDevMode ? [{ debugName: "_phoneFilterCols" }] : /* istanbul ignore next */ []);
12001
12128
  this._showColumnControls = computed(() => !this._error() && (this._items().length > 0 || !!this._sortField() || Object.values(this._colFilterValues()).some((v) => v.length > 0)), ...ngDevMode ? [{ debugName: "_showColumnControls" }] : /* istanbul ignore next */ []);
12129
+ this._emptyColumnKeys = computed(() => {
12130
+ const items = this._items();
12131
+ const out = /* @__PURE__ */ new Set();
12132
+ if (items.length === 0) return out;
12133
+ for (const col of this.visibleCols()) {
12134
+ if (!this._isSortable(col) || this._sortField() === col.key) continue;
12135
+ let hasValue = false;
12136
+ for (const item of items) {
12137
+ let text;
12138
+ try {
12139
+ text = this.cardCellText(col, item);
12140
+ } catch {
12141
+ hasValue = true;
12142
+ break;
12143
+ }
12144
+ const t = text === null || text === void 0 ? "" : String(text).trim();
12145
+ if (t !== "" && t !== "—") {
12146
+ hasValue = true;
12147
+ break;
12148
+ }
12149
+ }
12150
+ if (!hasValue) out.add(col.key);
12151
+ }
12152
+ return out;
12153
+ }, ...ngDevMode ? [{ debugName: "_emptyColumnKeys" }] : /* istanbul ignore next */ []);
12002
12154
  this._hasPhoneControls = computed(() => this._phoneSortOptions().length > 1 || this._phoneFilterCols().length > 0, ...ngDevMode ? [{ debugName: "_hasPhoneControls" }] : /* istanbul ignore next */ []);
12003
12155
  this._injector = inject(Injector);
12004
12156
  this._silentNext = false;
@@ -12120,6 +12272,9 @@ var DataTableComponent = class DataTableComponent {
12120
12272
  this.load();
12121
12273
  this._fetchCounts();
12122
12274
  }
12275
+ _canShowSort(col) {
12276
+ return this._isSortable(col) && this._showColumnControls() && !this._emptyColumnKeys().has(col.key);
12277
+ }
12123
12278
  onPhoneSort(value) {
12124
12279
  if (!value) {
12125
12280
  this._sortField.set(null);
@@ -13017,11 +13172,11 @@ var DataTableComponent = class DataTableComponent {
13017
13172
  [style.width]="col.width ?? null"
13018
13173
  [style.min-width]="col.width ?? null"
13019
13174
  [style.max-width]="col.width ?? null"
13020
- [attr.aria-sort]="_isSortable(col) && _showColumnControls() ? sortAriaLabel(col.key) : null"
13175
+ [attr.aria-sort]="_canShowSort(col) ? sortAriaLabel(col.key) : null"
13021
13176
  [class.dt-th-sorted]="_sortField() === col.key"
13022
13177
  [class.dt-th-actions]="col.cellType === 'actions'">
13023
13178
  <div class="dt-th-inner">
13024
- @if (_isSortable(col) && _showColumnControls()) {
13179
+ @if (_canShowSort(col)) {
13025
13180
  <button
13026
13181
  class="dt-sort-btn"
13027
13182
  (click)="onSort(col.key)"
@@ -13799,6 +13954,7 @@ var DataTableComponent = class DataTableComponent {
13799
13954
  "valueType",
13800
13955
  "required",
13801
13956
  "hint",
13957
+ "ariaDescribedBy",
13802
13958
  "error",
13803
13959
  "showErrors",
13804
13960
  "size",
@@ -13844,6 +14000,10 @@ var DataTableComponent = class DataTableComponent {
13844
14000
  "dialogTestId",
13845
14001
  "hideClose",
13846
14002
  "closable",
14003
+ "layout",
14004
+ "closeOnBackdrop",
14005
+ "closeOnEscape",
14006
+ "busy",
13847
14007
  "returnFocusTo"
13848
14008
  ],
13849
14009
  outputs: ["close"]
@@ -14085,11 +14245,11 @@ i0.ɵɵngDeclareClassMetadata({
14085
14245
  [style.width]="col.width ?? null"
14086
14246
  [style.min-width]="col.width ?? null"
14087
14247
  [style.max-width]="col.width ?? null"
14088
- [attr.aria-sort]="_isSortable(col) && _showColumnControls() ? sortAriaLabel(col.key) : null"
14248
+ [attr.aria-sort]="_canShowSort(col) ? sortAriaLabel(col.key) : null"
14089
14249
  [class.dt-th-sorted]="_sortField() === col.key"
14090
14250
  [class.dt-th-actions]="col.cellType === 'actions'">
14091
14251
  <div class="dt-th-inner">
14092
- @if (_isSortable(col) && _showColumnControls()) {
14252
+ @if (_canShowSort(col)) {
14093
14253
  <button
14094
14254
  class="dt-sort-btn"
14095
14255
  (click)="onSort(col.key)"
@@ -17388,6 +17548,7 @@ var BusinessHoursComponent = class BusinessHoursComponent {
17388
17548
  "valueType",
17389
17549
  "required",
17390
17550
  "hint",
17551
+ "ariaDescribedBy",
17391
17552
  "error",
17392
17553
  "showErrors",
17393
17554
  "size",
@@ -19084,6 +19245,7 @@ var PhoneNumberPickerComponent = class PhoneNumberPickerComponent {
19084
19245
  "inputmode",
19085
19246
  "readonly",
19086
19247
  "hint",
19248
+ "ariaDescribedBy",
19087
19249
  "error",
19088
19250
  "phoneFormat",
19089
19251
  "min",
@@ -20682,6 +20844,7 @@ var TextareaInputComponent = class TextareaInputComponent {
20682
20844
  this.required = input(false, ...ngDevMode ? [{ debugName: "required" }] : /* istanbul ignore next */ []);
20683
20845
  this.readonly = input(false, ...ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []);
20684
20846
  this.hint = input("", ...ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []);
20847
+ this.ariaDescribedBy = input("", ...ngDevMode ? [{ debugName: "ariaDescribedBy" }] : /* istanbul ignore next */ []);
20685
20848
  this.hintAsDescription = input(false, ...ngDevMode ? [{ debugName: "hintAsDescription" }] : /* istanbul ignore next */ []);
20686
20849
  this.error = input("", ...ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []);
20687
20850
  this.monospace = input(false, ...ngDevMode ? [{ debugName: "monospace" }] : /* istanbul ignore next */ []);
@@ -20694,13 +20857,14 @@ var TextareaInputComponent = class TextareaInputComponent {
20694
20857
  this.disabled = computed(() => this._disabledInput() || this._cvaDisabled(), ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
20695
20858
  this._value = signal("", ...ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []);
20696
20859
  this._unlabelledHint = computed(() => !this.label() && !!this.hint(), ...ngDevMode ? [{ debugName: "_unlabelledHint" }] : /* istanbul ignore next */ []);
20697
- this._describedBy = computed(() => {
20860
+ this._describedBy = computed(() => mergeDescribedBy(this._ownDescribedBy(), this.ariaDescribedBy()), ...ngDevMode ? [{ debugName: "_describedBy" }] : /* istanbul ignore next */ []);
20861
+ this._ownDescribedBy = computed(() => {
20698
20862
  if (!this.hintAsDescription()) return this._activeError() ? this._inputId + "-desc" : this._unlabelledHint() ? this._inputId + "-hint" : null;
20699
20863
  const ids = [];
20700
20864
  if (this.hint() && (this.label() || !this._activeError())) ids.push(this._inputId + "-hint");
20701
20865
  if (this._activeError()) ids.push(this._inputId + "-desc");
20702
20866
  return ids.length ? ids.join(" ") : null;
20703
- }, ...ngDevMode ? [{ debugName: "_describedBy" }] : /* istanbul ignore next */ []);
20867
+ }, ...ngDevMode ? [{ debugName: "_ownDescribedBy" }] : /* istanbul ignore next */ []);
20704
20868
  this._reveal = createFieldReveal(this.showErrors);
20705
20869
  this._issue = computed(() => this._check(this._value()), ...ngDevMode ? [{ debugName: "_issue" }] : /* istanbul ignore next */ []);
20706
20870
  this.invalid = computed(() => !!this.error() || !!this._issue(), ...ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []);
@@ -20826,6 +20990,13 @@ var TextareaInputComponent = class TextareaInputComponent {
20826
20990
  isRequired: false,
20827
20991
  transformFunction: null
20828
20992
  },
20993
+ ariaDescribedBy: {
20994
+ classPropertyName: "ariaDescribedBy",
20995
+ publicName: "ariaDescribedBy",
20996
+ isSignal: true,
20997
+ isRequired: false,
20998
+ transformFunction: null
20999
+ },
20829
21000
  hintAsDescription: {
20830
21001
  classPropertyName: "hintAsDescription",
20831
21002
  publicName: "hintAsDescription",
@@ -21071,6 +21242,14 @@ i0.ɵɵngDeclareClassMetadata({
21071
21242
  required: false
21072
21243
  }]
21073
21244
  }],
21245
+ ariaDescribedBy: [{
21246
+ type: i0.Input,
21247
+ args: [{
21248
+ isSignal: true,
21249
+ alias: "ariaDescribedBy",
21250
+ required: false
21251
+ }]
21252
+ }],
21074
21253
  hintAsDescription: [{
21075
21254
  type: i0.Input,
21076
21255
  args: [{
@@ -21349,6 +21528,7 @@ var BulkMessagePanelComponent = class BulkMessagePanelComponent {
21349
21528
  "inputmode",
21350
21529
  "readonly",
21351
21530
  "hint",
21531
+ "ariaDescribedBy",
21352
21532
  "error",
21353
21533
  "phoneFormat",
21354
21534
  "min",
@@ -21381,6 +21561,7 @@ var BulkMessagePanelComponent = class BulkMessagePanelComponent {
21381
21561
  "required",
21382
21562
  "readonly",
21383
21563
  "hint",
21564
+ "ariaDescribedBy",
21384
21565
  "hintAsDescription",
21385
21566
  "error",
21386
21567
  "monospace",
@@ -21500,6 +21681,679 @@ i0.ɵɵngDeclareClassMetadata({
21500
21681
  }]
21501
21682
  }
21502
21683
  });
21684
+ var FormRowComponent = class FormRowComponent {
21685
+ constructor() {
21686
+ this.cols = input(2, ...ngDevMode ? [{ debugName: "cols" }] : /* istanbul ignore next */ []);
21687
+ }
21688
+ static {
21689
+ this.ɵfac = i0.ɵɵngDeclareFactory({
21690
+ minVersion: "12.0.0",
21691
+ version: "22.2.2",
21692
+ ngImport: i0,
21693
+ type: FormRowComponent,
21694
+ deps: [],
21695
+ target: i0.ɵɵFactoryTarget.Component
21696
+ });
21697
+ }
21698
+ static {
21699
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
21700
+ minVersion: "17.1.0",
21701
+ version: "22.2.2",
21702
+ type: FormRowComponent,
21703
+ isStandalone: true,
21704
+ selector: "ui-form-row",
21705
+ inputs: { cols: {
21706
+ classPropertyName: "cols",
21707
+ publicName: "cols",
21708
+ isSignal: true,
21709
+ isRequired: false,
21710
+ transformFunction: null
21711
+ } },
21712
+ ngImport: i0,
21713
+ template: `<div class="fr-row" [class.fr-row--4]="cols() === 4" [style.--fr-cols]="cols()"><ng-content /></div>`,
21714
+ isInline: true,
21715
+ styles: ["ui-form-row{display:block}.fr-row{display:grid;grid-template-columns:repeat(var(--fr-cols, 2),1fr);gap:12px}.fr-row>.ui-span-2{grid-column:span 2}.fr-row>.ui-span-3{grid-column:span 3}.fr-row>.ui-span-all{grid-column:1 / -1}@media(max-width:768px){.fr-row--4{grid-template-columns:repeat(2,1fr)}.fr-row--4>.ui-span-3{grid-column:1 / -1}}@media(max-width:480px){.fr-row{grid-template-columns:1fr}.fr-row>.ui-span-2,.fr-row>.ui-span-3,.fr-row>.ui-span-all{grid-column:1 / -1}}\n"],
21716
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
21717
+ encapsulation: i0.ViewEncapsulation.None
21718
+ });
21719
+ }
21720
+ };
21721
+ i0.ɵɵngDeclareClassMetadata({
21722
+ minVersion: "12.0.0",
21723
+ version: "22.2.2",
21724
+ ngImport: i0,
21725
+ type: FormRowComponent,
21726
+ decorators: [{
21727
+ type: Component,
21728
+ args: [{
21729
+ selector: "ui-form-row",
21730
+ standalone: true,
21731
+ changeDetection: ChangeDetectionStrategy.OnPush,
21732
+ encapsulation: ViewEncapsulation.None,
21733
+ template: `<div class="fr-row" [class.fr-row--4]="cols() === 4" [style.--fr-cols]="cols()"><ng-content /></div>`,
21734
+ styles: ["ui-form-row{display:block}.fr-row{display:grid;grid-template-columns:repeat(var(--fr-cols, 2),1fr);gap:12px}.fr-row>.ui-span-2{grid-column:span 2}.fr-row>.ui-span-3{grid-column:span 3}.fr-row>.ui-span-all{grid-column:1 / -1}@media(max-width:768px){.fr-row--4{grid-template-columns:repeat(2,1fr)}.fr-row--4>.ui-span-3{grid-column:1 / -1}}@media(max-width:480px){.fr-row{grid-template-columns:1fr}.fr-row>.ui-span-2,.fr-row>.ui-span-3,.fr-row>.ui-span-all{grid-column:1 / -1}}\n"]
21735
+ }]
21736
+ }],
21737
+ propDecorators: { cols: [{
21738
+ type: i0.Input,
21739
+ args: [{
21740
+ isSignal: true,
21741
+ alias: "cols",
21742
+ required: false
21743
+ }]
21744
+ }] }
21745
+ });
21746
+ var FormSectionComponent = class FormSectionComponent {
21747
+ constructor() {
21748
+ this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
21749
+ this.divider = input(false, ...ngDevMode ? [{ debugName: "divider" }] : /* istanbul ignore next */ []);
21750
+ }
21751
+ static {
21752
+ this.ɵfac = i0.ɵɵngDeclareFactory({
21753
+ minVersion: "12.0.0",
21754
+ version: "22.2.2",
21755
+ ngImport: i0,
21756
+ type: FormSectionComponent,
21757
+ deps: [],
21758
+ target: i0.ɵɵFactoryTarget.Component
21759
+ });
21760
+ }
21761
+ static {
21762
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
21763
+ minVersion: "17.0.0",
21764
+ version: "22.2.2",
21765
+ type: FormSectionComponent,
21766
+ isStandalone: true,
21767
+ selector: "ui-form-section",
21768
+ inputs: {
21769
+ label: {
21770
+ classPropertyName: "label",
21771
+ publicName: "label",
21772
+ isSignal: true,
21773
+ isRequired: false,
21774
+ transformFunction: null
21775
+ },
21776
+ divider: {
21777
+ classPropertyName: "divider",
21778
+ publicName: "divider",
21779
+ isSignal: true,
21780
+ isRequired: false,
21781
+ transformFunction: null
21782
+ }
21783
+ },
21784
+ ngImport: i0,
21785
+ template: `
21786
+ @if (divider()) { <div class="fs-divider"></div> }
21787
+ @if (label()) { <p class="fs-label">{{ label() }}</p> }
21788
+ <div class="fs-fields"><ng-content /></div>
21789
+ `,
21790
+ isInline: true,
21791
+ styles: [":host{display:block}.fs-divider{height:1px;background:#f1f5f9;margin:8px -24px 16px}.fs-label{font-size:.6875rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#64748b;margin:0 0 12px}.fs-fields{display:flex;flex-direction:column;gap:14px}\n"],
21792
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
21793
+ });
21794
+ }
21795
+ };
21796
+ i0.ɵɵngDeclareClassMetadata({
21797
+ minVersion: "12.0.0",
21798
+ version: "22.2.2",
21799
+ ngImport: i0,
21800
+ type: FormSectionComponent,
21801
+ decorators: [{
21802
+ type: Component,
21803
+ args: [{
21804
+ selector: "ui-form-section",
21805
+ standalone: true,
21806
+ changeDetection: ChangeDetectionStrategy.OnPush,
21807
+ template: `
21808
+ @if (divider()) { <div class="fs-divider"></div> }
21809
+ @if (label()) { <p class="fs-label">{{ label() }}</p> }
21810
+ <div class="fs-fields"><ng-content /></div>
21811
+ `,
21812
+ styles: [":host{display:block}.fs-divider{height:1px;background:#f1f5f9;margin:8px -24px 16px}.fs-label{font-size:.6875rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#64748b;margin:0 0 12px}.fs-fields{display:flex;flex-direction:column;gap:14px}\n"]
21813
+ }]
21814
+ }],
21815
+ propDecorators: {
21816
+ label: [{
21817
+ type: i0.Input,
21818
+ args: [{
21819
+ isSignal: true,
21820
+ alias: "label",
21821
+ required: false
21822
+ }]
21823
+ }],
21824
+ divider: [{
21825
+ type: i0.Input,
21826
+ args: [{
21827
+ isSignal: true,
21828
+ alias: "divider",
21829
+ required: false
21830
+ }]
21831
+ }]
21832
+ }
21833
+ });
21834
+ const DEFAULT_BANK_MANDATE_TEXT = "By checking this box, I authorize the above business to initiate ACH debit entries to my bank account for agreed-upon payments. I understand I may revoke this authorization at any time by contacting the business.";
21835
+ const DEFAULT_BANK_ACCOUNT_TYPE_OPTIONS = [{
21836
+ value: "checking",
21837
+ label: "Checking"
21838
+ }, {
21839
+ value: "savings",
21840
+ label: "Savings"
21841
+ }];
21842
+ const DEFAULT_BANK_HOLDER_TYPE_OPTIONS = [{
21843
+ value: "individual",
21844
+ label: "Individual"
21845
+ }, {
21846
+ value: "company",
21847
+ label: "Business"
21848
+ }];
21849
+ const digitsOnly$1 = (max) => (raw) => raw.replace(/\D/g, "").slice(0, max);
21850
+ var BankAccountFormComponent = class BankAccountFormComponent {
21851
+ constructor() {
21852
+ this.showErrors = input(false, ...ngDevMode ? [{ debugName: "showErrors" }] : /* istanbul ignore next */ []);
21853
+ this.disabled = input(false, ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
21854
+ this.busy = input(false, ...ngDevMode ? [{ debugName: "busy" }] : /* istanbul ignore next */ []);
21855
+ this.mandateText = input(DEFAULT_BANK_MANDATE_TEXT, ...ngDevMode ? [{ debugName: "mandateText" }] : /* istanbul ignore next */ []);
21856
+ this.accountTypeOptions = input(DEFAULT_BANK_ACCOUNT_TYPE_OPTIONS, ...ngDevMode ? [{ debugName: "accountTypeOptions" }] : /* istanbul ignore next */ []);
21857
+ this.holderTypeOptions = input(DEFAULT_BANK_HOLDER_TYPE_OPTIONS, ...ngDevMode ? [{ debugName: "holderTypeOptions" }] : /* istanbul ignore next */ []);
21858
+ this.accountHolderNameDefault = input("", ...ngDevMode ? [{ debugName: "accountHolderNameDefault" }] : /* istanbul ignore next */ []);
21859
+ this.testIdPrefix = input("bank", ...ngDevMode ? [{ debugName: "testIdPrefix" }] : /* istanbul ignore next */ []);
21860
+ this.submitted = output();
21861
+ this.validChange = output();
21862
+ this.routingNumber = signal("", ...ngDevMode ? [{ debugName: "routingNumber" }] : /* istanbul ignore next */ []);
21863
+ this.accountNumber = signal("", ...ngDevMode ? [{ debugName: "accountNumber" }] : /* istanbul ignore next */ []);
21864
+ this.confirmAccount = signal("", ...ngDevMode ? [{ debugName: "confirmAccount" }] : /* istanbul ignore next */ []);
21865
+ this.accountHolderName = signal("", ...ngDevMode ? [{ debugName: "accountHolderName" }] : /* istanbul ignore next */ []);
21866
+ this.accountType = signal("checking", ...ngDevMode ? [{ debugName: "accountType" }] : /* istanbul ignore next */ []);
21867
+ this.holderType = signal("individual", ...ngDevMode ? [{ debugName: "holderType" }] : /* istanbul ignore next */ []);
21868
+ this.mandateAccepted = signal(false, ...ngDevMode ? [{ debugName: "mandateAccepted" }] : /* istanbul ignore next */ []);
21869
+ this._touched = signal(false, ...ngDevMode ? [{ debugName: "_touched" }] : /* istanbul ignore next */ []);
21870
+ this.routingFormatter = digitsOnly$1(9);
21871
+ this.accountFormatter = digitsOnly$1(17);
21872
+ this.locked = computed(() => this.disabled() || this.busy(), ...ngDevMode ? [{ debugName: "locked" }] : /* istanbul ignore next */ []);
21873
+ this.reveal = computed(() => this.showErrors() || this._touched(), ...ngDevMode ? [{ debugName: "reveal" }] : /* istanbul ignore next */ []);
21874
+ this.routingError = computed(() => {
21875
+ const v = this.routingNumber().trim();
21876
+ return v && v.length !== 9 ? "Routing number must be 9 digits." : "";
21877
+ }, ...ngDevMode ? [{ debugName: "routingError" }] : /* istanbul ignore next */ []);
21878
+ this.accountError = computed(() => {
21879
+ const v = this.accountNumber().trim();
21880
+ return v && v.length < 4 ? "Account number must be at least 4 digits." : "";
21881
+ }, ...ngDevMode ? [{ debugName: "accountError" }] : /* istanbul ignore next */ []);
21882
+ this.confirmError = computed(() => {
21883
+ const v = this.confirmAccount().trim();
21884
+ return v && v !== this.accountNumber().trim() ? "Account numbers do not match." : "";
21885
+ }, ...ngDevMode ? [{ debugName: "confirmError" }] : /* istanbul ignore next */ []);
21886
+ this.errorMessage = computed(() => {
21887
+ if (!this.accountHolderName().trim()) return "Account holder name is required.";
21888
+ if (!this.routingNumber().trim()) return "Routing number is required.";
21889
+ if (this.routingError()) return this.routingError();
21890
+ if (!this.accountNumber().trim()) return "Account number is required.";
21891
+ if (this.accountError()) return this.accountError();
21892
+ if (!this.confirmAccount().trim()) return "Confirm account number is required.";
21893
+ if (this.confirmError()) return this.confirmError();
21894
+ if (!this.accountTypeOptions().some((o) => String(o.value) === this.accountType())) return "Select a valid account type.";
21895
+ if (!this.holderTypeOptions().some((o) => String(o.value) === this.holderType())) return "Select a valid holder type.";
21896
+ if (!this.mandateAccepted()) return "You must authorize ACH debits to continue.";
21897
+ return "";
21898
+ }, ...ngDevMode ? [{ debugName: "errorMessage" }] : /* istanbul ignore next */ []);
21899
+ this.invalid = computed(() => this.errorMessage() !== "", ...ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []);
21900
+ this.valid = computed(() => !this.invalid(), ...ngDevMode ? [{ debugName: "valid" }] : /* istanbul ignore next */ []);
21901
+ this._fields = viewChildren(UiFieldValidity, ...ngDevMode ? [{ debugName: "_fields" }] : /* istanbul ignore next */ []);
21902
+ effect(() => {
21903
+ const d = this.accountHolderNameDefault();
21904
+ untracked(() => this.accountHolderName.set(d));
21905
+ });
21906
+ effect(() => {
21907
+ const v = this.valid();
21908
+ untracked(() => this.validChange.emit(v));
21909
+ });
21910
+ }
21911
+ id(name) {
21912
+ return `${this.testIdPrefix()}-${name}`;
21913
+ }
21914
+ onEnter(event) {
21915
+ const t = event.target;
21916
+ if (t instanceof HTMLInputElement && t.type === "text") {
21917
+ event.preventDefault();
21918
+ this.submit();
21919
+ }
21920
+ }
21921
+ submit() {
21922
+ if (this.locked()) return;
21923
+ if (this.invalid() || this._fields().some((f) => f.invalid())) {
21924
+ this._touched.set(true);
21925
+ return;
21926
+ }
21927
+ this.submitted.emit({
21928
+ routingNumber: this.routingNumber().trim(),
21929
+ accountNumber: this.accountNumber().trim(),
21930
+ accountType: this.accountType(),
21931
+ accountHolderName: this.accountHolderName().trim(),
21932
+ holderType: this.holderType(),
21933
+ mandateAccepted: true
21934
+ });
21935
+ }
21936
+ reset() {
21937
+ this.routingNumber.set("");
21938
+ this.accountNumber.set("");
21939
+ this.confirmAccount.set("");
21940
+ this.accountHolderName.set(this.accountHolderNameDefault());
21941
+ this.accountType.set("checking");
21942
+ this.holderType.set("individual");
21943
+ this.mandateAccepted.set(false);
21944
+ this._touched.set(false);
21945
+ }
21946
+ static {
21947
+ this.ɵfac = i0.ɵɵngDeclareFactory({
21948
+ minVersion: "12.0.0",
21949
+ version: "22.2.2",
21950
+ ngImport: i0,
21951
+ type: BankAccountFormComponent,
21952
+ deps: [],
21953
+ target: i0.ɵɵFactoryTarget.Component
21954
+ });
21955
+ }
21956
+ static {
21957
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
21958
+ minVersion: "17.2.0",
21959
+ version: "22.2.2",
21960
+ type: BankAccountFormComponent,
21961
+ isStandalone: true,
21962
+ selector: "ui-bank-account-form",
21963
+ inputs: {
21964
+ showErrors: {
21965
+ classPropertyName: "showErrors",
21966
+ publicName: "showErrors",
21967
+ isSignal: true,
21968
+ isRequired: false,
21969
+ transformFunction: null
21970
+ },
21971
+ disabled: {
21972
+ classPropertyName: "disabled",
21973
+ publicName: "disabled",
21974
+ isSignal: true,
21975
+ isRequired: false,
21976
+ transformFunction: null
21977
+ },
21978
+ busy: {
21979
+ classPropertyName: "busy",
21980
+ publicName: "busy",
21981
+ isSignal: true,
21982
+ isRequired: false,
21983
+ transformFunction: null
21984
+ },
21985
+ mandateText: {
21986
+ classPropertyName: "mandateText",
21987
+ publicName: "mandateText",
21988
+ isSignal: true,
21989
+ isRequired: false,
21990
+ transformFunction: null
21991
+ },
21992
+ accountTypeOptions: {
21993
+ classPropertyName: "accountTypeOptions",
21994
+ publicName: "accountTypeOptions",
21995
+ isSignal: true,
21996
+ isRequired: false,
21997
+ transformFunction: null
21998
+ },
21999
+ holderTypeOptions: {
22000
+ classPropertyName: "holderTypeOptions",
22001
+ publicName: "holderTypeOptions",
22002
+ isSignal: true,
22003
+ isRequired: false,
22004
+ transformFunction: null
22005
+ },
22006
+ accountHolderNameDefault: {
22007
+ classPropertyName: "accountHolderNameDefault",
22008
+ publicName: "accountHolderNameDefault",
22009
+ isSignal: true,
22010
+ isRequired: false,
22011
+ transformFunction: null
22012
+ },
22013
+ testIdPrefix: {
22014
+ classPropertyName: "testIdPrefix",
22015
+ publicName: "testIdPrefix",
22016
+ isSignal: true,
22017
+ isRequired: false,
22018
+ transformFunction: null
22019
+ }
22020
+ },
22021
+ outputs: {
22022
+ submitted: "submitted",
22023
+ validChange: "validChange"
22024
+ },
22025
+ host: { properties: { "attr.aria-busy": "busy() ? \"true\" : null" } },
22026
+ providers: [{
22027
+ provide: UiFieldValidity,
22028
+ useExisting: forwardRef(() => BankAccountFormComponent)
22029
+ }],
22030
+ viewQueries: [{
22031
+ propertyName: "_fields",
22032
+ predicate: UiFieldValidity,
22033
+ descendants: true,
22034
+ isSignal: true
22035
+ }],
22036
+ ngImport: i0,
22037
+ template: `
22038
+ <form novalidate (submit)="$event.preventDefault(); submit()" (keydown.enter)="onEnter($event)">
22039
+ <ui-form-section>
22040
+ <ui-text-input label="Account holder name" [inputTestId]="id('holder-name')" autocomplete="name" [required]="true" [maxlength]="100"
22041
+ [showErrors]="reveal()" [disabled]="locked()" [ngModel]="accountHolderName()" (ngModelChange)="accountHolderName.set($event ?? '')" [ngModelOptions]="{ standalone: true }" />
22042
+ <ui-text-input label="Routing number" [inputTestId]="id('routing')" inputmode="numeric" placeholder="9-digit routing number" [required]="true"
22043
+ [maxlength]="9" [formatter]="routingFormatter" [error]="routingError()" [showErrors]="reveal()" [disabled]="locked()"
22044
+ [ngModel]="routingNumber()" (ngModelChange)="routingNumber.set($event ?? '')" [ngModelOptions]="{ standalone: true }" />
22045
+ <ui-text-input label="Account number" [inputTestId]="id('account')" inputmode="numeric" placeholder="Account number" [required]="true"
22046
+ [maxlength]="17" [formatter]="accountFormatter" [error]="accountError()" [showErrors]="reveal()" [disabled]="locked()"
22047
+ [ngModel]="accountNumber()" (ngModelChange)="accountNumber.set($event ?? '')" [ngModelOptions]="{ standalone: true }" />
22048
+ <ui-text-input label="Confirm account number" [inputTestId]="id('confirm')" inputmode="numeric" placeholder="Re-enter account number" [required]="true"
22049
+ [maxlength]="17" [formatter]="accountFormatter" [error]="confirmError()" [showErrors]="reveal()" [disabled]="locked()"
22050
+ [ngModel]="confirmAccount()" (ngModelChange)="confirmAccount.set($event ?? '')" [ngModelOptions]="{ standalone: true }" />
22051
+ <ui-form-row>
22052
+ <ui-select label="Account type" [attr.data-testid]="id('account-type')" [options]="accountTypeOptions()" [required]="true" [showErrors]="reveal()"
22053
+ [disabled]="locked()" [ngModel]="accountType()" (ngModelChange)="accountType.set($event)" [ngModelOptions]="{ standalone: true }" />
22054
+ <ui-select label="Holder type" [attr.data-testid]="id('holder-type')" [options]="holderTypeOptions()" [required]="true" [showErrors]="reveal()"
22055
+ [disabled]="locked()" [ngModel]="holderType()" (ngModelChange)="holderType.set($event)" [ngModelOptions]="{ standalone: true }" />
22056
+ </ui-form-row>
22057
+ <ui-checkbox [testId]="id('mandate')" [label]="mandateText()" [required]="true" requiredMessage="You must authorize ACH debits to continue."
22058
+ [showErrors]="reveal()" [disabled]="locked()" [ngModel]="mandateAccepted()" (ngModelChange)="mandateAccepted.set(!!$event)" [ngModelOptions]="{ standalone: true }" />
22059
+ </ui-form-section>
22060
+ </form>
22061
+ `,
22062
+ isInline: true,
22063
+ styles: [":host{display:block}\n"],
22064
+ dependencies: [
22065
+ {
22066
+ kind: "ngmodule",
22067
+ type: FormsModule
22068
+ },
22069
+ {
22070
+ kind: "directive",
22071
+ type: i1.ɵNgNoValidate,
22072
+ selector: "form:not([ngNoForm]):not([ngNativeValidate])"
22073
+ },
22074
+ {
22075
+ kind: "directive",
22076
+ type: i1.NgControlStatus,
22077
+ selector: "[formControlName],[ngModel],[formControl]"
22078
+ },
22079
+ {
22080
+ kind: "directive",
22081
+ type: i1.NgControlStatusGroup,
22082
+ selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]"
22083
+ },
22084
+ {
22085
+ kind: "directive",
22086
+ type: i1.RequiredValidator,
22087
+ selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]",
22088
+ inputs: ["required"]
22089
+ },
22090
+ {
22091
+ kind: "directive",
22092
+ type: i1.MaxLengthValidator,
22093
+ selector: "[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]",
22094
+ inputs: ["maxlength"]
22095
+ },
22096
+ {
22097
+ kind: "directive",
22098
+ type: i1.NgModel,
22099
+ selector: "[ngModel]:not([formControlName]):not([formControl])",
22100
+ inputs: [
22101
+ "name",
22102
+ "disabled",
22103
+ "ngModel",
22104
+ "ngModelOptions"
22105
+ ],
22106
+ outputs: ["ngModelChange"],
22107
+ exportAs: ["ngModel"]
22108
+ },
22109
+ {
22110
+ kind: "directive",
22111
+ type: i1.NgForm,
22112
+ selector: "form:not([ngNoForm]):not([formGroup]):not([formArray]),ng-form,[ngForm]",
22113
+ inputs: ["ngFormOptions"],
22114
+ outputs: ["ngSubmit"],
22115
+ exportAs: ["ngForm"]
22116
+ },
22117
+ {
22118
+ kind: "component",
22119
+ type: CheckboxComponent,
22120
+ selector: "ui-checkbox, ui-checkbox-group",
22121
+ inputs: [
22122
+ "label",
22123
+ "ariaLabel",
22124
+ "testId",
22125
+ "labelTestId",
22126
+ "headingLevel",
22127
+ "indeterminate",
22128
+ "checked",
22129
+ "options",
22130
+ "legend",
22131
+ "orientation",
22132
+ "values",
22133
+ "description",
22134
+ "indent",
22135
+ "required",
22136
+ "requiredMessage",
22137
+ "hint",
22138
+ "error",
22139
+ "showErrors",
22140
+ "disabled"
22141
+ ],
22142
+ outputs: [
22143
+ "checkedChange",
22144
+ "valuesChange",
22145
+ "invalidChange"
22146
+ ]
22147
+ },
22148
+ {
22149
+ kind: "component",
22150
+ type: FormRowComponent,
22151
+ selector: "ui-form-row",
22152
+ inputs: ["cols"]
22153
+ },
22154
+ {
22155
+ kind: "component",
22156
+ type: FormSectionComponent,
22157
+ selector: "ui-form-section",
22158
+ inputs: ["label", "divider"]
22159
+ },
22160
+ {
22161
+ kind: "component",
22162
+ type: SelectComponent,
22163
+ selector: "ui-select",
22164
+ inputs: [
22165
+ "label",
22166
+ "ariaLabel",
22167
+ "placeholder",
22168
+ "options",
22169
+ "valueType",
22170
+ "required",
22171
+ "hint",
22172
+ "ariaDescribedBy",
22173
+ "error",
22174
+ "showErrors",
22175
+ "size",
22176
+ "disabled"
22177
+ ],
22178
+ outputs: ["invalidChange", "valueChange"]
22179
+ },
22180
+ {
22181
+ kind: "component",
22182
+ type: TextInputComponent,
22183
+ selector: "ui-text-input",
22184
+ inputs: [
22185
+ "label",
22186
+ "ariaLabel",
22187
+ "inputTestId",
22188
+ "placeholder",
22189
+ "prefix",
22190
+ "revealable",
22191
+ "passwordRequirements",
22192
+ "passwordRules",
22193
+ "type",
22194
+ "maxlength",
22195
+ "required",
22196
+ "autocomplete",
22197
+ "inputmode",
22198
+ "readonly",
22199
+ "hint",
22200
+ "ariaDescribedBy",
22201
+ "error",
22202
+ "phoneFormat",
22203
+ "min",
22204
+ "max",
22205
+ "maxDecimals",
22206
+ "step",
22207
+ "valueType",
22208
+ "formatter",
22209
+ "integer",
22210
+ "showErrors",
22211
+ "disabled"
22212
+ ],
22213
+ outputs: [
22214
+ "valueChange",
22215
+ "focused",
22216
+ "blurred",
22217
+ "invalidChange"
22218
+ ]
22219
+ }
22220
+ ],
22221
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
22222
+ });
22223
+ }
22224
+ };
22225
+ i0.ɵɵngDeclareClassMetadata({
22226
+ minVersion: "12.0.0",
22227
+ version: "22.2.2",
22228
+ ngImport: i0,
22229
+ type: BankAccountFormComponent,
22230
+ decorators: [{
22231
+ type: Component,
22232
+ args: [{
22233
+ selector: "ui-bank-account-form",
22234
+ standalone: true,
22235
+ changeDetection: ChangeDetectionStrategy.OnPush,
22236
+ imports: [
22237
+ FormsModule,
22238
+ CheckboxComponent,
22239
+ FormRowComponent,
22240
+ FormSectionComponent,
22241
+ SelectComponent,
22242
+ TextInputComponent
22243
+ ],
22244
+ providers: [{
22245
+ provide: UiFieldValidity,
22246
+ useExisting: forwardRef(() => BankAccountFormComponent)
22247
+ }],
22248
+ host: { "[attr.aria-busy]": "busy() ? \"true\" : null" },
22249
+ template: `
22250
+ <form novalidate (submit)="$event.preventDefault(); submit()" (keydown.enter)="onEnter($event)">
22251
+ <ui-form-section>
22252
+ <ui-text-input label="Account holder name" [inputTestId]="id('holder-name')" autocomplete="name" [required]="true" [maxlength]="100"
22253
+ [showErrors]="reveal()" [disabled]="locked()" [ngModel]="accountHolderName()" (ngModelChange)="accountHolderName.set($event ?? '')" [ngModelOptions]="{ standalone: true }" />
22254
+ <ui-text-input label="Routing number" [inputTestId]="id('routing')" inputmode="numeric" placeholder="9-digit routing number" [required]="true"
22255
+ [maxlength]="9" [formatter]="routingFormatter" [error]="routingError()" [showErrors]="reveal()" [disabled]="locked()"
22256
+ [ngModel]="routingNumber()" (ngModelChange)="routingNumber.set($event ?? '')" [ngModelOptions]="{ standalone: true }" />
22257
+ <ui-text-input label="Account number" [inputTestId]="id('account')" inputmode="numeric" placeholder="Account number" [required]="true"
22258
+ [maxlength]="17" [formatter]="accountFormatter" [error]="accountError()" [showErrors]="reveal()" [disabled]="locked()"
22259
+ [ngModel]="accountNumber()" (ngModelChange)="accountNumber.set($event ?? '')" [ngModelOptions]="{ standalone: true }" />
22260
+ <ui-text-input label="Confirm account number" [inputTestId]="id('confirm')" inputmode="numeric" placeholder="Re-enter account number" [required]="true"
22261
+ [maxlength]="17" [formatter]="accountFormatter" [error]="confirmError()" [showErrors]="reveal()" [disabled]="locked()"
22262
+ [ngModel]="confirmAccount()" (ngModelChange)="confirmAccount.set($event ?? '')" [ngModelOptions]="{ standalone: true }" />
22263
+ <ui-form-row>
22264
+ <ui-select label="Account type" [attr.data-testid]="id('account-type')" [options]="accountTypeOptions()" [required]="true" [showErrors]="reveal()"
22265
+ [disabled]="locked()" [ngModel]="accountType()" (ngModelChange)="accountType.set($event)" [ngModelOptions]="{ standalone: true }" />
22266
+ <ui-select label="Holder type" [attr.data-testid]="id('holder-type')" [options]="holderTypeOptions()" [required]="true" [showErrors]="reveal()"
22267
+ [disabled]="locked()" [ngModel]="holderType()" (ngModelChange)="holderType.set($event)" [ngModelOptions]="{ standalone: true }" />
22268
+ </ui-form-row>
22269
+ <ui-checkbox [testId]="id('mandate')" [label]="mandateText()" [required]="true" requiredMessage="You must authorize ACH debits to continue."
22270
+ [showErrors]="reveal()" [disabled]="locked()" [ngModel]="mandateAccepted()" (ngModelChange)="mandateAccepted.set(!!$event)" [ngModelOptions]="{ standalone: true }" />
22271
+ </ui-form-section>
22272
+ </form>
22273
+ `,
22274
+ styles: [":host{display:block}\n"]
22275
+ }]
22276
+ }],
22277
+ ctorParameters: () => [],
22278
+ propDecorators: {
22279
+ showErrors: [{
22280
+ type: i0.Input,
22281
+ args: [{
22282
+ isSignal: true,
22283
+ alias: "showErrors",
22284
+ required: false
22285
+ }]
22286
+ }],
22287
+ disabled: [{
22288
+ type: i0.Input,
22289
+ args: [{
22290
+ isSignal: true,
22291
+ alias: "disabled",
22292
+ required: false
22293
+ }]
22294
+ }],
22295
+ busy: [{
22296
+ type: i0.Input,
22297
+ args: [{
22298
+ isSignal: true,
22299
+ alias: "busy",
22300
+ required: false
22301
+ }]
22302
+ }],
22303
+ mandateText: [{
22304
+ type: i0.Input,
22305
+ args: [{
22306
+ isSignal: true,
22307
+ alias: "mandateText",
22308
+ required: false
22309
+ }]
22310
+ }],
22311
+ accountTypeOptions: [{
22312
+ type: i0.Input,
22313
+ args: [{
22314
+ isSignal: true,
22315
+ alias: "accountTypeOptions",
22316
+ required: false
22317
+ }]
22318
+ }],
22319
+ holderTypeOptions: [{
22320
+ type: i0.Input,
22321
+ args: [{
22322
+ isSignal: true,
22323
+ alias: "holderTypeOptions",
22324
+ required: false
22325
+ }]
22326
+ }],
22327
+ accountHolderNameDefault: [{
22328
+ type: i0.Input,
22329
+ args: [{
22330
+ isSignal: true,
22331
+ alias: "accountHolderNameDefault",
22332
+ required: false
22333
+ }]
22334
+ }],
22335
+ testIdPrefix: [{
22336
+ type: i0.Input,
22337
+ args: [{
22338
+ isSignal: true,
22339
+ alias: "testIdPrefix",
22340
+ required: false
22341
+ }]
22342
+ }],
22343
+ submitted: [{
22344
+ type: i0.Output,
22345
+ args: ["submitted"]
22346
+ }],
22347
+ validChange: [{
22348
+ type: i0.Output,
22349
+ args: ["validChange"]
22350
+ }],
22351
+ _fields: [{
22352
+ type: i0.ViewChildren,
22353
+ args: [i0.forwardRef(() => UiFieldValidity), { isSignal: true }]
22354
+ }]
22355
+ }
22356
+ });
21503
22357
  const SIZE_REM = {
21504
22358
  sm: "0.8125rem",
21505
22359
  md: "0.875rem",
@@ -22823,6 +23677,7 @@ var DateInputComponent = class DateInputComponent {
22823
23677
  this.min = input("", ...ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []);
22824
23678
  this.max = input("", ...ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []);
22825
23679
  this.hint = input("", ...ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []);
23680
+ this.ariaDescribedBy = input("", ...ngDevMode ? [{ debugName: "ariaDescribedBy" }] : /* istanbul ignore next */ []);
22826
23681
  this.error = input("", ...ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []);
22827
23682
  this.showErrors = input(false, ...ngDevMode ? [{ debugName: "showErrors" }] : /* istanbul ignore next */ []);
22828
23683
  this._disabledInput = input(false, {
@@ -22832,6 +23687,7 @@ var DateInputComponent = class DateInputComponent {
22832
23687
  this._cvaDisabled = signal(false, ...ngDevMode ? [{ debugName: "_cvaDisabled" }] : /* istanbul ignore next */ []);
22833
23688
  this.disabled = computed(() => this._disabledInput() || this._cvaDisabled(), ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
22834
23689
  this._value = signal("", ...ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []);
23690
+ this._describedBy = computed(() => mergeDescribedBy(this._activeError() || this.hint() ? this._inputId + "-desc" : null, this.ariaDescribedBy()), ...ngDevMode ? [{ debugName: "_describedBy" }] : /* istanbul ignore next */ []);
22835
23691
  this._reveal = createFieldReveal(this.showErrors);
22836
23692
  this._issue = computed(() => this._check(this._value()), ...ngDevMode ? [{ debugName: "_issue" }] : /* istanbul ignore next */ []);
22837
23693
  this.invalid = computed(() => !!this.error() || !!this._issue(), ...ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []);
@@ -22961,6 +23817,13 @@ var DateInputComponent = class DateInputComponent {
22961
23817
  isRequired: false,
22962
23818
  transformFunction: null
22963
23819
  },
23820
+ ariaDescribedBy: {
23821
+ classPropertyName: "ariaDescribedBy",
23822
+ publicName: "ariaDescribedBy",
23823
+ isSignal: true,
23824
+ isRequired: false,
23825
+ transformFunction: null
23826
+ },
22964
23827
  error: {
22965
23828
  classPropertyName: "error",
22966
23829
  publicName: "error",
@@ -23023,7 +23886,7 @@ var DateInputComponent = class DateInputComponent {
23023
23886
  [attr.max]="max() || null"
23024
23887
  [attr.required]="required() || null"
23025
23888
  [attr.aria-invalid]="_activeError() ? 'true' : null"
23026
- [attr.aria-describedby]="(_activeError() || hint()) ? _inputId + '-desc' : null"
23889
+ [attr.aria-describedby]="_describedBy()"
23027
23890
  (change)="onChange($event)"
23028
23891
  (blur)="onBlur()"
23029
23892
  />
@@ -23085,7 +23948,7 @@ i0.ɵɵngDeclareClassMetadata({
23085
23948
  [attr.max]="max() || null"
23086
23949
  [attr.required]="required() || null"
23087
23950
  [attr.aria-invalid]="_activeError() ? 'true' : null"
23088
- [attr.aria-describedby]="(_activeError() || hint()) ? _inputId + '-desc' : null"
23951
+ [attr.aria-describedby]="_describedBy()"
23089
23952
  (change)="onChange($event)"
23090
23953
  (blur)="onBlur()"
23091
23954
  />
@@ -23141,6 +24004,14 @@ i0.ɵɵngDeclareClassMetadata({
23141
24004
  required: false
23142
24005
  }]
23143
24006
  }],
24007
+ ariaDescribedBy: [{
24008
+ type: i0.Input,
24009
+ args: [{
24010
+ isSignal: true,
24011
+ alias: "ariaDescribedBy",
24012
+ required: false
24013
+ }]
24014
+ }],
23144
24015
  error: [{
23145
24016
  type: i0.Input,
23146
24017
  args: [{
@@ -23182,6 +24053,7 @@ var DatetimeInputComponent = class DatetimeInputComponent {
23182
24053
  this.min = input("", ...ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []);
23183
24054
  this.max = input("", ...ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []);
23184
24055
  this.hint = input("", ...ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []);
24056
+ this.ariaDescribedBy = input("", ...ngDevMode ? [{ debugName: "ariaDescribedBy" }] : /* istanbul ignore next */ []);
23185
24057
  this.error = input("", ...ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []);
23186
24058
  this.showErrors = input(false, ...ngDevMode ? [{ debugName: "showErrors" }] : /* istanbul ignore next */ []);
23187
24059
  this._disabledInput = input(false, {
@@ -23191,6 +24063,7 @@ var DatetimeInputComponent = class DatetimeInputComponent {
23191
24063
  this._cvaDisabled = signal(false, ...ngDevMode ? [{ debugName: "_cvaDisabled" }] : /* istanbul ignore next */ []);
23192
24064
  this.disabled = computed(() => this._disabledInput() || this._cvaDisabled(), ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
23193
24065
  this._value = signal("", ...ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []);
24066
+ this._describedBy = computed(() => mergeDescribedBy(this._activeError() || this.hint() ? this._inputId + "-desc" : null, this.ariaDescribedBy()), ...ngDevMode ? [{ debugName: "_describedBy" }] : /* istanbul ignore next */ []);
23194
24067
  this._reveal = createFieldReveal(this.showErrors);
23195
24068
  this._issue = computed(() => this._check(this._value()), ...ngDevMode ? [{ debugName: "_issue" }] : /* istanbul ignore next */ []);
23196
24069
  this.invalid = computed(() => !!this.error() || !!this._issue(), ...ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []);
@@ -23318,6 +24191,13 @@ var DatetimeInputComponent = class DatetimeInputComponent {
23318
24191
  isRequired: false,
23319
24192
  transformFunction: null
23320
24193
  },
24194
+ ariaDescribedBy: {
24195
+ classPropertyName: "ariaDescribedBy",
24196
+ publicName: "ariaDescribedBy",
24197
+ isSignal: true,
24198
+ isRequired: false,
24199
+ transformFunction: null
24200
+ },
23321
24201
  error: {
23322
24202
  classPropertyName: "error",
23323
24203
  publicName: "error",
@@ -23377,7 +24257,7 @@ var DatetimeInputComponent = class DatetimeInputComponent {
23377
24257
  [attr.max]="max() || null"
23378
24258
  [attr.required]="required() || null"
23379
24259
  [attr.aria-invalid]="_activeError() ? 'true' : null"
23380
- [attr.aria-describedby]="(_activeError() || hint()) ? _inputId + '-desc' : null"
24260
+ [attr.aria-describedby]="_describedBy()"
23381
24261
  (change)="onChange($event)"
23382
24262
  (blur)="onBlur()"
23383
24263
  />
@@ -23439,7 +24319,7 @@ i0.ɵɵngDeclareClassMetadata({
23439
24319
  [attr.max]="max() || null"
23440
24320
  [attr.required]="required() || null"
23441
24321
  [attr.aria-invalid]="_activeError() ? 'true' : null"
23442
- [attr.aria-describedby]="(_activeError() || hint()) ? _inputId + '-desc' : null"
24322
+ [attr.aria-describedby]="_describedBy()"
23443
24323
  (change)="onChange($event)"
23444
24324
  (blur)="onBlur()"
23445
24325
  />
@@ -23495,6 +24375,14 @@ i0.ɵɵngDeclareClassMetadata({
23495
24375
  required: false
23496
24376
  }]
23497
24377
  }],
24378
+ ariaDescribedBy: [{
24379
+ type: i0.Input,
24380
+ args: [{
24381
+ isSignal: true,
24382
+ alias: "ariaDescribedBy",
24383
+ required: false
24384
+ }]
24385
+ }],
23498
24386
  error: [{
23499
24387
  type: i0.Input,
23500
24388
  args: [{
@@ -23533,6 +24421,7 @@ var TimeInputComponent = class TimeInputComponent {
23533
24421
  this.min = input("", ...ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []);
23534
24422
  this.max = input("", ...ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []);
23535
24423
  this.hint = input("", ...ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []);
24424
+ this.ariaDescribedBy = input("", ...ngDevMode ? [{ debugName: "ariaDescribedBy" }] : /* istanbul ignore next */ []);
23536
24425
  this.error = input("", ...ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []);
23537
24426
  this.showErrors = input(false, ...ngDevMode ? [{ debugName: "showErrors" }] : /* istanbul ignore next */ []);
23538
24427
  this._disabledInput = input(false, {
@@ -23543,6 +24432,7 @@ var TimeInputComponent = class TimeInputComponent {
23543
24432
  this.disabled = computed(() => this._disabledInput() || this._cvaDisabled(), ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
23544
24433
  this._value = signal("", ...ngDevMode ? [{ debugName: "_value" }] : /* istanbul ignore next */ []);
23545
24434
  this._inputId = `tmi-${Math.random().toString(36).slice(2, 8)}`;
24435
+ this._describedBy = computed(() => mergeDescribedBy(this._activeError() || this.hint() ? this._inputId + "-desc" : null, this.ariaDescribedBy()), ...ngDevMode ? [{ debugName: "_describedBy" }] : /* istanbul ignore next */ []);
23546
24436
  this._reveal = createFieldReveal(this.showErrors);
23547
24437
  this._issue = computed(() => this._check(this._value()), ...ngDevMode ? [{ debugName: "_issue" }] : /* istanbul ignore next */ []);
23548
24438
  this.invalid = computed(() => !!this.error() || !!this._issue(), ...ngDevMode ? [{ debugName: "invalid" }] : /* istanbul ignore next */ []);
@@ -23680,6 +24570,13 @@ var TimeInputComponent = class TimeInputComponent {
23680
24570
  isRequired: false,
23681
24571
  transformFunction: null
23682
24572
  },
24573
+ ariaDescribedBy: {
24574
+ classPropertyName: "ariaDescribedBy",
24575
+ publicName: "ariaDescribedBy",
24576
+ isSignal: true,
24577
+ isRequired: false,
24578
+ transformFunction: null
24579
+ },
23683
24580
  error: {
23684
24581
  classPropertyName: "error",
23685
24582
  publicName: "error",
@@ -23741,7 +24638,7 @@ var TimeInputComponent = class TimeInputComponent {
23741
24638
  [attr.aria-label]="ariaLabel() || label() || null"
23742
24639
  [attr.aria-required]="required() ? 'true' : null"
23743
24640
  [attr.aria-invalid]="_activeError() ? 'true' : null"
23744
- [attr.aria-describedby]="(_activeError() || hint()) ? _inputId + '-desc' : null"
24641
+ [attr.aria-describedby]="_describedBy()"
23745
24642
  (change)="onChange($event)"
23746
24643
  (blur)="onBlur()"
23747
24644
  />
@@ -23805,7 +24702,7 @@ i0.ɵɵngDeclareClassMetadata({
23805
24702
  [attr.aria-label]="ariaLabel() || label() || null"
23806
24703
  [attr.aria-required]="required() ? 'true' : null"
23807
24704
  [attr.aria-invalid]="_activeError() ? 'true' : null"
23808
- [attr.aria-describedby]="(_activeError() || hint()) ? _inputId + '-desc' : null"
24705
+ [attr.aria-describedby]="_describedBy()"
23809
24706
  (change)="onChange($event)"
23810
24707
  (blur)="onBlur()"
23811
24708
  />
@@ -23869,6 +24766,14 @@ i0.ɵɵngDeclareClassMetadata({
23869
24766
  required: false
23870
24767
  }]
23871
24768
  }],
24769
+ ariaDescribedBy: [{
24770
+ type: i0.Input,
24771
+ args: [{
24772
+ isSignal: true,
24773
+ alias: "ariaDescribedBy",
24774
+ required: false
24775
+ }]
24776
+ }],
23872
24777
  error: [{
23873
24778
  type: i0.Input,
23874
24779
  args: [{
@@ -26581,156 +27486,6 @@ i0.ɵɵngDeclareClassMetadata({
26581
27486
  }]
26582
27487
  }
26583
27488
  });
26584
- var FormSectionComponent = class FormSectionComponent {
26585
- constructor() {
26586
- this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
26587
- this.divider = input(false, ...ngDevMode ? [{ debugName: "divider" }] : /* istanbul ignore next */ []);
26588
- }
26589
- static {
26590
- this.ɵfac = i0.ɵɵngDeclareFactory({
26591
- minVersion: "12.0.0",
26592
- version: "22.2.2",
26593
- ngImport: i0,
26594
- type: FormSectionComponent,
26595
- deps: [],
26596
- target: i0.ɵɵFactoryTarget.Component
26597
- });
26598
- }
26599
- static {
26600
- this.ɵcmp = i0.ɵɵngDeclareComponent({
26601
- minVersion: "17.0.0",
26602
- version: "22.2.2",
26603
- type: FormSectionComponent,
26604
- isStandalone: true,
26605
- selector: "ui-form-section",
26606
- inputs: {
26607
- label: {
26608
- classPropertyName: "label",
26609
- publicName: "label",
26610
- isSignal: true,
26611
- isRequired: false,
26612
- transformFunction: null
26613
- },
26614
- divider: {
26615
- classPropertyName: "divider",
26616
- publicName: "divider",
26617
- isSignal: true,
26618
- isRequired: false,
26619
- transformFunction: null
26620
- }
26621
- },
26622
- ngImport: i0,
26623
- template: `
26624
- @if (divider()) { <div class="fs-divider"></div> }
26625
- @if (label()) { <p class="fs-label">{{ label() }}</p> }
26626
- <div class="fs-fields"><ng-content /></div>
26627
- `,
26628
- isInline: true,
26629
- styles: [":host{display:block}.fs-divider{height:1px;background:#f1f5f9;margin:8px -24px 16px}.fs-label{font-size:.6875rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#64748b;margin:0 0 12px}.fs-fields{display:flex;flex-direction:column;gap:14px}\n"],
26630
- changeDetection: i0.ChangeDetectionStrategy.OnPush
26631
- });
26632
- }
26633
- };
26634
- i0.ɵɵngDeclareClassMetadata({
26635
- minVersion: "12.0.0",
26636
- version: "22.2.2",
26637
- ngImport: i0,
26638
- type: FormSectionComponent,
26639
- decorators: [{
26640
- type: Component,
26641
- args: [{
26642
- selector: "ui-form-section",
26643
- standalone: true,
26644
- changeDetection: ChangeDetectionStrategy.OnPush,
26645
- template: `
26646
- @if (divider()) { <div class="fs-divider"></div> }
26647
- @if (label()) { <p class="fs-label">{{ label() }}</p> }
26648
- <div class="fs-fields"><ng-content /></div>
26649
- `,
26650
- styles: [":host{display:block}.fs-divider{height:1px;background:#f1f5f9;margin:8px -24px 16px}.fs-label{font-size:.6875rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:#64748b;margin:0 0 12px}.fs-fields{display:flex;flex-direction:column;gap:14px}\n"]
26651
- }]
26652
- }],
26653
- propDecorators: {
26654
- label: [{
26655
- type: i0.Input,
26656
- args: [{
26657
- isSignal: true,
26658
- alias: "label",
26659
- required: false
26660
- }]
26661
- }],
26662
- divider: [{
26663
- type: i0.Input,
26664
- args: [{
26665
- isSignal: true,
26666
- alias: "divider",
26667
- required: false
26668
- }]
26669
- }]
26670
- }
26671
- });
26672
- var FormRowComponent = class FormRowComponent {
26673
- constructor() {
26674
- this.cols = input(2, ...ngDevMode ? [{ debugName: "cols" }] : /* istanbul ignore next */ []);
26675
- }
26676
- static {
26677
- this.ɵfac = i0.ɵɵngDeclareFactory({
26678
- minVersion: "12.0.0",
26679
- version: "22.2.2",
26680
- ngImport: i0,
26681
- type: FormRowComponent,
26682
- deps: [],
26683
- target: i0.ɵɵFactoryTarget.Component
26684
- });
26685
- }
26686
- static {
26687
- this.ɵcmp = i0.ɵɵngDeclareComponent({
26688
- minVersion: "17.1.0",
26689
- version: "22.2.2",
26690
- type: FormRowComponent,
26691
- isStandalone: true,
26692
- selector: "ui-form-row",
26693
- inputs: { cols: {
26694
- classPropertyName: "cols",
26695
- publicName: "cols",
26696
- isSignal: true,
26697
- isRequired: false,
26698
- transformFunction: null
26699
- } },
26700
- ngImport: i0,
26701
- template: `<div class="fr-row" [class.fr-row--4]="cols() === 4" [style.--fr-cols]="cols()"><ng-content /></div>`,
26702
- isInline: true,
26703
- styles: ["ui-form-row{display:block}.fr-row{display:grid;grid-template-columns:repeat(var(--fr-cols, 2),1fr);gap:12px}.fr-row>.ui-span-2{grid-column:span 2}.fr-row>.ui-span-3{grid-column:span 3}.fr-row>.ui-span-all{grid-column:1 / -1}@media(max-width:768px){.fr-row--4{grid-template-columns:repeat(2,1fr)}.fr-row--4>.ui-span-3{grid-column:1 / -1}}@media(max-width:480px){.fr-row{grid-template-columns:1fr}.fr-row>.ui-span-2,.fr-row>.ui-span-3,.fr-row>.ui-span-all{grid-column:1 / -1}}\n"],
26704
- changeDetection: i0.ChangeDetectionStrategy.OnPush,
26705
- encapsulation: i0.ViewEncapsulation.None
26706
- });
26707
- }
26708
- };
26709
- i0.ɵɵngDeclareClassMetadata({
26710
- minVersion: "12.0.0",
26711
- version: "22.2.2",
26712
- ngImport: i0,
26713
- type: FormRowComponent,
26714
- decorators: [{
26715
- type: Component,
26716
- args: [{
26717
- selector: "ui-form-row",
26718
- standalone: true,
26719
- changeDetection: ChangeDetectionStrategy.OnPush,
26720
- encapsulation: ViewEncapsulation.None,
26721
- template: `<div class="fr-row" [class.fr-row--4]="cols() === 4" [style.--fr-cols]="cols()"><ng-content /></div>`,
26722
- styles: ["ui-form-row{display:block}.fr-row{display:grid;grid-template-columns:repeat(var(--fr-cols, 2),1fr);gap:12px}.fr-row>.ui-span-2{grid-column:span 2}.fr-row>.ui-span-3{grid-column:span 3}.fr-row>.ui-span-all{grid-column:1 / -1}@media(max-width:768px){.fr-row--4{grid-template-columns:repeat(2,1fr)}.fr-row--4>.ui-span-3{grid-column:1 / -1}}@media(max-width:480px){.fr-row{grid-template-columns:1fr}.fr-row>.ui-span-2,.fr-row>.ui-span-3,.fr-row>.ui-span-all{grid-column:1 / -1}}\n"]
26723
- }]
26724
- }],
26725
- propDecorators: { cols: [{
26726
- type: i0.Input,
26727
- args: [{
26728
- isSignal: true,
26729
- alias: "cols",
26730
- required: false
26731
- }]
26732
- }] }
26733
- });
26734
27489
  var FormColSpanDirective = class FormColSpanDirective {
26735
27490
  constructor() {
26736
27491
  this.uiColSpan = input("", ...ngDevMode ? [{ debugName: "uiColSpan" }] : /* istanbul ignore next */ []);
@@ -27282,6 +28037,7 @@ const ICON_PATHS = {
27282
28037
  };
27283
28038
  const CALENDAR_PATH = "M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z M16 2v4 M8 2v4 M3 10h18";
27284
28039
  const EDIT_PATH = "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7 M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z";
28040
+ const TRASH_PATH = "M3 6h18 M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2 M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6 M10 11v6 M14 11v6";
27285
28041
  const INDICATOR_LABEL = {
27286
28042
  high: "High priority",
27287
28043
  medium: "Medium priority",
@@ -27303,10 +28059,20 @@ var CardListItemComponent = class CardListItemComponent {
27303
28059
  this.viewButton = input(false, ...ngDevMode ? [{ debugName: "viewButton" }] : /* istanbul ignore next */ []);
27304
28060
  this.editAriaLabel = input("", ...ngDevMode ? [{ debugName: "editAriaLabel" }] : /* istanbul ignore next */ []);
27305
28061
  this.viewAriaLabel = input("", ...ngDevMode ? [{ debugName: "viewAriaLabel" }] : /* istanbul ignore next */ []);
28062
+ this.deletable = input(false, ...ngDevMode ? [{ debugName: "deletable" }] : /* istanbul ignore next */ []);
28063
+ this.deleteLabel = input("Delete", ...ngDevMode ? [{ debugName: "deleteLabel" }] : /* istanbul ignore next */ []);
28064
+ this.deleteTestId = input("", ...ngDevMode ? [{ debugName: "deleteTestId" }] : /* istanbul ignore next */ []);
28065
+ this.actionLabel = input("", ...ngDevMode ? [{ debugName: "actionLabel" }] : /* istanbul ignore next */ []);
28066
+ this.actionTestId = input("", ...ngDevMode ? [{ debugName: "actionTestId" }] : /* istanbul ignore next */ []);
28067
+ this.actionAriaLabel = input("", ...ngDevMode ? [{ debugName: "actionAriaLabel" }] : /* istanbul ignore next */ []);
28068
+ this.hasBuiltInChip = computed(() => this.editButton() || this.viewButton() || !!this.actionLabel() || this.deletable(), ...ngDevMode ? [{ debugName: "hasBuiltInChip" }] : /* istanbul ignore next */ []);
27306
28069
  this.editClick = output();
27307
28070
  this.viewClick = output();
28071
+ this.delete = output();
28072
+ this.action = output();
27308
28073
  this.calendarPath = CALENDAR_PATH;
27309
28074
  this.editPath = EDIT_PATH;
28075
+ this.trashPath = TRASH_PATH;
27310
28076
  this.iconPath = computed(() => {
27311
28077
  const i = this.icon();
27312
28078
  return i ? ICON_PATHS[i] ?? null : null;
@@ -27421,11 +28187,55 @@ var CardListItemComponent = class CardListItemComponent {
27421
28187
  isSignal: true,
27422
28188
  isRequired: false,
27423
28189
  transformFunction: null
28190
+ },
28191
+ deletable: {
28192
+ classPropertyName: "deletable",
28193
+ publicName: "deletable",
28194
+ isSignal: true,
28195
+ isRequired: false,
28196
+ transformFunction: null
28197
+ },
28198
+ deleteLabel: {
28199
+ classPropertyName: "deleteLabel",
28200
+ publicName: "deleteLabel",
28201
+ isSignal: true,
28202
+ isRequired: false,
28203
+ transformFunction: null
28204
+ },
28205
+ deleteTestId: {
28206
+ classPropertyName: "deleteTestId",
28207
+ publicName: "deleteTestId",
28208
+ isSignal: true,
28209
+ isRequired: false,
28210
+ transformFunction: null
28211
+ },
28212
+ actionLabel: {
28213
+ classPropertyName: "actionLabel",
28214
+ publicName: "actionLabel",
28215
+ isSignal: true,
28216
+ isRequired: false,
28217
+ transformFunction: null
28218
+ },
28219
+ actionTestId: {
28220
+ classPropertyName: "actionTestId",
28221
+ publicName: "actionTestId",
28222
+ isSignal: true,
28223
+ isRequired: false,
28224
+ transformFunction: null
28225
+ },
28226
+ actionAriaLabel: {
28227
+ classPropertyName: "actionAriaLabel",
28228
+ publicName: "actionAriaLabel",
28229
+ isSignal: true,
28230
+ isRequired: false,
28231
+ transformFunction: null
27424
28232
  }
27425
28233
  },
27426
28234
  outputs: {
27427
28235
  editClick: "editClick",
27428
- viewClick: "viewClick"
28236
+ viewClick: "viewClick",
28237
+ delete: "delete",
28238
+ action: "action"
27429
28239
  },
27430
28240
  ngImport: i0,
27431
28241
  template: `
@@ -27435,7 +28245,7 @@ var CardListItemComponent = class CardListItemComponent {
27435
28245
  @if (status() && statusVariant()) { <ui-badge [label]="status()!" [variant]="statusVariant()!" /> }
27436
28246
  </div>
27437
28247
  }
27438
- <div class="cli-row" [class.cli-row--badges]="hasBadges()" [class.cli-row--badges-2]="hasBadges() && !!type() && !!status() && !!statusVariant()">
28248
+ <div class="cli-row" [class.cli-row--badges]="hasBadges()" [class.cli-row--badges-2]="hasBadges() && !!type() && !!status() && !!statusVariant()" [class.cli-row--badges-chip]="hasBadges() && hasBuiltInChip()">
27439
28249
  @if (iconPath(); as d) {
27440
28250
  <div class="cli-icon-circle" [class]="'cli-icon-circle cli-icon-circle--' + icon()" aria-hidden="true">
27441
28251
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" focusable="false"><path [attr.d]="d" /></svg>
@@ -27473,6 +28283,14 @@ var CardListItemComponent = class CardListItemComponent {
27473
28283
  @if (viewButton()) {
27474
28284
  <button class="cli-chip cli-chip--view" type="button" [attr.aria-label]="viewAriaLabel() || null" (click)="viewClick.emit()">View</button>
27475
28285
  }
28286
+ @if (actionLabel()) {
28287
+ <button class="cli-chip cli-chip--action" type="button" [attr.data-testid]="actionTestId() || null" [attr.aria-label]="actionAriaLabel() || null" (click)="action.emit()">{{ actionLabel() }}</button>
28288
+ }
28289
+ @if (deletable()) {
28290
+ <button class="cli-chip cli-chip--delete" type="button" [attr.data-testid]="deleteTestId() || null" [attr.aria-label]="deleteLabel() || 'Delete'" (click)="delete.emit()">
28291
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="trashPath" /></svg>
28292
+ </button>
28293
+ }
27476
28294
  <ng-content select="[card-list-action]" />
27477
28295
  <ng-content />
27478
28296
  </div>
@@ -27480,7 +28298,7 @@ var CardListItemComponent = class CardListItemComponent {
27480
28298
  <ng-content select="[card-detail]" />
27481
28299
  `,
27482
28300
  isInline: true,
27483
- styles: ["ui-card-list-item{position:relative;display:block;border:1px solid #e2e8f0;border-radius:8px;overflow:hidden;margin-bottom:8px}ui-card-list-item:last-child{margin-bottom:0}ui-card-list-item .cli-row{display:flex;align-items:flex-start;gap:12px;padding:13px 18px;transition:background .12s}ui-card-list-item .cli-row:hover{background:#f8fafc}@media(prefers-reduced-motion:reduce){ui-card-list-item .cli-row{transition:none}}ui-card-list-item .cli-dot{width:9px;height:9px;border-radius:50%;flex-shrink:0;margin-top:5px}ui-card-list-item .cli-dot:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}ui-card-list-item .cli-dot--high{background:#ef4444}ui-card-list-item .cli-dot--medium{background:#f59e0b}ui-card-list-item .cli-dot--low{background:#94a3b8}ui-card-list-item .cli-dot--blue{background:#3b82f6}ui-card-list-item .cli-dot--green{background:#22c55e}ui-card-list-item .cli-icon-circle{width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0}ui-card-list-item .cli-icon-circle--call{background:#dbeafe;color:#2563eb}ui-card-list-item .cli-icon-circle--email{background:#dcfce7;color:#16a34a}ui-card-list-item .cli-icon-circle--sms{background:#fef9c3;color:#ca8a04}ui-card-list-item .cli-icon-circle--task{background:#dbeafe;color:#2563eb}ui-card-list-item .cli-icon-circle--doc{background:#ffedd5;color:#ea580c}ui-card-list-item .cli-icon-circle--money{background:#d1fae5;color:#059669}ui-card-list-item .cli-icon-circle--deal{background:#e0f2fe;color:#0284c7}ui-card-list-item .cli-icon-circle--survey{background:#dbeafe;color:#2563eb}ui-card-list-item .cli-icon-circle--property{background:#fef3c7;color:#d97706}ui-card-list-item .cli-icon-circle--search{background:#e0f2fe;color:#0284c7}ui-card-list-item .cli-icon-circle--heart{background:#fce7f3;color:#db2777}ui-card-list-item .cli-icon-circle--calc{background:#d1fae5;color:#059669}ui-card-list-item .cli-icon-circle--repeat{background:#e0f2fe;color:#0284c7}ui-card-list-item .cli-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;overflow-wrap:anywhere;word-break:break-word}ui-card-list-item .cli-badges{position:absolute;top:10px;right:12px;display:flex;align-items:center;gap:6px;z-index:1}ui-card-list-item .cli-row--badges .cli-body{padding-right:96px}ui-card-list-item .cli-row--badges-2 .cli-body{padding-right:190px}ui-card-list-item .cli-row--badges .cli-chip{align-self:flex-end}ui-card-list-item .cli-title-row{display:flex;align-items:center;gap:7px;flex-wrap:wrap}ui-card-list-item .cli-title{font-size:.875rem;font-weight:600;color:#1e293b}ui-card-list-item .cli-desc-row{display:flex;align-items:center;gap:8px}ui-card-list-item .cli-desc-row:empty{display:none}ui-card-list-item .cli-description{font-size:.8125rem;color:#64748b;min-width:0}ui-card-list-item .cli-date{display:flex;align-items:center;gap:4px;font-size:.75rem;color:#64748b}ui-card-list-item .cli-chip{flex-shrink:0;display:inline-flex;align-items:center;gap:5px;align-self:center;box-sizing:border-box;font-family:inherit;font-size:.8rem;font-weight:500;line-height:1.4;background:none;cursor:pointer;padding:4px 10px;border-radius:6px;text-decoration:none;transition:background .15s,color .15s,border-color .15s}ui-card-list-item .cli-chip--edit{color:#64748b;border:1px solid #e2e8f0}ui-card-list-item .cli-chip--edit:hover{background:#f1f5f9;color:#1e293b}ui-card-list-item .cli-chip--view{color:#2563eb;border:1px solid #dbeafe}ui-card-list-item .cli-chip--view:hover{background:#eff6ff;border-color:#bfdbfe;color:#1d4ed8}ui-card-list-item .cli-chip:focus-visible,ui-card-list-item .cli-inline-link:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}ui-card-list-item .cli-inline-link{flex-shrink:0;margin-left:auto;display:inline-flex;align-items:center;gap:4px;font-size:.8rem;font-weight:500;color:#2563eb;text-decoration:none;transition:color .15s}ui-card-list-item .cli-inline-link:hover{color:#1d4ed8}@media(pointer:coarse),(max-width:480px){ui-card-list-item .cli-chip{min-height:44px;padding:4px 14px}}ui-card-list-item [card-stats]{display:flex;align-items:stretch;background:#f8fafc;border-top:1px solid #f1f5f9}ui-card-list-item [card-detail]{background:#f8fafc;border-top:1px solid #e2e8f0}ui-card-list-item .cli-stat{flex:1;display:flex;flex-direction:column;gap:2px;padding:10px 14px}ui-card-list-item .cli-stat-label{font-size:.6875rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:#64748b}ui-card-list-item .cli-stat-value{font-size:.9375rem;font-weight:600;color:#0f172a}ui-card-list-item .cli-stat-divider{width:1px;background:#e2e8f0;margin:8px 0}\n"],
28301
+ styles: ["ui-card-list-item{position:relative;display:block;border:1px solid #e2e8f0;border-radius:8px;overflow:hidden;margin-bottom:8px}ui-card-list-item:last-child{margin-bottom:0}ui-card-list-item .cli-row{display:flex;align-items:flex-start;gap:12px;padding:13px 18px;transition:background .12s}ui-card-list-item .cli-row:hover{background:#f8fafc}@media(prefers-reduced-motion:reduce){ui-card-list-item .cli-row{transition:none}}ui-card-list-item .cli-dot{width:9px;height:9px;border-radius:50%;flex-shrink:0;margin-top:5px}ui-card-list-item .cli-dot:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}ui-card-list-item .cli-dot--high{background:#ef4444}ui-card-list-item .cli-dot--medium{background:#f59e0b}ui-card-list-item .cli-dot--low{background:#94a3b8}ui-card-list-item .cli-dot--blue{background:#3b82f6}ui-card-list-item .cli-dot--green{background:#22c55e}ui-card-list-item .cli-icon-circle{width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0}ui-card-list-item .cli-icon-circle--call{background:#dbeafe;color:#2563eb}ui-card-list-item .cli-icon-circle--email{background:#dcfce7;color:#16a34a}ui-card-list-item .cli-icon-circle--sms{background:#fef9c3;color:#ca8a04}ui-card-list-item .cli-icon-circle--task{background:#dbeafe;color:#2563eb}ui-card-list-item .cli-icon-circle--doc{background:#ffedd5;color:#ea580c}ui-card-list-item .cli-icon-circle--money{background:#d1fae5;color:#059669}ui-card-list-item .cli-icon-circle--deal{background:#e0f2fe;color:#0284c7}ui-card-list-item .cli-icon-circle--survey{background:#dbeafe;color:#2563eb}ui-card-list-item .cli-icon-circle--property{background:#fef3c7;color:#d97706}ui-card-list-item .cli-icon-circle--search{background:#e0f2fe;color:#0284c7}ui-card-list-item .cli-icon-circle--heart{background:#fce7f3;color:#db2777}ui-card-list-item .cli-icon-circle--calc{background:#d1fae5;color:#059669}ui-card-list-item .cli-icon-circle--repeat{background:#e0f2fe;color:#0284c7}ui-card-list-item .cli-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;overflow-wrap:anywhere;word-break:break-word}ui-card-list-item .cli-badges{position:absolute;top:10px;right:12px;display:flex;align-items:center;gap:6px;z-index:1}ui-card-list-item .cli-row--badges .cli-body{padding-right:96px}ui-card-list-item .cli-row--badges-2 .cli-body{padding-right:190px}ui-card-list-item .cli-row--badges .cli-chip{align-self:flex-end}ui-card-list-item .cli-row--badges-chip{box-sizing:border-box;min-height:76px}ui-card-list-item .cli-row--badges:has([card-list-action]){box-sizing:border-box;min-height:76px}@media(pointer:coarse),(max-width:480px){ui-card-list-item .cli-row--badges-chip{min-height:92px}ui-card-list-item .cli-row--badges:has([card-list-action]){min-height:92px}}ui-card-list-item .cli-title-row{display:flex;align-items:center;gap:7px;flex-wrap:wrap}ui-card-list-item .cli-title{font-size:.875rem;font-weight:600;color:#1e293b}ui-card-list-item .cli-desc-row{display:flex;align-items:center;gap:8px}ui-card-list-item .cli-desc-row:empty{display:none}ui-card-list-item .cli-description{font-size:.8125rem;color:#64748b;min-width:0}ui-card-list-item .cli-date{display:flex;align-items:center;gap:4px;font-size:.75rem;color:#64748b}ui-card-list-item .cli-chip{flex-shrink:0;display:inline-flex;align-items:center;gap:5px;align-self:center;box-sizing:border-box;font-family:inherit;font-size:.8rem;font-weight:500;line-height:1.4;background:none;cursor:pointer;padding:4px 10px;border-radius:6px;text-decoration:none;transition:background .15s,color .15s,border-color .15s}ui-card-list-item .cli-chip--edit{color:#64748b;border:1px solid #e2e8f0}ui-card-list-item .cli-chip--edit:hover{background:#f1f5f9;color:#1e293b}ui-card-list-item .cli-chip--view{color:#2563eb;border:1px solid #dbeafe}ui-card-list-item .cli-chip--view:hover{background:#eff6ff;border-color:#bfdbfe;color:#1d4ed8}ui-card-list-item .cli-chip--action{color:#475569;border:1px solid #e2e8f0}ui-card-list-item .cli-chip--action:hover{background:#f1f5f9;color:#1e293b}ui-card-list-item .cli-chip--delete{position:relative;justify-content:center;width:28px;height:28px;padding:0;color:#b91c1c;border:1px solid #fecaca}ui-card-list-item .cli-chip--delete:hover{background:#fef2f2;border-color:#fca5a5;color:#991b1b}ui-card-list-item .cli-chip--delete:after{content:\"\";position:absolute;top:50%;left:50%;width:44px;height:44px;transform:translate(-50%,-50%)}ui-card-list-item .cli-chip:focus-visible,ui-card-list-item .cli-inline-link:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}ui-card-list-item .cli-inline-link{flex-shrink:0;margin-left:auto;display:inline-flex;align-items:center;gap:4px;font-size:.8rem;font-weight:500;color:#2563eb;text-decoration:none;transition:color .15s}ui-card-list-item .cli-inline-link:hover{color:#1d4ed8}@media(pointer:coarse),(max-width:480px){ui-card-list-item .cli-chip{min-height:44px;padding:4px 14px}ui-card-list-item .cli-chip--delete{min-height:28px;padding:0}}ui-card-list-item [card-stats]{display:flex;align-items:stretch;background:#f8fafc;border-top:1px solid #f1f5f9}ui-card-list-item [card-detail]{background:#f8fafc;border-top:1px solid #e2e8f0}ui-card-list-item .cli-stat{flex:1;display:flex;flex-direction:column;gap:2px;padding:10px 14px}ui-card-list-item .cli-stat-label{font-size:.6875rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:#64748b}ui-card-list-item .cli-stat-value{font-size:.9375rem;font-weight:600;color:#0f172a}ui-card-list-item .cli-stat-divider{width:1px;background:#e2e8f0;margin:8px 0}\n"],
27484
28302
  dependencies: [{
27485
28303
  kind: "component",
27486
28304
  type: BadgeComponent,
@@ -27517,7 +28335,7 @@ i0.ɵɵngDeclareClassMetadata({
27517
28335
  @if (status() && statusVariant()) { <ui-badge [label]="status()!" [variant]="statusVariant()!" /> }
27518
28336
  </div>
27519
28337
  }
27520
- <div class="cli-row" [class.cli-row--badges]="hasBadges()" [class.cli-row--badges-2]="hasBadges() && !!type() && !!status() && !!statusVariant()">
28338
+ <div class="cli-row" [class.cli-row--badges]="hasBadges()" [class.cli-row--badges-2]="hasBadges() && !!type() && !!status() && !!statusVariant()" [class.cli-row--badges-chip]="hasBadges() && hasBuiltInChip()">
27521
28339
  @if (iconPath(); as d) {
27522
28340
  <div class="cli-icon-circle" [class]="'cli-icon-circle cli-icon-circle--' + icon()" aria-hidden="true">
27523
28341
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" focusable="false"><path [attr.d]="d" /></svg>
@@ -27555,13 +28373,21 @@ i0.ɵɵngDeclareClassMetadata({
27555
28373
  @if (viewButton()) {
27556
28374
  <button class="cli-chip cli-chip--view" type="button" [attr.aria-label]="viewAriaLabel() || null" (click)="viewClick.emit()">View</button>
27557
28375
  }
28376
+ @if (actionLabel()) {
28377
+ <button class="cli-chip cli-chip--action" type="button" [attr.data-testid]="actionTestId() || null" [attr.aria-label]="actionAriaLabel() || null" (click)="action.emit()">{{ actionLabel() }}</button>
28378
+ }
28379
+ @if (deletable()) {
28380
+ <button class="cli-chip cli-chip--delete" type="button" [attr.data-testid]="deleteTestId() || null" [attr.aria-label]="deleteLabel() || 'Delete'" (click)="delete.emit()">
28381
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path [attr.d]="trashPath" /></svg>
28382
+ </button>
28383
+ }
27558
28384
  <ng-content select="[card-list-action]" />
27559
28385
  <ng-content />
27560
28386
  </div>
27561
28387
  <ng-content select="[card-stats]" />
27562
28388
  <ng-content select="[card-detail]" />
27563
28389
  `,
27564
- styles: ["ui-card-list-item{position:relative;display:block;border:1px solid #e2e8f0;border-radius:8px;overflow:hidden;margin-bottom:8px}ui-card-list-item:last-child{margin-bottom:0}ui-card-list-item .cli-row{display:flex;align-items:flex-start;gap:12px;padding:13px 18px;transition:background .12s}ui-card-list-item .cli-row:hover{background:#f8fafc}@media(prefers-reduced-motion:reduce){ui-card-list-item .cli-row{transition:none}}ui-card-list-item .cli-dot{width:9px;height:9px;border-radius:50%;flex-shrink:0;margin-top:5px}ui-card-list-item .cli-dot:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}ui-card-list-item .cli-dot--high{background:#ef4444}ui-card-list-item .cli-dot--medium{background:#f59e0b}ui-card-list-item .cli-dot--low{background:#94a3b8}ui-card-list-item .cli-dot--blue{background:#3b82f6}ui-card-list-item .cli-dot--green{background:#22c55e}ui-card-list-item .cli-icon-circle{width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0}ui-card-list-item .cli-icon-circle--call{background:#dbeafe;color:#2563eb}ui-card-list-item .cli-icon-circle--email{background:#dcfce7;color:#16a34a}ui-card-list-item .cli-icon-circle--sms{background:#fef9c3;color:#ca8a04}ui-card-list-item .cli-icon-circle--task{background:#dbeafe;color:#2563eb}ui-card-list-item .cli-icon-circle--doc{background:#ffedd5;color:#ea580c}ui-card-list-item .cli-icon-circle--money{background:#d1fae5;color:#059669}ui-card-list-item .cli-icon-circle--deal{background:#e0f2fe;color:#0284c7}ui-card-list-item .cli-icon-circle--survey{background:#dbeafe;color:#2563eb}ui-card-list-item .cli-icon-circle--property{background:#fef3c7;color:#d97706}ui-card-list-item .cli-icon-circle--search{background:#e0f2fe;color:#0284c7}ui-card-list-item .cli-icon-circle--heart{background:#fce7f3;color:#db2777}ui-card-list-item .cli-icon-circle--calc{background:#d1fae5;color:#059669}ui-card-list-item .cli-icon-circle--repeat{background:#e0f2fe;color:#0284c7}ui-card-list-item .cli-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;overflow-wrap:anywhere;word-break:break-word}ui-card-list-item .cli-badges{position:absolute;top:10px;right:12px;display:flex;align-items:center;gap:6px;z-index:1}ui-card-list-item .cli-row--badges .cli-body{padding-right:96px}ui-card-list-item .cli-row--badges-2 .cli-body{padding-right:190px}ui-card-list-item .cli-row--badges .cli-chip{align-self:flex-end}ui-card-list-item .cli-title-row{display:flex;align-items:center;gap:7px;flex-wrap:wrap}ui-card-list-item .cli-title{font-size:.875rem;font-weight:600;color:#1e293b}ui-card-list-item .cli-desc-row{display:flex;align-items:center;gap:8px}ui-card-list-item .cli-desc-row:empty{display:none}ui-card-list-item .cli-description{font-size:.8125rem;color:#64748b;min-width:0}ui-card-list-item .cli-date{display:flex;align-items:center;gap:4px;font-size:.75rem;color:#64748b}ui-card-list-item .cli-chip{flex-shrink:0;display:inline-flex;align-items:center;gap:5px;align-self:center;box-sizing:border-box;font-family:inherit;font-size:.8rem;font-weight:500;line-height:1.4;background:none;cursor:pointer;padding:4px 10px;border-radius:6px;text-decoration:none;transition:background .15s,color .15s,border-color .15s}ui-card-list-item .cli-chip--edit{color:#64748b;border:1px solid #e2e8f0}ui-card-list-item .cli-chip--edit:hover{background:#f1f5f9;color:#1e293b}ui-card-list-item .cli-chip--view{color:#2563eb;border:1px solid #dbeafe}ui-card-list-item .cli-chip--view:hover{background:#eff6ff;border-color:#bfdbfe;color:#1d4ed8}ui-card-list-item .cli-chip:focus-visible,ui-card-list-item .cli-inline-link:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}ui-card-list-item .cli-inline-link{flex-shrink:0;margin-left:auto;display:inline-flex;align-items:center;gap:4px;font-size:.8rem;font-weight:500;color:#2563eb;text-decoration:none;transition:color .15s}ui-card-list-item .cli-inline-link:hover{color:#1d4ed8}@media(pointer:coarse),(max-width:480px){ui-card-list-item .cli-chip{min-height:44px;padding:4px 14px}}ui-card-list-item [card-stats]{display:flex;align-items:stretch;background:#f8fafc;border-top:1px solid #f1f5f9}ui-card-list-item [card-detail]{background:#f8fafc;border-top:1px solid #e2e8f0}ui-card-list-item .cli-stat{flex:1;display:flex;flex-direction:column;gap:2px;padding:10px 14px}ui-card-list-item .cli-stat-label{font-size:.6875rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:#64748b}ui-card-list-item .cli-stat-value{font-size:.9375rem;font-weight:600;color:#0f172a}ui-card-list-item .cli-stat-divider{width:1px;background:#e2e8f0;margin:8px 0}\n"]
28390
+ styles: ["ui-card-list-item{position:relative;display:block;border:1px solid #e2e8f0;border-radius:8px;overflow:hidden;margin-bottom:8px}ui-card-list-item:last-child{margin-bottom:0}ui-card-list-item .cli-row{display:flex;align-items:flex-start;gap:12px;padding:13px 18px;transition:background .12s}ui-card-list-item .cli-row:hover{background:#f8fafc}@media(prefers-reduced-motion:reduce){ui-card-list-item .cli-row{transition:none}}ui-card-list-item .cli-dot{width:9px;height:9px;border-radius:50%;flex-shrink:0;margin-top:5px}ui-card-list-item .cli-dot:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}ui-card-list-item .cli-dot--high{background:#ef4444}ui-card-list-item .cli-dot--medium{background:#f59e0b}ui-card-list-item .cli-dot--low{background:#94a3b8}ui-card-list-item .cli-dot--blue{background:#3b82f6}ui-card-list-item .cli-dot--green{background:#22c55e}ui-card-list-item .cli-icon-circle{width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0}ui-card-list-item .cli-icon-circle--call{background:#dbeafe;color:#2563eb}ui-card-list-item .cli-icon-circle--email{background:#dcfce7;color:#16a34a}ui-card-list-item .cli-icon-circle--sms{background:#fef9c3;color:#ca8a04}ui-card-list-item .cli-icon-circle--task{background:#dbeafe;color:#2563eb}ui-card-list-item .cli-icon-circle--doc{background:#ffedd5;color:#ea580c}ui-card-list-item .cli-icon-circle--money{background:#d1fae5;color:#059669}ui-card-list-item .cli-icon-circle--deal{background:#e0f2fe;color:#0284c7}ui-card-list-item .cli-icon-circle--survey{background:#dbeafe;color:#2563eb}ui-card-list-item .cli-icon-circle--property{background:#fef3c7;color:#d97706}ui-card-list-item .cli-icon-circle--search{background:#e0f2fe;color:#0284c7}ui-card-list-item .cli-icon-circle--heart{background:#fce7f3;color:#db2777}ui-card-list-item .cli-icon-circle--calc{background:#d1fae5;color:#059669}ui-card-list-item .cli-icon-circle--repeat{background:#e0f2fe;color:#0284c7}ui-card-list-item .cli-body{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px;overflow-wrap:anywhere;word-break:break-word}ui-card-list-item .cli-badges{position:absolute;top:10px;right:12px;display:flex;align-items:center;gap:6px;z-index:1}ui-card-list-item .cli-row--badges .cli-body{padding-right:96px}ui-card-list-item .cli-row--badges-2 .cli-body{padding-right:190px}ui-card-list-item .cli-row--badges .cli-chip{align-self:flex-end}ui-card-list-item .cli-row--badges-chip{box-sizing:border-box;min-height:76px}ui-card-list-item .cli-row--badges:has([card-list-action]){box-sizing:border-box;min-height:76px}@media(pointer:coarse),(max-width:480px){ui-card-list-item .cli-row--badges-chip{min-height:92px}ui-card-list-item .cli-row--badges:has([card-list-action]){min-height:92px}}ui-card-list-item .cli-title-row{display:flex;align-items:center;gap:7px;flex-wrap:wrap}ui-card-list-item .cli-title{font-size:.875rem;font-weight:600;color:#1e293b}ui-card-list-item .cli-desc-row{display:flex;align-items:center;gap:8px}ui-card-list-item .cli-desc-row:empty{display:none}ui-card-list-item .cli-description{font-size:.8125rem;color:#64748b;min-width:0}ui-card-list-item .cli-date{display:flex;align-items:center;gap:4px;font-size:.75rem;color:#64748b}ui-card-list-item .cli-chip{flex-shrink:0;display:inline-flex;align-items:center;gap:5px;align-self:center;box-sizing:border-box;font-family:inherit;font-size:.8rem;font-weight:500;line-height:1.4;background:none;cursor:pointer;padding:4px 10px;border-radius:6px;text-decoration:none;transition:background .15s,color .15s,border-color .15s}ui-card-list-item .cli-chip--edit{color:#64748b;border:1px solid #e2e8f0}ui-card-list-item .cli-chip--edit:hover{background:#f1f5f9;color:#1e293b}ui-card-list-item .cli-chip--view{color:#2563eb;border:1px solid #dbeafe}ui-card-list-item .cli-chip--view:hover{background:#eff6ff;border-color:#bfdbfe;color:#1d4ed8}ui-card-list-item .cli-chip--action{color:#475569;border:1px solid #e2e8f0}ui-card-list-item .cli-chip--action:hover{background:#f1f5f9;color:#1e293b}ui-card-list-item .cli-chip--delete{position:relative;justify-content:center;width:28px;height:28px;padding:0;color:#b91c1c;border:1px solid #fecaca}ui-card-list-item .cli-chip--delete:hover{background:#fef2f2;border-color:#fca5a5;color:#991b1b}ui-card-list-item .cli-chip--delete:after{content:\"\";position:absolute;top:50%;left:50%;width:44px;height:44px;transform:translate(-50%,-50%)}ui-card-list-item .cli-chip:focus-visible,ui-card-list-item .cli-inline-link:focus-visible{outline:2px solid #3b82f6;outline-offset:2px}ui-card-list-item .cli-inline-link{flex-shrink:0;margin-left:auto;display:inline-flex;align-items:center;gap:4px;font-size:.8rem;font-weight:500;color:#2563eb;text-decoration:none;transition:color .15s}ui-card-list-item .cli-inline-link:hover{color:#1d4ed8}@media(pointer:coarse),(max-width:480px){ui-card-list-item .cli-chip{min-height:44px;padding:4px 14px}ui-card-list-item .cli-chip--delete{min-height:28px;padding:0}}ui-card-list-item [card-stats]{display:flex;align-items:stretch;background:#f8fafc;border-top:1px solid #f1f5f9}ui-card-list-item [card-detail]{background:#f8fafc;border-top:1px solid #e2e8f0}ui-card-list-item .cli-stat{flex:1;display:flex;flex-direction:column;gap:2px;padding:10px 14px}ui-card-list-item .cli-stat-label{font-size:.6875rem;font-weight:600;letter-spacing:.04em;text-transform:uppercase;color:#64748b}ui-card-list-item .cli-stat-value{font-size:.9375rem;font-weight:600;color:#0f172a}ui-card-list-item .cli-stat-divider{width:1px;background:#e2e8f0;margin:8px 0}\n"]
27565
28391
  }]
27566
28392
  }],
27567
28393
  propDecorators: {
@@ -27669,6 +28495,54 @@ i0.ɵɵngDeclareClassMetadata({
27669
28495
  required: false
27670
28496
  }]
27671
28497
  }],
28498
+ deletable: [{
28499
+ type: i0.Input,
28500
+ args: [{
28501
+ isSignal: true,
28502
+ alias: "deletable",
28503
+ required: false
28504
+ }]
28505
+ }],
28506
+ deleteLabel: [{
28507
+ type: i0.Input,
28508
+ args: [{
28509
+ isSignal: true,
28510
+ alias: "deleteLabel",
28511
+ required: false
28512
+ }]
28513
+ }],
28514
+ deleteTestId: [{
28515
+ type: i0.Input,
28516
+ args: [{
28517
+ isSignal: true,
28518
+ alias: "deleteTestId",
28519
+ required: false
28520
+ }]
28521
+ }],
28522
+ actionLabel: [{
28523
+ type: i0.Input,
28524
+ args: [{
28525
+ isSignal: true,
28526
+ alias: "actionLabel",
28527
+ required: false
28528
+ }]
28529
+ }],
28530
+ actionTestId: [{
28531
+ type: i0.Input,
28532
+ args: [{
28533
+ isSignal: true,
28534
+ alias: "actionTestId",
28535
+ required: false
28536
+ }]
28537
+ }],
28538
+ actionAriaLabel: [{
28539
+ type: i0.Input,
28540
+ args: [{
28541
+ isSignal: true,
28542
+ alias: "actionAriaLabel",
28543
+ required: false
28544
+ }]
28545
+ }],
27672
28546
  editClick: [{
27673
28547
  type: i0.Output,
27674
28548
  args: ["editClick"]
@@ -27676,6 +28550,14 @@ i0.ɵɵngDeclareClassMetadata({
27676
28550
  viewClick: [{
27677
28551
  type: i0.Output,
27678
28552
  args: ["viewClick"]
28553
+ }],
28554
+ delete: [{
28555
+ type: i0.Output,
28556
+ args: ["delete"]
28557
+ }],
28558
+ action: [{
28559
+ type: i0.Output,
28560
+ args: ["action"]
27679
28561
  }]
27680
28562
  }
27681
28563
  });
@@ -27756,26 +28638,44 @@ var NotesComponent = class NotesComponent {
27756
28638
  return ((parts[0]?.[0] ?? "") + (parts.length > 1 ? parts[parts.length - 1][0] : "")).toUpperCase();
27757
28639
  }
27758
28640
  tooLong(text) {
27759
- return text.trim().length > NOTES_MAX_LENGTH;
28641
+ return text.trim().length > this.maxLength();
27760
28642
  }
27761
28643
  validBody(text) {
27762
28644
  const n = text.trim().length;
27763
- return n > 0 && n <= 1e4;
28645
+ return n > 0 && n <= this.maxLength();
27764
28646
  }
27765
28647
  get listUrl() {
27766
- return `${this.apiBase}/notes/${this.resourceType()}/${this.resourceId()}`;
28648
+ return this.basePath() ? `${this.apiBase}${this.basePath()}` : `${this.apiBase}/notes/${this.resourceType()}/${this.resourceId()}`;
28649
+ }
28650
+ noteUrl(id) {
28651
+ return this.basePath() ? `${this.apiBase}${this.basePath()}/${id}` : `${this.apiBase}/notes/${id}`;
28652
+ }
28653
+ get ready() {
28654
+ return !!this.basePath() || !!this.resourceType() && !!this.resourceId();
28655
+ }
28656
+ payload(text) {
28657
+ return this.basePath() ? { content: text.trim() } : { body: text.trim() };
28658
+ }
28659
+ normalize(n) {
28660
+ return {
28661
+ ...n,
28662
+ body: n.body ?? n.content ?? "",
28663
+ updatedAt: n.updatedAt ?? n.createdAt
28664
+ };
27767
28665
  }
27768
28666
  constructor() {
27769
28667
  this.resourceType = input("", ...ngDevMode ? [{ debugName: "resourceType" }] : /* istanbul ignore next */ []);
27770
28668
  this.resourceId = input("", ...ngDevMode ? [{ debugName: "resourceId" }] : /* istanbul ignore next */ []);
28669
+ this.basePath = input("", ...ngDevMode ? [{ debugName: "basePath" }] : /* istanbul ignore next */ []);
27771
28670
  this.readOnly = input(false, ...ngDevMode ? [{ debugName: "readOnly" }] : /* istanbul ignore next */ []);
28671
+ this.editable = input(true, ...ngDevMode ? [{ debugName: "editable" }] : /* istanbul ignore next */ []);
28672
+ this.maxLength = input(NOTES_MAX_LENGTH, ...ngDevMode ? [{ debugName: "maxLength" }] : /* istanbul ignore next */ []);
27772
28673
  this.totalChange = output();
27773
28674
  this.http = inject(HttpClient);
27774
28675
  this.toast = inject(ToastService);
27775
28676
  this.destroyRef = inject(DestroyRef);
27776
28677
  this.apiBase = inject(FORGEROUTE_CONFIG, { optional: true })?.baseUrl ?? "/api";
27777
28678
  this.pageSize = NOTES_PAGE_SIZE;
27778
- this.maxLength = NOTES_MAX_LENGTH;
27779
28679
  this.notes = signal([], ...ngDevMode ? [{ debugName: "notes" }] : /* istanbul ignore next */ []);
27780
28680
  this.loading = signal(false, ...ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []);
27781
28681
  this.saving = signal(false, ...ngDevMode ? [{ debugName: "saving" }] : /* istanbul ignore next */ []);
@@ -27788,16 +28688,16 @@ var NotesComponent = class NotesComponent {
27788
28688
  effect(() => {
27789
28689
  const id = this.resourceId();
27790
28690
  const type = this.resourceType();
27791
- if (id && type) untracked(() => this.loadPage(0));
28691
+ if (this.basePath() || id && type) untracked(() => this.loadPage(0));
27792
28692
  });
27793
28693
  }
27794
28694
  loadPage(p) {
27795
- if (!this.resourceType() || !this.resourceId()) return;
28695
+ if (!this.ready) return;
27796
28696
  this.loading.set(true);
27797
28697
  this.http.get(`${this.listUrl}?page=${p}&size=${this.pageSize}`).pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
27798
28698
  next: (res) => {
27799
- this.notes.set(res.content);
27800
- this.page.set(res.page);
28699
+ this.notes.set(res.content.map((n) => this.normalize(n)));
28700
+ this.page.set(res.page ?? res.number ?? p);
27801
28701
  this.totalElements.set(res.totalElements);
27802
28702
  this.loading.set(false);
27803
28703
  this.totalChange.emit(res.totalElements);
@@ -27811,7 +28711,7 @@ var NotesComponent = class NotesComponent {
27811
28711
  addNote() {
27812
28712
  if (this.readOnly() || !this.validBody(this.newBody) || this.saving()) return;
27813
28713
  this.saving.set(true);
27814
- this.http.post(this.listUrl, { body: this.newBody.trim() }).pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
28714
+ this.http.post(this.listUrl, this.payload(this.newBody)).pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
27815
28715
  next: () => {
27816
28716
  this.newBody = "";
27817
28717
  this.saving.set(false);
@@ -27824,7 +28724,7 @@ var NotesComponent = class NotesComponent {
27824
28724
  });
27825
28725
  }
27826
28726
  startEdit(note) {
27827
- if (this.readOnly()) return;
28727
+ if (this.readOnly() || !this.editable()) return;
27828
28728
  this.editingId.set(note.id);
27829
28729
  this.editBody = note.body;
27830
28730
  }
@@ -27833,11 +28733,11 @@ var NotesComponent = class NotesComponent {
27833
28733
  this.editBody = "";
27834
28734
  }
27835
28735
  saveEdit(noteId) {
27836
- if (this.readOnly() || !this.validBody(this.editBody) || this.saving()) return;
28736
+ if (this.readOnly() || !this.editable() || !this.validBody(this.editBody) || this.saving()) return;
27837
28737
  this.saving.set(true);
27838
- this.http.put(`${this.apiBase}/notes/${noteId}`, { body: this.editBody.trim() }).pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
28738
+ this.http.put(this.noteUrl(noteId), this.payload(this.editBody)).pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
27839
28739
  next: (updated) => {
27840
- this.notes.update((arr) => arr.map((n) => n.id === noteId ? updated : n));
28740
+ this.notes.update((arr) => arr.map((n) => n.id === noteId ? this.normalize(updated) : n));
27841
28741
  this.editingId.set(null);
27842
28742
  this.saving.set(false);
27843
28743
  },
@@ -27855,7 +28755,7 @@ var NotesComponent = class NotesComponent {
27855
28755
  const id = this.deletingId();
27856
28756
  if (this.readOnly() || !id || this.saving()) return;
27857
28757
  this.saving.set(true);
27858
- this.http.delete(`${this.apiBase}/notes/${id}`).pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
28758
+ this.http.delete(this.noteUrl(id)).pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
27859
28759
  next: () => {
27860
28760
  this.deletingId.set(null);
27861
28761
  this.saving.set(false);
@@ -27900,12 +28800,33 @@ var NotesComponent = class NotesComponent {
27900
28800
  isRequired: false,
27901
28801
  transformFunction: null
27902
28802
  },
28803
+ basePath: {
28804
+ classPropertyName: "basePath",
28805
+ publicName: "basePath",
28806
+ isSignal: true,
28807
+ isRequired: false,
28808
+ transformFunction: null
28809
+ },
27903
28810
  readOnly: {
27904
28811
  classPropertyName: "readOnly",
27905
28812
  publicName: "readOnly",
27906
28813
  isSignal: true,
27907
28814
  isRequired: false,
27908
28815
  transformFunction: null
28816
+ },
28817
+ editable: {
28818
+ classPropertyName: "editable",
28819
+ publicName: "editable",
28820
+ isSignal: true,
28821
+ isRequired: false,
28822
+ transformFunction: null
28823
+ },
28824
+ maxLength: {
28825
+ classPropertyName: "maxLength",
28826
+ publicName: "maxLength",
28827
+ isSignal: true,
28828
+ isRequired: false,
28829
+ transformFunction: null
27909
28830
  }
27910
28831
  },
27911
28832
  outputs: { totalChange: "totalChange" },
@@ -27913,7 +28834,7 @@ var NotesComponent = class NotesComponent {
27913
28834
  template: `
27914
28835
  @if (!readOnly()) {
27915
28836
  <div class="note-add">
27916
- <ui-textarea-input ariaLabel="Add a note" placeholder="Add a note..." [rows]="3" [maxlength]="maxLength" [showErrors]="tooLong(newBody)" [disabled]="saving()" [(ngModel)]="newBody"
28837
+ <ui-textarea-input ariaLabel="Add a note" placeholder="Add a note..." [rows]="3" [maxlength]="maxLength()" [showErrors]="tooLong(newBody)" [disabled]="saving()" [(ngModel)]="newBody"
27917
28838
  (keydown.meta.enter)="addNote()" (keydown.control.enter)="addNote()" />
27918
28839
  <div class="note-add-footer">
27919
28840
  <ui-button variant="primary" size="sm" data-testid="note-add-btn" [loading]="saving()" [disabled]="!validBody(newBody)" (click)="addNote()">Add Note</ui-button>
@@ -27940,13 +28861,15 @@ var NotesComponent = class NotesComponent {
27940
28861
  }
27941
28862
  @if (!readOnly() && editingId() !== note.id) {
27942
28863
  <div class="note-actions">
27943
- <ui-icon name="edit" [size]="14" tooltip="Edit note" (iconClick)="startEdit(note)" />
28864
+ @if (editable()) {
28865
+ <ui-icon name="edit" [size]="14" tooltip="Edit note" (iconClick)="startEdit(note)" />
28866
+ }
27944
28867
  <ui-icon name="delete" variant="danger" [size]="14" tooltip="Delete note" (iconClick)="confirmDelete(note.id)" />
27945
28868
  </div>
27946
28869
  }
27947
28870
  </div>
27948
28871
  @if (editingId() === note.id) {
27949
- <ui-textarea-input ariaLabel="Edit note" [rows]="3" [maxlength]="maxLength" [showErrors]="tooLong(editBody)" [disabled]="saving()" [(ngModel)]="editBody" />
28872
+ <ui-textarea-input ariaLabel="Edit note" [rows]="3" [maxlength]="maxLength()" [showErrors]="tooLong(editBody)" [disabled]="saving()" [(ngModel)]="editBody" />
27950
28873
  <div class="note-item-footer">
27951
28874
  <ui-button variant="secondary" size="sm" (click)="cancelEdit()">Cancel</ui-button>
27952
28875
  <ui-button variant="primary" size="sm" [loading]="saving()" [disabled]="!validBody(editBody)" (click)="saveEdit(note.id)">Save</ui-button>
@@ -28041,6 +28964,10 @@ var NotesComponent = class NotesComponent {
28041
28964
  "dialogTestId",
28042
28965
  "hideClose",
28043
28966
  "closable",
28967
+ "layout",
28968
+ "closeOnBackdrop",
28969
+ "closeOnEscape",
28970
+ "busy",
28044
28971
  "returnFocusTo"
28045
28972
  ],
28046
28973
  outputs: ["close"]
@@ -28082,6 +29009,7 @@ var NotesComponent = class NotesComponent {
28082
29009
  "required",
28083
29010
  "readonly",
28084
29011
  "hint",
29012
+ "ariaDescribedBy",
28085
29013
  "hintAsDescription",
28086
29014
  "error",
28087
29015
  "monospace",
@@ -28156,7 +29084,7 @@ i0.ɵɵngDeclareClassMetadata({
28156
29084
  template: `
28157
29085
  @if (!readOnly()) {
28158
29086
  <div class="note-add">
28159
- <ui-textarea-input ariaLabel="Add a note" placeholder="Add a note..." [rows]="3" [maxlength]="maxLength" [showErrors]="tooLong(newBody)" [disabled]="saving()" [(ngModel)]="newBody"
29087
+ <ui-textarea-input ariaLabel="Add a note" placeholder="Add a note..." [rows]="3" [maxlength]="maxLength()" [showErrors]="tooLong(newBody)" [disabled]="saving()" [(ngModel)]="newBody"
28160
29088
  (keydown.meta.enter)="addNote()" (keydown.control.enter)="addNote()" />
28161
29089
  <div class="note-add-footer">
28162
29090
  <ui-button variant="primary" size="sm" data-testid="note-add-btn" [loading]="saving()" [disabled]="!validBody(newBody)" (click)="addNote()">Add Note</ui-button>
@@ -28183,13 +29111,15 @@ i0.ɵɵngDeclareClassMetadata({
28183
29111
  }
28184
29112
  @if (!readOnly() && editingId() !== note.id) {
28185
29113
  <div class="note-actions">
28186
- <ui-icon name="edit" [size]="14" tooltip="Edit note" (iconClick)="startEdit(note)" />
29114
+ @if (editable()) {
29115
+ <ui-icon name="edit" [size]="14" tooltip="Edit note" (iconClick)="startEdit(note)" />
29116
+ }
28187
29117
  <ui-icon name="delete" variant="danger" [size]="14" tooltip="Delete note" (iconClick)="confirmDelete(note.id)" />
28188
29118
  </div>
28189
29119
  }
28190
29120
  </div>
28191
29121
  @if (editingId() === note.id) {
28192
- <ui-textarea-input ariaLabel="Edit note" [rows]="3" [maxlength]="maxLength" [showErrors]="tooLong(editBody)" [disabled]="saving()" [(ngModel)]="editBody" />
29122
+ <ui-textarea-input ariaLabel="Edit note" [rows]="3" [maxlength]="maxLength()" [showErrors]="tooLong(editBody)" [disabled]="saving()" [(ngModel)]="editBody" />
28193
29123
  <div class="note-item-footer">
28194
29124
  <ui-button variant="secondary" size="sm" (click)="cancelEdit()">Cancel</ui-button>
28195
29125
  <ui-button variant="primary" size="sm" [loading]="saving()" [disabled]="!validBody(editBody)" (click)="saveEdit(note.id)">Save</ui-button>
@@ -28231,6 +29161,14 @@ i0.ɵɵngDeclareClassMetadata({
28231
29161
  required: false
28232
29162
  }]
28233
29163
  }],
29164
+ basePath: [{
29165
+ type: i0.Input,
29166
+ args: [{
29167
+ isSignal: true,
29168
+ alias: "basePath",
29169
+ required: false
29170
+ }]
29171
+ }],
28234
29172
  readOnly: [{
28235
29173
  type: i0.Input,
28236
29174
  args: [{
@@ -28239,6 +29177,22 @@ i0.ɵɵngDeclareClassMetadata({
28239
29177
  required: false
28240
29178
  }]
28241
29179
  }],
29180
+ editable: [{
29181
+ type: i0.Input,
29182
+ args: [{
29183
+ isSignal: true,
29184
+ alias: "editable",
29185
+ required: false
29186
+ }]
29187
+ }],
29188
+ maxLength: [{
29189
+ type: i0.Input,
29190
+ args: [{
29191
+ isSignal: true,
29192
+ alias: "maxLength",
29193
+ required: false
29194
+ }]
29195
+ }],
28242
29196
  totalChange: [{
28243
29197
  type: i0.Output,
28244
29198
  args: ["totalChange"]
@@ -33877,6 +34831,7 @@ var DateRangePickerComponent = class DateRangePickerComponent {
33877
34831
  "min",
33878
34832
  "max",
33879
34833
  "hint",
34834
+ "ariaDescribedBy",
33880
34835
  "error",
33881
34836
  "showErrors",
33882
34837
  "disabled"
@@ -42252,6 +43207,10 @@ var ImageGalleryDialogComponent = class ImageGalleryDialogComponent {
42252
43207
  "dialogTestId",
42253
43208
  "hideClose",
42254
43209
  "closable",
43210
+ "layout",
43211
+ "closeOnBackdrop",
43212
+ "closeOnEscape",
43213
+ "busy",
42255
43214
  "returnFocusTo"
42256
43215
  ],
42257
43216
  outputs: ["close"]
@@ -45220,6 +46179,7 @@ var SetupWizardComponent = class SetupWizardComponent {
45220
46179
  "inputmode",
45221
46180
  "readonly",
45222
46181
  "hint",
46182
+ "ariaDescribedBy",
45223
46183
  "error",
45224
46184
  "phoneFormat",
45225
46185
  "min",
@@ -47279,6 +48239,7 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
47279
48239
  "min",
47280
48240
  "max",
47281
48241
  "hint",
48242
+ "ariaDescribedBy",
47282
48243
  "error",
47283
48244
  "showErrors",
47284
48245
  "disabled"
@@ -47372,6 +48333,7 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
47372
48333
  "valueType",
47373
48334
  "required",
47374
48335
  "hint",
48336
+ "ariaDescribedBy",
47375
48337
  "error",
47376
48338
  "showErrors",
47377
48339
  "size",
@@ -47432,6 +48394,7 @@ var EmailTemplateEditorComponent = class EmailTemplateEditorComponent {
47432
48394
  "inputmode",
47433
48395
  "readonly",
47434
48396
  "hint",
48397
+ "ariaDescribedBy",
47435
48398
  "error",
47436
48399
  "phoneFormat",
47437
48400
  "min",
@@ -48203,6 +49166,6 @@ i0.ɵɵngDeclareClassMetadata({
48203
49166
  }]
48204
49167
  }
48205
49168
  });
48206
- export { ActionBarComponent, AlertComponent, AppShellComponent, AudioPlayerComponent, AvatarComponent, BADGE_VARIANT_STYLES, BadgeComponent, BarRowComponent, BoardCardDirective, BoardComponent, BulkMessagePanelComponent, BusinessHoursComponent, ButtonComponent, CalendarComponent, CardListItemComponent, CheckboxComponent, CheckboxTrailingDirective, ChipComponent, ChipGroupComponent, ColorInputComponent, ColumnFilterComponent, ColumnsComponent, ComboboxComponent, ConfirmOutletComponent, ConfirmService, ContactPickerComponent, DEFAULT_EMAIL_TEMPLATE_BLOCK_GROUPS, DEFAULT_EMAIL_TEMPLATE_VARIABLE_GROUPS, DEFAULT_PASSWORD_RULES, DROPDOWN_GROUP, DataTableComponent, DateInputComponent, DateRangePickerComponent, DatetimeInputComponent, DetailCardComponent, DiscountSelectorComponent, DividerComponent, DropdownComponent, EMAIL_BLOCK_DRAG_TYPE, EMAIL_TEMPLATE_MAX_BODY, EMAIL_TEMPLATE_MAX_TEXT, EMAIL_TEMPLATE_START_TEXT, EmailTemplateEditorComponent, EmptyStateComponent, ErrorComponent, ErrorStateComponent, FORGEROUTE_CONFIG, FadeComponent, FileInputComponent, FixedFooterComponent, FormColSpanDirective, FormComponent, FormRowComponent, FormSectionComponent, HintComponent, IDX_BEHAVIOR_SIGNALS, INTEGRATION_CATALOG, INTEGRATION_FIELD_DEFS, INTEGRATION_GROUP_ORDER, INTEGRATION_OPTION_DEFS, IconComponent, ImageComponent, ImageGalleryComponent, ImageGalleryDialogComponent, ImagePreviewComponent, ImageRepositionComponent, ImportExportComponent, ImportSourceGridComponent, KpiCardComponent, LAYOUT_GAP_PX, ListComponent, ListItemComponent, LiveRegionComponent, MAX_EMAIL_ADDRESS_LENGTH, ModalComponent, MoreMenuComponent, MultiSelectComponent, NOTES_MAX_LENGTH, NotesComponent, OptionCardComponent, PHONE_NUMBER_AREA_CODE_LENGTH, PHONE_NUMBER_ZIP_LENGTH, PageComponent, PaginationComponent, PanelInfoListComponent, PasswordRequirementsComponent, PdfHotspotComponent, PhoneNumberPickerComponent, PillTabsComponent, ProgressBarComponent, ProgressRingComponent, QrCodeComponent, QuickFilterTabsComponent, RICH_TEXT_OPTIONS, RadioComponent, RadioGroupComponent, RadioMatrixComponent, RadioOptionContentDirective, ReadonlyFieldsetComponent, RichTextEditorComponent, SEMANTIC_BADGE_MAP, SETUP_DONE_KEY, SETUP_INTEGRATIONS, SearchInputComponent, SectionHeaderComponent, SelectComponent, SetupWizardComponent, SetupWizardStepDirective, SetupWizardStepHeaderDirective, ShowComponent, SidePanelComponent, SidebarLayoutComponent, SignaturePadComponent, SkeletonComponent, StackComponent, StarComponent, StepperComponent, TableToolbarComponent, TextComponent, TextInputComponent, TextTemplatePickerComponent, TextareaInputComponent, TimeInputComponent, TimelineComponent, ToastComponent, ToastService, ToggleBadgeComponent, ToggleComponent, TooltipDirective, US_STATES, UiFieldValidity, acceptLabel, appShellGroupsStorageKey, autoVariant, blockHasContent, buildDefaultSchedule, buildPreviewDocument, buildVideoBlockHtml, builtInActionIcon, businessTimeOptions, createFieldReveal, decodeFilterValues, digitsOnly, downloadBlob, encodeFilterValue, encodeFilterValues, errorContextInterceptor, escapeHtml, fileMatchesAccept, formatAddress, formatCategoryLabel, formatCurrency, formatFileSize, formatIsoDate, formatIsoDateTime, formatTime, formatVideoDuration, getEligibleIds, getEligibleOptions, getErrorMessage, humanReadableMessage, iconPath, insideEditorBlock, integrationPlainText, integrationsForApp, integrationsOnlyFor, isBlockDrag, isValidEmailAddress, isWebUrl, isoKey, issueToErrors, maxLengthIssue, normalizeHexColor, parseBizHours, parseIso, parseTime, passwordMeetsRules, pluralize, provideForgerouteToast, reorderItems, requiredIssue, resolveLayoutGap, resolvePreset, serializeBizHours, serializedTextLength, setupIntegrations, splitIntro };
49169
+ export { ActionBarComponent, AlertComponent, AppShellComponent, AudioPlayerComponent, AvatarComponent, BADGE_VARIANT_STYLES, BadgeComponent, BankAccountFormComponent, BarRowComponent, BoardCardDirective, BoardComponent, BulkMessagePanelComponent, BusinessHoursComponent, ButtonComponent, CalendarComponent, CardListItemComponent, CheckboxComponent, CheckboxTrailingDirective, ChipComponent, ChipGroupComponent, ColorInputComponent, ColumnFilterComponent, ColumnsComponent, ComboboxComponent, ConfirmOutletComponent, ConfirmService, ContactPickerComponent, DEFAULT_BANK_ACCOUNT_TYPE_OPTIONS, DEFAULT_BANK_HOLDER_TYPE_OPTIONS, DEFAULT_BANK_MANDATE_TEXT, DEFAULT_EMAIL_TEMPLATE_BLOCK_GROUPS, DEFAULT_EMAIL_TEMPLATE_VARIABLE_GROUPS, DEFAULT_PASSWORD_RULES, DROPDOWN_GROUP, DataTableComponent, DateInputComponent, DateRangePickerComponent, DatetimeInputComponent, DetailCardComponent, DiscountSelectorComponent, DividerComponent, DropdownComponent, EMAIL_BLOCK_DRAG_TYPE, EMAIL_TEMPLATE_MAX_BODY, EMAIL_TEMPLATE_MAX_TEXT, EMAIL_TEMPLATE_START_TEXT, EmailTemplateEditorComponent, EmptyStateComponent, ErrorComponent, ErrorStateComponent, FORGEROUTE_CONFIG, FadeComponent, FileInputComponent, FixedFooterComponent, FormColSpanDirective, FormComponent, FormRowComponent, FormSectionComponent, HintComponent, IDX_BEHAVIOR_SIGNALS, INTEGRATION_CATALOG, INTEGRATION_FIELD_DEFS, INTEGRATION_GROUP_ORDER, INTEGRATION_OPTION_DEFS, IconComponent, ImageComponent, ImageGalleryComponent, ImageGalleryDialogComponent, ImagePreviewComponent, ImageRepositionComponent, ImportExportComponent, ImportSourceGridComponent, KpiCardComponent, LAYOUT_GAP_PX, ListComponent, ListItemComponent, LiveRegionComponent, MAX_EMAIL_ADDRESS_LENGTH, ModalComponent, MoreMenuComponent, MultiSelectComponent, NOTES_MAX_LENGTH, NotesComponent, OptionCardComponent, PHONE_NUMBER_AREA_CODE_LENGTH, PHONE_NUMBER_ZIP_LENGTH, PageComponent, PaginationComponent, PanelInfoListComponent, PasswordRequirementsComponent, PdfHotspotComponent, PhoneNumberPickerComponent, PillTabsComponent, ProgressBarComponent, ProgressRingComponent, QrCodeComponent, QuickFilterTabsComponent, RICH_TEXT_OPTIONS, RadioComponent, RadioGroupComponent, RadioMatrixComponent, RadioOptionContentDirective, ReadonlyFieldsetComponent, RichTextEditorComponent, SEMANTIC_BADGE_MAP, SETUP_DONE_KEY, SETUP_INTEGRATIONS, SearchInputComponent, SectionHeaderComponent, SelectComponent, SetupWizardComponent, SetupWizardStepDirective, SetupWizardStepHeaderDirective, ShowComponent, SidePanelComponent, SidebarLayoutComponent, SignaturePadComponent, SkeletonComponent, StackComponent, StarComponent, StepperComponent, TableToolbarComponent, TextComponent, TextInputComponent, TextTemplatePickerComponent, TextareaInputComponent, TimeInputComponent, TimelineComponent, ToastComponent, ToastService, ToggleBadgeComponent, ToggleComponent, TooltipDirective, US_STATES, UiFieldValidity, acceptLabel, appShellGroupsStorageKey, autoVariant, blockHasContent, buildDefaultSchedule, buildPreviewDocument, buildVideoBlockHtml, builtInActionIcon, businessTimeOptions, createFieldReveal, decodeFilterValues, digitsOnly, downloadBlob, encodeFilterValue, encodeFilterValues, errorContextInterceptor, escapeHtml, fileMatchesAccept, formatAddress, formatCategoryLabel, formatCurrency, formatFileSize, formatIsoDate, formatIsoDateTime, formatTime, formatVideoDuration, getEligibleIds, getEligibleOptions, getErrorMessage, humanReadableMessage, iconPath, insideEditorBlock, integrationPlainText, integrationsForApp, integrationsOnlyFor, isBlockDrag, isValidEmailAddress, isWebUrl, isoKey, issueToErrors, maxLengthIssue, mergeDescribedBy, normalizeHexColor, parseBizHours, parseIso, parseTime, passwordMeetsRules, pluralize, provideForgerouteToast, reorderItems, requiredIssue, resolveLayoutGap, resolvePreset, serializeBizHours, serializedTextLength, setupIntegrations, splitIntro };
48207
49170
 
48208
49171
  //# sourceMappingURL=forgeroute-ui.mjs.map