创意软件 · 新资源

Adobe Spectrum 设计系统.

通过可选择的创意素材表格和导出预设检查器,了解 React Spectrum v3。掌握 Provider 主题和输入缩放、受支持的样式属性、带键集合,以及 v3 与较新 Spectrum 2 实现之间的界限。

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

Adobe Spectrum 设计系统界面预览

检查三种原始素材变体,选择一批导出内容,并准备本地 PNG 或 JPEG 导出方案。

营销活动素材与导出检查器打开完整示例
对文档所述 v3 资源集合与检查器工作流的原始 HTML/CSS 解读。调色板和素材仅供示意;不包含原生 Spectrum 运行时或图像转换。· 实现参考
02

Adobe Spectrum 设计系统设计参考

React Spectrum v3 API 与尺寸映射。数值尺寸列记录了 Adobe 迁移表中的基础换算;对缩放敏感的 size-* 值可根据触控需求调整。这不是 Spectrum 2 设计令牌导出。预览颜色和自定义素材均为应用层选择。

Provider 与主题配置

来源
名称 / 规则值 / 配置用途
themedefaultTheme从 @adobe/react-spectrum 导入的必需根主题对象。
colorSchemelight | dark显式覆盖操作系统偏好设置。
scalemedium | large精细指针与粗略指针对应的缩放;通常交由 Provider 选择。
localeBCP 47 language tag区域设置与文字方向上下文。
breakpointscustom name → pixel width本指南显式设置 tablet: 640 和 desktop: 1024,以避免与参考页面中的默认值冲突。
isDisabled / isReadOnlyboolean group defaults嵌套的 Provider 和各个属性可以覆盖组级行为。

基础尺寸映射

来源
名称 / 规则值 / 配置用途
size-504px base小间距。
size-1008px base相关控件。
size-15012px base工具栏间距。
size-20016px base检查器组间距。
size-25020px base中等间距。
size-30024px base面板内边距。
size-40032px base较大的分组间距。
size-50040px base区块间距。
size-60048px base大型布局结构。
size-100080px base固定尺寸的插图区域。
size-2400192px base检查器宽度示例。
size-6000480px base较大的有界界面表面。

样式属性与自适应值

来源
名称 / 规则值 / 配置用途
marginStart / marginEndDimensionValue使用逻辑间距;为支持文字方向,优先于 left/right。
padding / backgroundColorView style props构建自定义外层界面表面,而不是覆盖原生控件内部样式。
widthsize-* | CSS length | calc(...)示例:calc(100% - size-2000)。
responsive value{base: value, tablet: value}键与显式设置的 Provider 断点相匹配。
UNSAFE_style / UNSAFE_classNamelast-resort escape hatch不要依赖私有组件 DOM 或样式。
single-line-height32 base mapping使用语义化尺寸,不要声称所有控件始终都是 32px。

集合选择约定

来源
名称 / 规则值 / 配置用途
selectionModenone | single | multiple此示例使用 multiple 来选择一批内容。
selectedKeysSet of row keys | all受控状态必须处理 all 哨兵值。
onSelectionChangecallback with selection不要将选择操作解读为已获批准或导出成功。
disallowEmptySelectionboolean适用于必选的单项选择;可选导出批次则无需设置。
TableHeader → Columncolumn anatomy为列指定稳定的键,以支持动态渲染。
TableBody → Row → Cellrow anatomy记录 ID 用于建立稳定的集合身份标识。

选择器与文本组合

来源
名称 / 规则值 / 配置用途
labelpersistent text为导出格式选择器命名。
selectedKeyone item key受控格式,例如 png 或 jpeg。
onSelectionChangekey callback与 DOM 事件处理器不同的约定。
Item keystable key值标识不依赖可见标签。
Heading level1–6语义化标题级别;原生样式随上下文而定。
Button onPresspress callback使用跨输入方式激活,而不是自定义仅支持鼠标的操作。
03

Adobe Spectrum 设计系统完整指南

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

DESIGN-adobe-spectrum.md

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

下载指南

Adobe Spectrum 设计系统:审慎选择 v3,不要混用 Spectrum 不同版本

此示例安装的内容

