@forgeroute/ui 0.3.12 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11345,6 +11345,278 @@ i0.ɵɵngDeclareClassMetadata({
11345
11345
  }]
11346
11346
  }
11347
11347
  });
11348
+ var ProgressRingComponent = class ProgressRingComponent {
11349
+ constructor() {
11350
+ this.value = input(0, ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
11351
+ this.max = input(100, ...ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []);
11352
+ this.size = input(58, ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
11353
+ this.strokeWidth = input(5, ...ngDevMode ? [{ debugName: "strokeWidth" }] : /* istanbul ignore next */ []);
11354
+ this.variant = input(null, ...ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []);
11355
+ this.label = input("", ...ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []);
11356
+ this.showValue = input(true, ...ngDevMode ? [{ debugName: "showValue" }] : /* istanbul ignore next */ []);
11357
+ this.ariaLabel = input("", ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
11358
+ this.ariaLabelledby = input("", ...ngDevMode ? [{ debugName: "ariaLabelledby" }] : /* istanbul ignore next */ []);
11359
+ this.valueText = input("", ...ngDevMode ? [{ debugName: "valueText" }] : /* istanbul ignore next */ []);
11360
+ this.safeMax = computed(() => {
11361
+ const m = this.max();
11362
+ return Number.isFinite(m) && m > 0 ? m : 0;
11363
+ }, ...ngDevMode ? [{ debugName: "safeMax" }] : /* istanbul ignore next */ []);
11364
+ this.clampedValue = computed(() => {
11365
+ const v = this.value();
11366
+ return Math.min(Math.max(Number.isNaN(v) ? 0 : v, 0), this.safeMax());
11367
+ }, ...ngDevMode ? [{ debugName: "clampedValue" }] : /* istanbul ignore next */ []);
11368
+ this.exact = computed(() => this.safeMax() > 0 ? this.clampedValue() / this.safeMax() * 100 : 0, ...ngDevMode ? [{ debugName: "exact" }] : /* istanbul ignore next */ []);
11369
+ this.percent = computed(() => Math.round(this.exact()), ...ngDevMode ? [{ debugName: "percent" }] : /* istanbul ignore next */ []);
11370
+ this.center = computed(() => this.size() / 2, ...ngDevMode ? [{ debugName: "center" }] : /* istanbul ignore next */ []);
11371
+ this.radius = computed(() => Math.max((this.size() - this.strokeWidth()) / 2, 0), ...ngDevMode ? [{ debugName: "radius" }] : /* istanbul ignore next */ []);
11372
+ this.circumference = computed(() => 2 * Math.PI * this.radius(), ...ngDevMode ? [{ debugName: "circumference" }] : /* istanbul ignore next */ []);
11373
+ this.dashOffset = computed(() => this.circumference() * (1 - this.exact() / 100), ...ngDevMode ? [{ debugName: "dashOffset" }] : /* istanbul ignore next */ []);
11374
+ this.effectiveVariant = computed(() => {
11375
+ const fixed = this.variant();
11376
+ if (fixed) return fixed;
11377
+ const e = this.exact();
11378
+ return e <= 25 ? "red" : e <= 50 ? "amber" : e <= 75 ? "blue" : "green";
11379
+ }, ...ngDevMode ? [{ debugName: "effectiveVariant" }] : /* istanbul ignore next */ []);
11380
+ }
11381
+ static {
11382
+ this.ɵfac = i0.ɵɵngDeclareFactory({
11383
+ minVersion: "12.0.0",
11384
+ version: "22.2.2",
11385
+ ngImport: i0,
11386
+ type: ProgressRingComponent,
11387
+ deps: [],
11388
+ target: i0.ɵɵFactoryTarget.Component
11389
+ });
11390
+ }
11391
+ static {
11392
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
11393
+ minVersion: "17.0.0",
11394
+ version: "22.2.2",
11395
+ type: ProgressRingComponent,
11396
+ isStandalone: true,
11397
+ selector: "ui-progress-ring",
11398
+ inputs: {
11399
+ value: {
11400
+ classPropertyName: "value",
11401
+ publicName: "value",
11402
+ isSignal: true,
11403
+ isRequired: false,
11404
+ transformFunction: null
11405
+ },
11406
+ max: {
11407
+ classPropertyName: "max",
11408
+ publicName: "max",
11409
+ isSignal: true,
11410
+ isRequired: false,
11411
+ transformFunction: null
11412
+ },
11413
+ size: {
11414
+ classPropertyName: "size",
11415
+ publicName: "size",
11416
+ isSignal: true,
11417
+ isRequired: false,
11418
+ transformFunction: null
11419
+ },
11420
+ strokeWidth: {
11421
+ classPropertyName: "strokeWidth",
11422
+ publicName: "strokeWidth",
11423
+ isSignal: true,
11424
+ isRequired: false,
11425
+ transformFunction: null
11426
+ },
11427
+ variant: {
11428
+ classPropertyName: "variant",
11429
+ publicName: "variant",
11430
+ isSignal: true,
11431
+ isRequired: false,
11432
+ transformFunction: null
11433
+ },
11434
+ label: {
11435
+ classPropertyName: "label",
11436
+ publicName: "label",
11437
+ isSignal: true,
11438
+ isRequired: false,
11439
+ transformFunction: null
11440
+ },
11441
+ showValue: {
11442
+ classPropertyName: "showValue",
11443
+ publicName: "showValue",
11444
+ isSignal: true,
11445
+ isRequired: false,
11446
+ transformFunction: null
11447
+ },
11448
+ ariaLabel: {
11449
+ classPropertyName: "ariaLabel",
11450
+ publicName: "ariaLabel",
11451
+ isSignal: true,
11452
+ isRequired: false,
11453
+ transformFunction: null
11454
+ },
11455
+ ariaLabelledby: {
11456
+ classPropertyName: "ariaLabelledby",
11457
+ publicName: "ariaLabelledby",
11458
+ isSignal: true,
11459
+ isRequired: false,
11460
+ transformFunction: null
11461
+ },
11462
+ valueText: {
11463
+ classPropertyName: "valueText",
11464
+ publicName: "valueText",
11465
+ isSignal: true,
11466
+ isRequired: false,
11467
+ transformFunction: null
11468
+ }
11469
+ },
11470
+ ngImport: i0,
11471
+ template: `
11472
+ <div class="pr"
11473
+ role="progressbar"
11474
+ [style.width.px]="size()"
11475
+ [style.height.px]="size()"
11476
+ [attr.aria-valuemin]="0"
11477
+ [attr.aria-valuemax]="safeMax()"
11478
+ [attr.aria-valuenow]="clampedValue()"
11479
+ [attr.aria-valuetext]="valueText() || null"
11480
+ [attr.aria-labelledby]="ariaLabelledby() || null"
11481
+ [attr.aria-label]="ariaLabelledby() ? null : (ariaLabel() || null)">
11482
+ <svg [attr.width]="size()" [attr.height]="size()" [attr.viewBox]="'0 0 ' + size() + ' ' + size()" aria-hidden="true" focusable="false">
11483
+ <circle class="pr-track" [attr.cx]="center()" [attr.cy]="center()" [attr.r]="radius()" fill="none" [attr.stroke-width]="strokeWidth()" />
11484
+ <circle [class]="'pr-arc pr-' + effectiveVariant()" [attr.cx]="center()" [attr.cy]="center()" [attr.r]="radius()" fill="none"
11485
+ [attr.stroke-width]="strokeWidth()" stroke-linecap="round"
11486
+ [attr.stroke-dasharray]="circumference()" [attr.stroke-dashoffset]="dashOffset()"
11487
+ [attr.transform]="'rotate(-90 ' + center() + ' ' + center() + ')'" />
11488
+ </svg>
11489
+ @if (showValue()) {
11490
+ <span class="pr-value" [style.font-size.px]="size() * 0.21">{{ label() || percent() + '%' }}</span>
11491
+ }
11492
+ </div>
11493
+ `,
11494
+ isInline: true,
11495
+ styles: [":host{display:inline-block;line-height:0}.pr{position:relative;display:inline-flex;align-items:center;justify-content:center}.pr svg{position:absolute;inset:0}.pr-track{stroke:#e2e8f0}.pr-arc{transition:stroke-dashoffset .8s ease}@media(prefers-reduced-motion:reduce){.pr-arc{transition:none}}.pr-blue{stroke:#3b82f6}.pr-green{stroke:#16a34a}.pr-amber{stroke:#f59e0b}.pr-red{stroke:#ef4444}.pr-slate{stroke:#94a3b8}.pr-sky{stroke:#0ea5e9}@media(forced-colors:active){.pr-track{stroke:CanvasText;opacity:.35}.pr-arc{stroke:Highlight}}.pr-value{position:relative;font-weight:700;line-height:1;color:#1e293b}\n"],
11496
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
11497
+ });
11498
+ }
11499
+ };
11500
+ i0.ɵɵngDeclareClassMetadata({
11501
+ minVersion: "12.0.0",
11502
+ version: "22.2.2",
11503
+ ngImport: i0,
11504
+ type: ProgressRingComponent,
11505
+ decorators: [{
11506
+ type: Component,
11507
+ args: [{
11508
+ selector: "ui-progress-ring",
11509
+ standalone: true,
11510
+ changeDetection: ChangeDetectionStrategy.OnPush,
11511
+ template: `
11512
+ <div class="pr"
11513
+ role="progressbar"
11514
+ [style.width.px]="size()"
11515
+ [style.height.px]="size()"
11516
+ [attr.aria-valuemin]="0"
11517
+ [attr.aria-valuemax]="safeMax()"
11518
+ [attr.aria-valuenow]="clampedValue()"
11519
+ [attr.aria-valuetext]="valueText() || null"
11520
+ [attr.aria-labelledby]="ariaLabelledby() || null"
11521
+ [attr.aria-label]="ariaLabelledby() ? null : (ariaLabel() || null)">
11522
+ <svg [attr.width]="size()" [attr.height]="size()" [attr.viewBox]="'0 0 ' + size() + ' ' + size()" aria-hidden="true" focusable="false">
11523
+ <circle class="pr-track" [attr.cx]="center()" [attr.cy]="center()" [attr.r]="radius()" fill="none" [attr.stroke-width]="strokeWidth()" />
11524
+ <circle [class]="'pr-arc pr-' + effectiveVariant()" [attr.cx]="center()" [attr.cy]="center()" [attr.r]="radius()" fill="none"
11525
+ [attr.stroke-width]="strokeWidth()" stroke-linecap="round"
11526
+ [attr.stroke-dasharray]="circumference()" [attr.stroke-dashoffset]="dashOffset()"
11527
+ [attr.transform]="'rotate(-90 ' + center() + ' ' + center() + ')'" />
11528
+ </svg>
11529
+ @if (showValue()) {
11530
+ <span class="pr-value" [style.font-size.px]="size() * 0.21">{{ label() || percent() + '%' }}</span>
11531
+ }
11532
+ </div>
11533
+ `,
11534
+ styles: [":host{display:inline-block;line-height:0}.pr{position:relative;display:inline-flex;align-items:center;justify-content:center}.pr svg{position:absolute;inset:0}.pr-track{stroke:#e2e8f0}.pr-arc{transition:stroke-dashoffset .8s ease}@media(prefers-reduced-motion:reduce){.pr-arc{transition:none}}.pr-blue{stroke:#3b82f6}.pr-green{stroke:#16a34a}.pr-amber{stroke:#f59e0b}.pr-red{stroke:#ef4444}.pr-slate{stroke:#94a3b8}.pr-sky{stroke:#0ea5e9}@media(forced-colors:active){.pr-track{stroke:CanvasText;opacity:.35}.pr-arc{stroke:Highlight}}.pr-value{position:relative;font-weight:700;line-height:1;color:#1e293b}\n"]
11535
+ }]
11536
+ }],
11537
+ propDecorators: {
11538
+ value: [{
11539
+ type: i0.Input,
11540
+ args: [{
11541
+ isSignal: true,
11542
+ alias: "value",
11543
+ required: false
11544
+ }]
11545
+ }],
11546
+ max: [{
11547
+ type: i0.Input,
11548
+ args: [{
11549
+ isSignal: true,
11550
+ alias: "max",
11551
+ required: false
11552
+ }]
11553
+ }],
11554
+ size: [{
11555
+ type: i0.Input,
11556
+ args: [{
11557
+ isSignal: true,
11558
+ alias: "size",
11559
+ required: false
11560
+ }]
11561
+ }],
11562
+ strokeWidth: [{
11563
+ type: i0.Input,
11564
+ args: [{
11565
+ isSignal: true,
11566
+ alias: "strokeWidth",
11567
+ required: false
11568
+ }]
11569
+ }],
11570
+ variant: [{
11571
+ type: i0.Input,
11572
+ args: [{
11573
+ isSignal: true,
11574
+ alias: "variant",
11575
+ required: false
11576
+ }]
11577
+ }],
11578
+ label: [{
11579
+ type: i0.Input,
11580
+ args: [{
11581
+ isSignal: true,
11582
+ alias: "label",
11583
+ required: false
11584
+ }]
11585
+ }],
11586
+ showValue: [{
11587
+ type: i0.Input,
11588
+ args: [{
11589
+ isSignal: true,
11590
+ alias: "showValue",
11591
+ required: false
11592
+ }]
11593
+ }],
11594
+ ariaLabel: [{
11595
+ type: i0.Input,
11596
+ args: [{
11597
+ isSignal: true,
11598
+ alias: "ariaLabel",
11599
+ required: false
11600
+ }]
11601
+ }],
11602
+ ariaLabelledby: [{
11603
+ type: i0.Input,
11604
+ args: [{
11605
+ isSignal: true,
11606
+ alias: "ariaLabelledby",
11607
+ required: false
11608
+ }]
11609
+ }],
11610
+ valueText: [{
11611
+ type: i0.Input,
11612
+ args: [{
11613
+ isSignal: true,
11614
+ alias: "valueText",
11615
+ required: false
11616
+ }]
11617
+ }]
11618
+ }
11619
+ });
11348
11620
  var AudioPlayerComponent = class AudioPlayerComponent {
11349
11621
  constructor() {
11350
11622
  this.src = input("", ...ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []);
@@ -13619,6 +13891,8 @@ var AlertComponent = class AlertComponent {
13619
13891
  this.variant = input("info", ...ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []);
13620
13892
  this.title = input("", ...ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []);
13621
13893
  this.dismissible = input(false, ...ngDevMode ? [{ debugName: "dismissible" }] : /* istanbul ignore next */ []);
13894
+ this.quiet = input(false, ...ngDevMode ? [{ debugName: "quiet" }] : /* istanbul ignore next */ []);
13895
+ this.compact = input(false, ...ngDevMode ? [{ debugName: "compact" }] : /* istanbul ignore next */ []);
13622
13896
  this.dismissed = output();
13623
13897
  }
13624
13898
  static {
@@ -13659,12 +13933,26 @@ var AlertComponent = class AlertComponent {
13659
13933
  isSignal: true,
13660
13934
  isRequired: false,
13661
13935
  transformFunction: null
13936
+ },
13937
+ quiet: {
13938
+ classPropertyName: "quiet",
13939
+ publicName: "quiet",
13940
+ isSignal: true,
13941
+ isRequired: false,
13942
+ transformFunction: null
13943
+ },
13944
+ compact: {
13945
+ classPropertyName: "compact",
13946
+ publicName: "compact",
13947
+ isSignal: true,
13948
+ isRequired: false,
13949
+ transformFunction: null
13662
13950
  }
13663
13951
  },
13664
13952
  outputs: { dismissed: "dismissed" },
13665
13953
  ngImport: i0,
13666
13954
  template: `
13667
- <div class="alert" [class]="'alert alert--' + variant()" [attr.role]="variant() === 'danger' ? 'alert' : 'status'">
13955
+ <div class="alert" [class]="'alert alert--' + variant()" [class.alert--compact]="compact()" [attr.role]="quiet() ? null : (variant() === 'danger' ? 'alert' : 'status')">
13668
13956
  <div class="alert-content">
13669
13957
  @if (title()) { <div class="alert-title">{{ title() }}</div> }
13670
13958
  <div class="alert-body"><ng-content /></div>
@@ -13679,7 +13967,7 @@ var AlertComponent = class AlertComponent {
13679
13967
  </div>
13680
13968
  `,
13681
13969
  isInline: true,
13682
- styles: [":host{display:block}.alert{display:flex;align-items:flex-start;gap:12px;padding:12px 14px;border-radius:8px;border-left:4px solid transparent;font-size:13px;line-height:1.5}.alert--info{background:#dbeafe;border-color:#3b82f6;color:#1e3a8a}.alert--success{background:#dcfce7;border-color:#22c55e;color:#14532d}.alert--warning{background:#ffedd5;border-color:#f97316;color:#7c2d12}.alert--danger{background:#fee2e2;border-color:#ef4444;color:#7f1d1d}.alert-content{flex:1;display:flex;flex-direction:column;gap:2px}.alert-title{font-weight:700}.alert-body{opacity:.9;display:flex;align-items:center;flex-wrap:wrap;gap:8px}.alert-dismiss{flex-shrink:0;background:none;border:none;cursor:pointer;padding:2px;border-radius:4px;color:inherit;opacity:.6;display:flex;align-items:center;transition:opacity .15s}.alert-dismiss:hover{opacity:1}\n"],
13970
+ styles: [":host{display:block}.alert{display:flex;align-items:flex-start;gap:12px;padding:12px 14px;border-radius:8px;border-left:4px solid transparent;font-size:13px;line-height:1.5}.alert--info{background:#dbeafe;border-color:#3b82f6;color:#1e3a8a}.alert--success{background:#dcfce7;border-color:#22c55e;color:#14532d}.alert--warning{background:#ffedd5;border-color:#f97316;color:#7c2d12}.alert--danger{background:#fee2e2;border-color:#ef4444;color:#7f1d1d}.alert--compact{padding:8px 12px;gap:8px;font-size:12.5px;line-height:1.4}.alert-content{flex:1;display:flex;flex-direction:column;gap:2px}.alert-title{font-weight:700}.alert-body{opacity:.9;display:flex;align-items:center;flex-wrap:wrap;gap:8px}.alert-dismiss{flex-shrink:0;background:none;border:none;cursor:pointer;padding:2px;border-radius:4px;color:inherit;opacity:.6;display:flex;align-items:center;transition:opacity .15s}.alert-dismiss:hover{opacity:1}\n"],
13683
13971
  changeDetection: i0.ChangeDetectionStrategy.OnPush
13684
13972
  });
13685
13973
  }
