mn-angular-lib 1.0.161 → 1.0.163
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/fesm2022/mn-angular-lib.mjs +601 -43
- package/fesm2022/mn-angular-lib.mjs.map +1 -1
- package/package.json +1 -1
- package/types/mn-angular-lib.d.ts +334 -14
package/package.json
CHANGED
|
@@ -2826,6 +2826,8 @@ type MnMultiSelectUIConfig = {
|
|
|
2826
2826
|
errorMessages?: Record<string, string>;
|
|
2827
2827
|
/** Text shown when no options match the search filter */
|
|
2828
2828
|
noOptionsFound?: string;
|
|
2829
|
+
/** Placeholder and accessible name for the dropdown's search input */
|
|
2830
|
+
searchPlaceholder?: string;
|
|
2829
2831
|
};
|
|
2830
2832
|
|
|
2831
2833
|
declare const MN_MULTI_SELECT_CONFIG: InjectionToken<MnMultiSelectUIConfig>;
|
|
@@ -3047,6 +3049,34 @@ declare class MnMultiSelect implements OnInit {
|
|
|
3047
3049
|
* is selected, then `collapsePlaceholder`, then `"{count} selected"`.
|
|
3048
3050
|
*/
|
|
3049
3051
|
get collapseSummaryText(): string;
|
|
3052
|
+
/** Trigger text shown while nothing is selected. */
|
|
3053
|
+
get placeholderLabel(): string;
|
|
3054
|
+
/**
|
|
3055
|
+
* Placeholder and accessible name of the dropdown's search input.
|
|
3056
|
+
*
|
|
3057
|
+
* Search auto-enables at `searchThreshold` options, so this box appears without any
|
|
3058
|
+
* call site opting in — which is exactly why it must be translatable without one.
|
|
3059
|
+
*/
|
|
3060
|
+
get searchPlaceholderLabel(): string;
|
|
3061
|
+
/** Empty text shown when the search filters every option away. */
|
|
3062
|
+
get noOptionsLabel(): string;
|
|
3063
|
+
/**
|
|
3064
|
+
* Resolves one of the component's own labels, preferring what the caller gave it
|
|
3065
|
+
* and falling back through the config layer, a conventional translation key and
|
|
3066
|
+
* finally a readable English default.
|
|
3067
|
+
*
|
|
3068
|
+
* Mirrors `MnCollectionBase.resolveLabel`. Every string this component puts on
|
|
3069
|
+
* screen that is not caller data goes through here: without the key step a
|
|
3070
|
+
* consumer could only translate these by repeating the same literal at every call
|
|
3071
|
+
* site, which is how "Search..." ends up in English on an otherwise Dutch page.
|
|
3072
|
+
*
|
|
3073
|
+
* @param explicit The label the caller passed through `props`, if any.
|
|
3074
|
+
* @param key The conventional translation key to try next.
|
|
3075
|
+
* @param fallback The English text used when neither resolves.
|
|
3076
|
+
* @param configured The value the config layer resolved, if any.
|
|
3077
|
+
* @returns The resolved label.
|
|
3078
|
+
*/
|
|
3079
|
+
private resolveLabel;
|
|
3050
3080
|
handleBlur(): void;
|
|
3051
3081
|
get control(): _angular_forms.AbstractControl<any, any, any> | null;
|
|
3052
3082
|
get showError(): boolean;
|
|
@@ -3909,6 +3939,28 @@ type MnSelectProps<TValue = unknown> = {
|
|
|
3909
3939
|
placeholder?: string;
|
|
3910
3940
|
/** Available options to select from */
|
|
3911
3941
|
options: MnSelectOption<TValue>[];
|
|
3942
|
+
/**
|
|
3943
|
+
* Whether to show a search/filter input at the top of the panel. When omitted, search
|
|
3944
|
+
* auto-enables once the number of options reaches `searchThreshold`, so long lists stay
|
|
3945
|
+
* filterable without every call site having to opt in. Set explicitly to force it on or off.
|
|
3946
|
+
*/
|
|
3947
|
+
searchable?: boolean;
|
|
3948
|
+
/**
|
|
3949
|
+
* Number of options at which the search input auto-enables (default: 8).
|
|
3950
|
+
* Ignored when `searchable` is set explicitly.
|
|
3951
|
+
*/
|
|
3952
|
+
searchThreshold?: number;
|
|
3953
|
+
/** Placeholder text for the search input */
|
|
3954
|
+
searchPlaceholder?: string;
|
|
3955
|
+
/**
|
|
3956
|
+
* Whether the option panel renders as a bottom sheet on small screens (< 640px).
|
|
3957
|
+
* Defaults to true. Set to false to keep the trigger-anchored panel on mobile.
|
|
3958
|
+
*
|
|
3959
|
+
* The anchored panel sits at the trigger's bottom edge, which puts it directly in
|
|
3960
|
+
* the path of the soft keyboard as soon as the search input takes focus. The sheet
|
|
3961
|
+
* is anchored to the viewport instead, so the list stays reachable.
|
|
3962
|
+
*/
|
|
3963
|
+
mobileSheet?: boolean;
|
|
3912
3964
|
/** Size variant of the select (default: 'md') */
|
|
3913
3965
|
size?: MnSelectVariants['size'];
|
|
3914
3966
|
/** Border radius variant (default: 'md') */
|
|
@@ -3940,45 +3992,248 @@ type MnSelectUIConfig = {
|
|
|
3940
3992
|
* These override built-in error messages but are overridden by props.errorMessages.
|
|
3941
3993
|
*/
|
|
3942
3994
|
errorMessages?: Record<string, string>;
|
|
3995
|
+
/** Text shown when no options match the search filter */
|
|
3996
|
+
noOptionsFound?: string;
|
|
3997
|
+
/** Placeholder and accessible name for the dropdown's search input */
|
|
3998
|
+
searchPlaceholder?: string;
|
|
3943
3999
|
};
|
|
3944
4000
|
|
|
3945
4001
|
declare const MN_SELECT_CONFIG: InjectionToken<MnSelectUIConfig>;
|
|
4002
|
+
/**
|
|
4003
|
+
* A single-value picker. The trigger opens a `role="listbox"` of {@link MnSelectOption}s;
|
|
4004
|
+
* choosing one sets the value and closes — this is the value-picker twin of the ⋯
|
|
4005
|
+
* command menu mn-dropdown, so it *is* a ControlValueAccessor.
|
|
4006
|
+
*
|
|
4007
|
+
* Presentation mirrors mn-multi-select: one custom field trigger at every size, an
|
|
4008
|
+
* anchored popover on desktop and the shared {@link MnBottomSheet} on mobile (< 640px) —
|
|
4009
|
+
* the same sheet mn-dropdown itself wraps. Both the popover and the sheet host are
|
|
4010
|
+
* portalled to `document.body` so their `position: fixed` anchors to the viewport rather
|
|
4011
|
+
* than any transformed/filtered ancestor (a table cell, a card) — the same root-cause fix
|
|
4012
|
+
* the multi-select applies.
|
|
4013
|
+
*/
|
|
3946
4014
|
declare class MnSelect implements OnInit {
|
|
3947
4015
|
ngControl: NgControl | null;
|
|
3948
4016
|
props: MnSelectProps;
|
|
3949
4017
|
/** Currently selected value */
|
|
3950
4018
|
selectedValue: unknown;
|
|
4019
|
+
isOpen: boolean;
|
|
3951
4020
|
isDisabled: boolean;
|
|
4021
|
+
searchTerm: string;
|
|
3952
4022
|
protected uiConfig: MnSelectUIConfig;
|
|
3953
4023
|
private readonly configService;
|
|
3954
4024
|
private readonly sectionPath;
|
|
3955
4025
|
private readonly explicitInstanceId;
|
|
4026
|
+
private readonly elRef;
|
|
3956
4027
|
private readonly lang;
|
|
3957
4028
|
private readonly destroyRef;
|
|
4029
|
+
private readonly renderer;
|
|
4030
|
+
private readonly cdr;
|
|
4031
|
+
/** Lucide data for the trailing check shown on the selected row. */
|
|
4032
|
+
protected readonly checkIcon: mn_angular_lib.LucideIconData;
|
|
4033
|
+
/** Reference to the trigger element for positioning the dropdown. */
|
|
4034
|
+
triggerRef: ElementRef<HTMLElement>;
|
|
4035
|
+
/** Layout classes for the anchored popover panel. The mobile sheet is rendered by
|
|
4036
|
+
* mn-bottom-sheet instead, so it no longer needs a branch here. */
|
|
4037
|
+
readonly panelClasses = "fixed z-9999 bg-base-100 border border-base-300 rounded-md shadow-lg max-h-60 overflow-auto";
|
|
4038
|
+
/** Layout classes for the invisible click shield rendered under the anchored panel.
|
|
4039
|
+
* One step below the panel's z-index so the panel itself stays clickable, and above
|
|
4040
|
+
* any modal/drawer chrome (which tops out well under 9998). */
|
|
4041
|
+
readonly shieldClasses = "fixed inset-0 z-9998";
|
|
4042
|
+
/** Option count at which the search input auto-enables when `searchable` is unset. */
|
|
4043
|
+
private static readonly DEFAULT_SEARCH_THRESHOLD;
|
|
4044
|
+
/** Tailwind's `sm` breakpoint — below this the panel renders as a bottom sheet.
|
|
4045
|
+
* Kept in step with the same constant in mn-bottom-sheet / mn-multi-select. */
|
|
4046
|
+
private static readonly SHEET_MAX_WIDTH;
|
|
4047
|
+
/** The anchored popover panel currently moved into `document.body`, if any. */
|
|
4048
|
+
private movedPanel;
|
|
4049
|
+
/** The click shield currently moved into `document.body`, if any. */
|
|
4050
|
+
private movedShield;
|
|
4051
|
+
/** The bottom-sheet host, for outside-click tests. The sheet owns its own placement. */
|
|
4052
|
+
private sheetHost;
|
|
4053
|
+
/** Whether the viewport is currently narrow enough for the sheet layout. */
|
|
4054
|
+
private isNarrowViewport;
|
|
4055
|
+
/** Live breakpoint match, so rotating the device re-evaluates the layout. */
|
|
4056
|
+
private sheetMedia;
|
|
4057
|
+
/** The listener registered on `sheetMedia`, retained for teardown. */
|
|
4058
|
+
private sheetMediaListener;
|
|
4059
|
+
/** `document.body`'s inline `overflow` before the sheet locked it, restored on close. */
|
|
4060
|
+
private previousBodyOverflow;
|
|
4061
|
+
/**
|
|
4062
|
+
* The sheet's height (px) captured the moment it opened, before any search. Re-applied
|
|
4063
|
+
* as a `min-height` floor so filtering the option list shorter cannot shrink the sheet
|
|
4064
|
+
* mid-type. Null while anchored or closed, so the popover and desktop path are untouched.
|
|
4065
|
+
*/
|
|
4066
|
+
sheetFloorPx: number | null;
|
|
4067
|
+
/**
|
|
4068
|
+
* Watches the trigger while the panel is open. The panel lives in `document.body`, so it
|
|
4069
|
+
* survives its own trigger being hidden by an ancestor — a wizard step or a tab switched
|
|
4070
|
+
* away with `display: none`. When the trigger stops being visible the panel goes with it.
|
|
4071
|
+
*/
|
|
4072
|
+
private visibilityObserver;
|
|
4073
|
+
/**
|
|
4074
|
+
* Capture-phase scroll listener installed while open. `window:scroll` only fires for the
|
|
4075
|
+
* document scroller, so scrolling an inner container (a modal body, a scrollable card)
|
|
4076
|
+
* would otherwise leave the portalled panel floating at its stale coordinates.
|
|
4077
|
+
*/
|
|
4078
|
+
private scrollCapture;
|
|
4079
|
+
/** Dropdown position calculated from the trigger's bounding rect. */
|
|
4080
|
+
dropdownStyle: {
|
|
4081
|
+
top: string;
|
|
4082
|
+
left: string;
|
|
4083
|
+
width: string;
|
|
4084
|
+
};
|
|
4085
|
+
private onChange;
|
|
4086
|
+
private onTouched;
|
|
3958
4087
|
private readonly builtInErrorMessages;
|
|
3959
4088
|
constructor();
|
|
3960
|
-
|
|
4089
|
+
/**
|
|
4090
|
+
* The dropdown panel element, queried while it is rendered by the `@if` block. The setter
|
|
4091
|
+
* relocates the panel to `document.body` so that its `position: fixed` coordinates resolve
|
|
4092
|
+
* against the viewport rather than any transformed/filtered ancestor (which would otherwise
|
|
4093
|
+
* become the containing block and push the panel to the middle of the screen — also broken
|
|
4094
|
+
* on iOS). Cleanup is handled when the query clears on close/destroy.
|
|
4095
|
+
*/
|
|
4096
|
+
set dropdownRef(ref: ElementRef<HTMLElement> | undefined);
|
|
4097
|
+
/**
|
|
4098
|
+
* The click shield sitting under the anchored panel, portalled alongside it for the same
|
|
4099
|
+
* reason: `position: fixed` must resolve against the viewport, not a transformed ancestor.
|
|
4100
|
+
*/
|
|
4101
|
+
set shieldRef(ref: ElementRef<HTMLElement> | undefined);
|
|
4102
|
+
/**
|
|
4103
|
+
* The bottom-sheet host, kept as a reference for outside-click tests. The sheet relocates
|
|
4104
|
+
* itself to `document.body`, so nothing is moved here. On open its container height is
|
|
4105
|
+
* captured as the sheet's `min-height` floor.
|
|
4106
|
+
*/
|
|
4107
|
+
set sheetRef(ref: ElementRef<HTMLElement> | undefined);
|
|
3961
4108
|
get control(): _angular_forms.AbstractControl<any, any, any> | null;
|
|
4109
|
+
get selectedOption(): MnSelectOption | undefined;
|
|
4110
|
+
/** The label shown in the trigger: the selected option, else the placeholder. */
|
|
4111
|
+
get displayText(): string;
|
|
4112
|
+
/** Trigger text shown while no option is selected. */
|
|
4113
|
+
get placeholderLabel(): string;
|
|
4114
|
+
/** Placeholder and accessible name of the dropdown's search input. */
|
|
4115
|
+
get searchPlaceholderLabel(): string;
|
|
4116
|
+
/** Empty text shown when the search filters every option away. */
|
|
4117
|
+
get noOptionsLabel(): string;
|
|
4118
|
+
/**
|
|
4119
|
+
* Resolves one of the component's own labels, preferring what the caller gave it
|
|
4120
|
+
* and falling back through the config layer, a conventional translation key and
|
|
4121
|
+
* finally a readable English default.
|
|
4122
|
+
*
|
|
4123
|
+
* Mirrors `MnCollectionBase.resolveLabel` and its twin in `MnMultiSelect`. Without
|
|
4124
|
+
* the key step a consumer could only translate these by repeating the same literal
|
|
4125
|
+
* at every call site, and the search box in particular auto-enables on option
|
|
4126
|
+
* count — it appears without anyone asking for it, so it must be translatable
|
|
4127
|
+
* without anyone asking either.
|
|
4128
|
+
*
|
|
4129
|
+
* @param explicit The label the caller passed through `props`, if any.
|
|
4130
|
+
* @param key The conventional translation key to try next.
|
|
4131
|
+
* @param fallback The English text used when neither resolves.
|
|
4132
|
+
* @param configured The value the config layer resolved, if any.
|
|
4133
|
+
* @returns The resolved label.
|
|
4134
|
+
*/
|
|
4135
|
+
private resolveLabel;
|
|
3962
4136
|
get showError(): boolean;
|
|
3963
4137
|
get errorMessages(): string[];
|
|
3964
4138
|
get errorMessage(): string | null;
|
|
3965
4139
|
get resolvedId(): string;
|
|
3966
4140
|
get resolvedName(): string | null;
|
|
3967
|
-
get
|
|
4141
|
+
get triggerClasses(): string;
|
|
4142
|
+
/** Whether the panel should currently render as a bottom sheet. */
|
|
4143
|
+
get isSheet(): boolean;
|
|
4144
|
+
/**
|
|
4145
|
+
* Whether the search input is shown: the explicit `searchable` prop when set, otherwise
|
|
4146
|
+
* auto-enabled once the option count reaches the threshold.
|
|
4147
|
+
*/
|
|
4148
|
+
get isSearchable(): boolean;
|
|
4149
|
+
get filteredOptions(): MnSelectOption[];
|
|
3968
4150
|
ngOnInit(): void;
|
|
3969
4151
|
writeValue(val: unknown): void;
|
|
3970
4152
|
registerOnChange(fn: (val: unknown) => void): void;
|
|
3971
4153
|
registerOnTouched(fn: () => void): void;
|
|
3972
4154
|
setDisabledState(isDisabled: boolean): void;
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
onSelectChange(event: Event): void;
|
|
4155
|
+
toggle(): void;
|
|
4156
|
+
/** Selects an option, notifies the form and closes — a single choice ends the interaction. */
|
|
4157
|
+
selectOption(option: MnSelectOption): void;
|
|
3977
4158
|
isSelected(option: MnSelectOption): boolean;
|
|
4159
|
+
onSearch(term: string | null): void;
|
|
4160
|
+
/**
|
|
4161
|
+
* The single close path. Every trigger (outside click, Escape, scroll, resize, the trigger
|
|
4162
|
+
* being hidden, a choice) funnels through here so the open-only listeners are always torn
|
|
4163
|
+
* down with the panel and never leak.
|
|
4164
|
+
*/
|
|
4165
|
+
close(): void;
|
|
3978
4166
|
handleBlur(): void;
|
|
4167
|
+
/**
|
|
4168
|
+
* Dismisses the anchored panel from a shield click, and stops the event there.
|
|
4169
|
+
*
|
|
4170
|
+
* Swallowing it is the point: the shield spans the viewport, so the click would otherwise
|
|
4171
|
+
* land on whatever the panel was floating over. Inside a modal that is the modal's own
|
|
4172
|
+
* backdrop, and "close the dropdown" would double as "throw away the modal". A first click
|
|
4173
|
+
* that only dismisses the overlay is also how native selects and menus behave.
|
|
4174
|
+
*/
|
|
4175
|
+
onShieldClick(event: Event): void;
|
|
4176
|
+
onDocumentClick(event: Event): void;
|
|
4177
|
+
/** Closes the dropdown on Escape for keyboard accessibility. */
|
|
4178
|
+
onEscape(): void;
|
|
4179
|
+
/**
|
|
4180
|
+
* Closes the dropdown when the page or a scrollable parent is scrolled.
|
|
4181
|
+
*
|
|
4182
|
+
* Skipped for a sheet: it is anchored to the viewport, not to the trigger, so it has no
|
|
4183
|
+
* stale position to escape. Crucially, opening the soft keyboard fires a `resize` on
|
|
4184
|
+
* Android — closing on that would dismiss the sheet the instant search is focused. A
|
|
4185
|
+
* genuine layout switch is handled by the `matchMedia` listener instead.
|
|
4186
|
+
*/
|
|
4187
|
+
onWindowScrollOrResize(): void;
|
|
3979
4188
|
protected isRequired(): boolean;
|
|
3980
|
-
|
|
3981
|
-
|
|
4189
|
+
/**
|
|
4190
|
+
* Tracks the sheet breakpoint through `matchMedia` rather than reading `innerWidth` once,
|
|
4191
|
+
* so rotating the device switches layout instead of leaving a panel positioned for the
|
|
4192
|
+
* previous orientation. An open panel is closed on the switch — its anchored coordinates
|
|
4193
|
+
* and its sheet layout are not interchangeable.
|
|
4194
|
+
*/
|
|
4195
|
+
private startWatchingViewport;
|
|
4196
|
+
/** Tears down the breakpoint listener. Idempotent. */
|
|
4197
|
+
private stopWatchingViewport;
|
|
4198
|
+
/**
|
|
4199
|
+
* Freezes the page behind an open sheet. The previous inline value is captured and restored
|
|
4200
|
+
* verbatim so a surrounding modal that set its own lock is left intact.
|
|
4201
|
+
*/
|
|
4202
|
+
private lockBodyScroll;
|
|
4203
|
+
/** Restores the pre-lock `overflow`. Idempotent. */
|
|
4204
|
+
private unlockBodyScroll;
|
|
4205
|
+
/** Calculates the fixed position for the dropdown based on the trigger element. */
|
|
4206
|
+
private updateDropdownPosition;
|
|
4207
|
+
/**
|
|
4208
|
+
* Starts the open-only watchers: an `IntersectionObserver` on the trigger (closes the panel
|
|
4209
|
+
* as soon as the trigger stops being rendered/visible) and a capture-phase `scroll` listener
|
|
4210
|
+
* (closes it when any ancestor scroller moves under it). Scrolls that originate inside the
|
|
4211
|
+
* panel's own option list are ignored.
|
|
4212
|
+
*/
|
|
4213
|
+
private startWatchingTrigger;
|
|
4214
|
+
/** Tears down the watchers installed by `startWatchingTrigger`. Idempotent. */
|
|
4215
|
+
private stopWatchingTrigger;
|
|
4216
|
+
/**
|
|
4217
|
+
* Records the sheet's opened height as its `min-height` floor. Measured on the next frame
|
|
4218
|
+
* so the read reflects the fully-rendered, unfiltered list (the search box is empty on
|
|
4219
|
+
* open) and never forces a reflow mid change-detection. The floor equals the content height
|
|
4220
|
+
* at that instant, so applying it triggers no resize — it only stops a later, shorter
|
|
4221
|
+
* filtered list from pulling the sheet down.
|
|
4222
|
+
*
|
|
4223
|
+
* `hostEl` is the portalled mn-bottom-sheet host (`display: contents`), so the height is
|
|
4224
|
+
* read from its `.mn-sheet-container` child rather than the host itself.
|
|
4225
|
+
*/
|
|
4226
|
+
private captureSheetFloor;
|
|
4227
|
+
/**
|
|
4228
|
+
* Move an overlay element to `document.body` when it appears, and detach it when the query
|
|
4229
|
+
* clears. Appending to the body root makes the element immune to ancestor
|
|
4230
|
+
* `transform`/`filter`/`will-change`, so `position: fixed` anchors to the viewport — without
|
|
4231
|
+
* this the panel lands mid-screen (and breaks outright on iOS).
|
|
4232
|
+
*
|
|
4233
|
+
* Returns the element now portalled, so the caller can store it. Idempotent and safe to
|
|
4234
|
+
* call with `null`.
|
|
4235
|
+
*/
|
|
4236
|
+
private portal;
|
|
3982
4237
|
private resolveConfig;
|
|
3983
4238
|
private pickErrorKey;
|
|
3984
4239
|
private resolveErrorMessageForKey;
|
|
@@ -4239,10 +4494,14 @@ type MnTranslatable = {
|
|
|
4239
4494
|
*/
|
|
4240
4495
|
type MnConfigValue<T = string> = T | MnTranslatable;
|
|
4241
4496
|
/**
|
|
4242
|
-
*
|
|
4243
|
-
*
|
|
4497
|
+
* Translations for a single locale, as a tree of keys.
|
|
4498
|
+
*
|
|
4499
|
+
* Both shapes resolve through the same dotted lookup: a bundle may nest
|
|
4500
|
+
* (`{ form: { email: { label } } }`), flatten (`{ "form.email.label": … }`), or mix the two.
|
|
4244
4501
|
*/
|
|
4245
|
-
type MnTranslationMap =
|
|
4502
|
+
type MnTranslationMap = {
|
|
4503
|
+
[key: string]: string | MnTranslationMap;
|
|
4504
|
+
};
|
|
4246
4505
|
/**
|
|
4247
4506
|
* All loaded translations keyed by locale code (e.g. "en", "nl", "de").
|
|
4248
4507
|
*/
|
|
@@ -4278,6 +4537,11 @@ declare class MnLanguageService {
|
|
|
4278
4537
|
private _locale$;
|
|
4279
4538
|
private _urlPattern;
|
|
4280
4539
|
private _debug;
|
|
4540
|
+
/**
|
|
4541
|
+
* `Intl.PluralRules` per locale. Cached because {@link translate} runs on every change
|
|
4542
|
+
* detection through the impure `mnTranslate` pipe, and constructing one is not cheap.
|
|
4543
|
+
*/
|
|
4544
|
+
private readonly _pluralRules;
|
|
4281
4545
|
/** Observable of the current active locale. */
|
|
4282
4546
|
readonly locale$: Observable<string>;
|
|
4283
4547
|
/** Current active locale. */
|
|
@@ -4309,8 +4573,42 @@ declare class MnLanguageService {
|
|
|
4309
4573
|
* Falls back to the key itself if no translation is found.
|
|
4310
4574
|
*
|
|
4311
4575
|
* Interpolation replaces `{{paramName}}` with the provided value.
|
|
4576
|
+
*
|
|
4577
|
+
* A `count` param additionally selects the wording that agrees with it: the key is
|
|
4578
|
+
* resolved against its CLDR plural category first (`key` + `One`/`Two`/`Few`/`Many`/
|
|
4579
|
+
* `Zero`), falling back to `key` when that sibling is undefined. Nothing has to opt in —
|
|
4580
|
+
* a key with no sibling behaves exactly as before.
|
|
4581
|
+
*
|
|
4582
|
+
* ```ts
|
|
4583
|
+
* // 'shift.asked' → '{{count}} members are notified'
|
|
4584
|
+
* // 'shift.askedOne' → '{{count}} member is notified'
|
|
4585
|
+
* lang.translate('shift.asked', { count: 3 }); // 3 members are notified
|
|
4586
|
+
* lang.translate('shift.asked', { count: 1 }); // 1 member is notified
|
|
4587
|
+
* ```
|
|
4312
4588
|
*/
|
|
4313
4589
|
translate(key: string, params?: Record<string, string | number>): string;
|
|
4590
|
+
/**
|
|
4591
|
+
* Picks the wording that agrees with a `count` param.
|
|
4592
|
+
*
|
|
4593
|
+
* A key carrying a count resolves against its CLDR plural category first, so
|
|
4594
|
+
* `askedMessage` + `askedMessageOne` render "3 leden krijgen bericht" and "1 lid krijgt
|
|
4595
|
+
* bericht" off the same call. Both languages change the verb as well as the noun, which
|
|
4596
|
+
* is why each form is a whole sentence under its own key rather than a swapped noun.
|
|
4597
|
+
*
|
|
4598
|
+
* Falls back to `key` whenever the sibling is undefined, so a key that never needed a
|
|
4599
|
+
* plural — or an app that has not written one yet — behaves exactly as it did before.
|
|
4600
|
+
* @param map The active locale's translations.
|
|
4601
|
+
* @param key The dot-notated translation key.
|
|
4602
|
+
* @param params The interpolation values, inspected for `count`.
|
|
4603
|
+
* @returns The key to look up: the plural sibling, or `key` itself.
|
|
4604
|
+
*/
|
|
4605
|
+
private resolvePluralKey;
|
|
4606
|
+
/**
|
|
4607
|
+
* The CLDR plural category of a count in the active locale.
|
|
4608
|
+
* @param count The count being quoted.
|
|
4609
|
+
* @returns The category, falling back to English rules for an unusable locale.
|
|
4610
|
+
*/
|
|
4611
|
+
private pluralCategory;
|
|
4314
4612
|
/**
|
|
4315
4613
|
* Helper to retrieve a value from a potentially nested translation map using a dot-notated key.
|
|
4316
4614
|
*/
|
|
@@ -7120,6 +7418,8 @@ declare class MnList<T = unknown> extends MnSelectableCollectionBase<T, ListData
|
|
|
7120
7418
|
protected applyFilter(searchForItems: boolean): void;
|
|
7121
7419
|
/** Accessible name for the scrollable list region. */
|
|
7122
7420
|
get listRegionLabel(): string;
|
|
7421
|
+
/** Label on the header checkbox that selects or clears every visible row. */
|
|
7422
|
+
get selectAllLabel(): string;
|
|
7123
7423
|
static ɵfac: i0.ɵɵFactoryDeclaration<MnList<any>, never>;
|
|
7124
7424
|
static ɵcmp: i0.ɵɵComponentDeclaration<MnList<any>, "mn-list", never, {}, { "itemClick": "itemClick"; }, never, never, true, never>;
|
|
7125
7425
|
}
|
|
@@ -8562,8 +8862,12 @@ declare class MnBreadcrumbs {
|
|
|
8562
8862
|
crumbClick: EventEmitter<MnBreadcrumbItem>;
|
|
8563
8863
|
/** Emits when the fallback "Back" control is activated. */
|
|
8564
8864
|
back: EventEmitter<void>;
|
|
8565
|
-
/**
|
|
8566
|
-
private static readonly
|
|
8865
|
+
/** Conventional key an app defines to translate the Back control's label. */
|
|
8866
|
+
private static readonly BACK_LABEL_KEY;
|
|
8867
|
+
/** Conventional key an app defines to name the navigation landmark. */
|
|
8868
|
+
private static readonly NAV_LABEL_KEY;
|
|
8869
|
+
/** Resolves this component's own labels against the app's bundle. */
|
|
8870
|
+
private readonly lang;
|
|
8567
8871
|
/** Resolved tailwind-variants slot functions for the current size. */
|
|
8568
8872
|
get styles(): {
|
|
8569
8873
|
root: (slotProps?: ({
|
|
@@ -8604,9 +8908,25 @@ declare class MnBreadcrumbs {
|
|
|
8604
8908
|
size?: "sm" | "md" | undefined;
|
|
8605
8909
|
} & tailwind_variants.ClassProp<tailwind_merge.ClassNameValue>) | undefined) => string;
|
|
8606
8910
|
} & {};
|
|
8911
|
+
/**
|
|
8912
|
+
* Accessible name of the `<nav>` landmark.
|
|
8913
|
+
*
|
|
8914
|
+
* A landmark's name is announced verbatim, so leaving it as a hardcoded English
|
|
8915
|
+
* "Breadcrumb" put one English word into every page of a translated app — in the
|
|
8916
|
+
* one place only screen-reader users hear.
|
|
8917
|
+
*/
|
|
8918
|
+
get navLabel(): string;
|
|
8607
8919
|
/** Whether a linkable trail should render (vs the Back fallback). */
|
|
8608
8920
|
get hasTrail(): boolean;
|
|
8609
|
-
/**
|
|
8921
|
+
/**
|
|
8922
|
+
* Text of the Back control, already translated.
|
|
8923
|
+
*
|
|
8924
|
+
* `data.backLabel` is a key (or a literal, which `translate` passes through
|
|
8925
|
+
* unchanged). Without one this falls back to the conventional key and then to
|
|
8926
|
+
* English — never to a raw key: the old default was the bare key `'back'`, which
|
|
8927
|
+
* the template's translate pipe echoed as lowercase "back" in every app that had
|
|
8928
|
+
* not happened to define it.
|
|
8929
|
+
*/
|
|
8610
8930
|
get backLabel(): string;
|
|
8611
8931
|
/** The last crumb is the current page and is rendered as plain text. */
|
|
8612
8932
|
isCurrent(index: number): boolean;
|