@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 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, 40px);
305
- --dropdown-option-height-medium: var(--theme-size-medium-2, 48px);
306
- --dropdown-option-height-large: var(--theme-size-medium-3, 56px);
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, var(--dropdown-option-height-medium));
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-option-font-size, var(--dropdown-text-medium-size));
2309
- font-weight: var(--dropdown-option-font-weight, var(--dropdown-text-weight));
2310
- line-height: var(--dropdown-option-line-height, var(--dropdown-text-medium-line-height));
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: flex;
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, var(--dropdown-text-medium-size));
2360
- line-height: var(--dropdown-text-line-height-selected, var(--dropdown-text-medium-line-height));
2361
- letter-spacing: var(--dropdown-text-letter-spacing-selected, var(--dropdown-text-medium-letter-spacing));
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniai-fe/uds-primitives",
3
- "version": "0.3.23",
3
+ "version": "0.3.25",
4
4
  "description": "UNIAI Design System; Primitives Components Package",
5
5
  "type": "module",
6
6
  "private": false,
@@ -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
- if (shouldRenderCheckbox) {
55
- const checkboxClassName = clsx(
56
- "dropdown-menu-item-checkbox",
57
- checkboxProps?.className,
58
- );
45
+ // 변경: 좌측 콘텐츠가 전혀 없고 multiple도 아니면 즉시 null을 반환한다.
46
+ if (!left && !multiple) {
47
+ return null;
48
+ }
59
49
 
60
- const checkboxAdditionalProps: CheckboxProps = {
61
- ...checkboxProps,
62
- checked: isSelected,
63
- onCheckedChange: checkboxProps?.onCheckedChange ?? (() => {}),
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 size="medium" {...checkboxAdditionalProps} />
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={hasDescription ? "true" : undefined}
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
- <span className="dropdown-menu-item-body">
101
- {resolvedLabelContent}
102
- {description ? (
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
- ) : null}
107
- </span>
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-option-font-size, var(--dropdown-text-medium-size));
95
- font-weight: var(--dropdown-option-font-weight, var(--dropdown-text-weight));
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
- // 변경: inline-* 금지 규칙에 맞춰 라벨 렌더 박스를 flex로 유지한다.
157
- display: flex;
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
- --dropdown-text-size-selected,
163
- var(--dropdown-text-medium-size)
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, 40px);
59
- --dropdown-option-height-medium: var(--theme-size-medium-2, 48px);
60
- --dropdown-option-height-large: var(--theme-size-medium-3, 56px);
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 = SelectTriggerDefaultProps &
333
- SelectDropdownConfigProps &
334
- SelectDropdownBehaviorProps &
335
- SelectWidthOption &
336
- SelectTriggerEventProps &
337
- SelectCustomOptionExtension &
338
- SelectFormRegisterExtension;
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 = SelectTriggerMultipleProps &
381
- SelectDropdownConfigProps &
382
- SelectDropdownBehaviorProps &
383
- SelectWidthOption &
384
- SelectMultipleAllOptionProps &
385
- SelectTriggerEventProps;
381
+ export type SelectMultipleComponentProps<OptionData = unknown> =
382
+ SelectTriggerMultipleProps &
383
+ SelectDropdownConfigProps<OptionData> &
384
+ SelectDropdownBehaviorProps &
385
+ SelectWidthOption &
386
+ SelectMultipleAllOptionProps &
387
+ SelectTriggerEventProps;