@joanroucoux/cairn-ui 0.7.1 → 0.7.2

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.2
4
+
5
+ ### Added
6
+
7
+ - `uiStaleLink` `size` input: `caption` (default, 12/17) or `label` (14/20), both at weight 500, for the dashboard
8
+ total's "1 cours en retard ›". The hit area stays 44px high, 40px with a mouse. `STALE_LINK_SIZES` and
9
+ `StaleLinkSize` are exported.
10
+ - `ui-line-chart` `rangeKey` input (`string | null`, default `null`): when bound, a new series interpolates and
11
+ fades "Départ" and the dashed line only if it comes with a new key. A new series under the same key (a reload
12
+ after a buy) is drawn at once, with no fade. The key may change before its series arrives; the interpolation
13
+ runs when the series does. Unbound, every new series interpolates, as before.
14
+ - `holdTransitionsUntilRendered()`: called in a constructor, it holds the transitions of the host and of everything
15
+ inside it until two frames after its first render, through `data-ui-settling` and the matching rule of
16
+ `styles/motion.css`. For a consumer element whose bound classes carry a transition.
17
+
18
+ ### Changed
19
+
20
+ - `ui-button` (and the `ui-async` retry button) no longer fades its opacity when it becomes disabled, busy or
21
+ enabled, and a `ui-segmented` option switches its label colour at once: MOUVEMENT.md animates neither. The press
22
+ scale and the hover fill keep their transitions.
23
+ - `uiAvatarLink` draws its current-page halo as a background image, so it appears at once when the route changes;
24
+ the hover glow keeps its 180 ms fade.
25
+ - `ui-nav-item` switches its active fill (now a background image) and its text colour at once on navigation, as
26
+ MOUVEMENT.md §4.1 asks of the sidebar; only the hover fill keeps its 180 ms fade, and the press scale stays.
27
+ `ui-tab` already switched at once (scale transition only); a story now checks it.
28
+
29
+ ### Fixed
30
+
31
+ - Nothing transitions on page open any more. A route's elements are created a tick before their classes are bound,
32
+ and a layout read in between (the router's scroll to the top, a view transition) turned the bound fill, colour
33
+ or switch track into a 180 ms transition. `ui-button`, `ui-async`, `ui-back-link`, `ui-nav-item`, `ui-row`,
34
+ `uiSwitch`, `ui-segmented` and `uiTable` now hold their transitions until rendered. Consumers already import
35
+ `styles/motion.css`, which carries the rule.
36
+ - `ui-menu` items stay on one line, left aligned (`whitespace-nowrap`, `text-left`). The menu places itself from
37
+ its layout size instead of its box scaled by the entry animation, and frees its right and bottom edges, so a
38
+ menu opened beside the right edge of a phone no longer narrows and wraps a long label.
39
+
3
40
  ## 0.7.1
4
41
 
5
42
  ### Added
@@ -273,6 +273,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
273
273
  }]
274
274
  }], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], currency: [{ type: i0.Input, args: [{ isSignal: true, alias: "currency", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], signed: [{ type: i0.Input, args: [{ isSignal: true, alias: "signed", required: false }] }], fractionDigits: [{ type: i0.Input, args: [{ isSignal: true, alias: "fractionDigits", required: false }] }], numeric: [{ type: i0.Input, args: [{ isSignal: true, alias: "numeric", required: false }] }], whenMasked: [{ type: i0.Input, args: [{ isSignal: true, alias: "whenMasked", required: false }] }] } });
275
275
 
276
+ /**
277
+ * Holds the transitions of the host and of everything inside it until two frames after its first
278
+ * render, through the `data-ui-settling` attribute and the matching rule of `styles/motion.css`.
279
+ * A route's elements are created a tick before their classes are bound; a layout read in between
280
+ * would otherwise turn the bound fill, colour or switch track into a transition on page open. Call it
281
+ * in an injection context. A host whose view is never refreshed (a detached change detector) keeps the
282
+ * attribute, and with it no transition.
283
+ *
284
+ * @example
285
+ * constructor() {
286
+ * holdTransitionsUntilRendered();
287
+ * }
288
+ */
289
+ function holdTransitionsUntilRendered() {
290
+ const host = inject(ElementRef).nativeElement;
291
+ host.setAttribute('data-ui-settling', '');
292
+ afterNextRender({
293
+ read: () => {
294
+ requestAnimationFrame(() => requestAnimationFrame(() => host.removeAttribute('data-ui-settling')));
295
+ },
296
+ });
297
+ }
298
+
276
299
  const SKELETON_DELAY_MS = 150;
277
300
  const SKELETON_MIN_MS = 400;
278
301
  /**
@@ -332,7 +355,7 @@ const ASYNC_STATES = ['loading', 'error', 'empty', 'ready'];
332
355
  const ASYNC_VARIANTS = ['elevated', 'plain', 'emphasis', 'inline'];
333
356
  /** Alignments of the error block; `auto` is centred from 64rem. `AsyncAlign` is derived from this tuple. */
334
357
  const ASYNC_ALIGNS = ['start', 'center', 'auto'];
335
- const RETRY_BASE_CLASSES = 'relative inline-flex items-center justify-center rounded-control font-medium whitespace-nowrap cursor-pointer select-none touch-manipulation transition-[scale,background-color,opacity] [transition-duration:var(--duration-press),var(--duration-fast),var(--duration-fast)] ease-out active:scale-(--press-scale) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring) text-label';
358
+ const RETRY_BASE_CLASSES = 'relative inline-flex items-center justify-center rounded-control font-medium whitespace-nowrap cursor-pointer select-none touch-manipulation transition-[scale,background-color] [transition-duration:var(--duration-press),var(--duration-fast)] ease-out active:scale-(--press-scale) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring) text-label';
336
359
  const RETRY_OUTLINE_CLASSES = 'bg-(--card) text-(--foreground) shadow-[inset_0_0_0_1px_var(--border)] hover:bg-(--glow)';
337
360
  const RETRY_PRIMARY_CLASSES = 'bg-(--primary) text-(--primary-foreground) hover:bg-(--primary-to)';
338
361
  const RETRY_BLOCK_CLASSES = 'min-h-(--row-min) gap-2 pl-3 pr-4';
@@ -440,6 +463,9 @@ class UiAsync {
440
463
  return `${RETRY_BASE_CLASSES} ${spec.retry} ${RETRY_BLOCK_CLASSES} ${spec.retryMargin[this.align()]}`;
441
464
  }, /* @ts-ignore */
442
465
  ...(ngDevMode ? [{ debugName: "retryButtonClasses" }] : /* istanbul ignore next */ []));
