sellmate-design-system-react 9.0.0-beta.64 → 9.0.0-beta.66

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 (58) hide show
  1. package/AGENTS.md +28 -3
  2. package/dist/components/SBarChart/README.md +2 -0
  3. package/dist/components/SBarChart/SBarChart.d.ts +4 -0
  4. package/dist/components/SBarChart/barChart.config.d.ts +12 -5
  5. package/dist/components/SBarcodeInput/README.md +1 -0
  6. package/dist/components/SBarcodeInput/SBarcodeInput.d.ts +8 -1
  7. package/dist/components/SChipInput/README.md +1 -0
  8. package/dist/components/SChipInput/SChipInput.d.ts +8 -1
  9. package/dist/components/SContextAlert/README.md +51 -0
  10. package/dist/components/SContextAlert/SContextAlert.d.ts +38 -0
  11. package/dist/components/SContextAlert/contextAlert.config.d.ts +29 -0
  12. package/dist/components/SContextAlert/index.d.ts +2 -0
  13. package/dist/components/SDatePicker/README.md +1 -0
  14. package/dist/components/SDatePicker/SDatePicker.d.ts +9 -2
  15. package/dist/components/SDateRangePicker/README.md +1 -0
  16. package/dist/components/SDateRangePicker/SDateRangePicker.d.ts +9 -2
  17. package/dist/components/SDonutChart/README.md +14 -0
  18. package/dist/components/SDonutChart/SDonutChart.d.ts +12 -0
  19. package/dist/components/SEditor/README.md +1 -0
  20. package/dist/components/SEditor/SEditor.d.ts +8 -1
  21. package/dist/components/SField/README.md +7 -0
  22. package/dist/components/SField/SField.d.ts +13 -0
  23. package/dist/components/SField/index.d.ts +1 -1
  24. package/dist/components/SFilePicker/README.md +1 -0
  25. package/dist/components/SFilePicker/SFilePicker.d.ts +9 -2
  26. package/dist/components/SIcon/README.md +2 -0
  27. package/dist/components/SInput/README.md +1 -0
  28. package/dist/components/SInput/SInput.d.ts +3 -1
  29. package/dist/components/SLineChart/README.md +10 -0
  30. package/dist/components/SLineChart/SLineChart.d.ts +8 -0
  31. package/dist/components/SLineChart/lineChart.config.d.ts +49 -33
  32. package/dist/components/SNumberInput/README.md +1 -0
  33. package/dist/components/SNumberInput/SNumberInput.d.ts +8 -1
  34. package/dist/components/SPieChart/README.md +2 -0
  35. package/dist/components/SPieChart/SPieChart.d.ts +4 -0
  36. package/dist/components/SSelect/README.md +1 -0
  37. package/dist/components/SSelect/SSelect.d.ts +8 -1
  38. package/dist/components/STextarea/README.md +1 -0
  39. package/dist/components/STextarea/STextarea.d.ts +8 -1
  40. package/dist/components/STimePicker/README.md +1 -0
  41. package/dist/components/STimePicker/STimePicker.d.ts +9 -2
  42. package/dist/components/STimeRangePicker/README.md +1 -0
  43. package/dist/components/STimeRangePicker/STimeRangePicker.d.ts +9 -2
  44. package/dist/index.cjs +451 -175
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.ts +1 -0
  47. package/dist/index.js +447 -176
  48. package/dist/index.js.map +1 -1
  49. package/dist/lib/chart/frame.d.ts +5 -1
  50. package/dist/lib/chart/legend.d.ts +8 -2
  51. package/dist/lib/chart/palette.d.ts +15 -13
  52. package/dist/lib/chart/radial.d.ts +20 -10
  53. package/dist/llms-full.txt +126 -4
  54. package/dist/llms.txt +32 -6
  55. package/dist/styles.css +162 -15
  56. package/dist/theme.css +104 -6
  57. package/eslint/scale.gen.mjs +1 -1
  58. package/package.json +1 -1
@@ -1,10 +1,14 @@
1
1
  /**
2
- * 차트 바깥 틀 — 패딩·배경과 "범례 / 그림" 두 칸의 세로 배치.
2
+ * 차트 바깥 틀 — 패딩·배경과 "제목·단위 / 범례 / 그림" 칸의 세로 배치.
3
3
  * 그림이 무엇인지(막대·선·파이)는 알지 않는다.
4
4
  */
5
5
  import { type CSSProperties, type HTMLAttributes, type ReactNode } from 'react';
6
6
  import type { SChartLegendPosition } from './types';
