@thangnqdev/ui 0.1.2 → 0.2.0
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/LICENSE +21 -0
- package/README.md +54 -206
- package/dist/bento/index.cjs.map +1 -1
- package/dist/bento/index.js +2 -2
- package/dist/bento/styles.css +2 -46
- package/dist/buttons/index.cjs +111 -18
- package/dist/buttons/index.cjs.map +1 -1
- package/dist/buttons/index.d.cts +1 -1
- package/dist/buttons/index.d.ts +1 -1
- package/dist/buttons/index.js +3 -3
- package/dist/buttons/styles.css +2 -6
- package/dist/{chunk-4S6L5V7X.js → chunk-2YJBW4E2.js} +2 -2
- package/dist/chunk-2YJBW4E2.js.map +1 -0
- package/dist/{chunk-F5Q7BTMH.js → chunk-4CRFNALF.js} +1011 -556
- package/dist/chunk-4CRFNALF.js.map +1 -0
- package/dist/{chunk-LWFRUJRU.js → chunk-4MS6ZHFQ.js} +225 -41
- package/dist/chunk-4MS6ZHFQ.js.map +1 -0
- package/dist/{chunk-2OXZK6IP.js → chunk-77KTYOMQ.js} +3 -3
- package/dist/chunk-77KTYOMQ.js.map +1 -0
- package/dist/{chunk-IABPUCAQ.js → chunk-ADO3SVUA.js} +2 -2
- package/dist/chunk-ADO3SVUA.js.map +1 -0
- package/dist/{chunk-GXI2H5XA.js → chunk-D7FB3TCA.js} +3 -3
- package/dist/chunk-D7FB3TCA.js.map +1 -0
- package/dist/chunk-DSEL7ELZ.js +314 -0
- package/dist/chunk-DSEL7ELZ.js.map +1 -0
- package/dist/{chunk-KJRBRTQE.js → chunk-EXFR2BFJ.js} +37 -28
- package/dist/chunk-EXFR2BFJ.js.map +1 -0
- package/dist/{chunk-PF4ZHGVW.js → chunk-GXWB6BSY.js} +116 -23
- package/dist/chunk-GXWB6BSY.js.map +1 -0
- package/dist/{chunk-66VWUJEI.js → chunk-I2FQBMVW.js} +3 -3
- package/dist/chunk-I2FQBMVW.js.map +1 -0
- package/dist/{chunk-EU2LPUYP.js → chunk-I5O2WCGF.js} +3 -3
- package/dist/chunk-I5O2WCGF.js.map +1 -0
- package/dist/{chunk-ATYGDTMK.js → chunk-ME4XILG5.js} +5 -5
- package/dist/chunk-ME4XILG5.js.map +1 -0
- package/dist/{chunk-5FZ6ZFII.js → chunk-PC5SZFZC.js} +373 -150
- package/dist/chunk-PC5SZFZC.js.map +1 -0
- package/dist/{chunk-C4SUXMI3.js → chunk-S6XJMYME.js} +3 -3
- package/dist/chunk-S6XJMYME.js.map +1 -0
- package/dist/{chunk-A7P3O5Z5.js → chunk-V52JOSDF.js} +3 -3
- package/dist/chunk-V52JOSDF.js.map +1 -0
- package/dist/{chunk-NFVONJUK.js → chunk-W5WNWTQC.js} +455 -211
- package/dist/chunk-W5WNWTQC.js.map +1 -0
- package/dist/{chunk-WAFHC4DQ.js → chunk-YJ64RI7J.js} +3 -3
- package/dist/chunk-YJ64RI7J.js.map +1 -0
- package/dist/chunk-YOCGBORV.js +155 -0
- package/dist/chunk-YOCGBORV.js.map +1 -0
- package/dist/chunk-ZEDXARXW.js +96 -0
- package/dist/chunk-ZEDXARXW.js.map +1 -0
- package/dist/components.css +2 -0
- package/dist/core/index.cjs +33 -24
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.js +2 -2
- package/dist/core/styles.css +2 -134
- package/dist/data-display/index.cjs +770 -247
- package/dist/data-display/index.cjs.map +1 -1
- package/dist/data-display/index.d.cts +1 -1
- package/dist/data-display/index.d.ts +1 -1
- package/dist/data-display/index.js +5 -4
- package/dist/data-display/styles.css +2 -4
- package/dist/feedback/index.cjs.map +1 -1
- package/dist/feedback/index.js +2 -2
- package/dist/feedback/styles.css +2 -4
- package/dist/forms/index.cjs +1211 -459
- package/dist/forms/index.cjs.map +1 -1
- package/dist/forms/index.d.cts +1 -1
- package/dist/forms/index.d.ts +1 -1
- package/dist/forms/index.js +8 -8
- package/dist/forms/styles.css +2 -6
- package/dist/glass/index.cjs.map +1 -1
- package/dist/glass/index.js +2 -2
- package/dist/glass/styles.css +2 -81
- package/dist/{index-D6fE7w-b.d.cts → index-BGt_hecO.d.cts} +1 -0
- package/dist/{index-D6fE7w-b.d.ts → index-BGt_hecO.d.ts} +1 -0
- package/dist/{index-DzcWh1Hs.d.cts → index-BtDvpZCf.d.cts} +7 -0
- package/dist/{index-DzcWh1Hs.d.ts → index-BtDvpZCf.d.ts} +7 -0
- package/dist/{index-Cle6QzQl.d.ts → index-COX1sBUN.d.ts} +27 -3
- package/dist/{index-BkRqGNG1.d.ts → index-Cg8MuP7u.d.cts} +40 -13
- package/dist/{index-BkRqGNG1.d.cts → index-Cg8MuP7u.d.ts} +40 -13
- package/dist/{index-CenuF_P2.d.ts → index-DHkPRTvE.d.cts} +39 -8
- package/dist/{index-CenuF_P2.d.cts → index-DHkPRTvE.d.ts} +39 -8
- package/dist/{index-TyK-Ldpy.d.cts → index-Du_oht9k.d.cts} +27 -3
- package/dist/index.cjs +2481 -917
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +19 -19
- package/dist/layout/index.cjs.map +1 -1
- package/dist/layout/index.js +2 -2
- package/dist/layout/styles.css +2 -8
- package/dist/navigation/index.cjs +288 -48
- package/dist/navigation/index.cjs.map +1 -1
- package/dist/navigation/index.d.cts +1 -1
- package/dist/navigation/index.d.ts +1 -1
- package/dist/navigation/index.js +6 -6
- package/dist/navigation/styles.css +2 -4
- package/dist/overlays/index.cjs +566 -229
- package/dist/overlays/index.cjs.map +1 -1
- package/dist/overlays/index.d.cts +1 -1
- package/dist/overlays/index.d.ts +1 -1
- package/dist/overlays/index.js +7 -7
- package/dist/overlays/styles.css +2 -8
- package/dist/reset.css +45 -0
- package/dist/styles.css +1 -1
- package/dist/tokens.css +11 -0
- package/dist/typography/index.cjs.map +1 -1
- package/dist/typography/index.js +4 -4
- package/dist/typography/styles.css +2 -5
- package/llms.txt +211 -113
- package/package.json +160 -116
- package/src/bento/BentoCard.tsx +140 -140
- package/src/bento/BentoGrid.tsx +50 -50
- package/src/bento/index.ts +2 -2
- package/src/bento/tokens.css +46 -46
- package/src/buttons/Button.tsx +104 -104
- package/src/buttons/ButtonGroup.tsx +43 -43
- package/src/buttons/IconButton.tsx +79 -79
- package/src/buttons/SplitButton.tsx +186 -86
- package/src/buttons/ToggleButton.tsx +157 -157
- package/src/buttons/index.ts +5 -5
- package/src/buttons/tokens.css +6 -6
- package/src/core/ThemeProvider.tsx +135 -123
- package/src/core/index.ts +2 -2
- package/src/core/tokens.css +134 -134
- package/src/data-display/Accordion.tsx +147 -147
- package/src/data-display/Avatar.tsx +134 -134
- package/src/data-display/Card.tsx +112 -112
- package/src/data-display/Chip.tsx +74 -74
- package/src/data-display/DataTablePro.tsx +299 -121
- package/src/data-display/StatCard.tsx +60 -60
- package/src/data-display/Table.tsx +74 -74
- package/src/data-display/Timeline.tsx +62 -62
- package/src/data-display/TreeView.tsx +243 -104
- package/src/data-display/tokens.css +4 -4
- package/src/feedback/Alert.tsx +80 -80
- package/src/feedback/EmptyState.tsx +45 -45
- package/src/feedback/Skeleton.tsx +66 -66
- package/src/feedback/Spinner.tsx +65 -65
- package/src/feedback/index.ts +5 -5
- package/src/feedback/tokens.css +4 -4
- package/src/forms/Checkbox.tsx +149 -69
- package/src/forms/CheckboxGroup.tsx +76 -29
- package/src/forms/Combobox.tsx +172 -28
- package/src/forms/DatePicker.tsx +385 -81
- package/src/forms/FileUpload.tsx +51 -7
- package/src/forms/FormField.tsx +115 -115
- package/src/forms/Input.tsx +151 -151
- package/src/forms/NumberInput.tsx +34 -20
- package/src/forms/PasswordInput.tsx +35 -35
- package/src/forms/PinInput.tsx +139 -125
- package/src/forms/Radio.tsx +142 -142
- package/src/forms/RangeSlider.tsx +237 -111
- package/src/forms/SearchInput.tsx +34 -34
- package/src/forms/Select.tsx +103 -103
- package/src/forms/Slider.tsx +85 -85
- package/src/forms/Textarea.tsx +114 -114
- package/src/forms/tokens.css +6 -6
- package/src/glass/GlassButton.tsx +59 -59
- package/src/glass/GlassCard.tsx +71 -71
- package/src/glass/index.ts +3 -3
- package/src/glass/tokens.css +81 -81
- package/src/index.ts +26 -26
- package/src/layout/AspectRatio.tsx +39 -39
- package/src/layout/Container.tsx +53 -53
- package/src/layout/Divider.tsx +61 -61
- package/src/layout/Flex.tsx +79 -79
- package/src/layout/Grid.tsx +124 -124
- package/src/layout/PageLayout.tsx +59 -59
- package/src/layout/Section.tsx +47 -47
- package/src/layout/Spacer.tsx +30 -30
- package/src/layout/Stack.tsx +88 -88
- package/src/layout/tokens.css +8 -8
- package/src/navigation/Breadcrumb.tsx +73 -73
- package/src/navigation/CommandPalette.tsx +142 -142
- package/src/navigation/DropdownMenu.tsx +244 -160
- package/src/navigation/Pagination.tsx +114 -114
- package/src/navigation/Stepper.tsx +93 -93
- package/src/navigation/Tabs.tsx +265 -133
- package/src/navigation/index.ts +6 -6
- package/src/navigation/tokens.css +4 -4
- package/src/overlays/AlertDialog.tsx +63 -54
- package/src/overlays/BottomSheet.tsx +30 -10
- package/src/overlays/ContextMenu.tsx +51 -9
- package/src/overlays/Drawer.tsx +160 -145
- package/src/overlays/FocusTrap.tsx +122 -49
- package/src/overlays/Modal.tsx +296 -219
- package/src/overlays/Popover.tsx +55 -25
- package/src/overlays/Portal.tsx +23 -23
- package/src/overlays/Toast.tsx +175 -137
- package/src/overlays/Tooltip.tsx +125 -100
- package/src/overlays/tokens.css +8 -8
- package/src/registry/components.ts +1368 -0
- package/src/styles/components.css +39 -0
- package/src/styles/index.css +2 -93
- package/src/styles/reset.css +45 -0
- package/src/styles/tokens.css +11 -2
- package/src/typography/Blockquote.tsx +32 -32
- package/src/typography/Code.tsx +89 -89
- package/src/typography/Heading.tsx +56 -56
- package/src/typography/Kbd.tsx +25 -25
- package/src/typography/Label.tsx +47 -47
- package/src/typography/Link.tsx +56 -56
- package/src/typography/Text.tsx +62 -62
- package/src/typography/index.ts +7 -7
- package/src/typography/tokens.css +5 -5
- package/src/utils/cn.ts +6 -6
- package/src/utils/scroll-lock.ts +19 -0
- package/src/utils/useControllableState.ts +54 -0
- package/ui-contract.json +192 -35
- package/dist/chunk-2OXZK6IP.js.map +0 -1
- package/dist/chunk-4S6L5V7X.js.map +0 -1
- package/dist/chunk-5FZ6ZFII.js.map +0 -1
- package/dist/chunk-66VWUJEI.js.map +0 -1
- package/dist/chunk-A7P3O5Z5.js.map +0 -1
- package/dist/chunk-ATYGDTMK.js.map +0 -1
- package/dist/chunk-C4SUXMI3.js.map +0 -1
- package/dist/chunk-EU2LPUYP.js.map +0 -1
- package/dist/chunk-F5Q7BTMH.js.map +0 -1
- package/dist/chunk-GXI2H5XA.js.map +0 -1
- package/dist/chunk-H3LCNPMC.js +0 -101
- package/dist/chunk-H3LCNPMC.js.map +0 -1
- package/dist/chunk-IABPUCAQ.js.map +0 -1
- package/dist/chunk-KJRBRTQE.js.map +0 -1
- package/dist/chunk-LBUBXUYQ.js +0 -40
- package/dist/chunk-LBUBXUYQ.js.map +0 -1
- package/dist/chunk-LWFRUJRU.js.map +0 -1
- package/dist/chunk-NFVONJUK.js.map +0 -1
- package/dist/chunk-PF4ZHGVW.js.map +0 -1
- package/dist/chunk-WAFHC4DQ.js.map +0 -1
- package/dist/chunk-X76KBH4Y.js +0 -71
- package/dist/chunk-X76KBH4Y.js.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 thangnqdev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# @thangnqdev/ui
|
|
2
2
|
|
|
3
|
-
> **AETHER** — Spatial Optics &
|
|
3
|
+
> **AETHER** — Spatial Optics & Enterprise-Grade Component Infrastructure for React & Tailwind CSS.
|
|
4
4
|
|
|
5
|
-
An enterprise-
|
|
5
|
+
An enterprise-ready architectural UI system engineered for complex SaaS, Fintech, AI Agents, ERP dashboards, and spatial web applications. Features machine-readable contracts (`llms.txt`, `ui-contract.json`), 100% SSOT parity, WCAG 2.1 AA accessibility tiers, hydration-safe SSR, and modular standalone CSS packaging.
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/@thangnqdev/ui)
|
|
8
8
|
[](LICENSE)
|
|
@@ -29,7 +29,7 @@ npm install react react-dom
|
|
|
29
29
|
|
|
30
30
|
## 🎨 Thiết Lập Nhanh (Quickstart)
|
|
31
31
|
|
|
32
|
-
### Cách 1: Sử dụng Standalone CSS
|
|
32
|
+
### Cách 1: Sử dụng Standalone All-In-One CSS
|
|
33
33
|
File `styles.css` đã được biên dịch trọn gói toàn bộ hệ thống Apple Liquid Glass, màu sắc HSL, font SF Pro và các class tiện ích:
|
|
34
34
|
|
|
35
35
|
```tsx
|
|
@@ -41,259 +41,107 @@ import { ThemeProvider, Button, DataTablePro, DatePicker, Combobox } from '@than
|
|
|
41
41
|
export default function App() {
|
|
42
42
|
return (
|
|
43
43
|
<ThemeProvider defaultTheme="dark">
|
|
44
|
-
<Button variant="primary">
|
|
44
|
+
<Button variant="primary">Primary Action</Button>
|
|
45
45
|
</ThemeProvider>
|
|
46
46
|
);
|
|
47
47
|
}
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
### Cách 2: Sử dụng Domain Modular Subpath CSS (Tối ưu hóa Bundle Size)
|
|
51
|
+
Mỗi domain module có stylesheet độc lập đã được biên dịch toàn bộ utility class và design tokens:
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { Button, IconButton } from '@thangnqdev/ui/buttons';
|
|
55
|
+
import '@thangnqdev/ui/buttons/styles.css';
|
|
56
|
+
|
|
57
|
+
import { Modal, ModalTitle, ModalBody } from '@thangnqdev/ui/overlays';
|
|
58
|
+
import '@thangnqdev/ui/overlays/styles.css';
|
|
59
|
+
```
|
|
60
|
+
|
|
50
61
|
---
|
|
51
62
|
|
|
52
|
-
|
|
63
|
+
## 🏛️ Kiến Trúc Hệ Thống (Architectural Pillars)
|
|
53
64
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
@import "tailwindcss";
|
|
65
|
+
### 1. Single Source of Truth (SSOT) Invariant Guarantee
|
|
66
|
+
Toàn bộ metadata component, public exports, `ui-contract.json` và `llms.txt` được liên kết trực tiếp với `COMPONENT_REGISTRY` (145 components). CI tự động kiểm tra tính bất biến 1-to-1:
|
|
67
|
+
$$\text{Registry Exports} \equiv \text{Public TS Exports} \equiv \text{ui-contract.json} \equiv \text{llms.txt}$$
|
|
58
68
|
|
|
59
|
-
|
|
60
|
-
|
|
69
|
+
### 2. Ba Cấp Độ Accessibility Rõ Ràng (A11y Tiers)
|
|
70
|
+
Không overclaim accessibility; mọi primitive được phân loại minh bạch:
|
|
71
|
+
- **`native`**: Các thẻ nền tảng browser (`Container`, `Grid`, `Heading`, `Text`, `Link`, `Portal`, `Divider`...).
|
|
72
|
+
- **`supported`**: Các component composite hỗ trợ ARIA attributes và keyboard shortcuts.
|
|
73
|
+
- **`verified`**: Các interactive primitives đã vượt qua kiểm thử WAI-ARIA pattern đầy đủ và automated audit bằng `axe-core` (`Button`, `Modal`, `FocusTrap`, `DatePicker`, `DateRangePicker`, `TimePicker`, `Tooltip`, `SplitButton`, `Checkbox`, `RangeSlider`, `Tabs`, `Accordion`, `DataTablePro`...).
|
|
61
74
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
75
|
+
### 3. Chuẩn Hóa State với `useControllableState`
|
|
76
|
+
Mọi stateful component (`CurrencyInput`, `NumberInput`, `Popover`, `DatePicker`, `Combobox`, `Checkbox`...) hỗ trợ cả **Controlled** và **Uncontrolled** mode với cam kết:
|
|
77
|
+
- Khi controlled, UI luôn trung thực với `value` prop (không bao giờ lệch khi parent reject update).
|
|
78
|
+
- Chuyển đổi trạng thái mượt mà, hỗ trợ `open` / `defaultOpen` / `onOpenChange` và `value` / `defaultValue` / `onChange`.
|
|
65
79
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
```javascript
|
|
69
|
-
/** @type {import('tailwindcss').Config} */
|
|
70
|
-
module.exports = {
|
|
71
|
-
content: [
|
|
72
|
-
'./src/**/*.{js,ts,jsx,tsx}',
|
|
73
|
-
'./node_modules/@thangnqdev/ui/dist/**/*.{js,cjs}',
|
|
74
|
-
],
|
|
75
|
-
darkMode: 'class',
|
|
76
|
-
theme: {
|
|
77
|
-
extend: {},
|
|
78
|
-
},
|
|
79
|
-
plugins: [],
|
|
80
|
-
};
|
|
81
|
-
```
|
|
80
|
+
### 4. Hydration-Safe SSR cho Next.js / Remix
|
|
81
|
+
`ThemeProvider` và toàn bộ overlay components khởi tạo an toàn, đồng bộ theme client-side sau mount để loại bỏ hoàn toàn lỗi React hydration mismatch.
|
|
82
82
|
|
|
83
83
|
---
|
|
84
84
|
|
|
85
|
-
## 🛠️ Hướng Dẫn Tùy Biến
|
|
86
|
-
|
|
87
|
-
Thư viện được thiết kế để người dùng có thể **tùy biến 100%** theo phong cách thương hiệu riêng qua 4 tầng:
|
|
85
|
+
## 🛠️ Hướng Dẫn Tùy Biến (Customization Guide)
|
|
88
86
|
|
|
89
87
|
### 1. Tùy Biến Toàn Cục bằng CSS Variables (Global Theming)
|
|
90
|
-
Mặc định, thư viện sử dụng bảng màu **Apple Human Interface (`#0071e3` / `#000000`)**.
|
|
91
|
-
|
|
92
|
-
Khi người khác kéo package về dùng, nếu họ muốn **đổi sang màu thương hiệu riêng** (ví dụ Fintech Indigo, Neon Cyberpunk...), họ chỉ cần ghi đè các biến CSS trong file `src/index.css` của họ:
|
|
93
88
|
|
|
94
89
|
```css
|
|
95
|
-
/* Ví dụ: Người dùng tùy biến đổi sang màu thương hiệu của riêng họ */
|
|
96
90
|
:root {
|
|
97
|
-
/* 🔤
|
|
91
|
+
/* 🔤 Font chữ & Monospace */
|
|
98
92
|
--ui-font-sans: 'Plus Jakarta Sans', 'Inter', sans-serif;
|
|
99
93
|
--ui-font-mono: 'JetBrains Mono', 'Fira Code', monospace;
|
|
100
94
|
|
|
101
|
-
/* 🎨
|
|
95
|
+
/* 🎨 Màu chủ đạo thương hiệu (Brand Colors) */
|
|
102
96
|
--ui-primary: #6366f1;
|
|
103
97
|
--ui-primary-hover: #4f46e5;
|
|
104
98
|
--ui-primary-glow: rgba(99, 102, 241, 0.35);
|
|
105
99
|
--ui-accent: #ec4899;
|
|
106
100
|
|
|
107
|
-
/* 📐
|
|
101
|
+
/* 📐 Bo góc */
|
|
108
102
|
--ui-radius-lg: 16px;
|
|
109
|
-
|
|
110
|
-
/* 📏 Phóng to/thu nhỏ toàn bộ tỷ lệ UI */
|
|
111
|
-
font-size: 16px;
|
|
112
103
|
}
|
|
113
104
|
|
|
114
|
-
/* Tùy chỉnh riêng cho Dark Mode của người dùng */
|
|
115
105
|
.dark, [data-theme="dark"] {
|
|
116
106
|
--ui-primary: #818cf8;
|
|
117
|
-
--ui-bg-page: #09090b;
|
|
118
|
-
--ui-bg-secondary: #18181b;
|
|
107
|
+
--ui-bg-page: #09090b;
|
|
108
|
+
--ui-bg-secondary: #18181b;
|
|
119
109
|
}
|
|
120
110
|
```
|
|
121
111
|
|
|
122
|
-
#### Bảng Biến CSS Tokens Chính:
|
|
123
|
-
| CSS Variable | Mô tả | Mặc định Light | Mặc định Dark |
|
|
124
|
-
|---|---|---|---|
|
|
125
|
-
| `--ui-font-sans` | Font chữ chính | SF Pro Display, Inter | SF Pro Display, Inter |
|
|
126
|
-
| `--ui-font-mono` | Font số & code | SF Mono, Consolas | SF Mono, Consolas |
|
|
127
|
-
| `--ui-primary` | Màu chính (Primary) | `#0071e3` (Apple Blue) | `#2997ff` (Vision Blue) |
|
|
128
|
-
| `--ui-accent` | Màu điểm nhấn (Accent) | `#af52de` (Apple Purple) | `#bf5af2` |
|
|
129
|
-
| `--ui-success` | Màu thành công / Pin | `#34c759` (Apple Green) | `#30d158` |
|
|
130
|
-
| `--ui-warning` | Màu cảnh báo | `#ff9500` (Apple Orange) | `#ffd60a` |
|
|
131
|
-
| `--ui-error` | Màu lỗi | `#ff3b30` (Apple Red) | `#ff453a` |
|
|
132
|
-
| `--ui-bg-page` | Màu nền trang | `#f5f5f7` | `#000000` |
|
|
133
|
-
| `--ui-bg-surface` | Màu bề mặt kính mờ | `rgba(255,255,255,0.75)` | `rgba(30,30,34,0.72)` |
|
|
134
|
-
| `--ui-radius-lg` | Bo góc tiêu chuẩn | `1.125rem` (18px) | `1.125rem` (18px) |
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
### 2. Tùy Biến Từng Component qua Props
|
|
139
|
-
Mọi component đều hỗ trợ đầy đủ các props để thay đổi kích cỡ, màu sắc, hiệu ứng:
|
|
140
|
-
|
|
141
|
-
```tsx
|
|
142
|
-
import { Button, GlassBadge, CircularProgress, GlassCard } from '@thangnqdev/ui';
|
|
143
|
-
|
|
144
|
-
// Nút bấm kích thước lớn, kiểu trong suốt
|
|
145
|
-
<Button variant="outline" size="lg" className="rounded-full">
|
|
146
|
-
Khám Phá Thêm
|
|
147
|
-
</Button>
|
|
148
|
-
|
|
149
|
-
// Thẻ kính mờ với viền phát sáng màu ngọc lam (Cyan Glow)
|
|
150
|
-
<GlassCard intensity="acrylic" glow="cyan" radius="xl" padding="lg">
|
|
151
|
-
<h3>Card Content</h3>
|
|
152
|
-
</GlassCard>
|
|
153
|
-
|
|
154
|
-
// Vòng tiến trình màu vàng cảnh báo với hiệu ứng phát sáng
|
|
155
|
-
<CircularProgress value={78} size={64} strokeWidth={6} variant="warning" glow />
|
|
156
|
-
```
|
|
157
|
-
|
|
158
112
|
---
|
|
159
113
|
|
|
160
|
-
|
|
161
|
-
Tất cả component đều được xử lý qua hàm `cn()` (`clsx` + `tailwind-merge`). Class bạn truyền vào sẽ tự động ghi đè class mặc định:
|
|
162
|
-
|
|
163
|
-
```tsx
|
|
164
|
-
// Ghi đè cỡ chữ 2xl, font Serif, background gradient
|
|
165
|
-
<Button className="text-2xl font-serif bg-gradient-to-r from-purple-500 to-pink-500 hover:opacity-90 shadow-2xl">
|
|
166
|
-
Custom Button
|
|
167
|
-
</Button>
|
|
114
|
+
## 🤖 Machine-Readable Contracts for AI Agents
|
|
168
115
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
116
|
+
Thư viện cung cấp hợp đồng chuẩn máy cho các trợ lý AI (Antigravity, Claude Code, Cursor, Codex):
|
|
117
|
+
- **`llms.txt`**: Đặc tả toàn diện cấu trúc import, signature, và quy tắc lập trình.
|
|
118
|
+
- **`ui-contract.json`**: Schema JSON chặt chẽ phục vụ validate và sinh code tự động.
|
|
172
119
|
|
|
173
120
|
---
|
|
174
121
|
|
|
175
|
-
|
|
176
|
-
Sử dụng hook `useTheme()` để tạo nút chuyển đổi giao diện trong 1 dòng:
|
|
177
|
-
|
|
178
|
-
```tsx
|
|
179
|
-
import { ThemeProvider, useTheme, Button } from '@thangnqdev/ui';
|
|
122
|
+
## 🧪 Quality Gates & Kiểm Thử
|
|
180
123
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
return (
|
|
185
|
-
<Button variant="outline" onClick={toggleTheme}>
|
|
186
|
-
{theme === 'dark' ? '☀️ Chuyển sang Light Mode' : '🌙 Chuyển sang Dark Mode'}
|
|
187
|
-
</Button>
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
export default function App() {
|
|
192
|
-
return (
|
|
193
|
-
<ThemeProvider defaultTheme="dark" storageKey="my-app-theme">
|
|
194
|
-
<Header />
|
|
195
|
-
</ThemeProvider>
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
---
|
|
124
|
+
```bash
|
|
125
|
+
# Kiểm tra strict TypeScript
|
|
126
|
+
npm run typecheck
|
|
201
127
|
|
|
202
|
-
|
|
203
|
-
|
|
128
|
+
# Chạy toàn bộ 115+ test cases (A11y, Axe, Invariant, SSR, Controllable State)
|
|
129
|
+
npm test
|
|
204
130
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
import { DatePicker, Combobox, NumberInput, Switch, Button } from '@thangnqdev/ui';
|
|
131
|
+
# Kiểm tra tính bất biến SSOT
|
|
132
|
+
npm run test:ssot
|
|
208
133
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
defaultValues: {
|
|
212
|
-
birthDate: new Date(),
|
|
213
|
-
role: 'developer',
|
|
214
|
-
experienceYears: 5,
|
|
215
|
-
notifications: true,
|
|
216
|
-
},
|
|
217
|
-
});
|
|
134
|
+
# Kiểm tra WAI-ARIA & Axe automated scans
|
|
135
|
+
npm run test:a11y
|
|
218
136
|
|
|
219
|
-
|
|
137
|
+
# Kiểm tra Server-Side Rendering
|
|
138
|
+
npm run test:ssr
|
|
220
139
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
<Controller
|
|
224
|
-
name="birthDate"
|
|
225
|
-
control={control}
|
|
226
|
-
render={({ field }) => <DatePicker value={field.value} onChange={field.onChange} />}
|
|
227
|
-
/>
|
|
228
|
-
|
|
229
|
-
<Controller
|
|
230
|
-
name="role"
|
|
231
|
-
control={control}
|
|
232
|
-
render={({ field }) => (
|
|
233
|
-
<Combobox
|
|
234
|
-
value={field.value}
|
|
235
|
-
onChange={field.onChange}
|
|
236
|
-
options={[
|
|
237
|
-
{ value: 'developer', label: 'Software Engineer' },
|
|
238
|
-
{ value: 'designer', label: 'UI/UX Designer' },
|
|
239
|
-
]}
|
|
240
|
-
/>
|
|
241
|
-
)}
|
|
242
|
-
/>
|
|
243
|
-
|
|
244
|
-
<Controller
|
|
245
|
-
name="experienceYears"
|
|
246
|
-
control={control}
|
|
247
|
-
render={({ field }) => <NumberInput value={field.value} onChange={field.onChange} min={1} max={30} />}
|
|
248
|
-
/>
|
|
249
|
-
|
|
250
|
-
<Button type="submit" variant="primary">Lưu Thay Đổi</Button>
|
|
251
|
-
</form>
|
|
252
|
-
);
|
|
253
|
-
}
|
|
140
|
+
# Quy trình Prepack Gate trước khi phát hành
|
|
141
|
+
npm run prepack
|
|
254
142
|
```
|
|
255
143
|
|
|
256
144
|
---
|
|
257
145
|
|
|
258
|
-
## 🚀 Danh Mục 48+ Components Chi Tiết
|
|
259
|
-
|
|
260
|
-
### 1. Nhóm Form & Nhập Liệu Phức Tạp (`@thangnqdev/ui/forms`)
|
|
261
|
-
* **`DatePicker` & `DateRangePicker`**: Lịch popover kính mờ, chọn ngày đơn lẻ hoặc khoảng ngày (Date Range).
|
|
262
|
-
* **`TimePicker`**: Bộ chọn giờ/phút định dạng 24h & 12h.
|
|
263
|
-
* **`Combobox` & `MultiSelect`**: Dropdown tìm kiếm gõ để lọc (search-as-you-type) & chọn nhiều tag.
|
|
264
|
-
* **`FileUpload` & Dropzone**: Vùng kéo thả file với hiệu ứng bắt sáng và xem trước ảnh.
|
|
265
|
-
* **`NumberInput` & `CurrencyInput`**: Input số tăng giảm `+ / -` và format tiền tệ tự động.
|
|
266
|
-
* **`MaskedInput`**: Input định dạng số điện thoại `(###) ###-####`, thẻ tín dụng, CCCD.
|
|
267
|
-
* **Cơ bản**: `FormField`, `Input`, `SearchInput`, `PasswordInput`, `Textarea`, `Select`, `Checkbox`, `Radio`, `Switch`, `Slider`, `RangeSlider`, `PinInput`.
|
|
268
|
-
|
|
269
|
-
### 2. Nhóm Xử Lý Dữ Liệu Lớn (`@thangnqdev/ui/data-display`)
|
|
270
|
-
* **`DataTablePro`**: Bảng dữ liệu cấp doanh nghiệp với Live Search toàn bộ cột, Multi-Column Sort, Row Selection, Phân trang và Export CSV.
|
|
271
|
-
* **`TreeView`**: Cây thư mục phân cấp chuẩn macOS Finder.
|
|
272
|
-
* **`Carousel`**: Trình chiếu trượt ngang tự động chạy với hiệu ứng Apple Keynote.
|
|
273
|
-
* **Cơ bản**: `Card`, `Table`, `Avatar`, `Accordion`, `Chip`, `StatCard`, `Timeline`.
|
|
274
|
-
|
|
275
|
-
### 3. Nhóm Điều Hướng & Overlays (`@thangnqdev/ui/overlays` & `@thangnqdev/ui/navigation`)
|
|
276
|
-
* **`BottomSheet`**: Tấm trượt đáy màn hình tối ưu cho Mobile.
|
|
277
|
-
* **`ContextMenu`**: Menu chuột phải Desktop với phím tắt (`⌘C`, `⌘S`).
|
|
278
|
-
* **`HoverCard`**: Card xem trước thông tin khi rê chuột.
|
|
279
|
-
* **Cơ bản**: `Modal`, `AlertDialog`, `Drawer`, `Tooltip`, `Popover`, `Toast`, `Tabs`, `Breadcrumb`, `Pagination`, `Stepper`, `CommandPalette`.
|
|
280
|
-
|
|
281
|
-
### 4. Nhóm Phản Hồi & Vật Liệu Apple (`@thangnqdev/ui/glass` & `@thangnqdev/ui/feedback`)
|
|
282
|
-
* **`GlassCard` & `GlassButton`**: Kính mờ Acrylic 28px blur với 1px viền phản quang (Specular Hairline).
|
|
283
|
-
* **`GlassBadge`**: Huy hiệu SF Pro capsule pill với đèn LED phát sáng xung nhịp.
|
|
284
|
-
* **`CircularProgress`**: Vòng tiến trình Apple Watch Activity gradient rings.
|
|
285
|
-
* **`ScrollArea`**: Thanh cuộn capsule tự ẩn chuẩn Apple.
|
|
286
|
-
* **`BentoGrid` & `BentoCard`**: Lưới bento Apple Keynote editorial.
|
|
287
|
-
|
|
288
|
-
---
|
|
289
|
-
|
|
290
|
-
## 🤖 AI Machine Context Manifests
|
|
291
|
-
|
|
292
|
-
Thư viện tích hợp sẵn các manifest định dạng chuẩn AI coding assistants (Cursor, Antigravity, Claude Code):
|
|
293
|
-
- `llms.txt`: Đặc tả đầy đủ token, API component và triết lý thiết kế.
|
|
294
|
-
- `ui-contract.json`: Schema JSON nghiêm ngặt để sinh mã tự động không bị lệch kiểu.
|
|
295
|
-
|
|
296
|
-
---
|
|
297
|
-
|
|
298
146
|
## 📄 License
|
|
299
147
|
MIT © 2026 AETHER Spatial UI
|
package/dist/bento/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/cn.ts","../../src/bento/BentoGrid.tsx","../../src/bento/BentoCard.tsx"],"names":["twMerge","clsx","cva","jsx","forwardRef","jsxs"],"mappings":"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","file":"index.cjs","sourcesContent":["import { clsx, type ClassValue } from 'clsx';\
|
|
1
|
+
{"version":3,"sources":["../../src/utils/cn.ts","../../src/bento/BentoGrid.tsx","../../src/bento/BentoCard.tsx"],"names":["twMerge","clsx","cva","jsx","forwardRef","jsxs"],"mappings":"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","file":"index.cjs","sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import React from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../utils/cn';\n\nconst bentoGridVariants = cva('grid w-full auto-rows-[minmax(240px,auto)]', {\n variants: {\n cols: {\n 1: 'grid-cols-1',\n 2: 'grid-cols-1 md:grid-cols-2',\n 3: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',\n 4: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-4',\n },\n gap: {\n sm: 'gap-4',\n md: 'gap-6',\n lg: 'gap-8',\n },\n flow: {\n row: 'grid-flow-row',\n col: 'grid-flow-col',\n dense: 'grid-flow-dense',\n 'row-dense': 'grid-flow-row-dense',\n 'col-dense': 'grid-flow-col-dense',\n },\n },\n defaultVariants: {\n cols: 3,\n gap: 'md',\n flow: 'row',\n },\n});\n\nexport interface BentoGridProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof bentoGridVariants> {}\n\nexport const BentoGrid: React.FC<BentoGridProps> = ({\n className,\n cols,\n gap,\n flow,\n children,\n ...props\n}) => {\n return (\n <div className={cn(bentoGridVariants({ cols, gap, flow, className }))} {...props}>\n {children}\n </div>\n );\n};\n","import React, { forwardRef } from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../utils/cn';\n\nconst bentoCardVariants = cva(\n 'group relative flex flex-col justify-between overflow-hidden transition-all duration-500 ease-out border text-[var(--ui-bento-text-title)]',\n {\n variants: {\n colSpan: {\n 1: 'col-span-1',\n 2: 'col-span-1 md:col-span-2',\n 3: 'col-span-1 md:col-span-2 lg:col-span-3',\n },\n rowSpan: {\n 1: 'row-span-1',\n 2: 'row-span-1 md:row-span-2 md:min-h-[460px]',\n 3: 'row-span-1 md:row-span-3 md:min-h-[680px]',\n },\n variant: {\n default:\n 'bg-[var(--ui-bento-bg-card)] border-[var(--ui-bento-border)] hover:border-[var(--ui-bento-border-hover)] hover:bg-[var(--ui-bento-bg-card-hover)] shadow-[var(--ui-bento-shadow)]',\n spotlight:\n 'bg-[var(--ui-bento-bg-card)] border-[var(--ui-bento-border)] hover:border-white/30 dark:hover:border-white/30 hover:shadow-[0_0_35px_-8px_rgba(255,255,255,0.12)]',\n elevated:\n 'bg-[image:var(--ui-bento-bg-elevated)] border-[var(--ui-bento-border)] hover:border-[var(--ui-bento-border-hover)] shadow-[var(--ui-bento-shadow-elevated)]',\n },\n radius: {\n md: 'rounded-[var(--ui-bento-radius-md)]',\n lg: 'rounded-[var(--ui-bento-radius-lg)]',\n },\n padding: {\n sm: 'p-4 sm:p-5',\n md: 'p-5 sm:p-7',\n lg: 'p-6 sm:p-9',\n },\n },\n defaultVariants: {\n colSpan: 1,\n rowSpan: 1,\n variant: 'default',\n radius: 'lg',\n padding: 'md',\n },\n }\n);\n\nexport interface BentoCardProps\n extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'>,\n VariantProps<typeof bentoCardVariants> {\n title?: React.ReactNode;\n description?: React.ReactNode;\n icon?: React.ReactNode;\n tag?: React.ReactNode;\n /**\n * Decorative background graphic. Non-interactive backdrop element.\n */\n backgroundGraphic?: React.ReactNode;\n /**\n * @deprecated Use `backgroundGraphic` instead.\n */\n graphic?: React.ReactNode;\n}\n\nexport const BentoCard = forwardRef<HTMLDivElement, BentoCardProps>(\n (\n {\n className,\n colSpan,\n rowSpan,\n variant,\n radius,\n padding,\n title,\n description,\n icon,\n tag,\n backgroundGraphic,\n graphic,\n children,\n ...props\n },\n ref\n ) => {\n const bgGraphic = backgroundGraphic ?? graphic;\n\n return (\n <div\n ref={ref}\n className={cn(bentoCardVariants({ colSpan, rowSpan, variant, radius, padding, className }))}\n {...props}\n >\n {/* Subtle Specular Top Line */}\n <div\n className=\"pointer-events-none absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-white/20 to-transparent opacity-50\"\n aria-hidden=\"true\"\n />\n\n {/* Background Visual Graphic Slot (Decorative) */}\n {bgGraphic && (\n <div className=\"absolute inset-0 z-0 overflow-hidden pointer-events-none opacity-70 transition-transform duration-700 ease-out motion-safe:group-hover:scale-105\">\n {bgGraphic}\n </div>\n )}\n\n {/* Top Header Section */}\n {(icon || tag) && (\n <div className=\"relative z-10 flex items-start justify-between gap-4\">\n {icon && (\n <div className=\"flex h-11 w-11 items-center justify-center rounded-2xl bg-[var(--ui-bento-icon-bg)] border border-[var(--ui-bento-icon-border)] backdrop-blur-md shadow-inner transition-transform duration-300 group-hover:scale-105\">\n {icon}\n </div>\n )}\n {tag && (\n <div className=\"font-mono text-[10px] font-semibold uppercase tracking-widest text-[var(--ui-bento-text-tag)] border border-[var(--ui-bento-icon-border)] bg-[var(--ui-bento-icon-bg)] px-2.5 py-1 rounded-md backdrop-blur-sm\">\n {tag}\n </div>\n )}\n </div>\n )}\n\n {/* Main Content Area */}\n <div className=\"relative z-10 mt-auto pt-6\">\n {title && (\n <h3 className=\"text-xl font-bold tracking-tight text-[var(--ui-bento-text-title)] transition-colors group-hover:text-[var(--ui-primary)] dark:group-hover:text-white\">\n {title}\n </h3>\n )}\n {description && (\n <p className=\"mt-2 text-sm leading-relaxed text-[var(--ui-bento-text-desc)] font-normal\">\n {description}\n </p>\n )}\n {children}\n </div>\n </div>\n );\n }\n);\n\nBentoCard.displayName = 'BentoCard';\n"]}
|
package/dist/bento/index.js
CHANGED