01SumUp Circuit 设计系统界面预览
尝试输入格式错误的金额、更改商品名称、切换备注字段,并查看本地快照。
原生使用 @sumup/circuit-ui 8.15.0 和 @sumup/design-tokens 7.3.1 浅色 CSS;原创本地商品编辑器。·
实现参考 原生使用 @sumup/circuit-ui 8.15.0 和 @sumup/design-tokens 7.3.1 浅色 CSS;原创本地商品编辑器。
| 名称 / 规则 | 值 / 配置 | 用途 |
|---|
--cui-bg-normal | #fff | 商户端浅色语义参考;将界面表面颜色用作前景色前,请确认它适用的配色组合。 |
--cui-bg-subtle | #f0f1f5 | 商户端浅色语义参考;将界面表面颜色用作前景色前,请确认它适用的配色组合。 |
--cui-bg-strong | #000 | 商户端浅色语义参考;将界面表面颜色用作前景色前,请确认它适用的配色组合。 |
--cui-bg-accent-strong | #0f131a | 商户端浅色语义参考;将界面表面颜色用作前景色前,请确认它适用的配色组合。 |
--cui-fg-normal | #0f131a | 商户端浅色语义参考;将界面表面颜色用作前景色前,请确认它适用的配色组合。 |
--cui-fg-subtle | #6a737c | 商户端浅色语义参考;将界面表面颜色用作前景色前,请确认它适用的配色组合。 |
--cui-fg-on-strong | #fff | 商户端浅色语义参考;将界面表面颜色用作前景色前,请确认它适用的配色组合。 |
--cui-fg-success | #018850 | 商户端浅色语义参考;将界面表面颜色用作前景色前,请确认它适用的配色组合。 |
--cui-fg-danger | #de331d | 商户端浅色语义参考;将界面表面颜色用作前景色前,请确认它适用的配色组合。 |
--cui-border-normal | #aeb6be | 商户端浅色语义参考;将界面表面颜色用作前景色前,请确认它适用的配色组合。 |
| 名称 / 规则 | 值 / 配置 | 用途 |
|---|
--cui-spacings-bit | 4px | 从锁定版本的 CSS 导出中复制的命名间距级别。 |
--cui-spacings-byte | 8px | 从锁定版本的 CSS 导出中复制的命名间距级别。 |
--cui-spacings-kilo | 12px | 从锁定版本的 CSS 导出中复制的命名间距级别。 |
--cui-spacings-mega | 16px | 从锁定版本的 CSS 导出中复制的命名间距级别。 |
--cui-spacings-giga | 24px | 从锁定版本的 CSS 导出中复制的命名间距级别。 |
--cui-spacings-tera | 32px | 从锁定版本的 CSS 导出中复制的命名间距级别。 |
--cui-spacings-peta | 40px | 从锁定版本的 CSS 导出中复制的命名间距级别。 |
--cui-spacings-exa | 48px | 从锁定版本的 CSS 导出中复制的命名间距级别。 |
--cui-spacings-zetta | 56px | 从锁定版本的 CSS 导出中复制的命名间距级别。 |
| 名称 / 规则 | 值 / 配置 | 用途 |
|---|
--cui-border-radius-bit | 4px | 根据控件或界面表面的用途选择形状。 |
--cui-border-radius-byte | 8px | 根据控件或界面表面的用途选择形状。 |
--cui-border-radius-kilo | 12px | 根据控件或界面表面的用途选择形状。 |
--cui-border-radius-mega | 16px | 根据控件或界面表面的用途选择形状。 |
--cui-border-radius-circle | 100% | 根据控件或界面表面的用途选择形状。 |
--cui-border-radius-pill | 999999px | 根据控件或界面表面的用途选择形状。 |
| 名称 / 规则 | 值 / 配置 | 用途 |
|---|
--cui-font-stack-default | aktiv-grotesk, Helvetica, Arial, system-ui, sans-serif, "Segoe UI", Roboto, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" | 此示例使用可用的回退字体,不会加载 Aktiv Grotesk。 |
--cui-font-stack-mono | Menlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospace | 此示例使用可用的回退字体,不会加载 Aktiv Grotesk。 |
--cui-font-weight-regular | 400 | 此示例使用可用的回退字体,不会加载 Aktiv Grotesk。 |
--cui-font-weight-bold | 700 | 此示例使用可用的回退字体,不会加载 Aktiv Grotesk。 |
| 名称 / 规则 | 值 / 配置 | 用途 |
|---|
--cui-bg-accent-strong | #0f131a | 分别保留常规、悬停、按下和禁用状态。 |
--cui-bg-accent-strong-hovered | #3b3f46 | 分别保留常规、悬停、按下和禁用状态。 |
--cui-bg-accent-strong-pressed | #6a737c | 分别保留常规、悬停、按下和禁用状态。 |
--cui-bg-accent-strong-disabled | rgba(15, 19, 26, .4) | 分别保留常规、悬停、按下和禁用状态。 |
| 名称 / 规则 | 值 / 配置 | 用途 |
|---|
Input.label | required string | 明确字段用途。 |
Input.invalid | boolean | 原生无效样式与无障碍状态。 |
Input.validationHint | string | 在控件下方显示具体说明。 |
Button.variant | primary / secondary / tertiary | 此锁定版本中的操作层级。 |
Button.size | s / m | 版本 8.15.0 中当前使用的尺寸值。 |
Button.stretch | boolean | 让本地审核操作填满父容器宽度。 |
03SumUp Circuit 设计系统完整指南
实用指南,介绍如何为真实界面选择、应用和评审此系统。
DESIGN-sumup-circuit.md完整指导、实现起点和源代码链接。
下载指南SumUp Circuit 设计系统商户编辑器编排
将商户输入与顾客端展示分开
商品编辑器和类似收据的预览展示了同一状态的两个视角。简短的表单用于填写商品名称、设置示例金额,并选择是否显示顾客备注字段。预览会展示这些设置的效果,但不会创建结账流程或索取付款信息。
使用原创产品插画
几何风格的印刷图案由 CSS 创作,并附有无障碍描述。它让顾客端预览中出现一个易于辨认的物件,而不是空白图片框,同时避免使用虚构的商户照片或复制的 SumUp 产品素材。
SumUp Circuit 设计系统语义主题与软件包范围
使用精确匹配的锁定主题
此示例使用 @sumup/circuit-ui 8.15.0 和 @sumup/design-tokens 7.3.1。参考表数据读取自该软件包的 light.css。上游文档目前已转向 @sumup-oss 命名空间;这里展示的是可复现的锁定版本集成,并非声称较旧的命名空间是最新版本。
加载组件样式与设计令牌样式
React 入口会同时导入组件样式表和浅色设计令牌文件。如果尚未定义组件类名所需的 CSS 自定义属性,仅有组件类名是不够的。作用域化的深色调色板也需要完整的基础主题,以提供通用的非颜色值。
SumUp Circuit 设计系统中性界面表面与操作对比度
让商品成为视觉焦点
编辑器使用白色界面表面和深色前景,顾客端预览则置于低调的中性背景之上。原创插画在商品图片内加入恰到好处的色彩,同时让原生主要操作清晰易读、易于找到。
让预览操作明显不可交互
顾客侧页脚是标有“仅供预览”的文本块,而不是会让人误以为结账流程即将可用的禁用“支付”按钮。唯一真正的提交操作属于编辑器,用于核对本地商品。这样有助于用户了解示例实际支持的交互范围。
SumUp Circuit 设计系统中的字体与回退字体
如实使用主题字体栈
已发布的字体栈以 Aktiv Grotesk 开头,并包含 Helvetica、Arial 和系统回退字体。此离线示例不会下载首选字体。原生 Headline 和 Body 组件仍能呈现预期的层次结构,而最终字形则取决于系统中可用的字体。
让金额与币种保持在一起
SumUp Circuit 设计系统中的间距与圆角界面表面
使用具名的步长序列
令牌刻度采用 bit、byte、kilo、mega 等名称。这些是设计标签,并非二的幂次运算。表格保留了精确的像素值,避免开发者根据命名方式臆造刻度。
对齐控件边缘,同时保留层次
表单采用统一的垂直间距和全宽主操作按钮。预览使用较大的圆角外层背景,以及较小的收据内层区域。在手机上,预览显示在表单之后;先缩小内边距,再压缩控件。
SumUp Circuit 设计系统中的商品验证与草稿状态
格式化前验证完整字符串
应用接受一至五位整数,以及最多两位小数,并要求数值为正数。这是示例自行设定的规则,可避免 parseFloat 接受 24abc 这样的不完整字符串,并会在提交后将焦点移到第一个无效的原生 Input。
任何编辑都会清除过期的核对结果
编辑名称、金额或备注可见性,都会使之前的快照失效。成功状态包含已核对的商品名称和金额,因此对应的是一份具体草稿。代码不会将此结果存入后端,也不会创建支付请求。
SumUp Circuit 设计系统中的输入恢复与预览语义
检查两个字段的错误处理
商品名称和价格使用原生必填标签、无效状态和 validationHint。源代码保留了输入框引用,以便将焦点移回第一个验证失败的字段。无需输入真实的顾客或银行卡数据,即可测试错误恢复。
- 清空名称并提交,查看第一个字段的错误提示。
- 尝试输入 24abc 或 0,然后将金额更正为 24.50。
- 在本地核对后编辑字段,过期的快照便会消失。
如实标注插图和静态预览
插图带有简短的图片用途说明。顾客备注区域是说明性占位内容,位于明确标注的预览中,并非伪装成可编辑的输入框。真正用于设置备注的复选框保留在商家表单中,并控制预览区域是否显示。
SumUp Circuit 设计系统 React 与 CSS 集成
引入公开的同级依赖和两个样式表
入口使用 React 18 和固定版本的 Circuit 组件,并按照软件包要求引入令牌、图标、国际化和 Emotion 同级依赖。代码显式导入 light.css 和 styles.css,不依赖未公开说明的 provider 或隐藏的项目级主题设置。
- @sumup/circuit-ui 8.15.0 组件样式。
- @sumup/design-tokens 7.3.1 完整浅色主题。
- React 18 以及组件包声明的同级依赖。
仅在真实应用中添加支付服务
SumUp Circuit 设计系统组件示例
main.jsx — 完整可运行示例
编辑商品并查看顾客侧预览。下方源代码是完整的 React 入口,包含所有状态和验证逻辑。
jsx
import React, { useState, useRef } from "react";
import { createRoot } from "react-dom/client";
import { Input, Checkbox, Button, Headline, Body } from "@sumup/circuit-ui";
import "@sumup/design-tokens/light.css";
import "@sumup/circuit-ui/styles.css";
import "./circuit.css";
function App() {
const [name, setName] = useState("Studio print"),
[price, setPrice] = useState("24.00"),
[note, setNote] = useState(true),
[errors, setErrors] = useState({}),
[review, setReview] = useState(null);
const nameRef = useRef(),
priceRef = useRef();
const valid = /^\d{1,5}(\.\d{1,2})?$/.test(price) && Number(price) > 0;
const amount = valid
? new Intl.NumberFormat("en-IE", {
style: "currency",
currency: "EUR",
}).format(Number(price))
: "—";
function change(fn) {
fn();
setReview(null);
setErrors({});
}
function submit(e) {
e.preventDefault();
const next = {};
if (!name.trim()) next.name = "Enter an item name.";
if (!valid)
next.price = "Use a positive amount with up to two decimal places.";
setErrors(next);
if (next.name) {
nameRef.current.focus();
return;
}
if (next.price) {
priceRef.current.focus();
return;
}
setReview({ name: name.trim(), amount, note });
}
return (
<main className="circuit-example">
<header>
<p className="eyebrow">MERCHANT TOOLS / LOCAL SPECIMEN</p>
<Headline as="h1">Prepare a simple item</Headline>
<Body>
Review how an item could appear to a customer. This example never
creates a payment link.
</Body>
</header>
<div className="circuit-grid">
<form onSubmit={submit} noValidate>
<h2>Item details</h2>
<Input
ref={nameRef}
label="Item name"
required
value={name}
maxLength={80}
invalid={!!errors.name}
validationHint={
errors.name || "Use a short name the customer can recognize."
}
onChange={(e) => change(() => setName(e.target.value))}
/>
<Input
ref={priceRef}
label="Price in EUR"
required
inputMode="decimal"
value={price}
invalid={!!errors.price}
validationHint={
errors.price || "Example amount only; no charge will be made."
}
onChange={(e) => change(() => setPrice(e.target.value))}
/>
<Checkbox
label="Show a customer note field"
checked={note}
onChange={(e) => change(() => setNote(e.target.checked))}
/>
<Button variant="primary" type="submit" stretch>
Review item locally
</Button>
{review && (
<div className="review" role="status">
<strong>Item reviewed</strong>
<p>
{review.name} · {review.amount}
</p>
<small>
Local snapshot only. No payment link or charge created.
</small>
</div>
)}
</form>
<section className="preview-surface" aria-labelledby="preview-heading">
<h2 id="preview-heading">Customer-side preview</h2>
<div className="receipt">
<div className="shop-mark" aria-hidden="true">
N
</div>
<p className="shop-name">Northstar Studio</p>
<div
className="print-art"
role="img"
aria-label="Original geometric print illustration"
>
<i></i>
<b></b>
<span></span>
</div>
<h3>{name.trim() || "Your item name"}</h3>
<p className="receipt-price">{amount}</p>
{note && (
<div className="note-placeholder">
<span>Customer note</span>
<p>A note field would appear here.</p>
</div>
)}
<div className="preview-action">
Preview only · checkout unavailable
</div>
</div>
</section>
</div>
<footer>
Native Circuit UI 8.15.0 components and design tokens 7.3.1. Original
item editor and illustration by OpenDesign.
</footer>
</main>
);
}
createRoot(document.getElementById("root")).render(<App />);
代码参考
- 创建 Vite React 项目,保留 <div id="root"></div>,并将以下内容保存为 src/main.jsx。
circuit.css — 原始响应式布局
围绕原生组件构建的应用布局。
css
* {
box-sizing: border-box;
}
body {
margin: 0;
background: var(--cui-bg-normal);
color: var(--cui-fg-normal);
font: 16px/1.5 var(--cui-font-stack-default);
}
.circuit-example {
padding: 32px;
}
.circuit-example header {
max-width: 720px;
margin-bottom: 32px;
}
.eyebrow {
font-size: 12px;
letter-spacing: 0.08em;
margin-bottom: 12px;
color: var(--cui-fg-subtle);
}
.circuit-grid {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(300px, 1fr);
gap: 48px;
}
.circuit-example h2 {
font-size: 20px;
font-weight: 700;
margin: 0 0 24px;
}
.circuit-example form {
max-width: 540px;
display: flex;
flex-direction: column;
gap: 24px;
}
.circuit-example form h2 {
margin: 0;
}
.preview-surface {
background: var(--cui-bg-subtle);
padding: 28px;
border-radius: 16px;
}
.preview-surface > h2 {
font-size: 14px;
color: var(--cui-fg-subtle);
text-align: center;
}
.receipt {
max-width: 340px;
margin: auto;
background: white;
border-radius: 12px;
box-shadow: 0 4px 20px #0000000d;
padding: 24px;
}
.shop-mark {
width: 40px;
height: 40px;
border-radius: 50%;
background: #0f131a;
color: #fff;
display: grid;
place-items: center;
font-weight: 700;
margin: auto;
}
.shop-name {
text-align: center;
font-size: 14px;
margin: 12px 0 20px;
}
.print-art {
height: 150px;
background: #f5dfbb;
position: relative;
overflow: hidden;
border-radius: 8px;
}
.print-art i {
position: absolute;
left: 24px;
bottom: 0;
width: 100px;
height: 130px;
border-radius: 60px 60px 0 0;
background: #ce663d;
}
.print-art b {
position: absolute;
right: 20px;
top: 20px;
width: 90px;
height: 90px;
border-radius: 50%;
background: #385d50;
}
.print-art span {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 24px;
background: #202e2a;
}
.receipt h3 {
font-size: 20px;
line-height: 1.3;
margin: 20px 0 8px;
overflow-wrap: anywhere;
}
.receipt-price {
font-size: 28px;
font-weight: 700;
margin: 0 0 24px;
}
.note-placeholder {
padding: 12px;
border: 1px solid #bfc6cf;
border-radius: 8px;
margin-bottom: 16px;
font-size: 12px;
}
.note-placeholder span {
font-weight: 700;
}
.note-placeholder p {
margin: 4px 0 0;
color: #4f5a65;
}
.preview-action {
background: #e9edf2;
text-align: center;
border-radius: 999px;
padding: 12px;
font-size: 12px;
color: #4f5a65;
}
.review {
padding: 20px;
background: #e7f5ef;
border-radius: 8px;
}
.review p {
margin: 8px 0;
}
.review small {
font-size: 12px;
}
.circuit-example footer {
font-size: 12px;
color: var(--cui-fg-subtle);
margin-top: 32px;
}
@media (max-width: 850px) {
.circuit-grid {
grid-template-columns: 1fr;
gap: 32px;
}
.circuit-example form {
max-width: none;
}
}
@media (max-width: 550px) {
.circuit-example {
padding: 20px 16px;
}
.preview-surface {
padding: 20px;
}
.receipt {
padding: 20px;
}
}
代码参考
- 将其保存在 main.jsx 旁边。这些自定义组合规则有别于库的设计令牌参考。
04SumUp Circuit 设计系统 AI Agent 设置
实现起点
已打包固定的原生示例,并在本地浏览器中完成检查。该示例仅使用本地应用状态。
适用于你项目的提示词
Agent 提示词
使用固定版本的原生控件和两个必需的样式表,构建 Circuit 商品编辑器。验证完整的金额字符串,保留币种格式,编辑后清除过期的本地核对结果,并确保顾客侧预览与真实结账流程明确区分。使用原始插图和准确的语义令牌角色。
05SumUp Circuit 设计系统:来源与范围
OpenDesign 针对固定版本 Circuit 包的应用指南。插图、金额和项目均为示例。此本地编辑器不会创建付款链接、发起扣款或执行任何 SumUp 账户操作;当前上游包使用更新后的 @sumup-oss 命名空间。