원본과 다른 점
Steel 이 Atlassian Design System 과 달라진 부분과 그 이유를 정리했어요.
Steel 은 ADS 의 토큰 값·시각 스펙·props 이름을 그대로 따르는 것을 목표로 해요. 다만 상표 리소스를 빼고, shadcn 방식(코드 복사 + Tailwind)에 맞추다 보니 구현 방식은 달라졌어요. 아래 표에서 한눈에 볼 수 있어요.
| 항목 | Atlassian Design System | Steel |
|---|---|---|
| 배포 | npm 패키지 (@atlaskit/button …) | shadcn registry (코드가 내 프로젝트로 복사) |
| 스타일 엔진 | Compiled (CSS-in-JS, 빌드 시 원자 클래스) | Tailwind CSS v4 유틸 + cva |
| 토큰 사용 | token('color.text.subtle') | text-ds-text-subtle 또는 var(--ds-text-subtle) |
| 서체 | Atlassian Sans / Atlassian Mono / Charlie | Inter / JetBrains Mono (+ Pretendard) |
| 아이콘 | @atlaskit/icon | lucide-react |
| 상호작용 기반 | 자체 구현, @atlaskit/popper, react-select | radix-ui 프리미티브 |
| 레이아웃 프리미티브 | @atlaskit/primitives (Box, Stack, Inline …, xcss) | primitives 컴포넌트 + Tailwind className |
| 다크 모드 | setGlobalTheme({ colorMode: 'dark' }) → html[data-color-mode] | 루트에 .dark 클래스 |
| 테마 버전 | 기본 테마 + 기능 플래그로 켜는 FY27 Finesse 오버라이드 | Finesse 오버라이드를 항상 적용 |
최신 테마 (FY27 Finesse)
Atlassian 은 Jira·Confluence 의 새 모습(FY27 "Finesse")을 기능 플래그 뒤에서 단계적으로 켜고 있어요. @atlaskit/tokens 에는 기본 테마와 함께 atlassian-light-finesse, atlassian-dark-finesse, atlassian-typography-finesse 오버라이드가 들어 있어요. Steel 은 이 오버라이드를 항상 덮어쓴 값을 기본으로 써요.
| 바뀐 점 | 기본 테마 | Steel (Finesse) |
|---|---|---|
선택 상태 (*.selected) | 파랑 글자 + 옅은 파랑 배경 | 진한 중립 글자 + 반투명 중립 배경 |
작은 제목 굵기 (font.heading.medium 이하) | 653 | 500 |
background.neutral.subtle.hovered | 기본 hover | 더 옅은 hover |
- 컴포넌트도 Atlaskit 소스에서 플래그가 켜진 쪽(visual refresh) 스타일을 기준으로 해요.
- 기본 테마로 돌아가고 싶다면 토큰을
--no-finesse로 다시 만들어요. 토큰 동기화 를 봐요.
서체
Atlassian Sans 와 Charlie 는 Atlassian 의 브랜드 서체라서 포함하지 않아요. 대신 비슷한 인상의 Inter 를 쓰고, 한국어는 Pretendard 로 이어져요. 코드는 JetBrains Mono 예요.
- 글자 크기·행간·굵기 토큰(
font.heading.*,font.body.*)의 값은 원본 그대로예요. 서체 이름만 바꿨어요. - 굵기 토큰
font.weight.bold는 원본처럼653이에요. 가변 서체인 Inter 에서도 그대로 표현돼요. - Finesse 테마를 따르기 때문에 작은 제목(
font.heading.medium·small·xsmall·xxsmall)은 653 이 아니라 500 이에요. - 서체가 달라서 같은 문구라도 너비가 조금 달라질 수 있어요.
아이콘
@atlaskit/icon 대신 lucide-react 를 써요. ADS 아이콘과 가장 가까운 모양을 골랐어요.
| 용도 | ADS 아이콘 | Steel (lucide) |
|---|---|---|
| 정보 | status-information | Info |
| 성공 | status-success | CircleCheck |
| 경고 | status-warning | TriangleAlert |
| 오류 | status-error | OctagonAlert / CircleAlert |
| 닫기 | cross | X |
| 펼치기 | chevron-down | ChevronDown |
- 기본 크기는 16px(
size-4),small은 12px 예요. 원본의medium/small크기 체계와 맞췄어요. - 아이콘 색은
text-ds-icon*토큰으로 줘요. 장식용 아이콘에는aria-hidden을, 의미가 있는 아이콘에는label을 줘요.
Compiled → Tailwind
Atlaskit 은 Compiled 로 스타일을 작성해서, 배포된 코드에는 _bfhk1856 같은 해시 클래스만 남아 있어요. Steel 은 이 클래스를 실제 CSS 로 풀어서 같은 값을 Tailwind 유틸로 옮겼어요.
원본 (해독 후) background-color: var(--ds-background-brand-bold)
:hover { background-color: var(--ds-background-brand-bold-hovered) }
height: 2rem; padding-inline: var(--ds-space-150)
Steel bg-ds-background-brand-bold hover:bg-ds-background-brand-bold-hovered h-8 px-ds-150xcssprop 은 없어요. 대신 모든 컴포넌트가className을 받고,cn()(tailwind-merge)으로 기본 스타일 위에 덮어써요.- 원본이 런타임에 계산하던 스타일 일부(예: 표면에 따라 글자색을 반전하는 처리)는 컨텍스트와 data 속성으로 다시 구현했어요.
상호작용 프리미티브
포커스 관리, 레이어, 키보드 탐색은 radix-ui 에 맡겼어요.
| 컴포넌트 | ADS 기반 | Steel 기반 |
|---|---|---|
| Select | react-select | 자체 구현 (radix Popover + listbox 키보드 탐색) |
| Modal dialog, Drawer | 자체 구현 + @atlaskit/layering | radix Dialog |
| Dropdown menu | @atlaskit/popup + 자체 메뉴 | radix DropdownMenu |
| Popup, Datetime picker | @atlaskit/popper | radix Popover |
| Tooltip | 자체 구현 | radix Tooltip |
그래서 일부 props 는 동작이 비슷하지만 똑같지는 않아요. 예를 들어 Select 는 react-select 의 수많은 옵션 중 문서에 나온 주요 props(options, isMulti, isSearchable, isClearable, isDisabled, isInvalid, spacing, appearance …)만 지원해요. 각 컴포넌트 문서의 Props 표가 기준이에요.
다크 모드와 테마
ADS 는 setGlobalTheme() 으로 html 에 data-color-mode 를 붙이고 테마 CSS 를 지연 로딩해요. Steel 은 라이트·다크 값을 한 CSS 에 담고 .dark 클래스로 바꿔요. shadcn 과 next-themes 의 관례를 그대로 쓰기 위해서예요.
- 지원: 라이트, 다크
- 미지원: 고대비 테마,
spacing테마 전환, 브랜드 색 커스텀 테마(UNSAFE_themeOptions)
포함하지 않은 것
- Atlassian 로고·제품 이름·제품 아이콘 (
@atlaskit/logo, 앱 스위처의 제품 목록) - 일러스트레이션과 스폿 이미지 (빈 상태 예제는 lucide 아이콘이나 직접 넣은 이미지를 써요)
- 분석 이벤트(
analyticsContext,createAnalyticsEvent)와onClick의 두 번째 인자(analytics event) - 서버 렌더링 전용 최적화, 기능 플래그 런타임(
fg()). 플래그로 갈리는 스타일은 켜진 쪽(최신 모습)으로 고정해서 옮겼어요.
props 호환
이름은 Atlaskit 과 같게 맞췄어요. ADS 예제 코드를 옮길 때는 import 경로만 바꾸면 대부분 그대로 동작해요.
// ADS
import Button from '@atlaskit/button/new';
<Button appearance="primary" isDisabled>이슈 만들기</Button>
// Steel
import { Button } from '@/components/ui/button';
<Button appearance="primary" isDisabled>이슈 만들기</Button>- ADS 는 대부분 default export 지만, Steel 은 shadcn 관례대로 named export 예요.
testId는data-testid로 그대로 출력돼요.- 레거시 API(
@atlaskit/button의 old-button,appearance="link"등)는 옮기지 않았어요. 현재 권장 API 만 따라요.