@highpixel-co/palda-design-system 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -2
- package/dist/guide/LICENSE +21 -0
- package/dist/guide/NOTICE +29 -0
- package/dist/guide/README.md +57 -0
- package/dist/guide/catalog/components.yml +272 -0
- package/dist/guide/catalog/drafts.yml +333 -0
- package/dist/guide/catalog/icons.yml +309 -0
- package/dist/guide/catalog/patterns.yml +124 -0
- package/dist/guide/catalog/tokens.yml +14 -0
- package/dist/guide/docs/ACCESSIBILITY.md +10 -0
- package/dist/guide/docs/AI_UI_DESIGNER_HANDOFF.md +256 -0
- package/dist/guide/docs/COMPONENT_POLICY.md +105 -0
- package/dist/guide/docs/CONSUMER_GUIDE.md +131 -0
- package/dist/guide/docs/CONTENT.md +148 -0
- package/dist/guide/docs/DESIGN_GRAMMAR.md +378 -0
- package/dist/guide/docs/DESIGN_PRINCIPLES.md +254 -0
- package/dist/guide/docs/FIGMA_ALIGNMENT_DELTA.md +141 -0
- package/dist/guide/docs/FIGMA_NAME_MAPPING.md +84 -0
- package/dist/guide/docs/FIGMA_WORKFLOW.md +33 -0
- package/dist/guide/docs/ICON_POLICY.md +175 -0
- package/dist/guide/docs/LAYOUT.md +221 -0
- package/dist/guide/docs/PATTERN_POLICY.md +13 -0
- package/dist/guide/docs/TOKEN_POLICY.md +255 -0
- package/dist/guide/icons/manifest.json +572 -0
- package/dist/harness/check.mjs +330 -0
- package/dist/harness/cli.mjs +88 -0
- package/dist/harness/metadata.json +1323 -0
- package/dist/scripts/check-examples.mjs +444 -0
- package/package.json +13 -2
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Content
|
|
2
|
+
|
|
3
|
+
**제품 문구의 말투와 표기를 정하는 문서다.**
|
|
4
|
+
|
|
5
|
+
읽는 사람은 스마트스토어를 혼자 운영하는 셀러다. 옆에서 대신 봐 줄 사람이 없고, 화면의 문구가
|
|
6
|
+
곧 안내다. 인상은 [`DESIGN_PRINCIPLES.md`](DESIGN_PRINCIPLES.md) §1·§2를 따른다.
|
|
7
|
+
|
|
8
|
+
## 말투
|
|
9
|
+
|
|
10
|
+
**문장은 "요"로 끝난다.** 해요체다. "~습니다"(합쇼체)를 쓰지 않는다.
|
|
11
|
+
|
|
12
|
+
**친절한 서비스직 말투다.** 매장에서 손님을 맞는 사람의 말이지, 공지문이나 약관의 말이 아니다.
|
|
13
|
+
딱딱하게 알리는 대신 옆에서 알려 주듯 쓴다.
|
|
14
|
+
|
|
15
|
+
| 이렇게 | 이렇게 말고 |
|
|
16
|
+
| --------------------------- | ------------------------------- |
|
|
17
|
+
| 변경한 내용을 저장했어요 | 변경사항이 저장되었습니다 |
|
|
18
|
+
| 연동할 스토어를 골라 주세요 | 스토어를 선택하십시오 |
|
|
19
|
+
| 아직 등록한 상품이 없어요 | 등록된 상품이 존재하지 않습니다 |
|
|
20
|
+
| 잠시만 기다려 주세요 | 처리 중입니다 |
|
|
21
|
+
|
|
22
|
+
**높임의 대상은 사람이지 사물이 아니다.** "주문이 있으세요"가 아니라 "주문이 있어요"다.
|
|
23
|
+
|
|
24
|
+
**명령하지 않는다.** "~하십시오"·"~하세요"보다 "~해 주세요"가 기본이고, 그마저 필요 없는 자리는
|
|
25
|
+
평서문으로 끝낸다.
|
|
26
|
+
|
|
27
|
+
## 오류와 성공 — 겁주지 않는다
|
|
28
|
+
|
|
29
|
+
**오류 문구가 무섭지 않아야 한다.** 혼자 쓰는 사람에게 강한 경고는 도움이 아니라 부담이다.
|
|
30
|
+
무슨 일이 있었는지와 지금 무엇을 하면 되는지, 둘만 담는다.
|
|
31
|
+
|
|
32
|
+
| 하지 않는 것 | 대신 |
|
|
33
|
+
| ----------------------------------- | ----------------------------------------------- |
|
|
34
|
+
| 겁주는 단어 — 경고·실패·오류·불가 | 무슨 일이 있었는지 그대로 ("저장하지 못했어요") |
|
|
35
|
+
| 느낌표 | 마침표 없는 평서문 |
|
|
36
|
+
| 사용자를 탓하기 ("잘못 입력했어요") | 조건을 알려 주기 ("숫자만 넣을 수 있어요") |
|
|
37
|
+
| 되돌릴 수 없다는 말을 앞세우기 | 무엇이 사라지는지 담담하게 |
|
|
38
|
+
| 원인만 적고 끝내기 | 다음에 할 일을 한 문장 덧붙이기 |
|
|
39
|
+
|
|
40
|
+
**되돌릴 수 없는 일은 숨기지 않는다.** 겁주지 않는 것과 알리지 않는 것은 다르다. "영구적으로
|
|
41
|
+
삭제됩니다!"가 아니라 "삭제하면 다시 불러올 수 없어요"다.
|
|
42
|
+
|
|
43
|
+
**성공은 짧게.** 한 문장이면 된다. 축하하거나 칭찬하지 않는다.
|
|
44
|
+
|
|
45
|
+
## 버튼
|
|
46
|
+
|
|
47
|
+
### 라벨은 고정이다
|
|
48
|
+
|
|
49
|
+
**버튼의 글자는 어떤 상태에서도 바뀌지 않는다.** 눌렀다고, 값이 정해졌다고, 처리 중이라고 글자가
|
|
50
|
+
바뀌지 않는다.
|
|
51
|
+
|
|
52
|
+
| 자리 | 이렇게 | 이렇게 말고 |
|
|
53
|
+
| -------------------- | ------------------ | ----------------------- |
|
|
54
|
+
| 스토어를 고르는 버튼 | `선택하기` 로 고정 | 고른 뒤 `우리집상회` 로 |
|
|
55
|
+
| 저장 중 | `저장하기` 로 고정 | `저장 중...` 으로 |
|
|
56
|
+
| 이미 연동된 스토어 | `연동하기` 로 고정 | `연동됨` 으로 |
|
|
57
|
+
|
|
58
|
+
버튼은 **누르면 무슨 일이 일어나는지**를 말하는 자리다. 지금 무엇이 골라졌는지, 처리가 어디까지
|
|
59
|
+
갔는지는 버튼 밖에서 말한다 — 고른 값은 버튼 옆이나 아래, 진행 상태는 `ProgressBar`나
|
|
60
|
+
`Toast`다.
|
|
61
|
+
|
|
62
|
+
**진행 중은 글자가 아니라 `disabled`로 표현한다.** `Button`에 로딩 전용 prop이 없는 것이
|
|
63
|
+
그래서다([`components/src/Button/Button.tsx`](https://github.com/highpixel-co/palda-design-system/blob/0504d8eaa033955d7a70414616ee999e447a0ced/components/src/Button/Button.tsx)).
|
|
64
|
+
|
|
65
|
+
### "~기"로 끝난다
|
|
66
|
+
|
|
67
|
+
**버튼 라벨은 동사이고 "~기"로 끝난다.** 명사로 끝내지 않는다.
|
|
68
|
+
|
|
69
|
+
| 이렇게 | 이렇게 말고 |
|
|
70
|
+
| --------- | ----------- |
|
|
71
|
+
| 저장하기 | 저장 |
|
|
72
|
+
| 다시 하기 | 다시 시도 |
|
|
73
|
+
| 더 보기 | 더보기 |
|
|
74
|
+
| 충전하기 | 충전 |
|
|
75
|
+
|
|
76
|
+
## 오류·성공·Empty State 문구 구조
|
|
77
|
+
|
|
78
|
+
**컴포넌트가 칸을 이미 정해 두었다.** 문구는 그 칸에 맞춘다.
|
|
79
|
+
|
|
80
|
+
| 자리 | 칸 | 무엇을 넣나 |
|
|
81
|
+
| --------------------- | --------------------------------------- | --------------------------------------------------- |
|
|
82
|
+
| `EmptyState` | `title` · `description` · `actionLabel` | 무엇이 없는지 · 왜 비어 있는지나 다음 할 일 · "~기" |
|
|
83
|
+
| `Alert` | 제목 · 본문 · action | 무슨 일인지 · 다음에 할 일 · "~기" |
|
|
84
|
+
| `Toast` | 메시지 한 줄 | 끝난 일 하나. 설명을 붙이지 않는다 |
|
|
85
|
+
| `TextField`의 `error` | 한 줄 | 무엇이 맞지 않는지와 어떤 값이면 되는지 |
|
|
86
|
+
|
|
87
|
+
**제목에는 상태를, 설명에는 다음 할 일을 쓴다.** 두 칸에 같은 말을 나눠 쓰지 않는다.
|
|
88
|
+
|
|
89
|
+
**Empty State는 사과하지 않는다.** "아직 없어요"까지가 사실이고, 그다음은 만들 수 있는 길이다.
|
|
90
|
+
|
|
91
|
+
## 설명은 언제 붙이나
|
|
92
|
+
|
|
93
|
+
**기본은 제목만이다.** `Card`·`FormSection`·`ListRow`의 `description`은 비워 둔다. 칸이 있으니
|
|
94
|
+
채우는 것이 화면에 설명이 쌓이는 가장 흔한 이유다.
|
|
95
|
+
|
|
96
|
+
### 붙일지는 사람이 정한다
|
|
97
|
+
|
|
98
|
+
**중복인지 아닌지를 매번 따져서 채우지 않는다.** 한 화면의 설명이 위층과 겹치는지, 아래 값과
|
|
99
|
+
겹치는지, 제목을 뒤집어 말한 것인지를 전부 확인하는 일은 화면마다 어렵고 판단도 갈린다.
|
|
100
|
+
|
|
101
|
+
그래서 절차로 가른다. **시안은 제목만 둔 상태로 만들고, 설명이 필요해 보이는 자리는 묻는다.**
|
|
102
|
+
묻지 않고 채우지 않는다. 붙이기로 정한 자리만 채운다.
|
|
103
|
+
|
|
104
|
+
### 붙이기로 했다면 — 그 자리에서만 할 수 있는 말
|
|
105
|
+
|
|
106
|
+
셋 중 하나가 아니면 설명이 아니다.
|
|
107
|
+
|
|
108
|
+
| 무엇 | 예 |
|
|
109
|
+
| ----------------------- | ---------------------------------------------- |
|
|
110
|
+
| 눈에 안 보이는 사실 | 10분마다 새 주문을 가져와요 |
|
|
111
|
+
| 제목이 원인일 때의 대처 | 스마트스토어에 다시 로그인하면 이어서 수집해요 |
|
|
112
|
+
| 어디로 가야 하는지 | 위의 자동 수집 스위치를 켜면 다시 시작해요 |
|
|
113
|
+
|
|
114
|
+
`Chrome · v1.4.2`나 `MacBook Pro · Chrome 129`처럼 **값을 적는 자리는 설명이 아니다.** 위 규칙의
|
|
115
|
+
대상이 아니고 그대로 둔다.
|
|
116
|
+
|
|
117
|
+
**제목을 다시 말하는 설명은 붙이기로 정한 자리에도 쓰지 않는다.** 뒤집어 말한 것도 다시 말한
|
|
118
|
+
것이다 — "브라우저를 닫아 뒀을 때 / 브라우저가 켜져 있을 때만 움직여요"는 한 문장을 앞뒤로 나눠
|
|
119
|
+
쓴 것이다.
|
|
120
|
+
|
|
121
|
+
**목록의 행 설명은 전부 붙이거나 전부 뺀다.** 한 행만 설명이 없으면 그 행이 덜 중요해 보인다.
|
|
122
|
+
어느 한 행에서 지울 이유가 생기면 지우는 대신 위 셋 중 하나로 고쳐 쓴다.
|
|
123
|
+
|
|
124
|
+
## 아직 확정되지 않은 것
|
|
125
|
+
|
|
126
|
+
**여기 있는 것은 화면에서 마주쳐도 지어내지 않고 멈춘다.**
|
|
127
|
+
|
|
128
|
+
| 무엇 | 상태 |
|
|
129
|
+
| --------------------- | ---------------------------------------------------------------------------------- |
|
|
130
|
+
| 메뉴 라벨 | 지금 코드의 사이드바 항목은 명사다(`배송과정`·`클레임`). 규칙으로 확정된 적은 없다 |
|
|
131
|
+
| 동일 액션의 고정 명칭 | 한 액션에 한 이름을 쓴다는 규칙만 있고, 대조표가 없다. 아래 §제안 참고 |
|
|
132
|
+
| 날짜 표기 | 미확정 |
|
|
133
|
+
| 금액 표기 | 미확정 |
|
|
134
|
+
| 수량 표기 | 미확정 |
|
|
135
|
+
| 대화상자 버튼의 예외 | `취소`·`확인`에도 "~기"를 붙일지 (`취소하기`·`확인하기`) |
|
|
136
|
+
|
|
137
|
+
### 제안 — 고정 명칭 후보
|
|
138
|
+
|
|
139
|
+
**확정 전이다.** 지금 저장소의 스토리·예시에 실제로 쓰인 라벨을 위 규칙에 맞춰 옮긴 것이다.
|
|
140
|
+
|
|
141
|
+
| 지금 코드에 있는 것 | 제안 |
|
|
142
|
+
| ------------------- | --------- |
|
|
143
|
+
| 저장 | 저장하기 |
|
|
144
|
+
| 초기화 | 되돌리기 |
|
|
145
|
+
| 다시 시도 | 다시 하기 |
|
|
146
|
+
| 알림 받기 | 알림 받기 |
|
|
147
|
+
| 확인 | 확인하기 |
|
|
148
|
+
| 취소 | 취소하기 |
|
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
# Design Grammar
|
|
2
|
+
|
|
3
|
+
**화면을 조립하며 갈리는 판단 — 어느 pattern을 쓰나, 무엇을 카드로 감싸나, 상태는 누가 갖나 — 을
|
|
4
|
+
한 곳에서 정하는 문서다.**
|
|
5
|
+
|
|
6
|
+
## 무엇을 언제 읽나
|
|
7
|
+
|
|
8
|
+
화면을 조립할 때 여는 표다. **문서가 아니라 절 단위로 연다** — `LAYOUT.md`와 이 문서는 각각
|
|
9
|
+
10KB라 통째로 읽으면 읽지 않는 것이 없어진다.
|
|
10
|
+
|
|
11
|
+
**순서는 되돌리기 비싼 것부터다.** 셸을 잘못 잡으면 전부 다시 짜야 하고, 색은 나중에 바꿔도 싸다.
|
|
12
|
+
|
|
13
|
+
| 질문 | 어디 |
|
|
14
|
+
| ------------------------- | ------------------------------------------------------------------------- |
|
|
15
|
+
| 무엇을 먼저 보여주나? | [`DESIGN_PRINCIPLES.md`](DESIGN_PRINCIPLES.md) §4 — 강조는 한 화면에 하나 |
|
|
16
|
+
| 이거 하면 안 되는 건가? | 같은 문서 §6 지양할 디자인 — 시각·구조 두 표 |
|
|
17
|
+
| 규칙끼리 부딪히면? | 같은 문서 §7 판단이 충돌할 때 |
|
|
18
|
+
| 이 화면의 틀은? | [`LAYOUT.md`](LAYOUT.md) §셸 — 모든 화면이 같다. 한 번만 읽으면 된다 |
|
|
19
|
+
| 페이지인가 모달인가? | 아래 §띄우나 마나 §언제 모달인가 — 세 관문 |
|
|
20
|
+
| 무엇으로 조립하나? | 아래 §어느 pattern을 고르나 |
|
|
21
|
+
| 이 자리에 이 패턴이 맞나? | [`catalog/patterns.yml`](../catalog/patterns.yml)의 `use_for`·`avoid_for` |
|
|
22
|
+
| 이게 이 화면 것인가? | 아래 §곁을 어디 두나 — 박스 질문보다 **먼저** 묻는다 |
|
|
23
|
+
| 박스로 감싸나? | 아래 §판단 한 줄 → §쓰는 경우 |
|
|
24
|
+
| 면인가 행인가? | [`TOKEN_POLICY.md`](TOKEN_POLICY.md) §간격 마지막 줄 + §라운드 표 |
|
|
25
|
+
| 이 카드는 눌리나? | 아래 §세 번째 질문 — 고르는 카드 / 담는 카드 |
|
|
26
|
+
| 로딩·빈·오류는 누가? | 아래 §상태는 누가 갖나 |
|
|
27
|
+
| 여백은 얼마? | [`LAYOUT.md`](LAYOUT.md) §고를 때 (§토큰 표는 그다음) |
|
|
28
|
+
| 색은? | [`TOKEN_POLICY.md`](TOKEN_POLICY.md) §색 — §켤레와 §글자와 아이콘 표만 |
|
|
29
|
+
| 글자 크기는? | [`TOKEN_POLICY.md`](TOKEN_POLICY.md) §타이포 |
|
|
30
|
+
| props는? | 타입. 문서에 없는 것이 의도된 것이다 |
|
|
31
|
+
| 좁아지면? | [`LAYOUT.md`](LAYOUT.md) §좁아질 때 |
|
|
32
|
+
|
|
33
|
+
**ADR은 여기서 읽지 않는다.** 근거 보관소지 지시서가 아니고, 대체된 값이 그대로 남아 있다.
|
|
34
|
+
기준은 [`AGENTS.md`](https://github.com/highpixel-co/palda-design-system/blob/0504d8eaa033955d7a70414616ee999e447a0ced/AGENTS.md)의 §ADR은 화면 만들 때 읽지 않는다에 있다.
|
|
35
|
+
|
|
36
|
+
### 아직 답할 문서가 없는 질문
|
|
37
|
+
|
|
38
|
+
지어내지 말고 멈춘다. 여기 질문이 있으면 화면에서 마주쳐도 값을 고르지 않는다.
|
|
39
|
+
|
|
40
|
+
**지금은 비어 있다.** 마지막으로 남아 있던 제목·본문·보조 정보의 위계는 2026-09-02에
|
|
41
|
+
[`TOKEN_POLICY.md`](TOKEN_POLICY.md) §타이포가 받았다 — 페이지 `headline`(24) → 섹션·카드
|
|
42
|
+
`body1`(16) → 행 `body2`(14) → 보조 `label`(12)이다.
|
|
43
|
+
|
|
44
|
+
### 주 액션을 어디 두나
|
|
45
|
+
|
|
46
|
+
**시스템이 고르지 않는다. 화면이 고르고 밝힌다.** 페이지 헤더 우측 상단(`LAYOUT.md` §셸의 바디)과
|
|
47
|
+
아래 `BottomBar` 둘 다 맞는 자리이고, 어느 쪽인지는 서비스 성격이 정한다 — 읽다가 가끔 누르는
|
|
48
|
+
화면은 위, 채워 넣고 마지막에 확정하는 화면은 아래다.
|
|
49
|
+
|
|
50
|
+
**고르는 것은 자유지만 개수는 하나다.** 한 화면의 주 액션은 하나이고, 고른 자리도 하나다. 위아래에
|
|
51
|
+
같은 액션을 두 번 두지 않는다. 근거는
|
|
52
|
+
[`DESIGN_PRINCIPLES.md`](DESIGN_PRINCIPLES.md) §4의 주 액션의 자리에 있다.
|
|
53
|
+
|
|
54
|
+
## 곁을 어디 두나
|
|
55
|
+
|
|
56
|
+
**박스를 두를지 묻기 전에 이것부터 묻는다.** 같은 블록이라도 이 화면 것이냐 아니냐로 규칙이
|
|
57
|
+
갈린다. 근거는 [`decisions/0022`](https://github.com/highpixel-co/palda-design-system/blob/0504d8eaa033955d7a70414616ee999e447a0ced/docs/decisions/0022-screens-declare-their-body.md)에 있다.
|
|
58
|
+
|
|
59
|
+
> 이것은 **이 화면이 선언한 본문**인가?
|
|
60
|
+
|
|
61
|
+
**모든 화면은 만들기 전에 본문을 한 문장으로 선언한다.** 본문은 이 화면이 하는 일이고 **하나다**
|
|
62
|
+
— 둘이면 화면을 쪼갠다. 선언은 승인 화면 문서(`examples/approved/{화면}.md`)가 받는다.
|
|
63
|
+
|
|
64
|
+
**선언에 들지 않은 것은 전부 곁이다.** 다른 기능의 요약이거나 그리로 가는 입구다. 판단이 아니라
|
|
65
|
+
뺄셈이라, 그릴 때마다 다시 고르지 않는다.
|
|
66
|
+
|
|
67
|
+
### 손잡이가 둘이다
|
|
68
|
+
|
|
69
|
+
하나로 보면 자리는 많이 먹으면서 눈에는 안 띄는 블록이 나온다.
|
|
70
|
+
|
|
71
|
+
| 손잡이 | 무엇 | 곁에서 |
|
|
72
|
+
| ------ | ---------------------------------- | ------ |
|
|
73
|
+
| 무게 | 자리를 얼마나 먹고 얼마나 강조되나 | 내린다 |
|
|
74
|
+
| 구분 | 다른 종류로 읽히나 | 낸다 |
|
|
75
|
+
|
|
76
|
+
### 곁의 규칙 셋
|
|
77
|
+
|
|
78
|
+
1. **세로로 한 줄이다.** 블록이 되지 않는다. (무게)
|
|
79
|
+
2. **본문이 쓰는 pattern을 쓰지 않는다.** 본문이 행 나열이면 곁은 행이 아니다. (구분)
|
|
80
|
+
3. **강조 예산을 쓰지 않는다.** `primary`·`accent` 채움을 주지 않는다.
|
|
81
|
+
[`DESIGN_PRINCIPLES.md`](DESIGN_PRINCIPLES.md) §4의 "강한 강조는 하나"는 본문이 갖는다. (무게)
|
|
82
|
+
|
|
83
|
+
### 자리는 시스템이 정하지 않는다
|
|
84
|
+
|
|
85
|
+
화면이 고르고 선언서에 밝힌다. 규칙 셋을 지키면 위든 아래든 무게는 이미 내려가 있고, 구분은
|
|
86
|
+
자리가 아니라 문법이 낸다.
|
|
87
|
+
|
|
88
|
+
**곁은 본문보다 먼저 올 수 있다. 넷째 규칙은 없다.** 순서를 규칙으로 세우면 "무게를 내리면 자리는
|
|
89
|
+
문제가 되지 않는다"는 전제가 무너지고, 곁을 아래로 밀어 두면 규칙 셋을 어겨도 넘어가게 된다.
|
|
90
|
+
검사가 순서로 막는 것은 헤더 하나뿐이다(`check:examples`). 2026-09-02에 시안 주석이 "규칙 넷 —
|
|
91
|
+
본문보다 먼저 오지 않는다"로 새어 나간 것을 이 문장으로 되돌렸다.
|
|
92
|
+
|
|
93
|
+
**곁이 위에 있는 것이 문제로 보이면 자리가 아니라 무게를 의심한다.** 한 줄이 아니거나, 본문
|
|
94
|
+
pattern을 쓰고 있거나, 강조를 갖고 있다.
|
|
95
|
+
|
|
96
|
+
**곁은 자리를 요구하지 않는다.** 상태·활성화 바(2단)에 얹는 것은 좋지만 둘을 지킨다.
|
|
97
|
+
|
|
98
|
+
- **곁 때문에 2단을 켜지 않는다.** 2단은 화면 전역을 켜고 끄는 것이 있을 때만 깔린다
|
|
99
|
+
([`LAYOUT.md`](LAYOUT.md) §콘텐츠 세로 순서).
|
|
100
|
+
- **곁이 2단의 배치를 바꾸지 않는다.** `band--inset`은 `space-between`이라 자리가 양끝 둘뿐이고,
|
|
101
|
+
전역 토글이 이미 그 둘을 쓴다. 얹을 수 있는 것은 한 자리가 실제로 비어 있을 때뿐이다.
|
|
102
|
+
|
|
103
|
+
바디 안에 두면 면이 캔버스와 같아지므로 구분을 문법이 전부 져야 한다. 읽는 문구는
|
|
104
|
+
`text/primary-sub`로 물러나고, 갈리는 표시는 `Link`의 밑줄 같은 것이 낸다.
|
|
105
|
+
|
|
106
|
+
## Card·border·shadow를 쓰는 조건
|
|
107
|
+
|
|
108
|
+
**기본값은 박스가 없는 것이다.** 정보는 여백·디바이더·타이포 위계로 구조화한다. 보더나 카드로
|
|
109
|
+
모든 것을 감싸지 않는다.
|
|
110
|
+
|
|
111
|
+
### 판단 한 줄
|
|
112
|
+
|
|
113
|
+
> 이 박스는 사용자가 **고르거나, 열리거나, 떠 있는** 것인가?
|
|
114
|
+
|
|
115
|
+
아니면 보더와 카드를 빼고 여백 + 디바이더 + 제목으로 만든다.
|
|
116
|
+
|
|
117
|
+
### 두 번째 질문 — 어느 층에 놓이나
|
|
118
|
+
|
|
119
|
+
박스를 두르기로 했으면 한 번 더 묻는다. **같은 내용이라도 층이 다르면 다른 것이다.**
|
|
120
|
+
|
|
121
|
+
> 이것은 **페이지 바디 최상위 블록**인가, **섹션 안의 행**인가?
|
|
122
|
+
|
|
123
|
+
| 층 | 무엇 | 안쪽 여백 | 라운드 | 대표 |
|
|
124
|
+
| ------------------ | ------- | -------------- | --------------- | ----------------------- |
|
|
125
|
+
| 페이지 바디 최상위 | 면·패널 | `inset/md`(16) | `container`(16) | `Card` |
|
|
126
|
+
| 섹션 안 | 행·요소 | `inset/md`(16) | `control`(10) | `ListRow tone="filled"` |
|
|
127
|
+
|
|
128
|
+
**층을 가르는 것은 라운드다.** 안쪽 여백은 둘 다 16이라 층을 가르지 못한다 — 행의 상하 여백을
|
|
129
|
+
16으로 올리면서 같아졌다([`decisions/0019`](https://github.com/highpixel-co/palda-design-system/blob/0504d8eaa033955d7a70414616ee999e447a0ced/docs/decisions/0019-list-row-vertical-inset.md)). 값의
|
|
130
|
+
근거는 [`TOKEN_POLICY.md`](TOKEN_POLICY.md) §라운드 표이고, 여백은 같은 문서 §간격에 있다.
|
|
131
|
+
|
|
132
|
+
**첫 질문은 상호작용만 가르고 층위는 가르지 않는다.** 고르지도 열리지도 떠 있지도 않은 요약
|
|
133
|
+
블록이라도, 페이지 바디 최상위에서 `Card`와 나란히 서면 면이다.
|
|
134
|
+
|
|
135
|
+
옆에 무엇이 서는지로 확인한다. 나란한 블록끼리 `border-radius`가 같은 칸이 아니면 층을 잘못 잡은
|
|
136
|
+
것이다. 눈으로는 6px 차이라 잘 넘어가므로 브라우저에서 계산된 값을 실제로 재본다.
|
|
137
|
+
|
|
138
|
+
### 쓰는 경우 — 이때만
|
|
139
|
+
|
|
140
|
+
| 자리 | 예 | 표면 |
|
|
141
|
+
| ------------------------------ | -------------------------------------- | ---------------------------------- |
|
|
142
|
+
| 고를 수 있는 개별 객체 | 템플릿 카드, 갤러리 아이템, 옵션 카드 | `surface/base` + 보더 |
|
|
143
|
+
| 페이지 바디 최상위의 요약 블록 | 익스텐션 연결 상태, 계정 요약 | `surface/base` + 보더 (`Card`) |
|
|
144
|
+
| 그중 앞으로 끌어낼 카드 하나 | 지금 해야 할 일을 든 카드 | `surface/raised` (`tone="filled"`) |
|
|
145
|
+
| 상태를 보여야 하는 순간 | 선택됨(accent 보더) · 포커스 · 활성 | 보더 색으로 표현 |
|
|
146
|
+
| 실제로 떠 있는 표면 | 드롭다운 메뉴 · 라이브 프리뷰 · 토스트 | `surface/raised` + `shadow/100` |
|
|
147
|
+
| 스크림 위에 뜨는 표면 | 모달 | `surface/base` + `shadow/100` |
|
|
148
|
+
| 입력 컨트롤 자체 | TextField | 컨트롤 규칙을 따른다 |
|
|
149
|
+
|
|
150
|
+
**카드의 기본 채움은 흰색이다.** 카드가 여럿 선 화면에서 회색 면이 반복되면 전부 똑같이
|
|
151
|
+
무거워져 어느 것도 앞에 서지 못한다. 그래서 `Card`의 기본은 `tone="plain"`이고, 강조는
|
|
152
|
+
기본값이 아니라 **한 화면에서 하나를 골라 `tone="filled"`로 올리는 것**이다. 채움만 갈리고
|
|
153
|
+
보더·라운드·여백은 둘이 같다 — 흰 캔버스 위에서는 보더가 유일한 경계라 `plain`에서도 빼지
|
|
154
|
+
않는다. `ListRow`의 `tone`과 같은 축이고 같은 뜻이다.
|
|
155
|
+
|
|
156
|
+
### 세 번째 질문 — 무엇이 눌리나
|
|
157
|
+
|
|
158
|
+
**"액션이 있나"로 가르지 않는다.** 고르는 것도 액션이고 버튼을 품은 것도 액션이라 그 축은 두
|
|
159
|
+
경우를 한 칸에 넣는다. 갈리는 것은 **무엇이 눌리는가**다.
|
|
160
|
+
|
|
161
|
+
> 이 카드 **자체**를 고르나, 카드 **안의 것**을 누르나?
|
|
162
|
+
|
|
163
|
+
| 이름 | 무엇 | 코드 | 그려지는 것 |
|
|
164
|
+
| --------------- | ------------------------------ | ------------------------- | --------------------------------------------- |
|
|
165
|
+
| **고르는 카드** | 카드 자신이 선택 대상 | `onClick` + `selected` 짝 | `button`, `aria-pressed`, 선택 시 accent 보더 |
|
|
166
|
+
| **담는 카드** | 카드는 면. 누를 것은 안에 둔다 | `onClick` 없음 | `section` |
|
|
167
|
+
|
|
168
|
+
`onClick`은 "누를 수 있다"가 아니라 **"고를 수 있다"**는 뜻이고 `selected` 없이 혼자 쓰지 않는다.
|
|
169
|
+
주는 순간 `aria-pressed`가 붙어, 고르는 것이 아닌 카드에 잘못된 상태를 알린다.
|
|
170
|
+
|
|
171
|
+
> **눌러서 무언가를 여는 카드는 없다.** 여는 것은 카드 안의 버튼이 한다.
|
|
172
|
+
|
|
173
|
+
시안이 "카드 전체 클릭"을 요구해도 이 문장을 따른다. 카드는 담는 카드로 두고 안에 `Button`을
|
|
174
|
+
놓는다.
|
|
175
|
+
|
|
176
|
+
`shadow/100`은 **떠 있는 표면에만** 준다. 고를 수 있는 객체는 보더까지다. 그림자는 "이 면이 다른
|
|
177
|
+
면 위에 있다"는 뜻이고, 페이지에 붙어 있는 블록은 떠 있지 않다.
|
|
178
|
+
|
|
179
|
+
**읽는 면이 가장 밝다.** 페이지 캔버스(`surface/base`)가 흰색이고, 틀과 조작하는 것
|
|
180
|
+
(`surface/raised` — 사이드바·모달·드롭다운·입력)이 회색으로 물러난다. 값을 강조해 담는 **요약 행은
|
|
181
|
+
카드가 아니라 옅은 회색 필**(`surface/raised`)이고 보더를 주지 않는다 — `ListRow`의
|
|
182
|
+
`tone="filled"`다. 전체 표는 [`LAYOUT.md`](LAYOUT.md)의 §배경 위계에 있다.
|
|
183
|
+
|
|
184
|
+
**채운 면은 `Card`든 `ListRow`든 같은 회색이다.** `tone="filled"`가 두 곳에서 같은 뜻이고 같은
|
|
185
|
+
값이며, 갈리는 것은 색이 아니라 층이다 — 여백과 라운드가 다르다
|
|
186
|
+
([`decisions/0018`](https://github.com/highpixel-co/palda-design-system/blob/0504d8eaa033955d7a70414616ee999e447a0ced/docs/decisions/0018-summary-row-shares-the-filled-surface.md)).
|
|
187
|
+
|
|
188
|
+
### 쓰지 않는 경우 — 기본값
|
|
189
|
+
|
|
190
|
+
| 자리 | 대신 |
|
|
191
|
+
| ------------------------------------------------ | ------------------------------------------------------ |
|
|
192
|
+
| 설정 섹션 묶기 | 제목(bold) + 설명(sub) + 콘텐츠, 섹션 간 `space-8`(32) |
|
|
193
|
+
| 정보 표시 (통계, 상태/남은 일수/기한, 잔여 건수) | 행 나열 + `border/default` 1px 디바이더 |
|
|
194
|
+
| 리스트 (주문완료·발송처리·배송완료) | 디바이더로 구분, 우측에 상태 배지 + chevron |
|
|
195
|
+
| 섹션 안에서 값을 강조해 담는 요약 행 (발송 채널) | `surface/raised` 필, 보더 없음 (`tone="filled"`) |
|
|
196
|
+
| 이미 제목과 여백으로 갈리는 그룹 | 아무것도 더하지 않는다 |
|
|
197
|
+
|
|
198
|
+
### 절대 규칙
|
|
199
|
+
|
|
200
|
+
**컨테이너 중첩 금지.** 카드 안에 또 보더 박스를 넣지 않는다. 최대 1 depth다. 카드 안의 목록은
|
|
201
|
+
디바이더로 가른다.
|
|
202
|
+
|
|
203
|
+
**강조는 컨테이너가 아니라 상태·타이포·색으로 만든다.** 정적인 블록을 보더로 둘러 강조하지 않는다.
|
|
204
|
+
|
|
205
|
+
| 강조하려는 것 | 방법 |
|
|
206
|
+
| ------------- | ------------------------------------------------------- |
|
|
207
|
+
| 활성 탭 | 2px 먹색 언더라인 + `text/primary` (`Tab`) |
|
|
208
|
+
| 선택된 카드 | `border/accent` |
|
|
209
|
+
| 상태 | 배지 — 발송 전은 중립(`primary`), 발송 중은 `secondary` |
|
|
210
|
+
| 주요 CTA | 다크 `primary` 풀폭 버튼 |
|
|
211
|
+
|
|
212
|
+
**필터는 탭이다.** 언더라인으로 활성을 표시한다. 채운 칩 박스로 만들지 않는다. 탭은 `Tab`
|
|
213
|
+
하나이고(0023), `Chip`은 토글과 선택 태그 자리에만 쓴다.
|
|
214
|
+
|
|
215
|
+
**벤토·카드 그리드는 개별 객체 모음에만.** 템플릿 갤러리 같은 자리다. 설정 폼과 정보 패널을
|
|
216
|
+
벤토로 만들지 않는다.
|
|
217
|
+
|
|
218
|
+
**앱 셸을 쓴다.** 화면은 좌측 사이드바 + 콘텐츠 구성이다. 풀폭 카드 스택으로 만들지 않는다.
|
|
219
|
+
|
|
220
|
+
**배경 위계.** 읽는 면(캔버스·바디)이 가장 밝고 틀과 조작하는 것이 회색으로 물러난다. 정보
|
|
221
|
+
블록에 불필요한 채움과 보더를 주지 않는다. 표는 [`LAYOUT.md`](LAYOUT.md)에 있다.
|
|
222
|
+
|
|
223
|
+
### pattern에 어떻게 들어가 있나
|
|
224
|
+
|
|
225
|
+
| pattern | 보더 | 그림자 | 자리 |
|
|
226
|
+
| ------------- | ---- | ------ | --------------------------------------------------------------------- |
|
|
227
|
+
| `FormSection` | 없음 | 없음 | **설정·정보 섹션의 기본**. 제목 + 설명 + 콘텐츠 |
|
|
228
|
+
| `ListRow` | 없음 | 없음 | 행 사이 디바이더만. 박스로 감싸지 않는다 |
|
|
229
|
+
| `Card` | 있음 | 없음 | 고를 수 있는 객체 · 페이지 최상위 요약 블록. 채움은 `tone`(기본 흰색) |
|
|
230
|
+
| `LivePreview` | 있음 | 있음 | 떠 있는 표면 |
|
|
231
|
+
| `BottomBar` | 있음 | 있음 | 화면 아래에 떠 있는 바 |
|
|
232
|
+
| `AppShell` | — | — | 사이드바 + 콘텐츠 틀 |
|
|
233
|
+
|
|
234
|
+
`Card`를 섹션 묶기에 쓰지 않는다. 섹션은 `FormSection`이다. 근거는
|
|
235
|
+
[`decisions/0011`](https://github.com/highpixel-co/palda-design-system/blob/0504d8eaa033955d7a70414616ee999e447a0ced/docs/decisions/0011-no-over-carding.md)에 있다.
|
|
236
|
+
|
|
237
|
+
## 띄우나 마나
|
|
238
|
+
|
|
239
|
+
**깊이와 끊김은 다른 축이다.** 위 §두 번째 질문은 페이지 **안쪽** 층(면인가 행인가)을 가르고,
|
|
240
|
+
이 절은 페이지 **위로** 뜨는 층을 가른다. 근거는
|
|
241
|
+
[`decisions/0020`](https://github.com/highpixel-co/palda-design-system/blob/0504d8eaa033955d7a70414616ee999e447a0ced/docs/decisions/0020-modal-depth-and-scrim.md)에 있다.
|
|
242
|
+
|
|
243
|
+
### 층
|
|
244
|
+
|
|
245
|
+
| 층 | 무엇 | 표면 | z | 흐름 | 대표 |
|
|
246
|
+
| ------------- | --------------------- | ------------------------------- | --- | -------- | ------------------------------- |
|
|
247
|
+
| 0 페이지 | 캔버스 위 콘텐츠 | `surface/base` | — | 안 끊음 | `AppShell` 바디 |
|
|
248
|
+
| 1 인라인 펼침 | 같은 흐름 안에서 열림 | 상속 | — | 안 끊음 | 접었다 펴는 행 |
|
|
249
|
+
| 2 붙어 뜸 | 트리거에 앵커 | `surface/raised` + `shadow/100` | 1 | 안 끊음 | `DropdownButton` 메뉴·`Tooltip` |
|
|
250
|
+
| 3 모서리에 뜸 | 화면 모서리에 고정 | `surface/raised` + `shadow/100` | 101 | 안 끊음 | `Toast` |
|
|
251
|
+
| 4 스크림 위 | 뒤를 막고 가운데 | `surface/base` + `shadow/100` | 100 | **끊음** | `Modal` |
|
|
252
|
+
|
|
253
|
+
**끊는 층은 4 하나뿐이다.** 나머지는 전부 뒤 화면을 계속 볼 수 있다. 표면 값의 근거는 위
|
|
254
|
+
§쓰는 경우에 있고, 모달만 `surface/base`인 이유는
|
|
255
|
+
[`TOKEN_POLICY.md`](TOKEN_POLICY.md) §표면과 오버레이에 있다.
|
|
256
|
+
|
|
257
|
+
**끊음을 실제로 만드는 것은 스크롤 잠금과 포커스 트랩이다**(`Modal.tsx`). 마지막 열은 성격
|
|
258
|
+
설명이 아니라 이 둘을 가리킨다. 접근성 요구라 시안 대상이 아니고 디자인 판단으로 뒤집지 않는다.
|
|
259
|
+
포커스 트랩이 모달 하나를 전제로 감기 때문에, 아래 §겹침의 이중 모달 금지와 뿌리가 같다.
|
|
260
|
+
|
|
261
|
+
**딤은 `overlay/dim`(70% 검정)이다.** 시안에서 온 값은 아니지만 2026-08-31에 이대로 확정했다.
|
|
262
|
+
옅게 잡으면 두 가지가 같이 무너진다 — 4층을 3층과 가르는 시각 신호가 딤뿐이고, **모달 카드가
|
|
263
|
+
흰색인 것**([`decisions/0013`](https://github.com/highpixel-co/palda-design-system/blob/0504d8eaa033955d7a70414616ee999e447a0ced/docs/decisions/0013-surface-base-is-white.md))**이 짙은 딤 위에서만
|
|
264
|
+
성립한다.** 카드와 딤 처리된 뒤 캔버스의 대비가 70%에서 8.5:1인데 30%에서는 2.1:1로 떨어져,
|
|
265
|
+
카드가 떠 있는 것으로 읽히지 않는다. 뒤 본문 대비도 70%에서 2.25:1이라 내용을 읽을 수 없고,
|
|
266
|
+
그래서 아래 1번 관문의 기준선이 흐려지지 않는다.
|
|
267
|
+
|
|
268
|
+
### 언제 모달인가 — 세 관문
|
|
269
|
+
|
|
270
|
+
> 1. **뒤 화면을 보면서 할 수 있나?** → 그렇다면 모달이 아니다. 1층(인라인 펼침)
|
|
271
|
+
> 2. **지금 답하지 않으면 다음으로 못 가나?** → 아니라면 모달이 아니다. 3층(`Toast`)·`Alert`
|
|
272
|
+
> 3. **화면을 새로 열 만큼 큰가?** → 그렇다면 모달이 아니다. 새 페이지
|
|
273
|
+
|
|
274
|
+
셋을 다 통과할 때만 모달이다. 하나라도 걸리면 오른쪽으로 간다.
|
|
275
|
+
|
|
276
|
+
**3번을 가장 자주 놓친다.** 필드가 여러 개인 편집 폼은 모달에 넣지 않는다. 모달 안에서 또 무언가를
|
|
277
|
+
골라야 하는 순간 이중 모달이 되고, 그건 아래에서 금지한다. 알림톡 템플릿 편집이 모달이 아니라
|
|
278
|
+
전체 페이지인 이유다.
|
|
279
|
+
|
|
280
|
+
### 겹침
|
|
281
|
+
|
|
282
|
+
| 규칙 | 값 |
|
|
283
|
+
| ----------------------- | ----------------------------- |
|
|
284
|
+
| 모달 위에 모달 | **금지.** 예외 없다 |
|
|
285
|
+
| 모달 위에 토스트 | **띄운다** |
|
|
286
|
+
| 모달 안의 드롭다운·툴팁 | 모달의 스택 안에서 뜬다 (2층) |
|
|
287
|
+
|
|
288
|
+
**모달 위에 모달을 금지하는 것이 3번 관문을 지탱한다.** 겹칠 수 있으면 "일단 모달에 넣고 안에서
|
|
289
|
+
또 띄우면 된다"가 되어 3번이 무의미해진다.
|
|
290
|
+
|
|
291
|
+
**z는 토큰으로 올리지 않는다.** 층이 다섯이고 값이 셋(`—`·`1`·`100`·`101`)뿐이라 스케일을 만들
|
|
292
|
+
만큼이 아니다. 리터럴로 두고 각 CSS 주석이 근거를 든다 — 보더 `1px`과 같은 예외다.
|
|
293
|
+
|
|
294
|
+
`Toast`가 `Modal`보다 1 높은 것은 순서에 기대지 않기 위해서다. 둘을 같은 값으로 두면 DOM 순서로
|
|
295
|
+
갈리는데, `Modal`은 `body`로 포털하고 `Toaster`는 제자리에 그려서 **동률이면 나중에 붙는 `Modal`이
|
|
296
|
+
이긴다** — 규칙과 반대다. `Toaster`를 stacking context를 만드는 조상 안에 두면 이 값도 듣지
|
|
297
|
+
않으므로, 앱 최상위에 하나만 둔다.
|
|
298
|
+
|
|
299
|
+
## 어느 pattern을 고르나
|
|
300
|
+
|
|
301
|
+
**하려는 일에서 고른다. 생김새가 비슷하다고 고르지 않는다.** 아래 오른쪽 열은 같은 자리에서
|
|
302
|
+
잘못 고르기 쉬운 것이다.
|
|
303
|
+
|
|
304
|
+
| 하려는 것 | pattern | 여기에 쓰지 않는 것 |
|
|
305
|
+
| ----------------------------------- | ----------------------- | --------------------------------- |
|
|
306
|
+
| 화면의 틀 (사이드바 + 콘텐츠 3단) | `AppShell` | — |
|
|
307
|
+
| 설정·정보 섹션을 제목 아래로 묶기 | `FormSection` | `Card` |
|
|
308
|
+
| 정보 나열, 통계, 목록의 한 줄 | `ListRow` + 디바이더 | `Card` |
|
|
309
|
+
| 섹션 안의 요약 행 | `ListRow tone="filled"` | `Card` (흰 카드가 아니라 회색 필) |
|
|
310
|
+
| 페이지 바디 최상위의 요약 블록 | `Card` | `ListRow tone="filled"` |
|
|
311
|
+
| 고를 수 있는 개별 객체 | `Card` | — |
|
|
312
|
+
| 같은 자리에서 갈래를 갈아 끼우기 | `Tab` | `Chip` |
|
|
313
|
+
| 여러 개를 동시에 거는 토글 | `Chip` | `Tab` |
|
|
314
|
+
| 폼 옆에서 입력 결과를 그대로 비추기 | `LivePreview` | — |
|
|
315
|
+
| 페이지 전체의 액션 | `BottomBar` | — |
|
|
316
|
+
| 목록·검색 결과가 비었을 때 | `EmptyState` | — |
|
|
317
|
+
|
|
318
|
+
`Card`를 섹션 묶기에 쓰지 않는 근거는 [`decisions/0011`](https://github.com/highpixel-co/palda-design-system/blob/0504d8eaa033955d7a70414616ee999e447a0ced/docs/decisions/0011-no-over-carding.md)에 있다.
|
|
319
|
+
`Tab`과 `Chip`이 갈리는 이유는 위 §절대 규칙의 "필터는 탭이다"와 같다 — 필터는 고르는 객체가
|
|
320
|
+
아니라 갈래 전환이라 선택된 카드와 같은 문법을 쓰지 않는다.
|
|
321
|
+
|
|
322
|
+
### 탭은 하나다
|
|
323
|
+
|
|
324
|
+
**한때 둘이었다.** `Tab`(컴포넌트)과 `FilterTabs`(pattern)가 "내용이 바뀌나, 같은 내용이
|
|
325
|
+
좁혀지나"로 갈렸는데 그 구분을 없앴다 — Figma 원본에 탭 컴포넌트 세트가 하나뿐이고, 두 자리는
|
|
326
|
+
실제로 같이 쓰인다. 어느 값이 남았는지와 근거는
|
|
327
|
+
[`decisions/0023`](https://github.com/highpixel-co/palda-design-system/blob/0504d8eaa033955d7a70414616ee999e447a0ced/docs/decisions/0023-one-tab.md)에 있다.
|
|
328
|
+
|
|
329
|
+
| 무엇 | 값 |
|
|
330
|
+
| ---------- | --------------------------------------------------------- |
|
|
331
|
+
| 활성 표시 | 2px 먹색 밑줄 (`primary/default`) |
|
|
332
|
+
| 안 고른 것 | `text/primary-sub` |
|
|
333
|
+
| hover | `state/hover-pressed` 채움 |
|
|
334
|
+
| 높이 | 48px 고정 |
|
|
335
|
+
| 주는 단위 | 탭 **하나**. 줄(`role="tablist"`)과 키보드 이동은 쓰는 쪽 |
|
|
336
|
+
|
|
337
|
+
**줄을 시스템이 주지 않는다.** `Tab`은 항목 하나짜리라 `role="tablist"` 컨테이너와 화살표 키
|
|
338
|
+
이동(roving tabindex), 패널 연결(`aria-controls`)은 쓰는 쪽이 만든다. 줄 전체를 받치는 1px 선도
|
|
339
|
+
그 컨테이너가 갖는다.
|
|
340
|
+
|
|
341
|
+
**갈래를 제목으로 세우지 않는다.** 같은 종류가 여러 갈래로 나뉜 목록은 제목을 갈래 수만큼 세우는
|
|
342
|
+
대신 탭이 가른다. 서로 다른 종류의 섹션은 그대로 제목과 여백으로 가른다(위 §쓰지 않는 경우).
|
|
343
|
+
|
|
344
|
+
## 상태는 누가 갖나
|
|
345
|
+
|
|
346
|
+
**틀은 상태를 갖지 않는다. 늘 그려지고, 상태는 안에 놓인 것이 가진다.** `AppShell`과 `Card`에
|
|
347
|
+
loading·empty·error를 두지 않는 이유다. 틀에 상태를 두면 같은 빈 화면을 틀과 내용이 각자
|
|
348
|
+
그리게 되고, 어느 쪽이 이겼는지가 중첩 순서로 정해진다.
|
|
349
|
+
|
|
350
|
+
| pattern | 갖는 상태 | 맡기는 곳 |
|
|
351
|
+
| ------------- | --------------------------------- | ------------------------------------------------------------------- |
|
|
352
|
+
| `AppShell` | 없음 | `children` |
|
|
353
|
+
| `Card` | 없음 | `children` |
|
|
354
|
+
| `ListRow` | 행 하나의 선택과 상태(`Badge`) | 목록 전체의 empty·error는 `EmptyState` |
|
|
355
|
+
| `FormSection` | 섹션 전체의 실패 (`role="alert"`) | 행 하나의 실패는 그 행의 `Badge`, 필드 하나는 `TextField`의 `error` |
|
|
356
|
+
| `BottomBar` | 없음 | 진행 중 표시는 안에 놓인 `Button`의 `disabled` |
|
|
357
|
+
| `LivePreview` | ready·loading·empty·error 네 가지 | — |
|
|
358
|
+
| `EmptyState` | 비어 있음 자체 | — |
|
|
359
|
+
|
|
360
|
+
`LivePreview`가 네 상태를 다 갖는 것은 그것이 틀이 아니라 **내용을 그리는 자리**이기 때문이다.
|
|
361
|
+
|
|
362
|
+
**상태는 그것을 가진 것에 가장 가까운 자리가 든다.** 한 단계 위로 올리는 것은 그 단계 전체가 못
|
|
363
|
+
쓰게 되었을 때뿐이다. 행 하나가 실패한 것을 섹션 배너로 올리면 같은 사실을 두 번 말하게 되고,
|
|
364
|
+
면적이 큰 배너가 본문보다 강해져 정작 봐야 할 목록을 덮는다. 근거는
|
|
365
|
+
[`decisions/0024`](https://github.com/highpixel-co/palda-design-system/blob/0504d8eaa033955d7a70414616ee999e447a0ced/docs/decisions/0024-state-belongs-to-the-nearest-owner.md)에 있다.
|
|
366
|
+
|
|
367
|
+
위 표는 pattern에서 **누가 소유하는가**만 정한다. 소유가 정해진 상태를 컴포넌트 하나 안에서
|
|
368
|
+
어떻게 표현하는지는 [`decisions/0004`](https://github.com/highpixel-co/palda-design-system/blob/0504d8eaa033955d7a70414616ee999e447a0ced/docs/decisions/0004-component-state-naming.md)의 5분류를
|
|
369
|
+
따른다 — 그중 prop으로 빼는 것은 "부모가 정함"(`selected`·`error`) 하나뿐이고, 나머지는 CSS
|
|
370
|
+
의사클래스·네이티브 속성·값에서 파생·내부 state다.
|
|
371
|
+
|
|
372
|
+
## 작성할 내용
|
|
373
|
+
|
|
374
|
+
- CTA 배치와 강조 우선순위
|
|
375
|
+
- 승인 화면과 anti-pattern 링크
|
|
376
|
+
|
|
377
|
+
페이지와 section의 기본 구조, 여백과 밀도의 기준은 [`LAYOUT.md`](LAYOUT.md)가 갖는다 — §셸과
|
|
378
|
+
§토큰이다. 여기서 다시 쓰지 않는다.
|