크리에이티브 소프트웨어 · 새 리소스

Adobe Spectrum 디자인 시스템.

선택 가능한 크리에이티브 에셋 테이블과 내보내기 프리셋 인스펙터를 통해 React Spectrum v3를 살펴보십시오. Provider 테마와 입력 스케일, 지원되는 스타일 props, 키가 지정된 컬렉션, 그리고 v3와 더 새로운 Spectrum 2 구현 사이의 경계를 이해하십시오.

OpenDesign 가이드9개 챕터36개 레퍼런스 항목독자적 적용 가이드
01

Adobe Spectrum 디자인 시스템 인터페이스 미리보기

세 가지 독자적 아트워크 변형을 검사하고, 내보내기 배치를 선택하고, 로컬 PNG 또는 JPEG 레시피를 준비하십시오.

캠페인 아트워크와 내보내기 인스펙터전체 예시 열기
문서화된 v3 컬렉션과 인스펙터 워크플로를 독자적으로 해석한 HTML/CSS입니다. 팔레트와 아트워크는 예시일 뿐이며, 네이티브 Spectrum 런타임이나 이미지 변환은 없습니다. · 구현 레퍼런스
02

Adobe Spectrum 디자인 시스템 디자인 레퍼런스

React Spectrum v3 API 및 차원 매핑. 숫자로 표시된 차원 열에는 Adobe 마이그레이션 표의 기본 변환 값이 기록되어 있으며, scale에 민감한 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로 컬렉션의 식별성을 안정적으로 유지합니다.

Picker와 텍스트 입력 조합

출처
이름 / 규칙값 / 구성용도
labelpersistent text내보내기 형식 선택기에 이름을 지정합니다.
selectedKeyone item keypng 또는 jpeg 같은 형식을 제어합니다.
onSelectionChangekey callbackDOM 이벤트 핸들러와는 다른 규약입니다.
Item keystable key표시 레이블과 별개로 값을 식별합니다.
Heading level1–6의미에 맞는 제목 수준을 지정하며, 기본 스타일은 컨텍스트를 따릅니다.
Button onPresspress callback마우스에만 의존하는 사용자 지정 동작 대신 여러 입력 방식으로 활성화할 수 있습니다.
03

Adobe Spectrum 디자인 시스템 완벽 가이드

실제 인터페이스를 위해 이 시스템을 선택하고 적용하고 검토하는 실용 가이드.

DESIGN-adobe-spectrum.md

완전한 안내와 구현 시작점, 소스 링크.

가이드 다운로드

Adobe Spectrum 디자인 시스템: Spectrum 세대를 혼합하지 말고 v3를 신중하게 선택하세요

이 예시에서 설치하는 항목

Adobe는 이제 v3 라이브러리와 함께 Spectrum 2도 문서화하고 있습니다. 이 페이지에서는 Provider, 컬렉션, 스타일 속성 규약을 활용해 완전하고 문서화된 에셋 검토 예제를 구성할 수 있도록 @adobe/react-spectrum@3을 선택합니다. v3 레시피는 기존 v3 애플리케이션에 유용하지만, 이를 최신 Spectrum 구현이라고 설명해서는 안 됩니다. 새로 도입할 세대를 결정하기 전에 링크된 마이그레이션 참고 자료를 확인하세요.

이 OpenDesign 가이드에서

실질적인 차이는 코드에서 드러납니다. v3에서는 스타일 속성으로 size-300을 전달하고 Provider에 defaultTheme을 제공합니다. 마이그레이션 가이드에서는 이러한 규칙을 다른 스타일링 API에 맞게 매핑합니다. 패키지 이름만 바꾼다고 예제가 마이그레이션되는 것은 아닙니다. 컴포넌트 가져오기, 스타일링, 지원 속성을 함께 검토해야 합니다.

지원 사양 읽기

Adobe Spectrum 디자인 시스템 Provider에서 모양, 배율, 로캘을 관리합니다

하나의 루트에서 여러 설정을 개별적으로 관리

