云平台 · 新资源

AWS Cloudscape 设计系统.

一份 Cloudscape 配置指南,包含真实的可视化刷新令牌、感知密度的间距、受控表单 API,以及可运行的两步资源向导。

OpenDesign 指南8 个章节50 个参考条目原始应用指南
01

AWS Cloudscape 设计系统界面预览

尝试无效名称、选择容量配置,在配置与审核步骤之间切换、更改外观,并在本地确认配置。

配置并审核工作区打开完整示例
原生 Cloudscape 3.0.1390 搭配 React 18.3.1;采用原创建向导组合和仅限本地的状态。· 实现参考
02

AWS Cloudscape 设计系统设计参考

Cloudscape 组件 3.0.1390 和 design-tokens 3.0.114,采用 visual-refresh 主题。数值取自已发布的令牌 JSON。颜色模式与内容密度是相互独立的维度。这是精选的实现参考,并非完整的令牌导出。

浅色与深色模式下的语义化颜色角色

来源
名称 / 规则值 / 配置用途
color-background-layout-mainlight: #ffffff; dark: #161d26请在该命名角色的预期使用场景中使用它;此处并列展示浅色与深色模式下的取值,并非可互换的色样。
color-background-container-contentlight: #ffffff; dark: #161d26请在该命名角色的预期使用场景中使用它;此处并列展示浅色与深色模式下的取值,并非可互换的色样。
color-text-body-defaultlight: #0f141a; dark: #c6c6cd请在该命名角色的预期使用场景中使用它;此处并列展示浅色与深色模式下的取值,并非可互换的色样。
color-text-body-secondarylight: #424650; dark: #c6c6cd请在该命名角色的预期使用场景中使用它;此处并列展示浅色与深色模式下的取值,并非可互换的色样。
color-text-interactive-defaultlight: #424650; dark: #dedee3请在该命名角色的预期使用场景中使用它;此处并列展示浅色与深色模式下的取值,并非可互换的色样。
color-text-link-defaultlight: #006ce0; dark: #42b4ff请在该命名角色的预期使用场景中使用它;此处并列展示浅色与深色模式下的取值,并非可互换的色样。
color-text-status-errorlight: #db0000; dark: #ff7a7a请在该命名角色的预期使用场景中使用它;此处并列展示浅色与深色模式下的取值,并非可互换的色样。
color-text-status-successlight: #00802f; dark: #2bb534请在该命名角色的预期使用场景中使用它;此处并列展示浅色与深色模式下的取值,并非可互换的色样。
color-border-input-defaultlight: #8c8c94; dark: #656871请在该命名角色的预期使用场景中使用它;此处并列展示浅色与深色模式下的取值,并非可互换的色样。
color-background-button-primary-defaultlight: #006ce0; dark: #42b4ff请在该命名角色的预期使用场景中使用它;此处并列展示浅色与深色模式下的取值,并非可互换的色样。

正文与标题排版

来源
名称 / 规则值 / 配置用途
font-size-body-m14px搭配使用同一角色的 font-size 和 line-height。Header 和 Box 的变体用于体现组件层级。
font-size-body-s12px搭配使用同一角色的 font-size 和 line-height。Header 和 Box 的变体用于体现组件层级。
font-size-heading-l20px搭配使用同一角色的 font-size 和 line-height。Header 和 Box 的变体用于体现组件层级。
font-size-heading-m18px搭配使用同一角色的 font-size 和 line-height。Header 和 Box 的变体用于体现组件层级。
font-size-heading-s16px搭配使用同一角色的 font-size 和 line-height。Header 和 Box 的变体用于体现组件层级。
font-size-heading-xl24px搭配使用同一角色的 font-size 和 line-height。Header 和 Box 的变体用于体现组件层级。
font-size-heading-xs14px搭配使用同一角色的 font-size 和 line-height。Header 和 Box 的变体用于体现组件层级。
line-height-body-m20px搭配使用同一角色的 font-size 和 line-height。Header 和 Box 的变体用于体现组件层级。
line-height-body-s16px搭配使用同一角色的 font-size 和 line-height。Header 和 Box 的变体用于体现组件层级。
line-height-heading-l24px搭配使用同一角色的 font-size 和 line-height。Header 和 Box 的变体用于体现组件层级。
line-height-heading-m22px搭配使用同一角色的 font-size 和 line-height。Header 和 Box 的变体用于体现组件层级。
line-height-heading-s20px搭配使用同一角色的 font-size 和 line-height。Header 和 Box 的变体用于体现组件层级。
line-height-heading-xl30px搭配使用同一角色的 font-size 和 line-height。Header 和 Box 的变体用于体现组件层级。
line-height-heading-xs18px搭配使用同一角色的 font-size 和 line-height。Header 和 Box 的变体用于体现组件层级。

