@besaitech/ng-design-system 0.0.35 → 0.0.37

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.
@@ -90,6 +90,8 @@ const SDS_ICONS = {
90
90
  'arrow-right': '<path d="M5 12h14"/><path d="m12 5 7 7-7 7"/>',
91
91
  'refresh-cw': '<path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M3 21v-5h5"/>',
92
92
  'loader-circle': '<path d="M21 12a9 9 0 1 1-6.219-8.56"/>',
93
+ bug: '<path d="M12 20v-9"/><path d="M14 7a4 4 0 0 1 4 4v3a6 6 0 0 1-12 0v-3a4 4 0 0 1 4-4z"/><path d="M14.12 3.88 16 2"/><path d="M21 21a4 4 0 0 0-3.81-4"/><path d="M21 5a4 4 0 0 1-3.55 3.97"/><path d="M22 13h-4"/><path d="M3 21a4 4 0 0 1 3.81-4"/><path d="M3 5a4 4 0 0 0 3.55 3.97"/><path d="M6 13H2"/><path d="m8 2 1.88 1.88"/><path d="M9 7.13V6a3 3 0 1 1 6 0v1.13"/>',
94
+ 'scroll-text': '<path d="M15 12h-5"/><path d="M15 8h-5"/><path d="M19 17V5a2 2 0 0 0-2-2H4"/><path d="M8 21h12a2 2 0 0 0 2-2v-1a1 1 0 0 0-1-1H11a1 1 0 0 0-1 1v1a2 2 0 1 1-4 0V5a2 2 0 1 0-4 0v2a1 1 0 0 0 1 1h3"/>',
93
95
  };
94
96
 
95
97
  const SIZE_PX = { sm: 16, md: 20, lg: 24, xl: 32 };
@@ -1734,6 +1736,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
1734
1736
  function startOfDay(d) {
1735
1737
  return new Date(d.getFullYear(), d.getMonth(), d.getDate());
1736
1738
  }
1739
+ /** Zero-pad a number to two digits (e.g. 9 → "09"). */
1740
+ function pad2(n) {
1741
+ return String(n).padStart(2, '0');
1742
+ }
1743
+ /** Format a date's time-of-day as HH:mm (24h, local time). */
1744
+ function formatHhMm(d) {
1745
+ return `${pad2(d.getHours())}:${pad2(d.getMinutes())}`;
1746
+ }
1737
1747
  function startOfMonth(d) {
1738
1748
  return new Date(d.getFullYear(), d.getMonth(), 1);
1739
1749
  }
@@ -1792,6 +1802,18 @@ class SdsCalendar {
1792
1802
  firstDayOfWeek = input(1, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : []));
1793
1803
  locale = input('fr-FR', ...(ngDevMode ? [{ debugName: "locale" }] : []));
1794
1804
  showActions = input(true, ...(ngDevMode ? [{ debugName: "showActions" }] : []));
