@sellmate/design-system-react 1.0.69 → 1.0.70

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
@@ -8,44 +8,323 @@ React component wrappers for Sellmate Design System built with Stencil web compo
8
8
  npm install @sellmate/design-system-react
9
9
  ```
10
10
 
11
- or
11
+ ---
12
12
 
13
- ```bash
14
- yarn add @sellmate/design-system-react
13
+ ## Project Setup
14
+
15
+ > 커스텀 엘리먼트는 패키지 import 시점에 자동 등록됩니다. `defineCustomElements()` 별도 호출이나 StencilProvider 설정은 불필요합니다.
16
+
17
+ ### React (Vite / CRA)
18
+
19
+ **1. CSS 전역 import** — `src/main.tsx`
20
+
21
+ ```tsx
22
+ import '@sellmate/design-system/styles.css';
15
23
  ```
16
24
 
17
- ## Quick Start
25
+ **2. SdModalContainer 최상단 배치** — `src/App.tsx`
18
26
 
19
- ### Basic Setup
27
+ `sdModal`은 `sd-modal-container`를 자동으로 생성하지만, z-index 제어 및 렌더 위치를 명시적으로 지정하려면 루트에 배치합니다.
20
28
 
21
29
  ```tsx
22
- import { SdButton } from '@sellmate/design-system-react';
30
+ import { SdModalContainer } from '@sellmate/design-system-react';
23
31
 
24
- export function App() {
32
+ export default function App() {
25
33
  return (
26
- <SdButton
27
- label="Click me"
28
- onClick={() => console.log('clicked')}
29
- >
30
- </SdButton>
34
+ <>
35
+ <SdModalContainer />
36
+ {/* 라우터, 레이아웃 등 */}
37
+ </>
31
38
  );
32
39
  }
33
40
  ```
34
41
 
