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
package/AGENTS.md CHANGED
@@ -28,7 +28,7 @@
28
28
  | --- | --- |
29
29
  | **버튼·링크** | `SButton` `SGhostButton` `SDropdownButton` `SSystemActionButton` `STextLink` `SSwitch` `SToggle` |
30
30
  | **입력 (폼)** | `SForm` `SField` `SInput` `SSearchInput` `SNumberInput` `STextarea` `SEditor` `SSelect` `SCheckbox` `SRadio` `SRadioGroup` `SRadioButton` `SRadioCard` `SRadioCardGroup` `SChip` `SChipInput` `SBarcodeInput` `SFilePicker` |
31
- | **날짜·시간** | `SCalendar` `SDatePicker` `SDatePickerYearListbox` `SDatePickerMonthListbox` `SDateRangePicker` `STimePicker` `STimeRangePicker` |
31
+ | **날짜·시간** | `SCalendar` `SCalendarBoard`(한 달치 일정 판) `SDatePicker` `SDatePickerYearListbox` `SDatePickerMonthListbox` `SDateRangePicker` `STimePicker` `STimeRangePicker` |
32
32
  | **표·목록** | `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SListItem` `SExpansionList` `SDraggableList` `SDraggableItem` `STree` |
33
33
  | **레이아웃** | `SLayout` `SGnb` `SGnbSystem` `SAccountListBox`(계정 행을 눌러 뜨는 계정 패널) `SPage`(제목 영역은 `header` prop) `SSectionHeaderCard` `SCard` `SDivider` `SSplitter` `SScrollArea` `SExpansionItem` |
34
34
  | **내비게이션** | `STabs` `SPagination` `SStepper` |
@@ -151,7 +151,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
151
151
  | 층 | 무엇인가 | 컴포넌트 |
152
152
  | --- | --- | --- |
153
153
  | **셸** | 앱 전체 뼈대. 페이지가 바뀌어도 남는다 | `SLayout` `SGnb` `SGnbSystem`(GNB 맨 아래 판 · 전폭 상단바 오른쪽 끝) `SPage`(제목 영역은 `header` prop) |
154
- | **블록** | `SPage` 의 직계 자식. 페이지를 세로로 쌓는 단위 | `SSectionHeaderCard` `SCard` `SForm` `SSplitter` `SScrollArea` `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SExpansionList` `SDraggableList` `STree` `SCallout` `STabs` `SStepper` `SPagination` `SDivider` |
154
+ | **블록** | `SPage` 의 직계 자식. 페이지를 세로로 쌓는 단위 | `SSectionHeaderCard` `SCard` `SForm` `SSplitter` `SScrollArea` `SCalendarBoard` `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SExpansionList` `SDraggableList` `STree` `SCallout` `STabs` `SStepper` `SPagination` `SDivider` |
155
155
  | **요소** | 블록 **안에** 놓이는 컨트롤. 혼자 페이지에 서지 않는다 | `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` |
156
156
  | **인라인** | 텍스트 흐름·셀·라벨 안에 섞인다. 혼자 블록이 되지 않는다 | `STag` `SBadge` `SIcon` `STextLink` `SChip` |
157
157
  | **레이어** | 문서 흐름 **밖**에 떠서 그려진다. 어느 층에서 띄우든 레이아웃에 영향이 없다 | `SModal` `SActionModal` `SConfirmModal` `SPopup` `SDrawer` `SPopover` `STooltip` `SPortal` `SAccountListBox`(계정 행에 붙어 뜬다 — 직접 띄우지 않는다) `SToast` `SLoadingModal` `SLoadingContainer` `SGuide` |
@@ -512,6 +512,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
512
512
  | 나열한 항목을 펼쳐 하위 내용을 보여준다 | `SExpansionList` + `SExpansionItem` | §3-7-7 |
513
513
  | 부모-자식 계층을 들여쓰기로 보여준다 | `STree` | §3-7-7 |
514
514
  | 사용자가 순서를 드래그로 바꾸게 한다 | `SDraggableList` + `SDraggableItem` | §3-7-6 |
515
+ | 날짜별 일정을 한 달치 격자로 펼쳐 보여준다 | `SCalendarBoard` | §3-7-4 |
515
516
  | 표 위에 건수 요약과 액션을 얹는다 | `STableBar` | §4-2 |
516
517
  | 상태·분류를 라벨로 찍는다 | `STag` | §3-1 |
517
518
  | 색 점만으로 상태를 찍는다 | `SBadge` | §3-1 |