466
+ constructor() {
467
+ holdTransitionsUntilRendered();
468
+ }
443
469
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiAsync, deps: [], target: i0.ɵɵFactoryTarget.Component });
444
470
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiAsync, isStandalone: true, selector: "ui-async", inputs: { state: { classPropertyName: "state", publicName: "state", isSignal: true, isRequired: true, transformFunction: null }, errorTitle: { classPropertyName: "errorTitle", publicName: "errorTitle", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null }, retryLabel: { classPropertyName: "retryLabel", publicName: "retryLabel", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, card: { classPropertyName: "card", publicName: "card", isSignal: true, isRequired: false, transformFunction: null }, fill: { classPropertyName: "fill", publicName: "fill", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { retry: "retry" }, host: { properties: { "attr.aria-busy": "state() === 'loading' || null", "class.flex": "filling()", "class.flex-col": "filling()" } }, ngImport: i0, template: `
445
471
  @switch (shown()) {
@@ -540,12 +566,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
540
566
  '[class.flex-col]': 'filling()',
541
567
  },
542
568
  }]
543
- }], propDecorators: { state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: true }] }], errorTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorTitle", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], retryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "retryLabel", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], card: [{ type: i0.Input, args: [{ isSignal: true, alias: "card", required: false }] }], fill: [{ type: i0.Input, args: [{ isSignal: true, alias: "fill", required: false }] }], retry: [{ type: i0.Output, args: ["retry"] }] } });
569
+ }], ctorParameters: () => [], propDecorators: { state: [{ type: i0.Input, args: [{ isSignal: true, alias: "state", required: true }] }], errorTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorTitle", required: false }] }], errorMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorMessage", required: false }] }], retryLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "retryLabel", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], card: [{ type: i0.Input, args: [{ isSignal: true, alias: "card", required: false }] }], fill: [{ type: i0.Input, args: [{ isSignal: true, alias: "fill", required: false }] }], retry: [{ type: i0.Output, args: ["retry"] }] } });
544
570
 
545
571
  /** Available avatar sizes. `AvatarSize` is derived from this tuple. */
546
572
  const AVATAR_SIZES = ['sm', 'md', 'lg', 'auto'];
547
573
  const BASE_CLASSES$8 = 'inline-flex items-center justify-center rounded-pill bg-(--muted) font-medium tabular-nums';
548
- const SIZE_CLASSES$7 = {
574
+ const SIZE_CLASSES$8 = {
549
575
  sm: 'size-8 text-caption',
550
576
  md: 'size-[34px] text-label',
551
577
  lg: 'size-14 text-title',
@@ -564,7 +590,7 @@ class UiAvatar {
564
590
  ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
565
591
  size = input('md', /* @ts-ignore */
566
592
  ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
567
- classes = computed(() => `${BASE_CLASSES$8} ${SIZE_CLASSES$7[this.size()]}`, /* @ts-ignore */
593
+ classes = computed(() => `${BASE_CLASSES$8} ${SIZE_CLASSES$8[this.size()]}`, /* @ts-ignore */
568
594
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
569
595
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiAvatar, deps: [], target: i0.ɵɵFactoryTarget.Component });
570
596
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UiAvatar, isStandalone: true, selector: "ui-avatar", inputs: { initials: { classPropertyName: "initials", publicName: "initials", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "img" }, properties: { "attr.aria-label": "label()", "class": "classes()" } }, ngImport: i0, template: '<span aria-hidden="true">{{ initials() }}</span>', isInline: true });
@@ -584,21 +610,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
584
610
  /**
585
611
  * Round hit area around a `ui-avatar` that links somewhere: 44px on touch, 40px from 64rem, with a
586
612
  * glow on hover and the press scale. On the current page (`aria-current="page"`, which `routerLinkActive`
587
- * sets through `ariaCurrentWhenActive`) it holds a soft halo. The avatar itself keeps its own size.
613
+ * sets through `ariaCurrentWhenActive`) it holds a soft halo, drawn at once when the route changes. The avatar
614
+ * itself keeps its own size.
588
615
  *
589
616
  * @example
590
617
  * <a uiAvatarLink routerLink="/profile"><ui-avatar initials="JR" label="Profile" size="auto" /></a>
591
618
  */
592
619
  class UiAvatarLink {
593
620
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiAvatarLink, deps: [], target: i0.ɵɵFactoryTarget.Directive });
594
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.7", type: UiAvatarLink, isStandalone: true, selector: "a[uiAvatarLink], button[uiAvatarLink]", host: { classAttribute: "rounded-pill grid size-11 lg:size-10 place-items-center cursor-pointer select-none touch-manipulation transition-[scale,background-color] [transition-duration:var(--duration-press),var(--duration-fast)] ease-out hover:bg-(--glow) aria-[current=page]:bg-(--soft) active:scale-(--press-scale) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring)" }, ngImport: i0 });
621
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.7", type: UiAvatarLink, isStandalone: true, selector: "a[uiAvatarLink], button[uiAvatarLink]", host: { classAttribute: "rounded-pill grid size-11 lg:size-10 place-items-center cursor-pointer select-none touch-manipulation transition-[scale,background-color] [transition-duration:var(--duration-press),var(--duration-fast)] ease-out hover:bg-(--glow) aria-[current=page]:bg-transparent aria-[current=page]:bg-[image:linear-gradient(var(--soft),var(--soft))] active:scale-(--press-scale) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring)" }, ngImport: i0 });
595
622
  }
596
623
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiAvatarLink, decorators: [{
597
624
  type: Directive,
598
625
  args: [{
599
626
  selector: 'a[uiAvatarLink], button[uiAvatarLink]',
600
627
  host: {
601
- class: 'rounded-pill grid size-11 lg:size-10 place-items-center cursor-pointer select-none touch-manipulation transition-[scale,background-color] [transition-duration:var(--duration-press),var(--duration-fast)] ease-out hover:bg-(--glow) aria-[current=page]:bg-(--soft) active:scale-(--press-scale) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring)',
628
+ class: 'rounded-pill grid size-11 lg:size-10 place-items-center cursor-pointer select-none touch-manipulation transition-[scale,background-color] [transition-duration:var(--duration-press),var(--duration-fast)] ease-out hover:bg-(--glow) aria-[current=page]:bg-transparent aria-[current=page]:bg-[image:linear-gradient(var(--soft),var(--soft))] active:scale-(--press-scale) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring)',
602
629
  },
603
630
  }]
604
631
  }] });
@@ -606,7 +633,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
606
633
  /** Available back link sizes. `BackLinkSize` is derived from this tuple. */
607
634
  const BACK_LINK_SIZES = ['md', 'sm', 'header'];
608
635
  const BASE_CLASSES$7 = 'inline-flex items-center gap-0.5 rounded-control text-body font-medium whitespace-nowrap cursor-pointer select-none touch-manipulation transition-[scale,background-color,color] [transition-duration:var(--duration-press),var(--duration-fast),var(--duration-fast)] ease-out active:scale-(--press-scale) focus-visible:outline-2 focus-visible:outline-(--ring)';
609
- const SIZE_CLASSES$6 = {
636
+ const SIZE_CLASSES$7 = {
610
637
  md: 'h-11 pr-3 pl-1 text-(--foreground) focus-visible:outline-offset-2',
611
638
  sm: 'h-9 pr-2 pl-0.5 text-(--muted-foreground) hover:bg-(--glow) hover:text-(--foreground) focus-visible:outline-offset-2',
612
639
  header: 'h-11 pr-3 pl-1 text-(--foreground) focus-visible:-outline-offset-2',
@@ -623,8 +650,11 @@ class UiBackLink {
623
650
  ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
624
651
  chevron = computed(() => CHEVRON[this.size()], /* @ts-ignore */
625
652
  ...(ngDevMode ? [{ debugName: "chevron" }] : /* istanbul ignore next */ []));
626
- classes = computed(() => `${BASE_CLASSES$7} ${SIZE_CLASSES$6[this.size()]}`, /* @ts-ignore */
653
+ classes = computed(() => `${BASE_CLASSES$7} ${SIZE_CLASSES$7[this.size()]}`, /* @ts-ignore */
627
654
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
655
+ constructor() {
656
+ holdTransitionsUntilRendered();
657
+ }
628
658
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiBackLink, deps: [], target: i0.ɵɵFactoryTarget.Component });
629
659
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UiBackLink, isStandalone: true, selector: "a[ui-back-link]", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: `
630
660
  <svg
@@ -667,13 +697,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
667
697
  '[class]': 'classes()',
668
698
  },
669
699
  }]
