@comitor/ui 0.2.1 → 0.3.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/README.md +236 -30
- package/dist/chart/chart-colors.d.ts +56 -0
- package/dist/chart/chart-colors.js +21 -0
- package/dist/chart/chart-colors.js.map +1 -0
- package/dist/chart/chart.d.ts +40 -0
- package/dist/chart/chart.js.map +1 -1
- package/dist/chart/comitor-chart.d.ts +21 -43
- package/dist/chart/comitor-chart.js +13 -24
- package/dist/chart/comitor-chart.js.map +1 -1
- package/dist/chart/index.d.ts +2 -1
- package/dist/chart/index.js +1 -0
- package/dist/chart/index.js.map +1 -1
- package/dist/components/composite/data-table-constants.d.ts +40 -0
- package/dist/components/composite/data-table-constants.js +13 -0
- package/dist/components/composite/data-table-constants.js.map +1 -0
- package/dist/components/composite/data-table.d.ts +2 -27
- package/dist/components/composite/data-table.js +1 -10
- package/dist/components/composite/data-table.js.map +1 -1
- package/dist/components/composite/date-picker-constants.d.ts +21 -0
- package/dist/components/composite/date-picker-constants.js +39 -0
- package/dist/components/composite/date-picker-constants.js.map +1 -0
- package/dist/components/composite/date-picker.d.ts +2 -18
- package/dist/components/composite/date-picker.js +6 -48
- package/dist/components/composite/date-picker.js.map +1 -1
- package/dist/components/composite/form-field-constants.d.ts +26 -0
- package/dist/components/composite/form-field-constants.js +13 -0
- package/dist/components/composite/form-field-constants.js.map +1 -0
- package/dist/components/composite/form-field.d.ts +1 -13
- package/dist/components/composite/form-field.js +1 -11
- package/dist/components/composite/form-field.js.map +1 -1
- package/dist/components/composite/search-filter-bar-constants.d.ts +52 -0
- package/dist/components/composite/search-filter-bar-constants.js +18 -0
- package/dist/components/composite/search-filter-bar-constants.js.map +1 -0
- package/dist/components/composite/search-filter-bar.d.ts +3 -37
- package/dist/components/composite/search-filter-bar.js +2 -15
- package/dist/components/composite/search-filter-bar.js.map +1 -1
- package/dist/components/composite/table-pagination-constants.d.ts +56 -0
- package/dist/components/composite/table-pagination-constants.js +18 -0
- package/dist/components/composite/table-pagination-constants.js.map +1 -0
- package/dist/components/composite/table-pagination.d.ts +2 -43
- package/dist/components/composite/table-pagination.js +4 -15
- package/dist/components/composite/table-pagination.js.map +1 -1
- package/dist/components/ui/badge.js +3 -3
- package/dist/components/ui/badge.js.map +1 -1
- package/dist/components/ui/button.js +4 -4
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/calendar.js +1 -1
- package/dist/components/ui/calendar.js.map +1 -1
- package/dist/components/ui/checkbox.js +2 -2
- package/dist/components/ui/checkbox.js.map +1 -1
- package/dist/components/ui/command.js +1 -1
- package/dist/components/ui/command.js.map +1 -1
- package/dist/components/ui/input-group.js +1 -1
- package/dist/components/ui/input-group.js.map +1 -1
- package/dist/components/ui/input-otp.js +1 -1
- package/dist/components/ui/input-otp.js.map +1 -1
- package/dist/components/ui/navigation-menu.js +1 -1
- package/dist/components/ui/navigation-menu.js.map +1 -1
- package/dist/components/ui/radio-group.js +1 -1
- package/dist/components/ui/radio-group.js.map +1 -1
- package/dist/components/ui/resizable.js +1 -1
- package/dist/components/ui/resizable.js.map +1 -1
- package/dist/components/ui/slider.js +1 -1
- package/dist/components/ui/slider.js.map +1 -1
- package/dist/components/ui/switch.js +1 -1
- package/dist/components/ui/switch.js.map +1 -1
- package/dist/components/ui/textarea.js +1 -1
- package/dist/components/ui/textarea.js.map +1 -1
- package/dist/index.d.ts +11 -6
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/shell/contrast-constants.d.ts +30 -0
- package/dist/shell/contrast-constants.js +16 -0
- package/dist/shell/contrast-constants.js.map +1 -0
- package/dist/shell/contrast-provider.d.ts +60 -0
- package/dist/shell/contrast-provider.js +61 -0
- package/dist/shell/contrast-provider.js.map +1 -0
- package/dist/shell/contrast-toggle.d.ts +24 -0
- package/dist/shell/contrast-toggle.js +29 -0
- package/dist/shell/contrast-toggle.js.map +1 -0
- package/dist/shell/index.d.ts +3 -0
- package/dist/shell/index.js +3 -0
- package/dist/shell/index.js.map +1 -1
- package/dist/shell/shell-context.js +3 -2
- package/dist/shell/shell-context.js.map +1 -1
- package/dist/tokens.d.ts +170 -70
- package/dist/tokens.js +124 -47
- package/dist/tokens.js.map +1 -1
- package/package.json +3 -2
- package/styles.css +255 -120
package/styles.css
CHANGED
|
@@ -29,6 +29,55 @@
|
|
|
29
29
|
cạnh nhau thì phải bọc thêm một lớp: <div class="dark"><div>…</div></div>. */
|
|
30
30
|
@custom-variant dark (&:is(.dark *));
|
|
31
31
|
|
|
32
|
+
/* ════════════════════════════════════════════════════════════════════════════
|
|
33
|
+
NGUỒN SỰ THẬT — ĐỌC TRƯỚC KHI ĐỔI BẤT KỲ GIÁ TRỊ NÀO Ở DƯỚI
|
|
34
|
+
|
|
35
|
+
Bảng màu và style component của gói này KHỚP VỚI comitor-ds (repo design system đã được
|
|
36
|
+
duyệt). comitor-ds là bản duyệt về HÌNH THỨC và nó thắng khi có mâu thuẫn.
|
|
37
|
+
|
|
38
|
+
0.2.x từng đi hướng ngược lại: nó tự sửa một loạt giá trị của comitor-ds để đạt ngưỡng WCAG,
|
|
39
|
+
và hệ quả là app dựng trên gói KHÔNG còn giống bản duyệt — mất gold ở mọi control đang BẬT,
|
|
40
|
+
viền ô nhập đậm hẳn lên, đỏ và chữ phụ tối đi. 0.3.0 kéo tất cả về đúng comitor-ds.
|
|
41
|
+
|
|
42
|
+
─ HAI BẢNG MÀU, MỘT BỘ COMPONENT ─
|
|
43
|
+
Bảng màu đã đo của 0.2.x KHÔNG bị xoá: nó thành bảng thứ hai, bật bằng
|
|
44
|
+
`<html data-contrast="high">` (khối 5b bên dưới), do NGƯỜI DÙNG chọn trong phần cài đặt của
|
|
45
|
+
app. Lý do có nó: bảng comitor-ds đủ rõ trên màn hình tốt nhưng không đủ trên màn hình rẻ,
|
|
46
|
+
độ sáng thấp, hoặc ngoài nắng.
|
|
47
|
+
|
|
48
|
+
Điều kiện để hai bảng cùng sống: MỌI component đi qua TOKEN VAI TRÒ (--control-on,
|
|
49
|
+
--control-edge, --control-check, --switch-track, --slider-track, --primary-ink, --link-ink…)
|
|
50
|
+
chứ không viết thẳng `bg-gold-300` / `bg-ash-300` / `text-gold-400`. Viết thẳng thang màu là
|
|
51
|
+
khoá cứng một bảng và bảng kia lặng lẽ sai — đó là lỗi dễ mắc nhất khi thêm component mới.
|
|
52
|
+
|
|
53
|
+
─ NHỮNG KHOẢN DƯỚI NGƯỠNG CỦA BẢNG MẶC ĐỊNH, ĐÃ BIẾT VÀ ĐÃ CHẤP NHẬN ─
|
|
54
|
+
Ghi ra để không ai tưởng là lỗi bỏ sót và "sửa" lại lần nữa — chỗ để sửa là bảng tương phản
|
|
55
|
+
cao, không phải bảng mặc định. Cột cuối là ngưỡng WCAG mà khoản đó không đạt:
|
|
56
|
+
|
|
57
|
+
viền control (--input / --control-edge) trên nền trang 1,16:1 (1.4.11 · 3:1)
|
|
58
|
+
rãnh Switch BẬT (--control-on) ⇄ nền trang và ⇄ núm 1,86:1 (1.4.11 · 3:1)
|
|
59
|
+
gạch active của Tabs, viền focus ô nhập (gold) 1,86:1 (1.4.11 · 3:1)
|
|
60
|
+
--muted-foreground trên --muted 3,58:1 (1.4.3 · 4,5:1)
|
|
61
|
+
chữ trắng trên nền --destructive 4,38:1 (1.4.3 · 4,5:1)
|
|
62
|
+
Button variant link (--gold-400) trên nền trang 3,15:1 (1.4.3 · 4,5:1)
|
|
63
|
+
Badge destructive: --red trên red/10 3,82:1 (1.4.3 · 4,5:1)
|
|
64
|
+
|
|
65
|
+
─ HAI NGOẠI LỆ GIỮ BẢN SỬA Ở CẢ HAI BẢNG MÀU ─
|
|
66
|
+
Chỉ hai chỗ mà màu chữ của comitor-ds gần trùng màu nền tới mức không đọc nổi trên BẤT KỲ màn
|
|
67
|
+
hình nào, nên chúng không chờ người dùng bật tương phản cao. Nền giữ NGUYÊN của bản duyệt,
|
|
68
|
+
chỉ đậm chữ:
|
|
69
|
+
|
|
70
|
+
Badge warning --yellow trên yellow/10 = 1,52:1 → --yellow-ink = 6,24:1
|
|
71
|
+
Badge success --green trên green/10 = 2,82:1 → --green-ink = 5,88:1
|
|
72
|
+
|
|
73
|
+
─ NGOÀI PHẠM VI ĐỐI CHIẾU ─
|
|
74
|
+
comitor-ds không có các cụm sau, nên không có bản duyệt nào để khớp và chúng giữ nguyên bảng
|
|
75
|
+
màu đã đo của gói: toàn bộ tầng composite (StatusPill, StatCard, DataTable, Toast,
|
|
76
|
+
FilterChips, LetterAvatar, EmptyState…), tầng shell (AppShell, Sidebar, AppLauncher…),
|
|
77
|
+
--app-accent-ink, và thang đổ bóng bản dark (--elevation-* trong .dark — comitor-ds không
|
|
78
|
+
khai bóng cho dark).
|
|
79
|
+
════════════════════════════════════════════════════════════════════════════ */
|
|
80
|
+
|
|
32
81
|
/* ────────────────────────────────────────────────────────────────────────────
|
|
33
82
|
4. BIẾN — LIGHT
|
|
34
83
|
──────────────────────────────────────────────────────────────────────────── */
|
|
@@ -107,8 +156,14 @@
|
|
|
107
156
|
% giữa Badge/LetterAvatar/Input), (c) `tokens.ts` mirror được ra hex thật.
|
|
108
157
|
⚠ Đổi --teal/--green/--red/--yellow thì PHẢI tính lại bậc ink tương ứng — không tự theo.
|
|
109
158
|
|
|
110
|
-
|
|
111
|
-
|
|
159
|
+
⚠ PHẠM VI ÁP DỤNG TỪ 0.3.0: hợp đồng này chỉ còn áp cho các cụm TONAL mà comitor-ds KHÔNG
|
|
160
|
+
có (Badge success/warning, StatusPill, LetterAvatar, StatCard, Toast) — đó là chỗ chữ đứng
|
|
161
|
+
trên tint của chính nó và bậc ink là thứ duy nhất giữ được chữ đọc ra. Với các primitive CÓ
|
|
162
|
+
trong comitor-ds (Button, Input, Switch, Checkbox, Tabs, Alert, Form…), bản duyệt là nguồn
|
|
163
|
+
sự thật và bậc ink đã được gỡ khỏi đường render — xem khối NGUỒN SỰ THẬT ở đầu file.
|
|
164
|
+
|
|
165
|
+
Ở DARK, --x-ink trỏ về var(--x): comitor-ds dùng một hex cho cả hai theme, nên bên dark bậc
|
|
166
|
+
ink chính là màu phụ. */
|
|
112
167
|
--teal-ink: #1a6668;
|
|
113
168
|
--green-ink: #216a48;
|
|
114
169
|
--red-ink: #9a3537;
|
|
@@ -147,47 +202,44 @@
|
|
|
147
202
|
--primary: #e8b824;
|
|
148
203
|
--primary-foreground: #0e1116;
|
|
149
204
|
/* Bậc INK của brand — gold khi nó phải ĐI LÊN nền trang thay vì tô nền. Đúng hợp đồng ba vai
|
|
150
|
-
trò ở khối "Bậc INK của màu phụ" bên trên
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
--
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
--primary-ink: var(--gold-500);
|
|
205
|
+
trò ở khối "Bậc INK của màu phụ" bên trên.
|
|
206
|
+
|
|
207
|
+
⚠ TỪ 0.3.0: --primary-ink TRỎ THẲNG VỀ --primary ở cả hai theme. comitor-ds tô gold #E8B824
|
|
208
|
+
cho mọi vai trò brand — kể cả những vai trò mà WCAG 1.4.11 đòi 3:1 (rãnh Switch BẬT, ô
|
|
209
|
+
Checkbox đã chọn, gạch active của Tabs, viền focus của ô nhập) — và bản duyệt đó là nguồn
|
|
210
|
+
sự thật. Bậc tối #7A5800 mà vòng token trước dùng cho các vai trò này ĐÃ ĐƯỢC GỠ; số đo còn
|
|
211
|
+
tồn: gold trên nền trắng 1,86:1 (dưới 3:1). Xem khối NGUỒN SỰ THẬT ở đầu file.
|
|
212
|
+
|
|
213
|
+
Token vẫn TỒN TẠI như API công khai (app đang import `text-primary-ink`) và vẫn là chỗ để
|
|
214
|
+
app ghi đè nếu muốn một bậc tối hơn cho brand của mình. Chỗ DUY NHẤT trong gói còn giữ bậc
|
|
215
|
+
tối là --app-accent-ink (accent theo app, không có bản duyệt nào để khớp) và ba tone tonal
|
|
216
|
+
của Badge/StatusPill. */
|
|
217
|
+
--primary-ink: var(--primary);
|
|
164
218
|
--secondary: #ede8d8;
|
|
165
219
|
--secondary-foreground: #0e1116;
|
|
166
220
|
--muted: #f7f7f8;
|
|
167
|
-
/* Bậc chữ phụ (placeholder, mô tả, nhãn trục biểu đồ)
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
#686C7A = 5,23:1 trên --background · 4,89:1 trên --muted · 5,01:1 trên --sidebar. */
|
|
172
|
-
--muted-foreground: #686c7a;
|
|
221
|
+
/* Bậc chữ phụ (placeholder, mô tả, nhãn trục biểu đồ). Giá trị của comitor-ds, bằng đúng
|
|
222
|
+
--ash-500. Số đo còn tồn (dưới AA 4,5:1 — ĐÃ BIẾT VÀ CHẤP NHẬN, xem khối NGUỒN SỰ THẬT ở
|
|
223
|
+
đầu file): 3,83:1 trên --background · 3,58:1 trên --muted · 3,67:1 trên --sidebar. */
|
|
224
|
+
--muted-foreground: #7e8290;
|
|
173
225
|
--accent: #fbf5dc;
|
|
174
226
|
--accent-foreground: #0e1116;
|
|
175
|
-
/* Đỏ dùng làm NỀN (nút xoá, chấm huy hiệu)
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
chart-5), còn màu để làm CHỮ đỏ là --red-ink / --destructive-ink ngay dưới. */
|
|
180
|
-
--destructive: #c93b3b;
|
|
227
|
+
/* Đỏ dùng làm NỀN (nút xoá, chấm huy hiệu). Giá trị của comitor-ds, ghim cho cả hai theme và
|
|
228
|
+
BẰNG ĐÚNG --red (bản duyệt không tách hai bậc). Số đo còn tồn: chữ trắng trên nền này được
|
|
229
|
+
4,38:1 — thiếu 0,12 so với AA 4,5:1. Xem khối NGUỒN SỰ THẬT ở đầu file. */
|
|
230
|
+
--destructive: #d64545;
|
|
181
231
|
--destructive-foreground: #ffffff;
|
|
182
|
-
/*
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
232
|
+
/* Nền nút xoá lúc HOVER. Phải là token riêng vì hai bảng màu đi hai HƯỚNG ngược nhau:
|
|
233
|
+
comitor-ds viết `hover:bg-red/90`, tức NHẠT dần về phía nền — #DA5A5A là đúng thứ nó render
|
|
234
|
+
trên trang trắng. Bảng tương phản cao thì phải ĐẬM thêm, nếu không chữ trắng tụt xuống
|
|
235
|
+
4,32:1. Ghim hex thay vì `/90` vì `/90` phụ thuộc nền phía sau: trên nền tối nó cho ra một
|
|
236
|
+
màu khác hẳn và không ai đo được. */
|
|
237
|
+
--destructive-hover: #da5a5a;
|
|
238
|
+
/* Chữ báo lỗi trên nền TRANG (helper text của Input, dòng lỗi của Form). comitor-ds viết thẳng
|
|
239
|
+
`text-destructive` / `border-red` cho vai trò này, tức CÙNG một hex với nền đỏ — nên token
|
|
240
|
+
trỏ về --destructive. Số đo: 4,38:1 trên --background (light) · 4,06:1 trên --card (dark).
|
|
241
|
+
Token giữ lại vì là API công khai và là chỗ app ghi đè nếu muốn bậc đỏ tối hơn. */
|
|
242
|
+
--destructive-ink: var(--destructive);
|
|
191
243
|
/* ─ RANH GIỚI: HAI VAI TRÒ, HAI TOKEN, TUYỆT ĐỐI ĐỪNG LẪN ─
|
|
192
244
|
|
|
193
245
|
--border (+ --sidebar-border) VIỀN TRANG TRÍ. Đường kẻ chia, khung Card lúc nghỉ, vạch
|
|
@@ -198,74 +250,73 @@
|
|
|
198
250
|
light #EDEEF1 trên trắng = 1,16:1 · dark #1E2128 trên #0E1116 = 1,17:1
|
|
199
251
|
dark #1E2128 trên --card #16181D = 1,10:1 · --sidebar-border/--sidebar = 1,11:1
|
|
200
252
|
|
|
201
|
-
--control-edge (
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
253
|
+
--control-edge (= --input) VIỀN CONTROL. TỪ 0.3.0 token này TRỎ VỀ --input, tức bằng
|
|
254
|
+
đúng bậc trang trí của comitor-ds (#EDEEF1 light · #1E2128 dark). Bản duyệt vẽ viền ô
|
|
255
|
+
nhập ở bậc đó và bản duyệt là nguồn sự thật; số đo còn tồn là 1,16:1, dưới 3:1 của
|
|
256
|
+
WCAG 1.4.11 — xem khối NGUỒN SỰ THẬT ở đầu file.
|
|
257
|
+
Dùng cho: Input/Textarea/Select/Combobox, ô Checkbox chưa chọn, viền Radio, rãnh
|
|
258
|
+
Slider, Button variant outline/secondary, Badge variant outline, ô tìm của
|
|
259
|
+
WorkspaceSwitcher. (Rãnh Switch khi TẮT KHÔNG đi qua đây — comitor-ds dùng
|
|
260
|
+
`bg-gray-300 dark:bg-gray-700`, xem switch.tsx.)
|
|
206
261
|
|
|
207
|
-
--control-edge-strong Cùng vai trò nhưng ở HOVER/ACTIVE
|
|
208
|
-
|
|
209
|
-
|
|
262
|
+
--control-edge-strong Cùng vai trò nhưng ở HOVER/ACTIVE. Giá trị của comitor-ds:
|
|
263
|
+
`hover:border-gray-300` ở light (--ash-300) và `dark:hover:border-gray-500` ở dark
|
|
264
|
+
(--ash-500).
|
|
210
265
|
|
|
211
266
|
⚠ `@layer base { * { @apply border-border } }` ở mục 7 gán viền TRANG TRÍ cho MỌI phần tử.
|
|
212
267
|
Control nào chỉ viết `border` mà không nêu màu sẽ lặng lẽ nhận bậc 1,16:1 — luôn phải nêu
|
|
213
268
|
`border-input` / `border-control-edge` tường minh. Bảng đầy đủ: docs/hop-dong-mau.md §3. */
|
|
214
269
|
--border: #edeef1;
|
|
215
|
-
/* Viền ô nhập
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
270
|
+
/* Viền ô nhập — giá trị của comitor-ds, cùng bậc với --border. Khối .dark khai lại (#1E2128). */
|
|
271
|
+
--input: #edeef1;
|
|
272
|
+
/* LỚP TÔ của ô nhập ở dark — comitor-ds viết `dark:bg-input/30`, và nó không phải trang trí:
|
|
273
|
+
ở dark viền --input (#1E2128) trên --card (#16181D) chỉ 1,10:1, nên lớp tô mờ này là thứ
|
|
274
|
+
DUY NHẤT còn khoanh vùng được ô Radio và ô OTP. Phải là token riêng chứ không viết thẳng
|
|
275
|
+
`bg-input/30`: ở bảng tương phản cao --input là #7E8290, tô 30% ra một mảng xám sáng làm
|
|
276
|
+
placeholder tụt còn 3,22:1 — bên đó viền đã đủ đậm nên lớp tô thành trong suốt.
|
|
277
|
+
Ở light comitor-ds không tô (class chỉ có nhánh `dark:`) nên giá trị này không được dùng. */
|
|
278
|
+
--input-fill: transparent;
|
|
219
279
|
--ring: #e8b824;
|
|
220
280
|
|
|
221
|
-
/* --
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
MỘT giá trị chạy được cả hai theme nên không cần biến thể dark:
|
|
230
|
-
|
|
231
|
-
light: --background 3,83 · --card 3,83 · --muted 3,58 · --sidebar 3,67 · --accent 3,50
|
|
232
|
-
· --secondary 3,13 · núm (trắng) 3,83:1 ✓
|
|
233
|
-
dark : --background 4,94 · --card 4,64 · --popover 4,64 · --muted 4,21 · --sidebar 4,64
|
|
234
|
-
· núm (#0E1116) 4,94:1 ✓
|
|
235
|
-
|
|
236
|
-
⚠ Chú thích bản trước ghi "núm Switch tô trắng ở CẢ hai theme" và kèm dải L cho dark — SAI cả
|
|
237
|
-
hai: núm là `bg-background` nên ở dark nó là #0E1116 (xem --control-knob), tức ở dark ràng
|
|
238
|
-
buộc phía núm TRÙNG với ràng buộc phía nền, không có chặn trên nào. Bỏ hẳn dải L: đó đúng là
|
|
239
|
-
chỗ số đã sai một lần; giữ phép đo tương phản là đủ và không tự mâu thuẫn. */
|
|
240
|
-
--control-edge: #7e8290;
|
|
241
|
-
/* Hover/active của viền control. Light = --ash-700, dark = --ash-300 — đúng thứ `Checkbox` đang
|
|
242
|
-
viết tay bằng `border-ash-700 dark:border-ash-300`; token hoá để Input/Select/Combobox khỏi
|
|
243
|
-
chép lệch (Select hiện đang sai chiều: hover NHẠT hơn lúc nghỉ).
|
|
244
|
-
light #3A3F4A: --background 10,55 · --muted 9,86 · --sidebar 10,11 · --secondary 8,61:1 ✓
|
|
245
|
-
dark #C8CBD3: --background 11,65 · --card 10,94 · --muted 9,93:1 ✓ */
|
|
246
|
-
--control-edge-strong: var(--ash-700);
|
|
281
|
+
/* Trỏ về --input, không còn là một bậc xám riêng. Token giữ lại vì component trong gói đang
|
|
282
|
+
viết `border-control-edge` và vì app có thể ghi đè MỘT chỗ này để làm đậm viền control mà
|
|
283
|
+
không đụng đường kẻ trang trí (--border). Số đo còn tồn: 1,16:1 light · 1,17:1 dark. */
|
|
284
|
+
--control-edge: var(--input);
|
|
285
|
+
/* Hover/active của viền control — đúng cặp của comitor-ds: `hover:border-gray-300` (ash-300,
|
|
286
|
+
#C8CBD3) ở light và `dark:hover:border-gray-500` (ash-500, #7E8290) ở dark. Token hoá để
|
|
287
|
+
Input/Select/Combobox/Checkbox khỏi chép lệch. */
|
|
288
|
+
--control-edge-strong: var(--ash-300);
|
|
247
289
|
|
|
248
290
|
/* ─ CONTROL Ở TRẠNG THÁI BẬT / ĐÃ CHỌN ─
|
|
249
|
-
Rãnh `Switch` khi BẬT, ô `Checkbox` đã chọn, chấm `Radio`, đoạn đã chọn của `Slider`.
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
--control-on
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
--control-
|
|
291
|
+
Rãnh `Switch` khi BẬT, ô `Checkbox` đã chọn, chấm `Radio`, đoạn đã chọn của `Slider`.
|
|
292
|
+
|
|
293
|
+
comitor-ds tô GOLD cho toàn bộ nhóm này (`data-[state=checked]:bg-gold-300`), nên --control-on
|
|
294
|
+
trỏ thẳng về --primary. Số đo còn tồn, ghi ra để không ai tưởng là bỏ sót: rãnh BẬT so với nền
|
|
295
|
+
trang 1,86:1 và so với núm trắng cũng 1,86:1 (dưới 3:1 của WCAG 1.4.11) — tức ở light, BẬT/TẮT
|
|
296
|
+
phân biệt chủ yếu bằng VỊ TRÍ núm và bằng sắc, không bằng độ sáng. Đây là đánh đổi ĐÃ CHỌN, xem
|
|
297
|
+
khối NGUỒN SỰ THẬT ở đầu file.
|
|
298
|
+
|
|
299
|
+
--control-knob là NÚM Switch / chấm Radio: TRẮNG ở cả hai theme, đúng `bg-white` của bản duyệt.
|
|
300
|
+
⚠ DẤU CHECK của Checkbox KHÔNG dùng token này — comitor-ds vẽ nó bằng `text-ink` trên nền gold
|
|
301
|
+
(10,19:1), xem checkbox.tsx.
|
|
302
|
+
⚠ App ghi đè --primary là control đổi màu theo ngay, không cần ghi đè thêm gì. */
|
|
303
|
+
--control-on: var(--primary);
|
|
304
|
+
--control-knob: #ffffff;
|
|
305
|
+
/* DẤU CHECK của Checkbox và chữ trên ô ngày ĐANG CHỌN của Calendar — tách khỏi --control-knob
|
|
306
|
+
vì hai vai trò đòi hai chiều tương phản khác nhau khi --control-on đổi giữa hai bảng màu:
|
|
307
|
+
bảng comitor-ds tô nền gold SÁNG nên dấu phải là MỰC (10,19:1); bảng tương phản cao tô nền
|
|
308
|
+
gold-500 TỐI nên dấu phải là màu nền trang (6,51:1). Núm Switch thì luôn trắng ở bảng duyệt,
|
|
309
|
+
nên nó ở lại --control-knob. */
|
|
310
|
+
--control-check: var(--ink);
|
|
311
|
+
/* Rãnh Switch khi TẮT và rãnh Slider — comitor-ds cho hai thứ này hai bậc khác nhau
|
|
312
|
+
(`bg-gray-300 dark:bg-gray-700` cho Switch, `bg-muted` cho Slider) nên phải là hai token,
|
|
313
|
+
không gộp được vào --control-edge. */
|
|
314
|
+
--switch-track: var(--ash-300);
|
|
315
|
+
--slider-track: var(--muted);
|
|
316
|
+
/* Button variant `link`. Tách khỏi --primary-ink vì comitor-ds dùng gold-400 cho chữ link
|
|
317
|
+
nhưng gold-300 cho viền focus/vạch active — hai bậc khác nhau của cùng thang. */
|
|
318
|
+
--link-ink: var(--gold-400);
|
|
319
|
+
--link-ink-hover: var(--gold-300);
|
|
269
320
|
|
|
270
321
|
--sidebar: #fafaf9;
|
|
271
322
|
--sidebar-foreground: #0e1116;
|
|
@@ -360,7 +411,11 @@
|
|
|
360
411
|
đo, mà đây đúng là chỗ 0.1.0 đã ngã. */
|
|
361
412
|
--app-accent: var(--primary);
|
|
362
413
|
--app-accent-foreground: var(--primary-foreground);
|
|
363
|
-
|
|
414
|
+
/* Bậc ink của accent app là chỗ DUY NHẤT còn giữ bậc tối sau khi 0.3.0 kéo --primary-ink về
|
|
415
|
+
gold: vai trò của nó là icon/vạch active của SidebarMenuItem và khung icon của PageHeader —
|
|
416
|
+
những cụm CHỈ có trong gói, comitor-ds không có bản duyệt nào để khớp. Gold đặc trên
|
|
417
|
+
--sidebar-accent #FBF5DC chỉ 1,70:1 (icon biến mất), gold-500 được 5,96:1. */
|
|
418
|
+
--app-accent-ink: var(--gold-500);
|
|
364
419
|
|
|
365
420
|
/* ─ Số đo khung ứng dụng (shell dùng ở cả CSS lẫn TS — xem tokens.ts) ─ */
|
|
366
421
|
--sidebar-width: 16rem; /* 256px */
|
|
@@ -381,7 +436,9 @@
|
|
|
381
436
|
overlay — lớp phủ lên nội dung (Dialog, Sheet, Popover, menu, Select, Tooltip) */
|
|
382
437
|
--elevation-surface: 0 1px 2px rgba(14, 17, 22, 0.04);
|
|
383
438
|
--elevation-control: 0 1px 2px rgba(14, 17, 22, 0.08);
|
|
384
|
-
|
|
439
|
+
/* Lớp thứ hai để 0.06 — đúng thứ Card variant="elevated" của comitor-ds render
|
|
440
|
+
(bản duyệt khai --shadow-card 0.04 nhưng không component nào đọc biến đó). */
|
|
441
|
+
--elevation-card: 0 1px 2px rgba(14, 17, 22, 0.04), 0 8px 24px rgba(14, 17, 22, 0.06);
|
|
385
442
|
--elevation-overlay: 0 8px 32px rgba(14, 17, 22, 0.16);
|
|
386
443
|
|
|
387
444
|
--radius: 0.375rem; /* 6px — chữ ký thị giác của Comitor */
|
|
@@ -405,23 +462,27 @@
|
|
|
405
462
|
--secondary: #1e2128;
|
|
406
463
|
--secondary-foreground: #f7f7f8;
|
|
407
464
|
--muted: #1e2128;
|
|
408
|
-
/*
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
#0E1116 của dark). "Tình cờ" là chữ đúng: đây là token CHỮ, ràng buộc phía núm KHÔNG được
|
|
413
|
-
bảo đảm ở đây — chỗ cần rãnh control phải dùng --control-edge. */
|
|
414
|
-
--muted-foreground: #888d9b;
|
|
465
|
+
/* Cùng một giá trị với bản light — comitor-ds không khai lại token này trong .dark. Số đo còn
|
|
466
|
+
tồn (dưới AA, ĐÃ BIẾT VÀ CHẤP NHẬN): 4,21:1 trên --muted · 4,73:1 trên --card. Xem khối
|
|
467
|
+
NGUỒN SỰ THẬT ở đầu file. */
|
|
468
|
+
--muted-foreground: #7e8290;
|
|
415
469
|
--accent: #1e2128;
|
|
416
470
|
--accent-foreground: #f7f7f8;
|
|
417
|
-
/* Ghim đúng giá trị của light —
|
|
418
|
-
--destructive: #
|
|
471
|
+
/* Ghim đúng giá trị của light — comitor-ds dùng chung một hex cho cả hai theme. */
|
|
472
|
+
--destructive: #d64545;
|
|
419
473
|
--destructive-foreground: #ffffff;
|
|
420
474
|
--border: #1e2128;
|
|
421
|
-
/*
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
--
|
|
475
|
+
/* Viền ô nhập bản dark của comitor-ds. --control-edge trỏ vào --input nên tự theo; --control-on
|
|
476
|
+
và --control-knob cũng không khai lại (chúng trỏ vào --primary — đã có bản dark ngay trên —
|
|
477
|
+
và vào trắng cố định, đúng như núm Switch của comitor-ds). */
|
|
478
|
+
--input: #1e2128;
|
|
479
|
+
--input-fill: color-mix(in srgb, var(--input) 30%, transparent);
|
|
480
|
+
/* Hover viền control bản dark của comitor-ds là dark:hover:border-gray-500, tức ash-500. */
|
|
481
|
+
--control-edge-strong: var(--ash-500);
|
|
482
|
+
/* Rãnh Switch khi TẮT bản dark của comitor-ds (dark:bg-gray-700). --slider-track không khai lại
|
|
483
|
+
vì nó trỏ vào --muted, biến đã có bản dark ngay trong khối này. --control-check cũng vậy:
|
|
484
|
+
comitor-ds vẽ dấu check bằng text-ink ở CẢ hai theme. */
|
|
485
|
+
--switch-track: var(--ash-700);
|
|
425
486
|
--ring: #f5d060;
|
|
426
487
|
|
|
427
488
|
--sidebar: #16181d;
|
|
@@ -430,17 +491,13 @@
|
|
|
430
491
|
--sidebar-accent: #1e2128;
|
|
431
492
|
--sidebar-accent-foreground: #f7f7f8;
|
|
432
493
|
|
|
433
|
-
/* Màu phụ bản dark —
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
--red: #f87171;
|
|
437
|
-
--green: #4ade80;
|
|
438
|
-
--yellow: #facc15;
|
|
494
|
+
/* Màu phụ KHÔNG có bản dark — comitor-ds dùng đúng một hex cho cả hai theme, và bản này theo.
|
|
495
|
+
Số đo trên tint /20 hợp lên --card (đọc được, tuy dưới AA ở hai tone): teal 3,39 · green 4,26
|
|
496
|
+
· red 3,34 · yellow 7,02:1.
|
|
439
497
|
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
chính nó ở --card: teal/15 7,12 · green/15 7,44 · red/15 5,18 · yellow/20 7,19:1 ✓ */
|
|
498
|
+
Bậc ink ở dark PHẢI khai lại (chứ không để rơi về hex của :root) vì bản light của --*-ink là
|
|
499
|
+
bậc tối đóng băng cho vai trò chữ-trên-nền-sáng; bỏ dòng nào thì bên dark rơi về đúng bậc tối
|
|
500
|
+
đó và chìm nghỉm vào nền. Trỏ về chính màu phụ = đúng thứ comitor-ds render ở dark. */
|
|
444
501
|
--teal-ink: var(--teal);
|
|
445
502
|
--green-ink: var(--green);
|
|
446
503
|
--red-ink: var(--red);
|
|
@@ -449,6 +506,9 @@
|
|
|
449
506
|
ink gánh vai trò đó (7,40:1 trên --background · 6,95:1 trên --card), và --chart-3 vì trỏ vào
|
|
450
507
|
--navy-ink nên tự đúng, không cần khai lại ở đây nữa. */
|
|
451
508
|
--navy-ink: #7ea2e8;
|
|
509
|
+
/* Accent app tách khỏi --primary-ink (xem :root): ở dark gold-500 chìm vào nền, nên bậc sáng
|
|
510
|
+
của brand gánh vai trò này. */
|
|
511
|
+
--app-accent-ink: var(--primary);
|
|
452
512
|
|
|
453
513
|
/* KHÔNG khai lại --*-foreground của trạng thái và của màu phụ: chúng là MỰC (#0E1116) ở cả hai
|
|
454
514
|
theme vì cả hai bản màu đều sáng — xem bảng số ở :root. --navy-foreground cũng vậy (trắng),
|
|
@@ -464,6 +524,74 @@
|
|
|
464
524
|
--elevation-overlay: 0 8px 32px rgba(0, 0, 0, 0.64);
|
|
465
525
|
}
|
|
466
526
|
|
|
527
|
+
/* ────────────────────────────────────────────────────────────────────────────
|
|
528
|
+
5b. BẢNG MÀU THỨ HAI — TƯƠNG PHẢN CAO `<html data-contrast="high">`
|
|
529
|
+
|
|
530
|
+
Bảng mặc định (khối 4 và 5) là comitor-ds: đẹp, đúng brand, và có một số cặp nằm dưới ngưỡng
|
|
531
|
+
WCAG — trên màn hình tốt thì không thành vấn đề, trên màn hình rẻ / độ sáng thấp / ngoài nắng
|
|
532
|
+
thì thành vấn đề thật. Khối này là bảng màu đã đo của 0.2.x, bật theo LỰA CHỌN CỦA NGƯỜI DÙNG.
|
|
533
|
+
|
|
534
|
+
─ CÁCH BẬT ─
|
|
535
|
+
`<ContrastProvider>` của @comitor/ui/shell gắn `data-contrast="high"` lên <html> (kèm script
|
|
536
|
+
chống nháy, cùng lối với next-themes). App chỉ cần bọc provider và đặt `<ContrastToggle>` vào
|
|
537
|
+
trang cài đặt — KHÔNG app nào tự khai lại màu.
|
|
538
|
+
|
|
539
|
+
─ VÌ SAO CHỈ KHAI LẠI BIẾN, KHÔNG ĐỘNG VÀO COMPONENT ─
|
|
540
|
+
Mọi component trong gói đi qua TOKEN VAI TRÒ (--control-on, --control-edge, --control-check,
|
|
541
|
+
--primary-ink, --link-ink…) chứ không viết thẳng `bg-gold-300`. Nhờ vậy hai bảng màu chỉ khác
|
|
542
|
+
nhau ở khối này; không có nhánh `data-contrast:` nào rải trong component, và cũng không có cách
|
|
543
|
+
nào để một bảng màu "quên" một component.
|
|
544
|
+
|
|
545
|
+
⚠ ĐỘ ĐẶC TẢ: [data-contrast="high"] và .dark cùng là (0,1,0). Khối này phải đứng SAU .dark để
|
|
546
|
+
thắng ở những token nó khai; token nào bản dark của bảng tương phản cao khác bản light thì
|
|
547
|
+
PHẢI khai lại ở .dark[data-contrast="high"] (0,2,0) bên dưới. Đảo thứ tự hai khối là hỏng.
|
|
548
|
+
──────────────────────────────────────────────────────────────────────────── */
|
|
549
|
+
[data-contrast="high"] {
|
|
550
|
+
/* Chữ phụ: 5,23:1 trên --background · 4,89:1 trên --muted (bảng duyệt: 3,83 / 3,58) */
|
|
551
|
+
--muted-foreground: #686c7a;
|
|
552
|
+
/* Nền đỏ + chữ trắng: 5,03:1 (bảng duyệt #D64545 chỉ 4,38:1) */
|
|
553
|
+
--destructive: #c93b3b;
|
|
554
|
+
/* Ngược chiều bảng duyệt: color-mix(--destructive, --ink 15%) — chữ trắng 6,19:1 */
|
|
555
|
+
--destructive-hover: #ad3535;
|
|
556
|
+
--destructive-ink: var(--red-ink);
|
|
557
|
+
/* Viền control: 3,83:1 trên nền trắng (bảng duyệt #EDEEF1 chỉ 1,16:1).
|
|
558
|
+
--control-edge trỏ vào --input nên tự theo. */
|
|
559
|
+
--input: #7e8290;
|
|
560
|
+
/* Viền đã đủ đậm ở cả hai theme nên bỏ hẳn lớp tô — nó chỉ làm placeholder khó đọc. */
|
|
561
|
+
--input-fill: transparent;
|
|
562
|
+
--control-edge-strong: var(--ash-700);
|
|
563
|
+
/* Control BẬT/ĐÃ CHỌN: rãnh ⇄ nền 6,51:1 và rãnh ⇄ núm 6,51:1 (bảng duyệt: 1,86 / 1,86) */
|
|
564
|
+
--control-on: var(--gold-500);
|
|
565
|
+
--control-knob: var(--background);
|
|
566
|
+
--control-check: var(--control-knob);
|
|
567
|
+
--switch-track: var(--control-edge);
|
|
568
|
+
--slider-track: var(--control-edge);
|
|
569
|
+
/* Brand khi phải ĐI LÊN nền trang: viền focus, gạch active của Tabs, ngày chọn của Calendar */
|
|
570
|
+
--primary-ink: var(--gold-500);
|
|
571
|
+
--link-ink: var(--gold-500);
|
|
572
|
+
--link-ink-hover: var(--gold-600);
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
.dark[data-contrast="high"] {
|
|
576
|
+
/* Sáng hơn bản light: chữ phụ ở dark hay nằm trên --card/--muted chứ ít khi trên nền trang.
|
|
577
|
+
5,70:1 trên --background · 5,35:1 trên --card · 4,86:1 trên --muted */
|
|
578
|
+
--muted-foreground: #888d9b;
|
|
579
|
+
/* Viền control ghim MỘT giá trị cho cả hai theme: 4,94:1 trên nền #0E1116 */
|
|
580
|
+
--input: #7e8290;
|
|
581
|
+
--control-edge-strong: var(--ash-300);
|
|
582
|
+
/* Bảng màu dark đã nâng --primary lên bậc sáng nên bậc ink trỏ thẳng về nó: 12,67:1 */
|
|
583
|
+
--control-on: var(--primary);
|
|
584
|
+
--primary-ink: var(--primary);
|
|
585
|
+
--link-ink: var(--gold-200);
|
|
586
|
+
--link-ink-hover: var(--gold-100);
|
|
587
|
+
/* Màu phụ bản dark — bản light quá tối để làm CHỮ trên nền #0E1116. Đo trên tint /15 hợp lên
|
|
588
|
+
--card: teal 7,12 · green 7,44 · red 5,18 · yellow /20 7,19:1 ✓ */
|
|
589
|
+
--teal: #2dd4bf;
|
|
590
|
+
--red: #f87171;
|
|
591
|
+
--green: #4ade80;
|
|
592
|
+
--yellow: #facc15;
|
|
593
|
+
}
|
|
594
|
+
|
|
467
595
|
/* ────────────────────────────────────────────────────────────────────────────
|
|
468
596
|
6. MAP BIẾN → NAMESPACE TAILWIND (sinh bg-*, text-*, border-*, rounded-*…)
|
|
469
597
|
|
|
@@ -501,6 +629,7 @@
|
|
|
501
629
|
--color-accent-foreground: var(--accent-foreground);
|
|
502
630
|
--color-destructive: var(--destructive);
|
|
503
631
|
--color-destructive-foreground: var(--destructive-foreground);
|
|
632
|
+
--color-destructive-hover: var(--destructive-hover);
|
|
504
633
|
--color-destructive-ink: var(--destructive-ink);
|
|
505
634
|
/* Ranh giới: `border-border` là TRANG TRÍ (không ngưỡng) · `border-input` /
|
|
506
635
|
`border-control-edge` là VIỀN CONTROL (3:1) · `border-control-edge-strong` cho hover/active.
|
|
@@ -508,10 +637,16 @@
|
|
|
508
637
|
--color-border: var(--border);
|
|
509
638
|
--color-input: var(--input);
|
|
510
639
|
--color-ring: var(--ring);
|
|
640
|
+
--color-input-fill: var(--input-fill);
|
|
511
641
|
--color-control-edge: var(--control-edge);
|
|
512
642
|
--color-control-edge-strong: var(--control-edge-strong);
|
|
513
643
|
--color-control-on: var(--control-on);
|
|
514
644
|
--color-control-knob: var(--control-knob);
|
|
645
|
+
--color-control-check: var(--control-check);
|
|
646
|
+
--color-switch-track: var(--switch-track);
|
|
647
|
+
--color-slider-track: var(--slider-track);
|
|
648
|
+
--color-link-ink: var(--link-ink);
|
|
649
|
+
--color-link-ink-hover: var(--link-ink-hover);
|
|
515
650
|
|
|
516
651
|
/* Sidebar */
|
|
517
652
|
--color-sidebar: var(--sidebar);
|