Nền tảng
Biểu tượng
Comitor chỉ dùng Lucide React. Thư viện này có bộ icon nét đồng nhất, hợp với hình học gọn gàng của Inter. lucide-react là peer dependency bắt buộc của @comitor/ui — một bản duy nhất trong bundle, gói và app dùng chung.
Chỉ dùng Lucide
Mọi icon trên mọi bề mặt sản phẩm Comitor phải lấy từ lucide-react. Không thư viện icon nào khác — không hero-icons, không font-awesome, không SVG tự vẽ trong chữ giao diện.
Bộ Lucide đầy đủ có hơn 1.500 icon, đủ cho mọi nhu cầu UI thông thường. Nếu Lucide không có icon cần dùng, mở một issue cho design system trước khi tự vẽ.
Lucide đã lên v1 — icon thương hiệu không còn
Số phiên bản nhảy từ 0.x lên 1.x mà không đổi API của icon, vì vậy gói khai peer là >=0.540.0. Thứ v1 thực sự đổi là bộ icon: các icon thương hiệu và logo của bên thứ ba đã bị gỡ. Import một icon như vậy là lỗi build, không phải một glyph bị thiếu.
| Bị gỡ ở v1 | Hệ thống này dùng thay | Vì sao |
|---|---|---|
| Github | GitBranch | Một dấu kho mã chung chung. Đọc vẫn đúng trong mục điều hướng và không bị ảnh hưởng khi bộ icon đổi lần nữa. |
| Figma | Component | Đại diện cho link tới nguồn thiết kế mà không mượn logo của bên thứ ba. |
Vài tên cũ vẫn còn dưới dạng alias đã ngừng dùng — Loader2 vẫn trỏ tới LoaderCircle, AlertCircle tới CircleAlert. Mã mới viết tên của v1.
Lưới kích cỡ
12px
Chevron và chấm trạng thái trong các hàng dày đặc
size-314px
Trong nút nhỏ và phần addon của input group
size-3.516px
Mặc định — mục điều hướng, nhãn, mọi chỗ không ghi cỡ
size-420px
Icon của thẻ, icon của callout
size-524px
Trạng thái trống, điểm nhấn tính năng
size-632px
Icon hero, minh hoạ lớn
size-8Cỡ icon lấy từ thang khoảng cách, không phải thang chữ. Nhờ vậy trục cỡ chữ di chuyển icon và nhãn cùng nhau: ở bậc lớn, icon size-4 to lên cùng nhãn 16px bên cạnh, thay vì đứng yên trong khi nhãn phình ra.
Tự định cỡ
Hai mươi mốt chỗ trong mười một họ component mang [&_svg:not([class*='size-'])]:size-4— hàng menu và command, trigger và mục của Select, ItemMedia, addon của InputGroup, ButtonGroupText, link của NavigationMenu, Toggle, và nút đóng của Dialog. Một icon đặt vào một trong những chỗ đó mà không có class cỡ riêng sẽ hiện ở 16px, nên ghi rõ size-4 ở đó là thừa, còn size-5 thì thật sự ghi đè.
Button cố ý không nằm trong số đó: nó đặt khe hở và cỡ chữ nhưng không áp gì lên svg con, nên icon trong nút giữ cỡ mặc định 24px của Lucide cho tới khi được định cỡ. Cho nó một class size-*, hoặc prop size khi nó đi qua leftIcon / rightIcon.
Màu icon theo hợp đồng màu
Lucide vẽ bằng stroke="currentColor", nên icon lấy màu chữ của thứ chứa nó. Vì vậy hợp đồng ba vai trò áp dụng y nguyên — và cũng có nghĩa là trình biên dịch không thấy được lựa chọn sai.
Truyền icon vào component
Các component shell nhận icon — mục điều hướng, mô tả app, mục thanh bên — nhận tham chiếu tới component chứ không nhận phần tử đã render, để chúng tự áp class cỡ và màu của mình lên icon.
import type { NavItem } from '@comitor/ui/shell'
import { LayoutDashboard } from 'lucide-react'
// The slot takes the COMPONENT, not an element:
// icon: LayoutDashboard ✓
// icon: <LayoutDashboard /> ✗
const item: NavItem = {
id: 'overview',
label: 'Overview',
href: '/tasks',
icon: LayoutDashboard,
}
// The slot's type is ShellIcon = LucideIcon | ComponentType<{ className?: string }>,
// so a custom SVG wrapper that accepts className fits the same slot.Icon mẫu — mặc định 16px
Nét và cách dùng
Nên
- Giữ độ dày nét ở mặc định 2 của Lucide trong mọi UI sản phẩm.
- Đi kèm icon với một nhãn chữ nhìn thấy được khi dùng trong điều hướng.
- Cho control chỉ có icon một tên truy cập —
aria-labelhoặc chữ ẩn khỏi mắt nhìn. - Định cỡ icon trong Button một cách tường minh — 14px trong nút nhỏ — và để hàng menu, addon và Select thừa hưởng cỡ tự động 16px.
Không nên
- Đừng đổi độ dày nét — nó phá sự đồng nhất thị giác giữa các bề mặt.
- Đừng dùng icon làm vật trang trí lấp chỗ mà không mang nghĩa.
- Đừng trộn Lucide với bất kỳ thư viện icon nào khác trên cùng một bề mặt.
- Đừng tô một icon mang nghĩa bằng token fill — nó sẽ không đạt 3:1.