使用 Box 配置版面

使用 Flexbox,以儲存格為單位建立儀表板外框:頂端列、側邊欄與卡片。

本章的應用程式正在你的主控台執行。按 ⌘⌥JCtrl+Shift+J⌘⌥KCtrl+Shift+K⌘⌥C 開啟主控台(先啟用開發者功能),然後試用。
觀看本章3:39

本章內容

  • 頂端列
  • 側邊欄與卡片
  • 預設支援響應式版面配置

主控台是由儲存格組成的網格。Text.js 使用 Yoga 配置版面,這也是 React Native 使用的 flexbox 引擎,因此 <Box> 遵循 CSS flexbox 規則。單位是儲存格:p-1 表示一欄寬、一列高的內距。

頂端列

多數畫面採垂直排列:先放一列高的頂端列,其餘內容接在下方。使用 h-1 固定頂端列的高度,再用 grow 讓內容佔滿剩餘空間。

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

<Spacer> 是會擴展的方塊:放在後面的內容都會推到右側邊緣。

加入帶有右邊框的固定寬度側邊欄,以及平分剩餘寬度的三張卡片。basis-0 搭配 grow 可讓每張卡片獲得相同寬度,不受內容影響。

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

在主控台按下 s 和 d。Yoga 會重新計算版面配置,並且只重繪有變動的列,因此切換側邊欄只需呼叫一次 console.log。

預設支援響應式版面配置

網格會配合停駐的 DevTools 面板調整。拖曳主控台使其變寬或變高,卡片就會重新排列。需要斷點時,useBreakpoint() 會回傳目前的斷點,以儲存格為單位。

試用

這是本章結束時的 Acme Deploys,正在 DevTools 中執行。點擊操作區,再使用下方按鍵。

▼ 02 · 使用 Box 配置版面

開啟主控台

⌘⌥J
CtrlShiftJ
⌘⌥K
CtrlShiftK
⌘⌥C

應用程式在 DevTools 中渲染。先在 Safari「設定」→「進階」中開啟「顯示網頁開發者功能」。 接著點擊這裡並按 s。

在電腦上開啟

此應用程式在 DevTools 主控台中渲染,需要桌面版瀏覽器。

測驗

2 個問題

回答所有問題以完成本章。

className 工具類別中的 p-1 代表什麼?

 

哪個類別能讓方塊佔用剩餘空間?