@uniai-fe/uds-primitives 0.3.34 → 0.3.36

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
@@ -387,15 +387,15 @@
387
387
  --input-textarea-counter-letter-spacing: var(
388
388
  --font-label-medium-letter-spacing
389
389
  );
390
- --input-table-text-small-size: var(--font-body-xxsmall-size);
391
- --input-table-text-small-line-height: var(--font-body-xxsmall-line-height);
392
- --input-table-text-small-weight: var(--font-body-xxsmall-weight);
393
- --input-table-text-medium-size: var(--font-body-xsmall-size);
394
- --input-table-text-medium-line-height: var(--font-body-xsmall-line-height);
395
- --input-table-text-medium-weight: var(--font-body-xsmall-weight);
396
- --input-table-text-large-size: var(--font-body-small-size);
397
- --input-table-text-large-line-height: var(--font-body-small-line-height);
398
- --input-table-text-large-weight: var(--font-body-small-weight);
390
+ --input-table-text-small-size: var(--table-td-text-size);
391
+ --input-table-text-small-line-height: var(--table-td-text-line-height);
392
+ --input-table-text-small-weight: var(--table-td-text-weight);
393
+ --input-table-text-medium-size: var(--table-td-text-size);
394
+ --input-table-text-medium-line-height: var(--table-td-text-line-height);
395
+ --input-table-text-medium-weight: var(--table-td-text-weight);
396
+ --input-table-text-large-size: var(--table-td-text-size);
397
+ --input-table-text-large-line-height: var(--table-td-text-line-height);
398
+ --input-table-text-large-weight: var(--table-td-text-weight);
399
399
  /* Figma size 매핑: small/medium/large typography 토큰 */
400
400
  --input-text-small-size: var(--font-body-xsmall-size);
401
401
  --input-text-small-line-height: var(--font-label-medium-line-height);
