sellmate-design-system-react 4.1.0 → 4.2.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.
@@ -158,7 +158,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
158
158
 
159
159
  ### 2-2. 간격 (spacing)
160
160
 
161
- - **간격 유틸리티는 `sd-` 접두를 붙인다** — `gap-sd-8`, `p-sd-20`, `mt-sd-12`. 숫자 = px 다.
161
+ - **간격 유틸리티는 `sd-` 접두를 붙인다** — `gap-sd-8`, `p-sd-16`, `mt-sd-12`. 숫자 = px 다.
162
162
  접두를 빼면 Tailwind 기본 스케일이 적용된다(`gap-8` = 32px). 접두는 속성 뒤, 숫자 앞에 온다.
163
163
  - 스케일: `2 4 6 8 10 12 16 19 20 22 24 28 32 36 40 44 48 56 60 62 80`
164
164
  - 형제 요소 간격은 margin 대신 부모의 `flex`/`grid` + `gap-sd-*`으로 잡는다.
@@ -166,7 +166,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
166
166
 
167
167
  | 상황 | 값 |
168
168
  | --- | --- |
169
- | **페이지 콘텐츠 패딩** | **`p-sd-20`** |
169
+ | **페이지 콘텐츠 패딩** | **16px — `SPage` 가 `--cmp-pageBody-padding` 으로 이미 넣는다.** 직접 주지 않는다 (덮어쓰면 토큰이 바뀌어도 안 따라간다). `SPage` 밖에서 같은 패딩이 필요하면 `p-sd-16` |
170
170
  | **섹션 ↔ 섹션** | **`gap-sd-12`** |
171
171
  | **페이지 내 블록 ↔ 블록** (헤더·필터·툴바·테이블 사이) | **`gap-sd-12`** |
172
172
  | 요소 ↔ 요소 | **기본 `gap-sd-8`** (`--sys-space-stack-gap-element-normal`) · 타이트 `gap-sd-4`(`-tight`) · 여유 `gap-sd-12`(`-relaxed`) / `gap-sd-16`(`-wide`) |
@@ -346,7 +346,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
346
346
  - 작은 창이 아니라 **화면 하나가 통째로** 들어간다 — 검색 필터·테이블·페이지네이션이 그대로 있는 목록(`엑셀 파일 관리`), 헤더 카드·탭이 있는 상세(`이동 오더 상세`).
347
347
  - 상세를 팝업으로 여는 이유는 **목록을 떠나지 않고 여러 건을 번갈아 보기** 위해서다. 단 상세가 **항상** 팝업인 것은 아니고, 데이터 양이 많을 때 팝업을 쓴다.
348
348
  - 구조는 헤더(제목 중앙) + 본문 + 푸터다. **확정할 작업이 있으면 푸터에 `저장`, 조회만이면 `useFooter={false}`** 로 푸터를 없앤다.
349
- - 본문에는 패딩이 없다 — 콘텐츠가 여백을 담당한다. 팝업 안도 일반 페이지와 같은 규칙(§4)을 따른다: 패딩 `p-sd-20`, 블록 간격 `gap-sd-12`, 표는 `SKeyValueTable` / `STable`.
349
+ - 본문에는 패딩이 없다 — 콘텐츠가 여백을 담당한다. 팝업 안도 일반 페이지와 같은 규칙(§4)을 따른다: 패딩 `p-sd-16`(`SPage` 가 아니라 직접 준다), 블록 간격 `gap-sd-12`, 표는 `SKeyValueTable` / `STable`.
350
350
 
