@area8975/ui 0.2.2-dev.39 → 0.2.2-dev.41

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.
@@ -304,13 +304,43 @@ function chartSeriesStyle(index, dashes, dark = false) {
304
304
  dashed: false
305
305
  };
306
306
  }
307
- var UiAxisChartBase = class UiAxisChartBase {
307
+ const HEX_COLOUR = /^#([0-9a-f]{6})$/i;
308
+ function hexChannels(colour) {
309
+ const digits = HEX_COLOUR.exec(colour)?.[1];
310
+ return digits ? [
311
+ 0,
312
+ 2,
313
+ 4
314
+ ].map((at) => parseInt(digits.slice(at, at + 2), 16)) : null;
315
+ }
316
+ function mixChartColours(colour, towards, strength) {
317
+ const from = hexChannels(colour);
318
+ const to = hexChannels(towards);
319
+ if (!from || !to) return null;
320
+ return `#${from.map((channel, index) => Math.round(channel * strength + to[index] * (1 - strength))).map((channel) => channel.toString(16).padStart(2, "0")).join("")}`;
321
+ }
322
+ const DARK_LABEL = CHART_INK.text;
323
+ const LIGHT_LABEL = "#ffffff";
324
+ function chartLabelInk(background) {
325
+ const channels = hexChannels(background);
326
+ if (!channels) return DARK_LABEL;
327
+ const backgroundLuminance = screenLuminance(channels);
328
+ return lightnessContrast(screenLuminance(hexChannels(LIGHT_LABEL)), backgroundLuminance) > lightnessContrast(screenLuminance(hexChannels(DARK_LABEL)), backgroundLuminance) ? LIGHT_LABEL : DARK_LABEL;
329
+ }
330
+ function screenLuminance(channels) {
331
+ const [red, green, blue] = channels.map((channel) => (channel / 255) ** 2.4);
332
+ const luminance = .2126729 * red + .7151522 * green + .072175 * blue;
333
+ return luminance < .022 ? luminance + (.022 - luminance) ** 1.414 : luminance;
334
+ }
335
+ function lightnessContrast(textLuminance, backgroundLuminance) {
336
+ const contrast = backgroundLuminance > textLuminance ? (backgroundLuminance ** .56 - textLuminance ** .57) * 1.14 : (backgroundLuminance ** .65 - textLuminance ** .62) * 1.14;
337
+ return Math.max(Math.abs(contrast) - .027, 0) * 100;
338
+ }
339
+ var UiChartBase = class UiChartBase {
308
340
  uiFormat = inject(UI_FORMAT);
309
341
  privacy = inject(UI_PRIVACY);
310
342
  dark = inject(UiDarkClass).isDark;
311
343
  ink = computed(() => chartInk(this.dark()), ...ngDevMode ? [{ debugName: "ink" }] : /* istanbul ignore next */ []);
312
- series = input.required(...ngDevMode ? [{ debugName: "series" }] : /* istanbul ignore next */ []);
313
- categories = input.required(...ngDevMode ? [{ debugName: "categories" }] : /* istanbul ignore next */ []);
314
344
  ariaLabel = input.required(...ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []);
315
345
  height = input(300, ...ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []);
316
346
  valueFormatter = input(numberFormatter(this.uiFormat.locale), ...ngDevMode ? [{ debugName: "valueFormatter" }] : /* istanbul ignore next */ []);
@@ -329,15 +359,9 @@ var UiAxisChartBase = class UiAxisChartBase {
329
359
  transform: booleanAttribute
330
360
  });
331
361
  options = input(null, ...ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []);
332
- highlight = input(null, ...ngDevMode ? [{ debugName: "highlight" }] : /* istanbul ignore next */ []);
333
- highlightKeepsColours = input(false, {
334
- ...ngDevMode ? { debugName: "highlightKeepsColours" } : /* istanbul ignore next */ {},
335
- transform: booleanAttribute
336
- });
337
362
  legend = input("auto", ...ngDevMode ? [{ debugName: "legend" }] : /* istanbul ignore next */ []);
338
363
  hiddenSeries = signal([], ...ngDevMode ? [{ debugName: "hiddenSeries" }] : /* istanbul ignore next */ []);
339
364
  emphasis = signal(null, ...ngDevMode ? [{ debugName: "emphasis" }] : /* istanbul ignore next */ []);
340
- supportsDashes = false;
341
365
  money = computed(() => moneyFormatterParts(this.valueFormatter()), ...ngDevMode ? [{ debugName: "money" }] : /* istanbul ignore next */ []);
342
366
  privacyMode = computed(() => this.sensitive() ?? !!this.money() ? this.privacy() : "visible", ...ngDevMode ? [{ debugName: "privacyMode" }] : /* istanbul ignore next */ []);
343
367
  masked = computed(() => this.privacyMode() !== "visible", ...ngDevMode ? [{ debugName: "masked" }] : /* istanbul ignore next */ []);
@@ -352,42 +376,6 @@ var UiAxisChartBase = class UiAxisChartBase {
352
376
  const height = this.height();
353
377
  return height === "fill" ? "100%" : height;
354
378
  }, ...ngDevMode ? [{ debugName: "apexHeight" }] : /* istanbul ignore next */ []);
355
- isEmpty = computed(() => !this.series().some((item) => item.data.some((value) => value !== null)), ...ngDevMode ? [{ debugName: "isEmpty" }] : /* istanbul ignore next */ []);
356
- isMuted = computed(() => {
357
- const highlight = this.highlight();
358
- return this.series().map((item) => !!highlight && !highlight.includes(item.name));
359
- }, ...ngDevMode ? [{ debugName: "isMuted" }] : /* istanbul ignore next */ []);
360
- colourOrder = computed(() => this.highlightKeepsColours() ? null : this.highlight(), ...ngDevMode ? [{ debugName: "colourOrder" }] : /* istanbul ignore next */ []);
361
- styles = computed(() => {
362
- const order = this.colourOrder();
363
- const muted = this.isMuted();
364
- return this.series().map((item, index) => {
365
- const dashed = this.supportsDashes && !!item.dashed;
366
- if (muted[index]) return {
367
- colour: this.ink().context,
368
- dashed
369
- };
370
- const style = chartSeriesStyle(order ? order.indexOf(item.name) : index, this.supportsDashes, this.dark());
371
- return {
372
- colour: item.colour ?? style.colour,
373
- dashed: style.dashed || dashed
374
- };
375
- });
376
- }, ...ngDevMode ? [{ debugName: "styles" }] : /* istanbul ignore next */ []);
377
- colours = computed(() => this.styles().map((style) => style.colour), ...ngDevMode ? [{ debugName: "colours" }] : /* istanbul ignore next */ []);
378
- dashed = computed(() => this.styles().map((style) => style.dashed), ...ngDevMode ? [{ debugName: "dashed" }] : /* istanbul ignore next */ []);
379
- legendItems = computed(() => {
380
- const order = this.colourOrder();
381
- const items = this.series().map((item, index) => ({
382
- name: item.name,
383
- ...this.styles()[index]
384
- })).filter((_, index) => !this.isMuted()[index]);
385
- return order ? items.sort((a, b) => order.indexOf(a.name) - order.indexOf(b.name)) : items;
386
- }, ...ngDevMode ? [{ debugName: "legendItems" }] : /* istanbul ignore next */ []);
387
- legendNote = computed(() => {
388
- const count = this.isMuted().filter(Boolean).length;
389
- return count ? `${count} more in grey` : "";
390
- }, ...ngDevMode ? [{ debugName: "legendNote" }] : /* istanbul ignore next */ []);
391
379
  formatValue(value) {
392
380
  return value === null || value === void 0 ? "-" : this.displayFormatter()(value);
393
381
  }
@@ -395,30 +383,16 @@ var UiAxisChartBase = class UiAxisChartBase {
395
383
  minVersion: "12.0.0",
396
384
  version: "22.2.1",
397
385
  ngImport: i0,
398
- type: UiAxisChartBase,
386
+ type: UiChartBase,
399
387
  deps: [],
400
388
  target: i0.ɵɵFactoryTarget.Directive
401
389
  });