670
- }], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
700
+ }], ctorParameters: () => [], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
671
701
 
672
702
  /** Available badge variants. `BadgeVariant` is derived from this tuple. */
673
703
  const BADGE_VARIANTS = ['neutral', 'outline'];
674
704
  const BADGE_SIZES = ['md', 'sm'];
675
705
  const BASE_CLASSES$6 = 'inline-flex items-center rounded-pill text-caption font-medium';
676
- const SIZE_CLASSES$5 = {
706
+ const SIZE_CLASSES$6 = {
677
707
  md: 'h-6 px-2.5',
678
708
  sm: 'h-[22px] px-2',
679
709
  };
@@ -692,7 +722,7 @@ class UiBadge {
692
722
  ...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
693
723
  size = input('md', /* @ts-ignore */
694
724
  ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
695
- classes = computed(() => `${BASE_CLASSES$6} ${SIZE_CLASSES$5[this.size()]} ${VARIANT_CLASSES$2[this.variant()]}`, /* @ts-ignore */
725
+ classes = computed(() => `${BASE_CLASSES$6} ${SIZE_CLASSES$6[this.size()]} ${VARIANT_CLASSES$2[this.variant()]}`, /* @ts-ignore */
696
726
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
697
727
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiBadge, deps: [], target: i0.ɵɵFactoryTarget.Component });
698
728
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UiBadge, isStandalone: true, selector: "ui-badge", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: '<ng-content />', isInline: true });
@@ -735,7 +765,7 @@ const BUTTON_SIZES = [
735
765
  'icon',
736
766
  'icon-sm',
737
767
  ];
738
- const BASE_CLASSES$5 = 'relative inline-flex items-center justify-center rounded-control font-medium whitespace-nowrap cursor-pointer select-none touch-manipulation transition-[scale,background-color,opacity] [transition-duration:var(--duration-press),var(--duration-fast),var(--duration-fast)] ease-out active:scale-(--press-scale) focus-visible:outline-2 focus-visible:outline-(--ring) disabled:pointer-events-none disabled:opacity-40 aria-disabled:not-aria-busy:opacity-40';
768
+ const BASE_CLASSES$5 = 'relative inline-flex items-center justify-center rounded-control font-medium whitespace-nowrap cursor-pointer select-none touch-manipulation transition-[scale,background-color] [transition-duration:var(--duration-press),var(--duration-fast)] ease-out active:scale-(--press-scale) focus-visible:outline-2 focus-visible:outline-(--ring) disabled:pointer-events-none disabled:opacity-40 aria-disabled:not-aria-busy:opacity-40';
739
769
  const RING_OUTSIDE = 'focus-visible:outline-offset-2';
740
770
  const RING_INSIDE = 'focus-visible:-outline-offset-2';
741
771
  const OUTLINE = 'bg-(--card) shadow-[inset_0_0_0_1px_var(--border)] hover:bg-(--glow) active:bg-(--soft)';
@@ -750,7 +780,7 @@ const VARIANT_CLASSES$1 = {
750
780
  'quiet-destructive': `${RING_INSIDE} bg-transparent text-(--muted-foreground) hover:bg-(--glow) hover:text-(--negative) active:bg-(--soft)`,
751
781
  'outline-destructive': `${RING_OUTSIDE} ${OUTLINE} text-(--negative)`,
752
782
  };
753
- const SIZE_CLASSES$4 = {
783
+ const SIZE_CLASSES$5 = {
754
784
  compact: 'h-8 lg:h-7 gap-1.5 px-2.5 lg:px-2 text-label before:absolute before:-inset-x-1 before:-inset-y-1.5 lg:before:hidden',
755
785
  slim: 'h-11 lg:h-8 gap-1.5 px-2.5 text-label',
756
786
  xs: 'h-8 gap-1.5 px-2.5 text-label',
@@ -780,9 +810,10 @@ class UiButton {
780
810
  busy = input(false, { ...(ngDevMode ? { debugName: "busy" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
781
811
  inactive = computed(() => this.loading() || this.busy(), /* @ts-ignore */
782
812
  ...(ngDevMode ? [{ debugName: "inactive" }] : /* istanbul ignore next */ []));
783
- classes = computed(() => `${BASE_CLASSES$5} ${VARIANT_CLASSES$1[this.variant()]} ${SIZE_CLASSES$4[this.size()]}${this.inactive() ? ' pointer-events-none opacity-70' : ''}`, /* @ts-ignore */
813
+ classes = computed(() => `${BASE_CLASSES$5} ${VARIANT_CLASSES$1[this.variant()]} ${SIZE_CLASSES$5[this.size()]}${this.inactive() ? ' pointer-events-none opacity-70' : ''}`, /* @ts-ignore */
784
814
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
785
815
  constructor() {
816
+ holdTransitionsUntilRendered();
786
817
  const host = inject(ElementRef).nativeElement;
787
818
  const guard = (event) => {
788
819
  if (this.inactive()) {
@@ -1220,7 +1251,7 @@ const DELTA_SIZES = ['label', 'inherit'];
1220
1251
  /** Font weights. `DeltaWeight` is derived from this tuple. */
1221
1252
  const DELTA_WEIGHTS = ['medium', 'regular'];
1222
1253
  const BASE_CLASSES$3 = 'inline-flex items-center gap-1 tabular-nums';
1223
- const SIZE_CLASSES$3 = {
1254
+ const SIZE_CLASSES$4 = {
1224
1255
  label: 'text-label',
1225
1256
  inherit: '',
1226
1257
  };
@@ -1276,7 +1307,7 @@ class UiDelta {
1276
1307
  classes = computed(() => {
1277
1308
  const sign = this.sign();
1278
1309
  const background = this.emphasis() === 'pill' ? `${PILL_CLASSES$1} ${PILL_BACKGROUND_CLASS}` : 'bg-transparent';
1279
- return `${BASE_CLASSES$3} ${SIZE_CLASSES$3[this.size()]} ${WEIGHT_CLASSES[this.weight()]} ${TEXT_CLASSES[sign]} ${background}`;
1310
+ return `${BASE_CLASSES$3} ${SIZE_CLASSES$4[this.size()]} ${WEIGHT_CLASSES[this.weight()]} ${TEXT_CLASSES[sign]} ${background}`;
1280
1311
  }, /* @ts-ignore */
1281
1312
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
1282
1313
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiDelta, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -2359,7 +2390,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
2359
2390
  const FACT_SIZES = ['md', 'sm', 'auto', 'recap'];
2360
2391
  /** Colour of the line under a fact value. `stale` flags an out-of-date figure. */
2361
2392
  const FACT_SUB_TONES = ['subtle', 'stale'];
2362
- const SIZE_CLASSES$2 = {
2393
+ const SIZE_CLASSES$3 = {
2363
2394
  md: { row: 'gap-4 py-3 [&:not(:first-child)]:shadow-[inset_0_1px_0_var(--hairline)]', value: 'text-body' },
2364
2395
  sm: { row: 'gap-4 py-2.5', value: 'text-label' },
2365
2396
  auto: {
@@ -2411,9 +2442,9 @@ class UiFact {
2411
2442
  ...(ngDevMode ? [{ debugName: "subTone" }] : /* istanbul ignore next */ []));
2412
2443
  size = input('md', /* @ts-ignore */
2413
2444
  ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
2414
- classes = computed(() => `flex items-baseline justify-between ${SIZE_CLASSES$2[this.size()].row}`, /* @ts-ignore */
2445
+ classes = computed(() => `flex items-baseline justify-between ${SIZE_CLASSES$3[this.size()].row}`, /* @ts-ignore */
2415
2446
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
2416
- valueClasses = computed(() => `${SIZE_CLASSES$2[this.size()].value} tabular-nums`, /* @ts-ignore */
2447
+ valueClasses = computed(() => `${SIZE_CLASSES$3[this.size()].value} tabular-nums`, /* @ts-ignore */
2417
2448
  ...(ngDevMode ? [{ debugName: "valueClasses" }] : /* istanbul ignore next */ []));
2418
2449
  subClasses = computed(() => `text-caption ${SUB_TONE_CLASSES$1[this.subTone()]}`, /* @ts-ignore */
2419
2450
  ...(ngDevMode ? [{ debugName: "subClasses" }] : /* istanbul ignore next */ []));
@@ -3067,6 +3098,7 @@ const animateShape = (from, to, duration, draw, done) => {
3067
3098
  class ShapeMotion {
3068
3099
  #view;
3069
3100
  #points = null;
3101
+ #rangeKey = null;
3070
3102
  #target = null;
3071
3103
  #held = null;
3072
3104
  #drawn = null;
@@ -3076,7 +3108,11 @@ class ShapeMotion {
3076
3108
  }
3077
3109
  follow(points, geometry, options) {
3078
3110
  const newSeries = !sameSeries(points, this.#points);
3111
+ const newRange = options.rangeKey === null || options.rangeKey !== this.#rangeKey;
3079
3112
  this.#points = points;
3113
+ if (newSeries) {
3114
+ this.#rangeKey = options.rangeKey;
3115
+ }
3080
3116
  if (this.#stop && !newSeries && !options.reduced && geometry?.line === this.#target?.line) {
3081
3117
  this.#target = geometry;
3082
3118
  return;
@@ -3085,7 +3121,13 @@ class ShapeMotion {
3085
3121
  const held = this.#held ?? this.#target;
3086
3122
  this.#target = geometry;
3087
3123
  this.stop();
3088
- if (!newSeries || !geometry || !from || from.length < 2 || geometry.points.length < 2 || options.reduced) {
3124
+ if (!newSeries ||
3125
+ !newRange ||
3126
+ !geometry ||
3127
+ !from ||
3128
+ from.length < 2 ||
3129
+ geometry.points.length < 2 ||
3130
+ options.reduced) {
3089
3131
  this.#settle(geometry);
3090
3132
  return;
3091
3133
  }
@@ -3140,6 +3182,10 @@ const wideViewport = () => {
3140
3182
  * only the first, middle and last ticks count; with `auto` every tick counts from `sm` up and the
3141
3183
  * three core ticks below it. Tick positions are unchanged.
3142
3184
  *
3185
+ * A new series interpolates from the drawn curve, fading the start label and the dashed line. With
3186
+ * `rangeKey` bound, only a series that comes with a new key does so: a new series under the same key
3187
+ * (a reload after a buy) is drawn at once, with no fade. The key may change before its series arrives.
3188
+ *
3143
3189
  * @example
3144
3190
  * <ui-line-chart [points]="points" label="Net worth over one month" startLabel="Since" [valueFormat]="formatEur" />
3145
3191
  */
@@ -3171,6 +3217,8 @@ class UiLineChart {
3171
3217
  axisGap = input(12, /* @ts-ignore */
3172
3218
  ...(ngDevMode ? [{ debugName: "axisGap" }] : /* istanbul ignore next */ []));
3173
3219
  axisTicks = input('auto', { ...(ngDevMode ? { debugName: "axisTicks" } : /* istanbul ignore next */ {}), transform: parseAxisTicks });
3220
+ rangeKey = input(null, /* @ts-ignore */
3221
+ ...(ngDevMode ? [{ debugName: "rangeKey" }] : /* istanbul ignore next */ []));
3174
3222
  #destroyRef = inject(DestroyRef);
3175
3223
  #host = inject(ElementRef);
3176
3224
  #wide = wideViewport();
@@ -3250,6 +3298,7 @@ class UiLineChart {
3250
3298
  const reduced = this.#reducedMotion();
3251
3299
  untracked(() => this.#motion.follow(points, geometry, {
3252
3300
  reduced,
3301
+ rangeKey: this.rangeKey(),
3253
3302
  duration: () => durationFrom(getComputedStyle(this.#host.nativeElement).getPropertyValue('--duration-base')),
3254
3303
  }));
3255
3304
  });
@@ -3289,7 +3338,7 @@ class UiLineChart {
3289
3338
  this.activeIndex.set(navigation.index);
3290
3339
  }
3291
3340
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiLineChart, deps: [], target: i0.ɵɵFactoryTarget.Component });
3292
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiLineChart, isStandalone: true, selector: "ui-line-chart", inputs: { points: { classPropertyName: "points", publicName: "points", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, valueFormat: { classPropertyName: "valueFormat", publicName: "valueFormat", isSignal: true, isRequired: false, transformFunction: null }, tooltipFormat: { classPropertyName: "tooltipFormat", publicName: "tooltipFormat", isSignal: true, isRequired: false, transformFunction: null }, deltaFormat: { classPropertyName: "deltaFormat", publicName: "deltaFormat", isSignal: true, isRequired: false, transformFunction: null }, timeFormat: { classPropertyName: "timeFormat", publicName: "timeFormat", isSignal: true, isRequired: false, transformFunction: null }, axisFormat: { classPropertyName: "axisFormat", publicName: "axisFormat", isSignal: true, isRequired: false, transformFunction: null }, startLabel: { classPropertyName: "startLabel", publicName: "startLabel", isSignal: true, isRequired: false, transformFunction: null }, timeColumnLabel: { classPropertyName: "timeColumnLabel", publicName: "timeColumnLabel", isSignal: true, isRequired: false, transformFunction: null }, valueColumnLabel: { classPropertyName: "valueColumnLabel", publicName: "valueColumnLabel", isSignal: true, isRequired: false, transformFunction: null }, sparkline: { classPropertyName: "sparkline", publicName: "sparkline", isSignal: true, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null }, tooltipDelta: { classPropertyName: "tooltipDelta", publicName: "tooltipDelta", isSignal: true, isRequired: false, transformFunction: null }, axisGap: { classPropertyName: "axisGap", publicName: "axisGap", isSignal: true, isRequired: false, transformFunction: null }, axisTicks: { classPropertyName: "axisTicks", publicName: "axisTicks", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "block h-full" }, viewQueries: [{ propertyName: "svgRef", first: true, predicate: ["svgRef"], descendants: true, isSignal: true }, { propertyName: "lineRef", first: true, predicate: ["lineRef"], descendants: true, isSignal: true }, { propertyName: "endRef", first: true, predicate: ["endRef"], descendants: true, isSignal: true }], ngImport: i0, template: `
3341
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiLineChart, isStandalone: true, selector: "ui-line-chart", inputs: { points: { classPropertyName: "points", publicName: "points", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, valueFormat: { classPropertyName: "valueFormat", publicName: "valueFormat", isSignal: true, isRequired: false, transformFunction: null }, tooltipFormat: { classPropertyName: "tooltipFormat", publicName: "tooltipFormat", isSignal: true, isRequired: false, transformFunction: null }, deltaFormat: { classPropertyName: "deltaFormat", publicName: "deltaFormat", isSignal: true, isRequired: false, transformFunction: null }, timeFormat: { classPropertyName: "timeFormat", publicName: "timeFormat", isSignal: true, isRequired: false, transformFunction: null }, axisFormat: { classPropertyName: "axisFormat", publicName: "axisFormat", isSignal: true, isRequired: false, transformFunction: null }, startLabel: { classPropertyName: "startLabel", publicName: "startLabel", isSignal: true, isRequired: false, transformFunction: null }, timeColumnLabel: { classPropertyName: "timeColumnLabel", publicName: "timeColumnLabel", isSignal: true, isRequired: false, transformFunction: null }, valueColumnLabel: { classPropertyName: "valueColumnLabel", publicName: "valueColumnLabel", isSignal: true, isRequired: false, transformFunction: null }, sparkline: { classPropertyName: "sparkline", publicName: "sparkline", isSignal: true, isRequired: false, transformFunction: null }, tooltip: { classPropertyName: "tooltip", publicName: "tooltip", isSignal: true, isRequired: false, transformFunction: null }, tooltipDelta: { classPropertyName: "tooltipDelta", publicName: "tooltipDelta", isSignal: true, isRequired: false, transformFunction: null }, axisGap: { classPropertyName: "axisGap", publicName: "axisGap", isSignal: true, isRequired: false, transformFunction: null }, axisTicks: { classPropertyName: "axisTicks", publicName: "axisTicks", isSignal: true, isRequired: false, transformFunction: null }, rangeKey: { classPropertyName: "rangeKey", publicName: "rangeKey", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "block h-full" }, viewQueries: [{ propertyName: "svgRef", first: true, predicate: ["svgRef"], descendants: true, isSignal: true }, { propertyName: "lineRef", first: true, predicate: ["lineRef"], descendants: true, isSignal: true }, { propertyName: "endRef", first: true, predicate: ["endRef"], descendants: true, isSignal: true }], ngImport: i0, template: `
3293
3342
  <div class="relative h-full">
3294
3343
  <svg
3295
3344
  #svgRef
@@ -3580,12 +3629,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
3580
3629
  class: 'block h-full',
3581
3630
  },
3582
3631
  }]
3583
- }], ctorParameters: () => [], propDecorators: { points: [{ type: i0.Input, args: [{ isSignal: true, alias: "points", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], valueFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueFormat", required: false }] }], tooltipFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipFormat", required: false }] }], deltaFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "deltaFormat", required: false }] }], timeFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeFormat", required: false }] }], axisFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "axisFormat", required: false }] }], startLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "startLabel", required: false }] }], timeColumnLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeColumnLabel", required: false }] }], valueColumnLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueColumnLabel", required: false }] }], sparkline: [{ type: i0.Input, args: [{ isSignal: true, alias: "sparkline", required: false }] }], tooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltip", required: false }] }], tooltipDelta: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipDelta", required: false }] }], axisGap: [{ type: i0.Input, args: [{ isSignal: true, alias: "axisGap", required: false }] }], axisTicks: [{ type: i0.Input, args: [{ isSignal: true, alias: "axisTicks", required: false }] }], svgRef: [{ type: i0.ViewChild, args: ['svgRef', { isSignal: true }] }], lineRef: [{ type: i0.ViewChild, args: ['lineRef', { isSignal: true }] }], endRef: [{ type: i0.ViewChild, args: ['endRef', { isSignal: true }] }] } });
3632
+ }], ctorParameters: () => [], propDecorators: { points: [{ type: i0.Input, args: [{ isSignal: true, alias: "points", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], valueFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueFormat", required: false }] }], tooltipFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipFormat", required: false }] }], deltaFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "deltaFormat", required: false }] }], timeFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeFormat", required: false }] }], axisFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "axisFormat", required: false }] }], startLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "startLabel", required: false }] }], timeColumnLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeColumnLabel", required: false }] }], valueColumnLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueColumnLabel", required: false }] }], sparkline: [{ type: i0.Input, args: [{ isSignal: true, alias: "sparkline", required: false }] }], tooltip: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltip", required: false }] }], tooltipDelta: [{ type: i0.Input, args: [{ isSignal: true, alias: "tooltipDelta", required: false }] }], axisGap: [{ type: i0.Input, args: [{ isSignal: true, alias: "axisGap", required: false }] }], axisTicks: [{ type: i0.Input, args: [{ isSignal: true, alias: "axisTicks", required: false }] }], rangeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "rangeKey", required: false }] }], svgRef: [{ type: i0.ViewChild, args: ['svgRef', { isSignal: true }] }], lineRef: [{ type: i0.ViewChild, args: ['lineRef', { isSignal: true }] }], endRef: [{ type: i0.ViewChild, args: ['endRef', { isSignal: true }] }] } });
3584
3633
 
