sellmate-design-system-react 4.3.1 → 5.0.2

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.
Files changed (38) hide show
  1. package/AGENTS.md +18 -0
  2. package/README.md +2 -2
  3. package/dist/components/SActionModal/README.md +6 -4
  4. package/dist/components/SActionModal/SActionModal.d.ts +3 -12
  5. package/dist/components/SActionModal/index.d.ts +1 -1
  6. package/dist/components/SButton/README.md +2 -6
  7. package/dist/components/SConfirmModal/README.md +1 -1
  8. package/dist/components/SConfirmModal/SConfirmModal.d.ts +1 -1
  9. package/dist/components/SDrawer/README.md +8 -5
  10. package/dist/components/SDrawer/SDrawer.d.ts +14 -11
  11. package/dist/components/SFooter/README.md +40 -0
  12. package/dist/components/SFooter/SFooter.d.ts +36 -0
  13. package/dist/components/SFooter/index.d.ts +1 -0
  14. package/dist/components/SGhostButton/README.md +2 -2
  15. package/dist/components/SGnb/README.md +0 -5
  16. package/dist/components/SGnb/SGnb.d.ts +6 -2
  17. package/dist/components/SGnb/gnb.config.d.ts +2 -0
  18. package/dist/components/SLayout/README.md +1 -6
  19. package/dist/components/SLayout/SLayout.d.ts +39 -17
  20. package/dist/components/SLoadingModal/README.md +1 -1
  21. package/dist/components/SLoadingModal/SLoadingModal.d.ts +1 -1
  22. package/dist/components/SModalContainer/README.md +1 -1
  23. package/dist/components/SModalContainer/SModalContainer.d.ts +6 -2
  24. package/dist/components/SOverlayHeader/README.md +45 -0
  25. package/dist/components/SOverlayHeader/SOverlayHeader.d.ts +28 -0
  26. package/dist/components/SOverlayHeader/index.d.ts +1 -0
  27. package/dist/components/SPage/SPage.d.ts +2 -2
  28. package/dist/components/SPopup/README.md +2 -2
  29. package/dist/index.cjs +405 -251
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.js +405 -251
  32. package/dist/index.js.map +1 -1
  33. package/dist/lib/isomorphic-layout-effect.d.ts +8 -0
  34. package/dist/llms-full.txt +109 -23
  35. package/dist/llms.txt +18 -0
  36. package/dist/styles.css +32 -22
  37. package/dist/theme.css +5 -5
  38. package/package.json +1 -1
package/AGENTS.md CHANGED
@@ -396,6 +396,24 @@ SModal.create({ component: OrderModal, componentProps: { orderId } })
396
396
  .onDismissed(() => {});
