跳到内容
栏目
语言,当前是简体中文
Rastrillo 设计系统

界面基元

组件无法成为的那些形状,因为它们包住的主体只有调用方知道:区块卡片、数据网格、展开菜单,以及外壳自身的框架。tokens.css 提供类名,应用自己写标记。下面的内容就是 ui.Styleguide 返回的标记,其中的文字换成了你的语言;ui 的测试正是拿这份标记来比对 tokens.css。

每个示例都能真实操作,但其中的链接不会跳转到任何地方。

box

带内边距的分节卡片,以及坐在它外面的那个标题。

哪张卡片是哪一种

rst-list 和 rst-card 故意没有内边距:它们装的是一串行,每行自己有内边距。把表单、段落、一排链接或任何不是行的东西直接塞进去,就会紧贴着边框渲染;文字碰到边缘就是那个信号。给任意内容用的有内边距卡片是 rst-box,它的标题是放在它前面的兄弟节点 rst-box-head。

预览
<div rst-box-head>
  <h2>结算款</h2>
  <a rst-btn href="/payout/edit">编辑</a>
</div>
<section rst-box>
  <p>屏幕上的一切都放在盒子里。</p>
  <div rst-box-foot>2 小时前更新</div>
</section>

button

按钮有四种样式和三种尺寸,链接也可以做成按钮的样子。表单提交时显示的加载圈,见 form-foot。

预览
<p>
  <button rst-btn type="button">取消</button> <button rst-btn="primary" type="button">保存</button> <button rst-btn="ghost" type="button">预览</button> <button rst-btn="danger" type="button">删除</button>
</p>
<p>
  <button rst-btn="primary sm" type="button">小</button> <button rst-btn="primary" type="button">默认</button> <button rst-btn="primary lg" type="button">大</button> <a rst-btn href="/orders">查看订单</a>
</p>
<p>
  <button rst-btn="primary block" type="button">继续</button>
</p>
<p>
  <button rst-btn type="button" disabled>已归档</button>
</p>

dropdown

藏在页眉溢出菜单和列表工具栏筛选背后的 details/summary 菜单,外加一枚可移除的已应用筛选标签。

预览
<details rst-dropdown name="rst-menus">
  <summary>
    筛选
    <span rst-caret 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="m6 9 6 6 6-6"/></svg>
    </span>
    <span class="rst-sr-only">筛选订单:已付款</span>
  </summary>
  <div rst-dropdown-menu>
    <a aria-current="true" href="/orders?status=paid">已付款</a>
    <details rst-menu-group name="rst-menus-price" open>
      <summary>价格</summary>
      <div>
        <a href="/orders?price=free">免费</a>
      </div>
    </details>
  </div>
</details>
<span rst-ftok>
  <span rst-ftok-k>已付款</span>
  <a href="/orders" aria-label="移除筛选条件:已付款">✕</a>
</span>

form-layout

给表单节奏感和保存栏的那些属性。没有片段会输出它们;它们包住调用方自己拼出来的一串字段。

预览
<form rst-form-flow method="post" action="/settings">
  <div rst-field>
    <label rst-field-label for="name">姓名</label>
    <input rst-input type="text" id="name" name="name">
  </div>
  <div rst-field>
    <label rst-field-label for="email">电子邮件</label>
    <input rst-input type="email" id="email" name="email">
  </div>
  <div rst-field-row>
    <div class="rst-grow" rst-field>
      <label rst-field-label for="city">城市</label>
      <input rst-input type="text" id="city" name="city">
    </div>
    <div rst-field>
      <label rst-field-label for="zip">邮编</label>
      <input rst-input="short" type="text" id="zip" name="zip">
    </div>
  </div>
  <div rst-form-bar>
    <span rst-form-bar-note>更改会立即保存。</span>
    <div rst-form-actions>
      <a rst-btn href="/settings">取消</a>
      <button rst-btn="primary" type="submit">保存</button>
    </div>
  </div>
</form>

help

一个带边框的问号,链接到帮助文章。它的 CSS 提示只是装饰;链接自己带着完整句子的标签。

预览
<a rst-help rst-tip href="/help/orders" target="_blank" rel="noopener" aria-label="帮助:订单" data-tip="关于订单">
  <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.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><path d="M12 17h.01"/></svg>
</a>

list-grid

真正的数据表格语汇:卡片一次性定好列,行只负责挑单元格。

页面是竖着堆起来的

一个页面就是一列:page-header,然后 section-header + 卡片,再下一个 section-header + 卡片,按阅读顺序排下去。横向排列只留给自带它的写法:rst-box-head、rst-field-row、rst-lbar、rst-lrow 单元格、rst-seg-tabs。

预览
<div rst-card style="--rst-cols: 2fr 110px var(--rst-col-menu)">
  <div rst-lrow="head">
    <span>订单</span>
    <span class="rst-m-hide">状态</span>
    <span></span>
  </div>
  <div rst-lrow>
    <a class="rst-nm" href="/orders/AB3PX"><bdi>Grace Hopper</bdi>
      <small>AB3PX · <bdi>grace@example.com</bdi></small>
    </a>
    <span class="rst-m-hide rst-cell-mut">已付款</span>
    <details rst-row-menu name="rst-menus">
      <summary aria-label="Grace Hopper 的操作">
        <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="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>
      </summary>
      <div rst-row-menu-panel>
        <a href="/orders/AB3PX">查看</a>
        <hr>
        <a class="rst-danger" href="/orders/AB3PX/refund">订单退款…</a>
      </div>
    </details>
  </div>
  <p rst-no-match>没有匹配的订单。<a href="/orders">清除筛选条件</a></p>
