Подготовьте черновик уведомления с темой и правилами использования кнопок Paste, проверенной шкалой интервалов и чётким разграничением редактирования, просмотра и фактической отправки сообщения.
Автономная интерпретация шкал Paste и правил состояний кнопок из исходного проекта HTML; это не нативная среда выполнения и не сервис обмена сообщениями. · Справочник по реализации
02
Twilio Paste Справочник по дизайн-системе
Проверенные исходники twilio-labs/paste. Ниже для значений указаны имена YAML-токенов и соответствующие им имена в стиле JavaScript. В этом справочнике независимое ответвление Paste DSys не представлено как документация Twilio.
Дизайн-система Twilio Paste: используйте исходную систему, не смешивая её с документацией независимого ответвления
Исходный проект Twilio и независимое продолжение
Paste опубликована в репозитории twilio-labs. Во время проверки старые страницы документации по адресу paste.twilio.design перенаправляли в этот репозиторий. Отдельно размещённый сайт Paste DSys называет себя независимым ответвлением, не связанным с Twilio. Поэтому в этом руководстве значения токенов и поведение компонентов основаны на файлах исходного проекта.
Редактор уведомлений — удобный пример: в нём можно показать несколько состояний, которые не уместить в статичную галерею кнопок: редактирование содержимого, подтверждение проверки, подготовленный снимок и чёткую границу перед отправкой. Этот предварительный просмотр не вызывает API API Twilio.
Дизайн-система Twilio Paste Изучите шкалу отступов, прежде чем выбирать суффикс
Числа в именах токенов — это не значения в пикселях
space30 равен половине rem, а space70 — полутора rem. Суффиксы 30 и 70 обозначают позиции в шкале, а не значения 30px и 70px. При корневом размере шрифта 16px в редакторе можно задать 8px между подписью и полем, 12px внутренних отступов элемента управления и 24px между областями.
В исходном YAML используются имена с дефисами. В справочной таблице приведены имена в формате JavaScript, используемые потребителями Paste, а рядом указаны разрешённые значения. Значение в rem масштабируется относительно размера корневого шрифта; его эквивалент в пикселях не следует считать неизменным значением, измеренным браузером.
Дизайн-система Twilio Paste: сочетайте размеры шрифта с отдельными токенами межстрочного интервала
Значения в шкале не обязаны совпадать численно
Для размеров шрифта и межстрочного интервала предусмотрены отдельные псевдонимы. При размере корневого шрифта по умолчанию fontSize30 равен 14px, а lineHeight30 — 20px. fontSize70 равен 24px, для него предусмотрен вариант межстрочного интервала 32px. Благодаря этим парам подписи и многострочный текст остаются удобочитаемыми, а каждый раздел не превращается в крупный рекламный заголовок.
Встроенный пример использует системный стек шрифтов без засечек и иллюстрацию телефона, созданную для приложения. Это явно обозначенные условные элементы. Проприетарный файл шрифта не распространяется, а размеры рамки телефона не представлены как токены Paste.
Дизайн-система Twilio Paste: семантические роли текста включают требования к контрастности
Приглушённый текст — не то же самое, что отключённый
В исходных данных цветов указаны сочетания с требуемой контрастностью для разных ролей. Основной и вторичный текст, сообщения об ошибках и об успехе рассчитаны на разные цвета переднего плана. Для роли приглушённого текста есть предупреждение: не используйте его для обычных активных элементов управления. Для неяркого счётчика символов не следует выбирать просто самый бледный из доступных оттенков серого.
В примере синий обозначает действие, а сообщение показано тёмным нейтральным текстом. Подготовленный черновик не становится зелёным просто потому, что пользователь нажал кнопку: его статус сообщает о создании локального снимка. Значения примера привязаны к связанной палитре; в других вариантах темы они могут отличаться.
Дизайн-система Twilio Paste: выбор темы — это явное изменение состояния
Варианты провайдера и поверхности приложения
Theme экспортирует Provider, Consumer, именованные объекты тем и утилиты. Среди текущих констант вариантов — default, dark, twilio, twilio-dark, sendgrid и evergreen. В примере переключение намеренно ограничено вариантами default и dark.
При смене провайдера элементы управления, созданные самим приложением, требуют соответствующего оформления поверхности. Провайдер может менять тему компонентов Paste, но не может автоматически оформлять каждый внешний виджет. В примере цвет текста и фон окружающей области задаются явно, а текстовая область обозначена как элемент, принадлежащий приложению.
Дизайн-система Twilio Paste: используйте состояние pressed только для поддерживаемого семейства кнопок
Для действий, навигации и ожидания выполнения предусмотрены разные правила
Реализация Button проверяет допустимость некоторых сочетаний свойств. Для переключателя темы используются secondary и pressed. Для действия отправки формы задано type="submit", поскольку по умолчанию компонент использует тип button. Кнопке в форме ссылки требуется href; её нельзя использовать как отключённое или загружающееся действие.
Используйте primary для подготовки черновика, а secondary — для независимого переключателя темы.
Для навигации используйте ссылку; не добавляйте href к кнопке без соответствующей формы ссылки.
Используйте loading только для реальной выполняющейся операции: это свойство меняет поведение и busy, и disabled.
Не используйте положительные значения tabIndex: реализация допускает только 0 и -1.
Дизайн-система Twilio Paste: храните редактируемый текст отдельно от проверенного снимка
Последовательность действий без ложных утверждений
Предварительный просмотр в реальном времени отображает текущее содержимое текстовой области. Подготовленный текст хранится отдельно и обновляется только после проверки. Повторное редактирование не должно незаметно менять уже подготовленный снимок. Флажок проверки — это локальный пример взаимодействия, а не подтверждение согласия получателя или соответствия требованиям законодательства.
Введите текст в подписанное поле.
Проверьте текущее сообщение и установите флажок локальной проверки.
Подготовьте снимок, не обращаясь к службе обмена сообщениями.
Отредактируйте текст ещё раз и сравните черновик с подготовленной копией, прежде чем создавать новый снимок.
Дизайн-система Twilio Paste: делайте обратную связь понятной без интерпретации макета телефона
Подписи и текстовая обратная связь размещены за пределами иллюстрации
У текстовой области есть видимая подпись и ссылки на описания счётчика и ошибки. Счётчик учитывает кодовые точки Unicode; он не измеряет сегменты SMS, кодировку или стоимость. Подготовленный результат также показан обычным текстом за пределами условного устройства.
Проверка должна сообщать о пустом сообщении или об отсутствии подтверждения проверки. Область статуса объявляет локальный результат, не создавая впечатления, что сообщение было доставлено. При фокусе на всех встроенных элементах управления и кнопках, в том числе при узкой ширине окна, он остаётся видимым.
Дизайн-система Twilio Paste: проверяйте пакет отдельно от автономной интерпретации
Что подтверждает предоставленный пример
В примере настройки подключаются настоящие пакеты Paste Theme и Button, а композиция React показана целиком. Встроенные элементы управления формы обозначены как принадлежащие приложению, а не приписываются непроверенному компоненту API. Встроенная версия — это автономная интерпретация HTML, не зависящая от внешней CDN.
Перед использованием в сервисе разрешите peer-зависимости, соберите пример со встроенными элементами управления и добавьте настоящий бэкенд для отправки сообщений. Успешная проверка локального предварительного просмотра подтверждает работу редактора, но не интеграцию с промышленной системой обмена сообщениями и не доставку через Twilio.
Сохраните весь документ в файле index.html и откройте его в браузере. Автономная интерпретация HTML исходных шкал Paste и правил состояний кнопок; это не нативная среда выполнения и не служба обмена сообщениями.
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>
На панели телефона отображается снимок черновика. SMS не отправляется; для работы нативных Theme и Button из Paste воспользуйтесь отдельным примером 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, а не сегменты SMS, единицы кодировки или тарифицируемый объём.
Исходный код примера с нативным пакетом проверен; автономное предварительное отображение HTML проверяется отдельно.
04
Дизайн-система Twilio Paste: настройка агента
Отправная точка для реализации
Используйте приведённую выше полную запись React вместе с корневым элементом. Модульные пакеты предоставляют нативные Provider и Button; выберите совместимые peer-зависимости и зафиксируйте разрешённые версии в lock-файле приложения.
Создайте редактор черновиков уведомлений с помощью Paste Theme.Provider и Button. Сохраните семантику переключателя secondary pressed, интервалы в rem, роли текста, подтверждённые исходниками, и раздельное состояние черновика и снимка. Не придумывайте количество сегментов SMS или результаты доставки.
05
Дизайн-система Twilio Paste: источники и область применения
Независимая справка OpenDesign по исходному Paste. Paste DSys — отдельный форк, не связанный с проектом. В этом примере сообщения не отправляются.