397
397
  ```
398
398
 
399
+ #### 3-3-5. 닫기 경로 — `persistent` 는 기본이 `true` 다
400
+
401
+ 모달 3종(`SActionModal` · `SConfirmModal` · `SLoadingModal`)과 `SDrawer` 는 **백드롭 클릭·ESC 로 닫히지 않는 것이 기본**이다. 닫기 시도는 흔들림(shake)으로만 반응한다. 작성 중인 내용을 실수로 잃지 않게 하기 위한 것이다.
402
+
403
+ | | 기본 닫기 경로 | 백드롭·ESC |
404
+ | --- | --- | --- |
405
+ | `SActionModal` · `SConfirmModal` · `SLoadingModal` | X 버튼, 모달 안의 버튼 | 막힘 (흔들림) |
406
+ | `SDrawer` | X 버튼, footer 버튼 | 막힘 (흔들림) |
407
+ | `SPopover` · `STooltip` · `SSelect` 등 floating | 바깥 클릭·ESC | **막지 않는다** — 이 규칙의 대상이 아니다 |
408
+
409
+ 따라서 다음을 지킨다.
410
+
411
+ - **닫을 수단을 반드시 하나는 둔다.** `SActionModal` 에 `showClose` 도 `button`/`footerLeft` 도 없으면 사용자가 모달을 닫을 방법이 없다. 백드롭이 더 이상 탈출구가 아니다.
412
+ - **`persistent` 를 `true` 로 직접 주지 않는다.** 기본값이므로 중복이다.
413
+ - **`persistent={false}` 는 잃을 입력이 없을 때만.** 단순 알림처럼 임의로 닫혀도 아무것도 사라지지 않는 경우로 한정한다.
414
+
415
+ 작성 중인 내용이 있을 때 닫기를 시도하면 이탈 안내를 띄우는 것은 **소비 앱 몫**이다. 디자인 시스템은 dirty 상태를 알지 못하므로 백드롭·ESC 를 일괄 차단할 뿐이다. 안내가 필요하면 앱이 자체 dirty 판정 후 `SModal.confirm` 으로 띄운다.
416
+
399
417
  ### 3-4. 테이블 컬럼 정렬
400
418
 
401
419
  **값의 크기를 비교하는 숫자 컬럼은 예외 없이 오른쪽 정렬한다** (`align: 'right'`).
package/README.md CHANGED
@@ -281,14 +281,14 @@ export default [...sellmate.configs.strict];
281
281
  | Atoms | `SIcon` · `SBadge` · `SCard` · `SDraggableItem` · `SDraggableList` · `SExpansionItem` · `SExpansionList` · `SList` · `SListItem` · `STree` · `SSectionHeaderCard` · `SDivider` · `SScrollArea` · `STag` · `SButton` · `SCallout` · `SLinearProgress` · `SCircleProgress` · `SLoadingContainer` |
282
282
  | Control | `STextLink` · `SDropdownButton` · `SGhostButton` · `SSwitch` · `SToggle` |
283
283
  | Overlays | `STooltip` · `SPopover` · `SPortal` · `SPopup` · `SGuide` |
284
- | Modals | `SConfirmModal` · `SActionModal` · `SLoadingModal` · `SModal` |
284
+ | Modals | `SConfirmModal` · `SActionModal` · `SLoadingModal` · `SDrawer` · `SModal` |
285
285
  | Layout | `SGnb` · `SLayout` · `SPage` |
286
286
  | Navigation | `STabs` · `SPagination` · `SStepper` |
287
287
  | Data | `STable` · `STableBar` · `SKeyValueTable` |
288
288
  | Feedback | `SToast` |
289
289
  | SField (폼) | `SForm` · `SField` · `SCheckbox` · `SRadio` · `SRadioButton` · `SInput` · `STextarea` · `SSelect` · `SNumberInput` · `SChip` · `SChipInput` · `SBarcodeInput` · `SCalendar` · `SDatePicker` · `SDateRangePicker` · `STimePicker` · `STimeRangePicker` · `SFilePicker` |
290
290
 
291
- `SModalContainer` 는 모달 3종의 내부 공통 컨테이너로 **공개 export 가 아닙니다.** 소비자는 `SConfirmModal`/`SActionModal`/`SLoadingModal` 을 사용하세요.
291
+ `SModalContainer` 는 모달 3종의 내부 공통 컨테이너로 **공개 export 가 아닙니다.** `SOverlayHeader` 는 모달·드로어 내부 제목 영역, `SFooter` 는 모달·드로어·팝업 하단 액션 영역 조합용 컴포넌트라 public export 에 포함하지 않습니다. 소비자는 `SConfirmModal`/`SActionModal`/`SLoadingModal`/`SDrawer`/`SPopup` 을 사용하세요.
292
292
 
293
293
  유틸리티도 함께 export 합니다.
294
294
 
@@ -9,10 +9,10 @@
9
9
  | Prop | Type | Default | Description |
10
10
  |------|------|---------|-------------|
11
11
  | `open?` | `boolean` | — | |
12
- | `persistent?` | `boolean` | — | true면 백드롭·ESC로 안 닫히고 흔들림 (sd-modal-container persistent) |
12
+ | `persistent?` | `boolean` | — | 백드롭·ESC로 안 닫히고 흔들림 (sd-modal-container persistent). **기본값 true** |
13
13
  | `modalTitle?` | `string` | `''` | |
14
14
  | `description?` | `ReactNode` | — | 제목 오른쪽에 붙는 보조 설명 (sd-action-modal 의 header-sub-title 슬롯). 문자열이면 서브텍스트 스타일로 렌더하고, 노드를 넘기면 그대로 배치한다. |
15
- | `button?` | `SActionModalButton` | — | 하단 액션 버튼 (주 액션 1개). 의도적으로 단수다 — 보조 버튼(취소·삭제 등)은 `footerLeft` 슬롯에 직접 배치한다. |
15
+ | `button?` | `SFooterButton` | — | 하단 액션 버튼 (주 액션 1개). 의도적으로 단수다 — 보조 버튼(취소·삭제 등)은 `footerLeft` 슬롯에 직접 배치한다. |
16
16
  | `footerLeft?` | `ReactNode` | — | footer 좌측 영역 (sd-action-modal 의 bottom-sub-content 슬롯). 보조 버튼이나 안내 문구를 넣는다. 버튼을 하나 더 쓰고 싶을 때 여기에 SButton 을 넣는다. |
17
17
  | `width?` | `number \| string` | — | |
18
18
  | `height?` | `number \| string` | — | |
@@ -29,14 +29,16 @@
29
29
 
30
30
  ### Depends on
31
31
 
32
- - [SButton](../SButton)
32
+ - [SFooter](../SFooter)
33
33
  - [SModalContainer](../SModalContainer)
34
+ - [SOverlayHeader](../SOverlayHeader)
34
35
 
35
36
  ### Graph
36
37
 
37
38
  ```mermaid
38
39
  graph TD;
39
- SActionModal --> SButton
40
+ SActionModal --> SFooter
40
41
  SActionModal --> SModalContainer
42
+ SActionModal --> SOverlayHeader
41
43
  style SActionModal fill:#f9f,stroke:#333,stroke-width:4px
