Layout với Box

Dựng khung bảng điều khiển bằng Flexbox theo ô: thanh trên cùng, thanh bên và các thẻ.

Ứ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:39

Trong chương này

  • Thanh trên cùng
  • Thanh bên và thẻ
  • Tự thích ứng theo mặc định

Console là một lưới ô. Text.js dùng Yoga để bố trí lưới, cùng bộ máy flexbox mà React Native sử dụng, nên <Box> tuân theo quy tắc flexbox của CSS. Đơn vị là ô: p-1 tạo khoảng đệm một cột và một hàng.

Thanh trên cùng

Hầu hết màn hình có dạng một cột: một thanh cao một hàng, rồi đến phần còn lại. Đặt chiều cao cố định cho thanh bằng h-1 và để nội dung chiếm phần còn lại bằng grow.

app/page.tsx+8-4tsx
Đã xóa: import { Box, Text, useInput } from "@textjs/app";Đã thêm: import { Box, Spacer, Text, useInput } from "@textjs/app";export default function Page() {  return (Đã xóa:     <Box className="flex-col border rounded px-2 py-1">Đã xóa:       <Text bold>▼ Acme Deploys</Text>Đã xóa:       <Text color="muted">Hello, console.</Text>Đã thêm:     <Box className="flex-col grow">Đã thêm:       <Box className="flex-row h-1 px-1 gap-2 shrink-0">Đã thêm:         <Text bold>▼ Acme</Text>Đã thêm:         <Text color="subtle">acme.local</Text>Đã thêm:         <Spacer />Đã thêm:       </Box>Đã thêm:       <Box className="flex-row grow">{/* sidebar + cards */}</Box>    </Box>  );}

<Spacer> là một hộp tự giãn: mọi thứ phía sau nó đều bị đẩy sang mép phải.

Thêm một thanh bên có chiều rộng cố định với đường viền bên phải và ba thẻ chia nhau chiều rộng còn lại. basis-0 kết hợp với grow chia đều chiều rộng cho mỗi thẻ bất kể nội dung.

app/page.tsx+31-1tsx
Đã thêm: const NAV = ["Overview", "Deployments", "Settings"];Đã thêm: Đã thêm: function Card({ title, value }: { title: string; value: string }) {Đã thêm:   return (Đã thêm:     <Box className="flex-col border rounded px-1 grow shrink basis-0" minWidth={14} minHeight={4}>Đã thêm:       <Text color="subtle">{title}</Text>Đã thêm:       <Text bold>{value}</Text>Đã thêm:     </Box>Đã thêm:   );Đã thêm: }Đã thêm: export default function Page() {Đã thêm:   const [sidebar, setSidebar] = useState(true);Đã thêm:   const [stacked, setStacked] = useState(false);Đã thêm: Đã thêm:   useInput((e) => {Đã thêm:     if (e.input === "s") setSidebar((v) => !v);Đã thêm:     if (e.input === "d") setStacked((v) => !v);Đã thêm:   });Đã thêm:   return (    <Box className="flex-col grow">      {/* top bar */}Đã xóa:       <Box className="flex-row grow">{/* sidebar + cards */}</Box>Đã thêm:       <Box className="flex-row grow">Đã thêm:         {sidebar && (Đã thêm:           <Box className="flex-col w-18 shrink-0 border-r px-1 pt-1">Đã thêm:             {NAV.map((item) => <Text key={item}>{item}</Text>)}Đã thêm:           </Box>Đã thêm:         )}Đã thêm:         <Box className={stacked ? "flex-col grow gap-1 p-1" : "flex-row grow items-start gap-1 p-1"}>Đã thêm:           <Card title="Production" value="acme-web" />Đã thêm:           <Card title="Deployments" value="6 today" />Đã thêm:           <Card title="Build time" value="38s p50" />Đã thêm:         </Box>Đã thêm:       </Box>    </Box>  );}

Nhấn s và d trong console. Yoga tính lại layout và chỉ vẽ lại những hàng đã thay đổi, nên bật tắt thanh bên chỉ tốn một lần gọi console.log.

Tự thích ứng theo mặc định

Lưới thay đổi theo bảng DevTools đang neo. Kéo console rộng hơn hoặc cao hơn và các thẻ sẽ tự sắp xếp lại. Khi bạn cần breakpoint, useBreakpoint() trả về breakpoint hiện tại, tính bằng ô.

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.

▼ 02 · Layout với Box

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 s.

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.

Trong các tiện ích className, p-1 nghĩa là gì?

 

Lớp nào cho phép hộp chiếm phần không gian còn lại?