适配密度的间距

来源
名称 / 规则值 / 配置用途
space-scaled-xxxscomfortable: 2px; compact: 0px根据当前密度使用舒适或紧凑模式下的取值。不要随这些间距变化缩放文本。
space-scaled-xxscomfortable: 4px; compact: 2px根据当前密度使用舒适或紧凑模式下的取值。不要随这些间距变化缩放文本。
space-scaled-xscomfortable: 8px; compact: 4px根据当前密度使用舒适或紧凑模式下的取值。不要随这些间距变化缩放文本。
space-scaled-scomfortable: 12px; compact: 8px根据当前密度使用舒适或紧凑模式下的取值。不要随这些间距变化缩放文本。
space-scaled-mcomfortable: 16px; compact: 12px根据当前密度使用舒适或紧凑模式下的取值。不要随这些间距变化缩放文本。
space-scaled-lcomfortable: 20px; compact: 16px根据当前密度使用舒适或紧凑模式下的取值。不要随这些间距变化缩放文本。
space-scaled-xlcomfortable: 24px; compact: 20px根据当前密度使用舒适或紧凑模式下的取值。不要随这些间距变化缩放文本。
space-scaled-xxlcomfortable: 32px; compact: 24px根据当前密度使用舒适或紧凑模式下的取值。不要随这些间距变化缩放文本。
space-scaled-xxxlcomfortable: 40px; compact: 32px根据当前密度使用舒适或紧凑模式下的取值。不要随这些间距变化缩放文本。

组件形状

来源
名称 / 规则值 / 配置用途
border-radius-container16px保留指定组件的形状。按钮圆角不等于容器的通用圆角。
border-radius-button20px保留指定组件的形状。按钮圆角不等于容器的通用圆角。
border-radius-input8px保留指定组件的形状。按钮圆角不等于容器的通用圆角。
border-radius-alert12px保留指定组件的形状。按钮圆角不等于容器的通用圆角。
border-radius-dropdown8px保留指定组件的形状。按钮圆角不等于容器的通用圆角。
border-radius-card-embedded8px保留指定组件的形状。按钮圆角不等于容器的通用圆角。

交互时序

来源
名称 / 规则值 / 配置用途
motion-duration-responsivedefault: 115ms; disabled: 0ms在禁用动态效果模式下,原生动效会归零。避免为同一交互添加无关的过渡效果。
motion-duration-expressivedefault: 165ms; disabled: 0ms在禁用动态效果模式下,原生动效会归零。避免为同一交互添加无关的过渡效果。
motion-duration-complexdefault: 250ms; disabled: 0ms在禁用动态效果模式下,原生动效会归零。避免为同一交互添加无关的过渡效果。

原生组合 API

来源
名称 / 规则值 / 配置用途
WizardactiveStepIndex · onNavigate · onSubmit在 React 中维护当前步骤;接受请求的下一步索引前先进行验证。
FormFieldlabel · constraintText · errorText将格式规则和无效输入反馈与名称输入框放在一起。
Inputvalue · onChange({ detail })读取 detail.value,而不是 DOM 事件目标。
SelectselectedOption · options · onChange保留所选选项对象,包括 label 和 value。
Containerheader={<Header variant="h2" />}将相关配置字段分组,无需另创一套卡片体系。
ColumnLayoutcolumns={2} · variant="text-grid"使用可响应组件库布局的列展示精简的审核元数据。
SpaceBetweensize="l"使用组件库的间距比例分隔字段和审核模块。
applyModeMode.Light / Mode.Dark切换全局视觉模式,以应用于原生组件和语义令牌。
03

AWS Cloudscape 设计系统完整指南

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

DESIGN-aws-cloudscape.md

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

下载指南

AWS Cloudscape 设计系统配置架构

使用 Wizard 匹配工作流

此示例将配置与审核分开。Wizard 提供步骤导航和操作;应用则负责当前索引、字段值、验证规则和最终确认。用户可以返回配置,而无需重新构建表单或丢失所选容量。相比将整个多步骤工作流藏在一个通用 Card 中,这种方式更合适。

摘自本 OpenDesign 指南

使用原生容器构建

