通信平台 · 新资源

Twilio Paste 设计系统.

使用 Paste 的主题与按钮规范撰写通知草稿,采用经过验证的间距比例,并清楚区分编辑、审核和实际发送消息的状态。

OpenDesign 指南9 个章节40 条参考条目原始应用指南
01

Twilio Paste 设计系统界面预览

编辑内容、查看手机预览,并准备单独的本地快照。

通知草稿工作室打开完整示例
对上游 Paste 比例和按钮状态规则的离线 HTML 解读;并非原生运行时或消息服务。· 实现参考
02

Twilio Paste 设计系统设计参考

已核实上游 twilio-labs/paste 来源。下方取值区分了 YAML 令牌名称与其 JavaScript 风格名称。本参考不会将独立的 Paste DSys 分支说成 Twilio 文档。

间距别名

来源
名称 / 规则值 / 配置用途
space100.125rem以 16px 根字号计算为 2px。
space200.25rem以 16px 根字号计算为 4px。
space300.5rem字段间距为 8px。
space400.75rem控件内边距为 12px。
space501rem16px,用于局部分组。
space601.25rem20px。
space701.5rem24px,用于区块间隔。
space902rem32px,用于较大的分组。
space1303rem48px,用于更大的区域。

字体大小别名

来源
名称 / 规则值 / 配置用途
fontSize200.75rem默认根字号为 12px。
fontSize300.875rem14px 正文选项。
fontSize401rem16px 正文选项。
fontSize601.25rem20px 标题选项。
fontSize701.5rem24px 标题选项。
fontSize902rem32px 展示文字选项。

行高

来源
名称 / 规则值 / 配置用途
lineHeight20 / lineHeight301.25rem20px,适用于紧凑文本。
lineHeight401.5rem24px,适用于 16px 文本。
lineHeight601.75rem28px,适用于 20px 文本。
lineHeight702rem32px,适用于 24px 文本。

圆角

来源
名称 / 规则值 / 配置用途
borderRadius102px最小圆角。
borderRadius204px小型控件圆角。
borderRadius308px中小型圆角。
borderRadius4012px中圆角。
borderRadiusCircle50%圆形要求宽度和高度相等。
borderRadiusPill100px胶囊形圆角,与圆形不同。

文本角色与搭配

来源
名称 / 规则值 / 配置用途
colorTextpalette-gray-100主要正文;在关联调色板中解析为 #121c2d。
colorTextWeakpalette-gray-60次要文本;在关联调色板中解析为 #606b85。
colorTextLinkpalette-blue-60链接;在关联调色板中解析为 #0263e0。
colorTextErrorpalette-red-60错误文本;在关联调色板中解析为 #db132a。
colorTextSuccesspalette-green-70成功文本;在关联调色板中解析为 #0e7c3a。
colorTextWeakerpalette-gray-40源码警告不要将其用于普通的启用状态文本。

按钮行为

来源
名称 / 规则值 / 配置用途
variantprimary / secondary / destructive / link and other explicit variants示例使用了主要提交按钮和次要切换按钮。
typebutton by default表单提交时应显式设置 submit。
pressedSecondary family only主题切换使用次要按钮。
loadingaria-busy and disabled control behavior仅在确实有待处理操作时使用。
as="a"Requires href导航链接不支持按钮的禁用或加载状态。
tabIndex0 or -1不接受正数 tabindex。

主题名称

来源
名称 / 规则值 / 配置用途
default / darkTheme variants主题选择是显式的。
twilio / twilio-darkSeparate variants不要将每种变体都描述为与默认主题完全相同。
sendgrid / evergreenAdditional variants应有意选择主题,而不是把品牌主题当作随意的装饰。
03

Twilio Paste 设计系统完整指南

实用指南,介绍如何为真实界面选择、应用和评审此系统。

DESIGN-twilio-paste.md

完整指导、实现起点和源代码链接。

下载指南

Twilio Paste 设计系统:使用上游系统时,勿与文档分支混淆

Twilio 源码与独立延续项目

Paste 发布在 twilio-labs 仓库中。核验期间,旧的 paste.twilio.design 文档路由会重定向到该仓库。独立托管的 Paste DSys 网站称自己是与 Twilio 无关联的独立分支。因此,本指南依据上游源文件说明设计令牌值和组件行为。

摘自本 OpenDesign 指南

通知编辑器是一个很实用的示例,因为它展示了静态按钮图库无法涵盖的多种状态:可编辑内容、确认审阅、已准备好的快照,以及发送前的明确边界。此预览不会调用任何 Twilio API。

阅读配套规范

Twilio Paste 设计系统:选择后缀前先了解间距比例

令牌编号是名称,不是像素值