3585
3634
  const MENU_CLASSES = 'm-0 min-w-44 p-1 rounded-container bg-(--elevated) shadow-[0_8px_24px_rgb(0_0_0/0.16),inset_0_0_0_1px_var(--border)] text-(--foreground) transition-[opacity,scale,overlay,display] transition-discrete duration-(--duration-fast) not-open:duration-[120ms] ease-out starting:open:opacity-0 starting:open:scale-(--enter-scale) opacity-0 scale-(--enter-scale) open:opacity-100 open:scale-100';
3586
3635
  const SHEET_CLASSES = 'max-lg:fixed max-lg:inset-x-4 max-lg:top-auto max-lg:w-auto max-lg:bottom-[calc(76px+env(safe-area-inset-bottom))] max-lg:min-w-0 max-lg:p-1.5 max-lg:bg-(--card) max-lg:shadow-[0_12px_32px_rgb(0_0_0/0.2),inset_0_0_0_1px_var(--border)] max-lg:backdrop:bg-[rgb(0_0_0/0.36)] max-lg:transition-[opacity,translate,overlay,display] max-lg:scale-100 max-lg:translate-y-4 max-lg:open:translate-y-0 max-lg:starting:open:scale-100 max-lg:starting:open:translate-y-4 max-lg:motion-reduce:translate-y-0 max-lg:motion-reduce:starting:open:translate-y-0';
