跳到內容
欄目
語言,而家係廣東話
Rastrillo 設計系統

展示

砌成一個畫面嘅嗰啲細塊講法:狀態、身分、進度,同唯一嗰種提示形狀。

每個例子都真係用得,不過入面啲連結唔會帶你去邊度。 HTML 顯示可以複製嘅標記。

status-pill

記錄狀態用有底色嘅膠囊標籤顯示,有顏色亦有文字。

預覽

neutral

<span rst-status rst-tone="neutral">草稿</span>

positive

<span rst-status rst-tone="positive">已發佈</span>

warning

<span rst-status rst-tone="warning">已排期</span>

negative

<span rst-status rst-tone="negative">失敗</span>

neutral

{{template "status-pill" dict "Label" "草稿"}}

positive

{{template "status-pill" dict "Label" "已發佈" "Tone" "positive"}}

warning

{{template "status-pill" dict "Label" "已排期" "Tone" "warning"}}

negative

{{template "status-pill" dict "Label" "失敗" "Tone" "negative"}}

neutral Tone 預設係 neutral,所以呢個呼叫冇寫佢。

badge

一個大寫字母、有邊框嘅細標記,用嚟做固定嘅記號。同 status-pill 唔同,嗰個係記錄嘅狀態。

預覽

冇色調(安靜嘅預設)

<span rst-badge>草稿</span>

neutral

<span rst-badge="neutral">內部</span>

positive

<span rst-badge="positive">上線</span>

warning

<span rst-badge="warning">測試版</span>

negative

<span rst-badge="negative">賣晒</span>

冇色調(安靜嘅預設)

{{template "badge" dict "Label" "草稿"}}

neutral

{{template "badge" dict "Label" "內部" "Tone" "neutral"}}

positive

{{template "badge" dict "Label" "上線" "Tone" "positive"}}

warning

{{template "badge" dict "Label" "測試版" "Tone" "warning"}}

negative

{{template "badge" dict "Label" "賣晒" "Tone" "negative"}}

meter

有數字嘅容量條。

預覽

空

<span rst-meter>
  <meter rst-meter-bar value="0" min="0" max="100" aria-hidden="true"></meter>
  <span rst-meter-num>0/500</span>
</span>

去到一半

<span rst-meter>
  <meter rst-meter-bar value="42" min="0" max="100" aria-hidden="true"></meter>
  <span rst-meter-num>210/500</span>
</span>

就嚟滿

<span rst-meter>
  <meter rst-meter-bar value="82" min="0" max="100" aria-hidden="true"></meter>
  <span rst-meter-num>412/500</span>
</span>

滿咗

<span rst-meter>
  <meter rst-meter-bar value="100" min="0" max="100" aria-hidden="true"></meter>
  <span rst-meter-num>500/500</span>
</span>

超出額度

<span rst-meter>
  <meter rst-meter-bar value="100" min="0" max="100" aria-hidden="true"></meter>
  <span rst-meter-num>700/500</span>
</span>

空

{{template "meter" dict "Percent" 0 "Text" "0/500"}}

去到一半

{{template "meter" dict "Percent" 42 "Text" "210/500"}}

就嚟滿

{{template "meter" dict "Percent" 82 "Text" "412/500"}}

滿咗

{{template "meter" dict "Percent" 100 "Text" "500/500"}}

超出額度

{{template "meter" dict "Percent" 140 "Text" "700/500"}}

超出額度 填充喺 partial 入面被限制喺 100%。

stat

儀表板上嘅一個數字,有標籤,同埋變咗幾多。

個大數字

預覽

將呢段放入 <div rst-stats> 入面。

<div rst-stat="lead">
  <span rst-stat-label>今個月收入</span>
  <span rst-stat-num>€48,210</span>
  <span rst-stat-delta rst-tone="positive">&#43;12%</span>
  <span rst-stat-note>對比上個月</span>
</div>

將呢段放入 <div rst-stats> 入面。

{{template "stat" dict
    "Label" "今個月收入"
    "Value" "€48,210"
    "Delta" "+12%"
    "Tone" "positive"
    "Note" "對比上個月"
    "Lead" true}}

喺一行入面其中一個數字加 Lead,佢就會變大。仲係同一個組件,只係大啲。

細啲嘅數字

預覽

將呢段放入 <div rst-stats> 入面。

<div rst-stat>
  <span rst-stat-label>未找數嘅發票</span>
  <span rst-stat-num>24</span>
</div>

將呢段放入 <div rst-stats> 入面。

{{template "stat" dict "Label" "未找數嘅發票" "Value" "24"}}

你只需要一個標籤同一個數字。其餘都係可選。

跌係好事嗰陣

預覽

將呢段放入 <div rst-stats> 入面。

<div rst-stat>
  <span rst-stat-label>第一次回覆用咗幾耐</span>
  <span rst-stat-num>1小時12分</span>
  <span rst-stat-delta rst-tone="positive">−38%</span>
  <span rst-stat-note>對比上個禮拜</span>
</div>

將呢段放入 <div rst-stats> 入面。

