@joanroucoux/cairn-ui 0.6.4 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -0
- package/fesm2022/joanroucoux-cairn-ui.mjs +1165 -212
- package/fesm2022/joanroucoux-cairn-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/styles/motion.css +83 -0
- package/styles/theme.css +6 -0
- package/styles/tokens.css +5 -0
- package/types/joanroucoux-cairn-ui.d.ts +205 -18
package/package.json
CHANGED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
@keyframes cairn-spin {
|
|
2
|
+
to {
|
|
3
|
+
transform: rotate(1turn);
|
|
4
|
+
}
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
@keyframes cairn-pulse {
|
|
8
|
+
from {
|
|
9
|
+
opacity: 1;
|
|
10
|
+
}
|
|
11
|
+
to {
|
|
12
|
+
opacity: 0.45;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@keyframes cairn-fade-in {
|
|
17
|
+
from {
|
|
18
|
+
opacity: 0;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@keyframes cairn-fade-up-in {
|
|
23
|
+
from {
|
|
24
|
+
opacity: 0;
|
|
25
|
+
transform: translateY(4px);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@keyframes cairn-panel-in {
|
|
30
|
+
from {
|
|
31
|
+
opacity: 0;
|
|
32
|
+
transform: translateX(8px);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@keyframes cairn-fade-out {
|
|
37
|
+
to {
|
|
38
|
+
opacity: 0;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.ui-enter-fade {
|
|
43
|
+
animation: cairn-fade-in var(--duration-fast) var(--ease-out);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.ui-enter-fade-up {
|
|
47
|
+
animation: cairn-fade-up-in var(--duration-fast) var(--ease-out);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.ui-enter-panel {
|
|
51
|
+
animation: cairn-panel-in var(--duration-base) var(--ease-out);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.ui-leave-fade {
|
|
55
|
+
animation: cairn-fade-out var(--duration-exit) var(--ease-out) forwards;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
::view-transition-old(root),
|
|
59
|
+
::view-transition-new(root) {
|
|
60
|
+
animation-duration: var(--duration-base);
|
|
61
|
+
animation-timing-function: var(--ease-out);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@view-transition {
|
|
65
|
+
navigation: auto;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
[data-theme-switching] * {
|
|
69
|
+
transition: none !important;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
@media (prefers-reduced-motion: reduce) {
|
|
73
|
+
.ui-enter-fade-up,
|
|
74
|
+
.ui-enter-panel {
|
|
75
|
+
animation-name: cairn-fade-in;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
::view-transition-group(*),
|
|
79
|
+
::view-transition-old(root),
|
|
80
|
+
::view-transition-new(root) {
|
|
81
|
+
animation: none;
|
|
82
|
+
}
|
|
83
|
+
}
|
package/styles/theme.css
CHANGED
|
@@ -28,4 +28,10 @@
|
|
|
28
28
|
|
|
29
29
|
--ease-out: cubic-bezier(0.23, 1, 0.32, 1);
|
|
30
30
|
--ease-sheet: cubic-bezier(0.32, 0.72, 0, 1);
|
|
31
|
+
|
|
32
|
+
--default-transition-timing-function: var(--ease-out);
|
|
33
|
+
--default-transition-duration: var(--duration-fast);
|
|
34
|
+
|
|
35
|
+
--animate-cairn-spin: cairn-spin var(--duration-spin) linear infinite;
|
|
36
|
+
--animate-cairn-pulse: cairn-pulse var(--pulse-duration) var(--ease-out) infinite alternate;
|
|
31
37
|
}
|
package/styles/tokens.css
CHANGED
|
@@ -101,6 +101,9 @@
|
|
|
101
101
|
--press-scale: 0.97;
|
|
102
102
|
--enter-scale: 0.95; /* dialogs and menus start at scale(0.95) and opacity 0, never scale(0) */
|
|
103
103
|
--pulse-duration: 1600ms; /* skeleton opacity pulse */
|
|
104
|
+
--duration-spin: 800ms; /* button spinner, one turn */
|
|
105
|
+
--duration-highlight: 1200ms; /* a freshly edited row fading back to its background */
|
|
106
|
+
--toast-duration: 5000ms; /* how long a confirmation stays */
|
|
104
107
|
|
|
105
108
|
/* Browser theme color (meta theme-color, iOS status bar) follows the top of the page:
|
|
106
109
|
light #f7f8f8, dark #0a0b0b - the --background values. */
|
|
@@ -137,6 +140,8 @@
|
|
|
137
140
|
--enter-scale: 1; /* slides and scales become short fades */
|
|
138
141
|
--duration-base: 150ms;
|
|
139
142
|
--pulse-duration: 0ms;
|
|
143
|
+
--duration-highlight: 600ms;
|
|
144
|
+
--duration-spin: 1600ms; /* the spinner still says work is in progress, only slower */
|
|
140
145
|
}
|
|
141
146
|
}
|
|
142
147
|
|
|
@@ -5,7 +5,8 @@ import { InjectionToken, Signal, ElementRef } from '@angular/core';
|
|
|
5
5
|
* Bar of actions fixed above the tab bar on iPhone: the primary actions of a detail screen, within
|
|
6
6
|
* thumb reach. It sits 52px plus the safe area above the bottom edge, so it clears `ui-tab-bar`, and
|
|
7
7
|
* it is hidden from `64rem`, where the same actions live in the page itself. Its children share the
|
|
8
|
-
* width equally.
|
|
8
|
+
* width equally. While it is on the page it publishes its height as `--action-bar-height` on the
|
|
9
|
+
* root element, which `ui-toaster` adds to its offset so a confirmation never covers the actions.
|
|
9
10
|
*
|
|
10
11
|
* @example
|
|
11
12
|
* <ui-action-bar>
|
|
@@ -14,6 +15,7 @@ import { InjectionToken, Signal, ElementRef } from '@angular/core';
|
|
|
14
15
|
* </ui-action-bar>
|
|
15
16
|
*/
|
|
16
17
|
declare class UiActionBar {
|
|
18
|
+
constructor();
|
|
17
19
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiActionBar, never>;
|
|
18
20
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiActionBar, "ui-action-bar", never, {}, {}, never, ["*"], true, never>;
|
|
19
21
|
}
|
|
@@ -22,6 +24,8 @@ declare const ALERT_VARIANTS: readonly ["error", "warning"];
|
|
|
22
24
|
type AlertVariant = (typeof ALERT_VARIANTS)[number];
|
|
23
25
|
/**
|
|
24
26
|
* Inline message explaining a failure or a consequence: an icon, an optional heading and a text.
|
|
27
|
+
* It fades in when it appears; set `[fadeIn]="false"` on an alert that is part of the page as it
|
|
28
|
+
* opens (an error state after a load), which shows without motion.
|
|
25
29
|
*
|
|
26
30
|
* @example
|
|
27
31
|
* <ui-alert heading="Sign-in failed">Try again.</ui-alert>
|
|
@@ -29,9 +33,10 @@ type AlertVariant = (typeof ALERT_VARIANTS)[number];
|
|
|
29
33
|
declare class UiAlert {
|
|
30
34
|
readonly variant: _angular_core.InputSignal<"error" | "warning">;
|
|
31
35
|
readonly heading: _angular_core.InputSignal<string | undefined>;
|
|
36
|
+
readonly fadeIn: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
32
37
|
protected readonly classes: _angular_core.Signal<string>;
|
|
33
38
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiAlert, never>;
|
|
34
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiAlert, "ui-alert", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "heading": { "alias": "heading"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
39
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiAlert, "ui-alert", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "heading": { "alias": "heading"; "required": false; "isSignal": true; }; "fadeIn": { "alias": "fadeIn"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
35
40
|
}
|
|
36
41
|
|
|
37
42
|
/** App-wide "amounts are hidden" state. Defaults to never masked; the app overrides it. */
|
|
@@ -104,6 +109,7 @@ declare class UiAsync {
|
|
|
104
109
|
readonly card: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
105
110
|
readonly fill: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
106
111
|
readonly retry: _angular_core.OutputEmitterRef<void>;
|
|
112
|
+
protected readonly shown: _angular_core.Signal<"error" | "loading" | "empty" | "ready" | null>;
|
|
107
113
|
protected readonly filling: _angular_core.Signal<boolean>;
|
|
108
114
|
protected readonly iconSize: _angular_core.Signal<16 | 18>;
|
|
109
115
|
protected readonly boxClasses: _angular_core.Signal<string>;
|
|
@@ -114,6 +120,17 @@ declare class UiAsync {
|
|
|
114
120
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiAsync, "ui-async", never, { "state": { "alias": "state"; "required": true; "isSignal": true; }; "errorTitle": { "alias": "errorTitle"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "retryLabel": { "alias": "retryLabel"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "card": { "alias": "card"; "required": false; "isSignal": true; }; "fill": { "alias": "fill"; "required": false; "isSignal": true; }; }, { "retry": "retry"; }, never, ["[asyncLoading]", "[asyncEmpty]", "*"], true, never>;
|
|
115
121
|
}
|
|
116
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Turns the live state of a call into the state to draw: `loading` only appears once the call has
|
|
125
|
+
* lasted 150 ms and, once shown, stays at least 400 ms, so a fast call never flashes a skeleton and a
|
|
126
|
+
* slow one never blinks. Until then the previous state stays on screen (a reload keeps its content);
|
|
127
|
+
* `null` means nothing to draw yet, for a first load still under 150 ms. Call it in an injection context.
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* protected readonly shown = delayedState(this.state);
|
|
131
|
+
*/
|
|
132
|
+
declare function delayedState(source: Signal<AsyncState>): Signal<AsyncState | null>;
|
|
133
|
+
|
|
117
134
|
/** Available avatar sizes. `AvatarSize` is derived from this tuple. */
|
|
118
135
|
declare const AVATAR_SIZES: readonly ["sm", "md", "lg", "auto"];
|
|
119
136
|
type AvatarSize = (typeof AVATAR_SIZES)[number];
|
|
@@ -341,6 +358,9 @@ type LayoutClasses = {
|
|
|
341
358
|
body: string;
|
|
342
359
|
footer: string;
|
|
343
360
|
};
|
|
361
|
+
/** What started a close, as `closed` reports it. `DialogCloseReason` is derived from this tuple. */
|
|
362
|
+
declare const DIALOG_CLOSE_REASONS: readonly ["escape", "backdrop", "cross", "drag", "programmatic"];
|
|
363
|
+
type DialogCloseReason = (typeof DIALOG_CLOSE_REASONS)[number];
|
|
344
364
|
/**
|
|
345
365
|
* Modal dialog on the native <dialog>: a bottom sheet under `64rem`, centered above it.
|
|
346
366
|
*
|
|
@@ -356,11 +376,12 @@ declare class UiDialog {
|
|
|
356
376
|
readonly heading: _angular_core.InputSignal<string>;
|
|
357
377
|
readonly description: _angular_core.InputSignal<string | undefined>;
|
|
358
378
|
readonly closeLabel: _angular_core.InputSignal<string | undefined>;
|
|
359
|
-
readonly layout: _angular_core.InputSignal<"list" | "
|
|
379
|
+
readonly layout: _angular_core.InputSignal<"list" | "form" | "trade" | "confirm">;
|
|
360
380
|
readonly truncateDescription: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
361
381
|
readonly width: _angular_core.InputSignal<"md" | "lg" | (string & {})>;
|
|
362
382
|
readonly open: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
363
383
|
readonly dismissed: _angular_core.OutputEmitterRef<void>;
|
|
384
|
+
readonly closed: _angular_core.OutputEmitterRef<"drag" | "escape" | "backdrop" | "cross" | "programmatic">;
|
|
364
385
|
protected readonly headingId: string;
|
|
365
386
|
protected readonly descriptionId: string;
|
|
366
387
|
protected readonly bodyId: string;
|
|
@@ -375,11 +396,13 @@ declare class UiDialog {
|
|
|
375
396
|
protected readonly footerClasses: _angular_core.Signal<string>;
|
|
376
397
|
protected readonly classes: _angular_core.Signal<string>;
|
|
377
398
|
constructor();
|
|
399
|
+
protected close(reason: DialogCloseReason): void;
|
|
400
|
+
protected onCancel(event: Event): void;
|
|
378
401
|
protected onPointerDown(event: MouseEvent): void;
|
|
379
402
|
protected onClick(event: MouseEvent): void;
|
|
380
403
|
protected onNativeClose(): void;
|
|
381
404
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiDialog, never>;
|
|
382
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiDialog, "ui-dialog", never, { "heading": { "alias": "heading"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "closeLabel": { "alias": "closeLabel"; "required": false; "isSignal": true; }; "layout": { "alias": "layout"; "required": false; "isSignal": true; }; "truncateDescription": { "alias": "truncateDescription"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; }, { "dismissed": "dismissed"; }, never, ["*", "[dialogActions]"], true, never>;
|
|
405
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiDialog, "ui-dialog", never, { "heading": { "alias": "heading"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "closeLabel": { "alias": "closeLabel"; "required": false; "isSignal": true; }; "layout": { "alias": "layout"; "required": false; "isSignal": true; }; "truncateDescription": { "alias": "truncateDescription"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; }, { "dismissed": "dismissed"; "closed": "closed"; }, never, ["*", "[dialogActions]"], true, never>;
|
|
383
406
|
}
|
|
384
407
|
|
|
385
408
|
type DonutSlice = {
|
|
@@ -423,7 +446,7 @@ declare class UiDonut {
|
|
|
423
446
|
protected readonly radius = 78;
|
|
424
447
|
protected readonly ringWidth = 30;
|
|
425
448
|
protected strokeColor(slice: RankedSlice): string;
|
|
426
|
-
protected
|
|
449
|
+
protected sliceClasses(slice: RankedSlice): string;
|
|
427
450
|
protected dotClasses(slice: RankedSlice): string;
|
|
428
451
|
protected rowClasses(slice: RankedSlice): string;
|
|
429
452
|
protected subLabel(slice: RankedSlice): string;
|
|
@@ -437,6 +460,22 @@ declare class UiDonut {
|
|
|
437
460
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiDonut, "ui-donut", never, { "slices": { "alias": "slices"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "othersLabel": { "alias": "othersLabel"; "required": true; "isSignal": true; }; "valueFormat": { "alias": "valueFormat"; "required": false; "isSignal": true; }; "shareFormat": { "alias": "shareFormat"; "required": false; "isSignal": true; }; "legendHref": { "alias": "legendHref"; "required": false; "isSignal": true; }; }, { "sliceSelect": "sliceSelect"; }, never, never, true, never>;
|
|
438
461
|
}
|
|
439
462
|
|
|
463
|
+
/**
|
|
464
|
+
* Centred empty state: a title, a hint and an action slot, such as a catalogue search that matches
|
|
465
|
+
* nothing. The padding is 24px, 48px from 64rem.
|
|
466
|
+
*
|
|
467
|
+
* @example
|
|
468
|
+
* <ui-empty heading="Aucun instrument ne correspond à « zzz »" hint="La recherche porte sur le nom et l'ISIN.">
|
|
469
|
+
* <button ui-button variant="outline" size="md" type="button">Ajouter une ligne</button>
|
|
470
|
+
* </ui-empty>
|
|
471
|
+
*/
|
|
472
|
+
declare class UiEmpty {
|
|
473
|
+
readonly heading: _angular_core.InputSignal<string>;
|
|
474
|
+
readonly hint: _angular_core.InputSignal<string>;
|
|
475
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiEmpty, never>;
|
|
476
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiEmpty, "ui-empty", never, { "heading": { "alias": "heading"; "required": true; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
477
|
+
}
|
|
478
|
+
|
|
440
479
|
/**
|
|
441
480
|
* Link to another site: the label followed by an external-link icon. A 44px target on touch,
|
|
442
481
|
* an underline on hover with a mouse.
|
|
@@ -636,10 +675,6 @@ declare class UiTextarea implements UiControl {
|
|
|
636
675
|
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiTextarea, "textarea[uiTextarea]", never, { "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
637
676
|
}
|
|
638
677
|
|
|
639
|
-
declare const TOOLTIP_SIZES: readonly ["compact", "large"];
|
|
640
|
-
type TooltipSize = (typeof TOOLTIP_SIZES)[number];
|
|
641
|
-
type AxisTicks = 3 | 5 | 'auto';
|
|
642
|
-
|
|
643
678
|
type ChartPoint = {
|
|
644
679
|
t: number;
|
|
645
680
|
v: number;
|
|
@@ -662,10 +697,26 @@ type ChartGeometry = {
|
|
|
662
697
|
plotTop: number;
|
|
663
698
|
};
|
|
664
699
|
|
|
700
|
+
type TickLabel = {
|
|
701
|
+
text: string;
|
|
702
|
+
classes: string;
|
|
703
|
+
};
|
|
704
|
+
|
|
705
|
+
declare const TOOLTIP_SIZES: readonly ["compact", "large"];
|
|
706
|
+
type TooltipSize = (typeof TOOLTIP_SIZES)[number];
|
|
707
|
+
type AxisTicks = 3 | 5 | 'auto';
|
|
708
|
+
|
|
665
709
|
type PlotRef = ElementRef<SVGSVGElement>;
|
|
710
|
+
type LineRef = ElementRef<SVGPathElement>;
|
|
711
|
+
type EndRef = ElementRef<SVGCircleElement>;
|
|
666
712
|
/**
|
|
667
713
|
* Value over time: a monotone curve with a dashed line at the starting value and a tooltip.
|
|
668
714
|
*
|
|
715
|
+
* Axis labels are never repeated: a tick whose `axisFormat` text equals the previous drawn label is
|
|
716
|
+
* not rendered. The first tick always is, so only the last edge label can drop. With `axisTicks="3"`
|
|
717
|
+
* only the first, middle and last ticks count; with `auto` every tick counts from `sm` up and the
|
|
718
|
+
* three core ticks below it. Tick positions are unchanged.
|
|
719
|
+
*
|
|
669
720
|
* @example
|
|
670
721
|
* <ui-line-chart [points]="points" label="Net worth over one month" startLabel="Since" [valueFormat]="formatEur" />
|
|
671
722
|
*/
|
|
@@ -686,10 +737,11 @@ declare class UiLineChart {
|
|
|
686
737
|
readonly tooltipDelta: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
687
738
|
readonly axisGap: _angular_core.InputSignal<number | "auto">;
|
|
688
739
|
readonly axisTicks: _angular_core.InputSignalWithTransform<AxisTicks, string | 3 | 5>;
|
|
689
|
-
protected readonly isCoreTick: (index: number, count: number) => boolean;
|
|
690
740
|
protected readonly svgRef: _angular_core.Signal<PlotRef>;
|
|
741
|
+
protected readonly lineRef: _angular_core.Signal<LineRef | undefined>;
|
|
742
|
+
protected readonly endRef: _angular_core.Signal<EndRef | undefined>;
|
|
691
743
|
protected readonly activeIndex: _angular_core.WritableSignal<number | null>;
|
|
692
|
-
protected readonly
|
|
744
|
+
protected readonly held: _angular_core.WritableSignal<ChartGeometry | null>;
|
|
693
745
|
protected readonly measuredSize: _angular_core.WritableSignal<{
|
|
694
746
|
width: number;
|
|
695
747
|
height: number;
|
|
@@ -704,8 +756,10 @@ declare class UiLineChart {
|
|
|
704
756
|
delta: string;
|
|
705
757
|
}>;
|
|
706
758
|
protected readonly geometry: _angular_core.Signal<ChartGeometry | null>;
|
|
707
|
-
protected readonly
|
|
759
|
+
protected readonly shown: _angular_core.Signal<ChartGeometry | null>;
|
|
760
|
+
protected readonly startFade: _angular_core.Signal<"opacity-0 duration-(--duration-exit)" | "duration-(--duration-fast)">;
|
|
708
761
|
protected readonly ticks: _angular_core.Signal<PlottedPoint[]>;
|
|
762
|
+
protected readonly tickTexts: _angular_core.Signal<(TickLabel | null)[]>;
|
|
709
763
|
protected readonly active: _angular_core.Signal<PlottedPoint | null>;
|
|
710
764
|
protected readonly startLabelInfo: _angular_core.Signal<{
|
|
711
765
|
label: string;
|
|
@@ -805,7 +859,7 @@ declare class UiMeter {
|
|
|
805
859
|
readonly value: _angular_core.InputSignal<number>;
|
|
806
860
|
readonly label: _angular_core.InputSignal<string>;
|
|
807
861
|
readonly valueText: _angular_core.InputSignal<string>;
|
|
808
|
-
readonly tone: _angular_core.InputSignal<2 | 4 |
|
|
862
|
+
readonly tone: _angular_core.InputSignal<2 | 4 | 1 | 3 | 6 | 5>;
|
|
809
863
|
readonly size: _angular_core.InputSignal<"sm" | "md">;
|
|
810
864
|
protected readonly trackClasses: _angular_core.Signal<string>;
|
|
811
865
|
protected readonly percent: _angular_core.Signal<number>;
|
|
@@ -814,6 +868,74 @@ declare class UiMeter {
|
|
|
814
868
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiMeter, "ui-meter", never, { "value": { "alias": "value"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "valueText": { "alias": "valueText"; "required": true; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
815
869
|
}
|
|
816
870
|
|
|
871
|
+
/**
|
|
872
|
+
* Slides the remaining children of a list into place when one is removed or inserted (FLIP): it
|
|
873
|
+
* measures every child before and after the change, then animates the shift in `translateY` over
|
|
874
|
+
* `--duration-base` `--ease-out`. Pair it with `animate.leave="ui-leave-fade"` on the item so it fades
|
|
875
|
+
* out first. Nothing moves under `prefers-reduced-motion`: the list closes up at once.
|
|
876
|
+
*
|
|
877
|
+
* @example
|
|
878
|
+
* <ul uiFlipList>
|
|
879
|
+
* @for (key of keys(); track key.id) {
|
|
880
|
+
* <li uiListRow animate.leave="ui-leave-fade">...</li>
|
|
881
|
+
* }
|
|
882
|
+
* </ul>
|
|
883
|
+
*/
|
|
884
|
+
declare class UiFlipList {
|
|
885
|
+
private readonly host;
|
|
886
|
+
private readonly reduced;
|
|
887
|
+
private readonly mutations;
|
|
888
|
+
private readonly resizes;
|
|
889
|
+
private readonly running;
|
|
890
|
+
private readonly watched;
|
|
891
|
+
private tops;
|
|
892
|
+
constructor();
|
|
893
|
+
private measure;
|
|
894
|
+
private interruptedOffset;
|
|
895
|
+
private onChange;
|
|
896
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiFlipList, never>;
|
|
897
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiFlipList, "[uiFlipList]", never, {}, {}, never, never, true, never>;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
/**
|
|
901
|
+
* Draws the eye to an element that just changed: scrolls it into view when it is off screen, holds the
|
|
902
|
+
* `--soft` fill for 200 ms, then fades back to the element's own background over `--duration-highlight`.
|
|
903
|
+
* Each new non-null token plays once, so pass a fresh value per event (an object or a counter), not a
|
|
904
|
+
* boolean. A non-null token already present at first render plays on arrival. On a `tr` it paints the
|
|
905
|
+
* cells, on a `td[ui-group-cell]` the band, anywhere else the host. Under `prefers-reduced-motion` the
|
|
906
|
+
* scroll is instant and the fade lasts 600 ms.
|
|
907
|
+
*
|
|
908
|
+
* Give the element `scroll-margin-top` and `scroll-margin-bottom` equal to what is pinned above and
|
|
909
|
+
* below it (header, tab bar, action bar): a row under them counts as off screen and is scrolled out.
|
|
910
|
+
* For an arrival on a page opened at the element, scroll to it at once first (`scrollIntoView` in
|
|
911
|
+
* `afterNextRender`) and set the token afterwards: a token present at first render scrolls smoothly
|
|
912
|
+
* from where the page is.
|
|
913
|
+
*
|
|
914
|
+
* @example
|
|
915
|
+
* <a ui-row [uiHighlight]="changed() === holding.id ? token() : null" routerLink="/holdings/1">...</a>
|
|
916
|
+
*/
|
|
917
|
+
declare class UiHighlight {
|
|
918
|
+
readonly uiHighlight: _angular_core.InputSignal<unknown>;
|
|
919
|
+
private readonly host;
|
|
920
|
+
private readonly reduced;
|
|
921
|
+
private cancel;
|
|
922
|
+
constructor();
|
|
923
|
+
private play;
|
|
924
|
+
private isVisible;
|
|
925
|
+
private flash;
|
|
926
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiHighlight, never>;
|
|
927
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiHighlight, "[uiHighlight]", never, { "uiHighlight": { "alias": "uiHighlight"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
/**
|
|
931
|
+
* A signal that follows the user's `prefers-reduced-motion` preference live.
|
|
932
|
+
* Call it in an injection context; the listener is removed with that context.
|
|
933
|
+
*
|
|
934
|
+
* @example
|
|
935
|
+
* protected readonly reduced = injectReducedMotion();
|
|
936
|
+
*/
|
|
937
|
+
declare function injectReducedMotion(): Signal<boolean>;
|
|
938
|
+
|
|
817
939
|
/**
|
|
818
940
|
* One destination of the sidebar navigation (Portfolio, Holdings, Allocation, Accounts).
|
|
819
941
|
*
|
|
@@ -837,7 +959,7 @@ type RowPadding = (typeof ROW_PADDINGS)[number];
|
|
|
837
959
|
declare const ROW_GAPS: readonly ["default", "sm"];
|
|
838
960
|
type RowGap = (typeof ROW_GAPS)[number];
|
|
839
961
|
/**
|
|
840
|
-
* Clickable row of a list: a holding, an
|
|
962
|
+
* Clickable row of a list: a holding, an account, a search result.
|
|
841
963
|
*
|
|
842
964
|
* @example
|
|
843
965
|
* <a ui-row [selected]="holding.id === openId()" [routerLink]="['/holdings', holding.id]">
|
|
@@ -846,12 +968,15 @@ type RowGap = (typeof ROW_GAPS)[number];
|
|
|
846
968
|
*/
|
|
847
969
|
declare class UiRow {
|
|
848
970
|
readonly selected: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
971
|
+
readonly busy: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
972
|
+
readonly unavailable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
849
973
|
readonly size: _angular_core.InputSignal<"md" | "lg" | "xl" | "card" | "dense">;
|
|
850
974
|
readonly padding: _angular_core.InputSignal<"sm" | "md" | "none">;
|
|
851
975
|
readonly gap: _angular_core.InputSignal<"sm" | "default">;
|
|
852
976
|
protected readonly classes: _angular_core.Signal<string>;
|
|
977
|
+
constructor();
|
|
853
978
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiRow, never>;
|
|
854
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiRow, "a[ui-row], button[ui-row]", never, { "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "padding": { "alias": "padding"; "required": false; "isSignal": true; }; "gap": { "alias": "gap"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
979
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiRow, "a[ui-row], button[ui-row]", never, { "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "busy": { "alias": "busy"; "required": false; "isSignal": true; }; "unavailable": { "alias": "unavailable"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "padding": { "alias": "padding"; "required": false; "isSignal": true; }; "gap": { "alias": "gap"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
855
980
|
}
|
|
856
981
|
/**
|
|
857
982
|
* Lays out a `ui-row` with a trailing action beside it, such as a "more" icon button: the row takes
|
|
@@ -972,6 +1097,21 @@ declare class UiSkeleton {
|
|
|
972
1097
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiSkeleton, "ui-skeleton", never, { "shape": { "alias": "shape"; "required": false; "isSignal": true; }; "lines": { "alias": "lines"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
973
1098
|
}
|
|
974
1099
|
|
|
1100
|
+
/**
|
|
1101
|
+
* Link in the stale tone, for a caption about data that is late or left out of a total, such as
|
|
1102
|
+
* "1 ligne sans cours, non comptée". Caption size, weight 500, underlined on hover, with an optional
|
|
1103
|
+
* trailing chevron.
|
|
1104
|
+
*
|
|
1105
|
+
* @example
|
|
1106
|
+
* <a uiStaleLink chevron routerLink="/holdings">1 cours en retard</a>
|
|
1107
|
+
*/
|
|
1108
|
+
declare class UiStaleLink {
|
|
1109
|
+
readonly chevron: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1110
|
+
protected readonly classes: _angular_core.Signal<"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)" | "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) 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)]">;
|
|
1111
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiStaleLink, never>;
|
|
1112
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiStaleLink, "a[uiStaleLink]", never, { "chevron": { "alias": "chevron"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
1113
|
+
}
|
|
1114
|
+
|
|
975
1115
|
/** Available stat sizes. `StatSize` is derived from this tuple. */
|
|
976
1116
|
declare const STAT_SIZES: readonly ["hero", "tile"];
|
|
977
1117
|
type StatSize = (typeof STAT_SIZES)[number];
|
|
@@ -1008,7 +1148,7 @@ declare class UiStat {
|
|
|
1008
1148
|
* <input type="checkbox" uiSwitch [checked]="hidden()" (change)="toggle()" aria-label="Hide amounts" />
|
|
1009
1149
|
*/
|
|
1010
1150
|
declare class UiSwitch {
|
|
1011
|
-
protected readonly classes = "relative shrink-0 w-[51px] h-[31px] pointer-fine:w-10 pointer-fine:h-6 appearance-none cursor-pointer rounded-pill bg-(--muted) checked:bg-(--primary) transition-
|
|
1151
|
+
protected readonly classes = "relative shrink-0 w-[51px] h-[31px] pointer-fine:w-10 pointer-fine:h-6 appearance-none cursor-pointer rounded-pill bg-(--muted) checked:bg-(--primary) transition-[background-color] duration-(--duration-fast) ease-out disabled:pointer-events-none disabled:opacity-40 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring) before:absolute before:inset-x-0 before:top-1/2 before:-translate-y-1/2 before:h-(--row-min) before:content-[''] after:absolute after:top-0.5 after:left-0.5 after:size-[27px] pointer-fine:after:size-5 after:rounded-pill after:bg-(--card) after:shadow-[0_1px_3px_rgb(0_0_0/0.2)] after:transition-transform after:duration-(--duration-fast) after:ease-out after:content-[''] checked:after:translate-x-[20px] pointer-fine:checked:after:translate-x-4";
|
|
1012
1152
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiSwitch, never>;
|
|
1013
1153
|
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiSwitch, "input[type=checkbox][uiSwitch]", never, {}, {}, never, never, true, never>;
|
|
1014
1154
|
}
|
|
@@ -1038,6 +1178,53 @@ declare class UiTab {
|
|
|
1038
1178
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiTab, "a[ui-tab]", never, { "active": { "alias": "active"; "required": false; "isSignal": true; }; }, {}, never, ["[tabIcon]", "*"], true, never>;
|
|
1039
1179
|
}
|
|
1040
1180
|
|
|
1181
|
+
type Toast = {
|
|
1182
|
+
readonly id: number;
|
|
1183
|
+
readonly text: string;
|
|
1184
|
+
};
|
|
1185
|
+
/**
|
|
1186
|
+
* One-slot confirmation message queue read by `ui-toaster`.
|
|
1187
|
+
*
|
|
1188
|
+
* @example
|
|
1189
|
+
* inject(UiToasts).show('Achat enregistré');
|
|
1190
|
+
*/
|
|
1191
|
+
declare class UiToasts {
|
|
1192
|
+
private readonly current;
|
|
1193
|
+
private sequence;
|
|
1194
|
+
readonly toast: _angular_core.Signal<Toast | null>;
|
|
1195
|
+
show(message: string): void;
|
|
1196
|
+
dismiss(): void;
|
|
1197
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiToasts, never>;
|
|
1198
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<any>;
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
/**
|
|
1202
|
+
* Confirmation message shown by `UiToasts.show`: one at a time, no action, gone after `--toast-duration`.
|
|
1203
|
+
* Place it once in the app shell.
|
|
1204
|
+
*
|
|
1205
|
+
* @example
|
|
1206
|
+
* <ui-toaster />
|
|
1207
|
+
*/
|
|
1208
|
+
declare class UiToaster {
|
|
1209
|
+
protected readonly toasts: UiToasts;
|
|
1210
|
+
protected readonly toastClasses = "pointer-events-auto max-w-[min(28rem,calc(100vw-2rem))] rounded-container bg-(--elevated) px-4 py-3 text-label text-(--foreground) shadow-[0_8px_24px_rgb(0_0_0/0.16),inset_0_0_0_1px_var(--border)] transition-[opacity,translate] duration-(--duration-base) ease-out starting:opacity-0 starting:translate-y-2 motion-reduce:starting:translate-y-0";
|
|
1211
|
+
private readonly host;
|
|
1212
|
+
private readonly hovered;
|
|
1213
|
+
private readonly focused;
|
|
1214
|
+
private lastId;
|
|
1215
|
+
private remaining;
|
|
1216
|
+
private startedAt;
|
|
1217
|
+
private timer;
|
|
1218
|
+
constructor();
|
|
1219
|
+
protected setHovered(value: boolean): void;
|
|
1220
|
+
protected setFocused(value: boolean): void;
|
|
1221
|
+
private resume;
|
|
1222
|
+
private pause;
|
|
1223
|
+
private stop;
|
|
1224
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiToaster, never>;
|
|
1225
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiToaster, "ui-toaster", never, {}, {}, never, never, true, never>;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1041
1228
|
/** Breakpoints a secondary column can be held back until. */
|
|
1042
1229
|
declare const CELL_BREAKPOINTS: readonly ["md", "lg"];
|
|
1043
1230
|
type CellBreakpoint = (typeof CELL_BREAKPOINTS)[number];
|
|
@@ -1172,5 +1359,5 @@ declare class UiCellSub {
|
|
|
1172
1359
|
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiCellSub, "[uiCellSub]", never, { "narrow": { "alias": "narrow"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
1173
1360
|
}
|
|
1174
1361
|
|
|
1175
|
-
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_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, UiExternalLink, UiFact, UiFacts, UiField, UiFieldLeading, UiFieldTrailing, UiFilterChips, UiGroup, UiGroupCell, UiInput, UiLineChart, UiListRow, UiMenu, UiMenuItem, UiMenuTrigger, UiMeter, UiNavItem, UiRow, UiRowAction, UiRowItem, UiRowLink, UiRowTile, UiSegmented, UiSelect, UiSkeleton, UiStat, UiSwitch, UiTab, UiTabBar, UiTable, UiTd, UiTextarea, UiTh, UiTr, formatAmount };
|
|
1176
|
-
export type { AlertVariant, AmountFormatOptions, AmountMasking, AmountNumeric, AsyncAlign, AsyncState, AsyncVariant, AvatarSize, AxisTicks, BackLinkSize, BadgeSize, BadgeVariant, ButtonSize, ButtonVariant, CardPadding, CardSurface, CardVariant, CellBreakpoint, ChartPoint, ChoiceChipOption, ControlSize, ControlSurface, DeltaEmphasis, DeltaSize, DeltaWeight, DialogLayout, DialogWidth, DonutSlice, FactSize, FactSubTone, FilterChipOption, GroupSize, MeterSize, MeterTone, RowGap, RowPadding, RowSize, SegmentedOption, SegmentedSize, SkeletonShape, StatSize, SubTone, TableRow, TooltipSize, UiControlError };
|
|
1362
|
+
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, 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 };
|
|
1363
|
+
export type { AlertVariant, AmountFormatOptions, AmountMasking, AmountNumeric, AsyncAlign, AsyncState, AsyncVariant, AvatarSize, AxisTicks, BackLinkSize, BadgeSize, BadgeVariant, ButtonSize, ButtonVariant, CardPadding, CardSurface, CardVariant, CellBreakpoint, ChartPoint, ChoiceChipOption, ControlSize, ControlSurface, DeltaEmphasis, DeltaSize, DeltaWeight, DialogCloseReason, DialogLayout, DialogWidth, DonutSlice, FactSize, FactSubTone, FilterChipOption, GroupSize, MeterSize, MeterTone, RowGap, RowPadding, RowSize, SegmentedOption, SegmentedSize, SkeletonShape, StatSize, SubTone, TableRow, Toast, TooltipSize, UiControlError };
|