@uniai-fe/uds-primitives 0.11.0 → 0.12.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 +38 -453
- package/dist/styles.css +370 -327
- package/package.json +2 -2
- package/src/components/input/index.tsx +1 -1
- package/src/components/input/markup/time/Template.tsx +412 -0
- package/src/components/input/markup/time/Trigger.tsx +233 -0
- package/src/components/input/markup/time/index.tsx +9 -2
- package/src/components/input/styles/time.scss +160 -317
- package/src/components/input/styles/variables.scss +9 -47
- package/src/components/input/types/time.ts +263 -120
- package/src/components/time-picker/img/minus.svg +3 -0
- package/src/components/time-picker/img/plus.svg +3 -0
- package/src/components/time-picker/index.scss +1 -0
- package/src/components/time-picker/index.tsx +11 -0
- package/src/components/time-picker/markup/Footer.tsx +53 -0
- package/src/components/time-picker/markup/HourSection.tsx +72 -0
- package/src/components/time-picker/markup/MinuteSection.tsx +68 -0
- package/src/components/time-picker/markup/Summary.tsx +19 -0
- package/src/components/time-picker/markup/Template.tsx +86 -0
- package/src/components/time-picker/markup/index.tsx +10 -0
- package/src/components/time-picker/styles/index.scss +2 -0
- package/src/components/time-picker/styles/template.scss +174 -0
- package/src/components/time-picker/styles/variables.scss +64 -0
- package/src/components/time-picker/types/index.ts +1 -0
- package/src/components/time-picker/types/time-picker.ts +193 -0
- package/src/components/time-picker/utils/index.ts +1 -0
- package/src/components/time-picker/utils/time.ts +110 -0
- package/src/index.scss +1 -0
- package/src/index.tsx +1 -0
- package/src/components/input/markup/time/Picker.tsx +0 -378
package/README.md
CHANGED
|
@@ -1,496 +1,81 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `@uniai-fe/uds-primitives`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Foundation token 위의 기초 UI와 공통 interaction을 제공한다. 공통 책임과 convention은
|
|
4
|
+
[`../DESIGN-SYSTEM-GUIDE.md`](../DESIGN-SYSTEM-GUIDE.md)를 따른다.
|
|
4
5
|
|
|
5
6
|
## 설치
|
|
6
7
|
|
|
8
|
+
현재 peer range는 `package.json`이 권위다.
|
|
9
|
+
|
|
7
10
|
```bash
|
|
8
11
|
pnpm add @uniai-fe/uds-foundation @uniai-fe/util-functions @uniai-fe/uds-primitives
|
|
9
12
|
```
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
`@uniai-fe/uds-primitives`는 디자인 토큰과 유틸리티 로직을 공유하기 위해 다음 패키지를 **같이 설치**해야 합니다.
|
|
14
|
-
|
|
15
|
-
- `@uniai-fe/uds-foundation@^0.0.1`
|
|
16
|
-
- `@uniai-fe/util-functions@^0.2.3`
|
|
17
|
-
- `react@>=19`, `react-dom@>=19`
|
|
18
|
-
- `react-hook-form@>=7`
|
|
19
|
-
|
|
20
|
-
peer dependency가 빠져 있을 경우 앱 번들 시점에 에러가 발생하니, 위 목록을 프로젝트 `package.json`에 명시해 주세요.
|
|
14
|
+
Raw TypeScript package를 사용하는 Next.js 앱은 현재 package contract에 맞게
|
|
15
|
+
`transpilePackages`를 설정한다.
|
|
21
16
|
|
|
22
17
|
```ts
|
|
23
|
-
// next.config.ts
|
|
24
18
|
const nextConfig = {
|
|
25
19
|
transpilePackages: ["@uniai-fe/uds-foundation", "@uniai-fe/uds-primitives"],
|
|
26
20
|
};
|
|
27
|
-
export default nextConfig;
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
CSS-only 프로젝트는 앱 루트에서 foundation CSS를 먼저 로드한 뒤 primitives CSS를 로드합니다. primitives CSS는 foundation token이 이미 로드되어 있다고 가정합니다.
|
|
31
|
-
|
|
32
|
-
```ts
|
|
33
|
-
import "@uniai-fe/uds-foundation/css";
|
|
34
|
-
import "@uniai-fe/uds-primitives/css";
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## 사용 예시
|
|
38
|
-
|
|
39
|
-
```tsx
|
|
40
|
-
import { Button } from "@uniai-fe/uds-primitives";
|
|
41
21
|
|
|
42
|
-
export default
|
|
43
|
-
return (
|
|
44
|
-
<Button.Default fill="solid" size="medium" priority="primary">
|
|
45
|
-
확인
|
|
46
|
-
</Button.Default>
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
## Public import surface
|
|
52
|
-
|
|
53
|
-
`@uniai-fe/uds-primitives`의 공식 안정 public surface는 root namespace import다.
|
|
54
|
-
|
|
55
|
-
```tsx
|
|
56
|
-
import { Button, Input, Select } from "@uniai-fe/uds-primitives";
|
|
22
|
+
export default nextConfig;
|
|
57
23
|
```
|
|
58
24
|
|
|
59
|
-
|
|
60
|
-
- `@uniai-fe/uds-primitives/styles`, `@uniai-fe/uds-primitives/css`, `@uniai-fe/uds-primitives/init/dayjs`, `@uniai-fe/uds-primitives/init/mantine`, `@uniai-fe/uds-primitives/mantine-style`는 package export map에 있는 style/init entry다.
|
|
61
|
-
- `@uniai-fe/uds-primitives/button`, `@uniai-fe/uds-primitives/input` 같은 short category subpath는 현재 안정 public surface로 안내하지 않는다.
|
|
62
|
-
- category subpath 공개 여부는 package contract gate 후보로 남긴다.
|
|
63
|
-
|
|
64
|
-
## 제공 도구 목록
|
|
65
|
-
|
|
66
|
-
아래 목록은 root namespace에서 확인하는 API inventory다. 카테고리 이름은 도구 탐색용이며, category subpath import 가능 여부의 SOT가 아니다.
|
|
25
|
+
## Public entries
|
|
67
26
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
- `Alternate.LoadingIcon`
|
|
71
|
-
- `Alternate.Text`
|
|
72
|
-
- `Alternate.Layout.Container`
|
|
73
|
-
- `Alternate.Layout.Figure`
|
|
74
|
-
- `Alternate.Layout.Title`
|
|
75
|
-
- `Alternate.Layout.Contents`
|
|
76
|
-
- `Alternate.Layout.TextButton`
|
|
77
|
-
- `Alternate.Layout.Button`
|
|
78
|
-
- `AlternateEmptyDataProps`
|
|
79
|
-
- `AlternateLoadingDefaultProps`
|
|
80
|
-
- `AlternateLoadingIconProps`
|
|
81
|
-
- `AlternateTextProps`
|
|
82
|
-
- `AlternateLayoutContainerProps`
|
|
83
|
-
- `AlternateLayoutFigureProps`
|
|
84
|
-
- `AlternateLayoutTitleProps`
|
|
85
|
-
- `AlternateLayoutContentsProps`
|
|
86
|
-
- `AlternateLayoutTextButtonProps`
|
|
87
|
-
- `AlternateLayoutButtonProps`
|
|
88
|
-
- `Badge`
|
|
89
|
-
- `BadgeProps`
|
|
90
|
-
- `Chip.Default`
|
|
91
|
-
- `Chip.ClickableStyle`
|
|
92
|
-
- `Chip.InputStyle`
|
|
93
|
-
- `Chip.Label`
|
|
94
|
-
- `Chip.List`
|
|
95
|
-
- `ChipProps`
|
|
96
|
-
- `ChipListRootProps`
|
|
97
|
-
- `ChipListItemData`
|
|
98
|
-
- `Calendar.Root`
|
|
99
|
-
- `Calendar.Container`
|
|
100
|
-
- `Calendar.Header`
|
|
101
|
-
- `Calendar.Body`
|
|
102
|
-
- `Calendar.Footer`
|
|
103
|
-
- `Calendar.Core`
|
|
104
|
-
- `Calendar.Icon`
|
|
105
|
-
- `CalendarValue`
|
|
106
|
-
- `CalendarRootProps`
|
|
107
|
-
- `CalendarContainerProps`
|
|
108
|
-
- `CalendarGridProps`
|
|
109
|
-
- `CalendarDatePickerProps`
|
|
110
|
-
- `Carousel.Provider`
|
|
111
|
-
- `Carousel.Container`
|
|
112
|
-
- `Carousel.Control`
|
|
113
|
-
- `Carousel.Track`
|
|
114
|
-
- `Carousel.Button.Base`
|
|
115
|
-
- `Carousel.Button.Prev`
|
|
116
|
-
- `Carousel.Button.Next`
|
|
117
|
-
- `useCarousel`
|
|
118
|
-
- `useCarouselProviderController`
|
|
119
|
-
- `CarouselProviderProps`
|
|
120
|
-
- `CarouselTrackProps`
|
|
121
|
-
- `CarouselContainerProps`
|
|
122
|
-
- `CarouselControlProps`
|
|
123
|
-
- `CarouselPrevButtonProps`
|
|
124
|
-
- `CarouselNextButtonProps`
|
|
125
|
-
- `DrawerRoot`
|
|
126
|
-
- `DrawerTrigger`
|
|
127
|
-
- `DrawerPortal`
|
|
128
|
-
- `DrawerOverlay`
|
|
129
|
-
- `DrawerContent`
|
|
130
|
-
- `DrawerHeader`
|
|
131
|
-
- `DrawerBody`
|
|
132
|
-
- `DrawerFooter`
|
|
133
|
-
- `DrawerTitle`
|
|
134
|
-
- `DrawerDescription`
|
|
135
|
-
- `DrawerClose`
|
|
136
|
-
- `DrawerRootProps`
|
|
137
|
-
- `DrawerTriggerProps`
|
|
138
|
-
- `DrawerContentProps`
|
|
139
|
-
- `useDrawerDrag`
|
|
140
|
-
- `Form.Provider`
|
|
141
|
-
- `Form.Field.Container`
|
|
142
|
-
- `Form.Field.Header`
|
|
143
|
-
- `Form.Field.Body`
|
|
144
|
-
- `Form.Field.Footer`
|
|
145
|
-
- `Form.Field.Template`
|
|
146
|
-
- `FormFieldTemplateProps`
|
|
147
|
-
- `FormFieldContainerProps`
|
|
148
|
-
- `FormFieldHeaderProps`
|
|
149
|
-
- `FormFieldFooterProps`
|
|
150
|
-
- `FormFieldWidth`
|
|
151
|
-
- `FormFieldState`
|
|
152
|
-
- `getFormFieldWidthAttr`
|
|
153
|
-
- `getFormFieldWidthValue`
|
|
154
|
-
- `InfoBox`
|
|
155
|
-
- `InfoBoxIcon`
|
|
156
|
-
- `InfoBoxProps`
|
|
157
|
-
- `InfoBoxState`
|
|
158
|
-
- `BottomNavigation`
|
|
159
|
-
- `BottomNavigationProps`
|
|
160
|
-
- `NavigationItem`
|
|
161
|
-
- `NavigationItemKey`
|
|
162
|
-
- `NavigationHrefItem`
|
|
163
|
-
- `NavigationActionItem`
|
|
164
|
-
- `NavigationSitemapNode`
|
|
165
|
-
- `NavigationSitemapCollection`
|
|
166
|
-
- `NavigationSitemapOptions`
|
|
167
|
-
- `composeNavigationClassName`
|
|
168
|
-
- `isHrefNavigationItem`
|
|
169
|
-
- `Pagination`
|
|
170
|
-
- `PaginationCarousel`
|
|
171
|
-
- `PaginationCount`
|
|
172
|
-
- `PaginationProps`
|
|
173
|
-
- `PaginationCarouselProps`
|
|
174
|
-
- `PaginationCountProps`
|
|
175
|
-
- `PaginationCountSize`
|
|
176
|
-
- `PaginationCarouselPriority`
|
|
177
|
-
- `normalizePaginationState`
|
|
178
|
-
- `createPaginationPages`
|
|
179
|
-
- `composePaginationClassName`
|
|
180
|
-
- `Slot.Base`
|
|
181
|
-
- `Slot.Text`
|
|
182
|
-
- `SlotComponentProps`
|
|
183
|
-
- `SlotTextProps`
|
|
184
|
-
- `Switch`
|
|
185
|
-
- `SwitchProps`
|
|
186
|
-
- `SwitchSize`
|
|
187
|
-
- `TabRoot`
|
|
188
|
-
- `TabList`
|
|
189
|
-
- `TabTrigger`
|
|
190
|
-
- `TabContent`
|
|
191
|
-
- `TabRootProps`
|
|
192
|
-
- `TabListProps`
|
|
193
|
-
- `TabTriggerProps`
|
|
194
|
-
- `TabContentProps`
|
|
195
|
-
- `TabVariant`
|
|
196
|
-
- `TabScale`
|
|
197
|
-
- `TabContext`
|
|
198
|
-
- `useTabContext`
|
|
199
|
-
- `SegmentedControl`
|
|
200
|
-
- `SegmentedControlLabel`
|
|
201
|
-
- `SegmentedControlProps`
|
|
202
|
-
- `SegmentedControlOption`
|
|
203
|
-
- `SegmentedControlValue`
|
|
204
|
-
- `Divider`
|
|
205
|
-
- `DividerProps`
|
|
206
|
-
- `DividerDirection`
|
|
207
|
-
- `scrollbar` (현재 public export 없음)
|
|
208
|
-
- `spinner` (현재 public export 없음)
|
|
209
|
-
- `Table.Root`
|
|
210
|
-
- `Table.Head`
|
|
211
|
-
- `Table.Body`
|
|
212
|
-
- `Table.Foot`
|
|
213
|
-
- `Table.Row`
|
|
214
|
-
- `Table.Th`
|
|
215
|
-
- `Table.Td`
|
|
216
|
-
- `Table.Cell`
|
|
217
|
-
- `Table.Text`
|
|
218
|
-
- `Table.Container`
|
|
219
|
-
- `Table.Colgroup`
|
|
220
|
-
- `Table.Col`
|
|
221
|
-
- `TableColumnData`
|
|
222
|
-
- `TableRootProps`
|
|
223
|
-
- `TableContainerProps`
|
|
224
|
-
- `TableCellProps`
|
|
225
|
-
- `Toast.Host`
|
|
226
|
-
- `Toast.Item`
|
|
227
|
-
- `ToastIcon`
|
|
228
|
-
- `ToastItemData`
|
|
229
|
-
- `ToastHostProps`
|
|
230
|
-
- `ToastItemProps`
|
|
231
|
-
- `ToastState`
|
|
232
|
-
- `ToastHorizontal`
|
|
233
|
-
- `ToastVertical`
|
|
234
|
-
- `Button.Default`
|
|
235
|
-
- `Button.Text`
|
|
236
|
-
- `Button.Rounded`
|
|
237
|
-
- `Button.Label`
|
|
238
|
-
- `ButtonProps`
|
|
239
|
-
- `TextButtonProps`
|
|
240
|
-
- `RoundButtonProps`
|
|
241
|
-
- `Input.Base`
|
|
242
|
-
- `Input.TextArea`
|
|
243
|
-
- `Input.Text.Password`
|
|
244
|
-
- `Input.Text.Phone`
|
|
245
|
-
- `Input.Text.Email`
|
|
246
|
-
- `Input.Text.Search`
|
|
247
|
-
- `Input.Text.AuthCode`
|
|
248
|
-
- `Input.Date.Template`
|
|
249
|
-
- `Input.Address.Template`
|
|
250
|
-
- `Input.Address.Button`
|
|
251
|
-
- `Input.File.UploadButton`
|
|
252
|
-
- `Input.File.UploadedChip`
|
|
253
|
-
- `Input.File.List.*`
|
|
254
|
-
- `useInputFile`
|
|
255
|
-
- `useInputFileContext`
|
|
256
|
-
- `Select.Default`
|
|
257
|
-
- `Select.Multiple`
|
|
258
|
-
- `Select.Container`
|
|
259
|
-
- `Select.Trigger.Base`
|
|
260
|
-
- `Select.Selected.Base`
|
|
261
|
-
- `Select.Selected.Multiple`
|
|
262
|
-
- `SelectDropdownOption`
|
|
263
|
-
- `SelectMultipleTag`
|
|
264
|
-
- `Dropdown.Root`
|
|
265
|
-
- `Dropdown.Trigger`
|
|
266
|
-
- `Dropdown.Container`
|
|
267
|
-
- `Dropdown.Menu.Item`
|
|
268
|
-
- `Dropdown.Menu.List`
|
|
269
|
-
- `Dropdown.Template`
|
|
270
|
-
- `DropdownTemplateItem`
|
|
271
|
-
- `DropdownTemplateChangePayload`
|
|
272
|
-
- `Radio`
|
|
273
|
-
- `RadioField`
|
|
274
|
-
- `RadioCard`
|
|
275
|
-
- `RadioCardGroup`
|
|
276
|
-
- `RadioProps`
|
|
277
|
-
- `RadioFieldProps`
|
|
278
|
-
- `Checkbox`
|
|
279
|
-
- `CheckboxField`
|
|
280
|
-
- `CheckboxProps`
|
|
281
|
-
- `CheckboxFieldProps`
|
|
282
|
-
- `CheckboxSize`
|
|
283
|
-
- `Tooltip.Root`
|
|
284
|
-
- `Tooltip.Trigger`
|
|
285
|
-
- `Tooltip.Message`
|
|
286
|
-
- `Tooltip.Text`
|
|
287
|
-
- `Tooltip.Template`
|
|
288
|
-
- `TooltipMessageProps`
|
|
289
|
-
- `PopOver.Root`
|
|
290
|
-
- `PopOver.Trigger`
|
|
291
|
-
- `PopOver.Content`
|
|
292
|
-
- `PopOverRootProps`
|
|
293
|
-
- `PopOverTriggerProps`
|
|
294
|
-
- `PopOverContentProps`
|
|
295
|
-
|
|
296
|
-
### Link/Anchor로 사용하기
|
|
27
|
+
Component, type, hook과 utility는 root public entry에서 가져온다. 실제 공개 범위는
|
|
28
|
+
`package.json` `exports`와 public barrel이 권위다.
|
|
297
29
|
|
|
298
30
|
```tsx
|
|
299
|
-
import
|
|
300
|
-
import { Button } from "@uniai-fe/uds-primitives";
|
|
31
|
+
import { Button, type BottomNavigationProps } from "@uniai-fe/uds-primitives";
|
|
301
32
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
fill="outlined"
|
|
308
|
-
size="medium"
|
|
309
|
-
priority="secondary"
|
|
310
|
-
>
|
|
311
|
-
대시보드로 이동
|
|
312
|
-
</Button.Default>
|
|
313
|
-
);
|
|
314
|
-
}
|
|
33
|
+
export const ConfirmButton = () => (
|
|
34
|
+
<Button.Default fill="solid" size="medium" priority="primary">
|
|
35
|
+
확인
|
|
36
|
+
</Button.Default>
|
|
37
|
+
);
|
|
315
38
|
```
|
|
316
39
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
- 기본 클래스: `.button` (padding/height/radius/타이포/커서 담당)
|
|
320
|
-
- 슬롯: `button-label`, `button-icon`, `button-left`, `button-right`, `button-loading`
|
|
321
|
-
- Modifier: `button-scale-*`, `button-fill-*`, `button-priority-*`, `button-state-*`, `button-size-*`, `button-block`, `button-icon-left/right`
|
|
322
|
-
- `scale` prop은 legacy 호환용이며 `fill`/`size`를 명시 사용하는 것이 권장된다.
|
|
323
|
-
- `Button.Default`의 `priority`는 `primary|secondary|tertiary|green|yellow|orange|teal|pink|red|darkGray|lightGray`를 지원한다. 신규 컬러 preset은 `--button-default-{priority}-*` 변수를 컨테이너 범위에서 재정의해 상태별로 교정할 수 있다.
|
|
324
|
-
- `loading` 상태는 readonly와 동일하게 잠기며 hover/pressed 반응을 막는다. anchor 등 커스텀 요소도 `aria-disabled="true"`를 통해 동일한 스타일을 적용받는다.
|
|
40
|
+
`@uniai-fe/uds-primitives/src/**`와 export map에 없는 category path는 public API가 아니다.
|
|
325
41
|
|
|
326
|
-
|
|
42
|
+
`Button.Default`의 `priority`는 `primary`, `secondary`, `tertiary`, `green`, `yellow`,
|
|
43
|
+
`orange`, `teal`, `pink`, `red`, `darkGray`, `lightGray`를 지원한다. Text와 Rounded
|
|
44
|
+
Button은 기존 priority 범위를 유지한다.
|
|
327
45
|
|
|
328
|
-
`
|
|
329
|
-
|
|
330
|
-
```tsx
|
|
331
|
-
import { Button } from "@uniai-fe/uds-primitives";
|
|
332
|
-
|
|
333
|
-
function Templates() {
|
|
334
|
-
return (
|
|
335
|
-
<>
|
|
336
|
-
<Button.Text priority="secondary" size="medium">
|
|
337
|
-
링크 스타일
|
|
338
|
-
</Button.Text>
|
|
339
|
-
|
|
340
|
-
<Button.Rounded aria-label="추가" size="small">
|
|
341
|
-
<span aria-hidden="true">+</span>
|
|
342
|
-
</Button.Rounded>
|
|
343
|
-
</>
|
|
344
|
-
);
|
|
345
|
-
}
|
|
346
|
-
```
|
|
46
|
+
`Input.Time.Template`과 standalone `TimePicker.Template`, `TimePickerUtils`도 root public
|
|
47
|
+
entry에서 제공한다.
|
|
347
48
|
|
|
348
|
-
|
|
349
|
-
- RoundButton(`Button.Rounded`)은 `priority="primary|secondary|tertiary"`만 사용한다.
|
|
350
|
-
- 템플릿별 클래스를 추가로 노출한다: `.button-template-text`, `.button-template-text-size-*`, `.button-template-round`, `.button-template-round-size-*`.
|
|
351
|
-
- 스토리북 `primitives/Button` Story에서 solid/outlined/텍스트/라운드 4가지 카테고리를 한 번에 확인할 수 있다.
|
|
49
|
+
## Styles
|
|
352
50
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
- `Button.Default`는 `Slot.Base`를 통해 `as` prop으로 전달된 요소(예: `Link`, `a`, `button`)에 공통 속성/`ref`를 안전하게 전달한다.
|
|
356
|
-
- `SlotComponentProps<C>`는 React가 허용하는 모든 native props + `data-*` 속성을 그대로 포함하고, `as/children/className`만 재정의한다.
|
|
357
|
-
- 필요 시 `import { Slot } from "@uniai-fe/uds-primitives";` 후 `Slot.Base`, `Slot.Text`를 직접 사용해 카드/배너 래퍼나 텍스트 슬롯을 구현할 수 있다.
|
|
358
|
-
- 자세한 도입 배경과 API는 `docs/CONTEXT-SLOT.md`에서 확인할 수 있다.
|
|
359
|
-
|
|
360
|
-
### 최근 업데이트
|
|
361
|
-
|
|
362
|
-
- TextInput Base 컴포넌트의 `clear` 버튼 로직을 pointer 이벤트 기반으로 재작성해 모바일 터치 환경에서도 안정적으로 입력값이 초기화되도록 했다.
|
|
363
|
-
- react-hook-form `register`와 연계된 값도 동일하게 초기화되며, focus가 빠지면 clear 버튼이 자동으로 숨겨진다.
|
|
364
|
-
- `Input.TextArea`를 추가했다.
|
|
365
|
-
- `height?: number | string`으로 높이를 직접 제어한다. (기본 `128px`)
|
|
366
|
-
- `length?: number`을 주면 `0 / n자` 카운터가 우측 하단에 노출된다.
|
|
367
|
-
- 기본 `resize`는 비활성(`none`)이며, `size` 축은 Input 기본 size token(`--input-default-*`)을 재사용한다.
|
|
368
|
-
- Select/Dropdown 계약을 `items` 중심으로 정렬했다.
|
|
369
|
-
- Select: `items`, `onSelectChange`, `dropdownOptions`, `open/defaultOpen/onOpen`
|
|
370
|
-
- Dropdown.Template: `items[].selected + onChange(payload)`
|
|
371
|
-
|
|
372
|
-
## 스타일 내보내기
|
|
373
|
-
|
|
374
|
-
primitives `styles/css` 엔트리는 primitives component styles만 제공하며 foundation 토큰을 다시 로드하지 않는다. Foundation style은 service app root 또는 global stylesheet에서 먼저 로드해야 한다.
|
|
375
|
-
|
|
376
|
-
### CSS-only consumer setup
|
|
377
|
-
|
|
378
|
-
Sass를 사용하지 않는 Next.js/webpack 소비자는 CSS entry를 순서대로 import한다.
|
|
51
|
+
CSS consumer는 Foundation 다음에 Primitives를 로드한다.
|
|
379
52
|
|
|
380
53
|
```ts
|
|
381
54
|
import "@uniai-fe/uds-foundation/css";
|
|
382
55
|
import "@uniai-fe/uds-primitives/css";
|
|
383
56
|
```
|
|
384
57
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
Sass 소비자는 foundation Sass public entry를 먼저 로드하고 primitives aggregate entry를 이어서 로드한다.
|
|
58
|
+
Sass consumer는 public style entry를 사용한다.
|
|
388
59
|
|
|
389
60
|
```scss
|
|
390
61
|
@use "@uniai-fe/uds-foundation/scss";
|
|
391
62
|
@use "@uniai-fe/uds-primitives/styles";
|
|
392
63
|
```
|
|
393
64
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
modules repo 내부 Storybook은 source style 변경을 빠르게 확인하기 위해 Preview에서 `@uniai-fe/uds-foundation/css` 이후 `@uniai-fe/uds-primitives/styles`를 로드한다. 이 설정은 Storybook local render setup이며 외부 consumer setup의 SOT가 아니다.
|
|
65
|
+
Storybook의 local Sass setup은 외부 consumer 계약을 대체하지 않는다.
|
|
397
66
|
|
|
398
|
-
|
|
67
|
+
## Package-local docs
|
|
399
68
|
|
|
400
|
-
|
|
69
|
+
- `docs/CONTEXT-INDEX.md`: module별 append-only 작업 이력 routing
|
|
70
|
+
- `docs/CONTEXT-GUIDELINES.md`: 과거 전역 기록과 최신 priority delta
|
|
71
|
+
- `docs/STORYBOOK.md`: Primitives Story routing
|
|
72
|
+
- `DESIGN-PRIMITIVES-SESSION-GUIDE.md`: 작업 세션 입력과 실행 순서
|
|
401
73
|
|
|
402
|
-
|
|
74
|
+
## Commands
|
|
403
75
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
## Next.js 통합 예시
|
|
410
|
-
|
|
411
|
-
Next.js 15(app router 기준)에서 primitives를 사용하는 최소 구성 예시는 다음과 같다.
|
|
412
|
-
|
|
413
|
-
```ts
|
|
414
|
-
// next.config.ts
|
|
415
|
-
const nextConfig = {
|
|
416
|
-
transpilePackages: ["@uniai-fe/uds-foundation", "@uniai-fe/uds-primitives"],
|
|
417
|
-
sassOptions: {
|
|
418
|
-
// monorepo가 아니어도 node_modules 경로를 자동 탐색하지만,
|
|
419
|
-
// 필요 시 디자인 토큰 경로를 명시해 두면 빌드 환경 차이를 줄일 수 있다.
|
|
420
|
-
includePaths: ["./node_modules"],
|
|
421
|
-
},
|
|
422
|
-
};
|
|
423
|
-
export default nextConfig;
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
아래 두 style load 방식 중 하나만 선택한다.
|
|
427
|
-
|
|
428
|
-
Sass 방식:
|
|
429
|
-
|
|
430
|
-
```scss
|
|
431
|
-
/* app/globals.scss */
|
|
432
|
-
@use "@uniai-fe/uds-foundation/scss";
|
|
433
|
-
@use "@uniai-fe/uds-primitives/styles";
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
CSS-only 방식:
|
|
437
|
-
|
|
438
|
-
```tsx
|
|
439
|
-
// app/layout.tsx
|
|
440
|
-
import type { ReactNode } from "react";
|
|
441
|
-
import "@uniai-fe/uds-foundation/css";
|
|
442
|
-
import "@uniai-fe/uds-primitives/css";
|
|
443
|
-
import { ThemeProvider } from "@uniai-fe/uds-foundation/provider";
|
|
444
|
-
|
|
445
|
-
export default function RootLayout({ children }: { children: ReactNode }) {
|
|
446
|
-
return (
|
|
447
|
-
<html lang="ko">
|
|
448
|
-
<body>
|
|
449
|
-
<ThemeProvider>{children}</ThemeProvider>
|
|
450
|
-
</body>
|
|
451
|
-
</html>
|
|
452
|
-
);
|
|
453
|
-
}
|
|
454
|
-
```
|
|
455
|
-
|
|
456
|
-
두 방식 모두 ThemeProvider가 foundation 패키지에서만 export되고 CSS를 재import하지 않는 현재 구조를 기준으로 한다. `globals.scss` 또는 루트에서 foundation/primitives styles를 반드시 각각 한 번 로드해야 한다. Sass 기반 프로젝트는 `@use "@uniai-fe/uds-foundation/scss"; @use "@uniai-fe/uds-primitives/styles";`, CSS-only 프로젝트는 `import "@uniai-fe/uds-foundation/css"; import "@uniai-fe/uds-primitives/css";`를 사용한다.
|
|
457
|
-
|
|
458
|
-
모든 컴포넌트는 `.component` 클래스 + CSS 변수 기반으로 override가 가능하며, 버튼처럼 Slot(left/right/icon 등)을 제공하는 항목은 `CONTEXT-*.md` 문서에 상세 API를 기록했습니다. 불필요한 `data-*` attribute는 제거했고, 상태 표시는 `:disabled`, `[aria-busy="true"]` 같은 표준 attribute만 사용합니다.
|
|
459
|
-
|
|
460
|
-
## 구조
|
|
461
|
-
|
|
462
|
-
```plaintext
|
|
463
|
-
src/components/{category}/
|
|
464
|
-
markup|unit|layout/ // 컴포넌트 구현
|
|
465
|
-
types/ // 외부 노출 타입
|
|
466
|
-
styles/ // SCSS (foundation 토큰 기반)
|
|
467
|
-
hooks/ // 카테고리 전용 훅
|
|
76
|
+
```bash
|
|
77
|
+
pnpm format:check
|
|
78
|
+
pnpm lint
|
|
79
|
+
pnpm typecheck
|
|
80
|
+
pnpm check
|
|
468
81
|
```
|
|
469
|
-
|
|
470
|
-
- 배럴(`components/{category}/index.tsx`)은 항상 `import "./index.scss"`를 포함합니다.
|
|
471
|
-
- 스타일은 foundation CSS 변수만 사용하며, `.button.button-priority-*` / `.button.button-fill-*` 클래스 조합으로 상태를 분기합니다.
|
|
472
|
-
|
|
473
|
-
## 스크립트
|
|
474
|
-
|
|
475
|
-
- `pnpm module:lint`
|
|
476
|
-
- `pnpm module:typecheck`
|
|
477
|
-
- `pnpm module:build`
|
|
478
|
-
|
|
479
|
-
루트에서는 `pnpm --filter @uniai-fe/uds-primitives <command>`로 실행할 수 있습니다.
|
|
480
|
-
|
|
481
|
-
## 문서
|
|
482
|
-
|
|
483
|
-
- `CONTEXT.md` 및 `CONTEXT-*.md`: 각 컴포넌트의 상태/진행/디자인 근거
|
|
484
|
-
- `CONTEXT-INPUT.md`: Phone/Email/OneTimeCode 등 인증 입력 시나리오 규칙을 포함하며, templates `CONTEXT-SIGNUP*.md`와 항상 동기화해야 한다.
|
|
485
|
-
- `RADIX-SIZE-GUIDE.md`: primitives 사이즈 체계와 Radix 매핑 규칙
|
|
486
|
-
|
|
487
|
-
### Signup 인증 입력 컴포넌트
|
|
488
|
-
|
|
489
|
-
- **PhoneInput**: 기본은 마스킹된 전화번호 입력만 제공한다. `onRequestCode`(optional)를 주입하면 인증요청 버튼이 우측 right 슬롯에 노출된다. 인증코드 입력 섹션은 templates 레이어(`Auth.AuthCode.Phone`)에서 `code.visible`, `code.inputProps`로 제어한다.
|
|
490
|
-
- **EmailInput**: 이메일 입력과 인증요청 버튼까지만 제공한다. 인증코드 UI와 countdown/state 관리는 `@uniai-fe/uds-templates`의 `Auth.AuthCode.Email` 템플릿에서 처리하며, `code.visible`, `code.helper`, `code.inputProps.length` 등의 옵션으로 Step2 Verify & Agreement 상태를 맞춘다.
|
|
491
|
-
- **AuthCodeInput**: length 지정형 OneTimeCode grid. EmailInput 내부에서 사용하지만 서비스 앱도 직접 import할 수 있다.
|
|
492
|
-
- 변경 시에는 다음 문서를 함께 업데이트한다: `packages/design/primitives/docs/CONTEXT-INPUT.md`, `packages/design/templates/docs/CONTEXT-SIGNUP.md`, `CONTEXT-SIGNUP-FLOW.md`, `packages/design/templates/docs/STORYBOOK.md`, `apps/design-storybook/src/stories/templates/auth/AuthSignup.stories.tsx`.
|
|
493
|
-
|
|
494
|
-
* **컨벤션**: 모든 컴포넌트/스토리/문서는 slot/prefix/suffix 용어를 사용하지 않고, 레이아웃 기준(`header/body/footer`, 2단 구조는 `upper/lower`)과 `util*` 키워드를 사용한다. 인터랙션 함수는 `on*` 접두사를 사용하고, JSDoc `@param`은 depth 전체를 풀어 쓴다.
|
|
495
|
-
|
|
496
|
-
필요한 컨텍스트를 확인한 뒤 컴포넌트를 import해 사용하면 됩니다.
|