@@ -2567,6 +2567,14 @@ figure.chip {
2567
2567
  .input--block {
2568
2568
  width: 100%;
2569
2569
  }
2570
+ .input[data-priority=table] {
2571
+ display: block;
2572
+ --input-width: 100%;
2573
+ height: 100%;
2574
+ }
2575
+ .input[data-priority=table] .input-box {
2576
+ height: 100%;
2577
+ }
2570
2578
 
2571
2579
  .input-label {
2572
2580
  color: var(--input-label-color);
@@ -2682,6 +2690,7 @@ figure.chip {
2682
2690
  margin-left: 0;
2683
2691
  }
2684
2692
  .input-field[data-priority=table] {
2693
+ height: 100%;
2685
2694
  border-radius: var(--input-table-radius-base);
2686
2695
  border-color: var(--input-border-table-default-color);
2687
2696
  background-color: var(--input-table-surface-color);
@@ -3812,6 +3821,14 @@ figure.chip {
3812
3821
  gap: var(--select-layout-gap);
3813
3822
  min-width: 0;
3814
3823
  }
3824
+ .select:where([data-priority=table]) {
3825
+ width: 100%;
3826
+ height: 100%;
3827
+ display: block;
3828
+ }
3829
+ .select:where([data-priority=table]) .select-button {
3830
+ height: 100%;
3831
+ }
3815
3832
 
3816
3833
  .select:where([data-width=auto]) {
3817
3834
  --select-width: auto;
@@ -4215,9 +4232,16 @@ figure.chip {
4215
4232
  width: 100%;
4216
4233
  height: 100%;
4217
4234
  }
4218
- .select-icon svg path {
4235
+
4236
+ .select-button:not([data-size=xsmall]):not([data-priority=table]) .select-icon svg path {
4219
4237
  fill: var(--select-icon-fill);
4220
4238
  }
4239
+ .select-button :where([data-size=xsmall]) svg path {
4240
+ stroke: var(--select-icon-fill);
4241
+ }
4242
+ .select-button :where([data-priority=table]) svg path {
4243
+ stroke: var(--select-icon-fill);
4244
+ }
4221
4245
 
4222
4246
  .tab-root {
4223
4247
  /* Figma node 694:4619 측정값을 CSS 변수로 고정해 Storybook과 실 서비스 간 시각 편차를 줄인다. */
@@ -4621,60 +4645,6 @@ figure.chip {
4621
4645
  padding: 0;
4622
4646
  }
4623
4647
 
4624
- .table-cell-content[data-padding=default] > :where(.input[data-priority=table]) {
4625
- width: calc(100% + var(--table-cell-padding-inline) * 2);
4626
- height: 100%;
4627
- min-height: calc(100% + var(--table-cell-padding-block) * 2);
4628
- margin-inline: calc(var(--table-cell-padding-inline) * -1);
4629
- margin-block: calc(var(--table-cell-padding-block) * -1);
4630
- flex: 1 1 auto;
4631
- }
4632
-
4633
- .table-cell-content[data-padding=default] :where(.input[data-priority=table] .input-box),
4634
- .table-cell-content[data-padding=default] :where(.input[data-priority=table] .input-field) {
4635
- width: 100%;
4636
- height: 100%;
4637
- }
4638
-
4639
- .table-cell-content[data-padding=default] > :where(.input-date-field) {
4640
- width: calc(100% + var(--table-cell-padding-inline) * 2);
4641
- height: 100%;
4642
- min-height: calc(100% + var(--table-cell-padding-block) * 2);
4643
- margin-inline: calc(var(--table-cell-padding-inline) * -1);
4644
- margin-block: calc(var(--table-cell-padding-block) * -1);
4645
- }
4646
-
4647
- .table-cell-content[data-padding=default] > :where(.select.select-container:has(.select-button[data-priority=table])) {
4648
- width: calc(100% + var(--table-cell-padding-inline) * 2);
4649
- margin-inline: calc(var(--table-cell-padding-inline) * -1);
4650
- margin-block: calc(var(--table-cell-padding-block) * -1);
4651
- flex: 1 1 auto;
4652
- }
4653
-
4654
- .table-cell-content[data-padding=default] > :where(.select.select-container:has(.select-button[data-priority=table])) .select-button {
4655
- width: 100%;
4656
- }
4657
-
4658
- .table-cell-content[data-padding=none] > :where(.select.select-container:has(.select-button[data-priority=table])),
4659
- .table-cell-content[data-no-padding=true] > :where(.select.select-container:has(.select-button[data-priority=table])) {
4660
- width: 100%;
4661
- margin: 0;
4662
- }
4663
-
4664
- .table-cell-content[data-padding=none] > :where(.input[data-priority=table]),
4665
- .table-cell-content[data-no-padding=true] > :where(.input[data-priority=table]),
4666
- .table-cell-content[data-padding=none] :where(.input[data-priority=table] .input-box,
4667
- .input[data-priority=table] .input-field),
4668
- .table-cell-content[data-no-padding=true] :where(.input[data-priority=table] .input-box,
4669
- .input[data-priority=table] .input-field),
4670
- .table-cell-content[data-padding=none] > :where(.input-date-field),
4671
- .table-cell-content[data-no-padding=true] > :where(.input-date-field) {
4672
- width: 100%;
4673
- height: 100%;
4674
- min-height: 100%;
4675
- margin: 0;
4676
- }
4677
-
4678
4648
  :where(.table-cell-content) :where(.table-cell-text) {
4679
4649
  color: inherit;
4680
4650
  font-size: inherit;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniai-fe/uds-primitives",
3
- "version": "0.3.34",
3
+ "version": "0.3.36",
4
4
  "description": "UNIAI Design System; Primitives Components Package",
5
5
  "type": "module",
6
6
  "private": false,
@@ -272,7 +272,6 @@ const InputBase = forwardRef<HTMLInputElement, InputProps>(
272
272
  />
273
273
  </div>
274
274
  <InputBaseUtil
275
- // table priority는 success/error 상태 아이콘 대신 border만으로 상태를 표현한다.
276
275
  priority={priority}
277
276
  state={currentState}
278
277
  isDisabled={isDisabled}
@@ -47,7 +47,8 @@ export default function InputBaseUtil({
47
47
  // 변경: table/tertiary priority는 상태 아이콘을 렌더하지 않는다.
48
48
  const resolvedStatusIcon =
49
49
  priority === "table" || priority === "tertiary" ? null : statusIcon;
50
- const clearIconNode = clear ?? InputStatusIcon.reset;
50
+ const clearIconNode =
51
+ clear ?? (priority === "table" ? null : InputStatusIcon.reset);
51
52
  const showClearIcon = Boolean(
52
53
  clearIconNode &&
53
54
  hasValue &&
@@ -34,6 +34,15 @@
34
34
  &--block {
35
35
  width: 100%;
36
36
  }
37
+
38
+ &[data-priority="table"] {
39
+ display: block;
40
+ --input-width: 100%;
41
+ height: 100%;
42
+ .input-box {
43
+ height: 100%;
44
+ }
45
+ }
37
46
  }
38
47
 
39
48
  .input-label {
@@ -170,7 +179,8 @@
170
179
  }
171
180
 
172
181
  &[data-priority="table"] {
173
- // table priority는 default에서 border를 숨기고 상태(border-color)만 드러낸다.
182
+ height: 100%;
183
+
174
184
  border-radius: var(--input-table-radius-base);
175
185
  border-color: var(--input-border-table-default-color);
176
186
  background-color: var(--input-table-surface-color);
@@ -42,15 +42,15 @@
42
42
  --input-textarea-counter-letter-spacing: var(
43
43
  --font-label-medium-letter-spacing
44
44
  );
45
- --input-table-text-small-size: var(--font-body-xxsmall-size);
46
- --input-table-text-small-line-height: var(--font-body-xxsmall-line-height);
47
- --input-table-text-small-weight: var(--font-body-xxsmall-weight);
48
- --input-table-text-medium-size: var(--font-body-xsmall-size);
49
- --input-table-text-medium-line-height: var(--font-body-xsmall-line-height);
50
- --input-table-text-medium-weight: var(--font-body-xsmall-weight);
51
- --input-table-text-large-size: var(--font-body-small-size);
52
- --input-table-text-large-line-height: var(--font-body-small-line-height);
53
- --input-table-text-large-weight: var(--font-body-small-weight);
45
+ --input-table-text-small-size: var(--table-td-text-size);
46
+ --input-table-text-small-line-height: var(--table-td-text-line-height);
47
+ --input-table-text-small-weight: var(--table-td-text-weight);
48
+ --input-table-text-medium-size: var(--table-td-text-size);
49
+ --input-table-text-medium-line-height: var(--table-td-text-line-height);
50
+ --input-table-text-medium-weight: var(--table-td-text-weight);
51
+ --input-table-text-large-size: var(--table-td-text-size);
52
+ --input-table-text-large-line-height: var(--table-td-text-line-height);
53
+ --input-table-text-large-weight: var(--table-td-text-weight);
54
54
  /* Figma size 매핑: small/medium/large typography 토큰 */
55
55
  --input-text-small-size: var(--font-body-xsmall-size);
56
56
  --input-text-small-line-height: var(--font-label-medium-line-height);
@@ -0,0 +1,3 @@
1
+ <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M4.17139 6L6.99981 8.82843L9.82824 6" stroke="#313235" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M4.17139 6L6.99981 8.82843L9.82824 6" stroke="#313235" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/>
3
+ </svg>
@@ -0,0 +1,3 @@
1
+ <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M4.17139 6L6.99981 8.82843L9.82824 6" stroke="#313235" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/>
3
+ </svg>
@@ -228,6 +228,9 @@ export function SelectDefault<OptionData = unknown>({
228
228
  className={clsx("select-trigger-container", className)}
229
229
  block={resolvedBlock}
230
230
  width={width}
231
+ priority={priority}
232
+ size={resolvedSize}
233
+ state={disabled ? "disabled" : state}
231
234
  >
232
235
  <Dropdown.Root
233
236
  open={dropdownOpen}
@@ -20,7 +20,20 @@ import {
20
20
  * @param {React.ReactNode} props.children trigger 및 dropdown 콘텐츠
21
21
  */
22
22
  const SelectContainer = forwardRef<HTMLDivElement, SelectContainerProps>(
23
- ({ className, children, block = false, width, style, ...restProps }, ref) => {
23
+ (
24
+ {
25
+ className,
26
+ children,
27
+ block = false,
28
+ width,
29
+ style,
30
+ priority,
31
+ size,
32
+ state,
33
+ ...restProps
34
+ },
35
+ ref,
36
+ ) => {
24
37
  const widthAttr =
25
38
  width !== undefined
26
39
  ? getFormFieldWidthAttr(width)
@@ -41,6 +54,9 @@ const SelectContainer = forwardRef<HTMLDivElement, SelectContainerProps>(
41
54
  "select-block": block,
42
55
  })}
43
56
  data-width={widthAttr}
57
+ data-priority={priority}
58
+ data-size={size}
59
+ data-state={state}
44
60
  style={mergedStyle}
45
61
  {...restProps}
46
62
  >
@@ -41,6 +41,19 @@ const SelectChevronSecondaryIcon: SelectChevronNonPrimaryIconSizeMap = {
41
41
  large: ChevronSecondaryLarge,
42
42
  };
43
43
 
44
+ /**
45
+ * Select; Chevron 아이콘 - table
46
+ * size 무관하게 모두 동일한 아이콘
47
+ * - small
48
+ * - medium
49
+ * - large
50
+ */
51
+ const SelectChevronTableIcon: SelectChevronNonPrimaryIconSizeMap = {
52
+ small: ChevronPrimaryXsmall,
53
+ medium: ChevronPrimaryXsmall,
54
+ large: ChevronPrimaryXsmall,
55
+ };
56
+
44
57
  /**
45
58
  * Select; Chevron 아이콘 컬렉션
46
59
  * - primary (xsmall, small, medium, large)
@@ -51,7 +64,7 @@ const SelectChevronIcon: SelectIconPriorityMap = {
51
64
  primary: SelectChevronPrimaryIcon,
52
65
  secondary: SelectChevronSecondaryIcon,
53
66
  // 변경: table priority는 secondary chevron 자산을 재사용한다.
54
- table: SelectChevronSecondaryIcon,
67
+ table: SelectChevronTableIcon,
55
68
  };
56
69
 
57
70
  /**
@@ -5,6 +5,15 @@
5
5
  flex-direction: column;
6
6
  gap: var(--select-layout-gap);
7
7
  min-width: 0;
8
+
9
+ &:where([data-priority="table"]) {
10
+ width: 100%;
11
+ height: 100%;
12
+ display: block;
13
+ .select-button {
14
+ height: 100%;
15
+ }
16
+ }
8
17
  }
9
18
 
10
19
  .select:where([data-width="auto"]) {
@@ -512,9 +521,27 @@
512
521
  display: block;
513
522
  width: 100%;
514
523
  height: 100%;
524
+ }
525
+ }
515
526
 
516
- path {
517
- fill: var(--select-icon-fill);
527
+ .select-button {
528
+ &:not([data-size="xsmall"]):not([data-priority="table"]) {
529
+ .select-icon {
530
+ svg {
531
+ path {
532
+ fill: var(--select-icon-fill);
533
+ }
534
+ }
535
+ }
536
+ }
537
+ :where([data-size="xsmall"]) {
538
+ svg path {
539
+ stroke: var(--select-icon-fill);
540
+ }
541
+ }
542
+ :where([data-priority="table"]) {
543
+ svg path {
544
+ stroke: var(--select-icon-fill);
518
545
  }
519
546
  }
520
547
  }
@@ -94,7 +94,8 @@ export interface SelectComponentState {
94
94
  * @property {boolean} [block] block 여부
95
95
  * @property {FormFieldWidth} [width] width preset
96
96
  */
97
- export interface SelectContainerProps extends HTMLAttributes<HTMLDivElement> {
97
+ export interface SelectContainerProps
98
+ extends HTMLAttributes<HTMLDivElement>, SelectStyleOptions {
98
99
  /**
99
100
  * 사용자 정의 className
100
101
  */
@@ -103,10 +104,6 @@ export interface SelectContainerProps extends HTMLAttributes<HTMLDivElement> {
103
104
  * trigger/Dropdown 등 내부 콘텐츠
104
105
  */
105
106
  children: ReactNode;
106
- /**
107
- * block 여부
108
- */
109
- block?: boolean;
110
107
  /**
111
108
  * width preset
112
109
  */
@@ -372,81 +372,81 @@
372
372
  padding: 0;
373
373
  }
374
374
 
375
- // 변경: table cell 내부 full-bleed 제어는 직계 child 루트에만 적용해 내부 컴포넌트 스타일 역전을 방지한다.
376
- .table-cell-content[data-padding="default"]
377
- > :where(.input[data-priority="table"]) {
378
- width: calc(100% + (var(--table-cell-padding-inline) * 2));
379
- height: 100%;
380
- min-height: calc(100% + (var(--table-cell-padding-block) * 2));
381
- margin-inline: calc(var(--table-cell-padding-inline) * -1);
382
- margin-block: calc(var(--table-cell-padding-block) * -1);
383
- flex: 1 1 auto;
384
- }
385
-
386
- .table-cell-content[data-padding="default"]
387
- :where(.input[data-priority="table"] .input-box),
388
- .table-cell-content[data-padding="default"]
389
- :where(.input[data-priority="table"] .input-field) {
390
- width: 100%;
391
- height: 100%;
392
- }
393
-
394
- .table-cell-content[data-padding="default"] > :where(.input-date-field) {
395
- width: calc(100% + (var(--table-cell-padding-inline) * 2));
396
- height: 100%;
397
- min-height: calc(100% + (var(--table-cell-padding-block) * 2));
398
- margin-inline: calc(var(--table-cell-padding-inline) * -1);
399
- margin-block: calc(var(--table-cell-padding-block) * -1);
400
- }
401
-
402
- .table-cell-content[data-padding="default"]
403
- > :where(
404
- .select.select-container:has(.select-button[data-priority="table"])
405
- ) {
406
- width: calc(100% + (var(--table-cell-padding-inline) * 2));
407
- margin-inline: calc(var(--table-cell-padding-inline) * -1);
408
- margin-block: calc(var(--table-cell-padding-block) * -1);
409
- flex: 1 1 auto;
410
- }
411
-
412
- .table-cell-content[data-padding="default"]
413
- > :where(.select.select-container:has(.select-button[data-priority="table"]))
414
- .select-button {
415
- // 변경 설명: select 버튼 높이는 select 컴포넌트 토큰(min-height/size) 계약을 우선한다.
416
- width: 100%;
417
- }
418
-
419
- .table-cell-content[data-padding="none"]
420
- > :where(.select.select-container:has(.select-button[data-priority="table"])),
421
- .table-cell-content[data-no-padding="true"]
422
- > :where(
423
- .select.select-container:has(.select-button[data-priority="table"])
424
- ) {
425
- width: 100%;
426
- margin: 0;
427
- }
428
-
429
- .table-cell-content[data-padding="none"]
430
- > :where(.input[data-priority="table"]),
431
- .table-cell-content[data-no-padding="true"]
432
- > :where(.input[data-priority="table"]),
433
- .table-cell-content[data-padding="none"]
434
- :where(
435
- .input[data-priority="table"] .input-box,
436
- .input[data-priority="table"] .input-field
437
- ),
438
- .table-cell-content[data-no-padding="true"]
439
- :where(
440
- .input[data-priority="table"] .input-box,
441
- .input[data-priority="table"] .input-field
442
- ),
443
- .table-cell-content[data-padding="none"] > :where(.input-date-field),
444
- .table-cell-content[data-no-padding="true"] > :where(.input-date-field) {
445
- width: 100%;
446
- height: 100%;
447
- min-height: 100%;
448
- margin: 0;
449
- }
375
+ // // 변경: table cell 내부 full-bleed 제어는 직계 child 루트에만 적용해 내부 컴포넌트 스타일 역전을 방지한다.
376
+ // .table-cell-content[data-padding="default"]
377
+ // > :where(.input[data-priority="table"]) {
378
+ // width: calc(100% + (var(--table-cell-padding-inline) * 2));
379
+ // height: 100%;
380
+ // min-height: calc(100% + (var(--table-cell-padding-block) * 2));
381
+ // margin-inline: calc(var(--table-cell-padding-inline) * -1);
382
+ // margin-block: calc(var(--table-cell-padding-block) * -1);
383
+ // flex: 1 1 auto;
384
+ // }
385
+
386
+ // .table-cell-content[data-padding="default"]
387
+ // :where(.input[data-priority="table"] .input-box),
388
+ // .table-cell-content[data-padding="default"]
389
+ // :where(.input[data-priority="table"] .input-field) {
390
+ // width: 100%;
391
+ // height: 100%;
392
+ // }
393
+
394
+ // .table-cell-content[data-padding="default"] > :where(.input-date-field) {
395
+ // width: calc(100% + (var(--table-cell-padding-inline) * 2));
396
+ // height: 100%;
397
+ // min-height: calc(100% + (var(--table-cell-padding-block) * 2));
398
+ // margin-inline: calc(var(--table-cell-padding-inline) * -1);
399
+ // margin-block: calc(var(--table-cell-padding-block) * -1);
400
+ // }
401
+
402
+ // .table-cell-content[data-padding="default"]
403
+ // > :where(
404
+ // .select.select-container:has(.select-button[data-priority="table"])
405
+ // ) {
406
+ // width: calc(100% + (var(--table-cell-padding-inline) * 2));
407
+ // margin-inline: calc(var(--table-cell-padding-inline) * -1);
408
+ // margin-block: calc(var(--table-cell-padding-block) * -1);
409
+ // flex: 1 1 auto;
410
+ // }
411
+
412
+ // .table-cell-content[data-padding="default"]
413
+ // > :where(.select.select-container:has(.select-button[data-priority="table"]))
414
+ // .select-button {
415
+ // // 변경 설명: select 버튼 높이는 select 컴포넌트 토큰(min-height/size) 계약을 우선한다.
416
+ // width: 100%;
417
+ // }
418
+
419
+ // .table-cell-content[data-padding="none"]
420
+ // > :where(.select.select-container:has(.select-button[data-priority="table"])),
421
+ // .table-cell-content[data-no-padding="true"]
422
+ // > :where(
423
+ // .select.select-container:has(.select-button[data-priority="table"])
424
+ // ) {
425
+ // width: 100%;
426
+ // margin: 0;
427
+ // }
428
+
429
+ // .table-cell-content[data-padding="none"]
430
+ // > :where(.input[data-priority="table"]),
431
+ // .table-cell-content[data-no-padding="true"]
432
+ // > :where(.input[data-priority="table"]),
433
+ // .table-cell-content[data-padding="none"]
434
+ // :where(
435
+ // .input[data-priority="table"] .input-box,
436
+ // .input[data-priority="table"] .input-field
437
+ // ),
438
+ // .table-cell-content[data-no-padding="true"]
439
+ // :where(
440
+ // .input[data-priority="table"] .input-box,
441
+ // .input[data-priority="table"] .input-field
442
+ // ),
443
+ // .table-cell-content[data-padding="none"] > :where(.input-date-field),
444
+ // .table-cell-content[data-no-padding="true"] > :where(.input-date-field) {
445
+ // width: 100%;
446
+ // height: 100%;
447
+ // min-height: 100%;
448
+ // margin: 0;
449
+ // }
450
450
 
451
451
  // 변경: Cell 슬롯 기본 텍스트 inherit는 저특이성(:where)으로 두어 section 토큰 규칙이 우선되게 한다.
452
452
  :where(.table-cell-content) {