3587
- const SHEET_ITEM_CLASSES = 'flex w-full items-center gap-3 lg:pointer-fine:gap-2.5 min-h-12 lg:min-h-11 lg:pointer-fine:min-h-9 px-3 lg:pointer-fine:px-2.5 rounded-[calc(var(--radius-container)-6px)] lg:rounded-[calc(var(--radius-container)-4px)] text-body lg:pointer-fine:text-label hover:bg-(--glow) focus-visible:bg-(--glow) active:bg-(--soft) transition-[background-color] duration-(--duration-fast) ease-out outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) [:where(&>svg)]:size-5 [:where(&>svg)]:flex-none lg:[:where(&>svg)]:size-[18px] lg:pointer-fine:[:where(&>svg)]:size-4';
3588
- const ITEM_CLASSES = 'flex w-full items-center gap-3 pointer-fine:gap-2.5 min-h-11 pointer-fine:min-h-9 px-3 pointer-fine:px-2.5 rounded-[calc(var(--radius-container)-4px)] text-body pointer-fine:text-label hover:bg-(--glow) focus-visible:bg-(--glow) active:bg-(--soft) transition-[background-color] duration-(--duration-fast) ease-out outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) [:where(&>svg)]:size-[18px] [:where(&>svg)]:flex-none pointer-fine:[:where(&>svg)]:size-4';
3636
+ const SHEET_ITEM_CLASSES = 'flex w-full items-center gap-3 lg:pointer-fine:gap-2.5 min-h-12 lg:min-h-11 lg:pointer-fine:min-h-9 px-3 lg:pointer-fine:px-2.5 rounded-[calc(var(--radius-container)-6px)] lg:rounded-[calc(var(--radius-container)-4px)] text-body lg:pointer-fine:text-label text-left whitespace-nowrap hover:bg-(--glow) focus-visible:bg-(--glow) active:bg-(--soft) transition-[background-color] duration-(--duration-fast) ease-out outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) [:where(&>svg)]:size-5 [:where(&>svg)]:flex-none lg:[:where(&>svg)]:size-[18px] lg:pointer-fine:[:where(&>svg)]:size-4';
3637
+ const ITEM_CLASSES = 'flex w-full items-center gap-3 pointer-fine:gap-2.5 min-h-11 pointer-fine:min-h-9 px-3 pointer-fine:px-2.5 rounded-[calc(var(--radius-container)-4px)] text-body pointer-fine:text-label text-left whitespace-nowrap hover:bg-(--glow) focus-visible:bg-(--glow) active:bg-(--soft) transition-[background-color] duration-(--duration-fast) ease-out outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) [:where(&>svg)]:size-[18px] [:where(&>svg)]:flex-none pointer-fine:[:where(&>svg)]:size-4';
3589
3638
  const nextId$1 = (() => {
3590
3639
  let count = 0;
3591
3640
  return () => `ui-menu-${++count}`;
@@ -3672,6 +3721,8 @@ class UiMenu {
3672
3721
  this.#host.style.position = '';
3673
3722
  this.#host.style.top = '';
3674
3723
  this.#host.style.left = '';
3724
+ this.#host.style.right = '';
3725
+ this.#host.style.bottom = '';
3675
3726
  }
3676
3727
  else {
3677
3728
  this.#position(trigger);
@@ -3731,13 +3782,15 @@ class UiMenu {
3731
3782
  #position(trigger) {
3732
3783
  const margin = 8;
3733
3784
  const triggerRect = trigger.getBoundingClientRect();
3734
- const menuRect = this.#host.getBoundingClientRect();
3785
+ const menuRect = { width: this.#host.offsetWidth, height: this.#host.offsetHeight };
3735
3786
  const fitsBelow = window.innerHeight - triggerRect.bottom >= menuRect.height + margin;
3736
3787
  const top = fitsBelow ? triggerRect.bottom + 4 : Math.max(margin, triggerRect.top - menuRect.height - 4);
3737
3788
  const left = Math.min(Math.max(triggerRect.right - menuRect.width, margin), window.innerWidth - menuRect.width - margin);
3738
3789
  this.#host.style.position = 'fixed';
3739
3790
  this.#host.style.top = `${Math.min(top, window.innerHeight - menuRect.height - margin)}px`;
3740
3791
  this.#host.style.left = `${left}px`;
3792
+ this.#host.style.right = 'auto';
3793
+ this.#host.style.bottom = 'auto';
3741
3794
  this.#host.style.transformOrigin = fitsBelow ? 'top right' : 'bottom right';
3742
3795
  }
3743
3796
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
@@ -4249,11 +4302,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
4249
4302
  }]
4250
4303
  }], ctorParameters: () => [], propDecorators: { uiHighlight: [{ type: i0.Input, args: [{ isSignal: true, alias: "uiHighlight", required: false }] }] } });
