@besaitech/ng-design-system 0.0.42 → 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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, input, computed, ChangeDetectionStrategy, Component, booleanAttribute, isDevMode, effect, output, signal, forwardRef, viewChild, numberAttribute, viewChildren, afterRenderEffect, ElementRef, model, Injector, afterNextRender, Injectable, TemplateRef, Directive, contentChildren, contentChild } from '@angular/core';
2
+ import { inject, input, computed, ChangeDetectionStrategy, Component, booleanAttribute, isDevMode, effect, output, signal, forwardRef, viewChild, numberAttribute, viewChildren, afterRenderEffect, ElementRef, model, Injector, afterNextRender, TemplateRef, Directive, contentChild, Injectable, contentChildren } from '@angular/core';
3
3
  import { DomSanitizer } from '@angular/platform-browser';
4
4
  import * as i1 from '@angular/forms';
5
5
  import { NG_VALUE_ACCESSOR, NG_VALIDATORS, FormsModule } from '@angular/forms';
@@ -4130,6 +4130,83 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
4130
4130
  }], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], inline: [{ type: i0.Input, args: [{ isSignal: true, alias: "inline", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], showActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "showActions", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTime", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], timeLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeLabel", required: false }] }], hoursLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "hoursLabel", required: false }] }], minutesLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "minutesLabel", required: false }] }], doneLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "doneLabel", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], openCalendarLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "openCalendarLabel", required: false }] }], closeCalendarLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeCalendarLabel", required: false }] }], panelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "panelLabel", required: false }] }], calendarLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "calendarLabel", required: false }] }], previousLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "previousLabel", required: false }] }], nextLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextLabel", required: false }] }], todayActionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "todayActionLabel", required: false }] }], clearActionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearActionLabel", required: false }] }], calendar: [{ type: i0.ViewChild, args: [i0.forwardRef(() => SdsCalendar), { isSignal: true }] }], trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }] } });
4131
4131
  let nextId$6 = 0;
4132
4132
 
