sellmate-design-system-react 9.0.0-beta.32 → 9.0.0-beta.34

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 (32) hide show
  1. package/AGENTS.md +21 -6
  2. package/dist/components/SBadge/README.md +2 -0
  3. package/dist/components/SButton/README.md +2 -0
  4. package/dist/components/SCalendarBoard/CalendarDayCard.d.ts +38 -0
  5. package/dist/components/SCalendarBoard/CalendarDayEventListBox.d.ts +26 -0
  6. package/dist/components/SCalendarBoard/CalendarEventButton.d.ts +13 -0
  7. package/dist/components/SCalendarBoard/CalendarMoreButton.d.ts +12 -0
  8. package/dist/components/SCalendarBoard/README.md +137 -0
  9. package/dist/components/SCalendarBoard/SCalendarBoard.d.ts +68 -0
  10. package/dist/components/SCalendarBoard/calendarBoard.config.d.ts +33 -0
  11. package/dist/components/SCalendarBoard/index.d.ts +3 -0
  12. package/dist/components/SCalendarBoard/types.d.ts +31 -0
  13. package/dist/components/SDivider/README.md +2 -0
  14. package/dist/components/SGhostButton/README.md +2 -0
  15. package/dist/components/SGnb/SGnb.d.ts +6 -0
  16. package/dist/components/SGnb/gnb.config.d.ts +3 -3
  17. package/dist/components/SGnbSystem/README.md +43 -1
  18. package/dist/components/SGnbSystem/SGnbSystem.d.ts +48 -2
  19. package/dist/components/SPortal/README.md +2 -0
  20. package/dist/components/SScrollArea/README.md +13 -0
  21. package/dist/components/SSystemActionButton/systemActionButton.config.d.ts +8 -2
  22. package/dist/components/STooltip/README.md +2 -0
  23. package/dist/index.cjs +823 -129
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.ts +1 -0
  26. package/dist/index.js +817 -129
  27. package/dist/index.js.map +1 -1
  28. package/dist/llms-full.txt +206 -7
  29. package/dist/llms.txt +23 -8
  30. package/dist/styles.css +290 -9
  31. package/dist/theme.css +74 -8
  32. package/package.json +1 -1
@@ -36,7 +36,7 @@
36
36
  | --- | --- |
37
37
  | **버튼·링크** | `SButton` `SGhostButton` `SDropdownButton` `SSystemActionButton` `STextLink` `SSwitch` `SToggle` |
38
38
  | **입력 (폼)** | `SForm` `SField` `SInput` `SSearchInput` `SNumberInput` `STextarea` `SEditor` `SSelect` `SCheckbox` `SRadio` `SRadioGroup` `SRadioButton` `SRadioCard` `SRadioCardGroup` `SChip` `SChipInput` `SBarcodeInput` `SFilePicker` |
39
- | **날짜·시간** | `SCalendar` `SDatePicker` `SDatePickerYearListbox` `SDatePickerMonthListbox` `SDateRangePicker` `STimePicker` `STimeRangePicker` |
39
+ | **날짜·시간** | `SCalendar` `SCalendarBoard`(한 달치 일정 판) `SDatePicker` `SDatePickerYearListbox` `SDatePickerMonthListbox` `SDateRangePicker` `STimePicker` `STimeRangePicker` |
40
40
  | **표·목록** | `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SListItem` `SExpansionList` `SDraggableList` `SDraggableItem` `STree` |
41
41
  | **레이아웃** | `SLayout` `SGnb` `SGnbSystem` `SAccountListBox`(계정 행을 눌러 뜨는 계정 패널) `SPage`(제목 영역은 `header` prop) `SSectionHeaderCard` `SCard` `SDivider` `SSplitter` `SScrollArea` `SExpansionItem` |
42
42
  | **내비게이션** | `STabs` `SPagination` `SStepper` |
@@ -159,7 +159,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
159
159
  | 층 | 무엇인가 | 컴포넌트 |
160
160
  | --- | --- | --- |
161
161
  | **셸** | 앱 전체 뼈대. 페이지가 바뀌어도 남는다 | `SLayout` `SGnb` `SGnbSystem`(GNB 맨 아래 판 · 전폭 상단바 오른쪽 끝) `SPage`(제목 영역은 `header` prop) |
162
- | **블록** | `SPage` 의 직계 자식. 페이지를 세로로 쌓는 단위 | `SSectionHeaderCard` `SCard` `SForm` `SSplitter` `SScrollArea` `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SExpansionList` `SDraggableList` `STree` `SCallout` `STabs` `SStepper` `SPagination` `SDivider` |
162
+ | **블록** | `SPage` 의 직계 자식. 페이지를 세로로 쌓는 단위 | `SSectionHeaderCard` `SCard` `SForm` `SSplitter` `SScrollArea` `SCalendarBoard` `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SExpansionList` `SDraggableList` `STree` `SCallout` `STabs` `SStepper` `SPagination` `SDivider` |
163
163
  | **요소** | 블록 **안에** 놓이는 컨트롤. 혼자 페이지에 서지 않는다 | `SButton` `SGhostButton` `SDropdownButton` `SSystemActionButton` `SField` `SInput` `SSearchInput` `SNumberInput` `STextarea` `SEditor` `SSelect` `SCheckbox` `SRadio` `SRadioGroup` `SRadioButton` `SRadioCard` `SRadioCardGroup` `SSwitch` `SToggle` `SChipInput` `SBarcodeInput` `SFilePicker` `SDatePicker` `SDatePickerYearListbox` `SDatePickerMonthListbox` `SDateRangePicker` `STimePicker` `STimeRangePicker` `SCalendar` `SListItem` `SExpansionItem` `SDraggableItem` `SImage` `SLinearProgress` `SCircleProgress` |
164
164
  | **인라인** | 텍스트 흐름·셀·라벨 안에 섞인다. 혼자 블록이 되지 않는다 | `STag` `SBadge` `SIcon` `STextLink` `SChip` |
165
165
  | **레이어** | 문서 흐름 **밖**에 떠서 그려진다. 어느 층에서 띄우든 레이아웃에 영향이 없다 | `SModal` `SActionModal` `SConfirmModal` `SPopup` `SDrawer` `SPopover` `STooltip` `SPortal` `SAccountListBox`(계정 행에 붙어 뜬다 — 직접 띄우지 않는다) `SToast` `SLoadingModal` `SLoadingContainer` `SGuide` |
@@ -520,6 +520,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
520
520
  | 나열한 항목을 펼쳐 하위 내용을 보여준다 | `SExpansionList` + `SExpansionItem` | §3-7-7 |
521
521
  | 부모-자식 계층을 들여쓰기로 보여준다 | `STree` | §3-7-7 |
522
522
  | 사용자가 순서를 드래그로 바꾸게 한다 | `SDraggableList` + `SDraggableItem` | §3-7-6 |
523
+ | 날짜별 일정을 한 달치 격자로 펼쳐 보여준다 | `SCalendarBoard` | §3-7-4 |
523
524
  | 표 위에 건수 요약과 액션을 얹는다 | `STableBar` | §4-2 |
524
525
  | 상태·분류를 라벨로 찍는다 | `STag` | §3-1 |
525
526
  | 색 점만으로 상태를 찍는다 | `SBadge` | §3-1 |