7
7
  export interface ChartFrameProps extends HTMLAttributes<HTMLDivElement> {
8
+ /** 차트 제목 — 왼쪽 위에 놓인다 */
9
+ title?: string;
10
+ /** 단위 — 오른쪽 위에 "단위 : " 를 붙여 놓는다. `title` 이 없어도 홀로 놓일 수 있다 */
11
+ unit?: string;
8
12
  /** 범례 — 없으면 칸 자체가 사라진다 */
9
13
  legend?: ReactNode;
10
14
  /** 범례 위치 */
@@ -3,13 +3,19 @@ export interface ChartLegendItem {
3
3
  name: string;
4
4
  /** 점 색 (CSS 색 문자열) */
5
5
  color: string;
6
+ /** `default` 변형에서만 쓰는 값 텍스트. `simple` 에서는 무시한다 */
7
+ value?: string;
8
+ /** `value` 글자색 (CSS 색 문자열). 없으면 이름과 같은 기본색을 쓴다 */
9
+ valueColor?: string;
6
10
  }
7
11
  export interface ChartLegendProps {
8
12
  items: ChartLegendItem[];
9
- /** 가로 정렬 — 시안은 그림 위 가운데다 */
13
+ /** 가로 정렬 — 시안은 그림 위 가운데다. `default` 변형에는 적용하지 않는다 */
10
14
  align?: 'start' | 'center' | 'end';
11
15
  /** 지금 강조 중인 계열. 나머지는 흐려진다 */
12
16
  activeIndex?: number | null;
13
17
  className?: string;
18
+ /** 범례 모양. `simple` 가로 나열(값 없음) · `default` 이름+값을 세로로 쌓는 목록 */
19
+ variant?: 'simple' | 'default';
14
20
  }
15
- export declare function ChartLegend({ items, align, activeIndex, className }: ChartLegendProps): import("react").JSX.Element | null;
21
+ export declare function ChartLegend({ items, align, activeIndex, className, variant, }: ChartLegendProps): import("react").JSX.Element | null;
@@ -3,24 +3,26 @@
3
3
  *
4
4
  * 계열이 팔레트 색 수보다 많으면 앞에서부터 **순환**한다. 색이 반복되면 범례로만
5
5
  * 구분되므로, 계열이 많을 때는 `multi`(11색) 를 쓰는 편이 낫다.
6
+ *
7
+ * 같은 모양의 팔레트가 하나 더 있다 — 선 그래프의 흐린 점
8
+ * (`--cmp-chart-line-point-dimmed-palette-*`). 잎 이름(`single` · `multi-*` ·
9
+ * `gradation-*` · `variation-*`)이 본 팔레트와 1:1 이라 고르는 규칙을 그대로 쓰고
10
+ * 변수 접두어만 바꾼다. 둘을 따로 적어 두면 팔레트에 색이 늘 때 한쪽만 고치게 된다.
6
11
  */
7
12
  import type { SChartColor, SChartPalette } from './types';
8
- /**
9
- * `custom` 팔레트에서 고를 수 있는 색. 이름이 뜻을 갖고 있으므로
10
- * (positive=늘어남, negative=줄어듦, neutral=변화 없음) 뜻에 맞게 고른다.
11
- */
12
13
  export declare const CHART_COLORS: Record<SChartColor, string>;
14
+ export declare const CHART_PALETTES: Record<"default" | "multi" | "gradation", readonly string[]>;
15
+ export declare function paletteColor(palette: SChartPalette, index: number, colors?: readonly SChartColor[]): string;
13
16
  /**
14
- * 색을 고르지 않는 팔레트들의 색 목록. 순서가 곧 계열 순서다.
17
+ * 선 그래프에서 **짚지 않은 항목의 점** 색.
15
18
  *
16
- * `gradation` 은 진한 쪽(1)부터 옅은 쪽(6)으로 간다 — 계열 순서가 크기 순서를
17
- * 나타내는 팔레트라 첫 계열이 가장 진해야 눈에 먼저 들어온다.
19
+ * 막대·원형은 흐릴 때 불투명도를 낮추지만, 선 그래프의 점은 옅은 색을 따로 갖는다
20
+ * (`chart.line.point.dimmed.palette.*`). 점이 선 위에 앉아 있어 불투명도를 낮추면
21
+ * 아래의 선이 비쳐 점이 탁해지기 때문이다 — 색을 바꾸면 점은 끝까지 또렷한 원으로 남는다.
18
22
  */
19
- export declare const CHART_PALETTES: Record<Exclude<SChartPalette, 'custom'>, readonly string[]>;
23
+ export declare function linePointDimmedColor(palette: SChartPalette, index: number, colors?: readonly SChartColor[]): string;
20
24
  /**
21
- * 계열 인덱스 → 색.
22
- *
23
- * `custom` 은 `colors` 로 받은 이름 배열을 순서대로 쓴다. 배열이 비어 있으면
24
- * 고를 것이 없으므로 `default` 로 떨어진다 — 색이 없어 아무것도 안 보이는 것보다 낫다.
25
+ * 계열 인덱스 → 값 텍스트 색. `paletteColor` 와 같은 규칙으로 고르되
26
+ * `chart.dataValue.palette.*`(위 주석 참조)를 쓴다.
25
27
  */
26
- export declare function paletteColor(palette: SChartPalette, index: number, colors?: readonly SChartColor[]): string;
28
+ export declare function dataValueColor(palette: SChartPalette, index: number, colors?: readonly SChartColor[]): string;
@@ -4,18 +4,20 @@
4
4
  * `SPieChart`·`SDonutChart` 는 이 위의 얇은 껍데기다. 두 차트는 가운데를 비우는지
5
5
  * (`innerRatio`)만 다르다. 도넛의 빈 가운데에는 글자를 두지 않는다.
6
6
  *
7
- * **시안이 없다.** 공용 차트 토큰(팔레트·범례·툴팁·바탕)은 그대로 쓰고, 원형 고유의
8
- * 치수만 아래 상수로 정했다. 디자인 토큰이 생기면 이 상수부터 토큰 참조로 바꾼다.
9
- *
10
- * 흐림·기본 불투명도는 막대 차트의 토큰(`--cmp-chart-bar-opacity-*`)을 빌려 쓴다.
11
- * 이름만 막대 것이고 뜻은 "짚지 않은 도형" 이라, 차트마다 값을 따로 두면 같은 동작이
12
- * 차트마다 다르게 보인다. `chart.pie.*` 토큰이 생기면 옮긴다.
7
+ * 원형 고유의 치수는 `chart.doughnut.*` 토큰이 정한다 — 이름은 도넛이지만 **파이도 같이
8
+ * 쓴다.** 두 차트가 한 구현이라 값을 따로 두면 구멍 유무만 달라야 할 것이 색·움직임까지
9
+ * 달라진다. 다만 조각은 SVG 경로를 좌표로 계산하므로 `var(--cmp-…)` 문자열을 넣을 수 없는
10
+ * 자리가 있다 — 그런 상수는 막대의 `BAR_RADIUS` 와 같은 규칙으로, 토큰과 **같은 값을 손으로
11
+ * 맞춰** 두고 어느 토큰을 베꼈는지 각 상수에 적는다. 불투명도처럼 CSS 로 넘길 수 있는 것은
12
+ * 토큰을 직접 참조한다.
13
13
  */
14
14
  import { type CSSProperties, type ReactNode } from 'react';
15
15
  import type { SChartColor, SChartLegendPosition, SChartPalette } from './types';
16
16
  /**
17
17
  * 도넛 안쪽 반지름 / 바깥 반지름. 너비에 따라 구멍과 고리 두께가 함께 늘고 준다.
18
- * 폭이 반응형이라 구멍을 px 로 고정하지 않고 시안의 비율(바깥 지름 248 · 구멍 지름 99)로 둔다.
18
+ * 폭이 반응형이라 구멍을 px 로 고정하지 않고 비율로 둔다 — 토큰
19
+ * `chart.doughnut.innerRatio`(`--cmp-chart-doughnut-innerRatio`)도 px 이 아닌 배수다.
20
+ * 반지름 계산에 곱하는 수라 CSS 변수로 넘기지 못하고 같은 값을 손으로 맞춰 둔다.
19
21
  */
20
22
  export declare const DONUT_INNER_RATIO = 0.4;
21
23
  /**
@@ -29,11 +31,13 @@ export declare const PIE_LABEL_RADIUS_RATIO = 0.65;
29
31
  * 짚은 조각이 자라는 길이(px). 각도는 그대로 두고 **안팎 양쪽으로** 자라, 이웃 조각을 덮지
30
32
  * 않고 고리만 두꺼워진다. 배율이 아니라 px 이라 차트가 커져도 자라는 양은 늘 같게 보인다.
31
33
  *
32
- * 시안(바깥 반지름 124)에서 짚은 조각은 128 · 46.08 이다 — 바깥으로 4px, 안쪽으로 3.52px.
33
- * 안쪽도 같은 4px 로 두어 규칙을 하나로 했다(시안과 0.48px 차이).
34
+ * 토큰 `chart.doughnut.hover.grow` 와 같은 값 — 경로 좌표라 숫자여야 해서 손으로 맞춰 둔다.
34
35
  */
35
36
  export declare const HOVER_GROW = 4;
36
- /** 짚은 조각의 모서리 둥글기(px). 자란 조각만 네 모서리를 둥글린다. */
37
+ /**
38
+ * 짚은 조각의 모서리 둥글기(px). 자란 조각만 네 모서리를 둥글린다.
39
+ * 토큰 `chart.doughnut.hover.radius` 와 같은 값 — 위와 같은 이유로 숫자다.
40
+ */
37
41
  export declare const HOVER_CORNER = 2;
38
42
  /** 조각 하나. */
39
43
  export interface RadialSlice {
@@ -51,11 +55,17 @@ export interface RadialSlicePoint {
51
55
  }
52
56
  export interface RadialChartProps {
53
57
  data: RadialSlice[];
58
+ /** 차트 제목 — 왼쪽 위에 놓인다 */
59
+ title?: string;
60
+ /** 단위 — 오른쪽 위에 "단위 : " 를 붙여 놓는다 */
61
+ unit?: string;
54
62
  palette?: Exclude<SChartPalette, 'default'>;
55
63
  colors?: SChartColor[];
56
64
  showValueLabel?: boolean;
57
65
  showLegend?: boolean;
58
66
  legendPosition?: SChartLegendPosition;
67
+ /** 범례 모양. `simple` 이름만 가로로 · `default` 이름+값을 세로로 쌓는 목록. 도넛 전용 — 파이는 항상 `simple` 이다 */
68
+ legendVariant?: 'simple' | 'default';
59
69
  showTooltip?: boolean;
60
70
  formatValue?: (value: number) => string;
61
71
  onSliceClick?: (slice: RadialSlicePoint) => void;
@@ -54,7 +54,7 @@
54
54
  | **레이아웃** | `SLayout` `SGnb` `SGnbSystem` `SSystemActionButton`(GNB system 패널에 한 줄씩 쌓는 액션 행 — 버튼 고르기는 §3-5) `SAccountListBox`(계정 행을 눌러 뜨는 계정 패널) `SLauncherListBox`(런처 버튼을 눌러 뜨는 서비스 목록) `SPage` `SPageHeader`(페이지 제목 영역 — `SLayout` 안에서 `SPage` 앞에 둔다) `SSectionHeaderCard` `SCard` `SLoginCard`(통합 계정 로그인 화면의 카드) `SDivider` `SSplitter` `SScrollArea` `SExpansionItem` |
55
55
  | **내비게이션** | `STabs` `SPagination` `SStepper` |
56
56
  | **차트** | `SBarChart`(막대 그래프 — 항목끼리 크기를 견준다. `stacked` 로 항목 안의 구성까지) `SLineChart`(꺾은선 그래프 — 순서가 있는 항목의 추이를 본다. `area` 로 크기까지, `stacked` 로 구성까지) `SPieChart`(원그래프 — 한 시점의 전체를 몇 개의 몫으로 나눈다) `SDonutChart`(도넛 그래프 — 가운데가 빈 원그래프. 구멍에 글자를 두지 않는다) |
57
- | **표시·상태** | `STag` `SBadge` `SIcon` `SLogo`(브랜드 로고를 아이콘처럼 — size 는 높이다) `SImage` `SCallout` `SGuide` |
57
+ | **표시·상태** | `STag` `SBadge` `SIcon` `SLogo`(브랜드 로고를 아이콘처럼 — size 는 높이다) `SImage` `SCallout` `SContextAlert`(한 줄짜리 맥락 알림 — 오른쪽에 후속 동작 버튼) `SGuide` |
58
58
  | **진행·로딩** | `SLinearProgress` `SCircleProgress` `SLoadingContainer` `SLoadingModal` |
59
59
  | **오버레이** | `STooltip` `SPopover` `SPopup` `SDrawer` `SPortal` |
60
60
  | **모달** | `SModal.confirm()` `SModal.create()` + `SActionModal` `SConfirmModal` `SModalOutlet`(앱 루트 1회) |
@@ -175,7 +175,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
175
175
  | 층 | 무엇인가 | 컴포넌트 |
176
176
  | --- | --- | --- |
177
177
  | **셸** | 앱 전체 뼈대. 페이지가 바뀌어도 남는다 | `SLayout` `SGnb` `SGnbSystem`(GNB 맨 아래 판 · 전폭 상단바 오른쪽 끝) `SPage` `SPageHeader`(`SLayout` 안에서 `SPage` 앞에 둔다) |
178
- | **블록** | `SPage` 의 직계 자식. 페이지를 세로로 쌓는 단위 | `SSectionHeaderCard` `SCard` `SChatMessage` `SChatSystemMessage` `SChatInput` `SLoginCard`(유일하게 `SPage` 밖에 선다 — 로그인 화면 자체가 자기 자리다, §4-6) `SForm` `SSplitter` `SScrollArea` `SCalendarBoard` `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SExpansionList` `SDraggableList` `STree` `SCallout` `SBarChart` `SLineChart` `SPieChart` `SDonutChart` `STabs` `SStepper` `SPagination` `SDivider` |
178
+ | **블록** | `SPage` 의 직계 자식. 페이지를 세로로 쌓는 단위 | `SSectionHeaderCard` `SCard` `SChatMessage` `SChatSystemMessage` `SChatInput` `SLoginCard`(유일하게 `SPage` 밖에 선다 — 로그인 화면 자체가 자기 자리다, §4-6) `SForm` `SSplitter` `SScrollArea` `SCalendarBoard` `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SExpansionList` `SDraggableList` `STree` `SCallout` `SContextAlert` `SBarChart` `SLineChart` `SPieChart` `SDonutChart` `STabs` `SStepper` `SPagination` `SDivider` |
179
179
  | **요소** | 블록 **안에** 놓이는 컨트롤. 혼자 페이지에 서지 않는다 | `SButton` `SGhostButton` `SMeatballButton` `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` `SChatAttachedFile` `SChatFile` `SImage` `SLinearProgress` `SCircleProgress` |
180
180
  | **인라인** | 텍스트 흐름·셀·라벨 안에 섞인다. 혼자 블록이 되지 않는다 | `STag` `SBadge` `SIcon` `SLogo` `STextLink` `SChip` |
181
181
  | **레이어** | 문서 흐름 **밖**에 떠서 그려진다. 어느 층에서 띄우든 레이아웃에 영향이 없다 | `SModal` `SActionModal` `SConfirmModal` `SPopup` `SDrawer` `SPopover` `STooltip` `SPortal` `SAccountListBox`(계정 행에 붙어 뜬다 — 직접 띄우지 않는다) `SLauncherListBox`(런처 버튼에 붙어 뜬다 — 직접 띄우지 않는다) `SToast` `SLoadingModal` `SLoadingContainer` `SGuide` |
@@ -650,6 +650,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
650
650
  | 하려는 일 | 컴포넌트 | 갈림 |
651
651
  | --- | --- | --- |
652
652
  | 화면에 상시 노출되는 안내·경고를 둔다 | `SCallout` | §3-2 |
653
+ | 한 자리에 붙는 **한 줄** 알림 + 후속 동작 버튼을 둔다 | `SContextAlert` | §3-2 |
653
654
  | 작업 결과를 일시적으로 알린다 | `SToast` | §3-2 |
654
655
  | 기능 온보딩·도움말을 붙인다 | `SGuide` | §3-2 |
655
656
 
@@ -683,7 +684,8 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
683
684
 
684
685
  | 상황 | 사용 |
685
686
  | --- | --- |
686
- | 화면에 **상시 노출**되는 안내·경고 문구 | `SCallout` — `type` + `message` 배열(중첩 = 들여쓰기) |
687
+ | 화면에 **상시 노출**되는 안내·경고 문구 (여러 줄 목록) | `SCallout` — `type` + `message` 배열(중첩 = 들여쓰기) |
688
+ | 한 자리의 상태를 **한 줄**로 알리고, 필요하면 후속 동작 버튼을 붙임 | `SContextAlert` — `intent` + `messages` 배열(한 줄씩) + `action` 슬롯 |
687
689
  | 작업 결과를 **일시적으로** 알림 | `SToast` (+ 루트에 `SToastContainer`) |
688
690
  | 진행 전 **확인/취소**를 받아야 할 때 | `SModal.confirm({...}).onOk(...)` — 무엇을 할지가 모달 밖에서 이미 정해진 경우다 (§3-3-2) |
689
691
  | 특정 UI 요소에 대한 **온보딩·기능 안내** | `SGuide` |
@@ -697,6 +699,22 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
697
699
  | `white` | 회색 면 위 (`background="neutral"`·`"screen"`) — 그 위에서는 `default` 가 배경에 묻힌다 |
698
700
  | `danger` | 경고. 좌측에 "주의사항" 타이틀이 붙으므로 단순 안내에는 쓰지 않는다. 주변에 이미 경고 맥락(제목 등)이 있어 타이틀이 중복되면 `showTitle={false}` 로 타이틀만 뺀다 — 경고 면은 유지된다 |
699
701
 
702
+ #### 3-2-1. SCallout vs SContextAlert
703
+
704
+ **둘은 면·테두리·패딩이 같은 상자다.** 색만 보고 고르면 같은 화면에서 같은 모양의 상자가 서로 다른 규칙으로 늘어난다. **무엇을 담는지**로 고른다.
705
+
706
+ | | `SCallout` | `SContextAlert` |
707
+ | --- | --- | --- |
708
+ | 담는 것 | 읽을 **문장들** — 여러 줄, 중첩 들여쓰기 | 지금 상태 **한 줄** |
709
+ | 후속 동작 | 없다 | `action` 슬롯에 버튼 하나 |
710
+ | 고르는 축 | `type` — **놓이는 면**이 정한다(위 표) | `intent` — **알림의 성격**이 정한다 |
711
+ | 자리 | 페이지·섹션 머리의 상시 안내 | 그 알림이 가리키는 **대상 바로 옆** |
712
+
713
+ - **`SContextAlert` 는 대상 옆에 둔다.** 페이지 맨 위에 놓고 "아래 어딘가의 이야기"를 하면 그건 `SCallout` 이 할 일이다.
714
+ - **`action` 에는 `SButton size="xs"` 를 넣는다.** 그 높이가 곧 상자의 콘텐츠 높이라, 더 큰 버튼을 넣으면 상자가 세로로 늘어나 한 줄 알림의 리듬이 깨진다. 버튼이 둘 이상 필요하면 한 줄로 끝날 이야기가 아니다 — 모달(§3-3)을 본다.
715
+ - **`messages` 는 줄을 나누는 용도지 문장을 자르는 용도가 아니다.** 한 문장이 길어 넘치는 것은 그냥 두면 줄바꿈된다. 서로 다른 사실일 때만 배열로 나눈다.
716
+ - **아이콘은 기본값을 그대로 둔다.** 인텐트 6종이 같은 아이콘을 쓰는 것이 시안의 규칙이다. `icon` 을 바꾸면 면의 색과 아이콘의 뜻이 따로 논다.
717
+
700
718
  ### 3-3. 플로팅/오버레이류
701
719
 
702
720
  | 상황 | 사용 |
@@ -2467,6 +2485,13 @@ const [initialDense] = useState(() => loadPref('list.dense', true));
2467
2485
  - **버튼 순서: 취소·닫기가 왼쪽, 저장·등록·수정·삭제가 오른쪽.** 이 순서는 모든 화면에서 동일하다.
2468
2486
  - **폼 페이지도 `contentHeight="fill"` 이 기본이다**(§2-2). 폼이 길어 페이지가 실제로 스크롤되는 화면에서만 `auto` + `scrollEndSpacing` 을 켠다.
2469
2487
  - **필드 폭은 등급으로 준다** — `width="md"` 처럼 `'xs' | 'sm' | 'md' | 'lg' | 'xl'` 중 하나다. px 를 직접 적지 않는다. 등급은 `maxLength`(= 스키마 상한)로 고르고, 상한이 `xl` 을 넘거나 상한이 없으면 `width="100%"` 로 행 전체를 쓴다 (§6 `field-width-grade`).
2488
+ - **이 골격에서는 `labelPosition` 을 쓰지 않는다.** 라벨은 컨트롤이 아니라 `SKeyValueTable` 의 왼쪽 칸이 그리므로, 컨트롤에는 `label` 자체가 가지 않아 아무 일도 일어나지 않는다.
2489
+
2490
+ **라벨을 컨트롤 위에 두는 자리 — `labelPosition="top"`.** 표 밖에서 컨트롤이 **제 `label` 을 직접 들고 설 때만** 쓴다. 모달 안의 짧은 폼, 좁은 단처럼 라벨과 컨트롤을 한 줄에 같이 세우면 컨트롤이 너무 좁아지는 자리다. `SField` 를 쓰는 입력 컨트롤 전부가 같은 이름으로 받는다.
2491
+
2492
+ - **한 폼 안에서는 섞지 않는다.** 라벨 시작점과 컨트롤 윗변이 행마다 어긋나 세로 정렬이 깨진다. 한 폼은 통째로 `left`(기본) 이거나 통째로 `top` 이다.
2493
+ - **간격을 직접 주지 않는다** — 라벨과 컨트롤 사이는 `SField` 가 `--sys-space-field-vertical-gap` 으로 넣는다. `size` 에 따라 달라지지 않는다.
2494
+ - **`labelWidth`·`labelHeight` 는 함께 쓰지 않는다.** 둘 다 라벨을 열로 줄 세우는 장치라 위에 선 라벨에는 뜻이 없고, 주더라도 무시된다. (`addonLabel` 의 폭에는 그대로 적용된다 — addon 은 테두리 박스 안이라 배치와 무관하다.)
2470
2495
 
2471
2496
  **날짜·시간 피커는 값 길이에 맞춘 폭 상한을 스스로 갖는다.** 표가 모든 컨트롤에 `width="100%"` 를 넘기지만 이 넷만 자기 상한에서 멈춘다 — `SDatePicker` · `SDateRangePicker` · `STimePicker` · `STimeRangePicker`. 그래서 한 행에 이런 필드가 섞이면 **왼쪽 끝만 맞고 오른쪽 끝이 어긋나** 보인다. 이것이 폼이 들쭉날쭉해 보이는 가장 흔한 원인이다.
2472
2497
 
@@ -3210,8 +3235,9 @@ Tailwind 유틸리티는 아래 스케일에 있는 값만 사용한다. 리터
3210
3235
  | typo-feedback-sm-semibold | 12px | 600 | 20px |
3211
3236
  | typo-feedback-sm-bold | 12px | 700 | 20px |
3212
3237
  | typo-feedback-sm-underline | 12px | 500 | 20px |
3213
- | typo-feedback-md-bold | 14px | 700 | 24px |
3238
+ | typo-feedback-md-regular | 14px | 400 | 24px |
3214
3239
  | typo-feedback-md-medium | 14px | 500 | 24px |
3240
+ | typo-feedback-md-bold | 14px | 700 | 24px |
3215
3241
  | typo-feedback-md-underline | 14px | 700 | 24px |
3216
3242
  | typo-field-xs-default | 11px | 400 | 18px |
3217
3243
  | typo-field-sm-default | 12px | 400 | 20px |
@@ -3511,6 +3537,8 @@ export const BADGE_COLORS = [
3511
3537
  |------|------|---------|-------------|
3512
3538
  | `categories` | `string[]` | — | 가로축(가로 막대면 세로축)에 놓일 항목 이름 |
3513
3539
  | `series` | `SBarChartSeries[]` | — | 계열 목록. 각 `data` 는 `categories` 와 같은 순서다 |
3540
+ | `title?` | `string` | — | 차트 제목 — 왼쪽 위에 놓인다 |
3541
+ | `unit?` | `string` | — | 단위 — 오른쪽 위에 "단위 : " 를 붙여 놓는다 |
3514
3542
  | `direction?` | `SBarChartDirection` | `'vertical'` | 막대가 자라는 방향 |
3515
3543
  | `stacked?` | `boolean` | `false` | 계열을 나란히 놓는 대신 **한 막대에 쌓는다**. 항목의 크기와 그 안의 구성을 함께 볼 때 쓴다. 첫 계열이 기준선에 붙고, 값 라벨은 조각마다가 아니라 **항목의 합계**를 한 번 적는다. 음수는 0 아래로 따로 쌓이며, 값 축도 개별 값이 아닌 항목별 합계로 잡힌다 |
3516
3544
  | `palette?` | `SBarChartPalette` | `'default'` | 색 팔레트. 계열이 하나면 계열 대신 **항목**마다 색이 바뀐다. `custom` 일 때만 `colors` 를 본다 |
@@ -3648,6 +3676,7 @@ export interface SBarChartTooltipCategory {
3648
3676
  | `inputClassName?` | `string` | — | |
3649
3677
  | `inputStyle?` | `CSSProperties` | — | |
3650
3678
  | `label?` | `string` | — | |
3679
+ | `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다). |
3651
3680
  | `labelWidth?` | `number \| string` | — | |
3652
3681
  | `icon?` | `SIconName` | — | |
3653
3682
  | `iconColor?` | `SColor` | — | |
@@ -4785,6 +4814,7 @@ export interface SChipFilterDatePreset {
4785
4814
  | `loadingRecommendedItems?` | `boolean` | `false` | |
4786
4815
  | `dropdownMinWidth?` | `number \| string` | `200` | 드롭다운 최소 너비 (숫자=px) |
4787
4816
  | `label?` | `string` | — | |
4817
+ | `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다). |
4788
4818
  | `labelWidth?` | `number \| string` | — | |
4789
4819
  | `hint?` | `string` | — | |
4790
4820
  | `errorMessage?` | `string` | — | |
@@ -4944,6 +4974,54 @@ export type SConfirmModalType = 'positive' | 'negative' | 'default';
4944
4974
 
4945
4975
  ---
4946
4976
 
4977
+ # SContextAlert
4978
+
4979
+ > 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
4980
+
4981
+ ### SContextAlert
4982
+
4983
+ #### Props
4984
+
4985
+ | Prop | Type | Default | Description |
4986
+ |------|------|---------|-------------|
4987
+ | `intent?` | `SContextAlertIntent` | `'default'` | 알림의 성격 — 면과 테두리 색이 바뀐다. 아이콘과 본문색은 인텐트와 무관하게 같다. `default` 안내 · `danger` 오류 · `warning` 주의 · `success` 완료 · `accent` 강조 · `discovery` 새 기능 |
4988
+ | `messages?` | `string[]` | `[]` | 본문. 각 문자열이 한 줄이 되고, 인라인 HTML(`<b>` · `<a>` 등)을 허용한다 — `sanitizeInlineHtml` 로 살균한 뒤 렌더하므로 스크립트·위험 스킴은 제거된다. |
4989
+ | `icon?` | `SIconName` | `CONTEXT_ALERT_DEFAULT_ICON` | 왼쪽 아이콘. 시안은 인텐트와 무관하게 원 안 느낌표 하나를 쓴다 |
4990
+ | `action?` | `ReactNode` | — | 오른쪽에 붙는 후속 동작. **`SButton size="xs"` 를 넣는다** — 그 높이(24px)가 곧 이 상자의 콘텐츠 높이라 시안의 40px 가 그대로 나온다. 더 큰 버튼을 넣으면 상자가 그만큼 세로로 늘어난다. |
4991
+ | `className?` | `string` | — | |
4992
+ | `style?` | `CSSProperties` | — | |
4993
+
4994
+ ## Types
4995
+
4996
+ ### SContextAlertIntent
4997
+
4998
+ ```ts
4999
+ export type SContextAlertIntent = (typeof CONTEXT_ALERT_INTENTS)[number];
5000
+ ```
5001
+
5002
+ ### CONTEXT_ALERT_INTENTS
5003
+
5004
+ ```ts
5005
+ export const CONTEXT_ALERT_INTENTS = [
5006
+ 'default',
5007
+ 'danger',
5008
+ 'warning',
5009
+ 'success',
5010
+ 'accent',
5011
+ 'discovery',
5012
+ ] as const;
5013
+ ```
5014
+
5015
+ ## Dependencies
5016
+
5017
+ ### Depends on
5018
+
5019
+ - [SIcon](../SIcon)
5020
+
5021
+ ### Graph
5022
+
5023
+ ---
5024
+
4947
5025
  # SDatePicker
4948
5026
 
4949
5027
  > 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
@@ -4986,6 +5064,7 @@ export type SConfirmModalType = 'positive' | 'negative' | 'default';
4986
5064
  | `rules?` | `Rule[]` | — | |
4987
5065
  | `status?` | `SFieldStatus` | — | |
4988
5066
  | `label?` | `string` | — | |
5067
+ | `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다). |
4989
5068
  | `labelWidth?` | `number \| string` | — | |
4990
5069
  | `icon?` | `SIconName` | — | |
4991
5070
  | `iconColor?` | `SColor` | — | |
@@ -5080,6 +5159,7 @@ export type SDatePickerSize = SFieldSize;
5080
5159
  | `rules?` | `Rule[]` | — | |
5081
5160
  | `status?` | `SFieldStatus` | — | |
5082
5161
  | `label?` | `string` | — | |
5162
+ | `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다). |
5083
5163
  | `labelWidth?` | `number \| string` | — | |
5084
5164
  | `icon?` | `SIconName` | — | |
5085
5165
  | `iconColor?` | `SColor` | — | |
@@ -5190,11 +5270,14 @@ export type SDateRangePickerSize = SFieldSize;
5190
5270
  | Prop | Type | Default | Description |
5191
5271
  |------|------|---------|-------------|
5192
5272
  | `data` | `SDonutChartSlice[]` | — | 조각 목록. 주는 순서대로 12시에서 시계 방향으로 그린다 — 보통 큰 순으로 준다 |
5273
+ | `title?` | `string` | — | 차트 제목 — 왼쪽 위에 놓인다 |
5274
+ | `unit?` | `string` | — | 단위 — 오른쪽 위에 "단위 : " 를 붙여 놓는다 |
5193
5275
  | `palette?` | `SDonutChartPalette` | `'multi'` | 색 팔레트. `custom` 일 때만 `colors` 를 본다 |
5194
5276
  | `colors?` | `SDonutChartColor[]` | — | `palette='custom'` 에서 쓸 색 이름을 조각 순서대로. 조각보다 짧으면 앞에서부터 순환하고, 비어 있으면 `multi` 로 그린다 |
5195
5277
  | `showValueLabel?` | `boolean` | `false` | 고리 위에 몫(%)을 적는다. 좁은 조각은 글자가 넘치므로 적지 않는다 |
5196
5278
  | `showLegend?` | `boolean` | `true` | 범례를 보인다 |
5197
5279
  | `legendPosition?` | `SDonutChartLegendPosition` | `'top'` | 범례 위치 |
5280
+ | `legendVariant?` | `SDonutChartLegendVariant` | `'simple'` | 범례 모양. `simple` 이름만 가로로 · `default` 이름+값을 세로로 쌓는 목록 |
5198
5281
  | `showTooltip?` | `boolean` | `true` | 조각에 마우스를 올리면 값 상자를 띄운다 |
5199
5282
  | `formatValue?` | `(value: number) => string` | — | 값 표시 형식 |
5200
5283
  | `tooltipFooter?` | `(slice: SDonutChartSlicePoint) => ReactNode` | — | 툴팁의 값 아래에 덧붙일 내용. 짚은 조각을 받아 그린다 — 몫·값만으로 모자란 맥락 (전월 대비, 건수 등)을 적는다. 툴팁은 누를 수 없으므로 버튼·링크는 넣지 않는다 |
@@ -5256,6 +5339,17 @@ export type SDonutChartColor =
5256
5339
  export type SDonutChartLegendPosition = 'top' | 'bottom';
5257
5340
  ```
5258
5341
 
5342
+ ### SDonutChartLegendVariant
5343
+
5344
+ ```ts
5345
+ /**
5346
+ * 범례 모양.
5347
+ * - `simple` 이름만 가로로 나열한다 (값 없음)
5348
+ * - `default` 이름 뒤에 값을 적어 세로로 쌓는 목록이다
5349
+ */
5350
+ export type SDonutChartLegendVariant = 'simple' | 'default';
5351
+ ```
5352
+
5259
5353
  ### SDonutChartSlicePoint
5260
5354
 
5261
5355
  ```ts
@@ -5624,6 +5718,7 @@ export interface SDropdownButtonItem {
5624
5718
  | `editorClassName?` | `string` | — | 편집 영역 className |
5625
5719
  | `editorStyle?` | `CSSProperties` | — | 편집 영역 style |
5626
5720
  | `label?` | `string` | — | |
5721
+ | `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다). |
5627
5722
  | `labelWidth?` | `number \| string` | — | |
5628
5723
  | `icon?` | `SIconName` | — | 레이블 영역 아이콘 |
5629
5724
  | `iconColor?` | `SColor` | — | |
@@ -5861,6 +5956,7 @@ export interface SExpansionItemRenderState {
5861
5956
  | `iconColor?` | `SColor` | — | 레이블 영역 아이콘 색상. 미지정 시 currentColor 상속 |
5862
5957
  | `labelTooltip?` | `string` | `''` | 레이블 툴팁 텍스트 |
5863
5958
  | `labelTooltipProps?` | `Partial<STooltipProps>` | — | 레이블 툴팁 상세 옵션 (SdTooltipProps 대응) |
5959
+ | `labelPosition?` | `SFieldLabelPosition` | `'left'` | 레이블을 컨트롤 **왼쪽**에 둘지 **위**에 둘지. 기본은 `left` — 이 서비스의 폼은 라벨 열을 세로로 맞춰 읽는다. 라벨이 길거나 컨트롤이 좁아 한 줄에 같이 세우기 어려울 때(모달 안의 폼, 한 줄짜리 칸) `top` 을 쓴다. **한 폼 안에서는 섞지 않는다** — 라벨 시작점이 행마다 어긋나 세로 정렬이 깨진다. `top` 이면 라벨과 컨트롤 사이 간격은 `--sys-space-field-vertical-gap` 이 정한다 (sm·md 구분 없이 고정). 라벨을 줄 세우는 장치인 `labelWidth`·`labelHeight` 는 위에 선 라벨에는 뜻이 없어 무시된다 — `addonLabel` 의 폭에는 그대로 적용된다. |
5864
5960
  | `labelWidth?` | `number \| string` | — | 레이블/어드온 레이블 너비 (숫자=px). label·addonLabel 폭에 공통 적용 |
5865
5961
  | `labelHeight?` | `number \| string` | — | 레이블 박스 높이 (숫자=px). 미지정 시 size별 기본값 사용. 컨트롤 박스가 기본 필드 높이보다 큰 경우(multiline 등) 첫 행에 세로 중앙 정렬을 맞추기 위해 컨트롤 박스 높이를 넘겨받는다. |
5866
5962
  | `size?` | `SFieldSize` | `'sm'` | 필드 크기 |
@@ -5899,6 +5995,12 @@ export interface SExpansionItemRenderState {
5899
5995
 
5900
5996
  ## Types
5901
5997
 
5998
+ ### SFieldLabelPosition
5999
+
6000
+ ```ts
6001
+ export type SFieldLabelPosition = 'left' | 'top';
6002
+ ```
6003
+
5902
6004
  ### SFieldSize
5903
6005
 
5904
6006
  ```ts
@@ -5971,6 +6073,7 @@ export type SFieldStatus = 'default' | 'pass' | 'error';
5971
6073
  | `status?` | `SFieldStatus` | — | |
5972
6074
  | `size?` | `SFieldSize` | `'sm'` | |
5973
6075
  | `label?` | `string` | — | |
6076
+ | `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다). |
5974
6077
  | `labelWidth?` | `number \| string` | — | |
5975
6078
  | `icon?` | `SIconName` | — | |
5976
6079
  | `iconColor?` | `SColor` | — | |
@@ -6605,6 +6708,7 @@ export type SGuideMessage = string | SGuideMessage[];
6605
6708
  - [SChipFilter](../SChipFilter)
6606
6709
  - [SChipInput](../SChipInput)
6607
6710
  - [SConfirmModal](../SConfirmModal)
6711
+ - [SContextAlert](../SContextAlert)
6608
6712
  - [SDatePicker](../SDatePicker)
6609
6713
  - [SDateRangePicker](../SDateRangePicker)
6610
6714
  - [SDraggableItem](../SDraggableItem)
@@ -6725,6 +6829,7 @@ export const IMAGE_FITS = ['cover', 'contain', 'fill', 'none', 'scale-down'] as
6725
6829
  | `inputClassName?` | `string` | — | 내부 input 요소 className |
6726
6830
  | `inputStyle?` | `CSSProperties` | — | 내부 input 요소 style |
6727
6831
  | `label?` | `string` | — | |
6832
+ | `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다) |
6728
6833
  | `labelWidth?` | `number \| string` | — | |
6729
6834
  | `labelTooltip?` | `string` | — | 레이블 툴팁 텍스트 |
6730
6835
  | `labelTooltipProps?` | `Partial<STooltipProps>` | — | 레이블 툴팁 상세 옵션 |
@@ -7035,7 +7140,10 @@ export type SLayoutHeader = SGnbHeader;
7035
7140
  |------|------|---------|-------------|
7036
7141
  | `categories` | `string[]` | — | 가로축에 놓일 항목 이름 |
7037
7142
  | `series` | `SLineChartSeries[]` | — | 계열 목록. 각 `data` 는 `categories` 와 같은 순서다 |
7143
+ | `title?` | `string` | — | 차트 제목 — 왼쪽 위에 놓인다 |
7144
+ | `unit?` | `string` | — | 단위 — 오른쪽 위에 "단위 : " 를 붙여 놓는다 |
7038
7145
  | `curve?` | `SLineChartCurve` | `'linear'` | 점을 잇는 방식. `smooth` 는 값을 넘어가 부풀지 않는 곡선이다 |
7146
+ | `lineStyle?` | `SLineChartLineStyle` | `'solid'` | 선 모양. `dashed` 는 차트의 모든 선을 점선으로 그린다 |
7039
7147
  | `area?` | `boolean` | `false` | 선 아래를 계열 색으로 채운다. 크기의 변화를 함께 보여줄 때 쓴다 |
7040
7148
  | `stacked?` | `boolean` | `false` | 계열을 겹쳐 그리는 대신 **아래 계열 위에 쌓는다**. 전체의 크기와 그 안의 구성을 함께 볼 때 쓴다 — 맨 위 선이 곧 합계다. 툴팁은 쌓기 전 각 계열의 값을 보여준다 |
7041
7149
  | `palette?` | `SLineChartPalette` | `'default'` | 색 팔레트. `custom` 일 때만 `colors` 를 본다 |
@@ -7080,6 +7188,13 @@ export interface SLineChartSeries {
7080
7188
  export type SLineChartCurve = 'linear' | 'smooth';
7081
7189
  ```
7082
7190
 
7191
+ ### SLineChartLineStyle
7192
+
7193
+ ```ts
7194
+ /** 선 모양. `dashed` 는 차트의 모든 선에 적용된다 — 일부 계열만 점선으로 구분하려면 쓰지 않는다 */
7195
+ export type SLineChartLineStyle = 'solid' | 'dashed';
7196
+ ```
7197
+
7083
7198
  ### SLineChartPalette
7084
7199
 
7085
7200
  ```ts
@@ -7839,6 +7954,7 @@ function OrderModal({ open, onOpenChange, onClose, modalRef, orderId }: OrderMod
7839
7954
  | `focused?` | `boolean` | — | 포커스 상태를 밖에서 지정한다 — 강조 테두리·링이 즉시 걸린다 (SField 로 그대로 넘어간다) |
7840
7955
  | `hovered?` | `boolean` | — | 호버 상태를 밖에서 지정한다 — 강조는 `focused` 와 같다 (SField 로 그대로 넘어간다) |
7841
7956
  | `label?` | `string` | — | |
7957
+ | `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다). |
7842
7958
  | `labelWidth?` | `number \| string` | — | |
7843
7959
  | `icon?` | `SIconName` | — | |
7844
7960
  | `iconColor?` | `SColor` | — | |
@@ -8115,6 +8231,8 @@ export const PAGE_CONTENT_WIDTHS = ['full', 'fixed', 'fixedCenter'] as const;
8115
8231
  | Prop | Type | Default | Description |
8116
8232
  |------|------|---------|-------------|
8117
8233
  | `data` | `SPieChartSlice[]` | — | 조각 목록. 주는 순서대로 12시에서 시계 방향으로 그린다 — 보통 큰 순으로 준다 |
8234
+ | `title?` | `string` | — | 차트 제목 — 왼쪽 위에 놓인다 |
8235
+ | `unit?` | `string` | — | 단위 — 오른쪽 위에 "단위 : " 를 붙여 놓는다 |
8118
8236
  | `palette?` | `SPieChartPalette` | `'multi'` | 색 팔레트. `custom` 일 때만 `colors` 를 본다 |
8119
8237
  | `colors?` | `SPieChartColor[]` | — | `palette='custom'` 에서 쓸 색 이름을 조각 순서대로. 조각보다 짧으면 앞에서부터 순환하고, 비어 있으면 `multi` 로 그린다 |
8120
8238
  | `showValueLabel?` | `boolean` | `false` | 조각 안에 몫(%)을 적는다. 좁은 조각은 글자가 넘치므로 적지 않는다 |
@@ -8788,6 +8906,7 @@ export type SSectionHeaderCardChildren = ReactNode;
8788
8906
  | `serverSearch?` | `boolean` | `false` | 검색을 서버로 넘긴다 — 내부 필터링을 하지 않고 `options` 를 받은 그대로 보여준다. `onSearchChange` 로 온 검색어에 맞는 목록을 소비 앱이 다시 내려줘야 한다. 켜면 검색바가 옵션 수와 무관하게 항상 나온다 — 검색 결과가 줄었다고 검색바가 사라지면 검색어를 지울 수단이 없어지기 때문이다. |
8789
8907
  | `searchDebounce?` | `number` | `DEFAULT_SEARCH_DEBOUNCE` | `serverSearch` 에서 검색어를 서버로 넘기기 전 기다리는 시간(ms) |
8790
8908
  | `label?` | `string` | — | |
8909
+ | `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다). |
8791
8910
  | `labelWidth?` | `number \| string` | — | |
8792
8911
  | `icon?` | `SIconName` | — | 레이블 영역 아이콘 |
8793
8912
  | `iconColor?` | `SColor` | — | |
@@ -9658,6 +9777,7 @@ export type STextLinkSize = 'sm' | 'md' | 'lg';
9658
9777
  | `textareaClassName?` | `string` | — | 내부 textarea 요소 className |
9659
9778
  | `textareaStyle?` | `CSSProperties` | — | 내부 textarea 요소 style |
9660
9779
  | `label?` | `string` | — | |
9780
+ | `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다). |
9661
9781
  | `labelWidth?` | `number \| string` | — | |
9662
9782
  | `icon?` | `SIconName` | — | 레이블 영역 아이콘 |
9663
9783
  | `iconColor?` | `SColor` | — | |
@@ -9720,6 +9840,7 @@ export type STextLinkSize = 'sm' | 'md' | 'lg';
9720
9840
  | `rules?` | `Rule[]` | — | |
9721
9841
  | `status?` | `SFieldStatus` | — | |
9722
9842
  | `label?` | `string` | — | |
9843
+ | `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다). |
9723
9844
  | `labelWidth?` | `number \| string` | — | |
9724
9845
  | `icon?` | `SIconName` | — | |
9725
9846
  | `iconColor?` | `SColor` | — | |
@@ -9795,6 +9916,7 @@ export type STimePickerSize = 'sm' | 'md';
9795
9916
  | `rules?` | `Rule[]` | — | |
9796
9917
  | `status?` | `SFieldStatus` | — | |
9797
9918
  | `label?` | `string` | — | |
9919
+ | `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다). |
9798
9920
  | `labelWidth?` | `number \| string` | — | |
9799
9921
  | `icon?` | `SIconName` | — | |
9800
9922
  | `iconColor?` | `SColor` | — | |
package/dist/llms.txt CHANGED
@@ -55,7 +55,7 @@
55
55
  | **레이아웃** | `SLayout` `SGnb` `SGnbSystem` `SSystemActionButton`(GNB system 패널에 한 줄씩 쌓는 액션 행 — 버튼 고르기는 §3-5) `SAccountListBox`(계정 행을 눌러 뜨는 계정 패널) `SLauncherListBox`(런처 버튼을 눌러 뜨는 서비스 목록) `SPage` `SPageHeader`(페이지 제목 영역 — `SLayout` 안에서 `SPage` 앞에 둔다) `SSectionHeaderCard` `SCard` `SLoginCard`(통합 계정 로그인 화면의 카드) `SDivider` `SSplitter` `SScrollArea` `SExpansionItem` |
56
56
  | **내비게이션** | `STabs` `SPagination` `SStepper` |
57
57
  | **차트** | `SBarChart`(막대 그래프 — 항목끼리 크기를 견준다. `stacked` 로 항목 안의 구성까지) `SLineChart`(꺾은선 그래프 — 순서가 있는 항목의 추이를 본다. `area` 로 크기까지, `stacked` 로 구성까지) `SPieChart`(원그래프 — 한 시점의 전체를 몇 개의 몫으로 나눈다) `SDonutChart`(도넛 그래프 — 가운데가 빈 원그래프. 구멍에 글자를 두지 않는다) |
58
- | **표시·상태** | `STag` `SBadge` `SIcon` `SLogo`(브랜드 로고를 아이콘처럼 — size 는 높이다) `SImage` `SCallout` `SGuide` |
58
+ | **표시·상태** | `STag` `SBadge` `SIcon` `SLogo`(브랜드 로고를 아이콘처럼 — size 는 높이다) `SImage` `SCallout` `SContextAlert`(한 줄짜리 맥락 알림 — 오른쪽에 후속 동작 버튼) `SGuide` |
59
59
  | **진행·로딩** | `SLinearProgress` `SCircleProgress` `SLoadingContainer` `SLoadingModal` |
60
60
  | **오버레이** | `STooltip` `SPopover` `SPopup` `SDrawer` `SPortal` |
61
61
  | **모달** | `SModal.confirm()` `SModal.create()` + `SActionModal` `SConfirmModal` `SModalOutlet`(앱 루트 1회) |
@@ -176,7 +176,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
176
176
  | 층 | 무엇인가 | 컴포넌트 |
177
177
  | --- | --- | --- |
178
178
  | **셸** | 앱 전체 뼈대. 페이지가 바뀌어도 남는다 | `SLayout` `SGnb` `SGnbSystem`(GNB 맨 아래 판 · 전폭 상단바 오른쪽 끝) `SPage` `SPageHeader`(`SLayout` 안에서 `SPage` 앞에 둔다) |
179
- | **블록** | `SPage` 의 직계 자식. 페이지를 세로로 쌓는 단위 | `SSectionHeaderCard` `SCard` `SChatMessage` `SChatSystemMessage` `SChatInput` `SLoginCard`(유일하게 `SPage` 밖에 선다 — 로그인 화면 자체가 자기 자리다, §4-6) `SForm` `SSplitter` `SScrollArea` `SCalendarBoard` `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SExpansionList` `SDraggableList` `STree` `SCallout` `SBarChart` `SLineChart` `SPieChart` `SDonutChart` `STabs` `SStepper` `SPagination` `SDivider` |
179
+ | **블록** | `SPage` 의 직계 자식. 페이지를 세로로 쌓는 단위 | `SSectionHeaderCard` `SCard` `SChatMessage` `SChatSystemMessage` `SChatInput` `SLoginCard`(유일하게 `SPage` 밖에 선다 — 로그인 화면 자체가 자기 자리다, §4-6) `SForm` `SSplitter` `SScrollArea` `SCalendarBoard` `STable` `STableBar` `SChipFilter` `SKeyValueTable` `SList` `SExpansionList` `SDraggableList` `STree` `SCallout` `SContextAlert` `SBarChart` `SLineChart` `SPieChart` `SDonutChart` `STabs` `SStepper` `SPagination` `SDivider` |
180
180
  | **요소** | 블록 **안에** 놓이는 컨트롤. 혼자 페이지에 서지 않는다 | `SButton` `SGhostButton` `SMeatballButton` `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` `SChatAttachedFile` `SChatFile` `SImage` `SLinearProgress` `SCircleProgress` |
181
181
  | **인라인** | 텍스트 흐름·셀·라벨 안에 섞인다. 혼자 블록이 되지 않는다 | `STag` `SBadge` `SIcon` `SLogo` `STextLink` `SChip` |
182
182
  | **레이어** | 문서 흐름 **밖**에 떠서 그려진다. 어느 층에서 띄우든 레이아웃에 영향이 없다 | `SModal` `SActionModal` `SConfirmModal` `SPopup` `SDrawer` `SPopover` `STooltip` `SPortal` `SAccountListBox`(계정 행에 붙어 뜬다 — 직접 띄우지 않는다) `SLauncherListBox`(런처 버튼에 붙어 뜬다 — 직접 띄우지 않는다) `SToast` `SLoadingModal` `SLoadingContainer` `SGuide` |
@@ -651,6 +651,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
651
651
  | 하려는 일 | 컴포넌트 | 갈림 |
652
652
  | --- | --- | --- |
653
653
  | 화면에 상시 노출되는 안내·경고를 둔다 | `SCallout` | §3-2 |
654
+ | 한 자리에 붙는 **한 줄** 알림 + 후속 동작 버튼을 둔다 | `SContextAlert` | §3-2 |
654
655
  | 작업 결과를 일시적으로 알린다 | `SToast` | §3-2 |
655
656
  | 기능 온보딩·도움말을 붙인다 | `SGuide` | §3-2 |
656
657
 
@@ -684,7 +685,8 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
684
685
 
685
686
  | 상황 | 사용 |
686
687
  | --- | --- |
687
- | 화면에 **상시 노출**되는 안내·경고 문구 | `SCallout` — `type` + `message` 배열(중첩 = 들여쓰기) |
688
+ | 화면에 **상시 노출**되는 안내·경고 문구 (여러 줄 목록) | `SCallout` — `type` + `message` 배열(중첩 = 들여쓰기) |
689
+ | 한 자리의 상태를 **한 줄**로 알리고, 필요하면 후속 동작 버튼을 붙임 | `SContextAlert` — `intent` + `messages` 배열(한 줄씩) + `action` 슬롯 |
688
690
  | 작업 결과를 **일시적으로** 알림 | `SToast` (+ 루트에 `SToastContainer`) |
689
691
  | 진행 전 **확인/취소**를 받아야 할 때 | `SModal.confirm({...}).onOk(...)` — 무엇을 할지가 모달 밖에서 이미 정해진 경우다 (§3-3-2) |
690
692
  | 특정 UI 요소에 대한 **온보딩·기능 안내** | `SGuide` |
@@ -698,6 +700,22 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
698
700
  | `white` | 회색 면 위 (`background="neutral"`·`"screen"`) — 그 위에서는 `default` 가 배경에 묻힌다 |
699
701
  | `danger` | 경고. 좌측에 "주의사항" 타이틀이 붙으므로 단순 안내에는 쓰지 않는다. 주변에 이미 경고 맥락(제목 등)이 있어 타이틀이 중복되면 `showTitle={false}` 로 타이틀만 뺀다 — 경고 면은 유지된다 |
700
702
 
703
+ #### 3-2-1. SCallout vs SContextAlert
704
+
705
+ **둘은 면·테두리·패딩이 같은 상자다.** 색만 보고 고르면 같은 화면에서 같은 모양의 상자가 서로 다른 규칙으로 늘어난다. **무엇을 담는지**로 고른다.
706
+
707
+ | | `SCallout` | `SContextAlert` |
708
+ | --- | --- | --- |
709
+ | 담는 것 | 읽을 **문장들** — 여러 줄, 중첩 들여쓰기 | 지금 상태 **한 줄** |
710
+ | 후속 동작 | 없다 | `action` 슬롯에 버튼 하나 |
711
+ | 고르는 축 | `type` — **놓이는 면**이 정한다(위 표) | `intent` — **알림의 성격**이 정한다 |
712
+ | 자리 | 페이지·섹션 머리의 상시 안내 | 그 알림이 가리키는 **대상 바로 옆** |
713
+
714
+ - **`SContextAlert` 는 대상 옆에 둔다.** 페이지 맨 위에 놓고 "아래 어딘가의 이야기"를 하면 그건 `SCallout` 이 할 일이다.
715
+ - **`action` 에는 `SButton size="xs"` 를 넣는다.** 그 높이가 곧 상자의 콘텐츠 높이라, 더 큰 버튼을 넣으면 상자가 세로로 늘어나 한 줄 알림의 리듬이 깨진다. 버튼이 둘 이상 필요하면 한 줄로 끝날 이야기가 아니다 — 모달(§3-3)을 본다.
716
+ - **`messages` 는 줄을 나누는 용도지 문장을 자르는 용도가 아니다.** 한 문장이 길어 넘치는 것은 그냥 두면 줄바꿈된다. 서로 다른 사실일 때만 배열로 나눈다.
717
+ - **아이콘은 기본값을 그대로 둔다.** 인텐트 6종이 같은 아이콘을 쓰는 것이 시안의 규칙이다. `icon` 을 바꾸면 면의 색과 아이콘의 뜻이 따로 논다.
718
+
701
719
  ### 3-3. 플로팅/오버레이류
702
720
 
703
721
  | 상황 | 사용 |
@@ -2468,6 +2486,13 @@ const [initialDense] = useState(() => loadPref('list.dense', true));
2468
2486
  - **버튼 순서: 취소·닫기가 왼쪽, 저장·등록·수정·삭제가 오른쪽.** 이 순서는 모든 화면에서 동일하다.
2469
2487
  - **폼 페이지도 `contentHeight="fill"` 이 기본이다**(§2-2). 폼이 길어 페이지가 실제로 스크롤되는 화면에서만 `auto` + `scrollEndSpacing` 을 켠다.
2470
2488
  - **필드 폭은 등급으로 준다** — `width="md"` 처럼 `'xs' | 'sm' | 'md' | 'lg' | 'xl'` 중 하나다. px 를 직접 적지 않는다. 등급은 `maxLength`(= 스키마 상한)로 고르고, 상한이 `xl` 을 넘거나 상한이 없으면 `width="100%"` 로 행 전체를 쓴다 (§6 `field-width-grade`).
2489
+ - **이 골격에서는 `labelPosition` 을 쓰지 않는다.** 라벨은 컨트롤이 아니라 `SKeyValueTable` 의 왼쪽 칸이 그리므로, 컨트롤에는 `label` 자체가 가지 않아 아무 일도 일어나지 않는다.
2490
+
2491
+ **라벨을 컨트롤 위에 두는 자리 — `labelPosition="top"`.** 표 밖에서 컨트롤이 **제 `label` 을 직접 들고 설 때만** 쓴다. 모달 안의 짧은 폼, 좁은 단처럼 라벨과 컨트롤을 한 줄에 같이 세우면 컨트롤이 너무 좁아지는 자리다. `SField` 를 쓰는 입력 컨트롤 전부가 같은 이름으로 받는다.
2492
+
2493
+ - **한 폼 안에서는 섞지 않는다.** 라벨 시작점과 컨트롤 윗변이 행마다 어긋나 세로 정렬이 깨진다. 한 폼은 통째로 `left`(기본) 이거나 통째로 `top` 이다.
2494
+ - **간격을 직접 주지 않는다** — 라벨과 컨트롤 사이는 `SField` 가 `--sys-space-field-vertical-gap` 으로 넣는다. `size` 에 따라 달라지지 않는다.
2495
+ - **`labelWidth`·`labelHeight` 는 함께 쓰지 않는다.** 둘 다 라벨을 열로 줄 세우는 장치라 위에 선 라벨에는 뜻이 없고, 주더라도 무시된다. (`addonLabel` 의 폭에는 그대로 적용된다 — addon 은 테두리 박스 안이라 배치와 무관하다.)
2471
2496
 
2472
2497
  **날짜·시간 피커는 값 길이에 맞춘 폭 상한을 스스로 갖는다.** 표가 모든 컨트롤에 `width="100%"` 를 넘기지만 이 넷만 자기 상한에서 멈춘다 — `SDatePicker` · `SDateRangePicker` · `STimePicker` · `STimeRangePicker`. 그래서 한 행에 이런 필드가 섞이면 **왼쪽 끝만 맞고 오른쪽 끝이 어긋나** 보인다. 이것이 폼이 들쭉날쭉해 보이는 가장 흔한 원인이다.
2473
2498
 
@@ -3211,8 +3236,9 @@ Tailwind 유틸리티는 아래 스케일에 있는 값만 사용한다. 리터
3211
3236
  | typo-feedback-sm-semibold | 12px | 600 | 20px |
3212
3237
  | typo-feedback-sm-bold | 12px | 700 | 20px |
3213
3238
  | typo-feedback-sm-underline | 12px | 500 | 20px |
3214
- | typo-feedback-md-bold | 14px | 700 | 24px |
3239
+ | typo-feedback-md-regular | 14px | 400 | 24px |
3215
3240
  | typo-feedback-md-medium | 14px | 500 | 24px |
3241
+ | typo-feedback-md-bold | 14px | 700 | 24px |
3216
3242
  | typo-feedback-md-underline | 14px | 700 | 24px |
3217
3243
  | typo-field-xs-default | 11px | 400 | 18px |
3218
3244
  | typo-field-sm-default | 12px | 400 | 20px |
@@ -3331,7 +3357,7 @@ Tailwind 유틸리티는 아래 스케일에 있는 값만 사용한다. 리터
3331
3357
  --sys-color-purple-strong
3332
3358
  --sys-color-purple-subtle
3333
3359
 
3334
- ## 3. 컴포넌트 인덱스 (85종)
3360
+ ## 3. 컴포넌트 인덱스 (86종)
3335
3361
 
3336
3362
  **Props 는 이 문서에 없다.** 쓸 컴포넌트를 정했으면 그 컴포넌트의 README 를 읽는다.
3337
3363
 
@@ -3340,4 +3366,4 @@ Tailwind 유틸리티는 아래 스케일에 있는 값만 사용한다. 리터
3340
3366
  예) SButton 을 쓴다면 `dist/components/SButton/README.md`.
3341
3367
  prop 을 추측해서 쓰지 말고 반드시 README 로 확인한다 (분류별 용도는 §1 의 "전체 컴포넌트 인덱스" 참조).
3342
3368
 
3343
- SAccountListBox · SActionModal · SBadge · SBarChart · SBarcodeInput · SButton · SCalendar · SCalendarBoard · SCallout · SCard · SChatAttachedFile · SChatFile · SChatInput · SChatMessage · SChatSystemMessage · SCheckbox · SChip · SChipFilter · SChipInput · SCircleProgress · SConfirmModal · SDatePicker · SDateRangePicker · SDivider · SDonutChart · SDraggableItem · SDraggableList · SDrawer · SDropdownButton · SEditor · SExpansionItem · SExpansionList · SField · SFilePicker · SForm · SGhostButton · SGnb · SGnbSystem · SGuide · SIcon · SImage · SInput · SKeyValueTable · SLauncherListBox · SLayout · SLineChart · SLinearProgress · SList · SListItem · SLoadingContainer · SLoadingModal · SLoginCard · SLogo · SMeatballButton · SModal · SNumberInput · SPage · SPagination · SPieChart · 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
3369
+ SAccountListBox · SActionModal · SBadge · SBarChart · SBarcodeInput · SButton · SCalendar · SCalendarBoard · SCallout · SCard · SChatAttachedFile · SChatFile · SChatInput · SChatMessage · SChatSystemMessage · SCheckbox · SChip · SChipFilter · SChipInput · SCircleProgress · SConfirmModal · SContextAlert · SDatePicker · SDateRangePicker · SDivider · SDonutChart · SDraggableItem · SDraggableList · SDrawer · SDropdownButton · SEditor · SExpansionItem · SExpansionList · SField · SFilePicker · SForm · SGhostButton · SGnb · SGnbSystem · SGuide · SIcon · SImage · SInput · SKeyValueTable · SLauncherListBox · SLayout · SLineChart · SLinearProgress · SList · SListItem · SLoadingContainer · SLoadingModal · SLoginCard · SLogo · SMeatballButton · SModal · SNumberInput · SPage · SPagination · SPieChart · 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