</div>
<p rst-count-line>显示第 <strong>1–20</strong> 条,共 <strong>412</strong> 条</p>

modal

模态框是它自己的一个网址,而不是客户端状态:下面的页面标记为 inert,面板浮在它上面,关闭是一个普通链接。

预览
<div rst-backdrop inert>
  <div rst-page>
    <h1>设置</h1>
  </div>
</div>
<div rst-modal-overlay>
  <dialog rst-modal-panel open aria-labelledby="modal-title">
    <nav>
      <a href="/settings/profile" aria-current="page">个人资料</a>
      <a href="/settings/billing">账单</a>
      <a href="/settings/notifications">通知</a>
    </nav>
    <section>
      <a rst-modal-close href="/settings" aria-label="关闭设置">✕</a>
      <h2 id="modal-title">个人资料</h2>
      <p>更新整个账户里显示的名字和照片。</p>
    </section>
  </dialog>
</div>

到它真正属于的那个网址上去看它运行 (在新标签页中打开).

selbox

列表行在选择模式下佩戴的那个勾选框。它的标签会把这一行的身份再说一遍。

预览
<label rst-selbox>
  <input type="checkbox" aria-label="选择订单 AB3PX">
</label>

shell-sidebar

sidebar 外壳在内容页上的框架:在手机上,是一个返回目录的控件。

预览
<div rst-shell-sidebar="page">
  <a rst-skip href="#main">跳到内容</a>
  <div rst-shell-back>
    <a href="/#nav-reports" rel="up" aria-label="返回栏目">栏目</a>
  </div>
  <aside rst-shell-rail>
    <h1 rst-shell-title>
      <span><a rst-shell-brand href="/">Notes</a></span><span>报表</span>
    </h1>
    <a rst-shell-brand href="/">Notes</a>
    <nav rst-shell-nav>
      <span rst-shell-group>工作</span>
      <a id="nav-dashboard" href="/dashboard">仪表板</a>
      <a id="nav-reports" href="/reports" aria-current="page">报表</a>
    </nav>
    <div rst-shell-rail-foot>
      <details rst-dropdown rst-shell-profile name="rst-shell-menu">
        <summary>
          <span rst-shell-avatar>
            <span rst-person-av aria-hidden="true">A</span>
            <span rst-person-name>Ada Lovelace</span>
          </span>
        </summary>
        <div rst-dropdown-menu>
          <div rst-shell-who>
            <span rst-person-av aria-hidden="true">A</span>
            <span rst-person-name>Ada Lovelace</span>
            <span rst-person-email>ada@example.com</span>
          </div>
          <a href="/settings">设置</a>
        </div>
      </details>
    </div>
  </aside>
  <main rst-shell-main id="main">
    <div rst-page>内容。</div>
  </main>
</div>

打开侧栏外壳演示,一个独立预览。 (在新标签页中打开).

shell-topbar

顶栏外壳自身的框架,以标记形式呈现。Layout 把它作为一整套模板提供。

预览
<div rst-shell-topbar>
  <a rst-skip href="#main">跳到内容</a>
  <header rst-shell-bar>
    <a rst-shell-brand href="/">Notes</a>
    <details rst-shell-menu name="rst-shell-menu">
      <summary>
        <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="M4 12h16"/><path d="M4 6h16"/><path d="M4 18h16"/></svg>菜单</summary>
    </details>
    <div rst-shell-tail>
      <nav rst-shell-nav>
        <a href="/" aria-current="page">首页</a>
        <a href="/archive">归档</a>
      </nav>
      <details rst-dropdown rst-shell-account name="rst-menus">
        <summary>
          账户
          <span rst-caret 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="m6 9 6 6 6-6"/></svg>
          </span>
        </summary>
        <div rst-dropdown-menu>
          <a href="/settings">设置</a>
        </div>
      </details>
    </div>
  </header>
  <main rst-page id="main">内容。</main>
  <footer rst-shell-foot>使用 rastrillo 制作</footer>
</div>

打开顶栏外壳演示,一个专门的预览。 (在新标签页中打开).

stat-band

仪表板顶部的一排数字。

预览
<div rst-stats>
  <div rst-stat="lead">
    <span rst-stat-label>本月收入</span>
    <span rst-stat-num>&euro;48,210</span>
    <span rst-stat-delta rst-tone="positive">+12%</span>
    <span rst-stat-note>较上月</span>
  </div>
  <div rst-stat>
    <span rst-stat-label>今日订单</span>
    <span rst-stat-num>318</span>
  </div>
  <div rst-stat>
    <span rst-stat-label>平均客单价</span>
    <span rst-stat-num>&euro;41.20</span>
    <span rst-stat-delta rst-tone="negative">&minus;3%</span>
  </div>
  <div rst-stat>
    <span rst-stat-label>退款</span>
    <span rst-stat-num>7</span>
  </div>
</div>

tblock

一张带边框的卡片,只有在它的开关打开时才通过 :has() 显示内容。开关是权威;显示只是便利。

预览
<div rst-tblock>
  <label rst-tblock-head>
    <input type="checkbox" name="notify" checked>
    <span rst-switch-track aria-hidden="true"></span>
    <span>
      <span rst-tblock-title>邮件通知</span>
      <span rst-tblock-desc>你参与的讨论每有一条回复就会发送。</span>
    </span>
  </label>
  <div rst-tblock-body>
    <div rst-field>
      <label rst-field-label for="notify-freq">频率</label>
      <input rst-input type="text" id="notify-freq" name="notify_freq" value="每日摘要">
    </div>
  </div>
</div>