Provider는 테이블, 선택기, 버튼이 사용하는 환경을 설정합니다. 테마 객체에는 색상 구성표와 배율 정의가 포함됩니다. colorScheme은 운영체제 기본 설정을 재정의할 수 있고, scale은 입력 장치 특성에 맞게 조정됩니다. 이 설정들은 서로 독립적입니다. 데스크톱의 어두운 표면에 큰 터치 대상이 필요한 것은 아니며, 밝은 터치스크린에 조밀한 마우스용 레이아웃을 무심코 적용해서도 안 됩니다.

일반적인 프로덕션 환경에서는 scale을 자동으로 설정하세요. 컴포넌트를 살펴보는 과정에서 medium이나 large를 명시적으로 선택하면 컨트롤을 비교하기 좋지만, 이 경우에는 검토를 위한 설정이라고 설명해야 합니다. locale은 언어 컨텍스트를 설정할 뿐 프로젝트 데이터를 번역하지는 않습니다. 캠페인 이름, 검토 메모, 레시피 레이블은 애플리케이션 콘텐츠로 유지됩니다.

지원 사양 읽기

Adobe Spectrum 디자인 시스템: 지원되는 차원과 외부 레이아웃 속성 사용

이름이 지정된 배율은 픽셀을 간단히 표시하는 방식이 아닙니다

기본 size-100 매핑은 8, size-200은 16, size-300은 24입니다. 참조 표에는 그 밖에도 유용한 단계가 포함되어 있습니다. size-* 차원은 플랫폼 배율에 따라 조정될 수 있지만, static-size-* 값은 의도적으로 고정됩니다. 인스펙터나 상호작용 대상의 크기를 지정할 때 이 차이를 유지하세요. 데스크톱에서 계산된 값을 모두 CSS에 복사하면 컴포넌트 환경이 제공하는 적응성을 잃게 됩니다.

Flex와 View를 사용하면 TableView 내부를 다시 작성하지 않고도 안정적인 외부 구조를 만들 수 있습니다. 테이블은 flex로 확장하고 minWidth={0}으로 축소할 수 있습니다. 인스펙터는 기본적으로 세로로 쌓이고 명시한 tablet 중단점부터 크기가 제한됩니다. 표면을 소유하는 View에 패딩을 지정하세요. 문서에서는 안전하지 않은 우회 방법으로 내부 색상, 테두리, 타이포그래피를 재정의하지 않도록 안내합니다.

지원 사양 읽기

Adobe Spectrum 디자인 시스템: 기본 색상과 타이포그래피는 테마에 맡기세요

예시 팔레트와 토큰 내보내기 결과 구분

미리보기에는 절제된 회색 캔버스, 중립적인 컨트롤, 직접 제작한 다채로운 아트워크가 사용됩니다. 일러스트의 색상은 Spectrum 토큰 값으로 인증된 것이 아닙니다. 기본 컴포넌트는 예제에서 defaultTheme을 통해 모양을 적용합니다. 사용자 지정 기본 표면에는 문서화된 backgroundColor 값을 사용하세요. 샘플링한 하나의 hex 값이 두 색상 구성표 모두에서 동일하게 작동한다고 가정해서는 안 됩니다.

Heading은 컨텍스트에 맞는 Spectrum 표현뿐 아니라 의미 구조도 제공합니다. 페이지 제목에는 level={1}을 사용하고, 선택 항목 수 같은 일반 콘텐츠에는 Text를 사용합니다. 사용자 지정 HTML 미리보기에서는 애플리케이션에서 선택한 시스템 글꼴 대체 글꼴과 글자 크기를 사용합니다. 이는 작업 흐름과 상대적 계층 구조를 보여 주기 위한 것으로, 주변 OpenDesign 글꼴이나 일러스트의 타이포그래피가 Spectrum 글꼴 사양을 따른다는 뜻은 아닙니다.

지원 사양 읽기

Adobe Spectrum 디자인 시스템 컬렉션 테이블에는 키, 열, 선택 의미가 필요합니다