402
390
  static ɵdir = i0.ɵɵngDeclareDirective({
403
391
  minVersion: "17.1.0",
404
392
  version: "22.2.1",
405
- type: UiAxisChartBase,
393
+ type: UiChartBase,
406
394
  isStandalone: true,
407
395
  inputs: {
408
- series: {
409
- classPropertyName: "series",
410
- publicName: "series",
411
- isSignal: true,
412
- isRequired: true,
413
- transformFunction: null
414
- },
415
- categories: {
416
- classPropertyName: "categories",
417
- publicName: "categories",
418
- isSignal: true,
419
- isRequired: true,
420
- transformFunction: null
421
- },
422
396
  ariaLabel: {
423
397
  classPropertyName: "ariaLabel",
424
398
  publicName: "ariaLabel",
@@ -482,20 +456,6 @@ var UiAxisChartBase = class UiAxisChartBase {
482
456
  isRequired: false,
483
457
  transformFunction: null
484
458
  },
485
- highlight: {
486
- classPropertyName: "highlight",
487
- publicName: "highlight",
488
- isSignal: true,
489
- isRequired: false,
490
- transformFunction: null
491
- },
492
- highlightKeepsColours: {
493
- classPropertyName: "highlightKeepsColours",
494
- publicName: "highlightKeepsColours",
495
- isSignal: true,
496
- isRequired: false,
497
- transformFunction: null
498
- },
499
459
  legend: {
500
460
  classPropertyName: "legend",
501
461
  publicName: "legend",
@@ -511,25 +471,9 @@ i0.ɵɵngDeclareClassMetadata({
511
471
  minVersion: "12.0.0",
512
472
  version: "22.2.1",
513
473
  ngImport: i0,
514
- type: UiAxisChartBase,
474
+ type: UiChartBase,
515
475
  decorators: [{ type: Directive }],
516
476
  propDecorators: {
517
- series: [{
518
- type: i0.Input,
519
- args: [{
520
- isSignal: true,
521
- alias: "series",
522
- required: true
523
- }]
524
- }],
525
- categories: [{
526
- type: i0.Input,
527
- args: [{
528
- isSignal: true,
529
- alias: "categories",
530
- required: true
531
- }]
532
- }],
533
477
  ariaLabel: [{
534
478
  type: i0.Input,
535
479
  args: [{
@@ -602,36 +546,153 @@ i0.ɵɵngDeclareClassMetadata({
602
546
  required: false
603
547
  }]
604
548
  }],
605
- highlight: [{
549
+ legend: [{
606
550
  type: i0.Input,
607
551
  args: [{
608
552
  isSignal: true,
609
- alias: "highlight",
553
+ alias: "legend",
610
554
  required: false
611
555
  }]
556
+ }]
557
+ }
558
+ });
559
+ function numberFormatter(locale) {
560
+ const formatter = new Intl.NumberFormat(locale);
561
+ return (value) => formatter.format(value);
562
+ }
563
+ var UiAxisChartBase = class UiAxisChartBase extends UiChartBase {
564
+ series = input.required(...ngDevMode ? [{ debugName: "series" }] : /* istanbul ignore next */ []);
565
+ categories = input.required(...ngDevMode ? [{ debugName: "categories" }] : /* istanbul ignore next */ []);
566
+ highlight = input(null, ...ngDevMode ? [{ debugName: "highlight" }] : /* istanbul ignore next */ []);
567
+ highlightKeepsColours = input(false, {
568
+ ...ngDevMode ? { debugName: "highlightKeepsColours" } : /* istanbul ignore next */ {},
569
+ transform: booleanAttribute
570
+ });
571
+ supportsDashes = false;
572
+ isEmpty = computed(() => !this.series().some((item) => item.data.some((value) => value !== null)), ...ngDevMode ? [{ debugName: "isEmpty" }] : /* istanbul ignore next */ []);
573
+ isMuted = computed(() => {
574
+ const highlight = this.highlight();
575
+ return this.series().map((item) => !!highlight && !highlight.includes(item.name));
576
+ }, ...ngDevMode ? [{ debugName: "isMuted" }] : /* istanbul ignore next */ []);
577
+ colourOrder = computed(() => this.highlightKeepsColours() ? null : this.highlight(), ...ngDevMode ? [{ debugName: "colourOrder" }] : /* istanbul ignore next */ []);
578
+ styles = computed(() => {
579
+ const order = this.colourOrder();
580
+ const muted = this.isMuted();
581
+ return this.series().map((item, index) => {
582
+ const dashed = this.supportsDashes && !!item.dashed;
583
+ if (muted[index]) return {
584
+ colour: this.ink().context,
585
+ dashed
586
+ };
587
+ const style = chartSeriesStyle(order ? order.indexOf(item.name) : index, this.supportsDashes, this.dark());
588
+ return {
589
+ colour: item.colour ?? style.colour,
590
+ dashed: style.dashed || dashed
591
+ };
592
+ });
593
+ }, ...ngDevMode ? [{ debugName: "styles" }] : /* istanbul ignore next */ []);
594
+ colours = computed(() => this.styles().map((style) => style.colour), ...ngDevMode ? [{ debugName: "colours" }] : /* istanbul ignore next */ []);
595
+ dashed = computed(() => this.styles().map((style) => style.dashed), ...ngDevMode ? [{ debugName: "dashed" }] : /* istanbul ignore next */ []);
596
+ legendItems = computed(() => {
597
+ const order = this.colourOrder();
598
+ const items = this.series().map((item, index) => ({
599
+ name: item.name,
600
+ ...this.styles()[index]
601
+ })).filter((_, index) => !this.isMuted()[index]);
602
+ return order ? items.sort((a, b) => order.indexOf(a.name) - order.indexOf(b.name)) : items;
603
+ }, ...ngDevMode ? [{ debugName: "legendItems" }] : /* istanbul ignore next */ []);
604
+ legendNote = computed(() => {
605
+ const count = this.isMuted().filter(Boolean).length;
606
+ return count ? `${count} more in grey` : "";
607
+ }, ...ngDevMode ? [{ debugName: "legendNote" }] : /* istanbul ignore next */ []);
608
+ static ɵfac = i0.ɵɵngDeclareFactory({
609
+ minVersion: "12.0.0",
610
+ version: "22.2.1",
611
+ ngImport: i0,
612
+ type: UiAxisChartBase,
613
+ deps: null,
614
+ target: i0.ɵɵFactoryTarget.Directive
615
+ });
616
+ static ɵdir = i0.ɵɵngDeclareDirective({
617
+ minVersion: "17.1.0",
618
+ version: "22.2.1",
619
+ type: UiAxisChartBase,
620
+ isStandalone: true,
621
+ inputs: {
622
+ series: {
623
+ classPropertyName: "series",
624
+ publicName: "series",
625
+ isSignal: true,
626
+ isRequired: true,
627
+ transformFunction: null
628
+ },
629
+ categories: {
630
+ classPropertyName: "categories",
631
+ publicName: "categories",
632
+ isSignal: true,
633
+ isRequired: true,
634
+ transformFunction: null
635
+ },
636
+ highlight: {
637
+ classPropertyName: "highlight",
638
+ publicName: "highlight",
639
+ isSignal: true,
640
+ isRequired: false,
641
+ transformFunction: null
642
+ },
643
+ highlightKeepsColours: {
644
+ classPropertyName: "highlightKeepsColours",
645
+ publicName: "highlightKeepsColours",
646
+ isSignal: true,
647
+ isRequired: false,
648
+ transformFunction: null
649
+ }
650
+ },
651
+ usesInheritance: true,
652
+ ngImport: i0
653
+ });
654
+ };
655
+ i0.ɵɵngDeclareClassMetadata({
656
+ minVersion: "12.0.0",
657
+ version: "22.2.1",
658
+ ngImport: i0,
659
+ type: UiAxisChartBase,
660
+ decorators: [{ type: Directive }],
661
+ propDecorators: {
662
+ series: [{
663
+ type: i0.Input,
664
+ args: [{
665
+ isSignal: true,
666
+ alias: "series",
667
+ required: true
668
+ }]
612
669
  }],
613
- highlightKeepsColours: [{
670
+ categories: [{
614
671
  type: i0.Input,
615
672
  args: [{
616
673
  isSignal: true,
617
- alias: "highlightKeepsColours",
674
+ alias: "categories",
675
+ required: true
676
+ }]
677
+ }],
678
+ highlight: [{
679
+ type: i0.Input,
680
+ args: [{
681
+ isSignal: true,
682
+ alias: "highlight",
618
683
  required: false
619
684
  }]
620
685
  }],
621
- legend: [{
686
+ highlightKeepsColours: [{
622
687
  type: i0.Input,
623
688
  args: [{
624
689
  isSignal: true,
625
- alias: "legend",
690
+ alias: "highlightKeepsColours",
626
691
  required: false
627
692
  }]
628
693
  }]
629
694
  }
630
695
  });
631
- function numberFormatter(locale) {
632
- const formatter = new Intl.NumberFormat(locale);
633
- return (value) => formatter.format(value);
634
- }
635
696
  function chartAxisLabels(ink) {
636
697
  return { style: {
637
698
  colors: ink.muted,
@@ -1208,7 +1269,7 @@ var UiChartComponent = class UiChartComponent {
1208
1269
  ></div>
1209
1270
  `,
1210
1271
  isInline: true,
1211
- styles: ["@layer properties;.ui-chart{display:block;width:100%;min-width:0px;font-family:var(--font-body, \"Inter\", sans-serif)}.ui-chart .apexcharts-tooltip.apexcharts-theme-light{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--border-line-2);background-color:var(--layer);--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ui-chart-tooltip{display:flex;min-width:calc(var(--spacing, .25rem) * 36);flex-direction:column;row-gap:var(--spacing, .25rem);padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2)}.ui-chart-tooltip-title{padding-bottom:var(--spacing, .25rem);color:var(--muted-foreground-1)}.ui-chart-tooltip-row{display:flex;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2);color:var(--foreground)}.ui-chart-tooltip-total{margin-top:var(--spacing, .25rem);border-top-style:var(--tw-border-style);border-top-width:1px;border-color:var(--border-line-2);padding-top:calc(var(--spacing, .25rem) * 2)}.ui-chart-tooltip-footer{padding-top:var(--spacing, .25rem);color:var(--muted-foreground-1)}.ui-chart-tooltip-dot{width:calc(var(--spacing, .25rem) * 2);height:calc(var(--spacing, .25rem) * 2);flex-shrink:0;border-radius:var(--radius-full, calc(infinity * 1px));background-color:var(--ui-chart-tooltip-colour)}.ui-chart-tooltip-dot--dashed{height:0px;width:calc(var(--spacing, .25rem) * 3);border-radius:0;border-top-style:var(--tw-border-style);border-top-width:2px;--tw-border-style: dashed;border-style:dashed;background-color:transparent;border-color:var(--ui-chart-tooltip-colour)}.ui-chart-tooltip-value{margin-inline-start:auto;padding-inline-start:calc(var(--spacing, .25rem) * 3);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.ui-chart .apexcharts-series{transition:opacity .15s ease}.ui-chart .ui-chart-series--faded{opacity:.15}.ui-chart .apexcharts-yaxis-label,.ui-chart .apexcharts-xaxis-label{font-variant-numeric:tabular-nums}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
1272
+ styles: [".ui-chart{display:block;width:100%;min-width:0px;font-family:var(--font-body, \"Inter\", sans-serif)}.ui-chart .apexcharts-series{transition:opacity .15s ease}.ui-chart .ui-chart-series--faded{opacity:.15}.ui-chart .apexcharts-yaxis-label,.ui-chart .apexcharts-xaxis-label{font-variant-numeric:tabular-nums}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n", "@layer properties;.ui-chart .apexcharts-tooltip.apexcharts-theme-light,.ui-chart-tooltip-panel{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--border-line-2);background-color:var(--layer);--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ui-chart-tooltip{display:flex;min-width:calc(var(--spacing, .25rem) * 36);flex-direction:column;row-gap:var(--spacing, .25rem);padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2)}.ui-chart-tooltip-title{padding-bottom:var(--spacing, .25rem);color:var(--muted-foreground-1)}.ui-chart-tooltip-row{display:flex;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2);color:var(--foreground)}.ui-chart-tooltip-total{margin-top:var(--spacing, .25rem);border-top-style:var(--tw-border-style);border-top-width:1px;border-color:var(--border-line-2);padding-top:calc(var(--spacing, .25rem) * 2)}.ui-chart-tooltip-footer{padding-top:var(--spacing, .25rem);color:var(--muted-foreground-1)}.ui-chart-tooltip-dot{width:calc(var(--spacing, .25rem) * 2);height:calc(var(--spacing, .25rem) * 2);flex-shrink:0;border-radius:var(--radius-full, calc(infinity * 1px));background-color:var(--ui-chart-tooltip-colour)}.ui-chart-tooltip-dot--dashed{height:0px;width:calc(var(--spacing, .25rem) * 3);border-radius:0;border-top-style:var(--tw-border-style);border-top-width:2px;--tw-border-style: dashed;border-style:dashed;background-color:transparent;border-color:var(--ui-chart-tooltip-colour)}.ui-chart-tooltip-value{margin-inline-start:auto;padding-inline-start:calc(var(--spacing, .25rem) * 3);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
1212
1273
  encapsulation: i0.ViewEncapsulation.None
1213
1274
  });
1214
1275
  };
@@ -1231,7 +1292,7 @@ i0.ɵɵngDeclareClassMetadata({
1231
1292
  `,
1232
1293
  encapsulation: ViewEncapsulation.None,
1233
1294
  host: { class: "ui-chart" },
1234
- styles: ["@layer properties;.ui-chart{display:block;width:100%;min-width:0px;font-family:var(--font-body, \"Inter\", sans-serif)}.ui-chart .apexcharts-tooltip.apexcharts-theme-light{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--border-line-2);background-color:var(--layer);--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ui-chart-tooltip{display:flex;min-width:calc(var(--spacing, .25rem) * 36);flex-direction:column;row-gap:var(--spacing, .25rem);padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2)}.ui-chart-tooltip-title{padding-bottom:var(--spacing, .25rem);color:var(--muted-foreground-1)}.ui-chart-tooltip-row{display:flex;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2);color:var(--foreground)}.ui-chart-tooltip-total{margin-top:var(--spacing, .25rem);border-top-style:var(--tw-border-style);border-top-width:1px;border-color:var(--border-line-2);padding-top:calc(var(--spacing, .25rem) * 2)}.ui-chart-tooltip-footer{padding-top:var(--spacing, .25rem);color:var(--muted-foreground-1)}.ui-chart-tooltip-dot{width:calc(var(--spacing, .25rem) * 2);height:calc(var(--spacing, .25rem) * 2);flex-shrink:0;border-radius:var(--radius-full, calc(infinity * 1px));background-color:var(--ui-chart-tooltip-colour)}.ui-chart-tooltip-dot--dashed{height:0px;width:calc(var(--spacing, .25rem) * 3);border-radius:0;border-top-style:var(--tw-border-style);border-top-width:2px;--tw-border-style: dashed;border-style:dashed;background-color:transparent;border-color:var(--ui-chart-tooltip-colour)}.ui-chart-tooltip-value{margin-inline-start:auto;padding-inline-start:calc(var(--spacing, .25rem) * 3);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.ui-chart .apexcharts-series{transition:opacity .15s ease}.ui-chart .ui-chart-series--faded{opacity:.15}.ui-chart .apexcharts-yaxis-label,.ui-chart .apexcharts-xaxis-label{font-variant-numeric:tabular-nums}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
1295
+ styles: [".ui-chart{display:block;width:100%;min-width:0px;font-family:var(--font-body, \"Inter\", sans-serif)}.ui-chart .apexcharts-series{transition:opacity .15s ease}.ui-chart .ui-chart-series--faded{opacity:.15}.ui-chart .apexcharts-yaxis-label,.ui-chart .apexcharts-xaxis-label{font-variant-numeric:tabular-nums}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n", "@layer properties;.ui-chart .apexcharts-tooltip.apexcharts-theme-light,.ui-chart-tooltip-panel{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--border-line-2);background-color:var(--layer);--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ui-chart-tooltip{display:flex;min-width:calc(var(--spacing, .25rem) * 36);flex-direction:column;row-gap:var(--spacing, .25rem);padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2)}.ui-chart-tooltip-title{padding-bottom:var(--spacing, .25rem);color:var(--muted-foreground-1)}.ui-chart-tooltip-row{display:flex;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2);color:var(--foreground)}.ui-chart-tooltip-total{margin-top:var(--spacing, .25rem);border-top-style:var(--tw-border-style);border-top-width:1px;border-color:var(--border-line-2);padding-top:calc(var(--spacing, .25rem) * 2)}.ui-chart-tooltip-footer{padding-top:var(--spacing, .25rem);color:var(--muted-foreground-1)}.ui-chart-tooltip-dot{width:calc(var(--spacing, .25rem) * 2);height:calc(var(--spacing, .25rem) * 2);flex-shrink:0;border-radius:var(--radius-full, calc(infinity * 1px));background-color:var(--ui-chart-tooltip-colour)}.ui-chart-tooltip-dot--dashed{height:0px;width:calc(var(--spacing, .25rem) * 3);border-radius:0;border-top-style:var(--tw-border-style);border-top-width:2px;--tw-border-style: dashed;border-style:dashed;background-color:transparent;border-color:var(--ui-chart-tooltip-colour)}.ui-chart-tooltip-value{margin-inline-start:auto;padding-inline-start:calc(var(--spacing, .25rem) * 3);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
1235
1296
  }]
1236
1297
  }],
1237
1298
  ctorParameters: () => [],
@@ -1711,14 +1772,18 @@ var UiChartFrameComponent = class UiChartFrameComponent {
1711
1772
  />
1712
1773
  }
1713
1774
 
1714
- <ui-chart
1715
- [class.grow]="fill()"
1716
- [class.min-h-0]="fill()"
1717
- [options]="options()"
1718
- [ariaLabel]="ariaLabel()"
1719
- [hiddenSeries]="hiddenSeries()"
1720
- [emphasis]="emphasis()"
1721
- />
1775
+ @if (options(); as options) {
1776
+ <ui-chart
1777
+ [class.grow]="fill()"
1778
+ [class.min-h-0]="fill()"
1779
+ [options]="options"
1780
+ [ariaLabel]="ariaLabel()"
1781
+ [hiddenSeries]="hiddenSeries()"
1782
+ [emphasis]="emphasis()"
1783
+ />
1784
+ } @else {
1785
+ <ng-content />
1786
+ }
1722
1787
 
1723
1788
  <ui-chart-table
1724
1789
  [caption]="ariaLabel()"
@@ -1821,14 +1886,18 @@ i0.ɵɵngDeclareClassMetadata({
1821
1886
  />
1822
1887
  }
1823
1888
 
1824
- <ui-chart
1825
- [class.grow]="fill()"
1826
- [class.min-h-0]="fill()"
1827
- [options]="options()"
1828
- [ariaLabel]="ariaLabel()"
1829
- [hiddenSeries]="hiddenSeries()"
1830
- [emphasis]="emphasis()"
1831
- />
1889
+ @if (options(); as options) {
1890
+ <ui-chart
1891
+ [class.grow]="fill()"
1892
+ [class.min-h-0]="fill()"
1893
+ [options]="options"
1894
+ [ariaLabel]="ariaLabel()"
1895
+ [hiddenSeries]="hiddenSeries()"
1896
+ [emphasis]="emphasis()"
1897
+ />
1898
+ } @else {
1899
+ <ng-content />
1900
+ }
1832
1901
 
1833
1902
  <ui-chart-table
1834
1903
  [caption]="ariaLabel()"
@@ -2004,16 +2073,7 @@ i0.ɵɵngDeclareClassMetadata({
2004
2073
  const MAX_BAR_THICKNESS = 24;
2005
2074
  const FADED_STRENGTH = .3;
2006
2075
  function fade(colour, ink) {
2007
- const hex = /^#([0-9a-f]{6})$/i;
2008
- const from = hex.exec(colour)?.[1];
2009
- const to = hex.exec(ink.surface)?.[1];
2010
- if (!from || !to) return ink.context;
2011
- const channel = (value, at) => parseInt(value.slice(at, at + 2), 16);
2012
- return `rgb(${[
2013
- 0,
2014
- 2,
2015
- 4
2016
- ].map((at) => Math.round(channel(from, at) * FADED_STRENGTH + channel(to, at) * .7)).join(", ")})`;
2076
+ return mixChartColours(colour, ink.surface, FADED_STRENGTH) ?? ink.context;
2017
2077
  }
2018
2078
  var UiBarChartComponent = class UiBarChartComponent extends UiAxisChartBase {
2019
2079
  orientation = input("vertical", ...ngDevMode ? [{ debugName: "orientation" }] : /* istanbul ignore next */ []);
@@ -2537,98 +2597,535 @@ var UiPieChartComponent = class UiPieChartComponent extends UiAxisChartBase {
2537
2597
  color: ink.muted,
2538
2598
  offsetY: -4
2539
2599
  };
2540
- return mergeChartOptions({
2541
- ...base,
2542
- chart: {
2543
- ...base.chart,
2544
- type: donut ? "donut" : "pie",
2545
- height: this.apexHeight()
2546
- },
2547
- colors: drawn.map((slice) => slice.colour),
2548
- labels: drawn.map((slice) => slice.name),
2549
- series: drawn.map((slice) => slice.value),
2550
- stroke: {
2551
- show: true,
2552
- width: 2,
2553
- colors: [ink.surface]
2554
- },
2555
- states: {
2556
- ...base.states,
2557
- hover: { filter: { type: concealed ? "none" : "darken" } }
2558
- },
2559
- plotOptions: { pie: {
2560
- expandOnClick: false,
2561
- donut: {
2562
- size: "65%",
2563
- labels: {
2564
- show: donut,
2565
- name: centreText,
2566
- value: {
2567
- fontSize: "20px",
2568
- fontWeight: 600,
2569
- color: ink.text,
2570
- offsetY: 4,
2571
- formatter: (value) => this.formatValue(Number(value))
2572
- },
2573
- total: {
2574
- show: true,
2575
- showAlways: true,
2576
- label: this.totalLabel(),
2577
- ...centreText,
2578
- formatter: () => this.formatValue(total)
2579
- }
2580
- }
2581
- }
2582
- } },
2583
- tooltip: concealed ? { enabled: false } : {
2584
- theme: "light",
2585
- fillSeriesColor: false,
2586
- custom: ({ seriesIndex }) => {
2587
- const slice = slices[seriesIndex];
2588
- return slice ? chartTooltipHtml("", [{
2589
- colour: slice.colour,
2590
- name: slice.name,
2591
- value: this.masked() ? void 0 : this.formatValue(slice.value)
2592
- }], total ? `${this.percentFormatter.format(slice.value / total)} of total` : "") : "";
2593
- }
2594
- }
2595
- }, this.options());
2596
- }, ...ngDevMode ? [{ debugName: "chartOptions" }] : /* istanbul ignore next */ []);
2600
+ return mergeChartOptions({
2601
+ ...base,
2602
+ chart: {
2603
+ ...base.chart,
2604
+ type: donut ? "donut" : "pie",
2605
+ height: this.apexHeight()
2606
+ },
2607
+ colors: drawn.map((slice) => slice.colour),
2608
+ labels: drawn.map((slice) => slice.name),
2609
+ series: drawn.map((slice) => slice.value),
2610
+ stroke: {
2611
+ show: true,
2612
+ width: 2,
2613
+ colors: [ink.surface]
2614
+ },
2615
+ states: {
2616
+ ...base.states,
2617
+ hover: { filter: { type: concealed ? "none" : "darken" } }
2618
+ },
2619
+ plotOptions: { pie: {
2620
+ expandOnClick: false,
2621
+ donut: {
2622
+ size: "65%",
2623
+ labels: {
2624
+ show: donut,
2625
+ name: centreText,
2626
+ value: {
2627
+ fontSize: "20px",
2628
+ fontWeight: 600,
2629
+ color: ink.text,
2630
+ offsetY: 4,
2631
+ formatter: (value) => this.formatValue(Number(value))
2632
+ },
2633
+ total: {
2634
+ show: true,
2635
+ showAlways: true,
2636
+ label: this.totalLabel(),
2637
+ ...centreText,
2638
+ formatter: () => this.formatValue(total)
2639
+ }
2640
+ }
2641
+ }
2642
+ } },
2643
+ tooltip: concealed ? { enabled: false } : {
2644
+ theme: "light",
2645
+ fillSeriesColor: false,
2646
+ custom: ({ seriesIndex }) => {
2647
+ const slice = slices[seriesIndex];
2648
+ return slice ? chartTooltipHtml("", [{
2649
+ colour: slice.colour,
2650
+ name: slice.name,
2651
+ value: this.masked() ? void 0 : this.formatValue(slice.value)
2652
+ }], total ? `${this.percentFormatter.format(slice.value / total)} of total` : "") : "";
2653
+ }
2654
+ }
2655
+ }, this.options());
2656
+ }, ...ngDevMode ? [{ debugName: "chartOptions" }] : /* istanbul ignore next */ []);
2657
+ static ɵfac = i0.ɵɵngDeclareFactory({
2658
+ minVersion: "12.0.0",
2659
+ version: "22.2.1",
2660
+ ngImport: i0,
2661
+ type: UiPieChartComponent,
2662
+ deps: null,
2663
+ target: i0.ɵɵFactoryTarget.Component
2664
+ });
2665
+ static ɵcmp = i0.ɵɵngDeclareComponent({
2666
+ minVersion: "17.1.0",
2667
+ version: "22.2.1",
2668
+ type: UiPieChartComponent,
2669
+ isStandalone: true,
2670
+ selector: "ui-pie-chart",
2671
+ inputs: {
2672
+ variant: {
2673
+ classPropertyName: "variant",
2674
+ publicName: "variant",
2675
+ isSignal: true,
2676
+ isRequired: false,
2677
+ transformFunction: null
2678
+ },
2679
+ totalLabel: {
2680
+ classPropertyName: "totalLabel",
2681
+ publicName: "totalLabel",
2682
+ isSignal: true,
2683
+ isRequired: false,
2684
+ transformFunction: null
2685
+ }
2686
+ },
2687
+ host: { classAttribute: "block w-full min-w-0" },
2688
+ usesInheritance: true,
2689
+ ngImport: i0,
2690
+ template: "<ui-chart-frame\n [options]=\"chartOptions()\"\n [ariaLabel]=\"ariaLabel()\"\n [categories]=\"categories()\"\n [series]=\"series()\"\n [legendItems]=\"legendItems()\"\n [legendNote]=\"legendNote()\"\n [(hiddenSeries)]=\"hiddenSeries\"\n [(emphasis)]=\"emphasis\"\n [showLegend]=\"legend() === 'auto'\"\n [valueFormatter]=\"displayFormatter()\"\n [masked]=\"masked()\"\n [categoryLabel]=\"categoryLabel()\"\n [height]=\"height()\"\n [emptyText]=\"emptyText()\"\n [loading]=\"loading()\"\n [empty]=\"isEmpty()\"\n [showTable]=\"showTable()\"\n/>\n",
2691
+ dependencies: [{
2692
+ kind: "component",
2693
+ type: UiChartFrameComponent,
2694
+ selector: "ui-chart-frame",
2695
+ inputs: [
2696
+ "options",
2697
+ "ariaLabel",
2698
+ "categories",
2699
+ "series",
2700
+ "legendItems",
2701
+ "legendNote",
2702
+ "hiddenSeries",
2703
+ "valueFormatter",
2704
+ "categoryLabel",
2705
+ "height",
2706
+ "emptyText",
2707
+ "loading",
2708
+ "empty",
2709
+ "showTable",
2710
+ "masked",
2711
+ "showLegend",
2712
+ "emphasis"
2713
+ ],
2714
+ outputs: ["hiddenSeriesChange", "emphasisChange"]
2715
+ }]
2716
+ });
2717
+ };
2718
+ i0.ɵɵngDeclareClassMetadata({
2719
+ minVersion: "12.0.0",
2720
+ version: "22.2.1",
2721
+ ngImport: i0,
2722
+ type: UiPieChartComponent,
2723
+ decorators: [{
2724
+ type: Component,
2725
+ args: [{
2726
+ selector: "ui-pie-chart",
2727
+ imports: [UiChartFrameComponent],
2728
+ host: { class: "block w-full min-w-0" },
2729
+ template: "<ui-chart-frame\n [options]=\"chartOptions()\"\n [ariaLabel]=\"ariaLabel()\"\n [categories]=\"categories()\"\n [series]=\"series()\"\n [legendItems]=\"legendItems()\"\n [legendNote]=\"legendNote()\"\n [(hiddenSeries)]=\"hiddenSeries\"\n [(emphasis)]=\"emphasis\"\n [showLegend]=\"legend() === 'auto'\"\n [valueFormatter]=\"displayFormatter()\"\n [masked]=\"masked()\"\n [categoryLabel]=\"categoryLabel()\"\n [height]=\"height()\"\n [emptyText]=\"emptyText()\"\n [loading]=\"loading()\"\n [empty]=\"isEmpty()\"\n [showTable]=\"showTable()\"\n/>\n"
2730
+ }]
2731
+ }],
2732
+ propDecorators: {
2733
+ variant: [{
2734
+ type: i0.Input,
2735
+ args: [{
2736
+ isSignal: true,
2737
+ alias: "variant",
2738
+ required: false
2739
+ }]
2740
+ }],
2741
+ totalLabel: [{
2742
+ type: i0.Input,
2743
+ args: [{
2744
+ isSignal: true,
2745
+ alias: "totalLabel",
2746
+ required: false
2747
+ }]
2748
+ }]
2749
+ }
2750
+ });
2751
+ const PieChartVariants = ["pie", "donut"];
2752
+ const SHADE_STEP = .16;
2753
+ const PALEST_SHADE = .4;
2754
+ const HEADER_MIN_WIDTH = 56;
2755
+ const HEADER_MIN_HEIGHT = 56;
2756
+ const NAME_MIN_WIDTH = 48;
2757
+ const NAME_MIN_HEIGHT = 24;
2758
+ const VALUE_MIN_HEIGHT = 42;
2759
+ function treemapGroupColours(groups, dark) {
2760
+ return groups.map((group, index) => group.colour ?? chartColour(index, dark));
2761
+ }
2762
+ function drawnTreemapGroups(groups, colours, hidden, shades, ink) {
2763
+ return groups.map((group, index) => drawnGroup(group, colours[index], shades, ink)).filter((group) => group.blocks.length > 0 && !hidden.includes(group.name));
2764
+ }
2765
+ function drawnGroup(group, colour, shades, ink) {
2766
+ const items = group.items.filter((item) => item.value > 0);
2767
+ const ranks = rankByValue(items.map((item) => item.value));
2768
+ const blocks = items.map((item, index) => {
2769
+ const fill = shades ? shadeOf(colour, ranks[index], ink) : colour;
2770
+ return {
2771
+ group: group.name,
2772
+ item: item.name,
2773
+ value: item.value,
2774
+ fill,
2775
+ labelInk: chartLabelInk(fill)
2776
+ };
2777
+ });
2778
+ return {
2779
+ name: group.name,
2780
+ colour,
2781
+ total: blocks.reduce((sum, block) => sum + block.value, 0),
2782
+ blocks
2783
+ };
2784
+ }
2785
+ function rankByValue(values) {
2786
+ const biggestFirst = values.map((value, index) => ({
2787
+ value,
2788
+ index
2789
+ })).sort((a, b) => b.value - a.value);
2790
+ const ranks = [];
2791
+ biggestFirst.forEach((entry, rank) => {
2792
+ ranks[entry.index] = rank;
2793
+ });
2794
+ return ranks;
2795
+ }
2796
+ function shadeOf(colour, rank, ink) {
2797
+ const strength = Math.max(1 - rank * SHADE_STEP, PALEST_SHADE);
2798
+ return mixChartColours(colour, ink.surface, strength) ?? colour;
2799
+ }
2800
+ function treemapTableRows(groups) {
2801
+ const items = groups.flatMap((group) => group.items.filter((item) => item.value > 0).map((item) => ({
2802
+ name: `${group.name} – ${item.name}`,
2803
+ value: item.value
2804
+ })));
2805
+ return {
2806
+ categories: items.map((item) => item.name),
2807
+ values: items.map((item) => item.value)
2808
+ };
2809
+ }
2810
+ function placeTreemapGroups(groups, bounds) {
2811
+ const groupRects = squarify(groups.map((group) => group.total), bounds, 8);
2812
+ return groups.map((group, index) => placeGroup(group, groupRects[index]));
2813
+ }
2814
+ function placeGroup(group, rect) {
2815
+ const hasHeader = rect.width >= HEADER_MIN_WIDTH && rect.height >= HEADER_MIN_HEIGHT;
2816
+ const headerHeight = hasHeader ? 24 : 0;
2817
+ const blockArea = {
2818
+ x: 0,
2819
+ y: headerHeight,
2820
+ width: rect.width,
2821
+ height: rect.height - headerHeight
2822
+ };
2823
+ const blockRects = squarify(group.blocks.map((block) => block.value), blockArea, 3);
2824
+ return {
2825
+ ...group,
2826
+ rect,
2827
+ hasHeader,
2828
+ placedBlocks: group.blocks.map((block, index) => ({
2829
+ ...block,
2830
+ rect: blockRects[index],
2831
+ label: labelFor(blockRects[index])
2832
+ }))
2833
+ };
2834
+ }
2835
+ function labelFor(rect) {
2836
+ if (rect.width < NAME_MIN_WIDTH || rect.height < NAME_MIN_HEIGHT) return "none";
2837
+ return rect.height < VALUE_MIN_HEIGHT ? "name" : "full";
2838
+ }
2839
+ function squarify(values, bounds, gap = 0) {
2840
+ const total = values.reduce((sum, value) => sum + value, 0);
2841
+ const rects = values.map(() => ({
2842
+ x: bounds.x,
2843
+ y: bounds.y,
2844
+ width: 0,
2845
+ height: 0
2846
+ }));
2847
+ if (total <= 0 || bounds.width <= 0 || bounds.height <= 0) return rects;
2848
+ const outer = grow(bounds, gap / 2);
2849
+ const scale = outer.width * outer.height / total;
2850
+ const biggestFirst = values.map((value, index) => ({
2851
+ index,
2852
+ area: value * scale
2853
+ })).sort((a, b) => b.area - a.area);
2854
+ let remaining = outer;
2855
+ let row = [];
2856
+ for (const entry of biggestFirst) {
2857
+ const side = Math.min(remaining.width, remaining.height);
2858
+ const longer = [...row, entry];
2859
+ if (row.length === 0 || worstAspect(longer, side) <= worstAspect(row, side)) row = longer;
2860
+ else {
2861
+ remaining = placeRow(row, remaining, rects);
2862
+ row = [entry];
2863
+ }
2864
+ }
2865
+ placeRow(row, remaining, rects);
2866
+ return rects.map((rect) => rect.width > 0 ? grow(rect, -gap / 2) : rect);
2867
+ }
2868
+ function worstAspect(row, side) {
2869
+ const sum = row.reduce((total, entry) => total + entry.area, 0);
2870
+ const largest = Math.max(...row.map((entry) => entry.area));
2871
+ const smallest = Math.min(...row.map((entry) => entry.area));
2872
+ return Math.max(side * side * largest / (sum * sum), sum * sum / (side * side * smallest));
2873
+ }
2874
+ function placeRow(row, area, rects) {
2875
+ const sum = row.reduce((total, entry) => total + entry.area, 0);
2876
+ if (area.width >= area.height) {
2877
+ const width = sum / area.height;
2878
+ let y = area.y;
2879
+ for (const entry of row) {
2880
+ const height = entry.area / width;
2881
+ rects[entry.index] = {
2882
+ x: area.x,
2883
+ y,
2884
+ width,
2885
+ height
2886
+ };
2887
+ y += height;
2888
+ }
2889
+ return {
2890
+ x: area.x + width,
2891
+ y: area.y,
2892
+ width: area.width - width,
2893
+ height: area.height
2894
+ };
2895
+ }
2896
+ const height = sum / area.width;
2897
+ let x = area.x;
2898
+ for (const entry of row) {
2899
+ const width = entry.area / height;
2900
+ rects[entry.index] = {
2901
+ x,
2902
+ y: area.y,
2903
+ width,
2904
+ height
2905
+ };
2906
+ x += width;
2907
+ }
2908
+ return {
2909
+ x: area.x,
2910
+ y: area.y + height,
2911
+ width: area.width,
2912
+ height: area.height - height
2913
+ };
2914
+ }
2915
+ function grow(rect, by) {
2916
+ return {
2917
+ x: rect.x - by,
2918
+ y: rect.y - by,
2919
+ width: Math.max(rect.width + by * 2, 0),
2920
+ height: Math.max(rect.height + by * 2, 0)
2921
+ };
2922
+ }
2923
+ const TOOLTIP_OFFSET = 12;
2924
+ var UiTreemapChartComponent = class UiTreemapChartComponent extends UiChartBase {
2925
+ groups = input.required(...ngDevMode ? [{ debugName: "groups" }] : /* istanbul ignore next */ []);
2926
+ height = input(360, ...ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []);
2927
+ shades = input(true, {
2928
+ ...ngDevMode ? { debugName: "shades" } : /* istanbul ignore next */ {},
2929
+ transform: booleanAttribute
2930
+ });
2931
+ selectable = input(false, {
2932
+ ...ngDevMode ? { debugName: "selectable" } : /* istanbul ignore next */ {},
2933
+ transform: booleanAttribute
2934
+ });
2935
+ valueLabel = input("Value", ...ngDevMode ? [{ debugName: "valueLabel" }] : /* istanbul ignore next */ []);
2936
+ itemSelect = output();
2937
+ canvas = viewChild("canvas", ...ngDevMode ? [{ debugName: "canvas" }] : /* istanbul ignore next */ []);
2938
+ size = signal({
2939
+ width: 0,
2940
+ height: 0
2941
+ }, ...ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []);
2942
+ pointed = signal(null, ...ngDevMode ? [{ debugName: "pointed" }] : /* istanbul ignore next */ []);
2943
+ settled = signal(false, ...ngDevMode ? [{ debugName: "settled" }] : /* istanbul ignore next */ []);
2944
+ percentFormatter = new Intl.NumberFormat(this.uiFormat.locale, {
2945
+ style: "percent",
2946
+ maximumFractionDigits: 1
2947
+ });
2948
+ fill = computed(() => this.height() === "fill", ...ngDevMode ? [{ debugName: "fill" }] : /* istanbul ignore next */ []);
2949
+ fixedHeight = computed(() => {
2950
+ const height = this.height();
2951
+ return height === "fill" ? null : height;
2952
+ }, ...ngDevMode ? [{ debugName: "fixedHeight" }] : /* istanbul ignore next */ []);
2953
+ colours = computed(() => treemapGroupColours(this.groups(), this.dark()), ...ngDevMode ? [{ debugName: "colours" }] : /* istanbul ignore next */ []);
2954
+ drawnGroups = computed(() => drawnTreemapGroups(this.groups(), this.colours(), this.hiddenSeries(), this.shades(), this.ink()), ...ngDevMode ? [{ debugName: "drawnGroups" }] : /* istanbul ignore next */ []);
2955
+ placedGroups = computed(() => {
2956
+ const { width, height } = this.size();
2957
+ return placeTreemapGroups(this.drawnGroups(), {
2958
+ x: 0,
2959
+ y: 0,
2960
+ width,
2961
+ height
2962
+ });
2963
+ }, ...ngDevMode ? [{ debugName: "placedGroups" }] : /* istanbul ignore next */ []);
2964
+ total = computed(() => this.drawnGroups().reduce((sum, group) => sum + group.total, 0), ...ngDevMode ? [{ debugName: "total" }] : /* istanbul ignore next */ []);
2965
+ tableRows = computed(() => treemapTableRows(this.groups()), ...ngDevMode ? [{ debugName: "tableRows" }] : /* istanbul ignore next */ []);
2966
+ categories = computed(() => this.tableRows().categories, ...ngDevMode ? [{ debugName: "categories" }] : /* istanbul ignore next */ []);
2967
+ series = computed(() => [{
2968
+ name: this.valueLabel(),
2969
+ data: this.tableRows().values
2970
+ }], ...ngDevMode ? [{ debugName: "series" }] : /* istanbul ignore next */ []);
2971
+ isEmpty = computed(() => this.categories().length === 0, ...ngDevMode ? [{ debugName: "isEmpty" }] : /* istanbul ignore next */ []);
2972
+ legendItems = computed(() => this.groups().map((group, index) => ({
2973
+ group,
2974
+ colour: this.colours()[index]
2975
+ })).filter(({ group }) => group.items.some((item) => item.value > 0)).map(({ group, colour }) => ({
2976
+ name: group.name,
2977
+ colour
2978
+ })), ...ngDevMode ? [{ debugName: "legendItems" }] : /* istanbul ignore next */ []);
2979
+ legendNote = computed(() => "", ...ngDevMode ? [{ debugName: "legendNote" }] : /* istanbul ignore next */ []);
2980
+ emphasised = computed(() => {
2981
+ const emphasis = this.emphasis();
2982
+ return this.drawnGroups().some((group) => group.name === emphasis) ? emphasis : null;
2983
+ }, ...ngDevMode ? [{ debugName: "emphasised" }] : /* istanbul ignore next */ []);
2984
+ tooltipFooter = computed(() => {
2985
+ const pointed = this.pointed();
2986
+ if (!pointed) return "";
2987
+ const { group, block } = pointed;
2988
+ const shareOfTotal = `${this.percent(block.value / this.total())} of total`;
2989
+ return group.blocks.length > 1 ? `${this.percent(block.value / group.total)} of ${group.name} · ${shareOfTotal}` : shareOfTotal;
2990
+ }, ...ngDevMode ? [{ debugName: "tooltipFooter" }] : /* istanbul ignore next */ []);
2991
+ tooltipPosition = computed(() => {
2992
+ const pointed = this.pointed();
2993
+ const { width } = this.size();
2994
+ if (!pointed) return null;
2995
+ const flipped = pointed.x > width / 2;
2996
+ return {
2997
+ left: flipped ? null : pointed.x + TOOLTIP_OFFSET,
2998
+ right: flipped ? width - pointed.x + TOOLTIP_OFFSET : null,
2999
+ top: pointed.y + TOOLTIP_OFFSET
3000
+ };
3001
+ }, ...ngDevMode ? [{ debugName: "tooltipPosition" }] : /* istanbul ignore next */ []);
3002
+ constructor() {
3003
+ super();
3004
+ effect((onCleanup) => {
3005
+ const canvas = this.canvas()?.nativeElement;
3006
+ if (!canvas) return;
3007
+ const observer = new ResizeObserver(([entry]) => {
3008
+ const { width, height } = entry.contentRect;
3009
+ this.size.set({
3010
+ width,
3011
+ height
3012
+ });
3013
+ if (!this.settled()) requestAnimationFrame(() => this.settled.set(true));
3014
+ });
3015
+ observer.observe(canvas);
3016
+ onCleanup(() => observer.disconnect());
3017
+ });
3018
+ }
3019
+ isFaded(group) {
3020
+ const emphasised = this.emphasised();
3021
+ return !!emphasised && group.name !== emphasised;
3022
+ }
3023
+ point(event, group, block) {
3024
+ const canvas = this.canvas()?.nativeElement;
3025
+ if (!canvas || event.pointerType === "touch") return;
3026
+ const bounds = canvas.getBoundingClientRect();
3027
+ this.pointed.set({
3028
+ group,
3029
+ block,
3030
+ x: event.clientX - bounds.left,
3031
+ y: event.clientY - bounds.top
3032
+ });
3033
+ }
3034
+ focus(group, block) {
3035
+ this.pointed.set({
3036
+ group,
3037
+ block,
3038
+ x: group.rect.x + block.rect.x + block.rect.width / 2,
3039
+ y: group.rect.y + block.rect.y + block.rect.height / 2
3040
+ });
3041
+ }
3042
+ select(block) {
3043
+ this.itemSelect.emit({
3044
+ group: block.group,
3045
+ item: block.item
3046
+ });
3047
+ }
3048
+ accessibleName(block) {
3049
+ const name = `${block.item}, ${block.group}`;
3050
+ return this.masked() ? name : `${name}, ${this.formatValue(block.value)}`;
3051
+ }
3052
+ percent(share) {
3053
+ return this.percentFormatter.format(share);
3054
+ }
2597
3055
  static ɵfac = i0.ɵɵngDeclareFactory({
2598
3056
  minVersion: "12.0.0",
2599
3057
  version: "22.2.1",
2600
3058
  ngImport: i0,
2601
- type: UiPieChartComponent,
2602
- deps: null,
3059
+ type: UiTreemapChartComponent,
3060
+ deps: [],
2603
3061
  target: i0.ɵɵFactoryTarget.Component
2604
3062
  });
2605
3063
  static ɵcmp = i0.ɵɵngDeclareComponent({
2606
- minVersion: "17.1.0",
3064
+ minVersion: "17.0.0",
2607
3065
  version: "22.2.1",
2608
- type: UiPieChartComponent,
3066
+ type: UiTreemapChartComponent,
2609
3067
  isStandalone: true,
2610
- selector: "ui-pie-chart",
3068
+ selector: "ui-treemap-chart",
2611
3069
  inputs: {
2612
- variant: {
2613
- classPropertyName: "variant",
2614
- publicName: "variant",
3070
+ groups: {
3071
+ classPropertyName: "groups",
3072
+ publicName: "groups",
3073
+ isSignal: true,
3074
+ isRequired: true,
3075
+ transformFunction: null
3076
+ },
3077
+ height: {
3078
+ classPropertyName: "height",
3079
+ publicName: "height",
2615
3080
  isSignal: true,
2616
3081
  isRequired: false,
2617
3082
  transformFunction: null
2618
3083
  },
2619
- totalLabel: {
2620
- classPropertyName: "totalLabel",
2621
- publicName: "totalLabel",
3084
+ shades: {
3085
+ classPropertyName: "shades",
3086
+ publicName: "shades",
3087
+ isSignal: true,
3088
+ isRequired: false,
3089
+ transformFunction: null
3090
+ },
3091
+ selectable: {
3092
+ classPropertyName: "selectable",
3093
+ publicName: "selectable",
3094
+ isSignal: true,
3095
+ isRequired: false,
3096
+ transformFunction: null
3097
+ },
3098
+ valueLabel: {
3099
+ classPropertyName: "valueLabel",
3100
+ publicName: "valueLabel",
2622
3101
  isSignal: true,
2623
3102
  isRequired: false,
2624
3103
  transformFunction: null
2625
3104
  }
2626
3105
  },
3106
+ outputs: { itemSelect: "itemSelect" },
2627
3107
  host: { classAttribute: "block w-full min-w-0" },
3108
+ viewQueries: [{
3109
+ propertyName: "canvas",
3110
+ first: true,
3111
+ predicate: ["canvas"],
3112
+ descendants: true,
3113
+ isSignal: true
3114
+ }],
2628
3115
  usesInheritance: true,
2629
3116
  ngImport: i0,
2630
- template: "<ui-chart-frame\n [options]=\"chartOptions()\"\n [ariaLabel]=\"ariaLabel()\"\n [categories]=\"categories()\"\n [series]=\"series()\"\n [legendItems]=\"legendItems()\"\n [legendNote]=\"legendNote()\"\n [(hiddenSeries)]=\"hiddenSeries\"\n [(emphasis)]=\"emphasis\"\n [showLegend]=\"legend() === 'auto'\"\n [valueFormatter]=\"displayFormatter()\"\n [masked]=\"masked()\"\n [categoryLabel]=\"categoryLabel()\"\n [height]=\"height()\"\n [emptyText]=\"emptyText()\"\n [loading]=\"loading()\"\n [empty]=\"isEmpty()\"\n [showTable]=\"showTable()\"\n/>\n",
3117
+ template: "<ui-chart-frame\n [options]=\"null\"\n [ariaLabel]=\"ariaLabel()\"\n [categories]=\"categories()\"\n [series]=\"series()\"\n [legendItems]=\"legendItems()\"\n [legendNote]=\"legendNote()\"\n [(hiddenSeries)]=\"hiddenSeries\"\n [(emphasis)]=\"emphasis\"\n [showLegend]=\"legend() === 'auto'\"\n [valueFormatter]=\"displayFormatter()\"\n [masked]=\"masked()\"\n [categoryLabel]=\"categoryLabel()\"\n [height]=\"height()\"\n [emptyText]=\"emptyText()\"\n [loading]=\"loading()\"\n [empty]=\"isEmpty()\"\n [showTable]=\"showTable()\"\n>\n <div\n #canvas\n class=\"ui-treemap\"\n [class.ui-treemap--settled]=\"settled()\"\n [class.grow]=\"fill()\"\n [class.min-h-0]=\"fill()\"\n [style.height.px]=\"fixedHeight()\"\n [attr.role]=\"selectable() ? 'group' : 'img'\"\n [attr.aria-label]=\"ariaLabel()\"\n (pointerleave)=\"pointed.set(null)\"\n >\n @if (concealed()) {\n <!-- the proportions alone would give the amounts away, so one grey block stands in for them all -->\n <div class=\"ui-treemap-concealed\" [style.background-color]=\"ink().grid\"></div>\n } @else {\n @for (group of placedGroups(); track group.name) {\n <div\n class=\"ui-treemap-group\"\n [class.ui-treemap-group--faded]=\"isFaded(group)\"\n [style.left.px]=\"group.rect.x\"\n [style.top.px]=\"group.rect.y\"\n [style.width.px]=\"group.rect.width\"\n [style.height.px]=\"group.rect.height\"\n >\n @if (group.hasHeader) {\n <div class=\"ui-treemap-header ui-text-caption\" aria-hidden=\"true\">\n <span class=\"ui-treemap-header-name\">{{ group.name }}</span>\n <span class=\"ui-treemap-header-total\">{{ formatValue(group.total) }}</span>\n </div>\n }\n\n @for (block of group.placedBlocks; track block.item) {\n @if (selectable()) {\n <button\n type=\"button\"\n class=\"ui-treemap-block ui-treemap-block--selectable ui-text-caption\"\n [style.left.px]=\"block.rect.x\"\n [style.top.px]=\"block.rect.y\"\n [style.width.px]=\"block.rect.width\"\n [style.height.px]=\"block.rect.height\"\n [style.background-color]=\"block.fill\"\n [style.color]=\"block.labelInk\"\n [attr.aria-label]=\"accessibleName(block)\"\n (pointermove)=\"point($event, group, block)\"\n (focus)=\"focus(group, block)\"\n (blur)=\"pointed.set(null)\"\n (click)=\"select(block)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"label\"\n [ngTemplateOutletContext]=\"{ $implicit: block }\"\n />\n </button>\n } @else {\n <div\n class=\"ui-treemap-block ui-text-caption\"\n aria-hidden=\"true\"\n [style.left.px]=\"block.rect.x\"\n [style.top.px]=\"block.rect.y\"\n [style.width.px]=\"block.rect.width\"\n [style.height.px]=\"block.rect.height\"\n [style.background-color]=\"block.fill\"\n [style.color]=\"block.labelInk\"\n (pointermove)=\"point($event, group, block)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"label\"\n [ngTemplateOutletContext]=\"{ $implicit: block }\"\n />\n </div>\n }\n }\n </div>\n }\n\n @if (pointed(); as pointed) {\n <div\n class=\"ui-chart-tooltip-panel ui-treemap-tooltip\"\n aria-hidden=\"true\"\n [style.left.px]=\"tooltipPosition()?.left\"\n [style.right.px]=\"tooltipPosition()?.right\"\n [style.top.px]=\"tooltipPosition()?.top\"\n >\n <div class=\"ui-chart-tooltip\">\n <div class=\"ui-chart-tooltip-title ui-text-caption\">{{ pointed.group.name }}</div>\n <div class=\"ui-chart-tooltip-row ui-text-body-alt\">\n <span\n class=\"ui-chart-tooltip-dot\"\n [style.--ui-chart-tooltip-colour]=\"pointed.block.fill\"\n ></span>\n <span class=\"ui-chart-tooltip-name\">{{ pointed.block.item }}</span>\n @if (!masked()) {\n <span class=\"ui-chart-tooltip-value\">{{ formatValue(pointed.block.value) }}</span>\n }\n </div>\n <div class=\"ui-chart-tooltip-footer ui-text-caption\">{{ tooltipFooter() }}</div>\n </div>\n </div>\n }\n }\n </div>\n</ui-chart-frame>\n\n<ng-template #label let-block>\n @if (block.label !== 'none') {\n <span class=\"ui-treemap-block-name\">{{ block.item }}</span>\n }\n @if (block.label === 'full') {\n <span class=\"ui-treemap-block-value\">{{ formatValue(block.value) }}</span>\n }\n</ng-template>\n",
3118
+ styles: ["@layer properties;.ui-treemap{position:relative;display:block;width:100%}.ui-treemap-concealed{position:absolute;inset:0;border-radius:var(--radius-md, .375rem)}.ui-treemap-group,.ui-treemap-block{position:absolute}@media(prefers-reduced-motion:no-preference){.ui-treemap--settled .ui-treemap-group,.ui-treemap--settled .ui-treemap-block{transition-property:left,top,width,height,opacity;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .3s;transition-duration:.3s;--tw-ease: var(--ease-out, cubic-bezier(0, 0, .2, 1));transition-timing-function:var(--ease-out, cubic-bezier(0, 0, .2, 1))}}.ui-treemap-group--faded{opacity:.15}.ui-treemap-header{display:flex;height:calc(var(--spacing, .25rem) * 6);align-items:baseline;column-gap:calc(var(--spacing, .25rem) * 2);padding-inline:calc(var(--spacing, .25rem) * .5)}.ui-treemap-header-name{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--foreground)}.ui-treemap-header-total{margin-inline-start:auto;flex-shrink:0;color:var(--muted-foreground-1);--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.ui-treemap-header-name,.ui-treemap-header-total{--tw-leading: calc(var(--spacing, .25rem) * 6);line-height:calc(var(--spacing, .25rem) * 6)}.ui-treemap-block{display:flex;flex-direction:column;align-items:flex-start;overflow:hidden;border-radius:var(--radius-md, .375rem);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 1.5);text-align:start}.ui-treemap-block--selectable{cursor:pointer}.ui-treemap-block--selectable:focus{--tw-outline-style: none;outline-style:none}.ui-treemap-block--selectable:focus-visible{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ui-treemap-block--selectable:focus-visible{--tw-ring-color: color-mix(in srgb, oklch(88.2% .059 254.128) 50%, transparent)}@supports (color: color-mix(in lab,red,red)){.ui-treemap-block--selectable:focus-visible{--tw-ring-color: color-mix(in oklab, var(--color-primary-200, var(--color-blue-200)) 50%, transparent)}}.ui-treemap-block--selectable:focus-visible{--tw-ring-offset-width: 1px;--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.ui-treemap-block:hover{filter:brightness(1.06)}.ui-treemap-block-name{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}.ui-treemap-block-value{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);opacity:85%}.ui-treemap-tooltip{pointer-events:none;position:absolute;z-index:10}@property --tw-duration{syntax: \"*\"; inherits: false;}@property --tw-ease{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-duration: initial;--tw-ease: initial;--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial;--tw-leading: initial;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n", "@layer properties;.ui-chart .apexcharts-tooltip.apexcharts-theme-light,.ui-chart-tooltip-panel{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--border-line-2);background-color:var(--layer);--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ui-chart-tooltip{display:flex;min-width:calc(var(--spacing, .25rem) * 36);flex-direction:column;row-gap:var(--spacing, .25rem);padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2)}.ui-chart-tooltip-title{padding-bottom:var(--spacing, .25rem);color:var(--muted-foreground-1)}.ui-chart-tooltip-row{display:flex;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2);color:var(--foreground)}.ui-chart-tooltip-total{margin-top:var(--spacing, .25rem);border-top-style:var(--tw-border-style);border-top-width:1px;border-color:var(--border-line-2);padding-top:calc(var(--spacing, .25rem) * 2)}.ui-chart-tooltip-footer{padding-top:var(--spacing, .25rem);color:var(--muted-foreground-1)}.ui-chart-tooltip-dot{width:calc(var(--spacing, .25rem) * 2);height:calc(var(--spacing, .25rem) * 2);flex-shrink:0;border-radius:var(--radius-full, calc(infinity * 1px));background-color:var(--ui-chart-tooltip-colour)}.ui-chart-tooltip-dot--dashed{height:0px;width:calc(var(--spacing, .25rem) * 3);border-radius:0;border-top-style:var(--tw-border-style);border-top-width:2px;--tw-border-style: dashed;border-style:dashed;background-color:transparent;border-color:var(--ui-chart-tooltip-colour)}.ui-chart-tooltip-value{margin-inline-start:auto;padding-inline-start:calc(var(--spacing, .25rem) * 3);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
2631
3119
  dependencies: [{
3120
+ kind: "directive",
3121
+ type: NgTemplateOutlet,
3122
+ selector: "[ngTemplateOutlet]",
3123
+ inputs: [
3124
+ "ngTemplateOutletContext",
3125
+ "ngTemplateOutlet",
3126
+ "ngTemplateOutletInjector"
3127
+ ]
3128
+ }, {
2632
3129
  kind: "component",
2633
3130
  type: UiChartFrameComponent,
2634
3131
  selector: "ui-chart-frame",
@@ -2652,43 +3149,78 @@ var UiPieChartComponent = class UiPieChartComponent extends UiAxisChartBase {
2652
3149
  "emphasis"
2653
3150
  ],
2654
3151
  outputs: ["hiddenSeriesChange", "emphasisChange"]
2655
- }]
3152
+ }],
3153
+ encapsulation: i0.ViewEncapsulation.None
2656
3154
  });
2657
3155
  };
2658
3156
  i0.ɵɵngDeclareClassMetadata({
2659
3157
  minVersion: "12.0.0",
2660
3158
  version: "22.2.1",
2661
3159
  ngImport: i0,
2662
- type: UiPieChartComponent,
3160
+ type: UiTreemapChartComponent,
2663
3161
  decorators: [{
2664
3162
  type: Component,
2665
3163
  args: [{
2666
- selector: "ui-pie-chart",
2667
- imports: [UiChartFrameComponent],
3164
+ selector: "ui-treemap-chart",
3165
+ encapsulation: ViewEncapsulation.None,
3166
+ imports: [NgTemplateOutlet, UiChartFrameComponent],
2668
3167
  host: { class: "block w-full min-w-0" },
2669
- template: "<ui-chart-frame\n [options]=\"chartOptions()\"\n [ariaLabel]=\"ariaLabel()\"\n [categories]=\"categories()\"\n [series]=\"series()\"\n [legendItems]=\"legendItems()\"\n [legendNote]=\"legendNote()\"\n [(hiddenSeries)]=\"hiddenSeries\"\n [(emphasis)]=\"emphasis\"\n [showLegend]=\"legend() === 'auto'\"\n [valueFormatter]=\"displayFormatter()\"\n [masked]=\"masked()\"\n [categoryLabel]=\"categoryLabel()\"\n [height]=\"height()\"\n [emptyText]=\"emptyText()\"\n [loading]=\"loading()\"\n [empty]=\"isEmpty()\"\n [showTable]=\"showTable()\"\n/>\n"
3168
+ template: "<ui-chart-frame\n [options]=\"null\"\n [ariaLabel]=\"ariaLabel()\"\n [categories]=\"categories()\"\n [series]=\"series()\"\n [legendItems]=\"legendItems()\"\n [legendNote]=\"legendNote()\"\n [(hiddenSeries)]=\"hiddenSeries\"\n [(emphasis)]=\"emphasis\"\n [showLegend]=\"legend() === 'auto'\"\n [valueFormatter]=\"displayFormatter()\"\n [masked]=\"masked()\"\n [categoryLabel]=\"categoryLabel()\"\n [height]=\"height()\"\n [emptyText]=\"emptyText()\"\n [loading]=\"loading()\"\n [empty]=\"isEmpty()\"\n [showTable]=\"showTable()\"\n>\n <div\n #canvas\n class=\"ui-treemap\"\n [class.ui-treemap--settled]=\"settled()\"\n [class.grow]=\"fill()\"\n [class.min-h-0]=\"fill()\"\n [style.height.px]=\"fixedHeight()\"\n [attr.role]=\"selectable() ? 'group' : 'img'\"\n [attr.aria-label]=\"ariaLabel()\"\n (pointerleave)=\"pointed.set(null)\"\n >\n @if (concealed()) {\n <!-- the proportions alone would give the amounts away, so one grey block stands in for them all -->\n <div class=\"ui-treemap-concealed\" [style.background-color]=\"ink().grid\"></div>\n } @else {\n @for (group of placedGroups(); track group.name) {\n <div\n class=\"ui-treemap-group\"\n [class.ui-treemap-group--faded]=\"isFaded(group)\"\n [style.left.px]=\"group.rect.x\"\n [style.top.px]=\"group.rect.y\"\n [style.width.px]=\"group.rect.width\"\n [style.height.px]=\"group.rect.height\"\n >\n @if (group.hasHeader) {\n <div class=\"ui-treemap-header ui-text-caption\" aria-hidden=\"true\">\n <span class=\"ui-treemap-header-name\">{{ group.name }}</span>\n <span class=\"ui-treemap-header-total\">{{ formatValue(group.total) }}</span>\n </div>\n }\n\n @for (block of group.placedBlocks; track block.item) {\n @if (selectable()) {\n <button\n type=\"button\"\n class=\"ui-treemap-block ui-treemap-block--selectable ui-text-caption\"\n [style.left.px]=\"block.rect.x\"\n [style.top.px]=\"block.rect.y\"\n [style.width.px]=\"block.rect.width\"\n [style.height.px]=\"block.rect.height\"\n [style.background-color]=\"block.fill\"\n [style.color]=\"block.labelInk\"\n [attr.aria-label]=\"accessibleName(block)\"\n (pointermove)=\"point($event, group, block)\"\n (focus)=\"focus(group, block)\"\n (blur)=\"pointed.set(null)\"\n (click)=\"select(block)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"label\"\n [ngTemplateOutletContext]=\"{ $implicit: block }\"\n />\n </button>\n } @else {\n <div\n class=\"ui-treemap-block ui-text-caption\"\n aria-hidden=\"true\"\n [style.left.px]=\"block.rect.x\"\n [style.top.px]=\"block.rect.y\"\n [style.width.px]=\"block.rect.width\"\n [style.height.px]=\"block.rect.height\"\n [style.background-color]=\"block.fill\"\n [style.color]=\"block.labelInk\"\n (pointermove)=\"point($event, group, block)\"\n >\n <ng-container\n [ngTemplateOutlet]=\"label\"\n [ngTemplateOutletContext]=\"{ $implicit: block }\"\n />\n </div>\n }\n }\n </div>\n }\n\n @if (pointed(); as pointed) {\n <div\n class=\"ui-chart-tooltip-panel ui-treemap-tooltip\"\n aria-hidden=\"true\"\n [style.left.px]=\"tooltipPosition()?.left\"\n [style.right.px]=\"tooltipPosition()?.right\"\n [style.top.px]=\"tooltipPosition()?.top\"\n >\n <div class=\"ui-chart-tooltip\">\n <div class=\"ui-chart-tooltip-title ui-text-caption\">{{ pointed.group.name }}</div>\n <div class=\"ui-chart-tooltip-row ui-text-body-alt\">\n <span\n class=\"ui-chart-tooltip-dot\"\n [style.--ui-chart-tooltip-colour]=\"pointed.block.fill\"\n ></span>\n <span class=\"ui-chart-tooltip-name\">{{ pointed.block.item }}</span>\n @if (!masked()) {\n <span class=\"ui-chart-tooltip-value\">{{ formatValue(pointed.block.value) }}</span>\n }\n </div>\n <div class=\"ui-chart-tooltip-footer ui-text-caption\">{{ tooltipFooter() }}</div>\n </div>\n </div>\n }\n }\n </div>\n</ui-chart-frame>\n\n<ng-template #label let-block>\n @if (block.label !== 'none') {\n <span class=\"ui-treemap-block-name\">{{ block.item }}</span>\n }\n @if (block.label === 'full') {\n <span class=\"ui-treemap-block-value\">{{ formatValue(block.value) }}</span>\n }\n</ng-template>\n",
3169
+ styles: ["@layer properties;.ui-treemap{position:relative;display:block;width:100%}.ui-treemap-concealed{position:absolute;inset:0;border-radius:var(--radius-md, .375rem)}.ui-treemap-group,.ui-treemap-block{position:absolute}@media(prefers-reduced-motion:no-preference){.ui-treemap--settled .ui-treemap-group,.ui-treemap--settled .ui-treemap-block{transition-property:left,top,width,height,opacity;transition-timing-function:var(--tw-ease, var(--default-transition-timing-function, cubic-bezier(.4, 0, .2, 1)));transition-duration:var(--tw-duration, var(--default-transition-duration, .15s));--tw-duration: .3s;transition-duration:.3s;--tw-ease: var(--ease-out, cubic-bezier(0, 0, .2, 1));transition-timing-function:var(--ease-out, cubic-bezier(0, 0, .2, 1))}}.ui-treemap-group--faded{opacity:.15}.ui-treemap-header{display:flex;height:calc(var(--spacing, .25rem) * 6);align-items:baseline;column-gap:calc(var(--spacing, .25rem) * 2);padding-inline:calc(var(--spacing, .25rem) * .5)}.ui-treemap-header-name{min-width:0px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--foreground)}.ui-treemap-header-total{margin-inline-start:auto;flex-shrink:0;color:var(--muted-foreground-1);--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.ui-treemap-header-name,.ui-treemap-header-total{--tw-leading: calc(var(--spacing, .25rem) * 6);line-height:calc(var(--spacing, .25rem) * 6)}.ui-treemap-block{display:flex;flex-direction:column;align-items:flex-start;overflow:hidden;border-radius:var(--radius-md, .375rem);padding-inline:calc(var(--spacing, .25rem) * 2);padding-block:calc(var(--spacing, .25rem) * 1.5);text-align:start}.ui-treemap-block--selectable{cursor:pointer}.ui-treemap-block--selectable:focus{--tw-outline-style: none;outline-style:none}.ui-treemap-block--selectable:focus-visible{--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ui-treemap-block--selectable:focus-visible{--tw-ring-color: color-mix(in srgb, oklch(88.2% .059 254.128) 50%, transparent)}@supports (color: color-mix(in lab,red,red)){.ui-treemap-block--selectable:focus-visible{--tw-ring-color: color-mix(in oklab, var(--color-primary-200, var(--color-blue-200)) 50%, transparent)}}.ui-treemap-block--selectable:focus-visible{--tw-ring-offset-width: 1px;--tw-ring-offset-shadow: var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.ui-treemap-block:hover{filter:brightness(1.06)}.ui-treemap-block-name{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500)}.ui-treemap-block-value{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);opacity:85%}.ui-treemap-tooltip{pointer-events:none;position:absolute;z-index:10}@property --tw-duration{syntax: \"*\"; inherits: false;}@property --tw-ease{syntax: \"*\"; inherits: false;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@property --tw-leading{syntax: \"*\"; inherits: false;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-duration: initial;--tw-ease: initial;--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial;--tw-leading: initial;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n", "@layer properties;.ui-chart .apexcharts-tooltip.apexcharts-theme-light,.ui-chart-tooltip-panel{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--border-line-2);background-color:var(--layer);--tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / .1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / .1));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ui-chart-tooltip{display:flex;min-width:calc(var(--spacing, .25rem) * 36);flex-direction:column;row-gap:var(--spacing, .25rem);padding-inline:calc(var(--spacing, .25rem) * 3);padding-block:calc(var(--spacing, .25rem) * 2)}.ui-chart-tooltip-title{padding-bottom:var(--spacing, .25rem);color:var(--muted-foreground-1)}.ui-chart-tooltip-row{display:flex;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2);color:var(--foreground)}.ui-chart-tooltip-total{margin-top:var(--spacing, .25rem);border-top-style:var(--tw-border-style);border-top-width:1px;border-color:var(--border-line-2);padding-top:calc(var(--spacing, .25rem) * 2)}.ui-chart-tooltip-footer{padding-top:var(--spacing, .25rem);color:var(--muted-foreground-1)}.ui-chart-tooltip-dot{width:calc(var(--spacing, .25rem) * 2);height:calc(var(--spacing, .25rem) * 2);flex-shrink:0;border-radius:var(--radius-full, calc(infinity * 1px));background-color:var(--ui-chart-tooltip-colour)}.ui-chart-tooltip-dot--dashed{height:0px;width:calc(var(--spacing, .25rem) * 3);border-radius:0;border-top-style:var(--tw-border-style);border-top-width:2px;--tw-border-style: dashed;border-style:dashed;background-color:transparent;border-color:var(--ui-chart-tooltip-colour)}.ui-chart-tooltip-value{margin-inline-start:auto;padding-inline-start:calc(var(--spacing, .25rem) * 3);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-inset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-shadow-color{syntax: \"*\"; inherits: false;}@property --tw-inset-shadow-alpha{syntax: \"<percentage>\"; inherits: false; initial-value: 100%;}@property --tw-ring-color{syntax: \"*\"; inherits: false;}@property --tw-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-inset-ring-color{syntax: \"*\"; inherits: false;}@property --tw-inset-ring-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-ring-inset{syntax: \"*\"; inherits: false;}@property --tw-ring-offset-width{syntax: \"<length>\"; inherits: false; initial-value: 0px;}@property --tw-ring-offset-color{syntax: \"*\"; inherits: false; initial-value: #fff;}@property --tw-ring-offset-shadow{syntax: \"*\"; inherits: false; initial-value: 0 0 #0000;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@property --tw-ordinal{syntax: \"*\"; inherits: false;}@property --tw-slashed-zero{syntax: \"*\"; inherits: false;}@property --tw-numeric-figure{syntax: \"*\"; inherits: false;}@property --tw-numeric-spacing{syntax: \"*\"; inherits: false;}@property --tw-numeric-fraction{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-shadow: 0 0 #0000;--tw-shadow-color: initial;--tw-shadow-alpha: 100%;--tw-inset-shadow: 0 0 #0000;--tw-inset-shadow-color: initial;--tw-inset-shadow-alpha: 100%;--tw-ring-color: initial;--tw-ring-shadow: 0 0 #0000;--tw-inset-ring-color: initial;--tw-inset-ring-shadow: 0 0 #0000;--tw-ring-inset: initial;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-offset-shadow: 0 0 #0000;--tw-font-weight: initial;--tw-ordinal: initial;--tw-slashed-zero: initial;--tw-numeric-figure: initial;--tw-numeric-spacing: initial;--tw-numeric-fraction: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
2670
3170
  }]
2671
3171
  }],
3172
+ ctorParameters: () => [],
2672
3173
  propDecorators: {
2673
- variant: [{
3174
+ groups: [{
2674
3175
  type: i0.Input,
2675
3176
  args: [{
2676
3177
  isSignal: true,
2677
- alias: "variant",
3178
+ alias: "groups",
3179
+ required: true
3180
+ }]
3181
+ }],
3182
+ height: [{
3183
+ type: i0.Input,
3184
+ args: [{
3185
+ isSignal: true,
3186
+ alias: "height",
2678
3187
  required: false
2679
3188
  }]
2680
3189
  }],
2681
- totalLabel: [{
3190
+ shades: [{
2682
3191
  type: i0.Input,
2683
3192
  args: [{
2684
3193
  isSignal: true,
2685
- alias: "totalLabel",
3194
+ alias: "shades",
3195
+ required: false
3196
+ }]
3197
+ }],
3198
+ selectable: [{
3199
+ type: i0.Input,
3200
+ args: [{
3201
+ isSignal: true,
3202
+ alias: "selectable",
3203
+ required: false
3204
+ }]
3205
+ }],
3206
+ valueLabel: [{
3207
+ type: i0.Input,
3208
+ args: [{
3209
+ isSignal: true,
3210
+ alias: "valueLabel",
2686
3211
  required: false
2687
3212
  }]
3213
+ }],
3214
+ itemSelect: [{
3215
+ type: i0.Output,
3216
+ args: ["itemSelect"]
3217
+ }],
3218
+ canvas: [{
3219
+ type: i0.ViewChild,
3220
+ args: ["canvas", { isSignal: true }]
2688
3221
  }]
2689
3222
  }
2690
3223
  });
2691
- const PieChartVariants = ["pie", "donut"];
2692
3224
  var UiCheckboxComponent = class UiCheckboxComponent {
2693
3225
  value = model.required(...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
2694
3226
  id = input("", ...ngDevMode ? [{ debugName: "id" }] : /* istanbul ignore next */ []);
@@ -13953,9 +14485,10 @@ var UiTableFiltersComponent = class UiTableFiltersComponent {
13953
14485
  value = model({}, ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
13954
14486
  collapseBelow = input("lg", ...ngDevMode ? [{ debugName: "collapseBelow" }] : /* istanbul ignore next */ []);
13955
14487
  idPrefix = `ui-table-filters-${nextId++}`;
13956
- anyDate = "any";
13957
- customDate = "custom";
13958
- customDates = signal(/* @__PURE__ */ new Set(), ...ngDevMode ? [{ debugName: "customDates" }] : /* istanbul ignore next */ []);
14488
+ anyRange = "any";
14489
+ customRange = "custom";
14490
+ customRanges = signal(/* @__PURE__ */ new Set(), ...ngDevMode ? [{ debugName: "customRanges" }] : /* istanbul ignore next */ []);
14491
+ amountDrafts = signal({}, ...ngDevMode ? [{ debugName: "amountDrafts" }] : /* istanbul ignore next */ []);
13959
14492
  expanded = signal(/* @__PURE__ */ new Set(), ...ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []);
13960
14493
  linked = computed(() => {
13961
14494
  const id = this.table();
@@ -14038,7 +14571,7 @@ var UiTableFiltersComponent = class UiTableFiltersComponent {
14038
14571
  };
14039
14572
  }
14040
14573
  dateMode(facet) {
14041
- if (this.customDates().has(facet.id)) return "custom";
14574
+ if (this.customRanges().has(facet.id)) return "custom";
14042
14575
  const applied = this.range(facet);
14043
14576
  if (!applied.start) return "any";
14044
14577
  const index = (facet.presets ?? []).findIndex((preset) => {
@@ -14055,18 +14588,61 @@ var UiTableFiltersComponent = class UiTableFiltersComponent {
14055
14588
  setRange(facet, range) {
14056
14589
  this.apply(facet.id, range.start ? range : void 0);
14057
14590
  }
14591
+ amountRange(facet) {
14592
+ return this.value()[facet.id];
14593
+ }
14594
+ amountMode(facet) {
14595
+ if (this.customRanges().has(facet.id)) return "custom";
14596
+ const applied = this.amountRange(facet);
14597
+ if (!applied) return "any";
14598
+ const index = (facet.presets ?? []).findIndex((preset) => isSameAmountRange(preset.range, applied));
14599
+ return index === -1 ? "custom" : index;
14600
+ }
14601
+ pickAmount(facet, mode) {
14602
+ this.setCustom(facet.id, mode === "custom");
14603
+ this.forgetAmountDraft(facet.id);
14604
+ if (mode === "any") this.apply(facet.id, void 0);
14605
+ else if (mode !== "custom") this.apply(facet.id, facet.presets?.[mode]?.range);
14606
+ }
14607
+ amountText(facet, end) {
14608
+ const draft = this.amountDrafts()[facet.id];
14609
+ const applied = this.amountRange(facet);
14610
+ if (draft && isSameAmountRange(amountRangeFrom(draft), applied)) return draft[end];
14611
+ return applied?.[end]?.toString() ?? "";
14612
+ }
14613
+ typeAmount(facet, end, text) {
14614
+ const draft = {
14615
+ min: this.amountText(facet, "min"),
14616
+ max: this.amountText(facet, "max"),
14617
+ [end]: text
14618
+ };
14619
+ this.amountDrafts.update((drafts) => ({
14620
+ ...drafts,
14621
+ [facet.id]: draft
14622
+ }));
14623
+ this.apply(facet.id, amountRangeFrom(draft));
14624
+ }
14625
+ isAmountValid(facet, end) {
14626
+ const draft = this.amountDrafts()[facet.id];
14627
+ if (!draft) return true;
14628
+ return isReadableAmount(draft[end]) && !isBackwards(draft);
14629
+ }
14058
14630
  clearAll() {
14059
- this.customDates.set(/* @__PURE__ */ new Set());
14631
+ this.customRanges.set(/* @__PURE__ */ new Set());
14632
+ this.amountDrafts.set({});
14060
14633
  this.write(this.withoutOwn(this.currentFilters()));
14061
14634
  }
14062
14635
  setCustom(id, custom) {
14063
- this.customDates.update((ids) => {
14636
+ this.customRanges.update((ids) => {
14064
14637
  const next = new Set(ids);
14065
14638
  if (custom) next.add(id);
14066
14639
  else next.delete(id);
14067
14640
  return next;
14068
14641
  });
14069
14642
  }
14643
+ forgetAmountDraft(id) {
14644
+ this.amountDrafts.update((drafts) => Object.fromEntries(Object.entries(drafts).filter(([draftId]) => draftId !== id)));
14645
+ }
14070
14646
  isPastCutoff(facet, index) {
14071
14647
  return facet.visibleOptions !== void 0 && index >= facet.visibleOptions;
14072
14648
  }
@@ -14144,8 +14720,8 @@ var UiTableFiltersComponent = class UiTableFiltersComponent {
14144
14720
  outputs: { value: "valueChange" },
14145
14721
  host: { classAttribute: "block" },
14146
14722
  ngImport: i0,
14147
- template: "@if (wide()) {\n <div class=\"ui-table-filters-panel ui-table-filters-panel--card\">\n <ng-container *ngTemplateOutlet=\"body; context: { $implicit: true }\" />\n </div>\n} @else {\n <ui-button\n appearance=\"white\"\n intent=\"secondary\"\n size=\"sm\"\n classes=\"gap-x-2 h-9.5 py-0!\"\n (click)=\"drawer.isOpen.set(true)\"\n >\n Filters\n @if (appliedCount()) {\n <ui-badge appearance=\"soft\" size=\"xs\" class=\"ui-text-caption\">{{\n appliedCount()\n }}</ui-badge>\n }\n </ui-button>\n\n <ui-drawer #drawer label=\"Filters\">\n <button\n drawer-actions\n type=\"button\"\n class=\"ui-table-filters-clear ui-text-body-alt\"\n [class.invisible]=\"!anyApplied()\"\n (click)=\"clearAll()\"\n >\n Clear all\n </button>\n\n <div class=\"ui-table-filters-panel\">\n <ng-container\n *ngTemplateOutlet=\"body; context: { $implicit: false }\"\n />\n </div>\n </ui-drawer>\n}\n\n<ng-template #body let-showHeader>\n @if (showHeader) {\n <div class=\"ui-table-filters-header\">\n <span class=\"ui-table-filters-title ui-text-body\">\n Filters\n </span>\n\n <button\n type=\"button\"\n class=\"ui-table-filters-clear ui-text-body-alt\"\n [class.invisible]=\"!anyApplied()\"\n (click)=\"clearAll()\"\n >\n Clear all\n </button>\n </div>\n }\n\n @for (facet of facets(); track facet.id) {\n <fieldset class=\"ui-table-filters-facet\">\n <legend class=\"ui-table-filters-legend ui-text-body-alt\">\n {{ facet.label }}\n </legend>\n\n <div\n class=\"ui-table-filters-choices\"\n [id]=\"groupName(facet) + '-options'\"\n >\n @switch (facet.kind) {\n @case ('options') {\n @if (facet.multiple) {\n @for (option of facet.options; track option.value; let index = $index) {\n @if (isShown(facet, option, index)) {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, index)\"\n >\n <ui-checkbox\n [id]=\"choiceId(facet, index)\"\n [value]=\"isChecked(facet, option)\"\n (valueChange)=\"check(facet, option, $event)\"\n />\n <span class=\"truncate\">{{\n option.label\n }}</span>\n </label>\n }\n }\n } @else {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'any')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'any')\"\n [value]=\"picked(facet)\"\n (valueChange)=\"pick(facet, $event)\"\n [option]=\"null\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Any</span>\n </label>\n\n @for (option of facet.options; track option.value; let index = $index) {\n @if (isShown(facet, option, index)) {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, index)\"\n >\n <ui-radio\n [id]=\"choiceId(facet, index)\"\n [value]=\"picked(facet)\"\n (valueChange)=\"pick(facet, $event)\"\n [option]=\"option.value\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">{{\n option.label\n }}</span>\n </label>\n }\n }\n }\n }\n @case ('dateRange') {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'any')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'any')\"\n [value]=\"dateMode(facet)\"\n (valueChange)=\"pickDate(facet, $event)\"\n [option]=\"anyDate\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Any time</span>\n </label>\n\n @for (preset of facet.presets ?? []; track preset.label; let index = $index) {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, index)\"\n >\n <ui-radio\n [id]=\"choiceId(facet, index)\"\n [value]=\"dateMode(facet)\"\n (valueChange)=\"pickDate(facet, $event)\"\n [option]=\"index\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">{{ preset.label }}</span>\n </label>\n }\n\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'custom')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'custom')\"\n [value]=\"dateMode(facet)\"\n (valueChange)=\"pickDate(facet, $event)\"\n [option]=\"customDate\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Custom range</span>\n </label>\n\n @if (dateMode(facet) === 'custom') {\n <label\n class=\"sr-only\"\n [for]=\"groupName(facet) + '-range'\"\n >{{ facet.label }} range</label>\n <ui-date-range-picker\n class=\"ui-table-filters-range\"\n [id]=\"groupName(facet) + '-range'\"\n [value]=\"range(facet)\"\n (valueChange)=\"setRange(facet, $event)\"\n [placeholder]=\"facet.placeholder ?? 'Select dates'\"\n [min]=\"facet.min ?? null\"\n [max]=\"facet.max ?? null\"\n />\n }\n }\n }\n </div>\n\n @if (facet.kind === 'options' && hiddenCount(facet)) {\n <button\n type=\"button\"\n class=\"ui-table-filters-more ui-text-body-alt\"\n [attr.aria-expanded]=\"isExpanded(facet)\"\n [attr.aria-controls]=\"groupName(facet) + '-options'\"\n (click)=\"toggleExpanded(facet)\"\n >\n @if (isExpanded(facet)) {\n Show fewer\n } @else {\n Show {{ hiddenCount(facet) }} more\n }\n </button>\n }\n </fieldset>\n }\n</ng-template>\n",
14148
- styles: ["@layer properties;.ui-table-filters-panel{display:flex;flex-direction:column;row-gap:calc(var(--spacing, .25rem) * 6)}.ui-table-filters-panel--card{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--card-line);background-color:var(--card);padding:calc(var(--spacing, .25rem) * 5)}.ui-table-filters-header{display:flex;align-items:center;justify-content:space-between;column-gap:calc(var(--spacing, .25rem) * 3)}.ui-table-filters-title{display:flex;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--foreground)}.ui-table-filters-clear{cursor:pointer;color:var(--muted-foreground-1)}.ui-table-filters-clear:hover{color:var(--foreground)}.ui-table-filters-clear:focus-visible{text-decoration-line:underline}.ui-table-filters-clear:focus-visible{--tw-outline-style: none;outline-style:none}.ui-table-filters-facet{margin:0;min-width:0px;border-style:var(--tw-border-style);border-width:0px;padding:0}.ui-table-filters-legend{margin-bottom:calc(var(--spacing, .25rem) * 3);padding:0;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--foreground)}.ui-table-filters-choices{display:flex;flex-direction:column;row-gap:calc(var(--spacing, .25rem) * 2.5)}.ui-table-filters-choice{display:flex;min-width:0px;cursor:pointer;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2.5);color:var(--muted-foreground-2)}.ui-table-filters-choice:hover{color:var(--foreground)}.ui-table-filters-range{margin-top:calc(var(--spacing, .25rem) * .5)}.ui-table-filters-more{margin-top:calc(var(--spacing, .25rem) * 2.5);cursor:pointer;color:var(--color-primary-500, var(--color-blue-500))}.ui-table-filters-more:hover{color:var(--color-primary-600, var(--color-blue-600))}.ui-table-filters-more:hover{text-decoration-line:underline}.ui-table-filters-more:focus-visible{color:var(--color-primary-600, var(--color-blue-600))}.ui-table-filters-more:focus-visible{text-decoration-line:underline}.ui-table-filters-more:focus-visible{--tw-outline-style: none;outline-style:none}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
14723
+ template: "@if (wide()) {\n <div class=\"ui-table-filters-panel ui-table-filters-panel--card\">\n <ng-container *ngTemplateOutlet=\"body; context: { $implicit: true }\" />\n </div>\n} @else {\n <ui-button\n appearance=\"white\"\n intent=\"secondary\"\n size=\"sm\"\n classes=\"gap-x-2 h-9.5 py-0!\"\n (click)=\"drawer.isOpen.set(true)\"\n >\n Filters\n @if (appliedCount()) {\n <ui-badge appearance=\"soft\" size=\"xs\" class=\"ui-text-caption\">{{\n appliedCount()\n }}</ui-badge>\n }\n </ui-button>\n\n <ui-drawer #drawer label=\"Filters\">\n <button\n drawer-actions\n type=\"button\"\n class=\"ui-table-filters-clear ui-text-body-alt\"\n [class.invisible]=\"!anyApplied()\"\n (click)=\"clearAll()\"\n >\n Clear all\n </button>\n\n <div class=\"ui-table-filters-panel\">\n <ng-container\n *ngTemplateOutlet=\"body; context: { $implicit: false }\"\n />\n </div>\n </ui-drawer>\n}\n\n<ng-template #body let-showHeader>\n @if (showHeader) {\n <div class=\"ui-table-filters-header\">\n <span class=\"ui-table-filters-title ui-text-body\">\n Filters\n </span>\n\n <button\n type=\"button\"\n class=\"ui-table-filters-clear ui-text-body-alt\"\n [class.invisible]=\"!anyApplied()\"\n (click)=\"clearAll()\"\n >\n Clear all\n </button>\n </div>\n }\n\n @for (facet of facets(); track facet.id) {\n <fieldset class=\"ui-table-filters-facet\">\n <legend class=\"ui-table-filters-legend ui-text-body-alt\">\n {{ facet.label }}\n </legend>\n\n <div\n class=\"ui-table-filters-choices\"\n [id]=\"groupName(facet) + '-options'\"\n >\n @switch (facet.kind) {\n @case ('options') {\n @if (facet.multiple) {\n @for (option of facet.options; track option.value; let index = $index) {\n @if (isShown(facet, option, index)) {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, index)\"\n >\n <ui-checkbox\n [id]=\"choiceId(facet, index)\"\n [value]=\"isChecked(facet, option)\"\n (valueChange)=\"check(facet, option, $event)\"\n />\n <span class=\"truncate\">{{\n option.label\n }}</span>\n </label>\n }\n }\n } @else {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'any')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'any')\"\n [value]=\"picked(facet)\"\n (valueChange)=\"pick(facet, $event)\"\n [option]=\"null\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Any</span>\n </label>\n\n @for (option of facet.options; track option.value; let index = $index) {\n @if (isShown(facet, option, index)) {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, index)\"\n >\n <ui-radio\n [id]=\"choiceId(facet, index)\"\n [value]=\"picked(facet)\"\n (valueChange)=\"pick(facet, $event)\"\n [option]=\"option.value\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">{{\n option.label\n }}</span>\n </label>\n }\n }\n }\n }\n @case ('dateRange') {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'any')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'any')\"\n [value]=\"dateMode(facet)\"\n (valueChange)=\"pickDate(facet, $event)\"\n [option]=\"anyRange\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Any time</span>\n </label>\n\n @for (preset of facet.presets ?? []; track preset.label; let index = $index) {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, index)\"\n >\n <ui-radio\n [id]=\"choiceId(facet, index)\"\n [value]=\"dateMode(facet)\"\n (valueChange)=\"pickDate(facet, $event)\"\n [option]=\"index\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">{{ preset.label }}</span>\n </label>\n }\n\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'custom')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'custom')\"\n [value]=\"dateMode(facet)\"\n (valueChange)=\"pickDate(facet, $event)\"\n [option]=\"customRange\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Custom range</span>\n </label>\n\n @if (dateMode(facet) === 'custom') {\n <label\n class=\"sr-only\"\n [for]=\"groupName(facet) + '-range'\"\n >{{ facet.label }} range</label>\n <ui-date-range-picker\n class=\"ui-table-filters-range\"\n [id]=\"groupName(facet) + '-range'\"\n [value]=\"range(facet)\"\n (valueChange)=\"setRange(facet, $event)\"\n [placeholder]=\"facet.placeholder ?? 'Select dates'\"\n [min]=\"facet.min ?? null\"\n [max]=\"facet.max ?? null\"\n />\n }\n }\n @case ('amountRange') {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'any')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'any')\"\n [value]=\"amountMode(facet)\"\n (valueChange)=\"pickAmount(facet, $event)\"\n [option]=\"anyRange\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Any amount</span>\n </label>\n\n @for (preset of facet.presets ?? []; track preset.label; let index = $index) {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, index)\"\n >\n <ui-radio\n [id]=\"choiceId(facet, index)\"\n [value]=\"amountMode(facet)\"\n (valueChange)=\"pickAmount(facet, $event)\"\n [option]=\"index\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">{{ preset.label }}</span>\n </label>\n }\n\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'custom')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'custom')\"\n [value]=\"amountMode(facet)\"\n (valueChange)=\"pickAmount(facet, $event)\"\n [option]=\"customRange\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Custom range</span>\n </label>\n\n @if (amountMode(facet) === 'custom') {\n <div class=\"ui-table-filters-amounts\">\n <ui-input\n class=\"ui-table-filters-amount ui-text-body-alt\"\n [id]=\"groupName(facet) + '-min'\"\n inputmode=\"decimal\"\n placeholder=\"Min\"\n [ariaLabel]=\"facet.label + ' from'\"\n [value]=\"amountText(facet, 'min')\"\n (valueChange)=\"typeAmount(facet, 'min', $event)\"\n [validationState]=\"isAmountValid(facet, 'min') ? null : false\"\n >\n @if (facet.prefix) {\n <ng-template #leading>\n <span class=\"ui-table-filters-prefix\">{{\n facet.prefix\n }}</span>\n </ng-template>\n }\n </ui-input>\n\n <span class=\"ui-table-filters-to ui-text-body-alt\">to</span>\n\n <ui-input\n class=\"ui-table-filters-amount ui-text-body-alt\"\n [id]=\"groupName(facet) + '-max'\"\n inputmode=\"decimal\"\n placeholder=\"Max\"\n [ariaLabel]=\"facet.label + ' up to'\"\n [value]=\"amountText(facet, 'max')\"\n (valueChange)=\"typeAmount(facet, 'max', $event)\"\n [validationState]=\"isAmountValid(facet, 'max') ? null : false\"\n >\n @if (facet.prefix) {\n <ng-template #leading>\n <span class=\"ui-table-filters-prefix\">{{\n facet.prefix\n }}</span>\n </ng-template>\n }\n </ui-input>\n </div>\n }\n }\n }\n </div>\n\n @if (facet.kind === 'options' && hiddenCount(facet)) {\n <button\n type=\"button\"\n class=\"ui-table-filters-more ui-text-body-alt\"\n [attr.aria-expanded]=\"isExpanded(facet)\"\n [attr.aria-controls]=\"groupName(facet) + '-options'\"\n (click)=\"toggleExpanded(facet)\"\n >\n @if (isExpanded(facet)) {\n Show fewer\n } @else {\n Show {{ hiddenCount(facet) }} more\n }\n </button>\n }\n </fieldset>\n }\n</ng-template>\n",
14724
+ styles: ["@layer properties;.ui-table-filters-panel{display:flex;flex-direction:column;row-gap:calc(var(--spacing, .25rem) * 6)}.ui-table-filters-panel--card{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--card-line);background-color:var(--card);padding:calc(var(--spacing, .25rem) * 5)}.ui-table-filters-header{display:flex;align-items:center;justify-content:space-between;column-gap:calc(var(--spacing, .25rem) * 3)}.ui-table-filters-title{display:flex;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--foreground)}.ui-table-filters-clear{cursor:pointer;color:var(--muted-foreground-1)}.ui-table-filters-clear:hover{color:var(--foreground)}.ui-table-filters-clear:focus-visible{text-decoration-line:underline}.ui-table-filters-clear:focus-visible{--tw-outline-style: none;outline-style:none}.ui-table-filters-facet{margin:0;min-width:0px;border-style:var(--tw-border-style);border-width:0px;padding:0}.ui-table-filters-legend{margin-bottom:calc(var(--spacing, .25rem) * 3);padding:0;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--foreground)}.ui-table-filters-choices{display:flex;flex-direction:column;row-gap:calc(var(--spacing, .25rem) * 2.5)}.ui-table-filters-choice{display:flex;min-width:0px;cursor:pointer;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2.5);color:var(--muted-foreground-2)}.ui-table-filters-choice:hover{color:var(--foreground)}.ui-table-filters-range{margin-top:calc(var(--spacing, .25rem) * .5)}.ui-table-filters-amounts{margin-top:calc(var(--spacing, .25rem) * .5);display:flex;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2)}.ui-table-filters-amount{min-width:0px;flex:1}.ui-table-filters-prefix{padding-inline-start:calc(var(--spacing, .25rem) * 3);color:var(--muted-foreground-1)}.ui-table-filters-to{flex-shrink:0;color:var(--muted-foreground-1)}.ui-table-filters-more{margin-top:calc(var(--spacing, .25rem) * 2.5);cursor:pointer;color:var(--color-primary-500, var(--color-blue-500))}.ui-table-filters-more:hover{color:var(--color-primary-600, var(--color-blue-600))}.ui-table-filters-more:hover{text-decoration-line:underline}.ui-table-filters-more:focus-visible{color:var(--color-primary-600, var(--color-blue-600))}.ui-table-filters-more:focus-visible{text-decoration-line:underline}.ui-table-filters-more:focus-visible{--tw-outline-style: none;outline-style:none}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"],
14149
14725
  dependencies: [
14150
14726
  {
14151
14727
  kind: "directive",
@@ -14224,6 +14800,49 @@ var UiTableFiltersComponent = class UiTableFiltersComponent {
14224
14800
  ],
14225
14801
  outputs: ["valueChange", "validationStateChange"]
14226
14802
  },
14803
+ {
14804
+ kind: "component",
14805
+ type: UiInputComponent,
14806
+ selector: "ui-input",
14807
+ inputs: [
14808
+ "value",
14809
+ "classes",
14810
+ "type",
14811
+ "id",
14812
+ "name",
14813
+ "placeholder",
14814
+ "autocomplete",
14815
+ "inputmode",
14816
+ "required",
14817
+ "disabled",
14818
+ "readonly",
14819
+ "validationState",
14820
+ "min",
14821
+ "max",
14822
+ "step",
14823
+ "pattern",
14824
+ "minlength",
14825
+ "maxlength",
14826
+ "autofocus",
14827
+ "spellcheck",
14828
+ "revealable",
14829
+ "list",
14830
+ "ariaLabel",
14831
+ "describedBy",
14832
+ "inputRole",
14833
+ "ariaExpanded",
14834
+ "ariaControls",
14835
+ "ariaActiveDescendant",
14836
+ "ariaAutocomplete",
14837
+ "ariaHasPopup"
14838
+ ],
14839
+ outputs: [
14840
+ "valueChange",
14841
+ "validationStateChange",
14842
+ "focused",
14843
+ "blurred"
14844
+ ]
14845
+ },
14227
14846
  {
14228
14847
  kind: "component",
14229
14848
  type: UiDateRangePickerComponent,
@@ -14265,11 +14884,12 @@ i0.ɵɵngDeclareClassMetadata({
14265
14884
  UiDrawerComponent,
14266
14885
  UiCheckboxComponent,
14267
14886
  UiRadioComponent,
14887
+ UiInputComponent,
14268
14888
  UiDateRangePickerComponent
14269
14889
  ],
14270
14890
  host: { class: "block" },
14271
- template: "@if (wide()) {\n <div class=\"ui-table-filters-panel ui-table-filters-panel--card\">\n <ng-container *ngTemplateOutlet=\"body; context: { $implicit: true }\" />\n </div>\n} @else {\n <ui-button\n appearance=\"white\"\n intent=\"secondary\"\n size=\"sm\"\n classes=\"gap-x-2 h-9.5 py-0!\"\n (click)=\"drawer.isOpen.set(true)\"\n >\n Filters\n @if (appliedCount()) {\n <ui-badge appearance=\"soft\" size=\"xs\" class=\"ui-text-caption\">{{\n appliedCount()\n }}</ui-badge>\n }\n </ui-button>\n\n <ui-drawer #drawer label=\"Filters\">\n <button\n drawer-actions\n type=\"button\"\n class=\"ui-table-filters-clear ui-text-body-alt\"\n [class.invisible]=\"!anyApplied()\"\n (click)=\"clearAll()\"\n >\n Clear all\n </button>\n\n <div class=\"ui-table-filters-panel\">\n <ng-container\n *ngTemplateOutlet=\"body; context: { $implicit: false }\"\n />\n </div>\n </ui-drawer>\n}\n\n<ng-template #body let-showHeader>\n @if (showHeader) {\n <div class=\"ui-table-filters-header\">\n <span class=\"ui-table-filters-title ui-text-body\">\n Filters\n </span>\n\n <button\n type=\"button\"\n class=\"ui-table-filters-clear ui-text-body-alt\"\n [class.invisible]=\"!anyApplied()\"\n (click)=\"clearAll()\"\n >\n Clear all\n </button>\n </div>\n }\n\n @for (facet of facets(); track facet.id) {\n <fieldset class=\"ui-table-filters-facet\">\n <legend class=\"ui-table-filters-legend ui-text-body-alt\">\n {{ facet.label }}\n </legend>\n\n <div\n class=\"ui-table-filters-choices\"\n [id]=\"groupName(facet) + '-options'\"\n >\n @switch (facet.kind) {\n @case ('options') {\n @if (facet.multiple) {\n @for (option of facet.options; track option.value; let index = $index) {\n @if (isShown(facet, option, index)) {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, index)\"\n >\n <ui-checkbox\n [id]=\"choiceId(facet, index)\"\n [value]=\"isChecked(facet, option)\"\n (valueChange)=\"check(facet, option, $event)\"\n />\n <span class=\"truncate\">{{\n option.label\n }}</span>\n </label>\n }\n }\n } @else {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'any')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'any')\"\n [value]=\"picked(facet)\"\n (valueChange)=\"pick(facet, $event)\"\n [option]=\"null\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Any</span>\n </label>\n\n @for (option of facet.options; track option.value; let index = $index) {\n @if (isShown(facet, option, index)) {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, index)\"\n >\n <ui-radio\n [id]=\"choiceId(facet, index)\"\n [value]=\"picked(facet)\"\n (valueChange)=\"pick(facet, $event)\"\n [option]=\"option.value\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">{{\n option.label\n }}</span>\n </label>\n }\n }\n }\n }\n @case ('dateRange') {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'any')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'any')\"\n [value]=\"dateMode(facet)\"\n (valueChange)=\"pickDate(facet, $event)\"\n [option]=\"anyDate\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Any time</span>\n </label>\n\n @for (preset of facet.presets ?? []; track preset.label; let index = $index) {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, index)\"\n >\n <ui-radio\n [id]=\"choiceId(facet, index)\"\n [value]=\"dateMode(facet)\"\n (valueChange)=\"pickDate(facet, $event)\"\n [option]=\"index\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">{{ preset.label }}</span>\n </label>\n }\n\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'custom')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'custom')\"\n [value]=\"dateMode(facet)\"\n (valueChange)=\"pickDate(facet, $event)\"\n [option]=\"customDate\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Custom range</span>\n </label>\n\n @if (dateMode(facet) === 'custom') {\n <label\n class=\"sr-only\"\n [for]=\"groupName(facet) + '-range'\"\n >{{ facet.label }} range</label>\n <ui-date-range-picker\n class=\"ui-table-filters-range\"\n [id]=\"groupName(facet) + '-range'\"\n [value]=\"range(facet)\"\n (valueChange)=\"setRange(facet, $event)\"\n [placeholder]=\"facet.placeholder ?? 'Select dates'\"\n [min]=\"facet.min ?? null\"\n [max]=\"facet.max ?? null\"\n />\n }\n }\n }\n </div>\n\n @if (facet.kind === 'options' && hiddenCount(facet)) {\n <button\n type=\"button\"\n class=\"ui-table-filters-more ui-text-body-alt\"\n [attr.aria-expanded]=\"isExpanded(facet)\"\n [attr.aria-controls]=\"groupName(facet) + '-options'\"\n (click)=\"toggleExpanded(facet)\"\n >\n @if (isExpanded(facet)) {\n Show fewer\n } @else {\n Show {{ hiddenCount(facet) }} more\n }\n </button>\n }\n </fieldset>\n }\n</ng-template>\n",
14272
- styles: ["@layer properties;.ui-table-filters-panel{display:flex;flex-direction:column;row-gap:calc(var(--spacing, .25rem) * 6)}.ui-table-filters-panel--card{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--card-line);background-color:var(--card);padding:calc(var(--spacing, .25rem) * 5)}.ui-table-filters-header{display:flex;align-items:center;justify-content:space-between;column-gap:calc(var(--spacing, .25rem) * 3)}.ui-table-filters-title{display:flex;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--foreground)}.ui-table-filters-clear{cursor:pointer;color:var(--muted-foreground-1)}.ui-table-filters-clear:hover{color:var(--foreground)}.ui-table-filters-clear:focus-visible{text-decoration-line:underline}.ui-table-filters-clear:focus-visible{--tw-outline-style: none;outline-style:none}.ui-table-filters-facet{margin:0;min-width:0px;border-style:var(--tw-border-style);border-width:0px;padding:0}.ui-table-filters-legend{margin-bottom:calc(var(--spacing, .25rem) * 3);padding:0;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--foreground)}.ui-table-filters-choices{display:flex;flex-direction:column;row-gap:calc(var(--spacing, .25rem) * 2.5)}.ui-table-filters-choice{display:flex;min-width:0px;cursor:pointer;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2.5);color:var(--muted-foreground-2)}.ui-table-filters-choice:hover{color:var(--foreground)}.ui-table-filters-range{margin-top:calc(var(--spacing, .25rem) * .5)}.ui-table-filters-more{margin-top:calc(var(--spacing, .25rem) * 2.5);cursor:pointer;color:var(--color-primary-500, var(--color-blue-500))}.ui-table-filters-more:hover{color:var(--color-primary-600, var(--color-blue-600))}.ui-table-filters-more:hover{text-decoration-line:underline}.ui-table-filters-more:focus-visible{color:var(--color-primary-600, var(--color-blue-600))}.ui-table-filters-more:focus-visible{text-decoration-line:underline}.ui-table-filters-more:focus-visible{--tw-outline-style: none;outline-style:none}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
14891
+ template: "@if (wide()) {\n <div class=\"ui-table-filters-panel ui-table-filters-panel--card\">\n <ng-container *ngTemplateOutlet=\"body; context: { $implicit: true }\" />\n </div>\n} @else {\n <ui-button\n appearance=\"white\"\n intent=\"secondary\"\n size=\"sm\"\n classes=\"gap-x-2 h-9.5 py-0!\"\n (click)=\"drawer.isOpen.set(true)\"\n >\n Filters\n @if (appliedCount()) {\n <ui-badge appearance=\"soft\" size=\"xs\" class=\"ui-text-caption\">{{\n appliedCount()\n }}</ui-badge>\n }\n </ui-button>\n\n <ui-drawer #drawer label=\"Filters\">\n <button\n drawer-actions\n type=\"button\"\n class=\"ui-table-filters-clear ui-text-body-alt\"\n [class.invisible]=\"!anyApplied()\"\n (click)=\"clearAll()\"\n >\n Clear all\n </button>\n\n <div class=\"ui-table-filters-panel\">\n <ng-container\n *ngTemplateOutlet=\"body; context: { $implicit: false }\"\n />\n </div>\n </ui-drawer>\n}\n\n<ng-template #body let-showHeader>\n @if (showHeader) {\n <div class=\"ui-table-filters-header\">\n <span class=\"ui-table-filters-title ui-text-body\">\n Filters\n </span>\n\n <button\n type=\"button\"\n class=\"ui-table-filters-clear ui-text-body-alt\"\n [class.invisible]=\"!anyApplied()\"\n (click)=\"clearAll()\"\n >\n Clear all\n </button>\n </div>\n }\n\n @for (facet of facets(); track facet.id) {\n <fieldset class=\"ui-table-filters-facet\">\n <legend class=\"ui-table-filters-legend ui-text-body-alt\">\n {{ facet.label }}\n </legend>\n\n <div\n class=\"ui-table-filters-choices\"\n [id]=\"groupName(facet) + '-options'\"\n >\n @switch (facet.kind) {\n @case ('options') {\n @if (facet.multiple) {\n @for (option of facet.options; track option.value; let index = $index) {\n @if (isShown(facet, option, index)) {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, index)\"\n >\n <ui-checkbox\n [id]=\"choiceId(facet, index)\"\n [value]=\"isChecked(facet, option)\"\n (valueChange)=\"check(facet, option, $event)\"\n />\n <span class=\"truncate\">{{\n option.label\n }}</span>\n </label>\n }\n }\n } @else {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'any')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'any')\"\n [value]=\"picked(facet)\"\n (valueChange)=\"pick(facet, $event)\"\n [option]=\"null\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Any</span>\n </label>\n\n @for (option of facet.options; track option.value; let index = $index) {\n @if (isShown(facet, option, index)) {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, index)\"\n >\n <ui-radio\n [id]=\"choiceId(facet, index)\"\n [value]=\"picked(facet)\"\n (valueChange)=\"pick(facet, $event)\"\n [option]=\"option.value\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">{{\n option.label\n }}</span>\n </label>\n }\n }\n }\n }\n @case ('dateRange') {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'any')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'any')\"\n [value]=\"dateMode(facet)\"\n (valueChange)=\"pickDate(facet, $event)\"\n [option]=\"anyRange\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Any time</span>\n </label>\n\n @for (preset of facet.presets ?? []; track preset.label; let index = $index) {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, index)\"\n >\n <ui-radio\n [id]=\"choiceId(facet, index)\"\n [value]=\"dateMode(facet)\"\n (valueChange)=\"pickDate(facet, $event)\"\n [option]=\"index\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">{{ preset.label }}</span>\n </label>\n }\n\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'custom')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'custom')\"\n [value]=\"dateMode(facet)\"\n (valueChange)=\"pickDate(facet, $event)\"\n [option]=\"customRange\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Custom range</span>\n </label>\n\n @if (dateMode(facet) === 'custom') {\n <label\n class=\"sr-only\"\n [for]=\"groupName(facet) + '-range'\"\n >{{ facet.label }} range</label>\n <ui-date-range-picker\n class=\"ui-table-filters-range\"\n [id]=\"groupName(facet) + '-range'\"\n [value]=\"range(facet)\"\n (valueChange)=\"setRange(facet, $event)\"\n [placeholder]=\"facet.placeholder ?? 'Select dates'\"\n [min]=\"facet.min ?? null\"\n [max]=\"facet.max ?? null\"\n />\n }\n }\n @case ('amountRange') {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'any')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'any')\"\n [value]=\"amountMode(facet)\"\n (valueChange)=\"pickAmount(facet, $event)\"\n [option]=\"anyRange\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Any amount</span>\n </label>\n\n @for (preset of facet.presets ?? []; track preset.label; let index = $index) {\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, index)\"\n >\n <ui-radio\n [id]=\"choiceId(facet, index)\"\n [value]=\"amountMode(facet)\"\n (valueChange)=\"pickAmount(facet, $event)\"\n [option]=\"index\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">{{ preset.label }}</span>\n </label>\n }\n\n <label\n class=\"ui-table-filters-choice ui-text-body-alt\"\n [for]=\"choiceId(facet, 'custom')\"\n >\n <ui-radio\n [id]=\"choiceId(facet, 'custom')\"\n [value]=\"amountMode(facet)\"\n (valueChange)=\"pickAmount(facet, $event)\"\n [option]=\"customRange\"\n [name]=\"groupName(facet)\"\n />\n <span class=\"truncate\">Custom range</span>\n </label>\n\n @if (amountMode(facet) === 'custom') {\n <div class=\"ui-table-filters-amounts\">\n <ui-input\n class=\"ui-table-filters-amount ui-text-body-alt\"\n [id]=\"groupName(facet) + '-min'\"\n inputmode=\"decimal\"\n placeholder=\"Min\"\n [ariaLabel]=\"facet.label + ' from'\"\n [value]=\"amountText(facet, 'min')\"\n (valueChange)=\"typeAmount(facet, 'min', $event)\"\n [validationState]=\"isAmountValid(facet, 'min') ? null : false\"\n >\n @if (facet.prefix) {\n <ng-template #leading>\n <span class=\"ui-table-filters-prefix\">{{\n facet.prefix\n }}</span>\n </ng-template>\n }\n </ui-input>\n\n <span class=\"ui-table-filters-to ui-text-body-alt\">to</span>\n\n <ui-input\n class=\"ui-table-filters-amount ui-text-body-alt\"\n [id]=\"groupName(facet) + '-max'\"\n inputmode=\"decimal\"\n placeholder=\"Max\"\n [ariaLabel]=\"facet.label + ' up to'\"\n [value]=\"amountText(facet, 'max')\"\n (valueChange)=\"typeAmount(facet, 'max', $event)\"\n [validationState]=\"isAmountValid(facet, 'max') ? null : false\"\n >\n @if (facet.prefix) {\n <ng-template #leading>\n <span class=\"ui-table-filters-prefix\">{{\n facet.prefix\n }}</span>\n </ng-template>\n }\n </ui-input>\n </div>\n }\n }\n }\n </div>\n\n @if (facet.kind === 'options' && hiddenCount(facet)) {\n <button\n type=\"button\"\n class=\"ui-table-filters-more ui-text-body-alt\"\n [attr.aria-expanded]=\"isExpanded(facet)\"\n [attr.aria-controls]=\"groupName(facet) + '-options'\"\n (click)=\"toggleExpanded(facet)\"\n >\n @if (isExpanded(facet)) {\n Show fewer\n } @else {\n Show {{ hiddenCount(facet) }} more\n }\n </button>\n }\n </fieldset>\n }\n</ng-template>\n",
14892
+ styles: ["@layer properties;.ui-table-filters-panel{display:flex;flex-direction:column;row-gap:calc(var(--spacing, .25rem) * 6)}.ui-table-filters-panel--card{border-radius:var(--radius-lg, .5rem);border-style:var(--tw-border-style);border-width:1px;border-color:var(--card-line);background-color:var(--card);padding:calc(var(--spacing, .25rem) * 5)}.ui-table-filters-header{display:flex;align-items:center;justify-content:space-between;column-gap:calc(var(--spacing, .25rem) * 3)}.ui-table-filters-title{display:flex;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2);--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--foreground)}.ui-table-filters-clear{cursor:pointer;color:var(--muted-foreground-1)}.ui-table-filters-clear:hover{color:var(--foreground)}.ui-table-filters-clear:focus-visible{text-decoration-line:underline}.ui-table-filters-clear:focus-visible{--tw-outline-style: none;outline-style:none}.ui-table-filters-facet{margin:0;min-width:0px;border-style:var(--tw-border-style);border-width:0px;padding:0}.ui-table-filters-legend{margin-bottom:calc(var(--spacing, .25rem) * 3);padding:0;--tw-font-weight: var(--font-weight-medium, 500);font-weight:var(--font-weight-medium, 500);color:var(--foreground)}.ui-table-filters-choices{display:flex;flex-direction:column;row-gap:calc(var(--spacing, .25rem) * 2.5)}.ui-table-filters-choice{display:flex;min-width:0px;cursor:pointer;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2.5);color:var(--muted-foreground-2)}.ui-table-filters-choice:hover{color:var(--foreground)}.ui-table-filters-range{margin-top:calc(var(--spacing, .25rem) * .5)}.ui-table-filters-amounts{margin-top:calc(var(--spacing, .25rem) * .5);display:flex;align-items:center;column-gap:calc(var(--spacing, .25rem) * 2)}.ui-table-filters-amount{min-width:0px;flex:1}.ui-table-filters-prefix{padding-inline-start:calc(var(--spacing, .25rem) * 3);color:var(--muted-foreground-1)}.ui-table-filters-to{flex-shrink:0;color:var(--muted-foreground-1)}.ui-table-filters-more{margin-top:calc(var(--spacing, .25rem) * 2.5);cursor:pointer;color:var(--color-primary-500, var(--color-blue-500))}.ui-table-filters-more:hover{color:var(--color-primary-600, var(--color-blue-600))}.ui-table-filters-more:hover{text-decoration-line:underline}.ui-table-filters-more:focus-visible{color:var(--color-primary-600, var(--color-blue-600))}.ui-table-filters-more:focus-visible{text-decoration-line:underline}.ui-table-filters-more:focus-visible{--tw-outline-style: none;outline-style:none}@property --tw-border-style{syntax: \"*\"; inherits: false; initial-value: solid;}@property --tw-font-weight{syntax: \"*\"; inherits: false;}@layer properties{@supports ((-webkit-hyphens: none) and (not (margin-trim: inline))) or ((-moz-orient: inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style: solid;--tw-font-weight: initial}}}\n/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */\n"]
14273
14893
  }]
