sellmate-design-system-react 9.0.0-beta.63 → 9.0.0-beta.65
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.
- package/AGENTS.md +31 -5
- package/dist/components/SBarChart/README.md +2 -0
- package/dist/components/SBarChart/SBarChart.d.ts +4 -0
- package/dist/components/SBarChart/barChart.config.d.ts +12 -5
- package/dist/components/SBarcodeInput/README.md +1 -0
- package/dist/components/SBarcodeInput/SBarcodeInput.d.ts +8 -1
- package/dist/components/SCalendarBoard/CalendarDayCard.d.ts +11 -3
- package/dist/components/SCalendarBoard/CalendarEventButton.d.ts +7 -2
- package/dist/components/SCalendarBoard/CalendarMoreButton.d.ts +2 -1
- package/dist/components/SCalendarBoard/README.md +11 -2
- package/dist/components/SCalendarBoard/SCalendarBoard.d.ts +4 -1
- package/dist/components/SCalendarBoard/calendar-board-layout.d.ts +49 -0
- package/dist/components/SCalendarBoard/types.d.ts +10 -1
- package/dist/components/SChipInput/README.md +1 -0
- package/dist/components/SChipInput/SChipInput.d.ts +8 -1
- package/dist/components/SContextAlert/README.md +51 -0
- package/dist/components/SContextAlert/SContextAlert.d.ts +38 -0
- package/dist/components/SContextAlert/contextAlert.config.d.ts +29 -0
- package/dist/components/SContextAlert/index.d.ts +2 -0
- package/dist/components/SDatePicker/README.md +1 -0
- package/dist/components/SDatePicker/SDatePicker.d.ts +9 -2
- package/dist/components/SDateRangePicker/README.md +1 -0
- package/dist/components/SDateRangePicker/SDateRangePicker.d.ts +9 -2
- package/dist/components/SDonutChart/README.md +2 -0
- package/dist/components/SDonutChart/SDonutChart.d.ts +4 -0
- package/dist/components/SEditor/README.md +1 -0
- package/dist/components/SEditor/SEditor.d.ts +8 -1
- package/dist/components/SField/README.md +7 -0
- package/dist/components/SField/SField.d.ts +13 -0
- package/dist/components/SField/index.d.ts +1 -1
- package/dist/components/SFilePicker/README.md +1 -0
- package/dist/components/SFilePicker/SFilePicker.d.ts +9 -2
- package/dist/components/SIcon/README.md +2 -0
- package/dist/components/SInput/README.md +1 -0
- package/dist/components/SInput/SInput.d.ts +3 -1
- package/dist/components/SLineChart/README.md +2 -0
- package/dist/components/SLineChart/SLineChart.d.ts +4 -0
- package/dist/components/SLineChart/lineChart.config.d.ts +42 -33
- package/dist/components/SNumberInput/README.md +1 -0
- package/dist/components/SNumberInput/SNumberInput.d.ts +8 -1
- package/dist/components/SPieChart/README.md +2 -0
- package/dist/components/SPieChart/SPieChart.d.ts +4 -0
- package/dist/components/SSelect/README.md +1 -0
- package/dist/components/SSelect/SSelect.d.ts +8 -1
- package/dist/components/STextarea/README.md +1 -0
- package/dist/components/STextarea/STextarea.d.ts +8 -1
- package/dist/components/STimePicker/README.md +1 -0
- package/dist/components/STimePicker/STimePicker.d.ts +9 -2
- package/dist/components/STimeRangePicker/README.md +1 -0
- package/dist/components/STimeRangePicker/STimeRangePicker.d.ts +9 -2
- package/dist/index.cjs +525 -223
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +521 -224
- package/dist/index.js.map +1 -1
- package/dist/lib/chart/frame.d.ts +5 -1
- package/dist/lib/chart/palette.d.ts +12 -15
- package/dist/lib/chart/radial.d.ts +18 -10
- package/dist/llms-full.txt +120 -8
- package/dist/llms.txt +35 -8
- package/dist/styles.css +170 -18
- package/dist/theme.css +104 -6
- package/eslint/scale.gen.mjs +1 -1
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
| **레이아웃** | `SLayout` `SGnb` `SGnbSystem` `SSystemActionButton`(GNB system 패널에 한 줄씩 쌓는 액션 행 — 버튼 고르기는 §3-5) `SAccountListBox`(계정 행을 눌러 뜨는 계정 패널) `SLauncherListBox`(런처 버튼을 눌러 뜨는 서비스 목록) `SPage` `SPageHeader`(페이지 제목 영역 — `SLayout` 안에서 `SPage` 앞에 둔다) `SSectionHeaderCard` `SCard` `SLoginCard`(통합 계정 로그인 화면의 카드) `SDivider` `SSplitter` `SScrollArea` `SExpansionItem` |
|
|
47
47
|
| **내비게이션** | `STabs` `SPagination` `SStepper` |
|
|
48
48
|
| **차트** | `SBarChart`(막대 그래프 — 항목끼리 크기를 견준다. `stacked` 로 항목 안의 구성까지) `SLineChart`(꺾은선 그래프 — 순서가 있는 항목의 추이를 본다. `area` 로 크기까지, `stacked` 로 구성까지) `SPieChart`(원그래프 — 한 시점의 전체를 몇 개의 몫으로 나눈다) `SDonutChart`(도넛 그래프 — 가운데가 빈 원그래프. 구멍에 글자를 두지 않는다) |
|
|
49
|
-
| **표시·상태** | `STag` `SBadge` `SIcon` `SLogo`(브랜드 로고를 아이콘처럼 — size 는 높이다) `SImage` `SCallout` `SGuide` |
|
|
49
|
+
| **표시·상태** | `STag` `SBadge` `SIcon` `SLogo`(브랜드 로고를 아이콘처럼 — size 는 높이다) `SImage` `SCallout` `SContextAlert`(한 줄짜리 맥락 알림 — 오른쪽에 후속 동작 버튼) `SGuide` |
|
|
50
50
|
| **진행·로딩** | `SLinearProgress` `SCircleProgress` `SLoadingContainer` `SLoadingModal` |
|
|
51
51
|
| **오버레이** | `STooltip` `SPopover` `SPopup` `SDrawer` `SPortal` |
|
|
52
52
|
| **모달** | `SModal.confirm()` `SModal.create()` + `SActionModal` `SConfirmModal` `SModalOutlet`(앱 루트 1회) |
|
|
@@ -167,7 +167,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
|
|
|
167
167
|
| 층 | 무엇인가 | 컴포넌트 |
|
|
168
168
|
| --- | --- | --- |
|
|
169
169
|
| **셸** | 앱 전체 뼈대. 페이지가 바뀌어도 남는다 | `SLayout` `SGnb` `SGnbSystem`(GNB 맨 아래 판 · 전폭 상단바 오른쪽 끝) `SPage` `SPageHeader`(`SLayout` 안에서 `SPage` 앞에 둔다) |
|
|
170
|
-
| **블록** | `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` |
|
|
170
|
+
| **블록** | `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` |
|
|
171
171
|
| **요소** | 블록 **안에** 놓이는 컨트롤. 혼자 페이지에 서지 않는다 | `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` |
|
|
172
172
|
| **인라인** | 텍스트 흐름·셀·라벨 안에 섞인다. 혼자 블록이 되지 않는다 | `STag` `SBadge` `SIcon` `SLogo` `STextLink` `SChip` |
|
|
173
173
|
| **레이어** | 문서 흐름 **밖**에 떠서 그려진다. 어느 층에서 띄우든 레이아웃에 영향이 없다 | `SModal` `SActionModal` `SConfirmModal` `SPopup` `SDrawer` `SPopover` `STooltip` `SPortal` `SAccountListBox`(계정 행에 붙어 뜬다 — 직접 띄우지 않는다) `SLauncherListBox`(런처 버튼에 붙어 뜬다 — 직접 띄우지 않는다) `SToast` `SLoadingModal` `SLoadingContainer` `SGuide` |
|
|
@@ -642,6 +642,7 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
|
|
|
642
642
|
| 하려는 일 | 컴포넌트 | 갈림 |
|
|
643
643
|
| --- | --- | --- |
|
|
644
644
|
| 화면에 상시 노출되는 안내·경고를 둔다 | `SCallout` | §3-2 |
|
|
645
|
+
| 한 자리에 붙는 **한 줄** 알림 + 후속 동작 버튼을 둔다 | `SContextAlert` | §3-2 |
|
|
645
646
|
| 작업 결과를 일시적으로 알린다 | `SToast` | §3-2 |
|
|
646
647
|
| 기능 온보딩·도움말을 붙인다 | `SGuide` | §3-2 |
|
|
647
648
|
|
|
@@ -675,7 +676,8 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
|
|
|
675
676
|
|
|
676
677
|
| 상황 | 사용 |
|
|
677
678
|
| --- | --- |
|
|
678
|
-
| 화면에 **상시 노출**되는 안내·경고 문구 | `SCallout` — `type` + `message` 배열(중첩 = 들여쓰기) |
|
|
679
|
+
| 화면에 **상시 노출**되는 안내·경고 문구 (여러 줄 목록) | `SCallout` — `type` + `message` 배열(중첩 = 들여쓰기) |
|
|
680
|
+
| 한 자리의 상태를 **한 줄**로 알리고, 필요하면 후속 동작 버튼을 붙임 | `SContextAlert` — `intent` + `messages` 배열(한 줄씩) + `action` 슬롯 |
|
|
679
681
|
| 작업 결과를 **일시적으로** 알림 | `SToast` (+ 루트에 `SToastContainer`) |
|
|
680
682
|
| 진행 전 **확인/취소**를 받아야 할 때 | `SModal.confirm({...}).onOk(...)` — 무엇을 할지가 모달 밖에서 이미 정해진 경우다 (§3-3-2) |
|
|
681
683
|
| 특정 UI 요소에 대한 **온보딩·기능 안내** | `SGuide` |
|
|
@@ -689,6 +691,22 @@ Tailwind 유틸리티는 **토큰 스케일에 있는 값만** 사용한다.
|
|
|
689
691
|
| `white` | 회색 면 위 (`background="neutral"`·`"screen"`) — 그 위에서는 `default` 가 배경에 묻힌다 |
|
|
690
692
|
| `danger` | 경고. 좌측에 "주의사항" 타이틀이 붙으므로 단순 안내에는 쓰지 않는다. 주변에 이미 경고 맥락(제목 등)이 있어 타이틀이 중복되면 `showTitle={false}` 로 타이틀만 뺀다 — 경고 면은 유지된다 |
|
|
691
693
|
|
|
694
|
+
#### 3-2-1. SCallout vs SContextAlert
|
|
695
|
+
|
|
696
|
+
**둘은 면·테두리·패딩이 같은 상자다.** 색만 보고 고르면 같은 화면에서 같은 모양의 상자가 서로 다른 규칙으로 늘어난다. **무엇을 담는지**로 고른다.
|
|
697
|
+
|
|
698
|
+
| | `SCallout` | `SContextAlert` |
|
|
699
|
+
| --- | --- | --- |
|
|
700
|
+
| 담는 것 | 읽을 **문장들** — 여러 줄, 중첩 들여쓰기 | 지금 상태 **한 줄** |
|
|
701
|
+
| 후속 동작 | 없다 | `action` 슬롯에 버튼 하나 |
|
|
702
|
+
| 고르는 축 | `type` — **놓이는 면**이 정한다(위 표) | `intent` — **알림의 성격**이 정한다 |
|
|
703
|
+
| 자리 | 페이지·섹션 머리의 상시 안내 | 그 알림이 가리키는 **대상 바로 옆** |
|
|
704
|
+
|
|
705
|
+
- **`SContextAlert` 는 대상 옆에 둔다.** 페이지 맨 위에 놓고 "아래 어딘가의 이야기"를 하면 그건 `SCallout` 이 할 일이다.
|
|
706
|
+
- **`action` 에는 `SButton size="xs"` 를 넣는다.** 그 높이가 곧 상자의 콘텐츠 높이라, 더 큰 버튼을 넣으면 상자가 세로로 늘어나 한 줄 알림의 리듬이 깨진다. 버튼이 둘 이상 필요하면 한 줄로 끝날 이야기가 아니다 — 모달(§3-3)을 본다.
|
|
707
|
+
- **`messages` 는 줄을 나누는 용도지 문장을 자르는 용도가 아니다.** 한 문장이 길어 넘치는 것은 그냥 두면 줄바꿈된다. 서로 다른 사실일 때만 배열로 나눈다.
|
|
708
|
+
- **아이콘은 기본값을 그대로 둔다.** 인텐트 6종이 같은 아이콘을 쓰는 것이 시안의 규칙이다. `icon` 을 바꾸면 면의 색과 아이콘의 뜻이 따로 논다.
|
|
709
|
+
|
|
692
710
|
### 3-3. 플로팅/오버레이류
|
|
693
711
|
|
|
694
712
|
| 상황 | 사용 |
|
|
@@ -1701,17 +1719,18 @@ useEffect(() => {
|
|
|
1701
1719
|
| 연도+월 선택 리스트만 필요하다 (트리거·팝오버는 직접 조합) | `SDatePickerMonthListbox` |
|
|
1702
1720
|
| **시작~종료** 를 값으로 받는다 | `SDateRangePicker` |
|
|
1703
1721
|
| 달력 격자 **자체가 화면 콘텐츠** 다 (날짜를 고르게 한다) | `SCalendar` |
|
|
1704
|
-
| 한 달치 **일정을 읽게** 펼친다 (칸마다 여러
|
|
1722
|
+
| 한 달치 **일정을 읽게** 펼친다 (칸마다 여러 건, 여러 날에 걸친 일정 포함) | `SCalendarBoard` |
|
|
1705
1723
|
|
|
1706
1724
|
- **기간을 `SDatePicker` 두 개로 만들지 않는다.** 시작이 종료보다 뒤인 입력을 막는 검증과 한쪽만 고른 중간 상태 처리가 `SDateRangePicker` 안에 이미 있다. 두 개로 쪼개면 그게 전부 앱 몫이 된다.
|
|
1707
1725
|
- `SDatePicker`·`SDateRangePicker` 는 내부적으로 `SCalendar` 를 팝오버로 띄운다. 값을 받는 자리에 `SCalendar` 를 직접 쓰지 않는다.
|
|
1708
1726
|
- **`SCalendar` 와 `SCalendarBoard` 는 방향이 반대다.** `SCalendar` 는 날짜를 **고르는** 달력(칸에는 점만 찍힌다)이고, `SCalendarBoard` 는 일정을 **읽는** 달력이다 — 칸마다 일정이 줄로 쌓이고, 칸 높이에 담기는 줄 수를 넘으면 "N개 더보기" 로 접히고, **"더보기" 또는 일정이 있는 칸 아무 데나** 누르면 **그 칸을 덮으며 뜨는 판**에 그 날짜의 일정이 전부 펼쳐진다. 폭도 다르다: `SCalendar` 는 제 폭을 갖는 요소, `SCalendarBoard` 는 페이지 폭을 채우는 블록이다.
|
|
1709
1727
|
- **`SCalendarBoard` 는 기본이 읽기 전용 판이다.** 날짜 칸을 눌러 **고르게** 하려면 `selectable` 을 켠다 — 켜야 `onValueChange(date, events)` 로 고른 날짜와 **그 날짜의 일정**이 함께 온다. 다만 **일정이 있는 칸은 `selectable` 과 무관하게 눌린다** — 그때는 목록 판이 열린다. 둘 다 켜져 있으면 고르기와 열기가 함께 일어난다. 일정 버튼과 "N개 더보기" 도 항상 눌린다.
|
|
1728
|
+
- **여러 날에 걸친 일정은 `events[].endDate` 로 준다.** 그날까지(그날 포함) **칸 경계를 넘어 하나의 막대로** 이어져 그려진다. 같은 일정을 날짜 수만큼 쪼개 넣지 않는다 — 쪼개면 칸마다 막대가 끊겨 보이고, 목록 판과 `onValueChange` 에도 건수가 부풀려 나간다. 줄은 **주 단위**로 정해져서, 막대가 지나가는 칸은 그 줄을 비워 두므로 다른 일정과 겹치지 않는다. 주 경계에서는 줄이 바뀌므로 조각이 나뉘고 **잘린 쪽 모서리가 평평해진다** — 앞/뒤로 이어진다는 표시다. **막대가 걸친 날은 모두 그 일정을 가진 날이다** — 어느 칸을 눌러도 목록 판에 함께 나오고 `onValueChange` 에도 실려 온다. `endDate` 가 `date` 보다 앞서면 하루짜리로 본다.
|
|
1710
1729
|
- **칸 배경과 일정 색은 다른 층이다.** 그날의 성격(마감·완료·휴무 등)은 `dayColors` 로 **칸 전체**에 칠하고(`default` `danger` `accent` `complete` `dim`), 일정 하나의 색은 `events[].color` 로 준다. 둘을 섞어 쓰면 서로를 가리지 않고 함께 읽힌다.
|
|
1711
1730
|
- 일정 왼쪽의 색 점은 `SBadge` 다 — `events[].color` 프리셋이 점 색까지 정하고, 따로 주려면 `dotColor` 에 `SBadge` 색(`SBadgeColor`) 중 하나를 넣는다 (§3-1).
|
|
1712
1731
|
- **칸 본문을 통째로 바꾸려면 `dayContent` 다.** 일정으로 표현되지 않는 그날치 요약(재고·매출 같은)을 칸에 얹을 때 쓴다. **슬롯을 준 날짜는 그 날짜의 `events` 를 그리지 않고 목록 판도 열지 않는다** — 한 칸에 둘을 겹쳐 담지 않는다. 일정과 요약을 함께 보여야 하면 요약을 일정 한 건(`events[]`)으로 넣는다.
|
|
1713
1732
|
- **`SCalendarBoard` 는 높이를 부모에게서 받는다.** 행이 그 높이를 균등하게 나눠 갖고, 칸 높이가 다시 "한 칸에 몇 줄이 보일지" 를 정한다. 그래서 **놓는 자리에 높이를 준다** — 페이지 본문의 남은 높이를 채우려면 `SPage` 안에서 스택을 `flex-1 min-h-0` 으로 두고 판에 `h-full` 을 준다. 높이를 주지 않으면 칸이 최소 높이로 주저앉아 한두 줄만 보인다.
|
|
1714
|
-
- **한 칸에 몇 줄을 펼칠지는 컴포넌트가 잰다.** 조절하는 prop 이 없다 — 칸 높이에서 나오는 값이라 따로 정할 것이 아니다. 줄이 넘치면 마지막 한 줄을 "N개 더보기" 에 내주므로 **접히든 아니든 칸 높이가 같다.** **소비 앱이 `events` 를 미리 잘라 넘기지 않는다.** 잘라 넘기면 "N개 더보기" 의 수가 실제 건수와 어긋나고, 눌러도 나머지가 나오지 않는다.
|
|
1733
|
+
- **한 칸에 몇 줄을 펼칠지는 컴포넌트가 잰다.** 조절하는 prop 이 없다 — 칸 높이에서 나오는 값이라 따로 정할 것이 아니다. 줄이 넘치면 마지막 한 줄을 "N개 더보기" 에 내주므로 **접히든 아니든 칸 높이가 같다.** 기간 막대가 접히면 **걸친 날마다 한 건으로** 세므로 날짜별 "N개" 가 서로 다를 수 있다. **소비 앱이 `events` 를 미리 잘라 넘기지 않는다.** 잘라 넘기면 "N개 더보기" 의 수가 실제 건수와 어긋나고, 눌러도 나머지가 나오지 않는다.
|
|
1715
1734
|
- **`events[].label` 은 필수다** — 일정이 무엇인지 알리는 부분이라 비워 두지 않는다. 인라인 HTML 을 받으므로 부분 강조가 필요할 때만 태그를 쓰고, 나머지는 `description`·`value` 로 나눠 담는다. 칸이 좁아지면 `label`+`description` 이 한 덩어리로 말줄임되고 `value` 만 끝에 온전히 남는다 — **금액·수량은 반드시 `value` 에 담는다.** `description` 에 넣으면 잘린다.
|
|
1716
1735
|
- `SDatePickerYearListbox`·`SDatePickerMonthListbox` 는 `SDatePicker` 의 mode listbox 조각만 떼어낸 컴포넌트다. 일반 폼 입력에는 `SDatePicker mode="year" | "month"` 를 우선 쓰고, 다른 트리거·팝오버 안에 리스트만 끼워 넣을 때만 직접 쓴다.
|
|
1717
1736
|
|
|
@@ -2458,6 +2477,13 @@ const [initialDense] = useState(() => loadPref('list.dense', true));
|
|
|
2458
2477
|
- **버튼 순서: 취소·닫기가 왼쪽, 저장·등록·수정·삭제가 오른쪽.** 이 순서는 모든 화면에서 동일하다.
|
|
2459
2478
|
- **폼 페이지도 `contentHeight="fill"` 이 기본이다**(§2-2). 폼이 길어 페이지가 실제로 스크롤되는 화면에서만 `auto` + `scrollEndSpacing` 을 켠다.
|
|
2460
2479
|
- **필드 폭은 등급으로 준다** — `width="md"` 처럼 `'xs' | 'sm' | 'md' | 'lg' | 'xl'` 중 하나다. px 를 직접 적지 않는다. 등급은 `maxLength`(= 스키마 상한)로 고르고, 상한이 `xl` 을 넘거나 상한이 없으면 `width="100%"` 로 행 전체를 쓴다 (§6 `field-width-grade`).
|
|
2480
|
+
- **이 골격에서는 `labelPosition` 을 쓰지 않는다.** 라벨은 컨트롤이 아니라 `SKeyValueTable` 의 왼쪽 칸이 그리므로, 컨트롤에는 `label` 자체가 가지 않아 아무 일도 일어나지 않는다.
|
|
2481
|
+
|
|
2482
|
+
**라벨을 컨트롤 위에 두는 자리 — `labelPosition="top"`.** 표 밖에서 컨트롤이 **제 `label` 을 직접 들고 설 때만** 쓴다. 모달 안의 짧은 폼, 좁은 단처럼 라벨과 컨트롤을 한 줄에 같이 세우면 컨트롤이 너무 좁아지는 자리다. `SField` 를 쓰는 입력 컨트롤 전부가 같은 이름으로 받는다.
|
|
2483
|
+
|
|
2484
|
+
- **한 폼 안에서는 섞지 않는다.** 라벨 시작점과 컨트롤 윗변이 행마다 어긋나 세로 정렬이 깨진다. 한 폼은 통째로 `left`(기본) 이거나 통째로 `top` 이다.
|
|
2485
|
+
- **간격을 직접 주지 않는다** — 라벨과 컨트롤 사이는 `SField` 가 `--sys-space-field-vertical-gap` 으로 넣는다. `size` 에 따라 달라지지 않는다.
|
|
2486
|
+
- **`labelWidth`·`labelHeight` 는 함께 쓰지 않는다.** 둘 다 라벨을 열로 줄 세우는 장치라 위에 선 라벨에는 뜻이 없고, 주더라도 무시된다. (`addonLabel` 의 폭에는 그대로 적용된다 — addon 은 테두리 박스 안이라 배치와 무관하다.)
|
|
2461
2487
|
|
|
2462
2488
|
**날짜·시간 피커는 값 길이에 맞춘 폭 상한을 스스로 갖는다.** 표가 모든 컨트롤에 `width="100%"` 를 넘기지만 이 넷만 자기 상한에서 멈춘다 — `SDatePicker` · `SDateRangePicker` · `STimePicker` · `STimeRangePicker`. 그래서 한 행에 이런 필드가 섞이면 **왼쪽 끝만 맞고 오른쪽 끝이 어긋나** 보인다. 이것이 폼이 들쭉날쭉해 보이는 가장 흔한 원인이다.
|
|
2463
2489
|
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
|------|------|---------|-------------|
|
|
11
11
|
| `categories` | `string[]` | — | 가로축(가로 막대면 세로축)에 놓일 항목 이름 |
|
|
12
12
|
| `series` | `SBarChartSeries[]` | — | 계열 목록. 각 `data` 는 `categories` 와 같은 순서다 |
|
|
13
|
+
| `title?` | `string` | — | 차트 제목 — 왼쪽 위에 놓인다 |
|
|
14
|
+
| `unit?` | `string` | — | 단위 — 오른쪽 위에 "단위 : " 를 붙여 놓는다 |
|
|
13
15
|
| `direction?` | `SBarChartDirection` | `'vertical'` | 막대가 자라는 방향 |
|
|
14
16
|
| `stacked?` | `boolean` | `false` | 계열을 나란히 놓는 대신 **한 막대에 쌓는다**. 항목의 크기와 그 안의 구성을 함께 볼 때 쓴다. 첫 계열이 기준선에 붙고, 값 라벨은 조각마다가 아니라 **항목의 합계**를 한 번 적는다. 음수는 0 아래로 따로 쌓이며, 값 축도 개별 값이 아닌 항목별 합계로 잡힌다 |
|
|
15
17
|
| `palette?` | `SBarChartPalette` | `'default'` | 색 팔레트. 계열이 하나면 계열 대신 **항목**마다 색이 바뀐다. `custom` 일 때만 `colors` 를 본다 |
|
|
@@ -46,6 +46,10 @@ export interface SBarChartProps {
|
|
|
46
46
|
categories: string[];
|
|
47
47
|
/** 계열 목록. 각 `data` 는 `categories` 와 같은 순서다 */
|
|
48
48
|
series: SBarChartSeries[];
|
|
49
|
+
/** 차트 제목 — 왼쪽 위에 놓인다 */
|
|
50
|
+
title?: string;
|
|
51
|
+
/** 단위 — 오른쪽 위에 "단위 : " 를 붙여 놓는다 */
|
|
52
|
+
unit?: string;
|
|
49
53
|
/** 막대가 자라는 방향 */
|
|
50
54
|
direction?: SBarChartDirection;
|
|
51
55
|
/**
|
|
@@ -17,15 +17,22 @@ export declare const BAR_GAP = 6;
|
|
|
17
17
|
export declare const GROUP_PADDING_MIN = 8;
|
|
18
18
|
/** 막대 묶음 좌우 여백의 상한(px) — 시안 `bar group paddingX max : 24`. */
|
|
19
19
|
export declare const GROUP_PADDING_MAX = 24;
|
|
20
|
-
/**
|
|
21
|
-
|
|
20
|
+
/**
|
|
21
|
+
* 막대 끝과 값 라벨 사이 간격(px) — 토큰 `chart.dataLabel.gap`(점·막대 ↔ 값 라벨).
|
|
22
|
+
* 라벨 자리를 좌표로 잡으므로 `var()` 가 아니라 같은 값을 손으로 맞춰 둔다.
|
|
23
|
+
*/
|
|
24
|
+
export declare const VALUE_LABEL_GAP = 4;
|
|
22
25
|
/**
|
|
23
26
|
* 막대 모서리 반경(px). SVG 경로를 좌표로 계산하므로 `var(--cmp-chart-bar-radius)`
|
|
24
27
|
* 문자열이 아니라 **숫자**여야 한다 — 시안의 clipPath 도 같은 이유로 8 을 좌표에
|
|
25
28
|
* 박아 두고 있다. 토큰(`chart.bar.radius`)과 같은 값을 손으로 맞춰 둔 유일한 자리다.
|
|
26
29
|
*/
|
|
27
30
|
export declare const BAR_RADIUS = 8;
|
|
28
|
-
|
|
31
|
+
/**
|
|
32
|
+
* 기본 불투명도는 막대만의 값이 아니라 차트 공용(`chart.opacity.default`)이다 —
|
|
33
|
+
* 도넛·파이도 같은 값을 쓴다. 흐려진 상태만 막대 고유(`chart.bar.opacity.dimmed`)다.
|
|
34
|
+
*/
|
|
35
|
+
export declare const BAR_OPACITY_DEFAULT = "var(--cmp-chart-opacity-default)";
|
|
29
36
|
export declare const BAR_OPACITY_DIMMED = "var(--cmp-chart-bar-opacity-dimmed)";
|
|
30
37
|
/**
|
|
31
38
|
* 호버한 항목의 막대 — 완전히 불투명하다.
|
|
@@ -34,12 +41,12 @@ export declare const BAR_OPACITY_DIMMED = "var(--cmp-chart-bar-opacity-dimmed)";
|
|
|
34
41
|
* 디자인 토큰으로 두지 않는 쪽이 맞으므로, 여기서는 토큰 대신 1 을 쓴다.
|
|
35
42
|
*/
|
|
36
43
|
export declare const BAR_OPACITY_HOVER = 1;
|
|
37
|
-
export declare const BAR_DATA_LABEL_COLOR = "var(--cmp-chart-
|
|
44
|
+
export declare const BAR_DATA_LABEL_COLOR = "var(--cmp-chart-dataLabel-color-default)";
|
|
38
45
|
/**
|
|
39
46
|
* 값 라벨의 타이포 — 호버한 항목만 굵고 크게 뜬다.
|
|
40
47
|
*
|
|
41
48
|
* 타이포 토큰은 `--cmp-*` 변수로 나오지 않고 `.typo-*` 유틸로만 나오므로,
|
|
42
|
-
* `chart.
|
|
49
|
+
* `chart.dataLabel.typography.default`(`body.sm.medium`) ·
|
|
43
50
|
* `.hover`(`body.md.bold`) 에 대응하는 클래스를 여기서 짝지어 둔다.
|
|
44
51
|
*/
|
|
45
52
|
export declare const BAR_DATA_LABEL_TYPO = "typo-body-sm-medium";
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
| `inputClassName?` | `string` | — | |
|
|
26
26
|
| `inputStyle?` | `CSSProperties` | — | |
|
|
27
27
|
| `label?` | `string` | — | |
|
|
28
|
+
| `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다). |
|
|
28
29
|
| `labelWidth?` | `number \| string` | — | |
|
|
29
30
|
| `icon?` | `SIconName` | — | |
|
|
30
31
|
| `iconColor?` | `SColor` | — | |
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type CSSProperties, type ReactNode } from 'react';
|
|
2
|
-
import { type SFieldSize, type SFieldAddonAlign, type SFieldStatus } from '../SField';
|
|
2
|
+
import { type SFieldSize, type SFieldAddonAlign, type SFieldStatus, type SFieldLabelPosition } from '../SField';
|
|
3
3
|
import { type SIconName } from '../SIcon';
|
|
4
4
|
import { type SColor } from '../../lib/color';
|
|
5
5
|
import { type Rule } from '../../lib/form';
|
|
@@ -32,6 +32,13 @@ export interface SBarcodeInputProps {
|
|
|
32
32
|
inputClassName?: string;
|
|
33
33
|
inputStyle?: CSSProperties;
|
|
34
34
|
label?: string;
|
|
35
|
+
/**
|
|
36
|
+
* 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다).
|
|
37
|
+
*
|
|
38
|
+
* @nodemo SField 에서 내려오는 공통 필드 옵션이다 — 같은 데모를 컨트롤마다 복제하지 않고
|
|
39
|
+
* 대표 컨트롤 `SInput` 과 `SField` 에 한 번 둔다 (scripts/check-docs-coverage.mjs 머리말).
|
|
40
|
+
*/
|
|
41
|
+
labelPosition?: SFieldLabelPosition;
|
|
35
42
|
labelWidth?: number | string;
|
|
36
43
|
icon?: SIconName;
|
|
37
44
|
iconColor?: SColor;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { type HTMLAttributes, type MouseEvent, type ReactNode } from 'react';
|
|
2
|
+
import type { CalendarBoardSegment } from './calendar-board-layout';
|
|
2
3
|
import { type SCalendarBoardDayColor } from './calendarBoard.config';
|
|
3
4
|
import type { SCalendarBoardEvent } from './types';
|
|
4
5
|
/**
|
|
5
6
|
* 달력의 날짜 한 칸 (SCalendarBoard 내부 조립 요소).
|
|
6
|
-
* 위에 날짜
|
|
7
|
+
* 위에 날짜 숫자가 서고, 그 아래로 일정 막대가 줄 단위로 얹힌다.
|
|
7
8
|
* `body` 를 받은 칸은 아래를 통째로 그것에 내준다 — 일정은 그리지 않는다.
|
|
8
9
|
*/
|
|
9
10
|
export declare const CalendarDayCard: import("react").ForwardRefExoticComponent<HTMLAttributes<HTMLDivElement> & {
|
|
@@ -19,8 +20,13 @@ export declare const CalendarDayCard: import("react").ForwardRefExoticComponent<
|
|
|
19
20
|
selectable: boolean;
|
|
20
21
|
/** 칸 배경 */
|
|
21
22
|
color: SCalendarBoardDayColor;
|
|
22
|
-
/**
|
|
23
|
-
|
|
23
|
+
/**
|
|
24
|
+
* **이 칸에서 시작하는** 일정 막대. 여러 날에 걸친 일정은 시작 칸이 그리고 오른쪽 칸 위로 뻗는다 —
|
|
25
|
+
* 지나가는 칸은 자기 줄을 비워 두므로(배치 계산이 이미 잡아 둔다) 겹치지 않는다.
|
|
26
|
+
*/
|
|
27
|
+
segments: CalendarBoardSegment[];
|
|
28
|
+
/** 이 날짜에 걸친 일정 수 — 하나라도 있으면 칸을 눌러 목록 판을 열 수 있다 */
|
|
29
|
+
dayEventCount: number;
|
|
24
30
|
/**
|
|
25
31
|
* 일정 자리를 대신 차지할 칸 본문 (SCalendarBoard 의 `dayContent`).
|
|
26
32
|
* 주면 일정·"더보기" 를 그리지 않는다. `content` 는 HTMLAttributes 가 이미 쓰는 이름이라 피했다.
|
|
@@ -28,6 +34,8 @@ export declare const CalendarDayCard: import("react").ForwardRefExoticComponent<
|
|
|
28
34
|
body?: ReactNode;
|
|
29
35
|
/** 접혀 있는 일정 수. 0 이면 "더보기" 를 그리지 않는다 */
|
|
30
36
|
hiddenCount: number;
|
|
37
|
+
/** "더보기" 가 앉는 줄. 접힌 것이 없는 주는 -1 */
|
|
38
|
+
moreLane: number;
|
|
31
39
|
/** 이 칸의 일정 목록 판이 열려 있는지 */
|
|
32
40
|
isOpen: boolean;
|
|
33
41
|
moreLabel?: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type MouseEvent } from 'react';
|
|
1
|
+
import { type CSSProperties, type MouseEvent } from 'react';
|
|
2
2
|
import type { SCalendarBoardEvent } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* 달력 칸/패널 안의 일정 한 줄 (SCalendarBoard 내부 조립 요소).
|
|
@@ -6,8 +6,13 @@ import type { SCalendarBoardEvent } from './types';
|
|
|
6
6
|
* 점 → 레이블(강조) → 설명 → `/` → 값 순서로 한 줄에 눕는다.
|
|
7
7
|
* 가운데 레이블 묶음만 줄어들고 값은 끝에 고정되므로, 좁은 칸에서도 금액이 잘리지 않는다.
|
|
8
8
|
*/
|
|
9
|
-
export declare function CalendarEventButton({ event, onSelect, className, }: {
|
|
9
|
+
export declare function CalendarEventButton({ event, onSelect, flatStart, flatEnd, className, style, }: {
|
|
10
10
|
event: SCalendarBoardEvent;
|
|
11
11
|
onSelect?: (event: SCalendarBoardEvent, e: MouseEvent<HTMLButtonElement>) => void;
|
|
12
|
+
/** 왼쪽 끝이 잘린 조각 — 앞 주에서 이어지므로 모서리를 평평하게 한다 */
|
|
13
|
+
flatStart?: boolean;
|
|
14
|
+
/** 오른쪽 끝이 잘린 조각 — 다음 주로 이어진다 */
|
|
15
|
+
flatEnd?: boolean;
|
|
12
16
|
className?: string;
|
|
17
|
+
style?: CSSProperties;
|
|
13
18
|
}): import("react").JSX.Element;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type MouseEvent } from 'react';
|
|
1
|
+
import { type CSSProperties, type MouseEvent } from 'react';
|
|
2
2
|
/**
|
|
3
3
|
* 칸에 다 담기지 않은 일정 수를 알리는 "N개 더보기" 줄 (SCalendarBoard 내부 조립 요소).
|
|
4
4
|
* 개수는 강조색, 뒷말은 본문색으로 갈라 개수가 먼저 읽히게 한다.
|
|
@@ -9,4 +9,5 @@ export declare const CalendarMoreButton: import("react").ForwardRefExoticCompone
|
|
|
9
9
|
label?: string;
|
|
10
10
|
onClick?: (e: MouseEvent<HTMLButtonElement>) => void;
|
|
11
11
|
className?: string;
|
|
12
|
+
style?: CSSProperties;
|
|
12
13
|
} & import("react").RefAttributes<HTMLButtonElement>>;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
| `defaultMonth?` | `number` | — | 처음 보여줄 월 1-12 (비제어). 없으면 오늘 |
|
|
15
15
|
| `selectable?` | `boolean` | `false` | 날짜 칸을 눌러 고를 수 있게 한다. 기본은 읽기 전용 판이다 — 켜야 칸에 커서·포커스·키보드(Enter·Space)가 붙고 `onValueChange` 가 온다. 일정 버튼과 "N개 더보기" 는 이 값과 무관하게 항상 눌린다. |
|
|
16
16
|
| `value?` | `string \| null` | — | 선택 날짜 (YYYY-MM-DD). `selectable` 과 별개로 강조만 주고 싶을 때도 쓴다 |
|
|
17
|
-
| `events?` | `SCalendarBoardEvent[]` | — |
|
|
17
|
+
| `events?` | `SCalendarBoardEvent[]` | — | 일정 목록. `date`(시작)로 칸에 배분되고, `endDate` 를 주면 그날까지 **하나의 막대로 이어져** 칸 경계를 넘어 그려진다. |
|
|
18
18
|
| `dayColors?` | `Record<string, SCalendarBoardDayColor>` | — | 날짜별 칸 배경. 키는 `YYYY-MM-DD`, 없는 날짜는 `'default'` 다. 그날의 성격(마감·완료·휴무 등)을 칸 전체로 알릴 때 쓴다 — 일정 하나의 색은 `events[].color` 다. |
|
|
19
19
|
| `dayContent?` | `Record<string, ReactNode>` | — | 날짜별 칸 본문. 키는 `YYYY-MM-DD`, 준 날짜는 **일정 자리를 통째로 이 내용이 차지한다** — 그날의 `events` 는 그리지 않고 목록 판도 열리지 않는다. 일정으로 표현되지 않는 것(재고 현황· 매출 요약 같은 그날치 요약)을 칸에 그대로 얹을 때 쓴다. |
|
|
20
20
|
| `todayLabel?` | `string` | `'오늘'` | 헤더 오른쪽 "오늘" 버튼 레이블. 빈 문자열이면 버튼을 그리지 않는다 |
|
|
@@ -52,8 +52,17 @@ export interface SCalendarBoardView {
|
|
|
52
52
|
export interface SCalendarBoardEvent {
|
|
53
53
|
/** 고유 식별자. 없으면 목록 순서로 key 를 만든다 */
|
|
54
54
|
id?: string;
|
|
55
|
-
/** 날짜 (YYYY-MM-DD) */
|
|
55
|
+
/** 시작 날짜 (YYYY-MM-DD). 하루짜리 일정은 이것만 준다 */
|
|
56
56
|
date: string;
|
|
57
|
+
/**
|
|
58
|
+
* 마지막 날 (YYYY-MM-DD, **그날 포함**). 주지 않거나 `date` 보다 앞서면 하루짜리로 본다.
|
|
59
|
+
*
|
|
60
|
+
* 여러 날에 걸친 일정은 칸 경계를 넘어 **하나의 막대로 이어져** 그려진다. 주 경계에서는 줄이
|
|
61
|
+
* 바뀌므로 조각이 나뉘고, 그렇게 잘린 쪽 모서리는 평평해져 "앞/뒤로 이어진다" 가 읽힌다.
|
|
62
|
+
*
|
|
63
|
+
* 막대가 걸친 날은 **모두** 그 일정을 가진 날로 친다 — 목록 판과 `onValueChange` 에 함께 온다.
|
|
64
|
+
*/
|
|
65
|
+
endDate?: string;
|
|
57
66
|
/**
|
|
58
67
|
* 강조 레이블 (필수) — 예: `"[입고 예정]"`.
|
|
59
68
|
* 일정이 무엇인지 한눈에 알리는 부분이라 비워 두지 않는다.
|
|
@@ -22,7 +22,10 @@ export interface SCalendarBoardProps {
|
|
|
22
22
|
value?: string | null;
|
|
23
23
|
/** 날짜 칸 선택 — 고른 날짜와 그 날짜의 일정이 함께 온다 (`selectable` 일 때만) */
|
|
24
24
|
onValueChange?: (date: string, events: SCalendarBoardEvent[]) => void;
|
|
25
|
-
/**
|
|
25
|
+
/**
|
|
26
|
+
* 일정 목록. `date`(시작)로 칸에 배분되고, `endDate` 를 주면 그날까지 **하나의 막대로 이어져**
|
|
27
|
+
* 칸 경계를 넘어 그려진다.
|
|
28
|
+
*/
|
|
26
29
|
events?: SCalendarBoardEvent[];
|
|
27
30
|
/**
|
|
28
31
|
* 날짜별 칸 배경. 키는 `YYYY-MM-DD`, 없는 날짜는 `'default'` 다.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 달력 판의 **일정 배치**를 계산한다 (순수 함수 — DOM 을 보지 않는다).
|
|
3
|
+
*
|
|
4
|
+
* 왜 필요한가: 일정이 하루짜리뿐이면 칸마다 자기 목록을 세로로 쌓으면 그만이다. 그런데 여러 날에
|
|
5
|
+
* 걸친 일정은 **칸 경계를 넘어 하나의 막대로 이어져야** 하므로, 칸 혼자서는 자기 줄을 정할 수 없다 —
|
|
6
|
+
* 같은 주의 다른 칸에 걸친 막대가 이미 그 줄을 쓰고 있을 수 있기 때문이다. 그래서 줄(lane) 배정은
|
|
7
|
+
* **주 단위**로 한 번에 푼다.
|
|
8
|
+
*
|
|
9
|
+
* 하루짜리 일정만 있는 판은 이 계산을 거쳐도 예전과 같은 화면이 된다 — 서로 다른 날의 일정은
|
|
10
|
+
* 겹치지 않아 전부 0번 줄부터 차곡차곡 앉기 때문이다.
|
|
11
|
+
*/
|
|
12
|
+
import type { DayCell } from '../../lib/date';
|
|
13
|
+
import type { SCalendarBoardEvent } from './types';
|
|
14
|
+
/** 한 주 안에서 이어지는 막대 하나 — 일정 하나가 주 경계에서 잘리면 조각이 여럿 된다 */
|
|
15
|
+
export interface CalendarBoardSegment {
|
|
16
|
+
event: SCalendarBoardEvent;
|
|
17
|
+
/** React key */
|
|
18
|
+
key: string;
|
|
19
|
+
/** 격자 칸 배열에서의 시작 인덱스 */
|
|
20
|
+
startIndex: number;
|
|
21
|
+
/** 이어지는 칸 수 (1 이상) */
|
|
22
|
+
span: number;
|
|
23
|
+
/** 그 주 안에서 몇 번째 줄인지 (0부터) */
|
|
24
|
+
lane: number;
|
|
25
|
+
/** 왼쪽 끝이 일정의 **실제 시작**인지. 아니면 앞에서 이어진 것이라 그 모서리를 평평하게 한다 */
|
|
26
|
+
startsHere: boolean;
|
|
27
|
+
/** 오른쪽 끝이 일정의 **실제 끝**인지 */
|
|
28
|
+
endsHere: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface CalendarBoardLayout {
|
|
31
|
+
/** 칸별로, **그 칸에서 시작하는** 막대. 막대는 시작 칸이 그린다 */
|
|
32
|
+
segmentsByCell: CalendarBoardSegment[][];
|
|
33
|
+
/** 칸별로, 그 날짜에 걸친 일정 전부 — 목록 판과 콜백에 넘기는 값 */
|
|
34
|
+
eventsByCell: SCalendarBoardEvent[][];
|
|
35
|
+
/** 칸별로 줄 수를 넘겨 접힌 일정 수 */
|
|
36
|
+
hiddenCountByCell: number[];
|
|
37
|
+
/** 주별로 "N개 더보기" 가 앉는 줄. 접힌 것이 없는 주는 -1 */
|
|
38
|
+
moreLaneByWeek: number[];
|
|
39
|
+
}
|
|
40
|
+
/** 일정의 마지막 날. `endDate` 가 없거나 시작보다 앞서면 하루짜리로 본다 */
|
|
41
|
+
export declare function eventEndDate(event: SCalendarBoardEvent): string;
|
|
42
|
+
export declare function layoutCalendarBoard({ cells, events, rowCapacity, blockedDates, }: {
|
|
43
|
+
cells: readonly DayCell[];
|
|
44
|
+
events: readonly SCalendarBoardEvent[];
|
|
45
|
+
/** 칸 하나에 담기는 줄 수 */
|
|
46
|
+
rowCapacity: number;
|
|
47
|
+
/** 일정을 그리지 않는 날짜 (`dayContent` 를 받은 칸) */
|
|
48
|
+
blockedDates: ReadonlySet<string>;
|
|
49
|
+
}): CalendarBoardLayout;
|
|
@@ -4,8 +4,17 @@ import type { SCalendarBoardEventColor } from './calendarBoard.config';
|
|
|
4
4
|
export interface SCalendarBoardEvent {
|
|
5
5
|
/** 고유 식별자. 없으면 목록 순서로 key 를 만든다 */
|
|
6
6
|
id?: string;
|
|
7
|
-
/** 날짜 (YYYY-MM-DD) */
|
|
7
|
+
/** 시작 날짜 (YYYY-MM-DD). 하루짜리 일정은 이것만 준다 */
|
|
8
8
|
date: string;
|
|
9
|
+
/**
|
|
10
|
+
* 마지막 날 (YYYY-MM-DD, **그날 포함**). 주지 않거나 `date` 보다 앞서면 하루짜리로 본다.
|
|
11
|
+
*
|
|
12
|
+
* 여러 날에 걸친 일정은 칸 경계를 넘어 **하나의 막대로 이어져** 그려진다. 주 경계에서는 줄이
|
|
13
|
+
* 바뀌므로 조각이 나뉘고, 그렇게 잘린 쪽 모서리는 평평해져 "앞/뒤로 이어진다" 가 읽힌다.
|
|
14
|
+
*
|
|
15
|
+
* 막대가 걸친 날은 **모두** 그 일정을 가진 날로 친다 — 목록 판과 `onValueChange` 에 함께 온다.
|
|
16
|
+
*/
|
|
17
|
+
endDate?: string;
|
|
9
18
|
/**
|
|
10
19
|
* 강조 레이블 (필수) — 예: `"[입고 예정]"`.
|
|
11
20
|
* 일정이 무엇인지 한눈에 알리는 부분이라 비워 두지 않는다.
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
| `loadingRecommendedItems?` | `boolean` | `false` | |
|
|
28
28
|
| `dropdownMinWidth?` | `number \| string` | `200` | 드롭다운 최소 너비 (숫자=px) |
|
|
29
29
|
| `label?` | `string` | — | |
|
|
30
|
+
| `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다). |
|
|
30
31
|
| `labelWidth?` | `number \| string` | — | |
|
|
31
32
|
| `hint?` | `string` | — | |
|
|
32
33
|
| `errorMessage?` | `string` | — | |
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type CSSProperties } from 'react';
|
|
2
|
-
import { type SFieldSize, type SFieldStatus } from '../SField';
|
|
2
|
+
import { type SFieldSize, type SFieldStatus, type SFieldLabelPosition } from '../SField';
|
|
3
3
|
import { type SIconName } from '../SIcon';
|
|
4
4
|
import { type SColor } from '../../lib/color';
|
|
5
5
|
import { type Rule } from '../../lib/form';
|
|
@@ -48,6 +48,13 @@ export interface SChipInputProps {
|
|
|
48
48
|
/** 드롭다운 최소 너비 (숫자=px) */
|
|
49
49
|
dropdownMinWidth?: number | string;
|
|
50
50
|
label?: string;
|
|
51
|
+
/**
|
|
52
|
+
* 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다).
|
|
53
|
+
*
|
|
54
|
+
* @nodemo SField 에서 내려오는 공통 필드 옵션이다 — 같은 데모를 컨트롤마다 복제하지 않고
|
|
55
|
+
* 대표 컨트롤 `SInput` 과 `SField` 에 한 번 둔다 (scripts/check-docs-coverage.mjs 머리말).
|
|
56
|
+
*/
|
|
57
|
+
labelPosition?: SFieldLabelPosition;
|
|
51
58
|
labelWidth?: number | string;
|
|
52
59
|
hint?: string;
|
|
53
60
|
errorMessage?: string;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# SContextAlert
|
|
2
|
+
|
|
3
|
+
> 자동 생성 문서 — `npm run docs:gen`. 소스: 각 컴포넌트의 Props/Handle 인터페이스 + import 의존성.
|
|
4
|
+
|
|
5
|
+
### SContextAlert
|
|
6
|
+
|
|
7
|
+
#### Props
|
|
8
|
+
|
|
9
|
+
| Prop | Type | Default | Description |
|
|
10
|
+
|------|------|---------|-------------|
|
|
11
|
+
| `intent?` | `SContextAlertIntent` | `'default'` | 알림의 성격 — 면과 테두리 색이 바뀐다. 아이콘과 본문색은 인텐트와 무관하게 같다. `default` 안내 · `danger` 오류 · `warning` 주의 · `success` 완료 · `accent` 강조 · `discovery` 새 기능 |
|
|
12
|
+
| `messages?` | `string[]` | `[]` | 본문. 각 문자열이 한 줄이 되고, 인라인 HTML(`<b>` · `<a>` 등)을 허용한다 — `sanitizeInlineHtml` 로 살균한 뒤 렌더하므로 스크립트·위험 스킴은 제거된다. |
|
|
13
|
+
| `icon?` | `SIconName` | `CONTEXT_ALERT_DEFAULT_ICON` | 왼쪽 아이콘. 시안은 인텐트와 무관하게 원 안 느낌표 하나를 쓴다 |
|
|
14
|
+
| `action?` | `ReactNode` | — | 오른쪽에 붙는 후속 동작. **`SButton size="xs"` 를 넣는다** — 그 높이(24px)가 곧 이 상자의 콘텐츠 높이라 시안의 40px 가 그대로 나온다. 더 큰 버튼을 넣으면 상자가 그만큼 세로로 늘어난다. |
|
|
15
|
+
| `className?` | `string` | — | |
|
|
16
|
+
| `style?` | `CSSProperties` | — | |
|
|
17
|
+
|
|
18
|
+
## Types
|
|
19
|
+
|
|
20
|
+
### SContextAlertIntent
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
export type SContextAlertIntent = (typeof CONTEXT_ALERT_INTENTS)[number];
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### CONTEXT_ALERT_INTENTS
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
export const CONTEXT_ALERT_INTENTS = [
|
|
30
|
+
'default',
|
|
31
|
+
'danger',
|
|
32
|
+
'warning',
|
|
33
|
+
'success',
|
|
34
|
+
'accent',
|
|
35
|
+
'discovery',
|
|
36
|
+
] as const;
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Dependencies
|
|
40
|
+
|
|
41
|
+
### Depends on
|
|
42
|
+
|
|
43
|
+
- [SIcon](../SIcon)
|
|
44
|
+
|
|
45
|
+
### Graph
|
|
46
|
+
|
|
47
|
+
```mermaid
|
|
48
|
+
graph TD;
|
|
49
|
+
SContextAlert --> SIcon
|
|
50
|
+
style SContextAlert fill:#f9f,stroke:#333,stroke-width:4px
|
|
51
|
+
```
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type CSSProperties, type ReactNode } from 'react';
|
|
2
|
+
import { type SIconName } from '../SIcon';
|
|
3
|
+
import { type SContextAlertIntent } from './contextAlert.config';
|
|
4
|
+
export interface SContextAlertProps {
|
|
5
|
+
/**
|
|
6
|
+
* 알림의 성격 — 면과 테두리 색이 바뀐다. 아이콘과 본문색은 인텐트와 무관하게 같다.
|
|
7
|
+
*
|
|
8
|
+
* `default` 안내 · `danger` 오류 · `warning` 주의 · `success` 완료 · `accent` 강조 · `discovery` 새 기능
|
|
9
|
+
*/
|
|
10
|
+
intent?: SContextAlertIntent;
|
|
11
|
+
/**
|
|
12
|
+
* 본문. 각 문자열이 한 줄이 되고, 인라인 HTML(`<b>` · `<a>` 등)을 허용한다 —
|
|
13
|
+
* `sanitizeInlineHtml` 로 살균한 뒤 렌더하므로 스크립트·위험 스킴은 제거된다.
|
|
14
|
+
*/
|
|
15
|
+
messages?: string[];
|
|
16
|
+
/** 왼쪽 아이콘. 시안은 인텐트와 무관하게 원 안 느낌표 하나를 쓴다 */
|
|
17
|
+
icon?: SIconName;
|
|
18
|
+
/**
|
|
19
|
+
* 오른쪽에 붙는 후속 동작.
|
|
20
|
+
*
|
|
21
|
+
* **`SButton size="xs"` 를 넣는다** — 그 높이(24px)가 곧 이 상자의 콘텐츠 높이라 시안의
|
|
22
|
+
* 40px 가 그대로 나온다. 더 큰 버튼을 넣으면 상자가 그만큼 세로로 늘어난다.
|
|
23
|
+
*/
|
|
24
|
+
action?: ReactNode;
|
|
25
|
+
className?: string;
|
|
26
|
+
style?: CSSProperties;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* SContextAlert — 한 줄짜리 맥락 알림.
|
|
30
|
+
*
|
|
31
|
+
* 화면의 특정 자리에 붙어 "지금 이 맥락에서 알아야 할 것"을 한 줄로 알리고, 필요하면
|
|
32
|
+
* 오른쪽에 후속 동작 버튼을 둔다. 여러 줄 목록으로 안내를 쌓는 자리는 `SCallout` 이다
|
|
33
|
+
* (AGENTS.md §3-2) — 두 컴포넌트는 면·테두리·패딩 토큰이 같고 **무엇을 담는지**가 다르다.
|
|
34
|
+
*
|
|
35
|
+
* 색은 `--cmp-contextAlert-*` 토큰이 정한다. 아이콘 색만 전용 토큰이 없어 시스템 토큰을
|
|
36
|
+
* 빌려 쓴다(`contextAlert.config.ts` 참고).
|
|
37
|
+
*/
|
|
38
|
+
export declare const SContextAlert: import("react").ForwardRefExoticComponent<SContextAlertProps & import("react").RefAttributes<HTMLDivElement>>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { SIconName } from '../SIcon';
|
|
2
|
+
export declare const CONTEXT_ALERT_INTENTS: readonly ["default", "danger", "warning", "success", "accent", "discovery"];
|
|
3
|
+
export type SContextAlertIntent = (typeof CONTEXT_ALERT_INTENTS)[number];
|
|
4
|
+
/**
|
|
5
|
+
* 인텐트별 표면 — 배경·테두리.
|
|
6
|
+
*
|
|
7
|
+
* `--cmp-contextAlert-<intent>-*` 로 이름을 조립하지 않고 표로 둔다. 조립하면 어떤 인텐트가
|
|
8
|
+
* 실제로 토큰을 갖고 있는지가 코드에서 사라지고, `check:refs` 도 접두어 존재만 확인하게 된다.
|
|
9
|
+
*
|
|
10
|
+
* **본문색은 여기 없다** — 전 인텐트 공통(`--cmp-contextAlert-content`)이라 컴포넌트가 직접 쓴다.
|
|
11
|
+
*/
|
|
12
|
+
export declare const CONTEXT_ALERT_SURFACE: Record<SContextAlertIntent, {
|
|
13
|
+
bg: string;
|
|
14
|
+
border: string;
|
|
15
|
+
}>;
|
|
16
|
+
/**
|
|
17
|
+
* 기본 아이콘 — 원 안 느낌표.
|
|
18
|
+
*
|
|
19
|
+
* 시안은 인텐트 6종 모두 같은 글리프를 쓴다. 인텐트마다 아이콘을 바꾸는 매핑은 없다.
|
|
20
|
+
*/
|
|
21
|
+
export declare const CONTEXT_ALERT_DEFAULT_ICON: SIconName;
|
|
22
|
+
/**
|
|
23
|
+
* 아이콘 색 — 본문(`--cmp-contextAlert-content`)보다 한 단계 옅다.
|
|
24
|
+
*
|
|
25
|
+
* ⚠️ contextAlert 토큰 그룹에 아이콘 **색**이 없다(크기만 있다). 시안의 값과 같은 시스템
|
|
26
|
+
* 토큰을 빌려 쓴다 — 디자인팀이 전용 토큰을 내면 이 한 줄을 그것으로 갈아끼운다
|
|
27
|
+
* (토큰 키는 만들지 않는다). `SCallout` 의 `white` 타입이 같은 방식으로 버티고 있다.
|
|
28
|
+
*/
|
|
29
|
+
export declare const CONTEXT_ALERT_ICON_COLOR = "var(--sys-color-fg-tertiary)";
|
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
| `rules?` | `Rule[]` | — | |
|
|
41
41
|
| `status?` | `SFieldStatus` | — | |
|
|
42
42
|
| `label?` | `string` | — | |
|
|
43
|
+
| `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다). |
|
|
43
44
|
| `labelWidth?` | `number \| string` | — | |
|
|
44
45
|
| `icon?` | `SIconName` | — | |
|
|
45
46
|
| `iconColor?` | `SColor` | — | |
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type CSSProperties } from 'react';
|
|
2
|
-
import { type SFieldSize, type SFieldAddonAlign, type SFieldStatus } from '../SField';
|
|
2
|
+
import { type SFieldSize, type SFieldAddonAlign, type SFieldStatus, type SFieldLabelPosition } from '../SField';
|
|
3
3
|
import { type SIconName } from '../SIcon';
|
|
4
4
|
import { type SColor } from '../../lib/color';
|
|
5
5
|
import { type Rule } from '../../lib/form';
|
|
@@ -51,6 +51,13 @@ export interface SDatePickerProps {
|
|
|
51
51
|
rules?: Rule[];
|
|
52
52
|
status?: SFieldStatus;
|
|
53
53
|
label?: string;
|
|
54
|
+
/**
|
|
55
|
+
* 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다).
|
|
56
|
+
*
|
|
57
|
+
* @nodemo SField 에서 내려오는 공통 필드 옵션이다 — 같은 데모를 컨트롤마다 복제하지 않고
|
|
58
|
+
* 대표 컨트롤 `SInput` 과 `SField` 에 한 번 둔다 (scripts/check-docs-coverage.mjs 머리말).
|
|
59
|
+
*/
|
|
60
|
+
labelPosition?: SFieldLabelPosition;
|
|
54
61
|
labelWidth?: number | string;
|
|
55
62
|
icon?: SIconName;
|
|
56
63
|
iconColor?: SColor;
|
|
@@ -95,4 +102,4 @@ export interface SDatePickerMonthListboxProps {
|
|
|
95
102
|
* 자체 트리거/팝오버 없이 연도+월 리스트만 필요한 커스텀 조합에 재사용한다. */
|
|
96
103
|
export declare function SDatePickerMonthListbox({ value, anchorYear, selectable, onValueChange, onMonthSelect, className, style, }: SDatePickerMonthListboxProps): import("react").JSX.Element;
|
|
97
104
|
/** SDatePicker — sd-date-picker 포팅. SField + SPopover(SCalendar). */
|
|
98
|
-
export declare function SDatePicker({ value, onValueChange, onViewChange, mode, size, placeholder, selectable, disabled, clearable, width, maxWidth, name, rules, status, label, labelWidth, icon, iconColor, labelTooltip, labelTooltipProps, addonLabel, addonAlign, hint, error, errorMessage, className, style, }: SDatePickerProps): import("react").JSX.Element;
|
|
105
|
+
export declare function SDatePicker({ value, onValueChange, onViewChange, mode, size, placeholder, selectable, disabled, clearable, width, maxWidth, name, rules, status, label, labelPosition, labelWidth, icon, iconColor, labelTooltip, labelTooltipProps, addonLabel, addonAlign, hint, error, errorMessage, className, style, }: SDatePickerProps): import("react").JSX.Element;
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
| `rules?` | `Rule[]` | — | |
|
|
23
23
|
| `status?` | `SFieldStatus` | — | |
|
|
24
24
|
| `label?` | `string` | — | |
|
|
25
|
+
| `labelPosition?` | `SFieldLabelPosition` | — | 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다). |
|
|
25
26
|
| `labelWidth?` | `number \| string` | — | |
|
|
26
27
|
| `icon?` | `SIconName` | — | |
|
|
27
28
|
| `iconColor?` | `SColor` | — | |
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type CSSProperties } from 'react';
|
|
2
|
-
import { type SFieldSize, type SFieldAddonAlign, type SFieldStatus } from '../SField';
|
|
2
|
+
import { type SFieldSize, type SFieldAddonAlign, type SFieldStatus, type SFieldLabelPosition } from '../SField';
|
|
3
3
|
import { type SIconName } from '../SIcon';
|
|
4
4
|
import { type SColor } from '../../lib/color';
|
|
5
5
|
import { type Rule } from '../../lib/form';
|
|
@@ -54,6 +54,13 @@ export interface SDateRangePickerProps {
|
|
|
54
54
|
rules?: Rule[];
|
|
55
55
|
status?: SFieldStatus;
|
|
56
56
|
label?: string;
|
|
57
|
+
/**
|
|
58
|
+
* 레이블 위치 — `top` 이면 라벨이 컨트롤 위에 선다 (SField 로 그대로 넘어간다).
|
|
59
|
+
*
|
|
60
|
+
* @nodemo SField 에서 내려오는 공통 필드 옵션이다 — 같은 데모를 컨트롤마다 복제하지 않고
|
|
61
|
+
* 대표 컨트롤 `SInput` 과 `SField` 에 한 번 둔다 (scripts/check-docs-coverage.mjs 머리말).
|
|
62
|
+
*/
|
|
63
|
+
labelPosition?: SFieldLabelPosition;
|
|
57
64
|
labelWidth?: number | string;
|
|
58
65
|
icon?: SIconName;
|
|
59
66
|
iconColor?: SColor;
|
|
@@ -84,4 +91,4 @@ export interface SRangeCalendarProps {
|
|
|
84
91
|
* 캘린더 그리드만 필요한 커스텀 조합(예: 다른 트리거에 팝오버로 얹는 경우)에 재사용한다. */
|
|
85
92
|
export declare function RangeCalendar({ value, selectable, maxRange, showTimePicker, onSelect, onPendingStartChange, onViewChange, }: SRangeCalendarProps): import("react").JSX.Element;
|
|
86
93
|
/** SDateRangePicker — sd-date-range-picker 포팅. SField + SPopover(범위 캘린더). */
|
|
87
|
-
export declare function SDateRangePicker({ value, onValueChange, onViewChange, size, placeholder, selectable, maxRange, showTimePicker, disabled, clearable, width, maxWidth, name, rules, status, label, labelWidth, icon, iconColor, labelTooltip, labelTooltipProps, addonLabel, addonAlign, hint, error, errorMessage, className, style, }: SDateRangePickerProps): import("react").JSX.Element;
|
|
94
|
+
export declare function SDateRangePicker({ value, onValueChange, onViewChange, size, placeholder, selectable, maxRange, showTimePicker, disabled, clearable, width, maxWidth, name, rules, status, label, labelPosition, labelWidth, icon, iconColor, labelTooltip, labelTooltipProps, addonLabel, addonAlign, hint, error, errorMessage, className, style, }: SDateRangePickerProps): import("react").JSX.Element;
|