@@ -13696,7 +13984,7 @@ i0.ɵɵngDeclareClassMetadata({
13696
13984
  standalone: true,
13697
13985
  changeDetection: ChangeDetectionStrategy.OnPush,
13698
13986
  template: `
13699
- <div class="alert" [class]="'alert alert--' + variant()" [attr.role]="variant() === 'danger' ? 'alert' : 'status'">
13987
+ <div class="alert" [class]="'alert alert--' + variant()" [class.alert--compact]="compact()" [attr.role]="quiet() ? null : (variant() === 'danger' ? 'alert' : 'status')">
13700
13988
  <div class="alert-content">
13701
13989
  @if (title()) { <div class="alert-title">{{ title() }}</div> }
13702
13990
  <div class="alert-body"><ng-content /></div>
@@ -13710,7 +13998,7 @@ i0.ɵɵngDeclareClassMetadata({
13710
13998
  }
13711
13999
  </div>
13712
14000
  `,
13713
- styles: [":host{display:block}.alert{display:flex;align-items:flex-start;gap:12px;padding:12px 14px;border-radius:8px;border-left:4px solid transparent;font-size:13px;line-height:1.5}.alert--info{background:#dbeafe;border-color:#3b82f6;color:#1e3a8a}.alert--success{background:#dcfce7;border-color:#22c55e;color:#14532d}.alert--warning{background:#ffedd5;border-color:#f97316;color:#7c2d12}.alert--danger{background:#fee2e2;border-color:#ef4444;color:#7f1d1d}.alert-content{flex:1;display:flex;flex-direction:column;gap:2px}.alert-title{font-weight:700}.alert-body{opacity:.9;display:flex;align-items:center;flex-wrap:wrap;gap:8px}.alert-dismiss{flex-shrink:0;background:none;border:none;cursor:pointer;padding:2px;border-radius:4px;color:inherit;opacity:.6;display:flex;align-items:center;transition:opacity .15s}.alert-dismiss:hover{opacity:1}\n"]
14001
+ styles: [":host{display:block}.alert{display:flex;align-items:flex-start;gap:12px;padding:12px 14px;border-radius:8px;border-left:4px solid transparent;font-size:13px;line-height:1.5}.alert--info{background:#dbeafe;border-color:#3b82f6;color:#1e3a8a}.alert--success{background:#dcfce7;border-color:#22c55e;color:#14532d}.alert--warning{background:#ffedd5;border-color:#f97316;color:#7c2d12}.alert--danger{background:#fee2e2;border-color:#ef4444;color:#7f1d1d}.alert--compact{padding:8px 12px;gap:8px;font-size:12.5px;line-height:1.4}.alert-content{flex:1;display:flex;flex-direction:column;gap:2px}.alert-title{font-weight:700}.alert-body{opacity:.9;display:flex;align-items:center;flex-wrap:wrap;gap:8px}.alert-dismiss{flex-shrink:0;background:none;border:none;cursor:pointer;padding:2px;border-radius:4px;color:inherit;opacity:.6;display:flex;align-items:center;transition:opacity .15s}.alert-dismiss:hover{opacity:1}\n"]
13714
14002
  }]
13715
14003
  }],
13716
14004
  propDecorators: {
@@ -13738,6 +14026,22 @@ i0.ɵɵngDeclareClassMetadata({
13738
14026
  required: false
13739
14027
  }]
13740
14028
  }],
14029
+ quiet: [{
14030
+ type: i0.Input,
14031
+ args: [{
14032
+ isSignal: true,
14033
+ alias: "quiet",
14034
+ required: false
14035
+ }]
14036
+ }],
14037
+ compact: [{
14038
+ type: i0.Input,
14039
+ args: [{
14040
+ isSignal: true,
14041
+ alias: "compact",
14042
+ required: false
14043
+ }]
14044
+ }],
13741
14045
  dismissed: [{
13742
14046
  type: i0.Output,
13743
14047
  args: ["dismissed"]
@@ -14291,7 +14595,9 @@ var PhoneNumberPickerComponent = class PhoneNumberPickerComponent {
14291
14595
  inputs: [
14292
14596
  "variant",
14293
14597
  "title",
14294
- "dismissible"
14598
+ "dismissible",
14599
+ "quiet",
14600
+ "compact"
14295
14601
  ],
14296
14602
  outputs: ["dismissed"]
14297
14603
  },
@@ -22573,7 +22879,9 @@ var SendEmailComponent = class SendEmailComponent {
22573
22879
  inputs: [
22574
22880
  "variant",
22575
22881
  "title",
22576
- "dismissible"
22882
+ "dismissible",
22883
+ "quiet",
22884
+ "compact"
22577
22885
  ],
22578
22886
  outputs: ["dismissed"]
22579
22887
  }
@@ -24191,7 +24499,9 @@ var SendTextComponent = class SendTextComponent {
24191
24499
  inputs: [
24192
24500
  "variant",
24193
24501
  "title",
24194
- "dismissible"
24502
+ "dismissible",
24503
+ "quiet",
24504
+ "compact"
24195
24505
  ],
24196
24506
  outputs: ["dismissed"]
24197
24507
  }
@@ -26274,21 +26584,123 @@ i0.ɵɵngDeclareClassMetadata({
26274
26584
  }]
26275
26585
  }
26276
26586
  });