42
44
  ```
@@ -1,20 +1,11 @@
1
1
  import { type ReactNode } from 'react';
2
- import { type SButtonColor, type SButtonSize } from '../SButton';
3
- export interface SActionModalButton {
4
- label?: string;
5
- color?: SButtonColor;
6
- outline?: boolean;
7
- size?: SButtonSize;
8
- disabled?: boolean;
9
- /** 클릭 핸들러. 모달은 자동으로 닫히지 않으므로 닫는 시점은 onOpenChange 로 직접 제어한다 */
10
- onClick?: () => void;
11
- }
2
+ import { type SFooterButton } from '../SFooter';
12
3
  export interface SActionModalProps {
13
4
  open?: boolean;
14
5
  onOpenChange?: (open: boolean) => void;
15
6
  /** 닫기(X) 버튼 클릭 (sdClose) */
16
7
  onClose?: () => void;
17
- /** true면 백드롭·ESC로 안 닫히고 흔들림 (sd-modal-container persistent) */
8
+ /** 백드롭·ESC로 안 닫히고 흔들림 (sd-modal-container persistent). **기본값 true** */
18
9
  persistent?: boolean;
19
10
  modalTitle?: string;
20
11
  /**
@@ -26,7 +17,7 @@ export interface SActionModalProps {
26
17
  * 하단 액션 버튼 (주 액션 1개).
27
18
  * 의도적으로 단수다 — 보조 버튼(취소·삭제 등)은 `footerLeft` 슬롯에 직접 배치한다.
28
19
  */
29
- button?: SActionModalButton;
20
+ button?: SFooterButton;
30
21
  /**
31
22
  * footer 좌측 영역 (sd-action-modal 의 bottom-sub-content 슬롯).
32
23
  * 보조 버튼이나 안내 문구를 넣는다. 버튼을 하나 더 쓰고 싶을 때 여기에 SButton 을 넣는다.
@@ -1 +1 @@
1
- export { SActionModal, type SActionModalProps, type SActionModalButton } from './SActionModal';
1
+ export { SActionModal, type SActionModalProps } from './SActionModal';
@@ -19,14 +19,12 @@
19
19
 
20
20
  ### Used by
21
21
 
22
- - [SActionModal](../SActionModal)
23
22
  - [SConfirmModal](../SConfirmModal)
24
- - [SDrawer](../SDrawer)
25
23
  - [SDropdownButton](../SDropdownButton)
24
+ - [SFooter](../SFooter)
26
25
  - [SKeyValueTable](../SKeyValueTable)
27
26
  - [SLoadingModal](../SLoadingModal)
28
27
  - [SPopover](../SPopover)
29
- - [SPopup](../SPopup)
30
28
  - [SToast](../SToast)
31
29
 
32
30
  ### Depends on
@@ -38,14 +36,12 @@
38
36
  ```mermaid
39
37
  graph TD;
40
38
  SButton --> SIcon
41
- SActionModal --> SButton
42
39
  SConfirmModal --> SButton
43
- SDrawer --> SButton
44
40
  SDropdownButton --> SButton
41
+ SFooter --> SButton
45
42
  SKeyValueTable --> SButton
46
43
  SLoadingModal --> SButton
47
44
  SPopover --> SButton
48
- SPopup --> SButton
49
45
  SToast --> SButton
50
46
  style SButton fill:#f9f,stroke:#333,stroke-width:4px
51
47
  ```
@@ -9,7 +9,7 @@
9
9
  | Prop | Type | Default | Description |
10
10
  |------|------|---------|-------------|
11
11
  | `open?` | `boolean` | — | |
12
- | `persistent?` | `boolean` | — | true면 백드롭·ESC로 안 닫히고 흔들림 (sd-modal-container persistent) |
12
+ | `persistent?` | `boolean` | — | 백드롭·ESC로 안 닫히고 흔들림 (sd-modal-container persistent). **기본값 true** |
13
13
  | `type?` | `SConfirmModalType` | `'positive'` | 타입 (아이콘·메인버튼 색 결정) |
14
14
  | `modalTitle?` | `string` | `''` | |
15
15
  | `titleClass?` | `string` | — | 제목 엘리먼트에 추가할 클래스 (sd-confirm-modal titleClass) |
@@ -6,7 +6,7 @@ export type ConfirmModalMainButton = 'primary_md' | 'primary_outline_md' | 'dang
6
6
  export interface SConfirmModalProps {
7
7
  open?: boolean;
8
8
  onOpenChange?: (open: boolean) => void;
9
- /** true면 백드롭·ESC로 안 닫히고 흔들림 (sd-modal-container persistent) */
9
+ /** 백드롭·ESC로 안 닫히고 흔들림 (sd-modal-container persistent). **기본값 true** */
10
10
  persistent?: boolean;
11
11
  /** 타입 (아이콘·메인버튼 색 결정) */
12
12
  type?: SConfirmModalType;
@@ -9,9 +9,12 @@
9
9
  | Prop | Type | Default | Description |
10
10
  |------|------|---------|-------------|
11
11
  | `open?` | `boolean` | — | 표시 여부 |
12
- | `persistent?` | `boolean` | `false` | true면 backdrop·ESC로 닫히지 않고 흔들림 효과를 준다. |
12
+ | `persistent?` | `boolean` | `true` | backdrop·ESC로 닫히지 않고 흔들림 효과를 준다. **기본값 true** — Drawer는 내용을 작성·구성하는 곳이라 임의 닫힘을 막는 것이 기본이다. 닫기 경로는 X 버튼과 footer 버튼뿐이다. false로 주면 backdrop·ESC 닫기가 열린다. |
13
13
  | `title?` | `string` | `''` | 접근성 제목 및 헤더 제목 |
14
14
  | `width?` | `number \| string` | `572` | Drawer 너비. 기본값은 Figma drawer 기준 572px이다. |
15
+ | `resizable?` | `boolean` | `false` | true면 왼쪽 테두리를 드래그해 너비를 조절할 수 있다. |
16
+ | `minWidth?` | `number \| string` | — | 리사이즈 가능한 최소 너비(px, %, vw, vh) |
17
+ | `maxWidth?` | `number \| string` | — | 리사이즈 가능한 최대 너비(px, %, vw, vh) |
15
18
  | `footerLeft?` | `ReactNode` | — | footer 좌측 슬롯 |
16
19
  | `button?` | `SDrawerButton` | — | 우측 기본 액션 버튼 |
17
20
  | `children?` | `ReactNode` | — | |
@@ -29,14 +32,14 @@
29
32
 
30
33
  ### Depends on
31
34
 
32
- - [SButton](../SButton)
33
- - [SGhostButton](../SGhostButton)
35
+ - [SFooter](../SFooter)
36
+ - [SOverlayHeader](../SOverlayHeader)
34
37
 
35
38
  ### Graph
36
39
 
37
40
  ```mermaid
