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

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 (30) hide show
  1. package/AGENTS.md +111 -21
  2. package/dist/components/SAccountListBox/AccountListBoxPortal.d.ts +31 -0
  3. package/dist/components/SAccountListBox/README.md +86 -0
  4. package/dist/components/SAccountListBox/SAccountListBox.d.ts +79 -0
  5. package/dist/components/SAccountListBox/SystemMenuPortal.d.ts +58 -0
  6. package/dist/components/SAccountListBox/accountListBox.config.d.ts +64 -0
  7. package/dist/components/SAccountListBox/index.d.ts +2 -0
  8. package/dist/components/SChipFilter/README.md +16 -3
  9. package/dist/components/SChipFilter/SChipFilter.d.ts +22 -4
  10. package/dist/components/SGnb/README.md +1 -1
  11. package/dist/components/SGnb/SGnb.d.ts +29 -7
  12. package/dist/components/SGnbSystem/README.md +29 -6
  13. package/dist/components/SGnbSystem/SGnbSystem.d.ts +57 -17
  14. package/dist/components/SGnbSystem/gnbSystem.config.d.ts +34 -1
  15. package/dist/components/SGnbSystem/index.d.ts +1 -1
  16. package/dist/components/SIcon/README.md +2 -0
  17. package/dist/components/SIcon/icons.gen.d.ts +2 -0
  18. package/dist/components/SPortal/README.md +2 -0
  19. package/dist/components/SSystemActionButton/README.md +96 -9
  20. package/dist/components/SSystemActionButton/SSystemActionButton.d.ts +97 -15
  21. package/dist/components/SSystemActionButton/index.d.ts +1 -1
  22. package/dist/index.cjs +1131 -398
  23. package/dist/index.cjs.map +1 -1
  24. package/dist/index.d.ts +1 -0
  25. package/dist/index.js +1125 -400
  26. package/dist/index.js.map +1 -1
  27. package/dist/llms-full.txt +333 -40
  28. package/dist/llms.txt +113 -23
  29. package/dist/styles.css +66 -26
  30. package/package.json +1 -1
@@ -64,7 +64,9 @@ export interface SChipFilterFieldBase {
64
64
  * 조용히 되살아난다. 처음부터 값이 정해져 있어야 하는 필터라면 그것이 `fixed`·`required` 다.
65
65
  *
66
66
  * required인데 지정하지 않으면 타입별 내장 기본값(select: 첫 번째 옵션,
67
- * datepicker-day·datepicker-range: 오늘 날짜)을 대신 쓴다. 인라인(radioButton) datepicker-range
67
+ * datepicker-day·datepicker-range: 오늘 날짜)을 대신 쓴다. `fixed`·`required` 인
68
+ * select·select-multi 는 후보가 하나뿐일 때 그 값이 기본값이 된다(options 참고) —
69
+ * defaultValue 를 함께 주면 그쪽이 이긴다. 인라인(radioButton) datepicker-range
68
70
  * 필드는 팝오버 없이 바에 바로 노출되어 빈 상태로 둘 수 없으므로, 이 규칙과 무관하게 언제나
69
71
  * 오늘이 채워진다 */
70
72
  defaultValue?: SChipFilterValue;
@@ -74,7 +76,18 @@ export interface SChipFilterFieldBase {
74
76
  }
75
77
  /** 후보 목록에서 고르는 필터 — select·select-multi·keyword */
76
78
  export interface SChipFilterOptionsField extends SChipFilterFieldBase {
77
- /** 고를 수 있는 후보 목록 */
79
+ /** 고를 수 있는 후보 목록.
80
+ *
81
+ * **`fixed`·`required` 인 select·select-multi 에서 고를 수 있는 후보가 하나뿐이면 그 값이
82
+ * 자동으로 선택된다** — 사용자가 고르지 않아도 `onValueChange` 로 값이 올라온다
83
+ * (select 는 그 값, select-multi 는 그 값 하나짜리 배열). 옵션이 API 응답이라 늦게 도착해도
84
+ * 도착한 시점에 채워진다. 사용자가 그 값을 지우면 다시 채우지 않는다 —
85
+ * 다만 "검색 초기화"는 되돌려 놓는다(다른 기본값과 같은 규칙).
86
+ * 후보가 하나인데 비활성(`disabled`)이면 고를 수 없는 값이므로 채우지 않는다.
87
+ *
88
+ * 뺄 수 있는 필터(= `fixed`·`required` 가 아닌 필드)는 후보가 하나여도 채우지 않는다 —
89
+ * 처음에 바에 없는 필터라 보이지도 지울 수도 없는 조건이 검색에 걸리기 때문이다.
90
+ * 후보가 하나뿐인 필터를 반드시 걸어야 한다면 `fixed` 나 `required` 로 준다 */
78
91
  options?: SChipFilterOption[];
79
92
  }
80
93
  /** 프리셋으로 기간을 고르는 필터 — datepicker-range·datepicker-statistics */
