@edmicro/olkit 1.1.2 → 1.1.3

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 _angular_core from '@angular/core';
2
- import { OnInit, AfterContentInit, OnDestroy, TemplateRef, ElementRef, QueryList, WritableSignal } from '@angular/core';
2
+ import { OnInit, AfterContentInit, OnDestroy, TemplateRef, ElementRef, QueryList } from '@angular/core';
3
3
  import { ControlValueAccessor } from '@angular/forms';
4
4
  import * as _edmicro_olkit from '@edmicro/olkit';
5
5
  import { SafeHtml } from '@angular/platform-browser';
@@ -174,6 +174,7 @@ declare const boDau: typeof stripDiacritics;
174
174
  */
175
175
  declare class OlCommand {
176
176
  private readonly focusTrap;
177
+ private readonly overlayContainer;
177
178
  private readonly destroyRef;
178
179
  private readonly panel;
179
180
  private readonly searchInput;
@@ -348,6 +349,10 @@ type AlertDialogTone = 'danger' | 'warning' | 'brand';
348
349
  * Build vẫn xanh, chỉ bộ đọc màn hình là đọc sai.
349
350
  */
350
351
  declare class OlAlertDialog {
352
+ private readonly overlayContainer;
353
+ /** Hàm gỡ khỏi ngăn xếp Escape. `null` khi đang đóng. */
354
+ private releaseEscape;
355
+ constructor();
351
356
  readonly isOpen: _angular_core.ModelSignal<boolean>;
352
357
  /**
353
358
  * `heading` chứ không phải `title`: `title` là thuộc tính HTML có sẵn, đặt
@@ -372,7 +377,6 @@ declare class OlAlertDialog {
372
377
  * đòi `alertdialog` phải đóng được bằng Esc, nên xử lý ở đây, và cho nó rơi
373
378
  * vào nhánh AN TOÀN chứ không phải nhánh xác nhận.
374
379
  */
375
- onEscape(): void;
376
380
  onConfirm(): void;
377
381
  onCancel(): void;
378
382
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlAlertDialog, never>;
@@ -510,7 +514,19 @@ declare class OlAvatarGroup {
510
514
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlAvatarGroup, "ol-avatar-group", never, { "size": { "alias": "size"; "required": false; "isSignal": true; }; "counter": { "alias": "counter"; "required": false; "isSignal": true; }; "counterAriaLabel": { "alias": "counterAriaLabel"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
511
515
  }
512
516
 
513
- type BadgeTheme = 'brand' | 'gray' | 'white' | 'danger' | 'warning' | 'success' | 'default' | 'dark' | 'red' | 'yellow' | 'green';
517
+ /**
518
+ * Sáu màu CHUẨN (Figma `ol-badge` #1146:22250, trục `Theme`, 126 biến thể):
519
+ * Gray · White · Brand · Danger · Warning · Success.
520
+ *
521
+ * `ghost` là màu THỨ BẢY, CHƯA CÓ TRONG FIGMA — thêm 2026-09-23 theo yêu cầu,
522
+ * bê khuôn từ `ol-button` (nền trong suốt, chữ `text-heading`). Đừng gỡ khi
523
+ * đối chiếu Figma thấy thừa; còn nợ vẽ biến thể `Theme=Ghost`.
524
+ *
525
+ * Năm giá trị cuối là BÍ DANH, `normalizedColor()` gập về sáu màu chuẩn.
526
+ */
527
+ type BadgeColor = 'brand' | 'gray' | 'white' | 'danger' | 'warning' | 'success' | 'ghost' | 'default' | 'dark' | 'red' | 'yellow' | 'green';
528
+ /** @deprecated Tên cũ của `BadgeColor`. Giữ để không phá mã đang chạy. */
529
+ type BadgeTheme = BadgeColor;
514
530
  type BadgeSize = 'xs' | 'sm' | 'lg';
515
531
  type BadgeShape = 'square' | 'pill';
516
532
  /**
@@ -523,8 +539,21 @@ type BadgeShape = 'square' | 'pill';
523
539
  */
524
540
  type BadgeType = 'default' | 'dot' | 'avatar' | 'loader' | 'secondary';
525
541
  declare class OlBadge {
526
- readonly theme: _angular_core.InputSignal<BadgeTheme>;
527
- readonly color: _angular_core.InputSignal<BadgeTheme>;
542
+ /**
543
+ * Màu ngữ nghĩa của nhãn. Tên `color` cho khớp `ol-button` và 9 component
544
+ * khác trong thư viện — badge từng là chỗ duy nhất gọi trục này là `theme`.
545
+ */
546
+ readonly color: _angular_core.InputSignal<BadgeColor>;
547
+ /**
548
+ * @deprecated Dùng `color`.
549
+ *
550
+ * Bản cũ hoà giải hai input bằng cách SO VỚI GIÁ TRỊ MẶC ĐỊNH — `theme`
551
+ * thắng trừ khi nó bằng `'gray'` — nên `[color]="'brand'"` kèm
552
+ * `theme="danger"` thì `color` bị nuốt im lặng, không gì báo lỗi.
553
+ *
554
+ * Nay: cái nào được TRUYỀN thì thắng. Chuỗi rỗng là "không truyền".
555
+ */
556
+ readonly theme: _angular_core.InputSignal<"" | BadgeColor>;
528
557
  readonly size: _angular_core.InputSignal<BadgeSize>;
529
558
  readonly shape: _angular_core.InputSignal<BadgeShape>;
530
559
  readonly rounded: _angular_core.InputSignal<boolean>;
@@ -539,7 +568,7 @@ declare class OlBadge {
539
568
  readonly removable: _angular_core.InputSignal<boolean>;
540
569
  readonly href: _angular_core.InputSignal<string | null>;
541
570
  readonly dismiss: _angular_core.OutputEmitterRef<MouseEvent>;
542
- readonly normalizedTheme: _angular_core.Signal<string>;
571
+ readonly normalizedColor: _angular_core.Signal<string>;
543
572
  readonly isPill: _angular_core.Signal<boolean>;
544
573
  readonly badgeClasses: _angular_core.Signal<string>;
545
574
  /**
@@ -551,7 +580,7 @@ declare class OlBadge {
551
580
  readonly dotClasses: _angular_core.Signal<"bg-fg-brand-strong" | "bg-fg-danger-strong" | "bg-fg-warning" | "bg-success-strong" | "bg-heading">;
552
581
  onDismiss(event: MouseEvent): void;
553
582
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlBadge, never>;
554
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlBadge, "ol-badge", never, { "theme": { "alias": "theme"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "shape": { "alias": "shape"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "dot": { "alias": "dot"; "required": false; "isSignal": true; }; "leftIcon": { "alias": "leftIcon"; "required": false; "isSignal": true; }; "rightIcon": { "alias": "rightIcon"; "required": false; "isSignal": true; }; "avatar": { "alias": "avatar"; "required": false; "isSignal": true; }; "avatarText": { "alias": "avatarText"; "required": false; "isSignal": true; }; "secondaryText": { "alias": "secondaryText"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "removable": { "alias": "removable"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; }, { "dismiss": "dismiss"; }, never, ["*"], true, never>;
583
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlBadge, "ol-badge", never, { "color": { "alias": "color"; "required": false; "isSignal": true; }; "theme": { "alias": "theme"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "shape": { "alias": "shape"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "dot": { "alias": "dot"; "required": false; "isSignal": true; }; "leftIcon": { "alias": "leftIcon"; "required": false; "isSignal": true; }; "rightIcon": { "alias": "rightIcon"; "required": false; "isSignal": true; }; "avatar": { "alias": "avatar"; "required": false; "isSignal": true; }; "avatarText": { "alias": "avatarText"; "required": false; "isSignal": true; }; "secondaryText": { "alias": "secondaryText"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "removable": { "alias": "removable"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; }, { "dismiss": "dismiss"; }, never, ["*"], true, never>;
555
584
  }
556
585
 
557
586
  type BannerVariant = 'brand' | 'gradient' | 'warning' | 'dark' | 'subtle';
@@ -643,12 +672,28 @@ declare class OlBreadcrumbItem {
643
672
  readonly status: _angular_core.InputSignal<BreadcrumbItemStatus>;
644
673
  readonly showSeparator: _angular_core.InputSignal<boolean>;
645
674
  readonly separator: _angular_core.InputSignal<BreadcrumbSeparator | null>;
675
+ /**
676
+ * Chặng không bấm được — ví dụ cấp cha mà người dùng chưa có quyền xem.
677
+ *
678
+ * VƯỢT FIGMA CÓ CHỦ Ý (2026-09-23): `ol-breadcrumb-item` #1148:31348 chỉ vẽ
679
+ * ba Status — Initial · Hover · Active. Không có Disabled. Đây là mở rộng
680
+ * theo yêu cầu, không phải đọc sót thiết kế; đừng gỡ khi đối chiếu Figma.
681
+ *
682
+ * Khác `current`: `current` là trang ĐANG đứng (mục cuối, có `aria-current`),
683
+ * còn `disabled` là chặng có tồn tại nhưng không đi tới được.
684
+ */
685
+ readonly disabled: _angular_core.InputSignal<boolean>;
646
686
  private readonly parentBreadcrumb;
647
687
  readonly isCurrent: _angular_core.Signal<boolean>;
648
688
  readonly effectiveSeparator: _angular_core.Signal<BreadcrumbSeparator>;
689
+ /**
690
+ * `disabled` phải chặn ở ĐÂY, không chỉ đổi màu: còn sinh thẻ `<a href>` thì
691
+ * vẫn bấm được, vẫn Tab tới được, vẫn mở bằng chuột giữa — tô mờ chỉ làm
692
+ * người dùng tưởng nó hỏng.
693
+ */
649
694
  readonly isLink: _angular_core.Signal<boolean>;
650
695
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlBreadcrumbItem, never>;
651
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlBreadcrumbItem, "ol-breadcrumb-item", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "routerLink": { "alias": "routerLink"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "current": { "alias": "current"; "required": false; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "showSeparator": { "alias": "showSeparator"; "required": false; "isSignal": true; }; "separator": { "alias": "separator"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
696
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlBreadcrumbItem, "ol-breadcrumb-item", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "routerLink": { "alias": "routerLink"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "current": { "alias": "current"; "required": false; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "showSeparator": { "alias": "showSeparator"; "required": false; "isSignal": true; }; "separator": { "alias": "separator"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
652
697
  }
653
698
 
654
699
  type AppDevice = 'appstore' | 'googleplay' | 'google-play' | 'apple' | 'google';
@@ -957,10 +1002,26 @@ declare class OlDatepicker implements ControlValueAccessor {
957
1002
  private readonly overlayContainer;
958
1003
  /** Hàm trả panel về chỗ cũ + hàm ngắt theo dõi vị trí. */
959
1004
  private detachPanel;
1005
+ /**
1006
+ * Hàm gỡ khỏi ngăn xếp Escape. `null` khi popup đang đóng.
1007
+ *
1008
+ * Xem `OlOverlayContainer.register` — chỉ lớp TRÊN CÙNG đóng khi nhấn
1009
+ * Escape, nên datepicker mở trong modal không còn kéo modal đóng theo.
1010
+ */
1011
+ private releaseEscape;
960
1012
  /** Hàm gỡ theo dõi trần chiều cao popup. */
961
1013
  private stopTrackingHeight;
962
1014
  readonly isOpen: _angular_core.WritableSignal<boolean>;
963
1015
  readonly inputValue: _angular_core.WritableSignal<string>;
1016
+ /**
1017
+ * Có gì để xoá hay không — dựa vào CHỮ TRONG Ô, không chỉ `value`.
1018
+ *
1019
+ * `value` chỉ được đặt khi chuỗi phân tích thành ngày hợp lệ (`if (parsed)`
1020
+ * trong `onInputChange`). Gõ dở "15/0" thì ô đã có chữ mà `value` vẫn rỗng,
1021
+ * nên nút xoá không hiện — đúng lúc người dùng gõ sai và cần xoá đi gõ lại.
1022
+ * Đo /datepicker: gõ "15/0" nút không hiện, gõ đủ "15/03/2026" mới hiện.
1023
+ */
1024
+ readonly hasContent: _angular_core.Signal<boolean>;
964
1025
  private onChange;
965
1026
  private onTouched;
966
1027
  private emitAllChanges;
@@ -987,7 +1048,7 @@ declare class OlDatepicker implements ControlValueAccessor {
987
1048
  * Bỏ `py-*`: chiều cao đã cố định thì đệm dọc chỉ ép chữ, giữ `px-*` cho đệm
988
1049
  * ngang và `ps-*` cho chỗ icon lịch.
989
1050
  */
990
- readonly inputSizeClasses: _angular_core.Signal<"h-9 px-3 ps-9 text-xs rounded-md" | "h-12 px-4 ps-11 text-base rounded-md" | "h-13 px-4 ps-11 text-base rounded-md" | "h-10 px-3.5 ps-10 text-sm rounded-md">;
1051
+ readonly inputSizeClasses: _angular_core.Signal<string>;
991
1052
  /**
992
1053
  * Cỡ icon lịch theo `size` của ô nhập.
993
1054
  *
@@ -1014,7 +1075,6 @@ declare class OlDatepicker implements ControlValueAccessor {
1014
1075
  /** Ngắt theo dõi vị trí và trả panel về chỗ cũ. Gọi được nhiều lần. */
1015
1076
  private donDepPanel;
1016
1077
  onDocumentClick(event: MouseEvent): void;
1017
- onEscape(): void;
1018
1078
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlDatepicker, never>;
1019
1079
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlDatepicker, "ol-datepicker", never, { "id": { "alias": "id"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "format": { "alias": "format"; "required": false; "isSignal": true; }; "minDate": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxDate": { "alias": "maxDate"; "required": false; "isSignal": true; }; "daysDisabled": { "alias": "daysDisabled"; "required": false; "isSignal": true; }; "datesDisabled": { "alias": "datesDisabled"; "required": false; "isSignal": true; }; "datesEnabled": { "alias": "datesEnabled"; "required": false; "isSignal": true; }; "appendTo": { "alias": "appendTo"; "required": false; "isSignal": true; }; "showFooter": { "alias": "showFooter"; "required": false; "isSignal": true; }; "inline": { "alias": "inline"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "disabled": "disabledChange"; "dateChange": "dateChange"; "timestampChange": "timestampChange"; "isoChange": "isoChange"; "formattedChange": "formattedChange"; }, never, never, true, never>;
1020
1080
  }
@@ -1073,11 +1133,18 @@ declare class OlDateRangePicker implements ControlValueAccessor {
1073
1133
  private readonly overlayContainer;
1074
1134
  /** Hàm trả panel về chỗ cũ + hàm ngắt theo dõi vị trí. */
1075
1135
  private detachPanel;
1136
+ /** Hàm gỡ khỏi ngăn xếp Escape. `null` khi đang đóng. */
1137
+ private releaseEscape;
1076
1138
  /** Hàm gỡ theo dõi trần chiều cao popup. */
1077
1139
  private stopTrackingHeight;
1078
1140
  readonly isOpen: _angular_core.WritableSignal<boolean>;
1079
1141
  readonly startInputValue: _angular_core.WritableSignal<string>;
1080
1142
  readonly endInputValue: _angular_core.WritableSignal<string>;
1143
+ /**
1144
+ * Có gì để xoá hay không — dựa vào CHỮ TRONG Ô, không chỉ `value`.
1145
+ * Cùng lý do với `ol-datepicker`: `value` chỉ đặt khi chuỗi phân tích được.
1146
+ */
1147
+ readonly hasContent: _angular_core.Signal<boolean>;
1081
1148
  private onChange;
1082
1149
  private onTouched;
1083
1150
  constructor();
@@ -1093,7 +1160,7 @@ declare class OlDateRangePicker implements ControlValueAccessor {
1093
1160
  * dùng y hệt `py-2 / py-2.5 / py-3.5` nên lệch cùng một kiểu; sửa một nửa là
1094
1161
  * để lại đúng lỗi đó ở chỗ khác.
1095
1162
  */
1096
- readonly inputSizeClasses: _angular_core.Signal<"h-9 px-3 text-xs rounded-md" | "h-12 px-4 text-base rounded-md" | "h-13 px-4 text-base rounded-md" | "h-10 px-3.5 text-sm rounded-md">;
1163
+ readonly inputSizeClasses: _angular_core.Signal<string>;
1097
1164
  /**
1098
1165
  * Cỡ cho biến thể `joined` — khung bọc mang viền, hai input bên trong trong
1099
1166
  * suốt. Phải tách khỏi `inputSizeClasses()`: ở đây chiều cao thuộc về KHUNG,
@@ -1127,7 +1194,6 @@ declare class OlDateRangePicker implements ControlValueAccessor {
1127
1194
  /** Ngắt theo dõi vị trí và trả panel về chỗ cũ. Gọi được nhiều lần. */
1128
1195
  private donDepPanel;
1129
1196
  onDocumentClick(event: MouseEvent): void;
1130
- onEscape(): void;
1131
1197
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlDateRangePicker, never>;
1132
1198
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlDateRangePicker, "ol-date-range-picker", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "startPlaceholder": { "alias": "startPlaceholder"; "required": false; "isSignal": true; }; "endPlaceholder": { "alias": "endPlaceholder"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "fromLabel": { "alias": "fromLabel"; "required": false; "isSignal": true; }; "toLabel": { "alias": "toLabel"; "required": false; "isSignal": true; }; "showInfoIcon": { "alias": "showInfoIcon"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "dualMonth": { "alias": "dualMonth"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "format": { "alias": "format"; "required": false; "isSignal": true; }; "minDate": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxDate": { "alias": "maxDate"; "required": false; "isSignal": true; }; "daysDisabled": { "alias": "daysDisabled"; "required": false; "isSignal": true; }; "datesDisabled": { "alias": "datesDisabled"; "required": false; "isSignal": true; }; "datesEnabled": { "alias": "datesEnabled"; "required": false; "isSignal": true; }; "appendTo": { "alias": "appendTo"; "required": false; "isSignal": true; }; "showFooter": { "alias": "showFooter"; "required": false; "isSignal": true; }; "presets": { "alias": "presets"; "required": false; "isSignal": true; }; "inline": { "alias": "inline"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "disabled": "disabledChange"; "rangeChange": "rangeChange"; }, never, never, true, never>;
1133
1199
  }
@@ -1263,7 +1329,7 @@ declare class OlDatepickerPopup {
1263
1329
  /**
1264
1330
  * Trần chiều cao + cuộn CHỈ cho popup nổi.
1265
1331
  *
1266
- * Dùng `[class]` trả chuỗi chứ KHÔNG `[class.max-h-[var(...)]]`: tên class
1332
+ * Dùng `[class]` trả chuỗi chứ KHÔNG `[class.max-h-…]` với giá trị tuỳ ý: tên class
1267
1333
  * chứa dấu chấm và ngoặc vuông nên Angular cắt hỏng tên khi dùng class
1268
1334
  * binding từng cái (`[class.h-1.5]` ra `h-1`).
1269
1335
  */
@@ -1355,6 +1421,7 @@ type DrawerPlacement = 'left' | 'right' | 'top' | 'bottom';
1355
1421
  type DrawerSize = 'sm' | 'base' | 'lg' | 'xl' | 'full';
1356
1422
  declare class OlDrawer {
1357
1423
  private readonly focusTrap;
1424
+ private readonly overlayContainer;
1358
1425
  private readonly destroyRef;
1359
1426
  private readonly panel;
1360
1427
  readonly isOpen: _angular_core.ModelSignal<boolean>;
@@ -1406,11 +1473,18 @@ declare class OlDrawerHeader {
1406
1473
  */
1407
1474
  readonly headingLevel: _angular_core.InputSignal<1 | 2 | 3 | 4 | 5 | 6>;
1408
1475
  readonly heading: _angular_core.InputSignal<string>;
1476
+ /** Icon đầu tiêu đề. Rỗng thì KHÔNG dựng khung. Xem `ol-modal-header`. */
1477
+ readonly icon: _angular_core.InputSignal<string>;
1478
+ /** Mô tả phụ dưới tiêu đề. Cùng tên với `ol-modal-header`. */
1479
+ readonly description: _angular_core.InputSignal<string>;
1480
+ /** @deprecated Dùng `description`. Giữ để không phá mã đang chạy. */
1409
1481
  readonly helperText: _angular_core.InputSignal<string>;
1482
+ /** Cái nào được TRUYỀN thì thắng. Xem chú thích ở `ol-modal-header`. */
1483
+ readonly descriptionText: _angular_core.Signal<string>;
1410
1484
  readonly showClose: _angular_core.InputSignal<boolean>;
1411
1485
  readonly closeClick: _angular_core.OutputEmitterRef<void>;
1412
1486
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlDrawerHeader, never>;
1413
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlDrawerHeader, "ol-drawer-header", never, { "headingLevel": { "alias": "headingLevel"; "required": false; "isSignal": true; }; "heading": { "alias": "heading"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "showClose": { "alias": "showClose"; "required": false; "isSignal": true; }; }, { "closeClick": "closeClick"; }, never, ["*"], true, never>;
1487
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlDrawerHeader, "ol-drawer-header", never, { "headingLevel": { "alias": "headingLevel"; "required": false; "isSignal": true; }; "heading": { "alias": "heading"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "showClose": { "alias": "showClose"; "required": false; "isSignal": true; }; }, { "closeClick": "closeClick"; }, never, ["*"], true, never>;
1414
1488
  }
1415
1489
 
1416
1490
  /** Khớp trục `Type` của Figma ol-drawer-footer (node 1149:37232). */
@@ -1450,6 +1524,8 @@ declare class OlDropdown {
1450
1524
  private cleanupAutoUpdate;
1451
1525
  /** Hàm trả menu về chỗ cũ khi đóng. */
1452
1526
  private detachMenu;
1527
+ /** Hàm gỡ khỏi ngăn xếp Escape. `null` khi đang đóng. */
1528
+ private releaseEscape;
1453
1529
  readonly label: _angular_core.InputSignal<string | null>;
1454
1530
  readonly isOpen: _angular_core.ModelSignal<boolean>;
1455
1531
  /**
@@ -1489,7 +1565,6 @@ declare class OlDropdown {
1489
1565
  private anchorElement;
1490
1566
  private stopAutoUpdate;
1491
1567
  onDocumentClick(event: MouseEvent): void;
1492
- onEscape(): void;
1493
1568
  /** Toạ độ con trỏ lần bấm chuột phải gần nhất, đổ vào mốc ẩn. */
1494
1569
  readonly cursorX: _angular_core.WritableSignal<number>;
1495
1570
  readonly cursorY: _angular_core.WritableSignal<number>;
@@ -1911,6 +1986,20 @@ declare class OlInput implements ControlValueAccessor {
1911
1986
  readonly addOnIcon: _angular_core.InputSignal<boolean>;
1912
1987
  readonly leftIcon: _angular_core.InputSignal<boolean>;
1913
1988
  readonly rightIcon: _angular_core.InputSignal<boolean>;
1989
+ /**
1990
+ * Hiện nút xoá khi ô có chữ.
1991
+ *
1992
+ * Mặc định **TẮT**, khác `ol-select` và `ol-datepicker` (mặc định bật).
1993
+ * Lý do: hai cái kia chọn từ danh sách nên xoá là thao tác thường gặp, còn
1994
+ * ô nhập chữ thì người dùng vẫn chọn-hết-rồi-gõ-đè như mọi ô nhập khác.
1995
+ * Bật sẵn cho MỌI `ol-input` đang chạy là thêm một nút vào giao diện của
1996
+ * người khác mà họ không yêu cầu.
1997
+ */
1998
+ readonly clearable: _angular_core.InputSignal<boolean>;
1999
+ /** Tên trợ năng của nút xoá. Đổi được khi ô có nghĩa cụ thể. */
2000
+ readonly clearAriaLabel: _angular_core.InputSignal<string>;
2001
+ /** Phát khi người dùng bấm nút xoá — nơi dùng biết để tải lại danh sách. */
2002
+ readonly cleared: _angular_core.OutputEmitterRef<void>;
1914
2003
  readonly rightHelperText: _angular_core.InputSignal<string>;
1915
2004
  readonly id: _angular_core.InputSignal<string>;
1916
2005
  /** Id thực dùng: ưu tiên id do nơi gọi truyền, không thì dùng id tự sinh. */
@@ -1942,10 +2031,18 @@ declare class OlInput implements ControlValueAccessor {
1942
2031
  setDisabledState(isDisabled: boolean): void;
1943
2032
  /** Gọi từ template mỗi khi giá trị đổi, để form biết. */
1944
2033
  protected phatThayDoi(val: string): void;
2034
+ /**
2035
+ * Xoá nội dung ô.
2036
+ *
2037
+ * `stopPropagation` vì nút nằm TRONG thẻ bọc: thiếu nó thì cú bấm lan ra
2038
+ * thẻ bọc, và ở component có hành vi bấm-để-mở (select, datepicker) sẽ mở
2039
+ * panel ngay sau khi xoá.
2040
+ */
2041
+ protected clearValue(event: MouseEvent): void;
1945
2042
  /** Gọi khi rời ô nhập — form dùng để đánh dấu `touched`. */
1946
2043
  protected markTouched(): void;
1947
2044
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlInput, never>;
1948
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlInput, "ol-input", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "state": { "alias": "state"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "showAsterisk": { "alias": "showAsterisk"; "required": false; "isSignal": true; }; "labelIcon": { "alias": "labelIcon"; "required": false; "isSignal": true; }; "labelTooltip": { "alias": "labelTooltip"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "prefixText": { "alias": "prefixText"; "required": false; "isSignal": true; }; "suffixText": { "alias": "suffixText"; "required": false; "isSignal": true; }; "addOnIcon": { "alias": "addOnIcon"; "required": false; "isSignal": true; }; "leftIcon": { "alias": "leftIcon"; "required": false; "isSignal": true; }; "rightIcon": { "alias": "rightIcon"; "required": false; "isSignal": true; }; "rightHelperText": { "alias": "rightHelperText"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "disabled": "disabledChange"; }, never, ["[addOnIcon], [leftIcon]", "[leftIcon]", "[rightIcon]", "[rightHelperAction]"], true, never>;
2045
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlInput, "ol-input", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "state": { "alias": "state"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "showAsterisk": { "alias": "showAsterisk"; "required": false; "isSignal": true; }; "labelIcon": { "alias": "labelIcon"; "required": false; "isSignal": true; }; "labelTooltip": { "alias": "labelTooltip"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "prefixText": { "alias": "prefixText"; "required": false; "isSignal": true; }; "suffixText": { "alias": "suffixText"; "required": false; "isSignal": true; }; "addOnIcon": { "alias": "addOnIcon"; "required": false; "isSignal": true; }; "leftIcon": { "alias": "leftIcon"; "required": false; "isSignal": true; }; "rightIcon": { "alias": "rightIcon"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "clearAriaLabel": { "alias": "clearAriaLabel"; "required": false; "isSignal": true; }; "rightHelperText": { "alias": "rightHelperText"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "disabled": "disabledChange"; "cleared": "cleared"; }, never, ["[addOnIcon], [leftIcon]", "[leftIcon]", "[rightIcon]", "[rightHelperAction]"], true, never>;
1949
2046
  }
1950
2047
 
1951
2048
  type TextareaState = 'default' | 'error' | 'success';
@@ -2002,6 +2099,34 @@ declare class OlTextarea implements ControlValueAccessor {
2002
2099
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlTextarea, "ol-textarea", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "rows": { "alias": "rows"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "maxLength": { "alias": "maxLength"; "required": false; "isSignal": true; }; "showCharCount": { "alias": "showCharCount"; "required": false; "isSignal": true; }; "state": { "alias": "state"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "showAsterisk": { "alias": "showAsterisk"; "required": false; "isSignal": true; }; "commentBox": { "alias": "commentBox"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "disabled": "disabledChange"; "submitComment": "submitComment"; }, never, never, true, never>;
2003
2100
  }
2004
2101
 
2102
+ /**
2103
+ * Bảng chuẩn kích thước và trạng thái cho MỌI ô nhập của thư viện.
2104
+ *
2105
+ * ## Vì sao cần
2106
+ *
2107
+ * Chín component họ form từng tự khai kích thước riêng, và chúng trôi khỏi
2108
+ * nhau. Đo ngày 2026-09-23 trên chín component:
2109
+ *
2110
+ * thiếu cỡ `xl` 3 component (select · autocomplete · input-counter)
2111
+ * nền sai 3 component (autocomplete · timepicker · datepicker)
2112
+ * viền sai 5 component
2113
+ * đệm ngang lệch 2px ở cả ba cỡ đầu (datepicker so với input)
2114
+ * cỡ chữ `sm` lệch 2px (14px vs 12px)
2115
+ *
2116
+ * Nền và viền lệch **chỉ lộ ở chế độ tối**: sáng thì `--bg-secondary` và
2117
+ * `--bg-secondary-medium` cùng ra `#f9fafb`, tối thì `gray-950` vs `gray-800`.
2118
+ * Nên lỗi sống rất lâu — người dựng nhìn chế độ sáng, thấy giống hệt nhau.
2119
+ *
2120
+ * Đọc từ đây thì thêm ô nhập mới cũng tự khớp, và đổi thang chỉ sửa một chỗ.
2121
+ *
2122
+ * ## Không gộp chiều cao với đệm ngang
2123
+ *
2124
+ * Hai thứ tách riêng vì component có icon cần `ps-*` thay `px-*`. Gộp lại thì
2125
+ * mỗi component phải cắt chuỗi ra để bỏ phần đệm — dễ sai hơn là ghép vào.
2126
+ */
2127
+ /** Bốn cỡ của họ form. Trùng `InputSize`, `SelectSize`, `DatepickerSize`. */
2128
+ type FieldSize = 'sm' | 'base' | 'lg' | 'xl';
2129
+
2005
2130
  /**
2006
2131
  * Thang cỡ theo Figma: `sm | base | lg`.
2007
2132
  *
@@ -2012,11 +2137,17 @@ declare class OlTextarea implements ControlValueAccessor {
2012
2137
  *
2013
2138
  * Cùng cách xử lý với `variant`/`currentPage` của `ol-pagination`.
2014
2139
  *
2015
- * LƯU Ý cho lượt sau: họ form nay là `sm | base | lg | xl` (`ol-input`,
2016
- * `ol-timepicker`, `ol-datepicker`). `ol-select` **thiếu `xl`** — thêm được
2017
- * nhưng là mở rộng API, cần chốt trước.
2140
+ * Họ form là `sm | base | lg | xl` (`ol-input`, `ol-timepicker`,
2141
+ * `ol-datepicker`), và `ol-select` **có đủ cả bốn** — `xl` đi qua bảng chuẩn
2142
+ * `FIELD_HEIGHT`/`FIELD_PADDING_X` trong `forms/shared/field-tokens.ts` như
2143
+ * mọi cỡ khác.
2144
+ *
2145
+ * (Chú thích cũ ở đây ghi "ol-select thiếu xl" — đã LẠC HẬU, gỡ 2026-09-23.
2146
+ * Bảng API của ba trang docs chép theo nó nên cũng thiếu `xl`; `check:api:days`
2147
+ * bắt được, nhưng guard đó chưa bao giờ chạy vì vòng lặp gọi guard dùng regex
2148
+ * `check:[a-z-]*` — không khớp tên có HAI dấu hai chấm.)
2018
2149
  */
2019
- type SelectSize = 'sm' | 'base' | 'lg' | 'md';
2150
+ type SelectSize = 'sm' | 'base' | 'lg' | 'xl' | 'md';
2020
2151
  type SelectState = 'default' | 'error' | 'success';
2021
2152
  interface SelectOption {
2022
2153
  label: string;
@@ -2133,6 +2264,26 @@ declare class OlSelect implements ControlValueAccessor {
2133
2264
  * và PrimeNG.
2134
2265
  */
2135
2266
  readonly appendTo: _angular_core.InputSignal<"body" | null>;
2267
+ /**
2268
+ * Lớp Tailwind cho panel thả xuống.
2269
+ *
2270
+ * Cùng tên và cùng ý nghĩa với `menuClass` của `ol-dropdown`.
2271
+ *
2272
+ * Chỉ có tác dụng khi `matchTriggerWidth` TẮT: bề rộng panel được đặt bằng
2273
+ * `style.width` inline, mà style inline thắng mọi lớp Tailwind.
2274
+ */
2275
+ readonly menuClass: _angular_core.InputSignal<string>;
2276
+ /**
2277
+ * Panel rộng đúng bằng ô neo hay không. Mặc định **bật** — giữ hành vi cũ.
2278
+ *
2279
+ * Tắt khi nội dung cần rộng hơn ô: nhãn dài, hai cột, hoặc nội dung tuỳ
2280
+ * biến truyền qua `ng-template`. Lúc đó `menuClass` mới có chỗ tác dụng.
2281
+ *
2282
+ * ```html
2283
+ * <ol-select [matchTriggerWidth]="false" menuClass="w-96" … />
2284
+ * ```
2285
+ */
2286
+ readonly matchTriggerWidth: _angular_core.InputSignal<boolean>;
2136
2287
  /** Tối đa bao nhiêu mục được chọn ở chế độ đa chọn. 0 = không giới hạn. */
2137
2288
  readonly maxSelectedItems: _angular_core.InputSignal<number>;
2138
2289
  /** Đóng danh sách ngay sau khi chọn. Mặc định: đơn chọn đóng, đa chọn không. */
@@ -2264,13 +2415,29 @@ declare class OlSelect implements ControlValueAccessor {
2264
2415
  readonly listboxId: _angular_core.Signal<string>;
2265
2416
  readonly describedBy: _angular_core.Signal<string | null>;
2266
2417
  readonly ariaInvalid: _angular_core.Signal<"true" | null>;
2267
- protected readonly resolvedSize: _angular_core.Signal<SelectSize>;
2418
+ /**
2419
+ * Cỡ đã bỏ bí danh `'md'`.
2420
+ *
2421
+ * Khai kiểu trả về là `FieldSize` chứ không để TypeScript suy: suy ra sẽ
2422
+ * giữ `'md'` trong kiểu hợp dù giá trị không bao giờ là `'md'`, và mọi chỗ
2423
+ * tra bảng chuẩn sẽ báo lỗi "Property 'md' does not exist".
2424
+ */
2425
+ protected readonly resolvedSize: _angular_core.Signal<FieldSize>;
2268
2426
  /**
2269
2427
  * Padding trái: 10 khi có icon, 3.5 khi không.
2270
2428
  * Không dùng `[class.ps-3.5]` vì Angular cắt phần sau dấu chấm — nó render
2271
2429
  * ra `ps-3` (12px thay vì 14px).
2272
2430
  */
2273
- readonly paddingStartClass: _angular_core.Signal<"ps-10" | "ps-3.5">;
2431
+ /**
2432
+ * Đệm trái theo bảng chuẩn, KHÔNG khoá cứng một giá trị cho mọi cỡ.
2433
+ *
2434
+ * Bản cũ trả `ps-3.5` (14px) cho cả bốn cỡ, trong khi `ol-input` dùng
2435
+ * 10/12/14/16px. Đặt `ol-select size="sm"` cạnh `ol-input size="sm"` là
2436
+ * lệch 4px, và ở `xl` lệch 2px theo chiều ngược lại.
2437
+ *
2438
+ * Có icon trái thì `ps-10` cố định — chỗ đó dành cho icon, không phải đệm.
2439
+ */
2440
+ readonly paddingStartClass: _angular_core.Signal<string>;
2274
2441
  private onChange;
2275
2442
  private onTouched;
2276
2443
  private readonly destroyRef;
@@ -2278,6 +2445,8 @@ declare class OlSelect implements ControlValueAccessor {
2278
2445
  private readonly overlayContainer;
2279
2446
  /** Hàm trả panel về chỗ cũ + hàm ngắt theo dõi vị trí. */
2280
2447
  private detachPanel;
2448
+ /** Hàm gỡ khỏi ngăn xếp Escape. `null` khi panel đang đóng. */
2449
+ private releaseEscape;
2281
2450
  private stopTracking;
2282
2451
  private wasOpen;
2283
2452
  private hengio;
@@ -2338,6 +2507,21 @@ declare class OlSelect implements ControlValueAccessor {
2338
2507
  * gì: nút chết còn khó hiểu hơn là không có nút.
2339
2508
  */
2340
2509
  readonly hasClearable: _angular_core.Signal<boolean>;
2510
+ /**
2511
+ * Có gì để nút xoá dọn hay không — mục đã chọn HOẶC chữ đang gõ ở ô tìm.
2512
+ *
2513
+ * `hasClearable()` chỉ nhìn mục đã chọn, nên gõ vào ô tìm mà chưa chọn gì
2514
+ * thì không có nút — người dùng gõ sai phải xoá từng ký tự. Đo /select: gõ
2515
+ * "to" vào ô tìm, số nút xoá vẫn 0.
2516
+ *
2517
+ * Nút dọn cả hai thứ (`clear()` đã gọi `searchQuery.set('')`), nên điều
2518
+ * kiện hiện phải nhìn cả hai.
2519
+ *
2520
+ * Tên `hasContent` dùng CHUNG với `ol-datepicker` và `ol-date-range-picker`
2521
+ * — cùng một khái niệm thì cùng một tên, để người đọc mã không phải nhớ ba
2522
+ * cách gọi cho một thứ.
2523
+ */
2524
+ readonly hasContent: _angular_core.Signal<boolean>;
2341
2525
  /**
2342
2526
  * Có hiện lối tạo mục mới không.
2343
2527
  *
@@ -2448,7 +2632,7 @@ declare class OlSelect implements ControlValueAccessor {
2448
2632
  registerOnTouched(fn: () => void): void;
2449
2633
  setDisabledState(isDisabled: boolean): void;
2450
2634
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlSelect, never>;
2451
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlSelect, "ol-select", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "state": { "alias": "state"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "showAsterisk": { "alias": "showAsterisk"; "required": false; "isSignal": true; }; "leftIcon": { "alias": "leftIcon"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "labelKey": { "alias": "labelKey"; "required": false; "isSignal": true; }; "valueKey": { "alias": "valueKey"; "required": false; "isSignal": true; }; "groupBy": { "alias": "groupBy"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "appendTo": { "alias": "appendTo"; "required": false; "isSignal": true; }; "maxSelectedItems": { "alias": "maxSelectedItems"; "required": false; "isSignal": true; }; "closeOnSelect": { "alias": "closeOnSelect"; "required": false; "isSignal": true; }; "hideSelected": { "alias": "hideSelected"; "required": false; "isSignal": true; }; "allowCreate": { "alias": "allowCreate"; "required": false; "isSignal": true; }; "createText": { "alias": "createText"; "required": false; "isSignal": true; }; "groupSeparator": { "alias": "groupSeparator"; "required": false; "isSignal": true; }; "searchPosition": { "alias": "searchPosition"; "required": false; "isSignal": true; }; "searchIcon": { "alias": "searchIcon"; "required": false; "isSignal": true; }; "searchPrefix": { "alias": "searchPrefix"; "required": false; "isSignal": true; }; "triggerIcon": { "alias": "triggerIcon"; "required": false; "isSignal": true; }; "triggerLabel": { "alias": "triggerLabel"; "required": false; "isSignal": true; }; "remoteSearch": { "alias": "remoteSearch"; "required": false; "isSignal": true; }; "minTermLength": { "alias": "minTermLength"; "required": false; "isSignal": true; }; "debounceMs": { "alias": "debounceMs"; "required": false; "isSignal": true; }; "typeToSearchText": { "alias": "typeToSearchText"; "required": false; "isSignal": true; }; "virtualScroll": { "alias": "virtualScroll"; "required": false; "isSignal": true; }; "itemHeight": { "alias": "itemHeight"; "required": false; "isSignal": true; }; "bufferAmount": { "alias": "bufferAmount"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "disabled": "disabledChange"; "search": "search"; "opened": "opened"; "closed": "closed"; "cleared": "cleared"; "added": "added"; "removed": "removed"; "selectionChange": "selectionChange"; }, ["optionTemplate", "labelTemplate"], ["[leftIcon]"], true, never>;
2635
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlSelect, "ol-select", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "state": { "alias": "state"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "showAsterisk": { "alias": "showAsterisk"; "required": false; "isSignal": true; }; "leftIcon": { "alias": "leftIcon"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "searchable": { "alias": "searchable"; "required": false; "isSignal": true; }; "clearable": { "alias": "clearable"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "labelKey": { "alias": "labelKey"; "required": false; "isSignal": true; }; "valueKey": { "alias": "valueKey"; "required": false; "isSignal": true; }; "groupBy": { "alias": "groupBy"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "searchPlaceholder": { "alias": "searchPlaceholder"; "required": false; "isSignal": true; }; "appendTo": { "alias": "appendTo"; "required": false; "isSignal": true; }; "menuClass": { "alias": "menuClass"; "required": false; "isSignal": true; }; "matchTriggerWidth": { "alias": "matchTriggerWidth"; "required": false; "isSignal": true; }; "maxSelectedItems": { "alias": "maxSelectedItems"; "required": false; "isSignal": true; }; "closeOnSelect": { "alias": "closeOnSelect"; "required": false; "isSignal": true; }; "hideSelected": { "alias": "hideSelected"; "required": false; "isSignal": true; }; "allowCreate": { "alias": "allowCreate"; "required": false; "isSignal": true; }; "createText": { "alias": "createText"; "required": false; "isSignal": true; }; "groupSeparator": { "alias": "groupSeparator"; "required": false; "isSignal": true; }; "searchPosition": { "alias": "searchPosition"; "required": false; "isSignal": true; }; "searchIcon": { "alias": "searchIcon"; "required": false; "isSignal": true; }; "searchPrefix": { "alias": "searchPrefix"; "required": false; "isSignal": true; }; "triggerIcon": { "alias": "triggerIcon"; "required": false; "isSignal": true; }; "triggerLabel": { "alias": "triggerLabel"; "required": false; "isSignal": true; }; "remoteSearch": { "alias": "remoteSearch"; "required": false; "isSignal": true; }; "minTermLength": { "alias": "minTermLength"; "required": false; "isSignal": true; }; "debounceMs": { "alias": "debounceMs"; "required": false; "isSignal": true; }; "typeToSearchText": { "alias": "typeToSearchText"; "required": false; "isSignal": true; }; "virtualScroll": { "alias": "virtualScroll"; "required": false; "isSignal": true; }; "itemHeight": { "alias": "itemHeight"; "required": false; "isSignal": true; }; "bufferAmount": { "alias": "bufferAmount"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "disabled": "disabledChange"; "search": "search"; "opened": "opened"; "closed": "closed"; "cleared": "cleared"; "added": "added"; "removed": "removed"; "selectionChange": "selectionChange"; }, ["optionTemplate", "labelTemplate"], ["[leftIcon]"], true, never>;
2452
2636
  }
2453
2637
 
2454
2638
  /**
@@ -2836,7 +3020,7 @@ declare class OlFloatingLabel implements ControlValueAccessor {
2836
3020
  * Thang cỡ theo Figma: `sm | base | lg`. `'md'` là BÍ DANH của `'base'`,
2837
3021
  * giữ cho mã cũ chạy tiếp và sẽ bỏ ở bản sau — dùng `'base'` cho mã mới.
2838
3022
  */
2839
- type InputCounterSize = 'sm' | 'base' | 'lg' | 'md';
3023
+ type InputCounterSize = 'sm' | 'base' | 'lg' | 'xl' | 'md';
2840
3024
  declare class OlInputCounter implements ControlValueAccessor {
2841
3025
  /** Id tự sinh khi nơi gọi không truyền id — để <label for> và
2842
3026
  * aria-describedby luôn nối được với ô nhập. */
@@ -2882,7 +3066,7 @@ declare class OlInputCounter implements ControlValueAccessor {
2882
3066
  /** Nhãn: `inline` bỏ margin dưới vì nó nằm cạnh, không nằm trên. */
2883
3067
  protected readonly labelClasses: _angular_core.Signal<"shrink-0 text-sm font-medium text-heading" | "block mb-1.5 text-sm font-medium text-heading">;
2884
3068
  /** Khối nút+ô: `ghost` bỏ nền, viền và đổ bóng. */
2885
- protected readonly groupClasses: _angular_core.Signal<"relative inline-flex items-center overflow-hidden" | "relative inline-flex items-center rounded-md shadow-xs border border-default bg-neutral-primary overflow-hidden">;
3069
+ protected readonly groupClasses: _angular_core.Signal<"relative inline-flex items-center overflow-hidden" | "relative inline-flex items-center rounded-md shadow-xs border border-default-medium bg-neutral-primary overflow-hidden">;
2886
3070
  /** Nút trong chế độ `ghost` cũng phải bỏ nền và đường ngăn. */
2887
3071
  protected readonly ghostNut: _angular_core.Signal<"" | "bg-transparent border-0">;
2888
3072
  increment(): void;
@@ -3215,7 +3399,7 @@ declare class OlTimepicker implements ControlValueAccessor {
3215
3399
  * Thang cỡ theo Figma: `sm | base | lg`. `'md'` là BÍ DANH của `'base'`,
3216
3400
  * giữ cho mã cũ chạy tiếp và sẽ bỏ ở bản sau — dùng `'base'` cho mã mới.
3217
3401
  */
3218
- type AutocompleteSize = 'sm' | 'base' | 'lg' | 'md';
3402
+ type AutocompleteSize = 'sm' | 'base' | 'lg' | 'xl' | 'md';
3219
3403
  type AutocompleteState = 'default' | 'error' | 'success';
3220
3404
  interface AutocompleteOption {
3221
3405
  label: string;
@@ -3272,6 +3456,26 @@ declare class OlAutocomplete implements ControlValueAccessor {
3272
3456
  * và PrimeNG.
3273
3457
  */
3274
3458
  readonly appendTo: _angular_core.InputSignal<"body" | null>;
3459
+ /**
3460
+ * Lớp Tailwind cho panel thả xuống.
3461
+ *
3462
+ * Cùng tên và cùng ý nghĩa với `menuClass` của `ol-dropdown`.
3463
+ *
3464
+ * Chỉ có tác dụng khi `matchTriggerWidth` TẮT: bề rộng panel được đặt bằng
3465
+ * `style.width` inline, mà style inline thắng mọi lớp Tailwind.
3466
+ */
3467
+ readonly menuClass: _angular_core.InputSignal<string>;
3468
+ /**
3469
+ * Panel rộng đúng bằng ô neo hay không. Mặc định **bật** — giữ hành vi cũ.
3470
+ *
3471
+ * Tắt khi nội dung cần rộng hơn ô: nhãn dài, hai cột, hoặc nội dung tuỳ
3472
+ * biến truyền qua `ng-template`. Lúc đó `menuClass` mới có chỗ tác dụng.
3473
+ *
3474
+ * ```html
3475
+ * <ol-select [matchTriggerWidth]="false" menuClass="w-96" … />
3476
+ * ```
3477
+ */
3478
+ readonly matchTriggerWidth: _angular_core.InputSignal<boolean>;
3275
3479
  readonly groupBy: _angular_core.InputSignal<string>;
3276
3480
  /**
3277
3481
  * LỌC TỪ XA. Bật lên thì component NGỪNG tự lọc `options` — nó chỉ phát
@@ -3323,6 +3527,8 @@ declare class OlAutocomplete implements ControlValueAccessor {
3323
3527
  private readonly overlayContainer;
3324
3528
  /** Hàm trả panel về chỗ cũ + hàm ngắt theo dõi vị trí. */
3325
3529
  private detachPanel;
3530
+ /** Hàm gỡ khỏi ngăn xếp Escape. `null` khi panel đang đóng. */
3531
+ private releaseEscape;
3326
3532
  private stopTracking;
3327
3533
  private readonly destroyRef;
3328
3534
  /** Trạng thái mở ở lượt chạy trước — để `effect` chỉ phát khi ĐỔI. */
@@ -3398,7 +3604,7 @@ declare class OlAutocomplete implements ControlValueAccessor {
3398
3604
  registerOnTouched(fn: any): void;
3399
3605
  setDisabledState(isDisabled: boolean): void;
3400
3606
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlAutocomplete, never>;
3401
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlAutocomplete, "ol-autocomplete", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "labelKey": { "alias": "labelKey"; "required": false; "isSignal": true; }; "valueKey": { "alias": "valueKey"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "state": { "alias": "state"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "showAsterisk": { "alias": "showAsterisk"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "errorText": { "alias": "errorText"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "allowCreate": { "alias": "allowCreate"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "appendTo": { "alias": "appendTo"; "required": false; "isSignal": true; }; "groupBy": { "alias": "groupBy"; "required": false; "isSignal": true; }; "remoteSearch": { "alias": "remoteSearch"; "required": false; "isSignal": true; }; "minTermLength": { "alias": "minTermLength"; "required": false; "isSignal": true; }; "debounceMs": { "alias": "debounceMs"; "required": false; "isSignal": true; }; "typeToSearchText": { "alias": "typeToSearchText"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "disabled": "disabledChange"; "createOption": "createOption"; "search": "search"; "opened": "opened"; "closed": "closed"; "cleared": "cleared"; "added": "added"; "removed": "removed"; "selectionChange": "selectionChange"; }, ["optionTemplate"], never, true, never>;
3607
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlAutocomplete, "ol-autocomplete", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "labelKey": { "alias": "labelKey"; "required": false; "isSignal": true; }; "valueKey": { "alias": "valueKey"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "state": { "alias": "state"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "showAsterisk": { "alias": "showAsterisk"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "errorText": { "alias": "errorText"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "allowCreate": { "alias": "allowCreate"; "required": false; "isSignal": true; }; "emptyText": { "alias": "emptyText"; "required": false; "isSignal": true; }; "appendTo": { "alias": "appendTo"; "required": false; "isSignal": true; }; "menuClass": { "alias": "menuClass"; "required": false; "isSignal": true; }; "matchTriggerWidth": { "alias": "matchTriggerWidth"; "required": false; "isSignal": true; }; "groupBy": { "alias": "groupBy"; "required": false; "isSignal": true; }; "remoteSearch": { "alias": "remoteSearch"; "required": false; "isSignal": true; }; "minTermLength": { "alias": "minTermLength"; "required": false; "isSignal": true; }; "debounceMs": { "alias": "debounceMs"; "required": false; "isSignal": true; }; "typeToSearchText": { "alias": "typeToSearchText"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "disabled": "disabledChange"; "createOption": "createOption"; "search": "search"; "opened": "opened"; "closed": "closed"; "cleared": "cleared"; "added": "added"; "removed": "removed"; "selectionChange": "selectionChange"; }, ["optionTemplate"], never, true, never>;
3402
3608
  }
3403
3609
 
3404
3610
  declare class OlKbd {
@@ -3467,6 +3673,16 @@ type OlModalRole = 'dialog' | 'alertdialog';
3467
3673
  declare class OlModal {
3468
3674
  private readonly focusTrap;
3469
3675
  private readonly destroyRef;
3676
+ private readonly overlayContainer;
3677
+ /**
3678
+ * Hàm gỡ khỏi ngăn xếp Escape. `null` khi modal đang đóng.
3679
+ *
3680
+ * Modal KHÔNG gọi `overlayContainer.attach()` — nó nằm trong cây DOM của
3681
+ * chính nó chứ không treo ra `<body>`. Nhưng vẫn phải vào ngăn xếp Escape,
3682
+ * nếu không lớp nổi mở bên trong nó (datepicker, dropdown) sẽ kéo nó đóng
3683
+ * theo khi nhấn Escape.
3684
+ */
3685
+ private releaseEscape;
3470
3686
  private readonly panel;
3471
3687
  /**
3472
3688
  * Bậc thẻ tiêu đề (h1–h6). Mặc định 3 — giữ nguyên bậc đang chạy.
@@ -3493,7 +3709,6 @@ declare class OlModal {
3493
3709
  constructor();
3494
3710
  readonly placementClasses: _angular_core.Signal<"items-start justify-start p-4" | "items-start justify-center p-4" | "items-start justify-end p-4" | "items-end justify-start p-4" | "items-end justify-center p-4" | "items-end justify-end p-4" | "items-center justify-center p-4">;
3495
3711
  readonly sizeClasses: _angular_core.Signal<"max-w-md" | "max-w-4xl" | "max-w-6xl" | "max-w-7xl" | "max-w-2xl">;
3496
- handleEscapeKey(): void;
3497
3712
  onBackdropClick(event: MouseEvent): void;
3498
3713
  show(): void;
3499
3714
  hide(): void;
@@ -3518,11 +3733,44 @@ declare class OlModalHeader {
3518
3733
  */
3519
3734
  readonly headingLevel: _angular_core.InputSignal<1 | 2 | 3 | 4 | 5 | 6>;
3520
3735
  readonly heading: _angular_core.InputSignal<string>;
3736
+ /**
3737
+ * Icon đầu tiêu đề. Rỗng thì KHÔNG dựng khung — không để lại thẻ trống.
3738
+ *
3739
+ * Figma `Type=Icon + Heading & helper text` (#1149:71412) vẽ khung 48px bo
3740
+ * 12px, icon 28px bên trong. Đó đúng là `ol-icon-shape` size `lg`, nên dùng
3741
+ * lại thay vì tự vẽ khung.
3742
+ *
3743
+ * `color="white"` chứ KHÔNG `gray`: Figma bind nền
3744
+ * `bg-neutral-primary-medium` (trắng) kèm viền `border-default-medium`, mà
3745
+ * trong `ol-icon-shape` chỉ nhánh `white` có cặp đó — `gray` ra nền xám đặc
3746
+ * và KHÔNG viền. Đo /modal lượt đầu: nền rgb(243,244,246), viền 0px.
3747
+ */
3748
+ readonly icon: _angular_core.InputSignal<string>;
3749
+ /**
3750
+ * Mô tả phụ dưới tiêu đề.
3751
+ *
3752
+ * Tên `description` theo `ol-alert-dialog` — thứ dựng trên chính `ol-modal`
3753
+ * — và `ol-empty`. `helperText` mang nghĩa "chú thích dưới ô nhập" ở họ form
3754
+ * (16 component dùng), đặt cho tiêu đề hộp thoại là lệch nghĩa.
3755
+ */
3756
+ readonly description: _angular_core.InputSignal<string>;
3757
+ /** @deprecated Dùng `description`. Giữ để không phá mã đang chạy. */
3521
3758
  readonly supportingText: _angular_core.InputSignal<string>;
3759
+ /** @deprecated Dùng `description`. Tên cũ của `ol-drawer-header`. */
3760
+ readonly helperText: _angular_core.InputSignal<string>;
3761
+ /**
3762
+ * Cái nào được TRUYỀN thì thắng — không phụ thuộc giá trị.
3763
+ *
3764
+ * `ol-badge` từng hoà giải hai input cùng nghĩa bằng cách so với giá trị mặc
3765
+ * định (`theme` thắng trừ khi nó bằng `'gray'`), nên truyền cả hai thì một
3766
+ * cái bị nuốt im lặng. Ở đây chuỗi rỗng là "không truyền", nên chỉ cần lấy
3767
+ * cái đầu tiên khác rỗng.
3768
+ */
3769
+ readonly descriptionText: _angular_core.Signal<string>;
3522
3770
  readonly showClose: _angular_core.InputSignal<boolean>;
3523
3771
  readonly closeClick: _angular_core.OutputEmitterRef<void>;
3524
3772
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlModalHeader, never>;
3525
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlModalHeader, "ol-modal-header", never, { "headingLevel": { "alias": "headingLevel"; "required": false; "isSignal": true; }; "heading": { "alias": "heading"; "required": false; "isSignal": true; }; "supportingText": { "alias": "supportingText"; "required": false; "isSignal": true; }; "showClose": { "alias": "showClose"; "required": false; "isSignal": true; }; }, { "closeClick": "closeClick"; }, never, ["*"], true, never>;
3773
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlModalHeader, "ol-modal-header", never, { "headingLevel": { "alias": "headingLevel"; "required": false; "isSignal": true; }; "heading": { "alias": "heading"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "supportingText": { "alias": "supportingText"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "showClose": { "alias": "showClose"; "required": false; "isSignal": true; }; }, { "closeClick": "closeClick"; }, never, ["*"], true, never>;
3526
3774
  }
3527
3775
 
3528
3776
  /** Khớp trục `Type` của Figma ol-modal-footer (node 1149:71444). */
@@ -3533,9 +3781,15 @@ type ModalFooterLayout = 'buttons' | 'three-buttons' | 'buttons-links' | 'pagina
3533
3781
  * Nút thật do nơi dùng truyền vào qua <ng-content>; component lo bố cục.
3534
3782
  *
3535
3783
  * KHÔNG lắp vào slot `[footer]` của `ol-modal`. Slot đó ĐÃ nằm sẵn trong một
3536
- * khung `p-5 border-t bg-neutral-secondary` do chính `ol-modal` dựng, nên lắp
3537
- * thêm component này vào là LỒNG HAI KHUNG. Đo /modal (2026-09-16): đệm cộng
3538
- * dồn 20 + 20 = 40px, hai viền trên 1px chồng nhau, nền lặp hai lần.
3784
+ * khung do chính `ol-modal` dựng, nên lắp thêm component này vào là LỒNG HAI
3785
+ * KHUNG. Đo /modal (2026-09-16, khi cả hai còn `p-5`): đệm cộng dồn 20 + 20 =
3786
+ * 40px, hai viền trên chồng nhau, nền lặp hai lần.
3787
+ *
3788
+ * Từ 2026-09-23 cả hai khung đều PHẲNG (không viền, không nền) nên lỗi lồng
3789
+ * khung KHÓ THẤY hơn hẳn — chỉ còn đệm cộng dồn 12 + 12 = 24px. Vì vậy cả hai
3790
+ * khung mang thuộc tính dấu `footer-frame`, và spec đếm số thẻ mang dấu đó
3791
+ * phải bằng 1. Neo vào dấu chứ không vào `p-3`: đổi con số đệm là việc thiết
3792
+ * kế bình thường, không nên làm đỏ một spec vốn gác chuyện khác.
3539
3793
  *
3540
3794
  * Dùng nó khi tự dựng hộp thoại (không qua `ol-modal`), hoặc trong `ol-drawer`
3541
3795
  * — `ol-drawer` chỉ có `<ng-content />` TRẦN nên ghép vừa khít. Đó là lý do
@@ -3595,10 +3849,11 @@ declare class OlNavDropdown {
3595
3849
  readonly alignRight: _angular_core.InputSignal<boolean>;
3596
3850
  readonly isOpen: _angular_core.WritableSignal<boolean>;
3597
3851
  private readonly elementRef;
3852
+ private readonly overlayContainer;
3853
+ constructor();
3598
3854
  toggle(): void;
3599
3855
  close(): void;
3600
3856
  handleClickOutside(event: MouseEvent): void;
3601
- handleEscape(): void;
3602
3857
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlNavDropdown, never>;
3603
3858
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlNavDropdown, "ol-nav-dropdown", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "alignRight": { "alias": "alignRight"; "required": false; "isSignal": true; }; }, {}, never, ["[slot=trigger], [trigger]", "*"], true, never>;
3604
3859
  }
@@ -4074,17 +4329,218 @@ declare class OlRating {
4074
4329
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlRating, "ol-rating", never, { "rating": { "alias": "rating"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "score": { "alias": "score"; "required": false; "isSignal": true; }; "badgeText": { "alias": "badgeText"; "required": false; "isSignal": true; }; "minLabel": { "alias": "minLabel"; "required": false; "isSignal": true; }; "maxLabel": { "alias": "maxLabel"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
4075
4330
  }
4076
4331
 
4332
+ /**
4333
+ * Kiểu dữ liệu cho `ol-app-nav` — menu điều hướng Ôn Luyện.
4334
+ *
4335
+ * Tách riêng khỏi component để nơi dùng khai được danh sách menu ở bất kỳ đâu:
4336
+ * hằng số trong mã, tệp JSON, hoặc trả về từ API theo quyền tài khoản. Component
4337
+ * KHÔNG nhúng sẵn danh sách nào — ba quyền Học sinh · Giáo viên · Phụ huynh đều
4338
+ * là dữ liệu truyền vào.
4339
+ *
4340
+ * Figma `ol-app-nav` (#5303:30109) mô tả ba quyền, nhưng đó là NỘI DUNG mẫu,
4341
+ * không phải ràng buộc của component. Thêm quyền thứ tư chỉ là thêm một mảng.
4342
+ */
4343
+ /** Một mục trong menu. */
4344
+ interface AppNavItem {
4345
+ /**
4346
+ * Khoá định danh, dùng để đánh dấu mục đang chọn.
4347
+ *
4348
+ * Tách khỏi `route` vì một mục có thể không có đường dẫn (mở hộp thoại, gọi
4349
+ * hàm), và hai mục có thể trỏ cùng route với tham số khác nhau.
4350
+ */
4351
+ id: string;
4352
+ /** Chữ hiển thị. Ở trạng thái thu gọn, chữ này thành tên trợ năng. */
4353
+ label: string;
4354
+ /**
4355
+ * Nhãn rút gọn cho chỗ hẹp — navbar đáy trên mobile.
4356
+ *
4357
+ * Đo ở 375px: navbar 5 ô, mỗi ô 75px. Nhãn dài hơn ~10 ký tự bị cắt cụt
4358
+ * ("Lịch học trực tuyến" cần 95px), và 8/15 nhãn của ba quyền mẫu vượt
4359
+ * ngưỡng đó — tức không phải ca hiếm.
4360
+ *
4361
+ * Rút tự động bằng thuật toán ra chữ vô nghĩa, nên để nơi dùng tự đặt.
4362
+ * Bỏ trống thì dùng `label`; chỗ hẹp vẫn nên đặt cho chắc.
4363
+ *
4364
+ * KHÔNG thay `label` ở tooltip và trợ năng — hai chỗ đó vẫn đọc tên đầy đủ.
4365
+ */
4366
+ shortLabel?: string;
4367
+ /** Tên icon theo `OlIconService` — dạng ngắn (`star`) hoặc có tiền tố bộ. */
4368
+ icon: string;
4369
+ /** Đường dẫn router. Bỏ trống thì mục chỉ phát sự kiện `itemClick`. */
4370
+ route?: string;
4371
+ /** Huy hiệu đếm bên phải nhãn, ví dụ số tin chưa đọc. */
4372
+ badge?: string | number;
4373
+ /** Mờ 40% và không bấm được — theo Figma State=Disabled. */
4374
+ disabled?: boolean;
4375
+ }
4376
+ /**
4377
+ * Một nhóm mục. Figma chia menu làm hai phần, ngăn bằng một đường kẻ:
4378
+ *
4379
+ * `main` phần trên — nghiệp vụ chính, chiếm hết chỗ trống
4380
+ * `footer` phần dưới — tiện ích, luôn nằm sát thẻ tài khoản
4381
+ *
4382
+ * Dùng `section` chứ không dựa vào thứ tự mảng: nơi dùng khai một danh sách
4383
+ * phẳng, component tự tách hai vùng.
4384
+ */
4385
+ interface AppNavGroup {
4386
+ section: 'main' | 'footer';
4387
+ items: AppNavItem[];
4388
+ }
4389
+ /** Thẻ tài khoản dưới cùng. */
4390
+ interface AppNavUser {
4391
+ name: string;
4392
+ /** Dòng phụ — Figma dùng email, nhưng nơi dùng đặt gì cũng được. */
4393
+ subtitle?: string;
4394
+ /** Ảnh đại diện. Bỏ trống thì `ol-avatar` tự dựng chữ cái đầu từ `name`. */
4395
+ avatarSrc?: string;
4396
+ }
4397
+ /**
4398
+ * Trọn bộ dữ liệu một menu — đúng thứ nơi dùng nạp từ JSON.
4399
+ *
4400
+ * ```ts
4401
+ * const menuHocSinh: AppNavConfig = {
4402
+ * groups: [
4403
+ * { section: 'main', items: [{ id: 'lop-hoc-so', label: 'Lớp học số', icon: 'calendar-add' }] },
4404
+ * { section: 'footer', items: [{ id: 'ho-tro', label: 'Hướng dẫn & Hỗ trợ', icon: 'question-circle' }] },
4405
+ * ],
4406
+ * user: { name: 'Nguyễn Nhật Linh', subtitle: 'hocsinh.demo@onluyen.vn' },
4407
+ * };
4408
+ * ```
4409
+ */
4410
+ interface AppNavConfig {
4411
+ groups: AppNavGroup[];
4412
+ user?: AppNavUser;
4413
+ }
4414
+
4415
+ /**
4416
+ * `ol-app-nav` — menu điều hướng dọc của Ôn Luyện.
4417
+ *
4418
+ * Figma `ol-app-nav` (#5303:30109), 6 biến thể: 3 quyền × 2 trạng thái.
4419
+ *
4420
+ * ## Khác gì `ol-sidebar`
4421
+ *
4422
+ * `ol-sidebar` là thanh bên ĐA DỤNG: nền sáng theo token, nhận nội dung tuỳ ý
4423
+ * qua `ng-content`, có menu con accordion. Component này là thanh điều hướng
4424
+ * RIÊNG của sản phẩm Ôn Luyện: nền gradient navy cố định, cấu trúc chốt sẵn
4425
+ * (logo → menu chính → đường kẻ → menu phụ → thẻ tài khoản), nhận dữ liệu qua
4426
+ * một đối tượng thay vì qua slot.
4427
+ *
4428
+ * Không gộp hai cái làm một: gộp thì `ol-sidebar` phải mang theo nền gradient
4429
+ * và bố cục ba vùng mà 90% nơi dùng không cần.
4430
+ *
4431
+ * ## Dữ liệu từ ngoài, không nhúng cứng
4432
+ *
4433
+ * Ba quyền trong Figma là NỘI DUNG mẫu. Component nhận `config` — nơi dùng nạp
4434
+ * từ hằng số, tệp JSON, hay API đều được. Thêm quyền thứ tư chỉ là thêm một
4435
+ * mảng, không phải sửa component.
4436
+ *
4437
+ * ## Nền gradient nằm ngoài thang token
4438
+ *
4439
+ * Figma chốt `linear-gradient(164.52deg, #445A9A, #0F2977)`. Hai màu này không
4440
+ * có trong `primitives.css` và cũng không nên có — chúng là bản sắc của MỘT
4441
+ * sản phẩm, không phải bậc màu dùng chung. Khai biến cục bộ trong template.
4442
+ *
4443
+ * Hệ quả: chữ trên nền này luôn trắng, không đổi theo chế độ sáng/tối. Đúng
4444
+ * như Figma mô tả ("dùng trên nền tối, chữ và biểu tượng đều `text-white`").
4445
+ */
4446
+ declare class OlAppNav {
4447
+ /** Danh sách menu và thẻ tài khoản. Xem `AppNavConfig`. */
4448
+ readonly config: _angular_core.InputSignal<AppNavConfig>;
4449
+ /**
4450
+ * Thu gọn còn 70px, chỉ hiện icon.
4451
+ *
4452
+ * `model()` để nơi dùng bind hai chiều `[(collapsed)]` — nút thu gọn thường
4453
+ * nằm ngoài component (trên thanh header), nhưng cũng có nơi tự điều khiển.
4454
+ */
4455
+ readonly collapsed: _angular_core.ModelSignal<boolean>;
4456
+ /**
4457
+ * Mục đang chọn, theo `id`.
4458
+ *
4459
+ * Dùng khi menu KHÔNG đi qua router — ví dụ một trang đơn đổi nội dung bằng
4460
+ * signal. Có `route` thì `routerLinkActive` tự lo, không cần đặt cái này.
4461
+ */
4462
+ readonly activeId: _angular_core.InputSignal<string | null>;
4463
+ /** Ảnh logo. Bỏ trống thì dựng chữ "Ôn luyện" bằng text. */
4464
+ readonly logoSrc: _angular_core.InputSignal<string>;
4465
+ /** Chiều rộng khi mở. Figma: 270px. */
4466
+ readonly width: _angular_core.InputSignal<string>;
4467
+ /** Chiều rộng khi thu gọn. Figma: 70px. */
4468
+ readonly collapsedWidth: _angular_core.InputSignal<string>;
4469
+ /** Phát khi bấm một mục. Mục có `route` thì router đã lo điều hướng. */
4470
+ readonly itemClick: _angular_core.OutputEmitterRef<AppNavItem>;
4471
+ /** Phát khi bấm thẻ tài khoản — nơi dùng mở menu đổi tài khoản, đăng xuất. */
4472
+ readonly userClick: _angular_core.OutputEmitterRef<void>;
4473
+ /**
4474
+ * Hiện thanh kéo (rail) ở mép phải để thu gọn / mở lại.
4475
+ *
4476
+ * Tắt mặc định vì nó chỉ hợp khi menu đứng cạnh nội dung trong một layout
4477
+ * thật. Dùng menu rời (như trang docs) thì thanh này lơ lửng vô nghĩa.
4478
+ */
4479
+ readonly showRail: _angular_core.InputSignal<boolean>;
4480
+ /** Chữ trên tooltip của thanh kéo, đổi theo trạng thái. */
4481
+ readonly railLabel: _angular_core.Signal<"Mở rộng" | "Thu gọn">;
4482
+ /** Mục của phần trên. */
4483
+ readonly mainItems: _angular_core.Signal<AppNavItem[]>;
4484
+ /** Mục của phần dưới, nằm sát thẻ tài khoản. */
4485
+ readonly footerItems: _angular_core.Signal<AppNavItem[]>;
4486
+ /** Đường kẻ chỉ vẽ khi phần dưới có mục — không thì thừa một vạch. */
4487
+ readonly showDivider: _angular_core.Signal<boolean>;
4488
+ readonly navWidth: _angular_core.Signal<string>;
4489
+ /**
4490
+ * Class cho một mục, theo trạng thái.
4491
+ *
4492
+ * Figma `ol-app-sidebar-item` (#5301:338): cao 44, bo 12, đệm 10, khe 8.
4493
+ *
4494
+ * Initial trong suốt
4495
+ * Hover nền brand/600
4496
+ * Active nền bg-warning, chữ đậm
4497
+ * Disabled mờ 40%
4498
+ *
4499
+ * Gộp vào MỘT chuỗi thay vì nhiều `[class.x]`: hai binding cùng tên thuộc
4500
+ * tính thì cái sau thắng, cái trước mất im lặng.
4501
+ */
4502
+ itemClasses(item: AppNavItem): string;
4503
+ /**
4504
+ * Chữ cái đầu cho ảnh đại diện, khi không có ảnh.
4505
+ *
4506
+ * `ol-avatar` IN NGUYÊN chuỗi truyền vào `text` chứ không tự cắt — truyền cả
4507
+ * họ tên thì nó hiện trọn tên trong vòng tròn 40px. Lấy chữ cái đầu của HAI
4508
+ * từ CUỐI: tên Việt để họ trước, "Nguyễn Nhật Linh" phải ra "NL" chứ không
4509
+ * phải "NN".
4510
+ */
4511
+ readonly userInitials: _angular_core.Signal<string>;
4512
+ onItemClick(item: AppNavItem): void;
4513
+ toggle(): void;
4514
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlAppNav, never>;
4515
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlAppNav, "ol-app-nav", never, { "config": { "alias": "config"; "required": true; "isSignal": true; }; "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; "activeId": { "alias": "activeId"; "required": false; "isSignal": true; }; "logoSrc": { "alias": "logoSrc"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "collapsedWidth": { "alias": "collapsedWidth"; "required": false; "isSignal": true; }; "showRail": { "alias": "showRail"; "required": false; "isSignal": true; }; }, { "collapsed": "collapsedChange"; "itemClick": "itemClick"; "userClick": "userClick"; }, never, never, true, never>;
4516
+ }
4517
+
4077
4518
  declare class OlSidebar {
4078
4519
  readonly collapsed: _angular_core.ModelSignal<boolean>;
4079
4520
  readonly width: _angular_core.InputSignal<string>;
4080
4521
  readonly collapsedWidth: _angular_core.InputSignal<string>;
4081
4522
  readonly collapsible: _angular_core.InputSignal<boolean>;
4082
4523
  readonly bordered: _angular_core.InputSignal<boolean>;
4524
+ /**
4525
+ * Hiện thanh kéo ở mép phải để thu gọn / mở rộng.
4526
+ *
4527
+ * Mặc định TẮT: `toggle()` vốn để nơi dùng tự dựng nút bên ngoài, bật sẵn
4528
+ * sẽ thêm một nút vào mọi sidebar đang chạy mà không ai yêu cầu.
4529
+ *
4530
+ * Thanh này ẩn dưới `md` — ở màn hẹp sidebar thường được thay bằng ngăn kéo
4531
+ * trượt, và một vạch 8px cạnh mép màn hình rất khó trúng bằng ngón tay.
4532
+ */
4533
+ readonly showRail: _angular_core.InputSignal<boolean>;
4534
+ /**
4535
+ * Chữ trên tooltip của thanh kéo — theo trạng thái SẼ TỚI, không phải trạng
4536
+ * thái đang đứng. Người dùng đọc nhãn để biết bấm vào thì được gì.
4537
+ */
4538
+ readonly railLabel: _angular_core.Signal<"Mở rộng" | "Thu gọn">;
4083
4539
  readonly currentWidth: _angular_core.Signal<string>;
4084
4540
  readonly sidebarClasses: _angular_core.Signal<string>;
4085
4541
  toggle(): void;
4086
4542
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlSidebar, never>;
4087
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlSidebar, "ol-sidebar", never, { "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "collapsedWidth": { "alias": "collapsedWidth"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; "bordered": { "alias": "bordered"; "required": false; "isSignal": true; }; }, { "collapsed": "collapsedChange"; }, never, ["[slot=header], [header]", "*", "[slot=footer], [footer]"], true, never>;
4543
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlSidebar, "ol-sidebar", never, { "collapsed": { "alias": "collapsed"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "collapsedWidth": { "alias": "collapsedWidth"; "required": false; "isSignal": true; }; "collapsible": { "alias": "collapsible"; "required": false; "isSignal": true; }; "bordered": { "alias": "bordered"; "required": false; "isSignal": true; }; "showRail": { "alias": "showRail"; "required": false; "isSignal": true; }; }, { "collapsed": "collapsedChange"; }, never, ["[slot=header], [header]", "*", "[slot=footer], [footer]"], true, never>;
4088
4544
  }
4089
4545
 
4090
4546
  declare class OlSidebarItem {
@@ -4096,7 +4552,7 @@ declare class OlSidebarItem {
4096
4552
  readonly href: _angular_core.InputSignal<string | null>;
4097
4553
  readonly icon: _angular_core.InputSignal<string | null>;
4098
4554
  readonly badge: _angular_core.InputSignal<string | number | null>;
4099
- readonly badgeTheme: _angular_core.InputSignal<BadgeTheme>;
4555
+ readonly badgeColor: _angular_core.InputSignal<BadgeColor>;
4100
4556
  readonly active: _angular_core.InputSignal<boolean>;
4101
4557
  readonly disabled: _angular_core.InputSignal<boolean>;
4102
4558
  readonly dot: _angular_core.InputSignal<boolean>;
@@ -4106,7 +4562,7 @@ declare class OlSidebarItem {
4106
4562
  */
4107
4563
  readonly itemClasses: _angular_core.Signal<string>;
4108
4564
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlSidebarItem, never>;
4109
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlSidebarItem, "ol-sidebar-item", never, { "routerLink": { "alias": "routerLink"; "required": false; "isSignal": true; }; "routerLinkActive": { "alias": "routerLinkActive"; "required": false; "isSignal": true; }; "routerLinkActiveOptions": { "alias": "routerLinkActiveOptions"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "badgeTheme": { "alias": "badgeTheme"; "required": false; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "dot": { "alias": "dot"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
4565
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlSidebarItem, "ol-sidebar-item", never, { "routerLink": { "alias": "routerLink"; "required": false; "isSignal": true; }; "routerLinkActive": { "alias": "routerLinkActive"; "required": false; "isSignal": true; }; "routerLinkActiveOptions": { "alias": "routerLinkActiveOptions"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "badgeColor": { "alias": "badgeColor"; "required": false; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "dot": { "alias": "dot"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
4110
4566
  }
4111
4567
 
4112
4568
  declare class OlSidebarGroup {
@@ -4119,7 +4575,7 @@ declare class OlSidebarSubmenu {
4119
4575
  readonly label: _angular_core.InputSignal<string>;
4120
4576
  readonly icon: _angular_core.InputSignal<string | null>;
4121
4577
  readonly badge: _angular_core.InputSignal<string | number | null>;
4122
- readonly badgeTheme: _angular_core.InputSignal<BadgeTheme>;
4578
+ readonly badgeColor: _angular_core.InputSignal<BadgeColor>;
4123
4579
  readonly isOpen: _angular_core.ModelSignal<boolean>;
4124
4580
  readonly active: _angular_core.InputSignal<boolean>;
4125
4581
  /**
@@ -4129,7 +4585,7 @@ declare class OlSidebarSubmenu {
4129
4585
  readonly triggerClasses: _angular_core.Signal<string>;
4130
4586
  toggle(): void;
4131
4587
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlSidebarSubmenu, never>;
4132
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlSidebarSubmenu, "ol-sidebar-submenu", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "badgeTheme": { "alias": "badgeTheme"; "required": false; "isSignal": true; }; "isOpen": { "alias": "isOpen"; "required": false; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; }, { "isOpen": "isOpenChange"; }, never, ["*"], true, never>;
4588
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlSidebarSubmenu, "ol-sidebar-submenu", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "badgeColor": { "alias": "badgeColor"; "required": false; "isSignal": true; }; "isOpen": { "alias": "isOpen"; "required": false; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; }, { "isOpen": "isOpenChange"; }, never, ["*"], true, never>;
4133
4589
  }
4134
4590
 
4135
4591
  /**
@@ -4233,6 +4689,10 @@ interface SpeedDialAction {
4233
4689
 
4234
4690
  declare class OlSpeedDial {
4235
4691
  private readonly elementRef;
4692
+ private readonly overlayContainer;
4693
+ /** Hàm gỡ khỏi ngăn xếp Escape. `null` khi đang đóng. */
4694
+ private releaseEscape;
4695
+ constructor();
4236
4696
  readonly direction: _angular_core.InputSignal<SpeedDialDirection>;
4237
4697
  readonly type: _angular_core.InputSignal<SpeedDialType>;
4238
4698
  readonly trigger: _angular_core.InputSignal<SpeedDialTrigger>;
@@ -4263,7 +4723,6 @@ declare class OlSpeedDial {
4263
4723
  onMouseLeave(): void;
4264
4724
  onBackdropMouseEnter(): void;
4265
4725
  onDocumentClick(event: MouseEvent): void;
4266
- onEscape(): void;
4267
4726
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlSpeedDial, never>;
4268
4727
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlSpeedDial, "ol-speed-dial", never, { "direction": { "alias": "direction"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "trigger": { "alias": "trigger"; "required": false; "isSignal": true; }; "color": { "alias": "color"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "tooltip": { "alias": "tooltip"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "backdrop": { "alias": "backdrop"; "required": false; "isSignal": true; }; "closeOnClickOutside": { "alias": "closeOnClickOutside"; "required": false; "isSignal": true; }; "closeOnEscape": { "alias": "closeOnEscape"; "required": false; "isSignal": true; }; "actions": { "alias": "actions"; "required": false; "isSignal": true; }; "customClass": { "alias": "class"; "required": false; "isSignal": true; }; "isOpen": { "alias": "isOpen"; "required": false; "isSignal": true; }; }, { "isOpen": "isOpenChange"; "onOpen": "onOpen"; "onClose": "onClose"; "actionClick": "actionClick"; }, never, ["*"], true, never>;
4269
4728
  }
@@ -4469,7 +4928,7 @@ declare class OlTabItem {
4469
4928
  readonly icon: _angular_core.InputSignal<string | null>;
4470
4929
  readonly avatar: _angular_core.InputSignal<string | null>;
4471
4930
  readonly badge: _angular_core.InputSignal<string | number | null>;
4472
- readonly badgeTheme: _angular_core.InputSignal<BadgeTheme>;
4931
+ readonly badgeColor: _angular_core.InputSignal<BadgeColor>;
4473
4932
  readonly disabled: _angular_core.InputSignal<boolean>;
4474
4933
  readonly displayLabel: _angular_core.Signal<string>;
4475
4934
  readonly displaySubtitle: _angular_core.Signal<string>;
@@ -4494,7 +4953,7 @@ declare class OlTabItem {
4494
4953
  */
4495
4954
  readonly hasTabRole: _angular_core.Signal<boolean>;
4496
4955
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlTabItem, never>;
4497
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlTabItem, "ol-tab-item", never, { "tabId": { "alias": "tabId"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "subtitle": { "alias": "subtitle"; "required": false; "isSignal": true; }; "helper": { "alias": "helper"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "avatar": { "alias": "avatar"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "badgeTheme": { "alias": "badgeTheme"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
4956
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlTabItem, "ol-tab-item", never, { "tabId": { "alias": "tabId"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "subtitle": { "alias": "subtitle"; "required": false; "isSignal": true; }; "helper": { "alias": "helper"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "avatar": { "alias": "avatar"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "badgeColor": { "alias": "badgeColor"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
4498
4957
  }
4499
4958
 
4500
4959
  /**
@@ -4869,12 +5328,12 @@ declare class OlBottomNavItem {
4869
5328
  readonly icon: _angular_core.InputSignal<string>;
4870
5329
  readonly label: _angular_core.InputSignal<string>;
4871
5330
  readonly badge: _angular_core.InputSignal<string | number | null>;
4872
- readonly badgeTheme: _angular_core.InputSignal<BadgeTheme>;
5331
+ readonly badgeColor: _angular_core.InputSignal<BadgeColor>;
4873
5332
  readonly isCenterAction: _angular_core.InputSignal<boolean>;
4874
5333
  readonly active: _angular_core.InputSignal<boolean>;
4875
5334
  readonly itemClasses: _angular_core.Signal<string>;
4876
5335
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlBottomNavItem, never>;
4877
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlBottomNavItem, "ol-bottom-nav-item", never, { "routerLink": { "alias": "routerLink"; "required": false; "isSignal": true; }; "routerLinkActive": { "alias": "routerLinkActive"; "required": false; "isSignal": true; }; "routerLinkActiveOptions": { "alias": "routerLinkActiveOptions"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "badgeTheme": { "alias": "badgeTheme"; "required": false; "isSignal": true; }; "isCenterAction": { "alias": "isCenterAction"; "required": false; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
5336
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlBottomNavItem, "ol-bottom-nav-item", never, { "routerLink": { "alias": "routerLink"; "required": false; "isSignal": true; }; "routerLinkActive": { "alias": "routerLinkActive"; "required": false; "isSignal": true; }; "routerLinkActiveOptions": { "alias": "routerLinkActiveOptions"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "badgeColor": { "alias": "badgeColor"; "required": false; "isSignal": true; }; "isCenterAction": { "alias": "isCenterAction"; "required": false; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
4878
5337
  }
4879
5338
 
4880
5339
  type StepState = 'initial' | 'active' | 'completed' | 'error' | 'disabled';
@@ -4938,7 +5397,7 @@ interface OlTreeNode {
4938
5397
  icon?: string;
4939
5398
  count?: number;
4940
5399
  badge?: string;
4941
- badgeTheme?: 'brand' | 'green' | 'yellow' | 'red' | 'gray';
5400
+ badgeColor?: 'brand' | 'green' | 'yellow' | 'red' | 'gray';
4942
5401
  children?: OlTreeNode[];
4943
5402
  expanded?: boolean;
4944
5403
  selected?: boolean;
@@ -4966,6 +5425,25 @@ declare class OlTree {
4966
5425
  * được truyền xuống MỌI cấp của cây đệ quy.
4967
5426
  */
4968
5427
  nodeTemplate?: TemplateRef<unknown>;
5428
+ /**
5429
+ * Nút/hành động gắn ở CUỐI mỗi hàng, khai bằng `#actionsTemplate`:
5430
+ *
5431
+ * ```html
5432
+ * <ol-tree [nodes]="nodes">
5433
+ * <ng-template #actionsTemplate let-node>
5434
+ * <ol-button size="xs" color="ghost" (btnClick)="sua(node)">Sửa</ol-button>
5435
+ * </ng-template>
5436
+ * </ol-tree>
5437
+ * ```
5438
+ *
5439
+ * Khác `#nodeTemplate` ở chỗ nó **cộng thêm** chứ không thay thế: icon, nhãn,
5440
+ * count và badge mặc định vẫn nguyên. `#nodeTemplate` là all-or-nothing —
5441
+ * bật lên thì phải tự vẽ lại cả bốn thứ đó, nên chỉ muốn thêm một nút ở cuối
5442
+ * mà phải dùng nó là chép thừa.
5443
+ *
5444
+ * Dùng được ĐỒNG THỜI với `#nodeTemplate`: nút vẫn hiện ở cả hai nhánh.
5445
+ */
5446
+ actionsTemplate?: TemplateRef<unknown>;
4969
5447
  readonly checkable: _angular_core.InputSignal<boolean>;
4970
5448
  readonly selectionMode: _angular_core.InputSignal<OlTreeSelectionMode>;
4971
5449
  readonly bordered: _angular_core.InputSignal<boolean>;
@@ -5012,7 +5490,7 @@ declare class OlTree {
5012
5490
  private setSelectedNodeSingle;
5013
5491
  private cloneTree;
5014
5492
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlTree, never>;
5015
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlTree, "ol-tree", never, { "nodes": { "alias": "nodes"; "required": false; "isSignal": true; }; "checkable": { "alias": "checkable"; "required": false; "isSignal": true; }; "selectionMode": { "alias": "selectionMode"; "required": false; "isSignal": true; }; "bordered": { "alias": "bordered"; "required": false; "isSignal": true; }; "toggleIcon": { "alias": "toggleIcon"; "required": false; "isSignal": true; }; }, { "nodes": "nodesChange"; "nodeSelect": "nodeSelect"; "nodeCheck": "nodeCheck"; }, ["nodeTemplate"], never, true, never>;
5493
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlTree, "ol-tree", never, { "nodes": { "alias": "nodes"; "required": false; "isSignal": true; }; "checkable": { "alias": "checkable"; "required": false; "isSignal": true; }; "selectionMode": { "alias": "selectionMode"; "required": false; "isSignal": true; }; "bordered": { "alias": "bordered"; "required": false; "isSignal": true; }; "toggleIcon": { "alias": "toggleIcon"; "required": false; "isSignal": true; }; }, { "nodes": "nodesChange"; "nodeSelect": "nodeSelect"; "nodeCheck": "nodeCheck"; }, ["nodeTemplate", "actionsTemplate"], never, true, never>;
5016
5494
  }
5017
5495
 
5018
5496
  type OlTreeNodeSelectionMode = 'single' | 'multiple';
@@ -5032,6 +5510,13 @@ declare class OlTreeNodeItem {
5032
5510
  * BUG-017 — họ không có cách nào biết phải khai lại những thứ đó.
5033
5511
  */
5034
5512
  readonly nodeTemplate: _angular_core.InputSignal<TemplateRef<unknown> | null>;
5513
+ /**
5514
+ * Template cho phần CUỐI hàng — nút, menu, hành động.
5515
+ *
5516
+ * Cộng thêm chứ không thay thế: dựng NGOÀI cặp `@if (nodeTemplate())` nên
5517
+ * hiện ở cả hai nhánh, dùng chung được với `nodeTemplate`.
5518
+ */
5519
+ readonly actionsTemplate: _angular_core.InputSignal<TemplateRef<unknown> | null>;
5035
5520
  readonly checkable: _angular_core.InputSignal<boolean>;
5036
5521
  readonly selectionMode: _angular_core.InputSignal<OlTreeNodeSelectionMode>;
5037
5522
  readonly toggleIcon: _angular_core.InputSignal<OlTreeNodeToggleIcon>;
@@ -5055,6 +5540,23 @@ declare class OlTreeNodeItem {
5055
5540
  protected readonly ariaLevel: _angular_core.Signal<number>;
5056
5541
  /** `aria-expanded` CHỈ đặt cho node có con; node lá để `null`. */
5057
5542
  protected readonly ariaExpanded: _angular_core.Signal<boolean | null>;
5543
+ /**
5544
+ * Ngữ cảnh cho CẢ HAI template. Một `computed` dùng chung chứ không viết
5545
+ * object thẳng trong template: viết thẳng thì mỗi lần dò thay đổi lại sinh
5546
+ * một object mới, `ngTemplateOutlet` thấy khác tham chiếu nên dựng lại nội
5547
+ * dung — mất cả trạng thái bên trong nút người dùng đặt vào.
5548
+ *
5549
+ * `$implicit` cho `let-node`; `node` cho `let-n="node"`. Ba khoá còn lại bắt
5550
+ * kịp `ol-autocomplete` (đã có `selected`) và mở thêm `level`/`expanded` —
5551
+ * hàng cây thường cần biết mình sâu bao nhiêu để thụt chữ hay đổi cỡ.
5552
+ */
5553
+ protected readonly tplContext: _angular_core.Signal<{
5554
+ $implicit: OlTreeNode;
5555
+ node: OlTreeNode;
5556
+ level: number;
5557
+ selected: boolean;
5558
+ expanded: boolean;
5559
+ }>;
5058
5560
  constructor();
5059
5561
  /**
5060
5562
  * Nút cha có con chọn một phần thì ô của nó phải là dấu gạch.
@@ -5075,7 +5577,7 @@ declare class OlTreeNodeItem {
5075
5577
  handleClick(): void;
5076
5578
  handleCheck(checked: boolean): void;
5077
5579
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlTreeNodeItem, never>;
5078
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlTreeNodeItem, "ol-tree-node", never, { "node": { "alias": "node"; "required": true; "isSignal": true; }; "nodeTemplate": { "alias": "nodeTemplate"; "required": false; "isSignal": true; }; "checkable": { "alias": "checkable"; "required": false; "isSignal": true; }; "selectionMode": { "alias": "selectionMode"; "required": false; "isSignal": true; }; "toggleIcon": { "alias": "toggleIcon"; "required": false; "isSignal": true; }; "level": { "alias": "level"; "required": false; "isSignal": true; }; "tabbableId": { "alias": "tabbableId"; "required": false; "isSignal": true; }; "focusedId": { "alias": "focusedId"; "required": false; "isSignal": true; }; }, { "nodeClick": "nodeClick"; "nodeCheck": "nodeCheck"; "toggleExpand": "toggleExpand"; "nodeFocus": "nodeFocus"; }, never, never, true, never>;
5580
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlTreeNodeItem, "ol-tree-node", never, { "node": { "alias": "node"; "required": true; "isSignal": true; }; "nodeTemplate": { "alias": "nodeTemplate"; "required": false; "isSignal": true; }; "actionsTemplate": { "alias": "actionsTemplate"; "required": false; "isSignal": true; }; "checkable": { "alias": "checkable"; "required": false; "isSignal": true; }; "selectionMode": { "alias": "selectionMode"; "required": false; "isSignal": true; }; "toggleIcon": { "alias": "toggleIcon"; "required": false; "isSignal": true; }; "level": { "alias": "level"; "required": false; "isSignal": true; }; "tabbableId": { "alias": "tabbableId"; "required": false; "isSignal": true; }; "focusedId": { "alias": "focusedId"; "required": false; "isSignal": true; }; }, { "nodeClick": "nodeClick"; "nodeCheck": "nodeCheck"; "toggleExpand": "toggleExpand"; "nodeFocus": "nodeFocus"; }, never, never, true, never>;
5079
5581
  }
5080
5582
 
5081
5583
  type ChartType = 'line' | 'smooth-line' | 'area' | 'smooth-area' | 'step-line' | 'bar' | 'stacked-bar' | 'horizontal-bar' | 'stacked-horizontal-bar' | 'diverging-bar' | 'pie' | 'donut' | 'rose' | 'radar' | 'gauge' | 'radial' | 'scatter' | 'heatmap' | 'boxplot';
@@ -5574,84 +6076,6 @@ declare class OlJumbotron {
5574
6076
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlJumbotron, "ol-jumbotron", never, { "headingLevel": { "alias": "headingLevel"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "subtitle": { "alias": "subtitle"; "required": false; "isSignal": true; }; "badgeText": { "alias": "badgeText"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; }, {}, never, ["[slot=badge-icon]", "[slot=actions]", "*"], true, never>;
5575
6077
  }
5576
6078
 
5577
- /**
5578
- * Abstract base class cho các overlay components (Modal, Drawer, Popover)
5579
- * Cung cấp functionality chung cho việc mở/đóng và xử lý interactions
5580
- */
5581
- declare abstract class OlOverlayBase implements OnDestroy {
5582
- /**
5583
- * Signal tracking trạng thái mở/đóng của overlay
5584
- */
5585
- isOpen: WritableSignal<boolean>;
5586
- /**
5587
- * Signal cho việc hiển thị backdrop
5588
- */
5589
- backdrop: WritableSignal<boolean>;
5590
- /**
5591
- * Signal cho phép đóng overlay khi nhấn Escape
5592
- */
5593
- closeOnEscape: WritableSignal<boolean>;
5594
- /**
5595
- * Signal cho phép đóng overlay khi click vào backdrop
5596
- */
5597
- closeOnBackdrop: WritableSignal<boolean>;
5598
- /**
5599
- * Signal tracking animation state
5600
- */
5601
- protected animating: WritableSignal<boolean>;
5602
- /** Handle của setTimeout animation — lưu lại để huỷ khi destroy, tránh
5603
- * callback chạy trên instance đã chết. */
5604
- private animationTimer;
5605
- constructor();
5606
- /**
5607
- * Mở overlay với optional animation
5608
- */
5609
- open(): void;
5610
- /**
5611
- * Đóng overlay với optional animation
5612
- */
5613
- close(): void;
5614
- /**
5615
- * Toggle trạng thái overlay
5616
- */
5617
- toggle(): void;
5618
- /**
5619
- * Xử lý sự kiện click vào backdrop
5620
- */
5621
- handleBackdropClick(event: MouseEvent): void;
5622
- /**
5623
- * Xử lý sự kiện nhấn phím Escape
5624
- */
5625
- protected handleEscape: (event: KeyboardEvent) => void;
5626
- /**
5627
- * Lifecycle hook được gọi khi overlay mở
5628
- * Override trong subclass để customize behavior
5629
- */
5630
- protected onOpen(): void;
5631
- /**
5632
- * Lifecycle hook được gọi khi overlay đóng
5633
- * Override trong subclass để customize behavior
5634
- */
5635
- protected onClose(): void;
5636
- /**
5637
- * Thêm event listener cho phím Escape
5638
- */
5639
- private addEscapeListener;
5640
- /**
5641
- * Xóa event listener cho phím Escape
5642
- */
5643
- private removeEscapeListener;
5644
- /**
5645
- * Cleanup khi component bị destroy.
5646
- * Gọi tự động qua ngOnDestroy — trước đây hàm này tồn tại nhưng không ai gọi,
5647
- * nên component destroy lúc đang mở sẽ để lại listener keydown trên document.
5648
- */
5649
- protected cleanup(): void;
5650
- ngOnDestroy(): void;
5651
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlOverlayBase, never>;
5652
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<OlOverlayBase, never, never, {}, {}, never, never, true, never>;
5653
- }
5654
-
5655
6079
  /**
5656
6080
  * Standalone Backdrop Component
5657
6081
  * Hiển thị overlay backdrop với animation fade in/out và dark mode support
@@ -5923,6 +6347,56 @@ declare class OlOverlayContainer {
5923
6347
  * Trả về hàm hoàn tác — gọi khi lớp đóng để trả phần tử về chỗ cũ.
5924
6348
  */
5925
6349
  attach(el: HTMLElement): () => void;
6350
+ /**
6351
+ * Các lớp nổi ĐANG MỞ, xếp theo thứ tự mở — phần tử cuối là lớp trên cùng.
6352
+ *
6353
+ * Dùng mảng chứ không `Set`: thứ tự chính là thông tin cần, và một lớp không
6354
+ * thể mở hai lần nên không sợ trùng.
6355
+ */
6356
+ private readonly openLayers;
6357
+ /** Trình nghe Escape duy nhất, gắn khi có lớp đầu tiên mở. */
6358
+ private escapeListener;
6359
+ /**
6360
+ * Đăng ký một lớp nổi vừa mở. Trả hàm gỡ — gọi khi lớp đóng.
6361
+ *
6362
+ * ## Vì sao cần
6363
+ *
6364
+ * Trước đây mỗi component tự gắn `@HostListener('document:keydown.escape')`.
6365
+ * Không ai chặn lan truyền và không ai biết ai, nên **một phím Escape đóng
6366
+ * MỌI lớp đang mở**: mở datepicker trong modal rồi nhấn Escape thì cả hai
6367
+ * cùng đóng, người dùng mất luôn hộp thoại đang điền dở.
6368
+ *
6369
+ * Ở đây một trình nghe duy nhất, chỉ gọi `close()` của lớp **trên cùng**.
6370
+ * Nhấn lần nữa mới tới lớp dưới — đúng cách người dùng chờ đợi.
6371
+ *
6372
+ * ## Dùng thế nào
6373
+ *
6374
+ * ```ts
6375
+ * private releaseEscape: (() => void) | null = null;
6376
+ *
6377
+ * open(): void {
6378
+ * this.releaseEscape = this.overlayContainer.register(() => this.close());
6379
+ * }
6380
+ *
6381
+ * close(): void {
6382
+ * this.releaseEscape?.();
6383
+ * this.releaseEscape = null;
6384
+ * }
6385
+ * ```
6386
+ *
6387
+ * Hàm gỡ **an toàn khi gọi nhiều lần** — `close()` thường chạy cả từ phím
6388
+ * Escape lẫn từ nút đóng, và cả hai đường đều gọi nó.
6389
+ */
6390
+ register(close: () => void): () => void;
6391
+ /**
6392
+ * Gắn trình nghe khi có lớp đầu tiên, không gắn sẵn từ lúc dựng service.
6393
+ *
6394
+ * Không có lớp nào mở mà vẫn nghe phím là bắt mọi lần nhấn Escape của cả
6395
+ * ứng dụng — kể cả khi người dùng đang gõ trong ô nhập bình thường.
6396
+ */
6397
+ private ensureEscapeListener;
6398
+ /** Gỡ trình nghe khi lớp cuối cùng đóng — không để nó nghe vô ích. */
6399
+ private teardownEscapeListenerIfIdle;
5926
6400
  /**
5927
6401
  * @deprecated Dùng `attach()`. Giữ lại vì đã publish trong
5928
6402
  * `@edmicro/olkit@1.1.1` — bỏ phương thức công khai là breaking change.
@@ -5932,6 +6406,6 @@ declare class OlOverlayContainer {
5932
6406
  static ɵprov: _angular_core.ɵɵInjectableDeclaration<any>;
5933
6407
  }
5934
6408
 
5935
- export { CHAT_BUBBLE_STATUS, MONTHS_FULL_EN, MONTHS_FULL_VI, MONTHS_SHORT_VI, OlAccordion, OlAccordionItem, OlAlert, OlAlertDialog, OlAspectRatio, OlAutocomplete, OlAvatar, OlAvatarGroup, OlBackdrop, OlBadge, OlBanner, OlBottomNav, OlBottomNavItem, OlBreadcrumb, OlBreadcrumbItem, OlButton, OlButtonGroup, OlCard, OlCarousel, OlCarouselSlide, OlChart, OlChatBubble, OlChatContainer, OlCheckbox, OlCheckboxRadioForm, OlCheckboxRadioGroup, OlClipboard, OlCollapse, OlCommand, OlDateRangePicker, OlDatepicker, OlDatepickerDirective, OlDatepickerFooter, OlDatepickerHeader, OlDatepickerPopup, OlDatepickerStateService, OlDayView, OlDeviceMockup, OlDownloadAppButton, OlDrawer, OlDrawerFooter, OlDrawerHeader, OlDropdown, OlDropdownHeader, OlDropdownItem, OlEmpty, OlFileInput, OlFloatingLabel, OlFocusTrapService, OlFooter, OlGallery, OlGalleryItem, OlHelper, OlIcon, OlIconService, OlIconShape, OlInput, OlInputCounter, OlJumbotron, OlKbd, OlLabel, OlListGroup, OlListGroupItem, OlLoadingOverlay, OlModal, OlModalFooter, OlModalHeader, OlMonthView, OlNavDropdown, OlNavbar, OlNavbarItem, OlOtpInput, OlOverlayBase, OlOverlayContainer, OlPagination, OlPopover, OlPopoverContent, OlPositioningService, OlProgress, OlProgressBarService, OlProgressBarTop, OlRadio, OlRange, OlRating, OlRichTextEditor, OlScrollArea, OlSelect, OlSeparator, OlSidebar, OlSidebarGroup, OlSidebarItem, OlSidebarSubmenu, OlSkeleton, OlSpeedDial, OlSpeedDialItem, OlSpinner, OlStepItem, OlStepper, OlTabItem, OlTable, OlTableLoading, OlTableRow, OlTabs, OlTagInput, OlTextarea, OlTimeline, OlTimelineItem, OlTimepicker, OlToast, OlToastContainer, OlToastService, OlToggle, OlToggleGroup, OlToggleInput, OlTooltip, OlTooltipDirective, OlTree, OlTreeNodeItem, OlYearView, WEEKDAYS_SHORT_EN, WEEKDAYS_SHORT_VI, boDau, cloneDate, endOfDay, formatDate, generateMonthMatrix, generateMonthsMatrix, generateYearsMatrix, isBetween, isDateDisabled, isSameDay, isSameMonth, isSameYear, isToday, parseDate, startOfDay, stripDiacritics };
5936
- export type { AccordionVariant, AlertColor, AlertDialogTone, AlertLayout, AlertRounded, AlertType, AlertVariant, AppDevice, AppTheme, AutocompleteOption, AutocompleteSize, AutocompleteState, AvatarShape, AvatarSize, AvatarStatus, BadgeShape, BadgeSize, BadgeTheme, BadgeType, BannerPosition, BannerVariant, BoxplotDataPoint, BreadcrumbItemStatus, BreadcrumbSeparator, BreadcrumbVariant, ButtonColor, ButtonGroupColor, ButtonGroupOrientation, ButtonGroupSize, ButtonSize, CardPadding, CardRadius, CardShadow, CardVariant, ChartDataPoint, ChartSeries, ChartType, ChatBubbleStatus, ChatSender, CheckboxSize, ChoiceControl, ChoiceControlPosition, ChoiceGroupLayout, ChoiceLayout, ChoiceShape, CommandGroup, CommandItem, DateCustomClass, DateRange, DatepickerPreset, DatepickerSelectionMode, DatepickerSize, DatepickerViewMode, DayCell, DeviceType, DrawerFooterLayout, DrawerPlacement, DrawerSize, DropdownAutoClose, DropdownPlacement, DropdownTrigger, EmptySize, FileInputSize, FloatingLabelSize, FloatingLabelState, FloatingLabelVariant, HeatmapData, HelperFeature, HelperRule, HelperSize, HelperState, IconColor, IconShapeColor, IconShapeSize, IconShapeType, IconSize, IconVariant, InputCounterSize, InputSize, InputState, JumbotronVariant, ListGroupType, ModalFooterLayout, ModalPlacement, ModalSize, MonthCell, OlAvatarStatusPosition, OlBottomNavPosition, OlButtonType, OlCheckboxRadioFormAlign, OlCheckboxRadioGroupRole, OlDateRangePickerVariant, OlGalleryGap, OlGalleryRatio, OlHelperType, OlModalBackdrop, OlModalRole, OlSkeletonAnimation, OlSkeletonAspectRatio, OlSkeletonRounded, OlSkeletonType, OlSpeedDialTooltipPosition, OlTimepickerAddonType, OlToggleInputAlign, OlTreeNode, OlTreeNodeSelectionMode, OlTreeNodeToggleIcon, OlTreeSelectionMode, OlTreeToggleIcon, OtpInputSize, PaginationType, PaginationVariant, PopoverPlacement, PopoverTrigger, PositionedCoordinates, PositioningOptions, ProgressColor, ProgressLabelPosition, ProgressSize, RadarIndicator, RadioSize, RatingType, ScatterDataPoint, ScatterSeries, ScrollAreaAxis, ScrollAreaScrollbar, SelectOption, SelectSize, SelectState, SeparatorOrientation, SpeedDialAction, SpeedDialColor, SpeedDialDirection, SpeedDialTrigger, SpeedDialType, StepState, StepperBreakpoint, StepperOrientation, StepperVariant, TabsSize, TabsVariant, TagInputSize, TextareaState, TimeObject, TimepickerFormat, TimepickerSize, TimepickerState, Toast, ToastConfig, ToastPosition, ToggleColor, TogglePosition, ToggleSize, YearCell };
6409
+ export { CHAT_BUBBLE_STATUS, MONTHS_FULL_EN, MONTHS_FULL_VI, MONTHS_SHORT_VI, OlAccordion, OlAccordionItem, OlAlert, OlAlertDialog, OlAppNav, OlAspectRatio, OlAutocomplete, OlAvatar, OlAvatarGroup, OlBackdrop, OlBadge, OlBanner, OlBottomNav, OlBottomNavItem, OlBreadcrumb, OlBreadcrumbItem, OlButton, OlButtonGroup, OlCard, OlCarousel, OlCarouselSlide, OlChart, OlChatBubble, OlChatContainer, OlCheckbox, OlCheckboxRadioForm, OlCheckboxRadioGroup, OlClipboard, OlCollapse, OlCommand, OlDateRangePicker, OlDatepicker, OlDatepickerDirective, OlDatepickerFooter, OlDatepickerHeader, OlDatepickerPopup, OlDatepickerStateService, OlDayView, OlDeviceMockup, OlDownloadAppButton, OlDrawer, OlDrawerFooter, OlDrawerHeader, OlDropdown, OlDropdownHeader, OlDropdownItem, OlEmpty, OlFileInput, OlFloatingLabel, OlFocusTrapService, OlFooter, OlGallery, OlGalleryItem, OlHelper, OlIcon, OlIconService, OlIconShape, OlInput, OlInputCounter, OlJumbotron, OlKbd, OlLabel, OlListGroup, OlListGroupItem, OlLoadingOverlay, OlModal, OlModalFooter, OlModalHeader, OlMonthView, OlNavDropdown, OlNavbar, OlNavbarItem, OlOtpInput, OlOverlayContainer, OlPagination, OlPopover, OlPopoverContent, OlPositioningService, OlProgress, OlProgressBarService, OlProgressBarTop, OlRadio, OlRange, OlRating, OlRichTextEditor, OlScrollArea, OlSelect, OlSeparator, OlSidebar, OlSidebarGroup, OlSidebarItem, OlSidebarSubmenu, OlSkeleton, OlSpeedDial, OlSpeedDialItem, OlSpinner, OlStepItem, OlStepper, OlTabItem, OlTable, OlTableLoading, OlTableRow, OlTabs, OlTagInput, OlTextarea, OlTimeline, OlTimelineItem, OlTimepicker, OlToast, OlToastContainer, OlToastService, OlToggle, OlToggleGroup, OlToggleInput, OlTooltip, OlTooltipDirective, OlTree, OlTreeNodeItem, OlYearView, WEEKDAYS_SHORT_EN, WEEKDAYS_SHORT_VI, boDau, cloneDate, endOfDay, formatDate, generateMonthMatrix, generateMonthsMatrix, generateYearsMatrix, isBetween, isDateDisabled, isSameDay, isSameMonth, isSameYear, isToday, parseDate, startOfDay, stripDiacritics };
6410
+ export type { AccordionVariant, AlertColor, AlertDialogTone, AlertLayout, AlertRounded, AlertType, AlertVariant, AppDevice, AppNavConfig, AppNavGroup, AppNavItem, AppNavUser, AppTheme, AutocompleteOption, AutocompleteSize, AutocompleteState, AvatarShape, AvatarSize, AvatarStatus, BadgeColor, BadgeShape, BadgeSize, BadgeTheme, BadgeType, BannerPosition, BannerVariant, BoxplotDataPoint, BreadcrumbItemStatus, BreadcrumbSeparator, BreadcrumbVariant, ButtonColor, ButtonGroupColor, ButtonGroupOrientation, ButtonGroupSize, ButtonSize, CardPadding, CardRadius, CardShadow, CardVariant, ChartDataPoint, ChartSeries, ChartType, ChatBubbleStatus, ChatSender, CheckboxSize, ChoiceControl, ChoiceControlPosition, ChoiceGroupLayout, ChoiceLayout, ChoiceShape, CommandGroup, CommandItem, DateCustomClass, DateRange, DatepickerPreset, DatepickerSelectionMode, DatepickerSize, DatepickerViewMode, DayCell, DeviceType, DrawerFooterLayout, DrawerPlacement, DrawerSize, DropdownAutoClose, DropdownPlacement, DropdownTrigger, EmptySize, FileInputSize, FloatingLabelSize, FloatingLabelState, FloatingLabelVariant, HeatmapData, HelperFeature, HelperRule, HelperSize, HelperState, IconColor, IconShapeColor, IconShapeSize, IconShapeType, IconSize, IconVariant, InputCounterSize, InputSize, InputState, JumbotronVariant, ListGroupType, ModalFooterLayout, ModalPlacement, ModalSize, MonthCell, OlAvatarStatusPosition, OlBottomNavPosition, OlButtonType, OlCheckboxRadioFormAlign, OlCheckboxRadioGroupRole, OlDateRangePickerVariant, OlGalleryGap, OlGalleryRatio, OlHelperType, OlModalBackdrop, OlModalRole, OlSkeletonAnimation, OlSkeletonAspectRatio, OlSkeletonRounded, OlSkeletonType, OlSpeedDialTooltipPosition, OlTimepickerAddonType, OlToggleInputAlign, OlTreeNode, OlTreeNodeSelectionMode, OlTreeNodeToggleIcon, OlTreeSelectionMode, OlTreeToggleIcon, OtpInputSize, PaginationType, PaginationVariant, PopoverPlacement, PopoverTrigger, PositionedCoordinates, PositioningOptions, ProgressColor, ProgressLabelPosition, ProgressSize, RadarIndicator, RadioSize, RatingType, ScatterDataPoint, ScatterSeries, ScrollAreaAxis, ScrollAreaScrollbar, SelectOption, SelectSize, SelectState, SeparatorOrientation, SpeedDialAction, SpeedDialColor, SpeedDialDirection, SpeedDialTrigger, SpeedDialType, StepState, StepperBreakpoint, StepperOrientation, StepperVariant, TabsSize, TabsVariant, TagInputSize, TextareaState, TimeObject, TimepickerFormat, TimepickerSize, TimepickerState, Toast, ToastConfig, ToastPosition, ToggleColor, TogglePosition, ToggleSize, YearCell };
5937
6411
  //# sourceMappingURL=edmicro-olkit.d.ts.map