@lifecorner/angular-ui-kit 3.27.2 → 3.29.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 (25) hide show
  1. package/fesm2022/lifecorner-angular-ui-kit-app-shell.mjs +102 -24
  2. package/fesm2022/lifecorner-angular-ui-kit-app-shell.mjs.map +1 -1
  3. package/fesm2022/lifecorner-angular-ui-kit-card.mjs +23 -3
  4. package/fesm2022/lifecorner-angular-ui-kit-card.mjs.map +1 -1
  5. package/fesm2022/lifecorner-angular-ui-kit-combobox.mjs +56 -1
  6. package/fesm2022/lifecorner-angular-ui-kit-combobox.mjs.map +1 -1
  7. package/fesm2022/lifecorner-angular-ui-kit-datepicker.mjs +257 -10
  8. package/fesm2022/lifecorner-angular-ui-kit-datepicker.mjs.map +1 -1
  9. package/fesm2022/lifecorner-angular-ui-kit-internal-overlay.mjs +31 -2
  10. package/fesm2022/lifecorner-angular-ui-kit-internal-overlay.mjs.map +1 -1
  11. package/fesm2022/lifecorner-angular-ui-kit-money.mjs +90 -7
  12. package/fesm2022/lifecorner-angular-ui-kit-money.mjs.map +1 -1
  13. package/fesm2022/lifecorner-angular-ui-kit-number-input.mjs +93 -9
  14. package/fesm2022/lifecorner-angular-ui-kit-number-input.mjs.map +1 -1
  15. package/fesm2022/lifecorner-angular-ui-kit-toast.mjs +12 -2
  16. package/fesm2022/lifecorner-angular-ui-kit-toast.mjs.map +1 -1
  17. package/package.json +1 -1
  18. package/types/lifecorner-angular-ui-kit-app-shell.d.ts +64 -0
  19. package/types/lifecorner-angular-ui-kit-card.d.ts +34 -0
  20. package/types/lifecorner-angular-ui-kit-combobox.d.ts +32 -1
  21. package/types/lifecorner-angular-ui-kit-datepicker.d.ts +143 -2
  22. package/types/lifecorner-angular-ui-kit-internal-overlay.d.ts +21 -0
  23. package/types/lifecorner-angular-ui-kit-money.d.ts +81 -2
  24. package/types/lifecorner-angular-ui-kit-number-input.d.ts +61 -0
  25. package/types/lifecorner-angular-ui-kit-toast.d.ts +25 -0
@@ -4,6 +4,8 @@ import * as i0 from "@angular/core";
4
4
  export type CardVariant = 'elevated' | 'outlined' | 'flat' | 'raised' | 'dashed';
5
5
  /** Heading level of `lc-card`'s built-in title. */
6
6
  export type CardHeadingLevel = 2 | 3 | 4 | 5 | 6;
7
+ /** Layout of `lc-card`'s `[card-footer]` slot: `default` (a flex row, end-aligned) or `equal` (children at equal width). */
8
+ export type CardFooterLayout = 'default' | 'equal';
7
9
  /**
8
10
  * Card component for content grouping and visual hierarchy.
9
11
  *
@@ -15,6 +17,8 @@ export type CardHeadingLevel = 2 | 3 | 4 | 5 | 6;
15
17
  * - Content projection for flexible body content
16
18
  * - Link mode (3.24): `href` or `route` make the whole card a real link,
17
19
  * the title stays a heading
20
+ * - Equal footer (3.29): `footerLayout="equal"` gives two answers of equal
21
+ * weight in the `[card-footer]` slot the same width
18
22
  *
19
23
  * @example
20
24
  * ```html
@@ -32,6 +36,15 @@ export type CardHeadingLevel = 2 | 3 | 4 | 5 | 6;
32
36
  * [route]="['/quellen', 'sap-ist']" [queryParams]="{ ansicht: 'laeufe' }">
33
37
  * ...
34
38
  * </lc-card>
39
+ *
40
+ * <!-- Two answers of equal weight (3.29): primary answer first -->
41
+ * <lc-card title="Netflix" variant="outlined" footerLayout="equal">
42
+ * ...
43
+ * <div card-footer>
44
+ * <lc-button variant="outline" size="lg" [fullWidth]="true">Stimmt</lc-button>
45
+ * <lc-button variant="outline" size="lg" [fullWidth]="true">Kein Vertrag</lc-button>
46
+ * </div>
47
+ * </lc-card>
35
48
  * ```
36
49
  */