@@ -1382,7 +1383,7 @@ const columns: STableColumn[] = [
1382
1383
  - 약관 동의처럼 **제출 시점에 값이 필요한 것은 항상 `SCheckbox`** 다 — 모양이 스위치에 가까워 보여도 그렇다.
1383
1384
  - `SToggle` 은 알약형 버튼이라 여러 개를 가로로 늘어놓는 필터 자리에 맞는다. 설정 화면의 on/off 한 줄에는 쓰지 않는다.
1384
1385
 
1385
- #### 3-7-4. 날짜 셋 — SDatePicker vs SDateRangePicker vs SCalendar
1386
+ #### 3-7-4. 날짜 셋 — SDatePicker vs SDateRangePicker vs SCalendar vs SCalendarBoard
1386
1387
 
1387
1388
  | 판별 | 사용 |
1388
1389
  | --- | --- |
@@ -1390,10 +1391,19 @@ const columns: STableColumn[] = [
1390
1391
  | 연도 선택 리스트만 필요하다 (트리거·팝오버는 직접 조합) | `SDatePickerYearListbox` |
1391
1392
  | 연도+월 선택 리스트만 필요하다 (트리거·팝오버는 직접 조합) | `SDatePickerMonthListbox` |
1392
1393
  | **시작~종료** 를 값으로 받는다 | `SDateRangePicker` |
1393
- | 달력 격자 **자체가 화면 콘텐츠** 다 (일정·이벤트 보기) | `SCalendar` |
1394
+ | 달력 격자 **자체가 화면 콘텐츠** 다 (날짜를 고르게 한다) | `SCalendar` |
1395
+ | 한 달치 **일정을 읽게** 펼친다 (칸마다 여러 건) | `SCalendarBoard` |
1394
1396
 
1395
1397
  - **기간을 `SDatePicker` 두 개로 만들지 않는다.** 시작이 종료보다 뒤인 입력을 막는 검증과 한쪽만 고른 중간 상태 처리가 `SDateRangePicker` 안에 이미 있다. 두 개로 쪼개면 그게 전부 앱 몫이 된다.
1396
1398
  - `SDatePicker`·`SDateRangePicker` 는 내부적으로 `SCalendar` 를 팝오버로 띄운다. 값을 받는 자리에 `SCalendar` 를 직접 쓰지 않는다.
1399
+ - **`SCalendar` 와 `SCalendarBoard` 는 방향이 반대다.** `SCalendar` 는 날짜를 **고르는** 달력(칸에는 점만 찍힌다)이고, `SCalendarBoard` 는 일정을 **읽는** 달력이다 — 칸마다 일정이 줄로 쌓이고, 칸 높이에 담기는 줄 수를 넘으면 "N개 더보기" 로 접히고, **"더보기" 또는 일정이 있는 칸 아무 데나** 누르면 **그 칸을 덮으며 뜨는 판**에 그 날짜의 일정이 전부 펼쳐진다. 폭도 다르다: `SCalendar` 는 제 폭을 갖는 요소, `SCalendarBoard` 는 페이지 폭을 채우는 블록이다.
1400
+ - **`SCalendarBoard` 는 기본이 읽기 전용 판이다.** 날짜 칸을 눌러 **고르게** 하려면 `selectable` 을 켠다 — 켜야 `onValueChange(date, events)` 로 고른 날짜와 **그 날짜의 일정**이 함께 온다. 다만 **일정이 있는 칸은 `selectable` 과 무관하게 눌린다** — 그때는 목록 판이 열린다. 둘 다 켜져 있으면 고르기와 열기가 함께 일어난다. 일정 버튼과 "N개 더보기" 도 항상 눌린다.
1401
+ - **칸 배경과 일정 색은 다른 층이다.** 그날의 성격(마감·완료·휴무 등)은 `dayColors` 로 **칸 전체**에 칠하고(`default` `danger` `accent` `complete` `dim`), 일정 하나의 색은 `events[].color` 로 준다. 둘을 섞어 쓰면 서로를 가리지 않고 함께 읽힌다.
1402
+ - 일정 왼쪽의 색 점은 `SBadge` 다 — `events[].color` 프리셋이 점 색까지 정하고, 따로 주려면 `dotColor` 에 `SBadge` 9색 중 하나를 넣는다 (§3-1).
1403
+ - **칸 본문을 통째로 바꾸려면 `dayContent` 다.** 일정으로 표현되지 않는 그날치 요약(재고·매출 같은)을 칸에 얹을 때 쓴다. **슬롯을 준 날짜는 그 날짜의 `events` 를 그리지 않고 목록 판도 열지 않는다** — 한 칸에 둘을 겹쳐 담지 않는다. 일정과 요약을 함께 보여야 하면 요약을 일정 한 건(`events[]`)으로 넣는다.
1404
+ - **`SCalendarBoard` 는 높이를 부모에게서 받는다.** 행이 그 높이를 균등하게 나눠 갖고, 칸 높이가 다시 "한 칸에 몇 줄이 보일지" 를 정한다. 그래서 **놓는 자리에 높이를 준다** — 페이지 본문의 남은 높이를 채우려면 `SPage` 안에서 스택을 `flex-1 min-h-0` 으로 두고 판에 `h-full` 을 준다. 높이를 주지 않으면 칸이 최소 높이로 주저앉아 한두 줄만 보인다.
1405
+ - **한 칸에 몇 줄을 펼칠지는 컴포넌트가 잰다.** 조절하는 prop 이 없다 — 칸 높이에서 나오는 값이라 따로 정할 것이 아니다. 줄이 넘치면 마지막 한 줄을 "N개 더보기" 에 내주므로 **접히든 아니든 칸 높이가 같다.** **소비 앱이 `events` 를 미리 잘라 넘기지 않는다.** 잘라 넘기면 "N개 더보기" 의 수가 실제 건수와 어긋나고, 눌러도 나머지가 나오지 않는다.
1406
+ - **`events[].label` 은 필수다** — 일정이 무엇인지 알리는 부분이라 비워 두지 않는다. 인라인 HTML 을 받으므로 부분 강조가 필요할 때만 태그를 쓰고, 나머지는 `description`·`value` 로 나눠 담는다. 칸이 좁아지면 `label`+`description` 이 한 덩어리로 말줄임되고 `value` 만 끝에 온전히 남는다 — **금액·수량은 반드시 `value` 에 담는다.** `description` 에 넣으면 잘린다.
1397
1407
  - `SDatePickerYearListbox`·`SDatePickerMonthListbox` 는 `SDatePicker` 의 mode listbox 조각만 떼어낸 컴포넌트다. 일반 폼 입력에는 `SDatePicker mode="year" | "month"` 를 우선 쓰고, 다른 트리거·팝오버 안에 리스트만 끼워 넣을 때만 직접 쓴다.
1398
1408
 
1399
1409
  **날짜·시간 피커는 폭 상한을 스스로 갖는다 — `width` 를 주지 않는다.** 값 길이가 `YYYY-MM-DD` 처럼 정해져 있어 컴포넌트가 사이즈별 상한을 안다. `SKeyValueTable` 이 모든 컨트롤에 `width="100%"` 를 넘기지만, 이 상한 덕분에 행 전체로 늘어나지 않고 제 폭에서 멈춘다.
@@ -1626,7 +1636,7 @@ export default function AppShell({
1626
1636
  ```tsx
1627
1637
  {/* 폭을 기억해야 하면 menuWidth 를 앱이 쥐고 onMenuWidthChange 로 되받아 저장한다.
1628
1638
  초기값만 정하면 되면 defaultMenuWidth 하나로 끝난다. */}
1629
- <SGnb items={MENU} value={current} onValueChange={navigate} resizable defaultMenuWidth={240} />
1639
+ <SGnb items={MENU} value={current} onValueChange={navigate} resizable defaultMenuWidth={220} />
1630
1640
  ```
1631
1641
 
1632
1642
  `onMenuWidthChange` 는 **드래그를 놓는 순간**(또는 방향키 조작) 한 번만 온다 — 저장 로직을 그대로 붙여도 프레임마다 쓰이지 않는다. 접혀 있거나 레일 리프가 활성이라 깔 메뉴가 없으면 조절선은 나오지 않는다.
@@ -1747,7 +1757,12 @@ import { SModalOutlet } from 'sellmate-design-system-react';
1747
1757
  - **`header="fix"` 를 접으면 알림·계정 아이콘만 남는다** — `actions`·`domain`·`setting` 은 48px 폭에 놓을 자리가 없어 렌더되지 않고, 알림 개수는 점 배지가 된다. **알림도 계정도 안 쓰는 조합이면 접힌 패널은 아예 렌더되지 않는다** — 접힌 상태에서도 반드시 눌러야 하는 것이 그 둘 밖에 있으면 `foldedTop`/`foldedFooter` 로 따로 준다.
1748
1758
  - **`header="full"` 은 접어도 상단바가 남으므로 조각들도 그대로 남는다.** 대신 가로로 자리가 넉넉하지 않아 알림·설정이 라벨을 벗고 아이콘(알림은 개수까지)만 남는다 — 이건 컴포넌트가 알아서 하므로 앱이 라벨을 지우지 않는다.
1749
1759
  - **`account` 를 쓰면 `account.listBox` 가 필수다** (§3-5-8) — 계정 행을 누르면 이메일·이름·권한과 계정 설정·언어 변경·로그아웃이 예외 없이 뜬다. 뜨는 방향은 판이 놓인 자리가 정하므로 앱이 넘기지 않는다 — 판이면 계정 행 위로, 상단바면 아래로 펼치고, 접힌 레일도 판과 같다. `account.onClick` 은 패널을 여는 것 말고 따로 할 일(로깅 등)이 있을 때만 준다.
1750
- - **알림 개수는 `alert.count` 하나로 표현한다.** 1 이상이면 벨이 울리는 아이콘과 강조색으로 바뀐다 — 색은 GNB 색이 정하므로 앱이 직접 칠하지 않는다.
1760
+ - **알림 개수는 `alert.count` 하나로 표현한다.** 1 이상이면 벨이 울리는 아이콘과 강조색으로 바뀐다 — 색은 GNB 색이 정하므로 앱이 직접 칠하지 않는다. **`resizable` 로 메뉴를 기본 폭보다 좁게 줄이면 개수를 적을 가로가 모자라 접힘과 같은 점 배지로 바뀐다** — 컴포넌트가 알아서 하므로 앱이 폭을 보고 `count` 를 지우지 않는다.
1761
+ - **알림을 눌러 뜨는 목록은 `alert.listBox` 에 내용만 넘긴다** — `SPortal` 을 따로 띄워 알림 버튼에 붙이지 않는다. 목록에 무엇을 쌓을지는 서비스마다 다르지만 **뜨는 자리는 늘 같아야 하므로**, 방향(판·접힌 레일은 버튼 오른쪽 · 상단바는 아래로 오른쪽 끝)과 바깥 클릭·ESC 닫힘, 배경·라운드·그림자는 컴포넌트가 쥔다. 여닫는 일도 알림 버튼이 하므로 **`onOpenChange` 는 그 사실을 알아야 할 때만** 받는다(연 김에 읽음 처리하는 화면 등) — 이 값으로 목록을 대신 열거나 막지 않는다. 계정 행(`account.listBox`)과 같은 규칙이다.
1762
+ - **알림에 안내 툴팁을 띄우려면 `alert.tooltip` 에 문구만 넘긴다** — `STooltip` 을 직접 세워 알림 버튼에 붙이지 않는다. 색(판이 light 면 기본 · 그 밖은 강조)과 방향(판·접힌 레일은 오른쪽 · 상단바는 아래)은 자리가 정하고, 스스로 사라지지 않다가 **알림을 누르거나 버튼에서 커서를 뺄 때** 닫힌다.
1763
+ - **닫힘은 `onTooltipDismiss` 로 받아 `tooltip` 을 비워 둔다.** 같은 값을 계속 넘기는 동안에는 다시 뜨지 않고, **비웠다 다시 넘기면 문구가 같아도 새 안내로 뜬다** — 새 알림마다 같은 안내를 다시 띄우는 화면이 막히지 않는다.
1764
+ - 재노출 신호는 문구가 **없음 → 있음** 으로 바뀌는 것이다. 한 이벤트 핸들러 안에서 비웠다 곧바로 넣으면 렌더가 한 번으로 묶여 신호가 되지 않는다 — 닫을 때 비우고, 다시 필요할 때 넘긴다.
1765
+ - 컴포넌트가 아는 범위는 그 자리가 서 있는 동안뿐이다(새로고침하거나 GNB 를 접어 알림이 다른 자리로 옮겨 서면 새로 마운트된다). **그 사용자에게 두 번 다시 보이지 않아야 하면 앱이 닫힘을 저장해 두고 `tooltip` 을 넘기지 않는다.**
1751
1766
  - **`header="fix"` + `useRail` 에서 하위 메뉴가 없는 레일 아이템이 활성이면 메뉴 컬럼째 사라지므로 이 패널도 함께 빠진다.** 항상 보여야 하는 계정·알림이라면 그런 레일 리프를 두지 않는다 — 또는 `header="full"` 로 두면 상단바에 남는다(그런 레일 리프가 있으면 GNB 가 `header` 를 `full` 로 강제한다).
1752
1767
 
1753
1768
  ### 4-2. 목록 페이지 (필터 + 테이블)
@@ -2500,6 +2515,7 @@ export const BADGE_COLORS = [
2500
2515
 
2501
2516
  ### Used by
2502
2517
 
2518
+ - [SCalendarBoard](../SCalendarBoard)
2503
2519
  - [SSectionHeaderCard](../SSectionHeaderCard)
2504
2520
 
2505
2521
  ### Graph
@@ -2629,6 +2645,7 @@ export const BUTTON_SIZES = ['xs', 'sm', 'md', 'lg'] as const;
2629
2645
 
2630
2646
  ### Used by
2631
2647
 
2648
+ - [SCalendarBoard](../SCalendarBoard)
2632
2649
  - [SConfirmModal](../SConfirmModal)
2633
2650
  - [SDropdownButton](../SDropdownButton)
2634
2651
  - [SEditor](../SEditor)
@@ -2698,6 +2715,136 @@ export interface SCalendarEventGroup {
2698
2715
 
2699
2716
  ---
2700
2717
 
2718
+ # SCalendarBoard
2719
+
2720
+ > 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
2721
+
2722
+ ### SCalendarBoard
2723
+
2724
+ #### Props
2725
+
2726
+ | Prop | Type | Default | Description |
2727
+ |------|------|---------|-------------|
2728
+ | `year?` | `number` | — | 보이는 연도 (제어). `month` 와 함께 준다 |
2729
+ | `month?` | `number` | — | 보이는 월 1-12 (제어). `year` 와 함께 준다 |
2730
+ | `defaultYear?` | `number` | — | 처음 보여줄 연도 (비제어). 없으면 오늘 |
2731
+ | `defaultMonth?` | `number` | — | 처음 보여줄 월 1-12 (비제어). 없으면 오늘 |
2732
+ | `selectable?` | `boolean` | `false` | 날짜 칸을 눌러 고를 수 있게 한다. 기본은 읽기 전용 판이다 — 켜야 칸에 커서·포커스·키보드(Enter·Space)가 붙고 `onValueChange` 가 온다. 일정 버튼과 "N개 더보기" 는 이 값과 무관하게 항상 눌린다. |
2733
+ | `value?` | `string \| null` | — | 선택 날짜 (YYYY-MM-DD). `selectable` 과 별개로 강조만 주고 싶을 때도 쓴다 |
2734
+ | `events?` | `SCalendarBoardEvent[]` | — | 날짜별 일정 목록. `date` 로 칸에 배분된다 |
2735
+ | `dayColors?` | `Record<string, SCalendarBoardDayColor>` | — | 날짜별 칸 배경. 키는 `YYYY-MM-DD`, 없는 날짜는 `'default'` 다. 그날의 성격(마감·완료·휴무 등)을 칸 전체로 알릴 때 쓴다 — 일정 하나의 색은 `events[].color` 다. |
2736
+ | `dayContent?` | `Record<string, ReactNode>` | — | 날짜별 칸 본문. 키는 `YYYY-MM-DD`, 준 날짜는 **일정 자리를 통째로 이 내용이 차지한다** — 그날의 `events` 는 그리지 않고 목록 판도 열리지 않는다. 일정으로 표현되지 않는 것(재고 현황· 매출 요약 같은 그날치 요약)을 칸에 그대로 얹을 때 쓴다. |
2737
+ | `todayLabel?` | `string` | `'오늘'` | 헤더 오른쪽 "오늘" 버튼 레이블. 빈 문자열이면 버튼을 그리지 않는다 |
2738
+ | `moreLabel?` | `string` | — | "N개" 뒤에 붙는 말 |
2739
+ | `headerRight?` | `ReactNode` | — | 헤더 오른쪽 끝에 붙일 추가 컨트롤 |
2740
+ | `className?` | `string` | — | |
2741
+ | `style?` | `CSSProperties` | — | |
2742
+
2743
+ #### Events
2744
+
2745
+ | Event | Type | Description |
2746
+ |-------|------|-------------|
2747
+ | `onViewChange` | `(view: SCalendarBoardView) => void` | 보이는 연·월 변경 |
2748
+ | `onValueChange` | `(date: string, events: SCalendarBoardEvent[]) => void` | 날짜 칸 선택 — 고른 날짜와 그 날짜의 일정이 함께 온다 (`selectable` 일 때만) |
2749
+ | `onEventClick` | `(event: SCalendarBoardEvent, e: MouseEvent<HTMLButtonElement>) => void` | 일정 클릭 |
2750
+ | `onMoreClick` | `(view: { date: string; events: SCalendarBoardEvent[] }) => void` | 그 날짜의 일정을 전부 열어 볼 때 — "N개 더보기" 를 눌렀을 때와 **일정이 있는 칸 자체를 눌렀을 때** 모두 온다. **주면 내장 일정 목록 판을 띄우지 않고 이 핸들러만 호출한다** — 그 날짜를 전용 화면·모달로 열고 싶을 때 쓴다. |
2751
+
2752
+ ## Types
2753
+
2754
+ ### SCalendarBoardView
2755
+
2756
+ ```ts
2757
+ /** 보이는 연·월 */
2758
+ export interface SCalendarBoardView {
2759
+ year: number;
2760
+ /** 1-12 */
2761
+ month: number;
2762
+ }
2763
+ ```
2764
+
2765
+ ### SCalendarBoardEvent
2766
+
2767
+ ```ts
2768
+ /** 달력 한 칸에 얹히는 일정 하나 */
2769
+ export interface SCalendarBoardEvent {
2770
+ /** 고유 식별자. 없으면 목록 순서로 key 를 만든다 */
2771
+ id?: string;
2772
+ /** 날짜 (YYYY-MM-DD) */
2773
+ date: string;
2774
+ /**
2775
+ * 강조 레이블 (필수) — 예: `"[입고 예정]"`.
2776
+ * 일정이 무엇인지 한눈에 알리는 부분이라 비워 두지 않는다.
2777
+ * 인라인 HTML(`<b>` `<strong>` `<i>` `<em>` `<span class>` `<a href>` `<br>`)을 받으며 살균 후 렌더한다.
2778
+ */
2779
+ label: string;
2780
+ /** 색상 프리셋 — 배경과 점 색이 함께 정해진다 */
2781
+ color?: SCalendarBoardEventColor;
2782
+ /** 왼쪽 점 색만 따로 지정 (프리셋 기본값을 덮어쓴다). 점은 `SBadge` 라 그 9색을 쓴다 */
2783
+ dotColor?: SBadgeColor;
2784
+ /** 본문 텍스트 — 예: `"RV20260728-000006"`. 평문만 받는다 */
2785
+ description?: string;
2786
+ /** 구분선(`/`) 뒤에 붙는 값 — 예: `"1,000"`. 평문만 받는다 */
2787
+ value?: string;
2788
+ /** 이 일정만 비활성 (클릭 불가) */
2789
+ disabled?: boolean;
2790
+ }
2791
+ ```
2792
+
2793
+ ### SCalendarBoardDayColor
2794
+
2795
+ ```ts
2796
+ export type SCalendarBoardDayColor = (typeof CALENDAR_BOARD_DAY_COLORS)[number];
2797
+ ```
2798
+
2799
+ ### SCalendarBoardEventColor
2800
+
2801
+ ```ts
2802
+ export type SCalendarBoardEventColor = (typeof CALENDAR_BOARD_EVENT_COLORS)[number];
2803
+ ```
2804
+
2805
+ ### CALENDAR_BOARD_DAY_COLORS
2806
+
2807
+ ```ts
2808
+ /** 날짜 칸 배경 — 그날의 성격을 칸 전체로 알린다 */
2809
+ export const CALENDAR_BOARD_DAY_COLORS = [
2810
+ 'default',
2811
+ 'danger',
2812
+ 'accent',
2813
+ 'complete',
2814
+ 'dim',
2815
+ ] as const;
2816
+ ```
2817
+
2818
+ ### CALENDAR_BOARD_EVENT_COLORS
2819
+
2820
+ ```ts
2821
+ export const CALENDAR_BOARD_EVENT_COLORS = [
2822
+ 'default',
2823
+ 'blue',
2824
+ 'oceanBlue',
2825
+ 'lightBlue',
2826
+ 'green',
2827
+ 'yellow',
2828
+ 'orange',
2829
+ 'red',
2830
+ 'white',
2831
+ ] as const;
2832
+ ```
2833
+
2834
+ ## Dependencies
2835
+
2836
+ ### Depends on
2837
+
2838
+ - [SBadge](../SBadge)
2839
+ - [SButton](../SButton)
2840
+ - [SDivider](../SDivider)
2841
+ - [SGhostButton](../SGhostButton)
2842
+ - [SScrollArea](../SScrollArea)
2843
+
2844
+ ### Graph
2845
+
2846
+ ---
2847
+
2701
2848
  # SCallout
2702
2849
 
2703
2850
  > 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
@@ -3667,6 +3814,7 @@ export type SDateRangePickerSize = SFieldSize;
3667
3814
  ### Used by
3668
3815
 
3669
3816
  - [SCalendar](../SCalendar)
3817
+ - [SCalendarBoard](../SCalendarBoard)
3670
3818
  - [SDateRangePicker](../SDateRangePicker)
3671
3819
  - [SList](../SList)
3672
3820
  - [STable](../STable)
@@ -4577,6 +4725,7 @@ export type SGhostButtonIntent = 'default' | 'danger' | 'action' | 'subAction' |
4577
4725
 
4578
4726
  - [SBarcodeInput](../SBarcodeInput)
4579
4727
  - [SCalendar](../SCalendar)
4728
+ - [SCalendarBoard](../SCalendarBoard)
4580
4729
  - [SChip](../SChip)
4581
4730
  - [SDatePicker](../SDatePicker)
4582
4731
  - [SDateRangePicker](../SDateRangePicker)
@@ -4762,12 +4911,50 @@ export interface SGnbSystemAlert {
4762
4911
  /** 라벨 텍스트. 기본 `'알림'` */
4763
4912
  label?: string;
4764
4913
  /**
4765
- * 읽지 않은 알림 개수. 1 이상이면 벨이 울리는 아이콘·강조색으로 바뀌고 개수(접히면 점)가 붙는다.
4914
+ * 읽지 않은 알림 개수. 1 이상이면 벨이 울리는 아이콘·강조색으로 바뀌고 개수가 붙는다.
4915
+ * 개수를 적을 가로가 모자란 자리(접힌 레일 · 기본 폭보다 좁게 줄인 판)에서는 점 배지로 바뀐다.
4766
4916
  * 표기는 컴포넌트가 맡는다 — 세 자리마다 콤마를 넣어 그리므로 앱이 포맷한 문자열을 넘기지 않는다.
4767
4917
  */
4768
4918
  count?: number;
4769
4919
  /** 클릭 */
4770
4920
  onClick?: () => void;
4921
+ /**
4922
+ * 알림 버튼에 붙는 안내 툴팁의 문구(한 줄이 한 항목). 주면 뜬다 — **문구만 앱이 정하고**
4923
+ * 색·방향·여닫힘은 컴포넌트가 쥔다: 색은 판이 light 면 기본, 그 밖(dark·상단바)이면 강조색이고
4924
+ * 방향은 자리가 정한다(판·접힌 레일이면 오른쪽, 상단바면 아래).
4925
+ *
4926
+ * 스스로 사라지지 않는다 — **알림 버튼을 누르거나, 버튼에 얹었다 커서를 뺄 때** 닫히고,
4927
+ * 같은 값을 계속 넘기는 동안에는 다시 뜨지 않는다.
4928
+ *
4929
+ * **다시 띄우려면 비웠다가 다시 넘긴다**(`undefined` → 문구). 문구가 같아도 상관없다 —
4930
+ * 컴포넌트는 닫았다는 사실만 기억하고 문구 내용은 기억하지 않으므로, 새 알림마다 같은 안내를
4931
+ * 다시 띄우는 화면도 막히지 않는다.
4932
+ */
4933
+ tooltip?: string[];
4934
+ /**
4935
+ * 알림을 누르면 뜨는 목록의 **내용**. 주면 컴포넌트가 알림 버튼에 붙여 띄운다 —
4936
+ * 목록에 무엇을 쌓을지는 서비스마다 다르지만 **뜨는 자리는 늘 같아야 하므로**, 방향·앵커·
4937
+ * 여닫힘(바깥 클릭·ESC 포함)과 배경·라운드·그림자는 컴포넌트가 쥐고 앱은 안에 담을 것만 준다.
4938
+ * 방향은 자리가 정한다 — 판·접힌 레일이면 버튼 오른쪽, 상단바면 아래.
4939
+ */
4940
+ listBox?: ReactNode;
4941
+ /**
4942
+ * 알림 목록이 열리고 닫힐 때. 여닫는 것은 알림 버튼이 스스로 하므로 **그 사실을 알아야 할
4943
+ * 때만** 준다(연 김에 읽음 처리하거나, 열려 있는 동안 다른 층을 접어 두는 화면).
4944
+ *
4945
+ * 앱이 누르지 않은 닫힘도 온다: GNB 를 접거나 펴면 알림 버튼이 다른 자리로 옮겨 서므로
4946
+ * 목록이 닫히고 `false` 가 온다(계정 행과 같다).
4947
+ */
4948
+ onOpenChange?: (open: boolean) => void;
4949
+ /**
4950
+ * 안내 툴팁이 닫힐 때. 받아서 `tooltip` 을 비워 두는 것이 기본 사용법이다 — 그러면 앱이
4951
+ * 다음에 넘기는 문구가 곧 다음 안내가 된다.
4952
+ *
4953
+ * 컴포넌트가 아는 "다시 뜨지 않는다" 는 **이 자리가 서 있는 동안**뿐이라(새로고침하거나
4954
+ * GNB 를 접어 알림이 다른 자리로 옮겨 서면 새로 마운트된다), 그 사용자에게 두 번 다시 보이지
4955
+ * 않아야 하면 앱이 이 신호를 저장해 두고 `tooltip` 을 그만 넘긴다.
4956
+ */
4957
+ onTooltipDismiss?: () => void;
4771
4958
  }
4772
4959
  ```
4773
4960
 
@@ -4840,7 +5027,9 @@ export const GNB_SYSTEM_COLORS = ['light', 'dark'] as const;
4840
5027
  - [SAccountListBox](../SAccountListBox)
4841
5028
  - [SGnb](../SGnb)
4842
5029
  - [SIcon](../SIcon)
5030
+ - [SPortal](../SPortal)
4843
5031
  - [SSystemActionButton](../SSystemActionButton)
5032
+ - [STooltip](../STooltip)
4844
5033
 
4845
5034
  ### Graph
4846
5035
 
@@ -6157,6 +6346,7 @@ export type SPortalAlign = 'start' | 'center' | 'end';
6157
6346
 
6158
6347
  - [SAccountListBox](../SAccountListBox)
6159
6348
  - [SChipInput](../SChipInput)
6349
+ - [SGnbSystem](../SGnbSystem)
6160
6350
  - [SSelect](../SSelect)
6161
6351
 
6162
6352
  ### Graph
@@ -6395,6 +6585,14 @@ export type SScrollAreaAxis = (typeof SCROLL_AREA_AXES)[number];
6395
6585
  export const SCROLL_AREA_AXES = ['vertical', 'horizontal', 'both'] as const;
6396
6586
  ```
6397
6587
 
6588
+ ## Dependencies
6589
+
6590
+ ### Used by
6591
+
6592
+ - [SCalendarBoard](../SCalendarBoard)
6593
+
6594
+ ### Graph
6595
+
6398
6596
  ---
6399
6597
 
6400
6598
  # SSearchInput
@@ -7752,6 +7950,7 @@ export type STooltipType = 'default' | 'danger' | 'warning' | 'accent';
7752
7950
 
7753
7951
  - [SChipFilter](../SChipFilter)
7754
7952
  - [SField](../SField)
7953
+ - [SGnbSystem](../SGnbSystem)
7755
7954
  - [SKeyValueTable](../SKeyValueTable)
7756
7955
  - [SSectionHeaderCard](../SSectionHeaderCard)
7757
7956
  - [SStepper](../SStepper)
package/dist/llms.txt CHANGED
@@ -37,7 +37,7 @@
37
37
  | --- | --- |
38
38
  | **버튼·링크** | `SButton` `SGhostButton` `SDropdownButton` `SSystemActionButton` `STextLink` `SSwitch` `SToggle` |
39
39
  | **입력 (폼)** | `SForm` `SField` `SInput` `SSearchInput` `SNumberInput` `STextarea` `SEditor` `SSelect` `SCheckbox` `SRadio` `SRadioGroup` `SRadioButton` `SRadioCard` `SRadioCardGroup` `SChip` `SChipInput` `SBarcodeInput` `SFilePicker` |
40
- | **날짜·시간** | `SCalendar` `SDatePicker` `SDatePickerYearListbox` `SDatePickerMonthListbox` `SDateRangePicker` `STimePicker` `STimeRangePicker` |
40
+ | **날짜·시간** | `SCalendar` `SCalendarBoard`(한 달치 일정 판) `SDatePicker` `SDatePickerYearListbox` `SDatePickerMonthListbox` `SDateRangePicker` `STimePicker` `STimeRangePicker` |
41
41
  | **표·목록** | `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SListItem` `SExpansionList` `SDraggableList` `SDraggableItem` `STree` |
42
42
  | **레이아웃** | `SLayout` `SGnb` `SGnbSystem` `SAccountListBox`(계정 행을 눌러 뜨는 계정 패널) `SPage`(제목 영역은 `header` prop) `SSectionHeaderCard` `SCard` `SDivider` `SSplitter` `SScrollArea` `SExpansionItem` |
43
43
  | **내비게이션** | `STabs` `SPagination` `SStepper` |
@@ -160,7 +160,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
160
160
  | 층 | 무엇인가 | 컴포넌트 |
161
161
  | --- | --- | --- |
162
162
  | **셸** | 앱 전체 뼈대. 페이지가 바뀌어도 남는다 | `SLayout` `SGnb` `SGnbSystem`(GNB 맨 아래 판 · 전폭 상단바 오른쪽 끝) `SPage`(제목 영역은 `header` prop) |
163
- | **블록** | `SPage` 의 직계 자식. 페이지를 세로로 쌓는 단위 | `SSectionHeaderCard` `SCard` `SForm` `SSplitter` `SScrollArea` `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SExpansionList` `SDraggableList` `STree` `SCallout` `STabs` `SStepper` `SPagination` `SDivider` |
163
+ | **블록** | `SPage` 의 직계 자식. 페이지를 세로로 쌓는 단위 | `SSectionHeaderCard` `SCard` `SForm` `SSplitter` `SScrollArea` `SCalendarBoard` `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SExpansionList` `SDraggableList` `STree` `SCallout` `STabs` `SStepper` `SPagination` `SDivider` |
164
164
  | **요소** | 블록 **안에** 놓이는 컨트롤. 혼자 페이지에 서지 않는다 | `SButton` `SGhostButton` `SDropdownButton` `SSystemActionButton` `SField` `SInput` `SSearchInput` `SNumberInput` `STextarea` `SEditor` `SSelect` `SCheckbox` `SRadio` `SRadioGroup` `SRadioButton` `SRadioCard` `SRadioCardGroup` `SSwitch` `SToggle` `SChipInput` `SBarcodeInput` `SFilePicker` `SDatePicker` `SDatePickerYearListbox` `SDatePickerMonthListbox` `SDateRangePicker` `STimePicker` `STimeRangePicker` `SCalendar` `SListItem` `SExpansionItem` `SDraggableItem` `SImage` `SLinearProgress` `SCircleProgress` |
165
165
  | **인라인** | 텍스트 흐름·셀·라벨 안에 섞인다. 혼자 블록이 되지 않는다 | `STag` `SBadge` `SIcon` `STextLink` `SChip` |
166
166
  | **레이어** | 문서 흐름 **밖**에 떠서 그려진다. 어느 층에서 띄우든 레이아웃에 영향이 없다 | `SModal` `SActionModal` `SConfirmModal` `SPopup` `SDrawer` `SPopover` `STooltip` `SPortal` `SAccountListBox`(계정 행에 붙어 뜬다 — 직접 띄우지 않는다) `SToast` `SLoadingModal` `SLoadingContainer` `SGuide` |
@@ -521,6 +521,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
521
521
  | 나열한 항목을 펼쳐 하위 내용을 보여준다 | `SExpansionList` + `SExpansionItem` | §3-7-7 |
522
522
  | 부모-자식 계층을 들여쓰기로 보여준다 | `STree` | §3-7-7 |
523
523
  | 사용자가 순서를 드래그로 바꾸게 한다 | `SDraggableList` + `SDraggableItem` | §3-7-6 |
524
+ | 날짜별 일정을 한 달치 격자로 펼쳐 보여준다 | `SCalendarBoard` | §3-7-4 |
524
525
  | 표 위에 건수 요약과 액션을 얹는다 | `STableBar` | §4-2 |
525
526
  | 상태·분류를 라벨로 찍는다 | `STag` | §3-1 |
526
527
  | 색 점만으로 상태를 찍는다 | `SBadge` | §3-1 |
@@ -1383,7 +1384,7 @@ const columns: STableColumn[] = [
1383
1384
  - 약관 동의처럼 **제출 시점에 값이 필요한 것은 항상 `SCheckbox`** 다 — 모양이 스위치에 가까워 보여도 그렇다.
1384
1385
  - `SToggle` 은 알약형 버튼이라 여러 개를 가로로 늘어놓는 필터 자리에 맞는다. 설정 화면의 on/off 한 줄에는 쓰지 않는다.
1385
1386
 
1386
- #### 3-7-4. 날짜 셋 — SDatePicker vs SDateRangePicker vs SCalendar
1387
+ #### 3-7-4. 날짜 셋 — SDatePicker vs SDateRangePicker vs SCalendar vs SCalendarBoard
1387
1388
 
1388
1389
  | 판별 | 사용 |
1389
1390
  | --- | --- |
@@ -1391,10 +1392,19 @@ const columns: STableColumn[] = [
1391
1392
  | 연도 선택 리스트만 필요하다 (트리거·팝오버는 직접 조합) | `SDatePickerYearListbox` |
1392
1393
  | 연도+월 선택 리스트만 필요하다 (트리거·팝오버는 직접 조합) | `SDatePickerMonthListbox` |
1393
1394
  | **시작~종료** 를 값으로 받는다 | `SDateRangePicker` |
1394
- | 달력 격자 **자체가 화면 콘텐츠** 다 (일정·이벤트 보기) | `SCalendar` |
1395
+ | 달력 격자 **자체가 화면 콘텐츠** 다 (날짜를 고르게 한다) | `SCalendar` |
1396
+ | 한 달치 **일정을 읽게** 펼친다 (칸마다 여러 건) | `SCalendarBoard` |
1395
1397
 
1396
1398
  - **기간을 `SDatePicker` 두 개로 만들지 않는다.** 시작이 종료보다 뒤인 입력을 막는 검증과 한쪽만 고른 중간 상태 처리가 `SDateRangePicker` 안에 이미 있다. 두 개로 쪼개면 그게 전부 앱 몫이 된다.
1397
1399
  - `SDatePicker`·`SDateRangePicker` 는 내부적으로 `SCalendar` 를 팝오버로 띄운다. 값을 받는 자리에 `SCalendar` 를 직접 쓰지 않는다.
1400
+ - **`SCalendar` 와 `SCalendarBoard` 는 방향이 반대다.** `SCalendar` 는 날짜를 **고르는** 달력(칸에는 점만 찍힌다)이고, `SCalendarBoard` 는 일정을 **읽는** 달력이다 — 칸마다 일정이 줄로 쌓이고, 칸 높이에 담기는 줄 수를 넘으면 "N개 더보기" 로 접히고, **"더보기" 또는 일정이 있는 칸 아무 데나** 누르면 **그 칸을 덮으며 뜨는 판**에 그 날짜의 일정이 전부 펼쳐진다. 폭도 다르다: `SCalendar` 는 제 폭을 갖는 요소, `SCalendarBoard` 는 페이지 폭을 채우는 블록이다.
1401
+ - **`SCalendarBoard` 는 기본이 읽기 전용 판이다.** 날짜 칸을 눌러 **고르게** 하려면 `selectable` 을 켠다 — 켜야 `onValueChange(date, events)` 로 고른 날짜와 **그 날짜의 일정**이 함께 온다. 다만 **일정이 있는 칸은 `selectable` 과 무관하게 눌린다** — 그때는 목록 판이 열린다. 둘 다 켜져 있으면 고르기와 열기가 함께 일어난다. 일정 버튼과 "N개 더보기" 도 항상 눌린다.
1402
+ - **칸 배경과 일정 색은 다른 층이다.** 그날의 성격(마감·완료·휴무 등)은 `dayColors` 로 **칸 전체**에 칠하고(`default` `danger` `accent` `complete` `dim`), 일정 하나의 색은 `events[].color` 로 준다. 둘을 섞어 쓰면 서로를 가리지 않고 함께 읽힌다.
1403
+ - 일정 왼쪽의 색 점은 `SBadge` 다 — `events[].color` 프리셋이 점 색까지 정하고, 따로 주려면 `dotColor` 에 `SBadge` 9색 중 하나를 넣는다 (§3-1).
1404
+ - **칸 본문을 통째로 바꾸려면 `dayContent` 다.** 일정으로 표현되지 않는 그날치 요약(재고·매출 같은)을 칸에 얹을 때 쓴다. **슬롯을 준 날짜는 그 날짜의 `events` 를 그리지 않고 목록 판도 열지 않는다** — 한 칸에 둘을 겹쳐 담지 않는다. 일정과 요약을 함께 보여야 하면 요약을 일정 한 건(`events[]`)으로 넣는다.
1405
+ - **`SCalendarBoard` 는 높이를 부모에게서 받는다.** 행이 그 높이를 균등하게 나눠 갖고, 칸 높이가 다시 "한 칸에 몇 줄이 보일지" 를 정한다. 그래서 **놓는 자리에 높이를 준다** — 페이지 본문의 남은 높이를 채우려면 `SPage` 안에서 스택을 `flex-1 min-h-0` 으로 두고 판에 `h-full` 을 준다. 높이를 주지 않으면 칸이 최소 높이로 주저앉아 한두 줄만 보인다.
1406
+ - **한 칸에 몇 줄을 펼칠지는 컴포넌트가 잰다.** 조절하는 prop 이 없다 — 칸 높이에서 나오는 값이라 따로 정할 것이 아니다. 줄이 넘치면 마지막 한 줄을 "N개 더보기" 에 내주므로 **접히든 아니든 칸 높이가 같다.** **소비 앱이 `events` 를 미리 잘라 넘기지 않는다.** 잘라 넘기면 "N개 더보기" 의 수가 실제 건수와 어긋나고, 눌러도 나머지가 나오지 않는다.
1407
+ - **`events[].label` 은 필수다** — 일정이 무엇인지 알리는 부분이라 비워 두지 않는다. 인라인 HTML 을 받으므로 부분 강조가 필요할 때만 태그를 쓰고, 나머지는 `description`·`value` 로 나눠 담는다. 칸이 좁아지면 `label`+`description` 이 한 덩어리로 말줄임되고 `value` 만 끝에 온전히 남는다 — **금액·수량은 반드시 `value` 에 담는다.** `description` 에 넣으면 잘린다.
1398
1408
  - `SDatePickerYearListbox`·`SDatePickerMonthListbox` 는 `SDatePicker` 의 mode listbox 조각만 떼어낸 컴포넌트다. 일반 폼 입력에는 `SDatePicker mode="year" | "month"` 를 우선 쓰고, 다른 트리거·팝오버 안에 리스트만 끼워 넣을 때만 직접 쓴다.
1399
1409
 
1400
1410
  **날짜·시간 피커는 폭 상한을 스스로 갖는다 — `width` 를 주지 않는다.** 값 길이가 `YYYY-MM-DD` 처럼 정해져 있어 컴포넌트가 사이즈별 상한을 안다. `SKeyValueTable` 이 모든 컨트롤에 `width="100%"` 를 넘기지만, 이 상한 덕분에 행 전체로 늘어나지 않고 제 폭에서 멈춘다.
@@ -1627,7 +1637,7 @@ export default function AppShell({
1627
1637
  ```tsx
1628
1638
  {/* 폭을 기억해야 하면 menuWidth 를 앱이 쥐고 onMenuWidthChange 로 되받아 저장한다.
1629
1639
  초기값만 정하면 되면 defaultMenuWidth 하나로 끝난다. */}
1630
- <SGnb items={MENU} value={current} onValueChange={navigate} resizable defaultMenuWidth={240} />
1640
+ <SGnb items={MENU} value={current} onValueChange={navigate} resizable defaultMenuWidth={220} />
1631
1641
  ```
1632
1642
 
1633
1643
  `onMenuWidthChange` 는 **드래그를 놓는 순간**(또는 방향키 조작) 한 번만 온다 — 저장 로직을 그대로 붙여도 프레임마다 쓰이지 않는다. 접혀 있거나 레일 리프가 활성이라 깔 메뉴가 없으면 조절선은 나오지 않는다.
@@ -1748,7 +1758,12 @@ import { SModalOutlet } from 'sellmate-design-system-react';
1748
1758
  - **`header="fix"` 를 접으면 알림·계정 아이콘만 남는다** — `actions`·`domain`·`setting` 은 48px 폭에 놓을 자리가 없어 렌더되지 않고, 알림 개수는 점 배지가 된다. **알림도 계정도 안 쓰는 조합이면 접힌 패널은 아예 렌더되지 않는다** — 접힌 상태에서도 반드시 눌러야 하는 것이 그 둘 밖에 있으면 `foldedTop`/`foldedFooter` 로 따로 준다.
1749
1759
  - **`header="full"` 은 접어도 상단바가 남으므로 조각들도 그대로 남는다.** 대신 가로로 자리가 넉넉하지 않아 알림·설정이 라벨을 벗고 아이콘(알림은 개수까지)만 남는다 — 이건 컴포넌트가 알아서 하므로 앱이 라벨을 지우지 않는다.
1750
1760
  - **`account` 를 쓰면 `account.listBox` 가 필수다** (§3-5-8) — 계정 행을 누르면 이메일·이름·권한과 계정 설정·언어 변경·로그아웃이 예외 없이 뜬다. 뜨는 방향은 판이 놓인 자리가 정하므로 앱이 넘기지 않는다 — 판이면 계정 행 위로, 상단바면 아래로 펼치고, 접힌 레일도 판과 같다. `account.onClick` 은 패널을 여는 것 말고 따로 할 일(로깅 등)이 있을 때만 준다.
1751
- - **알림 개수는 `alert.count` 하나로 표현한다.** 1 이상이면 벨이 울리는 아이콘과 강조색으로 바뀐다 — 색은 GNB 색이 정하므로 앱이 직접 칠하지 않는다.
1761
+ - **알림 개수는 `alert.count` 하나로 표현한다.** 1 이상이면 벨이 울리는 아이콘과 강조색으로 바뀐다 — 색은 GNB 색이 정하므로 앱이 직접 칠하지 않는다. **`resizable` 로 메뉴를 기본 폭보다 좁게 줄이면 개수를 적을 가로가 모자라 접힘과 같은 점 배지로 바뀐다** — 컴포넌트가 알아서 하므로 앱이 폭을 보고 `count` 를 지우지 않는다.
1762
+ - **알림을 눌러 뜨는 목록은 `alert.listBox` 에 내용만 넘긴다** — `SPortal` 을 따로 띄워 알림 버튼에 붙이지 않는다. 목록에 무엇을 쌓을지는 서비스마다 다르지만 **뜨는 자리는 늘 같아야 하므로**, 방향(판·접힌 레일은 버튼 오른쪽 · 상단바는 아래로 오른쪽 끝)과 바깥 클릭·ESC 닫힘, 배경·라운드·그림자는 컴포넌트가 쥔다. 여닫는 일도 알림 버튼이 하므로 **`onOpenChange` 는 그 사실을 알아야 할 때만** 받는다(연 김에 읽음 처리하는 화면 등) — 이 값으로 목록을 대신 열거나 막지 않는다. 계정 행(`account.listBox`)과 같은 규칙이다.
1763
+ - **알림에 안내 툴팁을 띄우려면 `alert.tooltip` 에 문구만 넘긴다** — `STooltip` 을 직접 세워 알림 버튼에 붙이지 않는다. 색(판이 light 면 기본 · 그 밖은 강조)과 방향(판·접힌 레일은 오른쪽 · 상단바는 아래)은 자리가 정하고, 스스로 사라지지 않다가 **알림을 누르거나 버튼에서 커서를 뺄 때** 닫힌다.
1764
+ - **닫힘은 `onTooltipDismiss` 로 받아 `tooltip` 을 비워 둔다.** 같은 값을 계속 넘기는 동안에는 다시 뜨지 않고, **비웠다 다시 넘기면 문구가 같아도 새 안내로 뜬다** — 새 알림마다 같은 안내를 다시 띄우는 화면이 막히지 않는다.
1765
+ - 재노출 신호는 문구가 **없음 → 있음** 으로 바뀌는 것이다. 한 이벤트 핸들러 안에서 비웠다 곧바로 넣으면 렌더가 한 번으로 묶여 신호가 되지 않는다 — 닫을 때 비우고, 다시 필요할 때 넘긴다.
1766
+ - 컴포넌트가 아는 범위는 그 자리가 서 있는 동안뿐이다(새로고침하거나 GNB 를 접어 알림이 다른 자리로 옮겨 서면 새로 마운트된다). **그 사용자에게 두 번 다시 보이지 않아야 하면 앱이 닫힘을 저장해 두고 `tooltip` 을 넘기지 않는다.**
1752
1767
  - **`header="fix"` + `useRail` 에서 하위 메뉴가 없는 레일 아이템이 활성이면 메뉴 컬럼째 사라지므로 이 패널도 함께 빠진다.** 항상 보여야 하는 계정·알림이라면 그런 레일 리프를 두지 않는다 — 또는 `header="full"` 로 두면 상단바에 남는다(그런 레일 리프가 있으면 GNB 가 `header` 를 `full` 로 강제한다).
1753
1768
 
1754
1769
  ### 4-2. 목록 페이지 (필터 + 테이블)
@@ -2340,7 +2355,7 @@ Tailwind 유틸리티는 아래 스케일에 있는 값만 사용한다. 리터
2340
2355
  --sys-color-navigation-gnb-bg-dark
2341
2356
  --sys-color-navigation-gnb-bg-system
2342
2357
 
2343
- ## 3. 컴포넌트 인덱스 (71종)
2358
+ ## 3. 컴포넌트 인덱스 (72종)
2344
2359
 
2345
2360
  **Props 는 이 문서에 없다.** 쓸 컴포넌트를 정했으면 그 컴포넌트의 README 를 읽는다.
2346
2361
 
@@ -2349,4 +2364,4 @@ Tailwind 유틸리티는 아래 스케일에 있는 값만 사용한다. 리터
2349
2364
  예) SButton 을 쓴다면 `dist/components/SButton/README.md`.
2350
2365
  prop 을 추측해서 쓰지 말고 반드시 README 로 확인한다 (분류별 용도는 §1 의 "전체 컴포넌트 인덱스" 참조).
2351
2366
 
2352
- SAccountListBox · SActionModal · SBadge · SBarcodeInput · SButton · SCalendar · SCallout · SCard · SCheckbox · SChip · SChipFilter · SChipInput · SCircleProgress · SConfirmModal · SDatePicker · SDateRangePicker · SDivider · SDraggableItem · SDraggableList · SDrawer · SDropdownButton · SEditor · SExpansionItem · SExpansionList · SField · SFilePicker · SForm · SGhostButton · SGnb · SGnbSystem · SGuide · SIcon · SImage · SInput · SKeyValueTable · SLayout · SLinearProgress · SList · SListItem · SLoadingContainer · SLoadingModal · SModal · SNumberInput · SPage · SPagination · SPopover · SPopup · SPortal · SRadio · SRadioButton · SRadioCard · SScrollArea · SSearchInput · SSectionHeaderCard · SSelect · SSplitter · SStepper · SSwitch · SSystemActionButton · STable · STableBar · STabs · STag · STextLink · STextarea · STimePicker · STimeRangePicker · SToast · SToggle · STooltip · STree
2367
+ SAccountListBox · SActionModal · SBadge · SBarcodeInput · SButton · SCalendar · SCalendarBoard · SCallout · SCard · SCheckbox · SChip · SChipFilter · SChipInput · SCircleProgress · SConfirmModal · SDatePicker · SDateRangePicker · SDivider · SDraggableItem · SDraggableList · SDrawer · SDropdownButton · SEditor · SExpansionItem · SExpansionList · SField · SFilePicker · SForm · SGhostButton · SGnb · SGnbSystem · SGuide · SIcon · SImage · SInput · SKeyValueTable · SLayout · SLinearProgress · SList · SListItem · SLoadingContainer · SLoadingModal · SModal · SNumberInput · SPage · SPagination · SPopover · SPopup · SPortal · SRadio · SRadioButton · SRadioCard · SScrollArea · SSearchInput · SSectionHeaderCard · SSelect · SSplitter · SStepper · SSwitch · SSystemActionButton · STable · STableBar · STabs · STag · STextLink · STextarea · STimePicker · STimeRangePicker · SToast · SToggle · STooltip · STree