@idbrnd/design-system 1.0.1 → 1.1.1

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
@@ -9,6 +9,7 @@ npm install @idbrnd/design-system
9
9
  ```
10
10
 
11
11
  `peerDependencies`
12
+
12
13
  - `react@^18.3.1`
13
14
  - `react-dom@^18.3.1`
14
15
 
@@ -17,8 +18,8 @@ npm install @idbrnd/design-system
17
18
  엔트리 파일(예: `src/main.tsx`)에서 스타일을 먼저 로드한 뒤 컴포넌트를 사용합니다.
18
19
 
19
20
  ```tsx
20
- import '@idbrnd/design-system/style.css';
21
- import { FillButton } from '@idbrnd/design-system';
21
+ import "@idbrnd/design-system/style.css";
22
+ import { FillButton } from "@idbrnd/design-system";
22
23
 
23
24
  export default function App() {
24
25
  return <FillButton>확인</FillButton>;
@@ -38,6 +39,10 @@ export default function App() {
38
39
  - 입력
39
40
  - `Input`
40
41
  - `SearchBar`
42
+ - 컨트롤
43
+ - `CheckBox`
44
+ - `Radio`
45
+ - `ToggleSwitch`
41
46
  - 피드백
42
47
  - `showToast`, `dismissToast`
43
48
  - `showSnackbar`, `dismissSnackbar`
@@ -54,16 +59,20 @@ import {
54
59
  FillButton,
55
60
  OutlineButton,
56
61
  TextButton,
57
- WeakButton
58
- } from '@idbrnd/design-system';
62
+ WeakButton,
63
+ } from "@idbrnd/design-system";
59
64
 
60
65
  function ButtonExample() {
61
66
  return (
62
67
  <>
63
68
  <FillButton variant="primary">저장</FillButton>
64
69
  <OutlineButton variant="secondary">취소</OutlineButton>
65
- <TextButton size="small" variant="assistive">텍스트 버튼</TextButton>
66
- <WeakButton size="xsmall" variant="error">삭제</WeakButton>
70
+ <TextButton size="small" variant="assistive">
71
+ 텍스트 버튼
72
+ </TextButton>
73
+ <WeakButton size="xsmall" variant="error">
74
+ 삭제
75
+ </WeakButton>
67
76
  </>
68
77
  );
69
78
  }
@@ -76,13 +85,13 @@ import {
76
85
  BasicIconButton,
77
86
  FillIconButton,
78
87
  OutlineIconButton,
79
- PushBadge
80
- } from '@idbrnd/design-system';
88
+ PushBadge,
89
+ } from "@idbrnd/design-system";
81
90
 