@@ -210,9 +223,14 @@ export interface SChipFilterProps {
210
223
  /** 실제 검색을 실행할 시점 — 편집 팝오버의 "검색" 버튼을 누르거나 팝오버가 닫힐 때(바깥 클릭·Esc·다른
211
224
  * 칩으로 전환 포함) 그 시점의 전체 값 맵과 함께 호출된다. 팝오버가 없는 필드(인라인 date 프리셋·custom,
212
225
  * clearable ×, 검색 초기화)는 값이 바뀌는 즉시 호출된다. keyword 필터에서 Enter 로 키워드를 추가할 때도
213
- * 그 즉시 호출된다 — 팝오버는 열린 채라 키워드를 이어서 더 넣을 수 있고, 넣을 때마다 조회가 갱신된다. dirty 체크가 기본 적용되어 있어 — 마지막으로
226
+ * 그 즉시 호출된다 — 팝오버는 열린 채라 키워드를 이어서 더 넣을 수 있고, 넣을 때마다 조회가 갱신된다.
227
+ * keyword 입력창에 Enter 없이 텍스트를 남긴 채 팝오버를 닫으면 그 텍스트도 키워드로 확정한 뒤
228
+ * 호출된다(input: 'csv'면 콤마로 쪼개는 규칙도 그대로 적용) — 사용자가 검색어를 넣고 "검색"을 누른
229
+ * 조작이 입력 확정 여부 때문에 사라지지 않게 한다. dirty 체크가 기본 적용되어 있어 — 마지막으로
214
230
  * 실제 검색이 실행된 값 맵과 비교해 하나라도 달라진 게 없으면(예: 팝오버를 열었다 아무것도 안 바꾸고
215
- * 닫는 경우) 호출되지 않는다. fields를 그룹으로 넘겼다면 rule을 만족하지 못한 그룹이 있는 동안엔
231
+ * 닫는 경우) 호출되지 않는다. 단 마운트 후 첫 호출은 비교할 기준이 없어 값이 처음 그대로여도 나간다 —
232
+ * 마운트 시 자동 조회하지 않는 화면(다이얼로그 등)에서 사용자의 첫 "검색"이 막히지 않게 하기 위함이다.
233
+ * fields를 그룹으로 넘겼다면 rule을 만족하지 못한 그룹이 있는 동안엔
216
234
  * onSearch가 호출되지 않는다 — 해당 그룹의 경고 툴팁은 이 시점과 무관하게 값이 비어 있는 동안 항상
217
235
  * 실시간으로 떠 있다(별도로 validate()를 호출할 필요 없음). required 필드가 비어 있는 동안에도
218
236
  * 마찬가지로 호출되지 않는다 — 정상 설정(내장 기본값 또는 defaultValue)이라면 원래 비워지지
@@ -26,7 +26,7 @@
26
26
  | `resizable?` | `boolean` | `false` | 메뉴 폭을 드래그로 조절할 수 있게 한다. 레일 폭은 고정이고 **메뉴 컬럼만** 늘고 준다. 조절선은 GNB 컬럼의 오른쪽 경계 전체다 — fix 는 상단바 높이까지, full 은 상단바가 전폭이라 본문 높이까지. 접혀 있거나 깔 메뉴가 없으면(레일 리프가 활성) 조절선이 나오지 않는다. |
27
27
  | `menuWidth?` | `number` | — | 메뉴 폭(px). 주면 controlled — onMenuWidthChange 로 직접 갱신해야 움직인다 |
28
28
  | `defaultMenuWidth?` | `number` | — | 메뉴 초기 폭(px). uncontrolled |
29
- | `system?` | `ReactNode` | — | GNB 맨 아래에 붙는 system 패널(`SGnbSystem`) 슬롯. 펼치면 메뉴 컬럼 바닥에, 접히면(header="fix" 레일) `foldedFooter` 아래 레일 바닥에 여백 없이 붙는다. 색·형태(펼침/접힘)는 GNB 가 내려주므로 SGnbSystem 에 다시 넘기지 않아도 된다. useRail 에서 메뉴가 없는 레일 아이템이 활성이면 메뉴 컬럼째 사라지므로 이 슬롯도 함께 빠진다. |
29
+ | `system?` | `ReactNode` | — | system 슬롯(`SGnbSystem`). 놓이는 자리와 형태는 `header` 가 정한다. - fix : GNB 맨 아래 세로 판. 펼치면 메뉴 컬럼 바닥에, 접히면 `foldedFooter` 아래 레일 바닥에 여백 없이 붙는다. useRail 에서 메뉴가 없는 레일 아이템이 활성이면 메뉴 컬럼째 사라지므로 이 슬롯도 함께 빠진다. - full: 전폭 상단바 오른쪽 끝에 가로 한 줄로 선다. 상단바는 접어도 남으므로 조각들도 늘 남는다. 색·형태는 GNB 가 내려주므로 SGnbSystem 에 다시 넘기지 않아도 된다. |
30
30
  | `ariaLabel?` | `string` | `'global navigation'` | 메뉴 landmark(nav) 의 접근성 레이블. 한 화면에 nav 가 여럿일 때 구분한다. |
31
31
 
32
32
  #### Events
@@ -1,18 +1,37 @@
1
1
  import { type HTMLAttributes, type ReactNode } from 'react';
2
+ import type { SGnbSystemPlacement } from '../SGnbSystem/gnbSystem.config';
2
3
  import { type SGnbType, type SGnbHeader, type SGnbColor, type SGnbMenuItem } from './gnb.config';
3
4
  /**
4
5
  * SGnb 가 `system` 슬롯에 내려주는 값. 슬롯에 놓인 SGnbSystem 이 이걸 읽어
5
- * 색과 형태(펼침/접힘)를 GNB 에 맞춘다 — 앱이 같은 값을 두 번 넘기지 않게 한다.
6
+ * 색과 형태(가로/세로 · 펼침/접힘)를 GNB 에 맞춘다 — 앱이 같은 값을 두 번 넘기지 않게 한다.
6
7
  *
7
- * `folded` 는 GNB 의 접힘 상태가 아니라 **그 자리가 접힌 레일인지**다. 슬롯은 두 곳에 놓이고
8
+ * 슬롯이 어디에 놓이는지는 header 가 정한다.
9
+ * - fix : 메뉴 컬럼 바닥 · 접힘 레일 바닥 → `placement: 'panel'` (세로 판)
10
+ * - full: 전폭 상단바 오른쪽 끝 → `placement: 'top'` (판 없이 가로 한 줄)
11
+ *
12
+ * `folded` 는 GNB 의 접힘 상태가 아니라 **그 자리가 접힌 레일인지**다. panel 은 두 곳에 놓이고
8
13
  * (메뉴 컬럼 바닥 · 접힘 레일 바닥) 각 자리가 자기 형태를 못 박으므로, 접는 동안 아직 미끄러져
9
14
  * 나가는 중인 메뉴 컬럼의 패널이 min 형태로 튀지 않는다.
15
+ *
16
+ * 그래서 fix 로 접혀 있는 동안 슬롯 내용은 **두 자리에 함께 마운트된다** — 미끄러져 나간 메뉴
17
+ * 컬럼(잔상)과 레일 바닥(실물). `active` 가 그 둘을 가른다.
10
18
  */
11
19
  export interface SGnbSystemContextValue {
12
20
  /** GNB 색 */
13
21
  color: SGnbColor;
14
- /** 이 자리가 접힌(48px) 레일인지 */
22
+ /** 이 자리가 접힌(48px) 레일인지. `placement: 'top'` 에서는 뜻이 없다 */
15
23
  folded: boolean;
24
+ /** 이 자리가 세로 판인지 전폭 상단바인지 */
25
+ placement: SGnbSystemPlacement;
26
+ /**
27
+ * 이 자리가 지금 화면에 살아 있는 자리인가. 접힌 GNB 의 메뉴 컬럼처럼 밖으로 미끄러져 나가
28
+ * 잔상으로만 남는 자리는 `false` 다.
29
+ *
30
+ * 잔상에서도 계정 리스트박스 같은 **떠 있는 층은 함께 숨지 않는다** — SPortal 로 문서 최상단에
31
+ * 그려져 컬럼의 `visibility: hidden` 이 닿지 않기 때문이다. 그래서 잔상이 된 자리는 열어 둔
32
+ * 것을 스스로 닫아야 하고, 그 신호가 이 값이다.
33
+ */
34
+ active: boolean;
16
35
  }
17
36
  export declare const SGnbSystemContext: import("react").Context<SGnbSystemContextValue | null>;
18
37
  export interface SGnbProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color'> {
@@ -96,10 +115,12 @@ export interface SGnbProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color'>
96
115
  /** 메뉴 폭이 확정될 때(드래그를 놓거나 방향키 조작). 드래그하는 동안에는 오지 않는다 */
97
116
  onMenuWidthChange?: (width: number) => void;
98
117
  /**
99
- * GNB 맨 아래에 붙는 system 패널(`SGnbSystem`) 슬롯. 펼치면 메뉴 컬럼 바닥에,
100
- * 접히면(header="fix" 레일) `foldedFooter` 아래 레일 바닥에 여백 없이 붙는다.
101
- * 색·형태(펼침/접힘)는 GNB 가 내려주므로 SGnbSystem 에 다시 넘기지 않아도 된다.
102
- * useRail 에서 메뉴가 없는 레일 아이템이 활성이면 메뉴 컬럼째 사라지므로 이 슬롯도 함께 빠진다.
118
+ * system 슬롯(`SGnbSystem`). 놓이는 자리와 형태는 `header` 가 정한다.
119
+ * - fix : GNB 맨 아래 세로 판. 펼치면 메뉴 컬럼 바닥에, 접히면 `foldedFooter` 아래 레일 바닥에
120
+ * 여백 없이 붙는다. useRail 에서 메뉴가 없는 레일 아이템이 활성이면 메뉴 컬럼째 사라지므로
121
+ * 이 슬롯도 함께 빠진다.
122
+ * - full: 전폭 상단바 오른쪽 끝에 가로 한 줄로 선다. 상단바는 접어도 남으므로 조각들도 늘 남는다.
123
+ * 색·형태는 GNB 가 내려주므로 SGnbSystem 에 다시 넘기지 않아도 된다.
103
124
  */
104
125
  system?: ReactNode;
105
126
  /** 메뉴 landmark(nav) 의 접근성 레이블. 한 화면에 nav 가 여럿일 때 구분한다. */
@@ -113,6 +134,7 @@ export interface SGnbProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color'>
113
134
  * header 가 배치와 접힘 형태를 정한다:
114
135
  * - fix: 상단바가 GNB 컬럼(메뉴 폭) 안에 있다. 접으면 48px 세로 레일로 좁혀지고 상단바에는 폴드 버튼만 남는다.
115
136
  * - full: 상단바가 레이아웃 전폭을 가로지르고 그 아래 [메뉴 | 페이지]. 접으면 메뉴만 사라진다.
137
+ * system 조각들도 메뉴 바닥이 아니라 이 상단바 오른쪽 끝으로 올라온다.
116
138
  *
117
139
  * useRail 이면 items 의 첫 depth 가 좌측 레일(아이콘+라벨 68px)로 서고, 선택된 레일 아이템의
118
140
  * children 이 메뉴 패널의 depth1 이 된다 — 트리는 그대로 두고 어디부터 그릴지만 바뀐다.
@@ -9,11 +9,11 @@
9
9
  | Prop | Type | Default | Description |
10
10
  |------|------|---------|-------------|
11
11
  | `color?` | `SGnbSystemColor` | — | 색상(패널 표면). light = 흰 면, dark = 오션블루 면. 미지정 시 자기를 담은 SGnb 의 color 를 따른다(단독으로 쓰면 `'light'`). |
12
- | `folded?` | `boolean` | — | 접힌(min) 형태 — 48px 레일 폭에 맞춰 알림·계정 아이콘만 남는다. 미지정 시 자기를 담은 SGnb 의 접힘 상태를 따른다. |
13
- | `actions?` | `SGnbSystemAction[]` | — | 패널 상단에 쌓는 행 목록. 각 원소는 `SSystemActionButton` 의 props 다(`color` 제외). 아래에 다른 조각이 있으면 그 사이에 구분선이 그어진다. 접히면 자리가 없어 렌더되지 않는다. |
12
+ | `folded?` | `boolean` | — | 접힌(min) 형태 — 48px 레일 폭에 맞춰 알림·계정 아이콘만 남는다. 미지정 시 자기를 담은 SGnb 의 접힘 상태를 따른다. 상단바 자리에서는 뜻이 없다. |
13
+ | `actions?` | `SGnbSystemAction[]` | — | 행 목록. 각 원소는 `SSystemActionButton` 의 props 다(`color` 제외 · 계정 행은 `account` 로 따로 준다). 판에서는 맨 위에 쌓이고, 상단바에서는 맨 왼쪽에 선다. 옆(아래)에 다른 조각이 있으면 그 사이에 구분선이 그어진다. 접히면 자리가 없어 렌더되지 않는다. |
14
14
  | `domain?` | `string` | — | 도메인 태그 텍스트. 접히면 자리가 없어 렌더되지 않는다 |
15
- | `alert?` | `SGnbSystemAlert` | — | 알림 버튼. 없으면 렌더하지 않는다. 설정과 나란히 서면 남는 폭을 먹고, 혼자면 폭을 다 먹는다 |
16
- | `setting?` | `SGnbSystemSetting` | — | 설정 버튼. 없으면 렌더하지 않는다. 알림과 나란히 서면 제 폭만 갖고, 혼자면 폭을 다 먹는다. 접히면 자리가 없어 렌더되지 않는다 — 접힌 상태에서도 닿아야 하면 SGnb 의 `foldedFooter` 에 둔다. |
15
+ | `alert?` | `SGnbSystemAlert` | — | 알림 버튼. 없으면 렌더하지 않는다. 판에서는 설정과 나란히 서면 남는 폭을 먹고 혼자면 폭을 다 먹는다. 상단바에서는 자리가 넉넉하지 않아 라벨 없이 아이콘+개수만 선다. |
16
+ | `setting?` | `SGnbSystemSetting` | — | 설정 버튼. 없으면 렌더하지 않는다. 판에서는 알림과 나란히 서면 제 폭만 갖고 혼자면 폭을 다 먹고, 상단바에서는 라벨 없이 아이콘만 선다. 접히면 자리가 없어 렌더되지 않는다 — 접힌 상태에서도 닿아야 하면 SGnb 의 `foldedFooter` 에 둔다. |
17
17
  | `account?` | `SGnbSystemAccount` | — | 계정 행. 없으면 렌더하지 않는다 |
18
18
 
19
19
  ## Types
@@ -30,8 +30,15 @@ export type SGnbSystemColor = (typeof GNB_SYSTEM_COLORS)[number];
30
30
  /**
31
31
  * 패널 상단에 쌓이는 행 하나. `SSystemActionButton` 의 props 를 그대로 받는다 —
32
32
  * 단 `color` 는 패널이 정하므로 받지 않고, 목록 key 로 쓸 `value` 만 더한다.
33
+ *
34
+ * `type: 'account'` 는 받지 않는다. 계정 행은 이 패널에 **하나뿐**이고 서는 자리도 맨 아래로
35
+ * 정해져 있어(§3-5-8) `account` prop 이 따로 있다 — 여기로도 받으면 계정 행이 둘인 패널이
36
+ * 만들어지고, 그중 하나는 자리가 틀린다.
33
37
  */
34
- export type SGnbSystemAction = DistributiveOmit<SSystemActionButtonProps, 'color'> & {
38
+ export type SGnbSystemAction = DistributiveOmit<
39
+ Exclude<SSystemActionButtonProps, { type: 'account' }>,
40
+ 'color'
41
+ > & {
35
42
  /** 목록 key. 없으면 순서를 key 로 쓴다 */
36
43
  value?: string;
37
44
  };
@@ -73,8 +80,22 @@ export interface SGnbSystemSetting {
73
80
  export interface SGnbSystemAccount {
74
81
  /** 계정 이름 */
75
82
  label?: string;
76
- /** 클릭 */
83
+ /** 클릭. 패널은 어차피 열리므로, 여는 것 말고 따로 할 일이 있을 때만 준다 */
77
84
  onClick?: () => void;
85
+ /**
86
+ * 계정 리스트박스가 열리고 닫힐 때. 여닫는 것은 계정 행이 스스로 하므로 **그 사실을 알아야 할
87
+ * 때만** 준다 — 열려 있는 동안 다른 층을 접어 두거나, 연 것을 기록하는 화면이 그렇다.
88
+ *
89
+ * 앱이 누르지 않은 닫힘도 온다: `header="fix"` 에서 GNB 를 접거나 펴면 계정 행이 다른 자리로
90
+ * 옮겨 서므로 패널이 닫히고 `false` 가 온다.
91
+ */
92
+ onOpenChange?: (open: boolean) => void;
93
+ /**
94
+ * 누르면 뜨는 계정 리스트박스(`SAccountListBox`) 내용. **필수다** — 계정 행은 늘 이 패널의
95
+ * 트리거이고, 눌러도 아무것도 뜨지 않는 계정 행은 없다.
96
+ * 뜨는 방향은 패널이 놓인 자리가 정하므로 앱이 넘기지 않는다.
97
+ */
98
+ listBox: SAccountListBoxContent;
78
99
  }
79
100
  ```
80
101
 
@@ -106,6 +127,7 @@ export const GNB_SYSTEM_COLORS = ['light', 'dark'] as const;
106
127
 
107
128
  ### Depends on
108
129
 
130
+ - [SAccountListBox](../SAccountListBox)
109
131
  - [SGnb](../SGnb)
110
132
  - [SIcon](../SIcon)
111
133
  - [SSystemActionButton](../SSystemActionButton)
@@ -114,6 +136,7 @@ export const GNB_SYSTEM_COLORS = ['light', 'dark'] as const;
114
136
 
115
137
  ```mermaid
116
138
  graph TD;
139
+ SGnbSystem --> SAccountListBox
117
140
  SGnbSystem --> SGnb
118
141
  SGnbSystem --> SIcon
119
142
  SGnbSystem --> SSystemActionButton
@@ -1,4 +1,5 @@
1
1
  import { type HTMLAttributes } from 'react';
2
+ import { type SAccountListBoxContent } from '../SAccountListBox';
2
3
  import { type SSystemActionButtonProps } from '../SSystemActionButton';
3
4
  import { type SGnbSystemColor } from './gnbSystem.config';
4
5
  /** 유니온을 유지한 채 키를 걷어낸다 — 그냥 Omit 하면 판별 유니온이 한 덩어리로 뭉개진다. */
@@ -6,8 +7,14 @@ type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K>
6
7
  /**
7
8
  * 패널 상단에 쌓이는 행 하나. `SSystemActionButton` 의 props 를 그대로 받는다 —
8
9
  * 단 `color` 는 패널이 정하므로 받지 않고, 목록 key 로 쓸 `value` 만 더한다.
10
+ *
11
+ * `type: 'account'` 는 받지 않는다. 계정 행은 이 패널에 **하나뿐**이고 서는 자리도 맨 아래로
12
+ * 정해져 있어(§3-5-8) `account` prop 이 따로 있다 — 여기로도 받으면 계정 행이 둘인 패널이
13
+ * 만들어지고, 그중 하나는 자리가 틀린다.
9
14
  */
10
- export type SGnbSystemAction = DistributiveOmit<SSystemActionButtonProps, 'color'> & {
15
+ export type SGnbSystemAction = DistributiveOmit<Exclude<SSystemActionButtonProps, {
16
+ type: 'account';
17
+ }>, 'color'> & {
11
18
  /** 목록 key. 없으면 순서를 key 로 쓴다 */
12
19
  value?: string;
13
20
  };
@@ -34,8 +41,22 @@ export interface SGnbSystemSetting {
34
41
  export interface SGnbSystemAccount {
35
42
  /** 계정 이름 */
36
43
  label?: string;
37
- /** 클릭 */
44
+ /** 클릭. 패널은 어차피 열리므로, 여는 것 말고 따로 할 일이 있을 때만 준다 */
38
45
  onClick?: () => void;
46
+ /**
47
+ * 계정 리스트박스가 열리고 닫힐 때. 여닫는 것은 계정 행이 스스로 하므로 **그 사실을 알아야 할
48
+ * 때만** 준다 — 열려 있는 동안 다른 층을 접어 두거나, 연 것을 기록하는 화면이 그렇다.
49
+ *
50
+ * 앱이 누르지 않은 닫힘도 온다: `header="fix"` 에서 GNB 를 접거나 펴면 계정 행이 다른 자리로
51
+ * 옮겨 서므로 패널이 닫히고 `false` 가 온다.
52
+ */
53
+ onOpenChange?: (open: boolean) => void;
54
+ /**
55
+ * 누르면 뜨는 계정 리스트박스(`SAccountListBox`) 내용. **필수다** — 계정 행은 늘 이 패널의
56
+ * 트리거이고, 눌러도 아무것도 뜨지 않는 계정 행은 없다.
57
+ * 뜨는 방향은 패널이 놓인 자리가 정하므로 앱이 넘기지 않는다.
58
+ */
59
+ listBox: SAccountListBoxContent;
39
60
  }
40
61
  export interface SGnbSystemProps extends Omit<HTMLAttributes<HTMLDivElement>, 'color'> {
41
62
  /**
@@ -45,20 +66,26 @@ export interface SGnbSystemProps extends Omit<HTMLAttributes<HTMLDivElement>, 'c
45
66
  color?: SGnbSystemColor;
46
67
  /**
47
68
  * 접힌(min) 형태 — 48px 레일 폭에 맞춰 알림·계정 아이콘만 남는다.
48
- * 미지정 시 자기를 담은 SGnb 의 접힘 상태를 따른다.
69
+ * 미지정 시 자기를 담은 SGnb 의 접힘 상태를 따른다. 상단바 자리에서는 뜻이 없다.
49
70
  */
50
71
  folded?: boolean;
51
72
  /**
52
- * 패널 상단에 쌓는 행 목록. 각 원소는 `SSystemActionButton` 의 props 다(`color` 제외).
53
- * 아래에 다른 조각이 있으면 그 사이에 구분선이 그어진다. 접히면 자리가 없어 렌더되지 않는다.
73
+ * 행 목록. 각 원소는 `SSystemActionButton` 의 props 다(`color` 제외 · 계정 행은 `account` 로
74
+ * 따로 준다). 판에서는 맨 위에 쌓이고,
75
+ * 상단바에서는 맨 왼쪽에 선다. 옆(아래)에 다른 조각이 있으면 그 사이에 구분선이 그어진다.
76
+ * 접히면 자리가 없어 렌더되지 않는다.
54
77
  */
55
78
  actions?: SGnbSystemAction[];
56
79
  /** 도메인 태그 텍스트. 접히면 자리가 없어 렌더되지 않는다 */
57
80
  domain?: string;
58
- /** 알림 버튼. 없으면 렌더하지 않는다. 설정과 나란히 서면 남는 폭을 먹고, 혼자면 폭을 다 먹는다 */
81
+ /**
82
+ * 알림 버튼. 없으면 렌더하지 않는다. 판에서는 설정과 나란히 서면 남는 폭을 먹고 혼자면 폭을 다 먹는다.
83
+ * 상단바에서는 자리가 넉넉하지 않아 라벨 없이 아이콘+개수만 선다.
84
+ */
59
85
  alert?: SGnbSystemAlert;
60
86
  /**
61
- * 설정 버튼. 없으면 렌더하지 않는다. 알림과 나란히 서면 제 폭만 갖고, 혼자면 폭을 다 먹는다.
87
+ * 설정 버튼. 없으면 렌더하지 않는다. 판에서는 알림과 나란히 서면 제 폭만 갖고 혼자면 폭을 다 먹고,
88
+ * 상단바에서는 라벨 없이 아이콘만 선다.
62
89
  * 접히면 자리가 없어 렌더되지 않는다 — 접힌 상태에서도 닿아야 하면 SGnb 의 `foldedFooter` 에 둔다.
63
90
  */
64
91
  setting?: SGnbSystemSetting;
@@ -66,28 +93,41 @@ export interface SGnbSystemProps extends Omit<HTMLAttributes<HTMLDivElement>, 'c
66
93
  account?: SGnbSystemAccount;
67
94
  }
68
95
  /**
69
- * SGnbSystem — GNB 맨 아래에 붙는 system 패널.
96
+ * SGnbSystem — GNB 의 system 조각들(액션 · 도메인 · 알림 · 설정 · 계정).
97
+ *
98
+ * 어디에 놓이느냐로 두 형태가 있고, 그 자리는 담은 SGnb 의 `header` 가 정해 내려준다(앱이 고르지 않는다).
99
+ * - `panel` (header="fix") — GNB 바닥에 깔리는 세로 판. 위에서부터 [행 목록(`actions`)] · 구분선 ·
100
+ * [도메인 태그] · [알림 | 설정] · [계정] 을 쌓는다.
101
+ * - `top` (header="full") — 레이아웃 전폭 상단바의 오른쪽 끝에 서는 가로 한 줄.
102
+ * [행 목록] | [알림] | [설정] | [도메인 계정] 순으로 서고 조각 사이에 세로 구분선이 놓인다
103
+ * (도메인·계정은 한 덩어리라 그 사이만 선 없이 붙는다).
70
104
  *
71
- * 위에서부터 [행 목록(`actions`)] · 구분선 · [도메인 태그] · [알림 | 설정] · [계정] 을 쌓는다.
72
105
  * 각 조각은 해당 prop 을 줄 때만 나타나므로, 서비스마다 필요한 만큼만 켜서 쓴다 — 계정만, 알림만,
73
106
  * 설정만, 알림+계정 … 어떤 부분집합이어도 그 조합만으로 판이 성립하도록 다음을 지킨다.
74
107
  *
75
- * - **구분선은 위아래 양쪽에 내용이 있을 때만** 긋는다. `actions` 만 주면 바닥에 뜻 없는 선이 남지 않는다.
76
- * - **알림·설정은 혼자 서면 폭을 다 먹는다.** 둘이 나란히 서면 알림이 남는 폭을, 설정이 제 폭을 갖고
77
- * 사이에 세로선이 놓인다. 어느 쪽이 빠져도 왼쪽 끝은 위아래 행과 맞는다.
108
+ * - **구분선은 양쪽에 내용이 있을 때만** 긋는다. `actions` 만 주면 뜻 없는 선이 남지 않는다.
109
+ * - **판에서 알림·설정은 혼자 서면 폭을 다 먹는다.** 둘이 나란히 서면 알림이 남는 폭을, 설정이 제 폭을
110
+ * 갖고 사이에 세로선이 놓인다. 어느 쪽이 빠져도 왼쪽 끝은 위아래 행과 맞는다.
78
111
  * - **켜진 조각이 하나도 없으면 아무것도 렌더하지 않는다** — 빈 판은 GNB 바닥에 정체 모를 경계선만 남긴다.
79
112
  *
80
- * 알림·설정·계정은 늘 함께 붙어 다니는 한 덩어리라 사이를 띄우지 않고, 그 위 조각들만 간격을 갖는다.
113
+ * 판에서 알림·설정·계정은 늘 함께 붙어 다니는 한 덩어리라 사이를 띄우지 않고, 그 위 조각들만 간격을 갖는다.
114
+ * 상단바에서는 자리가 가로로 넉넉하지 않아 알림·설정이 라벨을 벗고 아이콘(+개수)만 남는다.
81
115
  *
82
116
  * `folded` 면 48px 레일 폭에 맞춘 min 형태가 된다 — **알림·계정 아이콘만** 남고 라벨·태그·행 목록·설정은
83
117
  * 빠진다(시안). 알림 개수는 적을 자리가 없어 점 배지로 바뀐다. 둘 다 없는 조합(설정만 쓰는 앱 등)이면
84
118
  * 접힌 패널은 렌더되지 않으므로, 접힌 상태에서도 닿아야 하는 것은 SGnb 의 `foldedTop`·`foldedFooter` 에 둔다.
119
+ * 상단바는 접어도 남으므로 `top` 에는 접힘 형태가 없다.
120
+ *
121
+ * `alert.count` 가 1 이상이면 벨이 울리는 아이콘(`bellRinging`)과 강조색으로 바뀐다 — light 는 파랑,
122
+ * 어두운 면은 노랑(토큰이 정한다). 0 이거나 없으면 조용한 벨(`bell`)에 기본 색이다.
85
123
  *
86
- * `alert.count` 가 1 이상이면 벨이 울리는 아이콘(`alert`)과 강조색으로 바뀐다 — light 는 파랑,
87
- * dark 는 노랑(토큰이 정한다). 0 이거나 없으면 조용한 벨(`bell`)에 기본 색이다.
124
+ * 색은 놓인 면을 따른다: 판 위는 `light`/`dark`(오션블루 판), 판 없이 상단바 면에 바로 얹는 `top` 의
125
+ * dark 는 한 단계 어두운 `darker`(네이비) 색표다 — GNB_SYSTEM_TOP_COLOR_CONFIG 가 그 대응을 쥔다.
88
126
  *
89
- * SGnb 의 `system` 슬롯에 넣으면 `color` 와 `folded` 를 GNB 에서 받아오므로 앱이 다시 넘길 필요가 없다.
90
- * 단독으로 쓰면 두 prop 을 직접 준다. 폭은 늘 부모를 가득 채운다 — 좁은 GNB 컬럼에 놓이는 패널이다.
127
+ * **놓이는 자리(`placement`)는 prop 이 아니다** — 자기를 담은 SGnb 가 `header` 로 정해 내려준다.
128
+ * 앱이 고르면 세로 판 자리에 가로 한 줄이 서는 조합이 만들어지고, 그것을 고를 이유가 있는 화면은 없다.
129
+ * `color`·`folded` 도 슬롯 안에서는 GNB 가 내려주므로 다시 넘기지 않는다.
130
+ * 판은 폭이 늘 부모를 가득 채우고, 상단바 줄은 내용 폭만 갖는다.
91
131
  */
92
132
  export declare const SGnbSystem: import("react").ForwardRefExoticComponent<SGnbSystemProps & import("react").RefAttributes<HTMLDivElement>>;
93
133
  export {};
@@ -18,10 +18,18 @@ import type { SSystemActionButtonColor } from '../SSystemActionButton';
18
18
  /** 색상(표면). light = 흰 면, dark = 오션블루 면. GNB 의 color 를 그대로 따라간다 */
19
19
  export declare const GNB_SYSTEM_COLORS: readonly ["light", "dark"];
20
20
  export type SGnbSystemColor = (typeof GNB_SYSTEM_COLORS)[number];
21
+ /**
22
+ * 조각들이 놓이는 자리. GNB 의 `header` 가 정하므로 앱이 고르지 않는다.
23
+ * - `panel` — GNB 바닥에 깔리는 세로 판 (header="fix"). 접히면 48px 레일용 min 형태가 된다.
24
+ * - `top` — 레이아웃 전폭 상단바 위 (header="full"). 판을 깔지 않고 가로 한 줄로 선다.
25
+ */
26
+ export declare const GNB_SYSTEM_PLACEMENTS: readonly ["panel", "top"];
27
+ export type SGnbSystemPlacement = (typeof GNB_SYSTEM_PLACEMENTS)[number];
21
28
  /**
22
29
  * 패널 색이 곧 행 색이다 — 행(아이콘 프레임·라벨·hover)은 SSystemActionButton 과 같은
23
30
  * `--cmp-gnb-system-item-*` 토큰을 쓰므로, 그 색표를 그대로 빌려 두 컴포넌트가 어긋나지 않게 한다.
24
- * `darker`(패널 없이 어두운 GNB 면에 바로 얹는 색)는 패널에 대응 토큰이 없어 노출하지 않는다.
31
+ * `darker`(판 없이 어두운 GNB 면에 바로 얹는 색)는 판을 깔지 않는 `top` 자리가 쓴다
32
+ * → GNB_SYSTEM_TOP_COLOR_CONFIG.
25
33
  */
26
34
  export type GnbSystemItemColor = SSystemActionButtonColor;
27
35
  export interface GnbSystemColorTokens {
@@ -46,6 +54,31 @@ export interface GnbSystemColorTokens {
46
54
  alertHoverBg?: string;
47
55
  }
48
56
  export declare const GNB_SYSTEM_COLOR_CONFIG: Record<SGnbSystemColor, GnbSystemColorTokens>;
57
+ /**
58
+ * `top` 자리(전폭 상단바)의 색.
59
+ *
60
+ * 상단바에는 판을 깔지 않고 조각을 GNB 면에 바로 얹는다 — 그래서 행 색이 패널과 한 단계 다르다.
61
+ * dark 는 패널의 오션블루(`dark`)가 아니라 GNB 네이비 면용 `darker` 를 쓰고, 구분선·도메인 태그도
62
+ * 그에 맞춘 `*-darker-*` 토큰을 쓴다. 알림 강조색은 darker 대응 토큰이 없어 dark 값을 그대로 쓴다
63
+ * (두 면 모두 어두운 면이라 같은 노랑이 맞는다).
64
+ */
65
+ export interface GnbSystemTopColorTokens {
66
+ /** 조각(액션·알림·설정·계정)이 쓰는 행 색 */
67
+ item: GnbSystemItemColor;
68
+ /** 조각 사이 세로 구분선 */
69
+ divider: string;
70
+ /** 도메인 태그 배경 */
71
+ domainBg: string;
72
+ /** 도메인 태그 글자색 */
73
+ domainText: string;
74
+ /** 알림이 있을 때의 벨 글리프색 */
75
+ alertIcon: string;
76
+ /** 알림 개수 색 */
77
+ alertCount: string;
78
+ /** 알림이 있을 때의 hover 배경. 없으면 행 기본 hover 를 쓴다 */
79
+ alertHoverBg?: string;
80
+ }
81
+ export declare const GNB_SYSTEM_TOP_COLOR_CONFIG: Record<SGnbSystemColor, GnbSystemTopColorTokens>;
49
82
  /** 치수 — 전부 토큰 참조 */
50
83
  export declare const GNB_SYSTEM_LAYOUT: {
51
84
  /** 펼친 패널의 안쪽 여백 */
@@ -1,2 +1,2 @@
1
1
  export { SGnbSystem, type SGnbSystemProps, type SGnbSystemAction, type SGnbSystemAlert, type SGnbSystemSetting, type SGnbSystemAccount, } from './SGnbSystem';
2
- export { GNB_SYSTEM_COLORS, GNB_SYSTEM_COLOR_CONFIG, GNB_SYSTEM_LAYOUT, type SGnbSystemColor, type GnbSystemColorTokens, } from './gnbSystem.config';
2
+ export { GNB_SYSTEM_COLORS, GNB_SYSTEM_COLOR_CONFIG, GNB_SYSTEM_LAYOUT, GNB_SYSTEM_PLACEMENTS, GNB_SYSTEM_TOP_COLOR_CONFIG, type SGnbSystemColor, type SGnbSystemPlacement, type GnbSystemColorTokens, type GnbSystemTopColorTokens, } from './gnbSystem.config';
@@ -20,6 +20,7 @@
20
20
 
21
21
  ### Used by
22
22
 
23
+ - [SAccountListBox](../SAccountListBox)
23
24
  - [SButton](../SButton)
24
25
  - [SCallout](../SCallout)
25
26
  - [SCheckbox](../SCheckbox)
@@ -62,6 +63,7 @@
62
63
 
63
64
  ```mermaid
64
65
  graph TD;
66
+ SAccountListBox --> SIcon
65
67
  SButton --> SIcon
66
68
  SCallout --> SIcon
67
69
  SCheckbox --> SIcon
@@ -3,6 +3,7 @@ export type IconRenderProps = {
3
3
  size?: number | string;
4
4
  } & SVGProps<SVGSVGElement>;
5
5
  export declare const ICONS: {
6
+ readonly account: (p: IconRenderProps) => import("react").JSX.Element;
6
7
  readonly add: (p: IconRenderProps) => import("react").JSX.Element;
7
8
  readonly alert: (p: IconRenderProps) => import("react").JSX.Element;
8
9
  readonly alignKorean: (p: IconRenderProps) => import("react").JSX.Element;
@@ -15,6 +16,7 @@ export declare const ICONS: {
15
16
  readonly attachFile: (p: IconRenderProps) => import("react").JSX.Element;
16
17
  readonly barcode: (p: IconRenderProps) => import("react").JSX.Element;
17
18
  readonly bell: (p: IconRenderProps) => import("react").JSX.Element;
19
+ readonly bellRinging: (p: IconRenderProps) => import("react").JSX.Element;
18
20
  readonly bill: (p: IconRenderProps) => import("react").JSX.Element;
19
21
  readonly board: (p: IconRenderProps) => import("react").JSX.Element;
20
22
  readonly box: (p: IconRenderProps) => import("react").JSX.Element;
@@ -52,6 +52,7 @@ export type SPortalAlign = 'start' | 'center' | 'end';
52
52
 
53
53
  ### Used by
54
54
 
55
+ - [SAccountListBox](../SAccountListBox)
55
56
  - [SChipInput](../SChipInput)
56
57
  - [SSelect](../SSelect)
57
58
 
@@ -59,6 +60,7 @@ export type SPortalAlign = 'start' | 'center' | 'end';
59
60
 
60
61
  ```mermaid
61
62
  graph TD;
63
+ SAccountListBox --> SPortal
62
64
  SChipInput --> SPortal
63
65
  SSelect --> SPortal
64
66
  style SPortal fill:#f9f,stroke:#333,stroke-width:4px
@@ -10,7 +10,7 @@
10
10
  |------|------|---------|-------------|
11
11
  | `type` | `'account'` | — | 계정 행 |
12
12
  | `label?` | `string` | — | 라벨 텍스트 |
13
- | `option?` | `never` | — | 아이콘이 `user` 로 고정이라 받을 것이 없다 |
13
+ | `option` | `SSystemActionButtonAccountOption` | — | 누르면 뜨는 계정 리스트박스. **필수다** — 계정 행은 늘 이 패널의 트리거이고, 눌러도 아무것도 뜨지 않는 계정 행은 없다. 아이콘은 `user` 로 고정이라 여기서 받지 않는다. |
14
14
 
15
15
  ### SSystemActionButtonBase
16
16
 
@@ -39,20 +39,53 @@
39
39
  |------|------|---------|-------------|
40
40
  | `type` | `'status'` | — | 라벨 자리에 상태 태그가 들어가는 행 |
41
41
  | `label?` | `never` | — | 태그가 라벨 자리를 차지하므로 받지 않는다 |
42
- | `option?` | `SSystemActionButtonStatusOption` | — | 상태 태그 |
42
+ | `option` | `SSystemActionButtonStatusOption` | — | 상태 태그 + 고를 목록. **필수다** — 상태 행은 늘 그 상태를 바꾸는 메뉴의 트리거다. |
43
43
 
44
- ### SSystemActionButtonText
44
+ ### SSystemActionButtonSubSelect
45
45
 
46
46
  #### Props
47
47
 
48
48
  | Prop | Type | Default | Description |
49
49
  |------|------|---------|-------------|
50
- | `type` | `'switch' \| 'subSelect'` | — | 우측에 문구가 붙는 행. switch = 보조 조작 문구, subSelect = 지금 선택된 값 |
50
+ | `type` | `'subSelect'` | — | 우측에 지금 선택된 값이 붙는 행 |
51
+ | `label?` | `string` | — | 라벨 텍스트 |
52
+ | `option` | `SSystemActionButtonSubSelectOption` | — | 선행 아이콘 + 우측 값 + 고를 목록 |
53
+
54
+ ### SSystemActionButtonSwitch
55
+
56
+ #### Props
57
+
58
+ | Prop | Type | Default | Description |
59
+ |------|------|---------|-------------|
60
+ | `type` | `'switch'` | — | 우측에 보조 조작 문구가 붙는 행 |
51
61
  | `label?` | `string` | — | 라벨 텍스트 |
52
62
  | `option` | `SSystemActionButtonTextOption` | — | 선행 아이콘 + 우측 액션 텍스트 |
53
63
 
54
64
  ## Types
55
65
 
66
+ ### SSystemActionButtonAccountOption
67
+
68
+ ```ts
69
+ /**
70
+ * `account` 타입의 option — 행을 눌렀을 때 뜨는 계정 리스트박스.
71
+ * 내용(이메일·이름·권한·행들)은 `SAccountListBox` 와 같다.
72
+ *
73
+ * **뜨는 자리는 받지 않는다.** 계정 행이 놓인 자리가 정한다 — 판이면 행 위로 · 왼쪽 끝에 맞춰,
74
+ * 전폭 상단바면 행 아래로 · 오른쪽 끝에 맞춰 펼친다(시안). 화면마다 고를 값이 아니라,
75
+ * prop 으로 열면 같은 계정 행이 앱마다 다른 방향으로 뜬다.
76
+ */
77
+ export interface SSystemActionButtonAccountOption extends SAccountListBoxContent {
78
+ /**
79
+ * 리스트박스 열림 상태를 밖에서 쥔다(controlled). 주지 않으면 버튼이 스스로 여닫는다.
80
+ * 행을 담은 쪽이 닫아야 하는 자리가 있어 열어 둔 통로다 — 리스트박스는 SPortal 로 떠 있어
81
+ * 트리거가 화면에서 빠져도(GNB 를 접으면 메뉴 컬럼이 미끄러져 나간다) 따라 사라지지 않는다.
82
+ */
83
+ open?: boolean;
84
+ /** 리스트박스 열림/닫힘 변경 */
85
+ onOpenChange?: (open: boolean) => void;
86
+ }
87
+ ```
88
+
56
89
  ### SSystemActionButtonColor
57
90
 
58
91
  ```ts
@@ -72,12 +105,42 @@ export interface SSystemActionButtonIconOption {
72
105
  ### SSystemActionButtonStatusOption
73
106
 
74
107
  ```ts
75
- /** `status` 타입의 option — 라벨 자리에 들어가는 상태 태그 */
108
+ /**
109
+ * `status` 타입의 option — 라벨 자리에 들어가는 상태 태그 + 고를 목록.
110
+ *
111
+ * `options` 는 **필수다** — 상태 행은 늘 그 상태를 바꾸는 메뉴의 트리거이고, 지금 상태(`value`)에
112
+ * 해당하는 칸의 색·이름이 곧 태그가 된다. 보여주기만 하는 상태 줄이 필요하면 이 버튼이 아니라
113
+ * `STag` 를 쓴다.
114
+ */
76
115
  export interface SSystemActionButtonStatusOption {
77
- /** 상태 태그 색 */
78
- color?: STagColor;
79
- /** 상태 태그 텍스트 */
80
- label?: string;
116
+ /** 지금 상태. `options` 에서 같은 `value` 를 찾아 그 색·이름으로 태그를 그린다 */
117
+ value?: string;
118
+ /** 고를 수 있는 상태. **필수다** — 이 목록이 행 오른쪽으로 펼쳐진다 */
119
+ options: SSystemActionButtonStatusMenuOption[];
120
+ /** 메뉴에서 상태를 고름. 고르면 메뉴가 닫힌다 */
121
+ onChange?: (value: string) => void;
122
+ }
123
+ ```
124
+
125
+ ### SSystemActionButtonSubSelectOption
126
+
127
+ ```ts
128
+ /**
129
+ * `subSelect` 타입의 option — 지금 값 + 고를 목록.
130
+ *
131
+ * `options` 는 **필수다** — `subSelect` 는 "지금 값이 적혀 있고 눌러서 바꾸는 행"이라, 눌러도
132
+ * 아무것도 뜨지 않으면 그것은 `select`(눌러 들어가는 행)이지 `subSelect` 가 아니다.
133
+ */
134
+ export interface SSystemActionButtonSubSelectOption extends SSystemActionButtonIconOption {
135
+ /**
136
+ * 지금 값. `options` 에서 같은 `value` 를 찾아 우측에 그 `label` 로 적는다
137
+ * (못 찾으면 `value` 가 그대로 남는다).
138
+ */
139
+ value?: string;
140
+ /** 고를 수 있는 값. **필수다** — 이 목록이 행 오른쪽으로 펼쳐진다 */
141
+ options: SSystemActionButtonMenuOption[];
142
+ /** 메뉴에서 값을 고름. 고르면 메뉴가 닫힌다 */
143
+ onChange?: (value: string) => void;
81
144
  }
82
145
  ```
83
146
 
@@ -112,6 +175,28 @@ export interface SSystemActionButtonTextOption extends SSystemActionButtonIconOp
112
175
  export const SYSTEM_ACTION_BUTTON_COLORS = ['light', 'dark', 'darker'] as const;
113
176
  ```
114
177
 
178
+ ### SSystemActionButtonStatusMenuOption
179
+
180
+ ```ts
181
+ /** 상태 메뉴의 한 칸 — 점과 글자가 그 상태의 색으로 함께 물든다 */
182
+ export interface SSystemActionButtonStatusMenuOption extends SSystemActionButtonMenuOption {
183
+ /** 상태 색. 기본 `'blue'` */
184
+ color?: STagColor;
185
+ }
186
+ ```
187
+
188
+ ### SSystemActionButtonMenuOption
189
+
190
+ ```ts
191
+ /** 값 고르기 메뉴의 한 칸 */
192
+ export interface SSystemActionButtonMenuOption {
193
+ /** 값. `option.value` 와 맞춰 지금 값을 가린다 */
194
+ value: string;
195
+ /** 화면에 적히는 이름 */
196
+ label: string;
197
+ }
198
+ ```
199
+
115
200
  ## Dependencies
116
201
 
117
202
  ### Used by
@@ -120,6 +205,7 @@ export const SYSTEM_ACTION_BUTTON_COLORS = ['light', 'dark', 'darker'] as const;
120
205
 
121
206
  ### Depends on
122
207
 
208
+ - [SAccountListBox](../SAccountListBox)
123
209
  - [SIcon](../SIcon)
124
210
  - [STag](../STag)
125
211
 
@@ -127,6 +213,7 @@ export const SYSTEM_ACTION_BUTTON_COLORS = ['light', 'dark', 'darker'] as const;
127
213
 
128
214
  ```mermaid
129
215
  graph TD;
216
+ SSystemActionButton --> SAccountListBox
130
217
  SSystemActionButton --> SIcon
131
218
  SSystemActionButton --> STag
132
219
  SGnbSystem --> SSystemActionButton