金融テクノロジー · 新しいリソース

SumUp Circuitデザインシステム.

正確なセマンティックトークン、ネイティブの検証用props、完全なマーチャント向け商品編集画面、図解付きの顧客側プレビューを備えたCircuitガイド。

OpenDesign ガイド8章39件のリファレンス項目オリジナルアプリケーションガイド
01

SumUp Circuitデザインシステムのインターフェースプレビュー

形式が正しくない金額を入力し、商品名を変更し、備考欄を切り替えて、ローカルのスナップショットを確認します。

商品を編集し、顧客側のプレビューを確認完全な例を開く
ネイティブの@sumup/circuit-ui 8.15.0と、@sumup/design-tokens 7.3.1のlight CSSを使用した、オリジナルのローカル商品エディター。 実装リファレンス
02

SumUp Circuitデザインシステムのデザインリファレンス

ネイティブの@sumup/circuit-ui 8.15.0と、@sumup/design-tokens 7.3.1のlight 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-bit4px固定したCSSのエクスポートから取得した、名前付きのスペーシング段階。
--cui-spacings-byte8px固定したCSSのエクスポートから取得した、名前付きのスペーシング段階。
--cui-spacings-kilo12px固定したCSSのエクスポートから取得した、名前付きのスペーシング段階。
--cui-spacings-mega16px固定したCSSのエクスポートから取得した、名前付きのスペーシング段階。
--cui-spacings-giga24px固定したCSSのエクスポートから取得した、名前付きのスペーシング段階。
--cui-spacings-tera32px固定したCSSのエクスポートから取得した、名前付きのスペーシング段階。
--cui-spacings-peta40px固定したCSSのエクスポートから取得した、名前付きのスペーシング段階。
--cui-spacings-exa48px固定したCSSのエクスポートから取得した、名前付きのスペーシング段階。
--cui-spacings-zetta56px固定したCSSのエクスポートから取得した、名前付きのスペーシング段階。
名前 / ルール値 / 設定用途
--cui-border-radius-bit4pxコントロールまたは界面表面の役割に応じて形状を使い分けます。
--cui-border-radius-byte8pxコントロールまたは界面表面の役割に応じて形状を使い分けます。
--cui-border-radius-kilo12pxコントロールまたは界面表面の役割に応じて形状を使い分けます。
--cui-border-radius-mega16pxコントロールまたは界面表面の役割に応じて形状を使い分けます。
--cui-border-radius-circle100%コントロールまたは界面表面の役割に応じて形状を使い分けます。
--cui-border-radius-pill999999pxコントロールまたは界面表面の役割に応じて形状を使い分けます。

フォントファミリーとウェイト

ソース
名前 / ルール値 / 設定用途
--cui-font-stack-defaultaktiv-grotesk, Helvetica, Arial, system-ui, sans-serif, "Segoe UI", Roboto, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"この例では利用可能なフォールバックを使用しており、Aktiv Groteskは読み込みません。
--cui-font-stack-monoMenlo, Consolas, Monaco, Liberation Mono, Lucida Console, monospaceこの例では利用可能なフォールバックを使用しており、Aktiv Groteskは読み込みません。
--cui-font-weight-regular400この例では利用可能なフォールバックを使用しており、Aktiv Groteskは読み込みません。
--cui-font-weight-bold700この例では利用可能なフォールバックを使用しており、Aktiv Groteskは読み込みません。

主要アクションの状態

ソース
名前 / ルール値 / 設定用途
--cui-bg-accent-strong#0f131a 通常、ホバー、押下、無効の状態をそれぞれ維持します。
--cui-bg-accent-strong-hovered#3b3f46 通常、ホバー、押下、無効の状態をそれぞれ維持します。
--cui-bg-accent-strong-pressed#6a737c 通常、ホバー、押下、無効の状態をそれぞれ維持します。
--cui-bg-accent-strong-disabledrgba(15, 19, 26, .4)通常、ホバー、押下、無効の状態をそれぞれ維持します。

入力欄とボタンの公開プロパティ

