@uniai-fe/uds-primitives 0.3.23 → 0.3.25
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/dist/styles.css +23 -12
- package/package.json +1 -1
- package/src/components/dropdown/markup/foundation/MenuItem.tsx +34 -33
- package/src/components/dropdown/styles/dropdown.scss +17 -25
- package/src/components/dropdown/styles/variables.scss +10 -3
- package/src/components/select/types/props.ts +22 -20
package/dist/styles.css
CHANGED
|
@@ -299,11 +299,16 @@
|
|
|
299
299
|
--dropdown-description-color: var(--color-label-neutral);
|
|
300
300
|
--dropdown-description-size: 14px;
|
|
301
301
|
--dropdown-description-line-height: 22px;
|
|
302
|
+
--dropdown-text-size-selected: var(--dropdown-text-medium-size);
|
|
303
|
+
--dropdown-text-line-height-selected: var(--dropdown-text-medium-line-height);
|
|
304
|
+
--dropdown-text-letter-spacing-selected: var(
|
|
305
|
+
--dropdown-text-medium-letter-spacing
|
|
306
|
+
);
|
|
302
307
|
--dropdown-option-height-selected: var(--dropdown-option-height-medium);
|
|
303
308
|
--dropdown-option-height-xsmall: 24px;
|
|
304
|
-
--dropdown-option-height-small: var(--theme-size-medium-1
|
|
305
|
-
--dropdown-option-height-medium: var(--theme-size-medium-2
|
|
306
|
-
--dropdown-option-height-large: var(--theme-size-medium-3
|
|
309
|
+
--dropdown-option-height-small: var(--theme-size-medium-1);
|
|
310
|
+
--dropdown-option-height-medium: var(--theme-size-medium-2);
|
|
311
|
+
--dropdown-option-height-large: var(--theme-size-medium-3);
|
|
307
312
|
--dropdown-option-padding-inline-xsmall: var(--spacing-padding-3);
|
|
308
313
|
--dropdown-option-padding-block-xsmall: 0px;
|
|
309
314
|
--dropdown-option-radius-xsmall: 4px;
|
|
@@ -2299,15 +2304,15 @@ figure.chip {
|
|
|
2299
2304
|
align-items: center;
|
|
2300
2305
|
gap: var(--dropdown-option-gap-inline);
|
|
2301
2306
|
width: 100%;
|
|
2302
|
-
min-height: var(--dropdown-option-height-selected
|
|
2307
|
+
min-height: var(--dropdown-option-height-selected);
|
|
2303
2308
|
padding: var(--dropdown-option-padding-block-selected) var(--dropdown-option-padding-inline-selected);
|
|
2304
2309
|
border-radius: var(--dropdown-option-radius-selected);
|
|
2305
2310
|
background-color: transparent;
|
|
2306
2311
|
color: var(--dropdown-option-color);
|
|
2307
2312
|
cursor: pointer;
|
|
2308
|
-
font-size: var(--dropdown-
|
|
2309
|
-
font-weight: var(--dropdown-
|
|
2310
|
-
line-height: var(--dropdown-
|
|
2313
|
+
font-size: var(--dropdown-text-size-selected);
|
|
2314
|
+
font-weight: var(--dropdown-text-weight);
|
|
2315
|
+
line-height: var(--dropdown-text-line-height-selected);
|
|
2311
2316
|
}
|
|
2312
2317
|
.dropdown-menu-item-trigger span {
|
|
2313
2318
|
user-select: none;
|
|
@@ -2349,22 +2354,28 @@ figure.chip {
|
|
|
2349
2354
|
gap: 0.2rem;
|
|
2350
2355
|
flex: 1 1 auto;
|
|
2351
2356
|
min-width: 0;
|
|
2357
|
+
overflow: hidden;
|
|
2352
2358
|
}
|
|
2353
2359
|
|
|
2354
2360
|
.dropdown-menu-item-label {
|
|
2355
|
-
display:
|
|
2356
|
-
align-items: center;
|
|
2361
|
+
display: block;
|
|
2357
2362
|
min-width: 0;
|
|
2363
|
+
width: 100%;
|
|
2364
|
+
max-width: 100%;
|
|
2358
2365
|
color: inherit;
|
|
2359
|
-
font-size: var(--dropdown-text-size-selected
|
|
2360
|
-
line-height: var(--dropdown-text-line-height-selected
|
|
2361
|
-
letter-spacing: var(--dropdown-text-letter-spacing-selected
|
|
2366
|
+
font-size: var(--dropdown-text-size-selected);
|
|
2367
|
+
line-height: var(--dropdown-text-line-height-selected);
|
|
2368
|
+
letter-spacing: var(--dropdown-text-letter-spacing-selected);
|
|
2362
2369
|
font-weight: var(--dropdown-text-weight);
|
|
2363
2370
|
overflow: hidden;
|
|
2364
2371
|
text-overflow: ellipsis;
|
|
2365
2372
|
white-space: nowrap;
|
|
2366
2373
|
}
|
|
2367
2374
|
|
|
2375
|
+
.dropdown-menu-item-trigger > .dropdown-menu-item-label {
|
|
2376
|
+
flex: 1 1 auto;
|
|
2377
|
+
}
|
|
2378
|
+
|
|
2368
2379
|
.dropdown-menu-item-description {
|
|
2369
2380
|
font-size: var(--dropdown-description-size);
|
|
2370
2381
|
line-height: var(--dropdown-description-line-height);
|
package/package.json
CHANGED
|
@@ -6,7 +6,6 @@ import { forwardRef } from "react";
|
|
|
6
6
|
|
|
7
7
|
import type { DropdownMenuItemProps } from "../../types/props";
|
|
8
8
|
import { Checkbox } from "../../../checkbox/markup/Checkbox";
|
|
9
|
-
import type { CheckboxProps } from "../../../checkbox/types";
|
|
10
9
|
import { Slot } from "../../../slot";
|
|
11
10
|
|
|
12
11
|
/**
|
|
@@ -42,41 +41,36 @@ const DropdownMenuItem = forwardRef<HTMLDivElement, DropdownMenuItemProps>(
|
|
|
42
41
|
},
|
|
43
42
|
ref,
|
|
44
43
|
) => {
|
|
45
|
-
const labelContent = label ?? children;
|
|
46
|
-
// 변경: label 렌더링을 Slot.Text 경로로 통일해 string|number만 공통 래핑 규칙을 적용한다.
|
|
47
|
-
const resolvedLabelContent = (
|
|
48
|
-
<Slot.Text className="dropdown-menu-item-label">{labelContent}</Slot.Text>
|
|
49
|
-
);
|
|
50
|
-
const hasDescription = Boolean(description);
|
|
51
|
-
const shouldRenderCheckbox = multiple && !left;
|
|
52
|
-
|
|
53
44
|
const renderLeft = () => {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
);
|
|
45
|
+
// 변경: 좌측 콘텐츠가 전혀 없고 multiple도 아니면 즉시 null을 반환한다.
|
|
46
|
+
if (!left && !multiple) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
59
49
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
tabIndex: -1,
|
|
65
|
-
"aria-hidden": true,
|
|
66
|
-
className: checkboxClassName,
|
|
67
|
-
} as CheckboxProps;
|
|
50
|
+
// 변경: left가 있으면 우선 렌더링하고 체크박스 분기보다 앞에서 종료한다.
|
|
51
|
+
if (left) {
|
|
52
|
+
return <span className="dropdown-menu-item-left">{left}</span>;
|
|
53
|
+
}
|
|
68
54
|
|
|
55
|
+
if (multiple) {
|
|
69
56
|
return (
|
|
70
57
|
<span className="dropdown-menu-item-left" aria-hidden="true">
|
|
71
|
-
<Checkbox
|
|
58
|
+
<Checkbox
|
|
59
|
+
size="medium"
|
|
60
|
+
{...checkboxProps}
|
|
61
|
+
checked={isSelected}
|
|
62
|
+
onCheckedChange={checkboxProps?.onCheckedChange ?? (() => {})}
|
|
63
|
+
tabIndex={-1}
|
|
64
|
+
aria-hidden="true"
|
|
65
|
+
className={clsx(
|
|
66
|
+
"dropdown-menu-item-checkbox",
|
|
67
|
+
checkboxProps?.className,
|
|
68
|
+
)}
|
|
69
|
+
/>
|
|
72
70
|
</span>
|
|
73
71
|
);
|
|
74
72
|
}
|
|
75
73
|
|
|
76
|
-
if (left) {
|
|
77
|
-
return <span className="dropdown-menu-item-left">{left}</span>;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
74
|
return null;
|
|
81
75
|
};
|
|
82
76
|
|
|
@@ -88,7 +82,7 @@ const DropdownMenuItem = forwardRef<HTMLDivElement, DropdownMenuItemProps>(
|
|
|
88
82
|
className={clsx("dropdown-menu-item-trigger", className)}
|
|
89
83
|
data-state={isSelected ? "selected" : undefined}
|
|
90
84
|
data-multiple={multiple ? "true" : undefined}
|
|
91
|
-
data-has-description={
|
|
85
|
+
data-has-description={description ? "true" : undefined}
|
|
92
86
|
onSelect={event => {
|
|
93
87
|
if (multiple) {
|
|
94
88
|
event.preventDefault();
|
|
@@ -97,14 +91,21 @@ const DropdownMenuItem = forwardRef<HTMLDivElement, DropdownMenuItemProps>(
|
|
|
97
91
|
}}
|
|
98
92
|
>
|
|
99
93
|
{renderLeft()}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
94
|
+
{/* 변경: description이 있을 때만 body wrapper를 렌더링해 불필요한 중첩 span을 줄인다. */}
|
|
95
|
+
{description ? (
|
|
96
|
+
<span className="dropdown-menu-item-body">
|
|
97
|
+
<Slot.Text className="dropdown-menu-item-label">
|
|
98
|
+
{label ?? children}
|
|
99
|
+
</Slot.Text>
|
|
103
100
|
<span className="dropdown-menu-item-description">
|
|
104
101
|
{description}
|
|
105
102
|
</span>
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
</span>
|
|
104
|
+
) : (
|
|
105
|
+
<Slot.Text className="dropdown-menu-item-label">
|
|
106
|
+
{label ?? children}
|
|
107
|
+
</Slot.Text>
|
|
108
|
+
)}
|
|
108
109
|
{right ? (
|
|
109
110
|
<span className="dropdown-menu-item-right">{right}</span>
|
|
110
111
|
) : null}
|
|
@@ -81,22 +81,16 @@
|
|
|
81
81
|
align-items: center;
|
|
82
82
|
gap: var(--dropdown-option-gap-inline);
|
|
83
83
|
width: 100%;
|
|
84
|
-
min-height: var(
|
|
85
|
-
--dropdown-option-height-selected,
|
|
86
|
-
var(--dropdown-option-height-medium)
|
|
87
|
-
);
|
|
84
|
+
min-height: var(--dropdown-option-height-selected);
|
|
88
85
|
padding: var(--dropdown-option-padding-block-selected)
|
|
89
86
|
var(--dropdown-option-padding-inline-selected);
|
|
90
87
|
border-radius: var(--dropdown-option-radius-selected);
|
|
91
88
|
background-color: transparent;
|
|
92
89
|
color: var(--dropdown-option-color);
|
|
93
90
|
cursor: pointer;
|
|
94
|
-
font-size: var(--dropdown-
|
|
95
|
-
font-weight: var(--dropdown-
|
|
96
|
-
line-height: var(
|
|
97
|
-
--dropdown-option-line-height,
|
|
98
|
-
var(--dropdown-text-medium-line-height)
|
|
99
|
-
);
|
|
91
|
+
font-size: var(--dropdown-text-size-selected);
|
|
92
|
+
font-weight: var(--dropdown-text-weight);
|
|
93
|
+
line-height: var(--dropdown-text-line-height-selected);
|
|
100
94
|
|
|
101
95
|
span {
|
|
102
96
|
user-select: none;
|
|
@@ -150,32 +144,30 @@
|
|
|
150
144
|
gap: 0.2rem;
|
|
151
145
|
flex: 1 1 auto;
|
|
152
146
|
min-width: 0;
|
|
147
|
+
overflow: hidden;
|
|
153
148
|
}
|
|
154
149
|
|
|
155
150
|
.dropdown-menu-item-label {
|
|
156
|
-
// 변경:
|
|
157
|
-
display:
|
|
158
|
-
align-items: center;
|
|
151
|
+
// 변경: 말줄임표 동작을 위해 라벨 박스를 block + width 제약으로 고정한다.
|
|
152
|
+
display: block;
|
|
159
153
|
min-width: 0;
|
|
154
|
+
width: 100%;
|
|
155
|
+
max-width: 100%;
|
|
160
156
|
color: inherit;
|
|
161
|
-
font-size: var(
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
);
|
|
165
|
-
line-height: var(
|
|
166
|
-
--dropdown-text-line-height-selected,
|
|
167
|
-
var(--dropdown-text-medium-line-height)
|
|
168
|
-
);
|
|
169
|
-
letter-spacing: var(
|
|
170
|
-
--dropdown-text-letter-spacing-selected,
|
|
171
|
-
var(--dropdown-text-medium-letter-spacing)
|
|
172
|
-
);
|
|
157
|
+
font-size: var(--dropdown-text-size-selected);
|
|
158
|
+
line-height: var(--dropdown-text-line-height-selected);
|
|
159
|
+
letter-spacing: var(--dropdown-text-letter-spacing-selected);
|
|
173
160
|
font-weight: var(--dropdown-text-weight);
|
|
174
161
|
overflow: hidden;
|
|
175
162
|
text-overflow: ellipsis;
|
|
176
163
|
white-space: nowrap;
|
|
177
164
|
}
|
|
178
165
|
|
|
166
|
+
// 변경: description이 없어 body wrapper를 생략하는 경로에서 label이 가용 폭을 차지하도록 한다.
|
|
167
|
+
.dropdown-menu-item-trigger > .dropdown-menu-item-label {
|
|
168
|
+
flex: 1 1 auto;
|
|
169
|
+
}
|
|
170
|
+
|
|
179
171
|
.dropdown-menu-item-description {
|
|
180
172
|
font-size: var(--dropdown-description-size);
|
|
181
173
|
line-height: var(--dropdown-description-line-height);
|
|
@@ -53,11 +53,18 @@
|
|
|
53
53
|
--dropdown-description-size: 14px;
|
|
54
54
|
--dropdown-description-line-height: 22px;
|
|
55
55
|
|
|
56
|
+
// 변경: fallback 없는 토큰 계약을 위해 기본 selected typography를 root에서 명시한다.
|
|
57
|
+
--dropdown-text-size-selected: var(--dropdown-text-medium-size);
|
|
58
|
+
--dropdown-text-line-height-selected: var(--dropdown-text-medium-line-height);
|
|
59
|
+
--dropdown-text-letter-spacing-selected: var(
|
|
60
|
+
--dropdown-text-medium-letter-spacing
|
|
61
|
+
);
|
|
62
|
+
|
|
56
63
|
--dropdown-option-height-selected: var(--dropdown-option-height-medium);
|
|
57
64
|
--dropdown-option-height-xsmall: 24px;
|
|
58
|
-
--dropdown-option-height-small: var(--theme-size-medium-1
|
|
59
|
-
--dropdown-option-height-medium: var(--theme-size-medium-2
|
|
60
|
-
--dropdown-option-height-large: var(--theme-size-medium-3
|
|
65
|
+
--dropdown-option-height-small: var(--theme-size-medium-1);
|
|
66
|
+
--dropdown-option-height-medium: var(--theme-size-medium-2);
|
|
67
|
+
--dropdown-option-height-large: var(--theme-size-medium-3);
|
|
61
68
|
--dropdown-option-padding-inline-xsmall: var(--spacing-padding-3);
|
|
62
69
|
--dropdown-option-padding-block-xsmall: 0px;
|
|
63
70
|
--dropdown-option-radius-xsmall: 4px;
|
|
@@ -169,9 +169,9 @@ export interface SelectFormRegisterExtension {
|
|
|
169
169
|
* @property {SelectDropdownOption} [prevOption] 이전 기준 option
|
|
170
170
|
* @property {Event} [event] 원본 메뉴 선택 이벤트
|
|
171
171
|
*/
|
|
172
|
-
export type SelectCallbackParams = (
|
|
173
|
-
nextOption?: SelectDropdownOption
|
|
174
|
-
prevOption?: SelectDropdownOption
|
|
172
|
+
export type SelectCallbackParams<OptionData = unknown> = (
|
|
173
|
+
nextOption?: SelectDropdownOption<OptionData>,
|
|
174
|
+
prevOption?: SelectDropdownOption<OptionData>,
|
|
175
175
|
event?: Event,
|
|
176
176
|
) => void;
|
|
177
177
|
|
|
@@ -218,19 +218,19 @@ export interface SelectDropdownExtension {
|
|
|
218
218
|
* @property {SelectCallbackParams} [onSelectChange] 선택값 변경 콜백
|
|
219
219
|
* @property {SelectDropdownExtension} [dropdown] dropdown 확장 옵션
|
|
220
220
|
*/
|
|
221
|
-
export interface SelectDropdownConfigProps {
|
|
221
|
+
export interface SelectDropdownConfigProps<OptionData = unknown> {
|
|
222
222
|
/**
|
|
223
223
|
* dropdown item 리스트
|
|
224
224
|
*/
|
|
225
|
-
items: SelectDropdownOption[];
|
|
225
|
+
items: SelectDropdownOption<OptionData>[];
|
|
226
226
|
/**
|
|
227
227
|
* option 선택 액션 콜백
|
|
228
228
|
*/
|
|
229
|
-
onSelectOption?: SelectCallbackParams
|
|
229
|
+
onSelectOption?: SelectCallbackParams<OptionData>;
|
|
230
230
|
/**
|
|
231
231
|
* 선택값 변경 콜백
|
|
232
232
|
*/
|
|
233
|
-
onSelectChange?: SelectCallbackParams
|
|
233
|
+
onSelectChange?: SelectCallbackParams<OptionData>;
|
|
234
234
|
/**
|
|
235
235
|
* dropdown 확장 옵션
|
|
236
236
|
*/
|
|
@@ -329,13 +329,14 @@ export type SelectProps = SelectStyleOptions &
|
|
|
329
329
|
* @property {UseFormRegisterReturn} [register] source field register
|
|
330
330
|
* @property {UseFormRegisterReturn} [customRegister] custom field register
|
|
331
331
|
*/
|
|
332
|
-
export type SelectDefaultComponentProps =
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
332
|
+
export type SelectDefaultComponentProps<OptionData = unknown> =
|
|
333
|
+
SelectTriggerDefaultProps &
|
|
334
|
+
SelectDropdownConfigProps<OptionData> &
|
|
335
|
+
SelectDropdownBehaviorProps &
|
|
336
|
+
SelectWidthOption &
|
|
337
|
+
SelectTriggerEventProps &
|
|
338
|
+
SelectCustomOptionExtension &
|
|
339
|
+
SelectFormRegisterExtension;
|
|
339
340
|
|
|
340
341
|
/**
|
|
341
342
|
* Select.Multiple 전체 선택 옵션 props
|
|
@@ -377,9 +378,10 @@ export interface SelectMultipleAllOptionProps {
|
|
|
377
378
|
* @property {boolean} [showSelectAllOption] dropdown 첫 행에 "전체" 옵션 노출 여부
|
|
378
379
|
* @property {ReactNode} [selectAllLabel] "전체" 옵션 라벨 커스터마이징
|
|
379
380
|
*/
|
|
380
|
-
export type SelectMultipleComponentProps =
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
381
|
+
export type SelectMultipleComponentProps<OptionData = unknown> =
|
|
382
|
+
SelectTriggerMultipleProps &
|
|
383
|
+
SelectDropdownConfigProps<OptionData> &
|
|
384
|
+
SelectDropdownBehaviorProps &
|
|
385
|
+
SelectWidthOption &
|
|
386
|
+
SelectMultipleAllOptionProps &
|
|
387
|
+
SelectTriggerEventProps;
|