Skip to content

Theme & design token

Design token của @tasco/theme là nguồn duy nhất cho màu, font, bo góc và mật độ. Từ token, framework suy ra hai thứ: cấu hình theme cho Ant Design Vue và bộ biến CSS --tasco-*. App không cần cấu hình gì — layer áp sẵn cả hai.

Giá trị token và quy tắc dùng nằm ở khu UI/UX: Màu & tương phản, Chữ, khoảng cách & mật độ. Trang này nói cách theme chạy trong app.

Layer áp theme thế nào

app.vue của layer làm ba việc ở một chỗ:

  1. Bọc app trong <a-config-provider> với token của chế độ hiện tại, thuật toán sáng/tối của antdv và locale vi_VN.
  2. Gắn biến --tasco-* của chế độ hiện tại vào <head> (cssVarsText).
  3. Đặt data-theme="light|dark" trên thẻ <html>.

base.css của @tasco/theme (layer nạp sẵn) bổ sung phần antdv 4 không cấu hình được bằng token: header bảng nền navy, mật độ card/form/bảng/modal, màu chữ antdv tự suy ra ở chế độ tối.

Ghi đè app.vue

Tự tạo app/app.vue thì phải giữ lại cả ba việc trên — thiếu <a-config-provider> là toàn bộ màu, mật độ và tiếng Việt của antdv sai. Chép từ @tasco/nuxt-layer-base/app/app.vue rồi sửa.

Chế độ sáng / tối

Người dùng đổi chế độ bằng nút trên header; lựa chọn lưu ở cookie tasco:theme một năm, nên tải lại trang không bị nháy màu. Chế độ khởi tạo khi chưa có cookie lấy từ app.config.ts:

ts
export default defineAppConfig({
  tasco: { themeMode: 'dark' },
})

Đổi chế độ trong code:

ts
const { mode, isDark, setMode, toggle } = useThemeMode()

setMode('dark')

Chuyển chế độ chỉ đổi giá trị biến --tasco-* và thuật toán màu của antdv — không tải lại trang.

Dùng biến CSS

css
.don-hang__tom-tat {
  color: var(--tasco-color-text);
  background: var(--tasco-color-surface);
  border: 1px solid var(--tasco-color-border);
  padding: calc(var(--tasco-spacing-unit) * 2);
}

Biến đổi giá trị theo chế độ, nên CSS viết một lần chạy đúng cả sáng lẫn tối. Chọn cặp chữ/nền trong bảng cặp dùng được; quy tắc viết CSS: Viết CSS trong dự án.

Dùng token trong TypeScript

Hiếm khi cần — ví dụ màu cho thư viện biểu đồ vẽ trên canvas, không đọc được biến CSS:

ts
import { cssVars } from '@tasco/theme'

const { mode } = useThemeMode()
const palette = computed(() => {
  const vars = cssVars(mode.value)
  return [vars['--tasco-color-primary'], vars['--tasco-color-accent'], vars['--tasco-color-success']]
})

@tasco/theme là dependency của layer nhưng không nằm trong dependencies của app tạo từ CLI — muốn import trực tiếp thì thêm @tasco/theme cùng version với các package @tasco/* khác. Danh sách hàm: @tasco/theme.

Font

Layer tự host Quicksand (chữ thân) và Montserrat (tiêu đề) bằng @nuxt/fonts: lần build đầu tải font về, sau đó phục vụ từ app — không gọi Google Fonts lúc chạy. Máy build không ra được Internet thì phải có sẵn cache font trong node_modules/.cache.

Muốn đổi màu, font hay mật độ

Đổi ở @tasco/theme để mọi app đổi theo, không ghi đè riêng từng dự án — quy trình ở Đổi design token. Dự án chỉ cần khác biệt nhỏ cho một màn hình thì dùng prop của component trước, CSS sau cùng.

Liên quan