38
41
  graph TD;
39
- SDrawer --> SButton
40
- SDrawer --> SGhostButton
42
+ SDrawer --> SFooter
43
+ SDrawer --> SOverlayHeader
41
44
  style SDrawer fill:#f9f,stroke:#333,stroke-width:4px
42
45
  ```
@@ -1,13 +1,6 @@
1
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
- }
2
+ import { type SFooterButton } from '../SFooter';
3
+ export type SDrawerButton = SFooterButton;
11
4
  export interface SDrawerProps {
12
5
  /** 표시 여부 */
13
6
  open?: boolean;
@@ -15,12 +8,22 @@ export interface SDrawerProps {
15
8
  onOpenChange?: (open: boolean) => void;
16
9
  /** 닫기(X) 버튼 클릭 */
17
10
  onClose?: () => void;
18
- /** true면 backdrop·ESC로 닫히지 않고 흔들림 효과를 준다. */
11
+ /**
12
+ * backdrop·ESC로 닫히지 않고 흔들림 효과를 준다.
13
+ * **기본값 true** — Drawer는 내용을 작성·구성하는 곳이라 임의 닫힘을 막는 것이 기본이다.
14
+ * 닫기 경로는 X 버튼과 footer 버튼뿐이다. false로 주면 backdrop·ESC 닫기가 열린다.
15
+ */
19
16
  persistent?: boolean;
20
17
  /** 접근성 제목 및 헤더 제목 */
21
18
  title?: string;
22
19
  /** Drawer 너비. 기본값은 Figma drawer 기준 572px이다. */
23
20
  width?: number | string;
21
+ /** true면 왼쪽 테두리를 드래그해 너비를 조절할 수 있다. */
22
+ resizable?: boolean;
23
+ /** 리사이즈 가능한 최소 너비(px, %, vw, vh) */
24
+ minWidth?: number | string;
25
+ /** 리사이즈 가능한 최대 너비(px, %, vw, vh) */
26
+ maxWidth?: number | string;
24
27
  /** footer 좌측 슬롯 */
25
28
  footerLeft?: ReactNode;
26
29
  /** 우측 기본 액션 버튼 */
@@ -36,4 +39,4 @@ export interface SDrawerProps {
36
39
  * 모달을 추가로 열면 새 모달이 Drawer 위에 쌓이고, Drawer 내부 floating은 전용 portal
37
40
  * container를 통해 Drawer의 backdrop 위에 표시된다.
38
41
  */
39
- export declare function SDrawer({ open, onOpenChange, onClose, persistent, title, width, footerLeft, button, children, className, style, }: SDrawerProps): import("react").JSX.Element;
42
+ export declare function SDrawer({ open, onOpenChange, onClose, persistent, title, width, resizable, minWidth, maxWidth, footerLeft, button, children, className, style, }: SDrawerProps): import("react").JSX.Element;
@@ -0,0 +1,40 @@
1
+ # SFooter
2
+
3
+ > 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
4
+
5
+ ### SFooter
6
+
7
+ #### Props
8
+
9
+ | Prop | Type | Default | Description |
10
+ |------|------|---------|-------------|
11
+ | `bg?` | `SFooterBg` | `'white'` | 배경색 |
12
+ | `left?` | `ReactNode` | — | footer 좌측 slot |
13
+ | `children?` | `ReactNode` | — | footer 좌측 slot. left와 함께 쓰면 left 뒤에 렌더된다 |
14
+ | `button?` | `SFooterButton` | — | 우측 기본 액션 버튼 |
15
+ | `className?` | `string` | — | |
16
+ | `leftClassName?` | `string` | — | |
17
+ | `style?` | `CSSProperties` | — | |
18
+
19
+ ## Dependencies
20
+
21
+ ### Used by
22
+
23
+ - [SActionModal](../SActionModal)
24
+ - [SDrawer](../SDrawer)
25
+ - [SPopup](../SPopup)
26
+
27
+ ### Depends on
28
+
29
+ - [SButton](../SButton)
30
+
31
+ ### Graph
32
+
33
+ ```mermaid
34
+ graph TD;
35
+ SFooter --> SButton
36
+ SActionModal --> SFooter
37
+ SDrawer --> SFooter
38
+ SPopup --> SFooter
39
+ style SFooter fill:#f9f,stroke:#333,stroke-width:4px
40
+ ```
@@ -0,0 +1,36 @@
1
+ import { type CSSProperties, type ReactNode } from 'react';
2
+ import { type SButtonColor, type SButtonSize } from '../SButton';
3
+ export type SFooterBg = 'white' | 'grey';
4
+ export interface SFooterButton {
5
+ label?: string;
6
+ color?: SButtonColor;
7
+ outline?: boolean;
8
+ size?: SButtonSize;
9
+ disabled?: boolean;
10
+ onClick?: () => void;
11
+ }
12
+ /**
13
+ * @internal
14
+ * 모달·드로어·팝업 하단 영역 공통 props.
15
+ */
16
+ export interface SFooterProps {
17
+ /** 배경색 */
18
+ bg?: SFooterBg;
19
+ /** footer 좌측 slot */
20
+ left?: ReactNode;
21
+ /** footer 좌측 slot. left와 함께 쓰면 left 뒤에 렌더된다 */
22
+ children?: ReactNode;
23
+ /** 우측 기본 액션 버튼 */
24
+ button?: SFooterButton;
25
+ className?: string;
26
+ leftClassName?: string;
27
+ style?: CSSProperties;
28
+ }
29
+ /**
30
+ * SFooter — overlay 계열 내부 전용 footer.
31
+ *
32
+ * @internal
33
+ * SActionModal/SConfirmModal/SDrawer/SPopup 의 하단 액션 영역만 공통화한다.
34
+ * 패키지 public export 에 추가하지 말 것.
35
+ */
36
+ export declare function SFooter({ bg, left, button, children, className, leftClassName, style, }: SFooterProps): import("react").JSX.Element;
@@ -0,0 +1 @@
1
+ export { SFooter, type SFooterBg, type SFooterButton, type SFooterProps } from './SFooter';
@@ -35,12 +35,12 @@
35
35
  - [SCalendar](../SCalendar)
36
36
  - [SChip](../SChip)
37
37
  - [SDateRangePicker](../SDateRangePicker)
38
- - [SDrawer](../SDrawer)
39
38
  - [SFilePicker](../SFilePicker)
40
39
  - [SGnb](../SGnb)
41
40
  - [SGuide](../SGuide)
42
41
  - [SInput](../SInput)
43
42
  - [SModalContainer](../SModalContainer)
43
+ - [SOverlayHeader](../SOverlayHeader)
44
44
  - [SPopover](../SPopover)
45
45
  - [SSelect](../SSelect)
46
46
  - [STimePicker](../STimePicker)
@@ -64,12 +64,12 @@ graph TD;
64
64
  SCalendar --> SGhostButton
65
65
  SChip --> SGhostButton
66
66
  SDateRangePicker --> SGhostButton
67
- SDrawer --> SGhostButton
68
67
  SFilePicker --> SGhostButton
69
68
  SGnb --> SGhostButton
70
69
  SGuide --> SGhostButton
71
70
  SInput --> SGhostButton
72
71
  SModalContainer --> SGhostButton
72
+ SOverlayHeader --> SGhostButton
73
73
  SPopover --> SGhostButton
74
74
  SSelect --> SGhostButton
75
75
  STimePicker --> SGhostButton
@@ -33,10 +33,6 @@
33
33
 
34
34
  ## Dependencies
35
35
 
36
- ### Used by
37
-
38
- - [SLayout](../SLayout)
39
-
40
36
  ### Depends on
41
37
 
42
38
  - [SGhostButton](../SGhostButton)
@@ -52,6 +48,5 @@ graph TD;
52
48
  SGnb --> SIcon
53
49
  SGnb --> SLayout
54
50
  SGnb --> STag
55
- SLayout --> SGnb
56
51
  style SGnb fill:#f9f,stroke:#333,stroke-width:4px
57
52
  ```
