sellmate-design-system-react 4.1.0 → 4.3.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/AGENTS.md +41 -6
- package/README.md +19 -3
- package/dist/components/SButton/README.md +2 -0
- package/dist/components/SDrawer/README.md +42 -0
- package/dist/components/SDrawer/SDrawer.d.ts +39 -0
- package/dist/components/SDrawer/index.d.ts +1 -0
- package/dist/components/SGhostButton/README.md +2 -0
- package/dist/components/SGnb/README.md +2 -1
- package/dist/components/SGnb/SGnb.d.ts +7 -1
- package/dist/components/SGnb/gnb.config.d.ts +23 -0
- package/dist/components/SGnb/index.d.ts +1 -1
- package/dist/index.cjs +254 -97
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +253 -98
- package/dist/index.js.map +1 -1
- package/dist/llms-full.txt +83 -7
- package/dist/llms.txt +43 -8
- package/dist/styles.css +97 -9
- package/dist/theme.css +7 -0
- package/eslint/rules/no-off-scale-spacing.mjs +114 -35
- package/package.json +3 -1
package/AGENTS.md
CHANGED
|
@@ -150,15 +150,16 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
|
|
|
150
150
|
|
|
151
151
|
### 2-2. 간격 (spacing)
|
|
152
152
|
|
|
153
|
-
- **간격 유틸리티는 `sd-` 접두를 붙인다** — `gap-sd-8`, `p-sd-
|
|
153
|
+
- **간격 유틸리티는 `sd-` 접두를 붙인다** — `gap-sd-8`, `p-sd-16`, `mt-sd-12`. 숫자 = px 다.
|
|
154
154
|
접두를 빼면 Tailwind 기본 스케일이 적용된다(`gap-8` = 32px). 접두는 속성 뒤, 숫자 앞에 온다.
|
|
155
155
|
- 스케일: `2 4 6 8 10 12 16 19 20 22 24 28 32 36 40 44 48 56 60 62 80`
|
|
156
|
+
- **스케일에 없는 간격이 필요하면 임의 값(`p-[64px]`)으로 우회하지 않는다.** 가까운 스케일 값으로 맞추거나, 디자인상 그 값이어야 하면 **토큰 추가를 요청한다.** 이미 있는 토큰을 정확히 써야 할 때만 `gap-[var(--토큰명)]` 으로 참조한다.
|
|
156
157
|
- 형제 요소 간격은 margin 대신 부모의 `flex`/`grid` + `gap-sd-*`으로 잡는다.
|
|
157
158
|
- 시맨틱 간격 토큰 (텍스트 덩어리·요소 사이 기본 리듬):
|
|
158
159
|
|
|
159
160
|
| 상황 | 값 |
|
|
160
161
|
| --- | --- |
|
|
161
|
-
| **페이지 콘텐츠 패딩** |
|
|
162
|
+
| **페이지 콘텐츠 패딩** | **16px — `SPage` 가 `--cmp-pageBody-padding` 으로 이미 넣는다.** 직접 주지 않는다 (덮어쓰면 토큰이 바뀌어도 안 따라간다). `SPage` 밖에서 같은 패딩이 필요하면 `p-sd-16` |
|
|
162
163
|
| **섹션 ↔ 섹션** | **`gap-sd-12`** |
|
|
163
164
|
| **페이지 내 블록 ↔ 블록** (헤더·필터·툴바·테이블 사이) | **`gap-sd-12`** |
|
|
164
165
|
| 요소 ↔ 요소 | **기본 `gap-sd-8`** (`--sys-space-stack-gap-element-normal`) · 타이트 `gap-sd-4`(`-tight`) · 여유 `gap-sd-12`(`-relaxed`) / `gap-sd-16`(`-wide`) |
|
|
@@ -338,7 +339,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
|
|
|
338
339
|
- 작은 창이 아니라 **화면 하나가 통째로** 들어간다 — 검색 필터·테이블·페이지네이션이 그대로 있는 목록(`엑셀 파일 관리`), 헤더 카드·탭이 있는 상세(`이동 오더 상세`).
|
|
339
340
|
- 상세를 팝업으로 여는 이유는 **목록을 떠나지 않고 여러 건을 번갈아 보기** 위해서다. 단 상세가 **항상** 팝업인 것은 아니고, 데이터 양이 많을 때 팝업을 쓴다.
|
|
340
341
|
- 구조는 헤더(제목 중앙) + 본문 + 푸터다. **확정할 작업이 있으면 푸터에 `저장`, 조회만이면 `useFooter={false}`** 로 푸터를 없앤다.
|
|
341
|
-
- 본문에는 패딩이 없다 — 콘텐츠가 여백을 담당한다. 팝업 안도 일반 페이지와 같은 규칙(§4)을 따른다: 패딩 `p-sd-
|
|
342
|
+
- 본문에는 패딩이 없다 — 콘텐츠가 여백을 담당한다. 팝업 안도 일반 페이지와 같은 규칙(§4)을 따른다: 패딩 `p-sd-16`(`SPage` 가 아니라 직접 준다), 블록 간격 `gap-sd-12`, 표는 `SKeyValueTable` / `STable`.
|
|
342
343
|
|
|
343
344
|
```tsx
|
|
344
345
|
// 1) 목록에서 별도 창을 연다 — 창 크기 = 콘텐츠 크기
|
|
@@ -354,7 +355,7 @@ function openDetailPopup(orderId: string) {
|
|
|
354
355
|
export default function TransferOrderPopupPage() {
|
|
355
356
|
return (
|
|
356
357
|
<SPopup popupTitle="이동 오더 상세" useFooter={false}>
|
|
357
|
-
<div className="flex flex-col gap-sd-12 p-sd-
|
|
358
|
+
<div className="flex flex-col gap-sd-12 p-sd-16">
|
|
358
359
|
<SSectionHeaderCard>…</SSectionHeaderCard>
|
|
359
360
|
<STabs value={tab} tabs={TABS} onValueChange={setTab} />
|
|
360
361
|
<STable columns={columns} rows={rows} rowKey="id" />
|
|
@@ -490,6 +491,8 @@ const columns: STableColumn[] = [
|
|
|
490
491
|
| 테이블 **행 내부** 인라인 액션 | `xs` |
|
|
491
492
|
| 화면·목록 액션 (툴바, `STableBar`) | `sm` |
|
|
492
493
|
| **모달·위저드 푸터** | `md` |
|
|
494
|
+
| **페이지 하단 실행 버튼** (폼 저장·상세 수정 등) | `md` |
|
|
495
|
+
| 스크롤 시 헤더로 승격된 버튼 | `sm` (최대) |
|
|
493
496
|
|
|
494
497
|
`lg` 는 현재 사용처가 없다. 페이지 골격에서 쓰지 않는다.
|
|
495
498
|
|
|
@@ -610,12 +613,42 @@ export default function AppShell({ children }: { children: React.ReactNode }) {
|
|
|
610
613
|
<SLayout type="box" header="fix">
|
|
611
614
|
{/* type/header/folded 는 SLayout 에만 준다 — SGnb 는 context 에서 읽는다 */}
|
|
612
615
|
<SGnb items={MENU} value={current} onValueChange={navigate} logo={<Logo />} />
|
|
613
|
-
|
|
616
|
+
{/* 콘텐츠 패딩(16px)은 SPage 가 토큰으로 넣는다 — p-sd-* 로 덮어쓰지 않는다 */}
|
|
617
|
+
<SPage background="frame">{children}</SPage>
|
|
614
618
|
</SLayout>
|
|
615
619
|
);
|
|
616
620
|
}
|
|
617
621
|
```
|
|
618
622
|
|
|
623
|
+
**상단바 배치는 `header` 가 정한다.** 요소 순서가 달라지므로 슬롯을 채우기 전에 어느 쪽인지부터 정한다.
|
|
624
|
+
|
|
625
|
+
| `header` | 상단바 배치 | 로고 폭 | `topContent` |
|
|
626
|
+
| --- | --- | --- | --- |
|
|
627
|
+
| `"fix"` (기본) | `[런처 · 로고 … 폴드]` — 상단바가 GNB 컬럼 안에 있고 폴드가 컬럼 오른쪽 끝 | 내용 폭 | **렌더되지 않는다** (놓을 자리가 없다) |
|
|
628
|
+
| `"full"` | `[런처 · 폴드 · 로고 · topContent]` — 상단바가 화면 전폭 | **140px 고정** (런처 없으면 172px) | 로고 오른쪽 남는 폭 전체 |
|
|
629
|
+
|
|
630
|
+
- `topContent` 는 상단바 로고 오른쪽 슬롯이다. 전역 검색·계정 메뉴·알림처럼 **모든 페이지에 공통인 것만** 넣는다. 페이지별 액션은 여기가 아니라 §4-2 의 `STableBar` 로 간다.
|
|
631
|
+
- 슬롯이 남는 폭을 통째로 받으므로 **정렬은 안에서 직접 잡는다** (좌측 정렬 + 우측은 `ml-auto`).
|
|
632
|
+
- `header="full"` 에서 로고 자리는 140px 로 고정된다 — 로고 내용이 바뀌어도 `topContent` 시작점이 흔들리지 않게 하기 위함이다. 로고가 그보다 넓으면 잘리므로 이 폭에 맞춰 준비한다.
|
|
633
|
+
- `onLauncherClick` 을 주지 않으면 런처가 렌더되지 않고, 그 자리(버튼 + 간격)를 로고 슬롯이 이어받아 172px 가 된다. `topContent` 시작점은 런처 유무와 관계없이 같은 자리다.
|
|
634
|
+
|
|
635
|
+
```tsx
|
|
636
|
+
<SLayout type="box" header="full">
|
|
637
|
+
<SGnb
|
|
638
|
+
items={MENU} value={current} onValueChange={navigate}
|
|
639
|
+
logo={<Logo />}
|
|
640
|
+
topContent={
|
|
641
|
+
/* 남는 폭 전체를 받는다 — 왼쪽은 그대로, 오른쪽 끝은 ml-auto */
|
|
642
|
+
<div className="flex w-full items-center gap-sd-8">
|
|
643
|
+
<SInput value={keyword} onValueChange={setKeyword} placeholder="통합 검색" />
|
|
644
|
+
<SButton size="sm" color="neutral" outline label="내 계정" className="ml-auto" onClick={openAccount} />
|
|
645
|
+
</div>
|
|
646
|
+
}
|
|
647
|
+
/>
|
|
648
|
+
<SPage background="frame">{children}</SPage>
|
|
649
|
+
</SLayout>
|
|
650
|
+
```
|
|
651
|
+
|
|
619
652
|
### 4-2. 목록 페이지 (필터 + 테이블)
|
|
620
653
|
|
|
621
654
|
구조: **페이지 헤더(제목 + 가이드 링크) → 필터(`SKeyValueTable`) → `STableBar` → `STable`**
|
|
@@ -874,7 +907,7 @@ export default function ProductDetailPage() {
|
|
|
874
907
|
- [ ] 간격이 전부 `sd-` 접두 스케일 값인가 (`gap-13`·`gap-sd-13` ❌ → `gap-sd-12` ✅)
|
|
875
908
|
- [ ] 본문이 12px(`typo-body-sm-default`)인가 (14px 본문 ❌)
|
|
876
909
|
- [ ] 텍스트 회색 위계를 순차 적용했는가 (기본 → `text-fg-secondary` → `text-fg-tertiary`, 단계 건너뛰기 ❌)
|
|
877
|
-
- [ ]
|
|
910
|
+
- [ ] `SPage` 의 기본 패딩(16px)을 `p-sd-*` 로 덮어쓰지 않았는가, 블록·섹션 간격이 `gap-sd-12` 인가 (`gap-sd-16`/`gap-sd-24` ❌)
|
|
878
911
|
- [ ] 같은 컴포넌트를 나열할 때 §2-2 그룹 간격을 썼는가 (체크박스 가로 `gap-sd-24` 등)
|
|
879
912
|
- [ ] 페이지가 §4의 표준 골격에서 시작했는가
|
|
880
913
|
- [ ] 필터·폼·상세 정보를 `SKeyValueTable` 로 만들었는가 (컨트롤을 `div` 로 나열하지 않았는가)
|
|
@@ -918,4 +951,6 @@ export default function ProductDetailPage() {
|
|
|
918
951
|
|
|
919
952
|
`gap-sd-13` 처럼 스케일 밖 값은 Tailwind v4 에서 **에러 없이 조용히 무시된다**. 반대로 접두를 빠뜨린 `gap-8` 은 Tailwind 기본 스케일이라 **32px 이 적용된다**. 둘 다 "간격이 왜 이러지" 로만 보이므로 반드시 `sd-` 접두 스케일 값을 쓴다. (린트는 기본값에서 앞쪽만 잡는다 — 뒤쪽까지 강제하려면 `requirePrefix: true`)
|
|
920
953
|
|
|
954
|
+
접두 누락은 **자동 수정되지 않는다.** `p-16` 은 지금 64px 로 동작하는 코드라 `p-sd-16`(16px)으로 바꾸면 여백이 달라지기 때문이다. 린트는 "숫자를 px 로 의도했나(`p-sd-16`)" 와 "현재 값을 유지할 건가(스케일에 있으면 그 값)" 를 제안으로 내놓으니 **의도에 맞는 쪽을 골라 적용한다.**
|
|
955
|
+
|
|
921
956
|
린트가 잡지 못하는 것(§3 컴포넌트 선택, §4 페이지 골격, 버튼 배치)은 §5 체크리스트로 직접 확인한다.
|
package/README.md
CHANGED
|
@@ -252,9 +252,25 @@ export default [...sellmate.configs.strict];
|
|
|
252
252
|
{ rules: { 'sellmate/no-off-scale-spacing': ['error', { requirePrefix: true }] } }
|
|
253
253
|
```
|
|
254
254
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
255
|
+
접두 없는 `p-16` 은 **깨진 코드가 아니라 Tailwind 기본 스케일로 64px 이 적용되는 코드**입니다. 이걸 `p-sd-16`(16px)으로 옮기는 것은 표기 정규화가 아니라 값 변경이라, **자동 수정하지 않고 두 해석을 제안(suggestion)으로만** 냅니다.
|
|
256
|
+
|
|
257
|
+
```text
|
|
258
|
+
`p-4` 은 현재 16px 입니다 (Tailwind 기본 스케일).
|
|
259
|
+
4px 을 의도했다면 → `p-sd-4`
|
|
260
|
+
16px 을 유지하려면 → `p-sd-16`
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
편집기에서 둘 중 하나를 골라 적용하고, 스케일에 없는 값이면 대응 토큰이 없다는 안내가 나옵니다.
|
|
264
|
+
|
|
265
|
+
#### 3.x 에서 한 번에 옮길 때
|
|
266
|
+
|
|
267
|
+
3.x 이하의 간격 스케일(숫자 = px)을 쓰던 앱은 `unsafeFix` 로 예전의 일괄 수정을 켤 수 있습니다.
|
|
268
|
+
|
|
269
|
+
```js
|
|
270
|
+
{ rules: { 'sellmate/no-off-scale-spacing': ['error', { requirePrefix: true, unsafeFix: true }] } }
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
> ⚠️ `unsafeFix` 는 **"클래스의 숫자 = px"** 를 단정해 `p-16` → `p-sd-16` 으로 바꿉니다. 기본 Tailwind 스케일(`p-4` = 16px)로 쓰던 앱에서 켜면 **여백이 1/4 로 줄어듭니다.** 마이그레이션 커밋에서만 켜고 `eslint --fix` 를 돌린 뒤 다시 끄세요.
|
|
258
274
|
|
|
259
275
|
## 제공 컴포넌트
|
|
260
276
|
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
|
|
22
22
|
- [SActionModal](../SActionModal)
|
|
23
23
|
- [SConfirmModal](../SConfirmModal)
|
|
24
|
+
- [SDrawer](../SDrawer)
|
|
24
25
|
- [SDropdownButton](../SDropdownButton)
|
|
25
26
|
- [SKeyValueTable](../SKeyValueTable)
|
|
26
27
|
- [SLoadingModal](../SLoadingModal)
|
|
@@ -39,6 +40,7 @@ graph TD;
|
|
|
39
40
|
SButton --> SIcon
|
|
40
41
|
SActionModal --> SButton
|
|
41
42
|
SConfirmModal --> SButton
|
|
43
|
+
SDrawer --> SButton
|
|
42
44
|
SDropdownButton --> SButton
|
|
43
45
|
SKeyValueTable --> SButton
|
|
44
46
|
SLoadingModal --> SButton
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# SDrawer
|
|
2
|
+
|
|
3
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
4
|
+
|
|
5
|
+
### SDrawer
|
|
6
|
+
|
|
7
|
+
#### Props
|
|
8
|
+
|
|
9
|
+
| Prop | Type | Default | Description |
|
|
10
|
+
|------|------|---------|-------------|
|
|
11
|
+
| `open?` | `boolean` | — | 표시 여부 |
|
|
12
|
+
| `persistent?` | `boolean` | `false` | true면 backdrop·ESC로 닫히지 않고 흔들림 효과를 준다. |
|
|
13
|
+
| `title?` | `string` | `''` | 접근성 제목 및 헤더 제목 |
|
|
14
|
+
| `width?` | `number \| string` | `572` | Drawer 너비. 기본값은 Figma drawer 기준 572px이다. |
|
|
15
|
+
| `footerLeft?` | `ReactNode` | — | footer 좌측 슬롯 |
|
|
16
|
+
| `button?` | `SDrawerButton` | — | 우측 기본 액션 버튼 |
|
|
17
|
+
| `children?` | `ReactNode` | — | |
|
|
18
|
+
| `className?` | `string` | — | |
|
|
19
|
+
| `style?` | `CSSProperties` | — | |
|
|
20
|
+
|
|
21
|
+
#### Events
|
|
22
|
+
|
|
23
|
+
| Event | Type | Description |
|
|
24
|
+
|-------|------|-------------|
|
|
25
|
+
| `onOpenChange` | `(open: boolean) => void` | 표시 상태 변경 |
|
|
26
|
+
| `onClose` | `() => void` | 닫기(X) 버튼 클릭 |
|
|
27
|
+
|
|
28
|
+
## Dependencies
|
|
29
|
+
|
|
30
|
+
### Depends on
|
|
31
|
+
|
|
32
|
+
- [SButton](../SButton)
|
|
33
|
+
- [SGhostButton](../SGhostButton)
|
|
34
|
+
|
|
35
|
+
### Graph
|
|
36
|
+
|
|
37
|
+
```mermaid
|
|
38
|
+
graph TD;
|
|
39
|
+
SDrawer --> SButton
|
|
40
|
+
SDrawer --> SGhostButton
|
|
41
|
+
style SDrawer fill:#f9f,stroke:#333,stroke-width:4px
|
|
42
|
+
```
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type CSSProperties, type ReactNode } from 'react';
|
|
2
|
+
import { type SButtonColor, type SButtonSize } from '../SButton';
|
|
3
|
+
export interface SDrawerButton {
|
|
4
|
+
label?: string;
|
|
5
|
+
color?: SButtonColor;
|
|
6
|
+
outline?: boolean;
|
|
7
|
+
size?: SButtonSize;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
onClick?: () => void;
|
|
10
|
+
}
|
|
11
|
+
export interface SDrawerProps {
|
|
12
|
+
/** 표시 여부 */
|
|
13
|
+
open?: boolean;
|
|
14
|
+
/** 표시 상태 변경 */
|
|
15
|
+
onOpenChange?: (open: boolean) => void;
|
|
16
|
+
/** 닫기(X) 버튼 클릭 */
|
|
17
|
+
onClose?: () => void;
|
|
18
|
+
/** true면 backdrop·ESC로 닫히지 않고 흔들림 효과를 준다. */
|
|
19
|
+
persistent?: boolean;
|
|
20
|
+
/** 접근성 제목 및 헤더 제목 */
|
|
21
|
+
title?: string;
|
|
22
|
+
/** Drawer 너비. 기본값은 Figma drawer 기준 572px이다. */
|
|
23
|
+
width?: number | string;
|
|
24
|
+
/** footer 좌측 슬롯 */
|
|
25
|
+
footerLeft?: ReactNode;
|
|
26
|
+
/** 우측 기본 액션 버튼 */
|
|
27
|
+
button?: SDrawerButton;
|
|
28
|
+
children?: ReactNode;
|
|
29
|
+
className?: string;
|
|
30
|
+
style?: CSSProperties;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* SDrawer — Figma drawer 포팅.
|
|
34
|
+
*
|
|
35
|
+
* 모달과 동일한 전역 modal host와 stack을 공유한다. 따라서 Drawer가 열린 상태에서
|
|
36
|
+
* 모달을 추가로 열면 새 모달이 Drawer 위에 쌓이고, Drawer 내부 floating은 전용 portal
|
|
37
|
+
* container를 통해 Drawer의 backdrop 위에 표시된다.
|
|
38
|
+
*/
|
|
39
|
+
export declare function SDrawer({ open, onOpenChange, onClose, persistent, title, width, footerLeft, button, children, className, style, }: SDrawerProps): import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SDrawer, type SDrawerButton, type SDrawerProps } from './SDrawer';
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
- [SCalendar](../SCalendar)
|
|
36
36
|
- [SChip](../SChip)
|
|
37
37
|
- [SDateRangePicker](../SDateRangePicker)
|
|
38
|
+
- [SDrawer](../SDrawer)
|
|
38
39
|
- [SFilePicker](../SFilePicker)
|
|
39
40
|
- [SGnb](../SGnb)
|
|
40
41
|
- [SGuide](../SGuide)
|
|
@@ -63,6 +64,7 @@ graph TD;
|
|
|
63
64
|
SCalendar --> SGhostButton
|
|
64
65
|
SChip --> SGhostButton
|
|
65
66
|
SDateRangePicker --> SGhostButton
|
|
67
|
+
SDrawer --> SGhostButton
|
|
66
68
|
SFilePicker --> SGhostButton
|
|
67
69
|
SGnb --> SGhostButton
|
|
68
70
|
SGuide --> SGhostButton
|
|
@@ -15,7 +15,8 @@
|
|
|
15
15
|
| `useRail?` | `boolean` | — | 좌측 레일 사용 여부. 켜면 items 의 첫 depth 가 아이콘+라벨 버튼의 세로 레일로 서고, 선택된 레일 아이템의 children 이 오른쪽 메뉴 패널에 깔린다. 미지정 시 SLayout 의 useRail 을 따른다. children 없는 레일 아이템이 활성이면 메뉴 패널은 렌더되지 않고 레일만 남는다. |
|
|
16
16
|
| `value?` | `string` | `''` | 현재 선택된 아이템 value |
|
|
17
17
|
| `folded?` | `boolean` | — | 접힘(레일) 상태. 미지정 시 SLayout 의 folded 를 따른다. |
|
|
18
|
-
| `logo?` | `ReactNode` | — | 상단바 로고 영역 (slot) |
|
|
18
|
+
| `logo?` | `ReactNode` | — | 상단바 로고 영역 (slot). header="full" 이면 폭이 140px 로 고정된다. |
|
|
19
|
+
| `topContent?` | `ReactNode` | — | 상단바 로고 오른쪽 슬롯 (검색·액션 등). 로고와 16px 띄고 남는 폭을 모두 차지하므로 안에서 자유롭게 정렬한다. 상단바가 전폭인 header="full" 에서만 렌더된다 (fix 는 상단바가 좁은 GNB 컬럼 안이라 놓을 자리가 없다). |
|
|
19
20
|
| `railFooter?` | `ReactNode` | — | 레일 하단 고정 슬롯. 레일 아이템이 많아 넘치면 아이템 목록(ul)만 스크롤되고 이 슬롯은 레일 하단에 붙어 고정된다. useRail 일 때만 렌더된다. |
|
|
20
21
|
| `menuFooter?` | `ReactNode` | — | 메뉴 하단 고정 슬롯. 메뉴 아이템이 많아 넘치면 메뉴 목록(ul)만 스크롤되고 이 슬롯은 메뉴 하단에 붙어 고정된다. 메뉴가 렌더될 때만(showMenu) 나타난다. |
|
|
21
22
|
| `foldedFooter?` | `ReactNode` | — | 접힘(fix 레일) 하단 고정 슬롯. 접으면 본문이 빠져나가며 rail/menu footer 도 사라지므로, 48px 폴드 레일 바닥에 붙는 별도 슬롯이다. header="fix" 로 접혔을 때만 나타난다. |
|
|
@@ -30,8 +30,14 @@ export interface SGnbProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color'>
|
|
|
30
30
|
onFoldChange?: (folded: boolean) => void;
|
|
31
31
|
/** 앱런처(그리드) 버튼 클릭. 미지정 시 런처 버튼을 렌더하지 않는다. 접힘 레일(fix)에는 폴드 버튼만 남으므로 표시되지 않는다. */
|
|
32
32
|
onLauncherClick?: () => void;
|
|
33
|
-
/** 상단바 로고 영역 (slot) */
|
|
33
|
+
/** 상단바 로고 영역 (slot). header="full" 이면 폭이 140px 로 고정된다. */
|
|
34
34
|
logo?: ReactNode;
|
|
35
|
+
/**
|
|
36
|
+
* 상단바 로고 오른쪽 슬롯 (검색·액션 등). 로고와 16px 띄고 남는 폭을 모두 차지하므로
|
|
37
|
+
* 안에서 자유롭게 정렬한다. 상단바가 전폭인 header="full" 에서만 렌더된다
|
|
38
|
+
* (fix 는 상단바가 좁은 GNB 컬럼 안이라 놓을 자리가 없다).
|
|
39
|
+
*/
|
|
40
|
+
topContent?: ReactNode;
|
|
35
41
|
/**
|
|
36
42
|
* 레일 하단 고정 슬롯. 레일 아이템이 많아 넘치면 아이템 목록(ul)만 스크롤되고
|
|
37
43
|
* 이 슬롯은 레일 하단에 붙어 고정된다. useRail 일 때만 렌더된다.
|
|
@@ -115,6 +115,29 @@ export declare const GNB_EXPAND_MS = 200;
|
|
|
115
115
|
* header="full" 에서 SLayout 이 "메뉴 오른쪽 = 페이지" 영역을 잡을 때도 이 값을 쓴다.
|
|
116
116
|
*/
|
|
117
117
|
export declare const GNB_MENU_WIDTH = 240;
|
|
118
|
+
/**
|
|
119
|
+
* header="full" 상단바의 로고 슬롯 고정 폭(토큰 없음 → 상수).
|
|
120
|
+
* 전폭 상단바에서는 로고 오른쪽에 topContent 슬롯이 이어지므로, 로고 내용이 바뀌어도
|
|
121
|
+
* 그 시작점이 흔들리지 않도록 자리를 못 박는다. fix 는 상단바가 GNB 컬럼 안이라 내용 폭을 따른다.
|
|
122
|
+
* 런처를 쓰지 않으면 그 자리를 로고가 이어받는다 → GNB_FULL_LOGO_WIDTH_NO_LAUNCHER.
|
|
123
|
+
*/
|
|
124
|
+
export declare const GNB_FULL_LOGO_WIDTH = 140;
|
|
125
|
+
/**
|
|
126
|
+
* 상단바에서 아이콘 버튼끼리 붙는 간격(px, 디자인 스펙 — 전용 토큰 없음).
|
|
127
|
+
* header="full" 의 런처↔폴드가 여기 해당한다. 슬롯(로고·topContent)과의 간격은
|
|
128
|
+
* 이보다 넓은 --cmp-gnb-top-gap 을 쓴다.
|
|
129
|
+
*/
|
|
130
|
+
export declare const GNB_TOP_ICON_GAP = 8;
|
|
131
|
+
/**
|
|
132
|
+
* 상단바 아이콘 버튼(xs 고스트) 폭 = --cmp-ghostButton-xs-size.
|
|
133
|
+
* 토큰이 CSS 변수라 JS 에서 더할 수 없어 값을 상수로 둔다(GNB_RAIL_WIDTH 와 같은 이유).
|
|
134
|
+
*/
|
|
135
|
+
export declare const GNB_TOP_ICON_SIZE = 24;
|
|
136
|
+
/**
|
|
137
|
+
* 런처를 쓰지 않는 header="full" 의 로고 슬롯 폭 = 기본 폭 + 런처가 비운 자리(버튼 + 간격).
|
|
138
|
+
* 런처 유무로 topContent 시작점이 32px 씩 밀리지 않도록, 빈 자리를 로고가 흡수한다.
|
|
139
|
+
*/
|
|
140
|
+
export declare const GNB_FULL_LOGO_WIDTH_NO_LAUNCHER: number;
|
|
118
141
|
/**
|
|
119
142
|
* useRail 에서 value 를 품은 첫 depth(레일) 아이템의 value.
|
|
120
143
|
* value 자체가 레일 아이템이면 그 값을, 어디에도 없으면 undefined 를 반환한다.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { SGnb, type SGnbProps } from './SGnb';
|
|
2
|
-
export { GNB_HEADER, GNB_MENU, GNB_COLORS, GNB_COMMON, GNB_FOLD_MS, GNB_MENU_WIDTH, GNB_RAIL, GNB_RAIL_WIDTH, findGnbAncestors, findGnbRailValue, type SGnbType, type SGnbHeader, type SGnbColor, type SGnbMenuItem, } from './gnb.config';
|
|
2
|
+
export { GNB_HEADER, GNB_MENU, GNB_COLORS, GNB_COMMON, GNB_FOLD_MS, GNB_FULL_LOGO_WIDTH, GNB_MENU_WIDTH, GNB_RAIL, GNB_RAIL_WIDTH, findGnbAncestors, findGnbRailValue, type SGnbType, type SGnbHeader, type SGnbColor, type SGnbMenuItem, } from './gnb.config';
|