선택은 데이터 규약입니다

테이블은 TableHeader와 Column, 그리고 TableBody, Row, Cell로 구성됩니다. 각 에셋에는 안정적인 id가 있습니다. selectedKeys와 onSelectionChange는 선택을 제어 상태로 만들기 때문에, 내보내기 인스펙터는 동일한 상태에서 개수를 도출할 수 있습니다. 사용자는 에셋의 정체성을 바꾸지 않고 이름만 변경할 수 있습니다. 행 위치를 정체성으로 삼으면 재정렬 후 선택이 취약해집니다.

선택은 all 센티넬일 수 있습니다. 셋업은 레시피를 만들기 전에 이를 현재의 모든 에셋으로 해석합니다. 배치가 선택 사항이므로 빈 Set도 유효하며, disallowEmptySelection은 의도적으로 켜지 않았습니다. 원격 또는 페이지네이션 환경에서는 현재 렌더링된 행이 전체 컬렉션이라고 무작정 가정하지 말고, 해당 데이터 소스에서 all이 무엇을 뜻하는지 정의하세요.

  • 에셋 정체성: 컬렉션이 사용하는 안정적인 키.
  • 검사: 독립형 표본에서 어떤 아트워크가 더 크게 표시되는지.
  • 배치 선택: 준비된 레시피에 어떤 키가 포함되는지.

지원 사양 읽기

Adobe Spectrum 디자인 시스템 Picker와 Button으로 내보내기 인스펙터 완성

형식은 배치와 독립적으로 제어됩니다

Picker는 표시되는 레이블과 안정적인 Item 키를 사용합니다. selectedKey는 png 또는 jpeg이며, onSelectionChange가 선택된 키를 제공합니다. 이는 네이티브 select에서 event.target.value를 읽는 방식과 다릅니다. 배치를 비워도 형식은 그대로 유지되므로, 검토자는 프리셋을 다시 만들지 않고도 선택을 조정할 수 있습니다.

Button은 활성화에 onPress를 사용하며, 선택된 에셋이 없으면 isDisabled가 됩니다. 네이티브 예제는 id와 형식을 로컬 레시피로 직렬화합니다. 이미지 데이터를 변환하거나 실제 내보내기 파일을 만들거나 에셋 서비스에 접속하지는 않습니다. 이것은 유용한 구현 경계입니다. 변환 엔진이 디자인 시스템 바깥에 있더라도 액션과 그 입력은 구체적입니다.

지원 사양 읽기

Adobe Spectrum 디자인 시스템 아트를 압축하기보다 구성을 조정하세요

브레이크포인트 계약을 명시하세요

이 예제는 tablet:640과 desktop:1024를 선언합니다. Provider 페이지가 현재 설명 산문과 생성된 API 메타데이터 사이에서 기본값이 일관되지 않기 때문에 이 선택은 명시적입니다. 반응형 값은 바로 이 키를 참조합니다. 인스펙터는 기본에서 전체 너비이고, 그다음 유연한 테이블 옆으로 이동합니다. 이 브레이크포인트는 애플리케이션이 소유하며, 새로운 보편적 Spectrum 표준이 아닙니다.

독립형 일러스트레이션은 측면 인스펙터와 썸네일 레일이 있는 큰 캔버스를 사용합니다. 작은 화면에서는 인스펙터가 일반 흐름으로 이동하고 아트워크는 가로세로 비율을 유지합니다. 크기와 형식 같은 텍스트는 아트 바깥에 있으므로 가독성을 유지하고 검사 대상 아트워크를 바꾸지 않습니다.

지원 사양 읽기

Adobe Spectrum 디자인 시스템 검사, 선택, 준비는 서로 다른 작업입니다

데모를 테스트 가능하게 만드세요