Container、Header 和 SpaceBetween 用于定义表单区域。h1 介绍操作,h2 标示设置分组。说明文字紧邻其所描述的字段或步骤。外围 1200px 最大宽度和页面内边距是应用明确设置的 CSS,不是导出的 Cloudscape 布局令牌。

AWS Cloudscape 设计系统语义令牌与视觉模式

先选定用途,再选择值

此参考将布局背景、容器内容、正文文本、交互文本和状态反馈区分开来。它们的值并非一组无差别的配色。为自定义 UI 添加样式时,应从 @cloudscape-design/design-tokens 导入具名令牌,而不是在每种状态中复制浅色十六进制值。令牌约定的是用途,具体值则可以演进。

通过组件库切换模式

此预览通过 global-styles 中的 Mode.Light 或 Mode.Dark 调用 applyMode。这样会更新组件使用的模式,而不是替换任意 CSS 颜色。深色审核页面仍保留相同的标签、所选容量和导航状态。源 JSON 记录了浅色和深色模式下的解析结果,便于检查二者的区别。

AWS Cloudscape 设计系统字体排印与标题层级

搭配使用字体和行高角色

visual-refresh 中的 body-m 参考值为 14px 字号、20px 行高。heading-xl 为 24px 字号、30px 行高;heading-l 为 20px 字号、24px 行高;heading-m 为 18px 字号、22px 行高。这些角色定义了紧凑的表单层级,并非可以互换的营销展示字号。

使用语义化组件变体

使用 Header 的 h1 变体标示“创建工作区”。容器标题使用 h2,Box 的 awsui-key-label 变体则为审核标签提供一致的次级样式。审核值仍使用常规易读文本。不要仅为增强视觉分量,就把每个字段标签都提升为标题。

AWS Cloudscape 设计系统受控字段与审核组合

了解 detail 事件约定

Input 会触发一个事件,新文本位于 event 的 detail.value 中。Select 会触发包含 detail.selectedOption 的事件;它是一个选项对象,而非单独的字符串。完整示例会存储该对象,并在审核视图中显示其 label。这样可以避免常见的集成错误:只传入选项标识符作为 selectedOption,导致 Select 显示为空。

将字段说明与字段放在一起

  • 字段格式规则属于此示例应用。
  • 容量选项不代表产品或定价声明。
  • 原生组件负责呈现;配置由 React 状态维护。

AWS Cloudscape 设计系统密度与响应式布局

不要将紧凑模式视为缩放级别

已发布的缩放间距值会随密度而异。例如,space-scaled-m 在舒适模式下为 16px,在紧凑模式下为 12px;space-scaled-l 则分别为 20px 和 16px。这些差异会压缩垂直节奏,但不会重新定义内容,也不会任意缩小文字。原生组件会应用各自的密度规则。

让步骤和审核布局灵活适配

Wizard 会根据可用宽度调整导航呈现方式;ColumnLayout 会响应式排列审核元数据。应用的 CSS 会在宽度低于 600px 时缩小外围内边距。示例不会将桌面端步骤导航宽度写死,移动端也会保留本地可见的“下一步”“上一步”和“确认”操作。

AWS Cloudscape 设计系统 Wizard 验证与确认

接受导航前先进行验证

onNavigate 会接收 requestedStepIndex。应用会在切换到审核步骤前检查名称;如果名称无效,就保持当前步骤不变。编辑名称时会清除错误,以便下次提交时重新验证。返回设置步骤时,名称和所选选项都会保留。

  1. 提交无效名称,停留在配置步骤。
  2. 更正名称并选择其他容量配置档案。
  3. 前往审核并确认两个值。
  4. 使用“编辑设置”返回,同时保留这两个值。
  5. 在本地确认并重新开始示例。

区分操作示例与资源预置

最终操作会显示本地成功 Alert 和配置摘要,不会假装创建了真实资源。在实际应用中,资源预置期间应让提交操作保持待处理状态,区分请求已受理与资源已创建完成,并提供失败后的恢复方式,同时保留配置。

AWS Cloudscape 设计系统表单无障碍设计

保留标签和导航名称

Wizard 接收 navigationAriaLabel 和已翻译的操作文案。每个 Input 和 Select 都包含在带标签的 FormField 中。Alert 通过原生组件语义传达无效或成功的结果。可见的约束条件用于补充字段标签,而不是替代它。

检查整个操作流程中的键盘导航路径

使用键盘定位到名称字段,打开容量选择器,继续下一步、返回、编辑并确认。原生焦点行为会有所帮助,但步骤验证规则及确认操作的含义仍由应用负责。组件库无法自行验证缺失的业务规则。