26277
- var ImagePreviewComponent = class ImagePreviewComponent {
26587
+ const SIZE_REM = {
26588
+ sm: "0.8125rem",
26589
+ md: "0.875rem",
26590
+ lg: "1rem"
26591
+ };
26592
+ var TextComponent = class TextComponent {
26278
26593
  constructor() {
26279
- this.src = input(null, ...ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []);
26280
- this.alt = input("", ...ngDevMode ? [{ debugName: "alt" }] : /* istanbul ignore next */ []);
26281
- this.shape = input("rounded", ...ngDevMode ? [{ debugName: "shape" }] : /* istanbul ignore next */ []);
26594
+ this.text = input("", ...ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []);
26282
26595
  this.size = input("md", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
26283
- this.placeholder = input("image", ...ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []);
26284
- this.loading = input("lazy", ...ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []);
26285
- this.positionX = input(50, ...ngDevMode ? [{ debugName: "positionX" }] : /* istanbul ignore next */ []);
26286
- this.positionY = input(50, ...ngDevMode ? [{ debugName: "positionY" }] : /* istanbul ignore next */ []);
26287
- this.retryKey = input(null, ...ngDevMode ? [{ debugName: "retryKey" }] : /* istanbul ignore next */ []);
26288
- this._failed = signal(false, ...ngDevMode ? [{ debugName: "_failed" }] : /* istanbul ignore next */ []);
26289
- this._url = computed(() => this.src()?.trim() || null, ...ngDevMode ? [{ debugName: "_url" }] : /* istanbul ignore next */ []);
26290
- this._objectPosition = computed(() => `${this.positionX() ?? 50}% ${this.positionY() ?? 50}%`, ...ngDevMode ? [{ debugName: "_objectPosition" }] : /* istanbul ignore next */ []);
26291
- this._cls = computed(() => `ip-${this.shape()}-${this.size()}`, ...ngDevMode ? [{ debugName: "_cls" }] : /* istanbul ignore next */ []);
26596
+ this.tone = input("default", ...ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []);
26597
+ this.fontSize = computed(() => SIZE_REM[this.size()] ?? SIZE_REM.md, ...ngDevMode ? [{ debugName: "fontSize" }] : /* istanbul ignore next */ []);
26598
+ }
26599
+ static {
26600
+ this.ɵfac = i0.ɵɵngDeclareFactory({
26601
+ minVersion: "12.0.0",
26602
+ version: "22.2.2",
26603
+ ngImport: i0,
26604
+ type: TextComponent,
26605
+ deps: [],
26606
+ target: i0.ɵɵFactoryTarget.Component
26607
+ });
26608
+ }
26609
+ static {
26610
+ this.ɵcmp = i0.ɵɵngDeclareComponent({
26611
+ minVersion: "17.1.0",
26612
+ version: "22.2.2",
26613
+ type: TextComponent,
26614
+ isStandalone: true,
26615
+ selector: "ui-text",
26616
+ inputs: {
26617
+ text: {
26618
+ classPropertyName: "text",
26619
+ publicName: "text",
26620
+ isSignal: true,
26621
+ isRequired: false,
26622
+ transformFunction: null
26623
+ },
26624
+ size: {
26625
+ classPropertyName: "size",
26626
+ publicName: "size",
26627
+ isSignal: true,
26628
+ isRequired: false,
26629
+ transformFunction: null
26630
+ },
26631
+ tone: {
26632
+ classPropertyName: "tone",
26633
+ publicName: "tone",
26634
+ isSignal: true,
26635
+ isRequired: false,
26636
+ transformFunction: null
26637
+ }
26638
+ },
26639
+ ngImport: i0,
26640
+ template: `<div class="tx" [class.tx-muted]="tone() === 'muted'" [style.font-size]="fontSize()">{{ text() }}</div>`,
26641
+ isInline: true,
26642
+ styles: [":host{display:block;min-width:0}.tx{margin:0;line-height:1.5;color:#1f2937;white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word;-webkit-user-select:text;user-select:text}.tx-muted{color:#64748b}\n"],
26643
+ changeDetection: i0.ChangeDetectionStrategy.OnPush
26644
+ });
26645
+ }
26646
+ };
26647
+ i0.ɵɵngDeclareClassMetadata({
26648
+ minVersion: "12.0.0",
26649
+ version: "22.2.2",
26650
+ ngImport: i0,
26651
+ type: TextComponent,
26652
+ decorators: [{
26653
+ type: Component,
26654
+ args: [{
26655
+ selector: "ui-text",
26656
+ standalone: true,
26657
+ changeDetection: ChangeDetectionStrategy.OnPush,
26658
+ template: `<div class="tx" [class.tx-muted]="tone() === 'muted'" [style.font-size]="fontSize()">{{ text() }}</div>`,
26659
+ styles: [":host{display:block;min-width:0}.tx{margin:0;line-height:1.5;color:#1f2937;white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word;-webkit-user-select:text;user-select:text}.tx-muted{color:#64748b}\n"]
26660
+ }]
26661
+ }],
26662
+ propDecorators: {
26663
+ text: [{
26664
+ type: i0.Input,
26665
+ args: [{
26666
+ isSignal: true,
26667
+ alias: "text",
26668
+ required: false
26669
+ }]
26670
+ }],
26671
+ size: [{
26672
+ type: i0.Input,
26673
+ args: [{
26674
+ isSignal: true,
26675
+ alias: "size",
26676
+ required: false
26677
+ }]
26678
+ }],
26679
+ tone: [{
26680
+ type: i0.Input,
26681
+ args: [{
26682
+ isSignal: true,
26683
+ alias: "tone",
26684
+ required: false
26685
+ }]
26686
+ }]
26687
+ }
26688
+ });
26689
+ var ImagePreviewComponent = class ImagePreviewComponent {
26690
+ constructor() {
26691
+ this.src = input(null, ...ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []);
26692
+ this.alt = input("", ...ngDevMode ? [{ debugName: "alt" }] : /* istanbul ignore next */ []);
26693
+ this.shape = input("rounded", ...ngDevMode ? [{ debugName: "shape" }] : /* istanbul ignore next */ []);
26694
+ this.size = input("md", ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
26695
+ this.placeholder = input("image", ...ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []);
26696
+ this.loading = input("lazy", ...ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []);
26697
+ this.positionX = input(50, ...ngDevMode ? [{ debugName: "positionX" }] : /* istanbul ignore next */ []);
26698
+ this.positionY = input(50, ...ngDevMode ? [{ debugName: "positionY" }] : /* istanbul ignore next */ []);
26699
+ this.retryKey = input(null, ...ngDevMode ? [{ debugName: "retryKey" }] : /* istanbul ignore next */ []);
26700
+ this._failed = signal(false, ...ngDevMode ? [{ debugName: "_failed" }] : /* istanbul ignore next */ []);
26701
+ this._url = computed(() => this.src()?.trim() || null, ...ngDevMode ? [{ debugName: "_url" }] : /* istanbul ignore next */ []);
26702
+ this._objectPosition = computed(() => `${this.positionX() ?? 50}% ${this.positionY() ?? 50}%`, ...ngDevMode ? [{ debugName: "_objectPosition" }] : /* istanbul ignore next */ []);
26703
+ this._cls = computed(() => `ip-${this.shape()}-${this.size()}`, ...ngDevMode ? [{ debugName: "_cls" }] : /* istanbul ignore next */ []);
26292
26704
  effect(() => {
26293
26705
  this.src();
26294
26706
  this.retryKey();
@@ -29461,6 +29873,21 @@ function provideForgerouteToast(options = {}) {
29461
29873
  });
29462
29874
  })]);
29463
29875
  }
29876
+ const LAYOUT_GAP_PX = {
29877
+ none: 0,
29878
+ xs: 4,
29879
+ sm: 8,
29880
+ md: 16,
29881
+ lg: 24,
29882
+ xl: 32
29883
+ };
29884
+ const CSS_LENGTH = /^(?:0|-?(?:\d+\.?\d*|\.\d+)(?:px|rem|em|%|vh|vw|ch)|(?:calc|var)\([^;{}]*\))$/i;
29885
+ function resolveLayoutGap(gap, fallback) {
29886
+ const v = (gap ?? "").trim();
29887
+ if (Object.prototype.hasOwnProperty.call(LAYOUT_GAP_PX, v)) return `${LAYOUT_GAP_PX[v]}px`;
29888
+ if (v && CSS_LENGTH.test(v)) return v;
29889
+ return `${LAYOUT_GAP_PX[fallback]}px`;
29890
+ }
29464
29891
  function reorderItems(items, order) {
29465
29892
  return order.map((i) => items[i]);
29466
29893
  }
@@ -29480,30 +29907,69 @@ function defaultLabel(item, index) {
29480
29907
  if (typeof item === "number") return String(item);
29481
29908
  return `Item ${index + 1}`;
29482
29909
  }
29910
+ const DEFAULT_GAP_LIST = "0px";
29911
+ const DEFAULT_GAP_GRID = "12px";
29912
+ let nextId$2 = 0;
29483
29913
  var ListComponent = class ListComponent {
29484
29914
  constructor() {
29485
29915
  this.host = inject(ElementRef);
29486
29916
  this.injector = inject(Injector);
29487
29917
  this.items = input([], ...ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []);
29488
29918
  this.ordered = input(false, ...ngDevMode ? [{ debugName: "ordered" }] : /* istanbul ignore next */ []);
29919
+ this.layout = input("list", ...ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []);
29920
+ this.gridMin = input(130, ...ngDevMode ? [{ debugName: "gridMin" }] : /* istanbul ignore next */ []);
29921
+ this.gap = input(void 0, ...ngDevMode ? [{ debugName: "gap" }] : /* istanbul ignore next */ []);
29489
29922
  this.reorderable = input(false, ...ngDevMode ? [{ debugName: "reorderable" }] : /* istanbul ignore next */ []);
29490
29923
  this.disabled = input(false, ...ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []);
29924
+ this.moveControls = input("auto", ...ngDevMode ? [{ debugName: "moveControls" }] : /* istanbul ignore next */ []);
29925
+ this.dragDrop = input("auto", ...ngDevMode ? [{ debugName: "dragDrop" }] : /* istanbul ignore next */ []);
29491
29926
  this.ariaLabel = input(void 0, ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
29492
29927
  this.ariaLabelledby = input(void 0, ...ngDevMode ? [{ debugName: "ariaLabelledby" }] : /* istanbul ignore next */ []);
29493
29928
  this.itemLabelFn = input(defaultLabel, ...ngDevMode ? [{ debugName: "itemLabelFn" }] : /* istanbul ignore next */ []);
29494
29929
  this.trackBy = input((item) => item, ...ngDevMode ? [{ debugName: "trackBy" }] : /* istanbul ignore next */ []);
29930
+ this.moveEarlierLabel = input(void 0, ...ngDevMode ? [{ debugName: "moveEarlierLabel" }] : /* istanbul ignore next */ []);
29931
+ this.moveLaterLabel = input(void 0, ...ngDevMode ? [{ debugName: "moveLaterLabel" }] : /* istanbul ignore next */ []);
29932
+ this.helpText = input("Hold Shift and press the arrow keys to move this item. Shift plus Home or End moves it to the start or end.", ...ngDevMode ? [{ debugName: "helpText" }] : /* istanbul ignore next */ []);
29933
+ this.moveAnnouncement = input((label, position, total) => `${label} moved to position ${position} of ${total}`, ...ngDevMode ? [{ debugName: "moveAnnouncement" }] : /* istanbul ignore next */ []);
29934
+ this.itemsChange = output();
29495
29935
  this.reorder = output();
29496
29936
  this.rowTemplate = contentChild(TemplateRef, ...ngDevMode ? [{ debugName: "rowTemplate" }] : /* istanbul ignore next */ []);
29937
+ this.helpId = `ul-help-${nextId$2++}`;
29497
29938
  this.announcement = signal("", ...ngDevMode ? [{ debugName: "announcement" }] : /* istanbul ignore next */ []);
29498
29939
  this.movedKey = signal(void 0, ...ngDevMode ? [{ debugName: "movedKey" }] : /* istanbul ignore next */ []);
29940
+ this.dragIndex = signal(null, ...ngDevMode ? [{ debugName: "dragIndex" }] : /* istanbul ignore next */ []);
29941
+ this.overIndex = signal(null, ...ngDevMode ? [{ debugName: "overIndex" }] : /* istanbul ignore next */ []);
29499
29942
  this.pendingFocus = null;
29500
29943
  this.announceSeq = 0;
29501
29944
  this.dupTokens = /* @__PURE__ */ new Map();
29945
+ this.isGrid = computed(() => this.layout() === "grid", ...ngDevMode ? [{ debugName: "isGrid" }] : /* istanbul ignore next */ []);
29946
+ this.canReorder = computed(() => this.reorderable() && !this.disabled(), ...ngDevMode ? [{ debugName: "canReorder" }] : /* istanbul ignore next */ []);
29947
+ this.showControls = computed(() => {
29948
+ if (!this.reorderable()) return false;
29949
+ const m = this.moveControls();
29950
+ return m === true || m === "auto" && !this.isGrid();
29951
+ }, ...ngDevMode ? [{ debugName: "showControls" }] : /* istanbul ignore next */ []);
29952
+ this.direct = computed(() => {
29953
+ if (!this.canReorder()) return false;
29954
+ const d = this.dragDrop();
29955
+ return d === true || d === "auto" && this.isGrid();
29956
+ }, ...ngDevMode ? [{ debugName: "direct" }] : /* istanbul ignore next */ []);
29957
+ this.gapCss = computed(() => {
29958
+ const fallback = this.isGrid() ? DEFAULT_GAP_GRID : DEFAULT_GAP_LIST;
29959
+ const g = this.gap();
29960
+ if (g == null || String(g).trim() === "") return fallback;
29961
+ const a = resolveLayoutGap(g, "none");
29962
+ return a === resolveLayoutGap(g, "xl") ? a : fallback;
29963
+ }, ...ngDevMode ? [{ debugName: "gapCss" }] : /* istanbul ignore next */ []);
29502
29964
  this.rows = computed(() => {
29503
29965
  const items = this.items();
29504
29966
  const n = items.length;
29505
29967
  const keyFn = this.trackBy();
29506
29968
  const labelFn = this.itemLabelFn();
29969
+ const grid = this.isGrid();
29970
+ const earlier = this.moveEarlierLabel();
29971
+ const later = this.moveLaterLabel();
29972
+ const dragging = this.dragIndex();
29507
29973
  const out = new Array(n);
29508
29974
  const seen = /* @__PURE__ */ new Map();
29509
29975
  const nextTokens = /* @__PURE__ */ new Map();
@@ -29523,14 +29989,18 @@ var ListComponent = class ListComponent {
29523
29989
  key,
29524
29990
  index: i,
29525
29991
  label,
29526
- upLabel: `Move ${label} up`,
29527
- downLabel: `Move ${label} down`,
29992
+ earlierLabel: earlier !== void 0 ? `${earlier} ${label}` : grid ? `Move earlier ${label}` : `Move ${label} up`,
29993
+ laterLabel: later !== void 0 ? `${later} ${label}` : grid ? `Move later ${label}` : `Move ${label} down`,
29528
29994
  first: i === 0,
29529
29995
  last: i === n - 1,
29996
+ dragging: dragging === i,
29530
29997
  ctx: {
29531
29998
  $implicit: item,
29532
29999
  index: i,
29533
- count: n
30000
+ count: n,
30001
+ first: i === 0,
30002
+ last: i === n - 1,
30003
+ dragging: dragging === i
29534
30004
  }
29535
30005
  };
29536
30006
  }
@@ -29538,23 +30008,52 @@ var ListComponent = class ListComponent {
29538
30008
  return out;
29539
30009
  }, ...ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []);
29540
30010
  }
29541
- canReorder() {
29542
- return this.reorderable() && !this.disabled();
29543
- }
29544
30011
  rowIndexOf(el, list) {
29545
30012
  const li = el?.closest(".ul-item") ?? null;
29546
30013
  if (!li || li.parentElement !== list) return -1;
29547
30014
  return Number(li.getAttribute("data-index"));
29548
30015
  }
30016
+ move(from, to) {
30017
+ return this.apply(from, to, null);
30018
+ }
29549
30019
  onKeydown(e) {
29550
- if (!e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) return;
29551
- if (e.key !== "ArrowUp" && e.key !== "ArrowDown") return;
29552
- if (!this.canReorder()) return;
30020
+ if (!this.canReorder() || e.ctrlKey || e.metaKey) return;
30021
+ const list = e.currentTarget;
29553
30022
  const target = e.target;
29554
- if (target?.closest("input, textarea, select, [contenteditable=\"\"], [contenteditable=\"true\"]")) return;
29555
- const idx = this.rowIndexOf(target, e.currentTarget);
29556
- if (idx < 0) return;
29557
- if (this.move(idx, e.key === "ArrowUp" ? -1 : 1)) e.preventDefault();
30023
+ if (e.altKey && !e.shiftKey) {
30024
+ if (e.key !== "ArrowUp" && e.key !== "ArrowDown") return;
30025
+ if (target?.closest("input, textarea, select, [contenteditable=\"\"], [contenteditable=\"true\"]")) return;
30026
+ const idx = this.rowIndexOf(target, list);
30027
+ if (idx < 0) return;
30028
+ const onRow = this.direct() && target?.classList.contains("ul-item") === true;
30029
+ if (this.apply(idx, idx + (e.key === "ArrowUp" ? -1 : 1), onRow ? "row" : "button")) e.preventDefault();
30030
+ return;
30031
+ }
30032
+ if (e.shiftKey && !e.altKey && this.direct()) {
30033
+ if (!target?.classList.contains("ul-item")) return;
30034
+ const idx = this.rowIndexOf(target, list);
30035
+ if (idx < 0) return;
30036
+ let to;
30037
+ switch (e.key) {
30038
+ case "ArrowUp":
30039
+ case "ArrowLeft":
30040
+ to = idx - 1;
30041
+ break;
30042
+ case "ArrowDown":
30043
+ case "ArrowRight":
30044
+ to = idx + 1;
30045
+ break;
30046
+ case "Home":
30047
+ to = 0;
30048
+ break;
30049
+ case "End":
30050
+ to = this.rows().length - 1;
30051
+ break;
30052
+ default: return;
30053
+ }
30054
+ e.preventDefault();
30055
+ this.apply(idx, to, "row");
30056
+ }
29558
30057
  }
29559
30058
  onClick(e) {
29560
30059
  if (!this.canReorder()) return;
@@ -29563,34 +30062,75 @@ var ListComponent = class ListComponent {
29563
30062
  if (btn.querySelector("button")?.disabled) return;
29564
30063
  const idx = this.rowIndexOf(btn, e.currentTarget);
29565
30064
  if (idx < 0) return;
29566
- this.move(idx, btn.getAttribute("data-move") === "up" ? -1 : 1);
30065
+ const dir = btn.getAttribute("data-move") === "up" ? -1 : 1;
30066
+ this.apply(idx, idx + dir, "button");
29567
30067
  }
29568
30068
  onFocusOut(e) {
29569
30069
  if (this.pendingFocus) return;
29570
30070
  const next = e.relatedTarget;
29571
30071
  if (!next || !e.currentTarget.contains(next)) this.movedKey.set(void 0);
29572
30072
  }
29573
- move(from, dir) {
30073
+ onDragStart(e) {
30074
+ if (!this.direct()) return;
30075
+ const idx = this.rowIndexOf(e.target, e.currentTarget);
30076
+ if (idx < 0) return;
30077
+ this.dragIndex.set(idx);
30078
+ if (e.dataTransfer) {
30079
+ e.dataTransfer.effectAllowed = "move";
30080
+ e.dataTransfer.setData("text/plain", String(idx));
30081
+ }
30082
+ }
30083
+ onDragOver(e) {
30084
+ if (!this.direct() || this.dragIndex() === null) return;
30085
+ const idx = this.rowIndexOf(e.target, e.currentTarget);
30086
+ if (idx < 0) return;
30087
+ e.preventDefault();
30088
+ if (e.dataTransfer) e.dataTransfer.dropEffect = "move";
30089
+ this.overIndex.set(idx);
30090
+ }
30091
+ onDrop(e) {
30092
+ const from = this.dragIndex();
30093
+ if (!this.direct() || from === null) return;
30094
+ const idx = this.rowIndexOf(e.target, e.currentTarget);
30095
+ if (idx < 0) return;
30096
+ e.preventDefault();
30097
+ this.onDragEnd();
30098
+ this.apply(from, idx, null);
30099
+ }
30100
+ onDragEnd() {
30101
+ this.dragIndex.set(null);
30102
+ this.overIndex.set(null);
30103
+ }
30104
+ apply(from, to, focus) {
29574
30105
  const rows = this.rows();
29575
- const to = from + dir;
29576
- if (to < 0 || to >= rows.length) return false;
30106
+ const n = rows.length;
30107
+ if (!this.canReorder() || !Number.isInteger(from) || from < 0 || from >= n) return false;
30108
+ const target = Math.max(0, Math.min(n - 1, Number.isFinite(to) ? to : from));
30109
+ if (target === from) return false;
29577
30110
  const order = rows.map((r) => r.index);
29578
30111
  const [moved] = order.splice(from, 1);
29579
- order.splice(to, 0, moved);
30112
+ order.splice(target, 0, moved);
29580
30113
  const row = rows[from];
29581
- this.movedKey.set(row.key);
29582
- this.announce(`${row.label} moved to position ${to + 1} of ${rows.length}`);
29583
- this.pendingFocus = {
29584
- key: row.key,
29585
- item: row.item,
29586
- to,
29587
- dir
29588
- };
29589
- afterNextRender(() => this.restoreFocus(), { injector: this.injector });
30114
+ const items = reorderItems(this.items(), order);
30115
+ this.announce(this.moveAnnouncement()(this.itemLabelFn()(row.item, target), target + 1, n));
30116
+ if (focus) {
30117
+ this.movedKey.set(row.key);
30118
+ this.pendingFocus = {
30119
+ key: row.key,
30120
+ item: row.item,
30121
+ to: target,
30122
+ dir: target < from ? -1 : 1,
30123
+ target: focus
30124
+ };
30125
+ afterNextRender(() => this.restoreFocus(), { injector: this.injector });
30126
+ }
30127
+ this.itemsChange.emit(items);
29590
30128
  this.reorder.emit({
30129
+ item: row.item,
29591
30130
  from,
29592
- to,
29593
- order
30131
+ to: target,
30132
+ order,
30133
+ items
29594
30134
  });
29595
30135
  return true;
29596
30136
  }
@@ -29614,9 +30154,15 @@ var ListComponent = class ListComponent {
29614
30154
  if (idx < 0) return;
29615
30155
  const li = this.host.nativeElement.querySelector(`:scope > .ul-list > .ul-item[data-index="${idx}"]`);
29616
30156
  if (!li) return;
30157
+ if (p.target === "row") {
30158
+ li.focus();
30159
+ return;
30160
+ }
29617
30161
  const pick = (d) => li.querySelector(`:scope > .ul-row > .ul-controls > [data-move="${d}"] button:not(:disabled)`);
29618
30162
  const preferred = p.dir === -1 ? "up" : "down";
29619
- (pick(preferred) ?? pick(preferred === "up" ? "down" : "up"))?.focus();
30163
+ const btn = pick(preferred) ?? pick(preferred === "up" ? "down" : "up");
30164
+ if (btn) btn.focus();
30165
+ else if (this.direct()) li.focus();
29620
30166
  }
29621
30167
  static {
29622
30168
  this.ɵfac = i0.ɵɵngDeclareFactory({
@@ -29650,6 +30196,27 @@ var ListComponent = class ListComponent {
29650
30196
  isRequired: false,
29651
30197
  transformFunction: null
29652
30198
  },
30199
+ layout: {
30200
+ classPropertyName: "layout",
30201
+ publicName: "layout",
30202
+ isSignal: true,
30203
+ isRequired: false,
30204
+ transformFunction: null
30205
+ },
30206
+ gridMin: {
30207
+ classPropertyName: "gridMin",
30208
+ publicName: "gridMin",
30209
+ isSignal: true,
30210
+ isRequired: false,
30211
+ transformFunction: null
30212
+ },
30213
+ gap: {
30214
+ classPropertyName: "gap",
30215
+ publicName: "gap",
30216
+ isSignal: true,
30217
+ isRequired: false,
30218
+ transformFunction: null
30219
+ },
29653
30220
  reorderable: {
29654
30221
  classPropertyName: "reorderable",
29655
30222
  publicName: "reorderable",
@@ -29664,6 +30231,20 @@ var ListComponent = class ListComponent {
29664
30231
  isRequired: false,
29665
30232
  transformFunction: null
29666
30233
  },
30234
+ moveControls: {
30235
+ classPropertyName: "moveControls",
30236
+ publicName: "moveControls",
30237
+ isSignal: true,
30238
+ isRequired: false,
30239
+ transformFunction: null
30240
+ },
30241
+ dragDrop: {
30242
+ classPropertyName: "dragDrop",
30243
+ publicName: "dragDrop",
30244
+ isSignal: true,
30245
+ isRequired: false,
30246
+ transformFunction: null
30247
+ },
29667
30248
  ariaLabel: {
29668
30249
  classPropertyName: "ariaLabel",
29669
30250
  publicName: "ariaLabel",
@@ -29691,9 +30272,40 @@ var ListComponent = class ListComponent {
29691
30272
  isSignal: true,
29692
30273
  isRequired: false,
29693
30274
  transformFunction: null
30275
+ },
30276
+ moveEarlierLabel: {
30277
+ classPropertyName: "moveEarlierLabel",
30278
+ publicName: "moveEarlierLabel",
30279
+ isSignal: true,
30280
+ isRequired: false,
30281
+ transformFunction: null
30282
+ },
30283
+ moveLaterLabel: {
30284
+ classPropertyName: "moveLaterLabel",
30285
+ publicName: "moveLaterLabel",
30286
+ isSignal: true,
30287
+ isRequired: false,
30288
+ transformFunction: null
30289
+ },
30290
+ helpText: {
30291
+ classPropertyName: "helpText",
30292
+ publicName: "helpText",
30293
+ isSignal: true,
30294
+ isRequired: false,
30295
+ transformFunction: null
30296
+ },
30297
+ moveAnnouncement: {
30298
+ classPropertyName: "moveAnnouncement",
30299
+ publicName: "moveAnnouncement",
30300
+ isSignal: true,
30301
+ isRequired: false,
30302
+ transformFunction: null
29694
30303
  }
29695
30304
  },
29696
- outputs: { reorder: "reorder" },
30305
+ outputs: {
30306
+ itemsChange: "itemsChange",
30307
+ reorder: "reorder"
30308
+ },
29697
30309
  queries: [{
29698
30310
  propertyName: "rowTemplate",
29699
30311
  first: true,
@@ -29705,7 +30317,17 @@ var ListComponent = class ListComponent {
29705
30317
  template: `
29706
30318
  <ng-template #rowsTpl>
29707
30319
  @for (row of rows(); track row.key) {
29708
- <li class="ul-item" [class.ul-item--moved]="row.key === movedKey()" [attr.data-index]="row.index">
30320
+ <li class="ul-item" role="listitem"
30321
+ [class.ul-item--moved]="row.key === movedKey()"
30322
+ [class.ul-item--draggable]="direct()"
30323
+ [class.ul-item--dragging]="row.dragging"
30324
+ [class.ul-item--over]="dragIndex() !== null && dragIndex() !== row.index && overIndex() === row.index"
30325
+ [attr.data-index]="row.index"
30326
+ [attr.draggable]="direct() ? 'true' : null"
30327
+ [attr.tabindex]="direct() ? 0 : null"
30328
+ [attr.aria-roledescription]="direct() ? 'sortable item' : null"
30329
+ [attr.aria-label]="direct() ? row.label : null"
30330
+ [attr.aria-describedby]="direct() ? helpId : null">
29709
30331
  <div class="ul-row">
29710
30332
  <div class="ul-content">
29711
30333
  @if (rowTemplate(); as tpl) {
@@ -29714,12 +30336,12 @@ var ListComponent = class ListComponent {
29714
30336
  {{ row.label }}
29715
30337
  }
29716
30338
  </div>
29717
- @if (reorderable()) {
30339
+ @if (showControls()) {
29718
30340
  <div class="ul-controls">
29719
- <ui-button variant="icon" data-move="up" [ariaLabel]="row.upLabel" [disabled]="disabled() || row.first">
30341
+ <ui-button variant="icon" data-move="up" [ariaLabel]="row.earlierLabel" [disabled]="disabled() || row.first">
29720
30342
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M18 15l-6-6-6 6"/></svg>
29721
30343
  </ui-button>
29722
- <ui-button variant="icon" data-move="down" [ariaLabel]="row.downLabel" [disabled]="disabled() || row.last">
30344
+ <ui-button variant="icon" data-move="down" [ariaLabel]="row.laterLabel" [disabled]="disabled() || row.last">
29723
30345
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M6 9l6 6 6-6"/></svg>
29724
30346
  </ui-button>
29725
30347
  </div>
@@ -29731,15 +30353,19 @@ var ListComponent = class ListComponent {
29731
30353
 
29732
30354
  @if (rows().length) {
29733
30355
  @if (ordered()) {
29734
- <ol class="ul-list ul-list--ordered" role="list"
30356
+ <ol class="ul-list ul-list--ordered" role="list" [class.ul-list--grid]="isGrid()"
30357
+ [style.--ul-gap]="gapCss()" [style.--ul-min.px]="isGrid() ? gridMin() : null"
29735
30358
  [attr.aria-label]="ariaLabel() || null" [attr.aria-labelledby]="ariaLabelledby() || null"
29736
- (keydown)="onKeydown($event)" (click)="onClick($event)" (focusout)="onFocusOut($event)">
30359
+ (keydown)="onKeydown($event)" (click)="onClick($event)" (focusout)="onFocusOut($event)"
30360
+ (dragstart)="onDragStart($event)" (dragover)="onDragOver($event)" (drop)="onDrop($event)" (dragend)="onDragEnd()">
29737
30361
  <ng-container [ngTemplateOutlet]="rowsTpl" />
29738
30362
  </ol>
29739
30363
  } @else {
29740
- <ul class="ul-list ul-list--unordered" role="list"
30364
+ <ul class="ul-list ul-list--unordered" role="list" [class.ul-list--grid]="isGrid()"
30365
+ [style.--ul-gap]="gapCss()" [style.--ul-min.px]="isGrid() ? gridMin() : null"
29741
30366
  [attr.aria-label]="ariaLabel() || null" [attr.aria-labelledby]="ariaLabelledby() || null"
29742
- (keydown)="onKeydown($event)" (click)="onClick($event)" (focusout)="onFocusOut($event)">
30367
+ (keydown)="onKeydown($event)" (click)="onClick($event)" (focusout)="onFocusOut($event)"
30368
+ (dragstart)="onDragStart($event)" (dragover)="onDragOver($event)" (drop)="onDrop($event)" (dragend)="onDragEnd()">
29743
30369
  <ng-container [ngTemplateOutlet]="rowsTpl" />
29744
30370
  </ul>
29745
30371
  }
@@ -29747,12 +30373,15 @@ var ListComponent = class ListComponent {
29747
30373
  <ng-content select="[list-empty]" />
29748
30374
  }
29749
30375
 
30376
+ @if (direct() && rows().length) {
30377
+ <span class="ul-sr" [id]="helpId">{{ helpText() }}</span>
30378
+ }
29750
30379
  @if (reorderable()) {
29751
- <div class="ul-sr" aria-live="polite" aria-atomic="true">{{ announcement() }}</div>
30380
+ <div class="ul-sr" role="status" aria-live="polite" aria-atomic="true">{{ announcement() }}</div>
29752
30381
  }
29753
30382
  `,
29754
30383
  isInline: true,
29755
- styles: [":host{display:block;min-width:0}.ul-list{margin:0;padding:0;min-width:0}.ul-list--unordered{list-style:none}.ul-list--ordered{list-style:decimal;-webkit-padding-start:1.75rem;padding-inline-start:1.75rem}.ul-list--ordered>.ul-item::marker{color:var(--text-secondary, #64748b);font-size:.875rem}.ul-item{min-width:0;transition:background-color .4s ease}.ul-item.ul-item--moved{background-color:var(--surface-hover, #f1f5f9)}.ul-row{display:flex;align-items:center;gap:8px;min-width:0}.ul-content{flex:1 1 auto;min-width:0;word-break:break-word;overflow-wrap:anywhere}.ul-controls{display:flex;flex:0 0 auto;align-items:center;gap:2px}@media(pointer:coarse),(max-width:480px){.ul-controls{gap:16px}}@media(prefers-reduced-motion:reduce){.ul-item{transition:none}}@media(forced-colors:active){.ul-item.ul-item--moved{outline:2px solid Highlight;outline-offset:-2px}}.ul-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"],
30384
+ styles: [":host{display:block;min-width:0}.ul-list{margin:0;padding:0;min-width:0}.ul-list--unordered{list-style:none}.ul-list--ordered{list-style:decimal;-webkit-padding-start:1.75rem;padding-inline-start:1.75rem}.ul-list--ordered>.ul-item::marker{color:var(--text-secondary, #64748b);font-size:.875rem}.ul-item{min-width:0;transition:background-color .4s ease}.ul-item.ul-item--moved{background-color:var(--surface-hover, #f1f5f9)}.ul-list:not(.ul-list--grid)>.ul-item+.ul-item{margin-top:var(--ul-gap, 0px)}.ul-row{display:flex;align-items:center;gap:8px;min-width:0}.ul-content{flex:1 1 auto;min-width:0;word-break:break-word;overflow-wrap:anywhere}.ul-controls{display:flex;flex:0 0 auto;align-items:center;gap:2px}.ul-list.ul-list--grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(var(--ul-min, 130px),100%),1fr));gap:var(--ul-gap, 12px);list-style:none;-webkit-padding-start:0;padding-inline-start:0}.ul-list--grid>.ul-item>.ul-row{flex-direction:column;align-items:stretch;gap:6px}.ul-list--grid>.ul-item>.ul-row>.ul-controls{align-self:center}@media(pointer:coarse),(max-width:480px){.ul-controls{gap:16px}}.ul-item--draggable{-webkit-user-select:none;user-select:none;-webkit-user-drag:element}@media(hover:hover)and (pointer:fine){.ul-item--draggable{cursor:grab}.ul-item--draggable:active{cursor:grabbing}}.ul-item--draggable:focus{outline:2px solid #3b82f6;outline-offset:2px;border-radius:6px}.ul-item--draggable:focus:not(:focus-visible){outline:none}:host ::ng-deep .ul-item--draggable img,:host ::ng-deep .ul-item--draggable ui-image-preview{pointer-events:none;-webkit-user-drag:none}.ul-item--dragging{opacity:.5}.ul-item--over{outline:2px dashed #3b82f6;outline-offset:2px;border-radius:6px}@media(prefers-reduced-motion:reduce){.ul-item{transition:none}}@media(forced-colors:active){.ul-item.ul-item--moved{outline:2px solid Highlight;outline-offset:-2px}}@media(forced-colors:active){.ul-item.ul-item--dragging{outline:2px dotted Highlight;outline-offset:2px}.ul-item.ul-item--over{outline:2px dashed Highlight;outline-offset:2px}.ul-item--draggable:focus{outline:2px solid Highlight;outline-offset:2px}}.ul-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"],
29756
30385
  dependencies: [{
29757
30386
  kind: "directive",
29758
30387
  type: NgTemplateOutlet,
@@ -29807,7 +30436,17 @@ i0.ɵɵngDeclareClassMetadata({
29807
30436
  template: `
29808
30437
  <ng-template #rowsTpl>
29809
30438
  @for (row of rows(); track row.key) {
29810
- <li class="ul-item" [class.ul-item--moved]="row.key === movedKey()" [attr.data-index]="row.index">
30439
+ <li class="ul-item" role="listitem"
30440
+ [class.ul-item--moved]="row.key === movedKey()"
30441
+ [class.ul-item--draggable]="direct()"
30442
+ [class.ul-item--dragging]="row.dragging"
30443
+ [class.ul-item--over]="dragIndex() !== null && dragIndex() !== row.index && overIndex() === row.index"
30444
+ [attr.data-index]="row.index"
30445
+ [attr.draggable]="direct() ? 'true' : null"
30446
+ [attr.tabindex]="direct() ? 0 : null"
30447
+ [attr.aria-roledescription]="direct() ? 'sortable item' : null"
30448
+ [attr.aria-label]="direct() ? row.label : null"
30449
+ [attr.aria-describedby]="direct() ? helpId : null">
29811
30450
  <div class="ul-row">
29812
30451
  <div class="ul-content">
29813
30452
  @if (rowTemplate(); as tpl) {
@@ -29816,12 +30455,12 @@ i0.ɵɵngDeclareClassMetadata({
29816
30455
  {{ row.label }}
29817
30456
  }
29818
30457
  </div>
29819
- @if (reorderable()) {
30458
+ @if (showControls()) {
29820
30459
  <div class="ul-controls">
29821
- <ui-button variant="icon" data-move="up" [ariaLabel]="row.upLabel" [disabled]="disabled() || row.first">
30460
+ <ui-button variant="icon" data-move="up" [ariaLabel]="row.earlierLabel" [disabled]="disabled() || row.first">
29822
30461
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M18 15l-6-6-6 6"/></svg>
29823
30462
  </ui-button>
29824
- <ui-button variant="icon" data-move="down" [ariaLabel]="row.downLabel" [disabled]="disabled() || row.last">
30463
+ <ui-button variant="icon" data-move="down" [ariaLabel]="row.laterLabel" [disabled]="disabled() || row.last">
29825
30464
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false"><path d="M6 9l6 6 6-6"/></svg>
29826
30465
  </ui-button>
29827
30466
  </div>
@@ -29833,15 +30472,19 @@ i0.ɵɵngDeclareClassMetadata({
29833
30472
 
29834
30473
  @if (rows().length) {
29835
30474
  @if (ordered()) {
29836
- <ol class="ul-list ul-list--ordered" role="list"
30475
+ <ol class="ul-list ul-list--ordered" role="list" [class.ul-list--grid]="isGrid()"
30476
+ [style.--ul-gap]="gapCss()" [style.--ul-min.px]="isGrid() ? gridMin() : null"
29837
30477
  [attr.aria-label]="ariaLabel() || null" [attr.aria-labelledby]="ariaLabelledby() || null"
29838
- (keydown)="onKeydown($event)" (click)="onClick($event)" (focusout)="onFocusOut($event)">
30478
+ (keydown)="onKeydown($event)" (click)="onClick($event)" (focusout)="onFocusOut($event)"
30479
+ (dragstart)="onDragStart($event)" (dragover)="onDragOver($event)" (drop)="onDrop($event)" (dragend)="onDragEnd()">
29839
30480
  <ng-container [ngTemplateOutlet]="rowsTpl" />
29840
30481
  </ol>
29841
30482
  } @else {
29842
- <ul class="ul-list ul-list--unordered" role="list"
30483
+ <ul class="ul-list ul-list--unordered" role="list" [class.ul-list--grid]="isGrid()"
30484
+ [style.--ul-gap]="gapCss()" [style.--ul-min.px]="isGrid() ? gridMin() : null"
29843
30485
  [attr.aria-label]="ariaLabel() || null" [attr.aria-labelledby]="ariaLabelledby() || null"
29844
- (keydown)="onKeydown($event)" (click)="onClick($event)" (focusout)="onFocusOut($event)">
30486
+ (keydown)="onKeydown($event)" (click)="onClick($event)" (focusout)="onFocusOut($event)"
30487
+ (dragstart)="onDragStart($event)" (dragover)="onDragOver($event)" (drop)="onDrop($event)" (dragend)="onDragEnd()">
29845
30488
  <ng-container [ngTemplateOutlet]="rowsTpl" />
29846
30489
  </ul>
29847
30490
  }
@@ -29849,11 +30492,14 @@ i0.ɵɵngDeclareClassMetadata({
29849
30492
  <ng-content select="[list-empty]" />
29850
30493
  }
29851
30494
 
30495
+ @if (direct() && rows().length) {
30496
+ <span class="ul-sr" [id]="helpId">{{ helpText() }}</span>
30497
+ }
29852
30498
  @if (reorderable()) {
29853
- <div class="ul-sr" aria-live="polite" aria-atomic="true">{{ announcement() }}</div>
30499
+ <div class="ul-sr" role="status" aria-live="polite" aria-atomic="true">{{ announcement() }}</div>
29854
30500
  }
29855
30501
  `,
29856
- styles: [":host{display:block;min-width:0}.ul-list{margin:0;padding:0;min-width:0}.ul-list--unordered{list-style:none}.ul-list--ordered{list-style:decimal;-webkit-padding-start:1.75rem;padding-inline-start:1.75rem}.ul-list--ordered>.ul-item::marker{color:var(--text-secondary, #64748b);font-size:.875rem}.ul-item{min-width:0;transition:background-color .4s ease}.ul-item.ul-item--moved{background-color:var(--surface-hover, #f1f5f9)}.ul-row{display:flex;align-items:center;gap:8px;min-width:0}.ul-content{flex:1 1 auto;min-width:0;word-break:break-word;overflow-wrap:anywhere}.ul-controls{display:flex;flex:0 0 auto;align-items:center;gap:2px}@media(pointer:coarse),(max-width:480px){.ul-controls{gap:16px}}@media(prefers-reduced-motion:reduce){.ul-item{transition:none}}@media(forced-colors:active){.ul-item.ul-item--moved{outline:2px solid Highlight;outline-offset:-2px}}.ul-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"]
30502
+ styles: [":host{display:block;min-width:0}.ul-list{margin:0;padding:0;min-width:0}.ul-list--unordered{list-style:none}.ul-list--ordered{list-style:decimal;-webkit-padding-start:1.75rem;padding-inline-start:1.75rem}.ul-list--ordered>.ul-item::marker{color:var(--text-secondary, #64748b);font-size:.875rem}.ul-item{min-width:0;transition:background-color .4s ease}.ul-item.ul-item--moved{background-color:var(--surface-hover, #f1f5f9)}.ul-list:not(.ul-list--grid)>.ul-item+.ul-item{margin-top:var(--ul-gap, 0px)}.ul-row{display:flex;align-items:center;gap:8px;min-width:0}.ul-content{flex:1 1 auto;min-width:0;word-break:break-word;overflow-wrap:anywhere}.ul-controls{display:flex;flex:0 0 auto;align-items:center;gap:2px}.ul-list.ul-list--grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(var(--ul-min, 130px),100%),1fr));gap:var(--ul-gap, 12px);list-style:none;-webkit-padding-start:0;padding-inline-start:0}.ul-list--grid>.ul-item>.ul-row{flex-direction:column;align-items:stretch;gap:6px}.ul-list--grid>.ul-item>.ul-row>.ul-controls{align-self:center}@media(pointer:coarse),(max-width:480px){.ul-controls{gap:16px}}.ul-item--draggable{-webkit-user-select:none;user-select:none;-webkit-user-drag:element}@media(hover:hover)and (pointer:fine){.ul-item--draggable{cursor:grab}.ul-item--draggable:active{cursor:grabbing}}.ul-item--draggable:focus{outline:2px solid #3b82f6;outline-offset:2px;border-radius:6px}.ul-item--draggable:focus:not(:focus-visible){outline:none}:host ::ng-deep .ul-item--draggable img,:host ::ng-deep .ul-item--draggable ui-image-preview{pointer-events:none;-webkit-user-drag:none}.ul-item--dragging{opacity:.5}.ul-item--over{outline:2px dashed #3b82f6;outline-offset:2px;border-radius:6px}@media(prefers-reduced-motion:reduce){.ul-item{transition:none}}@media(forced-colors:active){.ul-item.ul-item--moved{outline:2px solid Highlight;outline-offset:-2px}}@media(forced-colors:active){.ul-item.ul-item--dragging{outline:2px dotted Highlight;outline-offset:2px}.ul-item.ul-item--over{outline:2px dashed Highlight;outline-offset:2px}.ul-item--draggable:focus{outline:2px solid Highlight;outline-offset:2px}}.ul-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\n"]
29857
30503
  }]
29858
30504
  }],
29859
30505
  propDecorators: {
@@ -29873,6 +30519,30 @@ i0.ɵɵngDeclareClassMetadata({
29873
30519
  required: false
29874
30520
  }]
29875
30521
  }],
30522
+ layout: [{
30523
+ type: i0.Input,
30524
+ args: [{
30525
+ isSignal: true,
30526
+ alias: "layout",
30527
+ required: false
30528
+ }]
30529
+ }],
30530
+ gridMin: [{
30531
+ type: i0.Input,
30532
+ args: [{
30533
+ isSignal: true,
30534
+ alias: "gridMin",
30535
+ required: false
30536
+ }]
30537
+ }],
30538
+ gap: [{
30539
+ type: i0.Input,
30540
+ args: [{
30541
+ isSignal: true,
30542
+ alias: "gap",
30543
+ required: false
30544
+ }]
30545
+ }],
29876
30546
  reorderable: [{
29877
30547
  type: i0.Input,
29878
30548
  args: [{
@@ -29889,6 +30559,22 @@ i0.ɵɵngDeclareClassMetadata({
29889
30559
  required: false
29890
30560
  }]
29891
30561
  }],
30562
+ moveControls: [{
30563
+ type: i0.Input,
30564
+ args: [{
30565
+ isSignal: true,
30566
+ alias: "moveControls",
30567
+ required: false
30568
+ }]
30569
+ }],
30570
+ dragDrop: [{
30571
+ type: i0.Input,
30572
+ args: [{
30573
+ isSignal: true,
30574
+ alias: "dragDrop",
30575
+ required: false
30576
+ }]
30577
+ }],
29892
30578
  ariaLabel: [{
29893
30579
  type: i0.Input,
29894
30580
  args: [{
@@ -29921,13 +30607,49 @@ i0.ɵɵngDeclareClassMetadata({
29921
30607
  required: false
29922
30608
  }]
29923
30609
  }],
29924
- reorder: [{
29925
- type: i0.Output,
29926
- args: ["reorder"]
30610
+ moveEarlierLabel: [{
30611
+ type: i0.Input,
30612
+ args: [{
30613
+ isSignal: true,
30614
+ alias: "moveEarlierLabel",
30615
+ required: false
30616
+ }]
29927
30617
  }],
29928
- rowTemplate: [{
29929
- type: i0.ContentChild,
29930
- args: [i0.forwardRef(() => TemplateRef), { isSignal: true }]
30618
+ moveLaterLabel: [{
30619
+ type: i0.Input,
30620
+ args: [{
30621
+ isSignal: true,
30622
+ alias: "moveLaterLabel",
30623
+ required: false
30624
+ }]
30625
+ }],
30626
+ helpText: [{
30627
+ type: i0.Input,
30628
+ args: [{
30629
+ isSignal: true,
30630
+ alias: "helpText",
30631
+ required: false
30632
+ }]
30633
+ }],
30634
+ moveAnnouncement: [{
30635
+ type: i0.Input,
30636
+ args: [{
30637
+ isSignal: true,
30638
+ alias: "moveAnnouncement",
30639
+ required: false
30640
+ }]
30641
+ }],
30642
+ itemsChange: [{
30643
+ type: i0.Output,
30644
+ args: ["itemsChange"]
30645
+ }],
30646
+ reorder: [{
30647
+ type: i0.Output,
30648
+ args: ["reorder"]
30649
+ }],
30650
+ rowTemplate: [{
30651
+ type: i0.ContentChild,
30652
+ args: [i0.forwardRef(() => TemplateRef), { isSignal: true }]
29931
30653
  }]
29932
30654
  }
29933
30655
  });
@@ -32535,450 +33257,55 @@ var IconComponent = class IconComponent {
32535
33257
  transformFunction: null
32536
33258
  },
32537
33259
  disabled: {
32538
- classPropertyName: "disabled",
32539
- publicName: "disabled",
32540
- isSignal: true,
32541
- isRequired: false,
32542
- transformFunction: null
32543
- },
32544
- loading: {
32545
- classPropertyName: "loading",
32546
- publicName: "loading",
32547
- isSignal: true,
32548
- isRequired: false,
32549
- transformFunction: null
32550
- },
32551
- interactive: {
32552
- classPropertyName: "interactive",
32553
- publicName: "interactive",
32554
- isSignal: true,
32555
- isRequired: false,
32556
- transformFunction: null
32557
- }
32558
- },
32559
- outputs: { iconClick: "iconClick" },
32560
- ngImport: i0,
32561
- template: `
32562
- @if (interactive()) {
32563
- <button type="button" class="icon-btn" [class.danger]="variant() === 'danger'"
32564
- [class.loading]="loading()" [disabled]="disabled() || loading()" [attr.aria-busy]="loading() ? 'true' : null"
32565
- [attr.aria-label]="accessibleName() || null" [uiTooltip]="tooltip()" (click)="onClick($event)">
32566
- <ng-container *ngTemplateOutlet="glyph" />
32567
- </button>
32568
- } @else {
32569
- <span class="icon-static" [class.danger]="variant() === 'danger'" [attr.aria-busy]="loading() ? 'true' : null"
32570
- [attr.role]="accessibleName() ? 'img' : null" [attr.aria-label]="accessibleName() || null" [uiTooltip]="tooltip()" [attr.aria-hidden]="accessibleName() ? null : 'true'">
32571
- <ng-container *ngTemplateOutlet="glyph" />
32572
- </span>
32573
- }
32574
- <ng-template #glyph>
32575
- @if (loading()) {
32576
- <span class="spinner" [style.width.px]="size()" [style.height.px]="size()" aria-hidden="true"></span>
32577
- } @else if (path(); as d) {
32578
- <svg viewBox="0 0 24 24" [attr.width]="size()" [attr.height]="size()" fill="none" stroke="currentColor"
32579
- stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
32580
- <path [attr.d]="d" />
32581
- </svg>
32582
- }
32583
- </ng-template>
32584
- `,
32585
- isInline: true,
32586
- styles: [":host{display:inline-flex}.icon-static{display:inline-flex;align-items:center;justify-content:center;color:inherit}.icon-static.danger{color:#b91c1c}.icon-static svg{display:block}.icon-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:6px;background:transparent;color:#475569;cursor:pointer;-webkit-appearance:none;appearance:none;font:inherit;transition:background .15s ease,color .15s ease}.icon-btn:hover:not(:disabled){background:#f1f5f9;color:#0f172a}.icon-btn.danger{color:#b91c1c}.icon-btn.danger:hover:not(:disabled){background:#fef2f2;color:#991b1b}.icon-btn:focus-visible{outline:2px solid #2563eb;outline-offset:2px}.icon-btn:disabled{opacity:.5;cursor:not-allowed}.icon-btn.loading:disabled{opacity:1;cursor:progress}.spinner{display:block;box-sizing:border-box;border:2px solid rgba(100,116,139,.3);border-top-color:currentColor;border-radius:50%;animation:ui-icon-spin .6s linear infinite}@keyframes ui-icon-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.spinner{animation-duration:2s}}.icon-btn:after{content:\"\";position:absolute;inset:-8px}\n"],
32587
- dependencies: [{
32588
- kind: "directive",
32589
- type: NgTemplateOutlet,
32590
- selector: "[ngTemplateOutlet]",
32591
- inputs: [
32592
- "ngTemplateOutletContext",
32593
- "ngTemplateOutlet",
32594
- "ngTemplateOutletInjector"
32595
- ]
32596
- }, {
32597
- kind: "directive",
32598
- type: TooltipDirective,
32599
- selector: "[uiTooltip]",
32600
- inputs: ["uiTooltip", "tooltipPosition"]
32601
- }],
32602
- changeDetection: i0.ChangeDetectionStrategy.OnPush
32603
- });
32604
- }
32605
- };
32606
- i0.ɵɵngDeclareClassMetadata({
32607
- minVersion: "12.0.0",
32608
- version: "22.2.2",
32609
- ngImport: i0,
32610
- type: IconComponent,
32611
- decorators: [{
32612
- type: Component,
32613
- args: [{
32614
- selector: "ui-icon",
32615
- standalone: true,
32616
- imports: [NgTemplateOutlet, TooltipDirective],
32617
- changeDetection: ChangeDetectionStrategy.OnPush,
32618
- template: `
32619
- @if (interactive()) {
32620
- <button type="button" class="icon-btn" [class.danger]="variant() === 'danger'"
32621
- [class.loading]="loading()" [disabled]="disabled() || loading()" [attr.aria-busy]="loading() ? 'true' : null"
32622
- [attr.aria-label]="accessibleName() || null" [uiTooltip]="tooltip()" (click)="onClick($event)">
32623
- <ng-container *ngTemplateOutlet="glyph" />
32624
- </button>
32625
- } @else {
32626
- <span class="icon-static" [class.danger]="variant() === 'danger'" [attr.aria-busy]="loading() ? 'true' : null"
32627
- [attr.role]="accessibleName() ? 'img' : null" [attr.aria-label]="accessibleName() || null" [uiTooltip]="tooltip()" [attr.aria-hidden]="accessibleName() ? null : 'true'">
32628
- <ng-container *ngTemplateOutlet="glyph" />
32629
- </span>
32630
- }
32631
- <ng-template #glyph>
32632
- @if (loading()) {
32633
- <span class="spinner" [style.width.px]="size()" [style.height.px]="size()" aria-hidden="true"></span>
32634
- } @else if (path(); as d) {
32635
- <svg viewBox="0 0 24 24" [attr.width]="size()" [attr.height]="size()" fill="none" stroke="currentColor"
32636
- stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
32637
- <path [attr.d]="d" />
32638
- </svg>
32639
- }
32640
- </ng-template>
32641
- `,
32642
- styles: [":host{display:inline-flex}.icon-static{display:inline-flex;align-items:center;justify-content:center;color:inherit}.icon-static.danger{color:#b91c1c}.icon-static svg{display:block}.icon-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:6px;background:transparent;color:#475569;cursor:pointer;-webkit-appearance:none;appearance:none;font:inherit;transition:background .15s ease,color .15s ease}.icon-btn:hover:not(:disabled){background:#f1f5f9;color:#0f172a}.icon-btn.danger{color:#b91c1c}.icon-btn.danger:hover:not(:disabled){background:#fef2f2;color:#991b1b}.icon-btn:focus-visible{outline:2px solid #2563eb;outline-offset:2px}.icon-btn:disabled{opacity:.5;cursor:not-allowed}.icon-btn.loading:disabled{opacity:1;cursor:progress}.spinner{display:block;box-sizing:border-box;border:2px solid rgba(100,116,139,.3);border-top-color:currentColor;border-radius:50%;animation:ui-icon-spin .6s linear infinite}@keyframes ui-icon-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.spinner{animation-duration:2s}}.icon-btn:after{content:\"\";position:absolute;inset:-8px}\n"]
32643
- }]
32644
- }],
32645
- propDecorators: {
32646
- name: [{
32647
- type: i0.Input,
32648
- args: [{
32649
- isSignal: true,
32650
- alias: "name",
32651
- required: true
32652
- }]
32653
- }],
32654
- tooltip: [{
32655
- type: i0.Input,
32656
- args: [{
32657
- isSignal: true,
32658
- alias: "tooltip",
32659
- required: false
32660
- }]
32661
- }],
32662
- ariaLabel: [{
32663
- type: i0.Input,
32664
- args: [{
32665
- isSignal: true,
32666
- alias: "ariaLabel",
32667
- required: false
32668
- }]
32669
- }],
32670
- size: [{
32671
- type: i0.Input,
32672
- args: [{
32673
- isSignal: true,
32674
- alias: "size",
32675
- required: false
32676
- }]
32677
- }],
32678
- variant: [{
32679
- type: i0.Input,
32680
- args: [{
32681
- isSignal: true,
32682
- alias: "variant",
32683
- required: false
32684
- }]
32685
- }],
32686
- disabled: [{
32687
- type: i0.Input,
32688
- args: [{
32689
- isSignal: true,
32690
- alias: "disabled",
32691
- required: false
32692
- }]
32693
- }],
32694
- loading: [{
32695
- type: i0.Input,
32696
- args: [{
32697
- isSignal: true,
32698
- alias: "loading",
32699
- required: false
32700
- }]
32701
- }],
32702
- interactive: [{
32703
- type: i0.Input,
32704
- args: [{
32705
- isSignal: true,
32706
- alias: "interactive",
32707
- required: false
32708
- }]
32709
- }],
32710
- iconClick: [{
32711
- type: i0.Output,
32712
- args: ["iconClick"]
32713
- }]
32714
- }
32715
- });
32716
- var SortableItemDirective = class SortableItemDirective {
32717
- constructor() {
32718
- this.template = inject(TemplateRef);
32719
- }
32720
- static ngTemplateContextGuard(_dir, _ctx) {
32721
- return true;
32722
- }
32723
- static {
32724
- this.ɵfac = i0.ɵɵngDeclareFactory({
32725
- minVersion: "12.0.0",
32726
- version: "22.2.2",
32727
- ngImport: i0,
32728
- type: SortableItemDirective,
32729
- deps: [],
32730
- target: i0.ɵɵFactoryTarget.Directive
32731
- });
32732
- }
32733
- static {
32734
- this.ɵdir = i0.ɵɵngDeclareDirective({
32735
- minVersion: "14.0.0",
32736
- version: "22.2.2",
32737
- type: SortableItemDirective,
32738
- isStandalone: true,
32739
- selector: "ng-template[uiSortableItem]",
32740
- ngImport: i0
32741
- });
32742
- }
32743
- };
32744
- i0.ɵɵngDeclareClassMetadata({
32745
- minVersion: "12.0.0",
32746
- version: "22.2.2",
32747
- ngImport: i0,
32748
- type: SortableItemDirective,
32749
- decorators: [{
32750
- type: Directive,
32751
- args: [{
32752
- selector: "ng-template[uiSortableItem]",
32753
- standalone: true
32754
- }]
32755
- }]
32756
- });
32757
- let nextId$2 = 0;
32758
- var SortableListComponent = class SortableListComponent {
32759
- constructor() {
32760
- this.items = model([], ...ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []);
32761
- this.sortable = input(false, ...ngDevMode ? [{ debugName: "sortable" }] : /* istanbul ignore next */ []);
32762
- this.layout = input("list", ...ngDevMode ? [{ debugName: "layout" }] : /* istanbul ignore next */ []);
32763
- this.gridMin = input(130, ...ngDevMode ? [{ debugName: "gridMin" }] : /* istanbul ignore next */ []);
32764
- this.ariaLabel = input("", ...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
32765
- this.itemLabel = input((_item, index) => `Item ${index + 1}`, ...ngDevMode ? [{ debugName: "itemLabel" }] : /* istanbul ignore next */ []);
32766
- this.moveControls = input(false, ...ngDevMode ? [{ debugName: "moveControls" }] : /* istanbul ignore next */ []);
32767
- this.moveEarlierLabel = input("Move earlier", ...ngDevMode ? [{ debugName: "moveEarlierLabel" }] : /* istanbul ignore next */ []);
32768
- this.moveLaterLabel = input("Move later", ...ngDevMode ? [{ debugName: "moveLaterLabel" }] : /* istanbul ignore next */ []);
32769
- this.helpText = input("Hold Shift and press the arrow keys to move this item. Shift plus Home or End moves it to the start or end.", ...ngDevMode ? [{ debugName: "helpText" }] : /* istanbul ignore next */ []);
32770
- this.moveAnnouncement = input((label, position, total) => `${label} moved to position ${position} of ${total}`, ...ngDevMode ? [{ debugName: "moveAnnouncement" }] : /* istanbul ignore next */ []);
32771
- this.orderChange = output();
32772
- this.itemTemplate = contentChild.required(SortableItemDirective, ...ngDevMode ? [{ debugName: "itemTemplate" }] : /* istanbul ignore next */ []);
32773
- this._helpId = `sl-help-${nextId$2++}`;
32774
- this._dragIndex = signal(null, ...ngDevMode ? [{ debugName: "_dragIndex" }] : /* istanbul ignore next */ []);
32775
- this._overIndex = signal(null, ...ngDevMode ? [{ debugName: "_overIndex" }] : /* istanbul ignore next */ []);
32776
- this._announcement = signal("", ...ngDevMode ? [{ debugName: "_announcement" }] : /* istanbul ignore next */ []);
32777
- this._count = computed(() => this.items().length, ...ngDevMode ? [{ debugName: "_count" }] : /* istanbul ignore next */ []);
32778
- }
32779
- move(from, to) {
32780
- const list = this.items();
32781
- if (!this.sortable() || from < 0 || from >= list.length) return;
32782
- const target = Math.max(0, Math.min(list.length - 1, to));
32783
- if (target === from) return;
32784
- const next = [...list];
32785
- const [item] = next.splice(from, 1);
32786
- next.splice(target, 0, item);
32787
- this.items.set(next);
32788
- this._announcement.set(this.moveAnnouncement()(this.itemLabel()(item, target), target + 1, next.length));
32789
- this.orderChange.emit({
32790
- item,
32791
- from,
32792
- to: target,
32793
- items: next
32794
- });
32795
- }
32796
- onDragStart(event, index) {
32797
- if (!this.sortable()) return;
32798
- this._dragIndex.set(index);
32799
- if (event.dataTransfer) {
32800
- event.dataTransfer.effectAllowed = "move";
32801
- event.dataTransfer.setData("text/plain", String(index));
32802
- }
32803
- }
32804
- onDragOver(event, index) {
32805
- if (!this.sortable() || this._dragIndex() === null) return;
32806
- event.preventDefault();
32807
- if (event.dataTransfer) event.dataTransfer.dropEffect = "move";
32808
- this._overIndex.set(index);
32809
- }
32810
- onDrop(event, index) {
32811
- const from = this._dragIndex();
32812
- if (!this.sortable() || from === null) return;
32813
- event.preventDefault();
32814
- this.onDragEnd();
32815
- this.move(from, index);
32816
- }
32817
- onDragEnd() {
32818
- this._dragIndex.set(null);
32819
- this._overIndex.set(null);
32820
- }
32821
- onKeydown(event, index) {
32822
- if (!this.sortable() || event.target !== event.currentTarget || !event.shiftKey) return;
32823
- let to = null;
32824
- switch (event.key) {
32825
- case "ArrowUp":
32826
- case "ArrowLeft":
32827
- to = index - 1;
32828
- break;
32829
- case "ArrowDown":
32830
- case "ArrowRight":
32831
- to = index + 1;
32832
- break;
32833
- case "Home":
32834
- to = 0;
32835
- break;
32836
- case "End": to = this._count() - 1;
32837
- }
32838
- if (to === null) return;
32839
- event.preventDefault();
32840
- this.move(index, to);
32841
- }
32842
- static {
32843
- this.ɵfac = i0.ɵɵngDeclareFactory({
32844
- minVersion: "12.0.0",
32845
- version: "22.2.2",
32846
- ngImport: i0,
32847
- type: SortableListComponent,
32848
- deps: [],
32849
- target: i0.ɵɵFactoryTarget.Component
32850
- });
32851
- }
32852
- static {
32853
- this.ɵcmp = i0.ɵɵngDeclareComponent({
32854
- minVersion: "17.0.0",
32855
- version: "22.2.2",
32856
- type: SortableListComponent,
32857
- isStandalone: true,
32858
- selector: "ui-sortable-list",
32859
- inputs: {
32860
- items: {
32861
- classPropertyName: "items",
32862
- publicName: "items",
32863
- isSignal: true,
32864
- isRequired: false,
32865
- transformFunction: null
32866
- },
32867
- sortable: {
32868
- classPropertyName: "sortable",
32869
- publicName: "sortable",
32870
- isSignal: true,
32871
- isRequired: false,
32872
- transformFunction: null
32873
- },
32874
- layout: {
32875
- classPropertyName: "layout",
32876
- publicName: "layout",
32877
- isSignal: true,
32878
- isRequired: false,
32879
- transformFunction: null
32880
- },
32881
- gridMin: {
32882
- classPropertyName: "gridMin",
32883
- publicName: "gridMin",
32884
- isSignal: true,
32885
- isRequired: false,
32886
- transformFunction: null
32887
- },
32888
- ariaLabel: {
32889
- classPropertyName: "ariaLabel",
32890
- publicName: "ariaLabel",
32891
- isSignal: true,
32892
- isRequired: false,
32893
- transformFunction: null
32894
- },
32895
- itemLabel: {
32896
- classPropertyName: "itemLabel",
32897
- publicName: "itemLabel",
32898
- isSignal: true,
32899
- isRequired: false,
32900
- transformFunction: null
32901
- },
32902
- moveControls: {
32903
- classPropertyName: "moveControls",
32904
- publicName: "moveControls",
32905
- isSignal: true,
32906
- isRequired: false,
32907
- transformFunction: null
32908
- },
32909
- moveEarlierLabel: {
32910
- classPropertyName: "moveEarlierLabel",
32911
- publicName: "moveEarlierLabel",
32912
- isSignal: true,
32913
- isRequired: false,
32914
- transformFunction: null
32915
- },
32916
- moveLaterLabel: {
32917
- classPropertyName: "moveLaterLabel",
32918
- publicName: "moveLaterLabel",
33260
+ classPropertyName: "disabled",
33261
+ publicName: "disabled",
32919
33262
  isSignal: true,
32920
33263
  isRequired: false,
32921
33264
  transformFunction: null
32922
33265
  },
32923
- helpText: {
32924
- classPropertyName: "helpText",
32925
- publicName: "helpText",
33266
+ loading: {
33267
+ classPropertyName: "loading",
33268
+ publicName: "loading",
32926
33269
  isSignal: true,
32927
33270
  isRequired: false,
32928
33271
  transformFunction: null
32929
33272
  },
32930
- moveAnnouncement: {
32931
- classPropertyName: "moveAnnouncement",
32932
- publicName: "moveAnnouncement",
33273
+ interactive: {
33274
+ classPropertyName: "interactive",
33275
+ publicName: "interactive",
32933
33276
  isSignal: true,
32934
33277
  isRequired: false,
32935
33278
  transformFunction: null
32936
33279
  }
32937
33280
  },
32938
- outputs: {
32939
- items: "itemsChange",
32940
- orderChange: "orderChange"
32941
- },
32942
- queries: [{
32943
- propertyName: "itemTemplate",
32944
- first: true,
32945
- predicate: SortableItemDirective,
32946
- descendants: true,
32947
- isSignal: true
32948
- }],
33281
+ outputs: { iconClick: "iconClick" },
32949
33282
  ngImport: i0,
32950
33283
  template: `
32951
- <div class="sl" [class.sl-grid]="layout() === 'grid'" [style.--sl-min.px]="gridMin()" role="list" [attr.aria-label]="ariaLabel() || null">
32952
- @for (item of items(); track item; let i = $index; let first = $first; let last = $last) {
32953
- <div class="sl-item" role="listitem"
32954
- [class.sl-sortable]="sortable()"
32955
- [class.sl-dragging]="_dragIndex() === i"
32956
- [class.sl-over]="_overIndex() === i && _dragIndex() !== null && _dragIndex() !== i"
32957
- [attr.draggable]="sortable() ? 'true' : null"
32958
- [attr.tabindex]="sortable() ? 0 : null"
32959
- [attr.aria-roledescription]="sortable() ? 'sortable item' : null"
32960
- [attr.aria-label]="sortable() ? itemLabel()(item, i) : null"
32961
- [attr.aria-describedby]="sortable() ? _helpId : null"
32962
- (dragstart)="onDragStart($event, i)" (dragover)="onDragOver($event, i)" (drop)="onDrop($event, i)" (dragend)="onDragEnd()"
32963
- (keydown)="onKeydown($event, i)">
32964
- <ng-container [ngTemplateOutlet]="itemTemplate().template"
32965
- [ngTemplateOutletContext]="{ $implicit: item, index: i, first: first, last: last, dragging: _dragIndex() === i }" />
32966
- @if (sortable() && moveControls()) {
32967
- <div class="sl-move">
32968
- <ui-icon name="chevron-up" [size]="16" [disabled]="first" [tooltip]="moveEarlierLabel() + ' ' + itemLabel()(item, i)" (iconClick)="move(i, i - 1)" />
32969
- <ui-icon name="chevron-down" [size]="16" [disabled]="last" [tooltip]="moveLaterLabel() + ' ' + itemLabel()(item, i)" (iconClick)="move(i, i + 1)" />
32970
- </div>
32971
- }
32972
- </div>
32973
- }
32974
- </div>
32975
- @if (sortable()) {
32976
- <span class="sl-sr" [id]="_helpId">{{ helpText() }}</span>
33284
+ @if (interactive()) {
33285
+ <button type="button" class="icon-btn" [class.danger]="variant() === 'danger'"
33286
+ [class.loading]="loading()" [disabled]="disabled() || loading()" [attr.aria-busy]="loading() ? 'true' : null"
33287
+ [attr.aria-label]="accessibleName() || null" [uiTooltip]="tooltip()" (click)="onClick($event)">
33288
+ <ng-container *ngTemplateOutlet="glyph" />
33289
+ </button>
33290
+ } @else {
33291
+ <span class="icon-static" [class.danger]="variant() === 'danger'" [attr.aria-busy]="loading() ? 'true' : null"
33292
+ [attr.role]="accessibleName() ? 'img' : null" [attr.aria-label]="accessibleName() || null" [uiTooltip]="tooltip()" [attr.aria-hidden]="accessibleName() ? null : 'true'">
33293
+ <ng-container *ngTemplateOutlet="glyph" />
33294
+ </span>
32977
33295
  }
32978
- <span class="sl-sr" role="status" aria-live="polite">{{ _announcement() }}</span>
33296
+ <ng-template #glyph>
33297
+ @if (loading()) {
33298
+ <span class="spinner" [style.width.px]="size()" [style.height.px]="size()" aria-hidden="true"></span>
33299
+ } @else if (path(); as d) {
33300
+ <svg viewBox="0 0 24 24" [attr.width]="size()" [attr.height]="size()" fill="none" stroke="currentColor"
33301
+ stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
33302
+ <path [attr.d]="d" />
33303
+ </svg>
33304
+ }
33305
+ </ng-template>
32979
33306
  `,
32980
33307
  isInline: true,
32981
- styles: [":host{display:block}.sl{display:flex;flex-direction:column;gap:12px}.sl-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--sl-min, 130px),1fr));gap:12px}.sl-item{position:relative;min-width:0}.sl-sortable{-webkit-user-select:none;user-select:none;-webkit-user-drag:element}@media(hover:hover)and (pointer:fine){.sl-sortable{cursor:grab}.sl-sortable:active{cursor:grabbing}}.sl-sortable:focus-visible{outline:2px solid #3b82f6;outline-offset:2px;border-radius:6px}:host ::ng-deep .sl-sortable img,:host ::ng-deep .sl-sortable ui-image-preview{pointer-events:none;-webkit-user-drag:none}.sl-dragging{opacity:.5}.sl-over{outline:2px dashed #3b82f6;outline-offset:2px;border-radius:6px}.sl-move{display:flex;justify-content:center;gap:4px;margin-top:6px}.sl-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}\n"],
33308
+ styles: [":host{display:inline-flex}.icon-static{display:inline-flex;align-items:center;justify-content:center;color:inherit}.icon-static.danger{color:#b91c1c}.icon-static svg{display:block}.icon-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:6px;background:transparent;color:#475569;cursor:pointer;-webkit-appearance:none;appearance:none;font:inherit;transition:background .15s ease,color .15s ease}.icon-btn:hover:not(:disabled){background:#f1f5f9;color:#0f172a}.icon-btn.danger{color:#b91c1c}.icon-btn.danger:hover:not(:disabled){background:#fef2f2;color:#991b1b}.icon-btn:focus-visible{outline:2px solid #2563eb;outline-offset:2px}.icon-btn:disabled{opacity:.5;cursor:not-allowed}.icon-btn.loading:disabled{opacity:1;cursor:progress}.spinner{display:block;box-sizing:border-box;border:2px solid rgba(100,116,139,.3);border-top-color:currentColor;border-radius:50%;animation:ui-icon-spin .6s linear infinite}@keyframes ui-icon-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.spinner{animation-duration:2s}}.icon-btn:after{content:\"\";position:absolute;inset:-8px}\n"],
32982
33309
  dependencies: [{
32983
33310
  kind: "directive",
32984
33311
  type: NgTemplateOutlet,
@@ -32989,20 +33316,10 @@ var SortableListComponent = class SortableListComponent {
32989
33316
  "ngTemplateOutletInjector"
32990
33317
  ]
32991
33318
  }, {
32992
- kind: "component",
32993
- type: IconComponent,
32994
- selector: "ui-icon",
32995
- inputs: [
32996
- "name",
32997
- "tooltip",
32998
- "ariaLabel",
32999
- "size",
33000
- "variant",
33001
- "disabled",
33002
- "loading",
33003
- "interactive"
33004
- ],
33005
- outputs: ["iconClick"]
33319
+ kind: "directive",
33320
+ type: TooltipDirective,
33321
+ selector: "[uiTooltip]",
33322
+ inputs: ["uiTooltip", "tooltipPosition"]
33006
33323
  }],
33007
33324
  changeDetection: i0.ChangeDetectionStrategy.OnPush
33008
33325
  });
@@ -33012,80 +33329,55 @@ i0.ɵɵngDeclareClassMetadata({
33012
33329
  minVersion: "12.0.0",
33013
33330
  version: "22.2.2",
33014
33331
  ngImport: i0,
33015
- type: SortableListComponent,
33332
+ type: IconComponent,
33016
33333
  decorators: [{
33017
33334
  type: Component,
33018
33335
  args: [{
33019
- selector: "ui-sortable-list",
33336
+ selector: "ui-icon",
33020
33337
  standalone: true,
33338
+ imports: [NgTemplateOutlet, TooltipDirective],
33021
33339
  changeDetection: ChangeDetectionStrategy.OnPush,
33022
- imports: [NgTemplateOutlet, IconComponent],
33023
33340
  template: `
33024
- <div class="sl" [class.sl-grid]="layout() === 'grid'" [style.--sl-min.px]="gridMin()" role="list" [attr.aria-label]="ariaLabel() || null">
33025
- @for (item of items(); track item; let i = $index; let first = $first; let last = $last) {
33026
- <div class="sl-item" role="listitem"
33027
- [class.sl-sortable]="sortable()"
33028
- [class.sl-dragging]="_dragIndex() === i"
33029
- [class.sl-over]="_overIndex() === i && _dragIndex() !== null && _dragIndex() !== i"
33030
- [attr.draggable]="sortable() ? 'true' : null"
33031
- [attr.tabindex]="sortable() ? 0 : null"
33032
- [attr.aria-roledescription]="sortable() ? 'sortable item' : null"
33033
- [attr.aria-label]="sortable() ? itemLabel()(item, i) : null"
33034
- [attr.aria-describedby]="sortable() ? _helpId : null"
33035
- (dragstart)="onDragStart($event, i)" (dragover)="onDragOver($event, i)" (drop)="onDrop($event, i)" (dragend)="onDragEnd()"
33036
- (keydown)="onKeydown($event, i)">
33037
- <ng-container [ngTemplateOutlet]="itemTemplate().template"
33038
- [ngTemplateOutletContext]="{ $implicit: item, index: i, first: first, last: last, dragging: _dragIndex() === i }" />
33039
- @if (sortable() && moveControls()) {
33040
- <div class="sl-move">
33041
- <ui-icon name="chevron-up" [size]="16" [disabled]="first" [tooltip]="moveEarlierLabel() + ' ' + itemLabel()(item, i)" (iconClick)="move(i, i - 1)" />
33042
- <ui-icon name="chevron-down" [size]="16" [disabled]="last" [tooltip]="moveLaterLabel() + ' ' + itemLabel()(item, i)" (iconClick)="move(i, i + 1)" />
33043
- </div>
33044
- }
33045
- </div>
33046
- }
33047
- </div>
33048
- @if (sortable()) {
33049
- <span class="sl-sr" [id]="_helpId">{{ helpText() }}</span>
33341
+ @if (interactive()) {
33342
+ <button type="button" class="icon-btn" [class.danger]="variant() === 'danger'"
33343
+ [class.loading]="loading()" [disabled]="disabled() || loading()" [attr.aria-busy]="loading() ? 'true' : null"
33344
+ [attr.aria-label]="accessibleName() || null" [uiTooltip]="tooltip()" (click)="onClick($event)">
33345
+ <ng-container *ngTemplateOutlet="glyph" />
33346
+ </button>
33347
+ } @else {
33348
+ <span class="icon-static" [class.danger]="variant() === 'danger'" [attr.aria-busy]="loading() ? 'true' : null"
33349
+ [attr.role]="accessibleName() ? 'img' : null" [attr.aria-label]="accessibleName() || null" [uiTooltip]="tooltip()" [attr.aria-hidden]="accessibleName() ? null : 'true'">
33350
+ <ng-container *ngTemplateOutlet="glyph" />
33351
+ </span>
33050
33352
  }
33051
- <span class="sl-sr" role="status" aria-live="polite">{{ _announcement() }}</span>
33353
+ <ng-template #glyph>
33354
+ @if (loading()) {
33355
+ <span class="spinner" [style.width.px]="size()" [style.height.px]="size()" aria-hidden="true"></span>
33356
+ } @else if (path(); as d) {
33357
+ <svg viewBox="0 0 24 24" [attr.width]="size()" [attr.height]="size()" fill="none" stroke="currentColor"
33358
+ stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">
33359
+ <path [attr.d]="d" />
33360
+ </svg>
33361
+ }
33362
+ </ng-template>
33052
33363
  `,
33053
- styles: [":host{display:block}.sl{display:flex;flex-direction:column;gap:12px}.sl-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--sl-min, 130px),1fr));gap:12px}.sl-item{position:relative;min-width:0}.sl-sortable{-webkit-user-select:none;user-select:none;-webkit-user-drag:element}@media(hover:hover)and (pointer:fine){.sl-sortable{cursor:grab}.sl-sortable:active{cursor:grabbing}}.sl-sortable:focus-visible{outline:2px solid #3b82f6;outline-offset:2px;border-radius:6px}:host ::ng-deep .sl-sortable img,:host ::ng-deep .sl-sortable ui-image-preview{pointer-events:none;-webkit-user-drag:none}.sl-dragging{opacity:.5}.sl-over{outline:2px dashed #3b82f6;outline-offset:2px;border-radius:6px}.sl-move{display:flex;justify-content:center;gap:4px;margin-top:6px}.sl-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}\n"]
33364
+ styles: [":host{display:inline-flex}.icon-static{display:inline-flex;align-items:center;justify-content:center;color:inherit}.icon-static.danger{color:#b91c1c}.icon-static svg{display:block}.icon-btn{position:relative;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:none;border-radius:6px;background:transparent;color:#475569;cursor:pointer;-webkit-appearance:none;appearance:none;font:inherit;transition:background .15s ease,color .15s ease}.icon-btn:hover:not(:disabled){background:#f1f5f9;color:#0f172a}.icon-btn.danger{color:#b91c1c}.icon-btn.danger:hover:not(:disabled){background:#fef2f2;color:#991b1b}.icon-btn:focus-visible{outline:2px solid #2563eb;outline-offset:2px}.icon-btn:disabled{opacity:.5;cursor:not-allowed}.icon-btn.loading:disabled{opacity:1;cursor:progress}.spinner{display:block;box-sizing:border-box;border:2px solid rgba(100,116,139,.3);border-top-color:currentColor;border-radius:50%;animation:ui-icon-spin .6s linear infinite}@keyframes ui-icon-spin{to{transform:rotate(360deg)}}@media(prefers-reduced-motion:reduce){.spinner{animation-duration:2s}}.icon-btn:after{content:\"\";position:absolute;inset:-8px}\n"]
33054
33365
  }]
33055
33366
  }],
33056
33367
  propDecorators: {
33057
- items: [{
33058
- type: i0.Input,
33059
- args: [{
33060
- isSignal: true,
33061
- alias: "items",
33062
- required: false
33063
- }]
33064
- }, {
33065
- type: i0.Output,
33066
- args: ["itemsChange"]
33067
- }],
33068
- sortable: [{
33069
- type: i0.Input,
33070
- args: [{
33071
- isSignal: true,
33072
- alias: "sortable",
33073
- required: false
33074
- }]
33075
- }],
33076
- layout: [{
33368
+ name: [{
33077
33369
  type: i0.Input,
33078
33370
  args: [{
33079
33371
  isSignal: true,
33080
- alias: "layout",
33081
- required: false
33372
+ alias: "name",
33373
+ required: true
33082
33374
  }]
33083
33375
  }],
33084
- gridMin: [{
33376
+ tooltip: [{
33085
33377
  type: i0.Input,
33086
33378
  args: [{
33087
33379
  isSignal: true,
33088
- alias: "gridMin",
33380
+ alias: "tooltip",
33089
33381
  required: false
33090
33382
  }]
33091
33383
  }],
@@ -33097,61 +33389,49 @@ i0.ɵɵngDeclareClassMetadata({
33097
33389
  required: false
33098
33390
  }]
33099
33391
  }],
33100
- itemLabel: [{
33101
- type: i0.Input,
33102
- args: [{
33103
- isSignal: true,
33104
- alias: "itemLabel",
33105
- required: false
33106
- }]
33107
- }],
33108
- moveControls: [{
33392
+ size: [{
33109
33393
  type: i0.Input,
33110
33394
  args: [{
33111
33395
  isSignal: true,
33112
- alias: "moveControls",
33396
+ alias: "size",
33113
33397
  required: false
33114
33398
  }]
33115
33399
  }],
33116
- moveEarlierLabel: [{
33400
+ variant: [{
33117
33401
  type: i0.Input,
33118
33402
  args: [{
33119
33403
  isSignal: true,
33120
- alias: "moveEarlierLabel",
33404
+ alias: "variant",
33121
33405
  required: false
33122
33406
  }]
33123
33407
  }],
33124
- moveLaterLabel: [{
33408
+ disabled: [{
33125
33409
  type: i0.Input,
33126
33410
  args: [{
33127
33411
  isSignal: true,
33128
- alias: "moveLaterLabel",
33412
+ alias: "disabled",
33129
33413
  required: false
33130
33414
  }]
33131
33415
  }],
33132
- helpText: [{
33416
+ loading: [{
33133
33417
  type: i0.Input,
33134
33418
  args: [{
33135
33419
  isSignal: true,
33136
- alias: "helpText",
33420
+ alias: "loading",
33137
33421
  required: false
33138
33422
  }]
33139
33423
  }],
33140
- moveAnnouncement: [{
33424
+ interactive: [{
33141
33425
  type: i0.Input,
33142
33426
  args: [{
33143
33427
  isSignal: true,
33144
- alias: "moveAnnouncement",
33428
+ alias: "interactive",
33145
33429
  required: false
33146
33430
  }]
33147
33431
  }],
33148
- orderChange: [{
33432
+ iconClick: [{
33149
33433
  type: i0.Output,
33150
- args: ["orderChange"]
33151
- }],
33152
- itemTemplate: [{
33153
- type: i0.ContentChild,
33154
- args: [i0.forwardRef(() => SortableItemDirective), { isSignal: true }]
33434
+ args: ["iconClick"]
33155
33435
  }]
33156
33436
  }
33157
33437
  });
@@ -33167,6 +33447,14 @@ var KpiCardComponent = class KpiCardComponent {
33167
33447
  this.highlight = input(false, ...ngDevMode ? [{ debugName: "highlight" }] : /* istanbul ignore next */ []);
33168
33448
  this.clickable = input(false, ...ngDevMode ? [{ debugName: "clickable" }] : /* istanbul ignore next */ []);
33169
33449
  this.valueColor = input("default", ...ngDevMode ? [{ debugName: "valueColor" }] : /* istanbul ignore next */ []);
33450
+ this.progress = input(null, ...ngDevMode ? [{ debugName: "progress" }] : /* istanbul ignore next */ []);
33451
+ this.progressMax = input(100, ...ngDevMode ? [{ debugName: "progressMax" }] : /* istanbul ignore next */ []);
33452
+ this.progressSize = input(58, ...ngDevMode ? [{ debugName: "progressSize" }] : /* istanbul ignore next */ []);
33453
+ this.progressStrokeWidth = input(5, ...ngDevMode ? [{ debugName: "progressStrokeWidth" }] : /* istanbul ignore next */ []);
33454
+ this.progressVariant = input(null, ...ngDevMode ? [{ debugName: "progressVariant" }] : /* istanbul ignore next */ []);
33455
+ this.progressAriaLabel = input("", ...ngDevMode ? [{ debugName: "progressAriaLabel" }] : /* istanbul ignore next */ []);
33456
+ this.progressValueText = input("", ...ngDevMode ? [{ debugName: "progressValueText" }] : /* istanbul ignore next */ []);
33457
+ this.hasProgress = computed(() => this.progress() !== null && this.progress() !== void 0, ...ngDevMode ? [{ debugName: "hasProgress" }] : /* istanbul ignore next */ []);
33170
33458
  this.iconSvg = computed(() => {
33171
33459
  const svg = KPI_ICONS[this.icon()];
33172
33460
  return svg ? this.sanitizer.bypassSecurityTrustHtml(svg) : null;
@@ -33250,6 +33538,55 @@ var KpiCardComponent = class KpiCardComponent {
33250
33538
  isSignal: true,
33251
33539
  isRequired: false,
33252
33540
  transformFunction: null
33541
+ },
33542
+ progress: {
33543
+ classPropertyName: "progress",
33544
+ publicName: "progress",
33545
+ isSignal: true,
33546
+ isRequired: false,
33547
+ transformFunction: null
33548
+ },
33549
+ progressMax: {
33550
+ classPropertyName: "progressMax",
33551
+ publicName: "progressMax",
33552
+ isSignal: true,
33553
+ isRequired: false,
33554
+ transformFunction: null
33555
+ },
33556
+ progressSize: {
33557
+ classPropertyName: "progressSize",
33558
+ publicName: "progressSize",
33559
+ isSignal: true,
33560
+ isRequired: false,
33561
+ transformFunction: null
33562
+ },
33563
+ progressStrokeWidth: {
33564
+ classPropertyName: "progressStrokeWidth",
33565
+ publicName: "progressStrokeWidth",
33566
+ isSignal: true,
33567
+ isRequired: false,
33568
+ transformFunction: null
33569
+ },
33570
+ progressVariant: {
33571
+ classPropertyName: "progressVariant",
33572
+ publicName: "progressVariant",
33573
+ isSignal: true,
33574
+ isRequired: false,
33575
+ transformFunction: null
33576
+ },
33577
+ progressAriaLabel: {
33578
+ classPropertyName: "progressAriaLabel",
33579
+ publicName: "progressAriaLabel",
33580
+ isSignal: true,
33581
+ isRequired: false,
33582
+ transformFunction: null
33583
+ },
33584
+ progressValueText: {
33585
+ classPropertyName: "progressValueText",
33586
+ publicName: "progressValueText",
33587
+ isSignal: true,
33588
+ isRequired: false,
33589
+ transformFunction: null
33253
33590
  }
33254
33591
  },
33255
33592
  host: {
@@ -33268,20 +33605,46 @@ var KpiCardComponent = class KpiCardComponent {
33268
33605
  @if (iconSvg()) {
33269
33606
  <div [class]="'kpi-icon ' + color() + '-icon'" aria-hidden="true" [innerHTML]="iconSvg()"></div>
33270
33607
  }
33271
- <span class="kpi-label">{{ label() }}</span>
33608
+ @if (hasProgress()) {
33609
+ <div class="kpi-top">
33610
+ <span class="kpi-label">{{ label() }}</span>
33611
+ <ui-progress-ring class="kpi-ring" [value]="progress()!" [max]="progressMax()" [size]="progressSize()" [strokeWidth]="progressStrokeWidth()"
33612
+ [variant]="progressVariant()" [ariaLabel]="progressAriaLabel() || (label() + ' progress')" [valueText]="progressValueText()" />
33613
+ </div>
33614
+ } @else {
33615
+ <span class="kpi-label">{{ label() }}</span>
33616
+ }
33272
33617
  <span class="kpi-value"
33273
33618
  [class.green-value]="highlight() || valueColor() === 'green'"
33274
33619
  [class.blue-value]="valueColor() === 'blue'">{{ value() }}</span>
33275
33620
  @if (subtitle()) {
33276
33621
  <span class="kpi-subtitle">{{ subtitle() }}</span>
33277
33622
  }
33623
+ <ng-content select="[kpi-footer]" />
33278
33624
  @if (clickable()) {
33279
33625
  <svg class="kpi-arrow" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>
33280
33626
  }
33281
33627
  </div>
33282
33628
  `,
33283
33629
  isInline: true,
33284
- styles: [":host{display:block;height:100%}.kpi-card{position:relative;background:#fff;border:1px solid #e2e8f0;border-radius:10px;padding:16px;display:flex;flex-direction:column;gap:4px;min-width:0;height:100%;box-sizing:border-box;transition:border-color .15s ease,box-shadow .15s ease}:host(:focus){outline:none}:host(:focus-visible) .kpi-card{outline:2px solid #3b82f6;outline-offset:2px}.kpi-card.clickable{cursor:pointer}.kpi-card.clickable:hover{border-color:#93c5fd;box-shadow:0 2px 8px #3b82f614}.kpi-card.clickable:hover .kpi-arrow{color:#3b82f6;transform:translate(2px)}.kpi-arrow{position:absolute;bottom:14px;right:14px;color:#94a3b8;transition:color .15s ease,transform .15s ease}.kpi-icon{flex-shrink:0;width:36px;height:36px;border-radius:8px;display:flex;align-items:center;justify-content:center;margin-bottom:8px}.green-icon{background:#dcfce7;color:#16a34a}.blue-icon{background:#dbeafe;color:#2563eb}.amber-icon{background:#fef3c7;color:#d97706}.orange-icon{background:#ffedd5;color:#c2410c}.red-icon{background:#fee2e2;color:#dc2626}.slate-icon{background:#f1f5f9;color:#475569}.kpi-label{font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.04em}.kpi-value{font-size:1.5rem;font-weight:700;color:#111827;line-height:1.1}.kpi-value.green-value{color:#16a34a}.kpi-value.blue-value{color:#3b82f6}.kpi-subtitle{font-size:.75rem;color:#64748b;margin-top:2px}\n"],
33630
+ styles: [":host{display:block;height:100%}.kpi-card{position:relative;background:#fff;border:1px solid #e2e8f0;border-radius:10px;padding:16px;display:flex;flex-direction:column;gap:4px;min-width:0;height:100%;box-sizing:border-box;transition:border-color .15s ease,box-shadow .15s ease}:host(:focus){outline:none}:host(:focus-visible) .kpi-card{outline:2px solid #3b82f6;outline-offset:2px}.kpi-card.clickable{cursor:pointer}.kpi-card.clickable:hover{border-color:#93c5fd;box-shadow:0 2px 8px #3b82f614}.kpi-card.clickable:hover .kpi-arrow{color:#3b82f6;transform:translate(2px)}.kpi-arrow{position:absolute;bottom:14px;right:14px;color:#94a3b8;transition:color .15s ease,transform .15s ease}.kpi-icon{flex-shrink:0;width:36px;height:36px;border-radius:8px;display:flex;align-items:center;justify-content:center;margin-bottom:8px}.green-icon{background:#dcfce7;color:#16a34a}.blue-icon{background:#dbeafe;color:#2563eb}.amber-icon{background:#fef3c7;color:#d97706}.orange-icon{background:#ffedd5;color:#c2410c}.red-icon{background:#fee2e2;color:#dc2626}.slate-icon{background:#f1f5f9;color:#475569}.kpi-label{font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.04em}.kpi-top{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;min-height:36px;margin-bottom:4px}.kpi-ring{flex-shrink:0}.kpi-value{font-size:1.5rem;font-weight:700;color:#111827;line-height:1.1}.kpi-value.green-value{color:#16a34a}.kpi-value.blue-value{color:#3b82f6}.kpi-subtitle{font-size:.75rem;color:#64748b;margin-top:2px}\n"],
33631
+ dependencies: [{
33632
+ kind: "component",
33633
+ type: ProgressRingComponent,
33634
+ selector: "ui-progress-ring",
33635
+ inputs: [
33636
+ "value",
33637
+ "max",
33638
+ "size",
33639
+ "strokeWidth",
33640
+ "variant",
33641
+ "label",
33642
+ "showValue",
33643
+ "ariaLabel",
33644
+ "ariaLabelledby",
33645
+ "valueText"
33646
+ ]
33647
+ }],
33285
33648
  changeDetection: i0.ChangeDetectionStrategy.OnPush
33286
33649
  });
33287
33650
  }
@@ -33296,6 +33659,7 @@ i0.ɵɵngDeclareClassMetadata({
33296
33659
  args: [{
33297
33660
  selector: "ui-kpi-card",
33298
33661
  standalone: true,
33662
+ imports: [ProgressRingComponent],
33299
33663
  changeDetection: ChangeDetectionStrategy.OnPush,
33300
33664
  host: {
33301
33665
  "[attr.role]": "clickable() ? \"button\" : null",
@@ -33308,19 +33672,28 @@ i0.ɵɵngDeclareClassMetadata({
33308
33672
  @if (iconSvg()) {
33309
33673
  <div [class]="'kpi-icon ' + color() + '-icon'" aria-hidden="true" [innerHTML]="iconSvg()"></div>
33310
33674
  }
33311
- <span class="kpi-label">{{ label() }}</span>
33675
+ @if (hasProgress()) {
33676
+ <div class="kpi-top">
33677
+ <span class="kpi-label">{{ label() }}</span>
33678
+ <ui-progress-ring class="kpi-ring" [value]="progress()!" [max]="progressMax()" [size]="progressSize()" [strokeWidth]="progressStrokeWidth()"
33679
+ [variant]="progressVariant()" [ariaLabel]="progressAriaLabel() || (label() + ' progress')" [valueText]="progressValueText()" />
33680
+ </div>
33681
+ } @else {
33682
+ <span class="kpi-label">{{ label() }}</span>
33683
+ }
33312
33684
  <span class="kpi-value"
33313
33685
  [class.green-value]="highlight() || valueColor() === 'green'"
33314
33686
  [class.blue-value]="valueColor() === 'blue'">{{ value() }}</span>
33315
33687
  @if (subtitle()) {
33316
33688
  <span class="kpi-subtitle">{{ subtitle() }}</span>
33317
33689
  }
33690
+ <ng-content select="[kpi-footer]" />
33318
33691
  @if (clickable()) {
33319
33692
  <svg class="kpi-arrow" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="9 18 15 12 9 6"/></svg>
33320
33693
  }
33321
33694
  </div>
33322
33695
  `,
33323
- styles: [":host{display:block;height:100%}.kpi-card{position:relative;background:#fff;border:1px solid #e2e8f0;border-radius:10px;padding:16px;display:flex;flex-direction:column;gap:4px;min-width:0;height:100%;box-sizing:border-box;transition:border-color .15s ease,box-shadow .15s ease}:host(:focus){outline:none}:host(:focus-visible) .kpi-card{outline:2px solid #3b82f6;outline-offset:2px}.kpi-card.clickable{cursor:pointer}.kpi-card.clickable:hover{border-color:#93c5fd;box-shadow:0 2px 8px #3b82f614}.kpi-card.clickable:hover .kpi-arrow{color:#3b82f6;transform:translate(2px)}.kpi-arrow{position:absolute;bottom:14px;right:14px;color:#94a3b8;transition:color .15s ease,transform .15s ease}.kpi-icon{flex-shrink:0;width:36px;height:36px;border-radius:8px;display:flex;align-items:center;justify-content:center;margin-bottom:8px}.green-icon{background:#dcfce7;color:#16a34a}.blue-icon{background:#dbeafe;color:#2563eb}.amber-icon{background:#fef3c7;color:#d97706}.orange-icon{background:#ffedd5;color:#c2410c}.red-icon{background:#fee2e2;color:#dc2626}.slate-icon{background:#f1f5f9;color:#475569}.kpi-label{font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.04em}.kpi-value{font-size:1.5rem;font-weight:700;color:#111827;line-height:1.1}.kpi-value.green-value{color:#16a34a}.kpi-value.blue-value{color:#3b82f6}.kpi-subtitle{font-size:.75rem;color:#64748b;margin-top:2px}\n"]
33696
+ styles: [":host{display:block;height:100%}.kpi-card{position:relative;background:#fff;border:1px solid #e2e8f0;border-radius:10px;padding:16px;display:flex;flex-direction:column;gap:4px;min-width:0;height:100%;box-sizing:border-box;transition:border-color .15s ease,box-shadow .15s ease}:host(:focus){outline:none}:host(:focus-visible) .kpi-card{outline:2px solid #3b82f6;outline-offset:2px}.kpi-card.clickable{cursor:pointer}.kpi-card.clickable:hover{border-color:#93c5fd;box-shadow:0 2px 8px #3b82f614}.kpi-card.clickable:hover .kpi-arrow{color:#3b82f6;transform:translate(2px)}.kpi-arrow{position:absolute;bottom:14px;right:14px;color:#94a3b8;transition:color .15s ease,transform .15s ease}.kpi-icon{flex-shrink:0;width:36px;height:36px;border-radius:8px;display:flex;align-items:center;justify-content:center;margin-bottom:8px}.green-icon{background:#dcfce7;color:#16a34a}.blue-icon{background:#dbeafe;color:#2563eb}.amber-icon{background:#fef3c7;color:#d97706}.orange-icon{background:#ffedd5;color:#c2410c}.red-icon{background:#fee2e2;color:#dc2626}.slate-icon{background:#f1f5f9;color:#475569}.kpi-label{font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.04em}.kpi-top{display:flex;align-items:flex-start;justify-content:space-between;gap:8px;min-height:36px;margin-bottom:4px}.kpi-ring{flex-shrink:0}.kpi-value{font-size:1.5rem;font-weight:700;color:#111827;line-height:1.1}.kpi-value.green-value{color:#16a34a}.kpi-value.blue-value{color:#3b82f6}.kpi-subtitle{font-size:.75rem;color:#64748b;margin-top:2px}\n"]
33324
33697
  }]
33325
33698
  }],
33326
33699
  propDecorators: {
@@ -33387,6 +33760,62 @@ i0.ɵɵngDeclareClassMetadata({
33387
33760
  alias: "valueColor",
33388
33761
  required: false
33389
33762
  }]
33763
+ }],
33764
+ progress: [{
33765
+ type: i0.Input,
33766
+ args: [{
33767
+ isSignal: true,
33768
+ alias: "progress",
33769
+ required: false
33770
+ }]
33771
+ }],
33772
+ progressMax: [{
33773
+ type: i0.Input,
33774
+ args: [{
33775
+ isSignal: true,
33776
+ alias: "progressMax",
33777
+ required: false
33778
+ }]
33779
+ }],
33780
+ progressSize: [{
33781
+ type: i0.Input,
33782
+ args: [{
33783
+ isSignal: true,
33784
+ alias: "progressSize",
33785
+ required: false
33786
+ }]
33787
+ }],
33788
+ progressStrokeWidth: [{
33789
+ type: i0.Input,
33790
+ args: [{
33791
+ isSignal: true,
33792
+ alias: "progressStrokeWidth",
33793
+ required: false
33794
+ }]
33795
+ }],
33796
+ progressVariant: [{
33797
+ type: i0.Input,
33798
+ args: [{
33799
+ isSignal: true,
33800
+ alias: "progressVariant",
33801
+ required: false
33802
+ }]
33803
+ }],
33804
+ progressAriaLabel: [{
33805
+ type: i0.Input,
33806
+ args: [{
33807
+ isSignal: true,
33808
+ alias: "progressAriaLabel",
33809
+ required: false
33810
+ }]
33811
+ }],
33812
+ progressValueText: [{
33813
+ type: i0.Input,
33814
+ args: [{
33815
+ isSignal: true,
33816
+ alias: "progressValueText",
33817
+ required: false
33818
+ }]
33390
33819
  }]
33391
33820
  }
33392
33821
  });
@@ -36918,21 +37347,6 @@ i0.ɵɵngDeclareClassMetadata({
36918
37347
  }]
36919
37348
  }
36920
37349
  });
36921
- const LAYOUT_GAP_PX = {
36922
- none: 0,
36923
- xs: 4,
36924
- sm: 8,
36925
- md: 16,
36926
- lg: 24,
36927
- xl: 32
36928
- };
36929
- const CSS_LENGTH = /^(?:0|-?(?:\d+\.?\d*|\.\d+)(?:px|rem|em|%|vh|vw|ch)|(?:calc|var)\([^;{}]*\))$/i;
36930
- function resolveLayoutGap(gap, fallback) {
36931
- const v = (gap ?? "").trim();
36932
- if (Object.prototype.hasOwnProperty.call(LAYOUT_GAP_PX, v)) return `${LAYOUT_GAP_PX[v]}px`;
36933
- if (v && CSS_LENGTH.test(v)) return v;
36934
- return `${LAYOUT_GAP_PX[fallback]}px`;
36935
- }
36936
37350
  var ColumnsComponent = class ColumnsComponent {
36937
37351
  constructor() {
36938
37352
  this.count = input(2, ...ngDevMode ? [{ debugName: "count" }] : /* istanbul ignore next */ []);
@@ -37386,6 +37800,6 @@ i0.ɵɵngDeclareClassMetadata({
37386
37800
  }]
37387
37801
  }
37388
37802
  });
37389
- export { ActionBarComponent, AlertComponent, AppShellComponent, AudioPlayerComponent, AvatarComponent, BADGE_VARIANT_STYLES, BadgeComponent, BarRowComponent, BulkMessagePanelComponent, BusinessHoursComponent, ButtonComponent, CheckboxComponent, ChipComponent, ChipGroupComponent, ColorInputComponent, ColumnFilterComponent, ColumnsComponent, ComboboxComponent, ConfirmOutletComponent, ConfirmService, ContactPickerComponent, DEFAULT_DOCUMENT_SUBJECT, DEFAULT_SIGNING_OPTIONS, DOCUMENT_PROVIDER_OPTIONS, DOCUMENT_PURPOSE_OPTIONS, DROPDOWN_GROUP, DataTableComponent, DateInputComponent, DateRangePickerComponent, DatetimeInputComponent, DetailCardComponent, DiscountSelectorComponent, DividerComponent, DocumentMergeCheckComponent, DocumentSendOptionsComponent, DocumentSignersComponent, DropdownComponent, EmptyStateComponent, ErrorComponent, ErrorStateComponent, FORGEROUTE_CONFIG, FileInputComponent, FormRowComponent, FormSectionComponent, HintComponent, IconComponent, ImagePreviewComponent, ImageRepositionComponent, ImportExportComponent, KpiCardComponent, LAYOUT_GAP_PX, ListComponent, ListItemComponent, MAX_CC, MERGE_CHECK_DEBOUNCE_MS, ModalComponent, MoreMenuComponent, MultiSelectComponent, PHONE_NUMBER_AREA_CODE_LENGTH, PHONE_NUMBER_ZIP_LENGTH, PaginationComponent, PanelInfoListComponent, PhoneNumberPickerComponent, PillTabsComponent, ProgressBarComponent, QrCodeComponent, QuickFilterTabsComponent, RICH_TEXT_OPTIONS, RadioComponent, RadioGroupComponent, RadioMatrixComponent, ReadonlyFieldsetComponent, RichTextEditorComponent, SEMANTIC_BADGE_MAP, SIGNER_ROLES, SIGNER_ROLE_LABEL_DEFAULT, SIGNING_LIMITS, SearchInputComponent, SectionHeaderComponent, SelectComponent, SendMessagePanelComponent, SidePanelComponent, SkeletonComponent, SortableItemDirective, SortableListComponent, StackComponent, StepperComponent, TableToolbarComponent, TemplatePickerComponent, TextInputComponent, TextareaInputComponent, TimeInputComponent, ToastComponent, ToastService, ToggleBadgeComponent, ToggleComponent, TooltipDirective, US_STATES, UiFieldValidity, VideoPickerComponent, acceptLabel, appShellGroupsStorageKey, appendVideoLink, applyVideoLine, autoVariant, buildDefaultSchedule, buildSigners, buildVideoLink, builtInActionIcon, businessTimeOptions, countersignLine, countersignPlaceLabel, createFieldReveal, decodeFilterValues, describeDocumentSigners, digitsOnly, effectiveRoles, encodeFilterValue, encodeFilterValues, errorContextInterceptor, fileMatchesAccept, formatFileSize, formatIsoDate, formatIsoDateTime, formatTime, forwardContext, getEligibleIds, getEligibleOptions, getErrorMessage, hasMappedDataFields, humanReadableMessage, iconPath, isoKey, issueToErrors, maxLengthIssue, mergeFieldText, mergeWarningLines, messagePreviewHtml, normalizeHexColor, normalizeRoles, parseBizHours, parseCcList, parseIso, parseTime, pluralize, provideForgerouteToast, reorderItems, requiredIssue, resolveLayoutGap, resolvePreset, roleNumber, sendExistingEnvelope, serializeBizHours, signerProblems, signerRoleLabel, stripVideoLink, suggestDocumentSubject, videoMessageLine };
37803
+ export { ActionBarComponent, AlertComponent, AppShellComponent, AudioPlayerComponent, AvatarComponent, BADGE_VARIANT_STYLES, BadgeComponent, BarRowComponent, BulkMessagePanelComponent, BusinessHoursComponent, ButtonComponent, CheckboxComponent, ChipComponent, ChipGroupComponent, ColorInputComponent, ColumnFilterComponent, ColumnsComponent, ComboboxComponent, ConfirmOutletComponent, ConfirmService, ContactPickerComponent, DEFAULT_DOCUMENT_SUBJECT, DEFAULT_SIGNING_OPTIONS, DOCUMENT_PROVIDER_OPTIONS, DOCUMENT_PURPOSE_OPTIONS, DROPDOWN_GROUP, DataTableComponent, DateInputComponent, DateRangePickerComponent, DatetimeInputComponent, DetailCardComponent, DiscountSelectorComponent, DividerComponent, DocumentMergeCheckComponent, DocumentSendOptionsComponent, DocumentSignersComponent, DropdownComponent, EmptyStateComponent, ErrorComponent, ErrorStateComponent, FORGEROUTE_CONFIG, FileInputComponent, FormRowComponent, FormSectionComponent, HintComponent, IconComponent, ImagePreviewComponent, ImageRepositionComponent, ImportExportComponent, KpiCardComponent, LAYOUT_GAP_PX, ListComponent, ListItemComponent, MAX_CC, MERGE_CHECK_DEBOUNCE_MS, ModalComponent, MoreMenuComponent, MultiSelectComponent, PHONE_NUMBER_AREA_CODE_LENGTH, PHONE_NUMBER_ZIP_LENGTH, PaginationComponent, PanelInfoListComponent, PhoneNumberPickerComponent, PillTabsComponent, ProgressBarComponent, ProgressRingComponent, QrCodeComponent, QuickFilterTabsComponent, RICH_TEXT_OPTIONS, RadioComponent, RadioGroupComponent, RadioMatrixComponent, ReadonlyFieldsetComponent, RichTextEditorComponent, SEMANTIC_BADGE_MAP, SIGNER_ROLES, SIGNER_ROLE_LABEL_DEFAULT, SIGNING_LIMITS, SearchInputComponent, SectionHeaderComponent, SelectComponent, SendMessagePanelComponent, SidePanelComponent, SkeletonComponent, StackComponent, StepperComponent, TableToolbarComponent, TemplatePickerComponent, TextComponent, TextInputComponent, TextareaInputComponent, TimeInputComponent, ToastComponent, ToastService, ToggleBadgeComponent, ToggleComponent, TooltipDirective, US_STATES, UiFieldValidity, VideoPickerComponent, acceptLabel, appShellGroupsStorageKey, appendVideoLink, applyVideoLine, autoVariant, buildDefaultSchedule, buildSigners, buildVideoLink, builtInActionIcon, businessTimeOptions, countersignLine, countersignPlaceLabel, createFieldReveal, decodeFilterValues, describeDocumentSigners, digitsOnly, effectiveRoles, encodeFilterValue, encodeFilterValues, errorContextInterceptor, fileMatchesAccept, formatFileSize, formatIsoDate, formatIsoDateTime, formatTime, forwardContext, getEligibleIds, getEligibleOptions, getErrorMessage, hasMappedDataFields, humanReadableMessage, iconPath, isoKey, issueToErrors, maxLengthIssue, mergeFieldText, mergeWarningLines, messagePreviewHtml, normalizeHexColor, normalizeRoles, parseBizHours, parseCcList, parseIso, parseTime, pluralize, provideForgerouteToast, reorderItems, requiredIssue, resolveLayoutGap, resolvePreset, roleNumber, sendExistingEnvelope, serializeBizHours, signerProblems, signerRoleLabel, stripVideoLink, suggestDocumentSubject, videoMessageLine };
37390
37804
 
37391
37805
  //# sourceMappingURL=forgeroute-ui.mjs.map