space30 是半个 rem,而 space70 是一个半 rem。后缀 30 和 70 表示比例中的位置,并非 30px 和 70px。在根字号为 16px 时,编辑器可以在标签与输入框之间使用 8px、控件内部使用 12px、区域之间使用 24px。

YAML 源文件使用连字符命名。参考表则展示 Paste 使用者采用的 JavaScript 样式名称,并列出解析后的值。基于 rem 的值会随根字号缩放;其像素等效值不应被视为浏览器中恒定不变的测量值。

阅读配套规范

Twilio Paste 设计系统:字体大小应与独立的行高令牌搭配使用

比例中的编号并不代表数值相同

字体大小和行高别名彼此独立。默认根字号下,fontSize30 为 14px,而 lineHeight30 为 20px。fontSize70 为 24px,并有 32px 的行高选项。这些组合让标签和多行内容保持易读,同时避免把每个区块都变成大型营销标题。

嵌入式示例使用系统无衬线字体栈,以及由应用提供的手机插图。这些选择明确仅供示意。示例未重新分发任何专有字体文件,也未将手机边框尺寸标示为 Paste 设计令牌。

阅读配套规范

Twilio Paste 设计系统:语义文本角色包含对比度限制

弱化文本不等同于禁用文本

上游颜色源码会记录各文本角色对应的对比度搭配。主要文本、次要文本、错误消息和成功消息各有不同的预期前景色角色。对于较弱的文本角色,源码警告不要将其用于普通的启用状态控件。字符计数等弱化信息不应直接使用最浅的灰色。

在示例中,蓝色表示操作,深色中性文本承载消息。草稿准备就绪后,不会仅仅因为用户按下按钮就变成绿色:其状态说明创建的是本地快照。示例值依据关联调色板;其他主题变体的解析结果可能有所不同。

阅读配套规范

Twilio Paste 设计系统:主题选择是显式的状态变更

Provider 变体与应用界面表面

Theme 会导出 Provider、Consumer、具名主题对象和实用工具。当前变体常量包括 default、dark、twilio、twilio-dark、sendgrid 和 evergreen。此示例有意仅在 default 与 dark 之间切换。

当主题提供器发生变化时,应用自有控件需要匹配的表面样式。主题提供器可以为 Paste 组件设置主题,但不会自动为所有外部控件重新设置样式。提供的代码显式设置周围区域的前景色和背景色,并标明文本区域归应用所有。

阅读配套规范

Twilio Paste Paste 设计系统:仅在受支持的按钮类型上使用按下状态

操作、导航和待处理工作各有不同约定

Button 实现会验证某些属性组合。主题切换按钮使用 secondary 和 pressed。表单操作设置 type="submit",因为该组件默认的类型是 button。锚点样式的按钮必须设置 href,不能将其当作禁用或加载中的操作。

  • 使用 primary 来准备草稿,使用 secondary 来切换独立的主题。
  • 导航应使用链接;不要在按钮上设置 href,除非使用相应的锚点形式。
  • 只有在操作确实待处理时才使用 loading,因为它会同时改变忙碌和禁用行为。
  • 避免使用正数 tabIndex;实现仅支持 0 和 -1。

阅读配套规范

Twilio Paste Paste 设计系统:将可编辑内容与已审核快照分开

如实呈现操作顺序

实时预览会跟随当前文本区域的值。准备好的副本会单独存储,只有通过验证后才会更新。再次编辑时,不应悄然改写此前准备好的快照。审核复选框仅用于本地交互演示,并不代表收件人已同意,也不代表符合相关法律要求。

  1. 在带有标签的文本区域中撰写内容。
  2. 检查当前消息,并勾选本地审核复选框以确认。
  3. 准备快照,不调用任何消息服务。
  4. 再次编辑,并在准备新的快照前,将草稿与已准备的副本进行比较。

阅读配套规范

Twilio Paste Paste 设计系统:让反馈一目了然,无需解读手机模型

说明标签和文本反馈位于插图之外

文本区域有清晰可见的标签,并关联字符计数和错误说明。字符计数按 Unicode 码点计算,不代表短信分段、编码方式或费用。准备好的结果也会以普通文本形式显示在示意设备之外。

验证必须指出消息为空或尚未确认审核。状态区域会播报本地操作结果,不会让人误以为消息已发送。所有原生控件和按钮(包括窄视口下的控件和按钮)都应保持清晰可见的键盘焦点。

阅读配套规范

Twilio Paste Paste 设计系统:单独验证软件包与离线演示

所提供示例能够证明的内容

此配置导入了真实的 Paste Theme 和 Button 软件包,并提供完整的 React 组合。原生表单控件明确标为应用自有控件,而非未经验证地归属于某个组件 API。内嵌版本是离线的 HTML 演示,不依赖外部 CDN。

