@joanroucoux/cairn-ui 0.6.0 → 0.6.1
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.
|
@@ -1,115 +1,38 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, signal,
|
|
2
|
+
import { Component, input, computed, InjectionToken, signal, inject, LOCALE_ID, booleanAttribute, output, Directive, ElementRef, DestroyRef, forwardRef, model, viewChildren, afterNextRender, afterRenderEffect, contentChild, viewChild, effect, numberAttribute, contentChildren } from '@angular/core';
|
|
3
|
+
import { NgTemplateOutlet } from '@angular/common';
|
|
3
4
|
import { scaleLinear } from 'd3-scale';
|
|
4
5
|
import { curveMonotoneX, line } from 'd3-shape';
|
|
5
6
|
|
|
6
|
-
const MINUS = '−';
|
|
7
|
-
const EM_DASH = '—';
|
|
8
|
-
const BULLETS = '••••';
|
|
9
|
-
/** Formats a number or an amount for the locale, with a missing value as an em dash and masking behind four bullets. */
|
|
10
|
-
function formatAmount(value, options, masked = false) {
|
|
11
|
-
if (value === null || value === undefined || Number.isNaN(value)) {
|
|
12
|
-
return EM_DASH;
|
|
13
|
-
}
|
|
14
|
-
const digits = options.fractionDigits ?? 2;
|
|
15
|
-
const format = new Intl.NumberFormat(options.locale, {
|
|
16
|
-
...(options.currency ? { style: 'currency', currency: options.currency } : {}),
|
|
17
|
-
minimumFractionDigits: digits,
|
|
18
|
-
maximumFractionDigits: digits,
|
|
19
|
-
});
|
|
20
|
-
const magnitude = Math.abs(value);
|
|
21
|
-
const parts = format.formatToParts(magnitude);
|
|
22
|
-
if (masked) {
|
|
23
|
-
let replaced = false;
|
|
24
|
-
return parts
|
|
25
|
-
.map((part) => {
|
|
26
|
-
if (['integer', 'group', 'decimal', 'fraction'].includes(part.type)) {
|
|
27
|
-
if (replaced) {
|
|
28
|
-
return '';
|
|
29
|
-
}
|
|
30
|
-
replaced = true;
|
|
31
|
-
return BULLETS;
|
|
32
|
-
}
|
|
33
|
-
return part.value;
|
|
34
|
-
})
|
|
35
|
-
.join('');
|
|
36
|
-
}
|
|
37
|
-
const text = parts.map((part) => part.value).join('');
|
|
38
|
-
const isZero = Number(format.format(magnitude).replace(/[^\d]/g, '')) === 0;
|
|
39
|
-
if (!options.signed || isZero) {
|
|
40
|
-
return value < 0 && !isZero ? `${MINUS}${text}` : text;
|
|
41
|
-
}
|
|
42
|
-
return `${value > 0 ? '+' : MINUS}${text}`;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** App-wide "amounts are hidden" state. Defaults to never masked; the app overrides it. */
|
|
46
|
-
const UI_AMOUNT_MASKED = new InjectionToken('UI_AMOUNT_MASKED', {
|
|
47
|
-
providedIn: 'root',
|
|
48
|
-
factory: () => signal(false),
|
|
49
|
-
});
|
|
50
|
-
/** Available figure styles. `AmountNumeric` is derived from this tuple. */
|
|
51
|
-
const AMOUNT_NUMERICS = ['tabular', 'proportional'];
|
|
52
|
-
/** Available masking behaviors. `AmountMasking` is derived from this tuple. */
|
|
53
|
-
const AMOUNT_MASKINGS = ['dots', 'hide'];
|
|
54
7
|
/**
|
|
55
|
-
*
|
|
8
|
+
* Bar of actions fixed above the tab bar on iPhone: the primary actions of a detail screen, within
|
|
9
|
+
* thumb reach. It sits 52px plus the safe area above the bottom edge, so it clears `ui-tab-bar`, and
|
|
10
|
+
* it is hidden from `64rem`, where the same actions live in the page itself. Its children share the
|
|
11
|
+
* width equally.
|
|
56
12
|
*
|
|
57
13
|
* @example
|
|
58
|
-
* <ui-
|
|
59
|
-
*
|
|
14
|
+
* <ui-action-bar>
|
|
15
|
+
* <button ui-button variant="outline" size="tall">Sell</button>
|
|
16
|
+
* <button ui-button size="tall">Buy</button>
|
|
17
|
+
* </ui-action-bar>
|
|
60
18
|
*/
|
|
61
|
-
class
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
currency = input(/* @ts-ignore */
|
|
65
|
-
...(ngDevMode ? [undefined, { debugName: "currency" }] : /* istanbul ignore next */ []));
|
|
66
|
-
locale = input(inject(LOCALE_ID), /* @ts-ignore */
|
|
67
|
-
...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
68
|
-
signed = input(false, { ...(ngDevMode ? { debugName: "signed" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
69
|
-
fractionDigits = input(2, /* @ts-ignore */
|
|
70
|
-
...(ngDevMode ? [{ debugName: "fractionDigits" }] : /* istanbul ignore next */ []));
|
|
71
|
-
numeric = input('tabular', /* @ts-ignore */
|
|
72
|
-
...(ngDevMode ? [{ debugName: "numeric" }] : /* istanbul ignore next */ []));
|
|
73
|
-
whenMasked = input('dots', /* @ts-ignore */
|
|
74
|
-
...(ngDevMode ? [{ debugName: "whenMasked" }] : /* istanbul ignore next */ []));
|
|
75
|
-
#masked = inject(UI_AMOUNT_MASKED);
|
|
76
|
-
hidden = computed(() => this.#masked() && this.whenMasked() === 'hide', /* @ts-ignore */
|
|
77
|
-
...(ngDevMode ? [{ debugName: "hidden" }] : /* istanbul ignore next */ []));
|
|
78
|
-
text = computed(() => formatAmount(this.value(), {
|
|
79
|
-
locale: this.locale(),
|
|
80
|
-
currency: this.currency(),
|
|
81
|
-
signed: this.signed(),
|
|
82
|
-
fractionDigits: this.fractionDigits(),
|
|
83
|
-
}, this.#masked()), /* @ts-ignore */
|
|
84
|
-
...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
|
|
85
|
-
classes = computed(() => {
|
|
86
|
-
const missing = this.value() === null || this.value() === undefined;
|
|
87
|
-
return [
|
|
88
|
-
'whitespace-nowrap',
|
|
89
|
-
this.numeric() === 'tabular' ? 'tabular-nums' : '',
|
|
90
|
-
missing ? 'text-(--subtle-foreground)' : '',
|
|
91
|
-
]
|
|
92
|
-
.filter(Boolean)
|
|
93
|
-
.join(' ');
|
|
94
|
-
}, /* @ts-ignore */
|
|
95
|
-
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
96
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiAmount, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
97
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UiAmount, isStandalone: true, selector: "ui-amount", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, currency: { classPropertyName: "currency", publicName: "currency", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, signed: { classPropertyName: "signed", publicName: "signed", isSignal: true, isRequired: false, transformFunction: null }, fractionDigits: { classPropertyName: "fractionDigits", publicName: "fractionDigits", isSignal: true, isRequired: false, transformFunction: null }, numeric: { classPropertyName: "numeric", publicName: "numeric", isSignal: true, isRequired: false, transformFunction: null }, whenMasked: { classPropertyName: "whenMasked", publicName: "whenMasked", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()", "attr.hidden": "hidden() || null" } }, ngImport: i0, template: '{{ text() }}', isInline: true });
|
|
19
|
+
class UiActionBar {
|
|
20
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiActionBar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
21
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.7", type: UiActionBar, isStandalone: true, selector: "ui-action-bar", host: { classAttribute: "fixed inset-x-0 bottom-[calc(52px+env(safe-area-inset-bottom))] z-40 grid grid-flow-col auto-cols-fr gap-2 bg-(--background) px-(--gutter) py-3 shadow-[0_-1px_0_var(--hairline)] lg:hidden" }, ngImport: i0, template: '<ng-content />', isInline: true });
|
|
98
22
|
}
|
|
99
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type:
|
|
23
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiActionBar, decorators: [{
|
|
100
24
|
type: Component,
|
|
101
25
|
args: [{
|
|
102
|
-
selector: 'ui-
|
|
103
|
-
template: '
|
|
26
|
+
selector: 'ui-action-bar',
|
|
27
|
+
template: '<ng-content />',
|
|
104
28
|
host: {
|
|
105
|
-
|
|
106
|
-
'[attr.hidden]': 'hidden() || null',
|
|
29
|
+
class: 'fixed inset-x-0 bottom-[calc(52px+env(safe-area-inset-bottom))] z-40 grid grid-flow-col auto-cols-fr gap-2 bg-(--background) px-(--gutter) py-3 shadow-[0_-1px_0_var(--hairline)] lg:hidden',
|
|
107
30
|
},
|
|
108
31
|
}]
|
|
109
|
-
}]
|
|
32
|
+
}] });
|
|
110
33
|
|
|
111
34
|
const ALERT_VARIANTS = ['error', 'warning'];
|
|
112
|
-
const BASE_CLASSES$
|
|
35
|
+
const BASE_CLASSES$8 = 'flex items-start gap-2.5 text-left text-label';
|
|
113
36
|
const VARIANT_CLASSES$3 = {
|
|
114
37
|
error: 'rounded-control bg-(--card) px-3.5 py-3 shadow-[inset_0_0_0_1px_var(--border)]',
|
|
115
38
|
warning: 'text-(--foreground)',
|
|
@@ -125,7 +48,7 @@ class UiAlert {
|
|
|
125
48
|
...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
126
49
|
heading = input(/* @ts-ignore */
|
|
127
50
|
...(ngDevMode ? [undefined, { debugName: "heading" }] : /* istanbul ignore next */ []));
|
|
128
|
-
classes = computed(() => `${BASE_CLASSES$
|
|
51
|
+
classes = computed(() => `${BASE_CLASSES$8} ${VARIANT_CLASSES$3[this.variant()]}`, /* @ts-ignore */
|
|
129
52
|
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
130
53
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiAlert, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
131
54
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiAlert, isStandalone: true, selector: "ui-alert", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()", "attr.role": "variant() === 'warning' ? 'status' : 'alert'" } }, ngImport: i0, template: `
|
|
@@ -224,9 +147,167 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
224
147
|
}]
|
|
225
148
|
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }] } });
|
|
226
149
|
|
|
150
|
+
const MINUS = '−';
|
|
151
|
+
const EM_DASH = '—';
|
|
152
|
+
const BULLETS = '••••';
|
|
153
|
+
/** Formats a number or an amount for the locale, with a missing value as an em dash and masking behind four bullets. */
|
|
154
|
+
function formatAmount(value, options, masked = false) {
|
|
155
|
+
if (value === null || value === undefined || Number.isNaN(value)) {
|
|
156
|
+
return EM_DASH;
|
|
157
|
+
}
|
|
158
|
+
const digits = options.fractionDigits ?? 2;
|
|
159
|
+
const format = new Intl.NumberFormat(options.locale, {
|
|
160
|
+
...(options.currency ? { style: 'currency', currency: options.currency } : {}),
|
|
161
|
+
minimumFractionDigits: digits,
|
|
162
|
+
maximumFractionDigits: digits,
|
|
163
|
+
});
|
|
164
|
+
const magnitude = Math.abs(value);
|
|
165
|
+
const parts = format.formatToParts(magnitude);
|
|
166
|
+
if (masked) {
|
|
167
|
+
let replaced = false;
|
|
168
|
+
return parts
|
|
169
|
+
.map((part) => {
|
|
170
|
+
if (['integer', 'group', 'decimal', 'fraction'].includes(part.type)) {
|
|
171
|
+
if (replaced) {
|
|
172
|
+
return '';
|
|
173
|
+
}
|
|
174
|
+
replaced = true;
|
|
175
|
+
return BULLETS;
|
|
176
|
+
}
|
|
177
|
+
return part.value;
|
|
178
|
+
})
|
|
179
|
+
.join('');
|
|
180
|
+
}
|
|
181
|
+
const text = parts.map((part) => part.value).join('');
|
|
182
|
+
const isZero = Number(format.format(magnitude).replace(/[^\d]/g, '')) === 0;
|
|
183
|
+
if (!options.signed || isZero) {
|
|
184
|
+
return value < 0 && !isZero ? `${MINUS}${text}` : text;
|
|
185
|
+
}
|
|
186
|
+
return `${value > 0 ? '+' : MINUS}${text}`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** App-wide "amounts are hidden" state. Defaults to never masked; the app overrides it. */
|
|
190
|
+
const UI_AMOUNT_MASKED = new InjectionToken('UI_AMOUNT_MASKED', {
|
|
191
|
+
providedIn: 'root',
|
|
192
|
+
factory: () => signal(false),
|
|
193
|
+
});
|
|
194
|
+
/** Available figure styles. `AmountNumeric` is derived from this tuple. */
|
|
195
|
+
const AMOUNT_NUMERICS = ['tabular', 'proportional'];
|
|
196
|
+
/** Available masking behaviors. `AmountMasking` is derived from this tuple. */
|
|
197
|
+
const AMOUNT_MASKINGS = ['dots', 'hide'];
|
|
198
|
+
/**
|
|
199
|
+
* A number or an amount of money, formatted for the locale and masked when the app hides amounts.
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* <ui-amount [value]="total" currency="EUR" numeric="proportional" />
|
|
203
|
+
* <ui-amount [value]="dayChange" currency="EUR" signed whenMasked="hide" />
|
|
204
|
+
*/
|
|
205
|
+
class UiAmount {
|
|
206
|
+
value = input(/* @ts-ignore */
|
|
207
|
+
...(ngDevMode ? [undefined, { debugName: "value" }] : /* istanbul ignore next */ []));
|
|
208
|
+
currency = input(/* @ts-ignore */
|
|
209
|
+
...(ngDevMode ? [undefined, { debugName: "currency" }] : /* istanbul ignore next */ []));
|
|
210
|
+
locale = input(inject(LOCALE_ID), /* @ts-ignore */
|
|
211
|
+
...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
212
|
+
signed = input(false, { ...(ngDevMode ? { debugName: "signed" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
213
|
+
fractionDigits = input(2, /* @ts-ignore */
|
|
214
|
+
...(ngDevMode ? [{ debugName: "fractionDigits" }] : /* istanbul ignore next */ []));
|
|
215
|
+
numeric = input('tabular', /* @ts-ignore */
|
|
216
|
+
...(ngDevMode ? [{ debugName: "numeric" }] : /* istanbul ignore next */ []));
|
|
217
|
+
whenMasked = input('dots', /* @ts-ignore */
|
|
218
|
+
...(ngDevMode ? [{ debugName: "whenMasked" }] : /* istanbul ignore next */ []));
|
|
219
|
+
#masked = inject(UI_AMOUNT_MASKED);
|
|
220
|
+
hidden = computed(() => this.#masked() && this.whenMasked() === 'hide', /* @ts-ignore */
|
|
221
|
+
...(ngDevMode ? [{ debugName: "hidden" }] : /* istanbul ignore next */ []));
|
|
222
|
+
text = computed(() => formatAmount(this.value(), {
|
|
223
|
+
locale: this.locale(),
|
|
224
|
+
currency: this.currency(),
|
|
225
|
+
signed: this.signed(),
|
|
226
|
+
fractionDigits: this.fractionDigits(),
|
|
227
|
+
}, this.#masked()), /* @ts-ignore */
|
|
228
|
+
...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
|
|
229
|
+
classes = computed(() => {
|
|
230
|
+
const missing = this.value() === null || this.value() === undefined;
|
|
231
|
+
return [
|
|
232
|
+
'whitespace-nowrap',
|
|
233
|
+
this.numeric() === 'tabular' ? 'tabular-nums' : '',
|
|
234
|
+
missing ? 'text-(--subtle-foreground)' : '',
|
|
235
|
+
]
|
|
236
|
+
.filter(Boolean)
|
|
237
|
+
.join(' ');
|
|
238
|
+
}, /* @ts-ignore */
|
|
239
|
+
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
240
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiAmount, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
241
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UiAmount, isStandalone: true, selector: "ui-amount", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, currency: { classPropertyName: "currency", publicName: "currency", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, signed: { classPropertyName: "signed", publicName: "signed", isSignal: true, isRequired: false, transformFunction: null }, fractionDigits: { classPropertyName: "fractionDigits", publicName: "fractionDigits", isSignal: true, isRequired: false, transformFunction: null }, numeric: { classPropertyName: "numeric", publicName: "numeric", isSignal: true, isRequired: false, transformFunction: null }, whenMasked: { classPropertyName: "whenMasked", publicName: "whenMasked", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()", "attr.hidden": "hidden() || null" } }, ngImport: i0, template: '{{ text() }}', isInline: true });
|
|
242
|
+
}
|
|
243
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiAmount, decorators: [{
|
|
244
|
+
type: Component,
|
|
245
|
+
args: [{
|
|
246
|
+
selector: 'ui-amount',
|
|
247
|
+
template: '{{ text() }}',
|
|
248
|
+
host: {
|
|
249
|
+
'[class]': 'classes()',
|
|
250
|
+
'[attr.hidden]': 'hidden() || null',
|
|
251
|
+
},
|
|
252
|
+
}]
|
|
253
|
+
}], 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 }] }] } });
|
|
254
|
+
|
|
227
255
|
/** Available async block states. `AsyncState` is derived from this tuple. */
|
|
228
256
|
const ASYNC_STATES = ['loading', 'error', 'empty', 'ready'];
|
|
229
|
-
|
|
257
|
+
/** Looks of the error block. `AsyncVariant` is derived from this tuple. */
|
|
258
|
+
const ASYNC_VARIANTS = ['elevated', 'plain', 'emphasis', 'inline'];
|
|
259
|
+
/** Alignments of the error block; `auto` is centred from 64rem. `AsyncAlign` is derived from this tuple. */
|
|
260
|
+
const ASYNC_ALIGNS = ['start', 'center', 'auto'];
|
|
261
|
+
const RETRY_BASE_CLASSES = 'relative inline-flex items-center justify-center rounded-control font-medium whitespace-nowrap cursor-pointer select-none touch-manipulation transition-[transform,background-color,opacity] duration-(--duration-press) ease-out active:scale-(--press-scale) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring) text-label';
|
|
262
|
+
const RETRY_OUTLINE_CLASSES = 'bg-(--card) text-(--foreground) shadow-[inset_0_0_0_1px_var(--border)] hover:bg-(--glow)';
|
|
263
|
+
const RETRY_PRIMARY_CLASSES = 'bg-(--primary) text-(--primary-foreground) hover:bg-(--primary-to)';
|
|
264
|
+
const RETRY_BLOCK_CLASSES = 'min-h-(--row-min) gap-2 pl-3 pr-4';
|
|
265
|
+
const RETRY_INLINE_CLASSES = 'h-11 pointer-fine:h-8 flex-none gap-1.5 pl-2.5 pr-3';
|
|
266
|
+
const ELEVATED_SURFACE_CLASSES = 'rounded-control bg-(--elevated)';
|
|
267
|
+
const CARD_SURFACE_CLASSES = 'rounded-container bg-(--card) shadow-[inset_0_0_0_1px_var(--border)]';
|
|
268
|
+
const BLOCK_SPECS = {
|
|
269
|
+
elevated: {
|
|
270
|
+
surface: ELEVATED_SURFACE_CLASSES,
|
|
271
|
+
gap: 'gap-1',
|
|
272
|
+
padding: { start: 'p-4', center: 'px-4 py-10', auto: 'p-4 lg:py-10' },
|
|
273
|
+
title: 'text-body font-medium',
|
|
274
|
+
message: { start: 'text-label', center: 'text-label', auto: 'text-label' },
|
|
275
|
+
retryMargin: { start: 'mt-2', center: 'mt-2', auto: 'mt-2' },
|
|
276
|
+
retry: RETRY_OUTLINE_CLASSES,
|
|
277
|
+
},
|
|
278
|
+
plain: {
|
|
279
|
+
surface: '',
|
|
280
|
+
gap: 'gap-1',
|
|
281
|
+
padding: { start: 'px-4 py-5', center: 'px-4 py-12', auto: 'px-4 py-5 lg:py-12' },
|
|
282
|
+
title: 'text-body leading-[normal] font-medium',
|
|
283
|
+
message: {
|
|
284
|
+
start: 'text-label leading-[normal]',
|
|
285
|
+
center: 'text-label leading-[normal]',
|
|
286
|
+
auto: 'text-label leading-[normal]',
|
|
287
|
+
},
|
|
288
|
+
retryMargin: { start: 'mt-2', center: 'mt-2', auto: 'mt-2' },
|
|
289
|
+
retry: RETRY_OUTLINE_CLASSES,
|
|
290
|
+
},
|
|
291
|
+
emphasis: {
|
|
292
|
+
surface: '',
|
|
293
|
+
gap: 'gap-3',
|
|
294
|
+
padding: { start: 'px-4 py-6', center: 'px-4 py-14', auto: 'px-4 py-6 lg:py-14' },
|
|
295
|
+
title: 'text-title font-semibold',
|
|
296
|
+
message: {
|
|
297
|
+
start: 'text-label',
|
|
298
|
+
center: 'text-body leading-[normal]',
|
|
299
|
+
auto: 'text-label lg:text-body lg:leading-[normal]',
|
|
300
|
+
},
|
|
301
|
+
retryMargin: { start: 'mt-1', center: 'mt-2', auto: 'mt-1 lg:mt-2' },
|
|
302
|
+
retry: RETRY_PRIMARY_CLASSES,
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
const ALIGN_CLASSES = {
|
|
306
|
+
start: 'items-start',
|
|
307
|
+
center: 'items-center text-center',
|
|
308
|
+
auto: 'items-start lg:items-center lg:text-center',
|
|
309
|
+
};
|
|
310
|
+
const INLINE_BOX_CLASSES = 'flex-row items-center justify-between gap-3 pt-1.5 pr-1.5 pb-2 pl-2.5';
|
|
230
311
|
/**
|
|
231
312
|
* The three states of a block that depends on a service call, next to the ready content.
|
|
232
313
|
*
|
|
@@ -246,32 +327,72 @@ class UiAsync {
|
|
|
246
327
|
...(ngDevMode ? [undefined, { debugName: "errorMessage" }] : /* istanbul ignore next */ []));
|
|
247
328
|
retryLabel = input(/* @ts-ignore */
|
|
248
329
|
...(ngDevMode ? [undefined, { debugName: "retryLabel" }] : /* istanbul ignore next */ []));
|
|
330
|
+
variant = input('elevated', /* @ts-ignore */
|
|
331
|
+
...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
332
|
+
align = input('start', /* @ts-ignore */
|
|
333
|
+
...(ngDevMode ? [{ debugName: "align" }] : /* istanbul ignore next */ []));
|
|
334
|
+
card = input(false, { ...(ngDevMode ? { debugName: "card" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
335
|
+
fill = input(false, { ...(ngDevMode ? { debugName: "fill" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
249
336
|
retry = output();
|
|
250
|
-
|
|
337
|
+
filling = computed(() => this.fill() && this.state() === 'error', /* @ts-ignore */
|
|
338
|
+
...(ngDevMode ? [{ debugName: "filling" }] : /* istanbul ignore next */ []));
|
|
339
|
+
iconSize = computed(() => (this.variant() === 'inline' ? 16 : 18), /* @ts-ignore */
|
|
340
|
+
...(ngDevMode ? [{ debugName: "iconSize" }] : /* istanbul ignore next */ []));
|
|
341
|
+
#spec = computed(() => {
|
|
342
|
+
const variant = this.variant();
|
|
343
|
+
return variant === 'inline' ? null : BLOCK_SPECS[variant];
|
|
344
|
+
}, /* @ts-ignore */
|
|
345
|
+
...(ngDevMode ? [{ debugName: "#spec" }] : /* istanbul ignore next */ []));
|
|
346
|
+
boxClasses = computed(() => {
|
|
347
|
+
const spec = this.#spec();
|
|
348
|
+
const fill = this.fill() ? ' flex-1 justify-center' : '';
|
|
349
|
+
if (spec === null) {
|
|
350
|
+
return `flex ${INLINE_BOX_CLASSES}${this.card() ? ` ${CARD_SURFACE_CLASSES}` : ''}${this.fill() ? ' flex-1' : ''}`;
|
|
351
|
+
}
|
|
352
|
+
const surface = this.card() ? CARD_SURFACE_CLASSES : spec.surface;
|
|
353
|
+
return `flex flex-col ${surface} ${spec.gap} ${ALIGN_CLASSES[this.align()]} ${spec.padding[this.align()]}${fill}`;
|
|
354
|
+
}, /* @ts-ignore */
|
|
355
|
+
...(ngDevMode ? [{ debugName: "boxClasses" }] : /* istanbul ignore next */ []));
|
|
356
|
+
titleClasses = computed(() => this.#spec()?.title ?? '', /* @ts-ignore */
|
|
357
|
+
...(ngDevMode ? [{ debugName: "titleClasses" }] : /* istanbul ignore next */ []));
|
|
358
|
+
messageClasses = computed(() => this.#spec()?.message[this.align()] ?? '', /* @ts-ignore */
|
|
359
|
+
...(ngDevMode ? [{ debugName: "messageClasses" }] : /* istanbul ignore next */ []));
|
|
360
|
+
retryButtonClasses = computed(() => {
|
|
361
|
+
const spec = this.#spec();
|
|
362
|
+
if (spec === null) {
|
|
363
|
+
return `${RETRY_BASE_CLASSES} ${RETRY_OUTLINE_CLASSES} ${RETRY_INLINE_CLASSES}`;
|
|
364
|
+
}
|
|
365
|
+
return `${RETRY_BASE_CLASSES} ${spec.retry} ${RETRY_BLOCK_CLASSES} ${spec.retryMargin[this.align()]}`;
|
|
366
|
+
}, /* @ts-ignore */
|
|
367
|
+
...(ngDevMode ? [{ debugName: "retryButtonClasses" }] : /* istanbul ignore next */ []));
|
|
251
368
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiAsync, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
252
|
-
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 } }, outputs: { retry: "retry" }, host: { properties: { "attr.aria-busy": "state() === 'loading' || null" } }, ngImport: i0, template: `
|
|
369
|
+
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: `
|
|
253
370
|
@switch (state()) {
|
|
254
371
|
@case ('loading') {
|
|
255
372
|
<ng-content select="[asyncLoading]" />
|
|
256
373
|
}
|
|
257
374
|
@case ('error') {
|
|
258
|
-
<div
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
375
|
+
<div aria-live="polite" role="alert" [class]="boxClasses()">
|
|
376
|
+
@if (variant() === 'inline') {
|
|
377
|
+
<span class="text-label text-(--muted-foreground)">{{ errorMessage() }}</span>
|
|
378
|
+
} @else {
|
|
379
|
+
@if (variant() === 'emphasis') {
|
|
380
|
+
<h2 [class]="titleClasses()">{{ errorTitle() }}</h2>
|
|
381
|
+
} @else {
|
|
382
|
+
<span [class]="titleClasses()">{{ errorTitle() }}</span>
|
|
383
|
+
}
|
|
384
|
+
<span class="text-(--muted-foreground)" [class]="messageClasses()">{{ errorMessage() }}</span>
|
|
385
|
+
}
|
|
386
|
+
<button type="button" [class]="retryButtonClasses()" (click)="retry.emit()">
|
|
266
387
|
<svg
|
|
267
388
|
aria-hidden="true"
|
|
268
389
|
class="block flex-none fill-none stroke-current"
|
|
269
|
-
height="18"
|
|
270
390
|
stroke-linecap="round"
|
|
271
391
|
stroke-linejoin="round"
|
|
272
392
|
stroke-width="1.75"
|
|
273
393
|
viewBox="0 0 24 24"
|
|
274
|
-
|
|
394
|
+
[attr.height]="iconSize()"
|
|
395
|
+
[attr.width]="iconSize()"
|
|
275
396
|
>
|
|
276
397
|
<path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" />
|
|
277
398
|
<path d="M21 3v5h-5" />
|
|
@@ -299,23 +420,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
299
420
|
<ng-content select="[asyncLoading]" />
|
|
300
421
|
}
|
|
301
422
|
@case ('error') {
|
|
302
|
-
<div
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
423
|
+
<div aria-live="polite" role="alert" [class]="boxClasses()">
|
|
424
|
+
@if (variant() === 'inline') {
|
|
425
|
+
<span class="text-label text-(--muted-foreground)">{{ errorMessage() }}</span>
|
|
426
|
+
} @else {
|
|
427
|
+
@if (variant() === 'emphasis') {
|
|
428
|
+
<h2 [class]="titleClasses()">{{ errorTitle() }}</h2>
|
|
429
|
+
} @else {
|
|
430
|
+
<span [class]="titleClasses()">{{ errorTitle() }}</span>
|
|
431
|
+
}
|
|
432
|
+
<span class="text-(--muted-foreground)" [class]="messageClasses()">{{ errorMessage() }}</span>
|
|
433
|
+
}
|
|
434
|
+
<button type="button" [class]="retryButtonClasses()" (click)="retry.emit()">
|
|
310
435
|
<svg
|
|
311
436
|
aria-hidden="true"
|
|
312
437
|
class="block flex-none fill-none stroke-current"
|
|
313
|
-
height="18"
|
|
314
438
|
stroke-linecap="round"
|
|
315
439
|
stroke-linejoin="round"
|
|
316
440
|
stroke-width="1.75"
|
|
317
441
|
viewBox="0 0 24 24"
|
|
318
|
-
|
|
442
|
+
[attr.height]="iconSize()"
|
|
443
|
+
[attr.width]="iconSize()"
|
|
319
444
|
>
|
|
320
445
|
<path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8" />
|
|
321
446
|
<path d="M21 3v5h-5" />
|
|
@@ -334,17 +459,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
334
459
|
`,
|
|
335
460
|
host: {
|
|
336
461
|
'[attr.aria-busy]': "state() === 'loading' || null",
|
|
462
|
+
'[class.flex]': 'filling()',
|
|
463
|
+
'[class.flex-col]': 'filling()',
|
|
337
464
|
},
|
|
338
465
|
}]
|
|
339
|
-
}], 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 }] }], retry: [{ type: i0.Output, args: ["retry"] }] } });
|
|
466
|
+
}], 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"] }] } });
|
|
340
467
|
|
|
341
468
|
/** Available avatar sizes. `AvatarSize` is derived from this tuple. */
|
|
342
|
-
const AVATAR_SIZES = ['sm', 'md', 'lg'];
|
|
343
|
-
const BASE_CLASSES$
|
|
344
|
-
const SIZE_CLASSES$
|
|
469
|
+
const AVATAR_SIZES = ['sm', 'md', 'lg', 'auto'];
|
|
470
|
+
const BASE_CLASSES$7 = 'inline-flex items-center justify-center rounded-pill bg-(--muted) font-medium tabular-nums';
|
|
471
|
+
const SIZE_CLASSES$7 = {
|
|
345
472
|
sm: 'size-8 text-caption',
|
|
346
473
|
md: 'size-[34px] text-label',
|
|
347
474
|
lg: 'size-14 text-title',
|
|
475
|
+
auto: 'size-[34px] text-label lg:size-8 lg:text-caption',
|
|
348
476
|
};
|
|
349
477
|
/**
|
|
350
478
|
* Initials in a disc, standing in for a person. Single-user application: there is exactly one.
|
|
@@ -359,7 +487,7 @@ class UiAvatar {
|
|
|
359
487
|
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
360
488
|
size = input('md', /* @ts-ignore */
|
|
361
489
|
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
362
|
-
classes = computed(() => `${BASE_CLASSES$
|
|
490
|
+
classes = computed(() => `${BASE_CLASSES$7} ${SIZE_CLASSES$7[this.size()]}`, /* @ts-ignore */
|
|
363
491
|
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
364
492
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiAvatar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
365
493
|
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 });
|
|
@@ -376,12 +504,98 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
376
504
|
},
|
|
377
505
|
}]
|
|
378
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
|
+
/**
|
|
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.
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* <a uiAvatarLink routerLink="/profile"><ui-avatar initials="JR" label="Profile" size="auto" /></a>
|
|
513
|
+
*/
|
|
514
|
+
class UiAvatarLink {
|
|
515
|
+
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
|
+
}
|
|
518
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiAvatarLink, decorators: [{
|
|
519
|
+
type: Directive,
|
|
520
|
+
args: [{
|
|
521
|
+
selector: 'a[uiAvatarLink], button[uiAvatarLink]',
|
|
522
|
+
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
|
+
},
|
|
525
|
+
}]
|
|
526
|
+
}] });
|
|
527
|
+
|
|
528
|
+
/** Available back link sizes. `BackLinkSize` is derived from this tuple. */
|
|
529
|
+
const BACK_LINK_SIZES = ['md', 'sm', 'header'];
|
|
530
|
+
const BASE_CLASSES$6 = 'inline-flex items-center gap-0.5 rounded-control text-body font-medium whitespace-nowrap cursor-pointer select-none touch-manipulation transition-[transform,background-color,color] duration-(--duration-press) ease-out active:scale-(--press-scale) focus-visible:outline-2 focus-visible:outline-(--ring)';
|
|
531
|
+
const SIZE_CLASSES$6 = {
|
|
532
|
+
md: 'h-11 pr-3 pl-1 text-(--foreground) focus-visible:outline-offset-2',
|
|
533
|
+
sm: 'h-9 pr-2 pl-0.5 text-(--muted-foreground) hover:bg-(--glow) hover:text-(--foreground) focus-visible:outline-offset-2',
|
|
534
|
+
header: 'h-11 pr-3 pl-1 text-(--foreground) focus-visible:-outline-offset-2',
|
|
535
|
+
};
|
|
536
|
+
const CHEVRON = { md: 22, sm: 22, header: 24 };
|
|
537
|
+
/**
|
|
538
|
+
* Link back to the parent screen: a chevron and the name of the destination.
|
|
539
|
+
*
|
|
540
|
+
* @example
|
|
541
|
+
* <a ui-back-link routerLink="/accounts">Accounts</a>
|
|
542
|
+
*/
|
|
543
|
+
class UiBackLink {
|
|
544
|
+
size = input('md', /* @ts-ignore */
|
|
545
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
546
|
+
chevron = computed(() => CHEVRON[this.size()], /* @ts-ignore */
|
|
547
|
+
...(ngDevMode ? [{ debugName: "chevron" }] : /* istanbul ignore next */ []));
|
|
548
|
+
classes = computed(() => `${BASE_CLASSES$6} ${SIZE_CLASSES$6[this.size()]}`, /* @ts-ignore */
|
|
549
|
+
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
550
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiBackLink, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
551
|
+
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: `
|
|
552
|
+
<svg
|
|
553
|
+
aria-hidden="true"
|
|
554
|
+
fill="none"
|
|
555
|
+
stroke="currentColor"
|
|
556
|
+
stroke-linecap="round"
|
|
557
|
+
stroke-linejoin="round"
|
|
558
|
+
stroke-width="1.75"
|
|
559
|
+
viewBox="0 0 24 24"
|
|
560
|
+
[attr.height]="chevron()"
|
|
561
|
+
[attr.width]="chevron()"
|
|
562
|
+
>
|
|
563
|
+
<path d="m15 18-6-6 6-6" />
|
|
564
|
+
</svg>
|
|
565
|
+
<ng-content />
|
|
566
|
+
`, isInline: true });
|
|
567
|
+
}
|
|
568
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiBackLink, decorators: [{
|
|
569
|
+
type: Component,
|
|
570
|
+
args: [{
|
|
571
|
+
selector: 'a[ui-back-link]',
|
|
572
|
+
template: `
|
|
573
|
+
<svg
|
|
574
|
+
aria-hidden="true"
|
|
575
|
+
fill="none"
|
|
576
|
+
stroke="currentColor"
|
|
577
|
+
stroke-linecap="round"
|
|
578
|
+
stroke-linejoin="round"
|
|
579
|
+
stroke-width="1.75"
|
|
580
|
+
viewBox="0 0 24 24"
|
|
581
|
+
[attr.height]="chevron()"
|
|
582
|
+
[attr.width]="chevron()"
|
|
583
|
+
>
|
|
584
|
+
<path d="m15 18-6-6 6-6" />
|
|
585
|
+
</svg>
|
|
586
|
+
<ng-content />
|
|
587
|
+
`,
|
|
588
|
+
host: {
|
|
589
|
+
'[class]': 'classes()',
|
|
590
|
+
},
|
|
591
|
+
}]
|
|
592
|
+
}], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
|
|
379
593
|
|
|
380
594
|
/** Available badge variants. `BadgeVariant` is derived from this tuple. */
|
|
381
595
|
const BADGE_VARIANTS = ['neutral', 'outline'];
|
|
382
596
|
const BADGE_SIZES = ['md', 'sm'];
|
|
383
597
|
const BASE_CLASSES$5 = 'inline-flex items-center rounded-pill text-caption font-medium';
|
|
384
|
-
const SIZE_CLASSES$
|
|
598
|
+
const SIZE_CLASSES$5 = {
|
|
385
599
|
md: 'h-6 px-2.5',
|
|
386
600
|
sm: 'h-[22px] px-2',
|
|
387
601
|
};
|
|
@@ -400,7 +614,7 @@ class UiBadge {
|
|
|
400
614
|
...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
401
615
|
size = input('md', /* @ts-ignore */
|
|
402
616
|
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
403
|
-
classes = computed(() => `${BASE_CLASSES$5} ${SIZE_CLASSES$
|
|
617
|
+
classes = computed(() => `${BASE_CLASSES$5} ${SIZE_CLASSES$5[this.size()]} ${VARIANT_CLASSES$2[this.variant()]}`, /* @ts-ignore */
|
|
404
618
|
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
405
619
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiBadge, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
406
620
|
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 });
|
|
@@ -417,22 +631,60 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
417
631
|
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
|
|
418
632
|
|
|
419
633
|
/** Available button variants. `ButtonVariant` is derived from this tuple. */
|
|
420
|
-
const BUTTON_VARIANTS = [
|
|
634
|
+
const BUTTON_VARIANTS = [
|
|
635
|
+
'primary',
|
|
636
|
+
'outline',
|
|
637
|
+
'ghost',
|
|
638
|
+
'destructive',
|
|
639
|
+
'quiet',
|
|
640
|
+
'quiet-destructive',
|
|
641
|
+
'outline-destructive',
|
|
642
|
+
'quiet-glow',
|
|
643
|
+
'tonal',
|
|
644
|
+
];
|
|
421
645
|
/** Available button sizes. */
|
|
422
|
-
const BUTTON_SIZES = [
|
|
423
|
-
|
|
646
|
+
const BUTTON_SIZES = [
|
|
647
|
+
'compact',
|
|
648
|
+
'slim',
|
|
649
|
+
'xs',
|
|
650
|
+
'sm',
|
|
651
|
+
'md',
|
|
652
|
+
'lg',
|
|
653
|
+
'xl',
|
|
654
|
+
'xxl',
|
|
655
|
+
'tall',
|
|
656
|
+
'block',
|
|
657
|
+
'icon',
|
|
658
|
+
'icon-sm',
|
|
659
|
+
];
|
|
660
|
+
const BASE_CLASSES$4 = 'relative inline-flex items-center justify-center rounded-control font-medium whitespace-nowrap cursor-pointer select-none touch-manipulation transition-[transform,background-color,opacity] duration-(--duration-press) 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';
|
|
661
|
+
const RING_OUTSIDE = 'focus-visible:outline-offset-2';
|
|
662
|
+
const RING_INSIDE = 'focus-visible:-outline-offset-2';
|
|
663
|
+
const OUTLINE = 'bg-(--card) shadow-[inset_0_0_0_1px_var(--border)] hover:bg-(--glow) active:bg-(--soft)';
|
|
424
664
|
const VARIANT_CLASSES$1 = {
|
|
425
|
-
primary:
|
|
426
|
-
outline:
|
|
427
|
-
ghost:
|
|
428
|
-
destructive:
|
|
665
|
+
primary: `${RING_OUTSIDE} bg-(--primary) text-(--primary-foreground) hover:bg-(--primary-to)`,
|
|
666
|
+
outline: `${RING_OUTSIDE} ${OUTLINE} text-(--foreground)`,
|
|
667
|
+
ghost: `${RING_OUTSIDE} bg-transparent text-(--foreground) hover:bg-(--glow) active:bg-(--soft)`,
|
|
668
|
+
destructive: `${RING_OUTSIDE} bg-(--destructive) text-(--destructive-foreground)`,
|
|
669
|
+
tonal: `${RING_OUTSIDE} bg-(--muted) text-(--foreground) lg:bg-transparent lg:hover:bg-(--glow)`,
|
|
670
|
+
'quiet-glow': `${RING_INSIDE} bg-transparent text-(--muted-foreground) hover:bg-(--glow) hover:text-(--foreground)`,
|
|
671
|
+
quiet: `${RING_INSIDE} bg-transparent text-(--muted-foreground) hover:bg-(--soft) hover:text-(--foreground) active:bg-(--soft)`,
|
|
672
|
+
'quiet-destructive': `${RING_INSIDE} bg-transparent text-(--muted-foreground) hover:bg-(--glow) hover:text-(--negative) active:bg-(--soft)`,
|
|
673
|
+
'outline-destructive': `${RING_OUTSIDE} ${OUTLINE} text-(--negative)`,
|
|
429
674
|
};
|
|
430
|
-
const SIZE_CLASSES$
|
|
675
|
+
const SIZE_CLASSES$4 = {
|
|
676
|
+
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',
|
|
677
|
+
slim: 'h-11 lg:h-8 gap-1.5 px-2.5 text-label',
|
|
678
|
+
xs: 'h-8 gap-1.5 px-2.5 text-label',
|
|
679
|
+
sm: 'h-9 gap-2 px-3 text-label',
|
|
431
680
|
md: 'min-h-(--row-min) gap-2 px-4 text-label has-[>svg:first-child]:pl-3',
|
|
432
681
|
lg: 'h-11 gap-2 px-[18px] text-label',
|
|
433
682
|
xl: 'h-[50px] gap-2 px-6 text-body',
|
|
434
|
-
xxl: 'h-[52px] gap-2.5 px-6 text-body',
|
|
683
|
+
xxl: 'h-[52px] lg:h-11 gap-2.5 px-6 lg:px-5 text-body lg:has-[>svg:first-child]:pl-4',
|
|
684
|
+
tall: 'h-12 lg:h-10 gap-2 px-4 text-body',
|
|
685
|
+
block: 'h-[50px] lg:h-11 gap-2 px-4 text-body',
|
|
435
686
|
icon: 'size-(--row-min) gap-2 p-0',
|
|
687
|
+
'icon-sm': 'size-11 pointer-fine:size-9 gap-2 p-0',
|
|
436
688
|
};
|
|
437
689
|
/**
|
|
438
690
|
* Styled native button or anchor, applied as an attribute so the host keeps every native behavior.
|
|
@@ -447,12 +699,15 @@ class UiButton {
|
|
|
447
699
|
size = input('md', /* @ts-ignore */
|
|
448
700
|
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
449
701
|
loading = input(false, { ...(ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
450
|
-
|
|
702
|
+
busy = input(false, { ...(ngDevMode ? { debugName: "busy" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
703
|
+
inactive = computed(() => this.loading() || this.busy(), /* @ts-ignore */
|
|
704
|
+
...(ngDevMode ? [{ debugName: "inactive" }] : /* istanbul ignore next */ []));
|
|
705
|
+
classes = computed(() => `${BASE_CLASSES$4} ${VARIANT_CLASSES$1[this.variant()]} ${SIZE_CLASSES$4[this.size()]}${this.inactive() ? ' pointer-events-none opacity-70' : ''}`, /* @ts-ignore */
|
|
451
706
|
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
452
707
|
constructor() {
|
|
453
708
|
const host = inject(ElementRef).nativeElement;
|
|
454
709
|
const guard = (event) => {
|
|
455
|
-
if (this.
|
|
710
|
+
if (this.inactive()) {
|
|
456
711
|
event.preventDefault();
|
|
457
712
|
event.stopImmediatePropagation();
|
|
458
713
|
}
|
|
@@ -461,7 +716,7 @@ class UiButton {
|
|
|
461
716
|
inject(DestroyRef).onDestroy(() => host.removeEventListener('click', guard, { capture: true }));
|
|
462
717
|
}
|
|
463
718
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiButton, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
464
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiButton, isStandalone: true, selector: "button[ui-button], a[ui-button]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()", "attr.aria-busy": "
|
|
719
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiButton, isStandalone: true, selector: "button[ui-button], a[ui-button]", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, busy: { classPropertyName: "busy", publicName: "busy", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()", "attr.aria-busy": "inactive() || null", "attr.aria-disabled": "inactive() || null" } }, ngImport: i0, template: `
|
|
465
720
|
@if (loading()) {
|
|
466
721
|
<span
|
|
467
722
|
aria-hidden="true"
|
|
@@ -486,42 +741,78 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
486
741
|
`,
|
|
487
742
|
host: {
|
|
488
743
|
'[class]': 'classes()',
|
|
489
|
-
'[attr.aria-busy]': '
|
|
490
|
-
'[attr.aria-disabled]': '
|
|
744
|
+
'[attr.aria-busy]': 'inactive() || null',
|
|
745
|
+
'[attr.aria-disabled]': 'inactive() || null',
|
|
491
746
|
},
|
|
492
747
|
}]
|
|
493
|
-
}], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }] } });
|
|
748
|
+
}], ctorParameters: () => [], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], busy: [{ type: i0.Input, args: [{ isSignal: true, alias: "busy", required: false }] }] } });
|
|
494
749
|
|
|
495
750
|
/** Available card variants. `CardVariant` is derived from this tuple. */
|
|
496
751
|
const CARD_VARIANTS = ['default', 'elevated'];
|
|
497
752
|
/** Available card paddings. `CardPadding` is derived from this tuple. */
|
|
498
|
-
const CARD_PADDINGS = ['none', 'sm', 'md', 'list'];
|
|
499
|
-
|
|
753
|
+
const CARD_PADDINGS = ['none', 'sm', 'md', 'list', 'rows'];
|
|
754
|
+
/** Where the card surface (fill, border, radius) and its padding apply. `CardSurface` is derived from this tuple. */
|
|
755
|
+
const CARD_SURFACES = ['always', 'lg', 'max-lg'];
|
|
756
|
+
const BASE_CLASSES$3 = 'block';
|
|
500
757
|
const VARIANT_CLASSES = {
|
|
501
|
-
default:
|
|
502
|
-
|
|
758
|
+
default: {
|
|
759
|
+
always: 'rounded-container bg-(--card) shadow-[inset_0_0_0_1px_var(--border)] text-(--card-foreground)',
|
|
760
|
+
lg: 'lg:rounded-container lg:bg-(--card) lg:shadow-[inset_0_0_0_1px_var(--border)] lg:text-(--card-foreground)',
|
|
761
|
+
'max-lg': 'max-lg:rounded-container max-lg:bg-(--card) max-lg:shadow-[inset_0_0_0_1px_var(--border)] max-lg:text-(--card-foreground)',
|
|
762
|
+
},
|
|
763
|
+
elevated: {
|
|
764
|
+
always: 'rounded-container bg-(--elevated) shadow-[inset_0_0_0_1px_var(--hairline)] text-(--foreground)',
|
|
765
|
+
lg: 'lg:rounded-container lg:bg-(--elevated) lg:shadow-[inset_0_0_0_1px_var(--hairline)] lg:text-(--foreground)',
|
|
766
|
+
'max-lg': 'max-lg:rounded-container max-lg:bg-(--elevated) max-lg:shadow-[inset_0_0_0_1px_var(--hairline)] max-lg:text-(--foreground)',
|
|
767
|
+
},
|
|
503
768
|
};
|
|
504
769
|
const PADDING_CLASSES$1 = {
|
|
505
|
-
none:
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
770
|
+
none: {
|
|
771
|
+
always: 'p-0',
|
|
772
|
+
lg: 'lg:p-0',
|
|
773
|
+
'max-lg': 'max-lg:p-0',
|
|
774
|
+
},
|
|
775
|
+
sm: {
|
|
776
|
+
always: 'p-3',
|
|
777
|
+
lg: 'lg:p-3',
|
|
778
|
+
'max-lg': 'max-lg:p-3',
|
|
779
|
+
},
|
|
780
|
+
md: {
|
|
781
|
+
always: 'p-(--inset-card)',
|
|
782
|
+
lg: 'lg:p-(--inset-card)',
|
|
783
|
+
'max-lg': 'max-lg:p-(--inset-card)',
|
|
784
|
+
},
|
|
785
|
+
list: {
|
|
786
|
+
always: 'px-2 py-3',
|
|
787
|
+
lg: 'lg:px-2 lg:py-3',
|
|
788
|
+
'max-lg': 'max-lg:px-2 max-lg:py-3',
|
|
789
|
+
},
|
|
790
|
+
rows: {
|
|
791
|
+
always: 'px-(--inset-card) py-1',
|
|
792
|
+
lg: 'lg:px-(--inset-card) lg:py-1',
|
|
793
|
+
'max-lg': 'max-lg:px-(--inset-card) max-lg:py-1',
|
|
794
|
+
},
|
|
509
795
|
};
|
|
510
796
|
/**
|
|
511
|
-
* Surface that groups related content: a summary block, a table, a side panel.
|
|
797
|
+
* Surface that groups related content: a summary block, a table, a side panel. `surface` limits the
|
|
798
|
+
* fill, border, radius and padding to one side of `64rem`, for a block that is a card on a desktop and
|
|
799
|
+
* plain on an iPhone, or the reverse.
|
|
512
800
|
*
|
|
513
801
|
* @example
|
|
514
802
|
* <ui-card variant="elevated" padding="sm">Total</ui-card>
|
|
803
|
+
* <ui-card surface="max-lg">Card on an iPhone, plain on a desktop</ui-card>
|
|
515
804
|
*/
|
|
516
805
|
class UiCard {
|
|
517
806
|
variant = input('default', /* @ts-ignore */
|
|
518
807
|
...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
519
808
|
padding = input('md', /* @ts-ignore */
|
|
520
809
|
...(ngDevMode ? [{ debugName: "padding" }] : /* istanbul ignore next */ []));
|
|
521
|
-
|
|
810
|
+
surface = input('always', /* @ts-ignore */
|
|
811
|
+
...(ngDevMode ? [{ debugName: "surface" }] : /* istanbul ignore next */ []));
|
|
812
|
+
classes = computed(() => `${BASE_CLASSES$3} ${VARIANT_CLASSES[this.variant()][this.surface()]} ${PADDING_CLASSES$1[this.padding()][this.surface()]}`, /* @ts-ignore */
|
|
522
813
|
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
523
814
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiCard, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
524
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UiCard, isStandalone: true, selector: "ui-card", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: '<ng-content />', isInline: true });
|
|
815
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UiCard, isStandalone: true, selector: "ui-card", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, surface: { classPropertyName: "surface", publicName: "surface", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: '<ng-content />', isInline: true });
|
|
525
816
|
}
|
|
526
817
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiCard, decorators: [{
|
|
527
818
|
type: Component,
|
|
@@ -532,7 +823,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
532
823
|
'[class]': 'classes()',
|
|
533
824
|
},
|
|
534
825
|
}]
|
|
535
|
-
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], padding: [{ type: i0.Input, args: [{ isSignal: true, alias: "padding", required: false }] }] } });
|
|
826
|
+
}], propDecorators: { variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], padding: [{ type: i0.Input, args: [{ isSignal: true, alias: "padding", required: false }] }], surface: [{ type: i0.Input, args: [{ isSignal: true, alias: "surface", required: false }] }] } });
|
|
536
827
|
|
|
537
828
|
/**
|
|
538
829
|
* Resolves to the styled control projected into a field.
|
|
@@ -544,8 +835,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
544
835
|
*/
|
|
545
836
|
const UI_CONTROL = new InjectionToken('UI_CONTROL');
|
|
546
837
|
|
|
547
|
-
/** Available control sizes. `md` is the 44/40px touch target. */
|
|
548
|
-
const CONTROL_SIZES = ['sm', 'md'];
|
|
838
|
+
/** Available control sizes. `md` is the 44/40px touch target; `lg` and `xl` are the 48px sheet and sign-in fields. */
|
|
839
|
+
const CONTROL_SIZES = ['sm', 'md', 'lg', 'xl'];
|
|
549
840
|
const CONTROL_BASE_CLASSES = 'w-full rounded-control px-3 text-body text-(--foreground) shadow-[inset_0_0_0_1px_var(--border)] transition-shadow duration-(--duration-fast) ease-out placeholder:text-(--muted-foreground) focus-visible:shadow-[inset_0_0_0_2px_var(--ring)] aria-invalid:shadow-[inset_0_0_0_2px_var(--negative)] disabled:cursor-not-allowed disabled:opacity-50';
|
|
550
841
|
const CONTROL_SURFACES = ['background', 'card'];
|
|
551
842
|
const CONTROL_SURFACE_CLASSES = {
|
|
@@ -555,7 +846,10 @@ const CONTROL_SURFACE_CLASSES = {
|
|
|
555
846
|
const CONTROL_SIZE_CLASSES = {
|
|
556
847
|
sm: 'h-9',
|
|
557
848
|
md: 'min-h-(--row-min)',
|
|
849
|
+
lg: 'min-h-12 lg:min-h-(--row-min)',
|
|
850
|
+
xl: 'h-12 lg:h-11',
|
|
558
851
|
};
|
|
852
|
+
const SEARCH_CLASSES = '[&::-webkit-search-cancel-button]:appearance-none';
|
|
559
853
|
/**
|
|
560
854
|
* Styled native text input. A directive (not a wrapper component) so the host
|
|
561
855
|
* stays a plain <input>: every forms flavor (ngModel, reactive, signal forms)
|
|
@@ -576,7 +870,7 @@ class UiInput {
|
|
|
576
870
|
...(ngDevMode ? [{ debugName: "errors" }] : /* istanbul ignore next */ []));
|
|
577
871
|
touched = input(false, /* @ts-ignore */
|
|
578
872
|
...(ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []));
|
|
579
|
-
classes = computed(() => `${CONTROL_BASE_CLASSES} ${CONTROL_SURFACE_CLASSES[this.surface()]} ${CONTROL_SIZE_CLASSES[this.size()]}`, /* @ts-ignore */
|
|
873
|
+
classes = computed(() => `${CONTROL_BASE_CLASSES} ${SEARCH_CLASSES} ${CONTROL_SURFACE_CLASSES[this.surface()]} ${CONTROL_SIZE_CLASSES[this.size()]}`, /* @ts-ignore */
|
|
580
874
|
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
581
875
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiInput, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
582
876
|
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.7", type: UiInput, isStandalone: true, selector: "input[uiInput]", inputs: { size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, surface: { classPropertyName: "surface", publicName: "surface", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, providers: [{ provide: UI_CONTROL, useExisting: forwardRef(() => UiInput) }], ngImport: i0 });
|
|
@@ -621,10 +915,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
621
915
|
}]
|
|
622
916
|
}], propDecorators: { errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }] } });
|
|
623
917
|
|
|
624
|
-
const CHIP_CLASSES = 'h-10 px-3.5 pointer-fine:h-8 pointer-fine:px-3 rounded-pill text-label font-medium cursor-pointer transition-transform duration-(--duration-press) ease-out active:scale-(--press-scale) disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring)';
|
|
918
|
+
const CHIP_CLASSES$1 = 'h-10 px-3.5 pointer-fine:h-8 pointer-fine:px-3 rounded-pill text-label font-medium cursor-pointer transition-transform duration-(--duration-press) ease-out active:scale-(--press-scale) disabled:cursor-not-allowed disabled:opacity-50 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring)';
|
|
625
919
|
const SELECTED_CLASSES$2 = 'bg-(--primary) text-(--primary-foreground)';
|
|
626
920
|
const UNSELECTED_CLASSES$1 = 'text-(--foreground) shadow-[inset_0_0_0_1px_var(--border)]';
|
|
627
|
-
const nextId$
|
|
921
|
+
const nextId$4 = (() => {
|
|
628
922
|
let count = 0;
|
|
629
923
|
return () => `ui-choice-chips-${++count}`;
|
|
630
924
|
})();
|
|
@@ -659,7 +953,7 @@ class UiChoiceChips {
|
|
|
659
953
|
touched = input(false, /* @ts-ignore */
|
|
660
954
|
...(ngDevMode ? [{ debugName: "touched" }] : /* istanbul ignore next */ []));
|
|
661
955
|
touch = output();
|
|
662
|
-
labelId = nextId$
|
|
956
|
+
labelId = nextId$4();
|
|
663
957
|
#host = inject(ElementRef);
|
|
664
958
|
radios = viewChildren('radio', /* @ts-ignore */
|
|
665
959
|
...(ngDevMode ? [{ debugName: "radios" }] : /* istanbul ignore next */ []));
|
|
@@ -669,7 +963,7 @@ class UiChoiceChips {
|
|
|
669
963
|
const state = optionValue === this.value()
|
|
670
964
|
? SELECTED_CLASSES$2
|
|
671
965
|
: `${CONTROL_SURFACE_CLASSES[this.surface()]} ${UNSELECTED_CLASSES$1}`;
|
|
672
|
-
return `${CHIP_CLASSES} ${state}`;
|
|
966
|
+
return `${CHIP_CLASSES$1} ${state}`;
|
|
673
967
|
}
|
|
674
968
|
tabIndexFor(optionValue) {
|
|
675
969
|
const opts = this.options();
|
|
@@ -784,8 +1078,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
784
1078
|
|
|
785
1079
|
/** Available delta emphases. `DeltaEmphasis` is derived from this tuple. */
|
|
786
1080
|
const DELTA_EMPHASES = ['text', 'pill'];
|
|
787
|
-
|
|
788
|
-
const
|
|
1081
|
+
/** Type sizes. `DeltaSize` is derived from this tuple. */
|
|
1082
|
+
const DELTA_SIZES = ['label', 'inherit'];
|
|
1083
|
+
/** Font weights. `DeltaWeight` is derived from this tuple. */
|
|
1084
|
+
const DELTA_WEIGHTS = ['medium', 'regular'];
|
|
1085
|
+
const BASE_CLASSES$2 = 'inline-flex items-center gap-1 tabular-nums';
|
|
1086
|
+
const SIZE_CLASSES$3 = {
|
|
1087
|
+
label: 'text-label',
|
|
1088
|
+
inherit: '',
|
|
1089
|
+
};
|
|
1090
|
+
const WEIGHT_CLASSES = {
|
|
1091
|
+
medium: 'font-medium',
|
|
1092
|
+
regular: 'font-normal',
|
|
1093
|
+
};
|
|
1094
|
+
const PILL_CLASSES$1 = 'h-6 rounded-pill px-2';
|
|
789
1095
|
const TEXT_CLASSES = {
|
|
790
1096
|
positive: 'text-(--positive)',
|
|
791
1097
|
negative: 'text-(--negative)',
|
|
@@ -812,6 +1118,10 @@ class UiDelta {
|
|
|
812
1118
|
...(ngDevMode ? [{ debugName: "unknownLabel" }] : /* istanbul ignore next */ []));
|
|
813
1119
|
emphasis = input('text', /* @ts-ignore */
|
|
814
1120
|
...(ngDevMode ? [{ debugName: "emphasis" }] : /* istanbul ignore next */ []));
|
|
1121
|
+
size = input('label', /* @ts-ignore */
|
|
1122
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
1123
|
+
weight = input('medium', /* @ts-ignore */
|
|
1124
|
+
...(ngDevMode ? [{ debugName: "weight" }] : /* istanbul ignore next */ []));
|
|
815
1125
|
sign = computed(() => {
|
|
816
1126
|
const value = this.value();
|
|
817
1127
|
if (value === null || value === undefined) {
|
|
@@ -828,12 +1138,12 @@ class UiDelta {
|
|
|
828
1138
|
...(ngDevMode ? [{ debugName: "sign" }] : /* istanbul ignore next */ []));
|
|
829
1139
|
classes = computed(() => {
|
|
830
1140
|
const sign = this.sign();
|
|
831
|
-
const background = this.emphasis() === 'pill' ? `${PILL_CLASSES} ${PILL_BACKGROUND_CLASS}` : 'bg-transparent';
|
|
832
|
-
return `${BASE_CLASSES$2} ${TEXT_CLASSES[sign]} ${background}`;
|
|
1141
|
+
const background = this.emphasis() === 'pill' ? `${PILL_CLASSES$1} ${PILL_BACKGROUND_CLASS}` : 'bg-transparent';
|
|
1142
|
+
return `${BASE_CLASSES$2} ${SIZE_CLASSES$3[this.size()]} ${WEIGHT_CLASSES[this.weight()]} ${TEXT_CLASSES[sign]} ${background}`;
|
|
833
1143
|
}, /* @ts-ignore */
|
|
834
1144
|
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
835
1145
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiDelta, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
836
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiDelta, isStandalone: true, selector: "ui-delta", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, unknownLabel: { classPropertyName: "unknownLabel", publicName: "unknownLabel", isSignal: true, isRequired: true, transformFunction: null }, emphasis: { classPropertyName: "emphasis", publicName: "emphasis", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: `
|
|
1146
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiDelta, isStandalone: true, selector: "ui-delta", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, unknownLabel: { classPropertyName: "unknownLabel", publicName: "unknownLabel", isSignal: true, isRequired: true, transformFunction: null }, emphasis: { classPropertyName: "emphasis", publicName: "emphasis", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, weight: { classPropertyName: "weight", publicName: "weight", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: `
|
|
837
1147
|
@if (sign() === 'unknown') {
|
|
838
1148
|
<span aria-hidden="true">—</span>
|
|
839
1149
|
<span class="sr-only">{{ unknownLabel() }}</span>
|
|
@@ -858,7 +1168,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
858
1168
|
'[class]': 'classes()',
|
|
859
1169
|
},
|
|
860
1170
|
}]
|
|
861
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], unknownLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "unknownLabel", required: true }] }], emphasis: [{ type: i0.Input, args: [{ isSignal: true, alias: "emphasis", required: false }] }] } });
|
|
1171
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], unknownLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "unknownLabel", required: true }] }], emphasis: [{ type: i0.Input, args: [{ isSignal: true, alias: "emphasis", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], weight: [{ type: i0.Input, args: [{ isSignal: true, alias: "weight", required: false }] }] } });
|
|
862
1172
|
|
|
863
1173
|
/** Named dialog widths; any other CSS length is accepted as is. `DialogWidth` is derived from this tuple. */
|
|
864
1174
|
const DIALOG_WIDTHS = ['md', 'lg'];
|
|
@@ -910,7 +1220,7 @@ const LAYOUTS = {
|
|
|
910
1220
|
footer: 'max-lg:pb-[calc(8px+env(safe-area-inset-bottom))] lg:pb-6',
|
|
911
1221
|
},
|
|
912
1222
|
};
|
|
913
|
-
const nextId$
|
|
1223
|
+
const nextId$3 = (() => {
|
|
914
1224
|
let count = 0;
|
|
915
1225
|
return () => `ui-dialog-${++count}`;
|
|
916
1226
|
})();
|
|
@@ -938,8 +1248,18 @@ class UiDialog {
|
|
|
938
1248
|
...(ngDevMode ? [{ debugName: "width" }] : /* istanbul ignore next */ []));
|
|
939
1249
|
open = input(false, { ...(ngDevMode ? { debugName: "open" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
940
1250
|
dismissed = output();
|
|
941
|
-
headingId = nextId$
|
|
1251
|
+
headingId = nextId$3();
|
|
942
1252
|
descriptionId = `${this.headingId}-description`;
|
|
1253
|
+
bodyId = `${this.headingId}-body`;
|
|
1254
|
+
scrollable = signal(false, /* @ts-ignore */
|
|
1255
|
+
...(ngDevMode ? [{ debugName: "scrollable" }] : /* istanbul ignore next */ []));
|
|
1256
|
+
describedBy = computed(() => {
|
|
1257
|
+
if (this.description()) {
|
|
1258
|
+
return this.descriptionId;
|
|
1259
|
+
}
|
|
1260
|
+
return this.layout() === 'confirm' ? this.bodyId : null;
|
|
1261
|
+
}, /* @ts-ignore */
|
|
1262
|
+
...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
|
|
943
1263
|
widthValue = computed(() => {
|
|
944
1264
|
const width = this.width();
|
|
945
1265
|
return Object.hasOwn(WIDTH_VALUES, width) ? WIDTH_VALUES[width] : width;
|
|
@@ -961,6 +1281,17 @@ class UiDialog {
|
|
|
961
1281
|
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
962
1282
|
#host = inject(ElementRef);
|
|
963
1283
|
constructor() {
|
|
1284
|
+
const destroyRef = inject(DestroyRef);
|
|
1285
|
+
afterNextRender(() => {
|
|
1286
|
+
if (typeof ResizeObserver === 'undefined') {
|
|
1287
|
+
return;
|
|
1288
|
+
}
|
|
1289
|
+
const body = this.#host.nativeElement.querySelector('[data-dialog-body]');
|
|
1290
|
+
const observer = new ResizeObserver(() => this.scrollable.set(body.scrollHeight > body.clientHeight));
|
|
1291
|
+
observer.observe(body);
|
|
1292
|
+
observer.observe(body.firstElementChild);
|
|
1293
|
+
destroyRef.onDestroy(() => observer.disconnect());
|
|
1294
|
+
});
|
|
964
1295
|
afterRenderEffect(() => {
|
|
965
1296
|
// viewChild.required can't target a #private field (NG1053); safe because the template has exactly one <dialog>.
|
|
966
1297
|
const dialog = this.#host.nativeElement.querySelector('dialog');
|
|
@@ -999,7 +1330,7 @@ class UiDialog {
|
|
|
999
1330
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiDialog, isStandalone: true, selector: "ui-dialog", inputs: { heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: true, transformFunction: null }, description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, closeLabel: { classPropertyName: "closeLabel", publicName: "closeLabel", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, truncateDescription: { classPropertyName: "truncateDescription", publicName: "truncateDescription", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dismissed: "dismissed" }, host: { listeners: { "pointerdown": "onPointerDown($event)", "click": "onClick($event)" } }, ngImport: i0, template: `
|
|
1000
1331
|
<dialog
|
|
1001
1332
|
#dlg
|
|
1002
|
-
[attr.aria-describedby]="
|
|
1333
|
+
[attr.aria-describedby]="describedBy()"
|
|
1003
1334
|
[attr.aria-labelledby]="headingId"
|
|
1004
1335
|
[attr.role]="layout() === 'confirm' ? 'alertdialog' : 'dialog'"
|
|
1005
1336
|
[class]="classes()"
|
|
@@ -1042,7 +1373,14 @@ class UiDialog {
|
|
|
1042
1373
|
}
|
|
1043
1374
|
</div>
|
|
1044
1375
|
|
|
1045
|
-
<div
|
|
1376
|
+
<div
|
|
1377
|
+
class="min-h-0 flex-1 overflow-y-auto px-4 outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) lg:px-6"
|
|
1378
|
+
data-dialog-body
|
|
1379
|
+
[attr.aria-labelledby]="scrollable() ? headingId : null"
|
|
1380
|
+
[attr.role]="scrollable() ? 'region' : null"
|
|
1381
|
+
[attr.tabindex]="scrollable() ? 0 : null"
|
|
1382
|
+
[id]="bodyId"
|
|
1383
|
+
>
|
|
1046
1384
|
<!-- empty:hidden keeps a body-less dialog from carrying the body's vertical padding. -->
|
|
1047
1385
|
<div class="flex flex-col gap-4 empty:hidden" [class]="spec().body">
|
|
1048
1386
|
<ng-content />
|
|
@@ -1060,7 +1398,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
1060
1398
|
args: [{ selector: 'ui-dialog', host: { '(pointerdown)': 'onPointerDown($event)', '(click)': 'onClick($event)' }, template: `
|
|
1061
1399
|
<dialog
|
|
1062
1400
|
#dlg
|
|
1063
|
-
[attr.aria-describedby]="
|
|
1401
|
+
[attr.aria-describedby]="describedBy()"
|
|
1064
1402
|
[attr.aria-labelledby]="headingId"
|
|
1065
1403
|
[attr.role]="layout() === 'confirm' ? 'alertdialog' : 'dialog'"
|
|
1066
1404
|
[class]="classes()"
|
|
@@ -1103,7 +1441,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
1103
1441
|
}
|
|
1104
1442
|
</div>
|
|
1105
1443
|
|
|
1106
|
-
<div
|
|
1444
|
+
<div
|
|
1445
|
+
class="min-h-0 flex-1 overflow-y-auto px-4 outline-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) lg:px-6"
|
|
1446
|
+
data-dialog-body
|
|
1447
|
+
[attr.aria-labelledby]="scrollable() ? headingId : null"
|
|
1448
|
+
[attr.role]="scrollable() ? 'region' : null"
|
|
1449
|
+
[attr.tabindex]="scrollable() ? 0 : null"
|
|
1450
|
+
[id]="bodyId"
|
|
1451
|
+
>
|
|
1107
1452
|
<!-- empty:hidden keeps a body-less dialog from carrying the body's vertical padding. -->
|
|
1108
1453
|
<div class="flex flex-col gap-4 empty:hidden" [class]="spec().body">
|
|
1109
1454
|
<ng-content />
|
|
@@ -1166,7 +1511,7 @@ function rankSlices(slices, othersLabel) {
|
|
|
1166
1511
|
|
|
1167
1512
|
const identityValue$1 = (value) => `${value}`;
|
|
1168
1513
|
const identityShare = (share) => `${Math.round(share * 100)}%`;
|
|
1169
|
-
const ROW_CLASSES$1 = 'flex w-full items-center gap-3 min-h-14 px-2 py-1 [font-variant-numeric:var(--numeric)] rounded-control text-left transition-colors duration-(--duration-fast) ease-out hover:bg-(--glow) focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring)';
|
|
1514
|
+
const ROW_CLASSES$1 = 'flex w-full items-center gap-3 min-h-14 px-2 py-1 [font-variant-numeric:var(--numeric)] rounded-control text-left transition-colors duration-(--duration-fast) ease-out hover:bg-(--glow) active:bg-(--soft) focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring)';
|
|
1170
1515
|
const RAMP_DOT_CLASSES = {
|
|
1171
1516
|
1: 'bg-(--ramp-1)',
|
|
1172
1517
|
2: 'bg-(--ramp-2)',
|
|
@@ -1193,6 +1538,8 @@ class UiDonut {
|
|
|
1193
1538
|
...(ngDevMode ? [{ debugName: "valueFormat" }] : /* istanbul ignore next */ []));
|
|
1194
1539
|
shareFormat = input(identityShare, /* @ts-ignore */
|
|
1195
1540
|
...(ngDevMode ? [{ debugName: "shareFormat" }] : /* istanbul ignore next */ []));
|
|
1541
|
+
legendHref = input(/* @ts-ignore */
|
|
1542
|
+
...(ngDevMode ? [undefined, { debugName: "legendHref" }] : /* istanbul ignore next */ []));
|
|
1196
1543
|
sliceSelect = output();
|
|
1197
1544
|
activeId = signal(null, /* @ts-ignore */
|
|
1198
1545
|
...(ngDevMode ? [{ debugName: "activeId" }] : /* istanbul ignore next */ []));
|
|
@@ -1241,12 +1588,22 @@ class UiDonut {
|
|
|
1241
1588
|
this.activeId.set(null);
|
|
1242
1589
|
}
|
|
1243
1590
|
}
|
|
1591
|
+
hrefFor(id) {
|
|
1592
|
+
return this.legendHref()?.(id) ?? null;
|
|
1593
|
+
}
|
|
1594
|
+
follow(event, slice) {
|
|
1595
|
+
if (event.button !== 0 || event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) {
|
|
1596
|
+
return;
|
|
1597
|
+
}
|
|
1598
|
+
event.preventDefault();
|
|
1599
|
+
this.select(slice);
|
|
1600
|
+
}
|
|
1244
1601
|
select(slice) {
|
|
1245
1602
|
this.activeId.set(slice.id);
|
|
1246
1603
|
this.sliceSelect.emit(slice.id);
|
|
1247
1604
|
}
|
|
1248
1605
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiDonut, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1249
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiDonut, isStandalone: true, selector: "ui-donut", inputs: { slices: { classPropertyName: "slices", publicName: "slices", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, othersLabel: { classPropertyName: "othersLabel", publicName: "othersLabel", isSignal: true, isRequired: true, transformFunction: null }, valueFormat: { classPropertyName: "valueFormat", publicName: "valueFormat", isSignal: true, isRequired: false, transformFunction: null }, shareFormat: { classPropertyName: "shareFormat", publicName: "shareFormat", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sliceSelect: "sliceSelect" }, host: { classAttribute: "flex flex-col items-center gap-3 sm:flex-row sm:items-center sm:gap-8" }, ngImport: i0, template: `
|
|
1606
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiDonut, isStandalone: true, selector: "ui-donut", inputs: { slices: { classPropertyName: "slices", publicName: "slices", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, othersLabel: { classPropertyName: "othersLabel", publicName: "othersLabel", isSignal: true, isRequired: true, transformFunction: null }, valueFormat: { classPropertyName: "valueFormat", publicName: "valueFormat", isSignal: true, isRequired: false, transformFunction: null }, shareFormat: { classPropertyName: "shareFormat", publicName: "shareFormat", isSignal: true, isRequired: false, transformFunction: null }, legendHref: { classPropertyName: "legendHref", publicName: "legendHref", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sliceSelect: "sliceSelect" }, host: { classAttribute: "flex flex-col items-center gap-3 sm:flex-row sm:items-center sm:gap-8" }, ngImport: i0, template: `
|
|
1250
1607
|
<div class="relative size-[232px] flex-none sm:size-60">
|
|
1251
1608
|
<svg class="block h-full w-full -rotate-90" role="img" viewBox="0 0 200 200" [attr.aria-label]="ariaLabel()">
|
|
1252
1609
|
<circle
|
|
@@ -1294,30 +1651,48 @@ class UiDonut {
|
|
|
1294
1651
|
|
|
1295
1652
|
<div class="flex w-full min-w-0 flex-1 flex-col sm:w-auto" data-testid="donut-legend">
|
|
1296
1653
|
@for (slice of ranked(); track slice.id) {
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1654
|
+
@if (hrefFor(slice.id); as href) {
|
|
1655
|
+
<a
|
|
1656
|
+
[attr.href]="href"
|
|
1657
|
+
[class]="rowClasses(slice)"
|
|
1658
|
+
(blur)="clearHighlight(slice.id)"
|
|
1659
|
+
(click)="follow($event, slice)"
|
|
1660
|
+
(focus)="highlight(slice.id)"
|
|
1661
|
+
(pointerenter)="highlight(slice.id)"
|
|
1662
|
+
(pointerleave)="clearHighlight(slice.id)"
|
|
1663
|
+
>
|
|
1664
|
+
<ng-container *ngTemplateOutlet="rowContent; context: { $implicit: slice }" />
|
|
1665
|
+
</a>
|
|
1666
|
+
} @else {
|
|
1667
|
+
<button
|
|
1668
|
+
type="button"
|
|
1669
|
+
[class]="rowClasses(slice)"
|
|
1670
|
+
(blur)="clearHighlight(slice.id)"
|
|
1671
|
+
(click)="select(slice)"
|
|
1672
|
+
(focus)="highlight(slice.id)"
|
|
1673
|
+
(pointerenter)="highlight(slice.id)"
|
|
1674
|
+
(pointerleave)="clearHighlight(slice.id)"
|
|
1675
|
+
>
|
|
1676
|
+
<ng-container *ngTemplateOutlet="rowContent; context: { $implicit: slice }" />
|
|
1677
|
+
</button>
|
|
1678
|
+
}
|
|
1318
1679
|
}
|
|
1319
1680
|
</div>
|
|
1320
|
-
|
|
1681
|
+
|
|
1682
|
+
<ng-template #rowContent let-slice>
|
|
1683
|
+
<span [class]="dotClasses(slice)"></span>
|
|
1684
|
+
<span class="flex min-w-0 flex-1 flex-col">
|
|
1685
|
+
<span class="text-body truncate font-medium">{{ slice.label }}</span>
|
|
1686
|
+
<span class="text-caption truncate tracking-(--tracking-caption) text-(--subtle-foreground)">{{
|
|
1687
|
+
subLabel(slice)
|
|
1688
|
+
}}</span>
|
|
1689
|
+
</span>
|
|
1690
|
+
<span class="flex flex-none flex-col items-end whitespace-nowrap">
|
|
1691
|
+
<span class="text-body font-medium">{{ shareFormat()(slice.share) }}</span>
|
|
1692
|
+
<span class="text-caption tracking-normal text-(--muted-foreground)">{{ valueFormat()(slice.value) }}</span>
|
|
1693
|
+
</span>
|
|
1694
|
+
</ng-template>
|
|
1695
|
+
`, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
|
|
1321
1696
|
}
|
|
1322
1697
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiDonut, decorators: [{
|
|
1323
1698
|
type: Component,
|
|
@@ -1371,37 +1746,201 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
1371
1746
|
|
|
1372
1747
|
<div class="flex w-full min-w-0 flex-1 flex-col sm:w-auto" data-testid="donut-legend">
|
|
1373
1748
|
@for (slice of ranked(); track slice.id) {
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1749
|
+
@if (hrefFor(slice.id); as href) {
|
|
1750
|
+
<a
|
|
1751
|
+
[attr.href]="href"
|
|
1752
|
+
[class]="rowClasses(slice)"
|
|
1753
|
+
(blur)="clearHighlight(slice.id)"
|
|
1754
|
+
(click)="follow($event, slice)"
|
|
1755
|
+
(focus)="highlight(slice.id)"
|
|
1756
|
+
(pointerenter)="highlight(slice.id)"
|
|
1757
|
+
(pointerleave)="clearHighlight(slice.id)"
|
|
1758
|
+
>
|
|
1759
|
+
<ng-container *ngTemplateOutlet="rowContent; context: { $implicit: slice }" />
|
|
1760
|
+
</a>
|
|
1761
|
+
} @else {
|
|
1762
|
+
<button
|
|
1763
|
+
type="button"
|
|
1764
|
+
[class]="rowClasses(slice)"
|
|
1765
|
+
(blur)="clearHighlight(slice.id)"
|
|
1766
|
+
(click)="select(slice)"
|
|
1767
|
+
(focus)="highlight(slice.id)"
|
|
1768
|
+
(pointerenter)="highlight(slice.id)"
|
|
1769
|
+
(pointerleave)="clearHighlight(slice.id)"
|
|
1770
|
+
>
|
|
1771
|
+
<ng-container *ngTemplateOutlet="rowContent; context: { $implicit: slice }" />
|
|
1772
|
+
</button>
|
|
1773
|
+
}
|
|
1395
1774
|
}
|
|
1396
1775
|
</div>
|
|
1776
|
+
|
|
1777
|
+
<ng-template #rowContent let-slice>
|
|
1778
|
+
<span [class]="dotClasses(slice)"></span>
|
|
1779
|
+
<span class="flex min-w-0 flex-1 flex-col">
|
|
1780
|
+
<span class="text-body truncate font-medium">{{ slice.label }}</span>
|
|
1781
|
+
<span class="text-caption truncate tracking-(--tracking-caption) text-(--subtle-foreground)">{{
|
|
1782
|
+
subLabel(slice)
|
|
1783
|
+
}}</span>
|
|
1784
|
+
</span>
|
|
1785
|
+
<span class="flex flex-none flex-col items-end whitespace-nowrap">
|
|
1786
|
+
<span class="text-body font-medium">{{ shareFormat()(slice.share) }}</span>
|
|
1787
|
+
<span class="text-caption tracking-normal text-(--muted-foreground)">{{ valueFormat()(slice.value) }}</span>
|
|
1788
|
+
</span>
|
|
1789
|
+
</ng-template>
|
|
1397
1790
|
`,
|
|
1791
|
+
imports: [NgTemplateOutlet],
|
|
1398
1792
|
host: {
|
|
1399
1793
|
class: 'flex flex-col items-center gap-3 sm:flex-row sm:items-center sm:gap-8',
|
|
1400
1794
|
},
|
|
1401
1795
|
}]
|
|
1402
|
-
}], propDecorators: { slices: [{ type: i0.Input, args: [{ isSignal: true, alias: "slices", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], othersLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "othersLabel", required: true }] }], valueFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueFormat", required: false }] }], shareFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "shareFormat", required: false }] }], sliceSelect: [{ type: i0.Output, args: ["sliceSelect"] }] } });
|
|
1796
|
+
}], propDecorators: { slices: [{ type: i0.Input, args: [{ isSignal: true, alias: "slices", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], othersLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "othersLabel", required: true }] }], valueFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueFormat", required: false }] }], shareFormat: [{ type: i0.Input, args: [{ isSignal: true, alias: "shareFormat", required: false }] }], legendHref: [{ type: i0.Input, args: [{ isSignal: true, alias: "legendHref", required: false }] }], sliceSelect: [{ type: i0.Output, args: ["sliceSelect"] }] } });
|
|
1403
1797
|
|
|
1404
|
-
|
|
1798
|
+
/**
|
|
1799
|
+
* Link to another site: the label followed by an external-link icon. A 44px target on touch,
|
|
1800
|
+
* an underline on hover with a mouse.
|
|
1801
|
+
*
|
|
1802
|
+
* @example
|
|
1803
|
+
* <a ui-external-link href="https://example.com" target="_blank" rel="noopener">Page on example.com</a>
|
|
1804
|
+
*/
|
|
1805
|
+
class UiExternalLink {
|
|
1806
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiExternalLink, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1807
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.7", type: UiExternalLink, isStandalone: true, selector: "a[ui-external-link]", host: { classAttribute: "inline-flex min-h-11 items-center gap-1.5 rounded-[4px] text-label leading-[17px] font-medium lg:min-h-0 hover:underline underline-offset-3 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring) [&>svg]:flex-none" }, ngImport: i0, template: `
|
|
1808
|
+
<ng-content />
|
|
1809
|
+
<svg
|
|
1810
|
+
aria-hidden="true"
|
|
1811
|
+
fill="none"
|
|
1812
|
+
height="14"
|
|
1813
|
+
stroke="currentColor"
|
|
1814
|
+
stroke-linecap="round"
|
|
1815
|
+
stroke-linejoin="round"
|
|
1816
|
+
stroke-width="1.75"
|
|
1817
|
+
viewBox="0 0 24 24"
|
|
1818
|
+
width="14"
|
|
1819
|
+
>
|
|
1820
|
+
<path d="M15 3h6v6" />
|
|
1821
|
+
<path d="M10 14 21 3" />
|
|
1822
|
+
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
|
|
1823
|
+
</svg>
|
|
1824
|
+
`, isInline: true });
|
|
1825
|
+
}
|
|
1826
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiExternalLink, decorators: [{
|
|
1827
|
+
type: Component,
|
|
1828
|
+
args: [{
|
|
1829
|
+
selector: 'a[ui-external-link]',
|
|
1830
|
+
template: `
|
|
1831
|
+
<ng-content />
|
|
1832
|
+
<svg
|
|
1833
|
+
aria-hidden="true"
|
|
1834
|
+
fill="none"
|
|
1835
|
+
height="14"
|
|
1836
|
+
stroke="currentColor"
|
|
1837
|
+
stroke-linecap="round"
|
|
1838
|
+
stroke-linejoin="round"
|
|
1839
|
+
stroke-width="1.75"
|
|
1840
|
+
viewBox="0 0 24 24"
|
|
1841
|
+
width="14"
|
|
1842
|
+
>
|
|
1843
|
+
<path d="M15 3h6v6" />
|
|
1844
|
+
<path d="M10 14 21 3" />
|
|
1845
|
+
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
|
|
1846
|
+
</svg>
|
|
1847
|
+
`,
|
|
1848
|
+
host: {
|
|
1849
|
+
class: 'inline-flex min-h-11 items-center gap-1.5 rounded-[4px] text-label leading-[17px] font-medium lg:min-h-0 hover:underline underline-offset-3 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring) [&>svg]:flex-none',
|
|
1850
|
+
},
|
|
1851
|
+
}]
|
|
1852
|
+
}] });
|
|
1853
|
+
|
|
1854
|
+
/** Available fact row sizes. `FactSize` is derived from this tuple. */
|
|
1855
|
+
const FACT_SIZES = ['md', 'sm', 'auto'];
|
|
1856
|
+
/** Colour of the line under a fact value. `stale` flags an out-of-date figure. */
|
|
1857
|
+
const FACT_SUB_TONES = ['subtle', 'stale'];
|
|
1858
|
+
const SIZE_CLASSES$2 = {
|
|
1859
|
+
md: { row: 'py-3 [&:not(:first-child)]:shadow-[inset_0_1px_0_var(--hairline)]', value: 'text-body' },
|
|
1860
|
+
sm: { row: 'py-2.5', value: 'text-label' },
|
|
1861
|
+
auto: {
|
|
1862
|
+
row: 'py-3 lg:py-2.5 max-lg:[&:not(:first-child)]:shadow-[inset_0_1px_0_var(--hairline)]',
|
|
1863
|
+
value: 'text-body lg:text-label',
|
|
1864
|
+
},
|
|
1865
|
+
};
|
|
1866
|
+
const SUB_TONE_CLASSES$1 = {
|
|
1867
|
+
subtle: 'text-(--subtle-foreground)',
|
|
1868
|
+
stale: 'text-(--stale)',
|
|
1869
|
+
};
|
|
1870
|
+
/**
|
|
1871
|
+
* The list that holds `div[ui-fact]` rows, as a native description list.
|
|
1872
|
+
*
|
|
1873
|
+
* @example
|
|
1874
|
+
* <dl uiFacts>
|
|
1875
|
+
* <div ui-fact label="Quantity">500</div>
|
|
1876
|
+
* <div ui-fact label="Price" sub="24/09 · Yahoo">28,64 €</div>
|
|
1877
|
+
* </dl>
|
|
1878
|
+
*/
|
|
1879
|
+
class UiFacts {
|
|
1880
|
+
ruled = input(false, { ...(ngDevMode ? { debugName: "ruled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1881
|
+
classes = computed(() => `m-0 flex flex-col${this.ruled() ? ' shadow-[inset_0_1px_0_var(--hairline)]' : ''}`, /* @ts-ignore */
|
|
1882
|
+
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
1883
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiFacts, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1884
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.7", type: UiFacts, isStandalone: true, selector: "dl[uiFacts]", inputs: { ruled: { classPropertyName: "ruled", publicName: "ruled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0 });
|
|
1885
|
+
}
|
|
1886
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiFacts, decorators: [{
|
|
1887
|
+
type: Directive,
|
|
1888
|
+
args: [{
|
|
1889
|
+
selector: 'dl[uiFacts]',
|
|
1890
|
+
host: { '[class]': 'classes()' },
|
|
1891
|
+
}]
|
|
1892
|
+
}], propDecorators: { ruled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ruled", required: false }] }] } });
|
|
1893
|
+
/**
|
|
1894
|
+
* One fact of a `dl[uiFacts]`: a label on the left, its value on the right, an optional sub-line
|
|
1895
|
+
* under the value, and a hairline above every row but the first at the `md` size (the `sm` desktop list is separated by space only). The projected content is the value.
|
|
1896
|
+
*
|
|
1897
|
+
* @example
|
|
1898
|
+
* <div ui-fact label="Price" sub="24/09 · Yahoo" subTone="stale">28,64 €</div>
|
|
1899
|
+
*/
|
|
1900
|
+
class UiFact {
|
|
1901
|
+
label = input.required(/* @ts-ignore */
|
|
1902
|
+
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
1903
|
+
sub = input(/* @ts-ignore */
|
|
1904
|
+
...(ngDevMode ? [undefined, { debugName: "sub" }] : /* istanbul ignore next */ []));
|
|
1905
|
+
subTone = input('subtle', /* @ts-ignore */
|
|
1906
|
+
...(ngDevMode ? [{ debugName: "subTone" }] : /* istanbul ignore next */ []));
|
|
1907
|
+
size = input('md', /* @ts-ignore */
|
|
1908
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
1909
|
+
classes = computed(() => `flex items-baseline justify-between gap-4 ${SIZE_CLASSES$2[this.size()].row}`, /* @ts-ignore */
|
|
1910
|
+
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
1911
|
+
valueClasses = computed(() => `${SIZE_CLASSES$2[this.size()].value} tabular-nums`, /* @ts-ignore */
|
|
1912
|
+
...(ngDevMode ? [{ debugName: "valueClasses" }] : /* istanbul ignore next */ []));
|
|
1913
|
+
subClasses = computed(() => `text-caption ${SUB_TONE_CLASSES$1[this.subTone()]}`, /* @ts-ignore */
|
|
1914
|
+
...(ngDevMode ? [{ debugName: "subClasses" }] : /* istanbul ignore next */ []));
|
|
1915
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiFact, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1916
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiFact, isStandalone: true, selector: "div[ui-fact]", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, sub: { classPropertyName: "sub", publicName: "sub", isSignal: true, isRequired: false, transformFunction: null }, subTone: { classPropertyName: "subTone", publicName: "subTone", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0, template: `
|
|
1917
|
+
<dt class="text-label text-(--muted-foreground)">{{ label() }}</dt>
|
|
1918
|
+
<dd class="m-0 flex flex-col items-end text-right">
|
|
1919
|
+
<span [class]="valueClasses()"><ng-content /></span>
|
|
1920
|
+
@if (sub()) {
|
|
1921
|
+
<span [class]="subClasses()">{{ sub() }}</span>
|
|
1922
|
+
}
|
|
1923
|
+
</dd>
|
|
1924
|
+
`, isInline: true });
|
|
1925
|
+
}
|
|
1926
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiFact, decorators: [{
|
|
1927
|
+
type: Component,
|
|
1928
|
+
args: [{
|
|
1929
|
+
selector: 'div[ui-fact]',
|
|
1930
|
+
template: `
|
|
1931
|
+
<dt class="text-label text-(--muted-foreground)">{{ label() }}</dt>
|
|
1932
|
+
<dd class="m-0 flex flex-col items-end text-right">
|
|
1933
|
+
<span [class]="valueClasses()"><ng-content /></span>
|
|
1934
|
+
@if (sub()) {
|
|
1935
|
+
<span [class]="subClasses()">{{ sub() }}</span>
|
|
1936
|
+
}
|
|
1937
|
+
</dd>
|
|
1938
|
+
`,
|
|
1939
|
+
host: { '[class]': 'classes()' },
|
|
1940
|
+
}]
|
|
1941
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], sub: [{ type: i0.Input, args: [{ isSignal: true, alias: "sub", required: false }] }], subTone: [{ type: i0.Input, args: [{ isSignal: true, alias: "subTone", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
|
|
1942
|
+
|
|
1943
|
+
const nextId$2 = (() => {
|
|
1405
1944
|
let count = 0;
|
|
1406
1945
|
return () => `ui-field-${++count}`;
|
|
1407
1946
|
})();
|
|
@@ -1430,6 +1969,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
1430
1969
|
},
|
|
1431
1970
|
}]
|
|
1432
1971
|
}] });
|
|
1972
|
+
/**
|
|
1973
|
+
* Marks an element, typically an icon button, as the trailing action of a `ui-field`: it sits on the
|
|
1974
|
+
* control's right edge, square to the control's height, and the control's text is padded to clear it.
|
|
1975
|
+
*
|
|
1976
|
+
* @example
|
|
1977
|
+
* <ui-field label="Password">
|
|
1978
|
+
* <input uiInput type="password" size="xl" />
|
|
1979
|
+
* <button uiFieldTrailing type="button" aria-label="Show the password" [attr.aria-pressed]="shown()">...</button>
|
|
1980
|
+
* </ui-field>
|
|
1981
|
+
*
|
|
1982
|
+
* A toggle such as this one should carry `aria-pressed`. The slot shares the right edge with `unit`:
|
|
1983
|
+
* set one or the other, not both.
|
|
1984
|
+
*/
|
|
1985
|
+
class UiFieldTrailing {
|
|
1986
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiFieldTrailing, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
1987
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.7", type: UiFieldTrailing, isStandalone: true, selector: "[uiFieldTrailing]", host: { classAttribute: "absolute right-0 grid h-full aspect-square place-items-center rounded-control cursor-pointer text-(--muted-foreground) hover:text-(--foreground) focus-visible:outline-2 focus-visible:-outline-offset-4 focus-visible:outline-(--ring)" }, ngImport: i0 });
|
|
1988
|
+
}
|
|
1989
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiFieldTrailing, decorators: [{
|
|
1990
|
+
type: Directive,
|
|
1991
|
+
args: [{
|
|
1992
|
+
selector: '[uiFieldTrailing]',
|
|
1993
|
+
host: {
|
|
1994
|
+
class: 'absolute right-0 grid h-full aspect-square place-items-center rounded-control cursor-pointer text-(--muted-foreground) hover:text-(--foreground) focus-visible:outline-2 focus-visible:-outline-offset-4 focus-visible:outline-(--ring)',
|
|
1995
|
+
},
|
|
1996
|
+
}]
|
|
1997
|
+
}] });
|
|
1433
1998
|
/**
|
|
1434
1999
|
* Label, control, hint and error as one unit. The control stays a plain native element:
|
|
1435
2000
|
* the field finds it in its own projected content and wires the ARIA attributes onto it.
|
|
@@ -1462,7 +2027,10 @@ class UiField {
|
|
|
1462
2027
|
...(ngDevMode ? [undefined, { debugName: "error" }] : /* istanbul ignore next */ []));
|
|
1463
2028
|
unit = input(/* @ts-ignore */
|
|
1464
2029
|
...(ngDevMode ? [undefined, { debugName: "unit" }] : /* istanbul ignore next */ []));
|
|
1465
|
-
|
|
2030
|
+
optional = input(/* @ts-ignore */
|
|
2031
|
+
...(ngDevMode ? [undefined, { debugName: "optional" }] : /* istanbul ignore next */ []));
|
|
2032
|
+
invalid = input(false, { ...(ngDevMode ? { debugName: "invalid" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
2033
|
+
#id = nextId$2();
|
|
1466
2034
|
hintId = `${this.#id}-hint`;
|
|
1467
2035
|
errorId = `${this.#id}-error`;
|
|
1468
2036
|
#host = inject(ElementRef);
|
|
@@ -1470,7 +2038,9 @@ class UiField {
|
|
|
1470
2038
|
...(ngDevMode ? [{ debugName: "control" }] : /* istanbul ignore next */ []));
|
|
1471
2039
|
leading = contentChild(UiFieldLeading, /* @ts-ignore */
|
|
1472
2040
|
...(ngDevMode ? [{ debugName: "leading" }] : /* istanbul ignore next */ []));
|
|
1473
|
-
|
|
2041
|
+
trailing = contentChild(UiFieldTrailing, /* @ts-ignore */
|
|
2042
|
+
...(ngDevMode ? [{ debugName: "trailing" }] : /* istanbul ignore next */ []));
|
|
2043
|
+
rowClasses = computed(() => `relative flex items-center${this.leading() ? ' [&>input]:pl-[38px]' : ''}${this.trailing() ? ' [&>input]:pr-12 lg:[&>input]:pr-11' : ''}`, /* @ts-ignore */
|
|
1474
2044
|
...(ngDevMode ? [{ debugName: "rowClasses" }] : /* istanbul ignore next */ []));
|
|
1475
2045
|
labelClasses = computed(() => this.labelHidden() ? 'sr-only' : 'text-label leading-[17px] font-medium text-(--muted-foreground)', /* @ts-ignore */
|
|
1476
2046
|
...(ngDevMode ? [{ debugName: "labelClasses" }] : /* istanbul ignore next */ []));
|
|
@@ -1491,6 +2061,7 @@ class UiField {
|
|
|
1491
2061
|
}, /* @ts-ignore */
|
|
1492
2062
|
...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
1493
2063
|
constructor() {
|
|
2064
|
+
let markedByField = false;
|
|
1494
2065
|
afterRenderEffect(() => {
|
|
1495
2066
|
// querySelector, not viewChild.required, so the "no control found" guard below stays reachable and testable.
|
|
1496
2067
|
const control = this.#host.nativeElement.querySelector('input, select, textarea');
|
|
@@ -1506,24 +2077,31 @@ class UiField {
|
|
|
1506
2077
|
else {
|
|
1507
2078
|
control.removeAttribute('aria-describedby');
|
|
1508
2079
|
}
|
|
1509
|
-
if (this.message()) {
|
|
2080
|
+
if (this.message() || this.invalid()) {
|
|
1510
2081
|
control.setAttribute('aria-invalid', 'true');
|
|
2082
|
+
markedByField = true;
|
|
1511
2083
|
}
|
|
1512
|
-
else {
|
|
2084
|
+
else if (markedByField) {
|
|
1513
2085
|
control.removeAttribute('aria-invalid');
|
|
2086
|
+
markedByField = false;
|
|
1514
2087
|
}
|
|
1515
2088
|
});
|
|
1516
2089
|
}
|
|
1517
2090
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiField, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1518
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiField, isStandalone: true, selector: "ui-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, labelHidden: { classPropertyName: "labelHidden", publicName: "labelHidden", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, unit: { classPropertyName: "unit", publicName: "unit", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "control", first: true, predicate: UI_CONTROL, descendants: true, isSignal: true }, { propertyName: "leading", first: true, predicate: UiFieldLeading, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
2091
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiField, isStandalone: true, selector: "ui-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, labelHidden: { classPropertyName: "labelHidden", publicName: "labelHidden", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, unit: { classPropertyName: "unit", publicName: "unit", isSignal: true, isRequired: false, transformFunction: null }, optional: { classPropertyName: "optional", publicName: "optional", isSignal: true, isRequired: false, transformFunction: null }, invalid: { classPropertyName: "invalid", publicName: "invalid", isSignal: true, isRequired: false, transformFunction: null } }, queries: [{ propertyName: "control", first: true, predicate: UI_CONTROL, descendants: true, isSignal: true }, { propertyName: "leading", first: true, predicate: UiFieldLeading, descendants: true, isSignal: true }, { propertyName: "trailing", first: true, predicate: UiFieldTrailing, descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
1519
2092
|
<div class="group flex flex-col gap-1.5">
|
|
1520
2093
|
<!-- eslint-disable-next-line @angular-eslint/template/label-has-associated-control -- htmlFor is wired at runtime, once the projected control's id is known -->
|
|
1521
|
-
<label [class]="labelClasses()"
|
|
2094
|
+
<label [class]="labelClasses()"
|
|
2095
|
+
>{{ label() }}
|
|
2096
|
+
@if (optional()) {
|
|
2097
|
+
{{ ' ' }}<span class="font-normal text-(--subtle-foreground)">{{ optional() }}</span>
|
|
2098
|
+
}
|
|
2099
|
+
</label>
|
|
1522
2100
|
|
|
1523
2101
|
<div [class]="rowClasses()">
|
|
1524
2102
|
<ng-content select="[uiFieldLeading]" />
|
|
1525
2103
|
<ng-content />
|
|
1526
|
-
|
|
2104
|
+
<ng-content select="[uiFieldTrailing]" />
|
|
1527
2105
|
@if (unit()) {
|
|
1528
2106
|
<span class="text-label pointer-events-none absolute right-3 text-(--subtle-foreground)">{{ unit() }}</span>
|
|
1529
2107
|
}
|
|
@@ -1542,32 +2120,117 @@ class UiField {
|
|
|
1542
2120
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiField, decorators: [{
|
|
1543
2121
|
type: Component,
|
|
1544
2122
|
args: [{
|
|
1545
|
-
selector: 'ui-field',
|
|
2123
|
+
selector: 'ui-field',
|
|
2124
|
+
template: `
|
|
2125
|
+
<div class="group flex flex-col gap-1.5">
|
|
2126
|
+
<!-- eslint-disable-next-line @angular-eslint/template/label-has-associated-control -- htmlFor is wired at runtime, once the projected control's id is known -->
|
|
2127
|
+
<label [class]="labelClasses()"
|
|
2128
|
+
>{{ label() }}
|
|
2129
|
+
@if (optional()) {
|
|
2130
|
+
{{ ' ' }}<span class="font-normal text-(--subtle-foreground)">{{ optional() }}</span>
|
|
2131
|
+
}
|
|
2132
|
+
</label>
|
|
2133
|
+
|
|
2134
|
+
<div [class]="rowClasses()">
|
|
2135
|
+
<ng-content select="[uiFieldLeading]" />
|
|
2136
|
+
<ng-content />
|
|
2137
|
+
<ng-content select="[uiFieldTrailing]" />
|
|
2138
|
+
@if (unit()) {
|
|
2139
|
+
<span class="text-label pointer-events-none absolute right-3 text-(--subtle-foreground)">{{ unit() }}</span>
|
|
2140
|
+
}
|
|
2141
|
+
</div>
|
|
2142
|
+
|
|
2143
|
+
@if (hint()) {
|
|
2144
|
+
<span class="text-label text-(--muted-foreground)" [id]="hintId">{{ hint() }}</span>
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
@if (message()) {
|
|
2148
|
+
<p class="text-label font-medium text-(--negative)" role="alert" [id]="errorId">{{ message() }}</p>
|
|
2149
|
+
}
|
|
2150
|
+
</div>
|
|
2151
|
+
`,
|
|
2152
|
+
}]
|
|
2153
|
+
}], ctorParameters: () => [], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], labelHidden: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelHidden", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], unit: [{ type: i0.Input, args: [{ isSignal: true, alias: "unit", required: false }] }], optional: [{ type: i0.Input, args: [{ isSignal: true, alias: "optional", required: false }] }], invalid: [{ type: i0.Input, args: [{ isSignal: true, alias: "invalid", required: false }] }], control: [{ type: i0.ContentChild, args: [i0.forwardRef(() => UI_CONTROL), { isSignal: true }] }], leading: [{ type: i0.ContentChild, args: [i0.forwardRef(() => UiFieldLeading), { isSignal: true }] }], trailing: [{ type: i0.ContentChild, args: [i0.forwardRef(() => UiFieldTrailing), { isSignal: true }] }] } });
|
|
2154
|
+
|
|
2155
|
+
const CHIP_CLASSES = 'flex-none flex h-11 items-center rounded-pill border-0 bg-transparent p-0 font-[inherit] cursor-pointer transition-transform duration-(--duration-press) ease-out active:scale-(--press-scale) focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) pointer-fine:h-8 pointer-fine:focus-visible:outline-offset-2';
|
|
2156
|
+
const PILL_CLASSES = 'flex h-[34px] items-center gap-1.5 rounded-pill px-3.5 text-label font-medium whitespace-nowrap pointer-fine:h-8 pointer-fine:px-3 pointer-fine:group-hover/chip:shadow-[inset_0_0_0_1px_var(--muted-foreground)]';
|
|
2157
|
+
const SELECTED_PILL_CLASSES = 'bg-(--primary) text-(--primary-foreground)';
|
|
2158
|
+
const UNSELECTED_PILL_CLASSES = 'bg-(--card) text-(--foreground) shadow-[inset_0_0_0_1px_var(--border)]';
|
|
2159
|
+
/**
|
|
2160
|
+
* A row of single-choice filter pills, each with an optional count, that narrows a list in place:
|
|
2161
|
+
* an asset class, a status. On touch it scrolls on one line, bleeding to the screen edges; with a
|
|
2162
|
+
* fine pointer it wraps.
|
|
2163
|
+
*
|
|
2164
|
+
* @example
|
|
2165
|
+
* <ui-filter-chips ariaLabel="Filter by class" [options]="classes()" [(value)]="selectedClass" />
|
|
2166
|
+
*/
|
|
2167
|
+
class UiFilterChips {
|
|
2168
|
+
options = input.required(/* @ts-ignore */
|
|
2169
|
+
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
2170
|
+
value = model.required(/* @ts-ignore */
|
|
2171
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
2172
|
+
ariaLabel = input.required(/* @ts-ignore */
|
|
2173
|
+
...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
2174
|
+
chipClasses = CHIP_CLASSES;
|
|
2175
|
+
pillClasses(optionValue) {
|
|
2176
|
+
return `${PILL_CLASSES} ${optionValue === this.value() ? SELECTED_PILL_CLASSES : UNSELECTED_PILL_CLASSES}`;
|
|
2177
|
+
}
|
|
2178
|
+
countClasses(optionValue) {
|
|
2179
|
+
return optionValue === this.value() ? 'text-(--primary-foreground)' : 'text-(--subtle-foreground)';
|
|
2180
|
+
}
|
|
2181
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiFilterChips, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2182
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiFilterChips, isStandalone: true, selector: "ui-filter-chips", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { value: "valueChange" }, host: { attributes: { "role": "group" }, properties: { "attr.aria-label": "ariaLabel()" }, classAttribute: "flex gap-2 overflow-x-auto [scrollbar-width:none] -mt-1 -mx-(--gutter) px-(--gutter) pointer-fine:m-0 pointer-fine:flex-wrap pointer-fine:overflow-visible pointer-fine:p-0" }, ngImport: i0, template: `
|
|
2183
|
+
@for (option of options(); track option.value) {
|
|
2184
|
+
<button
|
|
2185
|
+
class="group/chip"
|
|
2186
|
+
type="button"
|
|
2187
|
+
[attr.aria-pressed]="option.value === value()"
|
|
2188
|
+
[class]="chipClasses"
|
|
2189
|
+
(click)="value.set(option.value)"
|
|
2190
|
+
>
|
|
2191
|
+
<span data-chip [class]="pillClasses(option.value)"
|
|
2192
|
+
>{{ option.label }}
|
|
2193
|
+
@if (option.count !== undefined && option.count !== null) {
|
|
2194
|
+
&ngsp;<span class="[font-variant-numeric:var(--numeric)]" data-count [class]="countClasses(option.value)">{{
|
|
2195
|
+
option.count
|
|
2196
|
+
}}</span>
|
|
2197
|
+
}
|
|
2198
|
+
</span>
|
|
2199
|
+
</button>
|
|
2200
|
+
}
|
|
2201
|
+
`, isInline: true });
|
|
2202
|
+
}
|
|
2203
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiFilterChips, decorators: [{
|
|
2204
|
+
type: Component,
|
|
2205
|
+
args: [{
|
|
2206
|
+
selector: 'ui-filter-chips',
|
|
1546
2207
|
template: `
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
<p class="text-label font-medium text-(--negative)" role="alert" [id]="errorId">{{ message() }}</p>
|
|
1566
|
-
}
|
|
1567
|
-
</div>
|
|
2208
|
+
@for (option of options(); track option.value) {
|
|
2209
|
+
<button
|
|
2210
|
+
class="group/chip"
|
|
2211
|
+
type="button"
|
|
2212
|
+
[attr.aria-pressed]="option.value === value()"
|
|
2213
|
+
[class]="chipClasses"
|
|
2214
|
+
(click)="value.set(option.value)"
|
|
2215
|
+
>
|
|
2216
|
+
<span data-chip [class]="pillClasses(option.value)"
|
|
2217
|
+
>{{ option.label }}
|
|
2218
|
+
@if (option.count !== undefined && option.count !== null) {
|
|
2219
|
+
&ngsp;<span class="[font-variant-numeric:var(--numeric)]" data-count [class]="countClasses(option.value)">{{
|
|
2220
|
+
option.count
|
|
2221
|
+
}}</span>
|
|
2222
|
+
}
|
|
2223
|
+
</span>
|
|
2224
|
+
</button>
|
|
2225
|
+
}
|
|
1568
2226
|
`,
|
|
2227
|
+
host: {
|
|
2228
|
+
role: 'group',
|
|
2229
|
+
class: 'flex gap-2 overflow-x-auto [scrollbar-width:none] -mt-1 -mx-(--gutter) px-(--gutter) pointer-fine:m-0 pointer-fine:flex-wrap pointer-fine:overflow-visible pointer-fine:p-0',
|
|
2230
|
+
'[attr.aria-label]': 'ariaLabel()',
|
|
2231
|
+
},
|
|
1569
2232
|
}]
|
|
1570
|
-
}],
|
|
2233
|
+
}], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }, { type: i0.Output, args: ["valueChange"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: true }] }] } });
|
|
1571
2234
|
|
|
1572
2235
|
const axisTicks = (points, maxTicks = 5) => {
|
|
1573
2236
|
if (points.length <= maxTicks) {
|
|
@@ -1824,6 +2487,8 @@ class UiLineChart {
|
|
|
1824
2487
|
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
1825
2488
|
valueFormat = input(identityValue, /* @ts-ignore */
|
|
1826
2489
|
...(ngDevMode ? [{ debugName: "valueFormat" }] : /* istanbul ignore next */ []));
|
|
2490
|
+
tooltipFormat = input(/* @ts-ignore */
|
|
2491
|
+
...(ngDevMode ? [undefined, { debugName: "tooltipFormat" }] : /* istanbul ignore next */ []));
|
|
1827
2492
|
deltaFormat = input(identityDelta, /* @ts-ignore */
|
|
1828
2493
|
...(ngDevMode ? [{ debugName: "deltaFormat" }] : /* istanbul ignore next */ []));
|
|
1829
2494
|
timeFormat = input(identityTime, /* @ts-ignore */
|
|
@@ -1986,7 +2651,7 @@ class UiLineChart {
|
|
|
1986
2651
|
this.activeIndex.set(navigation.index);
|
|
1987
2652
|
}
|
|
1988
2653
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiLineChart, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1989
|
-
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 }, 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 }], ngImport: i0, template: `
|
|
2654
|
+
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 }], ngImport: i0, template: `
|
|
1990
2655
|
<div class="relative h-full">
|
|
1991
2656
|
<svg
|
|
1992
2657
|
#svgRef
|
|
@@ -2097,36 +2762,35 @@ class UiLineChart {
|
|
|
2097
2762
|
[class]="tooltipClasses().box"
|
|
2098
2763
|
[style]="tooltipStyle(point)"
|
|
2099
2764
|
>
|
|
2100
|
-
<p class="font-medium text-(--foreground)" [class]="tooltipClasses().value">
|
|
2765
|
+
<p class="font-medium text-(--foreground)" [class]="tooltipClasses().value">
|
|
2766
|
+
{{ tooltipFormat()?.(point) ?? valueFormat()(point.v) }}
|
|
2767
|
+
</p>
|
|
2101
2768
|
@if (tooltipDelta()) {
|
|
2102
2769
|
<p data-chart-delta [class]="deltaClasses(point)">{{ deltaFormat()(deltaFor(point)) }}</p>
|
|
2103
2770
|
}
|
|
2104
2771
|
<p class="text-caption text-(--subtle-foreground)" data-chart-date>{{ timeFormat()(point.t) }}</p>
|
|
2105
2772
|
</div>
|
|
2106
2773
|
}
|
|
2107
|
-
|
|
2108
2774
|
@if (points().length > 0) {
|
|
2109
|
-
<
|
|
2110
|
-
<
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
}}
|
|
2114
|
-
</caption>
|
|
2115
|
-
<thead>
|
|
2116
|
-
<tr>
|
|
2117
|
-
<th scope="col">{{ timeColumnLabel() }}</th>
|
|
2118
|
-
<th scope="col">{{ valueColumnLabel() }}</th>
|
|
2119
|
-
</tr>
|
|
2120
|
-
</thead>
|
|
2121
|
-
<tbody>
|
|
2122
|
-
@for (point of points(); track point.t) {
|
|
2775
|
+
<div class="sr-only">
|
|
2776
|
+
<table>
|
|
2777
|
+
<caption [textContent]="label()"></caption>
|
|
2778
|
+
<thead>
|
|
2123
2779
|
<tr>
|
|
2124
|
-
<
|
|
2125
|
-
<
|
|
2780
|
+
<th scope="col">{{ timeColumnLabel() }}</th>
|
|
2781
|
+
<th scope="col">{{ valueColumnLabel() }}</th>
|
|
2126
2782
|
</tr>
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2783
|
+
</thead>
|
|
2784
|
+
<tbody>
|
|
2785
|
+
@for (point of points(); track point.t) {
|
|
2786
|
+
<tr>
|
|
2787
|
+
<td>{{ timeFormat()(point.t) }}</td>
|
|
2788
|
+
<td>{{ valueFormat()(point.v) }}</td>
|
|
2789
|
+
</tr>
|
|
2790
|
+
}
|
|
2791
|
+
</tbody>
|
|
2792
|
+
</table>
|
|
2793
|
+
</div>
|
|
2130
2794
|
}
|
|
2131
2795
|
</div>
|
|
2132
2796
|
`, isInline: true });
|
|
@@ -2246,36 +2910,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
2246
2910
|
[class]="tooltipClasses().box"
|
|
2247
2911
|
[style]="tooltipStyle(point)"
|
|
2248
2912
|
>
|
|
2249
|
-
<p class="font-medium text-(--foreground)" [class]="tooltipClasses().value">
|
|
2913
|
+
<p class="font-medium text-(--foreground)" [class]="tooltipClasses().value">
|
|
2914
|
+
{{ tooltipFormat()?.(point) ?? valueFormat()(point.v) }}
|
|
2915
|
+
</p>
|
|
2250
2916
|
@if (tooltipDelta()) {
|
|
2251
2917
|
<p data-chart-delta [class]="deltaClasses(point)">{{ deltaFormat()(deltaFor(point)) }}</p>
|
|
2252
2918
|
}
|
|
2253
2919
|
<p class="text-caption text-(--subtle-foreground)" data-chart-date>{{ timeFormat()(point.t) }}</p>
|
|
2254
2920
|
</div>
|
|
2255
2921
|
}
|
|
2256
|
-
|
|
2257
2922
|
@if (points().length > 0) {
|
|
2258
|
-
<
|
|
2259
|
-
<
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
}}
|
|
2263
|
-
</caption>
|
|
2264
|
-
<thead>
|
|
2265
|
-
<tr>
|
|
2266
|
-
<th scope="col">{{ timeColumnLabel() }}</th>
|
|
2267
|
-
<th scope="col">{{ valueColumnLabel() }}</th>
|
|
2268
|
-
</tr>
|
|
2269
|
-
</thead>
|
|
2270
|
-
<tbody>
|
|
2271
|
-
@for (point of points(); track point.t) {
|
|
2923
|
+
<div class="sr-only">
|
|
2924
|
+
<table>
|
|
2925
|
+
<caption [textContent]="label()"></caption>
|
|
2926
|
+
<thead>
|
|
2272
2927
|
<tr>
|
|
2273
|
-
<
|
|
2274
|
-
<
|
|
2928
|
+
<th scope="col">{{ timeColumnLabel() }}</th>
|
|
2929
|
+
<th scope="col">{{ valueColumnLabel() }}</th>
|
|
2275
2930
|
</tr>
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2931
|
+
</thead>
|
|
2932
|
+
<tbody>
|
|
2933
|
+
@for (point of points(); track point.t) {
|
|
2934
|
+
<tr>
|
|
2935
|
+
<td>{{ timeFormat()(point.t) }}</td>
|
|
2936
|
+
<td>{{ valueFormat()(point.v) }}</td>
|
|
2937
|
+
</tr>
|
|
2938
|
+
}
|
|
2939
|
+
</tbody>
|
|
2940
|
+
</table>
|
|
2941
|
+
</div>
|
|
2279
2942
|
}
|
|
2280
2943
|
</div>
|
|
2281
2944
|
`,
|
|
@@ -2283,11 +2946,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
2283
2946
|
class: 'block h-full',
|
|
2284
2947
|
},
|
|
2285
2948
|
}]
|
|
2286
|
-
}], 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 }] }], 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 }] }] } });
|
|
2949
|
+
}], 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 }] }] } });
|
|
2287
2950
|
|
|
2288
2951
|
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,transform,overlay,display] transition-discrete duration-(--duration-fast) ease-out starting:open:opacity-0 starting:open:scale-(--enter-scale) opacity-0 scale-(--enter-scale) open:opacity-100 open:scale-100';
|
|
2289
|
-
const
|
|
2290
|
-
const
|
|
2952
|
+
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';
|
|
2953
|
+
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) 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';
|
|
2954
|
+
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) 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';
|
|
2955
|
+
const nextId$1 = (() => {
|
|
2291
2956
|
let count = 0;
|
|
2292
2957
|
return () => `ui-menu-${++count}`;
|
|
2293
2958
|
})();
|
|
@@ -2301,7 +2966,7 @@ class UiMenuItem {
|
|
|
2301
2966
|
destructive = input(false, { ...(ngDevMode ? { debugName: "destructive" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
2302
2967
|
#host = inject(ElementRef).nativeElement;
|
|
2303
2968
|
#menu = inject(UiMenu);
|
|
2304
|
-
classes = computed(() => `${ITEM_CLASSES}${this.destructive() ? ' text-(--negative)' : ''}`, /* @ts-ignore */
|
|
2969
|
+
classes = computed(() => `${this.#menu.sheet() ? SHEET_ITEM_CLASSES : ITEM_CLASSES}${this.destructive() ? ' text-(--negative)' : ''}`, /* @ts-ignore */
|
|
2305
2970
|
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
2306
2971
|
focus() {
|
|
2307
2972
|
this.#host.focus();
|
|
@@ -2328,7 +2993,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
2328
2993
|
}]
|
|
2329
2994
|
}], propDecorators: { destructive: [{ type: i0.Input, args: [{ isSignal: true, alias: "destructive", required: false }] }] } });
|
|
2330
2995
|
/**
|
|
2331
|
-
* Secondary actions menu, opened from its trigger through the native Popover API.
|
|
2996
|
+
* Secondary actions menu, opened from its trigger through the native Popover API. With `sheet`, below
|
|
2997
|
+
* 64rem it opens as a bottom action sheet above the tab bar instead of beside its trigger, and
|
|
2998
|
+
* `heading` names what the actions apply to. `width` fixes the outer popover width in pixels (the sheet
|
|
2999
|
+
* always spans the screen below 64rem); without it the menu fits its content.
|
|
2332
3000
|
*
|
|
2333
3001
|
* @example
|
|
2334
3002
|
* <button ui-button size="icon" aria-label="More" [uiMenuTrigger]="menu">...</button>
|
|
@@ -2340,10 +3008,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
2340
3008
|
class UiMenu {
|
|
2341
3009
|
label = input.required(/* @ts-ignore */
|
|
2342
3010
|
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
2343
|
-
|
|
3011
|
+
sheet = input(false, { ...(ngDevMode ? { debugName: "sheet" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
3012
|
+
heading = input(/* @ts-ignore */
|
|
3013
|
+
...(ngDevMode ? [undefined, { debugName: "heading" }] : /* istanbul ignore next */ []));
|
|
3014
|
+
width = input(undefined, { ...(ngDevMode ? { debugName: "width" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
3015
|
+
menuId = nextId$1();
|
|
2344
3016
|
isOpen = signal(false, /* @ts-ignore */
|
|
2345
3017
|
...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
|
|
2346
|
-
|
|
3018
|
+
hasWidth = computed(() => Number.isFinite(this.width()), /* @ts-ignore */
|
|
3019
|
+
...(ngDevMode ? [{ debugName: "hasWidth" }] : /* istanbul ignore next */ []));
|
|
3020
|
+
widthVar = computed(() => (this.hasWidth() ? `${this.width()}px` : null), /* @ts-ignore */
|
|
3021
|
+
...(ngDevMode ? [{ debugName: "widthVar" }] : /* istanbul ignore next */ []));
|
|
3022
|
+
classes = computed(() => {
|
|
3023
|
+
const width = !this.hasWidth() ? '' : this.sheet() ? ' lg:w-(--ui-menu-width)' : ' w-(--ui-menu-width)';
|
|
3024
|
+
return `${MENU_CLASSES}${this.sheet() ? ` ${SHEET_CLASSES}` : ''}${width}`;
|
|
3025
|
+
}, /* @ts-ignore */
|
|
3026
|
+
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
2347
3027
|
items = contentChildren(UiMenuItem, /* @ts-ignore */
|
|
2348
3028
|
...(ngDevMode ? [{ debugName: "items" }] : /* istanbul ignore next */ []));
|
|
2349
3029
|
#host = inject(ElementRef).nativeElement;
|
|
@@ -2354,7 +3034,14 @@ class UiMenu {
|
|
|
2354
3034
|
if (typeof this.#host.showPopover === 'function') {
|
|
2355
3035
|
this.#host.showPopover();
|
|
2356
3036
|
}
|
|
2357
|
-
this.#
|
|
3037
|
+
if (this.#isSheet()) {
|
|
3038
|
+
this.#host.style.position = '';
|
|
3039
|
+
this.#host.style.top = '';
|
|
3040
|
+
this.#host.style.left = '';
|
|
3041
|
+
}
|
|
3042
|
+
else {
|
|
3043
|
+
this.#position(trigger);
|
|
3044
|
+
}
|
|
2358
3045
|
this.items()[0]?.focus();
|
|
2359
3046
|
}
|
|
2360
3047
|
close() {
|
|
@@ -2404,6 +3091,9 @@ class UiMenu {
|
|
|
2404
3091
|
event.preventDefault();
|
|
2405
3092
|
items[nextIndex]?.focus();
|
|
2406
3093
|
}
|
|
3094
|
+
#isSheet() {
|
|
3095
|
+
return this.sheet() && typeof window.matchMedia === 'function' && !window.matchMedia('(min-width: 64rem)').matches;
|
|
3096
|
+
}
|
|
2407
3097
|
#position(trigger) {
|
|
2408
3098
|
const margin = 8;
|
|
2409
3099
|
const triggerRect = trigger.getBoundingClientRect();
|
|
@@ -2417,24 +3107,39 @@ class UiMenu {
|
|
|
2417
3107
|
this.#host.style.transformOrigin = fitsBelow ? 'top right' : 'bottom right';
|
|
2418
3108
|
}
|
|
2419
3109
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiMenu, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2420
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
3110
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiMenu, isStandalone: true, selector: "ui-menu", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, sheet: { classPropertyName: "sheet", publicName: "sheet", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, width: { classPropertyName: "width", publicName: "width", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "role": "menu", "popover": "auto" }, listeners: { "toggle": "onToggle($event)", "keydown": "onKeydown($event)" }, properties: { "id": "menuId", "style.--ui-menu-width": "widthVar()", "class": "classes()", "attr.aria-label": "label()" } }, queries: [{ propertyName: "items", predicate: UiMenuItem, isSignal: true }], ngImport: i0, template: `
|
|
3111
|
+
@if (sheet() && heading()) {
|
|
3112
|
+
<div aria-hidden="true" class="text-label px-3 pt-2 pb-1.5 leading-[17px] text-(--muted-foreground) lg:hidden">
|
|
3113
|
+
{{ heading() }}
|
|
3114
|
+
</div>
|
|
3115
|
+
}
|
|
3116
|
+
<ng-content />
|
|
3117
|
+
`, isInline: true });
|
|
2421
3118
|
}
|
|
2422
3119
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiMenu, decorators: [{
|
|
2423
3120
|
type: Component,
|
|
2424
3121
|
args: [{
|
|
2425
3122
|
selector: 'ui-menu',
|
|
2426
|
-
template:
|
|
3123
|
+
template: `
|
|
3124
|
+
@if (sheet() && heading()) {
|
|
3125
|
+
<div aria-hidden="true" class="text-label px-3 pt-2 pb-1.5 leading-[17px] text-(--muted-foreground) lg:hidden">
|
|
3126
|
+
{{ heading() }}
|
|
3127
|
+
</div>
|
|
3128
|
+
}
|
|
3129
|
+
<ng-content />
|
|
3130
|
+
`,
|
|
2427
3131
|
host: {
|
|
2428
3132
|
role: 'menu',
|
|
2429
3133
|
popover: 'auto',
|
|
2430
3134
|
'[id]': 'menuId',
|
|
2431
|
-
'[
|
|
3135
|
+
'[style.--ui-menu-width]': 'widthVar()',
|
|
3136
|
+
'[class]': 'classes()',
|
|
2432
3137
|
'[attr.aria-label]': 'label()',
|
|
2433
3138
|
'(toggle)': 'onToggle($event)',
|
|
2434
3139
|
'(keydown)': 'onKeydown($event)',
|
|
2435
3140
|
},
|
|
2436
3141
|
}]
|
|
2437
|
-
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], items: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => UiMenuItem), { isSignal: true }] }] } });
|
|
3142
|
+
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], sheet: [{ type: i0.Input, args: [{ isSignal: true, alias: "sheet", required: false }] }], heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], width: [{ type: i0.Input, args: [{ isSignal: true, alias: "width", required: false }] }], items: [{ type: i0.ContentChildren, args: [i0.forwardRef(() => UiMenuItem), { isSignal: true }] }] } });
|
|
2438
3143
|
/**
|
|
2439
3144
|
* Opens a `ui-menu` from a trigger element and wires `aria-haspopup`, `aria-expanded` and
|
|
2440
3145
|
* `aria-controls` on it.
|
|
@@ -2471,6 +3176,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
2471
3176
|
}]
|
|
2472
3177
|
}], propDecorators: { uiMenuTrigger: [{ type: i0.Input, args: [{ isSignal: true, alias: "uiMenuTrigger", required: true }] }] } });
|
|
2473
3178
|
|
|
3179
|
+
/** Track thicknesses. `MeterSize` is derived from this tuple. */
|
|
3180
|
+
const METER_SIZES = ['md', 'sm'];
|
|
3181
|
+
const TRACK_CLASSES = {
|
|
3182
|
+
md: 'h-1.5',
|
|
3183
|
+
sm: 'h-1',
|
|
3184
|
+
};
|
|
2474
3185
|
/** Ramp step used to paint the fill. `MeterTone` is derived from this tuple. */
|
|
2475
3186
|
const METER_TONES = [1, 2, 3, 4, 5, 6];
|
|
2476
3187
|
const TONE_CLASSES = {
|
|
@@ -2497,20 +3208,25 @@ class UiMeter {
|
|
|
2497
3208
|
...(ngDevMode ? [{ debugName: "valueText" }] : /* istanbul ignore next */ []));
|
|
2498
3209
|
tone = input(1, /* @ts-ignore */
|
|
2499
3210
|
...(ngDevMode ? [{ debugName: "tone" }] : /* istanbul ignore next */ []));
|
|
3211
|
+
size = input('md', /* @ts-ignore */
|
|
3212
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
3213
|
+
trackClasses = computed(() => TRACK_CLASSES[this.size()], /* @ts-ignore */
|
|
3214
|
+
...(ngDevMode ? [{ debugName: "trackClasses" }] : /* istanbul ignore next */ []));
|
|
2500
3215
|
percent = computed(() => Math.min(100, Math.max(0, this.value() * 100)), /* @ts-ignore */
|
|
2501
3216
|
...(ngDevMode ? [{ debugName: "percent" }] : /* istanbul ignore next */ []));
|
|
2502
3217
|
fillClasses = computed(() => `h-full rounded-pill ${TONE_CLASSES[this.tone()]}`, /* @ts-ignore */
|
|
2503
3218
|
...(ngDevMode ? [{ debugName: "fillClasses" }] : /* istanbul ignore next */ []));
|
|
2504
3219
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiMeter, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2505
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UiMeter, isStandalone: true, selector: "ui-meter", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, valueText: { classPropertyName: "valueText", publicName: "valueText", isSignal: true, isRequired: true, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
3220
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UiMeter, isStandalone: true, selector: "ui-meter", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, valueText: { classPropertyName: "valueText", publicName: "valueText", isSignal: true, isRequired: true, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
2506
3221
|
<div
|
|
2507
|
-
class="rounded-pill
|
|
3222
|
+
class="rounded-pill w-full overflow-hidden bg-(--muted)"
|
|
2508
3223
|
role="meter"
|
|
2509
3224
|
[attr.aria-label]="label()"
|
|
2510
3225
|
[attr.aria-valuemax]="1"
|
|
2511
3226
|
[attr.aria-valuemin]="0"
|
|
2512
3227
|
[attr.aria-valuenow]="value()"
|
|
2513
3228
|
[attr.aria-valuetext]="valueText()"
|
|
3229
|
+
[class]="trackClasses()"
|
|
2514
3230
|
>
|
|
2515
3231
|
<div data-testid="meter-fill" [class]="fillClasses()" [style.width.%]="percent()"></div>
|
|
2516
3232
|
</div>
|
|
@@ -2522,23 +3238,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
2522
3238
|
selector: 'ui-meter',
|
|
2523
3239
|
template: `
|
|
2524
3240
|
<div
|
|
2525
|
-
class="rounded-pill
|
|
3241
|
+
class="rounded-pill w-full overflow-hidden bg-(--muted)"
|
|
2526
3242
|
role="meter"
|
|
2527
3243
|
[attr.aria-label]="label()"
|
|
2528
3244
|
[attr.aria-valuemax]="1"
|
|
2529
3245
|
[attr.aria-valuemin]="0"
|
|
2530
3246
|
[attr.aria-valuenow]="value()"
|
|
2531
3247
|
[attr.aria-valuetext]="valueText()"
|
|
3248
|
+
[class]="trackClasses()"
|
|
2532
3249
|
>
|
|
2533
3250
|
<div data-testid="meter-fill" [class]="fillClasses()" [style.width.%]="percent()"></div>
|
|
2534
3251
|
</div>
|
|
2535
3252
|
`,
|
|
2536
3253
|
}]
|
|
2537
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], valueText: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueText", required: true }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }] } });
|
|
3254
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], valueText: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueText", required: true }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }] } });
|
|
2538
3255
|
|
|
2539
|
-
const BASE_CLASSES$1 = 'flex items-center gap-3 h-10 px-3 rounded-control text-label font-medium transition-colors duration-(--duration-press) hover:bg-(--glow) hover:text-(--foreground) focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring)';
|
|
3256
|
+
const BASE_CLASSES$1 = 'flex items-center gap-3 h-10 px-3 rounded-control text-label leading-normal font-medium transition-colors duration-(--duration-press) hover:bg-(--glow) hover:text-(--foreground) focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring)';
|
|
2540
3257
|
const ACTIVE_CLASSES = 'bg-(--soft) text-(--foreground)';
|
|
2541
|
-
const IDLE_CLASSES = 'text-(--muted-foreground)';
|
|
3258
|
+
const IDLE_CLASSES = 'text-(--muted-foreground) active:bg-(--soft)';
|
|
2542
3259
|
/**
|
|
2543
3260
|
* One destination of the sidebar navigation (Portfolio, Holdings, Allocation, Accounts).
|
|
2544
3261
|
*
|
|
@@ -2567,13 +3284,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
2567
3284
|
}]
|
|
2568
3285
|
}], propDecorators: { active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }] } });
|
|
2569
3286
|
|
|
2570
|
-
const ROW_SIZES = ['md', 'lg', 'xl'];
|
|
3287
|
+
const ROW_SIZES = ['md', 'lg', 'xl', 'card', 'dense'];
|
|
2571
3288
|
const ROW_PADDINGS = ['md', 'sm', 'none'];
|
|
2572
|
-
const
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
3289
|
+
const ROW_GAPS = ['default', 'sm'];
|
|
3290
|
+
const SIZE_CLASSES$1 = {
|
|
3291
|
+
md: 'min-h-14',
|
|
3292
|
+
lg: 'min-h-15',
|
|
3293
|
+
xl: 'min-h-18 pointer-fine:min-h-17',
|
|
3294
|
+
card: 'min-h-17',
|
|
3295
|
+
dense: 'min-h-14 lg:min-h-12',
|
|
2576
3296
|
};
|
|
3297
|
+
const SIZE_GAPS = { md: 'gap-2.5', lg: 'gap-2.5', xl: 'gap-3', card: 'gap-2', dense: 'gap-3' };
|
|
2577
3298
|
const PADDING_CLASSES = { md: 'px-2.5', sm: 'px-2', none: 'px-0' };
|
|
2578
3299
|
const BASE_CLASSES = 'flex w-full items-center py-1.5 rounded-control text-left select-none touch-manipulation transition-colors duration-(--duration-press) hover:bg-(--glow) active:bg-(--soft) focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring)';
|
|
2579
3300
|
const SELECTED_CLASSES$1 = 'bg-(--soft)';
|
|
@@ -2591,10 +3312,12 @@ class UiRow {
|
|
|
2591
3312
|
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
2592
3313
|
padding = input('md', /* @ts-ignore */
|
|
2593
3314
|
...(ngDevMode ? [{ debugName: "padding" }] : /* istanbul ignore next */ []));
|
|
2594
|
-
|
|
3315
|
+
gap = input('default', /* @ts-ignore */
|
|
3316
|
+
...(ngDevMode ? [{ debugName: "gap" }] : /* istanbul ignore next */ []));
|
|
3317
|
+
classes = computed(() => `${BASE_CLASSES} ${SIZE_CLASSES$1[this.size()]} ${this.gap() === 'sm' ? 'gap-2' : SIZE_GAPS[this.size()]} ${PADDING_CLASSES[this.padding()]}${this.selected() ? ` ${SELECTED_CLASSES$1}` : ''}`, /* @ts-ignore */
|
|
2595
3318
|
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
2596
3319
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiRow, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2597
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UiRow, isStandalone: true, selector: "a[ui-row], button[ui-row]", inputs: { selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()", "attr.aria-current": "selected() ? 'true' : null" } }, ngImport: i0, template: '<ng-content />', isInline: true });
|
|
3320
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UiRow, isStandalone: true, selector: "a[ui-row], button[ui-row]", inputs: { selected: { classPropertyName: "selected", publicName: "selected", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, padding: { classPropertyName: "padding", publicName: "padding", isSignal: true, isRequired: false, transformFunction: null }, gap: { classPropertyName: "gap", publicName: "gap", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()", "attr.aria-current": "selected() ? 'true' : null" } }, ngImport: i0, template: '<ng-content />', isInline: true });
|
|
2598
3321
|
}
|
|
2599
3322
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiRow, decorators: [{
|
|
2600
3323
|
type: Component,
|
|
@@ -2606,9 +3329,68 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
2606
3329
|
'[attr.aria-current]': "selected() ? 'true' : null",
|
|
2607
3330
|
},
|
|
2608
3331
|
}]
|
|
2609
|
-
}], propDecorators: { selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], padding: [{ type: i0.Input, args: [{ isSignal: true, alias: "padding", required: false }] }] } });
|
|
3332
|
+
}], propDecorators: { selected: [{ type: i0.Input, args: [{ isSignal: true, alias: "selected", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], padding: [{ type: i0.Input, args: [{ isSignal: true, alias: "padding", required: false }] }], gap: [{ type: i0.Input, args: [{ isSignal: true, alias: "gap", required: false }] }] } });
|
|
3333
|
+
/**
|
|
3334
|
+
* Lays out a `ui-row` with a trailing action beside it, such as a "more" icon button: the row takes
|
|
3335
|
+
* the room the action leaves and the action keeps its own size.
|
|
3336
|
+
*
|
|
3337
|
+
* @example
|
|
3338
|
+
* <div uiRowItem>
|
|
3339
|
+
* <a ui-row size="xl" padding="sm" routerLink="/accounts/1">...</a>
|
|
3340
|
+
* <button ui-button variant="quiet" size="icon-sm" aria-label="Account actions">...</button>
|
|
3341
|
+
* </div>
|
|
3342
|
+
*/
|
|
3343
|
+
class UiRowItem {
|
|
3344
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiRowItem, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3345
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.7", type: UiRowItem, isStandalone: true, selector: "[uiRowItem]", host: { classAttribute: "flex items-center gap-1 [&>[ui-row]]:w-auto [&>[ui-row]]:min-w-0 [&>[ui-row]]:flex-1 [&>:not([ui-row])]:flex-none" }, ngImport: i0 });
|
|
3346
|
+
}
|
|
3347
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiRowItem, decorators: [{
|
|
3348
|
+
type: Directive,
|
|
3349
|
+
args: [{
|
|
3350
|
+
selector: '[uiRowItem]',
|
|
3351
|
+
host: {
|
|
3352
|
+
class: 'flex items-center gap-1 [&>[ui-row]]:w-auto [&>[ui-row]]:min-w-0 [&>[ui-row]]:flex-1 [&>:not([ui-row])]:flex-none',
|
|
3353
|
+
},
|
|
3354
|
+
}]
|
|
3355
|
+
}] });
|
|
3356
|
+
/**
|
|
3357
|
+
* Non-interactive row of a list, separated from the next by a hairline: a passkey with its delete
|
|
3358
|
+
* button, a device, a setting. It is a 72px row (68px from 64rem) with a 12px gap; put it on an
|
|
3359
|
+
* `li` or a `div`. Use `ui-row` instead when the whole row is a link or an action.
|
|
3360
|
+
*
|
|
3361
|
+
* @example
|
|
3362
|
+
* <ul>
|
|
3363
|
+
* <li uiListRow>
|
|
3364
|
+
* <span class="flex-1">MacBook Air</span>
|
|
3365
|
+
* <button ui-button variant="quiet-destructive" size="icon-sm" aria-label="Delete MacBook Air">...</button>
|
|
3366
|
+
* </li>
|
|
3367
|
+
* </ul>
|
|
3368
|
+
*/
|
|
3369
|
+
class UiListRow {
|
|
3370
|
+
ruled = input(true, { ...(ngDevMode ? { debugName: "ruled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
3371
|
+
classes = computed(() => `flex min-h-18 items-center gap-3 py-1.5 lg:min-h-17${this.ruled() ? ' shadow-[inset_0_-1px_0_var(--hairline)]' : ''}`, /* @ts-ignore */
|
|
3372
|
+
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
3373
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiListRow, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3374
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.1.7", type: UiListRow, isStandalone: true, selector: "[uiListRow]", inputs: { ruled: { classPropertyName: "ruled", publicName: "ruled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0 });
|
|
3375
|
+
}
|
|
3376
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiListRow, decorators: [{
|
|
3377
|
+
type: Directive,
|
|
3378
|
+
args: [{
|
|
3379
|
+
selector: '[uiListRow]',
|
|
3380
|
+
host: { '[class]': 'classes()' },
|
|
3381
|
+
}]
|
|
3382
|
+
}], propDecorators: { ruled: [{ type: i0.Input, args: [{ isSignal: true, alias: "ruled", required: false }] }] } });
|
|
2610
3383
|
|
|
2611
|
-
const
|
|
3384
|
+
const nextId = (() => {
|
|
3385
|
+
let count = 0;
|
|
3386
|
+
return () => `ui-segmented-${++count}`;
|
|
3387
|
+
})();
|
|
3388
|
+
const OPTION_CLASSES = "relative z-10 flex-1 cursor-pointer px-3 text-label font-medium transition-colors 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)";
|
|
3389
|
+
const SEGMENTED_SIZES = ['md', 'sm'];
|
|
3390
|
+
const SIZE_CLASSES = {
|
|
3391
|
+
md: 'h-10 pointer-fine:h-8',
|
|
3392
|
+
sm: 'h-10 pointer-fine:h-[30px]',
|
|
3393
|
+
};
|
|
2612
3394
|
const SELECTED_CLASSES = 'text-(--foreground)';
|
|
2613
3395
|
const UNSELECTED_CLASSES = 'text-(--muted-foreground) hover:text-(--foreground)';
|
|
2614
3396
|
/**
|
|
@@ -2623,8 +3405,12 @@ class UiSegmented {
|
|
|
2623
3405
|
...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
|
|
2624
3406
|
label = input.required(/* @ts-ignore */
|
|
2625
3407
|
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
3408
|
+
showLabel = input(false, { ...(ngDevMode ? { debugName: "showLabel" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
3409
|
+
labelId = nextId();
|
|
2626
3410
|
value = model.required(/* @ts-ignore */
|
|
2627
3411
|
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
3412
|
+
size = input('md', /* @ts-ignore */
|
|
3413
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
2628
3414
|
radios = viewChildren('radio', /* @ts-ignore */
|
|
2629
3415
|
...(ngDevMode ? [{ debugName: "radios" }] : /* istanbul ignore next */ []));
|
|
2630
3416
|
thumbIndex = computed(() => {
|
|
@@ -2633,7 +3419,7 @@ class UiSegmented {
|
|
|
2633
3419
|
}, /* @ts-ignore */
|
|
2634
3420
|
...(ngDevMode ? [{ debugName: "thumbIndex" }] : /* istanbul ignore next */ []));
|
|
2635
3421
|
optionClasses(optionValue) {
|
|
2636
|
-
return `${OPTION_CLASSES} ${optionValue === this.value() ? SELECTED_CLASSES : UNSELECTED_CLASSES}`;
|
|
3422
|
+
return `${OPTION_CLASSES} ${SIZE_CLASSES[this.size()]} ${optionValue === this.value() ? SELECTED_CLASSES : UNSELECTED_CLASSES}`;
|
|
2637
3423
|
}
|
|
2638
3424
|
tabIndexFor(optionValue) {
|
|
2639
3425
|
const opts = this.options();
|
|
@@ -2657,37 +3443,45 @@ class UiSegmented {
|
|
|
2657
3443
|
this.radios()[nextIndex]?.nativeElement.focus();
|
|
2658
3444
|
}
|
|
2659
3445
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiSegmented, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2660
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiSegmented, isStandalone: true, selector: "ui-segmented", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { value: "valueChange" }, viewQueries: [{ propertyName: "radios", predicate: ["radio"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
2661
|
-
<div
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
>
|
|
2667
|
-
@if (thumbIndex(); as index) {
|
|
2668
|
-
<span
|
|
2669
|
-
aria-hidden="true"
|
|
2670
|
-
class="absolute top-0.5 bottom-0.5 left-0.5 rounded-[calc(var(--radius-control)-2px)] bg-(--card) shadow-[0_1px_2px_rgb(0_0_0/0.08),inset_0_0_0_1px_var(--border)] transition-transform duration-(--duration-fast) ease-out"
|
|
2671
|
-
data-thumb
|
|
2672
|
-
[style.transform]="'translateX(' + (index - 1) * 100 + '%)'"
|
|
2673
|
-
[style.width]="'calc((100% - 4px) / ' + options().length + ')'"
|
|
2674
|
-
></span>
|
|
3446
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiSegmented, isStandalone: true, selector: "ui-segmented", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: true, transformFunction: null }, showLabel: { classPropertyName: "showLabel", publicName: "showLabel", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, viewQueries: [{ propertyName: "radios", predicate: ["radio"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
3447
|
+
<div [class]="showLabel() ? 'flex flex-col gap-1.5' : ''">
|
|
3448
|
+
@if (showLabel()) {
|
|
3449
|
+
<span class="text-label leading-[17px] font-medium text-(--muted-foreground)" [id]="labelId">{{
|
|
3450
|
+
label()
|
|
3451
|
+
}}</span>
|
|
2675
3452
|
}
|
|
3453
|
+
<div
|
|
3454
|
+
class="rounded-control relative grid bg-(--muted) p-0.5"
|
|
3455
|
+
role="radiogroup"
|
|
3456
|
+
[attr.aria-label]="showLabel() ? null : label()"
|
|
3457
|
+
[attr.aria-labelledby]="showLabel() ? labelId : null"
|
|
3458
|
+
[style.grid-template-columns]="'repeat(' + options().length + ', 1fr)'"
|
|
3459
|
+
>
|
|
3460
|
+
@if (thumbIndex(); as index) {
|
|
3461
|
+
<span
|
|
3462
|
+
aria-hidden="true"
|
|
3463
|
+
class="absolute top-0.5 bottom-0.5 left-0.5 rounded-[calc(var(--radius-control)-2px)] bg-(--card) shadow-[0_1px_2px_rgb(0_0_0/0.08),inset_0_0_0_1px_var(--border)] transition-transform duration-(--duration-fast) ease-out"
|
|
3464
|
+
data-thumb
|
|
3465
|
+
[style.transform]="'translateX(' + (index - 1) * 100 + '%)'"
|
|
3466
|
+
[style.width]="'calc((100% - 4px) / ' + options().length + ')'"
|
|
3467
|
+
></span>
|
|
3468
|
+
}
|
|
2676
3469
|
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
3470
|
+
@for (option of options(); track option.value) {
|
|
3471
|
+
<button
|
|
3472
|
+
#radio
|
|
3473
|
+
role="radio"
|
|
3474
|
+
type="button"
|
|
3475
|
+
[attr.aria-checked]="option.value === value()"
|
|
3476
|
+
[attr.tabindex]="tabIndexFor(option.value)"
|
|
3477
|
+
[class]="optionClasses(option.value)"
|
|
3478
|
+
(click)="select(option.value)"
|
|
3479
|
+
(keydown)="onKeydown($event)"
|
|
3480
|
+
>
|
|
3481
|
+
{{ option.label }}
|
|
3482
|
+
</button>
|
|
3483
|
+
}
|
|
3484
|
+
</div>
|
|
2691
3485
|
</div>
|
|
2692
3486
|
`, isInline: true });
|
|
2693
3487
|
}
|
|
@@ -2696,40 +3490,48 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
2696
3490
|
args: [{
|
|
2697
3491
|
selector: 'ui-segmented',
|
|
2698
3492
|
template: `
|
|
2699
|
-
<div
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
>
|
|
2705
|
-
@if (thumbIndex(); as index) {
|
|
2706
|
-
<span
|
|
2707
|
-
aria-hidden="true"
|
|
2708
|
-
class="absolute top-0.5 bottom-0.5 left-0.5 rounded-[calc(var(--radius-control)-2px)] bg-(--card) shadow-[0_1px_2px_rgb(0_0_0/0.08),inset_0_0_0_1px_var(--border)] transition-transform duration-(--duration-fast) ease-out"
|
|
2709
|
-
data-thumb
|
|
2710
|
-
[style.transform]="'translateX(' + (index - 1) * 100 + '%)'"
|
|
2711
|
-
[style.width]="'calc((100% - 4px) / ' + options().length + ')'"
|
|
2712
|
-
></span>
|
|
3493
|
+
<div [class]="showLabel() ? 'flex flex-col gap-1.5' : ''">
|
|
3494
|
+
@if (showLabel()) {
|
|
3495
|
+
<span class="text-label leading-[17px] font-medium text-(--muted-foreground)" [id]="labelId">{{
|
|
3496
|
+
label()
|
|
3497
|
+
}}</span>
|
|
2713
3498
|
}
|
|
3499
|
+
<div
|
|
3500
|
+
class="rounded-control relative grid bg-(--muted) p-0.5"
|
|
3501
|
+
role="radiogroup"
|
|
3502
|
+
[attr.aria-label]="showLabel() ? null : label()"
|
|
3503
|
+
[attr.aria-labelledby]="showLabel() ? labelId : null"
|
|
3504
|
+
[style.grid-template-columns]="'repeat(' + options().length + ', 1fr)'"
|
|
3505
|
+
>
|
|
3506
|
+
@if (thumbIndex(); as index) {
|
|
3507
|
+
<span
|
|
3508
|
+
aria-hidden="true"
|
|
3509
|
+
class="absolute top-0.5 bottom-0.5 left-0.5 rounded-[calc(var(--radius-control)-2px)] bg-(--card) shadow-[0_1px_2px_rgb(0_0_0/0.08),inset_0_0_0_1px_var(--border)] transition-transform duration-(--duration-fast) ease-out"
|
|
3510
|
+
data-thumb
|
|
3511
|
+
[style.transform]="'translateX(' + (index - 1) * 100 + '%)'"
|
|
3512
|
+
[style.width]="'calc((100% - 4px) / ' + options().length + ')'"
|
|
3513
|
+
></span>
|
|
3514
|
+
}
|
|
2714
3515
|
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
3516
|
+
@for (option of options(); track option.value) {
|
|
3517
|
+
<button
|
|
3518
|
+
#radio
|
|
3519
|
+
role="radio"
|
|
3520
|
+
type="button"
|
|
3521
|
+
[attr.aria-checked]="option.value === value()"
|
|
3522
|
+
[attr.tabindex]="tabIndexFor(option.value)"
|
|
3523
|
+
[class]="optionClasses(option.value)"
|
|
3524
|
+
(click)="select(option.value)"
|
|
3525
|
+
(keydown)="onKeydown($event)"
|
|
3526
|
+
>
|
|
3527
|
+
{{ option.label }}
|
|
3528
|
+
</button>
|
|
3529
|
+
}
|
|
3530
|
+
</div>
|
|
2729
3531
|
</div>
|
|
2730
3532
|
`,
|
|
2731
3533
|
}]
|
|
2732
|
-
}], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }, { type: i0.Output, args: ["valueChange"] }], radios: [{ type: i0.ViewChildren, args: ['radio', { isSignal: true }] }] } });
|
|
3534
|
+
}], 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 }] }] } });
|
|
2733
3535
|
|
|
2734
3536
|
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]';
|
|
2735
3537
|
// Spelled out prefix included: Tailwind scans for literal strings, so a prefix applied in code
|
|
@@ -2790,7 +3592,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
2790
3592
|
}], propDecorators: { size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }] } });
|
|
2791
3593
|
|
|
2792
3594
|
/** Available skeleton shapes. `SkeletonShape` is derived from this tuple. */
|
|
2793
|
-
const SKELETON_SHAPES = ['text', 'figure', 'row', 'chart', 'ring'];
|
|
3595
|
+
const SKELETON_SHAPES = ['text', 'figure', 'row', 'chart', 'ring', 'dot'];
|
|
2794
3596
|
const LAST_LINE_WIDTH = '62%';
|
|
2795
3597
|
const PULSE_ANIMATION = 'cairn-pulse var(--pulse-duration) var(--ease-out) infinite alternate';
|
|
2796
3598
|
const BAR_CLASSES = 'block rounded-control bg-(--muted)';
|
|
@@ -2818,7 +3620,7 @@ class UiSkeleton {
|
|
|
2818
3620
|
}, /* @ts-ignore */
|
|
2819
3621
|
...(ngDevMode ? [{ debugName: "bars" }] : /* istanbul ignore next */ []));
|
|
2820
3622
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiSkeleton, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2821
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiSkeleton, isStandalone: true, selector: "ui-skeleton", inputs: { shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, lines: { classPropertyName: "lines", publicName: "lines", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "aria-hidden": "true" }, classAttribute: "flex flex-col gap-2" }, ngImport: i0, template: "\n @switch (shape()) {\n @case ('figure') {\n <span class=\"block rounded-control bg-(--muted) h-10 w-65\" [style.animation]=\"animation\"></span>\n }\n @case ('row') {\n <span class=\"flex h-14 items-center justify-between gap-4\">\n <span class=\"flex min-w-0 flex-1 flex-col gap-1.5\">\n <span class=\"block rounded-control bg-(--muted) h-4 w-3/5\" [style.animation]=\"animation\"></span>\n <span class=\"block rounded-control bg-(--muted) h-3 w-20\" [style.animation]=\"animation\"></span>\n </span>\n <span class=\"block rounded-control bg-(--muted) h-4 w-[90px] flex-none\" [style.animation]=\"animation\"></span>\n </span>\n }\n @case ('chart') {\n <span class=\"rounded-control min-h-50 w-full flex-1 bg-(--muted)\" [style.animation]=\"animation\"></span>\n }\n @case ('ring') {\n <span\n class=\"rounded-pill shadow-[inset_0_0_0_30px_var(--muted)]\"\n [style.animation]=\"animation\"\n [style.height.px]=\"size()\"\n [style.width.px]=\"size()\"\n ></span>\n }\n @default {\n @for (line of bars(); track $index) {\n <span\n class=\"block rounded-control bg-(--muted)\"\n [style.animation]=\"animation\"\n [style.height.px]=\"height()\"\n [style.width]=\"line\"\n ></span>\n }\n }\n }\n ", isInline: true, styles: ["@keyframes cairn-pulse{0%{opacity:1}to{opacity:.45}}\n"] });
|
|
3623
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.7", type: UiSkeleton, isStandalone: true, selector: "ui-skeleton", inputs: { shape: { classPropertyName: "shape", publicName: "shape", isSignal: true, isRequired: false, transformFunction: null }, lines: { classPropertyName: "lines", publicName: "lines", isSignal: true, isRequired: false, transformFunction: null }, height: { classPropertyName: "height", publicName: "height", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, host: { attributes: { "aria-hidden": "true" }, classAttribute: "flex flex-col gap-2" }, ngImport: i0, template: "\n @switch (shape()) {\n @case ('figure') {\n <span class=\"block rounded-control bg-(--muted) h-10 w-65\" [style.animation]=\"animation\"></span>\n }\n @case ('row') {\n <span class=\"flex h-14 items-center justify-between gap-4\">\n <span class=\"flex min-w-0 flex-1 flex-col gap-1.5\">\n <span class=\"block rounded-control bg-(--muted) h-4 w-3/5\" [style.animation]=\"animation\"></span>\n <span class=\"block rounded-control bg-(--muted) h-3 w-20\" [style.animation]=\"animation\"></span>\n </span>\n <span class=\"block rounded-control bg-(--muted) h-4 w-[90px] flex-none\" [style.animation]=\"animation\"></span>\n </span>\n }\n @case ('chart') {\n <span class=\"rounded-control min-h-50 w-full flex-1 bg-(--muted)\" [style.animation]=\"animation\"></span>\n }\n @case ('dot') {\n <span class=\"rounded-pill size-3 bg-(--muted)\" [style.animation]=\"animation\"></span>\n }\n @case ('ring') {\n <span\n class=\"rounded-pill shadow-[inset_0_0_0_30px_var(--muted)]\"\n [style.animation]=\"animation\"\n [style.height.px]=\"size()\"\n [style.width.px]=\"size()\"\n ></span>\n }\n @default {\n @for (line of bars(); track $index) {\n <span\n class=\"block rounded-control bg-(--muted)\"\n [style.animation]=\"animation\"\n [style.height.px]=\"height()\"\n [style.width]=\"line\"\n ></span>\n }\n }\n }\n ", isInline: true, styles: ["@keyframes cairn-pulse{0%{opacity:1}to{opacity:.45}}\n"] });
|
|
2822
3624
|
}
|
|
2823
3625
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiSkeleton, decorators: [{
|
|
2824
3626
|
type: Component,
|
|
@@ -2839,6 +3641,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
2839
3641
|
@case ('chart') {
|
|
2840
3642
|
<span class="rounded-control min-h-50 w-full flex-1 bg-(--muted)" [style.animation]="animation"></span>
|
|
2841
3643
|
}
|
|
3644
|
+
@case ('dot') {
|
|
3645
|
+
<span class="rounded-pill size-3 bg-(--muted)" [style.animation]="animation"></span>
|
|
3646
|
+
}
|
|
2842
3647
|
@case ('ring') {
|
|
2843
3648
|
<span
|
|
2844
3649
|
class="rounded-pill shadow-[inset_0_0_0_30px_var(--muted)]"
|
|
@@ -2975,6 +3780,62 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
2975
3780
|
}]
|
|
2976
3781
|
}] });
|
|
2977
3782
|
|
|
3783
|
+
const TAB_CLASSES = 'flex h-[52px] flex-col items-center justify-center gap-[3px] touch-manipulation select-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring)';
|
|
3784
|
+
const INACTIVE_TAB_CLASSES = 'font-medium text-(--muted-foreground)';
|
|
3785
|
+
const ACTIVE_TAB_CLASSES = 'font-semibold text-(--foreground)';
|
|
3786
|
+
/**
|
|
3787
|
+
* Bottom navigation bar for iPhone: 52px of tabs plus the home indicator's safe area.
|
|
3788
|
+
*
|
|
3789
|
+
* @example
|
|
3790
|
+
* <nav ui-tab-bar>
|
|
3791
|
+
* <a ui-tab [active]="url === '/'" routerLink="/"><lucide-icon tabIcon name="house" />Portfolio</a>
|
|
3792
|
+
* </nav>
|
|
3793
|
+
*/
|
|
3794
|
+
class UiTabBar {
|
|
3795
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiTabBar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3796
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.7", type: UiTabBar, isStandalone: true, selector: "nav[ui-tab-bar]", host: { classAttribute: "grid grid-flow-col auto-cols-fr items-stretch bg-(--background)/90 backdrop-blur [@media(prefers-reduced-transparency:reduce)]:bg-(--background) shadow-[inset_0_1px_0_var(--hairline)] pb-[env(safe-area-inset-bottom)]" }, ngImport: i0, template: '<ng-content />', isInline: true });
|
|
3797
|
+
}
|
|
3798
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiTabBar, decorators: [{
|
|
3799
|
+
type: Component,
|
|
3800
|
+
args: [{
|
|
3801
|
+
selector: 'nav[ui-tab-bar]',
|
|
3802
|
+
template: '<ng-content />',
|
|
3803
|
+
host: {
|
|
3804
|
+
class: 'grid grid-flow-col auto-cols-fr items-stretch bg-(--background)/90 backdrop-blur [@media(prefers-reduced-transparency:reduce)]:bg-(--background) shadow-[inset_0_1px_0_var(--hairline)] pb-[env(safe-area-inset-bottom)]',
|
|
3805
|
+
},
|
|
3806
|
+
}]
|
|
3807
|
+
}] });
|
|
3808
|
+
/**
|
|
3809
|
+
* One destination of `ui-tab-bar`.
|
|
3810
|
+
*
|
|
3811
|
+
* @example
|
|
3812
|
+
* <a ui-tab active routerLink="/"><lucide-icon tabIcon name="house" />Portfolio</a>
|
|
3813
|
+
*/
|
|
3814
|
+
class UiTab {
|
|
3815
|
+
active = input(false, { ...(ngDevMode ? { debugName: "active" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
3816
|
+
classes = computed(() => `${TAB_CLASSES} ${this.active() ? ACTIVE_TAB_CLASSES : INACTIVE_TAB_CLASSES}`, /* @ts-ignore */
|
|
3817
|
+
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
3818
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiTab, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3819
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UiTab, isStandalone: true, selector: "a[ui-tab]", 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: `
|
|
3820
|
+
<span class="size-6" data-tab-icon><ng-content select="[tabIcon]" /></span>
|
|
3821
|
+
<span class="text-caption leading-none" data-tab-label><ng-content /></span>
|
|
3822
|
+
`, isInline: true });
|
|
3823
|
+
}
|
|
3824
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiTab, decorators: [{
|
|
3825
|
+
type: Component,
|
|
3826
|
+
args: [{
|
|
3827
|
+
selector: 'a[ui-tab]',
|
|
3828
|
+
template: `
|
|
3829
|
+
<span class="size-6" data-tab-icon><ng-content select="[tabIcon]" /></span>
|
|
3830
|
+
<span class="text-caption leading-none" data-tab-label><ng-content /></span>
|
|
3831
|
+
`,
|
|
3832
|
+
host: {
|
|
3833
|
+
'[class]': 'classes()',
|
|
3834
|
+
'[attr.aria-current]': "active() ? 'page' : null",
|
|
3835
|
+
},
|
|
3836
|
+
}]
|
|
3837
|
+
}], propDecorators: { active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }] } });
|
|
3838
|
+
|
|
2978
3839
|
/** Breakpoints a secondary column can be held back until. */
|
|
2979
3840
|
const CELL_BREAKPOINTS = ['md', 'lg'];
|
|
2980
3841
|
/** Body row heights. */
|
|
@@ -3168,7 +4029,9 @@ class UiGroupCell {
|
|
|
3168
4029
|
[class]="size() === 'lg' ? 'min-h-12' : 'min-h-11'"
|
|
3169
4030
|
>
|
|
3170
4031
|
<div class="flex min-w-0 items-baseline gap-3">
|
|
3171
|
-
<h2 class="text-body m-0 font-semibold whitespace-nowrap"
|
|
4032
|
+
<h2 class="text-body m-0 font-semibold whitespace-nowrap outline-none" data-group-heading tabindex="-1">
|
|
4033
|
+
{{ name() }}
|
|
4034
|
+
</h2>
|
|
3172
4035
|
@if (meta()) {
|
|
3173
4036
|
<span class="text-label truncate text-(--muted-foreground)">{{ meta() }}</span>
|
|
3174
4037
|
}
|
|
@@ -3190,7 +4053,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
3190
4053
|
[class]="size() === 'lg' ? 'min-h-12' : 'min-h-11'"
|
|
3191
4054
|
>
|
|
3192
4055
|
<div class="flex min-w-0 items-baseline gap-3">
|
|
3193
|
-
<h2 class="text-body m-0 font-semibold whitespace-nowrap"
|
|
4056
|
+
<h2 class="text-body m-0 font-semibold whitespace-nowrap outline-none" data-group-heading tabindex="-1">
|
|
4057
|
+
{{ name() }}
|
|
4058
|
+
</h2>
|
|
3194
4059
|
@if (meta()) {
|
|
3195
4060
|
<span class="text-label truncate text-(--muted-foreground)">{{ meta() }}</span>
|
|
3196
4061
|
}
|
|
@@ -3277,62 +4142,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
3277
4142
|
}]
|
|
3278
4143
|
}], propDecorators: { narrow: [{ type: i0.Input, args: [{ isSignal: true, alias: "narrow", required: false }] }], tone: [{ type: i0.Input, args: [{ isSignal: true, alias: "tone", required: false }] }] } });
|
|
3279
4144
|
|
|
3280
|
-
const TAB_CLASSES = 'flex h-[52px] flex-col items-center justify-center gap-[3px] touch-manipulation select-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring)';
|
|
3281
|
-
const INACTIVE_TAB_CLASSES = 'font-medium text-(--muted-foreground)';
|
|
3282
|
-
const ACTIVE_TAB_CLASSES = 'font-semibold text-(--foreground)';
|
|
3283
|
-
/**
|
|
3284
|
-
* Bottom navigation bar for iPhone: 52px of tabs plus the home indicator's safe area.
|
|
3285
|
-
*
|
|
3286
|
-
* @example
|
|
3287
|
-
* <nav ui-tab-bar>
|
|
3288
|
-
* <a ui-tab [active]="url === '/'" routerLink="/"><lucide-icon tabIcon name="house" />Portfolio</a>
|
|
3289
|
-
* </nav>
|
|
3290
|
-
*/
|
|
3291
|
-
class UiTabBar {
|
|
3292
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiTabBar, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3293
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.1.7", type: UiTabBar, isStandalone: true, selector: "nav[ui-tab-bar]", host: { classAttribute: "grid grid-flow-col auto-cols-fr items-stretch bg-(--background)/90 backdrop-blur [@media(prefers-reduced-transparency:reduce)]:bg-(--background) shadow-[inset_0_1px_0_var(--hairline)] pb-[env(safe-area-inset-bottom)]" }, ngImport: i0, template: '<ng-content />', isInline: true });
|
|
3294
|
-
}
|
|
3295
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiTabBar, decorators: [{
|
|
3296
|
-
type: Component,
|
|
3297
|
-
args: [{
|
|
3298
|
-
selector: 'nav[ui-tab-bar]',
|
|
3299
|
-
template: '<ng-content />',
|
|
3300
|
-
host: {
|
|
3301
|
-
class: 'grid grid-flow-col auto-cols-fr items-stretch bg-(--background)/90 backdrop-blur [@media(prefers-reduced-transparency:reduce)]:bg-(--background) shadow-[inset_0_1px_0_var(--hairline)] pb-[env(safe-area-inset-bottom)]',
|
|
3302
|
-
},
|
|
3303
|
-
}]
|
|
3304
|
-
}] });
|
|
3305
|
-
/**
|
|
3306
|
-
* One destination of `ui-tab-bar`.
|
|
3307
|
-
*
|
|
3308
|
-
* @example
|
|
3309
|
-
* <a ui-tab active routerLink="/"><lucide-icon tabIcon name="house" />Portfolio</a>
|
|
3310
|
-
*/
|
|
3311
|
-
class UiTab {
|
|
3312
|
-
active = input(false, { ...(ngDevMode ? { debugName: "active" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
3313
|
-
classes = computed(() => `${TAB_CLASSES} ${this.active() ? ACTIVE_TAB_CLASSES : INACTIVE_TAB_CLASSES}`, /* @ts-ignore */
|
|
3314
|
-
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
3315
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiTab, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3316
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "22.1.7", type: UiTab, isStandalone: true, selector: "a[ui-tab]", 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: `
|
|
3317
|
-
<span class="size-6" data-tab-icon><ng-content select="[tabIcon]" /></span>
|
|
3318
|
-
<span class="text-caption leading-none" data-tab-label><ng-content /></span>
|
|
3319
|
-
`, isInline: true });
|
|
3320
|
-
}
|
|
3321
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImport: i0, type: UiTab, decorators: [{
|
|
3322
|
-
type: Component,
|
|
3323
|
-
args: [{
|
|
3324
|
-
selector: 'a[ui-tab]',
|
|
3325
|
-
template: `
|
|
3326
|
-
<span class="size-6" data-tab-icon><ng-content select="[tabIcon]" /></span>
|
|
3327
|
-
<span class="text-caption leading-none" data-tab-label><ng-content /></span>
|
|
3328
|
-
`,
|
|
3329
|
-
host: {
|
|
3330
|
-
'[class]': 'classes()',
|
|
3331
|
-
'[attr.aria-current]': "active() ? 'page' : null",
|
|
3332
|
-
},
|
|
3333
|
-
}]
|
|
3334
|
-
}], propDecorators: { active: [{ type: i0.Input, args: [{ isSignal: true, alias: "active", required: false }] }] } });
|
|
3335
|
-
|
|
3336
4145
|
/*
|
|
3337
4146
|
* Public API surface of the ui library.
|
|
3338
4147
|
*/
|
|
@@ -3341,5 +4150,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.7", ngImpor
|
|
|
3341
4150
|
* Generated bundle index. Do not edit.
|
|
3342
4151
|
*/
|
|
3343
4152
|
|
|
3344
|
-
export { ALERT_VARIANTS, AMOUNT_MASKINGS, AMOUNT_NUMERICS, ASYNC_STATES, AVATAR_SIZES, BADGE_SIZES, BADGE_VARIANTS, BUTTON_SIZES, BUTTON_VARIANTS, CARD_PADDINGS, CARD_VARIANTS, CELL_BREAKPOINTS, CONTROL_SIZES, CONTROL_SURFACES, DELTA_EMPHASES, DIALOG_LAYOUTS, DIALOG_WIDTHS, GROUP_SIZES, METER_TONES, ROW_PADDINGS, ROW_SIZES, STAT_SIZES, SUB_TONES, TABLE_ROWS, UI_AMOUNT_MASKED, UiAlert, UiAmount, UiAsync, UiAvatar, UiBadge, UiButton, UiCard, UiCellSub, UiChoiceChips, UiDelta, UiDialog, UiDonut, UiField, UiFieldLeading, UiGroup, UiGroupCell, UiInput, UiLineChart, UiMenu, UiMenuItem, UiMenuTrigger, UiMeter, UiNavItem, UiRow, UiRowAction, UiRowLink, UiSegmented, UiSelect, UiSkeleton, UiStat, UiSwitch, UiTab, UiTabBar, UiTable, UiTd, UiTextarea, UiTh, UiTr, formatAmount };
|
|
4153
|
+
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, UiSegmented, UiSelect, UiSkeleton, UiStat, UiSwitch, UiTab, UiTabBar, UiTable, UiTd, UiTextarea, UiTh, UiTr, formatAmount };
|
|
3345
4154
|
//# sourceMappingURL=joanroucoux-cairn-ui.mjs.map
|