@openway/ui 1.0.0 → 1.0.2

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.
Files changed (58) hide show
  1. package/README.md +203 -181
  2. package/dist/chunk-X4LIYOS5.js +3 -0
  3. package/dist/chunk-X4LIYOS5.js.map +1 -0
  4. package/dist/index.cjs +5 -1
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.d.cts +2740 -1473
  7. package/dist/index.d.ts +2740 -1473
  8. package/dist/index.js +5 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/query.cjs +3 -0
  11. package/dist/query.cjs.map +1 -0
  12. package/dist/query.d.cts +431 -0
  13. package/dist/query.d.ts +431 -0
  14. package/dist/query.js +3 -0
  15. package/dist/query.js.map +1 -0
  16. package/dist/useInfiniteScroll-D9AW6cQV.d.cts +598 -0
  17. package/dist/useInfiniteScroll-D9AW6cQV.d.ts +598 -0
  18. package/docs/AGENTS.md +144 -0
  19. package/docs/README.md +150 -0
  20. package/docs/SKILL.md +54 -0
  21. package/docs/components/alert.md +246 -0
  22. package/docs/components/badge.md +238 -0
  23. package/docs/components/button.md +262 -0
  24. package/docs/components/carousel.md +354 -0
  25. package/docs/components/checkbox.md +252 -0
  26. package/docs/components/collapse.md +318 -0
  27. package/docs/components/confirm.md +322 -0
  28. package/docs/components/datepicker.md +259 -0
  29. package/docs/components/daterangepicker.md +260 -0
  30. package/docs/components/datetimepicker.md +226 -0
  31. package/docs/components/datetimerangepicker.md +222 -0
  32. package/docs/components/dropdown.md +275 -0
  33. package/docs/components/empty.md +200 -0
  34. package/docs/components/file-preview.md +180 -0
  35. package/docs/components/input.md +559 -0
  36. package/docs/components/modal.md +293 -0
  37. package/docs/components/popover.md +255 -0
  38. package/docs/components/radio.md +245 -0
  39. package/docs/components/select.md +254 -0
  40. package/docs/components/skeleton.md +150 -0
  41. package/docs/components/slider.md +346 -0
  42. package/docs/components/table.md +316 -0
  43. package/docs/components/tabs.md +432 -0
  44. package/docs/components/textarea.md +193 -0
  45. package/docs/components/timepicker.md +242 -0
  46. package/docs/components/timerangepicker.md +210 -0
  47. package/docs/components/toast.md +282 -0
  48. package/docs/components/toggle.md +211 -0
  49. package/docs/components/tooltip.md +213 -0
  50. package/docs/components/upload-avatar.md +318 -0
  51. package/docs/components/upload-file.md +245 -0
  52. package/docs/components/upload-image.md +126 -0
  53. package/docs/hooks/useDebounce.md +92 -0
  54. package/docs/hooks/useInfiniteScroll.md +95 -0
  55. package/docs/hooks/useMutationApp.md +242 -0
  56. package/docs/hooks/useSelectInfiniteQuery.md +123 -0
  57. package/docs/hooks/useTableQuery.md +124 -0
  58. package/package.json +31 -12
