@lifecorner/angular-ui-kit 3.34.0 → 3.36.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 +1 -0
- package/fesm2022/lifecorner-angular-ui-kit-alert.mjs +2 -2
- package/fesm2022/lifecorner-angular-ui-kit-alert.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-bottom-nav.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-button.mjs +6 -6
- package/fesm2022/lifecorner-angular-ui-kit-button.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-card.mjs +82 -16
- package/fesm2022/lifecorner-angular-ui-kit-card.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-combobox.mjs +23 -4
- package/fesm2022/lifecorner-angular-ui-kit-combobox.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-description-list.mjs +43 -5
- package/fesm2022/lifecorner-angular-ui-kit-description-list.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-drawer.mjs +30 -2
- package/fesm2022/lifecorner-angular-ui-kit-drawer.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-gallery.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-header.mjs +45 -8
- package/fesm2022/lifecorner-angular-ui-kit-header.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-hero.mjs +57 -5
- package/fesm2022/lifecorner-angular-ui-kit-hero.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-internal-overlay.mjs +6 -1
- package/fesm2022/lifecorner-angular-ui-kit-internal-overlay.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-list.mjs +24 -5
- package/fesm2022/lifecorner-angular-ui-kit-list.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-modal.mjs +2 -4
- package/fesm2022/lifecorner-angular-ui-kit-modal.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-sidenav.mjs +41 -1
- package/fesm2022/lifecorner-angular-ui-kit-sidenav.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-stacked-bar-chart.mjs +47 -5
- package/fesm2022/lifecorner-angular-ui-kit-stacked-bar-chart.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-state-strip.mjs +203 -0
- package/fesm2022/lifecorner-angular-ui-kit-state-strip.mjs.map +1 -0
- package/fesm2022/lifecorner-angular-ui-kit-table.mjs +25 -4
- package/fesm2022/lifecorner-angular-ui-kit-table.mjs.map +1 -1
- package/fesm2022/lifecorner-angular-ui-kit-textarea.mjs +3 -0
- package/fesm2022/lifecorner-angular-ui-kit-textarea.mjs.map +1 -1
- 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 +74 -0
- package/types/lifecorner-angular-ui-kit-alert.d.ts +12 -2
- package/types/lifecorner-angular-ui-kit-bottom-nav.d.ts +5 -1
- package/types/lifecorner-angular-ui-kit-button.d.ts +7 -3
- package/types/lifecorner-angular-ui-kit-card.d.ts +51 -3
- package/types/lifecorner-angular-ui-kit-combobox.d.ts +36 -0
- package/types/lifecorner-angular-ui-kit-description-list.d.ts +40 -0
- package/types/lifecorner-angular-ui-kit-drawer.d.ts +37 -1
- package/types/lifecorner-angular-ui-kit-gallery.d.ts +3 -1
- package/types/lifecorner-angular-ui-kit-header.d.ts +44 -2
- package/types/lifecorner-angular-ui-kit-hero.d.ts +32 -0
- package/types/lifecorner-angular-ui-kit-internal-overlay.d.ts +9 -1
- package/types/lifecorner-angular-ui-kit-list.d.ts +17 -0
- package/types/lifecorner-angular-ui-kit-sidenav.d.ts +42 -1
- package/types/lifecorner-angular-ui-kit-stacked-bar-chart.d.ts +36 -0
- package/types/lifecorner-angular-ui-kit-state-strip.d.ts +107 -0
- package/types/lifecorner-angular-ui-kit-table.d.ts +37 -0
- package/types/lifecorner-angular-ui-kit-textarea.d.ts +17 -0
- package/types/lifecorner-angular-ui-kit-toast.d.ts +4 -2
- package/types/lifecorner-angular-ui-kit.d.ts +1 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AvatarColor, AvatarFallback } from "@lifecorner/angular-ui-kit/avatar";
|
|
2
2
|
import { MenuItem } from "@lifecorner/angular-ui-kit/menu";
|
|
3
3
|
import { ThemeService } from "@lifecorner/angular-ui-kit/theme";
|
|
4
|
+
import { BadgeVariant } from "@lifecorner/angular-ui-kit/badge";
|
|
4
5
|
import * as i0 from "@angular/core";
|
|
5
6
|
/** A link in the header's main navigation (`navItems`). */
|
|
6
7
|
export interface HeaderNavItem {
|
|
@@ -31,6 +32,18 @@ export type HeaderUserMenuTrigger = 'icon' | 'avatar';
|
|
|
31
32
|
* the title. From 641 px both render it inline.
|
|
32
33
|
*/
|
|
33
34
|
export type HeaderContextPlacement = 'inline' | 'below';
|
|
35
|
+
/**
|
|
36
|
+
* State of the header's context (3.36, `contextBadge`): an `lc-badge`
|
|
37
|
+
* (`sm`, rounded) inside the context button after `contextName`, e.g.
|
|
38
|
+
* `{ label: 'Freigegeben', variant: 'success' }`. Keep the label to one or two
|
|
39
|
+
* words.
|
|
40
|
+
*/
|
|
41
|
+
export interface HeaderContextBadge {
|
|
42
|
+
/** Visible badge text; it ends the button's accessible name. */
|
|
43
|
+
label: string;
|
|
44
|
+
/** Badge variant, as `lc-badge`. @default 'default' */
|
|
45
|
+
variant?: BadgeVariant;
|
|
46
|
+
}
|
|
34
47
|
/**
|
|
35
48
|
* AppHeaderComponent - Global application header for the LifeCorner shell
|
|
36
49
|
*
|
|
@@ -78,6 +91,9 @@ export type HeaderContextPlacement = 'inline' | 'below';
|
|
|
78
91
|
* of being hidden; from 641 px it sits in the end group as before.
|
|
79
92
|
* - `focusContext()` (3.34): moves the focus to the context button after the
|
|
80
93
|
* next render, e.g. after a choice in the sheet it opened (WCAG 2.4.3).
|
|
94
|
+
* - `contextBadge` (3.36): the context's state as a badge inside the context
|
|
95
|
+
* button, part of its accessible name; `hamburgerClick` emits the
|
|
96
|
+
* hamburger's `<button>`, e.g. for `lc-sidenav [returnFocusTo]`.
|
|
81
97
|
* - Every built-in label is an input (`homeAriaLabel`, `hamburgerAriaLabel`,
|
|
82
98
|
* `userMenuAriaLabel`, `navAriaLabel`, `profileLabel`, `logoutLabel`,
|
|
83
99
|
* `themeToDarkAriaLabel`, `themeToLightAriaLabel`, `contextAriaLabel`);
|
|
@@ -222,6 +238,19 @@ export declare class HeaderComponent {
|
|
|
222
238
|
* @default 'inline'
|
|
223
239
|
*/
|
|
224
240
|
readonly contextPlacement: import("@angular/core").InputSignal<HeaderContextPlacement>;
|
|
241
|
+
/**
|
|
242
|
+
* State of the context (3.36, app-shell row 1): an `lc-badge` (`sm`,
|
|
243
|
+
* rounded) inside the context button after `contextName`, e.g.
|
|
244
|
+
* `{ label: 'Freigegeben', variant: 'success' }`, wherever the button shows
|
|
245
|
+
* (`inline` and `below`, every size). Its label ends the button's accessible
|
|
246
|
+
* name („Monatsstand wählen, Monatsstand Oktober 2026 · Fassung 1,
|
|
247
|
+
* Freigegeben“, WCAG 2.5.3) unless `contextAriaLabel` already holds it. With
|
|
248
|
+
* a badge the button may grow to 340 px (220 without); a long name ends with
|
|
249
|
+
* "…" and the badge stays whole. Keep the label to one or two words. Target
|
|
250
|
+
* size, focus ring, `contextClick` and `focusContext()` don't change.
|
|
251
|
+
* @default undefined
|
|
252
|
+
*/
|
|
253
|
+
readonly contextBadge: import("@angular/core").InputSignal<HeaderContextBadge | undefined>;
|
|
225
254
|
readonly menuSize: import("@angular/core").InputSignal<"sm" | "md" | "lg">;
|
|
226
255
|
readonly showProfileMenuItem: import("@angular/core").InputSignal<boolean>;
|
|
227
256
|
/** Render the account menu (avatar trigger with Profile/Logout). */
|
|
@@ -271,12 +300,19 @@ export declare class HeaderComponent {
|
|
|
271
300
|
readonly profileLabel: import("@angular/core").InputSignal<string>;
|
|
272
301
|
/** Label of the Logout entry in the account menu. */
|
|
273
302
|
readonly logoutLabel: import("@angular/core").InputSignal<string>;
|
|
274
|
-
|
|
303
|
+
/**
|
|
304
|
+
* Emitted when the hamburger is clicked. Since 3.36 it carries the
|
|
305
|
+
* hamburger's native `<button>`, the element that has the focus, so a page
|
|
306
|
+
* can hand it to `lc-sidenav`: `(hamburgerClick)="trigger = $event; open = true"`
|
|
307
|
+
* with `[returnFocusTo]="trigger"`. Handlers without `$event` work as before.
|
|
308
|
+
*/
|
|
309
|
+
readonly hamburgerClick: import("@angular/core").OutputEmitterRef<HTMLElement>;
|
|
275
310
|
readonly themeToggleClick: import("@angular/core").OutputEmitterRef<void>;
|
|
276
311
|
readonly logoutClick: import("@angular/core").OutputEmitterRef<void>;
|
|
277
312
|
readonly profileClick: import("@angular/core").OutputEmitterRef<void>;
|
|
278
313
|
readonly contextClick: import("@angular/core").OutputEmitterRef<void>;
|
|
279
314
|
private readonly injector;
|
|
315
|
+
private readonly hostElement;
|
|
280
316
|
private themeServiceInstance;
|
|
281
317
|
/**
|
|
282
318
|
* Resolved on first use, i.e. only when the theme button is shown: creating
|
|
@@ -338,7 +374,8 @@ export declare class HeaderComponent {
|
|
|
338
374
|
*/
|
|
339
375
|
focusContext(): void;
|
|
340
376
|
/**
|
|
341
|
-
* Handle hamburger click
|
|
377
|
+
* Handle hamburger click: emits the hamburger's native `<button>` (3.36).
|
|
378
|
+
* Called without a rendered hamburger, it emits the header's host element.
|
|
342
379
|
*/
|
|
343
380
|
onHamburgerClick(): void;
|
|
344
381
|
/**
|
|
@@ -500,6 +537,11 @@ export declare class HeaderComponent {
|
|
|
500
537
|
"required": false;
|
|
501
538
|
"isSignal": true;
|
|
502
539
|
};
|
|
540
|
+
"contextBadge": {
|
|
541
|
+
"alias": "contextBadge";
|
|
542
|
+
"required": false;
|
|
543
|
+
"isSignal": true;
|
|
544
|
+
};
|
|
503
545
|
"menuSize": {
|
|
504
546
|
"alias": "menuSize";
|
|
505
547
|
"required": false;
|
|
@@ -10,6 +10,8 @@ export type HeroVariant = 'default' | 'slim' | 'light';
|
|
|
10
10
|
* background stays full-bleed
|
|
11
11
|
*/
|
|
12
12
|
export type HeroContentWidth = 'full' | 'lg';
|
|
13
|
+
/** Heading level of `lc-hero`'s title (3.36): `h1`–`h6`, the same look at every level. */
|
|
14
|
+
export type HeroHeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
13
15
|
/**
|
|
14
16
|
* Hero component for prominent page headers with gradient backgrounds.
|
|
15
17
|
*
|
|
@@ -24,6 +26,9 @@ export type HeroContentWidth = 'full' | 'lg';
|
|
|
24
26
|
* - Media slot (`[hero-media]`) for a visual: below the text on small screens,
|
|
25
27
|
* beside it from 1024 px, never under the body's 85 % opacity
|
|
26
28
|
* - Content width `lg`: a full-bleed band whose text lines up with the page column
|
|
29
|
+
* - `headingLevel` (3.36): the title as `h1`–`h6`, the same look at every level
|
|
30
|
+
* - `focusTitle()` (3.36): moves focus to the title (`tabindex="-1"`, out of the
|
|
31
|
+
* Tab order) after an action replaced the stage (WCAG 2.4.3)
|
|
27
32
|
*
|
|
28
33
|
* @example
|
|
29
34
|
* ```html
|
|
@@ -79,6 +84,28 @@ export declare class HeroComponent {
|
|
|
79
84
|
* @default 'full'
|
|
80
85
|
*/
|
|
81
86
|
contentWidth: import("@angular/core").InputSignal<HeroContentWidth>;
|
|
87
|
+
/**
|
|
88
|
+
* Element of the title (`h1`–`h6`), so the hero fits the page's outline
|
|
89
|
+
* (3.36, cockpit row 1). Only the element changes: size, weight, line height
|
|
90
|
+
* and spacing are the same at every level, `size`, `variant` and breakpoint.
|
|
91
|
+
* Use 2 under an `lc-page-header`, which holds the page's `h1`.
|
|
92
|
+
* @default 1
|
|
93
|
+
*/
|
|
94
|
+
headingLevel: import("@angular/core").InputSignal<HeroHeadingLevel>;
|
|
95
|
+
private readonly titleEl;
|
|
96
|
+
private readonly labelEl;
|
|
97
|
+
/**
|
|
98
|
+
* Moves the focus to the title (3.36, monatsstand row 1), e.g. after an
|
|
99
|
+
* action replaced the stage and the button that was used is gone, so focus
|
|
100
|
+
* doesn't fall back to the page (WCAG 2.4.3). Gives the title
|
|
101
|
+
* `tabindex="-1"` first: it stays out of the Tab order. With a `label`, the
|
|
102
|
+
* title is named "label title" (`aria-labelledby` on both, ids set at the
|
|
103
|
+
* call), so the label is read before it. Call it after the new state has
|
|
104
|
+
* rendered, e.g. `afterNextRender(() => this.hero().focusTitle(), { injector })`
|
|
105
|
+
* with `hero = viewChild.required(HeroComponent)`, as
|
|
106
|
+
* `lc-next-step-card.focusTitle()`. Without a call nothing changes.
|
|
107
|
+
*/
|
|
108
|
+
focusTitle(): void;
|
|
82
109
|
protected heroClasses: import("@angular/core").Signal<string>;
|
|
83
110
|
static ɵfac: i0.ɵɵFactoryDeclaration<HeroComponent, never>;
|
|
84
111
|
static ɵcmp: i0.ɵɵComponentDeclaration<HeroComponent, "lc-hero", never, {
|
|
@@ -117,5 +144,10 @@ export declare class HeroComponent {
|
|
|
117
144
|
"required": false;
|
|
118
145
|
"isSignal": true;
|
|
119
146
|
};
|
|
147
|
+
"headingLevel": {
|
|
148
|
+
"alias": "headingLevel";
|
|
149
|
+
"required": false;
|
|
150
|
+
"isSignal": true;
|
|
151
|
+
};
|
|
120
152
|
}, {}, never, ["*", "[hero-media]", "[hero-footer]"], true, never>;
|
|
121
153
|
}
|
|
@@ -49,4 +49,12 @@ export declare class OverlayInsetsService {
|
|
|
49
49
|
readonly bottom: import("@angular/core").WritableSignal<string | null>;
|
|
50
50
|
static ɵfac: i0.ɵɵFactoryDeclaration<OverlayInsetsService, never>;
|
|
51
51
|
static ɵprov: i0.ɵɵInjectableDeclaration<any>;
|
|
52
|
-
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Gives the focus to an overlay's `returnFocusTo` element (3.34 in
|
|
55
|
+
* `lc-modal`, shared since 3.35 with `lc-drawer` and `lc-sidenav`). A
|
|
56
|
+
* custom-element host that can't take focus (`<lc-button>`) hands it to its
|
|
57
|
+
* first focusable descendant. An element that can't take focus at all leaves
|
|
58
|
+
* the focus where it is.
|
|
59
|
+
*/
|
|
60
|
+
export declare function focusReturnTarget(target: HTMLElement): void;
|
|
@@ -121,6 +121,8 @@ export type ListItemPart = 'row' | 'action';
|
|
|
121
121
|
* - `focusItem(id, part)` (3.34): moves the focus to a row's button or link,
|
|
122
122
|
* or to its action, e.g. when the sheet that action opened closes
|
|
123
123
|
* (WCAG 2.4.3)
|
|
124
|
+
* - `showChevron` (3.36): a decorative chevron at the end of every
|
|
125
|
+
* `clickable` or `href` row
|
|
124
126
|
*
|
|
125
127
|
* @example
|
|
126
128
|
* ```html
|
|
@@ -168,6 +170,16 @@ export declare class ListComponent {
|
|
|
168
170
|
* @default 'xs'
|
|
169
171
|
*/
|
|
170
172
|
actionSize: import("@angular/core").InputSignal<ButtonSize>;
|
|
173
|
+
/**
|
|
174
|
+
* Ends every row that opens something, a `clickable` row or an `href` row,
|
|
175
|
+
* with the kit's `chevron-right` (20 px, `--color-text-tertiary`) after its
|
|
176
|
+
* badge, metadata and action (3.36, quellen row 3). Decorative: hidden from
|
|
177
|
+
* screen readers. Plain rows get none, and neither do rows drawn by an
|
|
178
|
+
* `lcListItem` template (add the icon to the template there). Row height,
|
|
179
|
+
* target size, focus ring, badge and `actionClick` don't change.
|
|
180
|
+
* @default false
|
|
181
|
+
*/
|
|
182
|
+
showChevron: import("@angular/core").InputSignal<boolean>;
|
|
171
183
|
/** Event emitted when an item is clicked */
|
|
172
184
|
readonly itemClick: import("@angular/core").OutputEmitterRef<ListItem>;
|
|
173
185
|
/** Event emitted when an action button is clicked */
|
|
@@ -276,6 +288,11 @@ export declare class ListComponent {
|
|
|
276
288
|
"required": false;
|
|
277
289
|
"isSignal": true;
|
|
278
290
|
};
|
|
291
|
+
"showChevron": {
|
|
292
|
+
"alias": "showChevron";
|
|
293
|
+
"required": false;
|
|
294
|
+
"isSignal": true;
|
|
295
|
+
};
|
|
279
296
|
}, {
|
|
280
297
|
"itemClick": "itemClick";
|
|
281
298
|
"actionClick": "actionClick";
|
|
@@ -53,7 +53,9 @@ export type SidenavVariant = 'default' | 'transparent';
|
|
|
53
53
|
* `--color-on-surface-selected` (AA on the selected tint)
|
|
54
54
|
* - Accessible: the inner `<nav>` is the navigation landmark; in drawer mode
|
|
55
55
|
* the panel is a modal dialog (`role="dialog"`, focus moved to the close
|
|
56
|
-
* button on open, trapped while open, restored on close)
|
|
56
|
+
* button on open, trapped while open, restored on close); `returnFocusTo`
|
|
57
|
+
* (3.35) names the element that gets the focus back after the drawer
|
|
58
|
+
* closed (WebKit doesn't focus a tapped button)
|
|
57
59
|
*
|
|
58
60
|
* @example
|
|
59
61
|
* ```html
|
|
@@ -162,6 +164,22 @@ export declare class SidenavComponent implements OnDestroy {
|
|
|
162
164
|
readonly ariaLabel: import("@angular/core").InputSignal<string>;
|
|
163
165
|
/** Whether to show the overlay backdrop */
|
|
164
166
|
readonly hasOverlay: import("@angular/core").InputSignal<boolean>;
|
|
167
|
+
/**
|
|
168
|
+
* Drawer mode only (`mode="drawer"`, or `docked` below `mobileBreakpoint`):
|
|
169
|
+
* element that gets the focus back after the drawer closed (3.35), instead
|
|
170
|
+
* of the one that had it at open. Set it to the trigger: WebKit (Safari,
|
|
171
|
+
* every iOS browser) doesn't focus a tapped button, so the captured element
|
|
172
|
+
* is `body`. Applied after the next render, once the panel has left the DOM
|
|
173
|
+
* and the focus trap has restored its captured element. Holds on ×,
|
|
174
|
+
* Escape, backdrop, an item or brand tap on a phone (they close it through
|
|
175
|
+
* `closed`), `isOpen` false, and when the sidenav is destroyed while open.
|
|
176
|
+
* A custom-element host that can't take focus (`<lc-button>`) hands it to
|
|
177
|
+
* its first focusable descendant. Ignored when the element is no longer in
|
|
178
|
+
* the document or can't take focus; the captured element then keeps it.
|
|
179
|
+
* `null`: as before.
|
|
180
|
+
* @default null
|
|
181
|
+
*/
|
|
182
|
+
readonly returnFocusTo: import("@angular/core").InputSignal<HTMLElement | null>;
|
|
165
183
|
/**
|
|
166
184
|
* Navigation items (`NavigationItem[]`): `id`, `icon`, `label`, `route`,
|
|
167
185
|
* `displayOrder` (sort order, 1 = first); optional `children`
|
|
@@ -261,8 +279,26 @@ export declare class SidenavComponent implements OnDestroy {
|
|
|
261
279
|
* Event emitted when an item's action button is clicked
|
|
262
280
|
*/
|
|
263
281
|
readonly itemAction: import("@angular/core").OutputEmitterRef<NavigationItem>;
|
|
282
|
+
/** Whether the drawer panel is rendered (drawer mode and open). */
|
|
283
|
+
private readonly drawerOpen;
|
|
284
|
+
/** Whether the drawer panel was shown without a close after it. */
|
|
285
|
+
private drawerShown;
|
|
286
|
+
/**
|
|
287
|
+
* The environment injector: a node injector would cancel the focus-return
|
|
288
|
+
* hook when the sidenav is destroyed while open.
|
|
289
|
+
*/
|
|
290
|
+
private readonly environmentInjector;
|
|
264
291
|
constructor();
|
|
265
292
|
ngOnDestroy(): void;
|
|
293
|
+
/** Ends a shown drawer panel; schedules `returnFocusTo` when set. */
|
|
294
|
+
private drawerClosed;
|
|
295
|
+
/**
|
|
296
|
+
* Focuses `returnFocusTo` after the next render: the template refresh has
|
|
297
|
+
* removed the panel, and `cdkTrapFocus` has restored its captured element
|
|
298
|
+
* on destroy, so this is the last focus write. Reads the input again then,
|
|
299
|
+
* so a trigger re-rendered meanwhile is taken from a fresh query.
|
|
300
|
+
*/
|
|
301
|
+
private scheduleFocusReturn;
|
|
266
302
|
private setupMediaQuery;
|
|
267
303
|
private teardownMediaQuery;
|
|
268
304
|
/**
|
|
@@ -434,6 +470,11 @@ export declare class SidenavComponent implements OnDestroy {
|
|
|
434
470
|
"required": false;
|
|
435
471
|
"isSignal": true;
|
|
436
472
|
};
|
|
473
|
+
"returnFocusTo": {
|
|
474
|
+
"alias": "returnFocusTo";
|
|
475
|
+
"required": false;
|
|
476
|
+
"isSignal": true;
|
|
477
|
+
};
|
|
437
478
|
"items": {
|
|
438
479
|
"alias": "items";
|
|
439
480
|
"required": false;
|
|
@@ -10,6 +10,11 @@ export interface StackedBarLegend {
|
|
|
10
10
|
color?: string;
|
|
11
11
|
}
|
|
12
12
|
export type StackedBarOrientation = 'vertical' | 'horizontal';
|
|
13
|
+
/**
|
|
14
|
+
* Form of `lc-stacked-bar-chart` (3.36): `chart` (axes, grid, labels and
|
|
15
|
+
* paddings, as before) or `band` (one horizontal bar edge to edge).
|
|
16
|
+
*/
|
|
17
|
+
export type StackedBarVariant = 'chart' | 'band';
|
|
13
18
|
export declare class StackedBarChartComponent {
|
|
14
19
|
private readonly _el;
|
|
15
20
|
private readonly _destroyRef;
|
|
@@ -42,6 +47,32 @@ export declare class StackedBarChartComponent {
|
|
|
42
47
|
* series names and every category's total.
|
|
43
48
|
*/
|
|
44
49
|
ariaLabel: import("@angular/core").InputSignal<string>;
|
|
50
|
+
/**
|
|
51
|
+
* Form of the chart (3.36, cockpit row 2). `chart`: axes, grid, labels and
|
|
52
|
+
* paddings, as before. `band`: one horizontal bar that fills the host's
|
|
53
|
+
* width edge to edge, `height` px thick, scaled from 0 to the sum of the
|
|
54
|
+
* values, without axes, grid, labels, values or paddings; the parts are
|
|
55
|
+
* split by a 2 px gap in the surface colour (CSS hooks
|
|
56
|
+
* `--lc-stacked-bar-chart-band-gap`, default `2px`, and
|
|
57
|
+
* `--lc-stacked-bar-chart-band-gap-color`, default `var(--color-surface)`:
|
|
58
|
+
* set it to the band's background off a card). `ariaLabel`, `legends` and
|
|
59
|
+
* the legend work as in `chart`. Needs exactly one category (otherwise it
|
|
60
|
+
* renders as `chart`, with a warning in dev mode); `orientation` is
|
|
61
|
+
* ignored; negative values draw nothing, and a sum of 0 draws no parts.
|
|
62
|
+
* Part widths are percentages, so the band is exact in prerendered HTML.
|
|
63
|
+
* @default 'chart'
|
|
64
|
+
*/
|
|
65
|
+
variant: import("@angular/core").InputSignal<StackedBarVariant>;
|
|
66
|
+
/** `band` with exactly one category (3.36); otherwise the chart renders. */
|
|
67
|
+
protected readonly isBand: import("@angular/core").Signal<boolean>;
|
|
68
|
+
/** The band's parts as percentages of the width: 0 … sum of the positive values. */
|
|
69
|
+
protected readonly bandParts: import("@angular/core").Signal<{
|
|
70
|
+
x: number;
|
|
71
|
+
w: number;
|
|
72
|
+
color: string;
|
|
73
|
+
}[]>;
|
|
74
|
+
/** The boundaries between two drawn parts, where the band's gap lines sit. */
|
|
75
|
+
protected readonly bandGaps: import("@angular/core").Signal<number[]>;
|
|
45
76
|
private readonly PL;
|
|
46
77
|
private readonly PR;
|
|
47
78
|
private readonly PT;
|
|
@@ -167,5 +198,10 @@ export declare class StackedBarChartComponent {
|
|
|
167
198
|
"required": false;
|
|
168
199
|
"isSignal": true;
|
|
169
200
|
};
|
|
201
|
+
"variant": {
|
|
202
|
+
"alias": "variant";
|
|
203
|
+
"required": false;
|
|
204
|
+
"isSignal": true;
|
|
205
|
+
};
|
|
170
206
|
}, {}, never, never, true, never>;
|
|
171
207
|
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
2
|
+
/** State of one run in `lc-state-strip` (3.36). */
|
|
3
|
+
export type StateStripState = 'success' | 'warning' | 'error' | 'neutral';
|
|
4
|
+
/** One run of `lc-state-strip`: its state, and a `label` that names it („Mo 06.10., 06:00“). */
|
|
5
|
+
export interface StateStripSegment {
|
|
6
|
+
state: StateStripState;
|
|
7
|
+
label: string;
|
|
8
|
+
}
|
|
9
|
+
/** The words of the four states, for the counts and the segment names. */
|
|
10
|
+
export type StateStripLabels = Record<StateStripState, string>;
|
|
11
|
+
/** English state words of `lc-state-strip`; pass `stateLabels` for another language. */
|
|
12
|
+
export declare const DEFAULT_STATE_STRIP_LABELS: Readonly<StateStripLabels>;
|
|
13
|
+
/**
|
|
14
|
+
* The states of the last runs at a glance (3.36, quellen row 1): one segment
|
|
15
|
+
* per run, oldest first. The state is a shape, not only a colour: success a
|
|
16
|
+
* block in the upper half, error one in the lower half, warning a centred
|
|
17
|
+
* block, neutral a flat dash, so the strip reads without hue and in forced
|
|
18
|
+
* colours.
|
|
19
|
+
*
|
|
20
|
+
* Accessibility: an APG single-row grid. The strip is named by `ariaLabel`
|
|
21
|
+
* and the count per state („Letzte 10 Ladeläufe, 9 geladen, 1
|
|
22
|
+
* fehlgeschlagen“); each segment is a grid cell named by its `label` and
|
|
23
|
+
* state word. One Tab stop (the newest run first), Arrow Left/Right, Home and
|
|
24
|
+
* End move between the runs, Escape hides the caption. Hovering or focusing a
|
|
25
|
+
* segment shows its name below the strip (hidden from screen readers, which
|
|
26
|
+
* read the cell).
|
|
27
|
+
*
|
|
28
|
+
* Without segments it renders nothing. The segments are in the prerendered
|
|
29
|
+
* HTML. CSS hooks: `--lc-state-strip-height` (default `2rem`) and
|
|
30
|
+
* `--lc-state-strip-segment-max-width` (default `1.5rem`; more segments than
|
|
31
|
+
* fit share the width, never overflowing).
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```html
|
|
35
|
+
* <lc-state-strip
|
|
36
|
+
* ariaLabel="Letzte 10 Ladeläufe"
|
|
37
|
+
* [stateLabels]="{ success: 'geladen', warning: 'teilweise geladen', error: 'fehlgeschlagen', neutral: 'ausstehend' }"
|
|
38
|
+
* [segments]="runs"
|
|
39
|
+
* />
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export declare class StateStripComponent {
|
|
43
|
+
/**
|
|
44
|
+
* The runs, in order, oldest first: one segment each. Empty renders nothing
|
|
45
|
+
* (no box, no accessibility node).
|
|
46
|
+
* @default []
|
|
47
|
+
*/
|
|
48
|
+
readonly segments: import("@angular/core").InputSignal<readonly StateStripSegment[]>;
|
|
49
|
+
/**
|
|
50
|
+
* Start of the strip's accessible name; the count per state follows it
|
|
51
|
+
* („Letzte 10 Ladeläufe, 9 geladen, 1 fehlgeschlagen“).
|
|
52
|
+
* @default ''
|
|
53
|
+
*/
|
|
54
|
+
readonly ariaLabel: import("@angular/core").InputSignal<string>;
|
|
55
|
+
/**
|
|
56
|
+
* The state words for the counts and the segment names, over the English
|
|
57
|
+
* defaults (`DEFAULT_STATE_STRIP_LABELS`: succeeded, with warnings, failed,
|
|
58
|
+
* pending). German: `{ success: 'geladen', warning: 'teilweise geladen',
|
|
59
|
+
* error: 'fehlgeschlagen', neutral: 'ausstehend' }`.
|
|
60
|
+
* @default {}
|
|
61
|
+
*/
|
|
62
|
+
readonly stateLabels: import("@angular/core").InputSignal<Partial<StateStripLabels>>;
|
|
63
|
+
private readonly cellEls;
|
|
64
|
+
/** The state words in use. */
|
|
65
|
+
private readonly words;
|
|
66
|
+
/** One entry per segment: its state (unknown states draw as neutral) and its name. */
|
|
67
|
+
protected readonly cells: import("@angular/core").Signal<{
|
|
68
|
+
state: StateStripState;
|
|
69
|
+
name: string;
|
|
70
|
+
}[]>;
|
|
71
|
+
/** The strip's name: `ariaLabel`, then the count per state (0 left out). */
|
|
72
|
+
protected readonly gridLabel: import("@angular/core").Signal<string>;
|
|
73
|
+
/** The roving Tab stop: the newest run until the user moves. */
|
|
74
|
+
protected readonly current: import("@angular/core").WritableSignal<number>;
|
|
75
|
+
/** The segment under the pointer, the one with focus, and whether Escape hid the caption. */
|
|
76
|
+
private readonly hovered;
|
|
77
|
+
private readonly focused;
|
|
78
|
+
private readonly dismissed;
|
|
79
|
+
/** The segment whose name the caption shows, if any. */
|
|
80
|
+
private readonly captionIndex;
|
|
81
|
+
/** The caption's text: the name of the hovered or focused segment ('' hides it). */
|
|
82
|
+
protected readonly caption: import("@angular/core").Signal<string>;
|
|
83
|
+
protected onFocus(index: number): void;
|
|
84
|
+
protected onBlur(): void;
|
|
85
|
+
protected onPointerEnter(index: number): void;
|
|
86
|
+
protected onPointerLeave(): void;
|
|
87
|
+
/** Arrow Left/Right, Home, End move between the runs (no wrap); Escape hides the caption. */
|
|
88
|
+
protected onKeydown(event: KeyboardEvent): void;
|
|
89
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<StateStripComponent, never>;
|
|
90
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<StateStripComponent, "lc-state-strip", never, {
|
|
91
|
+
"segments": {
|
|
92
|
+
"alias": "segments";
|
|
93
|
+
"required": false;
|
|
94
|
+
"isSignal": true;
|
|
95
|
+
};
|
|
96
|
+
"ariaLabel": {
|
|
97
|
+
"alias": "ariaLabel";
|
|
98
|
+
"required": false;
|
|
99
|
+
"isSignal": true;
|
|
100
|
+
};
|
|
101
|
+
"stateLabels": {
|
|
102
|
+
"alias": "stateLabels";
|
|
103
|
+
"required": false;
|
|
104
|
+
"isSignal": true;
|
|
105
|
+
};
|
|
106
|
+
}, {}, never, never, true, never>;
|
|
107
|
+
}
|
|
@@ -12,6 +12,9 @@ import { ButtonVariant } from "@lifecorner/angular-ui-kit/button";
|
|
|
12
12
|
* </ng-template>
|
|
13
13
|
* </lc-table>
|
|
14
14
|
* ```
|
|
15
|
+
*
|
|
16
|
+
* In the `footerRow` (3.36) the same template renders with `footer: true` in
|
|
17
|
+
* its context (`let-footer="footer"`), e.g. to leave out a badge in the sum.
|
|
15
18
|
*/
|
|
16
19
|
export declare class TableCellDirective {
|
|
17
20
|
/** The column key this template applies to */
|
|
@@ -83,6 +86,15 @@ export interface TableAction {
|
|
|
83
86
|
variant?: ButtonVariant;
|
|
84
87
|
/** Optional tooltip / aria-label, useful for icon-only actions */
|
|
85
88
|
tooltip?: string;
|
|
89
|
+
/**
|
|
90
|
+
* Accessible name of the action's button (3.36, services row 2): a string,
|
|
91
|
+
* or a function of the row, so each row's button names its object
|
|
92
|
+
* (`(row) => 'Herkunft von ' + row.name` → „Herkunft von Demo Netz“) while
|
|
93
|
+
* the visible label, icon and look stay the same. Wins over `tooltip`,
|
|
94
|
+
* `label` and `key`; an empty result falls back to them. Keep the visible
|
|
95
|
+
* label in it (WCAG 2.5.3).
|
|
96
|
+
*/
|
|
97
|
+
ariaLabel?: string | ((row: Record<string, unknown>, rowIndex: number) => string);
|
|
86
98
|
/** Hide this action for specific rows */
|
|
87
99
|
hidden?: (row: Record<string, unknown>, rowIndex: number) => boolean;
|
|
88
100
|
/** Disable this action for specific rows */
|
|
@@ -184,6 +196,8 @@ interface DisplayRow {
|
|
|
184
196
|
* - `caption` as the table's `<caption>`, visible or for screen readers only
|
|
185
197
|
* (`showCaption`, 3.16)
|
|
186
198
|
* - Empty state text for no data
|
|
199
|
+
* - `footerRow` (3.36): a sum row in `<tfoot>`, outside sorting, filtering,
|
|
200
|
+
* paging and the tree; `TableAction.ariaLabel` names each row's action
|
|
187
201
|
* - Accessible with proper table semantics
|
|
188
202
|
*
|
|
189
203
|
* @example
|
|
@@ -297,6 +311,19 @@ export declare class TableComponent {
|
|
|
297
311
|
actionsWidth: import("@angular/core").InputSignal<string | undefined>;
|
|
298
312
|
/** Horizontal alignment of the action buttons (and header label) within the cell */
|
|
299
313
|
actionsAlign: import("@angular/core").InputSignal<TableActionsAlign>;
|
|
314
|
+
/**
|
|
315
|
+
* One footer row below all data rows (3.36, services row 1), e.g. a sum:
|
|
316
|
+
* a record of the data's shape, rendered as a `<tfoot>` row with the
|
|
317
|
+
* table's columns, `lcTableCell` templates (their context has
|
|
318
|
+
* `footer: true`), `cellClass`, `cellStyle` and `formatter` (`rowIndex`
|
|
319
|
+
* −1). It is never sorted, filtered, searched, paged, selected or counted,
|
|
320
|
+
* stays last in every tree state, and its first cell is the row header
|
|
321
|
+
* (`<th scope="row">`). A 1 px rule above and a 3 px double rule below
|
|
322
|
+
* (`--color-field-border`) separate it; its cells are semibold with tabular
|
|
323
|
+
* figures. The table scrolls on small screens, and the footer with it.
|
|
324
|
+
* @default undefined
|
|
325
|
+
*/
|
|
326
|
+
footerRow: import("@angular/core").InputSignal<Record<string, unknown> | undefined>;
|
|
300
327
|
/**
|
|
301
328
|
* Row field holding the unique id. Required (together with {@link parentKey})
|
|
302
329
|
* to enable hierarchical "tree mode". Absent ⇒ today's flat table.
|
|
@@ -458,6 +485,11 @@ export declare class TableComponent {
|
|
|
458
485
|
protected readonly hasActions: import("@angular/core").Signal<boolean>;
|
|
459
486
|
protected isActionHidden(action: TableAction, row: Record<string, unknown>, rowIndex: number): boolean;
|
|
460
487
|
protected isActionDisabled(action: TableAction, row: Record<string, unknown>, rowIndex: number): boolean;
|
|
488
|
+
/**
|
|
489
|
+
* Accessible name of an action button (3.36): `ariaLabel` (a string or the
|
|
490
|
+
* row's result) over `tooltip`, `label` and `key`; without it, as before.
|
|
491
|
+
*/
|
|
492
|
+
protected actionAriaLabel(action: TableAction, row: Record<string, unknown>, rowIndex: number): string;
|
|
461
493
|
/**
|
|
462
494
|
* Handles an action button click. The DOM click is stopped from propagating
|
|
463
495
|
* (see template `$event.stopPropagation()`), so the row's `rowClick` never fires.
|
|
@@ -659,6 +691,11 @@ export declare class TableComponent {
|
|
|
659
691
|
"required": false;
|
|
660
692
|
"isSignal": true;
|
|
661
693
|
};
|
|
694
|
+
"footerRow": {
|
|
695
|
+
"alias": "footerRow";
|
|
696
|
+
"required": false;
|
|
697
|
+
"isSignal": true;
|
|
698
|
+
};
|
|
662
699
|
"idKey": {
|
|
663
700
|
"alias": "idKey";
|
|
664
701
|
"required": false;
|
|
@@ -14,6 +14,8 @@ import { ControlValueAccessor } from "@angular/forms";
|
|
|
14
14
|
* - ControlValueAccessor integration for reactive forms
|
|
15
15
|
* - Plain form posts without JavaScript: `name`, and a `value` that is
|
|
16
16
|
* prerendered into the native `<textarea>`
|
|
17
|
+
* - `focus()` (3.35): moves the focus into the native `<textarea>` when a
|
|
18
|
+
* form opens or after a rejected save (WCAG 2.4.3)
|
|
17
19
|
*
|
|
18
20
|
* @example
|
|
19
21
|
* ```html
|
|
@@ -214,6 +216,21 @@ export declare class TextareaComponent implements ControlValueAccessor {
|
|
|
214
216
|
* Handle blur event
|
|
215
217
|
*/
|
|
216
218
|
onBlur(): void;
|
|
219
|
+
/**
|
|
220
|
+
* Moves the focus into the native `<textarea>` (3.35), e.g. when a form
|
|
221
|
+
* opens with this field first, or to the field with the error after a
|
|
222
|
+
* rejected save (422) (WCAG 2.4.3). `options` as for `HTMLElement.focus()`
|
|
223
|
+
* (`{ preventScroll: true }`). Shows the same focus ring as a user's focus.
|
|
224
|
+
* A disabled field takes no focus (it stays where it is); a read-only one
|
|
225
|
+
* does. Call it once the field has rendered, e.g.
|
|
226
|
+
* `afterNextRender(() => this.note().focus(), { injector })` with
|
|
227
|
+
* `note = viewChild.required(TextareaComponent)` and the page component's
|
|
228
|
+
* `injector = inject(Injector)`. In an `lc-modal` that opens with the field,
|
|
229
|
+
* that call runs after the dialog moved the focus to its first control.
|
|
230
|
+
* Does nothing before the component has rendered.
|
|
231
|
+
* @param options Passed to the native `focus()`.
|
|
232
|
+
*/
|
|
233
|
+
focus(options?: FocusOptions): void;
|
|
217
234
|
writeValue(value: string | null | undefined): void;
|
|
218
235
|
registerOnChange(fn: (value: string) => void): void;
|
|
219
236
|
registerOnTouched(fn: () => void): void;
|
|
@@ -194,8 +194,10 @@ type ToastLive = 'polite' | 'assertive';
|
|
|
194
194
|
* as the space between the offsets and scrolls when its toasts need more
|
|
195
195
|
* (200 % text), so each toast stays reachable.
|
|
196
196
|
*
|
|
197
|
-
* Bottom stacks show the newest toast nearest the edge (3.33)
|
|
198
|
-
*
|
|
197
|
+
* Bottom stacks show the newest toast nearest the edge (3.33). A top stack
|
|
198
|
+
* shows its assertive region (error, warning) above its polite one (success,
|
|
199
|
+
* info), each oldest first, so a newer error sits above an older success
|
|
200
|
+
* (3.35, 053-n2). The toasts of a stack are 8 px (`--spacing-2`) apart
|
|
199
201
|
* (3.33.1), within a live region and across the two; an empty region and the
|
|
200
202
|
* last toast add no space, and the stack keeps its 16 px padding. A `top-*`
|
|
201
203
|
* stack lies over the page on purpose (a toast stays visible wherever the
|
|
@@ -54,6 +54,7 @@ export * from "@lifecorner/angular-ui-kit/app-shell";
|
|
|
54
54
|
export * from "@lifecorner/angular-ui-kit/avatar";
|
|
55
55
|
export * from "@lifecorner/angular-ui-kit/badge";
|
|
56
56
|
export * from "@lifecorner/angular-ui-kit/status-dot";
|
|
57
|
+
export * from "@lifecorner/angular-ui-kit/state-strip";
|
|
57
58
|
export * from "@lifecorner/angular-ui-kit/toggle-group";
|
|
58
59
|
export * from "@lifecorner/angular-ui-kit/list";
|
|
59
60
|
export * from "@lifecorner/angular-ui-kit/chip";
|