@@ -73,7 +73,11 @@ export interface SGnbProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color'>
73
73
  * 접힘/펼침은 GNB_FOLD_MS 동안의 슬라이드다 — 레일·메뉴가 함께 왼쪽으로 빠져나가고 펼치면 오른쪽에서 들어온다.
74
74
  * 페이지 쪽 폭은 fix 면 이 컴포넌트의 폭 전환이, full 이면 SLayout 의 메뉴 열 전환이 같은 길이로 맞춘다.
75
75
  *
76
- * SLayout 안에서 쓰면 type·header·folded 를 context 에서 읽어 앱이 중복으로 넘길 필요가 없다.
77
- * SLayout 없이 단독으로도 동작한다(prop 또는 기본값 사용).
76
+ * SLayout 안에서 쓰면 type·header·folded 를 context 에서 읽어 앱이 중복으로 넘길 필요가 없고,
77
+ * 자기 치수(컬럼 폭·상단바 높이·전환 길이)를 registerNav 로 되올려 프레임이 그 값으로 그리드를 깐다.
78
+ *
79
+ * SLayout 없이 단독으로도 동작한다(prop 또는 기본값 사용). 단 full 을 **페이지와 나란히** 놓으려면
80
+ * SLayout 이 필요하다 — 그 안에서만 루트를 display:contents 로 지워 상단바·본문을 프레임 그리드의
81
+ * header/nav 셀에 앉힌다. 단독일 때는 루트가 전폭 세로 상자로 남아 [상단바 / 본문] 을 스스로 쌓는다.
78
82
  */
79
83
  export declare const SGnb: import("react").ForwardRefExoticComponent<SGnbProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -143,5 +143,7 @@ export declare const GNB_FULL_LOGO_WIDTH_NO_LAUNCHER: number;
143
143
  * value 자체가 레일 아이템이면 그 값을, 어디에도 없으면 undefined 를 반환한다.
144
144
  */
145
145
  export declare function findGnbRailValue(items: SGnbMenuItem[], value: string): string | undefined;