14274
14894
  }],
14275
14895
  ctorParameters: () => [],
@@ -14311,6 +14931,30 @@ i0.ɵɵngDeclareClassMetadata({
14311
14931
  }]
14312
14932
  }
14313
14933
  });
14934
+ function amountFrom(text) {
14935
+ const digits = text.trim().replaceAll(",", "");
14936
+ if (!digits) return null;
14937
+ const amount = Number(digits);
14938
+ return Number.isFinite(amount) ? amount : null;
14939
+ }
14940
+ function isReadableAmount(text) {
14941
+ return !text.trim() || amountFrom(text) !== null;
14942
+ }
14943
+ function isBackwards(draft) {
14944
+ const min = amountFrom(draft.min);
14945
+ const max = amountFrom(draft.max);
14946
+ return min !== null && max !== null && min > max;
14947
+ }
14948
+ function amountRangeFrom(draft) {
14949
+ const range = {
14950
+ min: amountFrom(draft.min),
14951
+ max: amountFrom(draft.max)
14952
+ };
14953
+ return range.min === null && range.max === null || isBackwards(draft) ? void 0 : range;
14954
+ }
14955
+ function isSameAmountRange(first, second) {
14956
+ return (first?.min ?? null) === (second?.min ?? null) && (first?.max ?? null) === (second?.max ?? null);
14957
+ }
14314
14958
  var UiUserMenuComponent = class UiUserMenuComponent {
14315
14959
  dropdown = inject(UiDropdownComponent, { optional: true });
14316
14960
  name = input.required(...ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []);
@@ -14684,6 +15328,6 @@ i0.ɵɵngDeclareClassMetadata({
14684
15328
  }]
14685
15329
  }