82
91
  function IconButtonExample() {
83
92
  return (
84
93
  <>
85
- <div style={{ position: 'relative', width: 'fit-content' }}>
94
+ <div style={{ position: "relative", width: "fit-content" }}>
86
95
  <BasicIconButton>+</BasicIconButton>
87
96
  <PushBadge variant="dot" />
88
97
  </div>
@@ -91,9 +100,7 @@ function IconButtonExample() {
91
100
  +
92
101
  </FillIconButton>
93
102
 
94
- <OutlineIconButton size="medium">
95
- +
96
- </OutlineIconButton>
103
+ <OutlineIconButton size="medium">+</OutlineIconButton>
97
104
  </>
98
105
  );
99
106
  }
@@ -102,7 +109,7 @@ function IconButtonExample() {
102
109
  `PushBadge` 단독 사용:
103
110
 
104
111
  ```tsx
105
- import { PushBadge } from '@idbrnd/design-system';
112
+ import { PushBadge } from "@idbrnd/design-system";
106
113
 
107
114
  function PushBadgeExample() {
108
115
  return (
@@ -120,11 +127,11 @@ function PushBadgeExample() {
120
127
  `Input`은 `value` + `onChange`를 받는 controlled 컴포넌트입니다.
121
128
 
122
129
  ```tsx
123
- import { useState } from 'react';
124
- import { Input } from '@idbrnd/design-system';
130
+ import { useState } from "react";
131
+ import { Input } from "@idbrnd/design-system";
125
132
 
126
133
  function InputExample() {
127
- const [email, setEmail] = useState('');
134
+ const [email, setEmail] = useState("");
128
135
 
129
136
  return (
130
137
  <Input
@@ -154,18 +161,18 @@ function InputExample() {
154
161
  `variant="default"`는 내부 `Input`의 `basic`에 매핑되며, `onTyping`/`typed`/`error`도 각각 대응됩니다.
155
162
 
156
163
  ```tsx
157
- import { useState } from 'react';
158
- import { SearchBar } from '@idbrnd/design-system';
164
+ import { useState } from "react";
165
+ import { SearchBar } from "@idbrnd/design-system";
159
166
 
160
167
  function SearchExample() {
161
- const [keyword, setKeyword] = useState('');
168
+ const [keyword, setKeyword] = useState("");
162
169
 
163
170
  return (
164
171
  <SearchBar
165
172
  value={keyword}
166
173
  onChange={(event) => setKeyword(event.target.value)}
167
174
  onSearch={(value) => {
168
- console.log('search:', value);
175
+ console.log("search:", value);
169
176
  }}
170
177
  placeholder="검색어를 입력하세요"
171
178
  />
@@ -173,19 +180,130 @@ function SearchExample() {
173
180
  }
174
181
  ```
175
182
 
176
- ### 5. Spinner
183
+ ### 5. CheckBox
184
+
185
+ `CheckBox`는 `checked` + `onChange`를 받는 controlled 컴포넌트입니다.
186
+ `indeterminate`는 `checked={true}`와 함께 사용하면 체크 아이콘 대신 대시(–) 아이콘을 표시합니다.
187
+
188
+ ```tsx
189
+ import { useState } from "react";
190
+ import { CheckBox } from "@idbrnd/design-system";
191
+
192
+ function CheckBoxExample() {
193
+ const [checked, setChecked] = useState(false);
194
+ const [indeterminate, setIndeterminate] = useState(false);
195
+
196
+ return (
197
+ <>
198
+ {/* 기본 */}
199
+ <CheckBox checked={checked} onChange={(value) => setChecked(value)} />
200
+
201
+ {/* indeterminate: checked와 함께 사용 */}
202
+ <CheckBox
203
+ checked={indeterminate}
204
+ indeterminate={indeterminate}
205
+ onChange={(value) => setIndeterminate(value)}
206
+ />
207
+
208
+ {/* variant / size / density */}
209
+ <CheckBox variant="assistive" size="small" density="compact" checked />
210
+
211
+ {/* disabled */}
212
+ <CheckBox checked disabled />
213
+ </>
214
+ );
215
+ }
216
+ ```
217
+
218
+ 유의사항:
219
+
220
+ - `indeterminate={true}`는 `checked={true}`일 때만 대시 아이콘을 표시합니다. `checked={false}`이면 빈 박스로 표시됩니다.
221
+ - `variant`는 `"primary"(기본값)` | `"assistive"`를 지원합니다.
222
+ - `density="compact"`은 wrapper 크기만 줄이며, 아이콘은 box width에 맞춰 `size` 기준으로 그대로 표시됩니다.
223
+
224
+ ### 6. Radio
225
+
226
+ `Radio`는 그룹 내 단일 선택을 위한 controlled 컴포넌트입니다.
227
+ 브라우저 기본 `name` 그룹 동작에 의존하지 않으며, `checked` prop으로 직접 선택 상태를 제어합니다.
228
+
229
+ ```tsx
230
+ import { useState } from "react";
231
+ import { Radio } from "@idbrnd/design-system";
232
+
233
+ function RadioGroupExample() {
234
+ const [selected, setSelected] = useState("");
235
+
236
+ return (
237
+ <>
238
+ {["A", "B", "C"].map((v) => (
239
+ <label
240
+ key={v}
241
+ style={{ display: "flex", alignItems: "center", gap: 6 }}
242
+ >
243
+ <Radio
244
+ name="group"
245
+ value={v}
246
+ checked={selected === v}
247
+ onChange={(isChecked) => isChecked && setSelected(v)}
248
+ />
249
+ Option {v}
250
+ </label>
251
+ ))}
252
+ </>
253
+ );
254
+ }
255
+ ```
256
+
257
+ 유의사항:
258
+
259
+ - `name`이 같아도 자동으로 하나만 선택되지 않습니다. `checked={selected === value}` 비교로 직접 제어해야 합니다.
260
+ - `onChange`는 `(checked: boolean) => void` 시그니처이며, 클릭 시 `true`가 전달됩니다. `isChecked && setSelected(v)` 패턴으로 true일 때만 state를 변경합니다.
261
+ - `variant`는 `"primary"(기본값)` | `"assistive"`를 지원합니다.
262
+
263
+ ### 7. ToggleSwitch
264
+
265
+ `ToggleSwitch`는 `active` + `onChange`를 받는 controlled 컴포넌트입니다.
266
+
267
+ ```tsx
268
+ import { useState } from "react";
269
+ import { ToggleSwitch } from "@idbrnd/design-system";
270
+
271
+ function ToggleSwitchExample() {
272
+ const [active, setActive] = useState(false);
273
+
274
+ return (
275
+ <>
276
+ <ToggleSwitch active={active} onChange={(value) => setActive(value)} />
277
+
278
+ {/* size */}
279
+ <ToggleSwitch size="small" active={active} onChange={setActive} />
280
+ <ToggleSwitch size="large" active={active} onChange={setActive} />
281
+
282
+ {/* disabled */}
283
+ <ToggleSwitch active disabled />
284
+ </>
285
+ );
286
+ }
287
+ ```
288
+
289
+ 유의사항:
290
+
291
+ - 체크 상태를 나타내는 prop 이름이 `checked`가 아닌 `active`입니다.
292
+ - `size`는 `"small"` | `"medium"(기본값)` | `"large"`를 지원합니다.
293
+
294
+ ### 9. Spinner
177
295
 
178
296
  ```tsx
179
297
  import {
180
298
  Spinner,
181
299
  CustomSpinner,
182
300
  Clip,
183
- FadeSpinner
184
- } from '@idbrnd/design-system';
301
+ FadeSpinner,
302
+ } from "@idbrnd/design-system";
185
303
 
186
304
  function SpinnerExample() {
187
305
  return (
188
- <div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>
306
+ <div style={{ display: "flex", gap: "12px", alignItems: "center" }}>
189
307
  <Spinner />
190
308
  <CustomSpinner size={12} />
191
309
  <Clip size={24} color="var(--semantic-primary-default)" />
@@ -195,14 +313,10 @@ function SpinnerExample() {
195
313
  }
196
314
  ```
197
315
 
198
- ### 6. Toast
316
+ ### 10. Toast
199
317
 
200
318
  ```tsx
201
- import {
202
- FillButton,
203
- showToast,
204
- dismissToast
205
- } from '@idbrnd/design-system';
319
+ import { FillButton, showToast, dismissToast } from "@idbrnd/design-system";
206
320
 
207
321
  function ToastExample() {
208
322
  return (
@@ -210,8 +324,8 @@ function ToastExample() {
210
324
  <FillButton
211
325
  onClick={() =>
212
326
  showToast({
213
- variant: 'positive',
214
- message: '저장되었습니다.'
327
+ variant: "positive",
328
+ message: "저장되었습니다.",
215
329
  })
216
330
  }
217
331
  >
@@ -226,14 +340,14 @@ function ToastExample() {
226
340
  }
227
341
  ```
228
342
 
229
- ### 7. Snackbar
343
+ ### 11. Snackbar
230
344
 
231
345
  ```tsx
232
346
  import {
233
347
  FillButton,
234
348
  showSnackbar,
235
- dismissSnackbar
236
- } from '@idbrnd/design-system';
349
+ dismissSnackbar,
350
+ } from "@idbrnd/design-system";
237
351
 
238
352
  function SnackbarExample() {
239
353
  return (
@@ -241,12 +355,12 @@ function SnackbarExample() {
241
355
  <FillButton
242
356
  onClick={() =>
243
357
  showSnackbar({
244
- variant: 'basic',
245
- heading: 'Message deleted.',
246
- description: 'You can undo this action.',
247
- actionLabel: '실행 취소',
248
- onActionClick: () => console.log('undo'),
249
- closeButton: true
358
+ variant: "basic",
359
+ heading: "Message deleted.",
360
+ description: "You can undo this action.",
361
+ actionLabel: "실행 취소",
362
+ onActionClick: () => console.log("undo"),
363
+ closeButton: true,
250
364
  })
251
365
  }
252
366
  >
@@ -266,11 +380,27 @@ function SnackbarExample() {
266
380
  모든 컴포넌트의 Props 타입을 패키지에서 직접 import 할 수 있습니다.
267
381
 
268
382
  ```tsx
269
- import type { FillButtonProps, InputProps, ToastShowOptions } from '@idbrnd/design-system';
383
+ import type {
384
+ FillButtonProps,
385
+ InputProps,
386
+ CheckBoxProps,
387
+ CheckBoxVariant,
388
+ CheckBoxSize,
389
+ CheckBoxDensity,
390
+ RadioProps,
391
+ RadioVariant,
392
+ RadioSize,
393
+ RadioDensity,
394
+ ToggleSwitchProps,
395
+ ToggleSwitchSize,
396
+ ToastShowOptions,
397
+ } from "@idbrnd/design-system";
270
398
  ```
271
399
 
272
400
  ## 주의사항
273
401
 
274
- - `Input`, `SearchBar`는 controlled 방식으로 사용해야 합니다.
402
+ - `Input`, `SearchBar`, `CheckBox`, `Radio`, `ToggleSwitch`는 controlled 방식으로 사용해야 합니다.
403
+ - `Radio`는 `name` prop만으로 단일 선택이 보장되지 않습니다. `checked={selected === value}` 비교로 직접 제어해야 합니다.
404
+ - `CheckBox`의 `indeterminate={true}`는 `checked={true}`와 함께 사용해야 대시 아이콘이 표시됩니다.
275
405
  - `showToast`, `showSnackbar`는 내부적으로 `document.body`에 포털을 생성하므로 브라우저 환경에서 호출해야 합니다.
276
406
  - CSS 변수/타이포그래피를 포함한 스타일을 위해 `@idbrnd/design-system/style.css` import를 권장합니다.
@@ -0,0 +1,15 @@
1
+ import { type CSSProperties, type InputHTMLAttributes } from "react";
2
+ export type CheckBoxVariant = "primary" | "assistive";
3
+ export type CheckBoxSize = "medium" | "small";
4
+ export type CheckBoxDensity = "default" | "compact";
5
+ export interface CheckBoxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "style" | "size" | "type" | "checked" | "defaultChecked" | "onChange"> {
6
+ variant?: CheckBoxVariant;
7
+ size?: CheckBoxSize;
8
+ density?: CheckBoxDensity;
9
+ customStyle?: CSSProperties;
10
+ checked?: boolean;
11
+ indeterminate?: boolean;
12
+ onChange?: (checked: boolean) => void;
13
+ }
14
+ declare function CheckBox({ variant, size, density, disabled, customStyle, className, checked, indeterminate, onChange, ...rest }: CheckBoxProps): import("react/jsx-runtime").JSX.Element;
15
+ export default CheckBox;
@@ -0,0 +1,13 @@
1
+ import { type CSSProperties, type InputHTMLAttributes } from "react";
2
+ export type RadioVariant = "primary" | "assistive";
3
+ export type RadioSize = "medium" | "small";
4
+ export type RadioDensity = "default" | "compact";
5
+ export interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "style" | "size" | "type" | "onChange"> {
6
+ variant?: RadioVariant;
7
+ size?: RadioSize;
8
+ density?: RadioDensity;
9
+ customStyle?: CSSProperties;
10
+ onChange?: (checked: boolean) => void;
11
+ }
12
+ declare function Radio({ variant, size, density, disabled, checked, customStyle, className, onChange, ...rest }: RadioProps): import("react/jsx-runtime").JSX.Element;
13
+ export default Radio;
@@ -0,0 +1,10 @@
1
+ import { type CSSProperties, type InputHTMLAttributes } from "react";
2
+ export type ToggleSwitchSize = "small" | "medium" | "large";
3
+ export interface ToggleSwitchProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "style" | "size" | "type" | "checked" | "defaultChecked" | "onChange"> {
4
+ size?: ToggleSwitchSize;
5
+ active?: boolean;
6
+ customStyle?: CSSProperties;
7
+ onChange?: (active: boolean) => void;
8
+ }
9
+ declare function ToggleSwitch({ size, active, disabled, customStyle, className, onChange, ...rest }: ToggleSwitchProps): import("react/jsx-runtime").JSX.Element;
10
+ export default ToggleSwitch;
package/dist/index.d.ts CHANGED
@@ -1,28 +1,34 @@
1
- import './styles/variables.css';
2
- import './styles/font-metrics.css';
3
- export { default as BasicIconButton } from './components/Button/BasicIcon/BasicIconButton';
4
- export { default as FillButton } from './components/Button/Fill/FillButton';
5
- export { default as FillIconButton } from './components/Button/FillIcon/FillIconButton';
6
- export { default as Input } from './components/Input/Input';
7
- export { default as OutlineButton } from './components/Button/Outline/OutlineButton';
8
- export { default as OutlineIconButton } from './components/Button/OutlineIcon/OutlineIconButton';
9
- export { default as PushBadge } from './components/PushBadge/PushBadge';
10
- export { default as SearchBar } from './components/SearchBar/SearchBar';
11
- export { dismissSnackbar, showSnackbar } from './components/Snackbar/Snackbar';
12
- export { default as Spinner, Clip, CustomSpinner, FadeSpinner } from './components/Spinner/Spinner';
13
- export { dismissToast, showToast } from './components/Toast/Toast';
14
- export { default as TextButton } from './components/Button/Text/TextButton';
15
- export { default as WeakButton } from './components/Button/Weak/WeakButton';
16
- export type { BasicIconButtonProps, BasicIconButtonSize } from './components/Button/BasicIcon/BasicIconButton';
17
- export type { FillButtonProps, FillButtonSize, FillButtonVariant, FillButtonWidthType } from './components/Button/Fill/FillButton';
18
- export type { FillIconButtonProps, FillIconButtonSize, FillIconButtonVariant } from './components/Button/FillIcon/FillIconButton';
19
- export type { InputProps, InputSize, DesignType, InputVariant } from './components/Input/Input';
20
- export type { PushBadgeProps, PushBadgeVariant } from './components/PushBadge/PushBadge';
21
- export type { SearchBarProps, SearchBarSize, SearchBarVariant } from './components/SearchBar/SearchBar';
22
- export type { SnackbarShowOptions, SnackbarVariant } from './components/Snackbar/Snackbar';
23
- export type { ClipProps, CustomSpinnerProps, FadeSpinnerProps } from './components/Spinner/Spinner';
24
- export type { ToastShowOptions, ToastVariant } from './components/Toast/Toast';
25
- export type { OutlineButtonProps, OutlineButtonSize, OutlineButtonVariant, OutlineButtonWidthType } from './components/Button/Outline/OutlineButton';
26
- export type { OutlineIconButtonProps, OutlineIconButtonSize } from './components/Button/OutlineIcon/OutlineIconButton';
27
- export type { TextButtonProps, TextButtonSize, TextButtonVariant, TextButtonWidthType } from './components/Button/Text/TextButton';
28
- export type { WeakButtonProps, WeakButtonSize, WeakButtonVariant, WeakButtonWidthType } from './components/Button/Weak/WeakButton';
1
+ import "./styles/variables.css";
2
+ import "./styles/font-metrics.css";
3
+ export { default as BasicIconButton } from "./components/Button/BasicIcon/BasicIconButton";
4
+ export { default as FillButton } from "./components/Button/Fill/FillButton";
5
+ export { default as FillIconButton } from "./components/Button/FillIcon/FillIconButton";
6
+ export { default as Input } from "./components/Input/Input";
7
+ export { default as OutlineButton } from "./components/Button/Outline/OutlineButton";
8
+ export { default as OutlineIconButton } from "./components/Button/OutlineIcon/OutlineIconButton";
9
+ export { default as PushBadge } from "./components/Feedback/PushBadge/PushBadge";
10
+ export { default as SearchBar } from "./components/SearchBar/SearchBar";
11
+ export { dismissSnackbar, showSnackbar } from "./components/Feedback/Snackbar/Snackbar";
12
+ export { default as Spinner, Clip, CustomSpinner, FadeSpinner, } from "./components/Spinner/Spinner";
13
+ export { dismissToast, showToast } from "./components/Feedback/Toast/Toast";
14
+ export { default as TextButton } from "./components/Button/Text/TextButton";
15
+ export { default as WeakButton } from "./components/Button/Weak/WeakButton";
16
+ export { default as CheckBox } from "./components/Control/CheckBox/CheckBox";
17
+ export { default as Radio } from "./components/Control/Radio/Radio";
18
+ export { default as ToggleSwitch } from "./components/Control/ToggleSwitch/ToggleSwitch";
19
+ export type { BasicIconButtonProps, BasicIconButtonSize, } from "./components/Button/BasicIcon/BasicIconButton";
20
+ export type { FillButtonProps, FillButtonSize, FillButtonVariant, FillButtonWidthType, } from "./components/Button/Fill/FillButton";
21
+ export type { FillIconButtonProps, FillIconButtonSize, FillIconButtonVariant, } from "./components/Button/FillIcon/FillIconButton";
22
+ export type { InputProps, InputSize, DesignType, InputVariant, } from "./components/Input/Input";
23
+ export type { PushBadgeProps, PushBadgeVariant, } from "./components/Feedback/PushBadge/PushBadge";
24
+ export type { SearchBarProps, SearchBarSize, SearchBarVariant, } from "./components/SearchBar/SearchBar";
25
+ export type { SnackbarShowOptions, SnackbarVariant, } from "./components/Feedback/Snackbar/Snackbar";
26
+ export type { ClipProps, CustomSpinnerProps, FadeSpinnerProps, } from "./components/Spinner/Spinner";
27
+ export type { ToastShowOptions, ToastVariant } from "./components/Feedback/Toast/Toast";
28
+ export type { OutlineButtonProps, OutlineButtonSize, OutlineButtonVariant, OutlineButtonWidthType, } from "./components/Button/Outline/OutlineButton";
29
+ export type { OutlineIconButtonProps, OutlineIconButtonSize, } from "./components/Button/OutlineIcon/OutlineIconButton";
30
+ export type { TextButtonProps, TextButtonSize, TextButtonVariant, TextButtonWidthType, } from "./components/Button/Text/TextButton";
31
+ export type { WeakButtonProps, WeakButtonSize, WeakButtonVariant, WeakButtonWidthType, } from "./components/Button/Weak/WeakButton";
32
+ export type { CheckBoxProps, CheckBoxVariant, CheckBoxSize, CheckBoxDensity, } from "./components/Control/CheckBox/CheckBox";
33
+ export type { RadioProps, RadioVariant, RadioSize, RadioDensity, } from "./components/Control/Radio/Radio";
34
+ export type { ToggleSwitchProps, ToggleSwitchSize, } from "./components/Control/ToggleSwitch/ToggleSwitch";