AWS Cloudscape 设计系统安装与自定义边界

同时安装相关软件包

实现通过各自的软件包子路径导入组件,并且只加载一次 global-styles。design-tokens 提供自定义样式参考。提供的 React 入口文件和精简的 CSS 文件,可在 Vite React 应用中复现此交互示例。请确保 Cloudscape 软件包版本彼此兼容。

以提供的示例为实际起点

AWS Cloudscape 设计系统组件示例

main.jsx — 完整配置向导

使用原生 Wizard、FormField、Select 和审核元数据,并通过受控导航和本地确认进行管理。

jsx
import React, { useState } from "react";
import { createRoot } from "react-dom/client";
import Wizard from "@cloudscape-design/components/wizard";
import Container from "@cloudscape-design/components/container";
import Header from "@cloudscape-design/components/header";
import FormField from "@cloudscape-design/components/form-field";
import Input from "@cloudscape-design/components/input";
import Select from "@cloudscape-design/components/select";
import SpaceBetween from "@cloudscape-design/components/space-between";
import ColumnLayout from "@cloudscape-design/components/column-layout";
import Box from "@cloudscape-design/components/box";
import Button from "@cloudscape-design/components/button";
import Alert from "@cloudscape-design/components/alert";
import Toggle from "@cloudscape-design/components/toggle";
import { applyMode, Mode } from "@cloudscape-design/global-styles";
import "@cloudscape-design/global-styles/index.css";
import "./cloudscape.css";
const sizes = [
  { label: "Development · 2 vCPU / 4 GiB", value: "dev" },
  { label: "Standard · 4 vCPU / 8 GiB", value: "standard" },
  { label: "Compute · 8 vCPU / 16 GiB", value: "compute" },
];
function App() {
  const [name, setName] = useState("analytics-sandbox"),
    [size, setSize] = useState(sizes[0]),
    [step, setStep] = useState(0),
    [error, setError] = useState(""),
    [complete, setComplete] = useState(false),
    [dark, setDark] = useState(false);
  function next(index) {
    if (index > 0 && !/^[a-z][a-z0-9-]{2,29}$/.test(name)) {
      setError(
        "Use 3–30 lowercase letters, numbers or hyphens, starting with a letter.",
      );
      return;
    }
    setError("");
    setStep(index);
  }
  function reset() {
    setStep(0);
    setComplete(false);
    setError("");
    setName("analytics-sandbox");
    setSize(sizes[0]);
  }
  return (
    <main className="awsui-typography cloudscape-example">
      <div className="appearance">
        <span>CLOUDSCAPE · RESOURCE CONFIGURATION</span>
        <Toggle
          checked={dark}
          onChange={({ detail }) => {
            setDark(detail.checked);
            applyMode(detail.checked ? Mode.Dark : Mode.Light);
          }}
        >
          Dark mode
        </Toggle>
      </div>
      <Header
        variant="h1"
        description="Configure a fictional compute workspace. This example does not create a cloud resource."
      >
        Create a workspace
      </Header>
      <div className="wizard-content">
        {complete ? (
          <SpaceBetween size="l">
            <Alert type="success" header="Configuration confirmed locally">
              The {name} recipe is ready for review. No cloud API was called and
              no resource was provisioned.
            </Alert>
            <Container header={<Header variant="h2">Workspace recipe</Header>}>
              <ColumnLayout columns={2} variant="text-grid">
                <div>
                  <Box variant="awsui-key-label">Name</Box>
                  {name}
                </div>
                <div>
                  <Box variant="awsui-key-label">Capacity</Box>
                  {size.label}
                </div>
              </ColumnLayout>
            </Container>
            <Button onClick={reset}>Start another example</Button>
          </SpaceBetween>
        ) : (
          <Wizard
            activeStepIndex={step}
            onNavigate={({ detail }) => next(detail.requestedStepIndex)}
            onCancel={reset}
            onSubmit={() => setComplete(true)}
            i18nStrings={{
              stepNumberLabel: (stepNumber) => `Step ${stepNumber}`,
              collapsedStepsLabel: (stepNumber, stepsCount) =>
                `Step ${stepNumber} of ${stepsCount}`,
              skipToButtonLabel: (step) => `Skip to ${step.title}`,
              navigationAriaLabel: "Configuration steps",
              cancelButton: "Reset",
              previousButton: "Previous",
              nextButton: "Next",
              submitButton: "Confirm locally",
              optional: "optional",
            }}
            steps={[
              {
                title: "Configure workspace",
                description: "Choose the identity and capacity.",
                content: (
                  <Container
                    header={<Header variant="h2">Workspace settings</Header>}
                  >
                    <SpaceBetween size="l">
                      <FormField
                        label="Workspace name"
                        constraintText="3–30 characters; lowercase letters, numbers and hyphens."
                        errorText={error}
                      >
                        <Input
                          value={name}
                          onChange={({ detail }) => {
                            setName(detail.value);
                            setError("");
                          }}
                        />
                      </FormField>
                      <FormField
                        label="Capacity profile"
                        description="These profiles are sample application data, not real cloud products or prices."
                      >
                        <Select
                          selectedOption={size}
                          onChange={({ detail }) =>
                            setSize(detail.selectedOption)
                          }
                          options={sizes}
                        />
                      </FormField>
                    </SpaceBetween>
                  </Container>
                ),
              },
              {
                title: "Review configuration",
                description:
                  "Check the values before confirming the local example.",
                content: (
                  <SpaceBetween size="l">
                    <Container
                      header={
                        <Header
                          variant="h2"
                          actions={
                            <Button onClick={() => setStep(0)}>
                              Edit settings
                            </Button>
                          }
                        >
                          Workspace settings
                        </Header>
                      }
                    >
                      <ColumnLayout columns={2} variant="text-grid">
                        <div>
                          <Box variant="awsui-key-label">Workspace name</Box>
                          {name}
                        </div>
                        <div>
                          <Box variant="awsui-key-label">Capacity profile</Box>
                          {size.label}
                        </div>
                      </ColumnLayout>
                    </Container>
                    <Alert type="info">
                      Confirmation changes the preview only. Production
                      provisioning would require a real service, permissions and
                      a verified response.
                    </Alert>
                  </SpaceBetween>
                ),
              },
            ]}
          />
        )}
      </div>
      <footer>
        Native Cloudscape components 3.0.1390 · configuration, validation,
        review and local confirmation.
      </footer>
    </main>
  );
}
createRoot(document.getElementById("root")).render(<App />);

