@nurihaus/web-design-system 3.2.0 → 3.4.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 +36 -0
- package/dist/ai/components.md +123 -12
- package/dist/ai/tokens.md +2 -0
- package/dist/avatar.js +5 -5
- package/dist/bottom-nav.js +22 -8
- package/dist/breadcrumb.js +25 -10
- package/dist/check-box.js +24 -8
- package/dist/chip-group.js +21 -7
- package/dist/{chunk-563.js → chunk-1563.js} +26 -13
- package/dist/{chunk-657.js → chunk-1657.js} +2 -2
- package/dist/{chunk-777.js → chunk-2777.js} +2 -2
- package/dist/{chunk-558.js → chunk-4558.js} +2 -2
- package/dist/chunk-4560.js +77 -0
- package/dist/{chunk-917.js → chunk-4917.js} +2 -2
- package/dist/{chunk-77.js → chunk-5077.js} +2 -2
- package/dist/{chunk-149.js → chunk-6149.js} +2 -2
- package/dist/{chunk-302.js → chunk-6302.js} +2 -2
- package/dist/{chunk-364.js → chunk-6364.js} +2 -2
- package/dist/{chunk-713.js → chunk-6713.js} +2 -2
- package/dist/{chunk-298.js → chunk-7298.js} +2 -2
- package/dist/{chunk-653.js → chunk-7653.js} +7 -3
- package/dist/{chunk-739.js → chunk-7739.js} +2 -2
- package/dist/{chunk-309.js → chunk-8690.js} +2 -2
- package/dist/{chunk-933.js → chunk-8933.js} +2 -2
- package/dist/chunk-910.js +23 -10
- package/dist/{chunk-387.js → chunk-9387.js} +2 -2
- package/dist/{chunk-436.js → chunk-9436.js} +2 -2
- package/dist/{chunk-976.js → chunk-9976.js} +3 -3
- package/dist/collapsible-menu.js +25 -12
- package/dist/components/badge/badge-props.d.ts +4 -4
- package/dist/components/badge/badge.stories.d.ts +1 -1
- package/dist/components/bottom-nav/bottom-nav-type.d.ts +5 -2
- package/dist/components/breadcrumb/breadcrumb-type.d.ts +2 -1
- package/dist/components/button/button-props.d.ts +2 -2
- package/dist/components/button/button-type.d.ts +2 -1
- package/dist/components/button/button.stories.d.ts +1 -1
- package/dist/components/check-box/check-box-type.d.ts +2 -1
- package/dist/components/chip-group/chip-group-type.d.ts +2 -1
- package/dist/components/collapsible-menu/collapsible-menu-type.d.ts +2 -1
- package/dist/components/drawer/drawer-type.d.ts +2 -1
- package/dist/components/drop-down/drop-down-type.d.ts +2 -1
- package/dist/components/icon/icon-paths.d.ts +4 -0
- package/dist/components/icon/icon-props.d.ts +2 -2
- package/dist/components/icon/icon.stories.d.ts +2 -2
- package/dist/components/logging/log-context.d.ts +9 -0
- package/dist/components/logging/logging-type.d.ts +25 -0
- package/dist/components/logging/logging.d.ts +5 -0
- package/dist/components/logging/logging.stories.d.ts +18 -0
- package/dist/components/modal/modal-type.d.ts +2 -1
- package/dist/components/pagination/pagination-type.d.ts +2 -1
- package/dist/components/radio/radio-type.d.ts +3 -1
- package/dist/components/radio/radio.d.ts +2 -1
- package/dist/components/radio/radio.stories.d.ts +1 -1
- package/dist/components/switch/switch-type.d.ts +2 -1
- package/dist/components/table/table-type.d.ts +2 -1
- package/dist/components/tabs/tabs-type.d.ts +2 -1
- package/dist/components/text-area/text-area-type.d.ts +2 -1
- package/dist/components/text-field/text-field-type.d.ts +2 -1
- package/dist/components/toast/toast-type.d.ts +2 -1
- package/dist/components/toast/toast.stories.d.ts +3 -1
- package/dist/components/tooltip/tooltip-type.d.ts +2 -1
- package/dist/components.css +48 -0
- package/dist/cta-button.js +35 -20
- package/dist/data-table.js +19 -7
- package/dist/drawer.js +23 -9
- package/dist/drop-down.js +25 -9
- package/dist/helpers/hooks/useTrack.d.ts +3 -0
- package/dist/icon-text-badge.js +12 -10
- package/dist/icon-text-option-badge.js +6 -6
- package/dist/icon.js +5 -5
- package/dist/index.d.ts +2 -0
- package/dist/index.js +438 -81
- package/dist/loading.js +6 -6
- package/dist/logging.js +147 -0
- package/dist/modal-with-double-button.js +14 -12
- package/dist/modal.js +39 -26
- package/dist/option-badge.js +12 -10
- package/dist/pagination.js +23 -9
- package/dist/radio.js +24 -10
- package/dist/skeleton.js +4 -4
- package/dist/step-progress.js +3 -3
- package/dist/styles.css +42 -0
- package/dist/switch.js +24 -8
- package/dist/tabs.js +22 -6
- package/dist/text-area.js +30 -8
- package/dist/text-field.js +31 -9
- package/dist/text.js +5 -5
- package/dist/toast.js +32 -15
- package/dist/tokens.css +2 -0
- package/dist/tooltip.js +33 -18
- package/package.json +5 -1
package/README.md
CHANGED
|
@@ -118,6 +118,42 @@ npm run tokens # figma.json → tokens/generated/{tokens.css, *.ts}
|
|
|
118
118
|
|
|
119
119
|
새 서비스가 다른 의미 토큰 값(버튼 색 등)을 써야 하면 `tokens/figma.json` 에 `semantic_{이름}` 세트를 추가하고 `npm run tokens` 를 돌린다. `<html data-ds-theme="{이름}">` 로 고르는 테마가 생긴다. 자세한 규칙은 `docs/tokens.md`.
|
|
120
120
|
|
|
121
|
+
## 사용 로그
|
|
122
|
+
|
|
123
|
+
컴포넌트가 사용자 상호작용을 이벤트로 내보내고, 어디로 보낼지는 앱이 정한다. 디자인시스템은 로그 수집기를 모른다.
|
|
124
|
+
|
|
125
|
+
앱 루트에 `LogProvider` 를 한 번 둔다. `onEvent` 가 받은 이벤트를 앱의 로그 수집기로 보낸다.
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
import { LogProvider } from '@nurihaus/web-design-system/logging';
|
|
129
|
+
|
|
130
|
+
export default function App({ children }) {
|
|
131
|
+
return <LogProvider onEvent={(event) => console.log(event)}>{children}</LogProvider>;
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
컴포넌트에 `track` 을 준다. 누르면 `{ component: 'CTAButton', action: 'click', track: 'report/download', props: { format: 'csv' }, timestamp }` 가 `onEvent` 로 간다.
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
<CTAButton text='리포트 받기' track='report/download' trackProps={{ format: 'csv' }} />
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`track` 을 받는 컴포넌트는 CTAButton · DataTable(`click`), Modal · Drawer(`open` · `close`), Tabs · DropDown · ChipGroup · Radio · Checkbox · Switch · Pagination · TextField · TextArea(`change`), BottomNav · Breadcrumb · CollapsibleMenu(`navigate`), Toast · Tooltip(`show`) 다. `value` 에는 탭 id · 칩 id · 옵션 value 처럼 개발자가 정한 id 만 들어간다. TextField · TextArea 는 포커스가 빠질 때 값이 바뀌었으면 값 없이 `change` 를 한 번 보낸다. `LogProvider` 가 없거나 `track` 을 주지 않으면 아무것도 보내지 않는다.
|
|
142
|
+
|
|
143
|
+
컴포넌트 밖의 로그는 `useLog` 로 남긴다.
|
|
144
|
+
|
|
145
|
+
```tsx
|
|
146
|
+
import { useEffect } from 'react';
|
|
147
|
+
|
|
148
|
+
import { useLog } from '@nurihaus/web-design-system/logging';
|
|
149
|
+
|
|
150
|
+
const ReportPage = () => {
|
|
151
|
+
const log = useLog();
|
|
152
|
+
useEffect(() => log({ component: 'ReportPage', action: 'view', track: 'report/view' }), [log]);
|
|
153
|
+
// …
|
|
154
|
+
};
|
|
155
|
+
```
|
|
156
|
+
|
|
121
157
|
## AI 설명서
|
|
122
158
|
|
|
123
159
|
배포물의 `dist/ai/` 에 쓰는 쪽 AI 가 읽는 설명서가 들어 있다.
|
package/dist/ai/components.md
CHANGED
|
@@ -30,6 +30,26 @@ import '@nurihaus/web-design-system/components.css';
|
|
|
30
30
|
|
|
31
31
|
**Tooltip 이 여러 개면 `TooltipProvider` 로 감싼다.** 앱 루트에 한 번 두면 된다. 조건이 맞을 때만 띄우려면 `open` 을 제어하지 말고 `disabled` 를 쓴다.
|
|
32
32
|
|
|
33
|
+
**사용 로그는 `track` 으로 남긴다.** 앱 루트에 `LogProvider` 를 한 번 두고 `onEvent` 에서 로그 수집기로 보낸다. 컴포넌트에 `track="report/download"` 처럼 개발자가 정한 이름을 주면 아래 상호작용이 이벤트로 나간다. `component` 는 컴포넌트의 displayName 이다(Checkbox 는 `'CheckBox'`).
|
|
34
|
+
|
|
35
|
+
| 컴포넌트 | 보내는 때 | action | value |
|
|
36
|
+
| --- | --- | --- | --- |
|
|
37
|
+
| CTAButton | 누를 때 | `click` | 없음 |
|
|
38
|
+
| DataTable | `onClickRow` 가 있는 헤더 칸을 누를 때 | `click` | 그 칸의 `id` |
|
|
39
|
+
| Modal · Drawer | 열고 닫을 때 | `open` · `close` | 없음 |
|
|
40
|
+
| Tabs · DropDown · ChipGroup · Radio | 고를 때 | `change` | 탭 id · 옵션 value · 칩 id · 선택지 id |
|
|
41
|
+
| Checkbox · Switch | 켜고 끌 때 | `change` | `'on'` · `'off'` |
|
|
42
|
+
| Pagination | 페이지가 바뀔 때 | `change` | 페이지 번호(문자열) |
|
|
43
|
+
| TextField · TextArea | 포커스가 빠질 때, 포커스를 받을 때와 값이 다르면 한 번 | `change` | 없음 |
|
|
44
|
+
| BottomNav | 탭을 누를 때 | `navigate` | 탭 id |
|
|
45
|
+
| Breadcrumb | 현재 위치가 아닌 링크를 누를 때 | `navigate` | 항목 `id` |
|
|
46
|
+
| CollapsibleMenu | 링크·버튼 항목을 고를 때. 그룹 여닫기는 보내지 않는다 | `navigate` | 항목 `key` |
|
|
47
|
+
| Toast · Tooltip | 뜰 때 | `show` | 없음 |
|
|
48
|
+
|
|
49
|
+
`value` 에는 개발자가 정한 id 만 들어가고 사용자가 입력한 글자는 들어가지 않는다. TextField · TextArea 가 값을 싣지 않는 것도 그래서다. 더 붙일 값은 `trackProps` 로 준다. `LogProvider` 가 없거나 `track` 이 없으면 아무것도 보내지 않는다. 컴포넌트 밖의 로그(화면 진입 등)는 `useLog` 를 쓴다.
|
|
50
|
+
|
|
51
|
+
Avatar · OptionBadge · IconTextBadge · IconTextOptionBadge · Skeleton · Text · Icon · StepProgress · Spinner · InlineLoading · OverlayLoading 은 상호작용 핸들러가 없어 `track` 을 받지 않는다. ModalWithDoubleButton 은 `left` · `right` 가 CTAButton props 라 거기에 `track` 을 준다.
|
|
52
|
+
|
|
33
53
|
**없는 것은 지어내지 않는다.** 이 문서 끝의 "아직 없는 것" 표에 있는 컴포넌트는 없다. 없는 prop · variant · 토큰 이름도 만들지 않는다. 틀린 variant 나 size 값은 타입 오류가 난다.
|
|
34
54
|
|
|
35
55
|
## 목록
|
|
@@ -66,6 +86,7 @@ import '@nurihaus/web-design-system/components.css';
|
|
|
66
86
|
- [BottomNav](#bottomnav)
|
|
67
87
|
- [StepProgress](#stepprogress)
|
|
68
88
|
- [ChipGroup](#chipgroup)
|
|
89
|
+
- [LogProvider](#logprovider)
|
|
69
90
|
|
|
70
91
|
## Avatar
|
|
71
92
|
|
|
@@ -102,12 +123,15 @@ import { CTAButton } from '@nurihaus/web-design-system/cta-button'; // 이 컴
|
|
|
102
123
|
import { CTAButton } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
|
|
103
124
|
```
|
|
104
125
|
|
|
105
|
-
**언제 쓴다.** 저장, 확인, 다음 단계처럼 사용자가 실행하는 동작 버튼에 쓴다. `variant`로 강조 단계를 고르고, `loading`이 true면 `text` 대신 Spinner가 표시된다.
|
|
126
|
+
**언제 쓴다.** 저장, 확인, 다음 단계처럼 사용자가 실행하는 동작 버튼에 쓴다. `variant`로 강조 단계를 고르고, `loading`이 true면 `text` 대신 Spinner가 표시된다. Google·Apple·Facebook 로그인 버튼은 `variant="social"`(흰 바탕·검정 글자, 공급자 가이드)에 공급자 로고를 `leftIcon`으로 준다.
|
|
106
127
|
|
|
107
128
|
**쓰지 않는다.** 확인과 취소 두 버튼을 가진 대화상자는 버튼을 직접 배치하지 말고 ModalWithDoubleButton을 쓴다. 화면 안의 패널 전환은 Tabs, 사이드 메뉴 항목은 CollapsibleMenu를 쓴다.
|
|
108
129
|
|
|
109
130
|
```tsx
|
|
110
|
-
|
|
131
|
+
<>
|
|
132
|
+
<CTAButton variant="primary" size="m" text="저장" onClick={() => {}} />
|
|
133
|
+
<CTAButton variant="social" size="l" text="Google로 계속하기" leftIcon={<img src="/icons/google.svg" alt="" />} />
|
|
134
|
+
</>
|
|
111
135
|
```
|
|
112
136
|
|
|
113
137
|
### props
|
|
@@ -115,11 +139,13 @@ import { CTAButton } from '@nurihaus/web-design-system'; // 루트.
|
|
|
115
139
|
| prop | 타입 | 필수 | 기본값 |
|
|
116
140
|
| --- | --- | --- | --- |
|
|
117
141
|
| `size` | `'xs' \| 's' \| 'm' \| 'l' \| 'xl'` | | `'m'` |
|
|
142
|
+
| `track` | `string` | | |
|
|
118
143
|
| `text` | `ReactNode` | 예 | |
|
|
119
|
-
| `variant` | `'neutral' \| 'primary' \| 'outlined' \| 'secondary' \| 'ghost' \| 'confirm'` | | `'primary'` |
|
|
144
|
+
| `variant` | `'neutral' \| 'primary' \| 'outlined' \| 'secondary' \| 'ghost' \| 'confirm' \| 'social'` | | `'primary'` |
|
|
120
145
|
| `leftIcon` | `ReactNode` | | |
|
|
121
146
|
| `rightIcon` | `ReactNode` | | |
|
|
122
147
|
| `loading` | `boolean` | | |
|
|
148
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
123
149
|
|
|
124
150
|
이 밖에 React·HTML 기본 속성 276개를 받는다.
|
|
125
151
|
|
|
@@ -130,19 +156,23 @@ import { OptionBadge } from '@nurihaus/web-design-system/option-badge'; // 이
|
|
|
130
156
|
import { OptionBadge } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
|
|
131
157
|
```
|
|
132
158
|
|
|
133
|
-
**언제 쓴다.** 상태값이나 분류처럼 짧은 값 하나(`option`)를 라벨로 보여줄 때 쓴다. `variant`로 색을 고른다(`neutral`·`primary`·`danger`·`outlined`). 색 prop 은 없다. `tooltip`을 주면 마우스를 올렸을 때 설명이 뜬다.
|
|
159
|
+
**언제 쓴다.** 상태값이나 분류처럼 짧은 값 하나(`option`)를 라벨로 보여줄 때 쓴다. `variant`로 색을 고른다(`neutral`·`primary`·`danger`·`outlined`). 색 prop 은 없다. `tooltip`을 주면 마우스를 올렸을 때 설명이 뜬다. 버튼 같은 대상의 모서리에 늘 떠 있는 말풍선(예: 로그인 버튼의 "최근 사용")은 `variant="callout"`이다 — 꼬리가 아래 왼쪽을 가리키고, 자리(`position: absolute` 와 위치)는 쓰는 쪽이 `className`으로 정한다.
|
|
134
160
|
|
|
135
161
|
**쓰지 않는다.** 아이콘이 함께 필요하면 IconTextBadge를, 아이콘과 텍스트 오른쪽에 수치 같은 부가 값까지 붙여야 하면 IconTextOptionBadge를 쓴다. 클릭 동작이 필요한 요소에는 CTAButton을 쓴다.
|
|
136
162
|
|
|
137
163
|
```tsx
|
|
138
|
-
|
|
164
|
+
<>
|
|
165
|
+
<OptionBadge option="진행 중" variant="primary" size="s" width="fit-content" />
|
|
166
|
+
{/* 자리는 쓰는 쪽 CSS: 감싼 요소 position: relative, .last-used { position: absolute; top: -12px; right: 14px; } */}
|
|
167
|
+
<OptionBadge option="최근 사용" variant="callout" size="xs" width="fit-content" className="last-used" />
|
|
168
|
+
</>
|
|
139
169
|
```
|
|
140
170
|
|
|
141
171
|
### props
|
|
142
172
|
|
|
143
173
|
| prop | 타입 | 필수 | 기본값 |
|
|
144
174
|
| --- | --- | --- | --- |
|
|
145
|
-
| `variant` | `'neutral' \| 'primary' \| 'danger' \| 'outlined'` | | `'neutral'` |
|
|
175
|
+
| `variant` | `'neutral' \| 'primary' \| 'danger' \| 'outlined' \| 'callout'` | | `'neutral'` |
|
|
146
176
|
| `width` | `string \| number` | | `'100%'` |
|
|
147
177
|
| `size` | `'xs' \| 's' \| 'm' \| 'l' \| 'xl'` | | `'xl'` |
|
|
148
178
|
| `option` | `ReactNode` | 예 | |
|
|
@@ -178,7 +208,7 @@ import { IconTextBadge } from '@nurihaus/web-design-system'; // 루
|
|
|
178
208
|
|
|
179
209
|
| prop | 타입 | 필수 | 기본값 |
|
|
180
210
|
| --- | --- | --- | --- |
|
|
181
|
-
| `variant` | `'neutral' \| 'primary' \| 'danger' \| 'outlined'` | | `'neutral'` |
|
|
211
|
+
| `variant` | `'neutral' \| 'primary' \| 'danger' \| 'outlined' \| 'callout'` | | `'neutral'` |
|
|
182
212
|
| `width` | `string \| number` | | `'100%'` |
|
|
183
213
|
| `size` | `'xs' \| 's' \| 'm' \| 'l' \| 'xl'` | | `'xl'` |
|
|
184
214
|
| `icon` | `ReactNode` | 예 | |
|
|
@@ -215,7 +245,7 @@ import { IconTextOptionBadge } from '@nurihaus/web-design-system'; /
|
|
|
215
245
|
|
|
216
246
|
| prop | 타입 | 필수 | 기본값 |
|
|
217
247
|
| --- | --- | --- | --- |
|
|
218
|
-
| `variant` | `'neutral' \| 'primary' \| 'danger' \| 'outlined'` | | `'neutral'` |
|
|
248
|
+
| `variant` | `'neutral' \| 'primary' \| 'danger' \| 'outlined' \| 'callout'` | | `'neutral'` |
|
|
219
249
|
| `width` | `string \| number` | | `'100%'` |
|
|
220
250
|
| `size` | `'xs' \| 's' \| 'm' \| 'l' \| 'xl'` | | `'xl'` |
|
|
221
251
|
| `icon` | `ReactNode` | 예 | |
|
|
@@ -235,6 +265,8 @@ import { DataTable } from '@nurihaus/web-design-system'; // 루트.
|
|
|
235
265
|
|
|
236
266
|
**언제 쓴다.** 여러 레코드를 열 단위로 나열하는 목록 화면에 쓴다. 이름과 달리 `rows`는 헤더 열 정의(`id`, 헤더 내용)이고 `columns`는 데이터 행 배열이며, 각 데이터 행은 `rows`의 모든 `id`를 키로 가진다. 열 너비는 셀 내용의 너비를 따르므로 같은 열의 헤더와 셀 내용에 같은 너비를 준다.
|
|
237
267
|
|
|
268
|
+
`track`을 주면 `onClickRow`가 있는 `rows` 항목(헤더 칸)을 누를 때 `click`과 그 `id`를 `value`에 담아 사용 로그로 보낸다. `onClickRow`가 없는 칸과 본문 셀은 보내지 않는다.
|
|
269
|
+
|
|
238
270
|
**쓰지 않는다.** 정렬, 페이지네이션, 행 선택, 빈 상태 표시는 내장되어 있지 않으므로 데이터를 바깥에서 가공해 넘기고 빈 목록은 따로 그린다. 헤더는 위에 고정되고 `fixedRowsIndex`로 왼쪽 열을 고정할 수 있지만, 그 외의 표 동작이 필요하면 직접 만든다.
|
|
239
271
|
|
|
240
272
|
```tsx
|
|
@@ -264,6 +296,8 @@ import { DataTable } from '@nurihaus/web-design-system'; // 루트.
|
|
|
264
296
|
| `rowHeight` | `number` | | `60` |
|
|
265
297
|
| `cellHeight` | `number` | | |
|
|
266
298
|
| `className` | `string` | | |
|
|
299
|
+
| `track` | `string` | | |
|
|
300
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
267
301
|
|
|
268
302
|
이 밖에 React·HTML 기본 속성 2개를 받는다.
|
|
269
303
|
|
|
@@ -276,6 +310,8 @@ import { TextField } from '@nurihaus/web-design-system'; // 루트.
|
|
|
276
310
|
|
|
277
311
|
**언제 쓴다.** 한 줄 텍스트를 입력받을 때 쓴다. 위 라벨(`title`), 아래 안내 문구(`helperText`), 좌우 아이콘을 함께 붙일 수 있고, `isError`가 true면 `helperText`가 오류 스타일로 바뀐다.
|
|
278
312
|
|
|
313
|
+
`track`을 주면 포커스가 빠질 때 값이 포커스를 받을 때와 다르면 `change`를 한 번 사용 로그로 보낸다. 값은 싣지 않는다. 사용자가 입력한 글자는 로그에 들어가지 않는다.
|
|
314
|
+
|
|
279
315
|
**쓰지 않는다.** 여러 줄 입력은 지원하지 않는다(`<input>`만 렌더한다). 정해진 값 중에서 고르는 입력은 DropDown이나 Radio를 쓴다.
|
|
280
316
|
|
|
281
317
|
```tsx
|
|
@@ -297,11 +333,13 @@ import { TextField } from '@nurihaus/web-design-system'; // 루트.
|
|
|
297
333
|
| `className` | `string` | | |
|
|
298
334
|
| `size` | `'xs' \| 's' \| 'm' \| 'l' \| 'xl'` | 예 | `'s'` |
|
|
299
335
|
| `title` | `ReactNode` | | |
|
|
336
|
+
| `track` | `string` | | |
|
|
300
337
|
| `name` | `string` | 예 | |
|
|
301
338
|
| `value` | `string` | | |
|
|
302
339
|
| `defaultValue` | `string` | | |
|
|
303
340
|
| `leftIcon` | `ReactNode` | | |
|
|
304
341
|
| `rightIcon` | `ReactNode` | | |
|
|
342
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
305
343
|
| `width` | `string \| number` | 예 | `'100%'` |
|
|
306
344
|
| `helperText` | `ReactNode` | | |
|
|
307
345
|
| `isError` | `boolean` | | |
|
|
@@ -317,6 +355,8 @@ import { Radio } from '@nurihaus/web-design-system'; // 루트. 첫
|
|
|
317
355
|
|
|
318
356
|
**언제 쓴다.** 몇 개의 선택지를 모두 펼쳐 보여주고 그중 하나만 고르게 할 때 쓴다. 선택 상태는 항상 부모가 가지므로 `onChange`에서 받은 id로 `selected`를 갱신해야 선택이 바뀐다.
|
|
319
357
|
|
|
358
|
+
`track`을 주면 선택지를 누를 때 `change`와 그 선택지 `id`를 `value`에 담아 사용 로그로 보낸다.
|
|
359
|
+
|
|
320
360
|
**쓰지 않는다.** 여러 개를 동시에 고르면 Checkbox를 쓴다. 선택지가 많아 모두 펼치기 어려우면 DropDown을 쓴다.
|
|
321
361
|
|
|
322
362
|
```tsx
|
|
@@ -338,6 +378,8 @@ import { Radio } from '@nurihaus/web-design-system'; // 루트. 첫
|
|
|
338
378
|
| `options` | `{ id: string; label: ReactNode; disabled?: boolean \| undefined; }[]` | 예 | |
|
|
339
379
|
| `selected` | `string \| null` | | |
|
|
340
380
|
| `onChange` | `((id: string \| null) => void)` | | |
|
|
381
|
+
| `track` | `string` | | |
|
|
382
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
341
383
|
|
|
342
384
|
이 밖에 React·HTML 기본 속성 2개를 받는다.
|
|
343
385
|
|
|
@@ -350,6 +392,8 @@ import { Checkbox } from '@nurihaus/web-design-system'; // 루트.
|
|
|
350
392
|
|
|
351
393
|
**언제 쓴다.** 동의 여부처럼 켜고 끄는 값 하나를 받거나, 목록의 항목을 각각 독립적으로 선택할 때 쓴다. `onChange`는 바뀐 체크 상태(boolean)를 받는다.
|
|
352
394
|
|
|
395
|
+
`track`을 주면 체크 상태가 바뀔 때마다 `change`와 `'on'`·`'off'`를 `value`에 담아 사용 로그로 보낸다. 이벤트의 `component`는 displayName 인 `'CheckBox'`다.
|
|
396
|
+
|
|
353
397
|
**쓰지 않는다.** 여러 선택지 중 하나만 골라야 하면 Radio를, 목록에서 값 하나를 고르면 DropDown을 쓴다.
|
|
354
398
|
|
|
355
399
|
```tsx
|
|
@@ -368,6 +412,8 @@ import { Checkbox } from '@nurihaus/web-design-system'; // 루트.
|
|
|
368
412
|
| `onChange` | `((checked: boolean) => void)` | | |
|
|
369
413
|
| `id` | `string` | 예 | |
|
|
370
414
|
| `disabled` | `boolean` | | |
|
|
415
|
+
| `track` | `string` | | |
|
|
416
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
371
417
|
|
|
372
418
|
이 밖에 React·HTML 기본 속성 2개를 받는다.
|
|
373
419
|
|
|
@@ -380,6 +426,8 @@ import { Switch } from '@nurihaus/web-design-system'; // 루트. 첫
|
|
|
380
426
|
|
|
381
427
|
**언제 쓴다.** 알림 켜기처럼 켜고 끄는 설정 하나를 바로 반영할 때 쓴다. `onChange`는 바뀐 켜짐 상태(boolean)를 받는다. `className`·`style`은 루트 버튼에 붙는다. `label`을 주지 않으면 `aria-label`로 이름을 준다.
|
|
382
428
|
|
|
429
|
+
`track`을 주면 켜짐 상태가 바뀔 때마다 `change`와 `'on'`·`'off'`를 `value`에 담아 사용 로그로 보낸다.
|
|
430
|
+
|
|
383
431
|
**쓰지 않는다.** 제출 버튼을 눌러야 반영되는 폼 항목이나 동의 여부는 Checkbox를, 여러 선택지 중 하나는 Radio를 쓴다.
|
|
384
432
|
|
|
385
433
|
```tsx
|
|
@@ -393,10 +441,12 @@ import { Switch } from '@nurihaus/web-design-system'; // 루트. 첫
|
|
|
393
441
|
| `className` | `string` | | |
|
|
394
442
|
| `size` | `'s' \| 'm' \| 'l'` | | `'m'` |
|
|
395
443
|
| `label` | `ReactNode` | | |
|
|
444
|
+
| `track` | `string` | | |
|
|
396
445
|
| `disabled` | `boolean` | | |
|
|
397
446
|
| `defaultChecked` | `boolean` | | |
|
|
398
447
|
| `id` | `string` | 예 | |
|
|
399
448
|
| `onChange` | `((checked: boolean) => void)` | | |
|
|
449
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
400
450
|
| `checked` | `boolean` | | |
|
|
401
451
|
|
|
402
452
|
이 밖에 React·HTML 기본 속성 270개를 받는다.
|
|
@@ -410,6 +460,8 @@ import { TextArea } from '@nurihaus/web-design-system'; // 루트.
|
|
|
410
460
|
|
|
411
461
|
**언제 쓴다.** 메모·설명처럼 여러 줄 텍스트를 입력받을 때 쓴다. 위 라벨(`title`), 아래 안내 문구(`helperText`)를 함께 붙일 수 있고, `isError`가 true면 `helperText`가 오류 스타일로 바뀐다. 높이는 `rows`가 정하고 `size`는 글자 크기와 안쪽 여백만 바꾼다. `resize`는 `'vertical'`(기본)·`'none'` 중 고른다. `className`·`style`은 textarea를 감싸는 테두리 요소에 붙고, `ref`는 textarea 요소를 가리킨다.
|
|
412
462
|
|
|
463
|
+
`track`을 주면 포커스가 빠질 때 값이 포커스를 받을 때와 다르면 `change`를 한 번 사용 로그로 보낸다. 값은 싣지 않는다. 사용자가 입력한 글자는 로그에 들어가지 않는다.
|
|
464
|
+
|
|
413
465
|
**쓰지 않는다.** 한 줄 입력은 TextField를 쓴다. 정해진 값 중에서 고르는 입력은 DropDown이나 Radio를 쓴다.
|
|
414
466
|
|
|
415
467
|
```tsx
|
|
@@ -423,9 +475,11 @@ import { TextArea } from '@nurihaus/web-design-system'; // 루트.
|
|
|
423
475
|
| `className` | `string` | | |
|
|
424
476
|
| `size` | `'s' \| 'm'` | | `'s'` |
|
|
425
477
|
| `title` | `ReactNode` | | |
|
|
478
|
+
| `track` | `string` | | |
|
|
426
479
|
| `name` | `string` | 예 | |
|
|
427
480
|
| `value` | `string` | | |
|
|
428
481
|
| `defaultValue` | `string` | | |
|
|
482
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
429
483
|
| `width` | `string \| number` | | `'100%'` |
|
|
430
484
|
| `resize` | `'none' \| 'vertical'` | | `'vertical'` |
|
|
431
485
|
| `helperText` | `ReactNode` | | |
|
|
@@ -455,8 +509,10 @@ import { Toast } from '@nurihaus/web-design-system'; // 루트. 첫
|
|
|
455
509
|
| `className` | `string` | | |
|
|
456
510
|
| `style` | `CSSProperties` | | |
|
|
457
511
|
| `title` | `ReactNode` | 예 | |
|
|
512
|
+
| `track` | `string` | | |
|
|
458
513
|
| `onPause` | `(() => void)` | | |
|
|
459
514
|
| `variant` | `'secondary' \| 'default' \| 'success' \| 'warning' \| 'error'` | | `'default'` |
|
|
515
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
460
516
|
| `onResume` | `(() => void)` | | |
|
|
461
517
|
| `open` | `boolean` | | |
|
|
462
518
|
| `defaultOpen` | `boolean` | | |
|
|
@@ -503,6 +559,8 @@ import { Pagination } from '@nurihaus/web-design-system'; // 루트.
|
|
|
503
559
|
|
|
504
560
|
**언제 쓴다.** 목록이나 검색 결과가 여러 페이지로 나뉘어 있고 사용자가 번호로 페이지를 고를 때 쓴다. `totalPages`는 필수다. 현재 페이지는 `page`(controlled)·`defaultPage`(uncontrolled)로 주고, `onPageChange`는 새 페이지 번호(1부터)를 받는다. 1과 마지막 페이지는 항상 보이고, 현재 페이지 양옆 `siblingCount`(기본 1)개를 보이며 사이가 벌어지면 `…`를 넣는다. `className`·`style`은 루트 `nav`에 붙는다. `aria-label`을 주면 nav 이름을 바꾼다(기본 "페이지 탐색").
|
|
505
561
|
|
|
562
|
+
`track`을 주면 페이지가 바뀔 때 `change`와 새 페이지 번호(문자열)를 `value`에 담아 사용 로그로 보낸다. 현재 페이지를 다시 누르면 보내지 않는다.
|
|
563
|
+
|
|
506
564
|
**쓰지 않는다.** 스크롤로 계속 불러오는 목록이나 "더 보기" 버튼으로 이어 붙이는 목록에는 쓰지 않는다. 화면 안의 내용 영역을 바꾸는 탭 전환은 Tabs를 쓴다.
|
|
507
565
|
|
|
508
566
|
```tsx
|
|
@@ -514,7 +572,9 @@ import { Pagination } from '@nurihaus/web-design-system'; // 루트.
|
|
|
514
572
|
| prop | 타입 | 필수 | 기본값 |
|
|
515
573
|
| --- | --- | --- | --- |
|
|
516
574
|
| `size` | `'s' \| 'm'` | | `'m'` |
|
|
575
|
+
| `track` | `string` | | |
|
|
517
576
|
| `disabled` | `boolean` | | |
|
|
577
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
518
578
|
| `page` | `number` | | |
|
|
519
579
|
| `totalPages` | `number` | 예 | |
|
|
520
580
|
| `defaultPage` | `number` | | |
|
|
@@ -562,6 +622,8 @@ import { Modal } from '@nurihaus/web-design-system'; // 루트. 첫
|
|
|
562
622
|
| `onOpenChange` | `((open: boolean) => void)` | | |
|
|
563
623
|
| `className` | `string` | | |
|
|
564
624
|
| `style` | `CSSProperties` | | |
|
|
625
|
+
| `track` | `string` | | |
|
|
626
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
565
627
|
|
|
566
628
|
이 밖에 React·HTML 기본 속성 2개를 받는다.
|
|
567
629
|
|
|
@@ -599,6 +661,8 @@ import { Drawer } from '@nurihaus/web-design-system'; // 루트. 첫
|
|
|
599
661
|
| `onOpenChange` | `((open: boolean) => void)` | | |
|
|
600
662
|
| `className` | `string` | | |
|
|
601
663
|
| `style` | `CSSProperties` | | |
|
|
664
|
+
| `track` | `string` | | |
|
|
665
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
602
666
|
|
|
603
667
|
이 밖에 React·HTML 기본 속성 2개를 받는다.
|
|
604
668
|
|
|
@@ -638,6 +702,8 @@ import { Breadcrumb } from '@nurihaus/web-design-system'; // 루트.
|
|
|
638
702
|
|
|
639
703
|
**언제 쓴다.** 계층이 있는 화면에서 현재 위치와 상위 경로를 한 줄로 보여 줄 때 쓴다. `items`의 마지막 항목이 현재 위치라 링크가 아니고 `aria-current="page"`가 붙는다. `href`가 있는 항목은 `<a>` 링크로, `onItemClick`은 클릭한 항목의 `id`를 받는다. Next.js 나 React Router 안에서는 `linkComponent={Link}`를 넘겨 라우터 링크로 그린다. 넘기지 않으면 일반 `<a>`라 페이지가 새로 고쳐진다. `className`·`style`은 `nav` 루트에 붙는다.
|
|
640
704
|
|
|
705
|
+
`track`을 주면 링크 항목을 누를 때 `navigate`와 그 항목의 `id`를 `value`에 담아 사용 로그로 보낸다. 마지막(현재 위치) 항목은 링크가 아니라 보내지 않는다.
|
|
706
|
+
|
|
641
707
|
**쓰지 않는다.** 같은 깊이의 화면을 오가는 데는 Tabs를, 사이드바 메뉴에는 CollapsibleMenu를 쓴다. 계층이 한 단계뿐이면 쓰지 않는다.
|
|
642
708
|
|
|
643
709
|
```tsx
|
|
@@ -661,6 +727,8 @@ import { Breadcrumb } from '@nurihaus/web-design-system'; // 루트.
|
|
|
661
727
|
| `linkComponent` | `ElementType` | | |
|
|
662
728
|
| `className` | `string` | | |
|
|
663
729
|
| `style` | `CSSProperties` | | |
|
|
730
|
+
| `track` | `string` | | |
|
|
731
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
664
732
|
|
|
665
733
|
이 밖에 React·HTML 기본 속성 2개를 받는다.
|
|
666
734
|
|
|
@@ -714,6 +782,8 @@ import { DropDown } from '@nurihaus/web-design-system'; // 루트.
|
|
|
714
782
|
| `position` | `'popper' \| 'item-aligned'` | | |
|
|
715
783
|
| `className` | `string` | | |
|
|
716
784
|
| `style` | `CSSProperties` | | |
|
|
785
|
+
| `track` | `string` | | |
|
|
786
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
717
787
|
|
|
718
788
|
이 밖에 React·HTML 기본 속성 2개를 받는다.
|
|
719
789
|
|
|
@@ -726,6 +796,8 @@ import { CollapsibleMenu } from '@nurihaus/web-design-system'; //
|
|
|
726
796
|
|
|
727
797
|
**언제 쓴다.** 사이드바 같은 세로 내비게이션 메뉴에 쓴다. `children`이 있는 항목은 펼치고 접는 그룹이 되고, 없는 항목은 `href`가 있으면 링크, 없으면 버튼으로 렌더되며, `activeKey` 항목과 그 상위 그룹이 강조된다. 링크는 기본으로 `<a>`다. 라우터의 링크로 바꾸려면 `linkComponent`에 넘긴다. 받는 props는 `href`·`className`·`children`·`onClick`·`aria-current`·`aria-disabled`이고, 그대로 링크에 전달하면 된다.
|
|
728
798
|
|
|
799
|
+
`track`을 주면 링크·버튼 항목을 고를 때 `navigate`와 그 항목의 `key`를 `value`에 담아 사용 로그로 보낸다. 그룹을 펼치고 접는 것은 보내지 않는다.
|
|
800
|
+
|
|
729
801
|
**쓰지 않는다.** 같은 화면 안에서 패널을 바꾸는 용도는 Tabs를 쓴다. 본문 콘텐츠를 접고 펼치는 아코디언 용도로는 쓰지 않는다(`<nav>`로 렌더된다). 값을 고르는 폼 입력은 DropDown을 쓴다.
|
|
730
802
|
|
|
731
803
|
Next.js 에서는 `next/link` 의 `Link` 를 그대로 넘긴다.
|
|
@@ -770,6 +842,8 @@ import Link from 'next/link';
|
|
|
770
842
|
| `linkComponent` | `ComponentType<CollapsibleMenuLinkProps>` | | |
|
|
771
843
|
| `className` | `string` | | |
|
|
772
844
|
| `style` | `CSSProperties` | | |
|
|
845
|
+
| `track` | `string` | | |
|
|
846
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
773
847
|
|
|
774
848
|
이 밖에 React·HTML 기본 속성 2개를 받는다.
|
|
775
849
|
|
|
@@ -813,6 +887,8 @@ import { Tooltip } from '@nurihaus/web-design-system'; // 루트.
|
|
|
813
887
|
|
|
814
888
|
**언제 쓴다.** 아이콘이나 짧은 라벨에 마우스를 올렸을 때 짧은 설명을 띄울 때 쓴다. `trigger`에는 DOM 요소 하나(예: `<span>`)를 넘기고 `direction`으로 뜨는 방향을 고른다. 조건이 맞을 때만 띄우려면 `open`을 제어하지 말고 `disabled`를 쓴다(예: 사이드바가 접혔을 때만 `disabled={!collapsed}`). `disabled`이면 `trigger`만 그려 툴팁이 열린 채 남지 않는다.
|
|
815
889
|
|
|
890
|
+
`track`을 주면 툴팁이 열릴 때 `show`를 사용 로그로 보낸다. 닫힐 때와 `disabled`일 때는 보내지 않는다.
|
|
891
|
+
|
|
816
892
|
**쓰지 않는다.** 툴팁 안에 링크나 버튼처럼 클릭할 내용을 넣지 않는다. 툴팁 위로 마우스를 옮기면 닫힌다. 배지에 설명을 붙일 때는 OptionBadge, IconTextBadge의 `tooltip` prop을 쓴다.
|
|
817
893
|
|
|
818
894
|
```tsx
|
|
@@ -832,6 +908,8 @@ import { Tooltip } from '@nurihaus/web-design-system'; // 루트.
|
|
|
832
908
|
| `onOpenChange` | `((open: boolean) => void)` | | |
|
|
833
909
|
| `delayDuration` | `number` | | |
|
|
834
910
|
| `disableHoverableContent` | `boolean` | | |
|
|
911
|
+
| `track` | `string` | | |
|
|
912
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
835
913
|
|
|
836
914
|
이 밖에 React·HTML 기본 속성 2개를 받는다.
|
|
837
915
|
|
|
@@ -895,6 +973,8 @@ import { Tabs } from '@nurihaus/web-design-system'; // 루트. 첫
|
|
|
895
973
|
| `onValueChange` | `((id: TabsValue) => void)` | | |
|
|
896
974
|
| `className` | `string` | | |
|
|
897
975
|
| `style` | `CSSProperties` | | |
|
|
976
|
+
| `track` | `string` | | |
|
|
977
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
898
978
|
|
|
899
979
|
이 밖에 React·HTML 기본 속성 2개를 받는다.
|
|
900
980
|
|
|
@@ -1035,7 +1115,7 @@ import { Icon } from '@nurihaus/web-design-system/icon'; // 이 컴포넌트
|
|
|
1035
1115
|
import { Icon } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
|
|
1036
1116
|
```
|
|
1037
1117
|
|
|
1038
|
-
**언제 쓴다.** 화면에 아이콘을 그릴 때 쓴다. 모양은 Phosphor(MIT) 에서 고른 것만 있고, `name` 으로 고른다. 색은 글자색(`currentColor`)을 따르므로 감싼 요소의 `color` 로 바꾼다. 꺼진 상태는 선(`weight="regular"`, 기본), 켜진 상태나 강조는 채움(`weight="fill"`)을 쓴다. 크기는 `s`(18) · `m`(20) · `l`(24, 기본). `className`·`style` 은 `<svg>` 에 붙는다.
|
|
1118
|
+
**언제 쓴다.** 화면에 아이콘을 그릴 때 쓴다. 모양은 Phosphor(MIT) 에서 고른 것만 있고, `name` 으로 고른다. 색은 글자색(`currentColor`)을 따르므로 감싼 요소의 `color` 로 바꾼다. 꺼진 상태는 선(`weight="regular"`, 기본), 켜진 상태나 강조는 채움(`weight="fill"`)을 쓴다. 크기는 `xs`(16) · `s`(18) · `m`(20) · `l`(24, 기본) · `xl`(32). `className`·`style` 은 `<svg>` 에 붙는다.
|
|
1039
1119
|
|
|
1040
1120
|
글자 없이 아이콘만으로 뜻을 전하면(닫기 버튼 등) `label` 을 준다. 없으면 화면 낭독기가 건너뛴다.
|
|
1041
1121
|
|
|
@@ -1059,9 +1139,9 @@ import { Icon } from '@nurihaus/web-design-system'; // 루트. 첫
|
|
|
1059
1139
|
|
|
1060
1140
|
| prop | 타입 | 필수 | 기본값 |
|
|
1061
1141
|
| --- | --- | --- | --- |
|
|
1062
|
-
| `size` | `'s' \| 'm' \| 'l'` | | `'l'` |
|
|
1142
|
+
| `size` | `'xs' \| 's' \| 'm' \| 'l' \| 'xl'` | | `'l'` |
|
|
1063
1143
|
| `label` | `string` | | |
|
|
1064
|
-
| `name` | `'link' \| 'image' \| 'x' \| 'warning' \| 'house' \| 'megaphone-simple' \| 'chats-circle' \| 'user-circle' \| 'bell' \| 'caret-left' \| 'magnifying-glass' \| 'dots-three' \| 'gear-six' \| 'chat-circle' \| 'paper-plane-tilt' \| 'plus' \| 'camera' \| 'video-camera' \| 'upload-simple' \| 'calendar-blank' \| 'clock' \| 'map-pin' \| 'truck' \| 'ticket' \| 'qr-code' \| 'sparkle' \| 'gift' \| 'wallet' \| 'bank' \| 'credit-card' \| 'check-circle' \| 'check' \| 'info' \| 'question' \| 'lock' \| 'pencil-simple' \| 'trash' \| 'copy' \| 'share-network' \| 'eye' \| 'sliders-horizontal' \| 'heart' \| 'star' \| 'globe' \| 'sign-out' \| 'caret-right' \| 'arrow-right' \| 'instagram-logo' \| 'tiktok-logo' \| 'youtube-logo'` | 예 | |
|
|
1144
|
+
| `name` | `'link' \| 'image' \| 'x' \| 'warning' \| 'house' \| 'megaphone-simple' \| 'chats-circle' \| 'user-circle' \| 'bell' \| 'caret-left' \| 'magnifying-glass' \| 'dots-three' \| 'gear-six' \| 'chat-circle' \| 'paper-plane-tilt' \| 'plus' \| 'camera' \| 'video-camera' \| 'play' \| 'upload-simple' \| 'calendar-blank' \| 'clock' \| 'map-pin' \| 'truck' \| 'ticket' \| 'qr-code' \| 'sparkle' \| 'gift' \| 'wallet' \| 'bank' \| 'credit-card' \| 'check-circle' \| 'check' \| 'info' \| 'question' \| 'lock' \| 'pencil-simple' \| 'trash' \| 'copy' \| 'share-network' \| 'eye' \| 'sliders-horizontal' \| 'heart' \| 'star' \| 'globe' \| 'sign-out' \| 'caret-right' \| 'arrow-right' \| 'instagram-logo' \| 'tiktok-logo' \| 'youtube-logo'` | 예 | |
|
|
1065
1145
|
| `weight` | `'fill' \| 'regular'` | | |
|
|
1066
1146
|
|
|
1067
1147
|
이 밖에 React·HTML 기본 속성 474개를 받는다.
|
|
@@ -1077,7 +1157,7 @@ import { BottomNav } from '@nurihaus/web-design-system'; // 루트.
|
|
|
1077
1157
|
|
|
1078
1158
|
화면 아래에 고정(`position: fixed`)되고 내용 위에 떠 있다. 화면 본문은 아래를 `calc(var(--bottom-nav-space) + env(safe-area-inset-bottom))` 만큼 비워 마지막 내용이 가려지지 않게 한다. `className`·`style` 은 `<nav>` 에 붙는다.
|
|
1079
1159
|
|
|
1080
|
-
링크는 기본으로 `<a>` 다. 라우터의 링크로 바꾸려면 `linkComponent` 에 넘긴다. 받는 props 는 `href`·`className`·`children`·`aria-current` 이고, 그대로 링크에 전달하면 된다.
|
|
1160
|
+
링크는 기본으로 `<a>` 다. 라우터의 링크로 바꾸려면 `linkComponent` 에 넘긴다. 받는 props 는 `href`·`className`·`children`·`aria-current`·`onClick` 이고, 그대로 링크에 전달하면 된다. `onClick` 을 빠뜨리면 `track` 로그가 나가지 않는다.
|
|
1081
1161
|
|
|
1082
1162
|
배지는 `badge` 로 단다. `count` 가 없으면 점, 있으면 숫자(99 넘으면 99+)다. `label` 은 화면 낭독기가 읽는 말이다.
|
|
1083
1163
|
|
|
@@ -1114,6 +1194,8 @@ import Link from 'next/link';
|
|
|
1114
1194
|
| `linkComponent` | `ComponentType<BottomNavLinkProps>` | | |
|
|
1115
1195
|
| `className` | `string` | | |
|
|
1116
1196
|
| `style` | `CSSProperties` | | |
|
|
1197
|
+
| `track` | `string` | | |
|
|
1198
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
1117
1199
|
|
|
1118
1200
|
이 밖에 React·HTML 기본 속성 2개를 받는다.
|
|
1119
1201
|
|
|
@@ -1186,9 +1268,38 @@ import { ChipGroup } from '@nurihaus/web-design-system'; // 루트.
|
|
|
1186
1268
|
| `label` | `string` | 예 | |
|
|
1187
1269
|
| `className` | `string` | | |
|
|
1188
1270
|
| `style` | `CSSProperties` | | |
|
|
1271
|
+
| `track` | `string` | | |
|
|
1272
|
+
| `trackProps` | `Record<string, string \| number \| boolean>` | | |
|
|
1189
1273
|
|
|
1190
1274
|
이 밖에 React·HTML 기본 속성 2개를 받는다.
|
|
1191
1275
|
|
|
1276
|
+
## LogProvider
|
|
1277
|
+
|
|
1278
|
+
```ts
|
|
1279
|
+
import { LogProvider } from '@nurihaus/web-design-system/logging'; // 이 컴포넌트만 싣는다 (권장)
|
|
1280
|
+
import { LogProvider } from '@nurihaus/web-design-system'; // 루트. 첫 로드 JS 가 커진다
|
|
1281
|
+
```
|
|
1282
|
+
|
|
1283
|
+
**언제 쓴다.** 앱 루트에 한 번 두고 사용 로그를 받는다. 디자인시스템 컴포넌트에 `track` 을 주면 그 컴포넌트의 상호작용이 이벤트 하나(`LogEvent`)로 `onEvent` 에 온다. 이벤트를 어느 로그 수집기로 보낼지는 `onEvent` 안에서 앱이 정한다. `onEvent` 가 던져도 화면 동작은 멈추지 않는다.
|
|
1284
|
+
`track` 에는 `'report/download'` 처럼 개발자가 정한 이름을 쓴다. 이벤트의 `value` 에는 탭 id·칩 id·옵션 value 처럼 개발자가 정한 id 만 들어가고 사용자가 입력한 글자는 들어가지 않는다. 더 붙일 값은 `trackProps` 로 명시한다.
|
|
1285
|
+
LogProvider 가 없거나 `track` 을 주지 않으면 아무것도 보내지 않는다.
|
|
1286
|
+
컴포넌트 밖의 로그(화면 진입, 직접 만든 요소)는 `useLog()` 가 돌려주는 함수에 `{ component, action, track }` 을 넘긴다. `timestamp` 는 자동으로 붙는다.
|
|
1287
|
+
|
|
1288
|
+
**쓰지 않는다.** 에러 보고에 쓰지 않는다. 에러는 앱의 에러 처리에서 따로 남긴다. 화면마다 LogProvider 를 겹쳐 두지 않는다. 안쪽 Provider 가 바깥 것을 가린다.
|
|
1289
|
+
|
|
1290
|
+
```tsx
|
|
1291
|
+
<LogProvider onEvent={(event) => console.log(event)}>
|
|
1292
|
+
<CTAButton text="리포트 받기" track="report/download" trackProps={{ format: "csv" }} />
|
|
1293
|
+
</LogProvider>
|
|
1294
|
+
```
|
|
1295
|
+
|
|
1296
|
+
### props
|
|
1297
|
+
|
|
1298
|
+
| prop | 타입 | 필수 | 기본값 |
|
|
1299
|
+
| --- | --- | --- | --- |
|
|
1300
|
+
| `onEvent` | `(event: LogEvent) => void` | 예 | |
|
|
1301
|
+
| `children` | `ReactNode` | | |
|
|
1302
|
+
|
|
1192
1303
|
## 아직 없는 것
|
|
1193
1304
|
|
|
1194
1305
|
아래는 디자인 시스템에 없다. 비슷한 이름의 컴포넌트를 지어내 import 하지 않는다.
|
package/dist/ai/tokens.md
CHANGED
|
@@ -355,9 +355,11 @@
|
|
|
355
355
|
| `--bottom-nav-badge-count` | `18px` | 폭 |
|
|
356
356
|
| `--glass-blur` | `18px` | 폭 |
|
|
357
357
|
| `--step-bar-height` | `4px` | 진행 단계 바 |
|
|
358
|
+
| `--icon-size-xs` | `16px` | 그 밖의 치수 |
|
|
358
359
|
| `--icon-size-s` | `18px` | 그 밖의 치수 |
|
|
359
360
|
| `--icon-size-m` | `20px` | 그 밖의 치수 |
|
|
360
361
|
| `--icon-size-l` | `24px` | 그 밖의 치수 |
|
|
362
|
+
| `--icon-size-xl` | `32px` | 그 밖의 치수 |
|
|
361
363
|
| `--tooltip-arrow` | `8px` | 그 밖의 치수 |
|
|
362
364
|
| `--spinner-stroke` | `3px` | 그 밖의 치수 |
|
|
363
365
|
| `--overlay-spinner-size` | `64px` | 그 밖의 치수 |
|
package/dist/avatar.js
CHANGED
|
@@ -280,7 +280,7 @@ module.exports = x({ ["jsx"]: () => (__WEBPACK_EXTERNAL_MODULE_react_jsx_runtime
|
|
|
280
280
|
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
|
281
281
|
/******/ // [resolve, Promise] = chunk loading, 0 = chunk loaded
|
|
282
282
|
/******/ var installedChunks = {
|
|
283
|
-
/******/
|
|
283
|
+
/******/ 8716: 0
|
|
284
284
|
/******/ };
|
|
285
285
|
/******/
|
|
286
286
|
/******/ var installChunk = (data) => {
|
|
@@ -320,17 +320,17 @@ module.exports = x({ ["jsx"]: () => (__WEBPACK_EXTERNAL_MODULE_react_jsx_runtime
|
|
|
320
320
|
/******/
|
|
321
321
|
/************************************************************************/
|
|
322
322
|
/******/
|
|
323
|
-
/******/ import * as __webpack_chunk_1__ from "./chunk-
|
|
323
|
+
/******/ import * as __webpack_chunk_1__ from "./chunk-6364.js";
|
|
324
324
|
/******/ __nuri_require__.C(__webpack_chunk_1__);
|
|
325
|
-
/******/ import * as __webpack_chunk_2__ from "./chunk-
|
|
325
|
+
/******/ import * as __webpack_chunk_2__ from "./chunk-2777.js";
|
|
326
326
|
/******/ __nuri_require__.C(__webpack_chunk_2__);
|
|
327
|
-
/******/ import * as __webpack_chunk_3__ from "./chunk-
|
|
327
|
+
/******/ import * as __webpack_chunk_3__ from "./chunk-7298.js";
|
|
328
328
|
/******/ __nuri_require__.C(__webpack_chunk_3__);
|
|
329
329
|
/******/
|
|
330
330
|
/******/ // startup
|
|
331
331
|
/******/ // Load entry module and return exports
|
|
332
332
|
/******/ // This entry module depends on other loaded chunks and execution need to be delayed
|
|
333
|
-
/******/ var __webpack_exports__ = __nuri_require__.O(undefined, [
|
|
333
|
+
/******/ var __webpack_exports__ = __nuri_require__.O(undefined, [6364,2777,7298], () => (__nuri_require__(5468)))
|
|
334
334
|
/******/ __webpack_exports__ = __nuri_require__.O(__webpack_exports__);
|
|
335
335
|
/******/ const __webpack_exports__default = __webpack_exports__.A;
|
|
336
336
|
/******/ export { __webpack_exports__default as default };
|
package/dist/bottom-nav.js
CHANGED
|
@@ -17,6 +17,8 @@ __nuri_require__.d(__webpack_exports__, {
|
|
|
17
17
|
var jsx_runtime_ = __nuri_require__(612);
|
|
18
18
|
// EXTERNAL MODULE: external {"root":"React","commonjs2":"react","commonjs":"react","amd":"react","module":"react"}
|
|
19
19
|
var external_root_React_commonjs2_react_commonjs_react_amd_react_module_react_ = __nuri_require__(1041);
|
|
20
|
+
// EXTERNAL MODULE: ./helpers/hooks/useTrack.ts
|
|
21
|
+
var useTrack = __nuri_require__(4560);
|
|
20
22
|
// EXTERNAL MODULE: ./helpers/utils/classNames.js
|
|
21
23
|
var classNames = __nuri_require__(3274);
|
|
22
24
|
// EXTERNAL MODULE: ./helpers/utils/getMergedProps.ts
|
|
@@ -118,6 +120,7 @@ var bottom_nav_assign = undefined && undefined.__assign || function () {
|
|
|
118
120
|
|
|
119
121
|
|
|
120
122
|
|
|
123
|
+
|
|
121
124
|
var Anchor = function Anchor(props) {
|
|
122
125
|
return (0,jsx_runtime_.jsx)("a", bottom_nav_assign({}, props));
|
|
123
126
|
};
|
|
@@ -130,7 +133,13 @@ var BottomNav = /*#__PURE__*/(0,external_root_React_commonjs2_react_commonjs_rea
|
|
|
130
133
|
items = _a.items,
|
|
131
134
|
value = _a.value,
|
|
132
135
|
label = _a.label,
|
|
133
|
-
linkComponent = _a.linkComponent
|
|
136
|
+
linkComponent = _a.linkComponent,
|
|
137
|
+
track = _a.track,
|
|
138
|
+
trackProps = _a.trackProps;
|
|
139
|
+
var emit = (0,useTrack/* useTrack */.n)('BottomNav', {
|
|
140
|
+
track: track,
|
|
141
|
+
trackProps: trackProps
|
|
142
|
+
});
|
|
134
143
|
var Link = linkComponent !== null && linkComponent !== void 0 ? linkComponent : Anchor;
|
|
135
144
|
var activeIndex = items.findIndex(function (item) {
|
|
136
145
|
return item.id === value;
|
|
@@ -153,6 +162,9 @@ var BottomNav = /*#__PURE__*/(0,external_root_React_commonjs2_react_commonjs_rea
|
|
|
153
162
|
className: itemClassName,
|
|
154
163
|
href: item.href,
|
|
155
164
|
"aria-current": isActive ? 'page' : undefined,
|
|
165
|
+
onClick: function onClick() {
|
|
166
|
+
return emit('navigate', item.id);
|
|
167
|
+
},
|
|
156
168
|
children: [(0,jsx_runtime_.jsx)("span", {
|
|
157
169
|
className: 'bottom-nav-label',
|
|
158
170
|
children: item.label
|
|
@@ -244,7 +256,7 @@ var x = (y) => {
|
|
|
244
256
|
var x = {}; __nuri_require__.d(x, y); return x
|
|
245
257
|
}
|
|
246
258
|
var y = (x) => (() => (x))
|
|
247
|
-
module.exports = x({ ["forwardRef"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.forwardRef) });
|
|
259
|
+
module.exports = x({ ["createContext"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.createContext), ["forwardRef"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.forwardRef), ["useCallback"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.useCallback), ["useContext"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.useContext), ["useRef"]: () => (__WEBPACK_EXTERNAL_MODULE_react__.useRef) });
|
|
248
260
|
|
|
249
261
|
/***/ },
|
|
250
262
|
|
|
@@ -349,8 +361,8 @@ module.exports = x({ ["jsx"]: () => (__WEBPACK_EXTERNAL_MODULE_react_jsx_runtime
|
|
|
349
361
|
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
|
|
350
362
|
/******/ // [resolve, Promise] = chunk loading, 0 = chunk loaded
|
|
351
363
|
/******/ var installedChunks = {
|
|
352
|
-
/******/
|
|
353
|
-
/******/
|
|
364
|
+
/******/ 918: 0,
|
|
365
|
+
/******/ 6480: 0
|
|
354
366
|
/******/ };
|
|
355
367
|
/******/
|
|
356
368
|
/******/ var installChunk = (data) => {
|
|
@@ -390,17 +402,19 @@ module.exports = x({ ["jsx"]: () => (__WEBPACK_EXTERNAL_MODULE_react_jsx_runtime
|
|
|
390
402
|
/******/
|
|
391
403
|
/************************************************************************/
|
|
392
404
|
/******/
|
|
393
|
-
/******/ import * as __webpack_chunk_1__ from "./chunk-
|
|
405
|
+
/******/ import * as __webpack_chunk_1__ from "./chunk-6364.js";
|
|
394
406
|
/******/ __nuri_require__.C(__webpack_chunk_1__);
|
|
395
|
-
/******/ import * as __webpack_chunk_2__ from "./chunk-
|
|
407
|
+
/******/ import * as __webpack_chunk_2__ from "./chunk-4560.js";
|
|
396
408
|
/******/ __nuri_require__.C(__webpack_chunk_2__);
|
|
397
|
-
/******/ import * as __webpack_chunk_3__ from "./chunk-
|
|
409
|
+
/******/ import * as __webpack_chunk_3__ from "./chunk-7298.js";
|
|
398
410
|
/******/ __nuri_require__.C(__webpack_chunk_3__);
|
|
411
|
+
/******/ import * as __webpack_chunk_4__ from "./chunk-7653.js";
|
|
412
|
+
/******/ __nuri_require__.C(__webpack_chunk_4__);
|
|
399
413
|
/******/
|
|
400
414
|
/******/ // startup
|
|
401
415
|
/******/ // Load entry module and return exports
|
|
402
416
|
/******/ // This entry module depends on other loaded chunks and execution need to be delayed
|
|
403
|
-
/******/ var __webpack_exports__ = __nuri_require__.O(undefined, [
|
|
417
|
+
/******/ var __webpack_exports__ = __nuri_require__.O(undefined, [6364,4560,7298,7653], () => (__nuri_require__(1768)))
|
|
404
418
|
/******/ __webpack_exports__ = __nuri_require__.O(__webpack_exports__);
|
|
405
419
|
/******/ const __webpack_exports__default = __webpack_exports__.A;
|
|
406
420
|
/******/ export { __webpack_exports__default as default };
|