Adobe 目前在 v3 库之外也提供了 Spectrum 2 的文档。本页选择 @adobe/react-spectrum@3,因为它的 Provider、集合和样式属性约定共同构成了一个完整且有文档说明的素材审核示例。对于现有的 v3 应用,v3 方案仍然适用,但不应将其描述为最新的 Spectrum 实现。决定采用新版本时,应先查看链接的迁移参考,再选择版本系列。

摘自本 OpenDesign 指南

代码中能直观看出实际差异。v3 通过样式属性传入 size-300,并向 Provider 提供 defaultTheme。迁移指南会将这些约定映射到不同的样式体系 API。仅替换包名并不能完成示例迁移;必须一并检查组件导入、样式和受支持的属性。

阅读配套规范

Adobe Spectrum 设计系统 Provider 统一管理外观、缩放与区域设置

一个根级 Provider,几项相互独立的设置

Provider 建立表格、选择器和按钮所使用的环境。主题对象包含配色方案和缩放定义。colorScheme 可以覆盖操作系统偏好设置,而 scale 则用于适配输入设备特性。这些是彼此独立的设置:深色桌面界面不需要因此采用更大的触控目标,浅色触屏也不应意外沿用紧凑的鼠标布局。

在一般生产环境中,将 scale 保持为自动。在组件研究中,明确选择 medium 或 large 有助于比较控件,但应将其描述为检查设置。locale 用于设置语言环境,而不是翻译项目数据。活动名称、评审备注和配方标签仍属于应用内容。

阅读配套规范

Adobe Spectrum 设计系统 使用受支持的尺寸和外部布局属性

命名 scale 不只是像素的简写

基础映射中,size-100 对应 8,size-200 对应 16,size-300 对应 24。参考表还列出了其他实用的步进值。size-* 尺寸可随平台 scale 调整;static-size-* 值则不会。为检查器或交互目标设置尺寸时,请保留这一区别。将每个解析后的桌面端数值都复制到 CSS,会丢失组件环境提供的自适应能力。

Flex 和 View 为示例提供稳定的外层结构,无需改写 TableView 的内部实现。表格可以通过 flex 增长,并通过 minWidth={0} 收缩;检查器在基础尺寸下纵向排列,并在明确指定的 tablet 断点处变为有边界的布局。内边距应由负责该界面表面的 View 设置。文档不建议通过不安全的逃逸方式覆盖内部颜色、边框和字体排版。

阅读配套规范

Adobe Spectrum 设计系统 让主题管理原生颜色和字体排版

区分示例调色板与令牌导出

预览使用克制的灰色画布、中性色控件和原有的彩色插画。这些插画颜色并非经认证的 Spectrum 令牌值。在原生示例中,受支持的组件会从 defaultTheme 获取外观。自定义原生界面表面应使用文档中列出的 backgroundColor 值,而不要假设某个取样得到的十六进制颜色在两种色彩方案下都适用。

Heading 在其上下文中既提供语义结构,也呈现 Spectrum 样式。页面标题使用 level={1};Text 用于选择数量等普通内容。自定义的 HTML 预览使用由应用选择的系统字体回退和字号。它展示的是工作流程和相对层级,并不表示周围的 OpenDesign 字体或插画字体排版就是 Spectrum 的字体规范。

阅读配套规范

Adobe Spectrum 设计系统 集合表具有键、列和选择语义

选择是一项数据契约

该表由 TableHeader 和 Column,以及 TableBody、Row 和 Cell 构成。每项素材都有稳定的 id。selectedKeys 和 onSelectionChange 使选择状态受控,因此导出检查器可以从同一状态计算数量。用户可以重命名素材,而不会改变其身份。如果使用行位置作为身份,重新排序后选择状态就会变得脆弱。

选择结果可以是 all 哨兵值。创建配方前,初始化逻辑会将其解析为当前所有素材。空 Set 仍然有效,因为批处理是可选的;这里有意不启用 disallowEmptySelection。在远程或分页应用中,应明确数据源中的“全部”具体指什么,而不要盲目假定当前渲染的行包含完整集合。

  • 素材身份:集合中使用的稳定键。
  • 检查:在独立示例中放大显示的插画。
  • 批量选择:要包含在已准备配方中的键。

阅读配套规范

Adobe Spectrum 设计系统 使用 Picker 和 Button 完成导出检查器

格式与批次分别受控