42
+ ---
43
+
44
+ ### Next.js (App Router)
45
+
46
+ **1. CSS 전역 import** — `app/layout.tsx`
47
+
48
+ ```tsx
49
+ import '@sellmate/design-system/styles.css';
50
+ ```
51
+
52
+ **2. `'use client'` 필수** — 컴포넌트를 사용하는 모든 파일에 선언 필요
53
+
54
+ ```tsx
55
+ 'use client';
56
+
57
+ import { SdButton } from '@sellmate/design-system-react/next';
58
+ ```
59
+
60
+ **3. SdModalContainer 루트 배치** — `app/layout.tsx`
61
+
62
+ `layout.tsx`는 서버 컴포넌트이므로 클라이언트 전용 Provider를 별도 파일로 분리합니다.
63
+
64
+ ```tsx
65
+ // app/providers.tsx
66
+ 'use client';
67
+
68
+ import { SdModalContainer } from '@sellmate/design-system-react/next';
69
+
70
+ export default function Providers({ children }: { children: React.ReactNode }) {
71
+ return (
72
+ <>
73
+ <SdModalContainer />
74
+ {children}
75
+ </>
76
+ );
77
+ }
78
+ ```
79
+
80
+ ```tsx
81
+ // app/layout.tsx
82
+ import '@sellmate/design-system/styles.css';
83
+ import Providers from './providers';
84
+
85
+ export default function RootLayout({
86
+ children,
87
+ }: {
88
+ children: React.ReactNode;
89
+ }) {
90
+ return (
91
+ <html lang='ko'>
92
+ <body>
93
+ <Providers>{children}</Providers>
94
+ </body>
95
+ </html>
96
+ );
97
+ }
98
+ ```
99
+
100
+ **4. 컴포넌트 import** — `dynamic({ ssr: false })` 패턴
101
+
102
+ ```tsx
103
+ 'use client';
104
+
105
+ import dynamic from 'next/dynamic';
106
+
107
+ const SdButton = dynamic(
108
+ () =>
109
+ import('@sellmate/design-system-react').then((mod) => ({
110
+ default: mod.SdButton,
111
+ })),
112
+ { ssr: false, loading: () => <></> },
113
+ );
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Utility Functions
119
+
120
+ ### `sdModal` — `@sellmate/design-system-react`
121
+
122
+ React 컴포넌트를 모달로 열 수 있는 React-aware 버전입니다.
123
+
124
+ ```ts
125
+ import { sdModal } from '@sellmate/design-system-react';
126
+
127
+ // Confirm 모달
128
+ sdModal
129
+ .confirm({
130
+ type: 'positive' | 'negative' | 'default',
131
+ title: '제목',
132
+ topMessage: ['메시지'],
133
+ mainButtonLabel: '확인',
134
+ subButtonLabel: '취소',
135
+ persistent: false, // true 시 ESC/백드롭으로 닫기 불가
136
+ })
137
+ .onOk(() => {})
138
+ .onCancel(() => {})
139
+ .onClose(() => {});
140
+
141
+ // React 컴포넌트를 모달로 열기
142
+ sdModal.create({
143
+ component: MyModalComponent,
144
+ componentProps: { title: '제목' }, // 컴포넌트에 전달할 props
145
+ persistent: true,
146
+ });
147
+
148
+ // Loading 모달
149
+ const dialog = sdModal.loading({ state: 'loading' });
150
+ dialog.update({ state: 'error', message: '오류 발생' });
151
+ dialog.close();
152
+
153
+ // 전역 설정
154
+ sdModal.configure({ zIndex: 1000 });
155
+ ```
156
+
157
+ > **주의**: `sdModal.create`에 React 컴포넌트를 전달하면 내부적으로 새로운 React 루트가 생성됩니다. 부모 트리의 Context(Redux, React Router, Theme 등)가 **자동으로 상속되지 않으므로** 모달 컴포넌트 내부에서 필요한 Provider를 직접 감싸야 합니다.
158
+
159
+ ---
160
+
161
+ ### `sdToast` — `@sellmate/design-system`
162
+
163
+ ```ts
164
+ import { sdToast } from '@sellmate/design-system';
165
+
166
+ // 토스트 생성
167
+ await sdToast.create('메시지', 'success' | 'error' | 'warning' | 'info');
168
+
169
+ // 개별/전체 닫기
170
+ await sdToast.dismiss(id);
171
+ await sdToast.dismissAll();
172
+
173
+ // 전역 설정
174
+ sdToast.configure({
175
+ position: 'top-right',
176
+ maxVisible: 5,
177
+ defaultDuration: 3000,
178
+ zIndex: 9999,
179
+ });
180
+ ```
181
+
182
+ > `sdToast`는 `sd-toast-container`를 자동으로 생성하므로 별도의 Provider 배치가 불필요합니다.
183
+
184
+ ---
185
+
186
+ ### `sdLoading` — `@sellmate/design-system`
187
+
188
+ ```ts
189
+ import { sdLoading } from '@sellmate/design-system';
190
+
191
+ const hide = sdLoading.show(); // 전체화면 로딩 표시
192
+ hide(); // 로딩 숨김
193
+
194
+ sdLoading.show({ message: '처리 중...' });
195
+ ```
196
+
197
+ ---
198
+
35
199
  ## Available Components
36
200
 
37
- - `SdButton` - Button component
38
- - `SdInput` - Input component
39
- - `SdCheckbox` - Checkbox component
40
- - `SdSelect` - Select dropdown component
41
- - `SdTableBackup` - Table component
42
- - `SdTag` - Tag component
43
- - `SdIcon` - Icon component
44
- - `SdTooltip` - Tooltip component
45
- - `SdPopover` - Popover component
46
- - `SdDatePicker` - Date picker component
47
- - `SdDateRangePicker` - Date range picker component
48
- - `SdPagination` - Pagination component
201
+ ### 입력
202
+
203
+ | 컴포넌트 | 설명 |
204
+ | ----------------------- | -------------------- |
205
+ | `SdInput` | 텍스트 입력 |
206
+ | `SdNumberInput` | 숫자 입력 |
207
+ | `SdTextarea` | 멀티라인 텍스트 입력 |
208
+ | `SdBarcodeInput` | 바코드 스캐너 입력 |
209
+ | `SdCheckbox` | 체크박스 |
210
+ | `SdRadio` | 라디오 버튼 |
211
+ | `SdRadioGroup` | 라디오 그룹 |
212
+ | `SdRadioButton` | 버튼형 라디오 |
213
+ | `SdSwitch` | 스위치 토글 |
214
+ | `SdToggle` | 토글 |
215
+ | `SdSelect` | 단일 선택 드롭다운 |
216
+ | `SdSelectGroup` | 그룹형 단일 선택 |
217
+ | `SdSelectMultiple` | 다중 선택 드롭다운 |
218
+ | `SdSelectMultipleGroup` | 그룹형 다중 선택 |
219
+ | `SdSelectV2` | 단일/다중 선택 V2 |
220
+ | `SdDatePicker` | 날짜 선택 |
221
+ | `SdDateRangePicker` | 날짜 범위 선택 |
222
+ | `SdFilePicker` | 파일 선택 |
223
+
224
+ ### 버튼
225
+
226
+ | 컴포넌트 | 설명 |
227
+ | ------------------ | ---------------- |
228
+ | `SdButton` | 기본 버튼 |
229
+ | `SdButtonV2` | 버튼 V2 |
230
+ | `SdGhostButton` | 고스트 버튼 |
231
+ | `SdDropdownButton` | 드롭다운 버튼 |
232
+ | `SdTextLink` | 텍스트 링크 버튼 |
233
+
234
+ ### 표시
235
+
236
+ | 컴포넌트 | 설명 |
237
+ | -------------------- | ---------------------- |
238
+ | `SdTag` | 태그 |
239
+ | `SdBadge` | 뱃지 |
240
+ | `SdIcon` | 아이콘 |
241
+ | `SdTooltip` | 툴팁 |
242
+ | `SdPopover` | 팝오버 |
243
+ | `SdProgress` | 진행 바 |
244
+ | `SdCircleProgress` | 원형 진행 바 |
245
+ | `SdLoadingContainer` | 로딩 오버레이 컨테이너 |
246
+ | `SdGuide` | 가이드 텍스트 |
247
+ | `SdCard` | 카드 |
248
+ | `SdCalendar` | 캘린더 표시 |
249
+
250
+ ### 레이아웃 / 구조
251
+
252
+ | 컴포넌트 | 설명 |
253
+ | -------------- | ------------------------------------ |
254
+ | `SdField` | 폼 필드 래퍼 (label + input + error) |
255
+ | `SdForm` | 폼 유효성 검사 컨테이너 |
256
+ | `SdTabs` | 탭 네비게이션 |
257
+ | `SdTable` | 데이터 테이블 |
258
+ | `SdPagination` | 페이지네이션 |
259
+
260
+ ### 모달 / 알림
261
+
262
+ | 컴포넌트 | 설명 |
263
+ | ------------------ | ------------------------------------ |
264
+ | `SdModalContainer` | sdModal Provider (루트에 1회 배치) |
265
+ | `SdConfirmModal` | Confirm 모달 (직접 렌더) |
266
+ | `SdActionModal` | Action 모달 (직접 렌더) |
267
+ | `SdLoadingModal` | Loading 모달 (직접 렌더) |
268
+ | `SdToastContainer` | Toast 컨테이너 (sdToast가 자동 생성) |
269
+ | `SdToast` | 개별 Toast |
270
+
271
+ ---
272
+
273
+ ## Available Types
274
+
275
+ ```ts
276
+ import type {
277
+ // Table
278
+ SdTableColumn,
279
+ SdTableRow,
280
+ // Select
281
+ SelectOption,
282
+ SelectOptionGroup,
283
+ SelectV2Option,
284
+ SelectV2Value,
285
+ // Radio
286
+ RadioValue,
287
+ RadioOption,
288
+ // Button
289
+ ButtonVariant,
290
+ ButtonSize,
291
+ ButtonV2Name,
292
+ DropdownButtonItem,
293
+ // Form
294
+ Rule,
295
+ ValidatableField,
296
+ // Checkbox
297
+ CheckedType,
298
+ // Tag
299
+ TagName,
300
+ // Toast
301
+ ToastType,
302
+ // DateBox
303
+ DateBoxType,
304
+ // Tabs
305
+ TabOption,
306
+ // sdModal
307
+ SdModalCreateOption,
308
+ } from '@sellmate/design-system-react';
309
+ ```
310
+
311
+ ---
312
+
313
+ ## Hooks
314
+
315
+ ### `useSdTableVirtualScroll`
316
+
317
+ ```ts
318
+ import { useSdTableVirtualScroll } from '@sellmate/design-system-react';
319
+
320
+ const { virtualRows, totalHeight, scrollToIndex } = useSdTableVirtualScroll({
321
+ rowCount: data.length,
322
+ rowHeight: 48,
323
+ containerHeight: 400,
324
+ });
325
+ ```
326
+
327
+ ---
49
328
 
50
329
  ## Requirements
51
330
 
@@ -218,7 +218,9 @@ export type SdPaginationEvents = {
218
218
  onSdPageChange: EventName<CustomEvent<number>>;
219
219
  };
220
220
  export declare const SdPagination: StencilReactComponent<SdPaginationElement, SdPaginationEvents>;
221
- export type SdPopoverEvents = NonNullable<unknown>;
221
+ export type SdPopoverEvents = {
222
+ onSdShowChange: EventName<CustomEvent<boolean>>;
223
+ };
222
224
  export declare const SdPopover: StencilReactComponent<SdPopoverElement, SdPopoverEvents>;
223
225
  export type SdPortalEvents = {
224
226
  onSdClose: EventName<CustomEvent<void>>;
@@ -312,6 +314,8 @@ export type SdSelectV2ListboxEvents = {
312
314
  export declare const SdSelectV2Listbox: StencilReactComponent<SdSelectV2ListboxElement, SdSelectV2ListboxEvents>;
313
315
  export type SdSelectV2TriggerEvents = {
314
316
  onSdTriggerClick: EventName<CustomEvent<void>>;
317
+ onSdTriggerFocus: EventName<CustomEvent<void>>;
318
+ onSdTriggerBlur: EventName<CustomEvent<void>>;
315
319
  };
316
320
  export declare const SdSelectV2Trigger: StencilReactComponent<SdSelectV2TriggerElement, SdSelectV2TriggerEvents>;
317
321
  export type SdSwitchEvents = {
@@ -370,7 +370,7 @@ export const SdPopover = /*@__PURE__*/ createComponent({
370
370
  elementClass: SdPopoverElement,
371
371
  // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.
372
372
  react: React,
373
- events: {},
373
+ events: { onSdShowChange: 'sdShowChange' },
374
374
  defineCustomElement: defineSdPopover
375
375
  });
376
376
  export const SdPortal = /*@__PURE__*/ createComponent({
@@ -539,7 +539,11 @@ export const SdSelectV2Trigger = /*@__PURE__*/ createComponent({
539
539
  elementClass: SdSelectV2TriggerElement,
540
540
  // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.
541
541
  react: React,
542
- events: { onSdTriggerClick: 'sdTriggerClick' },
542
+ events: {
543
+ onSdTriggerClick: 'sdTriggerClick',
544
+ onSdTriggerFocus: 'sdTriggerFocus',
545
+ onSdTriggerBlur: 'sdTriggerBlur'
546
+ },
543
547
  defineCustomElement: defineSdSelectV2Trigger
544
548
  });
545
549
  export const SdSwitch = /*@__PURE__*/ createComponent({
@@ -220,7 +220,9 @@ export type SdPaginationEvents = {
220
220
  onSdPageChange: EventName<CustomEvent<number>>;
221
221
  };
222
222
  export declare const SdPagination: StencilReactComponent<SdPaginationElement, SdPaginationEvents>;
223
- export type SdPopoverEvents = NonNullable<unknown>;
223
+ export type SdPopoverEvents = {
224
+ onSdShowChange: EventName<CustomEvent<boolean>>;
225
+ };
224
226
  export declare const SdPopover: StencilReactComponent<SdPopoverElement, SdPopoverEvents>;
225
227
  export type SdPortalEvents = {
226
228
  onSdClose: EventName<CustomEvent<void>>;
@@ -314,6 +316,8 @@ export type SdSelectV2ListboxEvents = {
314
316
  export declare const SdSelectV2Listbox: StencilReactComponent<SdSelectV2ListboxElement, SdSelectV2ListboxEvents>;
315
317
  export type SdSelectV2TriggerEvents = {
316
318
  onSdTriggerClick: EventName<CustomEvent<void>>;
319
+ onSdTriggerFocus: EventName<CustomEvent<void>>;
320
+ onSdTriggerBlur: EventName<CustomEvent<void>>;
317
321
  };
318
322
  export declare const SdSelectV2Trigger: StencilReactComponent<SdSelectV2TriggerElement, SdSelectV2TriggerEvents>;
319
323
  export type SdSwitchEvents = {
@@ -500,11 +500,11 @@ export const SdPopover = /*@__PURE__*/ createComponent({
500
500
  label: 'label',
501
501
  buttonSize: 'button-size',
502
502
  buttonVariant: 'button-variant',
503
- menuTitle: 'title',
503
+ menuTitle: 'menu-title',
504
504
  menuClass: 'menu-class',
505
- noHover: 'no-hover',
506
505
  useClose: 'use-close',
507
- messages: 'messages'
506
+ messages: 'messages',
507
+ buttons: 'buttons'
508
508
  },
509
509
  hydrateModule: import('@sellmate/design-system/hydrate'),
510
510
  clientModule: clientComponents.SdPopover,
@@ -697,7 +697,7 @@ export const SdPagination: StencilReactComponent<SdPaginationElement, SdPaginati
697
697
  serializeShadowRoot,
698
698
  });
699
699
 
700
- export type SdPopoverEvents = NonNullable<unknown>;
700
+ export type SdPopoverEvents = { onSdShowChange: EventName<CustomEvent<boolean>> };
701
701
 
702
702
  export const SdPopover: StencilReactComponent<SdPopoverElement, SdPopoverEvents> = /*@__PURE__*/ createComponent<SdPopoverElement, SdPopoverEvents>({
703
703
  tagName: 'sd-popover',
@@ -710,11 +710,11 @@ export const SdPopover: StencilReactComponent<SdPopoverElement, SdPopoverEvents>
710
710
  label: 'label',
711
711
  buttonSize: 'button-size',
712
712
  buttonVariant: 'button-variant',
713
- menuTitle: 'title',
713
+ menuTitle: 'menu-title',
714
714
  menuClass: 'menu-class',
715
- noHover: 'no-hover',
716
715
  useClose: 'use-close',
717
- messages: 'messages'},
716
+ messages: 'messages',
717
+ buttons: 'buttons'},
718
718
  hydrateModule: import('@sellmate/design-system/hydrate') as Promise<HydrateModule>,
719
719
  clientModule: clientComponents.SdPopover as ReactWebComponent<SdPopoverElement, SdPopoverEvents>,
720
720
  serializeShadowRoot,
@@ -1084,7 +1084,11 @@ export const SdSelectV2Listbox: StencilReactComponent<SdSelectV2ListboxElement,
1084
1084
  serializeShadowRoot,
1085
1085
  });
1086
1086
 
1087
- export type SdSelectV2TriggerEvents = { onSdTriggerClick: EventName<CustomEvent<void>> };
1087
+ export type SdSelectV2TriggerEvents = {
1088
+ onSdTriggerClick: EventName<CustomEvent<void>>,
1089
+ onSdTriggerFocus: EventName<CustomEvent<void>>,
1090
+ onSdTriggerBlur: EventName<CustomEvent<void>>
1091
+ };
1088
1092
 
1089
1093
  export const SdSelectV2Trigger: StencilReactComponent<SdSelectV2TriggerElement, SdSelectV2TriggerEvents> = /*@__PURE__*/ createComponent<SdSelectV2TriggerElement, SdSelectV2TriggerEvents>({
1090
1094
  tagName: 'sd-select-v2-trigger',
@@ -523,14 +523,14 @@ export const SdPagination: StencilReactComponent<SdPaginationElement, SdPaginati
523
523
  defineCustomElement: defineSdPagination
524
524
  });
525
525
 
526
- export type SdPopoverEvents = NonNullable<unknown>;
526
+ export type SdPopoverEvents = { onSdShowChange: EventName<CustomEvent<boolean>> };
527
527
 
528
528
  export const SdPopover: StencilReactComponent<SdPopoverElement, SdPopoverEvents> = /*@__PURE__*/ createComponent<SdPopoverElement, SdPopoverEvents>({
529
529
  tagName: 'sd-popover',
530
530
  elementClass: SdPopoverElement,
531
531
  // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.
532
532
  react: React,
533
- events: {} as SdPopoverEvents,
533
+ events: { onSdShowChange: 'sdShowChange' } as SdPopoverEvents,
534
534
  defineCustomElement: defineSdPopover
535
535
  });
536
536
 
@@ -788,14 +788,22 @@ export const SdSelectV2Listbox: StencilReactComponent<SdSelectV2ListboxElement,
788
788
  defineCustomElement: defineSdSelectV2Listbox
789
789
  });
790
790
 
791
- export type SdSelectV2TriggerEvents = { onSdTriggerClick: EventName<CustomEvent<void>> };
791
+ export type SdSelectV2TriggerEvents = {
792
+ onSdTriggerClick: EventName<CustomEvent<void>>,
793
+ onSdTriggerFocus: EventName<CustomEvent<void>>,
794
+ onSdTriggerBlur: EventName<CustomEvent<void>>
795
+ };
792
796
 
793
797
  export const SdSelectV2Trigger: StencilReactComponent<SdSelectV2TriggerElement, SdSelectV2TriggerEvents> = /*@__PURE__*/ createComponent<SdSelectV2TriggerElement, SdSelectV2TriggerEvents>({
794
798
  tagName: 'sd-select-v2-trigger',
795
799
  elementClass: SdSelectV2TriggerElement,
796
800
  // @ts-ignore - ignore potential React type mismatches between the Stencil Output Target and your project.
797
801
  react: React,
798
- events: { onSdTriggerClick: 'sdTriggerClick' } as SdSelectV2TriggerEvents,
802
+ events: {
803
+ onSdTriggerClick: 'sdTriggerClick',
804
+ onSdTriggerFocus: 'sdTriggerFocus',
805
+ onSdTriggerBlur: 'sdTriggerBlur'
806
+ } as SdSelectV2TriggerEvents,
799
807
  defineCustomElement: defineSdSelectV2Trigger
800
808
  });
801
809
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sellmate/design-system-react",
3
- "version": "1.0.69",
3
+ "version": "1.0.70",
4
4
  "description": "Design System - React Component Wrappers",
5
5
  "keywords": [
6
6
  "react",
@@ -54,7 +54,7 @@
54
54
  "dev": "tsc --watch"
55
55
  },
56
56
  "dependencies": {
57
- "@sellmate/design-system": "^1.0.69",
57
+ "@sellmate/design-system": "^1.0.70",
58
58
  "@stencil/react-output-target": "^1.2.0"
59
59
  },
60
60
  "peerDependencies": {