4251
4304
 
4252
- const BASE_CLASSES$2 = 'flex items-center gap-3 h-10 px-3 rounded-control text-label leading-normal font-medium transition-[scale,background-color,color] [transition-duration:var(--duration-press),var(--duration-fast),var(--duration-fast)] ease-out active:scale-(--press-scale) hover:bg-(--glow) hover:text-(--foreground) focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring)';
4253
- const ACTIVE_CLASSES = 'bg-(--soft) text-(--foreground)';
4305
+ const BASE_CLASSES$2 = 'flex items-center gap-3 h-10 px-3 rounded-control text-label leading-normal font-medium transition-[scale,background-color] [transition-duration:var(--duration-press),var(--duration-fast)] ease-out active:scale-(--press-scale) hover:bg-(--glow) hover:text-(--foreground) focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring)';
4306
+ const ACTIVE_CLASSES = 'bg-[image:linear-gradient(var(--soft),var(--soft))] text-(--foreground)';
4254
4307
  const IDLE_CLASSES = 'text-(--muted-foreground) active:bg-(--soft)';
4255
4308
  /**
4256
- * One destination of the sidebar navigation (Portfolio, Holdings, Allocation, Accounts).
4309
+ * One destination of the sidebar navigation (Portfolio, Holdings, Allocation, Accounts). The active
4310
+ * fill and text colour switch at once on navigation; only the hover fill fades.
4257
4311
  *
4258
4312
  * @example
4259
4313
  * <a ui-nav-item [active]="url === '/'" routerLink="/">
@@ -4265,6 +4319,9 @@ class UiNavItem {
4265
4319
  active = input(false, { ...(ngDevMode ? { debugName: "active" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4266
4320
  classes = computed(() => `${BASE_CLASSES$2} ${this.active() ? ACTIVE_CLASSES : IDLE_CLASSES}`, /* @ts-ignore */
4267
4321
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
4322
+ constructor() {
4323
+ holdTransitionsUntilRendered();
4324
+ }
4268
4325
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiNavItem, deps: [], target: i0.ɵɵFactoryTarget.Component });
4269
4326
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UiNavItem, isStandalone: true, selector: "a[ui-nav-item]", inputs: { active: { classPropertyName: "active", publicName: "active", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()", "attr.aria-current": "active() ? 'page' : null" } }, ngImport: i0, template: '<ng-content select="[navIcon]" /><ng-content />', isInline: true });
4270
4327
  }
@@ -4278,12 +4335,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
4278
4335
  '[attr.aria-current]': "active() ? 'page' : null",
4279
4336
  },
4280
4337
  }]
4281
- }], propDecorators: { active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }] } });
4338
+ }], ctorParameters: () => [], propDecorators: { active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }] } });
4282
4339
 
4283
4340
  const ROW_SIZES = ['md', 'lg', 'xl', 'card', 'dense'];
4284
4341
  const ROW_PADDINGS = ['md', 'sm', 'none'];
4285
4342
  const ROW_GAPS = ['default', 'sm'];
