@lifecorner/angular-ui-kit 3.15.0 → 3.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/fesm2022/lifecorner-angular-ui-kit-button.mjs +12 -7
- package/fesm2022/lifecorner-angular-ui-kit-button.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-icon.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-icon.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-icons.mjs +26 -2
- package/fesm2022/lifecorner-angular-ui-kit-icons.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-internal-icon-set.mjs +10 -1
- package/fesm2022/lifecorner-angular-ui-kit-internal-icon-set.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-list.mjs +29 -6
- package/fesm2022/lifecorner-angular-ui-kit-list.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-money.mjs +250 -0
- package/fesm2022/lifecorner-angular-ui-kit-money.mjs.map +1 -0
- package/fesm2022/lifecorner-angular-ui-kit-next-step-card.mjs +21 -2
- package/fesm2022/lifecorner-angular-ui-kit-next-step-card.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-progress-bar.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-progress-bar.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-switch.mjs +21 -4
- package/fesm2022/lifecorner-angular-ui-kit-switch.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-table.mjs +73 -7
- package/fesm2022/lifecorner-angular-ui-kit-table.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-toast.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-toast.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit.mjs +1 -0
- package/package.json +5 -1
- package/src/styles/theme-contrast.spec.ts +79 -0
- package/types/lifecorner-angular-ui-kit-button.d.ts +28 -1
- package/types/lifecorner-angular-ui-kit-icon.d.ts +2 -1
- package/types/lifecorner-angular-ui-kit-icons.d.ts +5 -1
- package/types/lifecorner-angular-ui-kit-list.d.ts +38 -0
- package/types/lifecorner-angular-ui-kit-money.d.ts +150 -0
- package/types/lifecorner-angular-ui-kit-next-step-card.d.ts +26 -0
- package/types/lifecorner-angular-ui-kit-progress-bar.d.ts +12 -1
- package/types/lifecorner-angular-ui-kit-switch.d.ts +19 -0
- package/types/lifecorner-angular-ui-kit-table.d.ts +61 -2
- package/types/lifecorner-angular-ui-kit-toast.d.ts +3 -1
- package/types/lifecorner-angular-ui-kit.d.ts +1 -0
|
@@ -280,3 +280,82 @@ describe('Component pairings of 3.15 (request 020)', () => {
|
|
|
280
280
|
});
|
|
281
281
|
});
|
|
282
282
|
});
|
|
283
|
+
|
|
284
|
+
// Request 022 (3.16): the focus ring of clickable table rows and list link rows
|
|
285
|
+
// (--color-primary-500, 2 px) on every row fill (1.4.11 and 2.4.13 need 3:1).
|
|
286
|
+
describe('Component pairings of 3.16 (request 022)', () => {
|
|
287
|
+
/** Design 022 §5, per palette [light, dark]: table row fills on the card (--color-surface). */
|
|
288
|
+
const rows: [string, [number, number]][] = [
|
|
289
|
+
['--color-surface', [4.37, 9.13]],
|
|
290
|
+
['--color-surface-2', [4.18, 7.58]],
|
|
291
|
+
['--color-surface-hover', [3.97, 8.18]],
|
|
292
|
+
['--color-surface-selected', [3.76, 6.87]],
|
|
293
|
+
];
|
|
294
|
+
|
|
295
|
+
describe.each(palettes.map(([name, tokens], i) => [name, tokens, i] as const))('%s palette', (_palette, tokens, i) => {
|
|
296
|
+
const solid = (name: string, base = '--color-surface') => over(color(tokens, name), color(tokens, base));
|
|
297
|
+
|
|
298
|
+
it.each(rows)('AC-5: the --color-primary-500 row ring reaches 3:1 on %s', (fill, values) => {
|
|
299
|
+
const r = ratio(solid('--color-primary-500'), solid(fill));
|
|
300
|
+
expect(r).toBeCloseTo(values[i], 1);
|
|
301
|
+
expect(r).toBeGreaterThanOrEqual(3);
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// Request 021 (3.17): the lc-list status badges (12 px / 500, so 4.5:1) and the
|
|
307
|
+
// focus ring of a loading lc-button, which its 0.5 opacity fades. The token
|
|
308
|
+
// names come from the compiled component stylesheets, the values from the themes.
|
|
309
|
+
describe('Component pairings of 3.17 (request 021)', () => {
|
|
310
|
+
const listCss = compile(resolve(__dirname, '../lib/list/list.component.scss')).css;
|
|
311
|
+
const buttonCss = compile(resolve(__dirname, '../lib/button/button.component.scss')).css;
|
|
312
|
+
|
|
313
|
+
/** The background and ink token of a list badge variant (a fallback after the name is ignored). */
|
|
314
|
+
function badgeTokens(variant: string): [string, string] {
|
|
315
|
+
const body = listCss.match(new RegExp(`\\n\\.lc-list__badge--${variant} \\{([^}]*)\\}`))?.[1] ?? '';
|
|
316
|
+
const bg = body.match(/background-color: var\((--[\w-]+)/)?.[1] ?? '';
|
|
317
|
+
const ink = body.match(/\scolor: var\((--[\w-]+)/)?.[1] ?? '';
|
|
318
|
+
expect([bg, ink]).toEqual([expect.stringMatching(/^--color-/), expect.stringMatching(/^--color-/)]);
|
|
319
|
+
return [bg, ink];
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/** Design 021 §5: the minimum over the bases, per palette [light, dark]. */
|
|
323
|
+
const badges: [string, [string, string], [number, number]][] = [
|
|
324
|
+
['success', ['--color-success-subtle', '--color-on-success-subtle'], [4.85, 5.17]],
|
|
325
|
+
['warning', ['--color-warning-subtle', '--color-on-warning-subtle'], [5.52, 4.61]],
|
|
326
|
+
['error', ['--color-error-100', '--color-on-error-subtle'], [6.33, 7.17]],
|
|
327
|
+
['primary', ['--color-primary-100', '--color-primary-700'], [7.85, 9.68]],
|
|
328
|
+
['default', ['--color-surface-hover', '--color-text-secondary'], [6.87, 8.18]],
|
|
329
|
+
];
|
|
330
|
+
|
|
331
|
+
describe.each(palettes.map(([name, tokens], i) => [name, tokens, i] as const))('%s palette', (_palette, tokens, i) => {
|
|
332
|
+
/** The grounds a list sits on: the page, the card surfaces and a hovered row (over the surface). */
|
|
333
|
+
const bases: Rgba[] = [
|
|
334
|
+
color(tokens, '--color-background'),
|
|
335
|
+
color(tokens, '--color-surface'),
|
|
336
|
+
over(color(tokens, '--color-surface-2'), color(tokens, '--color-surface')),
|
|
337
|
+
over(color(tokens, '--color-surface-hover'), color(tokens, '--color-surface')),
|
|
338
|
+
].map((c) => over(c, color(tokens, '--color-background')));
|
|
339
|
+
|
|
340
|
+
it.each(badges)('AC-12: the %s list badge reaches 4.5:1 on every ground', (variant, pair, values) => {
|
|
341
|
+
expect(badgeTokens(variant)).toEqual(pair);
|
|
342
|
+
const [bg, ink] = pair;
|
|
343
|
+
const min = Math.min(
|
|
344
|
+
...bases.map((base) => {
|
|
345
|
+
const fill = over(color(tokens, bg), base);
|
|
346
|
+
return ratio(over(color(tokens, ink), fill), fill);
|
|
347
|
+
}),
|
|
348
|
+
);
|
|
349
|
+
expect(min).toBeCloseTo(values[i], 2);
|
|
350
|
+
expect(min).toBeGreaterThanOrEqual(4.5);
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
it('AC-7: the ring of a focused loading button (--color-text-primary at 50 %) reaches 3:1 on the page and the surfaces', () => {
|
|
354
|
+
expect(buttonCss).toMatch(/\n\.btn\.btn-loading:focus-visible \{\s*outline-color: var\(--color-text-primary\);/);
|
|
355
|
+
const ink = color(tokens, '--color-text-primary');
|
|
356
|
+
for (const base of bases.slice(0, 3)) {
|
|
357
|
+
expect(ratio(over([ink[0], ink[1], ink[2], 0.5], base), base)).toBeGreaterThanOrEqual(3);
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
});
|
|
@@ -28,7 +28,28 @@ export declare class ButtonComponent {
|
|
|
28
28
|
*/
|
|
29
29
|
readonly tone: import("@angular/core").InputSignal<ButtonTone>;
|
|
30
30
|
readonly size: import("@angular/core").InputSignal<ButtonSize>;
|
|
31
|
+
/**
|
|
32
|
+
* Natively disabled: the button leaves the focus order and ignores clicks.
|
|
33
|
+
* For a temporary busy state that keeps focus, use `loading`.
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
31
36
|
readonly disabled: import("@angular/core").InputSignal<boolean>;
|
|
37
|
+
/**
|
|
38
|
+
* Shows a spinner in place of the icon slots and makes the button
|
|
39
|
+
* unavailable without removing it from the focus order (3.17). The inner
|
|
40
|
+
* `<button>` gets `aria-disabled="true"` and `aria-busy="true"` instead of
|
|
41
|
+
* the native `disabled`, so a focused button keeps focus. While it is
|
|
42
|
+
* loading, click, Enter and Space are ignored: `clicked` is not emitted, the
|
|
43
|
+
* click event stops at the button (a `(click)` on the host doesn't fire),
|
|
44
|
+
* and a `type="submit"`/`"reset"` button doesn't submit or reset its form.
|
|
45
|
+
* The look is unchanged: spinner, 50 % opacity, no hover. Screen readers may
|
|
46
|
+
* announce the state change ("unavailable"/"dimmed"), but the button doesn't
|
|
47
|
+
* announce the outcome: the page does that, for example with a polite live
|
|
48
|
+
* region ("USM wird geladen.", then the result). `disabledReason` also
|
|
49
|
+
* applies while loading. If `disabled` is set too, the native `disabled`
|
|
50
|
+
* wins.
|
|
51
|
+
* @default false
|
|
52
|
+
*/
|
|
32
53
|
readonly loading: import("@angular/core").InputSignal<boolean>;
|
|
33
54
|
readonly iconOnly: import("@angular/core").InputSignal<boolean>;
|
|
34
55
|
readonly fullWidth: import("@angular/core").InputSignal<boolean>;
|
|
@@ -72,7 +93,13 @@ export declare class ButtonComponent {
|
|
|
72
93
|
* `title` otherwise.
|
|
73
94
|
*/
|
|
74
95
|
readonly effectiveTitle: import("@angular/core").Signal<string | null>;
|
|
75
|
-
|
|
96
|
+
/**
|
|
97
|
+
* Emits `clicked` unless the button is disabled or loading. While loading
|
|
98
|
+
* (and not natively disabled) the event is cancelled and stopped, so a form
|
|
99
|
+
* isn't submitted and a host `(click)` doesn't fire. The parameter is
|
|
100
|
+
* optional, so callers without an argument still work.
|
|
101
|
+
*/
|
|
102
|
+
handleClick(event?: Event): void;
|
|
76
103
|
handleFocus(): void;
|
|
77
104
|
handleBlur(): void;
|
|
78
105
|
focus(): void;
|
|
@@ -284,7 +284,8 @@ export type IconName = string;
|
|
|
284
284
|
* `provideLcIcons()` or loaded with the kit's set (3.6, AS-17). Covers the
|
|
285
285
|
* hand-picked inline set, the Tabler icons inlined at build time (mail,
|
|
286
286
|
* users, settings, logout, key, chevron-right, …) and aliases that resolve
|
|
287
|
-
* to either — the
|
|
287
|
+
* to either — the names of 3.5.1, plus `wallet`, `building-bank` and
|
|
288
|
+
* `shield-lock` since 3.16 (TD-3). Use it to lint an app or a static
|
|
288
289
|
* site against icons that would be fetched.
|
|
289
290
|
*
|
|
290
291
|
* @example
|
|
@@ -132,8 +132,12 @@ export declare const ICON_ALERT_CIRCLE: LcIconDefinition;
|
|
|
132
132
|
export declare const ICON_ALERT_CIRCLE_SOLID: LcIconDefinition;
|
|
133
133
|
export declare const ICON_CIRCLE_X: LcIconDefinition;
|
|
134
134
|
export declare const ICON_CIRCLE_X_SOLID: LcIconDefinition;
|
|
135
|
+
export declare const ICON_WALLET: LcIconDefinition;
|
|
136
|
+
export declare const ICON_BUILDING_BANK: LcIconDefinition;
|
|
137
|
+
export declare const ICON_SHIELD_LOCK: LcIconDefinition;
|
|
138
|
+
export declare const ICON_SHIELD_LOCK_SOLID: LcIconDefinition;
|
|
135
139
|
/**
|
|
136
|
-
* Every glyph above (
|
|
140
|
+
* Every glyph above (137): `provideLcIcons(BUNDLED_ICONS)` restores the
|
|
137
141
|
* synchronous rendering of 3.5.1 for every inline name, e.g. in tests or
|
|
138
142
|
* Storybook. An app that imports it bundles all of them.
|
|
139
143
|
*/
|
|
@@ -64,6 +64,15 @@ export interface ListItem {
|
|
|
64
64
|
* label must be part of it (WCAG 2.5.3).
|
|
65
65
|
*/
|
|
66
66
|
actionAriaLabel?: string;
|
|
67
|
+
/**
|
|
68
|
+
* URL of the row link (3.16, TD-4). The row renders as an `<a>` over its
|
|
69
|
+
* full area (at least 44 px high) with real link semantics (middle click,
|
|
70
|
+
* "open in new tab"). Not rendered with `href`: `action` (no control inside
|
|
71
|
+
* a link; a dev warning). Not emitted: `itemClick` (see `linkClick`). With
|
|
72
|
+
* `disabled` the row is the plain disabled row, no link. A custom
|
|
73
|
+
* `lcListItem` template must not hold controls in `href` rows.
|
|
74
|
+
*/
|
|
75
|
+
href?: string;
|
|
67
76
|
/** Item identifier */
|
|
68
77
|
id?: string;
|
|
69
78
|
/** Whether the item is disabled */
|
|
@@ -77,6 +86,15 @@ export interface ListItem {
|
|
|
77
86
|
* List item size
|
|
78
87
|
*/
|
|
79
88
|
export type ListSize = 'sm' | 'md' | 'lg';
|
|
89
|
+
/**
|
|
90
|
+
* A plain click (or Enter) on an `href` row (3.16, TD-4): `item` is the row,
|
|
91
|
+
* `event` the click. Call `event.preventDefault()` to navigate with your
|
|
92
|
+
* router instead of a full page load.
|
|
93
|
+
*/
|
|
94
|
+
export interface ListLinkClickEvent {
|
|
95
|
+
item: ListItem;
|
|
96
|
+
event: MouseEvent;
|
|
97
|
+
}
|
|
80
98
|
/**
|
|
81
99
|
* List component for displaying structured item collections.
|
|
82
100
|
*
|
|
@@ -87,6 +105,8 @@ export type ListSize = 'sm' | 'md' | 'lg';
|
|
|
87
105
|
* - Icon and avatar support per item
|
|
88
106
|
* - Action buttons with click events
|
|
89
107
|
* - Accessible with ARIA list role; `clickable` rows are keyboard-operable
|
|
108
|
+
* - `ListItem.href` rows are real links over the full row (3.16, TD-4);
|
|
109
|
+
* `linkClick` hands plain clicks to your router
|
|
90
110
|
*
|
|
91
111
|
* @example
|
|
92
112
|
* ```html
|
|
@@ -138,6 +158,18 @@ export declare class ListComponent {
|
|
|
138
158
|
readonly itemClick: import("@angular/core").OutputEmitterRef<ListItem>;
|
|
139
159
|
/** Event emitted when an action button is clicked */
|
|
140
160
|
readonly actionClick: import("@angular/core").OutputEmitterRef<ListItem>;
|
|
161
|
+
/**
|
|
162
|
+
* A plain click (or Enter) on an `href` row: primary button, no
|
|
163
|
+
* Ctrl/Cmd/Shift/Alt (3.16, TD-4). Emitted before the browser follows the
|
|
164
|
+
* link; call `event.preventDefault()` and navigate with your router for an
|
|
165
|
+
* in-app route (`router.navigateByUrl(item.href)`). The kit never prevents
|
|
166
|
+
* the default; modifier and middle clicks are never emitted, so "open in new
|
|
167
|
+
* tab" keeps working.
|
|
168
|
+
*/
|
|
169
|
+
readonly linkClick: import("@angular/core").OutputEmitterRef<ListLinkClickEvent>;
|
|
170
|
+
constructor();
|
|
171
|
+
/** Whether a row renders as a link: `href` set and not disabled. */
|
|
172
|
+
protected isLinkRow(item: ListItem): boolean;
|
|
141
173
|
/**
|
|
142
174
|
* Computed CSS classes for the list
|
|
143
175
|
*/
|
|
@@ -161,6 +193,11 @@ export declare class ListComponent {
|
|
|
161
193
|
* Handle action button click
|
|
162
194
|
*/
|
|
163
195
|
onActionClick(item: ListItem): void;
|
|
196
|
+
/**
|
|
197
|
+
* A click on a link row: only a plain primary click reaches `linkClick`.
|
|
198
|
+
* The default (following the link) is left to the browser and the consumer.
|
|
199
|
+
*/
|
|
200
|
+
protected onLinkClick(event: MouseEvent, item: ListItem): void;
|
|
164
201
|
static ɵfac: i0.ɵɵFactoryDeclaration<ListComponent, never>;
|
|
165
202
|
static ɵcmp: i0.ɵɵComponentDeclaration<ListComponent, "lc-list", never, {
|
|
166
203
|
"items": {
|
|
@@ -211,5 +248,6 @@ export declare class ListComponent {
|
|
|
211
248
|
}, {
|
|
212
249
|
"itemClick": "itemClick";
|
|
213
250
|
"actionClick": "actionClick";
|
|
251
|
+
"linkClick": "linkClick";
|
|
214
252
|
}, ["itemTemplate"], never, true, never>;
|
|
215
253
|
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
/**
|
|
3
|
+
* How the sign of an amount shows, as `Intl.NumberFormat`'s `signDisplay`:
|
|
4
|
+
* - `auto`: negative amounts only (−42,17 €)
|
|
5
|
+
* - `always`: plus and minus, also on zero (+0,00 €)
|
|
6
|
+
* - `exceptZero`: plus and minus, no sign on zero
|
|
7
|
+
* - `never`: no sign
|
|
8
|
+
*/
|
|
9
|
+
type MoneySignDisplay = 'auto' | 'always' | 'exceptZero' | 'never';
|
|
10
|
+
/** Options of {@link formatMoney}. */
|
|
11
|
+
interface MoneyFormatOptions {
|
|
12
|
+
/** BCP 47 locale. An invalid one falls back to `en-US`. @default 'en-US' */
|
|
13
|
+
locale?: string;
|
|
14
|
+
/** As `Intl.NumberFormat`'s `signDisplay`. @default 'auto' */
|
|
15
|
+
signDisplay?: MoneySignDisplay;
|
|
16
|
+
/** Spoken word for the minus sign. @default 'minus' */
|
|
17
|
+
minusLabel?: string;
|
|
18
|
+
/** Spoken word for the plus sign. @default 'plus' */
|
|
19
|
+
plusLabel?: string;
|
|
20
|
+
}
|
|
21
|
+
/** A formatted amount: the visible text and the words a screen reader speaks. */
|
|
22
|
+
interface MoneyText {
|
|
23
|
+
/** Visible text, e.g. „−42,17 €“ (U+2212 minus, U+00A0 from `Intl`). */
|
|
24
|
+
text: string;
|
|
25
|
+
/** Spoken text, e.g. „minus 42,17 Euro“. */
|
|
26
|
+
spoken: string;
|
|
27
|
+
}
|
|
28
|
+
/** The ISO 4217 minor-unit exponent of `currency` (2 unless listed). */
|
|
29
|
+
declare function moneyMinorUnits(currency: string): number;
|
|
30
|
+
/** Text direction of an amount formatted for `locale`. */
|
|
31
|
+
declare function moneyDirection(locale: string): 'ltr' | 'rtl';
|
|
32
|
+
/**
|
|
33
|
+
* Formats an amount of money given in integer minor units (cents, yen, fils)
|
|
34
|
+
* exactly, never through a float: the decimal string goes into `Intl`.
|
|
35
|
+
* Returns `null` for an amount that is not a safe integer or a currency that
|
|
36
|
+
* is not a three-letter code. This is the formatter of `lc-money`, for table
|
|
37
|
+
* `formatter`s and texts.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* formatMoney(-4217, 'EUR', { locale: 'de-DE' });
|
|
42
|
+
* // { text: '−42,17 €', spoken: 'minus 42,17 Euro' }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare function formatMoney(amountMinor: number, currency: string, options?: MoneyFormatOptions): MoneyText | null;
|
|
46
|
+
/**
|
|
47
|
+
* Displays an amount of money (3.16, BA-4): locale, currency, sign, tabular
|
|
48
|
+
* figures and a spoken text. Display only, no input parsing or conversion.
|
|
49
|
+
*
|
|
50
|
+
* - `amountMinor` is an integer in the currency's minor units (cents, yen,
|
|
51
|
+
* fils), formatted exactly through a decimal string, never a float. Minor
|
|
52
|
+
* units follow ISO 4217: 2, except 0 (BIF CLP DJF GNF ISK JPY KMF KRW PYG
|
|
53
|
+
* RWF UGX UYI VND VUV XAF XOF XPF), 3 (BHD IQD JOD KWD LYD OMR TND) and 4
|
|
54
|
+
* (CLF UYW).
|
|
55
|
+
* - The visible amount („−42,17 €“, U+2212 minus, a no-break space from
|
|
56
|
+
* `Intl`) is `aria-hidden`; a visually hidden span holds the words
|
|
57
|
+
* („minus 42,17 Euro“), so a screen reader reads the amount once.
|
|
58
|
+
* - Tabular figures, no wrapping inside the amount; the amount is a `dir`
|
|
59
|
+
* isolate (`ltr`, or `rtl` for an RTL locale), safe inside RTL text.
|
|
60
|
+
* - Font and colour come from the context; colour never carries the sign.
|
|
61
|
+
* - `locale` empty: the app's `LOCALE_ID` (Angular's default `en-US`), the
|
|
62
|
+
* same on the server and in the browser.
|
|
63
|
+
* - For table `formatter`s and texts use {@link formatMoney}.
|
|
64
|
+
*
|
|
65
|
+
* Separate a `lc-money` from adjacent text with a space in your template, so
|
|
66
|
+
* the spoken text does not run into the words around it.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```html
|
|
70
|
+
* <lc-money [amountMinor]="-4217" currency="EUR" locale="de-DE" />
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
export declare class MoneyComponent {
|
|
74
|
+
private readonly appLocale;
|
|
75
|
+
/**
|
|
76
|
+
* Amount in minor units of `currency` (cents, yen, fils): a safe integer
|
|
77
|
+
* (±9,007,199,254,740,991), formatted exactly. Anything else renders
|
|
78
|
+
* nothing (a dev warning).
|
|
79
|
+
*/
|
|
80
|
+
readonly amountMinor: import("@angular/core").InputSignal<number>;
|
|
81
|
+
/**
|
|
82
|
+
* ISO 4217 currency code (`EUR`, `USD`, `JPY`, `KWD`). It sets the minor
|
|
83
|
+
* units and the symbol. Not a three-letter code: renders nothing (a dev
|
|
84
|
+
* warning).
|
|
85
|
+
*/
|
|
86
|
+
readonly currency: import("@angular/core").InputSignal<string>;
|
|
87
|
+
/**
|
|
88
|
+
* BCP 47 locale of the amount (`de-DE`, `en-GB`). Empty: the app's
|
|
89
|
+
* `LOCALE_ID` (Angular's default `en-US`). An invalid locale falls back to
|
|
90
|
+
* `en-US`.
|
|
91
|
+
* @default ''
|
|
92
|
+
*/
|
|
93
|
+
readonly locale: import("@angular/core").InputSignal<string>;
|
|
94
|
+
/**
|
|
95
|
+
* Which signs show, as `Intl.NumberFormat`: `auto` (negative only),
|
|
96
|
+
* `always`, `exceptZero`, `never`. The spoken text says the sign whenever
|
|
97
|
+
* it shows.
|
|
98
|
+
* @default 'auto'
|
|
99
|
+
*/
|
|
100
|
+
readonly signDisplay: import("@angular/core").InputSignal<MoneySignDisplay>;
|
|
101
|
+
/**
|
|
102
|
+
* Spoken word for the minus sign („minus 42,17 Euro“; the same in German).
|
|
103
|
+
* @default 'minus'
|
|
104
|
+
*/
|
|
105
|
+
readonly minusLabel: import("@angular/core").InputSignal<string>;
|
|
106
|
+
/**
|
|
107
|
+
* Spoken word for the plus sign („plus 42,17 Euro“; the same in German).
|
|
108
|
+
* @default 'plus'
|
|
109
|
+
*/
|
|
110
|
+
readonly plusLabel: import("@angular/core").InputSignal<string>;
|
|
111
|
+
/** The locale in use: the `locale` input or the app's `LOCALE_ID`. */
|
|
112
|
+
protected readonly effectiveLocale: import("@angular/core").Signal<string>;
|
|
113
|
+
protected readonly formatted: import("@angular/core").Signal<import("@lifecorner/angular-ui-kit/money").MoneyText | null>;
|
|
114
|
+
protected readonly dir: import("@angular/core").Signal<"ltr" | "rtl">;
|
|
115
|
+
constructor();
|
|
116
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<MoneyComponent, never>;
|
|
117
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<MoneyComponent, "lc-money", never, {
|
|
118
|
+
"amountMinor": {
|
|
119
|
+
"alias": "amountMinor";
|
|
120
|
+
"required": true;
|
|
121
|
+
"isSignal": true;
|
|
122
|
+
};
|
|
123
|
+
"currency": {
|
|
124
|
+
"alias": "currency";
|
|
125
|
+
"required": true;
|
|
126
|
+
"isSignal": true;
|
|
127
|
+
};
|
|
128
|
+
"locale": {
|
|
129
|
+
"alias": "locale";
|
|
130
|
+
"required": false;
|
|
131
|
+
"isSignal": true;
|
|
132
|
+
};
|
|
133
|
+
"signDisplay": {
|
|
134
|
+
"alias": "signDisplay";
|
|
135
|
+
"required": false;
|
|
136
|
+
"isSignal": true;
|
|
137
|
+
};
|
|
138
|
+
"minusLabel": {
|
|
139
|
+
"alias": "minusLabel";
|
|
140
|
+
"required": false;
|
|
141
|
+
"isSignal": true;
|
|
142
|
+
};
|
|
143
|
+
"plusLabel": {
|
|
144
|
+
"alias": "plusLabel";
|
|
145
|
+
"required": false;
|
|
146
|
+
"isSignal": true;
|
|
147
|
+
};
|
|
148
|
+
}, {}, never, never, true, never>;
|
|
149
|
+
}
|
|
150
|
+
export type { MoneyFormatOptions, MoneySignDisplay, MoneyText };
|
|
@@ -15,6 +15,15 @@ export type NextStepCardVariant = 'default' | 'soft';
|
|
|
15
15
|
* - `stacked`: always in their own row, one per line at equal width, 8 px apart
|
|
16
16
|
*/
|
|
17
17
|
export type NextStepCardActionsLayout = 'inline' | 'stacked';
|
|
18
|
+
/**
|
|
19
|
+
* Weight of the two built-in actions.
|
|
20
|
+
* - `default`: a filled primary and a ghost secondary with a chevron, the
|
|
21
|
+
* primary last
|
|
22
|
+
* - `equal`: two answers of the same weight (a question such as „Teilen?“):
|
|
23
|
+
* both `outline` in the primary tone at `actionSize`, the primary first,
|
|
24
|
+
* no chevron
|
|
25
|
+
*/
|
|
26
|
+
export type NextStepCardActionsStyle = 'default' | 'equal';
|
|
18
27
|
/** Element that renders the title (semantics only, the look stays the same). */
|
|
19
28
|
export type NextStepCardTitleTag = 'div' | 'h2' | 'h3';
|
|
20
29
|
/** Size of the built-in action buttons (`sm` 32 px, `md` 42 px, `lg` 48.5 px). */
|
|
@@ -44,6 +53,8 @@ export type NextStepCardActionSize = 'sm' | 'md' | 'lg';
|
|
|
44
53
|
* `fullWidth` button gets its own row at every width.
|
|
45
54
|
* - `variant="soft"`: the tinted card of the "Weite" look; `actionsLayout`
|
|
46
55
|
* `stacked` for several equal-width actions; `titleTag` for a heading
|
|
56
|
+
* - `actionsStyle="equal"` (3.16, BA-5): a question with two answers of the
|
|
57
|
+
* same weight, both outline buttons in the primary tone, primary first
|
|
47
58
|
*
|
|
48
59
|
* The host is a size container (`container-type: inline-size`) and takes the
|
|
49
60
|
* full inline size of its parent.
|
|
@@ -106,6 +117,16 @@ export declare class NextStepCardComponent implements AfterViewChecked {
|
|
|
106
117
|
* @default 'sm'
|
|
107
118
|
*/
|
|
108
119
|
actionSize: import("@angular/core").InputSignal<NextStepCardActionSize>;
|
|
120
|
+
/**
|
|
121
|
+
* Weight of the built-in actions. `default`: filled primary, ghost secondary
|
|
122
|
+
* with a chevron, primary last. `equal`: two answers of the same weight, both
|
|
123
|
+
* `outline` in the primary tone at `actionSize`, primary first, no chevron
|
|
124
|
+
* (`primaryClick`, `secondaryClick`, `primaryLoading`, `primaryDisabled` and
|
|
125
|
+
* `announce` work as before). Use `actionSize="lg"` (48.5 px, the 44 px
|
|
126
|
+
* target; a dev warning otherwise). No effect on `[slot='actions']`.
|
|
127
|
+
* @default 'default'
|
|
128
|
+
*/
|
|
129
|
+
actionsStyle: import("@angular/core").InputSignal<NextStepCardActionsStyle>;
|
|
109
130
|
/** Message below the title. For markup, use the default slot instead. */
|
|
110
131
|
message: import("@angular/core").InputSignal<string | undefined>;
|
|
111
132
|
/** Label of the primary action. Omit to render no primary button. */
|
|
@@ -200,6 +221,11 @@ export declare class NextStepCardComponent implements AfterViewChecked {
|
|
|
200
221
|
"required": false;
|
|
201
222
|
"isSignal": true;
|
|
202
223
|
};
|
|
224
|
+
"actionsStyle": {
|
|
225
|
+
"alias": "actionsStyle";
|
|
226
|
+
"required": false;
|
|
227
|
+
"isSignal": true;
|
|
228
|
+
};
|
|
203
229
|
"message": {
|
|
204
230
|
"alias": "message";
|
|
205
231
|
"required": false;
|
|
@@ -12,6 +12,13 @@ export type ProgressBarVariant = 'linear' | 'circular';
|
|
|
12
12
|
* - Animated value transitions
|
|
13
13
|
* - Accessible with ARIA progressbar role
|
|
14
14
|
*
|
|
15
|
+
* The bar is a visual aid; the text next to it carries the meaning. Write the
|
|
16
|
+
* status as text ('USM wird geladen …') and announce changes from a live
|
|
17
|
+
* region (`role="status"`). Screen readers don't announce a progress bar's
|
|
18
|
+
* changes by themselves. Give `ariaLabel` the same words as the status. Under
|
|
19
|
+
* `forced-colors: active` the fill is `Highlight`, the linear track gets a
|
|
20
|
+
* 1 px `CanvasText` outline and the circle's track is `GrayText` (3.17).
|
|
21
|
+
*
|
|
15
22
|
* @example
|
|
16
23
|
* ```html
|
|
17
24
|
* <lc-progress-bar [value]="75" color="primary" size="md"></lc-progress-bar>
|
|
@@ -57,7 +64,11 @@ export declare class ProgressBarComponent {
|
|
|
57
64
|
*/
|
|
58
65
|
inline: import("@angular/core").InputSignal<boolean>;
|
|
59
66
|
/**
|
|
60
|
-
*
|
|
67
|
+
* Progress of unknown length: no value (`aria-valuenow` is absent) and no
|
|
68
|
+
* label. The linear bar moves a 40 % segment across the track, and the
|
|
69
|
+
* circle spins. Under `prefers-reduced-motion: reduce` nothing moves: the
|
|
70
|
+
* linear bar shows a full-width striped fill and the circle a dashed ring,
|
|
71
|
+
* so it still reads as busy, not as a value (3.17).
|
|
61
72
|
* @default false
|
|
62
73
|
*/
|
|
63
74
|
indeterminate: import("@angular/core").InputSignal<boolean>;
|
|
@@ -8,6 +8,10 @@ import * as i0 from "@angular/core";
|
|
|
8
8
|
* - Size options (sm, md, lg)
|
|
9
9
|
* - Loading state with spinner
|
|
10
10
|
* - Configurable label positioning (left/right)
|
|
11
|
+
* - Help text below the label, linked by `aria-describedby` (`helpText`, 3.16)
|
|
12
|
+
* - Rows with a label or help text are at least 44 px high
|
|
13
|
+
* (`--lc-switch-min-height`, default `var(--size-min-touch-height)`; `0`
|
|
14
|
+
* restores the 3.15 rows of 21/24/28 px)
|
|
11
15
|
* - Keyboard toggle support
|
|
12
16
|
* - Disabled and required states
|
|
13
17
|
* - ControlValueAccessor integration for reactive forms
|
|
@@ -54,12 +58,22 @@ export declare class SwitchComponent implements ControlValueAccessor {
|
|
|
54
58
|
* ARIA label for accessibility (overrides the visible label as accessible name)
|
|
55
59
|
*/
|
|
56
60
|
readonly ariaLabel: import("@angular/core").InputSignal<string | undefined>;
|
|
61
|
+
/**
|
|
62
|
+
* Description below the label, linked to the switch by `aria-describedby`
|
|
63
|
+
* (read after the name and state). Wraps; 14 px secondary text. A tap on it
|
|
64
|
+
* toggles the switch like the label. Empty renders no element and no
|
|
65
|
+
* `aria-describedby` (3.15).
|
|
66
|
+
* @default ''
|
|
67
|
+
*/
|
|
68
|
+
readonly helpText: import("@angular/core").InputSignal<string>;
|
|
57
69
|
/**
|
|
58
70
|
* Emitted when checked state changes
|
|
59
71
|
*/
|
|
60
72
|
readonly checkedChange: import("@angular/core").OutputEmitterRef<boolean>;
|
|
61
73
|
/** Per-instance id so the visible `<label for>` points at this switch. */
|
|
62
74
|
readonly switchId: string;
|
|
75
|
+
/** id of the rendered help text (only while `helpText` is set). */
|
|
76
|
+
readonly helpTextId: import("@angular/core").Signal<string | null>;
|
|
63
77
|
/**
|
|
64
78
|
* Effective checked state: follows the `checked` input, overridden by
|
|
65
79
|
* form writes (`writeValue`) and user toggles.
|
|
@@ -135,6 +149,11 @@ export declare class SwitchComponent implements ControlValueAccessor {
|
|
|
135
149
|
"required": false;
|
|
136
150
|
"isSignal": true;
|
|
137
151
|
};
|
|
152
|
+
"helpText": {
|
|
153
|
+
"alias": "helpText";
|
|
154
|
+
"required": false;
|
|
155
|
+
"isSignal": true;
|
|
156
|
+
};
|
|
138
157
|
}, {
|
|
139
158
|
"checkedChange": "checkedChange";
|
|
140
159
|
}, never, never, true, never>;
|
|
@@ -37,7 +37,11 @@ export interface TableColumn {
|
|
|
37
37
|
width?: string;
|
|
38
38
|
/** Optional CSS class(es) applied to both th and td cells */
|
|
39
39
|
cssClass?: string;
|
|
40
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Optional CSS class(es) for td cells only (string or resolver callback).
|
|
42
|
+
* A class colour or font size loses to the kit's cell rule; set them with
|
|
43
|
+
* `cellStyle`.
|
|
44
|
+
*/
|
|
41
45
|
cellClass?: TableCellClass;
|
|
42
46
|
/** Optional inline styles for td cells only (object or resolver callback) */
|
|
43
47
|
cellStyle?: TableCellStyle;
|
|
@@ -49,7 +53,21 @@ export interface TableColumn {
|
|
|
49
53
|
editType?: 'text' | 'number' | 'select';
|
|
50
54
|
/** Options for select edit type */
|
|
51
55
|
editOptions?: string[];
|
|
56
|
+
/**
|
|
57
|
+
* Horizontal alignment of the column's header and cells. `end` aligns both
|
|
58
|
+
* at the end edge (right in LTR) and sets `font-variant-numeric:
|
|
59
|
+
* tabular-nums`, for amounts, counts and percentages. A sort arrow then sits
|
|
60
|
+
* before the label, so the label stays flush with the figures. Adds
|
|
61
|
+
* `lc-table__cell--end` to the `th` and every `td`. It wins over a
|
|
62
|
+
* `cellClass` that sets `text-align`; use `cellStyle` to override it. A
|
|
63
|
+
* custom `lcTableCell` template inherits the alignment, but a flex or block
|
|
64
|
+
* child needs its own `justify-content: flex-end`. (3.17)
|
|
65
|
+
* @default 'start'
|
|
66
|
+
*/
|
|
67
|
+
align?: TableColumnAlign;
|
|
52
68
|
}
|
|
69
|
+
/** Horizontal alignment of a table column (3.17). */
|
|
70
|
+
export type TableColumnAlign = 'start' | 'end';
|
|
53
71
|
/**
|
|
54
72
|
* A row-level action rendered in the table's actions column (e.g. Freigeben, Ablehnen).
|
|
55
73
|
* Action button clicks never trigger the row's `rowClick` output.
|
|
@@ -162,6 +180,9 @@ interface DisplayRow {
|
|
|
162
180
|
* - Composed cells (e.g. avatar + badge + actions)
|
|
163
181
|
* - Hierarchical "tree" rows (grouped / expandable) via `idKey` + `parentKey`
|
|
164
182
|
* - Responsive horizontal scrolling
|
|
183
|
+
* - `clickable` rows: tab stops, Enter/Space emit `rowClick` (3.16)
|
|
184
|
+
* - `caption` as the table's `<caption>`, visible or for screen readers only
|
|
185
|
+
* (`showCaption`, 3.16)
|
|
165
186
|
* - Empty state text for no data
|
|
166
187
|
* - Accessible with proper table semantics
|
|
167
188
|
*
|
|
@@ -198,6 +219,29 @@ export declare class TableComponent {
|
|
|
198
219
|
size: import("@angular/core").InputSignal<TableSize>;
|
|
199
220
|
/** Whether rows should highlight on hover */
|
|
200
221
|
hoverable: import("@angular/core").InputSignal<boolean>;
|
|
222
|
+
/**
|
|
223
|
+
* Rows are interactive (3.16, BA-3): each data row is a tab stop, Enter and
|
|
224
|
+
* Space emit `rowClick` (Space does not scroll the page), pointer and hover
|
|
225
|
+
* as `hoverable`. Clicks and keys on controls inside a row (buttons, links,
|
|
226
|
+
* inputs, switches) stay theirs and emit no `rowClick`. Set it whenever you
|
|
227
|
+
* handle `rowClick`. Tree mode keeps its roving tab stop. A focused row is
|
|
228
|
+
* read by its cells, not as "clickable": let the row open something that
|
|
229
|
+
* announces itself (a dialog, a page).
|
|
230
|
+
* @default false
|
|
231
|
+
*/
|
|
232
|
+
clickable: import("@angular/core").InputSignal<boolean>;
|
|
233
|
+
/**
|
|
234
|
+
* Title of the table, rendered as its `<caption>` (3.16, BA-3), so it also
|
|
235
|
+
* names the table for screen readers. Empty renders no caption.
|
|
236
|
+
* @default ''
|
|
237
|
+
*/
|
|
238
|
+
caption: import("@angular/core").InputSignal<string>;
|
|
239
|
+
/**
|
|
240
|
+
* Show the caption above the table (16 px semibold, 12 px above the table);
|
|
241
|
+
* `false` keeps it for screen readers only.
|
|
242
|
+
* @default true
|
|
243
|
+
*/
|
|
244
|
+
showCaption: import("@angular/core").InputSignal<boolean>;
|
|
201
245
|
/** Whether table should be responsive (horizontal scroll on mobile) */
|
|
202
246
|
responsive: import("@angular/core").InputSignal<boolean>;
|
|
203
247
|
/** Text shown when data is empty */
|
|
@@ -398,7 +442,7 @@ export declare class TableComponent {
|
|
|
398
442
|
protected treeCellLabel(row: Record<string, unknown>): string;
|
|
399
443
|
getCellTemplate(columnKey: string): TableCellDirective | undefined;
|
|
400
444
|
hasCustomTemplate(columnKey: string): boolean;
|
|
401
|
-
onRowClick(row: Record<string, unknown
|
|
445
|
+
onRowClick(row: Record<string, unknown>, event?: Event): void;
|
|
402
446
|
/** Whether the trailing actions column should be rendered */
|
|
403
447
|
protected readonly hasActions: import("@angular/core").Signal<boolean>;
|
|
404
448
|
protected isActionHidden(action: TableAction, row: Record<string, unknown>, rowIndex: number): boolean;
|
|
@@ -469,6 +513,21 @@ export declare class TableComponent {
|
|
|
469
513
|
"required": false;
|
|
470
514
|
"isSignal": true;
|
|
471
515
|
};
|
|
516
|
+
"clickable": {
|
|
517
|
+
"alias": "clickable";
|
|
518
|
+
"required": false;
|
|
519
|
+
"isSignal": true;
|
|
520
|
+
};
|
|
521
|
+
"caption": {
|
|
522
|
+
"alias": "caption";
|
|
523
|
+
"required": false;
|
|
524
|
+
"isSignal": true;
|
|
525
|
+
};
|
|
526
|
+
"showCaption": {
|
|
527
|
+
"alias": "showCaption";
|
|
528
|
+
"required": false;
|
|
529
|
+
"isSignal": true;
|
|
530
|
+
};
|
|
472
531
|
"responsive": {
|
|
473
532
|
"alias": "responsive";
|
|
474
533
|
"required": false;
|
|
@@ -22,7 +22,9 @@ export interface Toast extends Required<Omit<ToastConfig, 'action'>> {
|
|
|
22
22
|
* Toast service for showing ephemeral notifications.
|
|
23
23
|
*
|
|
24
24
|
* The toasts are rendered by `<lc-toast-outlet />`, which the application
|
|
25
|
-
* places once (e.g. in its shell); without it nothing is shown.
|
|
25
|
+
* places once (e.g. in its shell); without it nothing is shown. The options,
|
|
26
|
+
* their defaults, the timing and how a toast is announced to screen readers
|
|
27
|
+
* are documented under *Feedback/Toast Outlet* (3.17).
|
|
26
28
|
*
|
|
27
29
|
* @example
|
|
28
30
|
* ```typescript
|
|
@@ -58,6 +58,7 @@ export * from "@lifecorner/angular-ui-kit/toggle-group";
|
|
|
58
58
|
export * from "@lifecorner/angular-ui-kit/list";
|
|
59
59
|
export * from "@lifecorner/angular-ui-kit/chip";
|
|
60
60
|
export * from "@lifecorner/angular-ui-kit/table";
|
|
61
|
+
export * from "@lifecorner/angular-ui-kit/money";
|
|
61
62
|
export * from "@lifecorner/angular-ui-kit/field-group";
|
|
62
63
|
export * from "@lifecorner/angular-ui-kit/stepper";
|
|
63
64
|
export * from "@lifecorner/angular-ui-kit/filter-bar";
|