@joanroucoux/cairn-ui 0.6.3 → 0.6.5

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.
@@ -506,21 +506,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
506
506
  }], propDecorators: { initials: [{ type: i0.Input, args: [{ isSignal: true, alias: "initials", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
507
507
  /**
508
508
  * Round hit area around a `ui-avatar` that links somewhere: 44px on touch, 40px from 64rem, with a
509
- * glow on hover and the press scale. The avatar itself keeps its own size.
509
+ * glow on hover and the press scale. On the current page (`aria-current="page"`, which `routerLinkActive`
510
+ * sets through `ariaCurrentWhenActive`) it holds a soft halo. The avatar itself keeps its own size.
510
511
  *
511
512
  * @example
512
513
  * <a uiAvatarLink routerLink="/profile"><ui-avatar initials="JR" label="Profile" size="auto" /></a>
513
514
  */
514
515
  class UiAvatarLink {
515
516
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiAvatarLink, deps: [], target: i0.ɵɵFactoryTarget.Directive });
516
- 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-[transform,background-color] duration-(--duration-press) ease-out hover:bg-(--glow) active:scale-(--press-scale) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring)" }, ngImport: i0 });
517
+ 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-[transform,background-color] duration-(--duration-press) 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 });
517
518
  }
518
519
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiAvatarLink, decorators: [{
519
520
  type: Directive,
520
521
  args: [{
521
522
  selector: 'a[uiAvatarLink], button[uiAvatarLink]',
522
523
  host: {
523
- class: 'rounded-pill grid size-11 lg:size-10 place-items-center cursor-pointer select-none touch-manipulation transition-[transform,background-color] duration-(--duration-press) ease-out hover:bg-(--glow) active:scale-(--press-scale) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring)',
524
+ class: 'rounded-pill grid size-11 lg:size-10 place-items-center cursor-pointer select-none touch-manipulation transition-[transform,background-color] duration-(--duration-press) 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)',
524
525
  },
525
526
  }]
526
527
  }] });
@@ -2317,6 +2318,33 @@ const isCoreTick = (index, count) => {
2317
2318
  const middle = Math.floor((count - 1) / 2);
2318
2319
  return index === 0 || index === count - 1 || index === middle;
2319
2320
  };
2321
+ const firstOfEachRun = (labels, included) => {
2322
+ let previous = null;
2323
+ return labels.map((text, index) => {
2324
+ if (!included(index)) {
2325
+ return false;
2326
+ }
2327
+ const distinct = text !== previous;
2328
+ previous = text;
2329
+ return distinct;
2330
+ });
2331
+ };
2332
+ const tickLabels = (ticks, format, mode) => {
2333
+ const labels = ticks.map((tick) => format(tick.t));
2334
+ const count = labels.length;
2335
+ const core = (index) => isCoreTick(index, count);
2336
+ const everyTick = firstOfEachRun(labels, () => true);
2337
+ const coreTicks = firstOfEachRun(labels, core);
2338
+ return labels.map((text, index) => {
2339
+ const wide = mode === 3 ? coreTicks[index] : everyTick[index];
2340
+ const narrow = coreTicks[index];
2341
+ if (!wide && !narrow) {
2342
+ return null;
2343
+ }
2344
+ const classes = mode === 'auto' ? `${narrow ? '' : 'max-sm:hidden'} ${wide ? '' : 'sm:hidden'}`.trim() : wide ? '' : 'hidden';
2345
+ return { text, classes };
2346
+ });
2347
+ };
2320
2348
 
2321
2349
  const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