37
50
  export declare class CardComponent {
@@ -152,6 +165,22 @@ export declare class CardComponent {
152
165
  * @default undefined
153
166
  */
154
167
  queryParams: import("@angular/core").InputSignal<Params | null | undefined>;
168
+ /**
169
+ * Layout of the `[card-footer]` slot (3.29, CC-2). `equal`: its children
170
+ * share the row at equal width once the card is at least 480 px (30rem)
171
+ * wide, and stack full width, 8 px apart, below that (the card's own width,
172
+ * at any viewport; long labels wrap inside the buttons, which get the
173
+ * row's height). For two answers of equal weight, put
174
+ * `<lc-button variant="outline" size="lg" [fullWidth]="true">` in it,
175
+ * primary answer first; the card adds layout only (gap, divider and
176
+ * spacing as `default`) and never restyles the buttons. The card becomes a
177
+ * size container and takes its parent's full width. Keep the default
178
+ * `padding` (with `none` the buttons' focus ring is clipped). Works in link
179
+ * cards (the buttons stay clickable above the link) and in prerendered
180
+ * HTML (CSS only).
181
+ * @default 'default'
182
+ */
183
+ footerLayout: import("@angular/core").InputSignal<CardFooterLayout>;
155
184
  /**
156
185
  * Emitted when a `clickable` card is clicked or activated with Enter or
157
186
  * Space. Not emitted on a link card (`href`/`route`): the link navigates by
@@ -275,6 +304,11 @@ export declare class CardComponent {
275
304
  "required": false;
276
305
  "isSignal": true;
277
306
  };
307
+ "footerLayout": {
308
+ "alias": "footerLayout";
309
+ "required": false;
310
+ "isSignal": true;
311
+ };
278
312
  }, {
279
313
  "cardClick": "cardClick";
280
314
  }, never, ["[card-badge]", "[card-header-action]", "[card-header]", "*", "[card-footer]"], true, never>;
@@ -19,12 +19,16 @@ export type ComboboxSize = 'xs' | 'sm' | 'md' | 'lg';
19
19
  * The suggestion list is rendered in a CDK overlay so it is never clipped
20
20
  * by `overflow: hidden` ancestors (cards, modals, table cells).
21
21
  *
22
+ * The selection is two-way bindable by an option's `value` string
23
+ * (`[(selectedValue)]`, single mode), next to the `valueChange` output with
24
+ * the option object and the forms binding.
25
+ *
22
26
  * @example
23
27
  * ```html
24
28
  * <lc-combobox
25
29
  * label="Assign to user"
26
30
  * [loadOptions]="searchUsers"
27
- * [(value)]="assignee"
31
+ * [(selectedValue)]="assigneeId"
28
32
  * allowCreate
29
33
  * />
30
34
  * ```
@@ -71,6 +75,19 @@ export declare class ComboboxComponent implements ControlValueAccessor {
71
75
  readonly createOptionLabel: import("@angular/core").InputSignal<string>;
72
76
  /** Size */
73
77
  readonly size: import("@angular/core").InputSignal<ComboboxSize>;
78
+ /**
79
+ * The `value` of the selected option, two-way (3.29, regeln row 2):
80
+ * `[(selectedValue)]="month"`. Shows the matching option's label (from
81
+ * `options`, or the current selection); an unknown value shows an empty
82
+ * field and is filled in when `options` with it arrive. Page writes
83
+ * (including back to `null`) select or clear silently: no
84
+ * `selectedValueChange`, no `valueChange`, no forms `onChange`. Every user
85
+ * choice or clear emits `selectedValueChange`, next to the unchanged
86
+ * `valueChange` (the option object). Single mode only: ignored with
87
+ * `multiple` (a dev warning). Use it or a forms binding, not both.
88
+ * @default null
89
+ */
90
+ readonly selectedValue: import("@angular/core").ModelSignal<string | null>;
74
91
  /** Value change event */
75
92
  readonly valueChange: import("@angular/core").OutputEmitterRef<ComboboxValue>;
76
93
  /** Query change event */
@@ -92,6 +109,10 @@ export declare class ComboboxComponent implements ControlValueAccessor {
92
109
  /** Selected values */
93
110
  protected selectedSingle: import("@angular/core").WritableSignal<ComboboxOption | null>;
94
111
  protected selectedMultiple: import("@angular/core").WritableSignal<ComboboxOption[]>;
112
+ /** The last `selectedValue` the component applied or emitted: a different one is a page write. */
113
+ private seenSelectedValue;
114
+ /** A page-written `selectedValue` no option matched yet: selected silently once `options` hold it. */
115
+ private pendingSelectedValue;
95
116
  /** Resolved visible options */
96
117
  protected visibleOptions: import("@angular/core").Signal<ComboboxOption[]>;
97
118
  /** Grouped options */
@@ -113,6 +134,10 @@ export declare class ComboboxComponent implements ControlValueAccessor {
113
134
  private onChange;
114
135
  private onTouched;
115
136
  constructor();
137
+ /** Shows the option with `value` (or clears for `null`) without emitting anything. */
138
+ private applySelectedValue;
139
+ /** Emits a user's single choice or clear through `selectedValueChange` (not in `multiple` mode). */
140
+ private emitSelectedValue;
116
141
  writeValue(value: ComboboxValue): void;
117
142
  registerOnChange(fn: (value: ComboboxValue) => void): void;
118
143
  registerOnTouched(fn: () => void): void;
@@ -213,7 +238,13 @@ export declare class ComboboxComponent implements ControlValueAccessor {
213
238
  "required": false;
214
239
  "isSignal": true;
215
240
  };
241
+ "selectedValue": {
242
+ "alias": "selectedValue";
243
+ "required": false;
244
+ "isSignal": true;
245
+ };
216
246
  }, {
247
+ "selectedValue": "selectedValueChange";
217
248
  "valueChange": "valueChange";
218
249
  "queryChange": "queryChange";
219
250
  "optionSelected": "optionSelected";
@@ -1,11 +1,27 @@
1
1
  import { ControlValueAccessor } from "@angular/forms";
2
2
  import * as i0 from "@angular/core";
3
3
  export type DateValue = Date | string | null;
4
+ /** What `lc-datepicker` picks: a day (`'day'`) or a month (`'month'`). */
5
+ export type DatepickerGranularity = 'day' | 'month';
6
+ /** One cell of the month grid (`granularity="month"`). */
7
+ interface MonthCell {
8
+ /** 0–11. */
9
+ month: number;
10
+ /** Visible name („Juli“). */
11
+ name: string;
12
+ /** Accessible name with the year („Juli 2026“). */
13
+ label: string;
14
+ selected: boolean;
15
+ current: boolean;
16
+ disabled: boolean;
17
+ }
4
18
  /**
5
19
  * Datepicker component for date selection with calendar overlay.
6
20
  *
7
21
  * Features:
8
22
  * - Calendar popup with month and year navigation
23
+ * - Month granularity (3.29): `granularity="month"` picks a month in a
24
+ * 12-month grid with year navigation and emits its first day
9
25
  * - Manual date entry in the configured format
10
26
  * - Min/max date constraints
11
27
  * - Disabled specific dates and weekends
@@ -18,6 +34,7 @@ export type DateValue = Date | string | null;
18
34
  * @example
19
35
  * ```html
20
36
  * <lc-datepicker placeholder="Select date" [(ngModel)]="selectedDate" />
37
+ * <lc-datepicker granularity="month" format="YYYY-MM" placeholder="Select a month" [(ngModel)]="validFrom" />
21
38
  * ```
22
39
  */
23
40
  export declare class DatepickerComponent implements ControlValueAccessor {
@@ -102,6 +119,42 @@ export declare class DatepickerComponent implements ControlValueAccessor {
102
119
  readonly todayLabel: import("@angular/core").InputSignal<string>;
103
120
  /** Appended to the selected day's accessible name (`…, selected`). */
104
121
  readonly selectedAriaLabel: import("@angular/core").InputSignal<string>;
122
+ /**
123
+ * Pick a day (`'day'`) or a month (`'month'`, 3.29, regeln row 1). Month:
124
+ * a 12-month grid with year navigation; `dateChange` and the forms value
125
+ * are the 1st of the month (local midnight, as day mode); `format` should
126
+ * be a month format (`'YYYY-MM'`; a `DD` token shows `01`), and typing
127
+ * „2026-07“ commits like a day. `minDate`/`maxDate` keep a month
128
+ * selectable when any of its days is in range; a `disabledDates` entry
129
+ * disables its whole month; `disableWeekends` is ignored. Set
130
+ * `placeholder` (e.g. "Select a month"). Keys in the grid: arrows move by
131
+ * month and row, PageUp/PageDown by year, Home/End to the first/last month
132
+ * of the year, Enter/Space select, Escape closes.
133
+ * @default 'day'
134
+ */
135
+ readonly granularity: import("@angular/core").InputSignal<DatepickerGranularity>;
136
+ /**
137
+ * Accessible name of the previous-year button (month mode).
138
+ * @default 'Previous year'
139
+ */
140
+ readonly previousYearAriaLabel: import("@angular/core").InputSignal<string>;
141
+ /**
142
+ * Accessible name of the next-year button (month mode).
143
+ * @default 'Next year'
144
+ */
145
+ readonly nextYearAriaLabel: import("@angular/core").InputSignal<string>;
146
+ /**
147
+ * Accessible name of the month dialog (month mode; `dialogAriaLabel`
148
+ * stays the day dialog's).
149
+ * @default 'Choose month'
150
+ */
151
+ readonly monthDialogAriaLabel: import("@angular/core").InputSignal<string>;
152
+ /**
153
+ * Label of the quick action that shows the current year (month mode; day
154
+ * mode keeps `todayLabel`).
155
+ * @default 'This month'
156
+ */
157
+ readonly currentMonthLabel: import("@angular/core").InputSignal<string>;
105
158
  /**
106
159
  * Emitted when date selection changes
107
160
  */
@@ -122,6 +175,8 @@ export declare class DatepickerComponent implements ControlValueAccessor {
122
175
  private readonly formDisabled;
123
176
  /** Effective disabled state: the `disabled` input OR the form control's disabled state. */
124
177
  readonly isDisabled: import("@angular/core").Signal<boolean>;
178
+ /** Month granularity (3.29). */
179
+ protected readonly isMonthMode: import("@angular/core").Signal<boolean>;
125
180
  readonly formattedDate: import("@angular/core").Signal<string>;
126
181
  /**
127
182
  * Text currently shown in the input. Follows the selected date, but the user
@@ -134,6 +189,18 @@ export declare class DatepickerComponent implements ControlValueAccessor {
134
189
  readonly currentMonthName: import("@angular/core").Signal<string>;
135
190
  /** Weekday headers in grid order, starting at `firstDayOfWeek`. */
136
191
  readonly weekdayLabels: import("@angular/core").Signal<string[]>;
192
+ /** Header title: „July 2026“ (day mode) or the year „2026“ (month mode). */
193
+ protected readonly headerTitle: import("@angular/core").Signal<string>;
194
+ /** The twelve months of the shown year (month mode). */
195
+ protected readonly monthCells: import("@angular/core").Signal<MonthCell[]>;
196
+ /** The month grid's four rows of three. */
197
+ protected readonly monthRows: import("@angular/core").Signal<MonthCell[][]>;
198
+ /**
199
+ * The month cell that is the grid's one tab stop (roving `tabindex`): the
200
+ * selected month in the shown year, else the current month, else the first
201
+ * enabled one; `-1` when the whole year is disabled. Keys move it.
202
+ */
203
+ protected readonly monthTabStop: import("@angular/core").WritableSignal<number>;
137
204
  /** `firstDayOfWeek` clamped to 0–6. */
138
205
  private readonly gridStart;
139
206
  /** id of the helper/error text the input is described by (aria-describedby) */
@@ -143,6 +210,7 @@ export declare class DatepickerComponent implements ControlValueAccessor {
143
210
  */
144
211
  readonly datepickerClasses: import("@angular/core").Signal<string>;
145
212
  private readonly document;
213
+ private readonly injector;
146
214
  private onChange;
147
215
  private onTouched;
148
216
  /**
@@ -196,6 +264,22 @@ export declare class DatepickerComponent implements ControlValueAccessor {
196
264
  * Navigate to today
197
265
  */
198
266
  goToToday(): void;
267
+ /** Month mode: show the previous year. */
268
+ protected previousYear(): void;
269
+ /** Month mode: show the next year. */
270
+ protected nextYear(): void;
271
+ /** Month mode's quick action: show the current year. */
272
+ protected showCurrentYear(): void;
273
+ /** Month mode: select `month` of the shown year (its 1st), emit, close and focus the field. */
274
+ protected selectMonth(month: number): void;
275
+ /**
276
+ * Keys on a month cell (APG date grid): arrows ±1 month and ±3 (a row),
277
+ * PageUp/PageDown ±1 year (the nearest enabled month of that year),
278
+ * Home/End the first/last enabled month of the year; disabled months are
279
+ * skipped, and with none left focus stays. Enter/Space select, Escape
280
+ * closes. Arrows only move focus.
281
+ */
282
+ protected onMonthKeydown(event: KeyboardEvent, month: number): void;
199
283
  /**
200
284
  * Handle input change (manual date entry). Partial input is kept as text
201
285
  * only; the model changes once the text is a complete, valid, selectable date.
@@ -221,6 +305,36 @@ export declare class DatepickerComponent implements ControlValueAccessor {
221
305
  * Check if date is in current month
222
306
  */
223
307
  isCurrentMonth(date: Date): boolean;
308
+ /** The selected month of the shown year, else the current month, else the first enabled one; `-1` if none. */
309
+ private defaultMonthTabStop;
310
+ /**
311
+ * Keys in the field while the month panel is open: ArrowDown moves focus
312
+ * into the grid, Escape closes, Enter closes when a month is selected;
313
+ * the other keys stay with the text (caret, typing „2026-07“).
314
+ */
315
+ private onMonthFieldKeyDown;
316
+ /**
317
+ * Month mode: a month is disabled when all its days are before `minDate`
318
+ * or after `maxDate` (compared by day), or when `disabledDates` holds one
319
+ * of its days. `disableWeekends` does not apply.
320
+ */
321
+ private isMonthDisabled;
322
+ /** A typed date that cannot be committed: its day (day mode) or its month (month mode) is disabled. */
323
+ private isUnavailable;
324
+ /** Whether `date` is the current selection: the same day, or in month mode the same month. */
325
+ private isSameSelection;
326
+ /** Year and month (0–11) of a month index `year * 12 + month`. */
327
+ private monthAt;
328
+ /** The next enabled month from `index` in steps of `step` (up to ten years), or `null`. */
329
+ private nextEnabledMonth;
330
+ /** `month` of `year` if enabled, else the enabled month of that year nearest to it, or `null`. */
331
+ private nearestEnabledMonth;
332
+ /** The first (`dir` 1) or last (`dir` -1) enabled month of `year`, or `null`. */
333
+ private edgeEnabledMonth;
334
+ /** Moves the grid's tab stop and focus to the month `index`; the shown year follows. */
335
+ private moveMonthFocus;
336
+ /** Focuses the month cell `month` (0–11) of the open panel; the cells are kept across years. */
337
+ private focusMonthCell;
224
338
  private commitDate;
225
339
  private showMonthOf;
226
340
  private restoreFocusFromPanel;
@@ -234,7 +348,8 @@ export declare class DatepickerComponent implements ControlValueAccessor {
234
348
  * Strict parse: the text must match the format's length, carry digits at the
235
349
  * YYYY/MM/DD positions and round-trip through formatDate (which rejects
236
350
  * things like month 13 or Feb 31 that `new Date` would silently roll over).
237
- * Returns null for partial or invalid input.
351
+ * Returns null for partial or invalid input. Month mode also takes a format
352
+ * without `DD` (`YYYY-MM`) and returns the 1st of the month.
238
353
  */
239
354
  private parseDate;
240
355
  protected getInputValue(event: Event): string;
@@ -355,9 +470,35 @@ export declare class DatepickerComponent implements ControlValueAccessor {
355
470
  "required": false;
356
471
  "isSignal": true;
357
472
  };
473
+ "granularity": {
474
+ "alias": "granularity";
475
+ "required": false;
476
+ "isSignal": true;
477
+ };
478
+ "previousYearAriaLabel": {
479
+ "alias": "previousYearAriaLabel";
480
+ "required": false;
481
+ "isSignal": true;
482
+ };
483
+ "nextYearAriaLabel": {
484
+ "alias": "nextYearAriaLabel";
485
+ "required": false;
486
+ "isSignal": true;
487
+ };
488
+ "monthDialogAriaLabel": {
489
+ "alias": "monthDialogAriaLabel";
490
+ "required": false;
491
+ "isSignal": true;
492
+ };
493
+ "currentMonthLabel": {
494
+ "alias": "currentMonthLabel";
495
+ "required": false;
496
+ "isSignal": true;
497
+ };
358
498
  }, {
359
499
  "dateChange": "dateChange";
360
500
  "opened": "opened";
361
501
  "closed": "closed";
362
502
  }, never, never, true, never>;
363
- }
503
+ }
504
+ export {};
@@ -28,4 +28,25 @@ export declare class OverlayStackService {
28
28
  claim(id: string, event: Event): boolean;
29
29
  static ɵfac: i0.ɵɵFactoryDeclaration<OverlayStackService, never>;
30
30
  static ɵprov: i0.ɵɵInjectableDeclaration<any>;
31
+ }
32
+ /**
33
+ * The space a fixed overlay keeps free at the top and the bottom of the
34
+ * viewport, as CSS lengths (3.28, AS-34). `lc-app-shell` writes them in the
35
+ * browser: `top` is its header's bottom edge, `bottom` the shown bottom bar's
36
+ * top edge, measured from the viewport's bottom (or the safe-area insets when
37
+ * there is no header or no bar). `lc-toast-outlet` reads them, so its stacks
38
+ * clear the header and the bar even when the app renders the outlet outside
39
+ * the shell (no custom property can inherit there).
40
+ *
41
+ * `null` means "no shell": on the server, before the shell has measured,
42
+ * without ResizeObserver and after the shell is destroyed. Internal to the
43
+ * library; not part of the public API and without a semver guarantee.
44
+ */
45
+ export declare class OverlayInsetsService {
46
+ /** CSS length kept free above top-edge overlays, e.g. `'56px'`. */
47
+ readonly top: import("@angular/core").WritableSignal<string | null>;
48
+ /** CSS length kept free below bottom-edge overlays, e.g. `'102px'`. */
49
+ readonly bottom: import("@angular/core").WritableSignal<string | null>;
50
+ static ɵfac: i0.ɵɵFactoryDeclaration<OverlayInsetsService, never>;
51
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
31
52
  }
@@ -27,6 +27,15 @@ interface MoneyFormatOptions {
27
27
  */
28
28
  showCurrency?: boolean;
29
29
  }
30
+ /** Options of {@link formatMoneyRange}: those of {@link formatMoney}, for both amounts, and the joining word. */
31
+ interface MoneyRangeFormatOptions extends MoneyFormatOptions {
32
+ /**
33
+ * Word between the two amounts, in `text` and in `spoken`. Empty: from
34
+ * `locale`, „bis“ for German (`de`), "to" for every other locale.
35
+ * @default ''
36
+ */
37
+ separatorLabel?: string;
38
+ }
30
39
  /** A formatted amount: the visible text and the words a screen reader speaks. */
31
40
  interface MoneyText {
32
41
  /**
@@ -58,6 +67,33 @@ declare function moneyDirection(locale: string): 'ltr' | 'rtl';
58
67
  * ```
59
68
  */
60
69
  export declare function formatMoney(amountMinor: number, currency: string, options?: MoneyFormatOptions): MoneyText | null;
70
+ /** U+00A0: glues the joining word of a range to the second amount. */
71
+ declare const MONEY_RANGE_GLUE: string;
72
+ /** The word between the amounts of a range: „bis“ for a German locale (`de`), "to" otherwise. */
73
+ declare function moneyRangeSeparator(locale: string): string;
74
+ /** Both amounts of a range and the joining word; `null` if either amount fails {@link formatMoney}. */
75
+ declare function moneyRangeParts(fromMinor: number, toMinor: number, currency: string, options?: MoneyRangeFormatOptions): {
76
+ from: MoneyText;
77
+ to: MoneyText;
78
+ word: string;
79
+ } | null;
80
+ /**
81
+ * Formats a range of two amounts in minor units with the same currency and
82
+ * options („9,99 € bis 12,99 €“), for table `formatter`s and texts. The
83
+ * joining word is glued to the second amount with a no-break space (U+00A0),
84
+ * so a line breaks only before it. The amounts are kept as given (no
85
+ * sorting; equal amounts give a range). Returns `null` if either amount fails
86
+ * {@link formatMoney}. `lc-money` shows the same with `rangeToMinor`.
87
+ *
88
+ * @example
89
+ * ```ts
90
+ * formatMoneyRange(999, 1299, 'EUR', { locale: 'de-DE' });
91
+ * // { text: '9,99 € bis 12,99 €', spoken: '9,99 Euro bis 12,99 Euro' }
92
+ * formatMoneyRange(999, 1299, 'EUR', { locale: 'en-US' });
93
+ * // { text: '€9.99 to €12.99', spoken: '9.99 euros to 12.99 euros' }
94
+ * ```
95
+ */
96
+ export declare function formatMoneyRange(fromMinor: number, toMinor: number, currency: string, options?: MoneyRangeFormatOptions): MoneyText | null;
61
97
  /**
62
98
  * Displays an amount of money (3.16, BA-4): locale, currency, sign, tabular
63
99
  * figures and a spoken text. Display only, no input parsing or conversion.
@@ -77,7 +113,11 @@ export declare function formatMoney(amountMinor: number, currency: string, optio
77
113
  * „Kosten in €“); the spoken text keeps the currency.
78
114
  * - `locale` empty: the app's `LOCALE_ID` (Angular's default `en-US`), the
79
115
  * same on the server and in the browser.
80
- * - For table `formatter`s and texts use {@link formatMoney}.
116
+ * - A range (3.29, CC-1): `rangeToMinor` adds an upper amount, „9,99 € bis
117
+ * 12,99 €“, read once („9,99 Euro bis 12,99 Euro“). It may wrap before the
118
+ * joining word, never inside an amount.
119
+ * - For table `formatter`s and texts use {@link formatMoney} and
120
+ * {@link formatMoneyRange}.
81
121
  *
82
122
  * Separate a `lc-money` from adjacent text with a space in your template, so
83
123
  * the spoken text does not run into the words around it.
@@ -85,6 +125,7 @@ export declare function formatMoney(amountMinor: number, currency: string, optio
85
125
  * @example
86
126
  * ```html
87
127
  * <lc-money [amountMinor]="-4217" currency="EUR" locale="de-DE" />
128
+ * <lc-money [amountMinor]="999" [rangeToMinor]="1299" currency="EUR" locale="de-DE" />
88
129
  * ```
89
130
  */
90
131
  export declare class MoneyComponent {
@@ -134,9 +175,37 @@ export declare class MoneyComponent {
134
175
  * @default true
135
176
  */
136
177
  readonly showCurrency: import("@angular/core").InputSignal<boolean>;
178
+ /**
179
+ * Upper amount of a range, in minor units of the same `currency` (3.29,
180
+ * CC-1). Shows „9,99 € bis 12,99 €“ (`de-DE`) or "€9.99 to €12.99"
181
+ * (`en-US`) with the same `locale`, `signDisplay` and `showCurrency`, read
182
+ * once („9,99 Euro bis 12,99 Euro“). Rendered as given: no sorting, equal
183
+ * amounts show a range. The range may wrap before the joining word, never
184
+ * inside an amount. Not a safe integer: the single amount (a dev warning).
185
+ * `null`/`undefined`: no range.
186
+ * @default undefined
187
+ */
188
+ readonly rangeToMinor: import("@angular/core").InputSignal<number | null | undefined>;
189
+ /**
190
+ * Word between the amounts of a range, shown and spoken. Empty: from the
191
+ * locale, „bis“ for German (`de`), "to" for every other locale.
192
+ * @default ''
193
+ */
194
+ readonly rangeSeparatorLabel: import("@angular/core").InputSignal<string>;
137
195
  /** The locale in use: the `locale` input or the app's `LOCALE_ID`. */
138
196
  protected readonly effectiveLocale: import("@angular/core").Signal<string>;
139
197
  protected readonly formatted: import("@angular/core").Signal<import("@lifecorner/angular-ui-kit/money").MoneyText | null>;
198
+ /**
199
+ * The range's parts (3.29): both visible amounts, the joining text between
200
+ * them (the word glued to the second amount by U+00A0, so a line breaks
201
+ * only before it) and the one spoken text. `null`: no range.
202
+ */
203
+ protected readonly range: import("@angular/core").Signal<{
204
+ from: import("@lifecorner/angular-ui-kit/money").MoneyText;
205
+ to: import("@lifecorner/angular-ui-kit/money").MoneyText;
206
+ joint: string;
207
+ spoken: string;
208
+ } | null>;
140
209
  protected readonly dir: import("@angular/core").Signal<"ltr" | "rtl">;
141
210
  constructor();
142
211
  static ɵfac: i0.ɵɵFactoryDeclaration<MoneyComponent, never>;
@@ -176,6 +245,16 @@ export declare class MoneyComponent {
176
245
  "required": false;
177
246
  "isSignal": true;
178
247
  };
248
+ "rangeToMinor": {
249
+ "alias": "rangeToMinor";
250
+ "required": false;
251
+ "isSignal": true;
252
+ };
253
+ "rangeSeparatorLabel": {
254
+ "alias": "rangeSeparatorLabel";
255
+ "required": false;
256
+ "isSignal": true;
257
+ };
179
258
  }, {}, never, never, true, never>;
180
259
  }
181
- export type { MoneyFormatOptions, MoneySignDisplay, MoneyText };
260
+ export type { MoneyFormatOptions, MoneyRangeFormatOptions, MoneySignDisplay, MoneyText };
@@ -1,5 +1,7 @@
1
1
  import { ControlValueAccessor } from "@angular/forms";
2
2
  import * as i0 from "@angular/core";
3
+ /** Height of `lc-number-input`'s field and steppers: `xs` 24, `sm` 32, `md` 40 (the default), `lg` 44 px. */
4
+ export type NumberInputSize = 'xs' | 'sm' | 'md' | 'lg';
3
5
  export declare class NumberInputComponent implements ControlValueAccessor {
4
6
  private static nextId;
5
7
  /** Minimum value */
@@ -24,6 +26,36 @@ export declare class NumberInputComponent implements ControlValueAccessor {
24
26
  decrementAriaLabel: import("@angular/core").InputSignal<string>;
25
27
  /** Accessible name of the plus button. */
26
28
  incrementAriaLabel: import("@angular/core").InputSignal<string>;
29
+ /**
30
+ * BCP 47 locale of the shown number (3.29, regeln row 3). Only the decimal
31
+ * separator follows it: `de-DE` shows „7,5“, `en-US` "7.5"; a locale whose
32
+ * separator is neither `,` nor `.` shows a point. No grouping. `''`: a
33
+ * point, as before. Typing accepts `,` and `.` in every locale and shows
34
+ * the locale's separator; the model stays a `number`; blur clamps to
35
+ * `min`/`max`.
36
+ * @default ''
37
+ */
38
+ locale: import("@angular/core").InputSignal<string>;
39
+ /**
40
+ * Unit shown after the value inside the field („7,5 %“, 3.29). Not typed
41
+ * and not part of the model; with a suffix the value aligns to the end.
42
+ * Screen readers read `suffixAriaLabel` (or the suffix) once after the value.
43
+ * @default ''
44
+ */
45
+ suffix: import("@angular/core").InputSignal<string>;
46
+ /**
47
+ * Spoken unit („Prozent“), read once after the value as the field's
48
+ * description (before the helper or error text). `''`: the `suffix`.
49
+ * @default ''
50
+ */
51
+ suffixAriaLabel: import("@angular/core").InputSignal<string>;
52
+ /**
53
+ * Height of the field and the steppers (3.29, regeln row 4): `xs` 24,
54
+ * `sm` 32, `md` 40 (as before), `lg` 44 px (touch: field and both
55
+ * steppers at least 44 × 44 px).
56
+ * @default 'md'
57
+ */
58
+ size: import("@angular/core").InputSignal<NumberInputSize>;
27
59
  /** Emits value on change */
28
60
  valueChange: import("@angular/core").OutputEmitterRef<number>;
29
61
  /** Per-instance id wiring the label, hint and error to the field. */
@@ -44,6 +76,12 @@ export declare class NumberInputComponent implements ControlValueAccessor {
44
76
  private readonly stepPrecision;
45
77
  /** Fractions need a decimal key on touch keyboards; integers do not. */
46
78
  protected readonly inputMode: import("@angular/core").Signal<"decimal" | "numeric">;
79
+ /** The decimal separator shown in the field: the `locale`'s `,` or `.`. */
80
+ private readonly separator;
81
+ /** The spoken unit: `suffixAriaLabel`, else the `suffix`; `''` = none. */
82
+ protected readonly spokenSuffix: import("@angular/core").Signal<string>;
83
+ /** Icon size of the steppers: `xs` (16 px) for the `xs`/`sm` fields, `sm` (20 px) as before. */
84
+ protected readonly iconSize: import("@angular/core").Signal<"xs" | "sm">;
47
85
  protected readonly describedBy: import("@angular/core").Signal<string | null>;
48
86
  protected containerClasses: import("@angular/core").Signal<string>;
49
87
  protected canDecrement: import("@angular/core").Signal<boolean>;
@@ -56,7 +94,10 @@ export declare class NumberInputComponent implements ControlValueAccessor {
56
94
  onKeydown(event: KeyboardEvent): void;
57
95
  onInput(event: Event): void;
58
96
  onBlur(): void;
97
+ /** The model as text: `String(val)` with the locale's decimal separator, no grouping. */
59
98
  private format;
99
+ /** A press on the visible unit puts the caret in the field, as a click on the field would. */
100
+ protected focusField(event: MouseEvent): void;
60
101
  private clamp;
61
102
  private setValue;
62
103
  writeValue(val: number | null): void;
@@ -120,6 +161,26 @@ export declare class NumberInputComponent implements ControlValueAccessor {
120
161
  "required": false;
121
162
  "isSignal": true;
122
163
  };
164
+ "locale": {
165
+ "alias": "locale";
166
+ "required": false;
167
+ "isSignal": true;
168
+ };
169
+ "suffix": {
170
+ "alias": "suffix";
171
+ "required": false;
172
+ "isSignal": true;
173
+ };
174
+ "suffixAriaLabel": {
175
+ "alias": "suffixAriaLabel";
176
+ "required": false;
177
+ "isSignal": true;
178
+ };
179
+ "size": {
180
+ "alias": "size";
181
+ "required": false;
182
+ "isSignal": true;
183
+ };
123
184
  }, {
124
185
  "valueChange": "valueChange";
125
186
  }, never, never, true, never>;
@@ -1,5 +1,6 @@
1
1
  import * as i0 from "@angular/core";
2
2
  import { Signal } from "@angular/core";
3
+ import { OverlayInsetsService } from "@lifecorner/angular-ui-kit/internal/overlay";
3
4
  export type ToastVariant = 'success' | 'error' | 'warning' | 'info';
4
5
  export type ToastPosition = 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
5
6
  export interface ToastAction {
@@ -181,11 +182,35 @@ type ToastLive = 'polite' | 'assertive';
181
182
  * into an *existing* live region — one `polite` for success/info toasts and one
182
183
  * `assertive` for error/warning toasts. Dismissing a toast (close button,
183
184
  * action, auto-dismiss) removes it from the service.
185
+ *
186
+ * Offsets (3.28, AS-34): with `lc-app-shell` in the app (the outlet may sit
187
+ * before or after it), the `top-*` stacks start below the shell's header and
188
+ * the `bottom-*` stacks end above its bottom bar, each with the stack's 16 px
189
+ * padding as the gap. The shell measures both in the browser (the header's
190
+ * bottom edge with the top inset; the shown bar's top edge, from the
191
+ * viewport's bottom, with the bottom inset). From 1024 px, where the bar is
192
+ * hidden, the bottom offset is the safe-area inset. Without a shell, and in
193
+ * prerendered HTML, both are `0px`, as before. Every stack is at most as high
194
+ * as the space between the offsets and scrolls when its toasts need more
195
+ * (200 % text), so each toast stays reachable. In the shell, prefer the
196
+ * `bottom-*` positions: a top toast can still cover a page title placed
197
+ * right under the header.
198
+ *
199
+ * CSS hooks (set them on `lc-toast-outlet` or any ancestor, e.g. `:root`;
200
+ * each wins over the shell's value; write lengths, `0px` rather than `0`):
201
+ * - `--lc-toast-outlet-offset-top` — the space kept free above the `top-*`
202
+ * stacks. Default `0px`; with `lc-app-shell`: its header's bottom edge, or
203
+ * `env(safe-area-inset-top, 0px)` without a header.
204
+ * - `--lc-toast-outlet-offset-bottom` — the space kept free below the
205
+ * `bottom-*` stacks. Default `0px`; with `lc-app-shell`: the shown bottom
206
+ * bar's top edge, measured from the viewport's bottom, or
207
+ * `env(safe-area-inset-bottom, 0px)` when no bar shows.
184
208
  */
185
209
  export declare class ToastOutletComponent {
186
210
  protected readonly positions: readonly ToastPosition[];
187
211
  protected readonly liveLevels: readonly ToastLive[];
188
212
  private readonly toastService;
213
+ protected readonly insets: OverlayInsetsService;
189
214
  /** Accessible name of every toast's close button (forwarded to lc-toast). */
190
215
  readonly closeAriaLabel: import("@angular/core").InputSignal<string>;
191
216
  /** Toasts keyed by `${position}:${politeness}` in the order they were shown. */