@lifecorner/angular-ui-kit 3.33.1 → 3.35.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.
Files changed (38) hide show
  1. package/fesm2022/lifecorner-angular-ui-kit-alert.mjs +2 -2
  2. package/fesm2022/lifecorner-angular-ui-kit-alert.mjs.map +1 -1
  3. package/fesm2022/lifecorner-angular-ui-kit-bottom-nav.mjs.map +1 -1
  4. package/fesm2022/lifecorner-angular-ui-kit-combobox.mjs +5 -2
  5. package/fesm2022/lifecorner-angular-ui-kit-combobox.mjs.map +1 -1
  6. package/fesm2022/lifecorner-angular-ui-kit-confirm-dialog.mjs +21 -3
  7. package/fesm2022/lifecorner-angular-ui-kit-confirm-dialog.mjs.map +1 -1
  8. package/fesm2022/lifecorner-angular-ui-kit-drawer.mjs +30 -2
  9. package/fesm2022/lifecorner-angular-ui-kit-drawer.mjs.map +1 -1
  10. package/fesm2022/lifecorner-angular-ui-kit-gallery.mjs.map +1 -1
  11. package/fesm2022/lifecorner-angular-ui-kit-header.mjs +22 -3
  12. package/fesm2022/lifecorner-angular-ui-kit-header.mjs.map +1 -1
  13. package/fesm2022/lifecorner-angular-ui-kit-internal-overlay.mjs +6 -1
  14. package/fesm2022/lifecorner-angular-ui-kit-internal-overlay.mjs.map +1 -1
  15. package/fesm2022/lifecorner-angular-ui-kit-list.mjs +25 -3
  16. package/fesm2022/lifecorner-angular-ui-kit-list.mjs.map +1 -1
  17. package/fesm2022/lifecorner-angular-ui-kit-modal.mjs +31 -2
  18. package/fesm2022/lifecorner-angular-ui-kit-modal.mjs.map +1 -1
  19. package/fesm2022/lifecorner-angular-ui-kit-sidenav.mjs +41 -1
  20. package/fesm2022/lifecorner-angular-ui-kit-sidenav.mjs.map +1 -1
  21. package/fesm2022/lifecorner-angular-ui-kit-textarea.mjs +3 -0
  22. package/fesm2022/lifecorner-angular-ui-kit-textarea.mjs.map +1 -1
  23. package/fesm2022/lifecorner-angular-ui-kit-toast.mjs.map +1 -1
  24. package/package.json +1 -1
  25. package/src/styles/theme-contrast.spec.ts +2 -0
  26. package/types/lifecorner-angular-ui-kit-alert.d.ts +12 -2
  27. package/types/lifecorner-angular-ui-kit-bottom-nav.d.ts +5 -1
  28. package/types/lifecorner-angular-ui-kit-combobox.d.ts +21 -0
  29. package/types/lifecorner-angular-ui-kit-confirm-dialog.d.ts +16 -0
  30. package/types/lifecorner-angular-ui-kit-drawer.d.ts +37 -1
  31. package/types/lifecorner-angular-ui-kit-gallery.d.ts +3 -1
  32. package/types/lifecorner-angular-ui-kit-header.d.ts +15 -0
  33. package/types/lifecorner-angular-ui-kit-internal-overlay.d.ts +9 -1
  34. package/types/lifecorner-angular-ui-kit-list.d.ts +26 -0
  35. package/types/lifecorner-angular-ui-kit-modal.d.ts +38 -2
  36. package/types/lifecorner-angular-ui-kit-sidenav.d.ts +42 -1
  37. package/types/lifecorner-angular-ui-kit-textarea.d.ts +17 -0
  38. package/types/lifecorner-angular-ui-kit-toast.d.ts +4 -2