4286
- const SIZE_CLASSES$1 = {
4343
+ const SIZE_CLASSES$2 = {
4287
4344
  md: 'min-h-14',
4288
4345
  lg: 'min-h-15',
4289
4346
  xl: 'min-h-18 pointer-fine:min-h-17',
@@ -4314,9 +4371,10 @@ class UiRow {
4314
4371
  ...(ngDevMode ? [{ debugName: "padding" }] : /* istanbul ignore next */ []));
4315
4372
  gap = input('default', /* @ts-ignore */
4316
4373
  ...(ngDevMode ? [{ debugName: "gap" }] : /* istanbul ignore next */ []));
4317
- classes = computed(() => `${BASE_CLASSES$1} ${SIZE_CLASSES$1[this.size()]} ${this.gap() === 'sm' ? 'gap-2' : SIZE_GAPS[this.size()]} ${PADDING_CLASSES[this.padding()]}${this.unavailable() ? ` ${UNAVAILABLE_CLASSES}` : ` ${INTERACTIVE_CLASSES}`}${this.selected() ? ` ${SELECTED_CLASSES$1}` : ''}${this.busy() ? ' pointer-events-none' : ''}`, /* @ts-ignore */
4374
+ classes = computed(() => `${BASE_CLASSES$1} ${SIZE_CLASSES$2[this.size()]} ${this.gap() === 'sm' ? 'gap-2' : SIZE_GAPS[this.size()]} ${PADDING_CLASSES[this.padding()]}${this.unavailable() ? ` ${UNAVAILABLE_CLASSES}` : ` ${INTERACTIVE_CLASSES}`}${this.selected() ? ` ${SELECTED_CLASSES$1}` : ''}${this.busy() ? ' pointer-events-none' : ''}`, /* @ts-ignore */
4318
4375
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
4319
4376
  constructor() {
4377
+ holdTransitionsUntilRendered();
4320
4378
  const host = inject(ElementRef).nativeElement;
4321
4379
  const guard = (event) => {
4322
4380
  if (this.busy() || this.unavailable()) {
@@ -4437,9 +4495,9 @@ const nextId = (() => {
4437
4495
  let count = 0;
4438
4496
  return () => `ui-segmented-${++count}`;
4439
4497
  })();
4440
- const OPTION_CLASSES = "relative z-10 flex-1 cursor-pointer px-3 text-label font-medium transition-[scale,color] duration-(--duration-press) ease-out after:absolute after:inset-x-0 after:top-1/2 after:h-(--row-min) after:-translate-y-1/2 after:content-[''] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) active:scale-(--press-scale)";
4498
+ const OPTION_CLASSES = "relative z-10 flex-1 cursor-pointer px-3 text-label font-medium transition-[scale] duration-(--duration-press) ease-out after:absolute after:inset-x-0 after:top-1/2 after:h-(--row-min) after:-translate-y-1/2 after:content-[''] focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) active:scale-(--press-scale)";
4441
4499
  const SEGMENTED_SIZES = ['md', 'sm'];
4442
- const SIZE_CLASSES = {
4500
+ const SIZE_CLASSES$1 = {
4443
4501
  md: 'h-10 pointer-fine:h-8',
4444
4502
  sm: 'h-10 pointer-fine:h-[30px]',
4445
4503
  };
@@ -4470,8 +4528,11 @@ class UiSegmented {
4470
4528
  return index === -1 ? 0 : index + 1;
4471
4529
  }, /* @ts-ignore */
4472
4530
  ...(ngDevMode ? [{ debugName: "thumbIndex" }] : /* istanbul ignore next */ []));
4531
+ constructor() {
4532
+ holdTransitionsUntilRendered();
4533
+ }
4473
4534
  optionClasses(optionValue) {
4474
- return `${OPTION_CLASSES} ${SIZE_CLASSES[this.size()]} ${optionValue === this.value() ? SELECTED_CLASSES : UNSELECTED_CLASSES}`;
4535
+ return `${OPTION_CLASSES} ${SIZE_CLASSES$1[this.size()]} ${optionValue === this.value() ? SELECTED_CLASSES : UNSELECTED_CLASSES}`;
4475
4536
  }
4476
4537
  tabIndexFor(optionValue) {
4477
4538
  const opts = this.options();
@@ -4583,7 +4644,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
4583
4644
  </div>
4584
4645
  `,
4585
4646
  }]
4586
- }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], showLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabel", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }, { type: i0.Output, args: ["valueChange"] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], radios: [{ type: i0.ViewChildren, args: ['radio', { isSignal: true }] }] } });
4647
+ }], ctorParameters: () => [], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], showLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showLabel", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }, { type: i0.Output, args: ["valueChange"] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], radios: [{ type: i0.ViewChildren, args: ['radio', { isSignal: true }] }] } });
4587
4648
 
4588
4649
  const SELECT_CLASSES = 'cursor-pointer appearance-none pr-10 bg-(image:--chevron-down) bg-no-repeat bg-[position:right_0.75rem_center] bg-[size:1.125rem]';
4589
4650
  // Spelled out prefix included: Tailwind scans for literal strings, so a prefix applied in code
@@ -4725,22 +4786,31 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
4725
4786
  }]
4726
4787
  }], propDecorators: { shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "shape", required: false }] }], lines: [{ type: i0.Input, args: [{ isSignal: true, alias: "lines", required: false }] }], height: [{ type: i0.Input, args: [{ isSignal: true, alias: "height", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
4727
4788
 
4728
- const BASE_CLASSES = "relative inline-flex items-center gap-0.5 rounded-[4px] text-caption font-medium text-(--stale) hover:underline underline-offset-3 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring) before:absolute before:inset-x-0 before:top-1/2 before:h-11 pointer-fine:before:h-10 before:-translate-y-1/2 before:content-['']";
4789
+ /** Available stale link sizes. `StaleLinkSize` is derived from this tuple. */
4790
+ const STALE_LINK_SIZES = ['caption', 'label'];
4791
+ const BASE_CLASSES = "relative inline-flex items-center gap-0.5 rounded-[4px] font-medium text-(--stale) hover:underline underline-offset-3 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring) before:absolute before:inset-x-0 before:top-1/2 before:h-11 pointer-fine:before:h-10 before:-translate-y-1/2 before:content-['']";
4792
+ const SIZE_CLASSES = {
4793
+ caption: 'text-caption',
4794
+ label: 'text-label',
4795
+ };
4729
4796
  const CHEVRON_CLASSES = "after:size-4 after:flex-none after:bg-current after:content-[''] after:mask-center after:mask-no-repeat after:mask-[url(data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%2024%2024%27%20fill%3D%27none%27%20stroke%3D%27black%27%20stroke-width%3D%271.75%27%20stroke-linecap%3D%27round%27%20stroke-linejoin%3D%27round%27%3E%3Cpath%20d%3D%27m9%2018%206-6-6-6%27%2F%3E%3C%2Fsvg%3E)]";
4730
4797
  /**
4731
4798
  * Link in the stale tone, for a caption about data that is late or left out of a total, such as
4732
- * "1 ligne sans cours, non comptée". Caption size, weight 500, underlined on hover, with an optional
4733
- * trailing chevron.
4799
+ * "1 ligne sans cours, non comptée". Weight 500, underlined on hover, with an optional trailing
4800
+ * chevron. `size` is `caption` (12/17, the default) or `label` (14/20, the dashboard total's
4801
+ * "1 cours en retard").
4734
4802
  *
4735
4803
  * @example
4736
- * <a uiStaleLink chevron routerLink="/holdings">1 cours en retard</a>
4804
+ * <a uiStaleLink chevron size="label" routerLink="/holdings">1 cours en retard</a>
4737
4805
  */
4738
4806
  class UiStaleLink {
4739
4807
  chevron = input(false, { ...(ngDevMode ? { debugName: "chevron" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
4740
- classes = computed(() => (this.chevron() ? `${BASE_CLASSES} ${CHEVRON_CLASSES}` : BASE_CLASSES), /* @ts-ignore */
4808
+ size = input('caption', /* @ts-ignore */
4809
+ ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
4810
+ classes = computed(() => `${BASE_CLASSES} ${SIZE_CLASSES[this.size()]}${this.chevron() ? ` ${CHEVRON_CLASSES}` : ''}`, /* @ts-ignore */
4741
4811
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
4742
4812
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiStaleLink, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4743
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.7", type: UiStaleLink, isStandalone: true, selector: "a[uiStaleLink]", inputs: { chevron: { classPropertyName: "chevron", publicName: "chevron", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0 });
4813
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.7", type: UiStaleLink, isStandalone: true, selector: "a[uiStaleLink]", inputs: { chevron: { classPropertyName: "chevron", publicName: "chevron", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0 });
4744
4814
  }
4745
4815
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiStaleLink, decorators: [{
4746
4816
  type: Directive,
@@ -4748,7 +4818,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
4748
4818
  selector: 'a[uiStaleLink]',
4749
4819
  host: { '[class]': 'classes()' },
4750
4820
  }]
4751
- }], propDecorators: { chevron: [{ type: i0.Input, args: [{ isSignal: true, alias: "chevron", required: false }] }] } });
4821
+ }], propDecorators: { chevron: [{ type: i0.Input, args: [{ isSignal: true, alias: "chevron", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
4752
4822
 
4753
4823
  /** Available stat sizes. `StatSize` is derived from this tuple. */
4754
4824
  const STAT_SIZES = ['hero', 'tile'];
@@ -4847,6 +4917,9 @@ const CLASSES = "relative shrink-0 w-[51px] h-[31px] pointer-fine:w-10 pointer-f
4847
4917
  */
4848
4918
  class UiSwitch {
4849
4919
  classes = CLASSES;
4920
+ constructor() {
4921
+ holdTransitionsUntilRendered();
4922
+ }
4850
4923
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiSwitch, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4851
4924
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.7", type: UiSwitch, isStandalone: true, selector: "input[type=checkbox][uiSwitch]", host: { attributes: { "role": "switch" }, properties: { "class": "classes" } }, ngImport: i0 });
4852
4925
  }
@@ -4859,7 +4932,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
4859
4932
  '[class]': 'classes',
4860
4933
  },
4861
4934
  }]
4862
- }] });
4935
+ }], ctorParameters: () => [] });
4863
4936
 
4864
4937
  const HEIGHT_PROPERTY = '--tab-bar-height';
4865
4938
  const HEIGHT = 'calc(52px + env(safe-area-inset-bottom))';
@@ -5108,6 +5181,9 @@ class UiTable {
5108
5181
  this.spaced() ? '[--table-head-gap:0.25rem]' : '[--table-head-gap:0px]',
5109
5182
  ].join(' '), /* @ts-ignore */
5110
5183
  ...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
5184
+ constructor() {
5185
+ holdTransitionsUntilRendered();
5186
+ }
5111
5187
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiTable, deps: [], target: i0.ɵɵFactoryTarget.Directive });
5112
5188
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.7", type: UiTable, isStandalone: true, selector: "table[uiTable]", inputs: { row: { classPropertyName: "row", publicName: "row", isSignal: true, isRequired: false, transformFunction: null }, rule: { classPropertyName: "rule", publicName: "rule", isSignal: true, isRequired: false, transformFunction: null }, spaced: { classPropertyName: "spaced", publicName: "spaced", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0 });
5113
5189
  }
@@ -5119,7 +5195,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
5119
5195
  '[class]': 'classes()',
5120
5196
  },
5121
5197
  }]
5122
- }], propDecorators: { row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: false }] }], rule: [{ type: i0.Input, args: [{ isSignal: true, alias: "rule", required: false }] }], spaced: [{ type: i0.Input, args: [{ isSignal: true, alias: "spaced", required: false }] }] } });
5198
+ }], ctorParameters: () => [], propDecorators: { row: [{ type: i0.Input, args: [{ isSignal: true, alias: "row", required: false }] }], rule: [{ type: i0.Input, args: [{ isSignal: true, alias: "rule", required: false }] }], spaced: [{ type: i0.Input, args: [{ isSignal: true, alias: "spaced", required: false }] }] } });
5123
5199
  /** Body of one group of rows: leaves a 4px tail after its last row. */
5124
5200
  class UiGroup {
5125
5201
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiGroup, deps: [], target: i0.ɵɵFactoryTarget.Directive });
@@ -5386,5 +5462,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
5386
5462
  * Generated bundle index. Do not edit.
5387
5463
  */
5388
5464
 
5389
- export { ALERT_VARIANTS, AMOUNT_MASKINGS, AMOUNT_NUMERICS, ASYNC_ALIGNS, ASYNC_STATES, ASYNC_VARIANTS, AVATAR_SIZES, BACK_LINK_SIZES, BADGE_SIZES, BADGE_VARIANTS, BUTTON_SIZES, BUTTON_VARIANTS, CARD_PADDINGS, CARD_SURFACES, CARD_VARIANTS, CELL_BREAKPOINTS, CONTROL_SIZES, CONTROL_SURFACES, DELTA_EMPHASES, DELTA_SIZES, DELTA_WEIGHTS, DIALOG_CLOSE_REASONS, DIALOG_LAYOUTS, DIALOG_WIDTHS, FACT_SIZES, FACT_SUB_TONES, GROUP_SIZES, METER_SIZES, METER_TONES, ROW_GAPS, ROW_PADDINGS, ROW_SIZES, SEGMENTED_SIZES, SKELETON_SHAPES, STAT_SIZES, SUB_TONES, TABLE_ROWS, UI_AMOUNT_MASKED, UiActionBar, UiAlert, UiAmount, UiAsync, UiAvatar, UiAvatarLink, UiBackLink, UiBadge, UiButton, UiCard, UiCellSub, UiChoiceChips, UiDelta, UiDialog, UiDonut, UiEmpty, UiExternalLink, UiFact, UiFacts, UiField, UiFieldLeading, UiFieldTrailing, UiFilterChips, UiFlipItem, UiFlipList, UiGroup, UiGroupCell, UiHighlight, UiInput, UiLineChart, UiListRow, UiMenu, UiMenuItem, UiMenuTrigger, UiMeter, UiNavItem, UiRow, UiRowAction, UiRowItem, UiRowLink, UiRowTile, UiSegmented, UiSelect, UiSkeleton, UiStaleLink, UiStat, UiSwitch, UiTab, UiTabBar, UiTable, UiTd, UiTextarea, UiTh, UiToaster, UiToasts, UiTr, delayedState, formatAmount, injectReducedMotion };
5465
+ export { ALERT_VARIANTS, AMOUNT_MASKINGS, AMOUNT_NUMERICS, ASYNC_ALIGNS, ASYNC_STATES, ASYNC_VARIANTS, AVATAR_SIZES, BACK_LINK_SIZES, BADGE_SIZES, BADGE_VARIANTS, BUTTON_SIZES, BUTTON_VARIANTS, CARD_PADDINGS, CARD_SURFACES, CARD_VARIANTS, CELL_BREAKPOINTS, CONTROL_SIZES, CONTROL_SURFACES, DELTA_EMPHASES, DELTA_SIZES, DELTA_WEIGHTS, DIALOG_CLOSE_REASONS, DIALOG_LAYOUTS, DIALOG_WIDTHS, FACT_SIZES, FACT_SUB_TONES, GROUP_SIZES, METER_SIZES, METER_TONES, ROW_GAPS, ROW_PADDINGS, ROW_SIZES, SEGMENTED_SIZES, SKELETON_SHAPES, STALE_LINK_SIZES, STAT_SIZES, SUB_TONES, TABLE_ROWS, UI_AMOUNT_MASKED, UiActionBar, UiAlert, UiAmount, UiAsync, UiAvatar, UiAvatarLink, UiBackLink, UiBadge, UiButton, UiCard, UiCellSub, UiChoiceChips, UiDelta, UiDialog, UiDonut, UiEmpty, UiExternalLink, UiFact, UiFacts, UiField, UiFieldLeading, UiFieldTrailing, UiFilterChips, UiFlipItem, UiFlipList, UiGroup, UiGroupCell, UiHighlight, UiInput, UiLineChart, UiListRow, UiMenu, UiMenuItem, UiMenuTrigger, UiMeter, UiNavItem, UiRow, UiRowAction, UiRowItem, UiRowLink, UiRowTile, UiSegmented, UiSelect, UiSkeleton, UiStaleLink, UiStat, UiSwitch, UiTab, UiTabBar, UiTable, UiTd, UiTextarea, UiTh, UiToaster, UiToasts, UiTr, delayedState, formatAmount, holdTransitionsUntilRendered, injectReducedMotion };
5390
5466
  //# sourceMappingURL=joanroucoux-cairn-ui.mjs.map