2322
2350
  const nearestPointIndex = (points, x) => {
@@ -2543,6 +2571,11 @@ const wideViewport = () => {
2543
2571
  /**
2544
2572
  * Value over time: a monotone curve with a dashed line at the starting value and a tooltip.
2545
2573
  *
2574
+ * Axis labels are never repeated: a tick whose `axisFormat` text equals the previous drawn label is
2575
+ * not rendered. The first tick always is, so only the last edge label can drop. With `axisTicks="3"`
2576
+ * only the first, middle and last ticks count; with `auto` every tick counts from `sm` up and the
2577
+ * three core ticks below it. Tick positions are unchanged.
2578
+ *
2546
2579
  * @example
2547
2580
  * <ui-line-chart [points]="points" label="Net worth over one month" startLabel="Since" [valueFormat]="formatEur" />
2548
2581
  */
@@ -2579,7 +2612,6 @@ class UiLineChart {
2579
2612
  #frame = null;
2580
2613
  #hasRenderedOnce = false;
2581
2614
  #previousGeometry = null;
2582
- isCoreTick = isCoreTick;
2583
2615
  svgRef = viewChild.required('svgRef', /* @ts-ignore */
2584
2616
  ...(ngDevMode ? [{ debugName: "svgRef" }] : /* istanbul ignore next */ []));
2585
2617
  activeIndex = signal(null, /* @ts-ignore */
@@ -2607,6 +2639,8 @@ class UiLineChart {
2607
2639
  ...(ngDevMode ? [{ debugName: "displayLine" }] : /* istanbul ignore next */ []));
2608
2640
  ticks = computed(() => axisTicks(this.geometry().points), /* @ts-ignore */
2609
2641
  ...(ngDevMode ? [{ debugName: "ticks" }] : /* istanbul ignore next */ []));
2642
+ tickTexts = computed(() => tickLabels(this.ticks(), this.axisFormat(), this.axisTicks()), /* @ts-ignore */
2643
+ ...(ngDevMode ? [{ debugName: "tickTexts" }] : /* istanbul ignore next */ []));
2610
2644
  active = computed(() => {
2611
2645
  const geometry = this.geometry();
2612
2646
  const index = this.activeIndex();
@@ -2776,25 +2810,19 @@ class UiLineChart {
2776
2810
  [attr.cy]="geometry.end.y"
2777
2811
  />
2778
2812
 
2779
- @for (
2780
- tick of ticks();
2781
- track tick.t;
2782
- let index = $index;
2783
- let count = $count;
2784
- let first = $first;
2785
- let last = $last
2786
- ) {
2787
- <text
2788
- class="text-caption fill-(--subtle-foreground) tabular-nums"
2789
- data-chart-axis-tick
2790
- [attr.text-anchor]="first ? 'start' : last ? 'end' : 'middle'"
2791
- [attr.x]="tick.x"
2792
- [attr.y]="effectiveHeight() - 4"
2793
- [class.hidden]="axisTicks() === 3 && !isCoreTick(index, count)"
2794
- [class.max-sm:hidden]="axisTicks() === 'auto' && !isCoreTick(index, count)"
2795
- >
2796
- {{ axisFormat()(tick.t) }}
2797
- </text>
2813
+ @for (tick of ticks(); track tick.t; let index = $index; let first = $first; let last = $last) {
2814
+ @if (tickTexts()[index]; as label) {
2815
+ <text
2816
+ class="text-caption fill-(--subtle-foreground) tabular-nums"
2817
+ data-chart-axis-tick
2818
+ [attr.text-anchor]="first ? 'start' : last ? 'end' : 'middle'"
2819
+ [attr.x]="tick.x"
2820
+ [attr.y]="effectiveHeight() - 4"
2821
+ [class]="label.classes"
2822
+ >
2823
+ {{ label.text }}
2824
+ </text>
2825
+ }
2798
2826
  }
2799
2827
 
2800
2828
  @if (active(); as point) {
@@ -2924,25 +2952,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
2924
2952
  [attr.cy]="geometry.end.y"
2925
2953
  />
2926
2954
 
2927
- @for (
2928
- tick of ticks();
2929
- track tick.t;
2930
- let index = $index;
2931
- let count = $count;
2932
- let first = $first;
2933
- let last = $last
2934
- ) {
2935
- <text
2936
- class="text-caption fill-(--subtle-foreground) tabular-nums"
2937
- data-chart-axis-tick
2938
- [attr.text-anchor]="first ? 'start' : last ? 'end' : 'middle'"
2939
- [attr.x]="tick.x"
2940
- [attr.y]="effectiveHeight() - 4"
2941
- [class.hidden]="axisTicks() === 3 && !isCoreTick(index, count)"
2942
- [class.max-sm:hidden]="axisTicks() === 'auto' && !isCoreTick(index, count)"
2943
- >
2944
- {{ axisFormat()(tick.t) }}
2945
- </text>
2955
+ @for (tick of ticks(); track tick.t; let index = $index; let first = $first; let last = $last) {
2956
+ @if (tickTexts()[index]; as label) {
2957
+ <text
2958
+ class="text-caption fill-(--subtle-foreground) tabular-nums"
2959
+ data-chart-axis-tick
2960
+ [attr.text-anchor]="first ? 'start' : last ? 'end' : 'middle'"
2961
+ [attr.x]="tick.x"
2962
+ [attr.y]="effectiveHeight() - 4"
2963
+ [class]="label.classes"
2964
+ >
2965
+ {{ label.text }}
2966
+ </text>
2967
+ }
2946
2968
  }
2947
2969
 
2948
2970
  @if (active(); as point) {