@@ -1374,7 +1375,7 @@ const columns: STableColumn[] = [
1374
1375
  - 약관 동의처럼 **제출 시점에 값이 필요한 것은 항상 `SCheckbox`** 다 — 모양이 스위치에 가까워 보여도 그렇다.
1375
1376
  - `SToggle` 은 알약형 버튼이라 여러 개를 가로로 늘어놓는 필터 자리에 맞는다. 설정 화면의 on/off 한 줄에는 쓰지 않는다.
1376
1377
 
1377
- #### 3-7-4. 날짜 셋 — SDatePicker vs SDateRangePicker vs SCalendar
1378
+ #### 3-7-4. 날짜 셋 — SDatePicker vs SDateRangePicker vs SCalendar vs SCalendarBoard
1378
1379
 
1379
1380
  | 판별 | 사용 |
1380
1381
  | --- | --- |
@@ -1382,10 +1383,19 @@ const columns: STableColumn[] = [
1382
1383
  | 연도 선택 리스트만 필요하다 (트리거·팝오버는 직접 조합) | `SDatePickerYearListbox` |
1383
1384
  | 연도+월 선택 리스트만 필요하다 (트리거·팝오버는 직접 조합) | `SDatePickerMonthListbox` |
1384
1385
  | **시작~종료** 를 값으로 받는다 | `SDateRangePicker` |
1385
- | 달력 격자 **자체가 화면 콘텐츠** 다 (일정·이벤트 보기) | `SCalendar` |
1386
+ | 달력 격자 **자체가 화면 콘텐츠** 다 (날짜를 고르게 한다) | `SCalendar` |
1387
+ | 한 달치 **일정을 읽게** 펼친다 (칸마다 여러 건) | `SCalendarBoard` |
1386
1388
 
1387
1389
  - **기간을 `SDatePicker` 두 개로 만들지 않는다.** 시작이 종료보다 뒤인 입력을 막는 검증과 한쪽만 고른 중간 상태 처리가 `SDateRangePicker` 안에 이미 있다. 두 개로 쪼개면 그게 전부 앱 몫이 된다.
1388
1390
  - `SDatePicker`·`SDateRangePicker` 는 내부적으로 `SCalendar` 를 팝오버로 띄운다. 값을 받는 자리에 `SCalendar` 를 직접 쓰지 않는다.
1391
+ - **`SCalendar` 와 `SCalendarBoard` 는 방향이 반대다.** `SCalendar` 는 날짜를 **고르는** 달력(칸에는 점만 찍힌다)이고, `SCalendarBoard` 는 일정을 **읽는** 달력이다 — 칸마다 일정이 줄로 쌓이고, 칸 높이에 담기는 줄 수를 넘으면 "N개 더보기" 로 접히고, **"더보기" 또는 일정이 있는 칸 아무 데나** 누르면 **그 칸을 덮으며 뜨는 판**에 그 날짜의 일정이 전부 펼쳐진다. 폭도 다르다: `SCalendar` 는 제 폭을 갖는 요소, `SCalendarBoard` 는 페이지 폭을 채우는 블록이다.
1392
+ - **`SCalendarBoard` 는 기본이 읽기 전용 판이다.** 날짜 칸을 눌러 **고르게** 하려면 `selectable` 을 켠다 — 켜야 `onValueChange(date, events)` 로 고른 날짜와 **그 날짜의 일정**이 함께 온다. 다만 **일정이 있는 칸은 `selectable` 과 무관하게 눌린다** — 그때는 목록 판이 열린다. 둘 다 켜져 있으면 고르기와 열기가 함께 일어난다. 일정 버튼과 "N개 더보기" 도 항상 눌린다.
1393
+ - **칸 배경과 일정 색은 다른 층이다.** 그날의 성격(마감·완료·휴무 등)은 `dayColors` 로 **칸 전체**에 칠하고(`default` `danger` `accent` `complete` `dim`), 일정 하나의 색은 `events[].color` 로 준다. 둘을 섞어 쓰면 서로를 가리지 않고 함께 읽힌다.
1394
+ - 일정 왼쪽의 색 점은 `SBadge` 다 — `events[].color` 프리셋이 점 색까지 정하고, 따로 주려면 `dotColor` 에 `SBadge` 9색 중 하나를 넣는다 (§3-1).
1395
+ - **칸 본문을 통째로 바꾸려면 `dayContent` 다.** 일정으로 표현되지 않는 그날치 요약(재고·매출 같은)을 칸에 얹을 때 쓴다. **슬롯을 준 날짜는 그 날짜의 `events` 를 그리지 않고 목록 판도 열지 않는다** — 한 칸에 둘을 겹쳐 담지 않는다. 일정과 요약을 함께 보여야 하면 요약을 일정 한 건(`events[]`)으로 넣는다.
1396
+ - **`SCalendarBoard` 는 높이를 부모에게서 받는다.** 행이 그 높이를 균등하게 나눠 갖고, 칸 높이가 다시 "한 칸에 몇 줄이 보일지" 를 정한다. 그래서 **놓는 자리에 높이를 준다** — 페이지 본문의 남은 높이를 채우려면 `SPage` 안에서 스택을 `flex-1 min-h-0` 으로 두고 판에 `h-full` 을 준다. 높이를 주지 않으면 칸이 최소 높이로 주저앉아 한두 줄만 보인다.
1397
+ - **한 칸에 몇 줄을 펼칠지는 컴포넌트가 잰다.** 조절하는 prop 이 없다 — 칸 높이에서 나오는 값이라 따로 정할 것이 아니다. 줄이 넘치면 마지막 한 줄을 "N개 더보기" 에 내주므로 **접히든 아니든 칸 높이가 같다.** **소비 앱이 `events` 를 미리 잘라 넘기지 않는다.** 잘라 넘기면 "N개 더보기" 의 수가 실제 건수와 어긋나고, 눌러도 나머지가 나오지 않는다.
1398
+ - **`events[].label` 은 필수다** — 일정이 무엇인지 알리는 부분이라 비워 두지 않는다. 인라인 HTML 을 받으므로 부분 강조가 필요할 때만 태그를 쓰고, 나머지는 `description`·`value` 로 나눠 담는다. 칸이 좁아지면 `label`+`description` 이 한 덩어리로 말줄임되고 `value` 만 끝에 온전히 남는다 — **금액·수량은 반드시 `value` 에 담는다.** `description` 에 넣으면 잘린다.
1389
1399
  - `SDatePickerYearListbox`·`SDatePickerMonthListbox` 는 `SDatePicker` 의 mode listbox 조각만 떼어낸 컴포넌트다. 일반 폼 입력에는 `SDatePicker mode="year" | "month"` 를 우선 쓰고, 다른 트리거·팝오버 안에 리스트만 끼워 넣을 때만 직접 쓴다.
1390
1400
 
1391
1401
  **날짜·시간 피커는 폭 상한을 스스로 갖는다 — `width` 를 주지 않는다.** 값 길이가 `YYYY-MM-DD` 처럼 정해져 있어 컴포넌트가 사이즈별 상한을 안다. `SKeyValueTable` 이 모든 컨트롤에 `width="100%"` 를 넘기지만, 이 상한 덕분에 행 전체로 늘어나지 않고 제 폭에서 멈춘다.
@@ -1618,7 +1628,7 @@ export default function AppShell({
1618
1628
  ```tsx
1619
1629
  {/* 폭을 기억해야 하면 menuWidth 를 앱이 쥐고 onMenuWidthChange 로 되받아 저장한다.
1620
1630
  초기값만 정하면 되면 defaultMenuWidth 하나로 끝난다. */}
1621
- <SGnb items={MENU} value={current} onValueChange={navigate} resizable defaultMenuWidth={240} />
1631
+ <SGnb items={MENU} value={current} onValueChange={navigate} resizable defaultMenuWidth={220} />
1622
1632
  ```
1623
1633
 
1624
1634
  `onMenuWidthChange` 는 **드래그를 놓는 순간**(또는 방향키 조작) 한 번만 온다 — 저장 로직을 그대로 붙여도 프레임마다 쓰이지 않는다. 접혀 있거나 레일 리프가 활성이라 깔 메뉴가 없으면 조절선은 나오지 않는다.
@@ -1739,7 +1749,12 @@ import { SModalOutlet } from 'sellmate-design-system-react';
1739
1749
  - **`header="fix"` 를 접으면 알림·계정 아이콘만 남는다** — `actions`·`domain`·`setting` 은 48px 폭에 놓을 자리가 없어 렌더되지 않고, 알림 개수는 점 배지가 된다. **알림도 계정도 안 쓰는 조합이면 접힌 패널은 아예 렌더되지 않는다** — 접힌 상태에서도 반드시 눌러야 하는 것이 그 둘 밖에 있으면 `foldedTop`/`foldedFooter` 로 따로 준다.
1740
1750
  - **`header="full"` 은 접어도 상단바가 남으므로 조각들도 그대로 남는다.** 대신 가로로 자리가 넉넉하지 않아 알림·설정이 라벨을 벗고 아이콘(알림은 개수까지)만 남는다 — 이건 컴포넌트가 알아서 하므로 앱이 라벨을 지우지 않는다.
1741
1751
  - **`account` 를 쓰면 `account.listBox` 가 필수다** (§3-5-8) — 계정 행을 누르면 이메일·이름·권한과 계정 설정·언어 변경·로그아웃이 예외 없이 뜬다. 뜨는 방향은 판이 놓인 자리가 정하므로 앱이 넘기지 않는다 — 판이면 계정 행 위로, 상단바면 아래로 펼치고, 접힌 레일도 판과 같다. `account.onClick` 은 패널을 여는 것 말고 따로 할 일(로깅 등)이 있을 때만 준다.
1742
- - **알림 개수는 `alert.count` 하나로 표현한다.** 1 이상이면 벨이 울리는 아이콘과 강조색으로 바뀐다 — 색은 GNB 색이 정하므로 앱이 직접 칠하지 않는다.
1752
+ - **알림 개수는 `alert.count` 하나로 표현한다.** 1 이상이면 벨이 울리는 아이콘과 강조색으로 바뀐다 — 색은 GNB 색이 정하므로 앱이 직접 칠하지 않는다. **`resizable` 로 메뉴를 기본 폭보다 좁게 줄이면 개수를 적을 가로가 모자라 접힘과 같은 점 배지로 바뀐다** — 컴포넌트가 알아서 하므로 앱이 폭을 보고 `count` 를 지우지 않는다.
1753
+ - **알림을 눌러 뜨는 목록은 `alert.listBox` 에 내용만 넘긴다** — `SPortal` 을 따로 띄워 알림 버튼에 붙이지 않는다. 목록에 무엇을 쌓을지는 서비스마다 다르지만 **뜨는 자리는 늘 같아야 하므로**, 방향(판·접힌 레일은 버튼 오른쪽 · 상단바는 아래로 오른쪽 끝)과 바깥 클릭·ESC 닫힘, 배경·라운드·그림자는 컴포넌트가 쥔다. 여닫는 일도 알림 버튼이 하므로 **`onOpenChange` 는 그 사실을 알아야 할 때만** 받는다(연 김에 읽음 처리하는 화면 등) — 이 값으로 목록을 대신 열거나 막지 않는다. 계정 행(`account.listBox`)과 같은 규칙이다.
1754
+ - **알림에 안내 툴팁을 띄우려면 `alert.tooltip` 에 문구만 넘긴다** — `STooltip` 을 직접 세워 알림 버튼에 붙이지 않는다. 색(판이 light 면 기본 · 그 밖은 강조)과 방향(판·접힌 레일은 오른쪽 · 상단바는 아래)은 자리가 정하고, 스스로 사라지지 않다가 **알림을 누르거나 버튼에서 커서를 뺄 때** 닫힌다.
1755
+ - **닫힘은 `onTooltipDismiss` 로 받아 `tooltip` 을 비워 둔다.** 같은 값을 계속 넘기는 동안에는 다시 뜨지 않고, **비웠다 다시 넘기면 문구가 같아도 새 안내로 뜬다** — 새 알림마다 같은 안내를 다시 띄우는 화면이 막히지 않는다.
1756
+ - 재노출 신호는 문구가 **없음 → 있음** 으로 바뀌는 것이다. 한 이벤트 핸들러 안에서 비웠다 곧바로 넣으면 렌더가 한 번으로 묶여 신호가 되지 않는다 — 닫을 때 비우고, 다시 필요할 때 넘긴다.
1757
+ - 컴포넌트가 아는 범위는 그 자리가 서 있는 동안뿐이다(새로고침하거나 GNB 를 접어 알림이 다른 자리로 옮겨 서면 새로 마운트된다). **그 사용자에게 두 번 다시 보이지 않아야 하면 앱이 닫힘을 저장해 두고 `tooltip` 을 넘기지 않는다.**
1743
1758
  - **`header="fix"` + `useRail` 에서 하위 메뉴가 없는 레일 아이템이 활성이면 메뉴 컬럼째 사라지므로 이 패널도 함께 빠진다.** 항상 보여야 하는 계정·알림이라면 그런 레일 리프를 두지 않는다 — 또는 `header="full"` 로 두면 상단바에 남는다(그런 레일 리프가 있으면 GNB 가 `header` 를 `full` 로 강제한다).
1744
1759
 
1745
1760
  ### 4-2. 목록 페이지 (필터 + 테이블)
@@ -38,12 +38,14 @@ export const BADGE_COLORS = [
38
38
 
39
39
  ### Used by
40
40
 
41
+ - [SCalendarBoard](../SCalendarBoard)
41
42
  - [SSectionHeaderCard](../SSectionHeaderCard)
42
43
 
43
44
  ### Graph
44
45
 
45
46
  ```mermaid
46
47
  graph TD;
48
+ SCalendarBoard --> SBadge
47
49
  SSectionHeaderCard --> SBadge
48
50
  style SBadge fill:#f9f,stroke:#333,stroke-width:4px
49
51
  ```
@@ -53,6 +53,7 @@ export const BUTTON_SIZES = ['xs', 'sm', 'md', 'lg'] as const;
53
53
 
54
54
  ### Used by
55
55
 
56
+ - [SCalendarBoard](../SCalendarBoard)
56
57
  - [SConfirmModal](../SConfirmModal)
57
58
  - [SDropdownButton](../SDropdownButton)
58
59
  - [SEditor](../SEditor)
@@ -71,6 +72,7 @@ export const BUTTON_SIZES = ['xs', 'sm', 'md', 'lg'] as const;
71
72
  ```mermaid
72
73
  graph TD;
73
74
  SButton --> SIcon
75
+ SCalendarBoard --> SButton
74
76
  SConfirmModal --> SButton
75
77
  SDropdownButton --> SButton
76
78
  SEditor --> SButton
@@ -0,0 +1,38 @@
1
+ import { type HTMLAttributes, type MouseEvent, type ReactNode } from 'react';
2
+ import { type SCalendarBoardDayColor } from './calendarBoard.config';
3
+ import type { SCalendarBoardEvent } from './types';
4
+ /**
5
+ * 달력의 날짜 한 칸 (SCalendarBoard 내부 조립 요소).
6
+ * 위에 날짜 숫자, 아래에 일정 목록과 "N개 더보기" 가 쌓인다.
7
+ * `body` 를 받은 칸은 아래를 통째로 그것에 내준다 — 일정은 그리지 않는다.
8
+ */
9
+ export declare const CalendarDayCard: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & {
10
+ /** YYYY-MM-DD */
11
+ date: string;
12
+ /** 1-31 */
13
+ day: number;
14
+ /** 보고 있는 달에 속한 날짜인지 */
15
+ inCurrentMonth: boolean;
16
+ isToday: boolean;
17
+ isSelected: boolean;
18
+ /** 칸을 눌러 고를 수 있는지 */
19
+ selectable: boolean;
20
+ /** 칸 배경 */
21
+ color: SCalendarBoardDayColor;
22
+ /** 이 칸에 펼쳐 그릴 일정 */
23
+ events: SCalendarBoardEvent[];
24
+ /**
25
+ * 일정 자리를 대신 차지할 칸 본문 (SCalendarBoard 의 `dayContent`).
26
+ * 주면 일정·"더보기" 를 그리지 않는다. `content` 는 HTMLAttributes 가 이미 쓰는 이름이라 피했다.
27
+ */
28
+ body?: ReactNode;
29
+ /** 접혀 있는 일정 수. 0 이면 "더보기" 를 그리지 않는다 */
30
+ hiddenCount: number;
31
+ /** 이 칸의 일정 목록 판이 열려 있는지 */
32
+ isOpen: boolean;
33
+ moreLabel?: string;
34
+ onDaySelect?: (date: string) => void;
35
+ onEventClick?: (event: SCalendarBoardEvent, e: MouseEvent<HTMLButtonElement>) => void;
36
+ /** 일정 목록 판 열기 — 칸 자체를 눌렀을 때와 "더보기" 를 눌렀을 때 모두 여기로 온다 */
37
+ onOpenEvents?: () => void;
38
+ } & import("react").RefAttributes<HTMLDivElement>>;
@@ -0,0 +1,26 @@
1
+ import { type MouseEvent } from 'react';
2
+ import type { SCalendarBoardEvent } from './types';
3
+ /**
4
+ * 한 날짜의 일정을 전부 펼쳐 보여주는 목록 판 (SCalendarBoard 내부 조립 요소).
5
+ * 칸을 누르거나 "N개 더보기" 를 누르면 **그 날짜 칸을 덮은 채** 좌·상으로 아웃덴트만큼 빠져나와 뜬다 —
6
+ * 칸에서 자라난 것처럼 보이게 하기 위함이다. 위치와 최소 높이는 SCalendarBoard 가 정하고,
7
+ * 그보다 내용이 길면 자라다 상한에서 멈춘다.
8
+ */
9
+ export declare function CalendarDayEventListBox({ date, events, onEventClick, minWidth, minHeight, onClose, closeLabel, }: {
10
+ /** YYYY-MM-DD */
11
+ date: string;
12
+ /**
13
+ * 판이 적어도 이만큼은 넓어야 한다(px) — 덮는 칸 너비 + 좌·우 아웃덴트가 온다.
14
+ * 내용이 넓으면 글자가 잘리지 않게 여기서부터 자란다. 칸을 못 쟀으면 내용 너비를 따른다.
15
+ */
16
+ minWidth?: number;
17
+ /**
18
+ * 판이 적어도 이만큼은 높아야 한다(px) — 덮는 칸 높이 + 상·하 아웃덴트가 온다.
19
+ * 내용이 이보다 짧아도 칸을 딱 감싸는 모양이 유지된다. 칸을 못 쟀으면 내용 높이를 따른다.
20
+ */
21
+ minHeight?: number;
22
+ events: SCalendarBoardEvent[];
23
+ onEventClick?: (event: SCalendarBoardEvent, e: MouseEvent<HTMLButtonElement>) => void;
24
+ onClose?: () => void;
25
+ closeLabel?: string;
26
+ }): import("react").JSX.Element;
@@ -0,0 +1,13 @@
1
+ import { type MouseEvent } from 'react';
2
+ import type { SCalendarBoardEvent } from './types';
3
+ /**
4
+ * 달력 칸/패널 안의 일정 한 줄 (SCalendarBoard 내부 조립 요소).
5
+ *
6
+ * 점 → 레이블(강조) → 설명 → `/` → 값 순서로 한 줄에 눕는다.
7
+ * 가운데 레이블 묶음만 줄어들고 값은 끝에 고정되므로, 좁은 칸에서도 금액이 잘리지 않는다.
8
+ */
9
+ export declare function CalendarEventButton({ event, onSelect, className, }: {
10
+ event: SCalendarBoardEvent;
11
+ onSelect?: (event: SCalendarBoardEvent, e: MouseEvent<HTMLButtonElement>) => void;
12
+ className?: string;
13
+ }): import("react").JSX.Element;
@@ -0,0 +1,12 @@
1
+ import { type MouseEvent } from 'react';
2
+ /**
3
+ * 칸에 다 담기지 않은 일정 수를 알리는 "N개 더보기" 줄 (SCalendarBoard 내부 조립 요소).
4
+ * 개수는 강조색, 뒷말은 본문색으로 갈라 개수가 먼저 읽히게 한다.
5
+ */
6
+ export declare const CalendarMoreButton: import("react").ForwardRefExoticComponent<{
7
+ count: number;
8
+ /** 개수 뒤에 붙는 말 */
9
+ label?: string;
10
+ onClick?: (e: MouseEvent<HTMLButtonElement>) => void;
11
+ className?: string;
12
+ } & import("react").RefAttributes<HTMLButtonElement>>;
@@ -0,0 +1,137 @@
1
+ # SCalendarBoard
2
+
3
+ > 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
4
+
5
+ ### SCalendarBoard
6
+
7
+ #### Props
8
+
9
+ | Prop | Type | Default | Description |
10
+ |------|------|---------|-------------|
11
+ | `year?` | `number` | — | 보이는 연도 (제어). `month` 와 함께 준다 |
12
+ | `month?` | `number` | — | 보이는 월 1-12 (제어). `year` 와 함께 준다 |
13
+ | `defaultYear?` | `number` | — | 처음 보여줄 연도 (비제어). 없으면 오늘 |
14
+ | `defaultMonth?` | `number` | — | 처음 보여줄 월 1-12 (비제어). 없으면 오늘 |
15
+ | `selectable?` | `boolean` | `false` | 날짜 칸을 눌러 고를 수 있게 한다. 기본은 읽기 전용 판이다 — 켜야 칸에 커서·포커스·키보드(Enter·Space)가 붙고 `onValueChange` 가 온다. 일정 버튼과 "N개 더보기" 는 이 값과 무관하게 항상 눌린다. |
16
+ | `value?` | `string \| null` | — | 선택 날짜 (YYYY-MM-DD). `selectable` 과 별개로 강조만 주고 싶을 때도 쓴다 |
17
+ | `events?` | `SCalendarBoardEvent[]` | — | 날짜별 일정 목록. `date` 로 칸에 배분된다 |
18
+ | `dayColors?` | `Record<string, SCalendarBoardDayColor>` | — | 날짜별 칸 배경. 키는 `YYYY-MM-DD`, 없는 날짜는 `'default'` 다. 그날의 성격(마감·완료·휴무 등)을 칸 전체로 알릴 때 쓴다 — 일정 하나의 색은 `events[].color` 다. |
19
+ | `dayContent?` | `Record<string, ReactNode>` | — | 날짜별 칸 본문. 키는 `YYYY-MM-DD`, 준 날짜는 **일정 자리를 통째로 이 내용이 차지한다** — 그날의 `events` 는 그리지 않고 목록 판도 열리지 않는다. 일정으로 표현되지 않는 것(재고 현황· 매출 요약 같은 그날치 요약)을 칸에 그대로 얹을 때 쓴다. |
20
+ | `todayLabel?` | `string` | `'오늘'` | 헤더 오른쪽 "오늘" 버튼 레이블. 빈 문자열이면 버튼을 그리지 않는다 |
21
+ | `moreLabel?` | `string` | — | "N개" 뒤에 붙는 말 |
22
+ | `headerRight?` | `ReactNode` | — | 헤더 오른쪽 끝에 붙일 추가 컨트롤 |
23
+ | `className?` | `string` | — | |
24
+ | `style?` | `CSSProperties` | — | |
25
+
26
+ #### Events
27
+
28
+ | Event | Type | Description |
29
+ |-------|------|-------------|
30
+ | `onViewChange` | `(view: SCalendarBoardView) => void` | 보이는 연·월 변경 |
31
+ | `onValueChange` | `(date: string, events: SCalendarBoardEvent[]) => void` | 날짜 칸 선택 — 고른 날짜와 그 날짜의 일정이 함께 온다 (`selectable` 일 때만) |
32
+ | `onEventClick` | `(event: SCalendarBoardEvent, e: MouseEvent<HTMLButtonElement>) => void` | 일정 클릭 |
33
+ | `onMoreClick` | `(view: { date: string; events: SCalendarBoardEvent[] }) => void` | 그 날짜의 일정을 전부 열어 볼 때 — "N개 더보기" 를 눌렀을 때와 **일정이 있는 칸 자체를 눌렀을 때** 모두 온다. **주면 내장 일정 목록 판을 띄우지 않고 이 핸들러만 호출한다** — 그 날짜를 전용 화면·모달로 열고 싶을 때 쓴다. |
34
+
35
+ ## Types
36
+
37
+ ### SCalendarBoardView
38
+
39
+ ```ts
40
+ /** 보이는 연·월 */
41
+ export interface SCalendarBoardView {
42
+ year: number;
43
+ /** 1-12 */
44
+ month: number;
45
+ }
46
+ ```
47
+
48
+ ### SCalendarBoardEvent
49
+
50
+ ```ts
51
+ /** 달력 한 칸에 얹히는 일정 하나 */
52
+ export interface SCalendarBoardEvent {
53
+ /** 고유 식별자. 없으면 목록 순서로 key 를 만든다 */
54
+ id?: string;
55
+ /** 날짜 (YYYY-MM-DD) */
56
+ date: string;
57
+ /**
58
+ * 강조 레이블 (필수) — 예: `"[입고 예정]"`.
59
+ * 일정이 무엇인지 한눈에 알리는 부분이라 비워 두지 않는다.
60
+ * 인라인 HTML(`<b>` `<strong>` `<i>` `<em>` `<span class>` `<a href>` `<br>`)을 받으며 살균 후 렌더한다.
61
+ */
62
+ label: string;
63
+ /** 색상 프리셋 — 배경과 점 색이 함께 정해진다 */
64
+ color?: SCalendarBoardEventColor;
65
+ /** 왼쪽 점 색만 따로 지정 (프리셋 기본값을 덮어쓴다). 점은 `SBadge` 라 그 9색을 쓴다 */
66
+ dotColor?: SBadgeColor;
67
+ /** 본문 텍스트 — 예: `"RV20260728-000006"`. 평문만 받는다 */
68
+ description?: string;
69
+ /** 구분선(`/`) 뒤에 붙는 값 — 예: `"1,000"`. 평문만 받는다 */
70
+ value?: string;
71
+ /** 이 일정만 비활성 (클릭 불가) */
72
+ disabled?: boolean;
73
+ }
74
+ ```
75
+
76
+ ### SCalendarBoardDayColor
77
+
78
+ ```ts
79
+ export type SCalendarBoardDayColor = (typeof CALENDAR_BOARD_DAY_COLORS)[number];
80
+ ```
81
+
82
+ ### SCalendarBoardEventColor
83
+
84
+ ```ts
85
+ export type SCalendarBoardEventColor = (typeof CALENDAR_BOARD_EVENT_COLORS)[number];
86
+ ```
87
+
88
+ ### CALENDAR_BOARD_DAY_COLORS
89
+
90
+ ```ts
91
+ /** 날짜 칸 배경 — 그날의 성격을 칸 전체로 알린다 */
92
+ export const CALENDAR_BOARD_DAY_COLORS = [
93
+ 'default',
94
+ 'danger',
95
+ 'accent',
96
+ 'complete',
97
+ 'dim',
98
+ ] as const;
99
+ ```
100
+
101
+ ### CALENDAR_BOARD_EVENT_COLORS
102
+
103
+ ```ts
104
+ export const CALENDAR_BOARD_EVENT_COLORS = [
105
+ 'default',
106
+ 'blue',
107
+ 'oceanBlue',
108
+ 'lightBlue',
109
+ 'green',
110
+ 'yellow',
111
+ 'orange',
112
+ 'red',
113
+ 'white',
114
+ ] as const;
115
+ ```
116
+
117
+ ## Dependencies
118
+
119
+ ### Depends on
120
+
121
+ - [SBadge](../SBadge)
122
+ - [SButton](../SButton)
123
+ - [SDivider](../SDivider)
124
+ - [SGhostButton](../SGhostButton)
125
+ - [SScrollArea](../SScrollArea)
126
+
127
+ ### Graph
128
+
129
+ ```mermaid
130
+ graph TD;
131
+ SCalendarBoard --> SBadge
132
+ SCalendarBoard --> SButton
133
+ SCalendarBoard --> SDivider
134
+ SCalendarBoard --> SGhostButton
135
+ SCalendarBoard --> SScrollArea
136
+ style SCalendarBoard fill:#f9f,stroke:#333,stroke-width:4px
137
+ ```
@@ -0,0 +1,68 @@
1
+ import { type CSSProperties, type MouseEvent, type ReactNode } from 'react';
2
+ import { type SCalendarBoardDayColor } from './calendarBoard.config';
3
+ import type { SCalendarBoardEvent, SCalendarBoardView } from './types';
4
+ export interface SCalendarBoardProps {
5
+ /** 보이는 연도 (제어). `month` 와 함께 준다 */
6
+ year?: number;
7
+ /** 보이는 월 1-12 (제어). `year` 와 함께 준다 */
8
+ month?: number;
9
+ /** 처음 보여줄 연도 (비제어). 없으면 오늘 */
10
+ defaultYear?: number;
11
+ /** 처음 보여줄 월 1-12 (비제어). 없으면 오늘 */
12
+ defaultMonth?: number;
13
+ /** 보이는 연·월 변경 */
14
+ onViewChange?: (view: SCalendarBoardView) => void;
15
+ /**
16
+ * 날짜 칸을 눌러 고를 수 있게 한다. 기본은 읽기 전용 판이다 —
17
+ * 켜야 칸에 커서·포커스·키보드(Enter·Space)가 붙고 `onValueChange` 가 온다.
18
+ * 일정 버튼과 "N개 더보기" 는 이 값과 무관하게 항상 눌린다.
19
+ */
20
+ selectable?: boolean;
21
+ /** 선택 날짜 (YYYY-MM-DD). `selectable` 과 별개로 강조만 주고 싶을 때도 쓴다 */
22
+ value?: string | null;
23
+ /** 날짜 칸 선택 — 고른 날짜와 그 날짜의 일정이 함께 온다 (`selectable` 일 때만) */
24
+ onValueChange?: (date: string, events: SCalendarBoardEvent[]) => void;
25
+ /** 날짜별 일정 목록. `date` 로 칸에 배분된다 */
26
+ events?: SCalendarBoardEvent[];
27
+ /**
28
+ * 날짜별 칸 배경. 키는 `YYYY-MM-DD`, 없는 날짜는 `'default'` 다.
29
+ * 그날의 성격(마감·완료·휴무 등)을 칸 전체로 알릴 때 쓴다 — 일정 하나의 색은 `events[].color` 다.
30
+ */
31
+ dayColors?: Record<string, SCalendarBoardDayColor>;
32
+ /**
33
+ * 날짜별 칸 본문. 키는 `YYYY-MM-DD`, 준 날짜는 **일정 자리를 통째로 이 내용이 차지한다** —
34
+ * 그날의 `events` 는 그리지 않고 목록 판도 열리지 않는다. 일정으로 표현되지 않는 것(재고 현황·
35
+ * 매출 요약 같은 그날치 요약)을 칸에 그대로 얹을 때 쓴다.
36
+ */
37
+ dayContent?: Record<string, ReactNode>;
38
+ /** 일정 클릭 */
39
+ onEventClick?: (event: SCalendarBoardEvent, e: MouseEvent<HTMLButtonElement>) => void;
40
+ /**
41
+ * 그 날짜의 일정을 전부 열어 볼 때 — "N개 더보기" 를 눌렀을 때와 **일정이 있는 칸 자체를 눌렀을 때**
42
+ * 모두 온다. **주면 내장 일정 목록 판을 띄우지 않고 이 핸들러만 호출한다** —
43
+ * 그 날짜를 전용 화면·모달로 열고 싶을 때 쓴다.
44
+ */
45
+ onMoreClick?: (view: {
46
+ date: string;
47
+ events: SCalendarBoardEvent[];
48
+ }) => void;
49
+ /** 헤더 오른쪽 "오늘" 버튼 레이블. 빈 문자열이면 버튼을 그리지 않는다 */
50
+ todayLabel?: string;
51
+ /** "N개" 뒤에 붙는 말 */
52
+ moreLabel?: string;
53
+ /** 헤더 오른쪽 끝에 붙일 추가 컨트롤 */
54
+ headerRight?: ReactNode;
55
+ className?: string;
56
+ style?: CSSProperties;
57
+ }
58
+ /**
59
+ * SCalendarBoard — 한 달치 일정을 격자로 펼쳐 보여주는 달력 판.
60
+ *
61
+ * 날짜를 **고르는** 달력(`SCalendar` · `SDatePicker`)이 아니라 일정을 **읽는** 달력이다.
62
+ * 칸마다 일정이 줄로 쌓이고, 넘치면 "N개 더보기" 로 접혀 그 칸을 덮는 판으로 펼쳐진다.
63
+ *
64
+ * **판 높이는 부모가 정한다.** 행이 그 높이를 균등하게 나눠 갖고, 칸 높이가 다시 "한 칸에 몇 줄이
65
+ * 보일지" 를 정한다 — 그래서 놓는 자리에 높이를 주어야 한다 (`<div className="h-[640px]">` ·
66
+ * `SPage` 본문의 남은 높이 등). 높이를 주지 않으면 칸이 `dayCard.minHeight` 로 주저앉는다.
67
+ */
68
+ export declare function SCalendarBoard({ year, month, defaultYear, defaultMonth, onViewChange, selectable, value, onValueChange, events, dayColors, dayContent, onEventClick, onMoreClick, todayLabel, moreLabel, headerRight, className, style, }: SCalendarBoardProps): import("react").JSX.Element;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * SCalendarBoard 색상 프리셋 — component.calendarBoard 토큰 기반.
3
+ *
4
+ * 배경은 `--cmp-calendarBoard-eventButton-bg-*` 로 전부 토큰화돼 있다.
5
+ * 점(dot)은 `SBadge` 가 그리므로 색도 `--cmp-badge-*` 를 그대로 따른다 —
6
+ * 9색이 디자인 mock 의 점 hex 와 1:1 로 맞아떨어져 따로 매핑을 두지 않는다.
7
+ */
8
+ import type { SBadgeColor } from '../SBadge';
9
+ export declare const CALENDAR_BOARD_EVENT_COLORS: readonly ["default", "blue", "oceanBlue", "lightBlue", "green", "yellow", "orange", "red", "white"];
10
+ export type SCalendarBoardEventColor = (typeof CALENDAR_BOARD_EVENT_COLORS)[number];
11
+ export interface CalendarBoardEventPreset {
12
+ /** 이벤트 버튼 배경 */
13
+ bg: string;
14
+ /** 왼쪽 점(SBadge) 색 */
15
+ dot: SBadgeColor;
16
+ }
17
+ export declare const CALENDAR_BOARD_EVENT_PRESETS: Record<SCalendarBoardEventColor, CalendarBoardEventPreset>;
18
+ /**
19
+ * 칸에 몇 줄이 들어가는지 아직 **재지 못했을 때** 쓰는 기본값 (SSR·첫 렌더·ResizeObserver 부재).
20
+ *
21
+ * 실제로는 칸 높이가 줄 수를 정한다 — 판 높이를 부모가 정하고, 행이 그 높이를 균등 분할하고,
22
+ * 칸 높이에서 `header + n·item + (n−1)·gap + paddingBottom` 이 담기는 최대 n 이 그 값이다.
23
+ * 그래서 이 값을 조절하는 prop 은 없다.
24
+ */
25
+ export declare const CALENDAR_BOARD_MAX_VISIBLE_EVENTS = 4;
26
+ /** 날짜 칸 배경 — 그날의 성격을 칸 전체로 알린다 */
27
+ export declare const CALENDAR_BOARD_DAY_COLORS: readonly ["default", "danger", "accent", "complete", "dim"];
28
+ export type SCalendarBoardDayColor = (typeof CALENDAR_BOARD_DAY_COLORS)[number];
29
+ /**
30
+ * 칸 배경색. `default` 만 컴포넌트 토큰이고 나머지는 대응 토큰이 없어 팔레트 프리미티브를 가리킨다.
31
+ * (토큰이 생기면 여기만 `--cmp-calendarBoard-dayCard-bg-*` 로 갈아끼운다)
32
+ */
33
+ export declare const CALENDAR_BOARD_DAY_BG: Record<SCalendarBoardDayColor, string>;
@@ -0,0 +1,3 @@
1
+ export { SCalendarBoard, type SCalendarBoardProps } from './SCalendarBoard';
2
+ export type { SCalendarBoardEvent, SCalendarBoardView } from './types';
3
+ export { CALENDAR_BOARD_EVENT_COLORS, CALENDAR_BOARD_EVENT_PRESETS, CALENDAR_BOARD_MAX_VISIBLE_EVENTS, CALENDAR_BOARD_DAY_COLORS, CALENDAR_BOARD_DAY_BG, type SCalendarBoardEventColor, type SCalendarBoardDayColor, } from './calendarBoard.config';
@@ -0,0 +1,31 @@
1
+ import type { SBadgeColor } from '../SBadge';
2
+ import type { SCalendarBoardEventColor } from './calendarBoard.config';
3
+ /** 달력 한 칸에 얹히는 일정 하나 */
4
+ export interface SCalendarBoardEvent {
5
+ /** 고유 식별자. 없으면 목록 순서로 key 를 만든다 */
6
+ id?: string;
7
+ /** 날짜 (YYYY-MM-DD) */
8
+ date: string;
9
+ /**
10
+ * 강조 레이블 (필수) — 예: `"[입고 예정]"`.
11
+ * 일정이 무엇인지 한눈에 알리는 부분이라 비워 두지 않는다.
12
+ * 인라인 HTML(`<b>` `<strong>` `<i>` `<em>` `<span class>` `<a href>` `<br>`)을 받으며 살균 후 렌더한다.
13
+ */
14
+ label: string;
15
+ /** 색상 프리셋 — 배경과 점 색이 함께 정해진다 */
16
+ color?: SCalendarBoardEventColor;
17
+ /** 왼쪽 점 색만 따로 지정 (프리셋 기본값을 덮어쓴다). 점은 `SBadge` 라 그 9색을 쓴다 */
18
+ dotColor?: SBadgeColor;
19
+ /** 본문 텍스트 — 예: `"RV20260728-000006"`. 평문만 받는다 */
20
+ description?: string;
21
+ /** 구분선(`/`) 뒤에 붙는 값 — 예: `"1,000"`. 평문만 받는다 */
22
+ value?: string;
23
+ /** 이 일정만 비활성 (클릭 불가) */
24
+ disabled?: boolean;
25
+ }
26
+ /** 보이는 연·월 */
27
+ export interface SCalendarBoardView {
28
+ year: number;
29
+ /** 1-12 */
30
+ month: number;
31
+ }
@@ -16,6 +16,7 @@
16
16
  ### Used by
17
17
 
18
18
  - [SCalendar](../SCalendar)
19
+ - [SCalendarBoard](../SCalendarBoard)
19
20
  - [SDateRangePicker](../SDateRangePicker)
20
21
  - [SList](../SList)
21
22
  - [STable](../STable)
@@ -26,6 +27,7 @@
26
27
  ```mermaid
27
28
  graph TD;
28
29
  SCalendar --> SDivider
30
+ SCalendarBoard --> SDivider
29
31
  SDateRangePicker --> SDivider
30
32
  SList --> SDivider
31
33
  STable --> SDivider
@@ -47,6 +47,7 @@ export type SGhostButtonIntent = 'default' | 'danger' | 'action' | 'subAction' |
47
47
 
48
48
  - [SBarcodeInput](../SBarcodeInput)
49
49
  - [SCalendar](../SCalendar)
50
+ - [SCalendarBoard](../SCalendarBoard)
50
51
  - [SChip](../SChip)
51
52
  - [SDatePicker](../SDatePicker)
52
53
  - [SDateRangePicker](../SDateRangePicker)
@@ -79,6 +80,7 @@ graph TD;
79
80
  SGhostButton --> STag
80
81
  SBarcodeInput --> SGhostButton
81
82
  SCalendar --> SGhostButton
83
+ SCalendarBoard --> SGhostButton
82
84
  SChip --> SGhostButton
83
85
  SDatePicker --> SGhostButton
84
86
  SDateRangePicker --> SGhostButton
@@ -32,6 +32,12 @@ export interface SGnbSystemContextValue {
32
32
  * 것을 스스로 닫아야 하고, 그 신호가 이 값이다.
33
33
  */
34
34
  active: boolean;
35
+ /**
36
+ * 이 자리가 메뉴 기본 폭(GNB_MENU_WIDTH)보다 좁은가 — `resizable` 로 줄인 메뉴 컬럼이 그렇다.
37
+ * 좁아진 판에서는 알림 개수를 적을 가로가 모자라 개수 대신 점 배지가 붙는다.
38
+ * 없으면 좁지 않은 것으로 본다(접힘 레일·상단바는 자기 규칙을 따르므로 이 값과 무관하다).
39
+ */
40
+ narrow?: boolean;
35
41
  }
36
42
  export declare const SGnbSystemContext: import("react").Context<SGnbSystemContextValue | null>;
37
43
  export interface SGnbProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color'> {
@@ -116,13 +116,13 @@ export declare const GNB_EXPAND_MS = 200;
116
116
  * 메뉴 고정 폭. 두 header 모두 메뉴는 이 폭으로 좌측에 붙는다(토큰 없음 → 상수).
117
117
  * header="full" 에서 SLayout 이 "메뉴 오른쪽 = 페이지" 영역을 잡을 때도 이 값을 쓴다.
118
118
  */
119
- export declare const GNB_MENU_WIDTH = 240;
119
+ export declare const GNB_MENU_WIDTH = 214;
120
120
  /**
121
121
  * resizable 일 때 메뉴 폭이 움직일 수 있는 범위(px). 레일 폭은 고정이고 메뉴 컬럼만 늘고 준다.
122
- * 디자인이 아직 확정한 값이 아니라 임시다 확정되면 토큰으로 내려온다.
122
+ * 기본 폭(GNB_MENU_WIDTH)이 범위 안에 있다. 대응 토큰이 없어 상수로 둔다.
123
123
  */
124
124
  export declare const GNB_MENU_MIN_WIDTH = 200;
125
- export declare const GNB_MENU_MAX_WIDTH = 300;
125
+ export declare const GNB_MENU_MAX_WIDTH = 240;
126
126
  /** 메뉴 폭 조절에서 방향키 한 번에 움직이는 양(px). Shift 를 함께 누르면 large. */
127
127
  export declare const GNB_MENU_RESIZE_KEY_STEP: {
128
128
  normal: number;
@@ -52,12 +52,50 @@ export interface SGnbSystemAlert {
52
52
  /** 라벨 텍스트. 기본 `'알림'` */
53
53
  label?: string;
54
54
  /**
55
- * 읽지 않은 알림 개수. 1 이상이면 벨이 울리는 아이콘·강조색으로 바뀌고 개수(접히면 점)가 붙는다.
55
+ * 읽지 않은 알림 개수. 1 이상이면 벨이 울리는 아이콘·강조색으로 바뀌고 개수가 붙는다.
56
+ * 개수를 적을 가로가 모자란 자리(접힌 레일 · 기본 폭보다 좁게 줄인 판)에서는 점 배지로 바뀐다.
56
57
  * 표기는 컴포넌트가 맡는다 — 세 자리마다 콤마를 넣어 그리므로 앱이 포맷한 문자열을 넘기지 않는다.
57
58
  */
58
59
  count?: number;
59
60
  /** 클릭 */
60
61
  onClick?: () => void;
62
+ /**
63
+ * 알림 버튼에 붙는 안내 툴팁의 문구(한 줄이 한 항목). 주면 뜬다 — **문구만 앱이 정하고**
64
+ * 색·방향·여닫힘은 컴포넌트가 쥔다: 색은 판이 light 면 기본, 그 밖(dark·상단바)이면 강조색이고
65
+ * 방향은 자리가 정한다(판·접힌 레일이면 오른쪽, 상단바면 아래).
66
+ *
67
+ * 스스로 사라지지 않는다 — **알림 버튼을 누르거나, 버튼에 얹었다 커서를 뺄 때** 닫히고,
68
+ * 같은 값을 계속 넘기는 동안에는 다시 뜨지 않는다.
69
+ *
70
+ * **다시 띄우려면 비웠다가 다시 넘긴다**(`undefined` → 문구). 문구가 같아도 상관없다 —
71
+ * 컴포넌트는 닫았다는 사실만 기억하고 문구 내용은 기억하지 않으므로, 새 알림마다 같은 안내를
72
+ * 다시 띄우는 화면도 막히지 않는다.
73
+ */
74
+ tooltip?: string[];
75
+ /**
76
+ * 알림을 누르면 뜨는 목록의 **내용**. 주면 컴포넌트가 알림 버튼에 붙여 띄운다 —
77
+ * 목록에 무엇을 쌓을지는 서비스마다 다르지만 **뜨는 자리는 늘 같아야 하므로**, 방향·앵커·
78
+ * 여닫힘(바깥 클릭·ESC 포함)과 배경·라운드·그림자는 컴포넌트가 쥐고 앱은 안에 담을 것만 준다.
79
+ * 방향은 자리가 정한다 — 판·접힌 레일이면 버튼 오른쪽, 상단바면 아래.
80
+ */
81
+ listBox?: ReactNode;
82
+ /**
83
+ * 알림 목록이 열리고 닫힐 때. 여닫는 것은 알림 버튼이 스스로 하므로 **그 사실을 알아야 할
84
+ * 때만** 준다(연 김에 읽음 처리하거나, 열려 있는 동안 다른 층을 접어 두는 화면).
85
+ *
86
+ * 앱이 누르지 않은 닫힘도 온다: GNB 를 접거나 펴면 알림 버튼이 다른 자리로 옮겨 서므로
87
+ * 목록이 닫히고 `false` 가 온다(계정 행과 같다).
88
+ */
89
+ onOpenChange?: (open: boolean) => void;
90
+ /**
91
+ * 안내 툴팁이 닫힐 때. 받아서 `tooltip` 을 비워 두는 것이 기본 사용법이다 — 그러면 앱이
92
+ * 다음에 넘기는 문구가 곧 다음 안내가 된다.
93
+ *
94
+ * 컴포넌트가 아는 "다시 뜨지 않는다" 는 **이 자리가 서 있는 동안**뿐이라(새로고침하거나
95
+ * GNB 를 접어 알림이 다른 자리로 옮겨 서면 새로 마운트된다), 그 사용자에게 두 번 다시 보이지
96
+ * 않아야 하면 앱이 이 신호를 저장해 두고 `tooltip` 을 그만 넘긴다.
97
+ */
98
+ onTooltipDismiss?: () => void;
61
99
  }
62
100
  ```
63
101
 
@@ -130,7 +168,9 @@ export const GNB_SYSTEM_COLORS = ['light', 'dark'] as const;
130
168
  - [SAccountListBox](../SAccountListBox)
131
169
  - [SGnb](../SGnb)
132
170
  - [SIcon](../SIcon)
171
+ - [SPortal](../SPortal)
133
172
  - [SSystemActionButton](../SSystemActionButton)
173
+ - [STooltip](../STooltip)
134
174
 
135
175
  ### Graph
136
176
 
@@ -139,6 +179,8 @@ graph TD;
139
179
  SGnbSystem --> SAccountListBox
140
180
  SGnbSystem --> SGnb
141
181
  SGnbSystem --> SIcon
182
+ SGnbSystem --> SPortal
142
183
  SGnbSystem --> SSystemActionButton
184
+ SGnbSystem --> STooltip
143
185
  style SGnbSystem fill:#f9f,stroke:#333,stroke-width:4px
144
186
  ```