@uniai-fe/uds-primitives 0.12.6 → 0.12.7

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.
@@ -3,55 +3,28 @@
3
3
  // 라운드 버튼 사이즈 토큰을 맵으로 정의해 중복 제거
4
4
  $round-size-map: (
5
5
  small: (
6
- min-height: var(
7
- --button-round-height-small,
8
- var(--theme-size-small-2, 24px)
9
- ),
10
- padding-inline: var(
11
- --button-round-padding-inline-small,
12
- var(--spacing-padding-5, 12px)
13
- ),
14
- radius: var(--button-round-radius-small, var(--theme-radius-xlarge-2, 16px)),
6
+ min-height: var(--button-round-height-small),
7
+ padding-inline: var(--button-round-padding-inline-small),
8
+ radius: var(--button-round-radius-small),
15
9
  ),
16
10
  medium: (
17
- min-height: var(
18
- --button-round-height-medium,
19
- var(--theme-size-small-3, 32px)
20
- ),
21
- padding-inline: var(
22
- --button-round-padding-inline-medium,
23
- var(--spacing-padding-6, 16px)
24
- ),
25
- radius: var(
26
- --button-round-radius-medium,
27
- var(--theme-radius-xlarge-2, 16px)
28
- ),
11
+ min-height: var(--button-round-height-medium),
12
+ padding-inline: var(--button-round-padding-inline-medium),
13
+ radius: var(--button-round-radius-medium),
29
14
  ),
30
15
  large: (
31
- min-height: var(
32
- --button-round-height-large,
33
- var(--theme-size-medium-1, 40px)
34
- ),
35
- padding-inline: var(
36
- --button-round-padding-inline-large,
37
- var(--spacing-padding-7, 20px)
38
- ),
39
- radius: var(--button-round-radius-large, 30px),
16
+ min-height: var(--button-round-height-large),
17
+ padding-inline: var(--button-round-padding-inline-large),
18
+ radius: var(--button-round-radius-large),
40
19
  ),
41
20
  );
42
21
 
