Hệ thống thiết kế
Panel người dùng (cổng 2083) và panel quản trị (cổng 2087) dùng chung một hệ thống thiết kế: một bộ token (CSS custom property) và một bộ component (class CSS) chỉ được xây dựng từ các token đó. Nó tồn tại để một nút, một bảng hay một modal trông và hoạt động giống nhau trên mọi trang của cả hai panel, ở chế độ sáng và tối và trong mọi giao diện panel.
| Panel người dùng | Panel quản trị | |
|---|---|---|
| Tệp | hitechcloudpanel/static/css/design-system/ | hitechcloudadmin/static/css/design-system/ |
| Được liên kết từ | internal/web/templates/base.html | internal/webtemplates/_layout.html |
| URL | /static/css/design-system/index.css | /static/css/design-system/index.css |
Ba tệp này giống hệt nhau từng byte ở cả hai kho. Hãy thay đổi chúng ở cả hai, trong cùng một thay đổi.
| Tệp | Nội dung |
|---|---|
index.css | Điểm vào: import hai tệp bên dưới. Đây là tệp duy nhất mà layout liên kết tới. |
tokens.css | Mọi custom property --ds-*, giá trị sáng trên :root, giá trị tối trên .dark. |
components.css | Mọi class ds-*, bên trong layer components của Tailwind. |
Nguyên tắc
- Doanh nghiệp và giản dị. Màu phẳng, viền mảnh, bóng đổ trung tính nhẹ. Không pha trộn màu, không neon hay phát sáng, không làm mờ trong suốt ("glassmorphism"), không chuyển động trang trí.
- Chỉ dùng token. Một component không bao giờ ghi trực tiếp một giá trị màu, kích thước hay thời lượng; nó đọc một token. Thay đổi một token sẽ thay đổi mọi component.
- Tự chọn dùng, không hồi quy. Mọi class bắt đầu bằng
ds-, và không gì trong các tệp khớp với phần tử hay class mà một trang đang dùng. Liên kết stylesheet không thay đổi trang hiện có nào; một trang áp dụng hệ thống bằng cách dùng các class. - Một component, một class. Biến thể là modifier (
ds-btn--danger), các phần là con (ds-modal__footer). Đừng tạo nút, thẻ hay huy hiệu thứ hai: hãy mở rộng cái hiện có bằng một modifier. - Utility vẫn thắng. Các component nằm trong cascade layer
componentsmàoutput.csscủa Tailwind khai báo (nó được tải trước), nên một utility trên cùng phần tử sẽ ghi đè chúng:class="ds-btn w-full"là một nút rộng toàn phần. - Sẵn sàng cho chiều phải sang trái. Component dùng logical property
(
inline-start/inline-end), nên trang códir="rtl"tự lật mà không cần thêm quy tắc. - Dễ tiếp cận theo mặc định. Token văn bản giữ độ tương phản tối thiểu 4.5:1 trên các
bề mặt mà chúng được dùng; mọi component tương tác đều có vòng
:focus-visiblenhìn thấy được; trạng thái được đọc từ thuộc tính ARIA nếu có.
Chế độ tối và giao diện panel
Chế độ tối là class .dark trên <html>, công tắc mà cả hai panel đã dùng.
Mọi token màu đều có giá trị tối.
Các giao diện panel (data-theme-brand trên <html>: mặc định, kiểu cPanel,
kiểu DirectAdmin, kiểu Plesk, HiTechCloud 2) công bố màu của chúng dưới dạng
thuộc tính --tb-* trong brand-themes.css (panel người dùng) và themes.css (panel
quản trị). Các token thiết kế phụ thuộc thương hiệu đọc chúng trước và quay về
diện mạo mặc định:
--ds-color-primary: var(--tb-primary, #2563eb);
--ds-surface: var(--tb-card, #ffffff);
--ds-surface-sidebar: var(--tb-sidebar, #ffffff);
Vì vậy ds-btn--primary có màu cam trong kiểu cPanel và màu xanh trong
kiểu DirectAdmin mà không cần quy tắc riêng cho từng giao diện. Giao diện mới chỉ cần định nghĩa
các token --tb-* của mình.
Token
Kiểu chữ
Bộ font là bộ font giao diện hệ thống và monospace: không tải web font nào.
| Token | Giá trị | Dùng cho |
|---|---|---|
--ds-font-sans | bộ font giao diện hệ thống | Mọi văn bản |
--ds-font-mono | bộ font monospace hệ thống | Đường dẫn, khoá, mã, nhật ký |
--ds-text-2xs | 11px | Overline, chú thích dày đặc |
--ds-text-xs | 12px | Văn bản trợ giúp, huy hiệu, header bảng |
--ds-text-sm | 13px | Ô bảng, văn bản phụ |
--ds-text-base | 14px | Văn bản thân và điều khiển |
--ds-text-md | 16px | Tiêu đề thẻ, văn bản dẫn |
--ds-text-lg | 18px | Tiêu đề mục |
--ds-text-xl | 20px | Tiêu đề modal |
--ds-text-2xl | 24px | Tiêu đề trang |
--ds-text-3xl | 30px | Số liệu trên bảng điều khiển |
--ds-leading-tight / -snug / -normal | 1.25 / 1.375 / 1.5 | Tiêu đề / nhãn / thân |
--ds-weight-regular … -bold | 400, 500, 600, 700 | |
--ds-tracking-tight / -normal / -wide | -0.01em / 0 / 0.04em | Tiêu đề lớn / thân / nhãn viết hoa |
Class văn bản: ds-h1 … ds-h4, ds-body, ds-small, ds-caption,
ds-overline, ds-mono, ds-link.
Màu sắc
Token ngữ nghĩa; hãy dùng chúng, không dùng dải xám thô (--ds-gray-0 …
--ds-gray-950), trong component.
| Token | Sáng | Tối | Dùng cho |
|---|---|---|---|
--ds-color-primary | màu chính của giao diện, nếu không thì #2563eb | màu chính của giao diện, nếu không thì #2563eb | Nút chính, trạng thái được chọn, dấu đang hoạt động |
--ds-color-primary-hover / -active | #1d4ed8 / #1e40af | như trên | |
--ds-color-primary-subtle (+ -border, -text) | màu chính ở 8% trên bề mặt | màu chính ở 22% | Hàng và tuỳ chọn được chọn, huy hiệu chính; một sắc phẳng, nên đi theo giao diện |
--ds-color-on-primary | #ffffff | #ffffff | Văn bản trên nền màu chính (5.2:1) |
--ds-color-link | màu liên kết của giao diện, nếu không thì #1d4ed8 | màu liên kết của giao diện, nếu không thì #93c5fd | Liên kết, văn bản tab đang hoạt động |
--ds-surface-page | màu trang của giao diện, nếu không thì #f8fafc | #0b1120 | Nền trang |
--ds-surface | màu thẻ của giao diện, nếu không thì #ffffff | #111827 | Thẻ, ô nhập, bảng |
--ds-surface-raised | #ffffff | #1f2937 | Menu, modal, toast |
--ds-surface-sunken | #f1f5f9 | #0f172a | Header bảng, chân, vùng lõm |
--ds-surface-hover / -selected / -disabled | Nền tương tác | ||
--ds-surface-inverse | #1e293b | #f1f5f9 | Tooltip |
--ds-surface-overlay | slate ở 50% | gần đen ở 70% | Nền phủ của modal và drawer |
--ds-surface-header / -sidebar | thanh trên / thanh bên của giao diện | Khung giao diện | |
--ds-text | #0f172a (17.9:1) | #f1f5f9 (16.2:1) | Văn bản chính |
--ds-text-secondary | #475569 | #cbd5e1 | Văn bản phụ |
--ds-text-muted | #586579 (5.4:1 trên bề mặt lõm) | #94a3b8 | Văn bản trợ giúp, chú thích |
--ds-text-disabled | #94a3b8 | #64748b | Chỉ cho điều khiển bị vô hiệu |
--ds-border | màu viền của giao diện, nếu không thì #e2e8f0 | #1f2937 | Đường kẻ thẻ và bảng |
--ds-border-strong / -hover | #cbd5e1 / #94a3b8 | #374151 / #4b5563 | Viền điều khiển |
--ds-focus-color, --ds-focus-ring | màu chính | màu liên kết sáng hơn | Vòng focus: khoảng hở 2px + vòng 2px |
Mỗi màu trạng thái có bốn phần: màu đặc (biểu tượng, viền, nền), màu văn bản giữ 4.5:1 trên bề mặt nhạt tương ứng và trên nền trắng, một bề mặt nhạt và một viền nhạt.
| Trạng thái | Đặc | Văn bản | Nhạt | Viền |
|---|---|---|---|---|
| success | --ds-success | --ds-success-text | --ds-success-subtle | --ds-success-border |
| warning | --ds-warning | --ds-warning-text | --ds-warning-subtle | --ds-warning-border |
| danger | --ds-danger (+ -hover, -active) | --ds-danger-text | --ds-danger-subtle | --ds-danger-border |
| info | --ds-info | --ds-info-text | --ds-info-subtle | --ds-info-border |
| neutral | --ds-neutral | --ds-neutral-text | --ds-neutral-subtle | --ds-neutral-border |
Đừng bao giờ dùng màu làm tín hiệu duy nhất: huy hiệu trạng thái giữ chữ của nó, lỗi giữ thông báo của nó.
Biểu đồ: --ds-chart-1 … --ds-chart-8 là các chuỗi phân loại, theo thứ tự
(xanh dương, xanh mòng két, hổ phách, tím, hồng, xanh lá, lục lam, slate), với giá trị sáng hơn ở
chế độ tối; --ds-chart-grid và --ds-chart-axis tô màu khung biểu đồ. Biểu đồ
một chuỗi dùng --ds-chart-1.
Khoảng cách
Lưới 4px: --ds-space-0, -px, -0-5 (2px), -1 (4px), -1-5 (6px),
-2 (8px), -3 (12px), -4 (16px), -5 (20px), -6 (24px), -8 (32px),
-10 (40px), -12 (48px), -16 (64px).
Chiều cao điều khiển giúp mọi component dạng ô nhập thẳng hàng trên một dòng:
--ds-control-sm 32px, --ds-control-md 38px (mặc định), --ds-control-lg
44px (cũng là vùng chạm tối thiểu).
Bo góc
| Token | Giá trị | Dùng cho |
|---|---|---|
--ds-radius-none | 0 | |
--ds-radius-sm | 4px | Checkbox, huy hiệu nhỏ |
--ds-radius-md | 6px | Nút, ô nhập, mục menu |
--ds-radius-lg | 8px | Thẻ, menu, toast, bảng |
--ds-radius-xl | 12px | Modal |
--ds-radius-full | viên thuốc | Huy hiệu, công tắc, spinner |
Bóng đổ
Nhẹ, trung tính và chỉ để thể hiện độ nổi: --ds-shadow-xs (điều khiển, thẻ),
-sm (thẻ khi di chuột), -md (tooltip), -lg (menu, toast), -xl (modal,
drawer), -none. Chế độ tối dùng bóng đậm và dày hơn.
Z-index
| Token | Giá trị | Lớp |
|---|---|---|
--ds-z-base | 0 | |
--ds-z-raised | 10 | Mục đang focus nằm trên các mục bên cạnh |
--ds-z-sticky | 20 | Header bảng dính, thao tác biểu mẫu dính |
--ds-z-header | 40 | Header trang |
--ds-z-sidebar | 45 | Thanh bên |
--ds-z-dropdown | 1000 | Menu, listbox |
--ds-z-drawer | 1100 | Drawer |
--ds-z-modal-backdrop / --ds-z-modal | 1200 / 1210 | Modal |
--ds-z-popover | 1300 | Popover nằm trên modal |
--ds-z-tooltip | 1400 | Tooltip |
--ds-z-toast | 1500 | Toast, luôn nằm trên cùng |
Các giá trị lớp phủ nằm trên khung giao diện hiện có (Tailwind z-50), nên một
modal của hệ thống thiết kế che được thanh bên và header hiện tại.
Chuyển động
| Token | Giá trị | Dùng cho |
|---|---|---|
--ds-duration-fast | 120ms | Di chuột, focus, màu |
--ds-duration-base | 200ms | Menu, tooltip, công tắc |
--ds-duration-slow | 300ms | Modal, drawer |
--ds-ease-standard / -enter / -exit | đường cong cubic-bezier | Di chuyển / xuất hiện / rời đi |
Với prefers-reduced-motion: reduce, mọi thời lượng trở thành 0, skeleton ngừng
nh ấp nháy, và spinner vẫn quay (vì chúng mang ý nghĩa) ở nửa tốc độ.
Trạng thái
Mọi component thể hiện trạng thái theo cùng một cách. Hãy ưu tiên thuộc tính ARIA: nó vừa tạo kiểu cho component vừa báo cho công nghệ hỗ trợ cùng lúc.
| Trạng thái | Selector | Ghi chú |
|---|---|---|
| Mặc định | class trần | |
| Di chuột | :hover | Chỉ component tương tác |
| Focus | :focus-visible | --ds-focus-ring; không bao giờ bỏ nó |
| Đang hoạt động | :active; lâu dài: aria-selected, aria-current, aria-pressed, aria-expanded, .is-active | |
| Bị vô hiệu | :disabled, aria-disabled="true", .is-disabled | Dùng --ds-text-disabled / --ds-surface-disabled; con trỏ not-allowed |
| Đang tải | aria-busy="true", .is-loading | Một spinner hoặc nhấp nháy; chặn tương tác |
| Lỗi | aria-invalid="true", .is-error | Viền/màu danger; đi kèm một thông báo |
| Thành công | .is-success | Viền/màu success |
Component
Mỗi mục liệt kê các class và markup cần dùng. Chú thích phía trên mỗi
phần của components.css lặp lại markup đó.
Nút
<button class="ds-btn ds-btn--primary">Save</button>
<button class="ds-btn">Cancel</button>
<button class="ds-btn ds-btn--danger">Delete</button>
<button class="ds-btn ds-btn--ghost ds-btn--icon" aria-label="Refresh"><i class="bi bi-arrow-clockwise"></i></button>
<button class="ds-btn ds-btn--primary" aria-busy="true" disabled>Saving</button>
Biến thể --primary (một nút cho mỗi màn hình), --secondary (diện mạo mặc định),
--ghost, --danger, --link; kích thước --sm, --lg; --icon (vuông, cần
aria-label), --block (rộng toàn phần). Gom nhóm bằng ds-btn-group. Khi đang tải,
nút giữ độ rộng của nhãn và vẽ spinner đè lên; kết hợp với
disabled để thao tác không thể chạy hai lần.
Ô nhập và textarea
<input class="ds-input" type="text">
<textarea class="ds-input ds-textarea"></textarea>
<div class="ds-input-group"><span class="ds-input-group__addon">https://</span><input class="ds-input"></div>
<div class="ds-input-wrap" aria-busy="true"><input class="ds-input"></div>
Kích thước --sm, --lg; --mono cho đường dẫn và khoá. Ô nhập chỉ đọc dùng
bề mặt lõm. Lỗi: aria-invalid="true". Đang tải: bọc trong
ds-input-wrap với aria-busy.
Select
<div class="ds-select"><select>...</select></div>
Phần bọc vẽ mũi tên (không dùng hình ảnh), nên nó theo màu
văn bản trong mọi giao diện. Trạng thái đặt trên select (disabled,
aria-invalid) hoặc phần bọc (.is-error, .is-loading).
Combobox
<div class="ds-combobox">
<input class="ds-input" role="combobox" aria-expanded="true" aria-controls="lb" aria-activedescendant="o2">
<ul class="ds-listbox" role="listbox" id="lb">
<li class="ds-option" role="option" id="o1">example.com</li>
<li class="ds-option is-active" role="option" id="o2" aria-selected="true">example.net</li>
</ul>
</div>
Listbox hiển thị khi ô nhập có aria-expanded="true". .is-active là
tuỳ chọn đang được tô sáng bằng bàn phím; aria-selected là tuỳ chọn đã chọn.
ds-listbox__empty / __status cho "không khớp" và "đang tìm". Listbox có thể
dùng lại độc lập (cho tự động hoàn thành dưới bất kỳ trường nào).
Checkbox và radio
<label class="ds-check"><input type="checkbox" class="ds-checkbox"> Enable backups</label>
<label class="ds-check"><input type="radio" class="ds-radio" name="php"> PHP 8.3</label>
Checkbox trạng thái không xác định được vẽ (input.indeterminate = true). Một
ds-check__hint dưới nhãn thêm phần mô tả. Gom chúng trong một
ds-fieldset có legend.
Công tắc
<label class="ds-check"><input type="checkbox" role="switch" class="ds-switch"> Force HTTPS</label>
Công tắc áp dụng ngay lập tức; hãy dùng checkbox khi lựa chọn được lưu cùng một
biểu mẫu. Trong lúc thay đổi đang được áp dụng, đặt aria-busy="true".
Tab
<div class="ds-tabs" role="tablist">
<button class="ds-tab" role="tab" aria-selected="true">General</button>
<button class="ds-tab" role="tab" aria-selected="false">Logs <span class="ds-tab__count">3</span></button>
</div>
Liên kết dùng làm tab dùng aria-current="page". ds-tabs--pills cho diện mạo
phân đoạn dùng cho bộ lọc.
Menu thả xuống
<div class="ds-dropdown ds-dropdown--end">
<button class="ds-btn" aria-haspopup="menu" aria-expanded="false">Actions</button>
<div class="ds-menu" role="menu">
<p class="ds-menu__label">Site</p>
<button class="ds-menu__item" role="menuitem">Edit</button>
<div class="ds-menu__separator" role="separator"></div>
<button class="ds-menu__item ds-menu__item--danger" role="menuitem">Delete</button>
</div>
</div>
Menu hiển thị khi phần tử kích hoạt có aria-expanded="true" (hoặc dropdown
có .is-open).
Modal
<div class="ds-modal-backdrop">
<div class="ds-modal" role="dialog" aria-modal="true" aria-labelledby="t">
<div class="ds-modal__header"><h2 class="ds-modal__title" id="t">Delete site</h2></div>
<div class="ds-modal__body">...</div>
<div class="ds-modal__footer">
<button class="ds-btn">Cancel</button>
<button class="ds-btn ds-btn--danger">Delete</button>
</div>
</div>
</div>
Ẩn bằng thuộc tính hidden trên nền phủ. Một
<dialog class="ds-modal"> gốc mở bằng showModal() cũng hoạt động. Kích thước --sm, --lg,
--xl; --danger cho xác nhận mang tính phá huỷ. Nút ở chân: thao tác
chính đặt cuối cùng.
Drawer
<div class="ds-modal-backdrop ds-drawer-backdrop">
<aside class="ds-drawer" role="dialog" aria-modal="true">header / body / footer as the modal</aside>
</div>
Mở từ phía inline end; ds-drawer--start mở từ phía inline start,
--lg rộng hơn. Nó dùng lại các phần header, body và footer của modal.
Tooltip
<span class="ds-tooltip-wrap">
<button class="ds-btn ds-btn--ghost ds-btn--icon" aria-label="Help" aria-describedby="tt"><i class="bi bi-question-circle"></i></button>
<span class="ds-tooltip" role="tooltip" id="tt">Shown on hover and on keyboard focus</span>
</span>
--bottom đặt nó ở bên dưới. Đừng bao giờ đặt bản duy nhất của thông tin quan trọng
trong tooltip.
Toast
<div class="ds-toast-region" aria-live="polite">
<div class="ds-toast ds-toast--success" role="status">
<div class="ds-toast__body"><p class="ds-toast__title">Saved</p><p class="ds-toast__text">The site configuration was updated.</p></div>
</div>
</div>
Biến thể --info, --success, --warning, --danger (dùng role="alert"),
--loading (spinner). Toast dành cho thông báo thoáng qua; thông báo cần
ở lại trên trang là một alert.
Alert
<div class="ds-alert ds-alert--warning" role="alert">
<div class="ds-alert__body"><p class="ds-alert__title">Certificate expires in 5 days</p><p>Renew it from SSL.</p></div>
</div>
Biến thể --info, --success, --warning, --danger; ds-alert__actions
cho các nút bên trong.
Huy hiệu
<span class="ds-badge ds-badge--success ds-badge--dot">Running</span>
Biến thể --primary, --info, --success, --warning, --danger;
--square, --dot. Huy hiệu là liên kết hoặc nút sẽ có tr ạng thái di chuột và focus.
Thẻ
<section class="ds-card">
<header class="ds-card__header"><h3 class="ds-card__title">Disk</h3></header>
<div class="ds-card__body">...</div>
<footer class="ds-card__footer">...</footer>
</section>
a.ds-card hoặc ds-card--interactive là liên kết toàn thẻ có trạng thái di chuột, focus
và active. ds-card__body--flush cho bảng chạy sát mép thẻ.
ds-stat (__label, __value, __meta) bên trong thẻ là một số liệu bảng điều khiển.
Bảng
<div class="ds-table-wrap">
<table class="ds-table">
<thead><tr><th aria-sort="ascending"><button class="ds-table__sort">Domain</button></th><th class="ds-num">Size</th></tr></thead>
<tbody><tr aria-selected="true"><td>example.com</td><td class="ds-num">1.2 GB</td></tr></tbody>
</table>
</div>
Phần bọc cuộn ngang thay vì làm rộng trang; header dính lại.
--compact, --striped; ds-num căn phải số liệu, ds-actions cho các thao tác
của hàng. Trống: một hàng có ô ds-table__empty chứa một
ds-empty ds-empty--compact. Đang tải: aria-busy trên bảng, hoặc các hàng skeleton.
Phân trang
<nav class="ds-pagination" aria-label="Pagination">
<span class="ds-pagination__info">1-20 of 312</span>
<a class="ds-page" href="?p=1" aria-label="Previous">‹</a>
<a class="ds-page" aria-current="page">2</a>
<span class="ds-page ds-page--gap">…</span>
</nav>
Breadcrumb
<nav class="ds-breadcrumb" aria-label="Breadcrumb">
<ol><li><a href="/">Home</a></li><li><a href="/sites">Sites</a></li><li><a aria-current="page">example.com</a></li></ol>
</nav>
Dấu phân cách được vẽ và tự lật trên trang chiều phải sang trái.
Thanh bên và header
<nav class="ds-sidebar" aria-label="Main">
<p class="ds-sidebar__section">Websites</p>
<a class="ds-nav-item" href="/sites" aria-current="page"><i class="bi bi-globe"></i><span>Sites</span></a>
</nav>
<header class="ds-header">
<div class="ds-header__start">...</div>
<div class="ds-header__end">...</div>
</header>
Cả hai đọc token thanh bên và thanh trên của giao diện (--tb-sidebar*,
--tb-topbar*), nên thanh bên màu xanh navy đậm của một giao diện không cần quy tắc thêm. Hàng tiêu đề
riêng của một trang là ds-page-header (__title, __text, __actions).
Biểu mẫu
<form class="ds-form">
<div class="ds-field is-error">
<label class="ds-label" for="d">Domain <span class="ds-required" aria-hidden="true">*</span></label>
<input class="ds-input" id="d" aria-invalid="true" aria-describedby="d-help d-err">
<p class="ds-help" id="d-help">Without www.</p>
<p class="ds-field__error" id="d-err">This domain is already in use.</p>
</div>
<div class="ds-form__actions"><button class="ds-btn ds-btn--primary">Add</button></div>
</form>
ds-form__row xếp các trường cạnh nhau và xuống dòng trên màn hình hẹp;
ds-form__section gom chúng dưới một ds-form__section-title;
ds-form__actions--sticky giữ các thao tác luôn hiển thị trên biểu mẫu dài. Trường
sở hữu trạng thái của nó: .is-error hiển thị ds-field__error và tô màu điều khiển,
.is-success hiển thị ds-field__success. Biểu mẫu đang bận (aria-busy) chặn các
trường của nó.
Tải tệp lên
<label class="ds-dropzone">
<input type="file" class="ds-visually-hidden" multiple>
<span class="ds-dropzone__title">Drop files or <span class="ds-link">browse</span></span>
<span class="ds-dropzone__hint">Up to 50 MB each</span>
</label>
<ul class="ds-file-list">
<li class="ds-file"><span class="ds-file__name">backup.tar.gz</span><span class="ds-file__meta">42%</span>
<div class="ds-progress"><div class="ds-progress__bar" style="width:42%"></div></div></li>
</ul>
Script thêm .is-dragover khi một tệp được giữ trên vùng thả. Mỗi hàng tệp
nhận .is-error / .is-success.
Biểu đồ
<figure class="ds-chart">
<figcaption class="ds-chart__header">
<span class="ds-chart__title">CPU</span>
<ul class="ds-legend"><li><span class="ds-legend__swatch" style="--_c: var(--ds-chart-1)"></span>Used</li></ul>
</figcaption>
<div class="ds-chart__canvas"><canvas></canvas></div>
</figure>
Thư viện biểu đồ lấy màu từ các token lúc vẽ, ví dụ
getComputedStyle(document.documentElement).getPropertyValue('--ds-chart-1'),
và vẽ lại khi .dark thay đổi. Trạng thái: aria-busy (khung giữ chỗ nhấp nháy),
.is-empty, .is-error. Mục chú giải bật/tắt một chuỗi là button.ds-legend__item
với aria-pressed.
Đang tải
ds-spinner (--sm, --lg, với role="status" và một aria-label);
ds-progress với ds-progress__bar (role="progressbar" và
aria-valuenow), .is-indeterminate khi chưa biết mức độ,
.is-success / .is-error / --warning; ds-loading-overlay phủ một
container đã định vị.
Skeleton
ds-skeleton với --text, --title, --circle, --block: các hình xám
chỉ nhấp nháy độ mờ, thay thế cho nội dung đang tải. Trong lúc đó, đánh dấu
container bằng aria-busy="true".
Trạng thái trống
<div class="ds-empty">
<div class="ds-empty__icon"><i class="bi bi-globe"></i></div>
<h3 class="ds-empty__title">No sites yet</h3>
<p class="ds-empty__text">Add a site to start serving it.</p>
<div class="ds-empty__actions"><a class="ds-btn ds-btn--primary" href="/sites/new">Add site</a></div>
</div>
--compact bên trong thẻ và bảng; .is-error cho "không tải được".
Áp dụng hệ thống trên một trang
- Dùng các class
ds-*trong template; giữ utility của Tailwind cho bố cục (grid, flex, margin). - Thay điều khiển tự viết của trang bằng component, không phải bằng một bản sao của nó.
Nếu component còn thiếu gì đó, hãy thêm một modifier vào
components.cssở cả hai panel. - Trang có đầu ra thay đổi có chủ ý thì chụp lại golden của nó
(
hitechcloudpanel/engine/tests/goldens/legacy,TZ=UTC, xemengine/tests/goldens.rs); hãy nói rõ trong pull request.
Thay đổi hệ thống
- Thêm hoặc đổi một token trong
tokens.css, kèm giá trị tối của nó, và kiểm tra độ tương phản của mọi token văn bản với các bề mặt mà nó được dùng. - Giữ
components.csskhông có giá trị màu trực tiếp, pha trộn màu và làm mờ. - Sao chép các tệp đã thay đổi sang panel kia trong cùng thay đổi; hai bản sao phải giống hệt nhau.
- Cập nhật trang này.
- Nguyên tắc
- Chế độ tối và giao diện panel
- Token
- Kiểu chữ
- Màu sắc
- Khoảng cách
- Bo góc
- Bóng đổ
- Z-index
- Chuyển động
- Trạng thái
- Component
- Nút
- Ô nhập và textarea
- Select
- Combobox
- Checkbox và radio
- Công tắc
- Tab
- Menu thả xuống
- Modal
- Drawer
- Tooltip
- Toast
- Alert
- Huy hiệu
- Thẻ
- Bảng
- Phân trang
- Breadcrumb
- Thanh bên và header
- Biểu mẫu
- Tải tệp lên
- Biểu đồ
- Đang tải
- Skeleton
- Trạng thái trống
- Áp dụng hệ thống trên một trang
- Thay đổi hệ thống