146
+ /** value 를 가진 아이템의 형제(같은 부모의 나머지 아이템) value 목록을 반환 → 아코디언 펼침용 */
147
+ export declare function findGnbSiblingValues(items: SGnbMenuItem[], value: string): string[];
146
148
  /** value 로 선택된 아이템의 조상 value 목록(자기 자신 제외)을 반환 → 자동 펼침용 */
147
149
  export declare function findGnbAncestors(items: SGnbMenuItem[], value: string): string[];
@@ -10,7 +10,7 @@
10
10
  |------|------|---------|-------------|
11
11
  | `type?` | `SLayoutType` | `'box'` | 메뉴 스타일: box(라운드) / belt(풀폭 행). 자식 SGnb 가 이 값을 따른다. |
12
12
  | `header?` | `SLayoutHeader` | `'fix'` | 레이아웃 구조: fix(가로 분할) / full(풀폭 상단바). 자식 SGnb·SPage 가 이 값을 따른다. |
13
- | `useRail?` | `boolean` | `false` | GNB 좌측 레일 사용 여부. 자식 SGnb 가 이 값을 따르고, full 메뉴 폭도 레일만큼 넓어진다. 레일에 children 없는 아이템이 있으면 SGnb 가 header 를 full 강제하고, 이 레이아웃도 그에 맞춰 full 그리드로 선다. |
13
+ | `useRail?` | `boolean` | `false` | GNB 좌측 레일 사용 여부. 자식 SGnb 가 이 값을 따르고, 그만큼 넓어진 컬럼 폭을 되올린다. 레일에 children 없는 아이템이 있으면 SGnb 가 full 상단바를 요구하고, 이 레이아웃도 그에 맞춰 full 그리드로 선다. |
14
14
  | `folded?` | `boolean` | — | GNB 접힘 상태 (controlled) |
15
15
  | `defaultFolded?` | `boolean` | `false` | GNB 초기 접힘 상태 (uncontrolled) |
16
16
 
@@ -27,15 +27,10 @@
27
27
  - [SGnb](../SGnb)
28
28
  - [SPage](../SPage)
29
29
 
30
- ### Depends on
31
-
32
- - [SGnb](../SGnb)
33
-
34
30
  ### Graph
35
31
 