ソース
名前 / ルール値 / 設定用途
Input.labelrequired stringフィールドの用途を明示します。
Input.invalidbooleanネイティブの無効入力スタイルとアクセシビリティ状態。
Input.validationHintstringコントロールの下に具体的な案内を表示します。
Button.variantprimary / secondary / tertiary固定したこのバージョンにおけるアクションの優先順位。
Button.sizes / mバージョン8.15.0での現在のサイズ値。
Button.stretchbooleanローカルの確認アクションを親要素の幅いっぱいに広げます。
03

SumUp Circuitデザインシステム完全ガイド

実際のインターフェースで、このデザインシステムを選び、適用し、レビューするための実践ガイドです。

DESIGN-sumup-circuit.md

詳しいガイダンス、実装の出発点、ソースへのリンクをまとめています。

ガイドをダウンロード

SumUp Circuitデザインシステムのマーチャント向けエディター構成

販売者の入力と顧客向けの表示を分ける

商品エディターとレシート風のプレビューで、同じ状態を異なる視点から表示します。短いフォームで商品名と例示用の価格を設定し、顧客向けのメモ欄を表示するかどうかを選択できます。プレビューでその変更を確認できますが、チェックアウトは作成せず、支払い情報も求めません。

この OpenDesign ガイドから

オリジナルの商品イラストを使用する

幾何学模様の画像は、アクセシブルな説明文を添えたオリジナルのCSS作品です。空白の画像領域ではなく、顧客向けプレビューに目を引くオブジェクトを表示できます。販売者が撮影したように見える偽の写真や、SumUpの商品アセットの複製は使用しません。

SumUp Circuit デザインシステムのセマンティックテーマとパッケージの適用範囲

固定されたテーマをそのまま使用する

この例では、@sumup/circuit-ui 8.15.0 と @sumup/design-tokens 7.3.1 を使用します。参照表は、このパッケージの light.css から読み取ります。現在の上流ドキュメントでは @sumup-oss 名前空間への移行が進んでいます。この例は再現可能な固定バージョンでの統合であり、旧名前空間が最新リリースだと主張するものではありません。

コンポーネントのスタイルとデザイントークンのスタイルを読み込む

React エントリーポイントでは、コンポーネントのスタイルシートと light トークンファイルの両方を読み込みます。CSS カスタムプロパティが定義されていなければ、コンポーネントのクラス名だけでは不十分です。スコープを限定したダークパレットを使う場合も、共通の色以外の値を提供するため、完全なベーステーマが必要です。

SumUp Circuit デザインシステムのニュートラルな背景とアクションのコントラスト

商品を視覚的な主役にする

エディターには白い背景と暗い前景色を使用し、顧客向けプレビューは控えめなニュートラルカラーの背景に配置します。オリジナルのイラストは商品画像内に色を効果的に加えつつ、標準のプライマリアクションを読みやすく、見つけやすい状態に保ちます。

プレビューのアクションが操作できないことを明確にする

顧客側のフッターには「プレビューのみ」と示すテキストを配置します。まもなく利用できそうに見える無効状態の「支払う」ボタンは表示しません。実際の送信アクションはエディター内にのみあり、ローカルの商品を確認するためのものです。これにより、サンプルで実際に操作できる範囲がわかりやすくなります。

SumUp Circuit デザインシステムのタイポグラフィとフォールバック

テーマのフォントスタックを正確に扱う

公開されているフォントスタックは、Aktiv Grotesk を先頭に、Helvetica、Arial、システムフォントのフォールバックを含みます。このオフラインのサンプルでは、先頭のフォントをダウンロードしません。標準の Headline と Body コンポーネントで意図した階層を表現し、実際の字形は利用可能なフォントに応じて決まります。

価格と通貨を一緒に表示する

SumUp Circuit デザインシステムのスペーシングと角丸の背景

名前付きの段階をそのまま使う

トークンのスケールには、bit、byte、kilo、mega などの名前が付いています。これらはデザイン上のラベルであり、2 の累乗を表すものではありません。名前の比喩から独自のスケールを作らずに済むよう、表には正確なピクセル値を記載しています。

階層を崩さずにコントロールの端を揃える