package/docs/AGENTS.md ADDED
@@ -0,0 +1,144 @@
1
+ # 🎨 OpenWay Design System — Antigravity Guide (`@openway/ui`)
2
+
3
+ Tài liệu hướng dẫn chuyên sâu dành riêng cho **Antigravity AI Agent** khi làm việc với thư viện component `@openway/ui`.
4
+
5
+ ---
6
+
7
+ ## ⚡ Chỉ dẫn cấu hình cho Dự án con (Consumer Projects)
8
+
9
+ Khi cài đặt `@openway/ui` vào dự án bất kỳ, thêm đoạn sau vào file `AGENTS.md` ở thư mục gốc của dự án để Antigravity tự động kích hoạt kiến thức Design System:
10
+
11
+ ```markdown
12
+ <!-- openway-ui:start -->
13
+ # OpenWay UI Components Guideline
14
+ Khi tạo mới, sửa đổi hoặc sử dụng các component UI trong dự án:
15
+ - **LUÔN LUÔN** ưu tiên sử dụng các component từ `@openway/ui` thay vì tự viết HTML thẻ trần hoặc cài thư viện ngoài.
16
+ - Đọc chi tiết danh mục và tài liệu API tại: `node_modules/@openway/ui/docs/AGENTS.md`.
17
+ - Tra cứu từng component cụ thể tại: `node_modules/@openway/ui/docs/components/<component-name>.md`.
18
+ - Với phân trang server / infinite scroll cho Select: Dùng `useSelectInfiniteQuery` từ `@openway/ui/query`.
19
+ - Tuân thủ nghiêm ngặt chuẩn TypeScript **Zero `any`** và token màu **Tailwind CSS v4**.
20
+ <!-- openway-ui:end -->
21
+ ```
22
+
23
+ ---
24
+
25
+ ## 📦 Quy tắc Import Chuẩn
26
+
27
+ ```tsx
28
+ // 1. Tất cả 32 UI Components, Icons, và Core Hooks dùng chung
29
+ import {
30
+ Button,
31
+ IconButton,
32
+ Input,
33
+ Textarea,
34
+ Select,
35
+ MultiSelect,
36
+ Checkbox,
37
+ CheckboxGroup,
38
+ Radio,
39
+ RadioGroup,
40
+ Toggle,
41
+ Slider,
42
+ Table,
43
+ Modal,
44
+ Confirm,
45
+ Dropdown,
46
+ Popover,
47
+ Tooltip,
48
+ Alert,
49
+ Badge,
50
+ Skeleton,
51
+ Toast,
52
+ Tabs,
53
+ Collapse,
54
+ Empty,
55
+ DatePicker,
56
+ DateRangePicker,
57
+ TimePicker,
58
+ TimeRangePicker,
59
+ DateTimePicker,
60
+ DateTimeRangePicker,
61
+ UploadFile,
62
+ UploadAvatar,
63
+ UploadImage,
64
+ FilePreview,
65
+ Carousel,
66
+ useInfiniteScroll,
67
+ useDebounce,
68
+ useDebouncedCallback,
69
+ } from "@openway/ui";
70
+
71
+ // 2. Query Hooks chuyên dụng cho TanStack Query v5 (phân trang server, infinite scroll)
72
+ import { useSelectInfiniteQuery } from "@openway/ui/query";
73
+ ```
74
+
75
+ ---
76
+
77
+ ## 🧭 Danh mục 32 Components & Tài liệu Chi tiết
78
+
79
+ Tất cả tài liệu chi tiết của từng component được lưu trữ tại `node_modules/@openway/ui/docs/components/<name>.md`:
80
+
81
+ | Phân nhóm | Component | File Tài liệu | Mục đích sử dụng |
82
+ | :--- | :--- | :--- | :--- |
83
+ | **Buttons & Actions** | `<Button>`, `<IconButton>` | [`button.md`](./components/button.md) | Nút bấm chính/phụ, nút icon tròn/vuông, 6 variants, loading spinner. |
84
+ | **Form Inputs** | `<Input>` | [`input.md`](./components/input.md) | Nhập văn bản, số, password với mắt ẩn/hiện, start/end content. |
85
+ | | `<Textarea>` | [`textarea.md`](./components/textarea.md) | Nhập văn bản nhiều dòng, tự động co giãn độ cao theo nội dung. |
86
+ | | `<Select>`, `<MultiSelect>` | [`select.md`](./components/select.md) | Chọn đơn/nhiều, tìm kiếm client/server, menu filters, skeleton infinite scroll. |
87
+ | | `<Checkbox>`, `<CheckboxGroup>` | [`checkbox.md`](./components/checkbox.md) | Chọn nhiều giá trị, trạng thái indeterminate, bố cục ngang/dọc. |
88
+ | | `<Radio>`, `<RadioGroup>` | [`radio.md`](./components/radio.md) | Chọn 1 trong danh sách phương án, hỗ trợ custom card option. |
89
+ | | `<Toggle>` | [`toggle.md`](./components/toggle.md) | Công tắc bật/tắt (Switch), hỗ trợ icon và nhãn mô tả. |
90
+ | | `<Slider>` | [`slider.md`](./components/slider.md) | Thanh trượt chọn giá trị số hoặc dải giá trị (Radix Slider). |
91
+ | **Data Display** | `<Table>` | [`table.md`](./components/table.md) | Bảng dữ liệu TanStack Table v9, sort, filter, pagination, row selection, resize cột. |
92
+ | | `<Badge>` | [`badge.md`](./components/badge.md) | Huy hiệu số lượng, chấm trạng thái (dot), gắn góc avatar/nút. |
93
+ | | `<Empty>` | [`empty.md`](./components/empty.md) | Màn hình thông báo không có dữ liệu, minh họa trực quan kèm nút CTA. |
94
+ | | `<Carousel>` | [`carousel.md`](./components/carousel.md) | Trình chiếu slide ảnh/nội dung, điều hướng nút bấm & dot. |
95
+ | | `<Collapse>` | [`collapse.md`](./components/collapse.md) | Danh sách xếp gọn (Accordion), mở đơn lẻ hoặc mở đồng thời nhiều mục. |
96
+ | **Feedback & Status** | `<Alert>` | [`alert.md`](./components/alert.md) | Banner cảnh báo inline: success, error, warning, info, có nút đóng. |
97
+ | | `<Skeleton>` | [`skeleton.md`](./components/skeleton.md) | Khung placeholder nhấp nháy mô phỏng layout đang tải dữ liệu. |
98
+ | | `<Toast>` | [`toast.md`](./components/toast.md) | Thông báo góc màn hình nổi (dựa trên Sonner), hỗ trợ promise toast. |
99
+ | **Navigation** | `<Tabs>` | [`tabs.md`](./components/tabs.md) | Chuyển đổi tab nội dung với thanh chỉ thị hoạt họa mượt mà. |
100
+ | | `<Dropdown>` | [`dropdown.md`](./components/dropdown.md) | Menu thả xuống cho các thao tác phụ (hành động người dùng, menu bảng). |
101
+ | **Overlays & Dialogs** | `<Modal>` | [`modal.md`](./components/modal.md) | Hộp thoại modal, khóa scroll body, hỗ trợ animation mở/đóng. |
102
+ | | `<Confirm>` | [`confirm.md`](./components/confirm.md) | Hộp thoại xác nhận hành động nguy hiểm (Xóa, Hủy) kèm trạng thái loading. |
103
+ | | `<Popover>` | [`popover.md`](./components/popover.md) | Khung thông tin phụ nổi theo phần tử neo (Floating UI). |
104
+ | | `<Tooltip>` | [`tooltip.md`](./components/tooltip.md) | Gợi ý văn bản ngắn khi hover/focus vào nút hoặc icon. |
105
+ | **Date & Time Pickers** | `<DatePicker>`, `<DateRangePicker>` | [`datepicker.md`](./components/datepicker.md), [`daterangepicker.md`](./components/daterangepicker.md) | Chọn ngày, chọn khoảng ngày với preset tiện ích (Hôm nay, Tuần này). |
106
+ | | `<TimePicker>`, `<TimeRangePicker>` | [`timepicker.md`](./components/timepicker.md), [`timerangepicker.md`](./components/timerangepicker.md) | Chọn giờ phút giây dạng cột cuộn trực quan. |
107
+ | | `<DateTimePicker>`, `<DateTimeRangePicker>` | [`datetimepicker.md`](./components/datetimepicker.md), [`datetimerangepicker.md`](./components/datetimerangepicker.md) | Chọn kết hợp cả ngày và giờ trong cùng một popup. |
108
+ | **File & Media** | `<UploadFile>` | [`upload-file.md`](./components/upload-file.md) | Tải tệp tin đa định dạng (PDF, DOCX, ZIP...), thanh tiến trình, drag & drop. |
109
+ | | `<UploadAvatar>` | [`upload-avatar.md`](./components/upload-avatar.md) | Tải và xem trước ảnh đại diện người dùng dạng hình tròn. |
110
+ | | `<UploadImage>` | [`upload-image.md`](./components/upload-image.md) | Tải nhiều ảnh dạng Dropzone hoặc Picture Wall, tích hợp modal Crop ảnh. |
111
+ | | `<FilePreview>` | [`file-preview.md`](./components/file-preview.md) | Xem trước nội dung tệp tin, hình ảnh, tài liệu trực tiếp trên giao diện. |
112
+
113
+ ---
114
+
115
+ ## 🪝 Utility & Query Hooks
116
+
117
+ - **[`useInfiniteScroll`](./hooks/useInfiniteScroll.md)**: Tải dữ liệu vô tận thuần React 19 qua `IntersectionObserver`, tự động kích hoạt `onLoadMore` khi sentinel vào viewport.
118
+ - **[`useDebounce` & `useDebouncedCallback`](./hooks/useDebounce.md)**: Bộ đôi hoãn cập nhật giá trị hoặc hàm callback theo mili-giây, chống spam request.
119
+ - **[`useTableQuery`](./hooks/useTableQuery.md)** (`@openway/ui/query`): Adapter kết nối TanStack Query v5 với `<Table />`, hỗ trợ phân trang máy chủ, multi-column sorting, column filtering và `keepPreviousData`.
120
+ - **[`useSelectInfiniteQuery`](./hooks/useSelectInfiniteQuery.md)** (`@openway/ui/query`): Adapter kết nối TanStack Query v5 với `<Select />` và `<MultiSelect />`, tự động cuộn tải trang, debounce từ khóa và Skeleton loading.
121
+
122
+ ---
123
+
124
+ ## 🎨 Quy chuẩn Design Tokens & Styling
125
+
126
+ 1. **Bảng màu Tailwind CSS v4 Theme-Agnostic**:
127
+ - Component không cố định mã màu HEX mà sử dụng các biến theme:
128
+ `primary`, `secondary`, `neutral`, `error`, `success`, `warning`, `info`.
129
+ - Các mức sắc độ: `50`, `100`, `200`, `300`, `400`, `500` (màu chính), `600` (hover), `700` (focus ring), `800`, `900`, `950`.
130
+ 2. **Kích thước (`size`)**:
131
+ - `xs` (24px), `sm` (32px), `md` (40px - chuẩn cho form input/nút), `lg` (48px), `xl` (56px).
132
+ 3. **Bo góc (`radius`)**:
133
+ - `none` (0px), `sm` (4px), `md` (6px), `lg` (8px - chuẩn mặc định), `xl` (12px), `full` (tròn).
134
+ 4. **Hỗ trợ chế độ Tối (Dark Mode)**:
135
+ - Tất cả component tự động thích ứng qua class Tailwind `dark:`.
136
+
137
+ ---
138
+
139
+ ## 🚨 Nguyên tắc cốt lõi cho AI Agent khi code
140
+
141
+ 1. **KHÔNG tự chế component trần**: Khi cần nút, ô nhập, bảng, modal, dialog, picker -> Luôn import component tương ứng từ `@openway/ui`.
142
+ 2. **KHÔNG dùng `any`**: Sử dụng chính xác Generic Types exported từ thư viện (ví dụ `SelectOptionItem<TData>`, `ColumnDef<TData>`).
143
+ 3. **Tránh Double Debounce**: Khi dùng `useSelectInfiniteQuery`, `<Select>` đã tự động debounce từ khóa theo `debounceMs` rồi mới truyền vào `onSearch`.
144
+ 4. **Trợ năng WAI-ARIA**: Khi dùng `<IconButton>`, bắt buộc phải truyền `aria-label` để màn hình đọc hỗ trợ người khiếm thị.
package/docs/README.md ADDED
@@ -0,0 +1,150 @@
1
+ # 📚 OpenWay UI — Thư viện Tài liệu Toàn diện (`@openway/ui`)
2
+
3
+ Chào mừng bạn đến với trung tâm tài liệu chính thức của **OpenWay UI Design System**. Thư mục này được đóng gói sẵn trong package `node_modules/@openway/ui/docs/` để lập trình viên và các **AI Assistant (Antigravity)** có thể tra cứu và sử dụng nhanh chóng, chuẩn xác.
4
+
5
+ ---
6
+
7
+ ## 🚀 Mục lục Nhanh
8
+
9
+ - [1. Hướng dẫn Tích hợp Antigravity AI](#1-hướng-dẫn-tích-hợp-antigravity-ai)
10
+ - [2. Cài đặt & Cấu hình Theme Tailwind CSS](#2-cài-đặt--cấu-hình-theme-tailwind-css)
11
+ - [3. Danh mục 32 Components](#3-danh-mục-32-components)
12
+ - [4. Danh mục Hooks (`@openway/ui` & `@openway/ui/query`)](#4-danh-mục-hooks)
13
+ - [5. Quy chuẩn Thiết kế (Design Tokens)](#5-quy-chuẩn-thiết-kế-design-tokens)
14
+
15
+ ---
16
+
17
+ ## 1. Hướng dẫn Tích hợp Antigravity AI
18
+
19
+ Thư viện được tối ưu hóa đặc biệt cho **Antigravity AI Agent**. Bạn có thể tận dụng ngay 2 tài liệu cốt lõi:
20
+
21
+ - **[`AGENTS.md`](./AGENTS.md)**: Bản chỉ dẫn hành vi, sitemap, quy tắc import và checklist cho Antigravity.
22
+ - **[`SKILL.md`](./SKILL.md)**: Antigravity Skill định dạng chuẩn (`openway-ui`), cho phép Antigravity tự động kích hoạt on-demand khi tạo mới hoặc sửa đổi UI.
23
+
24
+ ### Cấu hình cho Dự án con (Consumer Project):
25
+ Thêm khối chỉ dẫn sau vào file `AGENTS.md` ở thư mục gốc dự án của bạn:
26
+
27
+ ```markdown
28
+ <!-- openway-ui:start -->
29
+ # OpenWay UI Components
30
+ Khi viết giao diện hoặc tạo/sửa component:
31
+ 1. Luôn ưu tiên dùng component có sẵn từ `@openway/ui`.
32
+ 2. Tham khảo tài liệu và ví dụ code mẫu tại: `node_modules/@openway/ui/docs/AGENTS.md`.
33
+ 3. Tra cứu từng component cụ thể tại: `node_modules/@openway/ui/docs/components/<component>.md`.
34
+ 4. Với phân trang server / infinite scroll: dùng hook từ `@openway/ui/query`.
35
+ 5. Tuyệt đối tuân thủ Zero `any` và token màu Tailwind CSS v4.
36
+ <!-- openway-ui:end -->
37
+ ```
38
+
39
+ ---
40
+
41
+ ## 2. Cài đặt & Cấu hình Theme Tailwind CSS
42
+
43
+ ### Cài đặt Package
44
+
45
+ ```bash
46
+ pnpm add @openway/ui
47
+ # hoặc
48
+ npm install @openway/ui
49
+ ```
50
+
51
+ ### Cấu hình Bảng màu trong `app/globals.css` (Tailwind CSS v4)
52
+
53
+ Thư viện theo triết lý **Theme-Agnostic** (không cố định màu HEX, dự án tự định nghĩa màu):
54
+
55
+ ```css
56
+ @import "tailwindcss";
57
+
58
+ /* 1. Quét các class của thư viện */
59
+ @source "../node_modules/@openway/ui";
60
+
61
+ /* 2. Cung cấp bảng màu thương hiệu của bạn */
62
+ @theme {
63
+ --color-primary-500: #0284c7; /* Màu chính của nút, checkbox active... */
64
+ --color-primary-600: #0369a1; /* Màu khi hover, active... */
65
+ --color-primary-700: #075985; /* Màu focus ring */
66
+
67
+ --color-secondary-500: #a855f7;
68
+ --color-secondary-600: #9333ea;
69
+
70
+ --color-error-500: #ef4444;
71
+ --color-warning-500: #f59e0b;
72
+ --color-success-500: #10b981;
73
+ --color-info-500: #3b82f6;
74
+ }
75
+ ```
76
+
77
+ ---
78
+
79
+ ## 3. Danh mục 32 Components
80
+
81
+ Tất cả tài liệu chi tiết của từng component được lưu trữ tại thư mục [`components/`](./components/):
82
+
83
+ ### Buttons & Actions
84
+ - **[`button.md`](./components/button.md)**: Nút bấm `<Button>` và nút icon `<IconButton>`, 5 kích cỡ, 6 biến thể (`filled`, `soft`, `outline`, `ghost`, `text`, `other`), loading spinner.
85
+
86
+ ### Form Inputs & Controls
87
+ - **[`input.md`](./components/input.md)**: Trường nhập văn bản `<Input>`, hiển thị mật khẩu ẩn/hiện, start/end content.
88
+ - **[`textarea.md`](./components/textarea.md)**: Vùng văn bản nhiều dòng `<Textarea>`, tự động co giãn độ cao (`autosize`).
89
+ - **[`select.md`](./components/select.md)**: Chọn đơn `<Select>` và chọn nhiều `<MultiSelect>`, tìm kiếm client/server, menu filters, skeleton infinite scroll.
90
+ - **[`checkbox.md`](./components/checkbox.md)**: Hộp kiểm `<Checkbox>` và nhóm `<CheckboxGroup>`, trạng thái indeterminate, bố cục flex.
91
+ - **[`radio.md`](./components/radio.md)**: Nút chọn 1 phương án `<Radio>` và nhóm `<RadioGroup>`, hỗ trợ giao diện dạng thẻ card.
92
+ - **[`toggle.md`](./components/toggle.md)**: Công tắc gạt `<Toggle>` (Switch), hỗ trợ icon bật/tắt và nhãn mô tả.
93
+ - **[`slider.md`](./components/slider.md)**: Thanh trượt `<Slider>` chọn số hoặc dải giá trị (Radix UI Slider).
94
+
95
+ ### Data Display
96
+ - **[`table.md`](./components/table.md)**: Bảng dữ liệu mạnh mẽ `<Table>` (TanStack Table v9), sắp xếp, lọc cột, phân trang, resize cột.
97
+ - **[`badge.md`](./components/badge.md)**: Huy hiệu `<Badge>` đếm số, chấm trạng thái (dot), gắn góc avatar/nút.
98
+ - **[`empty.md`](./components/empty.md)**: Màn hình trống `<Empty>` hiển thị khi không có dữ liệu kèm nút hành động CTA.
99
+ - **[`carousel.md`](./components/carousel.md)**: Trình chiếu slide `<Carousel>`, điều hướng nút bấm, autoplay, pagination dots.
100
+ - **[`collapse.md`](./components/collapse.md)**: Khối thu gọn `<Collapse>` (Accordion), hỗ trợ mở đơn mục hoặc đa mục.
101
+
102
+ ### Feedback & Status
103
+ - **[`alert.md`](./components/alert.md)**: Khung cảnh báo inline `<Alert>` (success, error, warning, info), nút đóng dismiss.
104
+ - **[`skeleton.md`](./components/skeleton.md)**: Khung placeholder nhấp nháy `<Skeleton>` giả lập layout đang tải.
105
+ - **[`toast.md`](./components/toast.md)**: Thông báo góc màn hình `<Toast>` (Sonner), hỗ trợ promise toast.
106
+
107
+ ### Navigation & Overlays
108
+ - **[`tabs.md`](./components/tabs.md)**: Chuyển đổi thẻ `<Tabs>`, thanh chỉ thị hoạt họa mượt mà.
109
+ - **[`dropdown.md`](./components/dropdown.md)**: Menu thả xuống `<Dropdown>` cho các thao tác phụ.
110
+ - **[`modal.md`](./components/modal.md)**: Hộp thoại `<Modal>`, khóa cuộn màn hình, hiệu ứng animation.
111
+ - **[`confirm.md`](./components/confirm.md)**: Hộp thoại xác nhận nguy hiểm `<Confirm>` (Xóa, Hủy) kèm loading state.
112
+ - **[`popover.md`](./components/popover.md)**: Khung nổi `<Popover>` neo theo phần tử (Floating UI).
113
+ - **[`tooltip.md`](./components/tooltip.md)**: Chú thích nhanh `<Tooltip>` khi hover/focus.
114
+
115
+ ### Date & Time Pickers
116
+ - **[`datepicker.md`](./components/datepicker.md)**: Bộ chọn ngày `<DatePicker>`, hỗ trợ các preset (Hôm nay, Hôm qua).
117
+ - **[`daterangepicker.md`](./components/daterangepicker.md)**: Bộ chọn khoảng ngày `<DateRangePicker>`.
118
+ - **[`timepicker.md`](./components/timepicker.md)**: Bộ chọn giờ phút giây `<TimePicker>` cột cuộn trực quan.
119
+ - **[`timerangepicker.md`](./components/timerangepicker.md)**: Bộ chọn khoảng thời gian `<TimeRangePicker>`.
120
+ - **[`datetimepicker.md`](./components/datetimepicker.md)**: Bộ chọn ngày và giờ kết hợp `<DateTimePicker>`.
121
+ - **[`datetimerangepicker.md`](./components/datetimerangepicker.md)**: Bộ chọn khoảng ngày và giờ `<DateTimeRangePicker>`.
122
+
123
+ ### File & Media Upload
124
+ - **[`upload-file.md`](./components/upload-file.md)**: Tải tệp tin đa năng `<UploadFile>`, thanh tiến trình, kéo thả.
125
+ - **[`upload-avatar.md`](./components/upload-avatar.md)**: Tải ảnh đại diện `<UploadAvatar>` hình tròn kèm xem trước.
126
+ - **[`upload-image.md`](./components/upload-image.md)**: Tải nhiều ảnh `<UploadImage>` (Dropzone / Picture Wall), tích hợp modal crop ảnh.
127
+ - **[`file-preview.md`](./components/file-preview.md)**: Xem trước tệp tin `<FilePreview>` (ảnh, tài liệu, video).
128
+
129
+ ---
130
+
131
+ ## 4. Danh mục Hooks
132
+
133
+ Tài liệu chi tiết của các hooks được lưu trữ tại thư mục [`hooks/`](./hooks/):
134
+
135
+ ### Core Hooks (`@openway/ui`)
136
+ - **[`useInfiniteScroll`](./hooks/useInfiniteScroll.md)**: Cơ chế tải vô tận thuần React 19 qua native `IntersectionObserver`, zero scroll event listener, an toàn với mutex lock.
137
+ - **[`useDebounce` & `useDebouncedCallback`](./hooks/useDebounce.md)**: Tối ưu hiệu năng, chống spam API cho giá trị tìm kiếm hoặc hàm callback.
138
+
139
+ ### TanStack Query v5 Adapters (`@openway/ui/query`)
140
+ - **[`useTableQuery`](./hooks/useTableQuery.md)**: Kết nối TanStack Query v5 với `<Table />`, quản lý phân trang, sorting, column filtering và `keepPreviousData`.
141
+ - **[`useSelectInfiniteQuery`](./hooks/useSelectInfiniteQuery.md)**: Kết nối TanStack Query v5 với `<Select />` và `<MultiSelect />`, tự động cuộn tải trang tiếp, debounce từ khóa và Skeleton loading.
142
+
143
+ ---
144
+
145
+ ## 5. Quy chuẩn Thiết kế (Design Tokens)
146
+
147
+ 1. **Zero `any`**: 100% các component và hook đều được khai báo TypeScript chặt chẽ, type-safe.
148
+ 2. **5 Kích thước Chuẩn (`size`)**: `xs` (24px), `sm` (32px), `md` (40px - chuẩn form), `lg` (48px), `xl` (56px).
149
+ 3. **Độ Bo Góc Chuẩn (`radius`)**: `none` (0px), `sm` (4px), `md` (6px), `lg` (8px - chuẩn mặc định), `xl` (12px), `full` (tròn).
150
+ 4. **Dark Mode**: Toàn bộ component hỗ trợ tự động thích ứng qua selector `dark:`.
package/docs/SKILL.md ADDED
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: openway-ui
3
+ description: Comprehensive guide and API reference for the OpenWay UI Design System (@openway/ui). Use this skill whenever generating, modifying, or refactoring UI components, forms, tables, modals, pickers, or infinite scroll queries.
4
+ ---
5
+
6
+ # OpenWay UI Design System Skill
7
+
8
+ This skill teaches the Antigravity agent how to leverage the `@openway/ui` component library effectively when building user interfaces.
9
+
10
+ ## Quick Lookup by Functional Need
11
+
12
+ When the user asks for:
13
+ - **Button, action trigger**: Use `<Button>` or `<IconButton>` ([docs/components/button.md](./components/button.md)).
14
+ - **Text, number input**: Use `<Input>` ([docs/components/input.md](./components/input.md)).
15
+ - **Long text input**: Use `<Textarea>` ([docs/components/textarea.md](./components/textarea.md)).
16
+ - **Dropdown single/multi select**: Use `<Select>` or `<MultiSelect>` ([docs/components/select.md](./components/select.md)).
17
+ - **Server pagination / Infinite scroll dropdown**: Use `<Select>` with `useSelectInfiniteQuery` from `@openway/ui/query` ([docs/components/select.md](./components/select.md)).
18
+ - **Checkboxes**: Use `<Checkbox>` or `<CheckboxGroup>` ([docs/components/checkbox.md](./components/checkbox.md)).
19
+ - **Radio options**: Use `<Radio>` or `<RadioGroup>` ([docs/components/radio.md](./components/radio.md)).
20
+ - **Switch / Toggle**: Use `<Toggle>` ([docs/components/toggle.md](./components/toggle.md)).
21
+ - **Data Table**: Use `<Table>` ([docs/components/table.md](./components/table.md)).
22
+ - **Modal / Popup dialog**: Use `<Modal>` or `<Confirm>` ([docs/components/modal.md](./components/modal.md), [docs/components/confirm.md](./components/confirm.md)).
23
+ - **Tooltip**: Use `<Tooltip>` ([docs/components/tooltip.md](./components/tooltip.md)).
24
+ - **Inline Alert / Notification**: Use `<Alert>` ([docs/components/alert.md](./components/alert.md)).
25
+ - **Floating Toast**: Use `toast` ([docs/components/toast.md](./components/toast.md)).
26
+ - **Date/Time Picker**: Use `<DatePicker>`, `<DateRangePicker>`, `<TimePicker>`, or `<DateTimePicker>` ([docs/components/datepicker.md](./components/datepicker.md)).
27
+ - **File / Image Upload**: Use `<UploadFile>`, `<UploadAvatar>`, or `<UploadImage>` ([docs/components/upload-image.md](./components/upload-image.md)).
28
+ - **Infinite scroll list**: Use `useInfiniteScroll` from `@openway/ui` ([docs/hooks/useInfiniteScroll.md](./hooks/useInfiniteScroll.md)).
29
+ - **Server-side Table Query**: Use `useTableQuery` from `@openway/ui/query` ([docs/hooks/useTableQuery.md](./hooks/useTableQuery.md)).
30
+ - **Server-side Select Infinite Query**: Use `useSelectInfiniteQuery` from `@openway/ui/query` ([docs/hooks/useSelectInfiniteQuery.md](./hooks/useSelectInfiniteQuery.md)).
31
+ - **Debounce Value / Callback**: Use `useDebounce` or `useDebouncedCallback` ([docs/hooks/useDebounce.md](./hooks/useDebounce.md)).
32
+
33
+ ## Code Generation Guidelines
34
+
35
+ 1. **Imports**:
36
+ ```tsx
37
+ import { Button, Input, Select, Table, Modal } from "@openway/ui";
38
+ // For TanStack Query server integration:
39
+ import { useSelectInfiniteQuery } from "@openway/ui/query";
40
+ ```
41
+ 2. **Zero `any`**:
42
+ Always type props, states, and option entities strictly:
43
+ ```tsx
44
+ interface Department {
45
+ id: string;
46
+ name: string;
47
+ }
48
+ const options: SelectOptionItem<Department>[] = ...;
49
+ ```
50
+ 3. **Accessibility (WAI-ARIA)**:
51
+ Always supply `aria-label` when using `<IconButton>`.
52
+ Always associate labels with inputs using `label` prop.
53
+ 4. **Tailwind CSS v4 Tokens**:
54
+ Rely on theme tokens (`primary`, `secondary`, `neutral`, `error`, `success`, `warning`, `info`) rather than raw hex codes (`#123456`).
@@ -0,0 +1,246 @@
1
+ # 📢 Alert Component (`@owa/ui`)
2
+
3
+ Component **Alert** hiển thị thông báo, cảnh báo theo ngữ cảnh (Inline Alert / Banner) với hiệu năng cao, thiết kế chuẩn **Design System**, **Pure Stateless Component** (0 dependencies) và hỗ trợ đầy đủ **WAI-ARIA Accessibility**.
4
+
5
+ ---
6
+
7
+ ## 🌟 Điểm nổi bật
8
+
9
+ - **Pure Stateless Component**: Hoàn toàn không phụ thuộc vào global store (Zustand/Redux). Render trực tiếp tại bất kỳ vị trí nào trong cây JSX.
10
+ - **Tự động đóng thông minh (`closable`)**: Mặc định `closable={true}`, khi bấm nút `(X)` Alert sẽ **tự động đóng/ẩn ngay lập tức** mà không bắt buộc phải viết hàm `onClose`. Nếu có truyền callback `onClose`, Alert sẽ tự động kích hoạt callback này.
11
+ - **Hỗ trợ linh hoạt cả `description` & `children`**: Cho phép truyền nội dung mô tả qua prop `description` (chuỗi text hoặc JSX ngắn) hoặc bọc qua `children` (JSX phức tạp).
12
+ - **5 Kích thước tiêu chuẩn (`size`)**: `xs`, `sm`, `md` *(mặc định)*, `lg`, `xl` với typography và spacing được căn chỉnh chính xác.
13
+ - **6 Biến thể giao diện (`variant`)**:
14
+ - `soft` *(mặc định)*: Nền pastel nhạt, viền mờ 2px tinh tế.
15
+ - `filled`: Nền màu đậm, chữ trắng tương phản cao.
16
+ - `outline`: Nền trắng, viền rõ nét theo màu chủ đề.
17
+ - `accent-left`: Nền pastel kèm viền nhấn bên trái dày 4px (`border-l-4`).
18
+ - `ghost`: Nền và viền trong suốt.
19
+ - `other`: Bỏ qua các class màu mặc định, tự do tùy biến màu sắc qua `className`.
20
+ - **7 Chủ đề màu sắc (`color`)**: `primary`, `secondary`, `neutral`, `error`, `success`, `warning`, `info` *(mặc định)*.
21
+ - **Tùy chỉnh bo góc (`radius`)**: `none`, `sm`, `md`, `lg` *(mặc định)*, `xl`, `full`.
22
+ - **Chế độ Banner (`banner`)**: Chiều rộng 100% (`w-full`), góc vuông phẳng (`rounded-none`), không viền 2 bên (`border-x-0`), thích hợp gắn cố định trên đầu trang.
23
+ - **Hỗ trợ Icon thông minh (`icon`)**:
24
+ - Tự động hiển thị icon SVG chuẩn theo `color` (`CheckCircleIcon`, `AlertTriangleIcon`, `AlertCircleIcon`, `InfoCircleIcon`).
25
+ - Tắt icon dễ dàng với `icon={false}`.
26
+ - Hỗ trợ truyền custom icon dạng JSX (`ReactNode`).
27
+ - **Action Slot (`action`)**: Vùng chuyên biệt để chèn nút bấm, liên kết thao tác nhanh.
28
+ - **Chuẩn Accessibility (A11y)**:
29
+ - Tự động thiết lập `role="alert"` và `aria-live="assertive"` cho các trạng thái nguy cấp (`error`, `warning`).
30
+ - Thiết lập `role="status"` và `aria-live="polite"` cho các trạng thái thông thường (`info`, `success`, `primary`, `secondary`, `neutral`).
31
+
32
+ ---
33
+
34
+ ## 🚀 Cài đặt & Import
35
+
36
+ ```tsx
37
+ import { Alert } from "@owa/ui";
38
+ import type { AlertProps, AlertColor, AlertVariant, AlertSize, AlertRadius } from "@owa/ui";
39
+ ```
40
+
41
+ ---
42
+
43
+ ## 📖 Hướng dẫn sử dụng
44
+
45
+ ### 1. Cách sử dụng cơ bản (Inline Alert)
46
+
47
+ Bạn có thể truyền nội dung thông báo qua prop `description` hoặc qua thẻ con `children`:
48
+
49
+ ```tsx
50
+ import { Alert } from "@owa/ui";
51
+
52
+ // Cách 1: Sử dụng prop description (ngắn gọn)
53
+ export function BasicAlertExample() {
54
+ return (
55
+ <Alert
56
+ color="info"
57
+ variant="soft"
58
+ title="Thông tin hệ thống"
59
+ description="Hệ thống sẽ tiến hành bảo trì định kỳ vào cuối tuần này."
60
+ />
61
+ );
62
+ }
63
+
64
+ // Cách 2: Sử dụng children (dành cho JSX tùy biến)
65
+ export function ChildrenAlertExample() {
66
+ return (
67
+ <Alert color="success" title="Đã lưu thành công!">
68
+ <p className="mt-1">Dữ liệu hồ sơ của bạn đã được cập nhật.</p>
69
+ </Alert>
70
+ );
71
+ }
72
+ ```
73
+
74
+ ---
75
+
76
+ ### 2. Tự động đóng thông báo (`closable` & `onClose`)
77
+
78
+ Nút đóng `(X)` mặc định luôn bật (`closable=true`). Người dùng có thể click để tắt thông báo ngay mà **không cần truyền bất kỳ hàm nào**:
79
+
80
+ ```tsx
81
+ // 1. Tự động đóng/ẩn ngay khi click (x) mà không cần viết thêm hàm gì:
82
+ <Alert title="Thông báo" description="Click nút x bên phải sẽ tự ẩn thông báo này." />
83
+
84
+ // 2. Tự động đóng kèm theo callback onClose (nếu muốn xử lý thêm logic):
85
+ <Alert
86
+ title="Thông báo"
87
+ description="Thực hiện logic khi người dùng tắt thông báo."
88
+ onClose={() => console.log("Alert đã được đóng!")}
89
+ />
90
+
91
+ // 3. Tắt nút đóng (không cho người dùng đóng):
92
+ <Alert closable={false} title="Thông báo bắt buộc" description="Nội dung không thể đóng." />
93
+ ```
94
+
95
+ ---
96
+
97
+ ### 3. Các chủ đề màu sắc (`color`)
98
+
99
+ Component cung cấp 7 tông màu chuẩn Design System:
100
+
101
+ ```tsx
102
+ <Alert color="primary" title="Primary" description="Thông báo chính của ứng dụng." />
103
+ <Alert color="secondary" title="Secondary" description="Thông báo phụ bổ sung thông tin." />
104
+ <Alert color="neutral" title="Neutral" description="Thông báo trung tính dạng ghi chú." />
105
+ <Alert color="info" title="Info" description="Thông tin hướng dẫn sử dụng." />
106
+ <Alert color="success" title="Success" description="Dữ liệu đã được lưu thành công." />
107
+ <Alert color="warning" title="Warning" description="Dung lượng bộ nhớ đã đạt mức 90%." />
108
+ <Alert color="error" title="Error" description="Không thể kết nối đến máy chủ." />
109
+ ```
110
+
111
+ ---
112
+
113
+ ### 4. Các biến thể giao diện (`variant`)
114
+
115
+ ```tsx
116
+ // 1. Soft (Mặc định)
117
+ <Alert variant="soft" color="success" title="Soft Variant" description="Nền pastel nhạt, chữ và viền cùng tông màu." />
118
+
119
+ // 2. Filled
120
+ <Alert variant="filled" color="error" title="Filled Variant" description="Nền màu đậm, độ tương phản cao, nổi bật." />
121
+
122
+ // 3. Outline
123
+ <Alert variant="outline" color="primary" title="Outline Variant" description="Nền trắng, viền rõ nét theo màu chủ đề." />
124
+
125
+ // 4. Accent Left
126
+ <Alert variant="accent-left" color="warning" title="Accent Left Variant" description="Nền pastel kèm viền nhấn dày 4px bên trái." />
127
+
128
+ // 5. Ghost
129
+ <Alert variant="ghost" color="info" title="Ghost Variant" description="Nền và viền trong suốt, chỉ hiển thị icon và chữ." />
130
+
131
+ // 6. Other (Tự do tùy biến)
132
+ <Alert
133
+ variant="other"
134
+ className="bg-purple-100 text-purple-900 border-2 border-purple-300"
135
+ title="Other Variant"
136
+ description="Tự do áp dụng class Tailwind tùy chỉnh bên ngoài."
137
+ />
138
+ ```
139
+
140
+ ---
141
+
142
+ ### 5. Kích cỡ (`size`) & Độ bo góc (`radius`)
143
+
144
+ ```tsx
145
+ // 5 kích cỡ tiêu chuẩn
146
+ <Alert size="xs" title="Size XS" description="Thông báo kích cỡ rất nhỏ" />
147
+ <Alert size="sm" title="Size SM" description="Thông báo kích cỡ nhỏ" />
148
+ <Alert size="md" title="Size MD" description="Thông báo kích cỡ vừa (mặc định)" />
149
+ <Alert size="lg" title="Size LG" description="Thông báo kích cỡ lớn" />
150
+ <Alert size="xl" title="Size XL" description="Thông báo kích cỡ rất lớn" />
151
+
152
+ // Tùy chỉnh độ bo góc
153
+ <Alert radius="none" title="Không bo góc" description="Góc vuông 0px" />
154
+ <Alert radius="sm" title="Bo góc nhỏ" description="rounded-sm" />
155
+ <Alert radius="md" title="Bo góc vừa" description="rounded-md" />
156
+ <Alert radius="lg" title="Bo góc lớn" description="rounded-lg (mặc định)" />
157
+ <Alert radius="xl" title="Bo góc rất lớn" description="rounded-xl" />
158
+ <Alert radius="full" title="Bo tròn" description="rounded-2xl" />
159
+ ```
160
+
161
+ ---
162
+
163
+ ### 6. Chế độ Banner (`banner`)
164
+
165
+ Chế độ Banner giúp thông báo trải rộng toàn bộ chiều ngang (`w-full`), loại bỏ bo góc (`rounded-none`) và viền 2 bên, rất phù hợp gắn cố định trên cùng màn hình:
166
+
167
+ ```tsx
168
+ <Alert
169
+ banner
170
+ color="error"
171
+ title="Sự cố đường truyền"
172
+ description="Hiện tại một số dịch vụ thanh toán đang bị gián đoạn."
173
+ action={
174
+ <button className="text-xs underline font-medium cursor-pointer">
175
+ Xem chi tiết
176
+ </button>
177
+ }
178
+ />
179
+ ```
180
+
181
+ ---
182
+
183
+ ### 7. Icon tùy biến & Action Slot
184
+
185
+ ```tsx
186
+ import { Alert, Button } from "@owa/ui";
187
+
188
+ export function AdvancedAlertExample() {
189
+ return (
190
+ <div className="space-y-4">
191
+ {/* Ẩn Icon */}
192
+ <Alert icon={false} color="neutral" title="Không có icon" description="Nội dung không kèm icon đầu dòng." />
193
+
194
+ {/* Custom Icon bằng JSX */}
195
+ <Alert
196
+ icon={<span className="text-lg">🚀</span>}
197
+ color="primary"
198
+ title="Tính năng mới"
199
+ description="Trải nghiệm phiên bản 2.0 với nhiều cải tiến vượt bậc."
200
+ />
201
+
202
+ {/* Action Slot kèm Button */}
203
+ <Alert
204
+ color="info"
205
+ title="Bản cập nhật mới sẵn sàng"
206
+ description="Vui lòng tải lại ứng dụng để áp dụng bản vá mới nhất."
207
+ action={
208
+ <Button size="xs" variant="filled" color="info">
209
+ Cập nhật ngay
210
+ </Button>
211
+ }
212
+ />
213
+ </div>
214
+ );
215
+ }
216
+ ```
217
+
218
+ ---
219
+
220
+ ## 🛠️ API Reference (`AlertProps`)
221
+
222
+ Component `Alert` nhận các props mở rộng từ thẻ HTML chuẩn `HTMLAttributes<HTMLDivElement>` (ngoại trừ prop `title`):
223
+
224
+ | Thuộc tính | Kiểu dữ liệu | Mặc định | Mô tả |
225
+ | :--- | :--- | :--- | :--- |
226
+ | `size` | `"xs" \| "sm" \| "md" \| "lg" \| "xl"` | `"md"` | Kích cỡ của Alert (ảnh hưởng padding, font size, icon size). |
227
+ | `variant` | `"soft" \| "filled" \| "outline" \| "accent-left" \| "ghost" \| "other"` | `"soft"` | Biến thể giao diện và phong cách hiển thị màu sắc. |
228
+ | `color` | `"primary" \| "secondary" \| "neutral" \| "error" \| "success" \| "warning" \| "info"` | `"info"` | Chủ đề màu sắc theo Design System. |
229
+ | `radius` | `"none" \| "sm" \| "md" \| "lg" \| "xl" \| "full"` | `"lg"` | Độ bo góc của khung thông báo. |
230
+ | `title` | `ReactNode` | `undefined` | Tiêu đề in đậm của Alert. |
231
+ | `description` | `ReactNode` | `undefined` | Nội dung mô tả ngắn của thông báo. |
232
+ | `children` | `ReactNode` | `undefined` | Nội dung mô tả tùy biến bằng JSX bên trong Alert. |
233
+ | `icon` | `ReactNode \| boolean` | `true` | Icon đầu thông báo: `true` = tự động theo màu, `false` = ẩn, `ReactNode` = custom icon. |
234
+ | `action` | `ReactNode` | `undefined` | Phần tử hành động phụ nằm ở góc phải (Button, Link, Tag). |
235
+ | `closable` | `boolean` | `true` | Hiển thị nút đóng `(X)` và tự động ẩn Alert khi click. |
236
+ | `onClose` | `() => void` | `undefined` | Callback được gọi khi người dùng bấm nút đóng. |
237
+ | `closeAriaLabel` | `string` | `"Close alert"` | Nhãn trợ năng (accessibility) cho nút đóng. |
238
+ | `banner` | `boolean` | `false` | Bật chế độ Banner: Full width (`w-full`), góc vuông (`rounded-none`), không viền 2 bên. |
239
+ | `titleClassName` | `string` | `""` | Tùy biến className riêng cho phần tiêu đề (`title`). |
240
+ | `descriptionClassName` | `string` | `""` | Tùy biến className riêng cho phần nội dung (`description` / `children`). |
241
+ | `actionClassName` | `string` | `""` | Tùy biến className riêng cho vùng `action`. |
242
+ | `iconClassName` | `string` | `""` | Tùy biến className riêng cho vùng chứa icon. |
243
+ | `closeButtonClassName` | `string` | `""` | Tùy biến className riêng cho nút đóng `(X)`. |
244
+ | `className` | `string` | `""` | Class tùy biến cho khung container bao ngoài. |
245
+ | `role` | `string` | Tự động | ARIA role (`"alert"` cho error/warning, `"status"` cho các màu khác). |
246
+ | `ref` | `Ref<HTMLDivElement>` | `undefined` | Ref chuyển tiếp đến phần tử thẻ `<div>` bọc ngoài. |