@@ -138,7 +138,11 @@ export declare class BottomNavComponent {
138
138
  * destinations' badges; pass the value to show. It sits on the bar's last
139
139
  * entry; values up to three characters (`'99+'`) fit: on the last entry a
140
140
  * badge that would pass the entry's edge moves left until it ends there
141
- * (3.33). `null` or `undefined`: no badge.
141
+ * (3.33). `null` or `undefined`: no badge. Known limit (3.35, 052-n3):
142
+ * '99+' on the last entry of a five-entry bar at 360 px starts 3.2 px
143
+ * (docked) / 3.4 px (floating) left of the pill centre and covers two of the
144
+ * More glyph's three dots; the label and the read badge text still name the
145
+ * entry.
142
146
  *
143
147
  * @default null
144
148
  */
@@ -25,6 +25,10 @@ export type ComboboxSize = 'xs' | 'sm' | 'md' | 'lg';
25
25
  * (`[(selectedValue)]`, single mode), next to the `valueChange` output with
26
26
  * the option object and the forms binding.
27
27
  *
28
+ * `focus()` (3.35) moves the focus into the field's `<input>` when a form
29
+ * opens or after a rejected save (WCAG 2.4.3); it opens the list as a user's
30
+ * focus does (`openOnFocus`).
31
+ *
28
32
  * @example
29
33
  * ```html
30
34
  * <lc-combobox
@@ -176,6 +180,23 @@ export declare class ComboboxComponent implements ControlValueAccessor {
176
180
  registerOnChange(fn: (value: ComboboxValue) => void): void;
177
181
  registerOnTouched(fn: () => void): void;
178
182
  setDisabledState(isDisabled: boolean): void;
183
+ /**
184
+ * Moves the focus into the field's `<input>` (3.35), e.g. when a form opens
185
+ * with this field first, or to the field with the error after a rejected
186
+ * save (422) (WCAG 2.4.3). `options` as for `HTMLElement.focus()`
187
+ * (`{ preventScroll: true }`). Shows the same focus ring as a user's focus.
188
+ * Like a user's focus it opens the list when `openOnFocus` is `true` and
189
+ * there is something to show; with `false` the list stays closed
190
+ * (`aria-expanded="false"`). A disabled field takes no focus (it stays where
191
+ * it is). Call it once the field has rendered, e.g.
192
+ * `afterNextRender(() => this.month().focus(), { injector })` with
193
+ * `month = viewChild.required(ComboboxComponent)` and the page component's
194
+ * `injector = inject(Injector)`. In an `lc-modal` that opens with the field,
195
+ * that call runs after the dialog moved the focus to its first control.
196
+ * Does nothing before the component has rendered.
197
+ * @param options Passed to the native `focus()`.
198
+ */
199
+ focus(options?: FocusOptions): void;
179
200
  /**
180
201
  * Clear the current selection and query. Emits `null` (single) or `[]`
181
202
  * (multiple) exactly once, like a user-initiated deselect.
@@ -67,6 +67,12 @@ export declare class ConfirmDialogComponent {
67
67
  * @default 'center'
68
68
  */
69
69
  readonly placement: import("@angular/core").InputSignal<ModalPlacement>;
70
+ /**
71
+ * Passed to `lc-modal` (3.34). The focus returns after confirm, cancel,
72
+ * Escape and ×. Set it to the trigger. `null`: as before.
73
+ * @default null
74
+ */
75
+ readonly returnFocusTo: import("@angular/core").InputSignal<HTMLElement | null>;
70
76
  /** Id of the title, which names the dialog. */
71
77
  protected readonly titleId: string;
72
78
  /** Emitted when user confirms */
@@ -156,6 +162,11 @@ export declare class ConfirmDialogComponent {
156
162
  "required": false;
157
163
  "isSignal": true;
158
164
  };
165
+ "returnFocusTo": {
166
+ "alias": "returnFocusTo";
167
+ "required": false;
168
+ "isSignal": true;
169
+ };
159
170
  }, {
160
171
  "confirmed": "confirmed";
161
172
  "cancelled": "cancelled";
@@ -175,6 +186,11 @@ export interface ConfirmOptions {
175
186
  buttonSize?: ConfirmDialogButtonSize;
176
187
  /** `center`, `auto` (a bottom sheet below 640 px) or `sheet` (3.3). */
177
188
  placement?: ModalPlacement;
189
+ /**
190
+ * Element that gets the focus back after the dialog closed (3.34); see
191
+ * `lc-modal` `returnFocusTo`.
192
+ */
193
+ returnFocusTo?: HTMLElement | null;
178
194
  }
179
195
  /**
180
196
  * Imperative confirm dialog service.
@@ -12,7 +12,10 @@ export type DrawerSize = 'sm' | 'md' | 'lg' | 'xl';
12
12
  * - Close on Escape key support
13
13
  * - Heading text display
14
14
  * - Content projection for arbitrary body content
15
- * - Accessible with ARIA dialog role, focus trap and focus restore
15
+ * - Accessible with ARIA dialog role, focus trap and focus restore;
16
+ * `returnFocusTo` (3.35) names the element that gets the focus back after
17
+ * the drawer closed (WebKit doesn't focus a tapped button, so the one
18
+ * captured at open is `body`)
16
19
  *
17
20
  * @example
18
21
  * ```html
@@ -42,6 +45,20 @@ export declare class DrawerComponent implements OnDestroy {
42
45
  readonly ariaLabel: import("@angular/core").InputSignal<string>;
43
46
  /** Accessible name of the close button. */
44
47
  readonly closeAriaLabel: import("@angular/core").InputSignal<string>;
48
+ /**
49
+ * Element that gets the focus back after the drawer closed (3.35), instead
50
+ * of the one that had it at open. Set it to the trigger: WebKit (Safari,
51
+ * every iOS browser) doesn't focus a tapped button, so the captured element
52
+ * is `body`. Applied when the panel has left the DOM after its 250 ms
53
+ * slide-out, once the focus trap has restored its captured element. Holds
54
+ * on ×, Escape, backdrop, `open` false, and when the drawer is destroyed
55
+ * while open. A custom-element host that can't take focus (`<lc-button>`)
56
+ * hands it to its first focusable descendant. Ignored when the element is
57
+ * no longer in the document or can't take focus; the captured element then
58
+ * keeps it. `null`: as before.
59
+ * @default null
60
+ */
61
+ readonly returnFocusTo: import("@angular/core").InputSignal<HTMLElement | null>;
45
62
  /** Emitted when the drawer should close. */
46
63
  readonly closed: import("@angular/core").OutputEmitterRef<void>;
47
64
  /** Internal visibility — stays true during the slide-out animation. */
@@ -54,8 +71,22 @@ export declare class DrawerComponent implements OnDestroy {
54
71
  private readonly drawerId;
55
72
  private closeTimer?;
56
73
  private originalOverflow?;
74
+ /**
75
+ * The environment injector: a node injector would cancel the focus-return
76
+ * hook when the drawer is destroyed while open.
77
+ */
78
+ private readonly environmentInjector;
79
+ private destroyed;
57
80
  constructor();
58
81
  ngOnDestroy(): void;
82
+ /**
83
+ * Focuses `returnFocusTo` after the next render (3.35): the template
84
+ * refresh has removed the panel, and `cdkTrapFocus` has restored its
85
+ * captured element on destroy, so this is the last focus write. Reads the
86
+ * input again then, so a trigger re-rendered meanwhile is taken from a
87
+ * fresh query. Does nothing when the drawer opened again meanwhile.
88
+ */
89
+ private scheduleFocusReturn;
59
90
  /**
60
91
  * Handle backdrop click. Ignored while another overlay (menu, popover, …)
61
92
  * sits above this drawer — the click belongs to that layer.
@@ -118,6 +149,11 @@ export declare class DrawerComponent implements OnDestroy {
118
149
  "required": false;
119
150
  "isSignal": true;
120
151
  };
152
+ "returnFocusTo": {
153
+ "alias": "returnFocusTo";
154
+ "required": false;
155
+ "isSignal": true;
156
+ };
121
157
  }, {
122
158
  "closed": "closed";
123
159
  }, never, ["*"], true, never>;
@@ -23,7 +23,9 @@ export interface GalleryItem {
23
23
  * - Configurable custom column count
24
24
  * - Lightbox overlay with navigation (prev/next)
25
25
  * - Keyboard navigation (Arrow keys, Escape); focus is trapped inside the
26
- * lightbox and returned to the originating thumbnail on close
26
+ * lightbox and returned to the originating thumbnail on close: the clicked
27
+ * or tapped thumbnail, also in WebKit, where a tap doesn't focus it, so the
28
+ * gallery needs no `returnFocusTo` (3.35)
27
29
  * - Optional captions and category filtering
28
30
  * - Lazy loading with placeholder shimmer
29
31
  * - Zoom control in lightbox
@@ -76,6 +76,8 @@ export type HeaderContextPlacement = 'inline' | 'below';
76
76
  * - `contextPlacement="below"` (3.33): up to 640 px the context button
77
77
  * (`contextName`) takes a full-width row of its own under the title instead
78
78
  * of being hidden; from 641 px it sits in the end group as before.
79
+ * - `focusContext()` (3.34): moves the focus to the context button after the
80
+ * next render, e.g. after a choice in the sheet it opened (WCAG 2.4.3).
79
81
  * - Every built-in label is an input (`homeAriaLabel`, `hamburgerAriaLabel`,
80
82
  * `userMenuAriaLabel`, `navAriaLabel`, `profileLabel`, `logoutLabel`,
81
83
  * `themeToDarkAriaLabel`, `themeToLightAriaLabel`, `contextAriaLabel`);
@@ -283,6 +285,10 @@ export declare class HeaderComponent {
283
285
  */
284
286
  protected get themeService(): ThemeService;
285
287
  private readonly hamburger;
288
+ /** The context button (`contextName`), while it is rendered. */
289
+ private readonly contextButton;
290
+ /** The `focusContext()` hook waiting for the next render. */
291
+ private pendingContextFocus?;
286
292
  constructor();
287
293
  /**
288
294
  * Name of the avatar trigger (AS-33, WCAG 2.5.3 Label in Name):
@@ -322,6 +328,15 @@ export declare class HeaderComponent {
322
328
  * Close profile dropdown
323
329
  */
324
330
  closeDropdown(): void;
331
+ /**
332
+ * Moves the focus to the context button after the next render (3.34), so a
333
+ * `contextName` set just before is already in its name. Call it right after
334
+ * the choice, or when the sheet that changes the context closes. Does
335
+ * nothing while the button isn't shown (no `contextName`, or up to 640 px
336
+ * with `contextPlacement="inline"`). A second call before that render
337
+ * replaces the first.
338
+ */
339
+ focusContext(): void;
325
340
  /**
326
341
  * Handle hamburger click
327
342
  */
@@ -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;
@@ -100,6 +100,12 @@ export interface ListLinkClickEvent {
100
100
  item: ListItem;
101
101
  event: MouseEvent;
102
102
  }
103
+ /**
104
+ * The part of a row that `focusItem()` focuses (3.34): `row`, the row's
105
+ * button (`clickable`) or link (`href`), or `action`, its built-in action
106
+ * button.
107
+ */
108
+ export type ListItemPart = 'row' | 'action';
103
109
  /**
104
110
  * List component for displaying structured item collections.
105
111
  *
@@ -112,6 +118,9 @@ export interface ListLinkClickEvent {
112
118
  * - Accessible with ARIA list role; `clickable` rows are keyboard-operable
113
119
  * - `ListItem.href` rows are real links over the full row (3.16, TD-4);
114
120
  * `linkClick` hands plain clicks to your router
121
+ * - `focusItem(id, part)` (3.34): moves the focus to a row's button or link,
122
+ * or to its action, e.g. when the sheet that action opened closes
123
+ * (WCAG 2.4.3)
115
124
  *
116
125
  * @example
117
126
  * ```html
@@ -172,7 +181,24 @@ export declare class ListComponent {
172
181
  * tab" keeps working.
173
182
  */
174
183
  readonly linkClick: import("@angular/core").OutputEmitterRef<ListLinkClickEvent>;
184
+ private readonly injector;
185
+ /** The `role="list"` element; each item renders exactly one child of it. */
186
+ private readonly listEl;
187
+ /** The `focusItem()` hook waiting for the next render. */
188
+ private pendingItemFocus?;
175
189
  constructor();
190
+ /**
191
+ * Moves the focus into the row of the first item with this `id` after the
192
+ * next render (3.34). `'row'`: the row's button (`clickable`) or link
193
+ * (`href`). `'action'`: its built-in action button. Does nothing for an
194
+ * unknown `id`, for a row without that part (a plain row, a disabled row for
195
+ * `'row'`, no `action`, an `lcListItem` template's own controls), or when
196
+ * the list is destroyed first. A second call before that render replaces the
197
+ * first.
198
+ * @param id The `ListItem.id` of the row.
199
+ * @param part Which part of the row gets the focus.
200
+ */
201
+ focusItem(id: string, part?: ListItemPart): void;
176
202
  /** Whether a row renders as a link: `href` set and not disabled. */
177
203
  protected isLinkRow(item: ListItem): boolean;
178
204
  /**
@@ -17,7 +17,9 @@ export type ModalPlacement = 'center' | 'auto' | 'sheet';
17
17
  * - Placement: centred, or a bottom sheet on phones (`placement="auto"`)
18
18
  * - Header and footer stay visible while the body scrolls; the close button
19
19
  * is a 44 px target
20
- * - Focus trap for keyboard accessibility
20
+ * - Focus trap for keyboard accessibility; `returnFocusTo` (3.34) names the
21
+ * element that gets the focus back after the dialog closed (WebKit doesn't
22
+ * focus a tapped button, so the one captured at open is `body`)
21
23
  * - Backdrop click and Escape key to close
22
24
  * - Two-way open binding
23
25
  * - Header, body, and footer content slots
@@ -84,6 +86,20 @@ export declare class ModalComponent implements OnDestroy {
84
86
  ariaDescribedBy: import("@angular/core").InputSignal<string | undefined>;
85
87
  /** Accessible name of the close button (`showCloseButton`). */
86
88
  closeAriaLabel: import("@angular/core").InputSignal<string>;
89
+ /**
90
+ * Element that gets the focus back after the dialog closed (3.34), instead
91
+ * of the one that had it at open. Set it to the trigger: WebKit (Safari,
92
+ * every iOS browser) doesn't focus a tapped button, so the captured element
93
+ * is `body`. Applied after the next render, once the dialog has left the DOM
94
+ * and the focus trap has restored its captured element. This holds on every
95
+ * close: ×, Escape, backdrop, `open` false, `closeModal()`, and destroying an
96
+ * open modal. A custom-element host that can't take focus (`<lc-button>`)
97
+ * hands it to its first focusable descendant. Ignored when the element is no
98
+ * longer in the document or can't take focus; the captured element then
99
+ * keeps it. `null`: as before.
100
+ * @default null
101
+ */
102
+ returnFocusTo: import("@angular/core").InputSignal<HTMLElement | null>;
87
103
  /**
88
104
  * Emitted when modal opens
89
105
  */
@@ -113,6 +129,13 @@ export declare class ModalComponent implements OnDestroy {
113
129
  /** Identifies this instance in the overlay stack. */
114
130
  private readonly modalId;
115
131
  private originalOverflow?;
132
+ /**
133
+ * The environment injector: a node injector would cancel the focus-return
134
+ * hook when the modal is destroyed while open (`ConfirmService`).
135
+ */
136
+ private readonly environmentInjector;
137
+ /** Whether `showModal()` ran without a `hideModal()` after it. */
138
+ private shown;
116
139
  constructor();
117
140
  ngOnDestroy(): void;
118
141
  /**
@@ -139,13 +162,21 @@ export declare class ModalComponent implements OnDestroy {
139
162
  protected onDocumentKeydown(event: KeyboardEvent): void;
140
163
  /**
141
164
  * Show the modal. Focus is moved inside and restored on close by the
142
- * template's `cdkTrapFocus` / `cdkTrapFocusAutoCapture`.
165
+ * template's `cdkTrapFocus` / `cdkTrapFocusAutoCapture`, then given to
166
+ * `returnFocusTo` when set (3.34).
143
167
  */
144
168
  private showModal;
145
169
  /**
146
170
  * Hide the modal
147
171
  */
148
172
  private hideModal;
173
+ /**
174
+ * Focuses `returnFocusTo` after the next render: the template refresh has
175
+ * removed the dialog, and `cdkTrapFocus` has restored its captured element
176
+ * on destroy, so this is the last focus write. Reads the input again then,
177
+ * so a trigger re-rendered meanwhile is taken from a fresh query.
178
+ */
179
+ private scheduleFocusReturn;
149
180
  static ɵfac: i0.ɵɵFactoryDeclaration<ModalComponent, never>;
150
181
  static ɵcmp: i0.ɵɵComponentDeclaration<ModalComponent, "lc-modal", never, {
151
182
  "open": {
@@ -198,6 +229,11 @@ export declare class ModalComponent implements OnDestroy {
198
229
  "required": false;
199
230
  "isSignal": true;
200
231
  };
232
+ "returnFocusTo": {
233
+ "alias": "returnFocusTo";
234
+ "required": false;
235
+ "isSignal": true;
236
+ };
201
237
  }, {
202
238
  "modalOpened": "modalOpened";
203
239
  "modalClosed": "modalClosed";
@@ -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;
@@ -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); top stacks the
198
- * oldest at the top. The toasts of a stack are 8 px (`--spacing-2`) apart
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