14686
15330
  });
14687
- export { AlertAppearances, AlertIntents, AvatarSizes, BadgeAppearances, BadgeIntents, BadgeSizes, BarChartOrientations, ButtonAppearances, ButtonGroupAppearances, ButtonIntents, ButtonSizes, ButtonTypes, CHART_COLOURS, CHART_INK, CHART_INK_DARK, CHART_MAX_LINE_SERIES, CHART_MAX_SERIES, CHART_PALETTE, CHART_PALETTE_DARK, CalendarModes, CardHeadingLevels, CardRadii, DisclosureTriggerAppearances, FileRejectionReasons, InputAriaAutocompletes, InputAriaHasPopups, InputModes, InputTypes, LineChartCurves, MoneySignDisplays, PRIVATE_TEXT_LABEL, PRIVATE_TEXT_MASK, PieChartVariants, ProgressIntents, ProgressLabelPositions, ProgressOrientations, ProgressShapes, ProgressSizes, SelectLocalDataSource, SelectMultipleDisplays, SelectRemoteDataSource, SkeletonShapes, TableFiltersBreakpoints, TableLocalDataSource, TableRemoteDataSource, TextareaResizeOptions, ToastIntents, ToasterPositions, UI_BUTTON_GROUP, UI_FORMAT, UI_FORMAT_DEFAULTS, UI_LOADING_TYPES, UI_PRIVACY, UI_THEME_CONFIG, UiAlertComponent, UiAvatarComponent, UiBadgeComponent, UiBarChartComponent, UiButtonComponent, UiButtonGroupComponent, UiCalendarComponent, UiCardComponent, UiCardHeaderComponent, UiChartComponent, UiChartFrameComponent, UiChartLegendComponent, UiChartTableComponent, UiCheckboxComponent, UiColourComponent, UiContainerComponent, UiCounterComponent, UiDateRangePickerComponent, UiDatepickerComponent, UiDisclosureChevronComponent, UiDisclosureComponent, UiDisclosurePanelDirective, UiDisclosureTriggerComponent, UiDrawerComponent, UiDropdownButtonComponent, UiDropdownComponent, UiDropdownDirective, UiDropdownMenuComponent, UiDropzoneComponent, UiFieldComponent, UiFileInputComponent, UiInputAddonComponent, UiInputComponent, UiInputGroupComponent, UiKpiComponent, UiLayoutComponent, UiLineChartComponent, UiLoadingComponent, UiModalComponent, UiMoneyComponent, UiOverlayComponent, UiPaginationComponent, UiPieChartComponent, UiPrivacies, UiPrivateComponent, UiProgressComponent, UiRadioComponent, UiSearchComponent, UiSegmentedComponent, UiSelectComponent, UiSidebarComponent, UiSidebarGroupComponent, UiSidebarItemComponent, UiSkeletonComponent, UiStatComponent, UiSwitchComponent, UiTabComponent, UiTabDirective, UiTableComponent, UiTableFiltersComponent, UiTableRegistry, UiTextareaComponent, UiThemeService, UiThemeSwitchComponent, UiTimeSelectComponent, UiToastComponent, UiToastService, UiToasterComponent, UiTooltipComponent, UiUserMenuComponent, WeekStarts, chartColour, chartInk, chartSeriesStyle, defaultDateRangePresets, financialYearPreset, injectMoneyFormatter, injectPrivateText, lastDaysPreset, maskMoney, moneyFormatterParts, monthPreset, pickedChartColour, provideUiFormat, provideUiPrivacy, provideUiTheme, radiusClasses, thisWeekPreset, todayPreset, yearPreset };
15331
+ export { AlertAppearances, AlertIntents, AvatarSizes, BadgeAppearances, BadgeIntents, BadgeSizes, BarChartOrientations, ButtonAppearances, ButtonGroupAppearances, ButtonIntents, ButtonSizes, ButtonTypes, CHART_COLOURS, CHART_INK, CHART_INK_DARK, CHART_MAX_LINE_SERIES, CHART_MAX_SERIES, CHART_PALETTE, CHART_PALETTE_DARK, CalendarModes, CardHeadingLevels, CardRadii, DisclosureTriggerAppearances, FileRejectionReasons, InputAriaAutocompletes, InputAriaHasPopups, InputModes, InputTypes, LineChartCurves, MoneySignDisplays, PRIVATE_TEXT_LABEL, PRIVATE_TEXT_MASK, PieChartVariants, ProgressIntents, ProgressLabelPositions, ProgressOrientations, ProgressShapes, ProgressSizes, SelectLocalDataSource, SelectMultipleDisplays, SelectRemoteDataSource, SkeletonShapes, TableFiltersBreakpoints, TableLocalDataSource, TableRemoteDataSource, TextareaResizeOptions, ToastIntents, ToasterPositions, UI_BUTTON_GROUP, UI_FORMAT, UI_FORMAT_DEFAULTS, UI_LOADING_TYPES, UI_PRIVACY, UI_THEME_CONFIG, UiAlertComponent, UiAvatarComponent, UiBadgeComponent, UiBarChartComponent, UiButtonComponent, UiButtonGroupComponent, UiCalendarComponent, UiCardComponent, UiCardHeaderComponent, UiChartComponent, UiChartFrameComponent, UiChartLegendComponent, UiChartTableComponent, UiCheckboxComponent, UiColourComponent, UiContainerComponent, UiCounterComponent, UiDateRangePickerComponent, UiDatepickerComponent, UiDisclosureChevronComponent, UiDisclosureComponent, UiDisclosurePanelDirective, UiDisclosureTriggerComponent, UiDrawerComponent, UiDropdownButtonComponent, UiDropdownComponent, UiDropdownDirective, UiDropdownMenuComponent, UiDropzoneComponent, UiFieldComponent, UiFileInputComponent, UiInputAddonComponent, UiInputComponent, UiInputGroupComponent, UiKpiComponent, UiLayoutComponent, UiLineChartComponent, UiLoadingComponent, UiModalComponent, UiMoneyComponent, UiOverlayComponent, UiPaginationComponent, UiPieChartComponent, UiPrivacies, UiPrivateComponent, UiProgressComponent, UiRadioComponent, UiSearchComponent, UiSegmentedComponent, UiSelectComponent, UiSidebarComponent, UiSidebarGroupComponent, UiSidebarItemComponent, UiSkeletonComponent, UiStatComponent, UiSwitchComponent, UiTabComponent, UiTabDirective, UiTableComponent, UiTableFiltersComponent, UiTableRegistry, UiTextareaComponent, UiThemeService, UiThemeSwitchComponent, UiTimeSelectComponent, UiToastComponent, UiToastService, UiToasterComponent, UiTooltipComponent, UiTreemapChartComponent, UiUserMenuComponent, WeekStarts, chartColour, chartInk, chartLabelInk, chartSeriesStyle, defaultDateRangePresets, financialYearPreset, injectMoneyFormatter, injectPrivateText, lastDaysPreset, maskMoney, mixChartColours, moneyFormatterParts, monthPreset, pickedChartColour, provideUiFormat, provideUiPrivacy, provideUiTheme, radiusClasses, thisWeekPreset, todayPreset, yearPreset };
14688
15332
 
14689
15333
  //# sourceMappingURL=area8975-ui.mjs.map