Picker 使用可见标签和稳定的 Item 键。selectedKey 的值为 png 或 jpeg;onSelectionChange 会提供所选键。这与从原生 select 读取 event.target.value 不同。清空批次后,所选格式仍会保留,方便评审者调整选择,而无需重新创建预设。

点击按钮可触发 onPress,未选择任何素材时则显示 isDisabled。原生示例会将 ID 和格式序列化为本地配方。它不会转换图像数据、生成实际的导出文件,也不会联系素材服务。这划定了一个实用的实现边界:操作及其输入都是具体的,而转换引擎则不属于设计系统的范畴。

阅读配套规范

Adobe Spectrum 设计系统:调整构图,而不是压缩图稿

明确断点约定

此示例定义了 tablet:640 和 desktop:1024。之所以明确这样选择,是因为 Provider 页面目前在说明文字和生成的 API 元数据中使用了不一致的默认值。响应式取值对应这些确切的键。检查器在基础尺寸下占满宽度,之后移至灵活表格旁边。这些断点由应用负责定义,并非新的通用 Spectrum 标准。

独立插图采用大画布,旁边设有检查器和缩略图栏。在小屏幕上,检查器会移入正常文档流,图稿则保持纵横比。尺寸和格式等文字位于图稿之外,因此始终清晰可读,也不会改变正在检查的图稿。

阅读配套规范

Adobe Spectrum 设计系统:检查、选择和准备是不同的操作

让演示可供测试

点击图稿缩略图会更换大幅插图及其描述性元数据。复选框则会更改导出批次。将这两项操作分开,便可以检查未选中的素材,而不会意外将其导出。预览会显示选中数量;审核者更改批次时,格式仍会保留。

原生 TableView 提供集合交互;HTML 示例使用普通按钮和复选框,并不声称能够复现完整的网格键盘交互模型。两者都提供了通过键盘执行示例操作的途径。配方结果以文本呈现,而非仅有临时的视觉效果,因此审核者可以检查具体准备了哪些 ID 和格式。

阅读配套规范

Adobe Spectrum 设计系统:先集成本地功能,再扩展工具

在明确的边界接入实际导出服务

在现有的 React 应用中安装 v3 套件,然后使用下方的完整入口。此示例包含 Provider、导入语句、集合数据、选择状态、格式状态和结果状态。生产环境中的集成应以导出请求取代配方准备,并针对每项素材显示已确认的结果。在导出服务尚未就绪前,不要将本地响应改名为“导出完成”。

迁移到 Spectrum 2 时,请使用 Adobe 提供的尺寸、断点和组件变更映射。请再次验证选择行为和格式持久性;外观相似的表格仍可能采用不同的约定。明确保留源代码所针对的版本,以免后续贡献者将 v3 Provider 与不兼容的示例混用。

  1. 选择一项素材,并确认其 ID 出现在本地配方中。
  2. 全选,将 PNG 更改为 JPEG,并检查完整的选中素材集。
  3. 清除选择,并确认操作按钮已禁用,而所选格式仍然保留。
  4. 缩窄视口,并确认检查、选择和配方输出功能仍可使用。

阅读配套规范

Adobe Spectrum 设计系统组件示例

完整的独立交互示例

将完整文档保存为 index.html,并在浏览器中打开。这是对文档所述 v3 集合和检查器工作流的原始 HTML/CSS 实现。调色板和图稿仅作示意;未使用原生 Spectrum 运行时,也未进行图像转换。