43
22
  .button {
44
23
  &:where(.button-template-round) {
45
24
  min-width: auto;
46
- padding-block: var(
47
- --button-round-padding-block-base,
48
- var(--spacing-padding-2, 4px)
49
- );
50
- padding-inline: var(
51
- --button-round-padding-inline-medium,
52
- var(--spacing-padding-6, 16px)
53
- );
54
- gap: var(--spacing-gap-2, 8px);
25
+ padding-block: var(--button-round-padding-block-base);
26
+ padding-inline: var(--button-round-padding-inline-medium);
27
+ gap: var(--spacing-gap-2);
55
28
  }
56
29
 
57
30
  @each $size, $tokens in $round-size-map {
@@ -3,28 +3,16 @@
3
3
  // 텍스트 버튼 사이즈 토큰을 맵으로 정의해 가독성을 높인다
4
4
  $text-size-map: (
5
5
  small: (
6
- min-height: var(--button-text-height-small, var(--theme-size-small-1, 20px)),
7
- padding-inline: var(
8
- --button-text-padding-inline-small,
9
- var(--spacing-padding-4, 8px)
10
- ),
6
+ min-height: var(--button-text-height-small),
7
+ padding-inline: var(--button-text-padding-inline-small),
11
8
  ),
12
9
  medium: (
13
- min-height: var(
14
- --button-text-height-medium,
15
- var(--theme-size-small-2, 24px)
16
- ),
17
- padding-inline: var(
18
- --button-text-padding-inline-medium,
19
- var(--spacing-padding-5, 12px)
20
- ),
10
+ min-height: var(--button-text-height-medium),
11
+ padding-inline: var(--button-text-padding-inline-medium),
21
12
  ),
22
13
  large: (
23
- min-height: var(--button-text-height-large, var(--theme-size-small-3, 32px)),
24
- padding-inline: var(
25
- --button-text-padding-inline-large,
26
- var(--spacing-padding-5, 12px)
27
- ),
14
+ min-height: var(--button-text-height-large),
15
+ padding-inline: var(--button-text-padding-inline-large),
28
16
  ),
29
17
  );
30
18
 
@@ -33,20 +21,11 @@ $text-size-map: (
33
21
  min-width: auto;
34
22
  border-color: transparent;
35
23
  background-color: transparent;
36
- padding-block: var(
37
- --button-text-padding-block-base,
38
- var(--spacing-padding-4, 8px)
39
- );
40
- padding-inline: var(
41
- --button-text-padding-inline-small,
42
- var(--spacing-padding-4, 8px)
43
- );
24
+ padding-block: var(--button-text-padding-block-base);
25
+ padding-inline: var(--button-text-padding-inline-small);
44
26
  border-width: 0;
45
- gap: var(--spacing-gap-1, 4px);
46
- border-radius: var(
47
- --button-text-radius-base,
48
- var(--theme-radius-small, 4px)
49
- );
27
+ gap: var(--spacing-gap-1);
28
+ border-radius: var(--button-text-radius-base);
50
29
  }
51
30
 
52
31
  @each $size, $tokens in $text-size-map {
@@ -62,45 +41,30 @@ $text-size-map: (
62
41
  }
63
42
 
64
43
  &:where(.button-template-text.button-priority-secondary) {
65
- color: var(
66
- --button-text-secondary-foreground,
67
- var(--color-primary-default)
68
- );
44
+ color: var(--button-text-secondary-foreground);
69
45
 
70
46
  &:hover:not(:disabled),
71
47
  &[data-user-action="hover"]:not(:disabled) {
72
- background-color: var(
73
- --button-text-secondary-hover-bg,
74
- var(--color-bg-alternative-cool-gray, var(--color-cool-gray-95))
75
- );
48
+ background-color: var(--button-text-secondary-hover-bg);
76
49
  }
77
50
 
78
51
  &:active:not(:disabled),
79
52
  &[data-user-action="pressed"]:not(:disabled) {
80
- background-color: var(
81
- --button-text-secondary-pressed-bg,
82
- var(--color-secondary-strong, var(--color-blue-90))
83
- );
53
+ background-color: var(--button-text-secondary-pressed-bg);
84
54
  }
85
55
  }
86
56
 
87
57
  &:where(.button-template-text.button-priority-tertiary) {
88
- color: var(--button-text-tertiary-foreground, var(--color-cool-gray-10));
58
+ color: var(--button-text-tertiary-foreground);
89
59
 
90
60
  &:hover:not(:disabled),
91
61
  &[data-user-action="hover"]:not(:disabled) {
92
- background-color: var(
93
- --button-text-tertiary-hover-bg,
94
- var(--color-bg-alternative-cool-gray, var(--color-cool-gray-95))
95
- );
62
+ background-color: var(--button-text-tertiary-hover-bg);
96
63
  }
97
64
 
98
65
  &:active:not(:disabled),
99
66
  &[data-user-action="pressed"]:not(:disabled) {
100
- background-color: var(
101
- --button-text-tertiary-pressed-bg,
102
- var(--color-surface-strong, var(--color-cool-gray-20))
103
- );
67
+ background-color: var(--button-text-tertiary-pressed-bg);
104
68
  }
105
69
  }
106
70
  }
@@ -25,11 +25,11 @@
25
25
  /* default button sizing */
26
26
  --button-default-width-min-base: var(--theme-size-small-2);
27
27
 
28
- --button-default-height-small: var(--theme-size-small-3, 32px);
29
- --button-default-height-medium: var(--theme-size-medium-1, 40px);
30
- --button-default-height-large: var(--theme-size-medium-2, 48px);
31
- --button-default-height-xlarge: var(--theme-size-medium-3, 56px);
32
- --button-default-height-table: var(--theme-size-small-2, 24px);
28
+ --button-default-height-small: var(--theme-size-small-3);
29
+ --button-default-height-medium: var(--theme-size-medium-1);
30
+ --button-default-height-large: var(--theme-size-medium-2);
31
+ --button-default-height-xlarge: var(--theme-size-medium-3);
32
+ --button-default-height-table: var(--theme-size-small-2);
33
33
 
34
34
  --button-default-radius-small: var(--theme-radius-medium-3);
35
35
  --button-default-radius-medium: var(--theme-radius-medium-3);
@@ -38,68 +38,57 @@
38
38
  --button-default-radius-table: var(--theme-radius-medium-2);
39
39
 
40
40
  /* text buttons */
41
- --button-text-padding-block-base: var(--spacing-padding-4, 8px);
42
- --button-text-padding-inline-small: var(--spacing-padding-4, 8px);
43
- --button-text-padding-inline-medium: var(--spacing-padding-5, 12px);
44
- --button-text-padding-inline-large: var(--spacing-padding-5, 12px);
45
- --button-text-height-small: var(--theme-size-small-1, 20px);
46
- --button-text-height-medium: var(--theme-size-small-2, 24px);
47
- --button-text-height-large: var(--theme-size-small-3, 32px);
48
- --button-text-radius-base: var(--theme-radius-small, 4px);
41
+ --button-text-padding-block-base: var(--spacing-padding-4);
42
+ --button-text-padding-inline-small: var(--spacing-padding-4);
43
+ --button-text-padding-inline-medium: var(--spacing-padding-5);
44
+ --button-text-padding-inline-large: var(--spacing-padding-5);
45
+ --button-text-height-small: var(--theme-size-small-1);
46
+ --button-text-height-medium: var(--theme-size-small-2);
47
+ --button-text-height-large: var(--theme-size-small-3);
48
+ --button-text-radius-base: var(--theme-radius-small);
49
49
 
50
50
  /* round buttons */
51
- --button-round-padding-inline-small: var(--spacing-padding-5, 12px);
52
- --button-round-padding-inline-medium: var(--spacing-padding-6, 16px);
53
- --button-round-padding-inline-large: var(--spacing-padding-7, 20px);
54
- --button-round-padding-block-base: var(--spacing-padding-2, 4px);
55
- --button-round-height-small: var(--theme-size-small-2, 24px);
56
- --button-round-height-medium: var(--theme-size-small-3, 32px);
57
- --button-round-height-large: var(--theme-size-medium-1, 40px);
58
- --button-round-radius-small: var(--theme-radius-xlarge-2, 16px);
59
- --button-round-radius-medium: var(--theme-radius-xlarge-2, 16px);
51
+ --button-round-padding-inline-small: var(--spacing-padding-5);
52
+ --button-round-padding-inline-medium: var(--spacing-padding-6);
53
+ --button-round-padding-inline-large: var(--spacing-padding-7);
54
+ --button-round-padding-block-base: var(--spacing-padding-2);
55
+ --button-round-height-small: var(--theme-size-small-2);
56
+ --button-round-height-medium: var(--theme-size-small-3);
57
+ --button-round-height-large: var(--theme-size-medium-1);
58
+ --button-round-radius-small: var(--theme-radius-xlarge);
59
+ --button-round-radius-medium: var(--theme-radius-xlarge);
60
60
  --button-round-radius-large: 30px;
61
61
 
62
62
  /* typography */
63
63
  --button-default-font-weight: 400;
64
- --button-default-font-body-medium-family: var(--font-body-medium-family);
65
64
  --button-default-font-body-medium-size: var(--font-body-medium-size);
66
65
  --button-default-font-body-medium-weight: var(--button-default-font-weight);
67
- --button-default-font-body-medium-line-height: var(
68
- --font-body-medium-line-height
69
- );
66
+ --button-default-font-body-medium-line-height: 1em;
70
67
  --button-default-font-body-medium-letter-spacing: var(
71
68
  --font-body-medium-letter-spacing
72
69
  );
73
70
  --button-default-font-label-medium-size: var(--font-body-xxsmall-size);
74
71
  --button-default-font-label-medium-weight: var(--button-default-font-weight);
75
- --button-default-font-label-medium-line-height: var(
76
- --font-body-xxsmall-line-height
77
- );
72
+ --button-default-font-label-medium-line-height: 1em;
78
73
  --button-default-font-label-medium-letter-spacing: var(
79
74
  --font-body-xxsmall-letter-spacing
80
75
  );
81
76
  --button-default-font-label-large-size: var(--font-body-xsmall-size);
82
77
  --button-default-font-label-large-weight: var(--button-default-font-weight);
83
- --button-default-font-label-large-line-height: var(
84
- --font-body-xsmall-line-height
85
- );
78
+ --button-default-font-label-large-line-height: 1em;
86
79
  --button-default-font-label-large-letter-spacing: var(
87
80
  --font-body-xsmall-letter-spacing
88
81
  );
89
82
  --button-default-font-body-large-size: var(--font-body-large-size);
90
83
  --button-default-font-body-large-weight: var(--button-default-font-weight);
91
- --button-default-font-body-large-line-height: var(
92
- --font-body-large-line-height
93
- );
84
+ --button-default-font-body-large-line-height: 1em;
94
85
  --button-default-font-body-large-letter-spacing: var(
95
86
  --font-body-large-letter-spacing
96
87
  );
97
88
  /* 변경: table 버튼은 caption-large 스케일(12px)을 사용한다. */
98
89
  --button-default-font-caption-large-size: var(--font-caption-large-size);
99
90
  --button-default-font-caption-large-weight: var(--button-default-font-weight);
100
- --button-default-font-caption-large-line-height: var(
101
- --font-caption-large-line-height
102
- );
91
+ --button-default-font-caption-large-line-height: 1em;
103
92
  --button-default-font-caption-large-letter-spacing: var(
104
93
  --font-caption-large-letter-spacing
105
94
  );
@@ -107,6 +96,7 @@
107
96
  --button-default-neutral-foreground: var(--color-neutral-20);
108
97
  --button-default-neutral-disabled-bg: var(--color-surface-standard);
109
98
  --button-default-neutral-disabled-foreground: var(--color-label-disabled);
99
+ --button-default-outline-bg: var(--color-surface-static-white);
110
100
 
111
101
  --button-default-primary-solid-bg: var(--color-primary-default);
112
102
  --button-default-primary-solid-hover-bg: var(--color-blue-50);
@@ -118,7 +108,7 @@
118
108
  --button-default-primary-outline-hover-foreground: var(--color-common-100);
119
109
  --button-default-primary-overlay-outlined-bg: var(--color-blue-90);
120
110
 
121
- --button-default-secondary-solid-bg: var(--color-blue-95, #e5eeff);
111
+ --button-default-secondary-solid-bg: var(--color-blue-95);
122
112
  --button-default-secondary-solid-hover-bg: #dbe9ff;
123
113
  --button-default-secondary-solid-active-bg: #ccdeff;
124
114
  --button-default-secondary-solid-foreground: var(--color-primary-default);
@@ -216,21 +206,9 @@
216
206
 
217
207
  /* text button colors */
218
208
  --button-text-secondary-foreground: var(--color-primary-default);
219
- --button-text-secondary-hover-bg: var(
220
- --color-bg-alternative-cool-gray,
221
- var(--color-cool-gray-95)
222
- );
223
- --button-text-secondary-pressed-bg: var(
224
- --color-secondary-strong,
225
- var(--color-blue-90)
226
- );
209
+ --button-text-secondary-hover-bg: var(--color-bg-alternative-cool-gray);
210
+ --button-text-secondary-pressed-bg: var(--color-secondary-strong);
227
211
  --button-text-tertiary-foreground: var(--color-cool-gray-10);
228
- --button-text-tertiary-hover-bg: var(
229
- --color-bg-alternative-cool-gray,
230
- var(--color-cool-gray-95)
231
- );
232
- --button-text-tertiary-pressed-bg: var(
233
- --color-surface-strong,
234
- var(--color-cool-gray-20)
235
- );
212
+ --button-text-tertiary-hover-bg: var(--color-bg-alternative-cool-gray);
213
+ --button-text-tertiary-pressed-bg: var(--color-surface-strong);
236
214
  }
@@ -10,22 +10,25 @@ import type {
10
10
 
11
11
  /**
12
12
  * Button Types; scale 구성 객체 타입
13
- * @property {ButtonFill} fill fill 옵션.
14
- * @property {ButtonScaleGroup} group scale group 옵션.
15
- * @property {ButtonSize} size size 옵션.
13
+ * @property {"solid" | "outlined"} fill fill 옵션.
14
+ * @property {"solid" | "outlined"} group scale group 옵션.
15
+ * @property {"xlarge" | "large" | "medium" | "small" | "table"} size size 옵션.
16
16
  * @deprecated
17
17
  */
18
- type ButtonScaleConfig = {
18
+ export type ButtonScaleConfig = {
19
19
  /**
20
20
  * fill 옵션.
21
+ * "solid" | "outlined"
21
22
  */
22
23
  fill: ButtonFill;
23
24
  /**
24
25
  * scale group 옵션.
26
+ * "solid" | "outlined"
25
27
  */
26
28
  group: ButtonScaleGroup;
27
29
  /**
28
30
  * size 옵션.
31
+ * "xlarge" | "large" | "medium" | "small" | "table"
29
32
  */
30
33
  size: ButtonSize;
31
34
  };
@@ -28,7 +28,7 @@ export type ButtonPriority =
28
28
  * @typedef {"solid" | "outlined"} ButtonFill
29
29
  * @desc
30
30
  * - solid: 배경을 채우는 스타일.
31
- * - outlined: 배경을 비우고 선만 두르는 스타일.
31
+ * - outlined: 흰색 기본 면에 테두리를 두르는 스타일.
32
32
  */
33
33
  export type ButtonFill = "solid" | "outlined";
34
34
 
@@ -52,6 +52,7 @@ export type ButtonSize = "xlarge" | "large" | "medium" | "small" | "table";
52
52
  * } ButtonScale
53
53
  * @deprecated
54
54
  * @desc
55
+ * Base는 전달된 값을 완전히 무시하며 fill/size fallback으로 사용하지 않는다.
55
56
  * - solid-xlarge~solid-small: Solid fill + size 조합.
56
57
  * - outlined-xlarge~outlined-small: Outline fill + size 조합.
57
58
  */
@@ -92,27 +93,27 @@ export type ButtonScaleGroup = ButtonFill;
92
93
  /**
93
94
  * Button; <button /> native props 타입
94
95
  */
95
- type NativeButtonProps = ComponentPropsWithoutRef<"button">;
96
+ export type NativeButtonProps = ComponentPropsWithoutRef<"button">;
96
97
  /**
97
98
  * Button; <a /> native props 타입
98
99
  */
99
- type AnchorProps = ComponentPropsWithoutRef<"a">;
100
+ export type AnchorProps = ComponentPropsWithoutRef<"a">;
100
101
 
101
102
  /**
102
103
  * Button; 컴포넌트 공통 props 타입
103
104
  */
104
- type SharedElementProps = Omit<NativeButtonProps, "children"> &
105
+ export type SharedElementProps = Omit<NativeButtonProps, "children"> &
105
106
  Omit<AnchorProps, "children">;
106
107
 
107
108
  /**
108
109
  * Button 컴포넌트의 공통 props.
109
110
  * @property {ElementType} [as] 렌더링할 요소. 기본값은 button.
110
111
  * @property {ReactNode} [children] 주 내용. 문자열이면 자동으로 .button-label로 감싼다.
111
- * @property {"solid-xlarge" | "solid-large" | "solid-medium" | "solid-small" | "outlined-xlarge" | "outlined-large" | "outlined-medium" | "outlined-small"} [scale] 레이아웃/spacing 집합. 추후 fill/size 조합으로 대체 예정이다.
112
- * @property {"solid" | "outlined"} fill 채움 스타일. scale 조합보다 우선한다.
113
- * @property {"xlarge" | "large" | "medium" | "small" | "table"} size 높이/타이포 스케일. scale 조합보다 우선한다.
112
+ * @property {"solid-xlarge" | "solid-large" | "solid-medium" | "solid-small" | "outlined-xlarge" | "outlined-large" | "outlined-medium" | "outlined-small"} [scale] deprecated 호환 입력. Base는 값을 완전히 무시하며 fill/size fallback이 아니다.
113
+ * @property {"solid" | "outlined"} fill 필수 채움 스타일.
114
+ * @property {"xlarge" | "large" | "medium" | "small" | "table"} size 필수 높이/타이포 스케일.
114
115
  * @property {"primary" | "secondary" | "tertiary" | "green" | "yellow" | "orange" | "teal" | "pink" | "red" | "darkGray" | "lightGray"} priority semantic color priority.
115
- * @property {"default" | "readonly" | "disabled"} [state] UI 상태. disabled prop과 조합된다.
116
+ * @property {"default" | "readonly" | "disabled"} [state] UI 상태. 최종 값은 loading → disabled state 순서로 계산된다.
116
117
  * @property {boolean} [block] width:100% 확장 여부.
117
118
  * @property {FormFieldWidth} [width] width preset. block보다 우선 적용된다.
118
119
  * @property {boolean} [loading] true면 readonly 처리 + aria-busy.
@@ -135,7 +136,7 @@ export interface ButtonProps extends SharedElementProps {
135
136
  * @deprecated
136
137
  * "solid-xlarge" | "solid-large" | "solid-medium" | "solid-small" |
137
138
  * "outlined-xlarge" | "outlined-large" | "outlined-medium" | "outlined-small"
138
- * fill/size 제공하지 않을 때만 fallback으로 사용한다.
139
+ * Base는 값을 완전히 무시하며 fill/size fallback이 아니다. 필수 fill과 size를 사용한다.
139
140
  */
140
141
  scale?: ButtonScale;
141
142
  /**
@@ -156,7 +157,7 @@ export interface ButtonProps extends SharedElementProps {
156
157
  size: ButtonSize;
157
158
  /**
158
159
  * 컴포넌트 내부 state.
159
- * disabled prop과 병합되어 최종 상태를 결정한다.
160
+ * loading → disabled state 우선순위로 최종 상태를 결정한다.
160
161
  * "default" | "readonly" | "disabled"
161
162
  */
162
163
  state?: ButtonState;
@@ -188,10 +189,6 @@ export interface ButtonProps extends SharedElementProps {
188
189
  "data-user-action"?: ButtonUserAction;
189
190
  }
190
191
 
191
- /**
192
- * 변경 사항: preset 타입 파일을 제거하고 props.ts로 통합한다.
193
- */
194
-
195
192
  /**
196
193
  * Button Types; Text preset size 옵션
197
194
  * @typedef {"small" | "medium" | "large"} TextButtonSize
@@ -1,15 +1,26 @@
1
1
  import clsx from "clsx";
2
- type ButtonClassNameOptions = {
2
+
3
+ /**
4
+ * Button utility; className 조합 입력
5
+ * @property {string} [className] 기본 `button` class와 병합할 추가 className.
6
+ */
7
+ export type ButtonClassNameOptions = {
8
+ /**
9
+ * 기본 `button` class와 병합할 추가 className.
10
+ */
3
11
  className?: string;
4
12
  };
5
13
 
6
14
  const BUTTON_CLASSNAME = "button";
7
15
 
8
16
  /**
9
- * 버튼 클래스 조합 helper: scale/fill/priority/size 별 modifier를 한 곳에서 관리한다.
17
+ * Button utility; 기본 className 조합
18
+ * @utility
19
+ * @property {string} [className] 기본 `button` class와 병합할 추가 className.
20
+ * @desc 기본 `button` class와 전달된 className만 clsx로 병합하며 modifier는 생성하지 않는다.
21
+ * @return {string} 병합된 className.
10
22
  */
11
23
  const composeButtonClassName = ({ className }: ButtonClassNameOptions) =>
12
24
  clsx(BUTTON_CLASSNAME, className);
13
25
 
14
26
  export { BUTTON_CLASSNAME, composeButtonClassName };
15
- export type { ButtonClassNameOptions };