아트워크 썸네일을 클릭하면 큰 일러스트레이션과 그 설명 메타데이터가 바뀝니다. 체크박스는 내보내기 배치를 바꿉니다. 이 둘을 독립적으로 유지하면 선택하지 않은 에셋을 의도치 않게 내보내지 않고도 검사할 수 있습니다. 미리보기는 선택된 개수를 보고하고, 검토자가 배치를 바꾸는 동안에도 형식을 유지합니다.

네이티브 TableView는 자체 컬렉션 상호작용을 제공하고, HTML 표본은 일반 버튼과 체크박스를 사용하며 전체 그리드 키보드 모델을 재현한다고 주장하지 않습니다. 둘 다 시연된 동작에 대한 키보드 경로를 제공합니다. 레시피 결과는 일시적인 시각 효과가 아니라 텍스트이므로, 검토자는 어떤 id와 형식이 준비되었는지 정확히 확인할 수 있습니다.

지원 사양 읽기

Adobe Spectrum 디자인 시스템 도구를 확장하기 전에 네이티브 슬라이스를 통합하세요

명시적 경계에서 실제 내보내기 서비스를 연결하세요

기존 React 앱에 v3 스위트를 설치한 다음, 아래의 전체 엔트리를 사용하세요. 예제에는 프로바이더, 임포트, 컬렉션 데이터, 선택 상태, 형식 상태, 결과 상태가 포함됩니다. 프로덕션 통합에서는 레시피 준비를 내보내기 요청으로 바꾸고 에셋별로 확인된 결과를 표시하게 됩니다. 그 서비스가 존재하기 전에는 로컬 응답의 이름을 Export complete로 바꾸지 마세요.

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 컬렉션 및 인스펙터 예제입니다. 이미지 파일이 아니라 로컬 상태로 내보내기 레시피를 만듭니다. 해석된 패키지 버전을 lockfile에 유지하고, 이 엔트리를 Spectrum 2 임포트와 혼용하지 마세요.

선택은 Set만이 아니라 all일 수도 있습니다

배치를 계산하거나 액션을 활성화하기 전에 컬렉션 계약을 정규화하세요. 이 프래그먼트는 전체 셋업의 에셋과 키를 사용합니다.

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와 반응형 props에 동일한 키를 사용하세요. 숫자는 의도적인 애플리케이션 구성입니다.

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는 물리적 left 및 right 여백보다 다양한 쓰기 방향에 잘 대응합니다.
04

Adobe Spectrum 디자인 시스템 에이전트 설정

구현 시작점

기존 React 앱을 위한 전체 v3 컬렉션 및 인스펙터 예제입니다. 이미지 파일이 아니라 로컬 상태로 내보내기 레시피를 만듭니다. 해석된 패키지 버전을 lockfile에 유지하고, 이 엔트리를 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 />);

프로젝트를 위한 프롬프트

에이전트 프롬프트
@adobe/react-spectrum v3에서 Provider와 defaultTheme을 사용하세요. 제공된 키 기반 TableView와 Picker, Item, Flex, View, Button을 사용해 내보내기 검사기를 구현하세요. 선택 항목은 Set 또는 전체 선택으로 처리하고, 선택 항목이 바뀌어도 형식을 유지하세요. 실제 변환 서비스가 연결되기 전까지 결과는 로컬 레시피로 명명하세요. 명시적인 태블릿/데스크톱 중단점 키와 지원되는 스타일 props를 사용하세요. v3와 Spectrum 2는 별도로 다루세요.
05

Adobe Spectrum 디자인 시스템 출처 및 범위

유지 관리되는 React Spectrum v3 문서를 바탕으로 @adobe/react-spectrum을 사용한 OpenDesign 구현 연구입니다. Spectrum 2도 제공되며 API가 다릅니다. 이 페이지에서는 v3를 최신 구현이라고 소개하지 않습니다. 독립형 에셋 보드 미리보기는 일러스트레이션 아트워크와 애플리케이션에서 선택한 색상을 사용한 독창적인 HTML/CSS 해석이며, 네이티브 Spectrum 컴포넌트나 색상 관리 이미지 편집기가 아닙니다.