フォームでは一貫した縦方向の間隔を使い、プライマリアクションを全幅にします。プレビューには、角丸を大きくした外側の背景と、ひと回り小さいレシート領域を使います。スマートフォンではプレビューをフォームの下に配置し、コントロールを圧縮する前にパディングを小さくします。

SumUp Circuit デザインシステムの商品検証と下書き状態

書式設定の前に文字列全体を検証する

アプリケーションでは、整数部分が1~5桁で小数部分が最大2桁の、正の数値を受け付けます。これはサンプル用に定めたルールです。24abc のような文字列の一部だけを parseFloat が受け入れてしまうのを防ぎ、送信時には、最初に無効となった標準の Input にフォーカスを移します。

編集があれば古い確認結果をクリアする

商品名、価格、メモ欄の表示設定のいずれを編集しても、前回のスナップショットは無効になります。成功時の状態には確認済みの商品名と価格が含まれるため、具体的な下書きに紐づきます。このコードは結果をバックエンドに保存せず、支払いリクエストも作成しません。

SumUp Circuit デザインシステムの入力エラーからの復帰とプレビューの意味

両方のフィールドエラーを確認する

商品名と価格には、標準の required ラベル、無効状態、validationHint を使用します。ソースコードでは入力への参照を保持し、最初にエラーとなったフィールドにフォーカスを戻します。顧客やカードの実データを入力せずに、エラーからの復帰をテストできます。

  1. 商品名を消して送信し、最初のフィールドエラーを確認します。
  2. 24abc または 0 を入力してから、価格を 24.50 に修正します。
  3. ローカルで確認したあと、フィールドを編集して古いスナップショットを閉じます。

イラストと静的プレビューを正確に説明する

イラストには、画像の役割を示す短い説明文を付けます。顧客向けメモ欄は、プレビューであることを明示した領域内の説明用プレースホルダーであり、編集できるように見せかけた入力欄ではありません。実際のメモ設定チェックボックスは販売者向けフォームにあり、プレビュー内の該当領域の表示を切り替えます。

SumUp Circuit デザインシステムのReactとCSSの統合

公開されているピア依存関係と両方のスタイルシートを含める

このエントリーポイントでは、React 18 と固定バージョンの Circuit コンポーネントを使用し、パッケージ要件に合ったトークン、アイコン、国際化、Emotion のピア依存関係を含めます。light.css と styles.css は明示的に読み込みます。ドキュメントに記載されていないプロバイダーや、プロジェクトレベルで隠れているテーマ設定には依存しません。

  • @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 と同じ場所に保存します。ライブラリのトークンリファレンスとは異なる、カスタムの構成ルールです。
04

SumUp Circuit デザインシステムのAIエージェント設定

実装の出発点

バージョンを固定したネイティブのサンプルをバンドルし、ローカルのブラウザーで動作を確認しました。このサンプルでは、アプリケーションのローカルな状態だけを使用します。

シェル
npm create vite@latest circuit-item -- --template react
cd circuit-item
npm install
npm install [email protected] [email protected] @sumup/[email protected] @sumup/[email protected] @sumup/icons @sumup/intl@1 @emotion/react @emotion/styled @emotion/is-prop-valid
# Replace src/main.jsx and add src/circuit.css.
npm run dev

あなたのプロジェクト向けプロンプト

AI エージェント用プロンプト
固定されたネイティブコントロールと、必須の2つのスタイルシートを使って、Circuitの項目編集画面を作成します。金額の文字列全体を検証し、通貨の書式を保持し、編集後は古いローカルレビューをクリアして、顧客向けプレビューと実際のチェックアウトを明確に区別してください。元のイラストと、正確なセマンティックトークンの役割を使用してください。
05

SumUp Circuit デザインシステムの情報源と対象範囲

固定されたCircuitパッケージ世代に対応するOpenDesignのアプリケーションガイドです。イラスト、金額、項目は例です。このローカル編集画面では、決済リンクの作成、請求、SumUpアカウントの操作は行いません。現在の上流パッケージでは、新しい@sumup-oss名前空間が使われています。