代码参考

  • 将此代码保存为 src/main.jsx。下一个代码块是导入的 src/cloudscape.css。

cloudscape.css — 示例页面框架

围绕原生 Cloudscape 组件设置应用宽度和内边距。

css
body {
  margin: 0;
}
.cloudscape-example {
  padding: 24px;
  max-width: 1200px;
  margin: auto;
}
.appearance {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 24px;
}
.appearance > span {
  font-size: 11px;
  letter-spacing: 0.06em;
  font-weight: 700;
}
.wizard-content {
  margin-top: 32px;
}
.cloudscape-example footer {
  font-size: 12px;
  margin-top: 32px;
  color: #5f6b7a;
}
@media (max-width: 600px) {
  .cloudscape-example {
    padding: 16px;
  }
  .appearance {
    align-items: start;
  }
  .appearance > span {
    max-width: 180px;
  }
  .wizard-content {
    margin-top: 24px;
  }
}

代码参考

  • 请勿使用此应用程序样式表覆盖原生组件类名。
04

AWS Cloudscape 设计系统 Agent 设置

实现起点

所展示的原生示例随 React 18.3.1 一同打包。请使用你所安装的 Vite 版本支持的 Node.js 版本;并保留应用锁文件中使用的版本。

sh
npm create vite@latest cloudscape-workspace -- --template react
cd cloudscape-workspace
npm install
npm install [email protected] [email protected] @cloudscape-design/[email protected] @cloudscape-design/[email protected] @cloudscape-design/global-styles
# Replace src/main.jsx and add src/cloudscape.css from the full examples.
npm run dev

适用于你项目的提示词

Agent 提示词
使用 Cloudscape 构建资源配置工作流。采用提供的原生 Wizard/Container/FormField/Input/Select 代码和 visual-refresh 设计令牌角色。在各步骤间保留字段值,导航前进行验证,并显示完整的审核信息。示例容量配置仅是领域模型的占位数据,并非真实云产品。只有在提供 API 后才集成资源预配;并明确区分等待处理、失败和已确认状态。
05

AWS Cloudscape 设计系统来源与范围

OpenDesign 指南,以及使用原生 Cloudscape 组件 3.0.1390 的原始本地工作区配置示例。容量配置是虚构的应用数据。不涉及云账户、资源预配 API 或实际服务定价。