1805
+ /** When true, a time editor (HH:mm, 24h) is shown and the value keeps its time-of-day. */
1806
+ showTime = input(false, ...(ngDevMode ? [{ debugName: "showTime", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
1807
+ /** When true, a "done" action is shown (used by the overlay picker to close the panel). */
1808
+ showDone = input(false, ...(ngDevMode ? [{ debugName: "showDone", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
1809
+ /** Visible label of the time editor. Translate it in the consuming app. */
1810
+ timeLabel = input('Heure', ...(ngDevMode ? [{ debugName: "timeLabel" }] : []));
1811
+ /** Accessible name of the hours field (it is a bare numeric input). */
1812
+ hoursLabel = input('Heures', ...(ngDevMode ? [{ debugName: "hoursLabel" }] : []));
1813
+ /** Accessible name of the minutes field. */
1814
+ minutesLabel = input('Minutes', ...(ngDevMode ? [{ debugName: "minutesLabel" }] : []));
1815
+ /** Visible text of the "done" action (shown when {@link showDone} is true). */
1816
+ doneLabel = input('Terminé', ...(ngDevMode ? [{ debugName: "doneLabel" }] : []));
1795
1817
  /**
1796
1818
  * Accessible name for the calendar container. French default so existing consumers are unchanged,
1797
1819
  * but an app serving more than one language MUST translate it.
@@ -1814,6 +1836,8 @@ class SdsCalendar {
1814
1836
  clearActionLabel = input('Effacer', ...(ngDevMode ? [{ debugName: "clearActionLabel" }] : []));
1815
1837
  /** Emitted when a concrete date is picked (day click or "Aujourd'hui"). */
1816
1838
  dateSelect = output();
1839
+ /** Emitted when the "done" action is used (see {@link showDone}). */
1840
+ done = output();
1817
1841
  view = signal('day', ...(ngDevMode ? [{ debugName: "view" }] : []));
1818
1842
  viewDate = signal(startOfMonth(new Date()), ...(ngDevMode ? [{ debugName: "viewDate" }] : []));
1819
1843
  focusedDate = signal(startOfDay(new Date()), ...(ngDevMode ? [{ debugName: "focusedDate" }] : []));
@@ -1833,6 +1857,9 @@ class SdsCalendar {
1833
1857
  navBtn = 'inline-flex h-8 w-8 items-center justify-center rounded-control text-ink-soft hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500';
1834
1858
  titleBtn = 'rounded-control px-2 py-1 capitalize hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500';
1835
1859
  actionBtn = 'rounded-control px-2 py-1 text-xs font-medium text-brand-700 hover:bg-brand-50 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500 disabled:cursor-not-allowed disabled:opacity-40';
1860
+ doneBtn = 'rounded-control bg-brand-600 px-3 py-1 text-xs font-semibold text-white hover:bg-brand-700 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-brand-500';
1861
+ timeInput = 'w-8 bg-transparent py-1 text-center text-sm text-ink outline-none disabled:cursor-not-allowed disabled:opacity-40';
1862
+ stepBtn = 'flex h-3.5 w-5 items-center justify-center text-ink-faint transition-colors hover:text-ink focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-30';
1836
1863
  // --- labels ---
1837
1864
  monthLong = computed(() => new Intl.DateTimeFormat(this.locale(), { month: 'long' }).format(this.viewDate()), ...(ngDevMode ? [{ debugName: "monthLong" }] : []));
1838
1865
  yearLabel = computed(() => this.viewDate().getFullYear(), ...(ngDevMode ? [{ debugName: "yearLabel" }] : []));
@@ -1929,12 +1956,24 @@ class SdsCalendar {
1929
1956
  selectDay(d) {
1930
1957
  if (isOutOfRange(d, this.min(), this.max()))
1931
1958
  return;
1932
- const day = startOfDay(d);
1959
+ // showTime keeps the current time-of-day (or 00:00 when nothing was set yet); otherwise midnight.
1960
+ const day = this.applyTime(startOfDay(d));
1933
1961
  this.value.set(day);
1934
1962
  this.viewDate.set(startOfMonth(day));
1935
- this.focusedDate.set(day);
1963
+ this.focusedDate.set(startOfDay(day));
1936
1964
  this.dateSelect.emit(day);
1937
1965
  }
1966
+ /** Carry the previously-selected time-of-day onto a freshly-picked day (only when showTime). */
1967
+ applyTime(day) {
1968
+ if (!this.showTime())
1969
+ return day;
1970
+ const prev = this.value();
1971
+ if (!prev)
1972
+ return day; // no prior time → keep 00:00
1973
+ const d = new Date(day);
1974
+ d.setHours(prev.getHours(), prev.getMinutes(), 0, 0);
1975
+ return d;
1976
+ }
1938
1977
  selectMonth(m) {
1939
1978
  this.viewDate.set(new Date(this.viewDate().getFullYear(), m, 1));
1940
1979
  this.view.set('day');
@@ -1950,6 +1989,55 @@ class SdsCalendar {
1950
1989
  clear() {
1951
1990
  this.value.set(null);
1952
1991
  }
1992
+ // --- time editor (only rendered when showTime) ---
1993
+ hoursText = computed(() => {
1994
+ const v = this.value();
1995
+ return v ? pad2(v.getHours()) : '';
1996
+ }, ...(ngDevMode ? [{ debugName: "hoursText" }] : []));
1997
+ minutesText = computed(() => {
1998
+ const v = this.value();
1999
+ return v ? pad2(v.getMinutes()) : '';
2000
+ }, ...(ngDevMode ? [{ debugName: "minutesText" }] : []));
2001
+ setHours(raw) {
2002
+ const v = this.value();
2003
+ if (!v)
2004
+ return;
2005
+ const n = parseInt(raw, 10);
2006
+ if (Number.isNaN(n))
2007
+ return;
2008
+ const d = new Date(v);
2009
+ d.setHours(Math.min(23, Math.max(0, n)));
2010
+ this.value.set(d);
2011
+ }
2012
+ setMinutes(raw) {
2013
+ const v = this.value();
2014
+ if (!v)
2015
+ return;
2016
+ const n = parseInt(raw, 10);
2017
+ if (Number.isNaN(n))
2018
+ return;
2019
+ const d = new Date(v);
2020
+ d.setMinutes(Math.min(59, Math.max(0, n)));
2021
+ this.value.set(d);
2022
+ }
2023
+ /** Wrap hours within 0–23; never carries into the day. */
2024
+ stepHours(delta) {
2025
+ const v = this.value();
2026
+ if (!v)
2027
+ return;
2028
+ const d = new Date(v);
2029
+ d.setHours((d.getHours() + delta + 24) % 24);
2030
+ this.value.set(d);
2031
+ }
2032
+ /** Wrap minutes within 0–59; never carries into the hour. */
2033
+ stepMinutes(delta) {
2034
+ const v = this.value();
2035
+ if (!v)
2036
+ return;
2037
+ const d = new Date(v);
2038
+ d.setMinutes((d.getMinutes() + delta + 60) % 60);
2039
+ this.value.set(d);
2040
+ }
1953
2041
  // --- keyboard (day grid) ---
1954
2042
  onGridKeydown(e) {
1955
2043
  let f = this.focusedDate();
@@ -2045,7 +2133,7 @@ class SdsCalendar {
2045
2133
  return cls;
2046
2134
  }
2047
2135
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsCalendar, deps: [], target: i0.ɵɵFactoryTarget.Component });
2048
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdsCalendar, isStandalone: true, selector: "sds-calendar", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: true, isRequired: false, transformFunction: null }, calendarLabel: { classPropertyName: "calendarLabel", publicName: "calendarLabel", isSignal: true, isRequired: false, transformFunction: null }, previousLabel: { classPropertyName: "previousLabel", publicName: "previousLabel", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null }, todayActionLabel: { classPropertyName: "todayActionLabel", publicName: "todayActionLabel", isSignal: true, isRequired: false, transformFunction: null }, clearActionLabel: { classPropertyName: "clearActionLabel", publicName: "clearActionLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", dateSelect: "dateSelect" }, host: { classAttribute: "block" }, ngImport: i0, template: `
2136
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdsCalendar, isStandalone: true, selector: "sds-calendar", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: true, isRequired: false, transformFunction: null }, showTime: { classPropertyName: "showTime", publicName: "showTime", isSignal: true, isRequired: false, transformFunction: null }, showDone: { classPropertyName: "showDone", publicName: "showDone", isSignal: true, isRequired: false, transformFunction: null }, timeLabel: { classPropertyName: "timeLabel", publicName: "timeLabel", isSignal: true, isRequired: false, transformFunction: null }, hoursLabel: { classPropertyName: "hoursLabel", publicName: "hoursLabel", isSignal: true, isRequired: false, transformFunction: null }, minutesLabel: { classPropertyName: "minutesLabel", publicName: "minutesLabel", isSignal: true, isRequired: false, transformFunction: null }, doneLabel: { classPropertyName: "doneLabel", publicName: "doneLabel", isSignal: true, isRequired: false, transformFunction: null }, calendarLabel: { classPropertyName: "calendarLabel", publicName: "calendarLabel", isSignal: true, isRequired: false, transformFunction: null }, previousLabel: { classPropertyName: "previousLabel", publicName: "previousLabel", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null }, todayActionLabel: { classPropertyName: "todayActionLabel", publicName: "todayActionLabel", isSignal: true, isRequired: false, transformFunction: null }, clearActionLabel: { classPropertyName: "clearActionLabel", publicName: "clearActionLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", dateSelect: "dateSelect", done: "done" }, host: { classAttribute: "block" }, ngImport: i0, template: `
2049
2137
  <div
2050
2138
  class="w-[20rem] select-none rounded-card border border-border bg-surface p-3 shadow-lg"
2051
2139
  role="group"
@@ -2153,18 +2241,115 @@ class SdsCalendar {
2153
2241
  </div>
2154
2242
  }
2155
2243
 
2244
+ <!-- Time editor -->
2245
+ @if (showTime()) {
2246
+ <div class="mt-2 flex items-center gap-2 border-t border-border pt-2">
2247
+ <span class="text-xs font-medium text-ink-soft">{{ timeLabel() }}</span>
2248
+ <div class="ml-auto inline-flex items-center gap-1.5">
2249
+ <div class="inline-flex items-center rounded-control border border-border bg-white">
2250
+ <input
2251
+ type="text"
2252
+ inputmode="numeric"
2253
+ maxlength="2"
2254
+ [value]="hoursText()"
2255
+ [disabled]="!value()"
2256
+ [attr.aria-label]="hoursLabel()"
2257
+ (change)="setHours($any($event.target).value)"
2258
+ (blur)="$any($event.target).value = hoursText()"
2259
+ (keydown.arrowup)="stepHours(1); $event.preventDefault()"
2260
+ (keydown.arrowdown)="stepHours(-1); $event.preventDefault()"
2261
+ [class]="timeInput"
2262
+ />
2263
+ <div class="flex flex-col border-l border-border">
2264
+ <button
2265
+ type="button"
2266
+ tabindex="-1"
2267
+ aria-hidden="true"
2268
+ [disabled]="!value()"
2269
+ [class]="stepBtn"
2270
+ (click)="stepHours(1)"
2271
+ >
2272
+ <span class="inline-flex rotate-180"
2273
+ ><sds-icon name="chevron-down" [size]="11"
2274
+ /></span>
2275
+ </button>
2276
+ <button
2277
+ type="button"
2278
+ tabindex="-1"
2279
+ aria-hidden="true"
2280
+ [disabled]="!value()"
2281
+ [class]="stepBtn"
2282
+ (click)="stepHours(-1)"
2283
+ >
2284
+ <sds-icon name="chevron-down" [size]="11" />
2285
+ </button>
2286
+ </div>
2287
+ </div>
2288
+ <span class="text-sm font-semibold text-ink-soft">:</span>
2289
+ <div class="inline-flex items-center rounded-control border border-border bg-white">
2290
+ <input
2291
+ type="text"
2292
+ inputmode="numeric"
2293
+ maxlength="2"
2294
+ [value]="minutesText()"
2295
+ [disabled]="!value()"
2296
+ [attr.aria-label]="minutesLabel()"
2297
+ (change)="setMinutes($any($event.target).value)"
2298
+ (blur)="$any($event.target).value = minutesText()"
2299
+ (keydown.arrowup)="stepMinutes(1); $event.preventDefault()"
2300
+ (keydown.arrowdown)="stepMinutes(-1); $event.preventDefault()"
2301
+ [class]="timeInput"
2302
+ />
2303
+ <div class="flex flex-col border-l border-border">
2304
+ <button
2305
+ type="button"
2306
+ tabindex="-1"
2307
+ aria-hidden="true"
2308
+ [disabled]="!value()"
2309
+ [class]="stepBtn"
2310
+ (click)="stepMinutes(1)"
2311
+ >
2312
+ <span class="inline-flex rotate-180"
2313
+ ><sds-icon name="chevron-down" [size]="11"
2314
+ /></span>
2315
+ </button>
2316
+ <button
2317
+ type="button"
2318
+ tabindex="-1"
2319
+ aria-hidden="true"
2320
+ [disabled]="!value()"
2321
+ [class]="stepBtn"
2322
+ (click)="stepMinutes(-1)"
2323
+ >
2324
+ <sds-icon name="chevron-down" [size]="11" />
2325
+ </button>
2326
+ </div>
2327
+ </div>
2328
+ </div>
2329
+ </div>
2330
+ }
2331
+
2156
2332
  <!-- Actions -->
2157
- @if (showActions()) {
2333
+ @if (showActions() || showDone()) {
2158
2334
  <div class="mt-2 flex items-center justify-between border-t border-border pt-2">
2159
- <button
2160
- type="button"
2161
- [class]="actionBtn"
2162
- [disabled]="todayDisabled()"
2163
- (click)="goToday()"
2164
- >
2165
- {{ todayActionLabel() }}
2166
- </button>
2167
- <button type="button" [class]="actionBtn" (click)="clear()">{{ clearActionLabel() }}</button>
2335
+ <div class="flex items-center gap-1">
2336
+ @if (showActions()) {
2337
+ <button
2338
+ type="button"
2339
+ [class]="actionBtn"
2340
+ [disabled]="todayDisabled()"
2341
+ (click)="goToday()"
2342
+ >
2343
+ {{ todayActionLabel() }}
2344
+ </button>
2345
+ <button type="button" [class]="actionBtn" (click)="clear()">
2346
+ {{ clearActionLabel() }}
2347
+ </button>
2348
+ }
2349
+ </div>
2350
+ @if (showDone()) {
2351
+ <button type="button" [class]="doneBtn" (click)="done.emit()">{{ doneLabel() }}</button>
2352
+ }
2168
2353
  </div>
2169
2354
  }
2170
2355
  </div>
@@ -2285,24 +2470,121 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
2285
2470
  </div>
2286
2471
  }
2287
2472
 
2473
+ <!-- Time editor -->
2474
+ @if (showTime()) {
2475
+ <div class="mt-2 flex items-center gap-2 border-t border-border pt-2">
2476
+ <span class="text-xs font-medium text-ink-soft">{{ timeLabel() }}</span>
2477
+ <div class="ml-auto inline-flex items-center gap-1.5">
2478
+ <div class="inline-flex items-center rounded-control border border-border bg-white">
2479
+ <input
2480
+ type="text"
2481
+ inputmode="numeric"
2482
+ maxlength="2"
2483
+ [value]="hoursText()"
2484
+ [disabled]="!value()"
2485
+ [attr.aria-label]="hoursLabel()"
2486
+ (change)="setHours($any($event.target).value)"
2487
+ (blur)="$any($event.target).value = hoursText()"
2488
+ (keydown.arrowup)="stepHours(1); $event.preventDefault()"
2489
+ (keydown.arrowdown)="stepHours(-1); $event.preventDefault()"
2490
+ [class]="timeInput"
2491
+ />
2492
+ <div class="flex flex-col border-l border-border">
2493
+ <button
2494
+ type="button"
2495
+ tabindex="-1"
2496
+ aria-hidden="true"
2497
+ [disabled]="!value()"
2498
+ [class]="stepBtn"
2499
+ (click)="stepHours(1)"
2500
+ >
2501
+ <span class="inline-flex rotate-180"
2502
+ ><sds-icon name="chevron-down" [size]="11"
2503
+ /></span>
2504
+ </button>
2505
+ <button
2506
+ type="button"
2507
+ tabindex="-1"
2508
+ aria-hidden="true"
2509
+ [disabled]="!value()"
2510
+ [class]="stepBtn"
2511
+ (click)="stepHours(-1)"
2512
+ >
2513
+ <sds-icon name="chevron-down" [size]="11" />
2514
+ </button>
2515
+ </div>
2516
+ </div>
2517
+ <span class="text-sm font-semibold text-ink-soft">:</span>
2518
+ <div class="inline-flex items-center rounded-control border border-border bg-white">
2519
+ <input
2520
+ type="text"
2521
+ inputmode="numeric"
2522
+ maxlength="2"
2523
+ [value]="minutesText()"
2524
+ [disabled]="!value()"
2525
+ [attr.aria-label]="minutesLabel()"
2526
+ (change)="setMinutes($any($event.target).value)"
2527
+ (blur)="$any($event.target).value = minutesText()"
2528
+ (keydown.arrowup)="stepMinutes(1); $event.preventDefault()"
2529
+ (keydown.arrowdown)="stepMinutes(-1); $event.preventDefault()"
2530
+ [class]="timeInput"
2531
+ />
2532
+ <div class="flex flex-col border-l border-border">
2533
+ <button
2534
+ type="button"
2535
+ tabindex="-1"
2536
+ aria-hidden="true"
2537
+ [disabled]="!value()"
2538
+ [class]="stepBtn"
2539
+ (click)="stepMinutes(1)"
2540
+ >
2541
+ <span class="inline-flex rotate-180"
2542
+ ><sds-icon name="chevron-down" [size]="11"
2543
+ /></span>
2544
+ </button>
2545
+ <button
2546
+ type="button"
2547
+ tabindex="-1"
2548
+ aria-hidden="true"
2549
+ [disabled]="!value()"
2550
+ [class]="stepBtn"
2551
+ (click)="stepMinutes(-1)"
2552
+ >
2553
+ <sds-icon name="chevron-down" [size]="11" />
2554
+ </button>
2555
+ </div>
2556
+ </div>
2557
+ </div>
2558
+ </div>
2559
+ }
2560
+
2288
2561
  <!-- Actions -->
2289
- @if (showActions()) {
2562
+ @if (showActions() || showDone()) {
2290
2563
  <div class="mt-2 flex items-center justify-between border-t border-border pt-2">
2291
- <button
2292
- type="button"
2293
- [class]="actionBtn"
2294
- [disabled]="todayDisabled()"
2295
- (click)="goToday()"
2296
- >
2297
- {{ todayActionLabel() }}
2298
- </button>
2299
- <button type="button" [class]="actionBtn" (click)="clear()">{{ clearActionLabel() }}</button>
2564
+ <div class="flex items-center gap-1">
2565
+ @if (showActions()) {
2566
+ <button
2567
+ type="button"
2568
+ [class]="actionBtn"
2569
+ [disabled]="todayDisabled()"
2570
+ (click)="goToday()"
2571
+ >
2572
+ {{ todayActionLabel() }}
2573
+ </button>
2574
+ <button type="button" [class]="actionBtn" (click)="clear()">
2575
+ {{ clearActionLabel() }}
2576
+ </button>
2577
+ }
2578
+ </div>
2579
+ @if (showDone()) {
2580
+ <button type="button" [class]="doneBtn" (click)="done.emit()">{{ doneLabel() }}</button>
2581
+ }
2300
2582
  </div>
2301
2583
  }
2302
2584
  </div>
2303
2585
  `,
2304
2586
  }]
2305
- }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], 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 }] }], showActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "showActions", 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 }] }], dateSelect: [{ type: i0.Output, args: ["dateSelect"] }] } });
2587
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], 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 }] }], showActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "showActions", required: false }] }], showTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTime", required: false }] }], showDone: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDone", 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 }] }], 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 }] }], dateSelect: [{ type: i0.Output, args: ["dateSelect"] }], done: [{ type: i0.Output, args: ["done"] }] } });
2306
2588
 
2307
2589
  const SIZES$5 = {
2308
2590
  sm: 'h-9 text-sm',
@@ -2335,8 +2617,22 @@ class SdsDatePicker {
2335
2617
  clearable = input(true, ...(ngDevMode ? [{ debugName: "clearable", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
2336
2618
  showActions = input(true, ...(ngDevMode ? [{ debugName: "showActions", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
2337
2619
  disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
2338
- /** Custom display formatter (default dd/MM/yyyy). */
2620
+ /**
2621
+ * When true, the calendar shows a time editor (HH:mm, 24h), the value keeps its time-of-day, and
2622
+ * the field displays date + time. The overlay stays open on day-select so the time can be set;
2623
+ * a "done" action (and click-away / Escape) closes it.
2624
+ */
2625
+ showTime = input(false, ...(ngDevMode ? [{ debugName: "showTime", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
2626
+ /** Custom display formatter for the DATE part (default dd/MM/yyyy). The time is appended as HH:mm. */
2339
2627
  format = input(formatDdMmYyyy, ...(ngDevMode ? [{ debugName: "format" }] : []));
2628
+ /** Visible label of the time editor (forwarded to the calendar). See {@link showTime}. */
2629
+ timeLabel = input('Heure', ...(ngDevMode ? [{ debugName: "timeLabel" }] : []));
2630
+ /** Accessible name of the hours field (forwarded to the calendar). */
2631
+ hoursLabel = input('Heures', ...(ngDevMode ? [{ debugName: "hoursLabel" }] : []));
2632
+ /** Accessible name of the minutes field (forwarded to the calendar). */
2633
+ minutesLabel = input('Minutes', ...(ngDevMode ? [{ debugName: "minutesLabel" }] : []));
2634
+ /** Visible text of the calendar's "done" action, shown in the overlay when {@link showTime}. */
2635
+ doneLabel = input('Terminé', ...(ngDevMode ? [{ debugName: "doneLabel" }] : []));
2340
2636
  /**
2341
2637
  * Accessible name for the clear button. French default so existing consumers are unchanged, but an
2342
2638
  * app serving more than one language MUST translate it — it is an icon-only control, so this string
@@ -2372,7 +2668,9 @@ class SdsDatePicker {
2372
2668
  isDisabled = computed(() => this.disabled() || this.cvaDisabled(), ...(ngDevMode ? [{ debugName: "isDisabled" }] : []));
2373
2669
  displayValue = computed(() => {
2374
2670
  const v = this.value();
2375
- return v ? this.format()(v) : '';
2671
+ if (!v)
2672
+ return '';
2673
+ return this.showTime() ? `${this.format()(v)} ${formatHhMm(v)}` : this.format()(v);
2376
2674
  }, ...(ngDevMode ? [{ debugName: "displayValue" }] : []));
2377
2675
  /** Whether the clear button is shown (affects the field's right padding). */
2378
2676
  showClear = computed(() => this.clearable() && !!this.value() && !this.isDisabled(), ...(ngDevMode ? [{ debugName: "showClear" }] : []));
@@ -2424,6 +2722,57 @@ class SdsDatePicker {
2424
2722
  onCalendarValue(v) {
2425
2723
  this.setValue(v);
2426
2724
  }
2725
+ /**
2726
+ * A day was clicked in the overlay. Without a time editor, a day click is the whole selection, so
2727
+ * close. With showTime, the user still needs to set the time, so keep the panel open (they close it
2728
+ * with the "done" action, a click away, or Escape).
2729
+ */
2730
+ onDateSelect() {
2731
+ if (!this.showTime())
2732
+ this.close(true);
2733
+ }
2734
+ /**
2735
+ * Escape closes the panel and consumes the event while the panel is open, so an ancestor modal does
2736
+ * not also dismiss on the same keystroke (mirrors sds-select). When the panel is already closed, the
2737
+ * event passes through so Escape can dismiss whatever contains the field.
2738
+ */
2739
+ onEscape(event) {
2740
+ if (!this.open())
2741
+ return;
2742
+ event.preventDefault();
2743
+ this.close(true);
2744
+ }
2745
+ /** The readonly trigger is not a button, so open the overlay on Enter / Space / ArrowDown too. */
2746
+ onTriggerKeydown(event) {
2747
+ event.preventDefault(); // stop Space/ArrowDown scrolling and Enter submitting an enclosing form
2748
+ if (!this.isDisabled() && !this.open())
2749
+ this.openPanel();
2750
+ }
2751
+ /**
2752
+ * Self-contained Tab trap for the overlay. The panel is relocated to document.body, so it sits
2753
+ * outside any ancestor modal's focus trap; without this, tabbing off the last control would land on
2754
+ * the page behind the dialog. Keeps Tab / Shift+Tab cycling within the panel's own focusables.
2755
+ */
2756
+ onPanelKeydown(event) {
2757
+ if (event.key !== 'Tab' || !this.panelEl)
2758
+ return;
2759
+ const sel = 'a[href],button:not([disabled]):not([tabindex="-1"]),input:not([disabled]),' +
2760
+ '[tabindex]:not([tabindex="-1"])';
2761
+ const items = Array.from(this.panelEl.querySelectorAll(sel)).filter((el) => el.offsetParent !== null);
2762
+ if (items.length === 0)
2763
+ return;
2764
+ const first = items[0];
2765
+ const last = items[items.length - 1];
2766
+ const active = document.activeElement;
2767
+ if (event.shiftKey && (active === first || !this.panelEl.contains(active))) {
2768
+ event.preventDefault();
2769
+ last.focus();
2770
+ }
2771
+ else if (!event.shiftKey && active === last) {
2772
+ event.preventDefault();
2773
+ first.focus();
2774
+ }
2775
+ }
2427
2776
  onDocumentClick(event) {
2428
2777
  if (!this.open())
2429
2778
  return;
@@ -2509,7 +2858,7 @@ class SdsDatePicker {
2509
2858
  this.cvaDisabled.set(isDisabled);
2510
2859
  }
2511
2860
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsDatePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
2512
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdsDatePicker, isStandalone: true, selector: "sds-date-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", 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 }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, inline: { classPropertyName: "inline", publicName: "inline", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null }, openCalendarLabel: { classPropertyName: "openCalendarLabel", publicName: "openCalendarLabel", isSignal: true, isRequired: false, transformFunction: null }, closeCalendarLabel: { classPropertyName: "closeCalendarLabel", publicName: "closeCalendarLabel", isSignal: true, isRequired: false, transformFunction: null }, panelLabel: { classPropertyName: "panelLabel", publicName: "panelLabel", isSignal: true, isRequired: false, transformFunction: null }, calendarLabel: { classPropertyName: "calendarLabel", publicName: "calendarLabel", isSignal: true, isRequired: false, transformFunction: null }, previousLabel: { classPropertyName: "previousLabel", publicName: "previousLabel", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null }, todayActionLabel: { classPropertyName: "todayActionLabel", publicName: "todayActionLabel", isSignal: true, isRequired: false, transformFunction: null }, clearActionLabel: { classPropertyName: "clearActionLabel", publicName: "clearActionLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)", "keydown.escape": "close(true)" }, classAttribute: "block" }, providers: [
2861
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.25", type: SdsDatePicker, isStandalone: true, selector: "sds-date-picker", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", 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 }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, inline: { classPropertyName: "inline", publicName: "inline", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, showActions: { classPropertyName: "showActions", publicName: "showActions", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, showTime: { classPropertyName: "showTime", publicName: "showTime", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, timeLabel: { classPropertyName: "timeLabel", publicName: "timeLabel", isSignal: true, isRequired: false, transformFunction: null }, hoursLabel: { classPropertyName: "hoursLabel", publicName: "hoursLabel", isSignal: true, isRequired: false, transformFunction: null }, minutesLabel: { classPropertyName: "minutesLabel", publicName: "minutesLabel", isSignal: true, isRequired: false, transformFunction: null }, doneLabel: { classPropertyName: "doneLabel", publicName: "doneLabel", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null }, openCalendarLabel: { classPropertyName: "openCalendarLabel", publicName: "openCalendarLabel", isSignal: true, isRequired: false, transformFunction: null }, closeCalendarLabel: { classPropertyName: "closeCalendarLabel", publicName: "closeCalendarLabel", isSignal: true, isRequired: false, transformFunction: null }, panelLabel: { classPropertyName: "panelLabel", publicName: "panelLabel", isSignal: true, isRequired: false, transformFunction: null }, calendarLabel: { classPropertyName: "calendarLabel", publicName: "calendarLabel", isSignal: true, isRequired: false, transformFunction: null }, previousLabel: { classPropertyName: "previousLabel", publicName: "previousLabel", isSignal: true, isRequired: false, transformFunction: null }, nextLabel: { classPropertyName: "nextLabel", publicName: "nextLabel", isSignal: true, isRequired: false, transformFunction: null }, todayActionLabel: { classPropertyName: "todayActionLabel", publicName: "todayActionLabel", isSignal: true, isRequired: false, transformFunction: null }, clearActionLabel: { classPropertyName: "clearActionLabel", publicName: "clearActionLabel", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)", "keydown.escape": "onEscape($event)" }, classAttribute: "block" }, providers: [
2513
2862
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => SdsDatePicker), multi: true },
2514
2863
  ], viewQueries: [{ propertyName: "calendar", first: true, predicate: SdsCalendar, descendants: true, isSignal: true }, { propertyName: "trigger", first: true, predicate: ["trigger"], descendants: true, isSignal: true }], ngImport: i0, template: `
2515
2864
  @if (label()) {
@@ -2526,6 +2875,10 @@ class SdsDatePicker {
2526
2875
  [firstDayOfWeek]="firstDayOfWeek()"
2527
2876
  [locale]="locale()"
2528
2877
  [showActions]="showActions()"
2878
+ [showTime]="showTime()"
2879
+ [timeLabel]="timeLabel()"
2880
+ [hoursLabel]="hoursLabel()"
2881
+ [minutesLabel]="minutesLabel()"
2529
2882
  [calendarLabel]="calendarLabel()"
2530
2883
  [previousLabel]="previousLabel()"
2531
2884
  [nextLabel]="nextLabel()"
@@ -2551,6 +2904,9 @@ class SdsDatePicker {
2551
2904
  [attr.aria-haspopup]="'dialog'"
2552
2905
  [attr.aria-expanded]="open()"
2553
2906
  [attr.aria-label]="!label() && ariaLabel() ? ariaLabel() : null"
2907
+ (keydown.enter)="onTriggerKeydown($event)"
2908
+ (keydown.space)="onTriggerKeydown($event)"
2909
+ (keydown.arrowdown)="onTriggerKeydown($event)"
2554
2910
  class="w-full cursor-pointer bg-transparent pl-3.5 text-ink outline-none placeholder:text-ink-faint disabled:cursor-not-allowed"
2555
2911
  [class.pr-20]="showClear()"
2556
2912
  [class.pr-11]="!showClear()"
@@ -2587,7 +2943,8 @@ class SdsDatePicker {
2587
2943
  role="dialog"
2588
2944
  aria-modal="false"
2589
2945
  [attr.aria-label]="panelLabel()"
2590
- (keydown.escape)="close(true)"
2946
+ (keydown.escape)="onEscape($event)"
2947
+ (keydown)="onPanelKeydown($event)"
2591
2948
  >
2592
2949
  <sds-calendar
2593
2950
  [value]="value()"
@@ -2596,13 +2953,20 @@ class SdsDatePicker {
2596
2953
  [firstDayOfWeek]="firstDayOfWeek()"
2597
2954
  [locale]="locale()"
2598
2955
  [showActions]="showActions()"
2956
+ [showTime]="showTime()"
2957
+ [showDone]="showTime()"
2958
+ [timeLabel]="timeLabel()"
2959
+ [hoursLabel]="hoursLabel()"
2960
+ [minutesLabel]="minutesLabel()"
2961
+ [doneLabel]="doneLabel()"
2599
2962
  [calendarLabel]="calendarLabel()"
2600
2963
  [previousLabel]="previousLabel()"
2601
2964
  [nextLabel]="nextLabel()"
2602
2965
  [todayActionLabel]="todayActionLabel()"
2603
2966
  [clearActionLabel]="clearActionLabel()"
2604
2967
  (valueChange)="onCalendarValue($event)"
2605
- (dateSelect)="close(true)"
2968
+ (dateSelect)="onDateSelect()"
2969
+ (done)="close(true)"
2606
2970
  />
2607
2971
  </div>
2608
2972
  }
@@ -2615,7 +2979,7 @@ class SdsDatePicker {
2615
2979
  @if (error()) {
2616
2980
  <p class="mt-1.5 text-xs font-medium text-danger">{{ error() }}</p>
2617
2981
  }
2618
- `, isInline: true, dependencies: [{ kind: "component", type: SdsIcon, selector: "sds-icon", inputs: ["name", "size", "strokeWidth"] }, { kind: "component", type: SdsCalendar, selector: "sds-calendar", inputs: ["value", "min", "max", "firstDayOfWeek", "locale", "showActions", "calendarLabel", "previousLabel", "nextLabel", "todayActionLabel", "clearActionLabel"], outputs: ["valueChange", "dateSelect"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2982
+ `, isInline: true, dependencies: [{ kind: "component", type: SdsIcon, selector: "sds-icon", inputs: ["name", "size", "strokeWidth"] }, { kind: "component", type: SdsCalendar, selector: "sds-calendar", inputs: ["value", "min", "max", "firstDayOfWeek", "locale", "showActions", "showTime", "showDone", "timeLabel", "hoursLabel", "minutesLabel", "doneLabel", "calendarLabel", "previousLabel", "nextLabel", "todayActionLabel", "clearActionLabel"], outputs: ["valueChange", "dateSelect", "done"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2619
2983
  }
2620
2984
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImport: i0, type: SdsDatePicker, decorators: [{
2621
2985
  type: Component,
@@ -2629,7 +2993,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
2629
2993
  host: {
2630
2994
  class: 'block',
2631
2995
  '(document:click)': 'onDocumentClick($event)',
2632
- '(keydown.escape)': 'close(true)',
2996
+ '(keydown.escape)': 'onEscape($event)',
2633
2997
  },
2634
2998
  template: `
2635
2999
  @if (label()) {
@@ -2646,6 +3010,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
2646
3010
  [firstDayOfWeek]="firstDayOfWeek()"
2647
3011
  [locale]="locale()"
2648
3012
  [showActions]="showActions()"
3013
+ [showTime]="showTime()"
3014
+ [timeLabel]="timeLabel()"
3015
+ [hoursLabel]="hoursLabel()"
3016
+ [minutesLabel]="minutesLabel()"
2649
3017
  [calendarLabel]="calendarLabel()"
2650
3018
  [previousLabel]="previousLabel()"
2651
3019
  [nextLabel]="nextLabel()"
@@ -2671,6 +3039,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
2671
3039
  [attr.aria-haspopup]="'dialog'"
2672
3040
  [attr.aria-expanded]="open()"
2673
3041
  [attr.aria-label]="!label() && ariaLabel() ? ariaLabel() : null"
3042
+ (keydown.enter)="onTriggerKeydown($event)"
3043
+ (keydown.space)="onTriggerKeydown($event)"
3044
+ (keydown.arrowdown)="onTriggerKeydown($event)"
2674
3045
  class="w-full cursor-pointer bg-transparent pl-3.5 text-ink outline-none placeholder:text-ink-faint disabled:cursor-not-allowed"
2675
3046
  [class.pr-20]="showClear()"
2676
3047
  [class.pr-11]="!showClear()"
@@ -2707,7 +3078,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
2707
3078
  role="dialog"
2708
3079
  aria-modal="false"
2709
3080
  [attr.aria-label]="panelLabel()"
2710
- (keydown.escape)="close(true)"
3081
+ (keydown.escape)="onEscape($event)"
3082
+ (keydown)="onPanelKeydown($event)"
2711
3083
  >
2712
3084
  <sds-calendar
2713
3085
  [value]="value()"
@@ -2716,13 +3088,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
2716
3088
  [firstDayOfWeek]="firstDayOfWeek()"
2717
3089
  [locale]="locale()"
2718
3090
  [showActions]="showActions()"
3091
+ [showTime]="showTime()"
3092
+ [showDone]="showTime()"
3093
+ [timeLabel]="timeLabel()"
3094
+ [hoursLabel]="hoursLabel()"
3095
+ [minutesLabel]="minutesLabel()"
3096
+ [doneLabel]="doneLabel()"
2719
3097
  [calendarLabel]="calendarLabel()"
2720
3098
  [previousLabel]="previousLabel()"
2721
3099
  [nextLabel]="nextLabel()"
2722
3100
  [todayActionLabel]="todayActionLabel()"
2723
3101
  [clearActionLabel]="clearActionLabel()"
2724
3102
  (valueChange)="onCalendarValue($event)"
2725
- (dateSelect)="close(true)"
3103
+ (dateSelect)="onDateSelect()"
3104
+ (done)="close(true)"
2726
3105
  />
2727
3106
  </div>
2728
3107
  }
@@ -2737,7 +3116,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
2737
3116
  }
2738
3117
  `,
2739
3118
  }]
2740
- }], 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 }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", 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 }] }] } });
3119
+ }], 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 }] }] } });
2741
3120
  let nextId$6 = 0;
2742
3121
 
2743
3122
  const SIZES$4 = {
@@ -7785,5 +8164,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.25", ngImpo
7785
8164
  * Generated bundle index. Do not edit.
7786
8165
  */
7787
8166
 
7788
- export { SDS_ICONS, SDS_PHONE_COUNTRIES, SdsAccordion, SdsAccordionContent, SdsAccordionHeader, SdsAccordionPanel, SdsAccordionStore, SdsAvatar, SdsBadge, SdsButton, SdsCalendar, SdsCard, SdsCheckbox, SdsDatePicker, SdsIcon, SdsInput, SdsMultiSelect, SdsNavGroup, SdsNavItem, SdsOtpInput, SdsPaginator, SdsPhoneInput, SdsSelect, SdsShell, SdsSidebar, SdsTab, SdsTabList, SdsTabPanel, SdsTabPanels, SdsTable, SdsTableCell, SdsTableRowExpansion, SdsTabs, SdsTabsStore, SdsTextarea, SdsToggleSwitch, SdsTopbar, SidebarStore, addDays, addMonths, addMonthsKeepDay, formatDdMmYyyy, isOutOfRange, isSameDay, isoDay, sdsFormatNational, sdsMatchDialCode, sdsNormalizeSignificant, startOfDay, startOfMonth };
8167
+ export { SDS_ICONS, SDS_PHONE_COUNTRIES, SdsAccordion, SdsAccordionContent, SdsAccordionHeader, SdsAccordionPanel, SdsAccordionStore, SdsAvatar, SdsBadge, SdsButton, SdsCalendar, SdsCard, SdsCheckbox, SdsDatePicker, SdsIcon, SdsInput, SdsMultiSelect, SdsNavGroup, SdsNavItem, SdsOtpInput, SdsPaginator, SdsPhoneInput, SdsSelect, SdsShell, SdsSidebar, SdsTab, SdsTabList, SdsTabPanel, SdsTabPanels, SdsTable, SdsTableCell, SdsTableRowExpansion, SdsTabs, SdsTabsStore, SdsTextarea, SdsToggleSwitch, SdsTopbar, SidebarStore, addDays, addMonths, addMonthsKeepDay, formatDdMmYyyy, formatHhMm, isOutOfRange, isSameDay, isoDay, pad2, sdsFormatNational, sdsMatchDialCode, sdsNormalizeSignificant, startOfDay, startOfMonth };
7789
8168
  //# sourceMappingURL=besaitech-ng-design-system.mjs.map