在服务中使用之前,请先解决对等依赖、构建原生示例,并为发送功能添加真正的后端边界。本地预览测试成功只能证明编辑器行为正常,并不能证明已集成生产环境的消息服务,也不能据此声称 Twilio 已成功送达消息。

阅读配套规范

Twilio Paste Paste 设计系统组件示例

完整的独立交互示例

将完整文档保存为 index.html 并在浏览器中打开。这是对上游 Paste 尺度规则和按钮状态规则的离线 HTML 演示,并非原生运行时或消息服务。

html
<!doctype html><html lang="en"><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Paste notification draft studio</title><style>
*{box-sizing:border-box}body{margin:0;background:#f4f4f6;color:#121c2d;font:14px/20px Arial,sans-serif}header{background:#121c2d;color:white;padding:20px 32px;display:flex;justify-content:space-between;gap:16px}.brand{font-weight:700;letter-spacing:.02em}header small{color:#cacdd8}main{max-width:1000px;padding:32px;margin:auto}h1{font-size:28px;line-height:40px;margin:0 0 8px}h2{font-size:18px;line-height:28px;margin:0 0 16px}.intro{color:#606b85;margin:0 0 32px}.layout{display:grid;grid-template-columns:minmax(0,1fr) 280px;gap:32px}form{background:white;border:1px solid #e1e3ea;border-radius:8px;padding:24px}label{display:block;font-weight:600}textarea{width:100%;font:16px/24px Arial,sans-serif;border:1px solid #8891aa;border-radius:4px;padding:12px;margin-top:8px;resize:vertical;min-height:150px}textarea:focus,button:focus-visible,input:focus-visible{outline:3px solid #0263e0;outline-offset:3px}.count{color:#606b85;font-size:12px;line-height:20px}.review{display:flex;align-items:start;gap:8px;margin-top:24px}.review label{font-weight:400}.review input{width:16px;height:16px;accent-color:#0263e0}button{font:600 14px/20px Arial,sans-serif;cursor:pointer;border:1px solid #0263e0;border-radius:4px;padding:10px 16px;background:#0263e0;color:white}button:hover{background:#043cb5}button.secondary{background:white;color:#0263e0}.error{color:#ad1111;min-height:20px}aside{text-align:center}.phone{margin:auto;background:white;border:8px solid #121c2d;border-radius:32px;min-height:400px;padding:24px 12px;box-shadow:0 12px 32px #121c2d14}.notch{width:72px;height:5px;background:#121c2d;border-radius:8px;margin:0 auto 24px}.sender{font-size:12px;color:#606b85;padding-bottom:16px;border-bottom:1px solid #e1e3ea}.bubble{background:#ebf4ff;border-radius:12px;padding:12px;margin-top:24px;text-align:left;white-space:pre-wrap;overflow-wrap:anywhere;min-height:70px}.caption{font-size:12px;color:#606b85}.prepared{padding:24px;background:#fff;border:1px solid #e1e3ea;border-radius:8px;margin-top:24px}.prepared p{white-space:pre-wrap;overflow-wrap:anywhere}.status{color:#606b85;font-size:12px}.foot{font-size:12px;color:#606b85;margin-top:24px}@media(max-width:650px){header{padding:16px}main{padding:24px 16px}.layout{grid-template-columns:1fr}.phone{max-width:250px;min-height:300px}form{padding:20px}.intro{margin-bottom:24px}}
</style><header><span class="brand">Paste / Message studio</span><small>Local preview</small></header><main><h1>Notification draft</h1><p class="intro">Write the message. Review the copy. Keep a prepared version.</p><div class="layout"><div><form id="composer" novalidate><h2>Compose your message</h2><label for="message">Message</label><textarea id="message" aria-describedby="count error">Your appointment is confirmed for Thursday at 10:00.</textarea><p id="count" class="count"></p><div class="review"><input id="reviewed" type="checkbox"><label for="reviewed">I reviewed this draft</label></div><p id="error" class="error" role="alert"></p><button>Prepare local draft</button></form><section class="prepared"><h2>Prepared copy</h2><p id="snapshot">No draft prepared yet.</p><p class="status" id="status" role="status">Nothing has been sent.</p></section></div><aside><div class="phone" aria-label="Illustrative phone preview"><div class="notch"></div><div class="sender">Sample service · Preview</div><div class="bubble" id="bubble"></div></div><p class="caption">Live preview of the editable message</p></aside></div><p class="foot">HTML interpretation of upstream Paste · Counts Unicode code points, not SMS segments · No messaging connection</p></main><script>
const $=id=>document.getElementById(id);function update(){$('bubble').textContent=$('message').value||'Your message will appear here.';$('count').textContent=Array.from($('message').value).length+' Unicode code points. Not an SMS segment estimate.'}$('message').oninput=()=>{update();$('reviewed').checked=false};$('composer').onsubmit=e=>{e.preventDefault();$('error').textContent='';$('message').removeAttribute('aria-invalid');if(!$('message').value.trim()){$('error').textContent='Write a message before preparing a draft.';$('message').setAttribute('aria-invalid','true');$('message').focus();return}if(!$('reviewed').checked){$('error').textContent='Confirm that you reviewed the message.';$('reviewed').focus();return}$('snapshot').textContent=$('message').value.trim();$('status').textContent='Draft prepared locally. Nothing was sent.'};update();
</script></html>

代码参考

  • 手机面板显示草稿快照。不发送短信;原生 Paste Theme 和 Button 行为需要使用单独的 React 示例。

使用真实 Paste 主题和按钮状态的本地草稿

Theme.Provider 包裹整个内容编辑器。secondary 的 pressed 状态会更改预览主题;primary 提交按钮会在应用完成验证后准备快照。标签、文本区域和复选框均明确标为应用原生控件。

jsx
// npm install @twilio-paste/button @twilio-paste/theme react react-dom
import React, {useState} from 'react';
import {createRoot} from 'react-dom/client';
import {Theme} from '@twilio-paste/theme';
import {Button} from '@twilio-paste/button';
// Native textarea and labels are application-owned; this is not Paste TextArea.
function Composer() {
  const [message,setMessage] = useState('Your appointment is confirmed for Thursday at 10:00.');
  const [snapshot,setSnapshot] = useState('');
  const [error,setError] = useState('');
  const [confirmed,setConfirmed] = useState(false);
  const [mode,setMode] = useState('default');
  const length = Array.from(message).length;
  const background = mode === 'dark' ? '#121c2d' : '#ffffff';
  const foreground = mode === 'dark' ? '#ffffff' : '#121c2d';
  function prepare(event) {
    event.preventDefault();
    if (!message.trim()) return setError('Write a message before preparing a draft.');
    if (!confirmed) return setError('Confirm that you reviewed the message.');
    setError(''); setSnapshot(message.trim());
  }
  return <Theme.Provider theme={mode}>
    <main style={{padding:24,background,color:foreground,maxWidth:760,margin:'auto'}}>
      <h1>Notification draft</h1>
      <Button variant="secondary" pressed={mode==='dark'} onClick={() => setMode(mode==='dark'?'default':'dark')}>Dark preview</Button>
      <form onSubmit={prepare}>
        <label htmlFor="message" style={{display:'block',marginTop:24}}>Message</label>
        <textarea id="message" rows={5} value={message} onChange={e=>{setMessage(e.target.value);setConfirmed(false);}}
          aria-describedby="count error" aria-invalid={!!error}
          style={{width:'100%',padding:12,margin:'8px 0',font:'inherit',borderRadius:4}} />
        <p id="count">{length} Unicode code points. This is not an SMS segment estimate.</p>
        <label><input type="checkbox" checked={confirmed} onChange={e=>setConfirmed(e.target.checked)} /> I reviewed this draft</label>
        <p id="error" role="alert">{error}</p>
        <Button variant="primary" type="submit">Prepare local draft</Button>
      </form>
      <section aria-label="Prepared draft" style={{marginTop:24}}>
        <h2>Prepared copy</h2>
        <p style={{whiteSpace:'pre-wrap'}}>{snapshot || 'No draft prepared yet.'}</p>
        <p role="status">{snapshot ? 'Draft prepared locally. Nothing was sent.' : ''}</p>
      </section>
    </main>
  </Theme.Provider>;
}
createRoot(document.getElementById('root')).render(<Composer />);

代码参考

  • 此示例不会声称原生控件就是 Paste TextArea 组件。
  • 字符计数按 Unicode 码点计算,不代表短信分段、编码单元或计费量。
  • 原生软件包示例已通过源码检查;离线 HTML 预览则单独测试。
04

Twilio Paste Paste 设计系统 Agent 配置

实现起点

使用上方完整的 React 入口,并提供一个根元素。模块化软件包提供原生主题提供器和按钮;请选择兼容的对等依赖,并在应用锁定文件中固定解析后的版本。

bash
npm install @twilio-paste/button @twilio-paste/theme react react-dom

适用于你项目的提示词

Agent 提示词
使用 Paste Theme.Provider 和 Button 构建通知草稿编辑器。保留次级按钮的按下态切换语义、rem 间距、有来源依据的文本角色,以及彼此独立的草稿状态和快照状态。不要虚构短信分段数或送达结果。
05

Twilio Paste 设计系统来源与范围

OpenDesign 对上游 Paste 的独立参考。Paste DSys 是一个独立且无关联的分支。本示例不会发送任何消息。