351
351
  ```tsx
352
352
  // 1) 목록에서 별도 창을 연다 — 창 크기 = 콘텐츠 크기
@@ -362,7 +362,7 @@ function openDetailPopup(orderId: string) {
362
362
  export default function TransferOrderPopupPage() {
363
363
  return (
364
364
  <SPopup popupTitle="이동 오더 상세" useFooter={false}>
365
- <div className="flex flex-col gap-sd-12 p-sd-20">
365
+ <div className="flex flex-col gap-sd-12 p-sd-16">
366
366
  <SSectionHeaderCard>…</SSectionHeaderCard>
367
367
  <STabs value={tab} tabs={TABS} onValueChange={setTab} />
368
368
  <STable columns={columns} rows={rows} rowKey="id" />
@@ -618,12 +618,41 @@ export default function AppShell({ children }: { children: React.ReactNode }) {
618
618
  <SLayout type="box" header="fix">
619
619
  {/* type/header/folded 는 SLayout 에만 준다 — SGnb 는 context 에서 읽는다 */}
620
620
  <SGnb items={MENU} value={current} onValueChange={navigate} logo={<Logo />} />
621
- <SPage background="frame" className="p-sd-20">{children}</SPage>
621
+ {/* 콘텐츠 패딩(16px)은 SPage 토큰으로 넣는다 — p-sd-* 로 덮어쓰지 않는다 */}
622
+ <SPage background="frame">{children}</SPage>
622
623
  </SLayout>
623
624
  );
624
625
  }
625
626
  ```
626
627
 
628
+ **상단바 배치는 `header` 가 정한다.** 요소 순서가 달라지므로 슬롯을 채우기 전에 어느 쪽인지부터 정한다.
629
+
630
+ | `header` | 상단바 배치 | 로고 폭 | `topContent` |
631
+ | --- | --- | --- | --- |
632
+ | `"fix"` (기본) | `[런처 · 로고 … 폴드]` — 상단바가 GNB 컬럼 안에 있고 폴드가 컬럼 오른쪽 끝 | 내용 폭 | **렌더되지 않는다** (놓을 자리가 없다) |
633
+ | `"full"` | `[런처 · 폴드 · 로고 · topContent]` — 상단바가 화면 전폭 | **140px 고정** | 로고 오른쪽 남는 폭 전체 |
634
+
635
+ - `topContent` 는 상단바 로고 오른쪽 슬롯이다. 전역 검색·계정 메뉴·알림처럼 **모든 페이지에 공통인 것만** 넣는다. 페이지별 액션은 여기가 아니라 §4-2 의 `STableBar` 로 간다.
636
+ - 슬롯이 남는 폭을 통째로 받으므로 **정렬은 안에서 직접 잡는다** (좌측 정렬 + 우측은 `ml-auto`).
637
+ - `header="full"` 에서 로고 자리는 140px 로 고정된다 — 로고 내용이 바뀌어도 `topContent` 시작점이 흔들리지 않게 하기 위함이다. 로고가 그보다 넓으면 잘리므로 이 폭에 맞춰 준비한다.
638
+
639
+ ```tsx
640
+ <SLayout type="box" header="full">
641
+ <SGnb
642
+ items={MENU} value={current} onValueChange={navigate}
643
+ logo={<Logo />}
644
+ topContent={
645
+ /* 남는 폭 전체를 받는다 — 왼쪽은 그대로, 오른쪽 끝은 ml-auto */
646
+ <div className="flex w-full items-center gap-sd-8">
647
+ <SInput value={keyword} onValueChange={setKeyword} placeholder="통합 검색" />
648
+ <SButton size="sm" color="neutral" outline label="내 계정" className="ml-auto" onClick={openAccount} />
649
+ </div>
650
+ }
651
+ />
652
+ <SPage background="frame">{children}</SPage>
653
+ </SLayout>
654
+ ```
655
+
627
656
  ### 4-2. 목록 페이지 (필터 + 테이블)
628
657
 
629
658
  구조: **페이지 헤더(제목 + 가이드 링크) → 필터(`SKeyValueTable`) → `STableBar` → `STable`**