36
32
  ```mermaid
37
33
  graph TD;
38
- SLayout --> SGnb
39
34
  SGnb --> SLayout
40
35
  SPage --> SLayout
41
36
  style SLayout fill:#f9f,stroke:#333,stroke-width:4px
@@ -1,32 +1,51 @@
1
1
  import { type HTMLAttributes } from 'react';
2
- import { type SGnbHeader, type SGnbType } from '../SGnb/gnb.config';
2
+ import type { SGnbHeader, SGnbType } from '../SGnb/gnb.config';
3
3
  /** 메뉴 스타일: box(라운드) / belt(풀폭 행) — 자식 SGnb 의 메뉴 모양 */
4
4
  export type SLayoutType = SGnbType;
5
5
  /** 레이아웃 구조: fix(좌측 GNB + 페이지 가로 분할) / full(풀폭 상단바 + 아래에 메뉴|페이지) */
6
6
  export type SLayoutHeader = SGnbHeader;
7
+ /**
8
+ * 자식 GNB 가 SLayout 에 올리는 자기 치수·요구사항.
9
+ *
10
+ * SLayout 은 GNB 의 내부 상수(레일·메뉴 폭, 상단바 높이, 전환 길이)도 items·activeRail 도 모른다 —
11
+ * 치수를 아는 쪽이 올리고 프레임은 받아 쓰기만 한다. GNB 내부 치수가 바뀌어도 프레임은 따라온다.
12
+ */
13
+ export interface SLayoutNavState {
14
+ /**
15
+ * 펼친 GNB 컬럼 폭(px). 레일·메뉴 유무를 반영한 합이다.
16
+ * 접힘은 SLayout 이 folded 로 따로 접으므로 여기엔 펼친 폭만 담는다.
17
+ */
18
+ columnWidth: number;
19
+ /** 상단바 높이(CSS 길이) — header="full" 그리드의 1행 높이가 된다. */
20
+ topHeight: string;
21
+ /** 접힘 전환 길이(ms) — 페이지 열이 메뉴와 같은 길이로 미끄러지도록 맞춘다. */
22
+ foldMs: number;
23
+ /**
24
+ * 상단바가 레이아웃 전폭이어야 하는지.
25
+ * 레일에 리프 아이템이 있으면 메뉴 폭이 출렁여 fix 상단바가 함께 흔들리므로 GNB 가 true 로 올린다.
26
+ * true 면 header prop 과 무관하게 full 로 선다.
27
+ */
28
+ requireFullHeader: boolean;
29
+ }
7
30
  export interface SLayoutContextValue {
8
31
  /** 메뉴 스타일 — 자식 SGnb 가 스타일을 맞추는 기준 */
9
32
  type: SLayoutType;
10
33
  /**
11
34
  * 상단바 구조 — 자식 SGnb·SPage 가 배치를 맞추는 기준(유효 header).
12
- * 레일에 children 없는 아이템이 있어 SGnb full 강제하면 여기에도 full 로 반영된다.
35
+ * 등록된 GNBrequireFullHeader 올리면 여기에도 full 로 반영된다.
13
36
  */
14
37
  header: SLayoutHeader;
15
- /** GNB 좌측 레일 사용 여부 — 자식 SGnb 가 따르고, header="full" 의 메뉴 열 폭도 이 값을 반영한다 */
38
+ /** GNB 좌측 레일 사용 여부 — 자식 SGnb 가 따른다 */
16
39
  useRail: boolean;
17
40
  /** GNB 접힘 상태 */
18
41
  folded: boolean;
19
42
  /** 접힘 상태 변경 */
20
43
  setFolded: (folded: boolean) => void;
21
44
  /**
22
- * 자식 SGnb런타임 배치 상태를 알린다(SLayout items·activeRail 모른다).
23
- * - forceFull: 레일에 리프(children 없는) 아이템이 있어 header 를 full 강제했는지 → 프레임을 grid 로 맞춘다.
24
- * - menuVisible: 활성 레일에 메뉴 패널이 깔렸는지 → false 면 메뉴 열을 빼 레일 폭만 예약한다(빈틈 방지).
45
+ * 자식 GNB자기 치수·요구사항을 등록한다. 언마운트하거나 SLayout 밖으로 나가면 null 로 해제한다.
46
+ * 페인트 전에 반영돼야 하므로 GNB 쪽에서 layout effect호출한다.
25
47
  */
26
- reportGnbState: (state: {
27
- forceFull: boolean;
28
- menuVisible: boolean;
29
- }) => void;
48
+ registerNav: (nav: SLayoutNavState | null) => void;
30
49
  }
31
50
  export declare const SLayoutContext: import("react").Context<SLayoutContextValue | null>;
32
51
  /**
@@ -40,8 +59,8 @@ export interface SLayoutProps extends HTMLAttributes<HTMLDivElement> {
40
59
  /** 레이아웃 구조: fix(가로 분할) / full(풀폭 상단바). 자식 SGnb·SPage 가 이 값을 따른다. */
41
60
  header?: SLayoutHeader;
42
61
  /**
43
- * GNB 좌측 레일 사용 여부. 자식 SGnb 가 이 값을 따르고, full 메뉴 폭도 레일만큼 넓어진다.
44
- * 레일에 children 없는 아이템이 있으면 SGnb 가 header 를 full 강제하고, 이 레이아웃도 그에 맞춰 full 그리드로 선다.
62
+ * GNB 좌측 레일 사용 여부. 자식 SGnb 가 이 값을 따르고, 그만큼 넓어진 컬럼 폭을 되올린다.
63
+ * 레일에 children 없는 아이템이 있으면 SGnb 가 full 상단바를 요구하고, 이 레이아웃도 그에 맞춰 full 그리드로 선다.
45
64
  */
46
65
  useRail?: boolean;
47
66
  /** GNB 접힘 상태 (controlled) */
@@ -57,10 +76,13 @@ export interface SLayoutProps extends HTMLAttributes<HTMLDivElement> {
57
76
  * 자식 SGnb·SPage 는 context 에서 type·header·folded 를 읽으므로 앱은 이 값들을 여기 한 곳에만 쓴다.
58
77
  * 높이는 기본 100%(부모를 채움) — 앱 루트로 쓸 땐 부모를 뷰포트 높이로 잡는다.
59
78
  *
60
- * - header="fix": [GNB(자기 소유) | 페이지] 가로 flex.
61
- * - header="full": 상단바가 풀폭이고 아래에 [메뉴 | 페이지] 나란히 서야 하는데, SGnb 가 상단바와
62
- * 메뉴를 한 엘리먼트로 갖고 있어 사이에 끼워넣을 수 없다. 그래서 grid 로 깔고
63
- * SGnb 셀에 겹친 뒤(root 투명) SPage (2행,2열) = "메뉴 오른쪽 투명 영역" 을 차지한다.
64
- * 접으면 메뉴가 사라지므로 1열을 0 으로 접어 페이지가 전폭을 쓴다.
79
+ * 치수는 자식이 소유한다: GNB registerNav 컬럼 폭·상단바 높이·전환 길이를 올리고
80
+ * 프레임은값으로 그리드를 깐다(SLayout GNB 내부 상수를 import 하지 않는다).
81
+ *
82
+ * - header="fix": [GNB(자기 소유) | 페이지] 가로 flex. 프레임이 폭에 관여하지 않는다.
83
+ * - header="full": 이름 있는 영역으로 그리드다.
84
+ * "header header" ← 전폭 상단바 (1행, 높이 = 등록된 topHeight)
85
+ * "nav page" ← 메뉴 열(등록된 columnWidth) | 페이지
86
+ * 접으면 nav 열을 0 으로 접어 페이지가 전폭을 쓴다.
65
87
  */
66
88
  export declare const SLayout: import("react").ForwardRefExoticComponent<SLayoutProps & import("react").RefAttributes<HTMLDivElement>>;
@@ -9,7 +9,7 @@
9
9
  | Prop | Type | Default | Description |
10
10
  |------|------|---------|-------------|
11
11
  | `open?` | `boolean` | — | |
12
- | `persistent?` | `boolean` | — | true면 백드롭·ESC로 안 닫히고 흔들림 (sd-modal-container persistent). 로딩 닫힘 방지에 유용 |
12
+ | `persistent?` | `boolean` | — | 백드롭·ESC로 안 닫히고 흔들림 (sd-modal-container persistent). **기본값 true** |
13
13
  | `state?` | `LoadingModalState` | `'loading'` | 상태 (loading: 스피너, error: 경고 아이콘) |
14
14
  | `progress?` | `number` | — | 진행률 (0–100) — 지정 시 determinate 스피너 |
15
15
  | `message?` | `string \| string[]` | — | 메시지 (없으면 state 기본값) |
@@ -4,7 +4,7 @@ export interface SLoadingModalProps {
4
4
  onOpenChange?: (open: boolean) => void;
5
5
  /** 닫기(X) 버튼 클릭 (sdClose) — error 상태에서만 노출 */
6
6
  onClose?: () => void;
7
- /** true면 백드롭·ESC로 안 닫히고 흔들림 (sd-modal-container persistent). 로딩 닫힘 방지에 유용 */
7
+ /** 백드롭·ESC로 안 닫히고 흔들림 (sd-modal-container persistent). **기본값 true** */
8
8
  persistent?: boolean;
9
9
  /** 상태 (loading: 스피너, error: 경고 아이콘) */
10
10
  state?: LoadingModalState;
@@ -11,7 +11,7 @@
11
11
  | `open?` | `boolean` | — | 표시 여부 (제어) |
12
12
  | `ariaTitle?` | `string` | `'모달'` | 접근성 제목 (스크린리더용). 시각 제목은 children이 담당 |
13
13
  | `showClose?` | `boolean` | `false` | 우측 상단 닫기 버튼 |
14
- | `persistent?` | `boolean` | `false` | true면 백드롭 클릭·ESC로 닫히지 않고 흔들림(shake) 애니메이션 (sd-modal-container persistent) |
14
+ | `persistent?` | `boolean` | `true` | 백드롭 클릭·ESC로 닫히지 않고 흔들림(shake) 애니메이션 (sd-modal-container persistent). **기본값 true** — 모달은 작성 중인 내용을 잃지 않도록 임의 닫힘을 막는 것이 기본이다. 닫기 경로는 X 버튼과 모달 안의 버튼뿐이다. false로 주면 백드롭·ESC 닫기가 열린다. |
15
15
  | `width?` | `number \| string` | — | 너비/높이 |
16
16
  | `height?` | `number \| string` | — | |
17
17
  | `children?` | `ReactNode` | — | |
@@ -15,7 +15,11 @@ export interface SModalContainerProps {
15
15
  showClose?: boolean;
16
16
  /** 닫기(X) 버튼 클릭 시 발생 (sd-modal-container 닫기 버튼 대응) */
17
17
  onClose?: () => void;
18
- /** true면 백드롭 클릭·ESC로 닫히지 않고 흔들림(shake) 애니메이션 (sd-modal-container persistent) */
18
+ /**
19
+ * 백드롭 클릭·ESC로 닫히지 않고 흔들림(shake) 애니메이션 (sd-modal-container persistent).
20
+ * **기본값 true** — 모달은 작성 중인 내용을 잃지 않도록 임의 닫힘을 막는 것이 기본이다.
21
+ * 닫기 경로는 X 버튼과 모달 안의 버튼뿐이다. false로 주면 백드롭·ESC 닫기가 열린다.
22
+ */
19
23
  persistent?: boolean;
20
24
  /** 너비/높이 */
21
25
  width?: number | string;
@@ -27,7 +31,7 @@ export interface SModalContainerProps {
27
31
  /**
28
32
  * SModalContainer — sd-modal-container 포팅 (Radix Dialog 기반).
29
33
  * 모든 모달(Confirm/Action/Loading)의 공통 컨테이너. 딤 오버레이 + 중앙 흰 카드.
30
- * persistent=true면 백드롭/ESC 닫기를 막고 흔들림 애니메이션을 준다.
34
+ * persistent(기본 true)면 백드롭/ESC 닫기를 막고 흔들림 애니메이션을 준다.
31
35
  *
32
36
  * @internal
33
37
  * 내부 전용 컴포넌트다. 패키지 public export(src/index.ts)에서 의도적으로 제외돼 있어
@@ -0,0 +1,45 @@
1
+ # SOverlayHeader
2
+
3
+ > 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
4
+
5
+ ### SOverlayHeader
6
+
7
+ #### Props
8
+
9
+ | Prop | Type | Default | Description |
10
+ |------|------|---------|-------------|
11
+ | `title?` | `ReactNode` | — | 시각 제목 |
12
+ | `description?` | `ReactNode` | — | 제목 오른쪽 보조 설명 |
13
+ | `showClose?` | `boolean` | `false` | 닫기 버튼 표시 |
14
+ | `reserveCloseSpace?` | `boolean` | `false` | 외부 absolute 닫기 버튼 공간 확보 |
15
+ | `className?` | `string` | — | |
16
+ | `titleClassName?` | `string` | — | |
17
+ | `descriptionClassName?` | `string` | — | |
18
+ | `style?` | `CSSProperties` | — | |
19
+
20
+ #### Events
21
+
22
+ | Event | Type | Description |
23
+ |-------|------|-------------|
24
+ | `onClose` | `() => void` | 닫기 버튼 클릭 |
25
+
26
+ ## Dependencies
27
+
28
+ ### Used by
29
+
30
+ - [SActionModal](../SActionModal)
31
+ - [SDrawer](../SDrawer)
32
+
33
+ ### Depends on
34
+
35
+ - [SGhostButton](../SGhostButton)
36
+
37
+ ### Graph
38
+
39
+ ```mermaid
40
+ graph TD;
41
+ SOverlayHeader --> SGhostButton
42
+ SActionModal --> SOverlayHeader
43
+ SDrawer --> SOverlayHeader
44
+ style SOverlayHeader fill:#f9f,stroke:#333,stroke-width:4px
45
+ ```