{{template "stat" dict
    "Label" "第一次回覆用咗幾耐"
    "Value" "1小時12分"
    "Delta" "−38%"
    "Tone" "positive"
    "Note" "對比上個禮拜"}}

顏色係你決定,唔係組件。呢度個數字跌咗,而咁係好消息,所以個變化係綠色。

升係壞事嗰陣

預覽

將呢段放入 <div rst-stats> 入面。

<div rst-stat>
  <span rst-stat-label>失敗嘅付款</span>
  <span rst-stat-num>9</span>
  <span rst-stat-delta rst-tone="negative">&#43;3</span>
  <span rst-stat-note>對比上個禮拜</span>
</div>

將呢段放入 <div rst-stats> 入面。

{{template "stat" dict
    "Label" "失敗嘅付款"
    "Value" "9"
    "Delta" "+3"
    "Tone" "negative"
    "Note" "對比上個禮拜"}}

呢度個數字升咗,而咁係壞消息,所以個變化係紅色。

講唔準嗰陣

預覽

將呢段放入 <div rst-stats> 入面。

<div rst-stat>
  <span rst-stat-label>平均瀏覽時間</span>
  <span rst-stat-num>4分12秒</span>
  <span rst-stat-delta rst-tone="neutral">&#43;18秒</span>
  <span rst-stat-note>由禮拜五開始</span>
</div>

將呢段放入 <div rst-stats> 入面。

{{template "stat" dict
    "Label" "平均瀏覽時間"
    "Value" "4分12秒"
    "Delta" "+18秒"
    "Note" "由禮拜五開始"}}

唔設顏色,個變化就係灰色。講唔準係好定壞嗰陣就咁做。

縮短咗嘅數字

預覽

將呢段放入 <div rst-stats> 入面。

<div rst-stat>
  <span rst-stat-label>已發出訊息</span>
  <span rst-stat-num><data value="4120">4.1k</data></span>
</div>

將呢段放入 <div rst-stats> 入面。

{{template "stat" dict "Label" "已發出訊息" "Value" "4.1k" "Exact" "4120"}}

顯示 4.1k 而唔係 4120?將完整數字放入 Exact。螢幕閱讀器淨係讀螢幕上有嘅嘢,所以人需要嘅資料要留喺個數字度。

person

首字母頭像、姓名同電郵。用嚟快速認出代表人嘅記錄。

姓名同電郵

預覽
<a rst-person href="/people/1">
  <span rst-person-av aria-hidden="true">G</span>
  <span rst-person-meta>
    <span rst-person-name>Grace Hopper</span>
    <span rst-person-email>grace@example.com</span>
  </span>
</a>
{{template "person" dict
    "Href" "/people/1"
    "Name" "Grace Hopper"
    "Email" "grace@example.com"
    "Initial" "G"}}

大碼,詳情頁頁首嘅尺寸

預覽
<a rst-person="lg" href="/people/2">
  <span rst-person-av aria-hidden="true">A</span>
  <span rst-person-meta>
    <span rst-person-name>Ada Lovelace</span>
    <span rst-person-email>ada@example.com</span>
  </span>
</a>
{{template "person" dict
    "Href" "/people/2"
    "Name" "Ada Lovelace"
    "Email" "ada@example.com"
    "Initial" "A"
    "Large" true}}

冇首字母

預覽
<a rst-person href="/people/3">
  <span rst-person-av="empty" aria-hidden="true"></span>
  <span rst-person-meta>
    <span rst-person-name>未接受嘅邀請</span>
    <span rst-person-email>invited@example.com</span>
  </span>
</a>
{{template "person" dict
    "Href" "/people/3"
    "Name" "未接受嘅邀請"
    "Email" "invited@example.com"}}

actor

邊個做咗啲嘢,用文字表示:一個人嘅名,或者代理同佢代表嘅人。冇徽章,亦冇圖示。

代表某人行動嘅代理

預覽
<span rst-actor>Claude(代表 Grace Hopper)</span>
{{template "actor" dict "Actor" .Actor}}

啟動時設定一次 ui.ActorName,將主體轉做名。應用程式本身,即係零值 Actor,唔會顯示任何嘢。

一個人

預覽
<span rst-actor>Grace Hopper</span>
{{template "actor" dict "Actor" .Actor}}

callout

提示嘅唯一一套講法:有顏色嘅條、色調圖示、可有可無嘅粗體標題,同一段正文。

info

預覽
<div rst-callout rst-tone="info">
  <span rst-callout-ic aria-hidden="true">
    <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>
  </span>
  <div rst-callout-body>
    <p>網站未發佈之前,文章淨係會員先睇到。</p>
  </div>
</div>
{{template "callout" dict "Body" "網站未發佈之前,文章淨係會員先睇到。" "Tone" "info"}}

positive

預覽
<div rst-callout rst-tone="positive">
  <span rst-callout-ic aria-hidden="true">
    <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="m9 12 2 2 4-4"/></svg>
  </span>
  <div rst-callout-body>
    <strong>付款已經連接好</strong>
    <p>而家可以收門票錢喇。</p>
  </div>
