@idbrnd/design-system 3.2.0 → 3.3.0

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @idbrnd/design-system
2
2
 
3
- ![Version](https://img.shields.io/badge/version-3.2.0-4B5FE1?style=flat-square)
3
+ ![Version](https://img.shields.io/badge/version-3.3.0-4B5FE1?style=flat-square)
4
4
  ![React](https://img.shields.io/badge/React-18.3.1-61DAFB?style=flat-square&logo=react&logoColor=white)
5
5
  ![Vite](https://img.shields.io/badge/Vite-7.3.0-646CFF?style=flat-square&logo=vite&logoColor=white)
6
6
  ![TypeScript](https://img.shields.io/badge/TypeScript-5.9.3-3178C6?style=flat-square&logo=typescript&logoColor=white)
@@ -40,6 +40,7 @@ export default function App() {
40
40
  - [OutlineButton](#outlinebutton)
41
41
  - [TextButton](#textbutton)
42
42
  - [WeakButton](#weakbutton)
43
+ - [TertiaryButton](#tertiarybutton)
43
44
  - [아이콘 버튼](#아이콘-버튼)
44
45
  - [BasicIconButton](#basiciconbutton)
45
46
  - [FillIconButton](#filliconbutton)
@@ -56,6 +57,7 @@ export default function App() {
56
57
  - [Toast](#toast)
57
58
  - [Snackbar](#snackbar)
58
59
  - [PushBadge](#pushbadge)
60
+ - [EmptyState](#emptystate)
59
61
  - [Tooltip](#tooltip)
60
62
  - [Select](#select)
61
63
  - [Dropdown](#dropdown)
@@ -161,6 +163,35 @@ import { WeakButton } from "@idbrnd/design-system";
161
163
  | `keepFocusOnClick` | `boolean` | `false` | 클릭 후 포커스 유지 |
162
164
  | `customStyle` | `CSSProperties` | — | 추가 인라인 스타일 |
163
165
 
166
+ ### TertiaryButton
167
+
168
+ 아이콘 슬롯을 갖는 보조 버튼입니다. 다른 버튼과 달리 `widthType`이 없고, `leadingIcon` / `trailingIcon`으로 텍스트 앞뒤에 아이콘을 배치할 수 있습니다.
169
+
170
+ ```tsx
171
+ import { TertiaryButton } from "@idbrnd/design-system";
172
+ import { ChevronDownIcon, PlusIcon } from "@idbrnd/design-system";
173
+
174
+ <TertiaryButton variant="fill">확인</TertiaryButton>
175
+ <TertiaryButton variant="primary" leadingIcon={<PlusIcon size={16} />}>추가</TertiaryButton>
176
+ <TertiaryButton variant="gray" size="small" trailingIcon={<ChevronDownIcon size={16} />}>더보기</TertiaryButton>
177
+ ```
178
+
179
+ | Prop | 타입 | 기본값 | 설명 |
180
+ | ------------------ | ----------------------------------------------------- | ---------- | ------------------- |
181
+ | `variant` | `"fill"` \| `"tinted"` \| `"gray"` \| `"primary"` | `"fill"` | 색상 변형 |
182
+ | `size` | `"small"` \| `"medium"` \| `"large"` | `"medium"` | 크기 |
183
+ | `leadingIcon` | `ReactNode` | — | 텍스트 앞 아이콘 |
184
+ | `trailingIcon` | `ReactNode` | — | 텍스트 뒤 아이콘 |
185
+ | `loading` | `boolean` | `false` | 로딩 스피너 표시 |
186
+ | `disabled` | `boolean` | `false` | 비활성화 |
187
+ | `keepFocusOnClick` | `boolean` | `false` | 클릭 후 포커스 유지 |
188
+ | `customStyle` | `CSSProperties` | — | 추가 인라인 스타일 |
189
+
190
+ 유의사항:
191
+
192
+ - `loading` 중에는 아이콘과 children 대신 스피너만 표시되며 클릭이 동작하지 않습니다.
193
+ - 다른 버튼들과 달리 `widthType`이 없어 항상 콘텐츠 크기를 따릅니다.
194
+
164
195
  ---
165
196
 
166
197
  ## 아이콘 버튼
@@ -645,6 +676,64 @@ import { PushBadge } from "@idbrnd/design-system";
645
676
  | `maxCount` | `number` | `999` | `count`가 초과하면 `{maxCount}+`로 표시 |
646
677
  | `customStyle` | `CSSProperties` | — | 추가 인라인 스타일 |
647
678
 
679
+ ### EmptyState
680
+
681
+ 사용자가 특정 페이지에 처음 접속했을 때나 표시할 수 있는 데이터가 없을 때 노출하는 컴포넌트입니다.
682
+
683
+ ```tsx
684
+ import { EmptyState, FillButton } from "@idbrnd/design-system";
685
+ import { FolderIcon } from "@idbrnd/design-system";
686
+
687
+ <EmptyState
688
+ size="medium"
689
+ visualContent={<FolderIcon size={36} />}
690
+ headingContent="등록된 프로젝트가 없습니다."
691
+ descriptionContent={"첫 번째 프로젝트를 생성하고\n모니터링을 시작해 보세요."}
692
+ buttonContent={
693
+ <FillButton variant="primary" size="xsmall">
694
+ 프로젝트 생성
695
+ </FillButton>
696
+ }
697
+ />;
698
+ ```
699
+
700
+ **텍스트만 사용 (위젯·테이블 내부)**
701
+
702
+ ```tsx
703
+ <EmptyState
704
+ size="small"
705
+ headingContent="검색 결과가 없습니다."
706
+ descriptionContent="다른 키워드로 다시 검색해 보세요."
707
+ />
708
+ ```
709
+
710
+ | Prop | 타입 | 기본값 | 설명 |
711
+ | -------------------- | -------------------------------------- | --------- | --------------------------------------------------------------- |
712
+ | `size` | `"large"` \| `"medium"` \| `"small"` | `"small"` | 배치 구역의 크기·위계에 따른 사이즈 |
713
+ | `visualContent` | `ReactNode` | — | 상단 시각 요소. 일러스트·아이콘·이미지·임의 컴포넌트 모두 가능 |
714
+ | `headingContent` | `ReactNode` | — | 타이틀. 상황을 짧게 요약하며 단일 행 권장 |
715
+ | `descriptionContent` | `ReactNode` | — | 설명. 개행(`\n`)이 그대로 반영되며 줄 수 제한 없음 |
716
+ | `buttonContent` | `ReactNode` | — | CTA 버튼 슬롯 |
717
+ | `customStyle` | `CSSProperties` | — | 루트에 적용할 추가 인라인 스타일 |
718
+ | `className` | `string` | — | 루트에 추가할 클래스명 |
719
+
720
+ **size별 스펙**
721
+
722
+ | | `large` | `medium` | `small` |
723
+ | ---------------- | -------------------------------- | -------------------------------- | --------------------------------- |
724
+ | 시각 요소 슬롯 | 80×80 | 48×48 | 32×32 |
725
+ | 타이틀 | `--text-heading-2-semibold` | `--text-heading-2-semibold` | `--text-body-2-normal-semibold` |
726
+ | 설명 | `--text-body-1-reading-regular` | `--text-body-1-reading-regular` | `--text-label-2-reading-regular` |
727
+ | 권장 버튼 | `FillButton` `assistive`/`small` | `FillButton` `assistive`/`xsmall`| `FillButton` `assistive`/`xsmall` |
728
+
729
+ 유의사항:
730
+
731
+ - **네 슬롯 모두 넘긴 것만 렌더됩니다.** 넘기지 않으면 해당 영역과 인접 간격이 함께 사라지므로, 화면 상황에 맞게 가볍거나 묵직하게 조합할 수 있습니다.
732
+ - 루트는 부모를 채우고(`width`/`height: 100%`) 콘텐츠를 중앙 정렬합니다. 상하 여백은 80px입니다.
733
+ - 전체 화면 단위에는 `size="large"` 또는 `"medium"`에 시각 요소와 버튼을 함께 두어 액션을 유도하고, 카드·테이블 내부에는 `size="small"`로 컴팩트하게 노출하는 것을 권장합니다.
734
+ - 텍스트는 `[상황 설명 + 해결책 제안]` 구조로 작성합니다. 설명은 두 줄 이내를 권장하지만 강제되지는 않습니다.
735
+ - `visualContent`에 넣은 노드는 슬롯 크기에 맞춰 `max-width`/`max-height: 100%`가 적용됩니다.
736
+
648
737
  ### Tooltip
649
738
 
650
739
  트리거 엘리먼트에 마우스를 올리거나 클릭하면 말풍선 형태의 안내 텍스트를 표시하는 컴포넌트입니다. `trigger="always"`로 항상 표시되는 고정 안내 형태로도 사용할 수 있습니다.
@@ -1941,6 +2030,9 @@ import type {
1941
2030
  WeakButtonSize,
1942
2031
  WeakButtonVariant,
1943
2032
  WeakButtonWidthType,
2033
+ TertiaryButtonProps,
2034
+ TertiaryButtonSize,
2035
+ TertiaryButtonVariant,
1944
2036
 
1945
2037
  // IconButton
1946
2038
  BasicIconButtonProps,
@@ -1961,6 +2053,11 @@ import type {
1961
2053
  SearchBarSize,
1962
2054
  SearchBarVariant,
1963
2055
 
2056
+ // Textarea
2057
+ TextareaProps,
2058
+ TextareaSize,
2059
+ TextareaVariant,
2060
+
1964
2061
  // Control
1965
2062
  CheckBoxProps,
1966
2063
  CheckBoxVariant,
@@ -1980,6 +2077,8 @@ import type {
1980
2077
  SnackbarVariant,
1981
2078
  PushBadgeProps,
1982
2079
  PushBadgeVariant,
2080
+ EmptyStateProps,
2081
+ EmptyStateSize,
1983
2082
  ClipProps,
1984
2083
  CustomSpinnerProps,
1985
2084
  FadeSpinnerProps,
@@ -2015,6 +2114,17 @@ import type {
2015
2114
  DropdownType,
2016
2115
  DropdownAlign,
2017
2116
 
2117
+ // Chip
2118
+ ChipProps,
2119
+ ChipVariant,
2120
+ ChipSize,
2121
+ ChipGroupProps,
2122
+ ChipGroupType,
2123
+ ChipGroupSize,
2124
+ FilterChipProps,
2125
+ FilterBarProps,
2126
+ FilterBarSize,
2127
+
2018
2128
  // SegmentedControl
2019
2129
  SegmentedControlProps,
2020
2130
  SegmentedControlVariant,
@@ -0,0 +1,30 @@
1
+ import type { CSSProperties, ReactNode } from 'react';
2
+ export type EmptyStateSize = 'large' | 'medium' | 'small';
3
+ export interface EmptyStateProps {
4
+ /** 배치 구역의 크기·위계에 따른 사이즈 */
5
+ size?: EmptyStateSize;
6
+ /**
7
+ * 상단 시각 요소 슬롯. 일러스트·아이콘·이미지·임의의 컴포넌트를 모두 받는다.
8
+ * 넘기지 않으면 영역 자체를 렌더하지 않는다.
9
+ */
10
+ visualContent?: ReactNode;
11
+ /**
12
+ * 타이틀. 상황을 짧게 요약하며 단일 행을 권장한다.
13
+ * 넘기지 않으면 영역 자체를 렌더하지 않는다.
14
+ */
15
+ headingContent?: ReactNode;
16
+ /**
17
+ * 설명. 개행(`\n`)이 그대로 반영되며, 줄 수는 제한하지 않는다 (가이드상 두 줄 권장).
18
+ * 넘기지 않으면 영역 자체를 렌더하지 않는다.
19
+ */
20
+ descriptionContent?: ReactNode;
21
+ /**
22
+ * CTA 버튼 슬롯. 소비처가 원하는 버튼 컴포넌트를 직접 넣는다.
23
+ * 넘기지 않으면 영역 자체를 렌더하지 않는다.
24
+ */
25
+ buttonContent?: ReactNode;
26
+ customStyle?: CSSProperties;
27
+ className?: string;
28
+ }
29
+ declare function EmptyState({ size, visualContent, headingContent, descriptionContent, buttonContent, customStyle, className }: EmptyStateProps): import("react/jsx-runtime").JSX.Element;
30
+ export default EmptyState;
package/dist/index.d.ts CHANGED
@@ -28,10 +28,12 @@ export { default as ToggleSwitch } from "./components/Control/ToggleSwitch/Toggl
28
28
  export type { CheckBoxProps, CheckBoxVariant, CheckBoxSize, CheckBoxDensity, } from "./components/Control/CheckBox/CheckBox";
29
29
  export type { RadioProps, RadioVariant, RadioSize, RadioDensity, } from "./components/Control/Radio/Radio";
30
30
  export type { ToggleSwitchProps, ToggleSwitchSize, } from "./components/Control/ToggleSwitch/ToggleSwitch";
31
+ export { default as EmptyState } from "./components/Feedback/EmptyState/EmptyState";
31
32
  export { default as PushBadge } from "./components/Feedback/PushBadge/PushBadge";
32
33
  export { dismissToast, showToast } from "./components/Feedback/Toast/Toast";
33
34
  export { dismissSnackbar, showSnackbar, } from "./components/Feedback/Snackbar/Snackbar";
34
35
  export { default as Spinner, Clip, CustomSpinner, FadeSpinner, } from "./components/Spinner/Spinner";
36
+ export type { EmptyStateProps, EmptyStateSize, } from "./components/Feedback/EmptyState/EmptyState";
35
37
  export type { PushBadgeProps, PushBadgeVariant, } from "./components/Feedback/PushBadge/PushBadge";
36
38
  export type { ToastShowOptions, ToastVariant, } from "./components/Feedback/Toast/Toast";
37
39
  export type { SnackbarShowOptions, SnackbarVariant, } from "./components/Feedback/Snackbar/Snackbar";