4133
+ /**
4134
+ * Supplies a custom template for each option row (and the selected value shown
4135
+ * in the trigger) of an `<sds-select>` / `<sds-multi-select>`. Use as a
4136
+ * structural template projected into the select:
4137
+ *
4138
+ * @example
4139
+ * <sds-select [options]="categories" optionLabel="name" optionValue="id" [(ngModel)]="catId">
4140
+ * <ng-template sdsSelectOption let-option let-selected="selected">
4141
+ * <span class="dot" [style.background]="option.color"></span>
4142
+ * <span class="truncate">{{ option.name }}</span>
4143
+ * </ng-template>
4144
+ * </sds-select>
4145
+ */
4146
+ class SdsSelectOption {
4147
+ /** The wrapped template, rendered by the host select via ngTemplateOutlet. */
4148
+ template = inject(TemplateRef);
4149
+ /** Lets the compiler type-check `let-*` bindings against SdsSelectOptionContext. */
4150
+ static ngTemplateContextGuard(_dir, _ctx) {
4151
+ return true;
4152
+ }
4153
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsSelectOption, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4154
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.25", type: SdsSelectOption, isStandalone: true, selector: "ng-template[sdsSelectOption]", ngImport: i0 });
4155
+ }
4156
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsSelectOption, decorators: [{
4157
+ type: Directive,
4158
+ args: [{
4159
+ selector: 'ng-template[sdsSelectOption]',
4160
+ standalone: true,
4161
+ }]
4162
+ }] });
4163
+ /**
4164
+ * Supplies a custom template shown in place of the default "no results" message
4165
+ * when a select has no (matching) options.
4166
+ *
4167
+ * @example
4168
+ * <ng-template sdsSelectEmpty let-q>No category matches "{{ q }}".</ng-template>
4169
+ */
4170
+ class SdsSelectEmpty {
4171
+ template = inject(TemplateRef);
4172
+ static ngTemplateContextGuard(_dir, _ctx) {
4173
+ return true;
4174
+ }
4175
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsSelectEmpty, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4176
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.25", type: SdsSelectEmpty, isStandalone: true, selector: "ng-template[sdsSelectEmpty]", ngImport: i0 });
4177
+ }
4178
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsSelectEmpty, decorators: [{
4179
+ type: Directive,
4180
+ args: [{
4181
+ selector: 'ng-template[sdsSelectEmpty]',
4182
+ standalone: true,
4183
+ }]
4184
+ }] });
4185
+ /**
4186
+ * Supplies a custom sticky footer rendered below the option list — e.g. a
4187
+ * "+ Create new" action. The `close` context callback dismisses the panel.
4188
+ *
4189
+ * @example
4190
+ * <ng-template sdsSelectFooter let-close="close">
4191
+ * <button (click)="createCategory(); close()">+ New category</button>
4192
+ * </ng-template>
4193
+ */
4194
+ class SdsSelectFooter {
4195
+ template = inject(TemplateRef);
4196
+ static ngTemplateContextGuard(_dir, _ctx) {
4197
+ return true;
4198
+ }
4199
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsSelectFooter, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4200
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.25", type: SdsSelectFooter, isStandalone: true, selector: "ng-template[sdsSelectFooter]", ngImport: i0 });
4201
+ }
4202
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsSelectFooter, decorators: [{
4203
+ type: Directive,
4204
+ args: [{
4205
+ selector: 'ng-template[sdsSelectFooter]',
4206
+ standalone: true,
4207
+ }]
4208
+ }] });
4209
+
4133
4210
  const SIZES$4 = {
4134
4211
  sm: 'h-9 text-sm',
4135
4212
  md: 'h-10 text-sm',
@@ -4146,9 +4223,25 @@ let nextId$5 = 0;
4146
4223
  * key; otherwise selection matching falls back to reference equality (a written
4147
4224
  * copy of an option will not match).
4148
4225
  *
4226
+ * Options render as plain text by default. To render richer options (an icon,
4227
+ * an avatar, a two-line row…) project template directives — the same content
4228
+ * also renders in the trigger for the selected value:
4229
+ * - `<ng-template sdsSelectOption let-option>` — one option row (see {@link SdsSelectOption});
4230
+ * context: the raw `option` (implicit), plus `label`, `value`, `selected`, `disabled`, `index`.
4231
+ * - `<ng-template sdsSelectEmpty let-query>` — replaces the "no results" message (see {@link SdsSelectEmpty}).
4232
+ * - `<ng-template sdsSelectFooter let-close="close">` — a sticky footer action, e.g. "+ New…"
4233
+ * (see {@link SdsSelectFooter}); `close()` dismisses the panel.
4234
+ *
4149
4235
  * @example
4150
4236
  * <sds-select [options]="services" optionLabel="name" optionValue="id"
4151
4237
  * placeholder="Choisir un service" [(ngModel)]="serviceId" filter clearable />
4238
+ *
4239
+ * @example
4240
+ * <sds-select [options]="categories" optionLabel="name" optionValue="id" [(ngModel)]="categoryId">
4241
+ * <ng-template sdsSelectOption let-option>
4242
+ * <span class="dot" [style.background]="option.color"></span> {{ option.name }}
4243
+ * </ng-template>
4244
+ * </sds-select>
4152
4245
  */
4153
4246
  class SdsSelect {
4154
4247
  host = inject(ElementRef);
@@ -4173,6 +4266,12 @@ class SdsSelect {
4173
4266
  filter = input(false, ...(ngDevMode ? [{ debugName: "filter", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
4174
4267
  filterPlaceholder = input('Rechercher…', ...(ngDevMode ? [{ debugName: "filterPlaceholder" }] : []));
4175
4268
  emptyMessage = input('Aucun résultat', ...(ngDevMode ? [{ debugName: "emptyMessage" }] : []));
4269
+ /** Optional projected `<ng-template sdsSelectOption>` — custom option + selected-value rendering. */
4270
+ optionTpl = contentChild(SdsSelectOption, ...(ngDevMode ? [{ debugName: "optionTpl" }] : []));
4271
+ /** Optional projected `<ng-template sdsSelectEmpty>` — custom no-results content. */
4272
+ emptyTpl = contentChild(SdsSelectEmpty, ...(ngDevMode ? [{ debugName: "emptyTpl" }] : []));
4273
+ /** Optional projected `<ng-template sdsSelectFooter>` — a sticky footer action. */
4274
+ footerTpl = contentChild(SdsSelectFooter, ...(ngDevMode ? [{ debugName: "footerTpl" }] : []));
4176
4275
  value = signal(null, ...(ngDevMode ? [{ debugName: "value" }] : []));
4177
4276
  open = signal(false, ...(ngDevMode ? [{ debugName: "open" }] : []));
4178
4277
  filterText = signal('', ...(ngDevMode ? [{ debugName: "filterText" }] : []));
@@ -4229,9 +4328,30 @@ class SdsSelect {
4229
4328
  const label = labelKey && labelKey in o ? String(o[labelKey]) : String(o['label'] ?? raw);
4230
4329
  const value = this.optionValue() ? o[this.optionValue()] : raw;
4231
4330
  const disabled = this.optionDisabled() ? !!o[this.optionDisabled()] : !!o['disabled'];
4232
- return { label, value, disabled };
4331
+ return { label, value, disabled, raw };
4233
4332
  }
4234
- return { label: String(raw), value: raw, disabled: false };
4333
+ return { label: String(raw), value: raw, disabled: false, raw };
4334
+ }
4335
+ /** Context for a projected option template (an option row). */
4336
+ optionContext(opt, index) {
4337
+ return {
4338
+ $implicit: opt.raw,
4339
+ option: opt.raw,
4340
+ label: opt.label,
4341
+ value: opt.value,
4342
+ selected: this.isSelected(opt.value),
4343
+ disabled: opt.disabled,
4344
+ index,
4345
+ };
4346
+ }
4347
+ /** Context for the option template reused in the trigger to render the selected value. */
4348
+ triggerContext = computed(() => {
4349
+ const sel = this.selectedOption();
4350
+ return sel ? this.optionContext(sel, -1) : null;
4351
+ }, ...(ngDevMode ? [{ debugName: "triggerContext" }] : []));
4352
+ /** Context for a projected footer template. */
4353
+ footerContext() {
4354
+ return { $implicit: this.filterText(), filterText: this.filterText(), close: () => this.close(true) };
4235
4355
  }
4236
4356
  equals(a, b) {
4237
4357
  const k = this.dataKey();
@@ -4503,7 +4623,7 @@ class SdsSelect {
4503
4623
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
4504
4624
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdsSelect, isStandalone: true, selector: "sds-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: false, transformFunction: null }, optionDisabled: { classPropertyName: "optionDisabled", publicName: "optionDisabled", isSignal: true, isRequired: false, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, appearance: { classPropertyName: "appearance", publicName: "appearance", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, filterPlaceholder: { classPropertyName: "filterPlaceholder", publicName: "filterPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)" }, classAttribute: "block" }, providers: [
4505
4625
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SdsSelect), multi: true },
4506
- ], viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], ngImport: i0, template: `
4626
+ ], queries: [{ propertyName: "optionTpl", first: true, predicate: SdsSelectOption, descendants: true, isSignal: true }, { propertyName: "emptyTpl", first: true, predicate: SdsSelectEmpty, descendants: true, isSignal: true }, { propertyName: "footerTpl", first: true, predicate: SdsSelectFooter, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], ngImport: i0, template: `
4507
4627
  @if (label()) {
4508
4628
  <label [for]="selectId" class="mb-1.5 block text-sm font-medium text-ink">
4509
4629
  {{ label() }}
@@ -4526,12 +4646,21 @@ class SdsSelect {
4526
4646
  (click)="toggle()"
4527
4647
  (keydown)="onTriggerKeydown($event)"
4528
4648
  >
4529
- <span
4530
- class="flex-1 truncate pl-3.5"
4531
- [class]="selectedOption() ? 'text-ink' : 'text-ink-faint'"
4532
- >
4533
- {{ selectedOption() ? selectedOption()!.label : placeholder() }}
4534
- </span>
4649
+ @if (optionTpl() && selectedOption()) {
4650
+ <span class="flex flex-1 items-center gap-2 truncate pl-3.5 text-ink">
4651
+ <ng-container
4652
+ [ngTemplateOutlet]="optionTpl()!.template"
4653
+ [ngTemplateOutletContext]="triggerContext()!"
4654
+ />
4655
+ </span>
4656
+ } @else {
4657
+ <span
4658
+ class="flex-1 truncate pl-3.5"
4659
+ [class]="selectedOption() ? 'text-ink' : 'text-ink-faint'"
4660
+ >
4661
+ {{ selectedOption() ? selectedOption()!.label : placeholder() }}
4662
+ </span>
4663
+ }
4535
4664
 
4536
4665
  @if (showClear()) {
4537
4666
  <button
@@ -4589,15 +4718,42 @@ class SdsSelect {
4589
4718
  (click)="opt.disabled ? null : selectOption(opt)"
4590
4719
  (mouseenter)="opt.disabled ? null : highlightedIndex.set(i)"
4591
4720
  >
4592
- <span class="truncate">{{ opt.label }}</span>
4721
+ @if (optionTpl()) {
4722
+ <span class="flex min-w-0 flex-1 items-center gap-2">
4723
+ <ng-container
4724
+ [ngTemplateOutlet]="optionTpl()!.template"
4725
+ [ngTemplateOutletContext]="optionContext(opt, i)"
4726
+ />
4727
+ </span>
4728
+ } @else {
4729
+ <span class="truncate">{{ opt.label }}</span>
4730
+ }
4593
4731
  @if (isSelected(opt.value)) {
4594
4732
  <sds-icon name="check" [size]="16" class="shrink-0 text-brand-600" />
4595
4733
  }
4596
4734
  </li>
4597
4735
  } @empty {
4598
- <li class="px-3 py-2 text-sm text-ink-faint">{{ emptyMessage() }}</li>
4736
+ @if (emptyTpl()) {
4737
+ <li class="px-3 py-2 text-sm text-ink-faint">
4738
+ <ng-container
4739
+ [ngTemplateOutlet]="emptyTpl()!.template"
4740
+ [ngTemplateOutletContext]="{ $implicit: filterText(), filterText: filterText() }"
4741
+ />
4742
+ </li>
4743
+ } @else {
4744
+ <li class="px-3 py-2 text-sm text-ink-faint">{{ emptyMessage() }}</li>
4745
+ }
4599
4746
  }
4600
4747
  </ul>
4748
+
4749
+ @if (footerTpl()) {
4750
+ <div class="border-t border-border">
4751
+ <ng-container
4752
+ [ngTemplateOutlet]="footerTpl()!.template"
4753
+ [ngTemplateOutletContext]="footerContext()"
4754
+ />
4755
+ </div>
4756
+ }
4601
4757
  </div>
4602
4758
  }
4603
4759
  </div>
@@ -4608,14 +4764,14 @@ class SdsSelect {
4608
4764
  @if (error()) {
4609
4765
  <p class="mt-1.5 text-xs font-medium text-danger">{{ error() }}</p>
4610
4766
  }
4611
- `, isInline: true, dependencies: [{ kind: "component", type: SdsIcon, selector: "sds-icon", inputs: ["name", "size", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4767
+ `, isInline: true, dependencies: [{ kind: "component", type: SdsIcon, selector: "sds-icon", inputs: ["name", "size", "strokeWidth"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
4612
4768
  }
4613
4769
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsSelect, decorators: [{
4614
4770
  type: Component,
4615
4771
  args: [{
4616
4772
  selector: 'sds-select',
4617
4773
  changeDetection: ChangeDetectionStrategy.OnPush,
4618
- imports: [SdsIcon],
4774
+ imports: [SdsIcon, NgTemplateOutlet],
4619
4775
  providers: [
4620
4776
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SdsSelect), multi: true },
4621
4777
  ],
@@ -4646,12 +4802,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
4646
4802
  (click)="toggle()"
4647
4803
  (keydown)="onTriggerKeydown($event)"
4648
4804
  >
4649
- <span
4650
- class="flex-1 truncate pl-3.5"
4651
- [class]="selectedOption() ? 'text-ink' : 'text-ink-faint'"
4652
- >
4653
- {{ selectedOption() ? selectedOption()!.label : placeholder() }}
4654
- </span>
4805
+ @if (optionTpl() && selectedOption()) {
4806
+ <span class="flex flex-1 items-center gap-2 truncate pl-3.5 text-ink">
4807
+ <ng-container
4808
+ [ngTemplateOutlet]="optionTpl()!.template"
4809
+ [ngTemplateOutletContext]="triggerContext()!"
4810
+ />
4811
+ </span>
4812
+ } @else {
4813
+ <span
4814
+ class="flex-1 truncate pl-3.5"
4815
+ [class]="selectedOption() ? 'text-ink' : 'text-ink-faint'"
4816
+ >
4817
+ {{ selectedOption() ? selectedOption()!.label : placeholder() }}
4818
+ </span>
4819
+ }
4655
4820
 
4656
4821
  @if (showClear()) {
4657
4822
  <button
@@ -4709,15 +4874,42 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
4709
4874
  (click)="opt.disabled ? null : selectOption(opt)"
4710
4875
  (mouseenter)="opt.disabled ? null : highlightedIndex.set(i)"
4711
4876
  >
4712
- <span class="truncate">{{ opt.label }}</span>
4877
+ @if (optionTpl()) {
4878
+ <span class="flex min-w-0 flex-1 items-center gap-2">
4879
+ <ng-container
4880
+ [ngTemplateOutlet]="optionTpl()!.template"
4881
+ [ngTemplateOutletContext]="optionContext(opt, i)"
4882
+ />
4883
+ </span>
4884
+ } @else {
4885
+ <span class="truncate">{{ opt.label }}</span>
4886
+ }
4713
4887
  @if (isSelected(opt.value)) {
4714
4888
  <sds-icon name="check" [size]="16" class="shrink-0 text-brand-600" />
4715
4889
  }
4716
4890
  </li>
4717
4891
  } @empty {
4718
- <li class="px-3 py-2 text-sm text-ink-faint">{{ emptyMessage() }}</li>
4892
+ @if (emptyTpl()) {
4893
+ <li class="px-3 py-2 text-sm text-ink-faint">
4894
+ <ng-container
4895
+ [ngTemplateOutlet]="emptyTpl()!.template"
4896
+ [ngTemplateOutletContext]="{ $implicit: filterText(), filterText: filterText() }"
4897
+ />
4898
+ </li>
4899
+ } @else {
4900
+ <li class="px-3 py-2 text-sm text-ink-faint">{{ emptyMessage() }}</li>
4901
+ }
4719
4902
  }
4720
4903
  </ul>
4904
+
4905
+ @if (footerTpl()) {
4906
+ <div class="border-t border-border">
4907
+ <ng-container
4908
+ [ngTemplateOutlet]="footerTpl()!.template"
4909
+ [ngTemplateOutletContext]="footerContext()"
4910
+ />
4911
+ </div>
4912
+ }
4721
4913
  </div>
4722
4914
  }
4723
4915
  </div>
@@ -4730,7 +4922,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
4730
4922
  }
4731
4923
  `,
4732
4924
  }]
4733
- }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], optionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionLabel", required: false }] }], optionValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionValue", required: false }] }], optionDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionDisabled", required: false }] }], dataKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataKey", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], filterPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPlaceholder", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }] } });
4925
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], optionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionLabel", required: false }] }], optionValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionValue", required: false }] }], optionDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionDisabled", required: false }] }], dataKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataKey", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], appearance: [{ type: i0.Input, args: [{ isSignal: true, alias: "appearance", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], filterPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPlaceholder", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], optionTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdsSelectOption), { isSignal: true }] }], emptyTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdsSelectEmpty), { isSignal: true }] }], footerTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdsSelectFooter), { isSignal: true }] }], trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }] } });
4734
4926
 
4735
4927
  const SIZES$3 = {
4736
4928
  sm: 'min-h-9 text-sm',
@@ -4748,9 +4940,24 @@ let nextId$4 = 0;
4748
4940
  * For object options, set [optionValue] or [dataKey] so written values match by
4749
4941
  * key; otherwise matching falls back to reference equality.
4750
4942
  *
4943
+ * Project template directives to customise the panel:
4944
+ * - `<ng-template sdsSelectOption let-option>` — the content of each option row, after its
4945
+ * checkbox (see {@link SdsSelectOption}); context: the raw `option` (implicit), plus `label`,
4946
+ * `value`, `selected`, `disabled`, `index`.
4947
+ * - `<ng-template sdsSelectEmpty let-query>` — replaces the "no results" message (see {@link SdsSelectEmpty}).
4948
+ * - `<ng-template sdsSelectFooter let-close="close">` — a sticky footer action (see {@link SdsSelectFooter});
4949
+ * `close()` dismisses the panel.
4950
+ *
4751
4951
  * @example
4752
4952
  * <sds-multi-select [options]="services" optionLabel="name" optionValue="code"
4753
4953
  * display="chip" filter [(ngModel)]="codes" />
4954
+ *
4955
+ * @example
4956
+ * <sds-multi-select [options]="tags" optionLabel="name" optionValue="id" [(ngModel)]="tagIds">
4957
+ * <ng-template sdsSelectOption let-option>
4958
+ * <span class="dot" [style.background]="option.color"></span> {{ option.name }}
4959
+ * </ng-template>
4960
+ * </sds-multi-select>
4754
4961
  */
4755
4962
  class SdsMultiSelect {
4756
4963
  host = inject(ElementRef);
@@ -4778,6 +4985,12 @@ class SdsMultiSelect {
4778
4985
  filter = input(false, ...(ngDevMode ? [{ debugName: "filter", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
4779
4986
  filterPlaceholder = input('Rechercher…', ...(ngDevMode ? [{ debugName: "filterPlaceholder" }] : []));
4780
4987
  emptyMessage = input('Aucun résultat', ...(ngDevMode ? [{ debugName: "emptyMessage" }] : []));
4988
+ /** Optional projected `<ng-template sdsSelectOption>` — custom option-row rendering. */
4989
+ optionTpl = contentChild(SdsSelectOption, ...(ngDevMode ? [{ debugName: "optionTpl" }] : []));
4990
+ /** Optional projected `<ng-template sdsSelectEmpty>` — custom no-results content. */
4991
+ emptyTpl = contentChild(SdsSelectEmpty, ...(ngDevMode ? [{ debugName: "emptyTpl" }] : []));
4992
+ /** Optional projected `<ng-template sdsSelectFooter>` — a sticky footer action. */
4993
+ footerTpl = contentChild(SdsSelectFooter, ...(ngDevMode ? [{ debugName: "footerTpl" }] : []));
4781
4994
  value = signal([], ...(ngDevMode ? [{ debugName: "value" }] : []));
4782
4995
  open = signal(false, ...(ngDevMode ? [{ debugName: "open" }] : []));
4783
4996
  filterText = signal('', ...(ngDevMode ? [{ debugName: "filterText" }] : []));
@@ -4843,9 +5056,25 @@ class SdsMultiSelect {
4843
5056
  const label = labelKey && labelKey in o ? String(o[labelKey]) : String(o['label'] ?? raw);
4844
5057
  const value = this.optionValue() ? o[this.optionValue()] : raw;
4845
5058
  const disabled = this.optionDisabled() ? !!o[this.optionDisabled()] : !!o['disabled'];
4846
- return { label, value, disabled };
5059
+ return { label, value, disabled, raw };
4847
5060
  }
4848
- return { label: String(raw), value: raw, disabled: false };
5061
+ return { label: String(raw), value: raw, disabled: false, raw };
5062
+ }
5063
+ /** Context for a projected option template (an option row). */
5064
+ optionContext(opt, index) {
5065
+ return {
5066
+ $implicit: opt.raw,
5067
+ option: opt.raw,
5068
+ label: opt.label,
5069
+ value: opt.value,
5070
+ selected: this.isSelected(opt.value),
5071
+ disabled: opt.disabled,
5072
+ index,
5073
+ };
5074
+ }
5075
+ /** Context for a projected footer template. */
5076
+ footerContext() {
5077
+ return { $implicit: this.filterText(), filterText: this.filterText(), close: () => this.close(true) };
4849
5078
  }
4850
5079
  equals(a, b) {
4851
5080
  const k = this.dataKey();
@@ -5157,7 +5386,7 @@ class SdsMultiSelect {
5157
5386
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsMultiSelect, deps: [], target: i0.ɵɵFactoryTarget.Component });
5158
5387
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdsMultiSelect, isStandalone: true, selector: "sds-multi-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, optionLabel: { classPropertyName: "optionLabel", publicName: "optionLabel", isSignal: true, isRequired: false, transformFunction: null }, optionValue: { classPropertyName: "optionValue", publicName: "optionValue", isSignal: true, isRequired: false, transformFunction: null }, optionDisabled: { classPropertyName: "optionDisabled", publicName: "optionDisabled", isSignal: true, isRequired: false, transformFunction: null }, dataKey: { classPropertyName: "dataKey", publicName: "dataKey", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, display: { classPropertyName: "display", publicName: "display", isSignal: true, isRequired: false, transformFunction: null }, maxSelectedLabels: { classPropertyName: "maxSelectedLabels", publicName: "maxSelectedLabels", isSignal: true, isRequired: false, transformFunction: null }, selectedItemsLabel: { classPropertyName: "selectedItemsLabel", publicName: "selectedItemsLabel", isSignal: true, isRequired: false, transformFunction: null }, showToggleAll: { classPropertyName: "showToggleAll", publicName: "showToggleAll", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, filter: { classPropertyName: "filter", publicName: "filter", isSignal: true, isRequired: false, transformFunction: null }, filterPlaceholder: { classPropertyName: "filterPlaceholder", publicName: "filterPlaceholder", isSignal: true, isRequired: false, transformFunction: null }, emptyMessage: { classPropertyName: "emptyMessage", publicName: "emptyMessage", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)" }, classAttribute: "block" }, providers: [
5159
5388
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SdsMultiSelect), multi: true },
5160
- ], viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], ngImport: i0, template: `
5389
+ ], queries: [{ propertyName: "optionTpl", first: true, predicate: SdsSelectOption, descendants: true, isSignal: true }, { propertyName: "emptyTpl", first: true, predicate: SdsSelectEmpty, descendants: true, isSignal: true }, { propertyName: "footerTpl", first: true, predicate: SdsSelectFooter, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], ngImport: i0, template: `
5161
5390
  @if (label()) {
5162
5391
  <label [for]="selectId" class="mb-1.5 block text-sm font-medium text-ink">
5163
5392
  {{ label() }}
@@ -5290,12 +5519,39 @@ class SdsMultiSelect {
5290
5519
  <sds-icon name="check" [size]="12" />
5291
5520
  }
5292
5521
  </span>
5293
- <span class="truncate">{{ opt.label }}</span>
5522
+ @if (optionTpl()) {
5523
+ <span class="flex min-w-0 flex-1 items-center gap-2">
5524
+ <ng-container
5525
+ [ngTemplateOutlet]="optionTpl()!.template"
5526
+ [ngTemplateOutletContext]="optionContext(opt, i)"
5527
+ />
5528
+ </span>
5529
+ } @else {
5530
+ <span class="truncate">{{ opt.label }}</span>
5531
+ }
5294
5532
  </li>
5295
5533
  } @empty {
5296
- <li class="px-3 py-2 text-sm text-ink-faint">{{ emptyMessage() }}</li>
5534
+ @if (emptyTpl()) {
5535
+ <li class="px-3 py-2 text-sm text-ink-faint">
5536
+ <ng-container
5537
+ [ngTemplateOutlet]="emptyTpl()!.template"
5538
+ [ngTemplateOutletContext]="{ $implicit: filterText(), filterText: filterText() }"
5539
+ />
5540
+ </li>
5541
+ } @else {
5542
+ <li class="px-3 py-2 text-sm text-ink-faint">{{ emptyMessage() }}</li>
5543
+ }
5297
5544
  }
5298
5545
  </ul>
5546
+
5547
+ @if (footerTpl()) {
5548
+ <div class="border-t border-border">
5549
+ <ng-container
5550
+ [ngTemplateOutlet]="footerTpl()!.template"
5551
+ [ngTemplateOutletContext]="footerContext()"
5552
+ />
5553
+ </div>
5554
+ }
5299
5555
  </div>
5300
5556
  }
5301
5557
  </div>
@@ -5306,14 +5562,14 @@ class SdsMultiSelect {
5306
5562
  @if (error()) {
5307
5563
  <p class="mt-1.5 text-xs font-medium text-danger">{{ error() }}</p>
5308
5564
  }
5309
- `, isInline: true, dependencies: [{ kind: "component", type: SdsIcon, selector: "sds-icon", inputs: ["name", "size", "strokeWidth"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5565
+ `, isInline: true, dependencies: [{ kind: "component", type: SdsIcon, selector: "sds-icon", inputs: ["name", "size", "strokeWidth"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
5310
5566
  }
5311
5567
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsMultiSelect, decorators: [{
5312
5568
  type: Component,
5313
5569
  args: [{
5314
5570
  selector: 'sds-multi-select',
5315
5571
  changeDetection: ChangeDetectionStrategy.OnPush,
5316
- imports: [SdsIcon],
5572
+ imports: [SdsIcon, NgTemplateOutlet],
5317
5573
  providers: [
5318
5574
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SdsMultiSelect), multi: true },
5319
5575
  ],
@@ -5454,12 +5710,39 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
5454
5710
  <sds-icon name="check" [size]="12" />
5455
5711
  }
5456
5712
  </span>
5457
- <span class="truncate">{{ opt.label }}</span>
5713
+ @if (optionTpl()) {
5714
+ <span class="flex min-w-0 flex-1 items-center gap-2">
5715
+ <ng-container
5716
+ [ngTemplateOutlet]="optionTpl()!.template"
5717
+ [ngTemplateOutletContext]="optionContext(opt, i)"
5718
+ />
5719
+ </span>
5720
+ } @else {
5721
+ <span class="truncate">{{ opt.label }}</span>
5722
+ }
5458
5723
  </li>
5459
5724
  } @empty {
5460
- <li class="px-3 py-2 text-sm text-ink-faint">{{ emptyMessage() }}</li>
5725
+ @if (emptyTpl()) {
5726
+ <li class="px-3 py-2 text-sm text-ink-faint">
5727
+ <ng-container
5728
+ [ngTemplateOutlet]="emptyTpl()!.template"
5729
+ [ngTemplateOutletContext]="{ $implicit: filterText(), filterText: filterText() }"
5730
+ />
5731
+ </li>
5732
+ } @else {
5733
+ <li class="px-3 py-2 text-sm text-ink-faint">{{ emptyMessage() }}</li>
5734
+ }
5461
5735
  }
5462
5736
  </ul>
5737
+
5738
+ @if (footerTpl()) {
5739
+ <div class="border-t border-border">
5740
+ <ng-container
5741
+ [ngTemplateOutlet]="footerTpl()!.template"
5742
+ [ngTemplateOutletContext]="footerContext()"
5743
+ />
5744
+ </div>
5745
+ }
5463
5746
  </div>
5464
5747
  }
5465
5748
  </div>
@@ -5472,7 +5755,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
5472
5755
  }
5473
5756
  `,
5474
5757
  }]
5475
- }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], optionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionLabel", required: false }] }], optionValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionValue", required: false }] }], optionDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionDisabled", required: false }] }], dataKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataKey", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], display: [{ type: i0.Input, args: [{ isSignal: true, alias: "display", required: false }] }], maxSelectedLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSelectedLabels", required: false }] }], selectedItemsLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItemsLabel", required: false }] }], showToggleAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "showToggleAll", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], filterPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPlaceholder", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }] } });
5758
+ }], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], optionLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionLabel", required: false }] }], optionValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionValue", required: false }] }], optionDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionDisabled", required: false }] }], dataKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataKey", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], display: [{ type: i0.Input, args: [{ isSignal: true, alias: "display", required: false }] }], maxSelectedLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSelectedLabels", required: false }] }], selectedItemsLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "selectedItemsLabel", required: false }] }], showToggleAll: [{ type: i0.Input, args: [{ isSignal: true, alias: "showToggleAll", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], filter: [{ type: i0.Input, args: [{ isSignal: true, alias: "filter", required: false }] }], filterPlaceholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "filterPlaceholder", required: false }] }], emptyMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyMessage", required: false }] }], optionTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdsSelectOption), { isSignal: true }] }], emptyTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdsSelectEmpty), { isSignal: true }] }], footerTpl: [{ type: i0.ContentChild, args: [i0.forwardRef(() => SdsSelectFooter), { isSignal: true }] }], trigger: [{ type: i0.ViewChild, args: ['trigger', { isSignal: true }] }] } });
5476
5759
 
5477
5760
  const SDS_PHONE_COUNTRIES = [
5478
5761
  { iso2: 'BE', name: 'Belgique', dialCode: '32', lengths: [9], format: '### ## ## ##', example: '470123456' },
@@ -9375,5 +9658,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
9375
9658
  * Generated bundle index. Do not edit.
9376
9659
  */
9377
9660
 
9378
- 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, 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 };
9661
+ 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 };
9379
9662
  //# sourceMappingURL=besaitech-ng-design-system.mjs.map