</div>
{{template "callout" dict
    "Body" "而家可以收門票錢喇。"
    "Title" "付款已經連接好"
    "Tone" "positive"}}

warning

預覽
<div rst-callout rst-tone="warning">
  <span rst-callout-ic aria-hidden="true">
    <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>
  </span>
  <div rst-callout-body>
    <strong>連接付款就可以開始賣</strong>
    <p>你嘅活動已經上線,但暫時未收到錢。</p>
  </div>
</div>
{{template "callout" dict
    "Body" "你嘅活動已經上線,但暫時未收到錢。"
    "Title" "連接付款就可以開始賣"
    "Tone" "warning"}}

negative

預覽
<div rst-callout rst-tone="negative">
  <span rst-callout-ic aria-hidden="true">
    <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></svg>
  </span>
  <div rst-callout-body>
    <strong>上一次匯入失敗咗</strong>
    <p>乜都冇改到。改好第 91 行再試多次。</p>
  </div>
</div>
{{template "callout" dict
    "Body" "乜都冇改到。改好第 91 行再試多次。"
    "Title" "上一次匯入失敗咗"
    "Tone" "negative"}}

negative,並且當警報咁報出嚟

預覽
<div rst-callout rst-tone="negative" role="alert">
  <span rst-callout-ic aria-hidden="true">
    <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="10"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/></svg>
  </span>
  <div rst-callout-body>
    <strong>匯入停咗</strong>
    <p>乜都冇改到。改好第 91 行再試多次。</p>
  </div>
</div>
{{template "callout" dict
    "Body" "乜都冇改到。改好第 91 行再試多次。"
    "Title" "匯入停咗"
    "Tone" "negative"
    "Alert" true}}

alert 會加上 role="alert",用嚟顯示重要訊息。

detail-list

詳情畫面上關於某筆記錄嘅定義清單。等寬標記用喺偏機器嘅值。

四項資料,其中一項偏機器

預覽

將呢段放入 <section rst-box> 入面。

<dl rst-detail>
  <dt>對象</dt>
  <dd>會員</dd>
  <dt>主頁</dt>
  <dd>否</dd>
  <dt>已發佈</dt>
  <dd>
    <time datetime="2026-08-02">2026年8月2日</time>
  </dd>
  <dt>編號</dt>
  <dd class="rst-mono">post_01H9ZQ</dd>
</dl>

將呢段放入 <section rst-box> 入面。

{{template "detail-list" dict
    "Items" (list
        (dict "Label" "對象" "Value" "會員")
        (dict "Label" "主頁" "Value" "否")
        (dict "DateTime" "2026-08-02" "Label" "已發佈" "Value" "2026年8月2日")
        (dict "Label" "編號" "Mono" true "Value" "post_01H9ZQ"))}}

notice

重新導向之後嘅一行確認。佢收普通字串,唔係 dict,字串係空嘅就咩都唔畫。

一句「已儲存」嘅訊息

預覽
<p rst-notice role="status">文章儲存咗。</p>
{{template "notice" "文章儲存咗。"}}

region:notice

每個外殼都擺喺頁面上嘅通知,顯示頁面資料入面嘅 Notice,等螢幕閱讀器聽到提示,live.js 又可以原地填返內容。

一句「已儲存」嘅訊息

預覽
<div id="notice" role="status">
  <p rst-notice>文章儲存咗。</p>
</div>
{{template "region:notice" dict "Notice" "文章儲存咗。"}}

form-error

表單嘅錯誤摘要行,role="alert"。佢收一個普通字串;冇錯誤嗰陣咩都唔畫。

畀人拒絕咗嘅提交

預覽
<p rst-form-error role="alert">呢個標題已經有人用咗。</p>
{{template "form-error" "呢個標題已經有人用咗。"}}

job-status

背景工作嘅輪詢片段。data-poll 屬性淨係喺工作行緊嗰陣先出:唔出佢就係停止輪詢嘅方法。

進行緊

預覽

<div rst-job data-poll="/jobs/1/fragment" data-poll-every="2">
  <span rst-spin aria-hidden="true"></span> <bdi><strong>匯入</strong></bdi>進行緊:<bdi>400 項入面 128 項</bdi>…
  <progress rst-job-bar value="32" min="0" max="100" aria-hidden="true"></progress>
</div>
{{template "job-status" dict
    "Name" "匯入"
    "Percent" 32
    "PollSeconds" 2
    "PollURL" "/jobs/1/fragment"
    "Progress" "400 項入面 128 項"
    "Status" "running"}}

呢個會輪詢:佢係成版入面唯一會向網絡攞嘢嘅樣本,而喺靜態網站度,佢永遠等唔到回覆。

完成咗

預覽

<div rst-job>
  <bdi><strong>匯入</strong></bdi>完成咗。
</div>
{{template "job-status" dict "Name" "匯入" "Status" "done"}}

失敗

預覽

<div rst-job>
  <bdi><strong>匯入</strong></bdi>失敗咗:<bdi>row 91: no such column &#34;published&#34;</bdi>
</div>
{{template "job-status" dict
    "Err" "row 91: no such column \"published\""
    "Name" "匯入"
    "Status" "failed"}}