Văn bản và kiểu dáng

Định kiểu thẻ triển khai bằng màu sắc, thuộc tính văn bản và token theme.

Ứng dụng của chương này đang chạy trong console của bạn. Mở console bằng ⌘⌥JCtrl+Shift+J⌘⌥KCtrl+Shift+K⌘⌥C (bật tính năng dành cho nhà phát triển trước), rồi dùng thử.
Xem chương3:24

Trong chương này

  • Thuộc tính văn bản
  • Token của theme
  • Thẻ triển khai
  • Theme

Mỗi ô có một ký tự, màu chữ, màu nền và một tập thuộc tính. Text.js biên dịch chúng thành các span CSS %c, nên console hiển thị màu sắc thật, chữ đậm và chữ nghiêng.

Thuộc tính văn bản

<Text> nhận bold, dim, italic, underline và strikethrough. Các phần tử <Text> lồng nhau trở thành các span có định dạng trong cùng một dòng.

<Text>  Deployed <Text bold>acme-web</Text> to <Text color="accent">iad1</Text></Text>

Token của theme

Prop color nhận giá trị hex, tên màu thông thường (emerald) và token của theme; các sắc độ trong bảng màu Tailwind dùng class (text-emerald-400). Token tuân theo theme đang dùng, nên ưu tiên dùng chúng cho màu mang ý nghĩa ngữ nghĩa. Thêm một component trạng thái:

app/status.tsx+15tsx
Đã thêm: import { Text } from "@textjs/app";Đã thêm: Đã thêm: export type DeployStatus = "ready" | "building" | "error" | "queued";Đã thêm: Đã thêm: export const STATUS = {Đã thêm:   ready: { label: "Ready", color: "success" },Đã thêm:   building: { label: "Building", color: "warning" },Đã thêm:   error: { label: "Error", color: "danger" },Đã thêm:   queued: { label: "Queued", color: "subtle" },Đã thêm: } as const;Đã thêm: Đã thêm: export function Status({ status }: { status: DeployStatus }) {Đã thêm:   const s = STATUS[status];Đã thêm:   return <Text color={s.color} wrap="nowrap">{`● ${s.label}`}</Text>;Đã thêm: }

Thẻ triển khai

bg-surface làm thẻ nổi lên khỏi nền. ID triển khai lấy màu trạng thái, chuyển sang chữ nghiêng khi đang build và có gạch ngang khi xảy ra lỗi.

app/page.tsx+23-1tsx
Đã xóa: import { Box, Spacer, Text, useInput } from "@textjs/app";Đã thêm: import { Box, Spacer, Text, useAppTheme, useInput } from "@textjs/app";Đã thêm: import { Status, STATUS, type DeployStatus } from "./status";Đã thêm: Đã thêm: const ORDER: DeployStatus[] = ["ready", "building", "error", "queued"];Đã thêm: export default function Page() {Đã thêm:   const { theme, cycleTheme } = useAppTheme();Đã thêm:   const [status, setStatus] = useState<DeployStatus>("ready");Đã thêm: Đã thêm:   useInput((e) => {Đã thêm:     if (e.input === "t") cycleTheme();Đã thêm:     if (e.input === "s") setStatus((s) => ORDER[(ORDER.indexOf(s) + 1) % ORDER.length]);Đã thêm:   });Đã thêm:   return (    <Box className="flex-col grow">      {/* top bar, now with the theme name on the right */}Đã thêm:       <Box className="flex-col border rounded px-2 py-1 bg-surface">Đã thêm:         <Box className="flex-row gap-2 h-1">Đã thêm:           <Text bold>acme-web</Text>Đã thêm:           <Status status={status} />Đã thêm:         </Box>Đã thêm:         <Text color="muted" wrap="truncate-end">feat: stream cells downward</Text>Đã thêm:         <Text color={STATUS[status].color} italic={status === "building"} strikethrough={status === "error"}>Đã thêm:           dpl_8fK2Đã thêm:         </Text>Đã thêm:       </Box>    </Box>  );}

wrap="truncate-end" kết thúc thông điệp commit dài bằng … thay vì xuống dòng thứ hai.

Theme

Text.js đi kèm năm theme: Geist Dark, OpenCode Dark, Tokyo Night, Amber CRT và Geist Light. Nhấn t trong console để lần lượt chuyển qua các theme. Toàn bộ frame vẽ lại theo bảng màu mới, vì mọi màu ở trên đều là token.

Dùng thử

Đây là Acme Deploys ở cuối chương, đang chạy trong DevTools. Nhấp vào vùng focus, rồi dùng các phím bên dưới.

▼ 03 · Văn bản và kiểu dáng

Mở console

⌘⌥J
CtrlShiftJ
⌘⌥K
CtrlShiftK
⌘⌥C

Ứng dụng render trong DevTools.Trước tiên bật “Hiển thị tính năng cho nhà phát triển web” trong Cài đặt Safari → Nâng cao. Sau đó nhấp vào đây và nhấn t.

Mở trên máy tính

Ứng dụng này render trong console của DevTools, cần trình duyệt trên máy tính.

Bài trắc nghiệm

2 câu hỏi

Trả lời mọi câu hỏi để hoàn thành chương.

Why use color="success" instead of a hex value?

 

What does wrap="truncate-end" do?