@highpixel-co/palda-design-system 0.5.0 → 0.6.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/dist/{chunk-GPCPGABI.js → chunk-6JZPK2W5.js} +10 -2
- package/dist/{chunk-Q4UXASZH.js → chunk-QW2SD3XV.js} +13 -5
- package/dist/guide/README.md +3 -3
- package/dist/guide/catalog/patterns.yml +9 -1
- package/dist/guide/docs/ACCESSIBILITY.md +27 -1
- package/dist/guide/docs/AI_UI_DESIGNER_HANDOFF.md +6 -4
- package/dist/guide/docs/COMPONENT_POLICY.md +2 -2
- package/dist/guide/docs/CONTENT.md +1 -1
- package/dist/guide/docs/DESIGN_GRAMMAR.md +131 -29
- package/dist/guide/docs/DESIGN_PRINCIPLES.md +18 -9
- package/dist/guide/docs/FIGMA_ALIGNMENT_DELTA.md +4 -4
- package/dist/guide/docs/FIGMA_NAME_MAPPING.md +4 -4
- package/dist/guide/docs/FIGMA_WORKFLOW.md +3 -3
- package/dist/guide/docs/ICON_POLICY.md +3 -3
- package/dist/guide/docs/LAYOUT.md +11 -11
- package/dist/guide/docs/TOKEN_POLICY.md +27 -16
- package/dist/harness/metadata.json +4 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/patterns.d.ts +15 -2
- package/dist/patterns.js +2 -2
- package/dist/scripts/check-examples.mjs +9 -47
- package/dist/styles.css +11 -0
- package/dist/ui.d.ts +6 -1
- package/dist/ui.js +1 -1
- package/package.json +1 -1
|
@@ -572,7 +572,14 @@ function Switch({ className = "", disabled, size = "md", ...props }) {
|
|
|
572
572
|
|
|
573
573
|
// ../../components/src/Tab/Tab.tsx
|
|
574
574
|
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
575
|
-
function Tab({
|
|
575
|
+
function Tab({
|
|
576
|
+
children,
|
|
577
|
+
className = "",
|
|
578
|
+
icon,
|
|
579
|
+
badge,
|
|
580
|
+
selected = false,
|
|
581
|
+
...props
|
|
582
|
+
}) {
|
|
576
583
|
const classes = [
|
|
577
584
|
"palda-tab",
|
|
578
585
|
selected ? "palda-tab--selected" : "",
|
|
@@ -581,7 +588,8 @@ function Tab({ children, className = "", icon, selected = false, ...props }) {
|
|
|
581
588
|
].filter(Boolean).join(" ");
|
|
582
589
|
return /* @__PURE__ */ jsxs12("button", { ...props, "aria-selected": selected, className: classes, role: "tab", type: "button", children: [
|
|
583
590
|
icon ? /* @__PURE__ */ jsx14("span", { "aria-hidden": "true", className: "palda-tab__icon", children: icon }) : null,
|
|
584
|
-
/* @__PURE__ */ jsx14("span", { className: "palda-tab__label", children })
|
|
591
|
+
/* @__PURE__ */ jsx14("span", { className: "palda-tab__label", children }),
|
|
592
|
+
badge ? /* @__PURE__ */ jsx14("span", { className: "palda-tab__badge", children: badge }) : null
|
|
585
593
|
] });
|
|
586
594
|
}
|
|
587
595
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Button
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6JZPK2W5.js";
|
|
4
4
|
import {
|
|
5
5
|
ChevronRightIcon
|
|
6
6
|
} from "./chunk-TWYJ2UTC.js";
|
|
@@ -105,12 +105,19 @@ function FormSection({ children, description, error, footer, title }) {
|
|
|
105
105
|
|
|
106
106
|
// ../../patterns/src/ListRow/ListRow.tsx
|
|
107
107
|
import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
108
|
-
var TITLE_TYPOGRAPHY_CLASS4 =
|
|
109
|
-
|
|
108
|
+
var TITLE_TYPOGRAPHY_CLASS4 = {
|
|
109
|
+
default: "palda-text-body2-regular-semibold",
|
|
110
|
+
strong: "palda-text-body1-regular-semibold"
|
|
111
|
+
};
|
|
112
|
+
var DESCRIPTION_TYPOGRAPHY_CLASS4 = {
|
|
113
|
+
default: "palda-text-label-reading-medium",
|
|
114
|
+
strong: "palda-text-body2-reading-medium"
|
|
115
|
+
};
|
|
110
116
|
function ListRow({
|
|
111
117
|
chevron,
|
|
112
118
|
children,
|
|
113
119
|
description,
|
|
120
|
+
emphasis = "default",
|
|
114
121
|
leading,
|
|
115
122
|
loading = false,
|
|
116
123
|
onClick,
|
|
@@ -122,6 +129,7 @@ function ListRow({
|
|
|
122
129
|
const classes = [
|
|
123
130
|
"palda-list-row",
|
|
124
131
|
`palda-list-row--${tone}`,
|
|
132
|
+
`palda-list-row--${emphasis}`,
|
|
125
133
|
selected ? "palda-list-row--selected" : "",
|
|
126
134
|
loading ? "palda-list-row--loading" : ""
|
|
127
135
|
].filter(Boolean).join(" ");
|
|
@@ -135,8 +143,8 @@ function ListRow({
|
|
|
135
143
|
const content = /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
136
144
|
leading ? /* @__PURE__ */ jsx6("span", { "aria-hidden": "true", className: "palda-list-row__leading", children: leading }) : null,
|
|
137
145
|
/* @__PURE__ */ jsxs6("span", { className: "palda-list-row__copy", children: [
|
|
138
|
-
/* @__PURE__ */ jsx6("span", { className: TITLE_TYPOGRAPHY_CLASS4, children: title }),
|
|
139
|
-
description ? /* @__PURE__ */ jsx6("span", { className: `palda-list-row__description ${DESCRIPTION_TYPOGRAPHY_CLASS4}`, children: description }) : null,
|
|
146
|
+
/* @__PURE__ */ jsx6("span", { className: TITLE_TYPOGRAPHY_CLASS4[emphasis], children: title }),
|
|
147
|
+
description ? /* @__PURE__ */ jsx6("span", { className: `palda-list-row__description ${DESCRIPTION_TYPOGRAPHY_CLASS4[emphasis]}`, children: description }) : null,
|
|
140
148
|
children
|
|
141
149
|
] }),
|
|
142
150
|
trailing ? /* @__PURE__ */ jsx6("span", { className: "palda-list-row__trailing", children: trailing }) : null,
|
package/dist/guide/README.md
CHANGED
|
@@ -35,13 +35,13 @@ import { Button } from '@highpixel-co/palda-design-system/ui';
|
|
|
35
35
|
`styles.css`를 함께 불러오지 않으면 토큰이 없어 색이 나오지 않습니다.
|
|
36
36
|
|
|
37
37
|
`tokens/`, `icons/`, `components/`, `patterns/`는 저장소 내부 모듈이며 개별 배포하지 않습니다.
|
|
38
|
-
배포와 소비 설정은 [`packages/palda-design-system/README.md`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
38
|
+
배포와 소비 설정은 [`packages/palda-design-system/README.md`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/packages/palda-design-system/README.md)를
|
|
39
39
|
따릅니다.
|
|
40
40
|
|
|
41
|
-
- 디자이너: [`docs/REPOSITORY_GUIDE.md`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
41
|
+
- 디자이너: [`docs/REPOSITORY_GUIDE.md`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/REPOSITORY_GUIDE.md)부터 읽습니다.
|
|
42
42
|
- 디자인 원칙: [`docs/DESIGN_PRINCIPLES.md`](docs/DESIGN_PRINCIPLES.md)
|
|
43
43
|
- Figma 운영: [`docs/FIGMA_WORKFLOW.md`](docs/FIGMA_WORKFLOW.md)
|
|
44
|
-
- 기여 절차: [`docs/CONTRIBUTING.md`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
44
|
+
- 기여 절차: [`docs/CONTRIBUTING.md`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/CONTRIBUTING.md)
|
|
45
45
|
|
|
46
46
|
현재 토큰과 컴포넌트 값은 구조를 보여주기 위한 예시이며, 디자이너 검토 후 확정해야 합니다.
|
|
47
47
|
|
|
@@ -58,6 +58,10 @@ list-row:
|
|
|
58
58
|
- 섹션 안에서 tone="filled"로 값을 강조해 담는 요약 행 (옅은 회색 필, 보더 없음).
|
|
59
59
|
페이지 바디 최상위 블록은 Card다 — 안쪽 여백은 둘 다 16으로 같고 라운드가 갈린다
|
|
60
60
|
- onClick을 주면 누를 수 있는 행(선택 상태 포함)
|
|
61
|
+
- 그 목록이 화면의 본문이면 emphasis="strong"으로 행을 한 칸 올린다
|
|
62
|
+
emphasis:
|
|
63
|
+
default: 제목 body2(14) + 설명 label(12). 곁·요약·참조 나열이다. 기본값이다
|
|
64
|
+
strong: 제목 body1(16) + 설명 body2(14). 선언서의 본문 문장이 가리키는 목록 하나에만 쓴다
|
|
61
65
|
avoid_for:
|
|
62
66
|
- 진행률·CTA·취소를 함께 든 작업 행. leading이 16px 아이콘 고정이라 썸네일이 들어가지 않고,
|
|
63
67
|
세로 여백과 가운데 정렬이 제목·설명 두 줄 기준이라 여러 단 내용이 붙어 보인다.
|
|
@@ -68,7 +72,11 @@ list-row:
|
|
|
68
72
|
선택은 보더가 아니라 색이다. onClick이 있으면 chevron이 기본으로 붙고, 오른쪽에 컨트롤이 오면
|
|
69
73
|
chevron={false}로 끈다. 목록 위에서 갈래를 가르는 것은 Tab이다(0023).
|
|
70
74
|
목록 전체의 empty/error는 EmptyState가 맡는다(docs/DESIGN_GRAMMAR.md의 §상태는 누가 갖나).
|
|
71
|
-
뼈대 높이는 텍스트 스타일의 font-size를
|
|
75
|
+
뼈대 높이는 텍스트 스타일의 font-size를 따르고 emphasis를 따라 같이 올라간다.
|
|
76
|
+
emphasis는 크기를 고르는 자리가 아니라 이 목록이 화면의 본문인지를 밝히는 자리다 — 판정은
|
|
77
|
+
"선언서의 본문 문장이 가리키는 목록인가" 하나이고 한 화면에 strong은 하나다(0034).
|
|
78
|
+
제목만 올리지 않는다. 16 → 12로 두 칸을 건너뛰면 설명이 각주가 된다.
|
|
79
|
+
tone="filled"와 겹쳐 쓰지 않는다 — 곁이 본문 크기를 갖는 일이다(0032).
|
|
72
80
|
|
|
73
81
|
form-section:
|
|
74
82
|
status: draft
|
|
@@ -2,9 +2,35 @@
|
|
|
2
2
|
|
|
3
3
|
**모든 컴포넌트와 화면이 예외 없이 지켜야 하는 접근성 최소선이다.**
|
|
4
4
|
|
|
5
|
-
- 텍스트와 UI의 색상 대비를 확인한다.
|
|
5
|
+
- 텍스트와 UI의 색상 대비를 확인한다. 수치는 아래 §대비가 갖는다.
|
|
6
6
|
- 모든 조작 요소에 visible focus를 제공한다.
|
|
7
7
|
- icon-only button에는 접근 가능한 이름을 제공한다.
|
|
8
8
|
- 색상만으로 상태를 전달하지 않는다.
|
|
9
9
|
- Form error는 관련 입력과 연결한다.
|
|
10
10
|
- motion 감소 설정을 존중한다.
|
|
11
|
+
|
|
12
|
+
## 대비
|
|
13
|
+
|
|
14
|
+
**읽어야 하는 글자는 아래를 넘는다.** 넘지 못하면 시각 표현이 아니라 위반이다 —
|
|
15
|
+
[`DESIGN_PRINCIPLES.md`](DESIGN_PRINCIPLES.md) §7의 "글자가 배경에 묻힌다 → 읽히는 쪽이 이긴다"에
|
|
16
|
+
수치를 준 것이다.
|
|
17
|
+
|
|
18
|
+
| 무엇 | 하한 |
|
|
19
|
+
| ------------------------------------------------- | ------- |
|
|
20
|
+
| 본문 글자 (18.66px 미만, 또는 24px 미만 non-bold) | `4.5:1` |
|
|
21
|
+
| 큰 글자 (18.66px 이상 bold, 또는 24px 이상) | `3:1` |
|
|
22
|
+
| 조작 요소의 경계와 상태 표시 | `3:1` |
|
|
23
|
+
|
|
24
|
+
흰 배경(`surface/base`) 위 실측이다.
|
|
25
|
+
|
|
26
|
+
| 토큰 | 값 | 대비 |
|
|
27
|
+
| ------------------ | ---------------------- | ------------ |
|
|
28
|
+
| `text/primary` | `gray-900` `#323236` | `12.76:1` |
|
|
29
|
+
| `text/accent` | `purple-600` `#4345e5` | `6.52:1` |
|
|
30
|
+
| `text/primary-sub` | `gray-500` `#86868d` | **`3.62:1`** |
|
|
31
|
+
|
|
32
|
+
**`text/primary-sub`는 14px 본문에서 하한을 넘지 못한다.** 24px 이상이거나 18.66px 이상 bold인
|
|
33
|
+
자리에만 쓴다. 그보다 작은 글자에 쓰면 읽히지 않는다.
|
|
34
|
+
|
|
35
|
+
**아직 정리되지 않은 자리가 있다.** `ListRow`의 `description`이 `label`(12px)에
|
|
36
|
+
`text/primary-sub`라 같은 미달이다. 토큰 값을 올릴지 그 자리만 바꿀지는 결정 대기다.
|
|
@@ -50,8 +50,10 @@ Palda가 목표로 하는 것은 단순히 컴포넌트를 많이 보유하는
|
|
|
50
50
|
### 2. 정보 위계와 Primary action 배치 — 확정됨
|
|
51
51
|
|
|
52
52
|
**타이포 위계**는 [`TOKEN_POLICY.md`](TOKEN_POLICY.md) §타이포가 갖는다 — 페이지 `headline`(24)
|
|
53
|
-
→ 섹션·카드 `body1`(16) → 행 `body2`(14) → 보조 `label`(12). 화면이 고르는 것은 페이지
|
|
54
|
-
|
|
53
|
+
→ 섹션·카드 `body1`(16) → 행 `body2`(14) → 보조 `label`(12). 화면이 고르는 것은 페이지 제목과
|
|
54
|
+
**본문 목록 여부** 둘이고 나머지는 pattern이 이미 갖고 있다. 선언서의 본문 문장이 가리키는
|
|
55
|
+
목록은 `ListRow`의 `emphasis="strong"`으로 제목 `body1`(16) + 설명 `body2`(14)가 된다
|
|
56
|
+
([`decisions/0034`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0034-the-body-list-lifts-one-step.md)).
|
|
55
57
|
|
|
56
58
|
**주 액션의 자리**는 [`DESIGN_GRAMMAR.md`](DESIGN_GRAMMAR.md) §주 액션을 어디 두나가 갖는다 —
|
|
57
59
|
페이지 헤더 우측과 `BottomBar` 둘 다 맞는 자리이고, 읽다가 가끔 누르는 화면은 위, 채워 넣고
|
|
@@ -83,7 +85,7 @@ AI에게 가장 효과적인 기준은 긴 설명보다 실제 정답 화면이
|
|
|
83
85
|
- 데스크톱과 모바일에서 달라지는 부분
|
|
84
86
|
- loading·empty·error 처리 방식
|
|
85
87
|
|
|
86
|
-
산출물은 [`../examples/approved/`](https://github.com/highpixel-co/palda-design-system/tree/
|
|
88
|
+
산출물은 [`../examples/approved/`](https://github.com/highpixel-co/palda-design-system/tree/ad23980481cd81dcf09a1044504d2295f0e4a0f3/examples/approved)에 보관한다.
|
|
87
89
|
|
|
88
90
|
**완료 기준:** AI가 새 화면을 만들 때 가장 가까운 승인 화면을 골라 구조와 판단 기준을 재사용할
|
|
89
91
|
수 있다.
|
|
@@ -101,7 +103,7 @@ AI가 자주 만들 수 있는 잘못된 화면도 시각적으로 남긴다.
|
|
|
101
103
|
- 모바일에서 버튼이나 긴 한글이 잘리는 화면
|
|
102
104
|
|
|
103
105
|
각 사례에는 문제가 되는 이유와 올바른 대안을 함께 기록한다. 산출물은
|
|
104
|
-
[`../examples/anti-patterns/`](https://github.com/highpixel-co/palda-design-system/tree/
|
|
106
|
+
[`../examples/anti-patterns/`](https://github.com/highpixel-co/palda-design-system/tree/ad23980481cd81dcf09a1044504d2295f0e4a0f3/examples/anti-patterns)에 보관한다.
|
|
105
107
|
|
|
106
108
|
**완료 기준:** AI가 동일한 실수를 반복하지 않고, 잘못된 구현을 구체적인 사례와 비교해 수정할 수
|
|
107
109
|
있다.
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
적는다. prop 이름과 기본값은 타입이 원본이므로 문서로 옮겨 적지 않는다.
|
|
16
16
|
|
|
17
17
|
**새 컴포넌트는 코드보다 먼저 property 목록과 상태 배치표를 낸다.** 상태는
|
|
18
|
-
[`decisions/0004`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
18
|
+
[`decisions/0004`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0004-component-state-naming.md)의 다섯 종류(상호작용 · 네이티브 ·
|
|
19
19
|
값에서 파생 · 컴포넌트 소유 · 부모가 정함)에 배치하고, **prop으로 빼도 되는 것은 "부모가 정함"
|
|
20
20
|
하나뿐이다.** `hovered`·`focused`·`filled` 같은 prop은 만들지 않는다. pattern에서 어느 것이
|
|
21
21
|
상태를 소유하는지는 [`DESIGN_GRAMMAR.md`](DESIGN_GRAMMAR.md)의 §상태는 누가 갖나에 있다.
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
([`DESIGN_GRAMMAR.md`](DESIGN_GRAMMAR.md) §자리는 시스템이 정하지 않는다). 컴포넌트 시안은 셸이 없어 이 검사를 받지 않는다.
|
|
45
45
|
- **렌더해서 흐리게 본다.** 시안을 실제로 그린 뒤, 스크린샷을 흐리게 봤을 때 가장 먼저 보이는
|
|
46
46
|
것이 본문이어야 한다. 상태 배너·경고처럼 면적이 큰 것이 본문보다 먼저 보이면 그것을 뺀다
|
|
47
|
-
([`decisions/0024`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
47
|
+
([`decisions/0024`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0024-state-belongs-to-the-nearest-owner.md)). 검사가 읽지
|
|
48
48
|
못하는 자리라 이 확인은 사람이 한다.
|
|
49
49
|
- **시안은 자기 클래스만 정의한다.** 시스템 클래스(`.palda-*`)를 셀렉터에 쓰지 않는다 — 붙이는
|
|
50
50
|
것은 마크업이 하고, 늘리거나 자리를 잡는 것은 감싸는 자리가 한다. pattern은 `className`을 받지
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
`Toast`다.
|
|
61
61
|
|
|
62
62
|
**진행 중은 글자가 아니라 `disabled`로 표현한다.** `Button`에 로딩 전용 prop이 없는 것이
|
|
63
|
-
그래서다([`components/src/Button/Button.tsx`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
63
|
+
그래서다([`components/src/Button/Button.tsx`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/components/src/Button/Button.tsx)).
|
|
64
64
|
|
|
65
65
|
### "~기"로 끝난다
|
|
66
66
|
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
| 무엇으로 조립하나? | 아래 §어느 pattern을 고르나 |
|
|
21
21
|
| 이 자리에 이 패턴이 맞나? | [`catalog/patterns.yml`](../catalog/patterns.yml)의 `use_for`·`avoid_for` |
|
|
22
22
|
| 이게 이 화면 것인가? | 아래 §곁을 어디 두나 — 박스 질문보다 **먼저** 묻는다 |
|
|
23
|
+
| 무엇을 크게 그리나? | 아래 §층이 무게를 정한다 — 그리기 전에 기능 위계부터 |
|
|
24
|
+
| 값이 나쁠 때는? | 아래 §값이 나쁘면 잠깐 올라온다 |
|
|
23
25
|
| 박스로 감싸나? | 아래 §판단 한 줄 → §쓰는 경우 |
|
|
24
26
|
| 면인가 행인가? | [`TOKEN_POLICY.md`](TOKEN_POLICY.md) §간격 마지막 줄 + §라운드 표 |
|
|
25
27
|
| 이 카드는 눌리나? | 아래 §세 번째 질문 — 고르는 카드 / 담는 카드 |
|
|
@@ -31,7 +33,7 @@
|
|
|
31
33
|
| 좁아지면? | [`LAYOUT.md`](LAYOUT.md) §좁아질 때 |
|
|
32
34
|
|
|
33
35
|
**ADR은 여기서 읽지 않는다.** 근거 보관소지 지시서가 아니고, 대체된 값이 그대로 남아 있다.
|
|
34
|
-
기준은 [`AGENTS.md`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
36
|
+
기준은 [`AGENTS.md`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/AGENTS.md)의 §ADR은 화면 만들 때 읽지 않는다에 있다.
|
|
35
37
|
|
|
36
38
|
### 아직 답할 문서가 없는 질문
|
|
37
39
|
|
|
@@ -39,7 +41,10 @@
|
|
|
39
41
|
|
|
40
42
|
**지금은 비어 있다.** 마지막으로 남아 있던 제목·본문·보조 정보의 위계는 2026-09-02에
|
|
41
43
|
[`TOKEN_POLICY.md`](TOKEN_POLICY.md) §타이포가 받았다 — 페이지 `headline`(24) → 섹션·카드
|
|
42
|
-
`body1`(16) → 행 `body2`(14) → 보조 `label`(12)이다.
|
|
44
|
+
`body1`(16) → 행 `body2`(14) → 보조 `label`(12)이다. 2026-09-03에 행이 두 칸으로 갈렸다.
|
|
45
|
+
**화면의 본문인 목록은 제목 `body1`(16) + 설명 `body2`(14)로 한 칸 올라간다**
|
|
46
|
+
([`decisions/0034`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0034-the-body-list-lifts-one-step.md)) — `ListRow`의 `emphasis`가
|
|
47
|
+
그것이고, 판정은 "선언서의 본문 문장이 가리키는 목록인가" 하나다.
|
|
43
48
|
|
|
44
49
|
### 주 액션을 어디 두나
|
|
45
50
|
|
|
@@ -51,10 +56,15 @@
|
|
|
51
56
|
같은 액션을 두 번 두지 않는다. 근거는
|
|
52
57
|
[`DESIGN_PRINCIPLES.md`](DESIGN_PRINCIPLES.md) §4의 주 액션의 자리에 있다.
|
|
53
58
|
|
|
59
|
+
**0개도 된다.** 목록을 훑고 행을 눌러 들어가는 화면은 행이 곧 액션이라 세울 것이 없다. 선언서에
|
|
60
|
+
`없음`이라 적는다 ([`decisions/0033`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0033-a-screen-may-have-no-primary-action.md)).
|
|
61
|
+
**자리를 채우려고 다른 층의 기능을 끌어올리지 않는다** — 스토어 알림톡 목록이 그렇게 결제
|
|
62
|
+
기능(3층)을 헤더 우측(1층)으로 올렸다가 되돌렸다.
|
|
63
|
+
|
|
54
64
|
## 곁을 어디 두나
|
|
55
65
|
|
|
56
66
|
**박스를 두를지 묻기 전에 이것부터 묻는다.** 같은 블록이라도 이 화면 것이냐 아니냐로 규칙이
|
|
57
|
-
갈린다. 근거는 [`decisions/0022`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
67
|
+
갈린다. 근거는 [`decisions/0022`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0022-screens-declare-their-body.md)에 있다.
|
|
58
68
|
|
|
59
69
|
> 이것은 **이 화면이 선언한 본문**인가?
|
|
60
70
|
|
|
@@ -73,16 +83,103 @@
|
|
|
73
83
|
| 무게 | 자리를 얼마나 먹고 얼마나 강조되나 | 내린다 |
|
|
74
84
|
| 구분 | 다른 종류로 읽히나 | 낸다 |
|
|
75
85
|
|
|
76
|
-
### 곁의 규칙
|
|
86
|
+
### 곁의 규칙 넷
|
|
77
87
|
|
|
78
|
-
1.
|
|
88
|
+
1. **기능 하나에 블록 하나다.** 기능이 다르면 블록도 다르다. 묶는 기준은 기능이지 층이
|
|
89
|
+
아니다 — 발송 채널과 잔여 알림톡은 둘 다 곁이지만 다른 기능이라 블록이 나뉜다. (구분)
|
|
79
90
|
2. **본문이 쓰는 pattern을 쓰지 않는다.** 본문이 행 나열이면 곁은 행이 아니다. (구분)
|
|
80
91
|
3. **강조 예산을 쓰지 않는다.** `primary`·`accent` 채움을 주지 않는다.
|
|
81
92
|
[`DESIGN_PRINCIPLES.md`](DESIGN_PRINCIPLES.md) §4의 "강한 강조는 하나"는 본문이 갖는다. (무게)
|
|
93
|
+
4. **stroke 없이 shade만.** `surface/raised` 필에 `radius/container`, **보더는 주지 않는다.**
|
|
94
|
+
(구분)
|
|
95
|
+
|
|
96
|
+
**면이 층을 가른다.** 본문은 흰 캔버스 위에서 디바이더로 갈리고 곁은 회색 면에 얹힌다. 글자는
|
|
97
|
+
양쪽 다 `text/primary`라 대비를 낮추지 않고도 층이 갈린다 — 규칙 1이 "세로로 한 줄이다"였을 때는
|
|
98
|
+
곁이 쓸 수 있는 것이 텍스트와 `Link`뿐이라 색 말고 가를 것이 없었다. 근거는
|
|
99
|
+
[`decisions/0032`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0032-asides-are-one-filled-block.md)에 있다.
|
|
100
|
+
|
|
101
|
+
| 자리 | 면 | 경계 | 글자 | 대비 |
|
|
102
|
+
| ---- | ---------------- | -------- | -------------- | --------- |
|
|
103
|
+
| 본문 | `surface/base` | 디바이더 | `text/primary` | `12.76:1` |
|
|
104
|
+
| 곁 | `surface/raised` | **없음** | `text/primary` | `11.72:1` |
|
|
105
|
+
|
|
106
|
+
**`ListRow`의 `tone="filled"`를 쓰지 않는다.** 같은 면이지만 본문 pattern이라 규칙 2에 걸린다.
|
|
107
|
+
곁 블록은 화면이 자기 클래스로 만든다.
|
|
108
|
+
|
|
109
|
+
**무게는 블록 개수가 아니라 줄 수가 지킨다.** 각 블록은 한두 줄을 넘지 않는다. 넘으면 그것은
|
|
110
|
+
곁이 아니라 본문이거나 다른 화면으로 가야 할 것이다.
|
|
111
|
+
|
|
112
|
+
### 층이 무게를 정한다
|
|
113
|
+
|
|
114
|
+
**규칙 셋은 "본문보다 가볍게"만 말하고 얼마나 가볍게는 말하지 않는다.** 그리기 전에 **기능
|
|
115
|
+
위계**를 정한다 — 이 페이지가 하는 일에 얼마나 직접 기여하는가. 근거는
|
|
116
|
+
[`decisions/0031`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0031-function-hierarchy-before-drawing.md)에 있다.
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
1. 페이지의 기능·텍스트를 **기능 단위로** 묶는다
|
|
120
|
+
2. 각 그룹이 페이지 목적에 얼마나 직접 기여하는지로 층을 정한다 ← 여기까지가 위계
|
|
121
|
+
3. 층이 UI 배정을 정한다 — pattern · 자리 · 면적 · 채움 · 타이포
|
|
122
|
+
4. 배정된 값이 읽히는지 확인한다 ← 위계와 무관한 하한
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
판정은 화면이 선언한 본문(0022)을 기준으로 한다.
|
|
126
|
+
|
|
127
|
+
| 층 | 판정 질문 | pattern | 나가는 자리 |
|
|
128
|
+
| ---------------------- | ------------------------------------- | -------------------- | ---------------------- |
|
|
129
|
+
| **1 · 이 페이지의 일** | 본문 문장이 말하는 그것인가? | 목록·폼·카드 그리드 | 주 액션 `primary` 하나 |
|
|
130
|
+
| **2 · 일의 전제** | 아래 셋 중 하나라도 예인가? | 상태 바 또는 곁 블록 | **`outline` Button** |
|
|
131
|
+
| **3 · 다른 곳의 일** | 참조하거나 그리로 나가는 문일 뿐인가? | 곁 블록 | **`Link`** |
|
|
132
|
+
|
|
133
|
+
**2층과 3층은 셋으로 가른다.** "여기서 하느냐"만 물으면 애매한 자리가 남아서다.
|
|
134
|
+
|
|
135
|
+
| 기준 | 묻는 것 | 발송 채널 | 잔여 알림톡 |
|
|
136
|
+
| ----------- | -------------------------------------------- | ------------------------ | ------------------- |
|
|
137
|
+
| **1. 소유** | 이 기능의 설정 화면이 이 페이지 아래에 있나? | 예 — `/alimtalk/channel` | 아니오 — `/payment` |
|
|
138
|
+
| **2. 변형** | 값이 바뀌면 본문의 **형태**가 바뀌나? | 예 — 템플릿 고르는 법 | 아니오 |
|
|
139
|
+
| **3. 성립** | 없으면 본문이 아예 안 뜨나? | 예 — `EmptyState` | 아니오 |
|
|
140
|
+
|
|
141
|
+
**하나라도 예면 2층, 셋 다 아니면 3층이다.** "잔액이 조건을 잠그지 않나"는 이 축의 물음이
|
|
142
|
+
아니다 — 잠그는 것은 **나쁜 값일 때**의 일이고 아래 §값이 나쁘면 잠깐 올라온다가 받는다.
|
|
143
|
+
|
|
144
|
+
**2층과 3층은 나가는 자리의 모양으로 갈린다.** 형태를 가진 버튼이 텍스트 링크보다 위다.
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
primary 채움 > outline 버튼 > subtle 버튼 > 텍스트 링크
|
|
148
|
+
1층 2층 3층
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
곁은 `primary`·`accent` 채움을 쓰지 못하므로 2층이 쓸 수 있는 가장 높은 칸이 `outline`이다.
|
|
152
|
+
**버튼의 보더는 곁 규칙 4와 부딪히지 않는다** — 그 규칙은 블록의 경계에 대한 것이고 버튼은 블록
|
|
153
|
+
안의 컨트롤이다. 2층이 셋을 넘으면 곁이 본문과 겨루기 시작하므로 한둘로 둔다.
|
|
154
|
+
|
|
155
|
+
**화면이 고르는 것은 층뿐이다.** "얼마나 눈에 띄게 그릴까"를 그리면서 판단하지 않는다. 안 보이면
|
|
156
|
+
색을 올리고 튀면 내리는 식으로는 화면마다 값이 달라진다.
|
|
157
|
+
|
|
158
|
+
**대비는 위계가 아니다.** 3층도 `text/primary`(12.76:1)를 쓴다 — `text/primary-sub`는 3.62:1로
|
|
159
|
+
14px 본문의 하한에 미달한다([`ACCESSIBILITY.md`](ACCESSIBILITY.md) §대비). 층 차이는 색이 아니라
|
|
160
|
+
pattern·자리·면적·채움이 낸다.
|
|
161
|
+
|
|
162
|
+
### 값이 나쁘면 잠깐 올라온다
|
|
163
|
+
|
|
164
|
+
곁에 실리는 정보는 시점에 따라 값이 다르다. **나쁜 값의 기준은 하나다 — 사용자가 무언가 해야만
|
|
165
|
+
정상으로 돌아가는가.** 잔액 `0개`, 구독 `만료`, 연동 `실패`가 그것이다.
|
|
166
|
+
|
|
167
|
+
| 값 | 무엇으로 |
|
|
168
|
+
| ------- | -------------------------------------------- |
|
|
169
|
+
| 좋은 값 | 자기 층의 무게 그대로. 대개 곁 한 줄 |
|
|
170
|
+
| 나쁜 값 | `Alert`. 무엇을 해야 하는지 액션을 함께 둔다 |
|
|
171
|
+
|
|
172
|
+
**올라온 것은 화면에 하나다.** 나쁜 값이 둘이면 더 먼저 손대야 하는 것만 올린다. 근거는
|
|
173
|
+
[`decisions/0030`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0030-asides-rise-only-on-bad-values.md)에 있다.
|
|
174
|
+
|
|
175
|
+
> 위계가 자리와 무게를 정하고, 상태는 그 자리에서 잠깐 올라올 뿐 위계를 바꾸지 않는다.
|
|
176
|
+
|
|
177
|
+
"잔액이 0이면 발송이 멈추니 항상 무겁게"는 틀렸다. 잔액이 0이 됐다고 잔액 관리가 이 페이지의
|
|
178
|
+
주요 기능이 되지 않는다.
|
|
82
179
|
|
|
83
180
|
### 자리는 시스템이 정하지 않는다
|
|
84
181
|
|
|
85
|
-
화면이 고르고 선언서에 밝힌다. 규칙
|
|
182
|
+
화면이 고르고 선언서에 밝힌다. 규칙 넷을 지키면 위든 아래든 무게는 이미 내려가 있고, 구분은
|
|
86
183
|
자리가 아니라 문법이 낸다.
|
|
87
184
|
|
|
88
185
|
**곁은 본문보다 먼저 올 수 있다. 넷째 규칙은 없다.** 순서를 규칙으로 세우면 "무게를 내리면 자리는
|
|
@@ -126,7 +223,7 @@ pattern을 쓰고 있거나, 강조를 갖고 있다.
|
|
|
126
223
|
| 섹션 안 | 행·요소 | `inset/md`(16) | `control`(10) | `ListRow tone="filled"` |
|
|
127
224
|
|
|
128
225
|
**층을 가르는 것은 라운드다.** 안쪽 여백은 둘 다 16이라 층을 가르지 못한다 — 행의 상하 여백을
|
|
129
|
-
16으로 올리면서 같아졌다([`decisions/0019`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
226
|
+
16으로 올리면서 같아졌다([`decisions/0019`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0019-list-row-vertical-inset.md)). 값의
|
|
130
227
|
근거는 [`TOKEN_POLICY.md`](TOKEN_POLICY.md) §라운드 표이고, 여백은 같은 문서 §간격에 있다.
|
|
131
228
|
|
|
132
229
|
**첫 질문은 상호작용만 가르고 층위는 가르지 않는다.** 고르지도 열리지도 떠 있지도 않은 요약
|
|
@@ -183,7 +280,7 @@ pattern을 쓰고 있거나, 강조를 갖고 있다.
|
|
|
183
280
|
|
|
184
281
|
**채운 면은 `Card`든 `ListRow`든 같은 회색이다.** `tone="filled"`가 두 곳에서 같은 뜻이고 같은
|
|
185
282
|
값이며, 갈리는 것은 색이 아니라 층이다 — 여백과 라운드가 다르다
|
|
186
|
-
([`decisions/0018`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
283
|
+
([`decisions/0018`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0018-summary-row-shares-the-filled-surface.md)).
|
|
187
284
|
|
|
188
285
|
### 쓰지 않는 경우 — 기본값
|
|
189
286
|
|
|
@@ -232,13 +329,13 @@ pattern을 쓰고 있거나, 강조를 갖고 있다.
|
|
|
232
329
|
| `AppShell` | — | — | 사이드바 + 콘텐츠 틀 |
|
|
233
330
|
|
|
234
331
|
`Card`를 섹션 묶기에 쓰지 않는다. 섹션은 `FormSection`이다. 근거는
|
|
235
|
-
[`decisions/0011`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
332
|
+
[`decisions/0011`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0011-no-over-carding.md)에 있다.
|
|
236
333
|
|
|
237
334
|
## 띄우나 마나
|
|
238
335
|
|
|
239
336
|
**깊이와 끊김은 다른 축이다.** 위 §두 번째 질문은 페이지 **안쪽** 층(면인가 행인가)을 가르고,
|
|
240
337
|
이 절은 페이지 **위로** 뜨는 층을 가른다. 근거는
|
|
241
|
-
[`decisions/0020`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
338
|
+
[`decisions/0020`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0020-modal-depth-and-scrim.md)에 있다.
|
|
242
339
|
|
|
243
340
|
### 층
|
|
244
341
|
|
|
@@ -260,7 +357,7 @@ pattern을 쓰고 있거나, 강조를 갖고 있다.
|
|
|
260
357
|
|
|
261
358
|
**딤은 `overlay/dim`(70% 검정)이다.** 시안에서 온 값은 아니지만 2026-08-31에 이대로 확정했다.
|
|
262
359
|
옅게 잡으면 두 가지가 같이 무너진다 — 4층을 3층과 가르는 시각 신호가 딤뿐이고, **모달 카드가
|
|
263
|
-
흰색인 것**([`decisions/0013`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
360
|
+
흰색인 것**([`decisions/0013`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0013-surface-base-is-white.md))**이 짙은 딤 위에서만
|
|
264
361
|
성립한다.** 카드와 딤 처리된 뒤 캔버스의 대비가 70%에서 8.5:1인데 30%에서는 2.1:1로 떨어져,
|
|
265
362
|
카드가 떠 있는 것으로 읽히지 않는다. 뒤 본문 대비도 70%에서 2.25:1이라 내용을 읽을 수 없고,
|
|
266
363
|
그래서 아래 1번 관문의 기준선이 흐려지지 않는다.
|
|
@@ -301,21 +398,26 @@ pattern을 쓰고 있거나, 강조를 갖고 있다.
|
|
|
301
398
|
**하려는 일에서 고른다. 생김새가 비슷하다고 고르지 않는다.** 아래 오른쪽 열은 같은 자리에서
|
|
302
399
|
잘못 고르기 쉬운 것이다.
|
|
303
400
|
|
|
304
|
-
| 하려는 것 | pattern
|
|
305
|
-
| ----------------------------------- |
|
|
306
|
-
| 화면의 틀 (사이드바 + 콘텐츠 3단) | `AppShell`
|
|
307
|
-
| 설정·정보 섹션을 제목 아래로 묶기 | `FormSection`
|
|
308
|
-
| 정보 나열, 통계, 목록의 한 줄 | `ListRow` + 디바이더
|
|
309
|
-
|
|
|
310
|
-
|
|
|
311
|
-
|
|
|
312
|
-
|
|
|
313
|
-
|
|
|
314
|
-
|
|
|
315
|
-
|
|
|
316
|
-
|
|
|
317
|
-
|
|
318
|
-
|
|
401
|
+
| 하려는 것 | pattern | 여기에 쓰지 않는 것 |
|
|
402
|
+
| ----------------------------------- | --------------------------- | --------------------------------- |
|
|
403
|
+
| 화면의 틀 (사이드바 + 콘텐츠 3단) | `AppShell` | — |
|
|
404
|
+
| 설정·정보 섹션을 제목 아래로 묶기 | `FormSection` | `Card` |
|
|
405
|
+
| 정보 나열, 통계, 목록의 한 줄 | `ListRow` + 디바이더 | `Card` |
|
|
406
|
+
| 그 목록이 화면의 본문일 때 | `ListRow emphasis="strong"` | 행마다 크기를 따로 고르는 것 |
|
|
407
|
+
| 섹션 안의 요약 행 | `ListRow tone="filled"` | `Card` (흰 카드가 아니라 회색 필) |
|
|
408
|
+
| 페이지 바디 최상위의 요약 블록 | `Card` | `ListRow tone="filled"` |
|
|
409
|
+
| 고를 수 있는 개별 객체 | `Card` | — |
|
|
410
|
+
| 같은 자리에서 갈래를 갈아 끼우기 | `Tab` | `Chip` |
|
|
411
|
+
| 여러 개를 동시에 거는 토글 | `Chip` | `Tab` |
|
|
412
|
+
| 폼 옆에서 입력 결과를 그대로 비추기 | `LivePreview` | — |
|
|
413
|
+
| 페이지 전체의 액션 | `BottomBar` | — |
|
|
414
|
+
| 목록·검색 결과가 비었을 때 | `EmptyState` | — |
|
|
415
|
+
|
|
416
|
+
**`emphasis="strong"`과 `tone="filled"`를 겹쳐 쓰지 않는다.** 곁의 요약 행이 본문 크기를 갖는
|
|
417
|
+
일이고 [`0032`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0032-asides-are-one-filled-block.md)와 어긋난다. 한 화면에 `strong`
|
|
418
|
+
목록은 하나다 ([`0034`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0034-the-body-list-lifts-one-step.md)).
|
|
419
|
+
|
|
420
|
+
`Card`를 섹션 묶기에 쓰지 않는 근거는 [`decisions/0011`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0011-no-over-carding.md)에 있다.
|
|
319
421
|
`Tab`과 `Chip`이 갈리는 이유는 위 §절대 규칙의 "필터는 탭이다"와 같다 — 필터는 고르는 객체가
|
|
320
422
|
아니라 갈래 전환이라 선택된 카드와 같은 문법을 쓰지 않는다.
|
|
321
423
|
|
|
@@ -324,7 +426,7 @@ pattern을 쓰고 있거나, 강조를 갖고 있다.
|
|
|
324
426
|
**한때 둘이었다.** `Tab`(컴포넌트)과 `FilterTabs`(pattern)가 "내용이 바뀌나, 같은 내용이
|
|
325
427
|
좁혀지나"로 갈렸는데 그 구분을 없앴다 — Figma 원본에 탭 컴포넌트 세트가 하나뿐이고, 두 자리는
|
|
326
428
|
실제로 같이 쓰인다. 어느 값이 남았는지와 근거는
|
|
327
|
-
[`decisions/0023`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
429
|
+
[`decisions/0023`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0023-one-tab.md)에 있다.
|
|
328
430
|
|
|
329
431
|
| 무엇 | 값 |
|
|
330
432
|
| ---------- | --------------------------------------------------------- |
|
|
@@ -362,10 +464,10 @@ loading·empty·error를 두지 않는 이유다. 틀에 상태를 두면 같은
|
|
|
362
464
|
**상태는 그것을 가진 것에 가장 가까운 자리가 든다.** 한 단계 위로 올리는 것은 그 단계 전체가 못
|
|
363
465
|
쓰게 되었을 때뿐이다. 행 하나가 실패한 것을 섹션 배너로 올리면 같은 사실을 두 번 말하게 되고,
|
|
364
466
|
면적이 큰 배너가 본문보다 강해져 정작 봐야 할 목록을 덮는다. 근거는
|
|
365
|
-
[`decisions/0024`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
467
|
+
[`decisions/0024`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0024-state-belongs-to-the-nearest-owner.md)에 있다.
|
|
366
468
|
|
|
367
469
|
위 표는 pattern에서 **누가 소유하는가**만 정한다. 소유가 정해진 상태를 컴포넌트 하나 안에서
|
|
368
|
-
어떻게 표현하는지는 [`decisions/0004`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
470
|
+
어떻게 표현하는지는 [`decisions/0004`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0004-component-state-naming.md)의 5분류를
|
|
369
471
|
따른다 — 그중 prop으로 빼는 것은 "부모가 정함"(`selected`·`error`) 하나뿐이고, 나머지는 CSS
|
|
370
472
|
의사클래스·네이티브 속성·값에서 파생·내부 state다.
|
|
371
473
|
|
|
@@ -70,12 +70,12 @@
|
|
|
70
70
|
(`Alert` · `FormSection`의 `error`)는 폭이 본문과 같고 면을 가져서 본문과 무게를 겨룬다. 한
|
|
71
71
|
화면에 하나이고, 본문보다 먼저 보이면 뺀다. 어느 자리가 상태를 드는지는
|
|
72
72
|
[`DESIGN_GRAMMAR.md`](DESIGN_GRAMMAR.md) §상태는 누가 갖나와
|
|
73
|
-
[`decisions/0024`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
73
|
+
[`decisions/0024`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0024-state-belongs-to-the-nearest-owner.md)에 있다.
|
|
74
74
|
|
|
75
75
|
**곁은 강조 예산을 쓰지 않는다.** 이 화면이 선언한 본문에 들지 않은 것 — 다른 기능의 요약이나
|
|
76
76
|
그리로 가는 입구 — 에는 `primary`·`accent` 채움을 주지 않는다. 강조 하나는 본문이 갖는다.
|
|
77
77
|
곁이 무엇이고 어떻게 그리는지는 [`DESIGN_GRAMMAR.md`](DESIGN_GRAMMAR.md) §곁을 어디 두나에 있고,
|
|
78
|
-
근거는 [`decisions/0022`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
78
|
+
근거는 [`decisions/0022`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0022-screens-declare-their-body.md)다.
|
|
79
79
|
|
|
80
80
|
**뉴트럴이 대부분이다.** 퍼플은 핵심 액션과 선택 상태에만, 오렌지는 CTA·알림 같은 최소한의
|
|
81
81
|
순간에만 쓴다.
|
|
@@ -95,8 +95,13 @@
|
|
|
95
95
|
**지키는 것은 개수다. 한 화면에 주 액션은 하나이고, 선언한 자리도 하나다.** 위아래에 같은 액션을
|
|
96
96
|
두 번 두지 않는다. 자리를 고르는 것은 자유지만 강조 하나 규칙(위 §4)은 그대로다.
|
|
97
97
|
|
|
98
|
+
**0개도 된다.** 고르는 행위가 본문 안에서 끝나는 화면 — 목록을 훑고 행을 눌러 들어가는 화면은
|
|
99
|
+
행이 곧 액션이라 헤더나 하단에 세울 것이 없다. 그때는 선언서에 `없음`이라 적는다
|
|
100
|
+
([`decisions/0033`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0033-a-screen-may-have-no-primary-action.md)). **자리를 채우려고
|
|
101
|
+
다른 층의 기능을 끌어올리지 않는다.**
|
|
102
|
+
|
|
98
103
|
**화면 단위 선언은 둘이다.** 주 액션의 자리가 하나이고, **이 화면의 본문**이 나머지 하나다
|
|
99
|
-
([`decisions/0022`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
104
|
+
([`decisions/0022`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0022-screens-declare-their-body.md)). 같은 장치를 두 축에 쓴다 —
|
|
100
105
|
시스템이 정해 주는 대신 화면이 고르고 밝히고, 지키는 것은 개수다. 둘 다 승인 화면 문서가 받는다.
|
|
101
106
|
|
|
102
107
|
슬롯은 이미 둘 다 있다 — 페이지 헤더 우측 상단은 바디 안이고, 아래는 `AppShell`의 `footer`에
|
|
@@ -104,7 +109,11 @@
|
|
|
104
109
|
|
|
105
110
|
> **타이포 위계는 확정됐다.** 페이지 `headline`(24) → 섹션·카드 `body1`(16) → 행 `body2`(14) →
|
|
106
111
|
> 보조 `label`(12)이고, 표는 [`TOKEN_POLICY.md`](TOKEN_POLICY.md) §타이포에 있다. 화면이 고르는
|
|
107
|
-
> 것은 페이지
|
|
112
|
+
> 것은 페이지 제목과 **본문 목록 여부** 둘이며 나머지는 pattern이 갖고 있다.
|
|
113
|
+
>
|
|
114
|
+
> **본문인 목록은 행이 한 칸 올라간다** — 제목 `body1`(16) + 설명 `body2`(14)
|
|
115
|
+
> ([`decisions/0034`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0034-the-body-list-lifts-one-step.md)). 선언서의 본문 문장이
|
|
116
|
+
> 가리키는 목록 하나에만 쓴다. 곁·요약·참조 나열은 그대로다.
|
|
108
117
|
|
|
109
118
|
## 5. Palda다운 대표 특징
|
|
110
119
|
|
|
@@ -148,7 +157,7 @@ subtle 3켤레로 움직이고, 알리기만 하는 색(그린·앰버)은 눌
|
|
|
148
157
|
[`TOKEN_POLICY.md`](TOKEN_POLICY.md) §패밀리·§켤레에 있다.
|
|
149
158
|
|
|
150
159
|
> **값의 원본은 `tokens/color.tokens.json`이고 이 표는 사본이다.** 어긋나면 토큰이 옳다
|
|
151
|
-
> ([`decisions/0001`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
160
|
+
> ([`decisions/0001`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0001-design-system-ssot.md)). 색 이름은 제안이며 디자이너가
|
|
152
161
|
> 확정한다. CSS에는 hex를 쓰지 않는다 — 언제나 `var(--token)`이다.
|
|
153
162
|
|
|
154
163
|
### 타이포
|
|
@@ -195,7 +204,7 @@ Pretendard, 절제된 무게. **강조는 크기가 아니라 계층과 무게
|
|
|
195
204
|
|
|
196
205
|
| 하지 않는 것 | 대신 | 어디 |
|
|
197
206
|
| ------------------------------ | ------------------------------- | ------------------------------------------- |
|
|
198
|
-
| 모든 것을 카드로 감싸기 | 여백 + 디바이더 + 제목 | [`0011`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
207
|
+
| 모든 것을 카드로 감싸기 | 여백 + 디바이더 + 제목 | [`0011`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0011-no-over-carding.md) |
|
|
199
208
|
| 컨테이너 중첩 (카드 안 보더) | 디바이더. 최대 1 depth | `DESIGN_GRAMMAR.md` §절대 규칙 |
|
|
200
209
|
| 정적인 블록을 보더로 둘러 강조 | 상태·타이포·색 | 〃 |
|
|
201
210
|
| 필터를 채운 칩 박스로 | 언더라인 탭(`Tab`) | 〃 |
|
|
@@ -223,13 +232,13 @@ Pretendard, 절제된 무게. **강조는 크기가 아니라 계층과 무게
|
|
|
223
232
|
| ---------------------------------- | ----------------- | ------------------------------------------------------------ |
|
|
224
233
|
| 강조를 하나 더 넣고 싶다 | 하나로 둔다 | 둘이면 어느 것도 강조가 아니다 (§4) |
|
|
225
234
|
| 시안이 "카드 전체 클릭"을 요구한다 | 문법 | `DESIGN_GRAMMAR.md` §세 번째 질문 |
|
|
226
|
-
| 시안의 색·값이 코드와 다르다 | 코드 | 코드가 SSOT ([`0001`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
235
|
+
| 시안의 색·값이 코드와 다르다 | 코드 | 코드가 SSOT ([`0001`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0001-design-system-ssot.md)) |
|
|
227
236
|
| 브랜드색이 예뻐서 넓게 깔고 싶다 | 뉴트럴 | 브랜드색은 강조와 포인트 전용 (§4) |
|
|
228
237
|
| 글자가 배경에 묻힌다 | 읽히는 쪽 | 수치 기준은 없어도 안 읽히면 시각 표현이 아니다 (2 > 3) |
|
|
229
|
-
| 필요한 토큰·variant·아이콘이 없다 | 멈추고 확인받는다 | 지어내지 않는다 ([`AGENTS.md`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
238
|
+
| 필요한 토큰·variant·아이콘이 없다 | 멈추고 확인받는다 | 지어내지 않는다 ([`AGENTS.md`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/AGENTS.md) §항상) |
|
|
230
239
|
|
|
231
240
|
**시안이 코드를 이기는 경우는 값의 다툼이 아니라 결정을 뒤집을 때뿐이다.** 그때는 ADR을 새로 쓴다
|
|
232
|
-
([`0000-template`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
241
|
+
([`0000-template`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0000-template.md)).
|
|
233
242
|
|
|
234
243
|
## 하지 않기로 한 것
|
|
235
244
|
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
둔 것이다. 여기 적힌 것은 코드에서 고칠 일이 아니다. 코드는 이미 오른쪽 열의 값을 갖고 있다.
|
|
7
7
|
|
|
8
8
|
이 저장소에서는 Figma를 편집할 수 없다. 그래서 "Figma가 이렇게 바뀌어야 한다"를 코드 변경 대신
|
|
9
|
-
문서로 내보낸다. 근거는 [`decisions/0001`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
9
|
+
문서로 내보낸다. 근거는 [`decisions/0001`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0001-design-system-ssot.md)이다.
|
|
10
10
|
|
|
11
11
|
**뉴트럴 스케일 자체는 더 이상 delta가 아니다.** primitive `gray-50`~`gray-900`을 Figma와 같은
|
|
12
|
-
차가운 회색으로 옮겼다([`decisions/0015`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
12
|
+
차가운 회색으로 옮겼다([`decisions/0015`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0015-neutral-scale-adopts-figma-cool-gray.md)).
|
|
13
13
|
값의 방향을 다시 정한 것이지 SSOT가 바뀐 것은 아니고, 아래 남은 항목은 여전히 **Figma가 코드에
|
|
14
14
|
맞춰야 할 것**이다.
|
|
15
15
|
|
|
@@ -35,7 +35,7 @@ primitive는 양쪽이 같아졌고, 아래 셋은 **semantic이 어느 단계
|
|
|
35
35
|
단계가 맞다. `#86868d`는 보조 문구(`color/text/primary-sub`)의 자리다.
|
|
36
36
|
|
|
37
37
|
`color/surface/base`와 `color/surface/sunken`은 배경 위계를 뒤집으면서 한 단계씩 옮겨졌다
|
|
38
|
-
([`decisions/0013`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
38
|
+
([`decisions/0013`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0013-surface-base-is-white.md)). 캔버스가 흰색이고 떠 있는 면과
|
|
39
39
|
요약 행이 회색이다.
|
|
40
40
|
|
|
41
41
|
## 남은 항목 — Figma에 아직 없는 것
|
|
@@ -85,7 +85,7 @@ Badge의 status variant는 틴트 배경 위 조합이다 — 배경 `{status}/s
|
|
|
85
85
|
|
|
86
86
|
`ListRow`의 `tone="filled"`는 `Card`의 `tone="filled"`와 같은 회색이 된다. 두 곳의 `filled`가 같은
|
|
87
87
|
뜻이라 값도 같아야 하고, 층은 색이 아니라 여백·라운드로 갈린다
|
|
88
|
-
([`decisions/0018`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
88
|
+
([`decisions/0018`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0018-summary-row-shares-the-filled-surface.md)).
|
|
89
89
|
|
|
90
90
|
### 새 컴포넌트 2종
|
|
91
91
|
|
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
쓸 때 이 표로 옮기고, Figma 쪽을 정리할 때도 이 표를 목표로 삼는다.
|
|
7
7
|
|
|
8
8
|
값이 다른 항목은 이 문서가 아니라 [`FIGMA_ALIGNMENT_DELTA.md`](FIGMA_ALIGNMENT_DELTA.md)에 있다.
|
|
9
|
-
여기는 **이름만** 다루고, 근거는 [`decisions/0001`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
9
|
+
여기는 **이름만** 다루고, 근거는 [`decisions/0001`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0001-design-system-ssot.md)이다.
|
|
10
10
|
|
|
11
11
|
## CSS 변수 접두사
|
|
12
12
|
|
|
13
13
|
코드의 CSS 변수는 Figma가 선언한 `cssVar`에 `palda-` 접두사를 붙인 것이다
|
|
14
14
|
(`--radius-md` ↔ `--palda-radius-md`). 무접두사 이름이 소비 앱의 전역 변수와 충돌해서다
|
|
15
|
-
([`decisions/0017`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
15
|
+
([`decisions/0017`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0017-css-variable-prefix.md)). Figma에서 변수 이름을 검색해
|
|
16
16
|
코드로 올 때는 접두사만 붙이면 되고, 그 외 규칙은 아래 표와 같다. 이 문서에서 패밀리를
|
|
17
17
|
뭉뚱그려 부를 때는 `--layout-*`처럼 접두사 없이 쓰고, 코드에 실재하는 변수를 가리킬 때는
|
|
18
18
|
`--palda-layout-inset`처럼 전체 이름을 쓴다.
|
|
@@ -74,11 +74,11 @@ Figma의 `regular`는 관례상 400이므로 500에 붙으면 다른 곳에서
|
|
|
74
74
|
| `depth100` | `shadow/100` |
|
|
75
75
|
|
|
76
76
|
단계 번호는 그대로 두고 접두어만 코드 컨벤션에 맞춘다. 근거는
|
|
77
|
-
[`decisions/0009`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
77
|
+
[`decisions/0009`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0009-elevation-shadow-tokens.md)에 있다.
|
|
78
78
|
|
|
79
79
|
## 이 표에 없는 것
|
|
80
80
|
|
|
81
81
|
레이아웃 여백·치수 토큰(`--layout-*` 패밀리와 `--palda-space-gap-xl` 등)은 Figma에 대응하는 변수가 없다. Figma
|
|
82
82
|
실측값을 코드에서 처음 토큰화한 것이라 매핑할 짝이 없다.
|
|
83
|
-
[`decisions/0008`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
83
|
+
[`decisions/0008`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0008-layout-scale-separate-from-component-scale.md)과
|
|
84
84
|
[`LAYOUT.md`](LAYOUT.md)를 본다.
|
|
@@ -2,19 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
**Figma에서 정한 것을 저장소에 반영하고, 시안 코드를 읽어 구현으로 옮기는 절차다.**
|
|
4
4
|
|
|
5
|
-
**원본은 저장소이고 Figma는 미러다**([`decisions/0016`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
5
|
+
**원본은 저장소이고 Figma는 미러다**([`decisions/0016`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0016-asset-ssot-boundary.md)).
|
|
6
6
|
그래서 이 문서의 절차는 한 방향이다 — Figma에서 정한 것을 저장소에 **반영해야** 끝나고, 반영되기
|
|
7
7
|
전까지는 확정이 아니다. 값이 어긋나면 코드가 옳고, Figma가 바뀌어야 할 목록은
|
|
8
8
|
[`FIGMA_ALIGNMENT_DELTA.md`](FIGMA_ALIGNMENT_DELTA.md)에 낸다.
|
|
9
9
|
|
|
10
|
-
1. `figma/LIBRARY_LINKS.md`에서 디자인 시스템 파일의 placeholder 이름을 확인한다. 실제 URL은 저장소가 아니라 각자의 `figma.local.config.json`에 있다([`decisions/0026`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
10
|
+
1. `figma/LIBRARY_LINKS.md`에서 디자인 시스템 파일의 placeholder 이름을 확인한다. 실제 URL은 저장소가 아니라 각자의 `figma.local.config.json`에 있다([`decisions/0026`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0026-figma-keys-stay-out-of-the-repository.md)).
|
|
11
11
|
2. Variables는 `tokens/`와 같은 이름과 의미를 사용한다. 이름이 다른 자리는
|
|
12
12
|
[`FIGMA_NAME_MAPPING.md`](FIGMA_NAME_MAPPING.md)에 있고, 정답은 `tokens/` 쪽 이름이다.
|
|
13
13
|
3. 반복 요소는 Component와 Variant로 만든다.
|
|
14
14
|
4. Auto Layout과 semantic layer name을 사용한다.
|
|
15
15
|
5. Figma에서 정한 변경은 저장소의 원본(`tokens/`·`icons/svg/`·`components/src/`·`catalog/`)에
|
|
16
16
|
반영해야 확정된다. 값을 옮기더라도 "Figma가 옳으니 따른다"가 아니라 저장소에서 다시 정한
|
|
17
|
-
것으로 기록한다 — 전례는 [`decisions/0015`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
17
|
+
것으로 기록한다 — 전례는 [`decisions/0015`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0015-neutral-scale-adopts-figma-cool-gray.md)다.
|
|
18
18
|
6. Library publish 전에 Storybook의 실제 브라우저 결과를 확인한다. 승인은 Figma가 아니라
|
|
19
19
|
Storybook과 `contact-sheet`에서 난다.
|
|
20
20
|
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
([`TOKEN_POLICY.md`](TOKEN_POLICY.md)). 아이콘의 모양과 뜻은 `contact-sheet` 승인으로 확정된다.
|
|
25
25
|
|
|
26
26
|
**아이콘의 원본은 `icons/svg/`다.** Figma는 미러이고, 어긋나면 SVG가 옳다
|
|
27
|
-
([`0016`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
27
|
+
([`0016`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0016-asset-ssot-boundary.md)). `catalog/icons.yml`의 `figma`가 아직 전부
|
|
28
28
|
`TODO`인 것은 미러가 안 만들어졌다는 뜻이지, 저장소가 앞서 있다는 신호가 아니다.
|
|
29
29
|
|
|
30
30
|
자리에 맞는 아이콘을 찾을 때는 셋 중 하나를 고른다. 가운데를 비워 두면 애매한 것이 전부
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
이름과 뜻이 확정된 뒤에 그린다. 그리고 나서도 `icons/svg/`에 바로 넣지 않고, **HTML로 기존
|
|
61
61
|
아이콘 옆에 놓아 보여주고 확정받는다** ([`COMPONENT_POLICY.md`](COMPONENT_POLICY.md) §시안은
|
|
62
62
|
HTML로 먼저 확정한다). 그림을 먼저 그리면 무엇을 그렸는지가 무슨 뜻인지를 정해 버린다.
|
|
63
|
-
[`AGENTS.md`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
63
|
+
[`AGENTS.md`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/AGENTS.md) §항상의 "지어내지 않고, 허용 상태와 사용 조건을 먼저 정의해 확인받는다"를
|
|
64
64
|
아이콘에 적용한 것이다.
|
|
65
65
|
|
|
66
66
|
### 새 아이콘이 들어왔을 때
|
|
@@ -76,7 +76,7 @@ HTML로 먼저 확정한다). 그림을 먼저 그리면 무엇을 그렸는지
|
|
|
76
76
|
## 출처
|
|
77
77
|
|
|
78
78
|
**아이콘마다 어디서 왔는지를 manifest에 적는다.** 세트마다 라이선스가 다르고, 들어온 때에
|
|
79
|
-
안 적으면 나중에 되짚을 수 없다. 근거는 [`decisions/0027`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
79
|
+
안 적으면 나중에 되짚을 수 없다. 근거는 [`decisions/0027`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0027-icons-record-where-they-came-from.md)이다.
|
|
80
80
|
|
|
81
81
|
```json
|
|
82
82
|
"copy": {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
컴포넌트 안쪽을 재는 `--space-*`와 다른 스케일이고, 섞어 쓰지
|
|
6
6
|
않는다. 계층을 나눈 이유는
|
|
7
|
-
[`decisions/0008`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
7
|
+
[`decisions/0008`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0008-layout-scale-separate-from-component-scale.md)에 있다.
|
|
8
8
|
|
|
9
9
|
값은 Figma 3화면에서 같은 값이 반복되는 것을 확인한 실측이다. 지어낸 값이 없다. 실측이 아니라
|
|
10
10
|
고른 값은 그 자리에 그렇게 적는다 — 지금은 §카드 그리드의 3열 하나다.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
**모든 화면이 이 구조를 따른다. 화면별로 재정의하지 않는다.** 기준 화면은 Figma PALDA node
|
|
15
15
|
`586-10288`이고, 수치와 값은 코드 토큰이 SSOT다. 근거는
|
|
16
|
-
[`decisions/0012`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
16
|
+
[`decisions/0012`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0012-canonical-app-shell.md)에 있다.
|
|
17
17
|
|
|
18
18
|
**사이드바(전체 높이) + 콘텐츠.** 사이드바 위를 덮는 전역 상단 바는 없다. 페이지 제목은
|
|
19
19
|
상단 바가 아니라 **바디 안**에 둔다. 스펙 확인용 토글 같은 Figma 전용 장치는 제품 UI로 만들지
|
|
@@ -30,16 +30,16 @@
|
|
|
30
30
|
**2단이 `(선택)`인 조건은 하나다 — 화면 전역을 켜고 끄는 것이 있을 때만 깔린다.** 없으면 깔지
|
|
31
31
|
않는다. 다른 기능의 요약이나 입구(곁)는 이 바를 켜는 이유가 되지 못하고, 이미 깔린 바의 배치를
|
|
32
32
|
바꾸지도 못한다 — `band--inset`은 `space-between`이라 자리가 양끝 둘뿐이고 전역 토글이 그 둘을
|
|
33
|
-
쓴다. 근거는 [`decisions/0022`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
33
|
+
쓴다. 근거는 [`decisions/0022`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0022-screens-declare-their-body.md)에 있다.
|
|
34
34
|
|
|
35
35
|
바디 상단 여백은 `space-8`(32)이고 **바디의 직계 자식 사이는 `space-gap-xl`(24)**이다. 자식은
|
|
36
|
-
섹션이 아니라 블록이라 24다 — 근거는 [`decisions/0021`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
36
|
+
섹션이 아니라 블록이라 24다 — 근거는 [`decisions/0021`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0021-body-children-are-blocks.md)에
|
|
37
37
|
있다. `AppShell`이 이 세 단을 `topRow` · `statusBar` · `children` 슬롯으로 갖고 있다.
|
|
38
38
|
|
|
39
39
|
### 배경 위계
|
|
40
40
|
|
|
41
41
|
**읽는 면이 가장 밝다.** 페이지 캔버스가 흰색이고, 틀과 조작하는 것이 회색으로 물러난다. 근거는
|
|
42
|
-
[`decisions/0013`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
42
|
+
[`decisions/0013`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0013-surface-base-is-white.md)에 있다.
|
|
43
43
|
|
|
44
44
|
| 자리 | 배경 | 색 |
|
|
45
45
|
| ------------------------------------ | ---------------- | --------- |
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
|
|
55
55
|
**채운 면의 회색은 한 종류다.** 앞으로 끌어낸 카드와 요약 행이 같은 `surface/raised`이고, 둘은
|
|
56
56
|
색이 아니라 층으로 갈린다 — 여백과 라운드가 다르다
|
|
57
|
-
([`decisions/0018`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
57
|
+
([`decisions/0018`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0018-summary-row-shares-the-filled-surface.md)).
|
|
58
58
|
`surface/sunken`은 화면 배경에서 빠지고 컨트롤 안쪽(스위치 트랙·`ProgressBar` 트랙·프리뷰 바닥)에만
|
|
59
59
|
남는다.
|
|
60
60
|
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
|
|
74
74
|
배경은 밴드가 아니라 바깥 단이 깔기 때문에 **화면 끝까지 간다(풀블리드).** 열에 폭을 걸면 넓은
|
|
75
75
|
화면에서 상태 바 틴트와 하단 바가 중간에서 끊긴다. 근거는
|
|
76
|
-
[`decisions/0014`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
76
|
+
[`decisions/0014`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0014-full-bleed-bands.md)에 있다.
|
|
77
77
|
|
|
78
78
|
좌우 여백도 밴드가 갖는다 — 상단 행·상태 바·하단 바는 `--palda-layout-inset`, 바디는
|
|
79
79
|
`--palda-layout-page-margin`이다. `box-sizing: border-box`라 `1440`에서의 계산은 그대로다.
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
값도 이미 primitive에 있어서다.
|
|
108
108
|
|
|
109
109
|
`--palda-layout-popup-width`(350px)는 브라우저 확장 팝업의 기존 외곽 폭을 보존한 Draft다. Stable
|
|
110
|
-
폭 표에 섞지 않으며 사용 조건과 검토 질문은 [`reviews/draft-tokens.md`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
110
|
+
폭 표에 섞지 않으며 사용 조건과 검토 질문은 [`reviews/draft-tokens.md`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/reviews/draft-tokens.md)가
|
|
111
111
|
정본이다.
|
|
112
112
|
|
|
113
113
|
## 기존 토큰으로 덮이는 값
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
primitive로 직접 쓰는 자리이며 대응하는 semantic이 없다.
|
|
130
130
|
|
|
131
131
|
**다만 이 32는 바디의 직계 자식에는 적용되지 않는다.** 그 자리는 블록이라 24이고, `AppShell`이
|
|
132
|
-
`gap`으로 준다([`decisions/0021`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
132
|
+
`gap`으로 준다([`decisions/0021`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0021-body-children-are-blocks.md)의 §대가).
|
|
133
133
|
|
|
134
134
|
**그래서 섹션을 바디에 바로 쌓지 않는다.** 섹션이 여럿이면 묶음 하나를 블록으로 세우고, 32는 그
|
|
135
135
|
묶음 안에서 준다 — 바디가 보는 것은 블록 하나이고 24가 그대로 맞는다. 시안 세 장이 전부
|
|
@@ -186,11 +186,11 @@ primitive index는 `px / 4`라는 기존 규칙 그대로다(`--palda-space-12`,
|
|
|
186
186
|
**기본값은 감싸지 않는 것이다.** 섹션은 제목과 여백으로 가르고, 목록은 디바이더로 가른다. 보더와
|
|
187
187
|
카드는 고르거나, 열리거나, 떠 있는 것에만 쓴다. 조건과 pattern별 적용은
|
|
188
188
|
[`DESIGN_GRAMMAR.md`](DESIGN_GRAMMAR.md), 근거는
|
|
189
|
-
[`decisions/0011`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
189
|
+
[`decisions/0011`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0011-no-over-carding.md)에 있다.
|
|
190
190
|
|
|
191
191
|
## 좁아질 때
|
|
192
192
|
|
|
193
|
-
breakpoint는 `desktop 1440` · `mobile 768` 둘이다([`decisions/0010`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
193
|
+
breakpoint는 `desktop 1440` · `mobile 768` 둘이다([`decisions/0010`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0010-breakpoints.md)).
|
|
194
194
|
위 표의 값은 `1440` 이상에서만 그대로 들어간다.
|
|
195
195
|
|
|
196
196
|
| 구간 | 본문 좌우 | 상단바·하단바 좌우 | 사이드바 | 2단 |
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
- 이름은 실제 값이 아니라 역할을 표현한다. 예: `color.action.primary.background`.
|
|
8
8
|
- 컴포넌트 CSS에는 `var(--token)` 참조만 쓴다. 시안에 적힌 리터럴 값(`#54B336`, `36px`)을 그대로 옮기지 않는다.
|
|
9
9
|
- 필요한 token이 없으면 추가하지 말고 먼저 확인받는다. 값을 지어내지 않는다. 과거에 있던 token이라도 복원은 확인 대상이다.
|
|
10
|
-
- **값이 어긋나면 코드가 옳다.** 저장소가 SSOT이고([`decisions/0001`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
10
|
+
- **값이 어긋나면 코드가 옳다.** 저장소가 SSOT이고([`decisions/0001`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0001-design-system-ssot.md), 자산별 경계는 [`decisions/0016`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0016-asset-ssot-boundary.md)), Figma와 다른 자리는 코드를 고치지 않고 [`FIGMA_ALIGNMENT_DELTA.md`](FIGMA_ALIGNMENT_DELTA.md)에 Figma가 바뀌어야 할 목록으로 적는다. 이름이 어긋나는 자리는 [`FIGMA_NAME_MAPPING.md`](FIGMA_NAME_MAPPING.md)에 있다.
|
|
11
11
|
- 저장소의 token 값은 확정치로 취급한다. 명도 대비 미달처럼 품질 문제를 발견하면 보고하되, 컴포넌트에서 다른 색으로 바꾸거나 값 변경을 반복해서 제안하지 않는다.
|
|
12
12
|
- 보더 두께는 예외다. 시스템 전체가 항상 `1px`이며 token으로 만들지 않고 CSS에 직접 쓴다.
|
|
13
13
|
- `tokens/generated/`는 직접 수정하지 않는다. `tokens/*.tokens.json`을 고치고 `pnpm tokens:build`로 다시 만든 뒤, 소스와 생성 파일을 함께 커밋한다. 생성 파일이 빠지면 `pnpm check:generated`가 실패한다.
|
|
@@ -163,19 +163,28 @@ focus에서 `border/focus`로 구분한다.
|
|
|
163
163
|
개별 `font-*` 속성을 컴포넌트 CSS에서 조립하지 않는다. 이유는
|
|
164
164
|
[`COMPONENT_POLICY.md`](COMPONENT_POLICY.md)에 있다.
|
|
165
165
|
|
|
166
|
-
| 계층 | 크기 | 언제
|
|
167
|
-
| ---------- | ---- |
|
|
168
|
-
| `display` | 32px | 쓰지 않는다
|
|
169
|
-
| `headline` | 24px | 페이지 제목
|
|
170
|
-
| `title` | 20px | 빈 화면 제목
|
|
171
|
-
| `body1` | 16px | 섹션·카드·모달 제목
|
|
172
|
-
| `body2` | 14px | 기본 컨트롤 라벨과 본문
|
|
173
|
-
| `label` | 12px | 작은 라벨, 보조 문구
|
|
174
|
-
| `caption` | 10px | 초소형 캡션
|
|
166
|
+
| 계층 | 크기 | 언제 | 쓰는 곳 |
|
|
167
|
+
| ---------- | ---- | ---------------------------------------- | ----------------------------------------------------------- |
|
|
168
|
+
| `display` | 32px | 쓰지 않는다 | **없음 — 폐기 후보** |
|
|
169
|
+
| `headline` | 24px | 페이지 제목 | 화면의 페이지 헤더 `h1` |
|
|
170
|
+
| `title` | 20px | 빈 화면 제목 | EmptyState |
|
|
171
|
+
| `body1` | 16px | 섹션·카드·모달 제목, 본문 목록의 행 제목 | FormSection·Card·Modal 제목·ListRow(`strong`) |
|
|
172
|
+
| `body2` | 14px | 기본 컨트롤 라벨과 본문 | Button·Chip·Radio·DropdownButton·TextField·Toast·EmptyState |
|
|
173
|
+
| `label` | 12px | 작은 라벨, 보조 문구 | Badge(md)·Button(sm)·Chip(sm)·TextField 하단·Tooltip |
|
|
174
|
+
| `caption` | 10px | 초소형 캡션 | Badge(sm) |
|
|
175
175
|
|
|
176
176
|
**한 화면의 제목 위계는 셋이다** — 페이지 `headline`(24) → 섹션·카드 `body1`(16) → 행
|
|
177
177
|
`body2`(14). 그 아래 보조 문구가 `label`(12)이다. 코드가 이미 이 값을 갖고 있어(`FormSection`·
|
|
178
|
-
`Card`·`ListRow`) 화면이 다시 고르는 것은 페이지
|
|
178
|
+
`Card`·`ListRow`) 화면이 다시 고르는 것은 페이지 제목과 **본문 목록 여부** 둘이다.
|
|
179
|
+
|
|
180
|
+
**행은 두 칸이고 그 목록이 화면의 본문인지가 고른다**
|
|
181
|
+
([`decisions/0034`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0034-the-body-list-lifts-one-step.md)). 곁·요약·참조 나열은 제목
|
|
182
|
+
`body2`(14) + 설명 `label`(12) 그대로이고, 선언서의 본문 문장이 가리키는 목록만 한 칸씩 올라가
|
|
183
|
+
제목 `body1`(16) + 설명 `body2`(14)가 된다. `ListRow`의 `emphasis`가 그것이고 기본값은 올리지
|
|
184
|
+
않는 쪽이다. **한 화면에 올린 목록은 하나다.**
|
|
185
|
+
|
|
186
|
+
**제목과 설명은 같이 움직인다.** 제목만 올리면 16 → 12로 두 칸을 건너뛰어 설명이 각주처럼
|
|
187
|
+
떨어진다.
|
|
179
188
|
|
|
180
189
|
**페이지 제목은 `headline`(24)이다.** 섹션 제목이 `body1`(16)이라 32는 두 칸을 건너뛰고, 화면에서
|
|
181
190
|
실제로 무겁게 읽힌다. 시안이 `display`(32)와 `title`(20)로 갈려 있던 것을 2026-09-02에 이렇게
|
|
@@ -193,10 +202,12 @@ focus에서 `border/focus`로 구분한다.
|
|
|
193
202
|
따른다. 누를 수 있는 컨트롤이라고 `semibold`가 되지는 않는다. Button은 `semibold`지만 Chip(md)과
|
|
194
203
|
DropdownButton은 `medium`이다.
|
|
195
204
|
|
|
196
|
-
크기를 키워서 강조를 만들지 않는다.
|
|
205
|
+
크기를 키워서 강조를 만들지 않는다. **임의의 px을 얹지 않는다**는 뜻이다. 고르는 것은 언제나
|
|
206
|
+
계층이고, 계층을 고르는 근거는 그것이 놓인 층이다 — `ListRow`의 `emphasis`가 px이 아니라 값
|
|
207
|
+
둘을 받는 것이 그래서다 (`decisions/0034`).
|
|
197
208
|
|
|
198
209
|
읽는 문장에 `label`(12px)을 쓰지 않는다. `label`은 `sm` 컨트롤 라벨과 하단 보조 문구처럼 짧은
|
|
199
|
-
조각의 자리다.
|
|
210
|
+
조각의 자리다. 본문 목록의 행 설명이 `body2`로 올라가는 이유도 이것이다.
|
|
200
211
|
|
|
201
212
|
## 간격
|
|
202
213
|
|
|
@@ -216,11 +227,11 @@ DropdownButton은 `medium`이다.
|
|
|
216
227
|
|
|
217
228
|
컨트롤은 `sm`, 컨테이너는 `md`, 큰 면은 `lg`가 기준이다. **목록의 행은 컨트롤이 아니라 `md`다** —
|
|
218
229
|
행은 눌리는 컨트롤이 아니라 읽는 줄이고, 제목이 `line-height/100`이라 `sm`으로는 디바이더가 글자에
|
|
219
|
-
붙는다([`decisions/0019`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
230
|
+
붙는다([`decisions/0019`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0019-list-row-vertical-inset.md)).
|
|
220
231
|
|
|
221
232
|
**페이지를 조립하는 여백과 폭은 이 스케일이 아니라 `--layout-*`이다.** 컴포넌트 안쪽을 재는
|
|
222
233
|
`--space-*`와 이름 공간이 갈라져 있다. 고르는 규칙은 [`LAYOUT.md`](LAYOUT.md), 근거는
|
|
223
|
-
[`decisions/0008`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
234
|
+
[`decisions/0008`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/docs/decisions/0008-layout-scale-separate-from-component-scale.md)에 있다.
|
|
224
235
|
`gap/xl`이 layout이 아니라 여기 있는 것은 성격이 "요소 사이"로 같고 값도 이미 primitive에 있어서다.
|
|
225
236
|
|
|
226
237
|
primitive를 직접 쓰는 자리가 둘 있다. focus 링의 `outline-offset`은 `space/1`을 쓴다. 안쪽도
|
|
@@ -248,7 +259,7 @@ primitive를 직접 쓰는 자리가 둘 있다. focus 링의 `outline-offset`
|
|
|
248
259
|
|
|
249
260
|
`pnpm check:css`가 막는 것은 정의되지 않은 token 참조, `1px`이 아닌 보더·아웃라인 두께,
|
|
250
261
|
`:focus-visible` 대신 쓴 `:focus` 셋이다. 위 표의 선택 규칙 자체는 검사하지 않으므로 사람과
|
|
251
|
-
에이전트가 지킨다. 같은 실수가 반복되면 [`AGENTS.md`](https://github.com/highpixel-co/palda-design-system/blob/
|
|
262
|
+
에이전트가 지킨다. 같은 실수가 반복되면 [`AGENTS.md`](https://github.com/highpixel-co/palda-design-system/blob/ad23980481cd81dcf09a1044504d2295f0e4a0f3/AGENTS.md) §항상의 "반복되는 오류는
|
|
252
263
|
검사로 승격한다"에 따라 검사로 올린다.
|
|
253
264
|
|
|
254
265
|
시안에 없는 값은 임의로 정하지 않고 확인받는다. 위 표에서 아직 쓰는 곳이 없다고 적힌 항목은
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
|
-
"packageVersion": "0.
|
|
4
|
-
"sourceRevision": "
|
|
3
|
+
"packageVersion": "0.6.0",
|
|
4
|
+
"sourceRevision": "ad23980481cd81dcf09a1044504d2295f0e4a0f3",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
7
7
|
"values": [
|
|
@@ -123,6 +123,7 @@
|
|
|
123
123
|
"LinkProps",
|
|
124
124
|
"LinkSize",
|
|
125
125
|
"LinkVariant",
|
|
126
|
+
"ListRowEmphasis",
|
|
126
127
|
"ListRowProps",
|
|
127
128
|
"LivePreviewProps",
|
|
128
129
|
"LivePreviewStatus",
|
|
@@ -293,6 +294,7 @@
|
|
|
293
294
|
"CardTone",
|
|
294
295
|
"EmptyStateProps",
|
|
295
296
|
"FormSectionProps",
|
|
297
|
+
"ListRowEmphasis",
|
|
296
298
|
"ListRowProps",
|
|
297
299
|
"LivePreviewProps",
|
|
298
300
|
"LivePreviewStatus"
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { AlarmIcon, AlertIcon, ArrowLeftIcon, ArrowRightIcon, BlankIcon, CableIcon, CameraIcon, CardIcon, CheckIcon, ChevronDownIcon, ChevronLeftIcon, ChevronRightIcon, ChevronUpIcon, CloseIcon, CopyIcon, DashboardIcon, ExternalLinkIcon, EyeIcon, EyeOffIcon, FilterIcon, GiftIcon, HelpIcon, HistoryIcon, HomeIcon, ImageIcon, InfoIcon, KeyIcon, LightbulbIcon, LinkIcon, LoadingIcon, LockIcon, LogoutIcon, MenuIcon, MessageIcon, MonitorIcon, MoreVerticalIcon, MousePointerClickIcon, PauseIcon, PencilIcon, PersonIcon, PhoneIcon, PlusIcon, ProductIcon, RefreshIcon, ReportIcon, SearchIcon, SendIcon, ShieldCheckIcon, SlidersIcon, SmartphoneIcon, SparklesIcon, StarIcon, StoreIcon, SuccessIcon, ThumbsUpIcon, TimerIcon, TrashIcon, TrendingUpIcon, TruckIcon, TypeIcon, UnplugIcon, UploadIcon } from './icons.js';
|
|
2
|
-
export { AppShell, AppShellProps, BottomBar, BottomBarProps, Card, CardProps, CardTone, EmptyState, EmptyStateProps, FormSection, FormSectionProps, ListRow, ListRowProps, LivePreview, LivePreviewProps, LivePreviewStatus } from './patterns.js';
|
|
2
|
+
export { AppShell, AppShellProps, BottomBar, BottomBarProps, Card, CardProps, CardTone, EmptyState, EmptyStateProps, FormSection, FormSectionProps, ListRow, ListRowEmphasis, ListRowProps, LivePreview, LivePreviewProps, LivePreviewStatus } from './patterns.js';
|
|
3
3
|
export { Alert, AlertProps, AlertVariant, Badge, BadgeProps, BadgeSize, BadgeVariant, Button, ButtonProps, ButtonSize, ButtonVariant, Checkbox, CheckboxProps, Chip, ChipProps, ChipSize, ChipVariant, DropdownButton, DropdownButtonAlign, DropdownButtonItem, DropdownButtonProps, DropdownButtonVariant, IconButton, IconButtonProps, IconButtonSize, IconButtonVariant, Link, LinkProps, LinkSize, LinkVariant, Modal, ModalActions, ModalActionsProps, ModalProps, NavigationButton, NavigationButtonProps, ProgressBar, ProgressBarProps, Radio, RadioProps, Switch, SwitchProps, SwitchSize, Tab, TabProps, TextField, TextFieldProps, TextFieldSize, TextFieldVariant, ToastOptions, ToastVariant, Toaster, ToasterPlacement, ToasterProps, Tooltip, TooltipPlacement, TooltipProps, toast } from './ui.js';
|
|
4
4
|
import 'react';
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
FormSection,
|
|
8
8
|
ListRow,
|
|
9
9
|
LivePreview
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-QW2SD3XV.js";
|
|
11
11
|
import "./chunk-EYFL232L.js";
|
|
12
12
|
import {
|
|
13
13
|
Alert,
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
Toaster,
|
|
30
30
|
Tooltip,
|
|
31
31
|
toast
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-6JZPK2W5.js";
|
|
33
33
|
import {
|
|
34
34
|
AlarmIcon,
|
|
35
35
|
AlertIcon,
|
package/dist/patterns.d.ts
CHANGED
|
@@ -112,11 +112,21 @@ interface FormSectionProps {
|
|
|
112
112
|
*/
|
|
113
113
|
declare function FormSection({ children, description, error, footer, title }: FormSectionProps): react.JSX.Element;
|
|
114
114
|
|
|
115
|
+
type ListRowEmphasis = 'default' | 'strong';
|
|
115
116
|
interface ListRowProps {
|
|
116
117
|
/** 누를 수 있는 행 오른쪽 끝의 chevron. `onClick`이 있으면 기본으로 붙는다. */
|
|
117
118
|
chevron?: boolean;
|
|
118
119
|
children?: ReactNode;
|
|
119
120
|
description?: ReactNode;
|
|
121
|
+
/**
|
|
122
|
+
* 행이 놓인 층. 크기를 고르는 자리가 아니라 이 목록이 화면의 본문인지를 밝히는 자리다.
|
|
123
|
+
* - `default`(기본) — 제목 `body2`(14) · 설명 `label`(12). 곁·요약·참조 나열이다.
|
|
124
|
+
* - `strong` — 제목 `body1`(16) · 설명 `body2`(14). 선언서의 본문 문장이 가리키는 목록
|
|
125
|
+
* 하나에만 쓴다. 한 화면에 `strong` 목록은 하나다.
|
|
126
|
+
*
|
|
127
|
+
* `tone="filled"`와 함께 쓰지 않는다 — 곁이 본문 크기를 갖는 일이다 (0032, 0034).
|
|
128
|
+
*/
|
|
129
|
+
emphasis?: ListRowEmphasis;
|
|
120
130
|
/** 제목 앞 아이콘이나 썸네일. */
|
|
121
131
|
leading?: ReactNode;
|
|
122
132
|
/** 자리를 잡아 두는 로딩 표시. 켜면 내용 대신 뼈대를 그린다. */
|
|
@@ -140,9 +150,12 @@ interface ListRowProps {
|
|
|
140
150
|
*
|
|
141
151
|
* `onClick`을 주면 누를 수 있는 행이 되어 button으로 그려지고 오른쪽 끝에 chevron이 붙는다.
|
|
142
152
|
*
|
|
153
|
+
* 이 목록이 화면의 본문이면 `emphasis="strong"`으로 제목·설명을 한 칸씩 올린다 (0034). 곁·요약
|
|
154
|
+
* 나열은 기본값 그대로 둔다.
|
|
155
|
+
*
|
|
143
156
|
* 목록 전체가 비었을 때와 실패했을 때는 이 컴포넌트가 아니라 `EmptyState`를 쓴다.
|
|
144
157
|
*/
|
|
145
|
-
declare function ListRow({ chevron, children, description, leading, loading, onClick, selected, title, tone, trailing, }: ListRowProps): react.JSX.Element;
|
|
158
|
+
declare function ListRow({ chevron, children, description, emphasis, leading, loading, onClick, selected, title, tone, trailing, }: ListRowProps): react.JSX.Element;
|
|
146
159
|
|
|
147
160
|
type LivePreviewStatus = 'ready' | 'loading' | 'empty' | 'error';
|
|
148
161
|
interface LivePreviewProps {
|
|
@@ -159,4 +172,4 @@ interface LivePreviewProps {
|
|
|
159
172
|
*/
|
|
160
173
|
declare function LivePreview({ children, message, status, title }: LivePreviewProps): react.JSX.Element;
|
|
161
174
|
|
|
162
|
-
export { AppShell, type AppShellProps, BottomBar, type BottomBarProps, Card, type CardProps, type CardTone, EmptyState, type EmptyStateProps, FormSection, type FormSectionProps, ListRow, type ListRowProps, LivePreview, type LivePreviewProps, type LivePreviewStatus };
|
|
175
|
+
export { AppShell, type AppShellProps, BottomBar, type BottomBarProps, Card, type CardProps, type CardTone, EmptyState, type EmptyStateProps, FormSection, type FormSectionProps, ListRow, type ListRowEmphasis, type ListRowProps, LivePreview, type LivePreviewProps, type LivePreviewStatus };
|
package/dist/patterns.js
CHANGED
|
@@ -41,7 +41,13 @@ const ROW = /^\|([^|]*)\|([^|]*)\|/;
|
|
|
41
41
|
/** 표의 구분선(`| --- | --- |`)은 항목이 아니다. */
|
|
42
42
|
const DIVIDER = /^[\s:-]*$/;
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
/**
|
|
45
|
+
* 주 액션의 자리. `없음`은 고르는 행위가 본문 안에서 끝나는 화면이다 — 목록을 훑고 행을 눌러
|
|
46
|
+
* 들어가는 화면은 행이 곧 액션이라 헤더나 하단에 세울 것이 없다
|
|
47
|
+
* (`docs/decisions/0033-a-screen-may-have-no-primary-action.md`). 행 자체는 여전히 필수라
|
|
48
|
+
* "적기를 잊은 것"과 "정말 없는 것"이 갈린다.
|
|
49
|
+
*/
|
|
50
|
+
const PRIMARY_ACTION_PLACES = new Set(['헤더 우측', 'BottomBar', '없음']);
|
|
45
51
|
|
|
46
52
|
/** 시안을 찾는 곳. `preview/`는 untracked라 CI에서는 비어 있고 로컬에서만 걸린다. */
|
|
47
53
|
const SCREEN_DIRS = ['preview', 'examples'];
|
|
@@ -79,41 +85,6 @@ const EMPHASIS_CLASSES = [
|
|
|
79
85
|
'palda-chip--accent',
|
|
80
86
|
];
|
|
81
87
|
|
|
82
|
-
/**
|
|
83
|
-
* 곁이 세로로 한 줄인지(0022 규칙 1)를 정적으로 근사한다. 블록 요소가 하나라도 들어 있으면
|
|
84
|
-
* 줄이 나뉜다 — 곁에 남는 표현은 텍스트와 `Link`라(0022 §대가) 인라인만으로 충분하다.
|
|
85
|
-
* 줄바꿈 자체는 폭에 달려 있어 여전히 못 읽는다. 이 검사가 잡는 것은 마크업으로 이미 갈라 둔
|
|
86
|
-
* 경우다.
|
|
87
|
-
*/
|
|
88
|
-
const BLOCK_ELEMENTS = new Set([
|
|
89
|
-
'address',
|
|
90
|
-
'article',
|
|
91
|
-
'aside',
|
|
92
|
-
'blockquote',
|
|
93
|
-
'div',
|
|
94
|
-
'dl',
|
|
95
|
-
'fieldset',
|
|
96
|
-
'figure',
|
|
97
|
-
'footer',
|
|
98
|
-
'form',
|
|
99
|
-
'h1',
|
|
100
|
-
'h2',
|
|
101
|
-
'h3',
|
|
102
|
-
'h4',
|
|
103
|
-
'h5',
|
|
104
|
-
'h6',
|
|
105
|
-
'header',
|
|
106
|
-
'hr',
|
|
107
|
-
'li',
|
|
108
|
-
'main',
|
|
109
|
-
'nav',
|
|
110
|
-
'ol',
|
|
111
|
-
'p',
|
|
112
|
-
'section',
|
|
113
|
-
'table',
|
|
114
|
-
'ul',
|
|
115
|
-
]);
|
|
116
|
-
|
|
117
88
|
/**
|
|
118
89
|
* 상태를 드는 자리 (0024 — 상태는 가장 가까운 자리가 든다).
|
|
119
90
|
* 한 섹션이 둘을 같이 쓰면 행 하나의 실패를 섹션이 대신 말한 것이다. `\b`가 `_`를 경계로 보지
|
|
@@ -325,16 +296,6 @@ function checkBlocks(blocks, declaredAsides, where, problems) {
|
|
|
325
296
|
);
|
|
326
297
|
}
|
|
327
298
|
}
|
|
328
|
-
|
|
329
|
-
// 규칙 1 — 세로로 한 줄이다. 블록 요소가 들어 있으면 이미 여러 줄이다.
|
|
330
|
-
const inner = scanTags(block.html)
|
|
331
|
-
.slice(1)
|
|
332
|
-
.filter((tag) => !tag.closing && BLOCK_ELEMENTS.has(tag.name));
|
|
333
|
-
if (inner.length > 0) {
|
|
334
|
-
problems.push(
|
|
335
|
-
`${where}: 곁 안에 블록 요소(<${inner[0].name}>)가 있다 — 곁은 세로로 한 줄이다 (0022 규칙 1)`,
|
|
336
|
-
);
|
|
337
|
-
}
|
|
338
299
|
}
|
|
339
300
|
|
|
340
301
|
// 상태는 가장 가까운 자리가 든다 (0024). 소속과 무관하게 바디 전체를 본다.
|
|
@@ -368,7 +329,8 @@ function checkBlocks(blocks, declaredAsides, where, problems) {
|
|
|
368
329
|
);
|
|
369
330
|
}
|
|
370
331
|
|
|
371
|
-
// 선언되지 않은 곁은 화면에 들어오지 못한다.
|
|
332
|
+
// 선언되지 않은 곁은 화면에 들어오지 못한다. 곁이 몇 개여야 하는지는 세지 않는다 — 기능이
|
|
333
|
+
// 다르면 블록도 다르고(0032 규칙 1), 개수는 기능 수가 정한다.
|
|
372
334
|
const drawn = roles.filter((role) => role === '곁').length;
|
|
373
335
|
if (drawn !== declaredAsides) {
|
|
374
336
|
problems.push(
|
package/dist/styles.css
CHANGED
|
@@ -1355,6 +1355,11 @@
|
|
|
1355
1355
|
justify-content: center;
|
|
1356
1356
|
width: 24px;
|
|
1357
1357
|
}
|
|
1358
|
+
.palda-tab__badge {
|
|
1359
|
+
align-items: center;
|
|
1360
|
+
display: inline-flex;
|
|
1361
|
+
flex-shrink: 0;
|
|
1362
|
+
}
|
|
1358
1363
|
.palda-tab__label {
|
|
1359
1364
|
white-space: nowrap;
|
|
1360
1365
|
}
|
|
@@ -2112,6 +2117,12 @@ button.palda-list-row:focus-visible {
|
|
|
2112
2117
|
height: var(--palda-font-size-xs);
|
|
2113
2118
|
width: 70%;
|
|
2114
2119
|
}
|
|
2120
|
+
.palda-list-row--strong .palda-list-row__skeleton--title {
|
|
2121
|
+
height: var(--palda-font-size-md);
|
|
2122
|
+
}
|
|
2123
|
+
.palda-list-row--strong .palda-list-row__skeleton--description {
|
|
2124
|
+
height: var(--palda-font-size-sm);
|
|
2125
|
+
}
|
|
2115
2126
|
@keyframes palda-list-row-pulse {
|
|
2116
2127
|
from {
|
|
2117
2128
|
opacity: 1;
|
package/dist/ui.d.ts
CHANGED
|
@@ -174,10 +174,15 @@ interface TabProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'role'
|
|
|
174
174
|
children: ReactNode;
|
|
175
175
|
/** 라벨 앞 아이콘. 시안 기준 24px 고정이다. */
|
|
176
176
|
icon?: ReactNode;
|
|
177
|
+
/**
|
|
178
|
+
* 라벨 뒤 배지. 그룹별 개수처럼 탭을 열지 않고도 보여야 하는 수를 싣는다.
|
|
179
|
+
* `Badge`를 넣는 자리이며 크기는 `sm`을 쓴다 — 라벨이 Body2(14px)라 md(28px)는 라벨보다 커진다.
|
|
180
|
+
*/
|
|
181
|
+
badge?: ReactNode;
|
|
177
182
|
/** 지금 보고 있는 탭. `aria-selected`로 함께 노출된다. */
|
|
178
183
|
selected?: boolean;
|
|
179
184
|
}
|
|
180
|
-
declare function Tab({ children, className, icon, selected, ...props }: TabProps): react.JSX.Element;
|
|
185
|
+
declare function Tab({ children, className, icon, badge, selected, ...props }: TabProps): react.JSX.Element;
|
|
181
186
|
|
|
182
187
|
type TextFieldVariant = 'outline' | 'accent' | 'subtle';
|
|
183
188
|
type TextFieldSize = 'md' | 'sm';
|
package/dist/ui.js
CHANGED