html
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Spectrum asset inspector study</title><style>*{box-sizing:border-box}body{margin:0;font:14px/1.5 -apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;color:#2c2c2c;background:#f5f5f5}button,input,select{font:inherit}button{cursor:pointer;border:1px solid #999;border-radius:16px;background:white;color:inherit;padding:5px 16px;font-weight:600}button:focus-visible,input:focus-visible,select:focus-visible{outline:3px solid #1473e6;outline-offset:3px}button:disabled{opacity:.45;cursor:not-allowed}header{padding:16px 24px;background:white;border-bottom:1px solid #ddd;display:flex;justify-content:space-between;gap:16px;align-items:center}header b{font-size:16px}header span{font-size:12px;color:#666}.workspace{display:grid;grid-template-columns:160px minmax(0,1fr) 230px;min-height:540px}.rail{padding:20px 16px;border-right:1px solid #ddd}.rail h2,.inspector h2{font-size:14px;margin:0 0 16px}.thumb{margin-bottom:20px}.thumb button{width:100%;border-radius:4px;padding:6px;background:transparent;border:2px solid transparent}.thumb button[aria-pressed=true]{border-color:#1473e6;background:#e7f1ff}.thumb label{display:flex;align-items:center;gap:6px;font-size:12px;margin-top:6px}.thumb input{accent-color:#1473e6}.mini{height:70px;display:grid;place-items:center;font-size:26px;font-weight:800;letter-spacing:-2px;background:linear-gradient(125deg,#fcab64,#ee6e63);color:#472c52;border-radius:2px}.thumb:nth-of-type(2) .mini{background:linear-gradient(125deg,#c4bdff,#8b7ddd)}.thumb:nth-of-type(3) .mini{background:linear-gradient(125deg,#9ed5c8,#449c8c)}.canvas-wrap{padding:24px;display:flex;flex-direction:column;align-items:center;justify-content:center;min-width:0}.canvas-meta{align-self:stretch;display:flex;justify-content:space-between;margin-bottom:20px;font-size:12px;color:#666;gap:12px}.art{width:min(100%,540px);aspect-ratio:4/3;background:linear-gradient(130deg,#ffbd7c,#ed8178);color:#412754;position:relative;overflow:hidden;display:flex;align-items:center;justify-content:center;text-align:center;isolation:isolate}.art:before{content:'';position:absolute;z-index:-1;width:70%;aspect-ratio:1;border:45px solid rgba(255,240,197,.65);border-radius:50%;left:-24%;bottom:-25%}.art:after{content:'';position:absolute;z-index:-1;width:60%;aspect-ratio:1;background:rgba(217,69,117,.32);border-radius:50%;right:-25%;top:-25%}.art small{letter-spacing:3px;font-size:11px;font-weight:700}.art h1{font-size:clamp(28px,5vw,64px);line-height:.96;margin:16px 0 18px;letter-spacing:-3px;font-weight:800}.art p{font-size:12px;margin:0}.art[data-art=square]{aspect-ratio:1;background:linear-gradient(130deg,#d8d0ff,#9588dd)}.art[data-art=story]{aspect-ratio:9/16;max-height:470px;width:auto;min-width:210px;background:linear-gradient(130deg,#caeee2,#69b7a5)}.art[data-art=story] h1{font-size:40px;letter-spacing:-2px}.canvas-note{font-size:12px;color:#666;margin-top:16px}.inspector{background:white;padding:24px 20px;border-left:1px solid #ddd}.inspector dl{margin:0 0 24px}.inspector dt{font-size:12px;color:#666;margin-top:16px}.inspector dd{margin:4px 0 0;overflow-wrap:anywhere}.inspector hr{border:0;border-top:1px solid #ddd;margin:24px 0}.inspector label{display:block;font-size:12px;font-weight:600;margin-bottom:6px}.inspector select{width:100%;border:1px solid #999;border-radius:4px;padding:8px;background:white}.selected-count{font-size:12px;margin:16px 0}.primary{background:#1473e6;border-color:#1473e6;color:white;width:100%}.primary:hover{background:#0d66d0}.result{margin:0 24px 20px;padding:16px;background:white;border:1px solid #ddd;border-radius:4px}.result[hidden]{display:none}.result h2{font-size:16px;margin:0 0 8px}.result pre{white-space:pre-wrap;font:12px/1.5 ui-monospace,monospace}.result p{font-size:12px;margin:0}footer{padding:12px 24px;color:#666;font-size:12px;border-top:1px solid #ddd;background:white}@media(max-width:760px){.workspace{grid-template-columns:110px minmax(0,1fr)}.rail{padding:16px 8px}.inspector{grid-column:1/-1;border-left:0;border-top:1px solid #ddd;display:grid;grid-template-columns:1fr 1fr;gap:12px 24px}.inspector h2{grid-column:1/-1;margin:0}.inspector dl{margin:0}.inspector hr{display:none}.canvas-wrap{padding:16px}.art h1{letter-spacing:-1px}.art p{padding:0 12px}.canvas-meta{display:block}.art:before{border-width:24px}header span{display:none}.inspector dt:first-child{margin-top:0}}@media(max-width:440px){.workspace{grid-template-columns:1fr}.rail{border-right:0;border-bottom:1px solid #ddd;display:flex;gap:8px}.rail h2{display:none}.thumb{flex:1;min-width:0;margin:0}.mini{height:44px;font-size:20px}.thumb label{font-size:11px}.art[data-art=story]{max-height:390px}.canvas-meta{display:flex}.inspector{grid-template-columns:1fr 1fr;padding:20px 16px}header{padding:16px}.result{margin:0 16px 16px}}
</style></head><body><header><b>Campaign library <span>/ Autumn collection</span></b><button id="select-all">Select all</button></header><main><div class="workspace"><nav class="rail" aria-label="Artwork variants"><h2>Assets</h2><div class="thumb"><button data-id="hero" aria-label="Inspect campaign master" aria-pressed="true"><div class="mini" aria-hidden="true">Made.</div></button><label><input type="checkbox" value="hero" checked>Master</label></div><div class="thumb"><button data-id="square" aria-label="Inspect social square" aria-pressed="false"><div class="mini" aria-hidden="true">Made.</div></button><label><input type="checkbox" value="square">Square</label></div><div class="thumb"><button data-id="story" aria-label="Inspect vertical story" aria-pressed="false"><div class="mini" aria-hidden="true">Made.</div></button><label><input type="checkbox" value="story">Story</label></div></nav><section class="canvas-wrap" aria-label="Selected artwork"><div class="canvas-meta"><span id="art-name">Campaign master</span><span id="dimensions">1600 × 1200</span></div><div class="art" id="art" data-art="hero" role="img" aria-label="Original orange campaign artwork with the words Made for what comes next"><div><small>AUTUMN COLLECTION</small><h1>Made for<br>what comes<br>next.</h1><p>Small ideas. A different perspective.</p></div></div><p class="canvas-note">Original artwork · illustrative preview</p></section><aside class="inspector"><h2>Export inspector</h2><dl><dt>Selected artwork</dt><dd id="detail-name">Campaign master</dd><dt>Source dimensions</dt><dd id="detail-dimensions">1600 × 1200 px</dd><dt>Review</dt><dd>Draft artwork</dd></dl><hr><div><label for="format">Export format</label><select id="format"><option value="png">PNG</option><option value="jpeg">JPEG</option></select><p class="selected-count" id="selected-count">1 asset selected</p><button class="primary" id="prepare">Prepare recipe</button><p style="font-size:12px;color:#666">Creates a local recipe only. No files are converted.</p></div></aside></div><section class="result" id="result" hidden><h2>Local export recipe</h2><pre id="recipe"></pre><p role="status" id="status"></p></section></main><footer>React Spectrum v3 collection study · HTML/CSS interpretation with illustrative colors. Inspecting an artwork and selecting it for export are independent.</footer><script>
const assets={hero:{name:'Campaign master',dimensions:'1600 × 1200',color:'orange'},square:{name:'Social square',dimensions:'1080 × 1080',color:'purple'},story:{name:'Vertical story',dimensions:'1080 × 1920',color:'green'}};const boxes=[...document.querySelectorAll('.thumb input')],$=id=>document.getElementById(id);document.querySelectorAll('[data-id]').forEach(button=>button.onclick=()=>{document.querySelectorAll('[data-id]').forEach(b=>b.setAttribute('aria-pressed',String(b===button)));const id=button.dataset.id,a=assets[id];$('art').dataset.art=id;$('art').setAttribute('aria-label','Original '+a.color+' campaign artwork with the words Made for what comes next');$('art-name').textContent=$('detail-name').textContent=a.name;$('dimensions').textContent=a.dimensions;$('detail-dimensions').textContent=a.dimensions+' px';});function update(){let n=boxes.filter(b=>b.checked).length;$('selected-count').textContent=n+' asset'+(n===1?'':'s')+' selected';$('prepare').disabled=n===0;$('select-all').textContent=n===boxes.length?'Clear selection':'Select all';$('result').hidden=true;}boxes.forEach(b=>b.onchange=update);$('format').onchange=()=>{$('result').hidden=true;};$('select-all').onclick=()=>{const all=boxes.every(b=>b.checked);boxes.forEach(b=>b.checked=!all);update();};$('prepare').onclick=()=>{const ids=boxes.filter(b=>b.checked).map(b=>b.value);$('recipe').textContent=JSON.stringify({format:$('format').value,assets:ids},null,2);$('status').textContent='Recipe prepared for '+ids.length+' assets. No image files were converted.';$('result').hidden=false;};
</script></body></html>

代码参考

  • 图稿为原创示例内容。准备配方只会生成选择元数据,不会转换图像文件;本文档不会加载 Spectrum v3 或 Spectrum 2。

完整的原生实现入口

此处汇总了从设置到完整实现的内容,并附有重点说明 API。请按照设置中的文档说明,满足软件包和构建前置条件。

jsx
// Terminal: npm install @adobe/react-spectrum@3
// Existing React app with <div id="root"></div>; entry: src/main.jsx
import * as React from 'react';
import {createRoot} from 'react-dom/client';
import {Provider, defaultTheme, Flex, View, Heading, Text, Button,
  TableView, TableHeader, Column, TableBody, Row, Cell, Picker, Item}
  from '@adobe/react-spectrum';
const assets = [
  {id: 'hero', name: 'Campaign master', dimensions: '1600 × 1200'},
  {id: 'square', name: 'Social square', dimensions: '1080 × 1080'},
  {id: 'story', name: 'Vertical story', dimensions: '1080 × 1920'}
];
function AssetReview() {
  const [keys, setKeys] = React.useState(new Set(['hero']));
  const [format, setFormat] = React.useState('png');
  const [recipe, setRecipe] = React.useState('');
  const selected = keys === 'all' ? assets : assets.filter(a => keys.has(a.id));
  return <Provider theme={defaultTheme} breakpoints={{tablet: 640, desktop: 1024}}>
    <View padding="size-300">
      <Heading level={1}>Campaign exports</Heading>
      <Flex direction={{base: 'column', tablet: 'row'}} gap="size-300">
        <TableView aria-label="Campaign assets" selectionMode="multiple"
          selectedKeys={keys} onSelectionChange={setKeys} flex minWidth={0}>
          <TableHeader><Column key="name">Asset</Column><Column key="dimensions">Dimensions</Column></TableHeader>
          <TableBody items={assets}>{asset => <Row key={asset.id}>
            <Cell>{asset.name}</Cell><Cell>{asset.dimensions}</Cell>
          </Row>}</TableBody>
        </TableView>
        <Flex direction="column" gap="size-200" width={{base:'100%',tablet:'size-2400'}}>
          <Picker label="Export format" selectedKey={format} onSelectionChange={setFormat}>
            <Item key="png">PNG</Item><Item key="jpeg">JPEG</Item>
          </Picker>
          <Text>{selected.length} assets selected</Text>
          <Button variant="accent" isDisabled={!selected.length} onPress={() =>
            setRecipe(JSON.stringify({format, assets:selected.map(a=>a.id)}, null, 2))}>
            Prepare recipe
          </Button>
        </Flex>
      </Flex>
      <p role="status">{recipe ? 'Local recipe prepared. No image files were converted.' : ''}</p>
      {recipe && <pre style={{whiteSpace:'pre-wrap'}}>{recipe}</pre>}
    </View>
  </Provider>;
}
createRoot(document.getElementById('root')).render(<AssetReview />);

代码参考

  • 为现有的 React 应用提供完整的 v3 资源集合与检查器示例。它会在本地状态中创建导出方案,而不会生成图像文件。请在锁定文件中保留已解析的软件包版本,并且不要将此条目与 Spectrum 2 的导入混用。

选择值可以是 all,而不只是 Set

在计算批次或启用操作前,先规范化资源集合约定。此代码片段使用完整配置中的资源和键。

jsx
const selected = keys === 'all'
  ? assets
  : assets.filter(asset => keys.has(asset.id));
<Button variant="accent" isDisabled={selected.length === 0}
  onPress={() => setRecipe(JSON.stringify({format, assets: selected.map(a => a.id)}))}>
  Prepare recipe
</Button>

代码参考

  • 稳定 ID 在排序和重命名后仍会保留。
  • 批次为空时,只禁用方案操作;不会清除当前格式。

使用明确断点名称的响应式检查器

Provider 和响应式属性使用相同的键。这些数值是有意设置的应用配置。

jsx
<Provider theme={defaultTheme} breakpoints={{tablet:640, desktop:1024}}>
  <Flex direction={{base:"column", tablet:"row"}} gap="size-300">
    <View flex minWidth={0}>Asset table</View>
    <View width={{base:"100%",tablet:"size-2400"}}>Export inspector</View>
  </Flex>
</Provider>

代码参考

  • Provider 参考文档中的说明与生成的默认值表对默认断点的描述不一致;使用显式映射可以消除歧义。
  • 与物理方向的左、右外边距相比,逻辑属性 marginStart 和 marginEnd 更能适应不同方向。
04

Adobe Spectrum 设计系统 AI Agent 设置

实现起点

为现有的 React 应用提供完整的 v3 资源集合与检查器示例。它会在本地状态中创建导出方案,而不会生成图像文件。请在锁定文件中保留已解析的软件包版本,并且不要将此条目与 Spectrum 2 的导入混用。

jsx
// Terminal: npm install @adobe/react-spectrum@3
// Existing React app with <div id="root"></div>; entry: src/main.jsx
import * as React from 'react';
import {createRoot} from 'react-dom/client';
import {Provider, defaultTheme, Flex, View, Heading, Text, Button,
  TableView, TableHeader, Column, TableBody, Row, Cell, Picker, Item}
  from '@adobe/react-spectrum';
const assets = [
  {id: 'hero', name: 'Campaign master', dimensions: '1600 × 1200'},
  {id: 'square', name: 'Social square', dimensions: '1080 × 1080'},
  {id: 'story', name: 'Vertical story', dimensions: '1080 × 1920'}
];
function AssetReview() {
  const [keys, setKeys] = React.useState(new Set(['hero']));
  const [format, setFormat] = React.useState('png');
  const [recipe, setRecipe] = React.useState('');
  const selected = keys === 'all' ? assets : assets.filter(a => keys.has(a.id));
  return <Provider theme={defaultTheme} breakpoints={{tablet: 640, desktop: 1024}}>
    <View padding="size-300">
      <Heading level={1}>Campaign exports</Heading>
      <Flex direction={{base: 'column', tablet: 'row'}} gap="size-300">
        <TableView aria-label="Campaign assets" selectionMode="multiple"
          selectedKeys={keys} onSelectionChange={setKeys} flex minWidth={0}>
          <TableHeader><Column key="name">Asset</Column><Column key="dimensions">Dimensions</Column></TableHeader>
          <TableBody items={assets}>{asset => <Row key={asset.id}>
            <Cell>{asset.name}</Cell><Cell>{asset.dimensions}</Cell>
          </Row>}</TableBody>
        </TableView>
        <Flex direction="column" gap="size-200" width={{base:'100%',tablet:'size-2400'}}>
          <Picker label="Export format" selectedKey={format} onSelectionChange={setFormat}>
            <Item key="png">PNG</Item><Item key="jpeg">JPEG</Item>
          </Picker>
          <Text>{selected.length} assets selected</Text>
          <Button variant="accent" isDisabled={!selected.length} onPress={() =>
            setRecipe(JSON.stringify({format, assets:selected.map(a=>a.id)}, null, 2))}>
            Prepare recipe
          </Button>
        </Flex>
      </Flex>
      <p role="status">{recipe ? 'Local recipe prepared. No image files were converted.' : ''}</p>
      {recipe && <pre style={{whiteSpace:'pre-wrap'}}>{recipe}</pre>}
    </View>
  </Provider>;
}
createRoot(document.getElementById('root')).render(<AssetReview />);

适用于你项目的提示词

Agent 提示词
使用 @adobe/react-spectrum v3、Provider 和 defaultTheme。通过 Picker、Item、Flex、View 和 Button 构建所提供的带键 TableView 与导出检查器。将选择值处理为 Set 或 all,在选择变化时保留格式;在接入真正的转换服务前,将结果称为本地方案。使用明确的 tablet/desktop 断点键和受支持的样式属性。将 v3 API 与 Spectrum 2 API 分开使用。
05

Adobe Spectrum 设计系统资料来源与范围

基于持续维护的 React Spectrum v3 文档、使用 @adobe/react-spectrum 的 OpenDesign 实现研究。Spectrum 2 也可用,且 API 不同;本页不会将 v3 称为最新实现。独立的资源面板预览是原创的 HTML/CSS演绎,使用示意性插图和应用选定的颜色,并非原生 Spectrum 组件,也不是具备色彩管理功能的图像编辑器。