@edmicro/olkit 1.1.5 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/edmicro-olkit.mjs +2678 -133
- package/fesm2022/edmicro-olkit.mjs.map +1 -1
- package/olkit.css +1 -1
- package/package.json +1 -1
- package/types/edmicro-olkit.d.ts +1177 -12
- package/types/edmicro-olkit.d.ts.map +1 -1
- package/version.txt +2 -2
- package/LICENSES/LICENSES/FLOWBITE-MIT.txt +0 -21
- package/LICENSES/LICENSES/MYNAUI-MIT.txt +0 -21
- package/LICENSES/LICENSES/SOLAR-CC-BY-4.0.txt +0 -49
package/types/edmicro-olkit.d.ts
CHANGED
|
@@ -246,6 +246,106 @@ declare class OlScrollArea {
|
|
|
246
246
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlScrollArea, "ol-scroll-area", never, { "scrollbar": { "alias": "scrollbar"; "required": false; "isSignal": true; }; "axis": { "alias": "axis"; "required": false; "isSignal": true; }; "smooth": { "alias": "smooth"; "required": false; "isSignal": true; }; "innerClass": { "alias": "innerClass"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
+
/** Một mục trong mục lục. */
|
|
250
|
+
interface OlScrollspyItem {
|
|
251
|
+
/** `id` của phần tử trên trang mà mục này trỏ tới. */
|
|
252
|
+
id: string;
|
|
253
|
+
label: string;
|
|
254
|
+
/** Cấp thụt lề: 1 là mục chính, 2 là mục con. */
|
|
255
|
+
level?: 1 | 2;
|
|
256
|
+
}
|
|
257
|
+
type OlScrollspyOrientation = 'vertical' | 'horizontal';
|
|
258
|
+
/**
|
|
259
|
+
* Mục lục tự đánh dấu phần đang xem.
|
|
260
|
+
*
|
|
261
|
+
* Chưa có node Figma — dựng theo design system, mục đang xem dùng
|
|
262
|
+
* `text-fg-brand` và một vạch `bg-brand` bên trái (dọc) hoặc dưới (ngang).
|
|
263
|
+
*
|
|
264
|
+
* ## Vì sao `IntersectionObserver` chứ không nghe sự kiện `scroll`
|
|
265
|
+
*
|
|
266
|
+
* Nghe `scroll` thì mỗi lần cuộn là một lần chạy tay tính `getBoundingClientRect()`
|
|
267
|
+
* cho MỌI phần — trang 63 mục như docs olkit là 63 phép đo mỗi khung hình.
|
|
268
|
+
* `IntersectionObserver` để trình duyệt tự báo, và chỉ báo phần nào đổi trạng
|
|
269
|
+
* thái.
|
|
270
|
+
*
|
|
271
|
+
* ## `rootMargin` quyết định "đang xem" nghĩa là gì
|
|
272
|
+
*
|
|
273
|
+
* Mặc định `-20% 0px -70% 0px` thu vùng quan sát thành một dải ngang mỏng ở
|
|
274
|
+
* khoảng 1/4 trên màn hình. Không thu thì phần nào chạm mép dưới màn hình cũng
|
|
275
|
+
* tính là đang xem, và cuộn một nhịp có thể sáng ba mục cùng lúc.
|
|
276
|
+
*
|
|
277
|
+
* Dải mỏng cũng xử lý được phần NGẮN hơn màn hình: nếu đợi phần chiếm trọn
|
|
278
|
+
* viewport mới tính, mục ngắn không bao giờ được đánh dấu.
|
|
279
|
+
*
|
|
280
|
+
* ## Phần cuối trang không bao giờ chạm dải
|
|
281
|
+
*
|
|
282
|
+
* Cuộn hết cỡ mà phần cuối vẫn nằm dưới dải quan sát thì nó không sáng. Nên
|
|
283
|
+
* khi chạm đáy trang, component đánh dấu thẳng mục cuối — `atBottom()`.
|
|
284
|
+
*
|
|
285
|
+
* ## Lưu ý khi viết test
|
|
286
|
+
*
|
|
287
|
+
* jsdom KHÔNG có `IntersectionObserver` (đo 2026-09-26: `typeof` trả
|
|
288
|
+
* `'undefined'`). Component tự bảo vệ bằng cách kiểm trước khi dùng, nên spec
|
|
289
|
+
* dựng được và khoá được phần hiển thị; còn việc đánh dấu theo cuộn phải
|
|
290
|
+
* nghiệm thu trên trình duyệt. Đừng giả lập `IntersectionObserver` rồi tưởng
|
|
291
|
+
* đã kiểm hành vi thật.
|
|
292
|
+
*/
|
|
293
|
+
declare class OlScrollspy {
|
|
294
|
+
private readonly elementRef;
|
|
295
|
+
private readonly destroyRef;
|
|
296
|
+
readonly items: _angular_core.InputSignal<OlScrollspyItem[]>;
|
|
297
|
+
readonly orientation: _angular_core.InputSignal<OlScrollspyOrientation>;
|
|
298
|
+
readonly ariaLabel: _angular_core.InputSignal<string>;
|
|
299
|
+
/**
|
|
300
|
+
* Vùng quan sát, theo cú pháp `rootMargin` của `IntersectionObserver`.
|
|
301
|
+
*
|
|
302
|
+
* Đổi giá trị này khi trang có thanh trên cố định: `-80px 0px -70% 0px` đẩy
|
|
303
|
+
* mép trên xuống dưới thanh đó.
|
|
304
|
+
*/
|
|
305
|
+
readonly rootMargin: _angular_core.InputSignal<string>;
|
|
306
|
+
/** Cuộn mượt khi bấm mục. Tắt nếu trang tự lo việc cuộn. */
|
|
307
|
+
readonly smoothScroll: _angular_core.InputSignal<boolean>;
|
|
308
|
+
/**
|
|
309
|
+
* Khung cuộn chứa nội dung. `null` (mặc định) nghĩa là cả trang.
|
|
310
|
+
*
|
|
311
|
+
* BẮT BUỘC truyền khi nội dung nằm trong một khung `overflow-y-auto` riêng:
|
|
312
|
+
* `IntersectionObserver` mặc định quan sát theo VIEWPORT, nên phần nào cũng
|
|
313
|
+
* "đang hiện" khi khung con nằm trong tầm mắt — đo được: cuộn khung con từ
|
|
314
|
+
* đầu tới đáy mà không mục nào sáng.
|
|
315
|
+
*/
|
|
316
|
+
readonly scrollRoot: _angular_core.InputSignal<HTMLElement | null>;
|
|
317
|
+
private readonly currentId;
|
|
318
|
+
/** `id` của phần đang xem. Rỗng khi chưa phần nào vào vùng quan sát. */
|
|
319
|
+
readonly activeId: _angular_core.Signal<string>;
|
|
320
|
+
readonly activeChange: _angular_core.OutputEmitterRef<string>;
|
|
321
|
+
private observer;
|
|
322
|
+
constructor();
|
|
323
|
+
private startObserving;
|
|
324
|
+
/** Khung (hoặc trang) đã cuộn tới sát đáy chưa — sai số 4px cho tròn số lẻ. */
|
|
325
|
+
private atBottom;
|
|
326
|
+
private stopObserving;
|
|
327
|
+
private setActive;
|
|
328
|
+
/**
|
|
329
|
+
* Bấm mục thì cuộn tới phần tương ứng và đánh dấu NGAY.
|
|
330
|
+
*
|
|
331
|
+
* Không đợi `IntersectionObserver` báo: cuộn mượt mất vài trăm mili giây, và
|
|
332
|
+
* trong quãng đó mục vừa bấm chưa sáng — người dùng tưởng bấm hụt.
|
|
333
|
+
*/
|
|
334
|
+
protected onClick(event: MouseEvent, item: OlScrollspyItem): void;
|
|
335
|
+
protected readonly navClasses: _angular_core.Signal<"block" | "block w-full overflow-x-auto">;
|
|
336
|
+
protected readonly listClasses: _angular_core.Signal<"flex flex-col gap-0.5 border-s border-default ps-0" | "flex items-center gap-1 border-b border-default">;
|
|
337
|
+
/**
|
|
338
|
+
* Class của một mục.
|
|
339
|
+
*
|
|
340
|
+
* Gom vào MỘT chuỗi qua ba-ngôi thay vì nhiều `[class.x]` rời: hai class
|
|
341
|
+
* cùng thuộc tính thì trình duyệt chọn theo thứ tự luật trong file CSS chứ
|
|
342
|
+
* không theo thứ tự viết, kết quả đổi theo bản build.
|
|
343
|
+
*/
|
|
344
|
+
protected linkClasses(item: OlScrollspyItem): string;
|
|
345
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlScrollspy, never>;
|
|
346
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlScrollspy, "ol-scrollspy", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "rootMargin": { "alias": "rootMargin"; "required": false; "isSignal": true; }; "smoothScroll": { "alias": "smoothScroll"; "required": false; "isSignal": true; }; "scrollRoot": { "alias": "scrollRoot"; "required": false; "isSignal": true; }; }, { "activeChange": "activeChange"; }, never, never, true, never>;
|
|
347
|
+
}
|
|
348
|
+
|
|
249
349
|
type ButtonColor = 'default' | 'brand' | 'primary' | 'alternative' | 'secondary' | 'tertiary' | 'ghost' | 'success' | 'green' | 'danger' | 'red' | 'warning' | 'yellow' | 'dark' | 'light';
|
|
250
350
|
type ButtonSize = 'xs' | 'sm' | 'base' | 'l' | 'xl';
|
|
251
351
|
type OlButtonType = 'button' | 'submit' | 'reset';
|
|
@@ -1629,6 +1729,8 @@ declare class OlDropdown {
|
|
|
1629
1729
|
private detachMenu;
|
|
1630
1730
|
/** Hàm gỡ khỏi ngăn xếp Escape. `null` khi đang đóng. */
|
|
1631
1731
|
private releaseEscape;
|
|
1732
|
+
/** Hàm gỡ listener Tab trên panel. `null` khi đang đóng. */
|
|
1733
|
+
private releaseMenuKeydown;
|
|
1632
1734
|
readonly label: _angular_core.InputSignal<string | null>;
|
|
1633
1735
|
readonly isOpen: _angular_core.ModelSignal<boolean>;
|
|
1634
1736
|
/**
|
|
@@ -1679,6 +1781,75 @@ declare class OlDropdown {
|
|
|
1679
1781
|
onTriggerClick(): void;
|
|
1680
1782
|
onMouseEnter(): void;
|
|
1681
1783
|
onMouseLeave(): void;
|
|
1784
|
+
/**
|
|
1785
|
+
* Danh sách phần tử nhận được tiêu điểm, theo thứ tự nhìn thấy.
|
|
1786
|
+
*
|
|
1787
|
+
* `tabindex="-1"` bị loại: đó là dấu hiệu tác giả cố ý đưa phần tử ra khỏi
|
|
1788
|
+
* đường Tab. `:disabled` cũng loại — trình duyệt không cho nó nhận tiêu điểm.
|
|
1789
|
+
*
|
|
1790
|
+
* Lọc phần ẩn bằng `[hidden]`/`[aria-hidden]` chứ KHÔNG `offsetParent`:
|
|
1791
|
+
* `offsetParent` là `null` với mọi phần tử trong `position: fixed`, và luôn
|
|
1792
|
+
* `null` trong jsdom — dùng nó thì danh sách rỗng, hàm thoát sớm, và toàn bộ
|
|
1793
|
+
* xử lý Tab lặng lẽ không chạy. Đã mắc: spec đỏ 3 ca trong khi trình duyệt
|
|
1794
|
+
* thật vẫn đúng, vì hai môi trường cho `offsetParent` khác nhau.
|
|
1795
|
+
*/
|
|
1796
|
+
private focusableItems;
|
|
1797
|
+
/**
|
|
1798
|
+
* Nút mở panel, kể cả khi nơi dùng tự khai qua slot `[trigger]`.
|
|
1799
|
+
*
|
|
1800
|
+
* `triggerButtonRef` CHỈ có giá trị với nút mặc định của component — hai
|
|
1801
|
+
* nhánh `@if` trong template vẽ ra nó. Nơi dùng truyền nút riêng qua
|
|
1802
|
+
* `<ng-content select="[trigger]">` thì cả hai nhánh đều không chạy và ref
|
|
1803
|
+
* là `undefined`. Đo 2026-09-25: header onluyenv4 (streak, chuông) đều dùng
|
|
1804
|
+
* nút slot, nên mọi xử lý bám vào ref đó lặng lẽ không chạy — gồm cả việc
|
|
1805
|
+
* trả tiêu điểm về nút sau khi Escape, vốn có từ trước.
|
|
1806
|
+
*
|
|
1807
|
+
* Nên tìm nút thật trong cây DOM của host khi không có ref.
|
|
1808
|
+
*/
|
|
1809
|
+
private triggerElement;
|
|
1810
|
+
/**
|
|
1811
|
+
* Phần tử nhận tiêu điểm đứng ngay sau `element` trong thứ tự Tab của trang.
|
|
1812
|
+
*
|
|
1813
|
+
* Quét từ `<body>` và loại chính panel ra: panel treo cuối `<body>` nên nếu
|
|
1814
|
+
* tính cả nó thì "phần tử sau nút trigger" lại rơi vào panel vừa đóng.
|
|
1815
|
+
*/
|
|
1816
|
+
private nextFocusableAfter;
|
|
1817
|
+
/**
|
|
1818
|
+
* Tab từ nút trigger khi panel đang mở → nhảy VÀO mục đầu panel.
|
|
1819
|
+
*
|
|
1820
|
+
* Vì sao cần: `appendTo="body"` treo panel ra cuối `<body>`, nên trong thứ
|
|
1821
|
+
* tự DOM nó nằm SAU toàn bộ nội dung trang. Bàn phím đi theo thứ tự DOM chứ
|
|
1822
|
+
* không theo vị trí nhìn thấy, nên Tab từ nút trigger nhảy sang phần tử kế
|
|
1823
|
+
* tiếp trong header rồi xuống thân trang — panel mở ngay trước mắt mà không
|
|
1824
|
+
* bao giờ tới được. Đo 2026-09-25: 8 lượt Tab, không lượt nào vào panel.
|
|
1825
|
+
*
|
|
1826
|
+
* KHÔNG cuốn tiêu điểm lúc mở: người dùng chuột không cần, và nhảy tiêu điểm
|
|
1827
|
+
* khi họ chưa yêu cầu là cướp quyền điều khiển. Chỉ khi họ chủ động nhấn Tab
|
|
1828
|
+
* mới dẫn vào — đúng lúc họ đang tìm đường đi tiếp.
|
|
1829
|
+
*
|
|
1830
|
+
* Shift+Tab bỏ qua: người dùng đang muốn lùi RA, giữ họ lại là bẫy.
|
|
1831
|
+
*/
|
|
1832
|
+
onTriggerKeydown(event: KeyboardEvent): void;
|
|
1833
|
+
/**
|
|
1834
|
+
* Tab BÊN TRONG panel — giữ đường đi liền mạch với chỗ panel đang hiện.
|
|
1835
|
+
*
|
|
1836
|
+
* Panel nằm cuối `<body>` nên nếu để trình duyệt tự xử, Tab ở mục cuối sẽ
|
|
1837
|
+
* rơi xuống phần tử sau panel trong DOM (thường là hết trang), còn Shift+Tab
|
|
1838
|
+
* ở mục đầu nhảy ngược lên thân trang — cả hai đều bỏ qua nút trigger, tức
|
|
1839
|
+
* người dùng mất mốc quay về.
|
|
1840
|
+
*
|
|
1841
|
+
* KHÔNG bẫy vòng tròn như hộp thoại: chuẩn WAI-ARIA cho menu quy định Tab
|
|
1842
|
+
* phải THOÁT được ra trang. Nên:
|
|
1843
|
+
*
|
|
1844
|
+
* - Tab ở mục CUỐI → đóng panel, trả tiêu điểm về nút trigger rồi để trình
|
|
1845
|
+
* duyệt đi tiếp bình thường (phần tử sau nút trong header)
|
|
1846
|
+
* - Shift+Tab ở mục ĐẦU → về thẳng nút trigger, panel vẫn mở để người dùng
|
|
1847
|
+
* còn thấy mình vừa rời khỏi đâu
|
|
1848
|
+
*
|
|
1849
|
+
* Giữa các mục thì không can thiệp — panel là một khối liền trong DOM nên
|
|
1850
|
+
* trình duyệt tự đi đúng.
|
|
1851
|
+
*/
|
|
1852
|
+
onMenuKeydown(event: KeyboardEvent): void;
|
|
1682
1853
|
show(): void;
|
|
1683
1854
|
hide(): void;
|
|
1684
1855
|
toggle(): void;
|
|
@@ -1702,6 +1873,19 @@ declare class OlDropdownItem {
|
|
|
1702
1873
|
readonly itemClick: _angular_core.OutputEmitterRef<MouseEvent>;
|
|
1703
1874
|
private readonly parentDropdown;
|
|
1704
1875
|
readonly isItemActive: _angular_core.Signal<boolean>;
|
|
1876
|
+
/**
|
|
1877
|
+
* Hình học theo Figma `ol-dropdown-item` (node 1149:39652, đo 2026-09-28):
|
|
1878
|
+
* lề 8px bốn cạnh (`px-2 py-2`, cao 36px), icon 16px cách chữ 6px, bo 8px
|
|
1879
|
+
* (`rounded` = `--radius: 8px`), chữ 14px medium. Bản trước `px-3` (12px),
|
|
1880
|
+
* icon cách chữ 10px, bo 6px.
|
|
1881
|
+
*
|
|
1882
|
+
* Độ đậm nằm TRONG từng nhánh, không gắn vô điều kiện — hai class cùng thuộc
|
|
1883
|
+
* tính thì thắng thua theo thứ tự luật CSS, không theo thứ tự trong chuỗi.
|
|
1884
|
+
*
|
|
1885
|
+
* Trạng thái đang chọn: Figma KHÔNG vẽ (chỉ có Initial / Hover / Disabled).
|
|
1886
|
+
* Bản trước tự đặt `bg-brand-softer` (#F5F8FF trên nền trắng — gần như không
|
|
1887
|
+
* thấy, báo 2026-09-28). Nay `bg-brand-soft` (#E3EAFF) + chữ brand đậm.
|
|
1888
|
+
*/
|
|
1705
1889
|
readonly itemClasses: _angular_core.Signal<string>;
|
|
1706
1890
|
handleClick(event: MouseEvent): void;
|
|
1707
1891
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlDropdownItem, never>;
|
|
@@ -1733,6 +1917,51 @@ declare class OlFooter {
|
|
|
1733
1917
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlFooter, "ol-footer", never, { "container": { "alias": "container"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
1734
1918
|
}
|
|
1735
1919
|
|
|
1920
|
+
type OlFrameSpacing = 'xs' | 'sm' | 'base' | 'lg';
|
|
1921
|
+
type OlFrameRounded = 'sm' | 'md' | 'lg' | 'xl';
|
|
1922
|
+
type OlFrameVariant = 'default' | 'ghost';
|
|
1923
|
+
/**
|
|
1924
|
+
* Khung bọc nhiều mảng nội dung, khoảng cách đều nhau.
|
|
1925
|
+
*
|
|
1926
|
+
* Chưa có node Figma — dựng theo design system.
|
|
1927
|
+
*
|
|
1928
|
+
* ## Vì sao KHÔNG dùng `ol-card` cho việc này
|
|
1929
|
+
*
|
|
1930
|
+
* `ol-card` là MỘT thẻ nội dung: có ảnh bìa, có `href`, có trạng thái chọn.
|
|
1931
|
+
* Còn đây là cái khung xếp NHIỀU mảng cạnh nhau với khoảng cách đều — như cột
|
|
1932
|
+
* thiết lập, bảng điều khiển, hay danh sách nhóm. Lồng nhiều `ol-card` vào một
|
|
1933
|
+
* `div` rồi tự đặt `space-y-*` cũng ra kết quả, nhưng mỗi nơi dùng lại chọn
|
|
1934
|
+
* một khoảng cách khác và trang trông lộn xộn.
|
|
1935
|
+
*
|
|
1936
|
+
* ## `stacked` bỏ viền giữa, không phải bỏ viền hết
|
|
1937
|
+
*
|
|
1938
|
+
* Xếp chồng thì các mảng dính thành một khối liền, chỉ còn một viền ngoài và
|
|
1939
|
+
* kẻ ngăn mảnh ở giữa — giống `ol-list-group`. Tách rời thì mỗi mảng là một
|
|
1940
|
+
* thẻ riêng có viền đủ bốn cạnh.
|
|
1941
|
+
*
|
|
1942
|
+
* Làm bằng `divide-y` cộng `overflow-hidden` trên khung, KHÔNG bằng
|
|
1943
|
+
* `[&>*:not(:last-child)]:border-b`: biến thể `:last-child` trong chuỗi class
|
|
1944
|
+
* của component con sẽ khớp MỌI thể hiện của con đó, kể cả khi nó là con duy
|
|
1945
|
+
* nhất ở nơi khác — lỗi đã gặp trong repo này.
|
|
1946
|
+
*
|
|
1947
|
+
* ## `ghost` bỏ nền và viền, giữ khoảng cách
|
|
1948
|
+
*
|
|
1949
|
+
* Dùng khi khung nằm trong một thẻ đã có viền rồi — hai lớp viền lồng nhau
|
|
1950
|
+
* trông như lỗi hiển thị.
|
|
1951
|
+
*/
|
|
1952
|
+
declare class OlFrame {
|
|
1953
|
+
readonly spacing: _angular_core.InputSignal<OlFrameSpacing>;
|
|
1954
|
+
readonly rounded: _angular_core.InputSignal<OlFrameRounded>;
|
|
1955
|
+
readonly variant: _angular_core.InputSignal<OlFrameVariant>;
|
|
1956
|
+
/** Dính các mảng thành một khối liền, chỉ còn kẻ ngăn ở giữa. */
|
|
1957
|
+
readonly stacked: _angular_core.InputSignal<boolean>;
|
|
1958
|
+
/** Xếp ngang thay vì dọc. Khoảng cách và kẻ ngăn đổi trục theo. */
|
|
1959
|
+
readonly horizontal: _angular_core.InputSignal<boolean>;
|
|
1960
|
+
protected readonly frameClasses: _angular_core.Signal<string>;
|
|
1961
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlFrame, never>;
|
|
1962
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlFrame, "ol-frame", never, { "spacing": { "alias": "spacing"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "stacked": { "alias": "stacked"; "required": false; "isSignal": true; }; "horizontal": { "alias": "horizontal"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
1963
|
+
}
|
|
1964
|
+
|
|
1736
1965
|
/**
|
|
1737
1966
|
* Bảng chuẩn kích thước và trạng thái cho MỌI ô nhập của thư viện.
|
|
1738
1967
|
*
|
|
@@ -3031,6 +3260,176 @@ declare class OlToggleGroup {
|
|
|
3031
3260
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlToggleGroup, "ol-toggle-group", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
3032
3261
|
}
|
|
3033
3262
|
|
|
3263
|
+
/**
|
|
3264
|
+
* Một lựa chọn của `ol-segmented`. `value` là thứ đổ vào model — dùng chuỗi
|
|
3265
|
+
* hoặc số, so bằng `===`.
|
|
3266
|
+
*/
|
|
3267
|
+
interface SegmentedOption<T = string | number> {
|
|
3268
|
+
value: T;
|
|
3269
|
+
label: string;
|
|
3270
|
+
icon?: string;
|
|
3271
|
+
disabled?: boolean;
|
|
3272
|
+
}
|
|
3273
|
+
type SegmentedSize = 'sm' | 'base';
|
|
3274
|
+
/**
|
|
3275
|
+
* Chọn MỘT trong vài chế độ loại trừ nhau, đặt cạnh nhau trên một rãnh xám;
|
|
3276
|
+
* mục đang chọn nổi lên nền trắng (segmented control).
|
|
3277
|
+
*
|
|
3278
|
+
* Khác `ol-tabs`: tabs chuyển PANEL nội dung, đây chọn GIÁ TRỊ (có CVA, dùng
|
|
3279
|
+
* được trong form). Khác `ol-toggle`: công tắc chỉ có hai trạng thái bật/tắt.
|
|
3280
|
+
*
|
|
3281
|
+
* Trợ năng theo mẫu radio group của WAI-ARIA: `role="radiogroup"`, mỗi mục
|
|
3282
|
+
* `role="radio"`, chỉ mục đang chọn nằm trong thứ tự Tab (roving tabindex),
|
|
3283
|
+
* mũi tên trái/phải/lên/xuống chuyển VÀ chọn luôn, Home/End về đầu/cuối.
|
|
3284
|
+
*
|
|
3285
|
+
* Figma chưa có thiết kế (tra `lip4g3...` 2026-09-28: không có component nào
|
|
3286
|
+
* tên segmented) — dựng theo token của hệ thống.
|
|
3287
|
+
*/
|
|
3288
|
+
declare class OlSegmented implements ControlValueAccessor {
|
|
3289
|
+
readonly options: _angular_core.InputSignal<SegmentedOption<string | number>[]>;
|
|
3290
|
+
readonly value: _angular_core.ModelSignal<string | number | null>;
|
|
3291
|
+
readonly size: _angular_core.InputSignal<SegmentedSize>;
|
|
3292
|
+
/** Giãn hết bề ngang khung, các mục chia đều. */
|
|
3293
|
+
readonly fullWidth: _angular_core.InputSignal<boolean>;
|
|
3294
|
+
/** `model()` để `setDisabledState()` của Reactive Forms đặt được. */
|
|
3295
|
+
readonly disabled: _angular_core.ModelSignal<boolean>;
|
|
3296
|
+
/** Tên nhóm cho bộ đọc màn hình — nên đặt, vì nhóm không có nhãn nhìn thấy. */
|
|
3297
|
+
readonly ariaLabel: _angular_core.InputSignal<string>;
|
|
3298
|
+
private readonly host;
|
|
3299
|
+
private onChange;
|
|
3300
|
+
private onTouched;
|
|
3301
|
+
protected readonly hostClasses: _angular_core.Signal<"block w-full" | "inline-block max-w-full">;
|
|
3302
|
+
protected readonly trackClasses: _angular_core.Signal<string>;
|
|
3303
|
+
/** Mục đang Tab vào được: mục đang chọn, không có thì mục bật đầu tiên. */
|
|
3304
|
+
protected readonly focusIndex: _angular_core.Signal<number>;
|
|
3305
|
+
protected itemClasses(option: SegmentedOption): string;
|
|
3306
|
+
select(option: SegmentedOption): void;
|
|
3307
|
+
protected onKeydown(event: KeyboardEvent, index: number): void;
|
|
3308
|
+
/** Mục bật kế tiếp theo chiều `step`, vòng quanh. -1 khi không có. */
|
|
3309
|
+
private nextEnabled;
|
|
3310
|
+
writeValue(v: string | number | null): void;
|
|
3311
|
+
registerOnChange(fn: (v: string | number | null) => void): void;
|
|
3312
|
+
registerOnTouched(fn: () => void): void;
|
|
3313
|
+
setDisabledState(isDisabled: boolean): void;
|
|
3314
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlSegmented, never>;
|
|
3315
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlSegmented, "ol-segmented", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "fullWidth": { "alias": "fullWidth"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "disabled": "disabledChange"; }, never, never, true, never>;
|
|
3316
|
+
}
|
|
3317
|
+
|
|
3318
|
+
/**
|
|
3319
|
+
* Loại tệp — nhận biết để chọn icon, màu và chữ mô tả.
|
|
3320
|
+
*
|
|
3321
|
+
* Mười loại phủ gần hết tệp giáo viên/học sinh tải lên: bài làm (ảnh, PDF,
|
|
3322
|
+
* Word), bảng điểm (Excel), bài giảng (PowerPoint, video), nghe (audio), nộp
|
|
3323
|
+
* gộp (nén), bài tin học (mã nguồn), ghi chú (văn bản thô).
|
|
3324
|
+
*/
|
|
3325
|
+
type FileKind = 'image' | 'pdf' | 'word' | 'excel' | 'powerpoint' | 'video' | 'audio' | 'archive' | 'code' | 'text' | 'other';
|
|
3326
|
+
interface FileKindMeta {
|
|
3327
|
+
label: string;
|
|
3328
|
+
/** Họ lucide `file-*` — một họ nét cho mọi loại, nhìn đồng bộ. */
|
|
3329
|
+
icon: string;
|
|
3330
|
+
/**
|
|
3331
|
+
* Màu ô icon, lấy từ bảng màu `ol-icon-shape` — không tự tô. KHÔNG dùng
|
|
3332
|
+
* `dark`: nó là ô ĐẶC đen giữa các ô nền nhạt, nặng hơn hẳn (đo 2026-09-28).
|
|
3333
|
+
*/
|
|
3334
|
+
color: IconShapeColor;
|
|
3335
|
+
}
|
|
3336
|
+
declare const FILE_KIND_META: Record<FileKind, FileKindMeta>;
|
|
3337
|
+
/** Phần mở rộng, chữ thường, không dấu chấm. Không có → chuỗi rỗng. */
|
|
3338
|
+
declare function fileExtension(name: string): string;
|
|
3339
|
+
/**
|
|
3340
|
+
* Nhận biết loại tệp — ưu tiên PHẦN MỞ RỘNG, lùi về MIME.
|
|
3341
|
+
*
|
|
3342
|
+
* Không tin MIME trước: trình duyệt đoán MIME theo đuôi và hệ điều hành, nên
|
|
3343
|
+
* cùng một tệp `.docx` có máy báo `application/vnd.openxml…`, có máy báo rỗng
|
|
3344
|
+
* (Windows thiếu Office), và `.csv` có máy báo `application/vnd.ms-excel`.
|
|
3345
|
+
*/
|
|
3346
|
+
declare function detectFileKind(name: string, mime?: string): FileKind;
|
|
3347
|
+
/**
|
|
3348
|
+
* Byte → chữ ngắn theo cách người Việt đọc: `850 B`, `12,4 KB`, `3,2 MB`.
|
|
3349
|
+
* Dấu phẩy thập phân; số nguyên thì bỏ phần lẻ (`2 MB`, không `2,0 MB`).
|
|
3350
|
+
*/
|
|
3351
|
+
declare function formatFileSize(bytes: number): string;
|
|
3352
|
+
/**
|
|
3353
|
+
* Tệp có khớp chuỗi `accept` của thẻ `<input type="file">` không.
|
|
3354
|
+
*
|
|
3355
|
+
* Hiểu đủ ba dạng của chuẩn HTML: đuôi (`.pdf`), MIME đầy đủ
|
|
3356
|
+
* (`application/pdf`), MIME đại diện (`image/*`). `*` hoặc rỗng → nhận hết.
|
|
3357
|
+
*
|
|
3358
|
+
* Cần tự kiểm vì `accept` chỉ LỌC hộp thoại chọn tệp — kéo thả thì trình duyệt
|
|
3359
|
+
* không lọc gì, và người dùng đổi bộ lọc hộp thoại sang "Tất cả tệp" là chọn
|
|
3360
|
+
* được tệp bất kỳ.
|
|
3361
|
+
*/
|
|
3362
|
+
declare function matchesAccept(file: {
|
|
3363
|
+
name: string;
|
|
3364
|
+
type: string;
|
|
3365
|
+
}, accept: string): boolean;
|
|
3366
|
+
type FileRejectReason = 'type' | 'size' | 'count';
|
|
3367
|
+
interface FileRejection {
|
|
3368
|
+
file: File;
|
|
3369
|
+
reason: FileRejectReason;
|
|
3370
|
+
/** Câu báo lỗi tiếng Việt, hiện được ngay. */
|
|
3371
|
+
message: string;
|
|
3372
|
+
}
|
|
3373
|
+
interface FileValidationRules {
|
|
3374
|
+
accept?: string;
|
|
3375
|
+
/** Byte. 0 hoặc không truyền → không giới hạn. */
|
|
3376
|
+
maxSize?: number;
|
|
3377
|
+
/** Tổng số tệp tối đa, TÍNH CẢ tệp đã có. 0 → không giới hạn. */
|
|
3378
|
+
maxFiles?: number;
|
|
3379
|
+
/** Số tệp đang có sẵn trước lượt chọn này. */
|
|
3380
|
+
existingCount?: number;
|
|
3381
|
+
}
|
|
3382
|
+
interface FileValidationResult {
|
|
3383
|
+
accepted: File[];
|
|
3384
|
+
rejected: FileRejection[];
|
|
3385
|
+
}
|
|
3386
|
+
/**
|
|
3387
|
+
* Chia tệp thành nhận / loại, kèm lý do từng tệp bị loại.
|
|
3388
|
+
*
|
|
3389
|
+
* Thứ tự kiểm: định dạng → dung lượng → số lượng. Tệp sai định dạng không
|
|
3390
|
+
* chiếm chỗ trong hạn mức số lượng — chọn 3 tệp, 1 tệp `.exe`, giới hạn 2 thì
|
|
3391
|
+
* nhận 2 tệp hợp lệ chứ không loại oan tệp thứ ba vì tệp `.exe` đứng trước.
|
|
3392
|
+
*/
|
|
3393
|
+
declare function validateFiles(files: File[], rules?: FileValidationRules): FileValidationResult;
|
|
3394
|
+
/** Trạng thái tải của một tệp — nơi gọi cập nhật theo tiến trình HTTP thật. */
|
|
3395
|
+
type UploadStatus = 'idle' | 'uploading' | 'success' | 'error';
|
|
3396
|
+
/**
|
|
3397
|
+
* Một tệp trong danh sách tải lên.
|
|
3398
|
+
*
|
|
3399
|
+
* `file` có thể vắng: tệp đã có sẵn trên máy chủ (mở lại bài đã nộp) chỉ có
|
|
3400
|
+
* tên, dung lượng và `url`, không có đối tượng `File`.
|
|
3401
|
+
*/
|
|
3402
|
+
interface OlUploadFile {
|
|
3403
|
+
id: string;
|
|
3404
|
+
name: string;
|
|
3405
|
+
size: number;
|
|
3406
|
+
file?: File;
|
|
3407
|
+
/** Ảnh xem trước hoặc liên kết tải về. */
|
|
3408
|
+
url?: string;
|
|
3409
|
+
status?: UploadStatus;
|
|
3410
|
+
/** 0–100, chỉ dùng khi `status = 'uploading'`. */
|
|
3411
|
+
progress?: number;
|
|
3412
|
+
/** Câu báo lỗi khi `status = 'error'`. */
|
|
3413
|
+
error?: string;
|
|
3414
|
+
}
|
|
3415
|
+
/** File → OlUploadFile, gán id duy nhất để `@for track` không lẫn hai tệp trùng tên. */
|
|
3416
|
+
declare function toUploadFile(file: File): OlUploadFile;
|
|
3417
|
+
/**
|
|
3418
|
+
* Tệp trong một lần dán (Ctrl+V / ⌘V).
|
|
3419
|
+
*
|
|
3420
|
+
* Đọc cả `clipboardData.files` lẫn `items` loại `file`: Chrome đặt ảnh chụp
|
|
3421
|
+
* màn hình ở cả hai, Safari có lúc chỉ ở `items`. Gộp theo đối tượng để không
|
|
3422
|
+
* nhận một ảnh hai lần.
|
|
3423
|
+
*
|
|
3424
|
+
* Ảnh chụp màn hình dán vào LUÔN tên `image.png` — dán ba lần là ba tệp trùng
|
|
3425
|
+
* tên, không phân biệt được trong danh sách. Đổi thành "Ảnh dán 14-32-05.png".
|
|
3426
|
+
*/
|
|
3427
|
+
declare function filesFromClipboard(data: DataTransfer | null, now?: Date): File[];
|
|
3428
|
+
/** Phím tắt dán theo hệ điều hành — để gợi ý đúng chữ người dùng thấy trên bàn phím. */
|
|
3429
|
+
declare function pasteShortcutLabel(platform?: string): string;
|
|
3430
|
+
/** Đang gõ trong ô nhập chữ — dán ở đó là dán CHỮ, không được cướp. */
|
|
3431
|
+
declare function isEditableTarget(target: EventTarget | null): boolean;
|
|
3432
|
+
|
|
3034
3433
|
/**
|
|
3035
3434
|
* Thang cỡ theo Figma: `sm | base | lg`. `'md'` là BÍ DANH của `'base'`,
|
|
3036
3435
|
* giữ cho mã cũ chạy tiếp và sẽ bỏ ở bản sau — dùng `'base'` cho mã mới.
|
|
@@ -3061,15 +3460,325 @@ declare class OlFileInput {
|
|
|
3061
3460
|
readonly accept: _angular_core.InputSignal<string>;
|
|
3062
3461
|
readonly multiple: _angular_core.InputSignal<boolean>;
|
|
3063
3462
|
readonly id: _angular_core.InputSignal<string>;
|
|
3463
|
+
/** Byte. 0 → không giới hạn. Có giá trị thì vùng kéo thả ghi "Dung lượng tối đa". */
|
|
3464
|
+
readonly maxSize: _angular_core.InputSignal<number>;
|
|
3465
|
+
/** Nhãn nút trong vùng kéo thả (Figma Advanced). Rỗng → không vẽ nút. */
|
|
3466
|
+
readonly ctaLabel: _angular_core.InputSignal<string>;
|
|
3467
|
+
/** Figma State: Danger / Success. Tệp bị loại tự chuyển sang `error`. */
|
|
3468
|
+
readonly state: _angular_core.InputSignal<"error" | "success" | "default">;
|
|
3469
|
+
/** Tệp đã nhận (sau khi kiểm). */
|
|
3064
3470
|
readonly selectedFiles: _angular_core.WritableSignal<File[]>;
|
|
3065
|
-
readonly
|
|
3471
|
+
protected readonly items: _angular_core.WritableSignal<OlUploadFile[]>;
|
|
3472
|
+
protected readonly errors: _angular_core.WritableSignal<string[]>;
|
|
3066
3473
|
readonly filesChanged: _angular_core.OutputEmitterRef<File[]>;
|
|
3474
|
+
/** Tệp bị loại kèm lý do — component đã tự hiện câu lỗi. */
|
|
3475
|
+
readonly rejected: _angular_core.OutputEmitterRef<FileRejection[]>;
|
|
3476
|
+
private readonly dropInput;
|
|
3477
|
+
private readonly host;
|
|
3478
|
+
protected readonly zoneState: _angular_core.Signal<"error" | "success" | "default">;
|
|
3479
|
+
/**
|
|
3480
|
+
* Dòng phụ trong vùng: "Dung lượng tối đa" nếu có `maxSize`, không thì
|
|
3481
|
+
* `description` — giữ nguyên chữ của mã cũ đang truyền `description`.
|
|
3482
|
+
*/
|
|
3483
|
+
protected readonly zoneHint: _angular_core.Signal<string>;
|
|
3067
3484
|
onFileSelected(event: Event): void;
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3485
|
+
protected openPicker(): void;
|
|
3486
|
+
/** Nhận tệp từ hộp chọn hoặc kéo thả: kiểm định dạng + dung lượng rồi phát. */
|
|
3487
|
+
protected receive(incoming: File[]): void;
|
|
3488
|
+
/** Dán tệp (Ctrl+V / ⌘V) khi tiêu điểm ở ô hoặc vùng kéo thả. */
|
|
3489
|
+
protected onPaste(event: ClipboardEvent): void;
|
|
3490
|
+
/**
|
|
3491
|
+
* Ô thường (không dropzone) hiện tên tệp bằng CHÍNH `<input type="file">` —
|
|
3492
|
+
* nhận tệp dán mà không gán vào nó thì ô vẫn ghi "Chưa chọn tệp" dù đã nhận.
|
|
3493
|
+
* `DataTransfer` là cách duy nhất gán `files` cho ô tệp.
|
|
3494
|
+
*/
|
|
3495
|
+
private syncNativeInput;
|
|
3496
|
+
protected removeItem(item: OlUploadFile): void;
|
|
3071
3497
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlFileInput, never>;
|
|
3072
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlFileInput, "ol-file-input", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "dropzone": { "alias": "dropzone"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; }, { "filesChanged": "filesChanged"; }, never, never, true, never>;
|
|
3498
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlFileInput, "ol-file-input", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "dropzone": { "alias": "dropzone"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "id": { "alias": "id"; "required": false; "isSignal": true; }; "maxSize": { "alias": "maxSize"; "required": false; "isSignal": true; }; "ctaLabel": { "alias": "ctaLabel"; "required": false; "isSignal": true; }; "state": { "alias": "state"; "required": false; "isSignal": true; }; }, { "filesChanged": "filesChanged"; "rejected": "rejected"; }, never, never, true, never>;
|
|
3499
|
+
}
|
|
3500
|
+
|
|
3501
|
+
/**
|
|
3502
|
+
* Ba dạng của một tệp:
|
|
3503
|
+
*
|
|
3504
|
+
* - `row` — dòng trong danh sách: icon loại tệp, tên, dung lượng, thanh tiến
|
|
3505
|
+
* trình khi đang tải, nút thử lại khi lỗi. Figma không vẽ dạng này; dựng theo
|
|
3506
|
+
* token để danh sách tải nhiều tệp có chỗ báo tiến trình từng tệp.
|
|
3507
|
+
* - `chip` — Figma "Button header + Dropbox (uploaded no limit)": viên bo góc,
|
|
3508
|
+
* nút xem 👁 + tên + ✕.
|
|
3509
|
+
* - `card` — Figma "Button header + Dropbox (uploaded max 1 file)": khung viền,
|
|
3510
|
+
* icon + tên ở giữa, ✕ ở góc.
|
|
3511
|
+
*/
|
|
3512
|
+
type FileItemVariant = 'row' | 'chip' | 'card';
|
|
3513
|
+
declare class OlFileItem {
|
|
3514
|
+
readonly file: _angular_core.InputSignal<OlUploadFile>;
|
|
3515
|
+
readonly variant: _angular_core.InputSignal<FileItemVariant>;
|
|
3516
|
+
readonly removable: _angular_core.InputSignal<boolean>;
|
|
3517
|
+
/** Hiện nút xem 👁 — nơi gọi tự mở tệp khi nhận `(preview)`. */
|
|
3518
|
+
readonly previewable: _angular_core.InputSignal<boolean>;
|
|
3519
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
3520
|
+
readonly remove: _angular_core.OutputEmitterRef<OlUploadFile>;
|
|
3521
|
+
readonly preview: _angular_core.OutputEmitterRef<OlUploadFile>;
|
|
3522
|
+
readonly retry: _angular_core.OutputEmitterRef<OlUploadFile>;
|
|
3523
|
+
protected readonly kind: _angular_core.Signal<_edmicro_olkit.FileKind>;
|
|
3524
|
+
protected readonly meta: _angular_core.Signal<_edmicro_olkit.FileKindMeta>;
|
|
3525
|
+
protected readonly sizeText: _angular_core.Signal<string>;
|
|
3526
|
+
protected readonly status: _angular_core.Signal<_edmicro_olkit.UploadStatus>;
|
|
3527
|
+
protected readonly progress: _angular_core.Signal<number>;
|
|
3528
|
+
/** Dòng phụ dưới tên: dung lượng + trạng thái, đọc được cả khi không nhìn màu. */
|
|
3529
|
+
protected readonly metaText: _angular_core.Signal<string>;
|
|
3530
|
+
protected readonly metaClass: _angular_core.Signal<"text-xs text-fg-danger" | "text-xs text-body-subtle">;
|
|
3531
|
+
protected readonly rowClass: _angular_core.Signal<string>;
|
|
3532
|
+
/** Nút hành động nhỏ — cùng hình với nút đóng của drawer/modal. */
|
|
3533
|
+
protected readonly actionClass = "inline-flex size-8 shrink-0 items-center justify-center rounded-md text-body-subtle transition-colors hover:bg-neutral-tertiary hover:text-heading focus-visible:outline-hidden focus-visible:ring-2 focus-visible:ring-brand-subtle disabled:pointer-events-none disabled:opacity-50";
|
|
3534
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlFileItem, never>;
|
|
3535
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlFileItem, "ol-file-item", never, { "file": { "alias": "file"; "required": true; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "removable": { "alias": "removable"; "required": false; "isSignal": true; }; "previewable": { "alias": "previewable"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "remove": "remove"; "preview": "preview"; "retry": "retry"; }, never, never, true, never>;
|
|
3536
|
+
}
|
|
3537
|
+
|
|
3538
|
+
/**
|
|
3539
|
+
* Vùng kéo–thả, theo Figma `ol-file-input-form` Type=Advanced (1149:48977):
|
|
3540
|
+
* icon tải lên · "Nhấn để tải lên hoặc kéo thả" · "Dung lượng tối đa: …" ·
|
|
3541
|
+
* (tuỳ chọn) nút "Chọn tệp".
|
|
3542
|
+
*
|
|
3543
|
+
* ## Cả vùng là MỘT `<button>`
|
|
3544
|
+
*
|
|
3545
|
+
* Bản cũ trong `ol-file-input` đặt `<input type="file" class="hidden">` —
|
|
3546
|
+
* `display: none` nên Tab không tới được, bàn phím không mở được hộp chọn tệp.
|
|
3547
|
+
* Ở đây vùng là nút thật: Tab tới, Enter/Space mở hộp chọn (qua `(pick)`, nơi
|
|
3548
|
+
* gọi gọi `input.click()`), và trình đọc màn hình đọc nhãn của nút.
|
|
3549
|
+
*
|
|
3550
|
+
* Nút "Chọn tệp" bên trong chỉ là HÌNH (`<span>`), không lồng `<button>` trong
|
|
3551
|
+
* `<button>` — HTML cấm, và hai nút lồng nhau làm một lần bấm bắn hai sự kiện.
|
|
3552
|
+
*/
|
|
3553
|
+
declare class OlFileDropzone {
|
|
3554
|
+
readonly title: _angular_core.InputSignal<string>;
|
|
3555
|
+
/** Dòng phụ, ví dụ "Dung lượng tối đa: 30MB". Rỗng → không vẽ. */
|
|
3556
|
+
readonly hint: _angular_core.InputSignal<string>;
|
|
3557
|
+
/** Nhãn nút "Chọn tệp" trong vùng (Figma Advanced). Rỗng → không vẽ nút. */
|
|
3558
|
+
readonly ctaLabel: _angular_core.InputSignal<string>;
|
|
3559
|
+
readonly icon: _angular_core.InputSignal<string>;
|
|
3560
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
3561
|
+
/** Trạng thái viền: lỗi / thành công (Figma State=Danger / Success). */
|
|
3562
|
+
readonly state: _angular_core.InputSignal<"error" | "success" | "default">;
|
|
3563
|
+
/** Chiều cao tối thiểu — vùng trong khung có tiêu đề thấp hơn vùng đứng riêng. */
|
|
3564
|
+
readonly compact: _angular_core.InputSignal<boolean>;
|
|
3565
|
+
readonly describedBy: _angular_core.InputSignal<string>;
|
|
3566
|
+
/** Dòng "hoặc dán ⌘V / Ctrl+V". Tắt khi nơi gọi không nhận tệp dán. */
|
|
3567
|
+
readonly pasteHint: _angular_core.InputSignal<boolean>;
|
|
3568
|
+
protected readonly shortcut: string;
|
|
3569
|
+
/** Bấm vào vùng (chuột hoặc bàn phím) — nơi gọi mở hộp chọn tệp. */
|
|
3570
|
+
readonly pick: _angular_core.OutputEmitterRef<void>;
|
|
3571
|
+
/** Tệp thả hoặc DÁN vào vùng. CHƯA kiểm định dạng — việc của nơi gọi. */
|
|
3572
|
+
readonly filesDropped: _angular_core.OutputEmitterRef<File[]>;
|
|
3573
|
+
protected readonly dragging: _angular_core.WritableSignal<boolean>;
|
|
3574
|
+
protected readonly zoneClass: _angular_core.Signal<string>;
|
|
3575
|
+
protected onDragOver(event: DragEvent): void;
|
|
3576
|
+
protected onDragLeave(event: DragEvent): void;
|
|
3577
|
+
/**
|
|
3578
|
+
* Dán khi tiêu điểm đang ở vùng. Có tệp thì nhận và `stopPropagation` — khung
|
|
3579
|
+
* cha (`ol-file-upload`) cũng nghe `paste`, không chặn là nhận hai lần. Không
|
|
3580
|
+
* có tệp (dán chữ) thì để yên cho trình duyệt.
|
|
3581
|
+
*/
|
|
3582
|
+
protected onPaste(event: ClipboardEvent): void;
|
|
3583
|
+
protected onDrop(event: DragEvent): void;
|
|
3584
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlFileDropzone, never>;
|
|
3585
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlFileDropzone, "ol-file-dropzone", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "ctaLabel": { "alias": "ctaLabel"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "state": { "alias": "state"; "required": false; "isSignal": true; }; "compact": { "alias": "compact"; "required": false; "isSignal": true; }; "describedBy": { "alias": "describedBy"; "required": false; "isSignal": true; }; "pasteHint": { "alias": "pasteHint"; "required": false; "isSignal": true; }; }, { "pick": "pick"; "filesDropped": "filesDropped"; }, never, never, true, never>;
|
|
3586
|
+
}
|
|
3587
|
+
|
|
3588
|
+
/**
|
|
3589
|
+
* Toán phóng/kéo ảnh — hàm thuần, không đụng DOM, để test chính xác từng px.
|
|
3590
|
+
*
|
|
3591
|
+
* Ảnh vẽ bằng `transform: translate(x, y) scale(s)`, gốc biến đổi ở TÂM ảnh.
|
|
3592
|
+
* Một điểm `p` của ảnh (tính từ tâm, đơn vị px lúc chưa phóng) hiện ra ở
|
|
3593
|
+
* `q = t + s·p` so với tâm khung. Phóng quanh điểm `q` (chỗ bấm / con trỏ /
|
|
3594
|
+
* giữa hai ngón) nghĩa là giữ `q` đứng yên: `p = (q − t) / s`, `t' = q − s'·p`.
|
|
3595
|
+
*/
|
|
3596
|
+
interface ZoomState {
|
|
3597
|
+
scale: number;
|
|
3598
|
+
x: number;
|
|
3599
|
+
y: number;
|
|
3600
|
+
}
|
|
3601
|
+
|
|
3602
|
+
/** Một ảnh trong trình xem. */
|
|
3603
|
+
interface OlPreviewImage {
|
|
3604
|
+
src: string;
|
|
3605
|
+
/** Chữ thay thế — cũng hiện làm chú thích dưới ảnh. */
|
|
3606
|
+
alt?: string;
|
|
3607
|
+
}
|
|
3608
|
+
/**
|
|
3609
|
+
* Xem ảnh phóng to trên lớp phủ toàn màn (lightbox) — một ảnh hoặc lướt qua
|
|
3610
|
+
* nhiều ảnh.
|
|
3611
|
+
*
|
|
3612
|
+
* - Nhiều ảnh: nút ‹ › hai bên, số thứ tự "2 / 5", phím ← → chuyển ảnh, vòng quanh.
|
|
3613
|
+
* - Phóng to/thu nhỏ (1×–4×): bấm ảnh để phóng 2× đúng chỗ bấm, bấm lại để về;
|
|
3614
|
+
* nút − / + trên thanh, phím + − 0; cuộn chuột / chụm trackpad quanh con
|
|
3615
|
+
* trỏ; chụm hai ngón trên điện thoại. Đang phóng thì kéo để xem chỗ khác.
|
|
3616
|
+
* - Escape, nút ✕ hoặc bấm ra nền tối để đóng. Tiêu điểm bị giữ trong lớp phủ
|
|
3617
|
+
* và trả về chỗ cũ khi đóng; nền trang khoá cuộn (`OlFocusTrapService`).
|
|
3618
|
+
* - Escape đi qua ngăn xếp `OlOverlayContainer`: mở trình xem trong modal rồi
|
|
3619
|
+
* nhấn Escape chỉ đóng trình xem, modal còn nguyên.
|
|
3620
|
+
*
|
|
3621
|
+
* Dùng riêng được (`[(open)]` + `[images]` + `[(index)]`); `ol-file-upload`
|
|
3622
|
+
* chế độ `image`/`images` dùng nó để xem ảnh vừa chọn.
|
|
3623
|
+
*/
|
|
3624
|
+
declare class OlImagePreview {
|
|
3625
|
+
readonly images: _angular_core.InputSignal<OlPreviewImage[]>;
|
|
3626
|
+
readonly open: _angular_core.ModelSignal<boolean>;
|
|
3627
|
+
/** Ảnh đang xem, tính từ 0. */
|
|
3628
|
+
readonly index: _angular_core.ModelSignal<number>;
|
|
3629
|
+
readonly closed: _angular_core.OutputEmitterRef<void>;
|
|
3630
|
+
private readonly panel;
|
|
3631
|
+
private readonly thumbStrip;
|
|
3632
|
+
private readonly imageEl;
|
|
3633
|
+
protected readonly zoom: _angular_core.WritableSignal<ZoomState>;
|
|
3634
|
+
protected readonly dragging: _angular_core.WritableSignal<boolean>;
|
|
3635
|
+
protected readonly zoomPercent: _angular_core.Signal<number>;
|
|
3636
|
+
protected readonly canZoomIn: _angular_core.Signal<boolean>;
|
|
3637
|
+
protected readonly canZoomOut: _angular_core.Signal<boolean>;
|
|
3638
|
+
protected readonly imageStyle: _angular_core.Signal<string>;
|
|
3639
|
+
protected readonly imageClasses: _angular_core.Signal<string>;
|
|
3640
|
+
/** Ngón tay / chuột đang ấn trên ảnh, theo pointerId. */
|
|
3641
|
+
private readonly pointers;
|
|
3642
|
+
private pinchStart;
|
|
3643
|
+
private moved;
|
|
3644
|
+
/** Vừa kéo xong: cú `click` theo sau không được tính là bấm (phóng / đóng). */
|
|
3645
|
+
private suppressClick;
|
|
3646
|
+
private readonly focusTrap;
|
|
3647
|
+
private readonly overlayContainer;
|
|
3648
|
+
private releaseEscape;
|
|
3649
|
+
protected readonly count: _angular_core.Signal<number>;
|
|
3650
|
+
/** Kẹp chỉ số: danh sách ảnh có thể ngắn lại (vừa xoá ảnh) trong lúc đang mở. */
|
|
3651
|
+
protected readonly current: _angular_core.Signal<number>;
|
|
3652
|
+
protected readonly image: _angular_core.Signal<OlPreviewImage>;
|
|
3653
|
+
constructor();
|
|
3654
|
+
/** Ô ảnh nhỏ: ảnh đang xem rõ + viền trắng; ảnh khác mờ, rê chuột thì rõ. */
|
|
3655
|
+
protected thumbClasses(i: number): string;
|
|
3656
|
+
close(): void;
|
|
3657
|
+
next(): void;
|
|
3658
|
+
prev(): void;
|
|
3659
|
+
private go;
|
|
3660
|
+
protected onKeydown(event: KeyboardEvent): void;
|
|
3661
|
+
/** Bấm đúng nền tối (không phải ảnh hay nút) thì đóng. */
|
|
3662
|
+
protected onBackdropClick(event: MouseEvent): void;
|
|
3663
|
+
zoomIn(): void;
|
|
3664
|
+
zoomOut(): void;
|
|
3665
|
+
/** Bàn phím trên ảnh (Enter / Space): phóng 2× quanh tâm, hoặc về cỡ gốc. */
|
|
3666
|
+
toggleZoom(): void;
|
|
3667
|
+
resetZoom(): void;
|
|
3668
|
+
/** Kích thước ảnh khi CHƯA phóng (offsetWidth không tính transform). */
|
|
3669
|
+
private imageSize;
|
|
3670
|
+
/**
|
|
3671
|
+
* Điểm màn hình → toạ độ tính từ TÂM ảnh lúc chưa phóng. Hộp đã biến đổi có
|
|
3672
|
+
* tâm = tâm gốc + (x, y) — phóng quanh tâm không dời tâm.
|
|
3673
|
+
*/
|
|
3674
|
+
private toCenter;
|
|
3675
|
+
private zoomAround;
|
|
3676
|
+
/** Bấm ảnh: đang ở cỡ gốc thì phóng 2× đúng chỗ bấm, đang phóng thì về. */
|
|
3677
|
+
protected onImageClick(event: MouseEvent): void;
|
|
3678
|
+
/** Cuộn chuột / chụm trackpad (trình duyệt gửi wheel + ctrlKey): phóng quanh con trỏ. */
|
|
3679
|
+
protected onWheel(event: WheelEvent): void;
|
|
3680
|
+
protected onPointerDown(event: PointerEvent): void;
|
|
3681
|
+
protected onPointerMove(event: PointerEvent): void;
|
|
3682
|
+
protected onPointerUp(event: PointerEvent): void;
|
|
3683
|
+
private pinchDistance;
|
|
3684
|
+
private releaseTraps;
|
|
3685
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlImagePreview, never>;
|
|
3686
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlImagePreview, "ol-image-preview", never, { "images": { "alias": "images"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; "index": { "alias": "index"; "required": false; "isSignal": true; }; }, { "open": "openChange"; "index": "indexChange"; "closed": "closed"; }, never, never, true, never>;
|
|
3687
|
+
}
|
|
3688
|
+
|
|
3689
|
+
/**
|
|
3690
|
+
* - `single` — một tệp; đã có thì thẻ tệp + nút "Thay đổi"
|
|
3691
|
+
* - `multiple` — nhiều tệp dạng chip (👁 + tên + ✕), cuộn khi dài
|
|
3692
|
+
* - `image` — một ảnh bìa phủ kín khung; bấm ảnh để xem phóng to
|
|
3693
|
+
* - `images` — nhiều ảnh dạng lưới ô vuông; bấm ô để xem, lướt ‹ › qua các ảnh
|
|
3694
|
+
* - `list` — nhiều tệp dạng DÒNG có thanh tiến trình — Figma không có,
|
|
3695
|
+
* dùng khi tải tệp lớn cần báo tiến trình từng tệp
|
|
3696
|
+
*/
|
|
3697
|
+
type FileUploadMode = 'single' | 'multiple' | 'image' | 'images' | 'list';
|
|
3698
|
+
/**
|
|
3699
|
+
* Khung tải tệp có tiêu đề — Figma `ol-file-input-form` "Button header + …"
|
|
3700
|
+
* (3587:6834 · 3592:6990 · 3603:2606 · 3611:3494).
|
|
3701
|
+
*
|
|
3702
|
+
* ## Component KHÔNG tự tải lên máy chủ
|
|
3703
|
+
*
|
|
3704
|
+
* Nó nhận tệp, kiểm định dạng/dung lượng/số lượng, thêm vào `files` với
|
|
3705
|
+
* `status: 'idle'` rồi phát `(filesAdded)`. Nơi gọi gửi HTTP và cập nhật
|
|
3706
|
+
* `status`/`progress` của từng tệp qua `[(files)]`. Để component tự gọi HTTP
|
|
3707
|
+
* thì nó phải biết URL, header xác thực, dạng phản hồi — ba thứ khác nhau ở
|
|
3708
|
+
* mỗi màn.
|
|
3709
|
+
*/
|
|
3710
|
+
declare class OlFileUpload {
|
|
3711
|
+
readonly title: _angular_core.InputSignal<string>;
|
|
3712
|
+
readonly required: _angular_core.InputSignal<boolean>;
|
|
3713
|
+
readonly mode: _angular_core.InputSignal<FileUploadMode>;
|
|
3714
|
+
/** Chuỗi `accept` của `<input type="file">` — cũng dùng để KIỂM tệp kéo thả. */
|
|
3715
|
+
readonly accept: _angular_core.InputSignal<string>;
|
|
3716
|
+
/** Byte. 0 → không giới hạn. */
|
|
3717
|
+
readonly maxSize: _angular_core.InputSignal<number>;
|
|
3718
|
+
/** Chỉ cho `multiple`/`list`. 0 → không giới hạn. */
|
|
3719
|
+
readonly maxFiles: _angular_core.InputSignal<number>;
|
|
3720
|
+
/** Nhãn nút ở đầu khung. Rỗng → tự chọn theo chế độ và trạng thái. */
|
|
3721
|
+
readonly buttonLabel: _angular_core.InputSignal<string>;
|
|
3722
|
+
/** Hiện nút 👁 trên từng tệp. */
|
|
3723
|
+
readonly previewable: _angular_core.InputSignal<boolean>;
|
|
3724
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
3725
|
+
/**
|
|
3726
|
+
* Nhận tệp dán (Ctrl+V / ⌘V) ở BẤT KỲ ĐÂU trên trang, không chỉ khi tiêu
|
|
3727
|
+
* điểm ở trong khung. Chỉ bật khi màn có MỘT khung tải — hai khung cùng bật
|
|
3728
|
+
* thì một lần dán vào cả hai. Đang gõ trong ô nhập chữ thì bỏ qua.
|
|
3729
|
+
*/
|
|
3730
|
+
readonly pasteFromPage: _angular_core.InputSignal<boolean>;
|
|
3731
|
+
/** Dòng gợi ý dưới khung, ví dụ định dạng cho phép. */
|
|
3732
|
+
readonly helperText: _angular_core.InputSignal<string>;
|
|
3733
|
+
readonly files: _angular_core.ModelSignal<OlUploadFile[]>;
|
|
3734
|
+
/** Tệp VỪA nhận, đã qua kiểm — nơi gọi bắt đầu tải lên từ đây. */
|
|
3735
|
+
readonly filesAdded: _angular_core.OutputEmitterRef<File[]>;
|
|
3736
|
+
readonly fileRemove: _angular_core.OutputEmitterRef<OlUploadFile>;
|
|
3737
|
+
readonly filePreview: _angular_core.OutputEmitterRef<OlUploadFile>;
|
|
3738
|
+
readonly fileRetry: _angular_core.OutputEmitterRef<OlUploadFile>;
|
|
3739
|
+
/** Tệp bị loại kèm lý do — component đã tự hiện câu lỗi dưới khung. */
|
|
3740
|
+
readonly rejected: _angular_core.OutputEmitterRef<FileRejection[]>;
|
|
3741
|
+
private readonly fileInput;
|
|
3742
|
+
private readonly host;
|
|
3743
|
+
protected readonly uid: string;
|
|
3744
|
+
protected readonly errors: _angular_core.WritableSignal<string[]>;
|
|
3745
|
+
protected readonly isMultiple: _angular_core.Signal<boolean>;
|
|
3746
|
+
protected readonly isImageMode: _angular_core.Signal<boolean>;
|
|
3747
|
+
protected readonly hasFiles: _angular_core.Signal<boolean>;
|
|
3748
|
+
protected readonly limitReached: _angular_core.Signal<boolean>;
|
|
3749
|
+
protected readonly resolvedButtonLabel: _angular_core.Signal<string>;
|
|
3750
|
+
protected readonly hintText: _angular_core.Signal<string>;
|
|
3751
|
+
protected readonly describedBy: _angular_core.Signal<string>;
|
|
3752
|
+
/**
|
|
3753
|
+
* Ảnh xem trước cho chế độ `image`/`images`, theo id tệp: `url` có sẵn (ảnh
|
|
3754
|
+
* đã trên máy chủ) hoặc object URL tạo từ `File`.
|
|
3755
|
+
*
|
|
3756
|
+
* Object URL phải THU HỒI khi tệp bị xoá / component huỷ, không thì mỗi ảnh
|
|
3757
|
+
* rò một khối bộ nhớ bằng cả ảnh. Giữ theo id để thêm một ảnh không tạo lại
|
|
3758
|
+
* URL của các ảnh cũ (ảnh cũ sẽ nháy vì `src` đổi).
|
|
3759
|
+
*/
|
|
3760
|
+
protected readonly imageUrls: _angular_core.WritableSignal<Record<string, string>>;
|
|
3761
|
+
private readonly objectUrls;
|
|
3762
|
+
/** Ảnh cho trình xem — chỉ tệp đã có URL. */
|
|
3763
|
+
protected readonly previewImages: _angular_core.Signal<OlPreviewImage[]>;
|
|
3764
|
+
protected readonly previewOpen: _angular_core.WritableSignal<boolean>;
|
|
3765
|
+
protected readonly previewIndex: _angular_core.WritableSignal<number>;
|
|
3766
|
+
constructor();
|
|
3767
|
+
/** Tạo URL cho ảnh mới, thu hồi URL của ảnh đã bị xoá. */
|
|
3768
|
+
private syncImageUrls;
|
|
3769
|
+
/** Mở trình xem tại ảnh của tệp này, và phát `(filePreview)`. */
|
|
3770
|
+
openPreview(file: OlUploadFile): void;
|
|
3771
|
+
openPicker(): void;
|
|
3772
|
+
protected onInputChange(event: Event): void;
|
|
3773
|
+
/** Nhận tệp từ hộp chọn hoặc kéo thả: kiểm, thêm vào `files`, phát sự kiện. */
|
|
3774
|
+
addFiles(incoming: File[]): void;
|
|
3775
|
+
/** Dán tệp khi tiêu điểm trong khung (nút, chip, dòng tệp). */
|
|
3776
|
+
protected onPaste(event: ClipboardEvent): void;
|
|
3777
|
+
/** Thả thêm tệp vào vùng chip đã có tệp. */
|
|
3778
|
+
protected onListDrop(event: DragEvent): void;
|
|
3779
|
+
protected removeFile(file: OlUploadFile): void;
|
|
3780
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlFileUpload, never>;
|
|
3781
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlFileUpload, "ol-file-upload", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; "accept": { "alias": "accept"; "required": false; "isSignal": true; }; "maxSize": { "alias": "maxSize"; "required": false; "isSignal": true; }; "maxFiles": { "alias": "maxFiles"; "required": false; "isSignal": true; }; "buttonLabel": { "alias": "buttonLabel"; "required": false; "isSignal": true; }; "previewable": { "alias": "previewable"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "pasteFromPage": { "alias": "pasteFromPage"; "required": false; "isSignal": true; }; "helperText": { "alias": "helperText"; "required": false; "isSignal": true; }; "files": { "alias": "files"; "required": false; "isSignal": true; }; }, { "files": "filesChange"; "filesAdded": "filesAdded"; "fileRemove": "fileRemove"; "filePreview": "filePreview"; "fileRetry": "fileRetry"; "rejected": "rejected"; }, never, ["[actions]"], true, never>;
|
|
3073
3782
|
}
|
|
3074
3783
|
|
|
3075
3784
|
declare class OlRange implements ControlValueAccessor {
|
|
@@ -4095,8 +4804,34 @@ declare class OlNavbar {
|
|
|
4095
4804
|
readonly onToggleMobileMenu: _angular_core.OutputEmitterRef<boolean>;
|
|
4096
4805
|
searchQuery: string;
|
|
4097
4806
|
private readonly elementRef;
|
|
4807
|
+
private readonly mobilePanel;
|
|
4808
|
+
private readonly navWrap;
|
|
4809
|
+
private readonly destroyRef;
|
|
4810
|
+
/** Nơi gọi có khai `slot="mobile-links"` (hoặc `slot="mobile"`) riêng. */
|
|
4811
|
+
readonly hasMobileLinks: _angular_core.WritableSignal<boolean>;
|
|
4812
|
+
/** Panel ☰ có gì để hiện — không thì đừng vẽ một dải trống có padding. */
|
|
4813
|
+
readonly hasPanelContent: _angular_core.WritableSignal<boolean>;
|
|
4814
|
+
constructor();
|
|
4815
|
+
/** Chiều cao khối mục xếp dọc (0 khi không xếp dọc) → `--ol-nav-stack-h`. */
|
|
4816
|
+
private observeStackHeight;
|
|
4817
|
+
private isStacked;
|
|
4818
|
+
/**
|
|
4819
|
+
* Đo lại mỗi lần mở ☰, không chỉ lúc đầu: nội dung chiếu vào có thể nằm
|
|
4820
|
+
* trong @if của nơi gọi và xuất hiện muộn.
|
|
4821
|
+
*/
|
|
4822
|
+
private detectMobileSlots;
|
|
4823
|
+
/**
|
|
4824
|
+
* Khối mục menu. Khung ≥ 78rem: nằm ngang cạnh logo.
|
|
4825
|
+
*
|
|
4826
|
+
* Khung hẹp mà ☰ đang mở và KHÔNG có menu di động riêng: xuống dòng
|
|
4827
|
+
* (`col-span-full row-start-2`) và xếp dọc — chính các mục desktop thành menu
|
|
4828
|
+
* di động. Bản trước chỉ ẩn chúng, nên 5/7 thanh trên /navbar và /blocks bấm
|
|
4829
|
+
* ☰ ra bảng trống (đo iPhone 13 giả lập, 2026-09-28).
|
|
4830
|
+
*/
|
|
4831
|
+
readonly navWrapClasses: _angular_core.Signal<string>;
|
|
4832
|
+
readonly mobilePanelClasses: _angular_core.Signal<"hidden" | "@[78rem]:hidden absolute inset-x-0 top-[calc(100%+var(--ol-nav-stack-h,0px))] z-dropdown max-h-[calc(100dvh-5rem)] overflow-y-auto border-t border-default bg-neutral-primary px-4 pt-4 pb-6 space-y-4 animate-in fade-in slide-in-from-top-2 duration-150 shadow-xl">;
|
|
4098
4833
|
readonly navbarClasses: _angular_core.Signal<string>;
|
|
4099
|
-
readonly containerClasses: _angular_core.Signal<"w-full px-4
|
|
4834
|
+
readonly containerClasses: _angular_core.Signal<"w-full px-4 @[40rem]:px-6" | "max-w-7xl mx-auto px-4 @[40rem]:px-6 @5xl:px-8">;
|
|
4100
4835
|
toggleMobileMenu(): void;
|
|
4101
4836
|
handleSearchSubmit(): void;
|
|
4102
4837
|
handleSearchInput(event: Event): void;
|
|
@@ -4125,7 +4860,40 @@ declare class OlNavDropdown {
|
|
|
4125
4860
|
readonly label: _angular_core.InputSignal<string>;
|
|
4126
4861
|
readonly icon: _angular_core.InputSignal<string | null>;
|
|
4127
4862
|
readonly alignRight: _angular_core.InputSignal<boolean>;
|
|
4863
|
+
/**
|
|
4864
|
+
* Đang ở một trang CON của menu này (ví dụ "Lớp học" khi đang xem 10A1).
|
|
4865
|
+
* Cùng hình với `ol-navbar-item` active — nền brand nhạt, chữ brand đậm —
|
|
4866
|
+
* để thanh điều hướng luôn chỉ ra người dùng đang ở phân hệ nào.
|
|
4867
|
+
*/
|
|
4868
|
+
readonly active: _angular_core.InputSignal<boolean>;
|
|
4869
|
+
protected readonly triggerClasses: _angular_core.Signal<string>;
|
|
4870
|
+
/**
|
|
4871
|
+
* Số cột của panel. `1` (mặc định) là menu thường; từ `2` là mega-menu.
|
|
4872
|
+
*
|
|
4873
|
+
* Mega-menu dùng cho menu có nhiều nhóm mục — thay vì một cột dài phải cuộn,
|
|
4874
|
+
* chia thành cột đứng cạnh nhau và người dùng quét mắt một lượt là thấy hết.
|
|
4875
|
+
*
|
|
4876
|
+
* Dưới `md` LUÔN về một cột bất kể giá trị: hai cột trên màn 390px là mỗi
|
|
4877
|
+
* cột 150px, chữ vỡ dòng giữa từ. Ngưỡng theo breakpoint chứ không theo bề
|
|
4878
|
+
* ngang panel vì panel treo tự do, không có container để đo.
|
|
4879
|
+
*/
|
|
4880
|
+
readonly columns: _angular_core.InputSignal<1 | 2 | 3 | 4>;
|
|
4881
|
+
/**
|
|
4882
|
+
* Panel rộng bằng cả navbar thay vì bám mép nút.
|
|
4883
|
+
*
|
|
4884
|
+
* Mega-menu nhiều cột mà vẫn bám mép nút thì nửa panel tràn ra ngoài màn
|
|
4885
|
+
* hình khi nút nằm bên phải. Trải hết chiều ngang thì luôn nằm trong khung.
|
|
4886
|
+
*/
|
|
4887
|
+
readonly fullWidth: _angular_core.InputSignal<boolean>;
|
|
4128
4888
|
readonly isOpen: _angular_core.WritableSignal<boolean>;
|
|
4889
|
+
/**
|
|
4890
|
+
* Class của panel.
|
|
4891
|
+
*
|
|
4892
|
+
* Gom vào MỘT chuỗi thay vì nhiều `[class.x]` rời: hai class cùng thuộc tính
|
|
4893
|
+
* thì trình duyệt chọn theo thứ tự luật trong file CSS chứ không theo thứ tự
|
|
4894
|
+
* viết, kết quả đổi theo bản build.
|
|
4895
|
+
*/
|
|
4896
|
+
protected readonly panelClasses: _angular_core.Signal<string>;
|
|
4129
4897
|
private readonly elementRef;
|
|
4130
4898
|
private readonly overlayContainer;
|
|
4131
4899
|
constructor();
|
|
@@ -4133,9 +4901,120 @@ declare class OlNavDropdown {
|
|
|
4133
4901
|
close(): void;
|
|
4134
4902
|
handleClickOutside(event: MouseEvent): void;
|
|
4135
4903
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlNavDropdown, never>;
|
|
4136
|
-
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>;
|
|
4904
|
+
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; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "fullWidth": { "alias": "fullWidth"; "required": false; "isSignal": true; }; }, {}, never, ["[slot=trigger], [trigger]", "*"], true, never>;
|
|
4905
|
+
}
|
|
4906
|
+
|
|
4907
|
+
/** Một mục trong menu thả xuống. */
|
|
4908
|
+
interface OlMenubarItem {
|
|
4909
|
+
id: string;
|
|
4910
|
+
label: string;
|
|
4911
|
+
/** Chữ phụ bên phải: phím tắt, ví dụ "⌘S". */
|
|
4912
|
+
shortcut?: string;
|
|
4913
|
+
disabled?: boolean;
|
|
4914
|
+
/** Kẻ ngăn NGAY TRƯỚC mục này. */
|
|
4915
|
+
separatorBefore?: boolean;
|
|
4916
|
+
}
|
|
4917
|
+
/** Một menu trên thanh: nhãn trên thanh + danh sách mục. */
|
|
4918
|
+
interface OlMenubarMenu {
|
|
4919
|
+
id: string;
|
|
4920
|
+
label: string;
|
|
4921
|
+
items: OlMenubarItem[];
|
|
4922
|
+
disabled?: boolean;
|
|
4923
|
+
}
|
|
4924
|
+
/**
|
|
4925
|
+
* Thanh menu kiểu ứng dụng để bàn — Tệp · Sửa · Xem.
|
|
4926
|
+
*
|
|
4927
|
+
* Chưa có node Figma — dựng theo design system, dùng lại cách trình bày của
|
|
4928
|
+
* `ol-dropdown-item`.
|
|
4929
|
+
*
|
|
4930
|
+
* ## Khác `ol-dropdown` ở ba điểm, và đó là lý do có component riêng
|
|
4931
|
+
*
|
|
4932
|
+
* 1. **Mở một menu rồi RÊ sang menu kế là mở luôn**, không phải bấm lại. Đây
|
|
4933
|
+
* là hành vi người dùng đã quen từ phần mềm để bàn; thiếu nó thì thanh menu
|
|
4934
|
+
* chỉ là mấy cái dropdown đặt cạnh nhau.
|
|
4935
|
+
* 2. **Mũi tên trái/phải đi giữa các menu**, lên/xuống đi trong menu đang mở.
|
|
4936
|
+
* WAI-ARIA quy định `role="menubar"` phải làm vậy.
|
|
4937
|
+
* 3. **Một menu mở thì menu khác đóng** — không bao giờ có hai panel cùng lúc.
|
|
4938
|
+
*
|
|
4939
|
+
* ## Vì sao KHÔNG treo panel ra `<body>`
|
|
4940
|
+
*
|
|
4941
|
+
* Thanh menu thường nằm ngay dưới tiêu đề cửa sổ, không bị `overflow: hidden`
|
|
4942
|
+
* cắt như dropdown trong bảng. Giữ panel trong cây DOM thì Tab đi vào được tự
|
|
4943
|
+
* nhiên, không phải xử lý riêng như `ol-dropdown` đã phải làm.
|
|
4944
|
+
*
|
|
4945
|
+
* ## Lưu ý khi viết test
|
|
4946
|
+
*
|
|
4947
|
+
* Rê chuột giữa các menu cần bố cục thật để tính vị trí. jsdom không có, nên
|
|
4948
|
+
* spec khoá phần bàn phím và trạng thái mở/đóng; hành vi rê nghiệm thu trên
|
|
4949
|
+
* trình duyệt.
|
|
4950
|
+
*/
|
|
4951
|
+
declare class OlMenubar {
|
|
4952
|
+
private readonly elementRef;
|
|
4953
|
+
private readonly destroyRef;
|
|
4954
|
+
private readonly overlayContainer;
|
|
4955
|
+
readonly menus: _angular_core.InputSignal<OlMenubarMenu[]>;
|
|
4956
|
+
readonly ariaLabel: _angular_core.InputSignal<string>;
|
|
4957
|
+
/** `id` của menu đang mở. Rỗng nghĩa là không menu nào mở. */
|
|
4958
|
+
private readonly openId;
|
|
4959
|
+
readonly openMenuId: _angular_core.Signal<string>;
|
|
4960
|
+
readonly itemSelect: _angular_core.OutputEmitterRef<{
|
|
4961
|
+
menu: OlMenubarMenu;
|
|
4962
|
+
item: OlMenubarItem;
|
|
4963
|
+
}>;
|
|
4964
|
+
private releaseEscape;
|
|
4965
|
+
constructor();
|
|
4966
|
+
protected toggle(menu: OlMenubarMenu): void;
|
|
4967
|
+
/**
|
|
4968
|
+
* Rê sang menu khác khi ĐANG có menu mở thì mở luôn menu đó.
|
|
4969
|
+
*
|
|
4970
|
+
* Không mở khi chưa menu nào mở — nếu không, lướt chuột ngang thanh là bung
|
|
4971
|
+
* ra một panel người dùng không định mở.
|
|
4972
|
+
*/
|
|
4973
|
+
protected onMenuHover(menu: OlMenubarMenu): void;
|
|
4974
|
+
private open;
|
|
4975
|
+
private closeAll;
|
|
4976
|
+
protected onItemClick(menu: OlMenubarMenu, item: OlMenubarItem): void;
|
|
4977
|
+
/**
|
|
4978
|
+
* Mũi tên trái/phải đi giữa các menu — WAI-ARIA quy định cho `role="menubar"`.
|
|
4979
|
+
*
|
|
4980
|
+
* Vòng lại đầu khi tới cuối: thanh menu là một dải kín, không phải danh sách
|
|
4981
|
+
* có điểm dừng. Người dùng nhấn phải liên tục thì quay về menu đầu.
|
|
4982
|
+
*
|
|
4983
|
+
* Dùng `(keydown)` trần rồi tự lọc phím vì thẻ đã có `(click)` — hai listener
|
|
4984
|
+
* khác kiểu sự kiện trên cùng thẻ thì Angular suy `$event` theo cái đầu.
|
|
4985
|
+
*/
|
|
4986
|
+
protected onTriggerKeydown(event: KeyboardEvent, index: number): void;
|
|
4987
|
+
/**
|
|
4988
|
+
* Menu kế tiếp **còn dùng được** theo hướng `step`, vòng lại khi tới biên.
|
|
4989
|
+
*
|
|
4990
|
+
* Phải bỏ qua menu `disabled`: nút gốc có thuộc tính `disabled` nên
|
|
4991
|
+
* `.focus()` trên nó KHÔNG có tác dụng nào — tiêu điểm đứng nguyên chỗ cũ và
|
|
4992
|
+
* người dùng tưởng bàn phím hỏng. Spec bắt đúng lỗi này khi menu cuối bị vô
|
|
4993
|
+
* hiệu: nhấn End là tiêu điểm rơi về `<body>`.
|
|
4994
|
+
*
|
|
4995
|
+
* Trả `null` khi KHÔNG có menu nào dùng được — lúc đó không `preventDefault`,
|
|
4996
|
+
* để phím về lại hành vi mặc định của trình duyệt.
|
|
4997
|
+
*
|
|
4998
|
+
* Nhận `from` ngoài dải (-1 hoặc `length`) để Home/End dùng chung một phép:
|
|
4999
|
+
* Home là "từ trước mục đầu, đi sang phải", End là "từ sau mục cuối, đi sang
|
|
5000
|
+
* trái".
|
|
5001
|
+
*/
|
|
5002
|
+
private nextEnabled;
|
|
5003
|
+
protected triggerClasses(menu: OlMenubarMenu): string;
|
|
5004
|
+
protected itemClasses(item: OlMenubarItem): string;
|
|
5005
|
+
protected readonly hasMenus: _angular_core.Signal<boolean>;
|
|
5006
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlMenubar, never>;
|
|
5007
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlMenubar, "ol-menubar", never, { "menus": { "alias": "menus"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "itemSelect": "itemSelect"; }, never, never, true, never>;
|
|
4137
5008
|
}
|
|
4138
5009
|
|
|
5010
|
+
/**
|
|
5011
|
+
* Bố cục thanh phân trang (Figma `ol-pagination` #1149:81850).
|
|
5012
|
+
*
|
|
5013
|
+
* `with-dropdown` là BÍ DANH: ≡ `text-buttons` + `[withDropdown]="true"`. Ô
|
|
5014
|
+
* chọn cỡ trang nay là cờ riêng gắn được vào MỌI type; giữ giá trị này vì gói
|
|
5015
|
+
* đã publish. (Chú thích đặt ở đây, không chen giữa các giá trị: guard
|
|
5016
|
+
* `check:gia-tri-ma-mau` đọc union sẽ đứt ở khối chú thích.)
|
|
5017
|
+
*/
|
|
4139
5018
|
type PaginationType = 'default' | 'arrows' | 'dropdown-buttons' | 'text-buttons' | 'two-buttons' | 'buttons-helper' | 'with-dropdown' | 'with-input' | 'simple-input'
|
|
4140
5019
|
/**
|
|
4141
5020
|
* `grouped` và `separated` trước chỉ có ở `PaginationVariant`. Thêm vào đây
|
|
@@ -4180,6 +5059,17 @@ declare class OlPagination {
|
|
|
4180
5059
|
readonly showText: _angular_core.InputSignal<boolean>;
|
|
4181
5060
|
readonly text: _angular_core.InputSignal<string>;
|
|
4182
5061
|
readonly showInfo: _angular_core.InputSignal<boolean>;
|
|
5062
|
+
/**
|
|
5063
|
+
* Thêm ô chọn số dòng mỗi trang ("10 mỗi trang") vào BẤT KỲ type nào — cạnh
|
|
5064
|
+
* dãy số, cạnh hai nút, cạnh ô nhập trang… Trước đây nó chỉ có ở một type
|
|
5065
|
+
* riêng (`with-dropdown`), muốn nó cạnh `arrows` hay `two-buttons` là không
|
|
5066
|
+
* được. Danh sách lấy từ `pageSizeOptions`, đổi thì phát `(pageChange)` về 1.
|
|
5067
|
+
*/
|
|
5068
|
+
readonly withDropdown: _angular_core.InputSignal<boolean>;
|
|
5069
|
+
/**
|
|
5070
|
+
* @deprecated Dùng `withDropdown`. Bí danh: bật là thêm ô chọn cỡ trang. Khi
|
|
5071
|
+
* không đặt `type`, nó vẫn chọn bố cục `with-dropdown` như trước.
|
|
5072
|
+
*/
|
|
4183
5073
|
readonly showSizeChanger: _angular_core.InputSignal<boolean>;
|
|
4184
5074
|
readonly showQuickJumper: _angular_core.InputSignal<boolean>;
|
|
4185
5075
|
readonly pageChange: _angular_core.OutputEmitterRef<number>;
|
|
@@ -4193,6 +5083,10 @@ declare class OlPagination {
|
|
|
4193
5083
|
* xảy ra. `type` đặt tường minh vẫn thắng; cờ chỉ điền vào chỗ trống.
|
|
4194
5084
|
*/
|
|
4195
5085
|
readonly effectiveType: _angular_core.Signal<PaginationType>;
|
|
5086
|
+
/** Bố cục vẽ ra: `with-dropdown` là bí danh nên quy về `text-buttons`. */
|
|
5087
|
+
readonly layoutType: _angular_core.Signal<PaginationType>;
|
|
5088
|
+
/** Có vẽ ô chọn cỡ trang không — cờ riêng, độc lập với type. */
|
|
5089
|
+
readonly hasPageSizeDropdown: _angular_core.Signal<boolean>;
|
|
4196
5090
|
/**
|
|
4197
5091
|
* Trang đang xem — gộp `pageIndex` và bí danh `currentPage`.
|
|
4198
5092
|
*
|
|
@@ -4264,7 +5158,7 @@ declare class OlPagination {
|
|
|
4264
5158
|
onPageSizeSelect(event: Event): void;
|
|
4265
5159
|
handleJump(): void;
|
|
4266
5160
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlPagination, never>;
|
|
4267
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlPagination, "ol-pagination", never, { "type": { "alias": "type"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "total": { "alias": "total"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "pageIndex": { "alias": "pageIndex"; "required": false; "isSignal": true; }; "currentPage": { "alias": "currentPage"; "required": false; "isSignal": true; }; "totalPagesInput": { "alias": "totalPages"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "showText": { "alias": "showText"; "required": false; "isSignal": true; }; "text": { "alias": "text"; "required": false; "isSignal": true; }; "showInfo": { "alias": "showInfo"; "required": false; "isSignal": true; }; "showSizeChanger": { "alias": "showSizeChanger"; "required": false; "isSignal": true; }; "showQuickJumper": { "alias": "showQuickJumper"; "required": false; "isSignal": true; }; }, { "pageSize": "pageSizeChange"; "pageIndex": "pageIndexChange"; "currentPage": "currentPageChange"; "pageChange": "pageChange"; }, never, never, true, never>;
|
|
5161
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlPagination, "ol-pagination", never, { "type": { "alias": "type"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "total": { "alias": "total"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "pageIndex": { "alias": "pageIndex"; "required": false; "isSignal": true; }; "currentPage": { "alias": "currentPage"; "required": false; "isSignal": true; }; "totalPagesInput": { "alias": "totalPages"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "showText": { "alias": "showText"; "required": false; "isSignal": true; }; "text": { "alias": "text"; "required": false; "isSignal": true; }; "showInfo": { "alias": "showInfo"; "required": false; "isSignal": true; }; "withDropdown": { "alias": "withDropdown"; "required": false; "isSignal": true; }; "showSizeChanger": { "alias": "showSizeChanger"; "required": false; "isSignal": true; }; "showQuickJumper": { "alias": "showQuickJumper"; "required": false; "isSignal": true; }; }, { "pageSize": "pageSizeChange"; "pageIndex": "pageIndexChange"; "currentPage": "currentPageChange"; "pageChange": "pageChange"; }, never, never, true, never>;
|
|
4268
5162
|
}
|
|
4269
5163
|
|
|
4270
5164
|
type PopoverPlacement = 'top' | 'bottom' | 'left' | 'right';
|
|
@@ -4320,6 +5214,29 @@ declare class OlPopover {
|
|
|
4320
5214
|
private cleanupAutoUpdate;
|
|
4321
5215
|
/** Hàm trả panel về chỗ cũ khi đóng. */
|
|
4322
5216
|
private detachPanel;
|
|
5217
|
+
/**
|
|
5218
|
+
* Selector cho phần tử nhận được tiêu điểm.
|
|
5219
|
+
*
|
|
5220
|
+
* `tabindex="-1"` bị loại: đó là dấu hiệu tác giả cố ý đưa phần tử ra khỏi
|
|
5221
|
+
* đường Tab. `:disabled` cũng loại — trình duyệt không cho nó nhận tiêu điểm.
|
|
5222
|
+
*/
|
|
5223
|
+
private static readonly FOCUSABLE;
|
|
5224
|
+
/**
|
|
5225
|
+
* Phần tử nhận tiêu điểm bên trong `root`, theo thứ tự nhìn thấy.
|
|
5226
|
+
*
|
|
5227
|
+
* Lọc phần ẩn bằng `[hidden]`/`[aria-hidden]` chứ KHÔNG `offsetParent`:
|
|
5228
|
+
* `offsetParent` là `null` với mọi phần tử trong `position: fixed` — mà panel
|
|
5229
|
+
* nổi hay dùng đúng kiểu định vị đó — nên danh sách sẽ rỗng và toàn bộ xử lý
|
|
5230
|
+
* Tab lặng lẽ không chạy.
|
|
5231
|
+
*/
|
|
5232
|
+
private focusablesIn;
|
|
5233
|
+
/**
|
|
5234
|
+
* Phần tử nhận tiêu điểm đứng ngay sau `element` trong thứ tự Tab của trang.
|
|
5235
|
+
*
|
|
5236
|
+
* Loại chính panel ra: nó treo cuối `<body>` nên nếu tính cả thì "phần tử sau
|
|
5237
|
+
* nút trigger" lại rơi vào panel vừa đóng.
|
|
5238
|
+
*/
|
|
5239
|
+
private nextFocusableAfter;
|
|
4323
5240
|
constructor();
|
|
4324
5241
|
toggle(): void;
|
|
4325
5242
|
open(): void;
|
|
@@ -4607,6 +5524,99 @@ declare class OlRating {
|
|
|
4607
5524
|
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>;
|
|
4608
5525
|
}
|
|
4609
5526
|
|
|
5527
|
+
type OlResizableDirection = 'horizontal' | 'vertical';
|
|
5528
|
+
/**
|
|
5529
|
+
* Hai khung chia nhau một vùng, kéo vạch giữa để đổi tỉ lệ.
|
|
5530
|
+
*
|
|
5531
|
+
* Chưa có node Figma — dựng theo design system: vạch kéo dùng `bg-default`,
|
|
5532
|
+
* sáng lên `bg-brand` khi rê chuột hoặc đang kéo.
|
|
5533
|
+
*
|
|
5534
|
+
* ## Vì sao tỉ lệ phần trăm chứ không pixel
|
|
5535
|
+
*
|
|
5536
|
+
* Người dùng đổi cỡ cửa sổ thì hai khung phải giãn theo. Lưu pixel thì khung
|
|
5537
|
+
* trái giữ nguyên còn khung phải nuốt toàn bộ phần thêm — tỉ lệ người dùng
|
|
5538
|
+
* chọn biến mất.
|
|
5539
|
+
*
|
|
5540
|
+
* ## Bắt chuột trên `document`, không trên vạch
|
|
5541
|
+
*
|
|
5542
|
+
* Kéo nhanh thì con trỏ rời khỏi vạch trước khi trình duyệt kịp gửi sự kiện
|
|
5543
|
+
* tiếp theo; nghe trên chính vạch thì kéo đứt đoạn. Nghe trên `document` lúc
|
|
5544
|
+
* đang kéo và gỡ ngay khi thả.
|
|
5545
|
+
*
|
|
5546
|
+
* `setPointerCapture` giải quyết đúng việc này nhưng không có trong jsdom, nên
|
|
5547
|
+
* spec sẽ không chạy được nhánh kéo — dùng `document` thì cả hai môi trường
|
|
5548
|
+
* cùng một đường mã.
|
|
5549
|
+
*
|
|
5550
|
+
* ## Bàn phím
|
|
5551
|
+
*
|
|
5552
|
+
* Vạch là `role="separator"` có `tabindex`, mũi tên đổi 2% mỗi lần, Home/End
|
|
5553
|
+
* về hai biên. Không có phần này thì người dùng bàn phím không đổi được tỉ lệ
|
|
5554
|
+
* — và một khung chia đôi không kéo được thì chỉ là hai `<div>` cạnh nhau.
|
|
5555
|
+
*
|
|
5556
|
+
* ## Lưu ý khi viết test
|
|
5557
|
+
*
|
|
5558
|
+
* jsdom không tính bố cục: `getBoundingClientRect()` trả 0 cho mọi thứ, nên
|
|
5559
|
+
* phép quy đổi toạ độ chuột sang phần trăm luôn ra `NaN` hoặc 0. Spec khoá
|
|
5560
|
+
* phần bàn phím và ràng buộc min/max (tính thuần số); việc kéo chuột nghiệm
|
|
5561
|
+
* thu trên trình duyệt.
|
|
5562
|
+
*/
|
|
5563
|
+
declare class OlResizable {
|
|
5564
|
+
private readonly elementRef;
|
|
5565
|
+
private readonly destroyRef;
|
|
5566
|
+
readonly direction: _angular_core.InputSignal<OlResizableDirection>;
|
|
5567
|
+
/** Tỉ lệ khung ĐẦU, tính bằng phần trăm. Hai chiều để nơi dùng lưu lại được. */
|
|
5568
|
+
readonly ratio: _angular_core.ModelSignal<number>;
|
|
5569
|
+
/** Chặn dưới và chặn trên, phần trăm. Khung nào cũng không nhỏ hơn `minRatio`. */
|
|
5570
|
+
readonly minRatio: _angular_core.InputSignal<number>;
|
|
5571
|
+
readonly maxRatio: _angular_core.InputSignal<number>;
|
|
5572
|
+
/** Bước đổi mỗi lần nhấn mũi tên, phần trăm. */
|
|
5573
|
+
readonly keyboardStep: _angular_core.InputSignal<number>;
|
|
5574
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
5575
|
+
readonly ariaLabel: _angular_core.InputSignal<string>;
|
|
5576
|
+
/**
|
|
5577
|
+
* Bắn khi thả chuột hoặc nhấn phím — KHÔNG bắn liên tục lúc đang kéo.
|
|
5578
|
+
*
|
|
5579
|
+
* Tên là `resizeEnd` chứ không `ratioChange`: `model()` đã tự sinh
|
|
5580
|
+
* `ratioChange` cho binding hai chiều, khai thêm output trùng tên là lỗi
|
|
5581
|
+
* biên dịch NG1054. Hai thứ cũng khác nghĩa — `ratioChange` bắn mỗi lần giá
|
|
5582
|
+
* trị đổi (kể cả từng nhịp kéo), còn `resizeEnd` chỉ bắn khi người dùng đã
|
|
5583
|
+
* thả tay, đúng lúc nên lưu tỉ lệ xuống máy chủ.
|
|
5584
|
+
*/
|
|
5585
|
+
readonly resizeEnd: _angular_core.OutputEmitterRef<number>;
|
|
5586
|
+
private readonly dragging;
|
|
5587
|
+
private releaseDrag;
|
|
5588
|
+
constructor();
|
|
5589
|
+
/** Ép tỉ lệ vào khoảng cho phép. Tách ra để spec khoá được mà không cần DOM. */
|
|
5590
|
+
clamp(value: number): number;
|
|
5591
|
+
protected onPointerDown(event: PointerEvent): void;
|
|
5592
|
+
private stopDrag;
|
|
5593
|
+
private applyFromPointer;
|
|
5594
|
+
protected onKeydown(event: KeyboardEvent): void;
|
|
5595
|
+
protected readonly rootClasses: _angular_core.Signal<"flex h-full w-full" | "flex h-full w-full flex-col">;
|
|
5596
|
+
/** Kích thước khung đầu — `flex-basis` phần trăm, khung sau lấp phần còn lại. */
|
|
5597
|
+
protected readonly firstStyle: _angular_core.Signal<string>;
|
|
5598
|
+
/**
|
|
5599
|
+
* Vạch chia.
|
|
5600
|
+
*
|
|
5601
|
+
* ## Vùng bấm rộng hơn vạch nhìn thấy
|
|
5602
|
+
*
|
|
5603
|
+
* Vạch chỉ dày 6px thì đúng thẩm mỹ nhưng vùng bấm 6px vi phạm WCAG 2.5.8
|
|
5604
|
+
* (ngưỡng 24px) — đo trên trình duyệt ra `6×188px`. Nên vạch nhận
|
|
5605
|
+
* `w-6`/`h-6` để vùng bấm đủ 24px, còn phần MÀU nằm ở `::before` chỉ
|
|
5606
|
+
* 6px ở giữa. Người dùng thấy vạch mảnh, tay và con trỏ thì có 24px để bắt.
|
|
5607
|
+
*
|
|
5608
|
+
* `::before` khai trong `handleBarClasses()` và đặt qua một `<span>` con chứ
|
|
5609
|
+
* không dùng biến thể `before:` của Tailwind: `before:` cần nhiều class cho
|
|
5610
|
+
* cùng một hình và khó đọc hơn một phần tử thật.
|
|
5611
|
+
*/
|
|
5612
|
+
protected readonly handleClasses: _angular_core.Signal<string>;
|
|
5613
|
+
/** Phần MÀU của vạch — mảnh 6px, nằm giữa vùng bấm 24px. */
|
|
5614
|
+
protected readonly handleBarClasses: _angular_core.Signal<string>;
|
|
5615
|
+
protected readonly ariaOrientation: _angular_core.Signal<"vertical" | "horizontal">;
|
|
5616
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlResizable, never>;
|
|
5617
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlResizable, "ol-resizable", never, { "direction": { "alias": "direction"; "required": false; "isSignal": true; }; "ratio": { "alias": "ratio"; "required": false; "isSignal": true; }; "minRatio": { "alias": "minRatio"; "required": false; "isSignal": true; }; "maxRatio": { "alias": "maxRatio"; "required": false; "isSignal": true; }; "keyboardStep": { "alias": "keyboardStep"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "ratio": "ratioChange"; "resizeEnd": "resizeEnd"; }, never, ["[first]", "[second]"], true, never>;
|
|
5618
|
+
}
|
|
5619
|
+
|
|
4610
5620
|
/**
|
|
4611
5621
|
* Kiểu dữ liệu cho `ol-app-nav` — menu điều hướng Ôn Luyện.
|
|
4612
5622
|
*
|
|
@@ -5402,13 +6412,13 @@ declare class OlToastContainer {
|
|
|
5402
6412
|
* cùng một union, tách thành hai kiểu riêng là để người dùng phải nhớ chúng
|
|
5403
6413
|
* bằng nhau.
|
|
5404
6414
|
*/
|
|
5405
|
-
type OlTooltipTheme = 'dark' | 'light' | 'brand';
|
|
6415
|
+
type OlTooltipTheme = 'subtle' | 'dark' | 'light' | 'brand';
|
|
5406
6416
|
/** Hướng hiện tooltip so với phần tử đích. */
|
|
5407
6417
|
type OlTooltipPosition = 'top' | 'bottom' | 'left' | 'right';
|
|
5408
6418
|
declare class OlTooltip {
|
|
5409
6419
|
/** Tooltip content text */
|
|
5410
6420
|
readonly content: _angular_core.InputSignal<string>;
|
|
5411
|
-
/** Theme variant */
|
|
6421
|
+
/** Theme variant — mặc định `subtle` (nền Primary 50). */
|
|
5412
6422
|
readonly theme: _angular_core.InputSignal<OlTooltipTheme>;
|
|
5413
6423
|
/** Tooltip ID for ARIA */
|
|
5414
6424
|
readonly tooltipId: _angular_core.InputSignal<string>;
|
|
@@ -5585,6 +6595,134 @@ declare class OlIconService {
|
|
|
5585
6595
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<any>;
|
|
5586
6596
|
}
|
|
5587
6597
|
|
|
6598
|
+
type OlIconStackSize = 'sm' | 'base' | 'lg';
|
|
6599
|
+
/**
|
|
6600
|
+
* Chồng nhiều icon hoặc logo lên nhau, kèm số đếm "+N".
|
|
6601
|
+
*
|
|
6602
|
+
* Chưa có node Figma — dựng theo `ol-avatar-group`, component cùng cơ chế đã
|
|
6603
|
+
* có trong thư viện. Khác ở chỗ: avatar là ảnh người nên luôn tròn, còn icon
|
|
6604
|
+
* thường là biểu tượng dịch vụ hay môn học nên mặc định bo vừa (`rounded-lg`)
|
|
6605
|
+
* và có nền để icon một màu vẫn tách khỏi icon bên dưới.
|
|
6606
|
+
*
|
|
6607
|
+
* ## Vòng viền là thứ làm nên hiệu ứng chồng
|
|
6608
|
+
*
|
|
6609
|
+
* Mỗi ô có `ring-2 ring-buffer` — vòng viền màu nền trang, không phải viền
|
|
6610
|
+
* màu. Nhờ nó hai ô chồng nhau vẫn thấy rõ ranh giới. Bỏ vòng này thì các ô
|
|
6611
|
+
* dính thành một khối nhoè.
|
|
6612
|
+
*
|
|
6613
|
+
* `ring-buffer` chứ không `ring-white`: ở chế độ tối nền không phải trắng, và
|
|
6614
|
+
* viền trắng trên nền đen là đường kẻ sáng chói quanh mỗi icon.
|
|
6615
|
+
*
|
|
6616
|
+
* ## Thứ tự chồng
|
|
6617
|
+
*
|
|
6618
|
+
* Mặc định ô ĐẦU nằm trên — giống xếp bài. `reverse` lật lại cho ô cuối nằm
|
|
6619
|
+
* trên, dùng khi ô cuối là thứ cần nhấn (icon "thêm", trạng thái mới nhất).
|
|
6620
|
+
*
|
|
6621
|
+
* Làm bằng `flex-row-reverse` cộng đảo thứ tự dữ liệu chứ không bằng
|
|
6622
|
+
* `z-index`: `z-index` cần stacking context và sẽ hỏng khi nơi gọi đặt
|
|
6623
|
+
* component vào một phần tử có `transform` hay `opacity`.
|
|
6624
|
+
*/
|
|
6625
|
+
declare class OlIconStack {
|
|
6626
|
+
readonly size: _angular_core.InputSignal<OlIconStackSize>;
|
|
6627
|
+
/** Số đếm "+N" ở cuối. `null` thì không vẽ. */
|
|
6628
|
+
readonly counter: _angular_core.InputSignal<string | number | null>;
|
|
6629
|
+
readonly counterAriaLabel: _angular_core.InputSignal<string>;
|
|
6630
|
+
/** Lật thứ tự chồng: ô CUỐI nằm trên thay vì ô đầu. */
|
|
6631
|
+
readonly reverse: _angular_core.InputSignal<boolean>;
|
|
6632
|
+
/**
|
|
6633
|
+
* Bo góc của từng ô. `full` cho logo tròn, `lg` cho biểu tượng vuông.
|
|
6634
|
+
*
|
|
6635
|
+
* Áp lên CON qua biến thể `*:` của Tailwind, nên nơi gọi chỉ việc đặt
|
|
6636
|
+
* `<ol-icon>` hay `<img>` vào là xong.
|
|
6637
|
+
*/
|
|
6638
|
+
readonly rounded: _angular_core.InputSignal<"lg" | "full">;
|
|
6639
|
+
protected readonly rootClasses: _angular_core.Signal<string>;
|
|
6640
|
+
/**
|
|
6641
|
+
* Ô đếm "+N".
|
|
6642
|
+
*
|
|
6643
|
+
* `text-heading` chứ KHÔNG `text-body`: tổ hợp `bg-neutral-quaternary` +
|
|
6644
|
+
* `text-body` đo được 6.10 ở chế độ sáng nhưng chỉ 3.96 ở chế độ tối — dưới
|
|
6645
|
+
* ngưỡng WCAG 4.5. Đây là kết luận đã đo ở `ol-avatar-group` (BUG-016 mục 5),
|
|
6646
|
+
* theo tiền lệ sẵn có chứ không đoán lại.
|
|
6647
|
+
*
|
|
6648
|
+
* Chú thích để Ở ĐÂY chứ không trong template: template là một chuỗi
|
|
6649
|
+
* template literal, nên dấu backtick trong chú thích HTML đóng chuỗi sớm và
|
|
6650
|
+
* TS báo lỗi ở dòng chẳng liên quan (đã mắc khi viết file này).
|
|
6651
|
+
*/
|
|
6652
|
+
protected readonly counterClasses: _angular_core.Signal<string>;
|
|
6653
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlIconStack, never>;
|
|
6654
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlIconStack, "ol-icon-stack", never, { "size": { "alias": "size"; "required": false; "isSignal": true; }; "counter": { "alias": "counter"; "required": false; "isSignal": true; }; "counterAriaLabel": { "alias": "counterAriaLabel"; "required": false; "isSignal": true; }; "reverse": { "alias": "reverse"; "required": false; "isSignal": true; }; "rounded": { "alias": "rounded"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
6655
|
+
}
|
|
6656
|
+
|
|
6657
|
+
type OlItemSize = 'sm' | 'base' | 'lg';
|
|
6658
|
+
type OlItemAlign = 'start' | 'center';
|
|
6659
|
+
/**
|
|
6660
|
+
* Một dòng nội dung: phần dẫn đầu · tiêu đề + mô tả · phần hành động.
|
|
6661
|
+
*
|
|
6662
|
+
* Chưa có node Figma — dựng theo design system, lấy khoảng cách và cỡ chữ từ
|
|
6663
|
+
* `ol-checkbox-radio-form` (component gần nhất đang có cấu trúc này).
|
|
6664
|
+
*
|
|
6665
|
+
* ## Vì sao KHÔNG mở rộng `ol-list-group-item`
|
|
6666
|
+
*
|
|
6667
|
+
* Cái đó là `<li>` và phải nằm trong `<ul>` của `ol-list-group` — HTML quy
|
|
6668
|
+
* định vậy. Còn dòng nội dung thì hay đứng một mình trong thẻ, trong ngăn kéo,
|
|
6669
|
+
* hay trong kết quả tìm kiếm. Nhồi cấu trúc vào `<li>` là buộc mọi nơi dùng
|
|
6670
|
+
* phải bọc thêm `<ul>` không có ý nghĩa ngữ nghĩa nào.
|
|
6671
|
+
*
|
|
6672
|
+
* Hai component dùng chung cách xếp; `ol-item` lo phần bên trong, đặt ở đâu là
|
|
6673
|
+
* việc của nơi gọi.
|
|
6674
|
+
*
|
|
6675
|
+
* ## Ba khe, KHÔNG phải ba input
|
|
6676
|
+
*
|
|
6677
|
+
* `[lead]` và `[actions]` là khe cắm chứ không phải input nhận tên icon: phần
|
|
6678
|
+
* dẫn đầu có thể là icon, avatar, ảnh bìa hay số thứ tự; phần hành động có thể
|
|
6679
|
+
* là nút, huy hiệu, hay một dòng chữ. Nhận tên icon thì mỗi lần cần thứ khác
|
|
6680
|
+
* lại phải thêm một input.
|
|
6681
|
+
*
|
|
6682
|
+
* Riêng `icon` giữ lại làm lối tắt cho ca hay gặp nhất. Nó nằm TRONG cùng khe
|
|
6683
|
+
* `[lead]`, sau nội dung chiếu — nơi gọi truyền cả hai thì có hai phần dẫn đầu
|
|
6684
|
+
* cạnh nhau, nhưng đó là ca hiếm và không đáng thêm selector CSS để chặn.
|
|
6685
|
+
*/
|
|
6686
|
+
declare class OlItem {
|
|
6687
|
+
readonly title: _angular_core.InputSignal<string>;
|
|
6688
|
+
readonly description: _angular_core.InputSignal<string>;
|
|
6689
|
+
/** Lối tắt cho phần dẫn đầu dạng icon. Khe `[lead]` đè lên nó. */
|
|
6690
|
+
readonly icon: _angular_core.InputSignal<string>;
|
|
6691
|
+
readonly size: _angular_core.InputSignal<OlItemSize>;
|
|
6692
|
+
/**
|
|
6693
|
+
* Căn phần dẫn đầu và hành động theo chiều dọc.
|
|
6694
|
+
*
|
|
6695
|
+
* `start` khi mô tả dài hai ba dòng — icon căn giữa một khối cao trông như
|
|
6696
|
+
* trôi lơ lửng. `center` khi chỉ có tiêu đề.
|
|
6697
|
+
*/
|
|
6698
|
+
readonly align: _angular_core.InputSignal<OlItemAlign>;
|
|
6699
|
+
/** Bấm được: thêm hiệu ứng hover và con trỏ tay, phát `itemClick`. */
|
|
6700
|
+
readonly interactive: _angular_core.InputSignal<boolean>;
|
|
6701
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
6702
|
+
/** Biến cả dòng thành liên kết. Bỏ qua khi `disabled`. */
|
|
6703
|
+
readonly href: _angular_core.InputSignal<string | null>;
|
|
6704
|
+
readonly itemClick: _angular_core.OutputEmitterRef<MouseEvent>;
|
|
6705
|
+
/**
|
|
6706
|
+
* Enter và Space kích hoạt dòng `interactive`, như một `<button>` thật.
|
|
6707
|
+
*
|
|
6708
|
+
* Dùng `(keydown)` trần rồi tự lọc phím, KHÔNG `(keydown.enter)`: hai
|
|
6709
|
+
* listener khác kiểu sự kiện trên cùng một thẻ thì Angular suy `$event` theo
|
|
6710
|
+
* cái đầu — `(click)` đứng trước nên `$event` thành `MouseEvent` và TS báo
|
|
6711
|
+
* lỗi ở dòng `keydown`.
|
|
6712
|
+
*
|
|
6713
|
+
* `preventDefault` cho Space, nếu không trang cuộn xuống một màn cùng lúc.
|
|
6714
|
+
*/
|
|
6715
|
+
protected onKeyActivate(event: KeyboardEvent): void;
|
|
6716
|
+
protected onClick(event: MouseEvent): void;
|
|
6717
|
+
protected readonly rootClasses: _angular_core.Signal<string>;
|
|
6718
|
+
protected readonly titleClasses: _angular_core.Signal<string>;
|
|
6719
|
+
protected readonly descriptionClasses: _angular_core.Signal<string>;
|
|
6720
|
+
/** Cỡ icon lối tắt, theo cỡ dòng. */
|
|
6721
|
+
protected readonly iconSize: _angular_core.Signal<number>;
|
|
6722
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<OlItem, never>;
|
|
6723
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<OlItem, "ol-item", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "interactive": { "alias": "interactive"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; }, { "itemClick": "itemClick"; }, never, ["[lead]", "*", "[actions]"], true, never>;
|
|
6724
|
+
}
|
|
6725
|
+
|
|
5588
6726
|
type OlBottomNavPosition = 'fixed' | 'relative';
|
|
5589
6727
|
declare class OlBottomNav {
|
|
5590
6728
|
readonly bordered: _angular_core.InputSignal<boolean>;
|
|
@@ -6423,6 +7561,24 @@ declare class OlFocusTrapService {
|
|
|
6423
7561
|
* @param autoFocus Tự động focus vào element đầu tiên (default: true)
|
|
6424
7562
|
*/
|
|
6425
7563
|
trap(element: HTMLElement, autoFocus?: boolean): void;
|
|
7564
|
+
/**
|
|
7565
|
+
* Chọn phần tử nhận focus khi overlay mở.
|
|
7566
|
+
*
|
|
7567
|
+
* Bản trước lấy phần tử focus được ĐẦU TIÊN theo thứ tự DOM. Header đứng
|
|
7568
|
+
* trước nội dung nên mở modal/drawer nào tiêu điểm cũng rơi vào nút ✕ —
|
|
7569
|
+
* người dùng phải Tab qua nút đóng mới tới ô nhập đầu tiên, và lỡ Enter là
|
|
7570
|
+
* đóng mất hộp thoại vừa mở (báo 2026-09-28).
|
|
7571
|
+
*
|
|
7572
|
+
* Thứ tự ưu tiên:
|
|
7573
|
+
* 1. phần tử nơi gọi đánh dấu `autofocus` / `data-autofocus` — trình duyệt
|
|
7574
|
+
* chỉ tôn trọng `autofocus` lúc tải trang, không phải lúc chèn hộp thoại,
|
|
7575
|
+
* nên service tự làm
|
|
7576
|
+
* 2. phần tử đầu tiên KHÔNG phải nút đóng (`[data-ol-dismiss]`) — thường là ô
|
|
7577
|
+
* nhập đầu tiên trong nội dung; nội dung không có gì bấm được thì tới nút
|
|
7578
|
+
* đầu tiên ở footer
|
|
7579
|
+
* 3. không còn gì khác mới về nút đóng, như cũ
|
|
7580
|
+
*/
|
|
7581
|
+
private initialFocusTarget;
|
|
6426
7582
|
/**
|
|
6427
7583
|
* Release focus trap và restore focus về element trước đó
|
|
6428
7584
|
*/
|
|
@@ -6458,6 +7614,15 @@ declare class OlFocusTrapService {
|
|
|
6458
7614
|
* Update danh sách focusable elements trong trap element
|
|
6459
7615
|
*/
|
|
6460
7616
|
private updateFocusableElements;
|
|
7617
|
+
/**
|
|
7618
|
+
* Phần tử có đang hiện không.
|
|
7619
|
+
*
|
|
7620
|
+
* KHÔNG dùng `offsetParent !== null`: nó trả `null` cho chính phần tử
|
|
7621
|
+
* `position: fixed` (nút nổi trong drawer/modal) dù phần tử hiện rõ, và luôn
|
|
7622
|
+
* `null` trong jsdom — nên mọi phần tử bị lọc mất, service không focus được
|
|
7623
|
+
* gì và spec không viết được.
|
|
7624
|
+
*/
|
|
7625
|
+
private isVisible;
|
|
6461
7626
|
/**
|
|
6462
7627
|
* Handle keyboard navigation trong trap
|
|
6463
7628
|
*/
|
|
@@ -6744,6 +7909,6 @@ declare class OlOverlayContainer {
|
|
|
6744
7909
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<any>;
|
|
6745
7910
|
}
|
|
6746
7911
|
|
|
6747
|
-
export { CHAT_BUBBLE_STATUS, FIELD_ASTERISK, FIELD_DISABLED, FIELD_HEIGHT, FIELD_HELPER, FIELD_HELPER_GAP, FIELD_LABEL, FIELD_LABEL_GAP, FIELD_MIN_HEIGHT, FIELD_PADDING_X, FIELD_RADIUS, FIELD_STATE, FIELD_TEXT, 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, fieldSizeClasses, formatDate, generateMonthMatrix, generateMonthsMatrix, generateYearsMatrix, isBetween, isDateDisabled, isSameDay, isSameMonth, isSameYear, isToday, parseDate, startOfDay, stripDiacritics };
|
|
6748
|
-
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, FieldSize, FieldState, 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, OverlayLayer, 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 };
|
|
7912
|
+
export { CHAT_BUBBLE_STATUS, FIELD_ASTERISK, FIELD_DISABLED, FIELD_HEIGHT, FIELD_HELPER, FIELD_HELPER_GAP, FIELD_LABEL, FIELD_LABEL_GAP, FIELD_MIN_HEIGHT, FIELD_PADDING_X, FIELD_RADIUS, FIELD_STATE, FIELD_TEXT, FILE_KIND_META, 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, OlFileDropzone, OlFileInput, OlFileItem, OlFileUpload, OlFloatingLabel, OlFocusTrapService, OlFooter, OlFrame, OlGallery, OlGalleryItem, OlHelper, OlIcon, OlIconService, OlIconShape, OlIconStack, OlImagePreview, OlInput, OlInputCounter, OlItem, OlJumbotron, OlKbd, OlLabel, OlListGroup, OlListGroupItem, OlLoadingOverlay, OlMenubar, OlModal, OlModalFooter, OlModalHeader, OlMonthView, OlNavDropdown, OlNavbar, OlNavbarItem, OlOtpInput, OlOverlayContainer, OlPagination, OlPopover, OlPopoverContent, OlPositioningService, OlProgress, OlProgressBarService, OlProgressBarTop, OlRadio, OlRange, OlRating, OlResizable, OlRichTextEditor, OlScrollArea, OlScrollspy, OlSegmented, 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, detectFileKind, endOfDay, fieldSizeClasses, fileExtension, filesFromClipboard, formatDate, formatFileSize, generateMonthMatrix, generateMonthsMatrix, generateYearsMatrix, isBetween, isDateDisabled, isEditableTarget, isSameDay, isSameMonth, isSameYear, isToday, matchesAccept, parseDate, pasteShortcutLabel, startOfDay, stripDiacritics, toUploadFile, validateFiles };
|
|
7913
|
+
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, FieldSize, FieldState, FileInputSize, FileItemVariant, FileKind, FileKindMeta, FileRejectReason, FileRejection, FileUploadMode, FileValidationResult, FileValidationRules, 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, OlFrameRounded, OlFrameSpacing, OlFrameVariant, OlGalleryGap, OlGalleryRatio, OlHelperType, OlIconStackSize, OlItemAlign, OlItemSize, OlMenubarItem, OlMenubarMenu, OlModalBackdrop, OlModalRole, OlPreviewImage, OlResizableDirection, OlScrollspyItem, OlScrollspyOrientation, OlSkeletonAnimation, OlSkeletonAspectRatio, OlSkeletonRounded, OlSkeletonType, OlSpeedDialTooltipPosition, OlTimepickerAddonType, OlToggleInputAlign, OlTreeNode, OlTreeNodeSelectionMode, OlTreeNodeToggleIcon, OlTreeSelectionMode, OlTreeToggleIcon, OlUploadFile, OtpInputSize, OverlayLayer, PaginationType, PaginationVariant, PopoverPlacement, PopoverTrigger, PositionedCoordinates, PositioningOptions, ProgressColor, ProgressLabelPosition, ProgressSize, RadarIndicator, RadioSize, RatingType, ScatterDataPoint, ScatterSeries, ScrollAreaAxis, ScrollAreaScrollbar, SegmentedOption, SegmentedSize, 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, UploadStatus, YearCell };
|
|
6749
7914
|
//# sourceMappingURL=edmicro-olkit.d.ts.map
|