@@ -882,7 +911,7 @@ export default function ProductDetailPage() {
882
911
  - [ ] 간격이 전부 `sd-` 접두 스케일 값인가 (`gap-13`·`gap-sd-13` ❌ → `gap-sd-12` ✅)
883
912
  - [ ] 본문이 12px(`typo-body-sm-default`)인가 (14px 본문 ❌)
884
913
  - [ ] 텍스트 회색 위계를 순차 적용했는가 (기본 → `text-fg-secondary` → `text-fg-tertiary`, 단계 건너뛰기 ❌)
885
- - [ ] 페이지 패딩이 `p-sd-20`, 블록·섹션 간격이 `gap-sd-12` 인가 (`gap-sd-16`/`gap-sd-24` ❌)
914
+ - [ ] `SPage` 기본 패딩(16px)을 `p-sd-*` 로 덮어쓰지 않았는가, 블록·섹션 간격이 `gap-sd-12` 인가 (`gap-sd-16`/`gap-sd-24` ❌)
886
915
  - [ ] 같은 컴포넌트를 나열할 때 §2-2 그룹 간격을 썼는가 (체크박스 가로 `gap-sd-24` 등)
887
916
  - [ ] 페이지가 §4의 표준 골격에서 시작했는가
888
917
  - [ ] 필터·폼·상세 정보를 `SKeyValueTable` 로 만들었는가 (컨트롤을 `div` 로 나열하지 않았는가)
@@ -2168,7 +2197,8 @@ Tailwind 유틸리티는 아래 스케일에 있는 값만 사용한다. 리터
2168
2197
  | `useRail?` | `boolean` | — | 좌측 레일 사용 여부. 켜면 items 의 첫 depth 가 아이콘+라벨 버튼의 세로 레일로 서고, 선택된 레일 아이템의 children 이 오른쪽 메뉴 패널에 깔린다. 미지정 시 SLayout 의 useRail 을 따른다. children 없는 레일 아이템이 활성이면 메뉴 패널은 렌더되지 않고 레일만 남는다. |
2169
2198
  | `value?` | `string` | `''` | 현재 선택된 아이템 value |
2170
2199
  | `folded?` | `boolean` | — | 접힘(레일) 상태. 미지정 시 SLayout 의 folded 를 따른다. |
2171
- | `logo?` | `ReactNode` | — | 상단바 로고 영역 (slot) |
2200
+ | `logo?` | `ReactNode` | — | 상단바 로고 영역 (slot). header="full" 이면 폭이 140px 로 고정된다. |
2201
+ | `topContent?` | `ReactNode` | — | 상단바 로고 오른쪽 슬롯 (검색·액션 등). 로고와 16px 띄고 남는 폭을 모두 차지하므로 안에서 자유롭게 정렬한다. 상단바가 전폭인 header="full" 에서만 렌더된다 (fix 는 상단바가 좁은 GNB 컬럼 안이라 놓을 자리가 없다). |
2172
2202
  | `railFooter?` | `ReactNode` | — | 레일 하단 고정 슬롯. 레일 아이템이 많아 넘치면 아이템 목록(ul)만 스크롤되고 이 슬롯은 레일 하단에 붙어 고정된다. useRail 일 때만 렌더된다. |
2173
2203
  | `menuFooter?` | `ReactNode` | — | 메뉴 하단 고정 슬롯. 메뉴 아이템이 많아 넘치면 메뉴 목록(ul)만 스크롤되고 이 슬롯은 메뉴 하단에 붙어 고정된다. 메뉴가 렌더될 때만(showMenu) 나타난다. |
2174
2204
  | `foldedFooter?` | `ReactNode` | — | 접힘(fix 레일) 하단 고정 슬롯. 접으면 본문이 빠져나가며 rail/menu footer 도 사라지므로, 48px 폴드 레일 바닥에 붙는 별도 슬롯이다. header="fix" 로 접혔을 때만 나타난다. |
package/dist/llms.txt CHANGED
@@ -159,7 +159,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
159
159
 
160
160
  ### 2-2. 간격 (spacing)
161
161
 
162
- - **간격 유틸리티는 `sd-` 접두를 붙인다** — `gap-sd-8`, `p-sd-20`, `mt-sd-12`. 숫자 = px 다.
162
+ - **간격 유틸리티는 `sd-` 접두를 붙인다** — `gap-sd-8`, `p-sd-16`, `mt-sd-12`. 숫자 = px 다.
163
163
  접두를 빼면 Tailwind 기본 스케일이 적용된다(`gap-8` = 32px). 접두는 속성 뒤, 숫자 앞에 온다.
164
164
  - 스케일: `2 4 6 8 10 12 16 19 20 22 24 28 32 36 40 44 48 56 60 62 80`
165
165
  - 형제 요소 간격은 margin 대신 부모의 `flex`/`grid` + `gap-sd-*`으로 잡는다.
@@ -167,7 +167,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
167
167
 
168
168
  | 상황 | 값 |
169
169
  | --- | --- |
170
- | **페이지 콘텐츠 패딩** | **`p-sd-20`** |
170
+ | **페이지 콘텐츠 패딩** | **16px — `SPage` 가 `--cmp-pageBody-padding` 으로 이미 넣는다.** 직접 주지 않는다 (덮어쓰면 토큰이 바뀌어도 안 따라간다). `SPage` 밖에서 같은 패딩이 필요하면 `p-sd-16` |
171
171
  | **섹션 ↔ 섹션** | **`gap-sd-12`** |
172
172
  | **페이지 내 블록 ↔ 블록** (헤더·필터·툴바·테이블 사이) | **`gap-sd-12`** |
173
173
  | 요소 ↔ 요소 | **기본 `gap-sd-8`** (`--sys-space-stack-gap-element-normal`) · 타이트 `gap-sd-4`(`-tight`) · 여유 `gap-sd-12`(`-relaxed`) / `gap-sd-16`(`-wide`) |
@@ -347,7 +347,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
347
347
  - 작은 창이 아니라 **화면 하나가 통째로** 들어간다 — 검색 필터·테이블·페이지네이션이 그대로 있는 목록(`엑셀 파일 관리`), 헤더 카드·탭이 있는 상세(`이동 오더 상세`).
348
348
  - 상세를 팝업으로 여는 이유는 **목록을 떠나지 않고 여러 건을 번갈아 보기** 위해서다. 단 상세가 **항상** 팝업인 것은 아니고, 데이터 양이 많을 때 팝업을 쓴다.
349
349
  - 구조는 헤더(제목 중앙) + 본문 + 푸터다. **확정할 작업이 있으면 푸터에 `저장`, 조회만이면 `useFooter={false}`** 로 푸터를 없앤다.
350
- - 본문에는 패딩이 없다 — 콘텐츠가 여백을 담당한다. 팝업 안도 일반 페이지와 같은 규칙(§4)을 따른다: 패딩 `p-sd-20`, 블록 간격 `gap-sd-12`, 표는 `SKeyValueTable` / `STable`.
350
+ - 본문에는 패딩이 없다 — 콘텐츠가 여백을 담당한다. 팝업 안도 일반 페이지와 같은 규칙(§4)을 따른다: 패딩 `p-sd-16`(`SPage` 가 아니라 직접 준다), 블록 간격 `gap-sd-12`, 표는 `SKeyValueTable` / `STable`.
351
351
 
352
352
  ```tsx
353
353
  // 1) 목록에서 별도 창을 연다 — 창 크기 = 콘텐츠 크기
@@ -363,7 +363,7 @@ function openDetailPopup(orderId: string) {
363
363
  export default function TransferOrderPopupPage() {
364
364
  return (
365
365
  <SPopup popupTitle="이동 오더 상세" useFooter={false}>
366
- <div className="flex flex-col gap-sd-12 p-sd-20">
366
+ <div className="flex flex-col gap-sd-12 p-sd-16">
367
367
  <SSectionHeaderCard>…</SSectionHeaderCard>
368
368
  <STabs value={tab} tabs={TABS} onValueChange={setTab} />
369
369
  <STable columns={columns} rows={rows} rowKey="id" />
@@ -619,12 +619,41 @@ export default function AppShell({ children }: { children: React.ReactNode }) {
619
619
  <SLayout type="box" header="fix">
620
620
  {/* type/header/folded 는 SLayout 에만 준다 — SGnb 는 context 에서 읽는다 */}
621
621
  <SGnb items={MENU} value={current} onValueChange={navigate} logo={<Logo />} />
622
- <SPage background="frame" className="p-sd-20">{children}</SPage>
622
+ {/* 콘텐츠 패딩(16px)은 SPage 토큰으로 넣는다 — p-sd-* 로 덮어쓰지 않는다 */}
623
+ <SPage background="frame">{children}</SPage>
623
624
  </SLayout>
624
625
  );
625
626
  }
626
627
  ```
627
628
 
629
+ **상단바 배치는 `header` 가 정한다.** 요소 순서가 달라지므로 슬롯을 채우기 전에 어느 쪽인지부터 정한다.
630
+
631
+ | `header` | 상단바 배치 | 로고 폭 | `topContent` |
632
+ | --- | --- | --- | --- |
633
+ | `"fix"` (기본) | `[런처 · 로고 … 폴드]` — 상단바가 GNB 컬럼 안에 있고 폴드가 컬럼 오른쪽 끝 | 내용 폭 | **렌더되지 않는다** (놓을 자리가 없다) |
634
+ | `"full"` | `[런처 · 폴드 · 로고 · topContent]` — 상단바가 화면 전폭 | **140px 고정** | 로고 오른쪽 남는 폭 전체 |
635
+
636
+ - `topContent` 는 상단바 로고 오른쪽 슬롯이다. 전역 검색·계정 메뉴·알림처럼 **모든 페이지에 공통인 것만** 넣는다. 페이지별 액션은 여기가 아니라 §4-2 의 `STableBar` 로 간다.
637
+ - 슬롯이 남는 폭을 통째로 받으므로 **정렬은 안에서 직접 잡는다** (좌측 정렬 + 우측은 `ml-auto`).
638
+ - `header="full"` 에서 로고 자리는 140px 로 고정된다 — 로고 내용이 바뀌어도 `topContent` 시작점이 흔들리지 않게 하기 위함이다. 로고가 그보다 넓으면 잘리므로 이 폭에 맞춰 준비한다.
639
+
640
+ ```tsx
641
+ <SLayout type="box" header="full">
642
+ <SGnb
643
+ items={MENU} value={current} onValueChange={navigate}
644
+ logo={<Logo />}
645
+ topContent={
646
+ /* 남는 폭 전체를 받는다 — 왼쪽은 그대로, 오른쪽 끝은 ml-auto */
647
+ <div className="flex w-full items-center gap-sd-8">
648
+ <SInput value={keyword} onValueChange={setKeyword} placeholder="통합 검색" />
649
+ <SButton size="sm" color="neutral" outline label="내 계정" className="ml-auto" onClick={openAccount} />
650
+ </div>
651
+ }
652
+ />
653
+ <SPage background="frame">{children}</SPage>
654
+ </SLayout>
655
+ ```
656
+
628
657
  ### 4-2. 목록 페이지 (필터 + 테이블)
629
658
 
630
659
  구조: **페이지 헤더(제목 + 가이드 링크) → 필터(`SKeyValueTable`) → `STableBar` → `STable`**
@@ -883,7 +912,7 @@ export default function ProductDetailPage() {
883
912
  - [ ] 간격이 전부 `sd-` 접두 스케일 값인가 (`gap-13`·`gap-sd-13` ❌ → `gap-sd-12` ✅)
884
913
  - [ ] 본문이 12px(`typo-body-sm-default`)인가 (14px 본문 ❌)
885
914
  - [ ] 텍스트 회색 위계를 순차 적용했는가 (기본 → `text-fg-secondary` → `text-fg-tertiary`, 단계 건너뛰기 ❌)
886
- - [ ] 페이지 패딩이 `p-sd-20`, 블록·섹션 간격이 `gap-sd-12` 인가 (`gap-sd-16`/`gap-sd-24` ❌)
915
+ - [ ] `SPage` 기본 패딩(16px)을 `p-sd-*` 로 덮어쓰지 않았는가, 블록·섹션 간격이 `gap-sd-12` 인가 (`gap-sd-16`/`gap-sd-24` ❌)
887
916
  - [ ] 같은 컴포넌트를 나열할 때 §2-2 그룹 간격을 썼는가 (체크박스 가로 `gap-sd-24` 등)
888
917
  - [ ] 페이지가 §4의 표준 골격에서 시작했는가
889
918
  - [ ] 필터·폼·상세 정보를 `SKeyValueTable` 로 만들었는가 (컨트롤을 `div` 로 나열하지 않았는가)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sellmate-design-system-react",
3
- "version": "4.1.0",
3
+ "version": "4.2.0",
4
4
  "description": "Sellmate Design System — React (TypeScript + Tailwind v4) port",
5
5
  "license": "UNLICENSED",
6
6
  "keywords": [