@besaitech/ng-design-system 0.0.41 → 0.0.44

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/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { OnDestroy, WritableSignal, OnInit, TemplateRef } from '@angular/core';
2
+ import { OnDestroy, TemplateRef, WritableSignal, OnInit } from '@angular/core';
3
3
  import { SafeHtml } from '@angular/platform-browser';
4
4
  import { ControlValueAccessor, Validator, AbstractControl, ValidationErrors } from '@angular/forms';
5
5
  import * as _besaitech_ng_design_system from '@besaitech/ng-design-system';
@@ -40,6 +40,9 @@ declare const SDS_ICONS: {
40
40
  readonly 'chevron-right': "<path d=\"m9 18 6-6-6-6\"/>";
41
41
  readonly 'chevron-left': "<path d=\"m15 18-6-6 6-6\"/>";
42
42
  readonly 'chevron-down': "<path d=\"m6 9 6 6 6-6\"/>";
43
+ readonly 'chevron-up': "<path d=\"m18 15-6-6-6 6\"/>";
44
+ readonly plus: "<path d=\"M5 12h14\"/><path d=\"M12 5v14\"/>";
45
+ readonly minus: "<path d=\"M5 12h14\"/>";
43
46
  readonly 'chevrons-left': "<path d=\"m11 17-5-5 5-5\"/><path d=\"m18 17-5-5 5-5\"/>";
44
47
  readonly 'chevrons-right': "<path d=\"m6 17 5-5-5-5\"/><path d=\"m13 17 5-5-5-5\"/>";
45
48
  readonly x: "<path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/>";
@@ -96,7 +99,7 @@ type SdsIconSize = 'sm' | 'md' | 'lg' | 'xl';
96
99
  declare class SdsIcon {
97
100
  private readonly sanitizer;
98
101
  /** Icon identifier from the registry. */
99
- readonly name: _angular_core.InputSignal<"chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "search" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "copy" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "filter" | "table" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "menu" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text">;
102
+ readonly name: _angular_core.InputSignal<"filter" | "copy" | "menu" | "search" | "table" | "chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevron-up" | "plus" | "minus" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text">;
100
103
  /** Square size: a pixel number, a numeric string, or a keyword (sm·md·lg·xl). */
101
104
  readonly size: _angular_core.InputSignalWithTransform<number, string | number>;
102
105
  /** Stroke width of the line icon. */
@@ -126,7 +129,7 @@ declare class SdsButton {
126
129
  * most important control.
127
130
  */
128
131
  readonly shape: _angular_core.InputSignal<SdsButtonShape>;
129
- readonly type: _angular_core.InputSignal<"button" | "submit" | "reset">;
132
+ readonly type: _angular_core.InputSignal<"reset" | "submit" | "button">;
130
133
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
131
134
  readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
132
135
  /** Full-width button. */
@@ -188,8 +191,8 @@ declare class SdsInput implements ControlValueAccessor {
188
191
  * is its only name.
189
192
  */
190
193
  readonly clearLabel: _angular_core.InputSignal<string>;
191
- readonly leadingIcon: _angular_core.InputSignal<"chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "search" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "copy" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "filter" | "table" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "menu" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
192
- readonly trailingIcon: _angular_core.InputSignal<"chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "search" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "copy" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "filter" | "table" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "menu" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
194
+ readonly leadingIcon: _angular_core.InputSignal<"filter" | "copy" | "menu" | "search" | "table" | "chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevron-up" | "plus" | "minus" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
195
+ readonly trailingIcon: _angular_core.InputSignal<"filter" | "copy" | "menu" | "search" | "table" | "chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevron-up" | "plus" | "minus" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
193
196
  /**
194
197
  * A CLICKABLE trailing icon, for the affordances that belong to the field itself — password reveal
195
198
  * above all. Distinct from {@link trailingIcon}, which is decorative and explicitly
@@ -199,7 +202,7 @@ declare class SdsInput implements ControlValueAccessor {
199
202
  * Always pair it with {@link trailingActionLabel} — an icon-only button with no accessible name is
200
203
  * unusable by a screen reader. For a toggle, also bind {@link trailingActionPressed}.
201
204
  */
202
- readonly trailingAction: _angular_core.InputSignal<"chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "search" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "copy" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "filter" | "table" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "menu" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
205
+ readonly trailingAction: _angular_core.InputSignal<"filter" | "copy" | "menu" | "search" | "table" | "chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevron-up" | "plus" | "minus" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
203
206
  /** Accessible name for {@link trailingAction}. Translate it in the consuming app. */
204
207
  readonly trailingActionLabel: _angular_core.InputSignal<string>;
205
208
  /** `aria-pressed` for a toggling action (e.g. show/hide password). Null renders no attribute. */
@@ -227,6 +230,147 @@ declare class SdsInput implements ControlValueAccessor {
227
230
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdsInput, "sds-input", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "appearance": { "alias": "appearance"; "required": false; "isSignal": true; }; "shape": { "alias": "shape"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; "leadingIcon": { "alias": "leadingIcon"; "required": false; "isSignal": true; }; "trailingIcon": { "alias": "trailingIcon"; "required": false; "isSignal": true; }; "trailingAction": { "alias": "trailingAction"; "required": false; "isSignal": true; }; "trailingActionLabel": { "alias": "trailingActionLabel"; "required": false; "isSignal": true; }; "trailingActionPressed": { "alias": "trailingActionPressed"; "required": false; "isSignal": true; }; }, { "trailingActionClick": "trailingActionClick"; }, never, never, true, never>;
228
231
  }
229
232
 
233
+ type SdsInputNumberSize = 'sm' | 'md' | 'lg';
234
+ type SdsInputNumberAppearance = 'default' | 'filled';
235
+ /**
236
+ * Formatting behaviour, backed by `Intl.NumberFormat`:
237
+ * - `decimal` — a plain grouped number (`42 723`).
238
+ * - `currency` — a monetary amount; pair with {@link SdsInputNumber.currency} (ISO 4217).
239
+ *
240
+ * For percentages, units or any other affix, use {@link SdsInputNumber.prefix} /
241
+ * {@link SdsInputNumber.suffix} on top of `decimal` — the stored value then stays the plain magnitude.
242
+ */
243
+ type SdsInputNumberMode = 'decimal' | 'currency';
244
+ /** How the currency is shown in `currency` mode — a symbol (€), the ISO code (EUR) or the name (euros). */
245
+ type SdsInputNumberCurrencyDisplay = 'symbol' | 'code' | 'name';
246
+ /**
247
+ * Placement of the increment/decrement spinner buttons:
248
+ * - `stacked` — a two-button column at the trailing edge (chevrons).
249
+ * - `horizontal` — a minus button before and a plus button after the field.
250
+ * - `vertical` — a plus button above and a minus button below the field.
251
+ */
252
+ type SdsInputNumberButtonLayout = 'stacked' | 'horizontal' | 'vertical';
253
+ /**
254
+ * Numeric input with locale-aware formatting, optional currency, prefix/suffix affixes, min/max/step
255
+ * boundaries and spinner buttons — the design-system counterpart of PrimeNG's `InputNumber`.
256
+ *
257
+ * The value is a `number | null` bound through ControlValueAccessor, so it works with reactive forms
258
+ * or `[(ngModel)]`: `<sds-input-number [(ngModel)]="amount" mode="currency" currency="EUR" />`.
259
+ *
260
+ * The field formats **live as you type**: the currency symbol, grouping separators and prefix/suffix
261
+ * stay visible on every keystroke, and the caret is kept where it belongs. The value is clamped to
262
+ * {@link min}/{@link max} on blur and on every spinner step; ArrowUp / ArrowDown also step it.
263
+ */
264
+ declare class SdsInputNumber implements ControlValueAccessor {
265
+ readonly inputId: string;
266
+ private readonly fieldRef;
267
+ readonly label: _angular_core.InputSignal<string>;
268
+ /** Accessible name used when no visible [label] is provided. */
269
+ readonly ariaLabel: _angular_core.InputSignal<string>;
270
+ readonly placeholder: _angular_core.InputSignal<string>;
271
+ readonly hint: _angular_core.InputSignal<string>;
272
+ readonly error: _angular_core.InputSignal<string>;
273
+ readonly size: _angular_core.InputSignal<SdsInputNumberSize>;
274
+ /** `filled` is a borderless field on a muted ground; `default` is the bordered white field. */
275
+ readonly appearance: _angular_core.InputSignal<SdsInputNumberAppearance>;
276
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
277
+ /** Read-only: the value is shown and selectable but cannot be typed or stepped. */
278
+ readonly readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
279
+ readonly mode: _angular_core.InputSignal<SdsInputNumberMode>;
280
+ /** BCP 47 locale for grouping/decimal symbols (e.g. `fr-FR`). Empty follows the runtime locale. */
281
+ readonly locale: _angular_core.InputSignal<string>;
282
+ /** ISO 4217 code, required when {@link mode} is `currency` (e.g. `EUR`, `USD`). */
283
+ readonly currency: _angular_core.InputSignal<string>;
284
+ readonly currencyDisplay: _angular_core.InputSignal<SdsInputNumberCurrencyDisplay>;
285
+ /** Thousands/grouping separators. */
286
+ readonly useGrouping: _angular_core.InputSignalWithTransform<boolean, unknown>;
287
+ readonly minFractionDigits: _angular_core.InputSignal<number | null>;
288
+ readonly maxFractionDigits: _angular_core.InputSignal<number | null>;
289
+ /** Text shown before the value (e.g. `↑ `). */
290
+ readonly prefix: _angular_core.InputSignal<string>;
291
+ /** Text shown after the value (e.g. ` kg`, `%`). */
292
+ readonly suffix: _angular_core.InputSignal<string>;
293
+ readonly min: _angular_core.InputSignal<number | null>;
294
+ readonly max: _angular_core.InputSignal<number | null>;
295
+ readonly step: _angular_core.InputSignalWithTransform<number, unknown>;
296
+ /** Show the increment/decrement spinner buttons. */
297
+ readonly showButtons: _angular_core.InputSignalWithTransform<boolean, unknown>;
298
+ readonly buttonLayout: _angular_core.InputSignal<SdsInputNumberButtonLayout>;
299
+ /** Override the increment button icon (defaults: chevron-up when stacked, plus otherwise). */
300
+ readonly incrementIcon: _angular_core.InputSignal<"filter" | "copy" | "menu" | "search" | "table" | "chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevron-up" | "plus" | "minus" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
301
+ /** Override the decrement button icon (defaults: chevron-down when stacked, minus otherwise). */
302
+ readonly decrementIcon: _angular_core.InputSignal<"filter" | "copy" | "menu" | "search" | "table" | "chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevron-up" | "plus" | "minus" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
303
+ /** Allow an empty (null) value. When false, blurring an empty field falls back to {@link min} or 0. */
304
+ readonly allowEmpty: _angular_core.InputSignalWithTransform<boolean, unknown>;
305
+ readonly clearable: _angular_core.InputSignalWithTransform<boolean, unknown>;
306
+ /**
307
+ * Accessible names for the icon-only controls. French defaults so existing consumers are unchanged;
308
+ * translate them in a multi-language app.
309
+ */
310
+ readonly clearLabel: _angular_core.InputSignal<string>;
311
+ readonly incrementLabel: _angular_core.InputSignal<string>;
312
+ readonly decrementLabel: _angular_core.InputSignal<string>;
313
+ /** The committed numeric value (driven by CVA + user input). */
314
+ protected readonly value: _angular_core.WritableSignal<number | null>;
315
+ private readonly cvaDisabled;
316
+ protected readonly isDisabled: _angular_core.Signal<boolean>;
317
+ protected readonly describedBy: _angular_core.Signal<string | null>;
318
+ protected readonly clearVisible: _angular_core.Signal<boolean>;
319
+ protected readonly incrementIconName: _angular_core.Signal<"filter" | "copy" | "menu" | "search" | "table" | "chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevron-up" | "plus" | "minus" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text">;
320
+ protected readonly decrementIconName: _angular_core.Signal<"filter" | "copy" | "menu" | "search" | "table" | "chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevron-up" | "plus" | "minus" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text">;
321
+ protected readonly canIncrement: _angular_core.Signal<boolean>;
322
+ protected readonly canDecrement: _angular_core.Signal<boolean>;
323
+ /** Locale grouping/decimal separators, derived from Intl so parsing matches formatting. */
324
+ private readonly separators;
325
+ /** Base Intl options (style/currency/grouping) without any fraction-digit constraints. */
326
+ private baseOptions;
327
+ private readonly committedOptions;
328
+ /** The most fraction digits the field will keep — the resolved Intl maximum (2 for USD, 0 for JPY…). */
329
+ private readonly maxFrac;
330
+ protected readonly wrapperClasses: _angular_core.Signal<string>;
331
+ protected readonly fieldCellClasses: _angular_core.Signal<string>;
332
+ protected readonly inputClasses: _angular_core.Signal<string>;
333
+ private readonly buttonBase;
334
+ protected readonly edgeButtonClasses: _angular_core.Signal<string>;
335
+ protected readonly stackedButtonClasses: _angular_core.Signal<string>;
336
+ constructor();
337
+ private isActive;
338
+ /** Paint the committed value into the field imperatively (used by spin/clear/blur). */
339
+ private paintCommitted;
340
+ /** Format a committed value with the configured min/max fraction digits (used at rest and on blur). */
341
+ private format;
342
+ /**
343
+ * Format a partially-typed value, keeping exactly the fraction digits the user has entered (so
344
+ * trailing zeros and a lone decimal separator survive) while still grouping the integer part and
345
+ * showing the currency symbol / affixes.
346
+ */
347
+ private formatLive;
348
+ private toNumber;
349
+ /** Pull the sign / integer / fraction fragments out of a formatted, partially-typed string. */
350
+ private parseInput;
351
+ /** Characters that "carry meaning" for caret placement (digits, minus, the decimal separator). */
352
+ private isSignificant;
353
+ private significantBefore;
354
+ /** The caret index in `formatted` that sits just after `target` significant characters. */
355
+ private caretAfter;
356
+ private clamp;
357
+ /** Trim binary-float drift (0.1 + 0.2) back to a clean decimal. */
358
+ private tidy;
359
+ protected onInput(event: Event): void;
360
+ protected onKeydown(event: KeyboardEvent): void;
361
+ protected onBlur(): void;
362
+ protected spin(direction: 1 | -1): void;
363
+ protected clear(): void;
364
+ private onChange;
365
+ protected onTouched: () => void;
366
+ writeValue(value: number | null): void;
367
+ registerOnChange(fn: (value: number | null) => void): void;
368
+ registerOnTouched(fn: () => void): void;
369
+ setDisabledState(isDisabled: boolean): void;
370
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdsInputNumber, never>;
371
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdsInputNumber, "sds-input-number", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "appearance": { "alias": "appearance"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "currency": { "alias": "currency"; "required": false; "isSignal": true; }; "currencyDisplay": { "alias": "currencyDisplay"; "required": false; "isSignal": true; }; "useGrouping": { "alias": "useGrouping"; "required": false; "isSignal": true; }; "minFractionDigits": { "alias": "minFractionDigits"; "required": false; "isSignal": true; }; "maxFractionDigits": { "alias": "maxFractionDigits"; "required": false; "isSignal": true; }; "prefix": { "alias": "prefix"; "required": false; "isSignal": true; }; "suffix": { "alias": "suffix"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "showButtons": { "alias": "showButtons"; "required": false; "isSignal": true; }; "buttonLayout": { "alias": "buttonLayout"; "required": false; "isSignal": true; }; "incrementIcon": { "alias": "incrementIcon"; "required": false; "isSignal": true; }; "decrementIcon": { "alias": "decrementIcon"; "required": false; "isSignal": true; }; "allowEmpty": { "alias": "allowEmpty"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; "incrementLabel": { "alias": "incrementLabel"; "required": false; "isSignal": true; }; "decrementLabel": { "alias": "decrementLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
372
+ }
373
+
230
374
  /** A translatable string held per language code — e.g. `{ fr: 'Titre', nl: 'Titel' }`. */
231
375
  type SdsLocalizedValue = Record<string, string>;
232
376
  type SdsLocalizedInputSize = 'sm' | 'md' | 'lg';
@@ -437,9 +581,9 @@ declare class SdsToggleSwitch implements ControlValueAccessor {
437
581
  /** Value emitted/stored when the switch is off. */
438
582
  readonly falseValue: _angular_core.InputSignal<unknown>;
439
583
  /** Icon shown on the knob when checked. */
440
- readonly onIcon: _angular_core.InputSignal<"chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "search" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "copy" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "filter" | "table" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "menu" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
584
+ readonly onIcon: _angular_core.InputSignal<"filter" | "copy" | "menu" | "search" | "table" | "chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevron-up" | "plus" | "minus" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
441
585
  /** Icon shown on the knob when unchecked. */
442
- readonly offIcon: _angular_core.InputSignal<"chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "search" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "copy" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "filter" | "table" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "menu" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
586
+ readonly offIcon: _angular_core.InputSignal<"filter" | "copy" | "menu" | "search" | "table" | "chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevron-up" | "plus" | "minus" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
443
587
  readonly hint: _angular_core.InputSignal<string>;
444
588
  readonly error: _angular_core.InputSignal<string>;
445
589
  /**
@@ -813,6 +957,94 @@ declare class SdsDatePicker implements ControlValueAccessor, OnDestroy {
813
957
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdsDatePicker, "sds-date-picker", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "firstDayOfWeek": { "alias": "firstDayOfWeek"; "required": false; "isSignal": true; }; "locale": { "alias": "locale"; "required": false; "isSignal": true; }; "inline": { "alias": "inline"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "showActions": { "alias": "showActions"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "showTime": { "alias": "showTime"; "required": false; "isSignal": true; }; "format": { "alias": "format"; "required": false; "isSignal": true; }; "timeLabel": { "alias": "timeLabel"; "required": false; "isSignal": true; }; "hoursLabel": { "alias": "hoursLabel"; "required": false; "isSignal": true; }; "minutesLabel": { "alias": "minutesLabel"; "required": false; "isSignal": true; }; "doneLabel": { "alias": "doneLabel"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; "openCalendarLabel": { "alias": "openCalendarLabel"; "required": false; "isSignal": true; }; "closeCalendarLabel": { "alias": "closeCalendarLabel"; "required": false; "isSignal": true; }; "panelLabel": { "alias": "panelLabel"; "required": false; "isSignal": true; }; "calendarLabel": { "alias": "calendarLabel"; "required": false; "isSignal": true; }; "previousLabel": { "alias": "previousLabel"; "required": false; "isSignal": true; }; "nextLabel": { "alias": "nextLabel"; "required": false; "isSignal": true; }; "todayActionLabel": { "alias": "todayActionLabel"; "required": false; "isSignal": true; }; "clearActionLabel": { "alias": "clearActionLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
814
958
  }
815
959
 
960
+ /**
961
+ * Context handed to a custom option template. Lets consumers destructure with
962
+ * `let-option`, `let-selected="selected"`, `let-label="label"`, etc., with full
963
+ * type inference (see {@link SdsSelectOption.ngTemplateContextGuard}).
964
+ */
965
+ interface SdsSelectOptionContext {
966
+ /** Same as {@link option} — enables the implicit `let-option` binding. Typed `any` so consumer templates
967
+ * can read their own option fields (e.g. `option.color`) without casting. */
968
+ $implicit: any;
969
+ /** The raw option object (or primitive) from the `options` array. */
970
+ option: any;
971
+ /** The resolved display label (via optionLabel). */
972
+ label: string;
973
+ /** The resolved option value (via optionValue). */
974
+ value: unknown;
975
+ /** Whether this option is currently selected. */
976
+ selected: boolean;
977
+ /** Whether this option is disabled. */
978
+ disabled: boolean;
979
+ /** Zero-based index within the currently displayed (filtered) options. */
980
+ index: number;
981
+ }
982
+ /**
983
+ * Supplies a custom template for each option row (and the selected value shown
984
+ * in the trigger) of an `<sds-select>` / `<sds-multi-select>`. Use as a
985
+ * structural template projected into the select:
986
+ *
987
+ * @example
988
+ * <sds-select [options]="categories" optionLabel="name" optionValue="id" [(ngModel)]="catId">
989
+ * <ng-template sdsSelectOption let-option let-selected="selected">
990
+ * <span class="dot" [style.background]="option.color"></span>
991
+ * <span class="truncate">{{ option.name }}</span>
992
+ * </ng-template>
993
+ * </sds-select>
994
+ */
995
+ declare class SdsSelectOption {
996
+ /** The wrapped template, rendered by the host select via ngTemplateOutlet. */
997
+ readonly template: TemplateRef<SdsSelectOptionContext>;
998
+ /** Lets the compiler type-check `let-*` bindings against SdsSelectOptionContext. */
999
+ static ngTemplateContextGuard(_dir: SdsSelectOption, _ctx: unknown): _ctx is SdsSelectOptionContext;
1000
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdsSelectOption, never>;
1001
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SdsSelectOption, "ng-template[sdsSelectOption]", never, {}, {}, never, never, true, never>;
1002
+ }
1003
+ /** Context handed to a custom empty-state template. */
1004
+ interface SdsSelectEmptyContext {
1005
+ /** Same as {@link filterText} — enables the implicit `let-filterText` binding. */
1006
+ $implicit: string;
1007
+ /** The current filter query (empty when the field isn't filterable or is blank). */
1008
+ filterText: string;
1009
+ }
1010
+ /**
1011
+ * Supplies a custom template shown in place of the default "no results" message
1012
+ * when a select has no (matching) options.
1013
+ *
1014
+ * @example
1015
+ * <ng-template sdsSelectEmpty let-q>No category matches "{{ q }}".</ng-template>
1016
+ */
1017
+ declare class SdsSelectEmpty {
1018
+ readonly template: TemplateRef<SdsSelectEmptyContext>;
1019
+ static ngTemplateContextGuard(_dir: SdsSelectEmpty, _ctx: unknown): _ctx is SdsSelectEmptyContext;
1020
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdsSelectEmpty, never>;
1021
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SdsSelectEmpty, "ng-template[sdsSelectEmpty]", never, {}, {}, never, never, true, never>;
1022
+ }
1023
+ /** Context handed to a custom footer template. */
1024
+ interface SdsSelectFooterContext {
1025
+ /** Same as {@link filterText} — enables the implicit `let-filterText` binding. */
1026
+ $implicit: string;
1027
+ /** The current filter query. */
1028
+ filterText: string;
1029
+ /** Closes the open panel — handy for a footer action (e.g. "+ New…"). */
1030
+ close: () => void;
1031
+ }
1032
+ /**
1033
+ * Supplies a custom sticky footer rendered below the option list — e.g. a
1034
+ * "+ Create new" action. The `close` context callback dismisses the panel.
1035
+ *
1036
+ * @example
1037
+ * <ng-template sdsSelectFooter let-close="close">
1038
+ * <button (click)="createCategory(); close()">+ New category</button>
1039
+ * </ng-template>
1040
+ */
1041
+ declare class SdsSelectFooter {
1042
+ readonly template: TemplateRef<SdsSelectFooterContext>;
1043
+ static ngTemplateContextGuard(_dir: SdsSelectFooter, _ctx: unknown): _ctx is SdsSelectFooterContext;
1044
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdsSelectFooter, never>;
1045
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<SdsSelectFooter, "ng-template[sdsSelectFooter]", never, {}, {}, never, never, true, never>;
1046
+ }
1047
+
816
1048
  type SdsSelectSize = 'sm' | 'md' | 'lg';
817
1049
  /** Field skin. `filled` is borderless on a muted ground (to sit inside a page, matching sds-input's
818
1050
  * filled appearance); `on-brand` is tuned for a dark surface. */
@@ -821,6 +1053,8 @@ interface NormOption$1 {
821
1053
  label: string;
822
1054
  value: unknown;
823
1055
  disabled: boolean;
1056
+ /** The original option (object or primitive), passed to a custom option template. */
1057
+ raw: unknown;
824
1058
  }
825
1059
  /**
826
1060
  * Single-select dropdown. Options may be primitives or objects (configure via
@@ -832,9 +1066,25 @@ interface NormOption$1 {
832
1066
  * key; otherwise selection matching falls back to reference equality (a written
833
1067
  * copy of an option will not match).
834
1068
  *
1069
+ * Options render as plain text by default. To render richer options (an icon,
1070
+ * an avatar, a two-line row…) project template directives — the same content
1071
+ * also renders in the trigger for the selected value:
1072
+ * - `<ng-template sdsSelectOption let-option>` — one option row (see {@link SdsSelectOption});
1073
+ * context: the raw `option` (implicit), plus `label`, `value`, `selected`, `disabled`, `index`.
1074
+ * - `<ng-template sdsSelectEmpty let-query>` — replaces the "no results" message (see {@link SdsSelectEmpty}).
1075
+ * - `<ng-template sdsSelectFooter let-close="close">` — a sticky footer action, e.g. "+ New…"
1076
+ * (see {@link SdsSelectFooter}); `close()` dismisses the panel.
1077
+ *
835
1078
  * @example
836
1079
  * <sds-select [options]="services" optionLabel="name" optionValue="id"
837
1080
  * placeholder="Choisir un service" [(ngModel)]="serviceId" filter clearable />
1081
+ *
1082
+ * @example
1083
+ * <sds-select [options]="categories" optionLabel="name" optionValue="id" [(ngModel)]="categoryId">
1084
+ * <ng-template sdsSelectOption let-option>
1085
+ * <span class="dot" [style.background]="option.color"></span> {{ option.name }}
1086
+ * </ng-template>
1087
+ * </sds-select>
838
1088
  */
839
1089
  declare class SdsSelect implements ControlValueAccessor, OnDestroy {
840
1090
  private readonly host;
@@ -859,6 +1109,12 @@ declare class SdsSelect implements ControlValueAccessor, OnDestroy {
859
1109
  readonly filter: _angular_core.InputSignalWithTransform<boolean, unknown>;
860
1110
  readonly filterPlaceholder: _angular_core.InputSignal<string>;
861
1111
  readonly emptyMessage: _angular_core.InputSignal<string>;
1112
+ /** Optional projected `<ng-template sdsSelectOption>` — custom option + selected-value rendering. */
1113
+ protected readonly optionTpl: _angular_core.Signal<SdsSelectOption | undefined>;
1114
+ /** Optional projected `<ng-template sdsSelectEmpty>` — custom no-results content. */
1115
+ protected readonly emptyTpl: _angular_core.Signal<SdsSelectEmpty | undefined>;
1116
+ /** Optional projected `<ng-template sdsSelectFooter>` — a sticky footer action. */
1117
+ protected readonly footerTpl: _angular_core.Signal<SdsSelectFooter | undefined>;
862
1118
  protected readonly value: _angular_core.WritableSignal<unknown>;
863
1119
  protected readonly open: _angular_core.WritableSignal<boolean>;
864
1120
  protected readonly filterText: _angular_core.WritableSignal<string>;
@@ -876,6 +1132,16 @@ declare class SdsSelect implements ControlValueAccessor, OnDestroy {
876
1132
  protected readonly activeDescId: _angular_core.Signal<string | null>;
877
1133
  protected readonly wrapperClasses: _angular_core.Signal<string>;
878
1134
  private norm;
1135
+ /** Context for a projected option template (an option row). */
1136
+ protected optionContext(opt: NormOption$1, index: number): SdsSelectOptionContext;
1137
+ /** Context for the option template reused in the trigger to render the selected value. */
1138
+ protected readonly triggerContext: _angular_core.Signal<SdsSelectOptionContext | null>;
1139
+ /** Context for a projected footer template. */
1140
+ protected footerContext(): {
1141
+ $implicit: string;
1142
+ filterText: string;
1143
+ close: () => void;
1144
+ };
879
1145
  private equals;
880
1146
  protected isSelected(v: unknown): boolean;
881
1147
  protected optionId(i: number): string;
@@ -914,7 +1180,7 @@ declare class SdsSelect implements ControlValueAccessor, OnDestroy {
914
1180
  registerOnTouched(fn: () => void): void;
915
1181
  setDisabledState(isDisabled: boolean): void;
916
1182
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdsSelect, never>;
917
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdsSelect, "sds-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "optionLabel": { "alias": "optionLabel"; "required": false; "isSignal": true; }; "optionValue": { "alias": "optionValue"; "required": false; "isSignal": true; }; "optionDisabled": { "alias": "optionDisabled"; "required": false; "isSignal": true; }; "dataKey": { "alias": "dataKey"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "appearance": { "alias": "appearance"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; "filterPlaceholder": { "alias": "filterPlaceholder"; "required": false; "isSignal": true; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1183
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdsSelect, "sds-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "optionLabel": { "alias": "optionLabel"; "required": false; "isSignal": true; }; "optionValue": { "alias": "optionValue"; "required": false; "isSignal": true; }; "optionDisabled": { "alias": "optionDisabled"; "required": false; "isSignal": true; }; "dataKey": { "alias": "dataKey"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "appearance": { "alias": "appearance"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; "filterPlaceholder": { "alias": "filterPlaceholder"; "required": false; "isSignal": true; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; "isSignal": true; }; }, {}, ["optionTpl", "emptyTpl", "footerTpl"], never, true, never>;
918
1184
  }
919
1185
 
920
1186
  type SdsMultiSelectSize = 'sm' | 'md' | 'lg';
@@ -923,6 +1189,8 @@ interface NormOption {
923
1189
  label: string;
924
1190
  value: unknown;
925
1191
  disabled: boolean;
1192
+ /** The original option (object or primitive), passed to a custom option template. */
1193
+ raw: unknown;
926
1194
  }
927
1195
  /**
928
1196
  * Multi-select dropdown (value is an array). Options may be primitives or
@@ -934,9 +1202,24 @@ interface NormOption {
934
1202
  * For object options, set [optionValue] or [dataKey] so written values match by
935
1203
  * key; otherwise matching falls back to reference equality.
936
1204
  *
1205
+ * Project template directives to customise the panel:
1206
+ * - `<ng-template sdsSelectOption let-option>` — the content of each option row, after its
1207
+ * checkbox (see {@link SdsSelectOption}); context: the raw `option` (implicit), plus `label`,
1208
+ * `value`, `selected`, `disabled`, `index`.
1209
+ * - `<ng-template sdsSelectEmpty let-query>` — replaces the "no results" message (see {@link SdsSelectEmpty}).
1210
+ * - `<ng-template sdsSelectFooter let-close="close">` — a sticky footer action (see {@link SdsSelectFooter});
1211
+ * `close()` dismisses the panel.
1212
+ *
937
1213
  * @example
938
1214
  * <sds-multi-select [options]="services" optionLabel="name" optionValue="code"
939
1215
  * display="chip" filter [(ngModel)]="codes" />
1216
+ *
1217
+ * @example
1218
+ * <sds-multi-select [options]="tags" optionLabel="name" optionValue="id" [(ngModel)]="tagIds">
1219
+ * <ng-template sdsSelectOption let-option>
1220
+ * <span class="dot" [style.background]="option.color"></span> {{ option.name }}
1221
+ * </ng-template>
1222
+ * </sds-multi-select>
940
1223
  */
941
1224
  declare class SdsMultiSelect implements ControlValueAccessor, OnDestroy {
942
1225
  private readonly host;
@@ -964,6 +1247,12 @@ declare class SdsMultiSelect implements ControlValueAccessor, OnDestroy {
964
1247
  readonly filter: _angular_core.InputSignalWithTransform<boolean, unknown>;
965
1248
  readonly filterPlaceholder: _angular_core.InputSignal<string>;
966
1249
  readonly emptyMessage: _angular_core.InputSignal<string>;
1250
+ /** Optional projected `<ng-template sdsSelectOption>` — custom option-row rendering. */
1251
+ protected readonly optionTpl: _angular_core.Signal<SdsSelectOption | undefined>;
1252
+ /** Optional projected `<ng-template sdsSelectEmpty>` — custom no-results content. */
1253
+ protected readonly emptyTpl: _angular_core.Signal<SdsSelectEmpty | undefined>;
1254
+ /** Optional projected `<ng-template sdsSelectFooter>` — a sticky footer action. */
1255
+ protected readonly footerTpl: _angular_core.Signal<SdsSelectFooter | undefined>;
967
1256
  protected readonly value: _angular_core.WritableSignal<unknown[]>;
968
1257
  protected readonly open: _angular_core.WritableSignal<boolean>;
969
1258
  protected readonly filterText: _angular_core.WritableSignal<string>;
@@ -986,6 +1275,14 @@ declare class SdsMultiSelect implements ControlValueAccessor, OnDestroy {
986
1275
  protected readonly activeDescId: _angular_core.Signal<string | null>;
987
1276
  protected readonly wrapperClasses: _angular_core.Signal<string>;
988
1277
  private norm;
1278
+ /** Context for a projected option template (an option row). */
1279
+ protected optionContext(opt: NormOption, index: number): SdsSelectOptionContext;
1280
+ /** Context for a projected footer template. */
1281
+ protected footerContext(): {
1282
+ $implicit: string;
1283
+ filterText: string;
1284
+ close: () => void;
1285
+ };
989
1286
  private equals;
990
1287
  protected isSelected(v: unknown): boolean;
991
1288
  protected optionId(i: number): string;
@@ -1027,7 +1324,7 @@ declare class SdsMultiSelect implements ControlValueAccessor, OnDestroy {
1027
1324
  registerOnTouched(fn: () => void): void;
1028
1325
  setDisabledState(isDisabled: boolean): void;
1029
1326
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<SdsMultiSelect, never>;
1030
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdsMultiSelect, "sds-multi-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "optionLabel": { "alias": "optionLabel"; "required": false; "isSignal": true; }; "optionValue": { "alias": "optionValue"; "required": false; "isSignal": true; }; "optionDisabled": { "alias": "optionDisabled"; "required": false; "isSignal": true; }; "dataKey": { "alias": "dataKey"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "display": { "alias": "display"; "required": false; "isSignal": true; }; "maxSelectedLabels": { "alias": "maxSelectedLabels"; "required": false; "isSignal": true; }; "selectedItemsLabel": { "alias": "selectedItemsLabel"; "required": false; "isSignal": true; }; "showToggleAll": { "alias": "showToggleAll"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; "filterPlaceholder": { "alias": "filterPlaceholder"; "required": false; "isSignal": true; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1327
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdsMultiSelect, "sds-multi-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "optionLabel": { "alias": "optionLabel"; "required": false; "isSignal": true; }; "optionValue": { "alias": "optionValue"; "required": false; "isSignal": true; }; "optionDisabled": { "alias": "optionDisabled"; "required": false; "isSignal": true; }; "dataKey": { "alias": "dataKey"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "display": { "alias": "display"; "required": false; "isSignal": true; }; "maxSelectedLabels": { "alias": "maxSelectedLabels"; "required": false; "isSignal": true; }; "selectedItemsLabel": { "alias": "selectedItemsLabel"; "required": false; "isSignal": true; }; "showToggleAll": { "alias": "showToggleAll"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; "filterPlaceholder": { "alias": "filterPlaceholder"; "required": false; "isSignal": true; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; "isSignal": true; }; }, {}, ["optionTpl", "emptyTpl", "footerTpl"], never, true, never>;
1031
1328
  }
1032
1329
 
1033
1330
  /**
@@ -2009,7 +2306,7 @@ declare class SdsNavGroup {
2009
2306
  /** Turn the label into an expand/collapse control. */
2010
2307
  readonly collapsible: _angular_core.InputSignalWithTransform<boolean, unknown>;
2011
2308
  /** Icon for a collapsible header, so it reads at the same weight as the items it sits among. */
2012
- readonly icon: _angular_core.InputSignal<"chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "search" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "copy" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "filter" | "table" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "menu" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
2309
+ readonly icon: _angular_core.InputSignal<"filter" | "copy" | "menu" | "search" | "table" | "chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevron-up" | "plus" | "minus" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
2013
2310
  /**
2014
2311
  * URL prefix owned by this group, e.g. `/payments`. While the active route starts with it the
2015
2312
  * group counts as active and opens itself — unless the person has explicitly toggled it since.
@@ -2061,7 +2358,7 @@ declare class SdsNavGroup {
2061
2358
  */
2062
2359
  declare class SdsNavItem {
2063
2360
  protected readonly store: SidebarStore;
2064
- readonly icon: _angular_core.InputSignal<"chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "search" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "copy" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "filter" | "table" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "menu" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
2361
+ readonly icon: _angular_core.InputSignal<"filter" | "copy" | "menu" | "search" | "table" | "chart-column" | "clipboard-list" | "credit-card" | "external-link" | "languages" | "megaphone" | "monitor" | "store" | "user-round" | "home" | "user-plus" | "user-check" | "hand" | "users" | "bike" | "building-2" | "package" | "package-plus" | "package-open" | "rotate-ccw" | "bar-chart-3" | "log-out" | "panel-left-close" | "panel-left-open" | "panel-left" | "calendar" | "chevron-right" | "chevron-left" | "chevron-down" | "chevron-up" | "plus" | "minus" | "chevrons-left" | "chevrons-right" | "x" | "check" | "alert-circle" | "info" | "type" | "tag" | "square" | "circle-user" | "layout-grid" | "panels-top-left" | "panel-top" | "rows-3" | "book-open" | "palette" | "bell" | "phone" | "settings" | "align-left" | "toggle-left" | "arrow-up" | "arrow-down" | "chevrons-up-down" | "eye" | "eye-off" | "user" | "check-circle" | "arrows-clockwise" | "file-text" | "hash" | "map-pin" | "inbox" | "arrow-right" | "refresh-cw" | "loader-circle" | "bug" | "scroll-text" | null>;
2065
2362
  readonly label: _angular_core.InputSignal<string>;
2066
2363
  /** Router link target; when null, the item behaves as a button. */
2067
2364
  readonly link: _angular_core.InputSignal<string | unknown[] | null>;
@@ -2075,5 +2372,5 @@ declare class SdsNavItem {
2075
2372
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<SdsNavItem, "sds-nav-item", never, { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "link": { "alias": "link"; "required": false; "isSignal": true; }; "exact": { "alias": "exact"; "required": false; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; }, { "select": "select"; }, never, never, true, never>;
2076
2373
  }
2077
2374
 
2078
- export { SDS_ICONS, SDS_PHONE_COUNTRIES, SdsAccordion, SdsAccordionContent, SdsAccordionHeader, SdsAccordionPanel, SdsAccordionStore, SdsAvatar, SdsBadge, SdsButton, SdsCalendar, SdsCard, SdsCheckbox, SdsDatePicker, SdsIcon, SdsInput, SdsLocalizedInput, SdsMultiSelect, SdsNavGroup, SdsNavItem, SdsOtpInput, SdsPaginator, SdsPhoneInput, SdsSelect, SdsShell, SdsSidebar, SdsTab, SdsTabList, SdsTabPanel, SdsTabPanels, SdsTable, SdsTableCell, SdsTableRowExpansion, SdsTabs, SdsTabsStore, SdsTextarea, SdsToastHost, SdsToastService, SdsToggleSwitch, SdsTopbar, SidebarStore, addDays, addMonths, addMonthsKeepDay, formatDdMmYyyy, formatHhMm, isOutOfRange, isSameDay, isoDay, pad2, sdsFormatNational, sdsMatchDialCode, sdsNormalizeSignificant, startOfDay, startOfMonth };
2079
- export type { SdsAccordionActive, SdsAccordionValue, SdsAvatarStatus, SdsBadgeSize, SdsBadgeVariant, SdsButtonShape, SdsButtonSize, SdsButtonVariant, SdsCardVariant, SdsCheckboxSize, SdsDatePickerSize, SdsIconName, SdsIconSize, SdsInputAppearance, SdsInputShape, SdsInputSize, SdsInputType, SdsLocalizedInputSize, SdsLocalizedValue, SdsMultiSelectDisplay, SdsMultiSelectSize, SdsOtpInputSize, SdsPaginatorSize, SdsPaginatorState, SdsPhoneCountry, SdsPhoneInputSize, SdsPhoneValue, SdsSelectAppearance, SdsSelectSize, SdsSortOrder, SdsTabValue, SdsTableCellContext, SdsTableColumn, SdsTableLazyEvent, SdsTableRowExpansionContext, SdsTableSize, SdsTableSortEvent, SdsTextareaResize, SdsTextareaSize, SdsToast, SdsToastKind, SdsToggleSwitchSize, SdsTopbarAppearance };
2375
+ export { SDS_ICONS, SDS_PHONE_COUNTRIES, SdsAccordion, SdsAccordionContent, SdsAccordionHeader, SdsAccordionPanel, SdsAccordionStore, SdsAvatar, SdsBadge, SdsButton, SdsCalendar, SdsCard, SdsCheckbox, SdsDatePicker, SdsIcon, SdsInput, SdsInputNumber, SdsLocalizedInput, SdsMultiSelect, SdsNavGroup, SdsNavItem, SdsOtpInput, SdsPaginator, SdsPhoneInput, SdsSelect, SdsSelectEmpty, SdsSelectFooter, SdsSelectOption, SdsShell, SdsSidebar, SdsTab, SdsTabList, SdsTabPanel, SdsTabPanels, SdsTable, SdsTableCell, SdsTableRowExpansion, SdsTabs, SdsTabsStore, SdsTextarea, SdsToastHost, SdsToastService, SdsToggleSwitch, SdsTopbar, SidebarStore, addDays, addMonths, addMonthsKeepDay, formatDdMmYyyy, formatHhMm, isOutOfRange, isSameDay, isoDay, pad2, sdsFormatNational, sdsMatchDialCode, sdsNormalizeSignificant, startOfDay, startOfMonth };
2376
+ export type { SdsAccordionActive, SdsAccordionValue, SdsAvatarStatus, SdsBadgeSize, SdsBadgeVariant, SdsButtonShape, SdsButtonSize, SdsButtonVariant, SdsCardVariant, SdsCheckboxSize, SdsDatePickerSize, SdsIconName, SdsIconSize, SdsInputAppearance, SdsInputNumberAppearance, SdsInputNumberButtonLayout, SdsInputNumberCurrencyDisplay, SdsInputNumberMode, SdsInputNumberSize, SdsInputShape, SdsInputSize, SdsInputType, SdsLocalizedInputSize, SdsLocalizedValue, SdsMultiSelectDisplay, SdsMultiSelectSize, SdsOtpInputSize, SdsPaginatorSize, SdsPaginatorState, SdsPhoneCountry, SdsPhoneInputSize, SdsPhoneValue, SdsSelectAppearance, SdsSelectEmptyContext, SdsSelectFooterContext, SdsSelectOptionContext, SdsSelectSize, SdsSortOrder, SdsTabValue, SdsTableCellContext, SdsTableColumn, SdsTableLazyEvent, SdsTableRowExpansionContext, SdsTableSize, SdsTableSortEvent, SdsTextareaResize, SdsTextareaSize, SdsToast, SdsToastKind, SdsToggleSwitchSize, SdsTopbarAppearance };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@besaitech/ng-design-system",
3
- "version": "0.0.41",
3
+ "version": "0.0.44",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org/",
6
6
  "access": "public"