@uniai-fe/uds-primitives 0.4.6 → 0.4.8

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.
@@ -1,9 +1,9 @@
1
1
  import * as TabsPrimitive from "@radix-ui/react-tabs";
2
2
  import clsx from "clsx";
3
- import { forwardRef, useEffect, useMemo } from "react";
3
+ import { forwardRef } from "react";
4
4
  import type { CSSProperties } from "react";
5
5
  import type { TabListProps } from "../types";
6
- import { useTabContext, DEFAULT_TAB_CONTEXT_VALUE } from "../utils";
6
+ import { DEFAULT_TAB_CONTEXT_VALUE, TabContext, useTabContext } from "../utils";
7
7
 
8
8
  /**
9
9
  * TabList: Tab trigger container with variant/tone propagation.
@@ -38,36 +38,34 @@ const TabList = forwardRef<HTMLDivElement, TabListProps>(
38
38
  scale ?? parentContext.scale ?? DEFAULT_TAB_CONTEXT_VALUE.scale;
39
39
  const resolvedColor =
40
40
  color ?? parentContext.color ?? DEFAULT_TAB_CONTEXT_VALUE.color;
41
-
42
- useEffect(() => {
43
- parentContext.setSharedConfig?.(
44
- resolvedVariant,
45
- resolvedColor,
46
- resolvedScale,
47
- );
48
- }, [parentContext, resolvedVariant, resolvedColor, resolvedScale]);
49
-
50
- const listStyle = useMemo<CSSProperties>(
51
- () => ({
52
- ...(style ?? {}),
53
- "--tab-color-active": resolvedColor,
54
- }),
55
- [style, resolvedColor],
56
- );
41
+ // 변경: List-local override는 nearest provider로만 전달해 Root state 역주입을 제거한다.
42
+ const listStyle = color
43
+ ? ({
44
+ ...(style ?? {}),
45
+ "--tab-color-active": resolvedColor,
46
+ } as CSSProperties)
47
+ : style;
57
48
 
58
49
  return (
59
- <TabsPrimitive.List
60
- {...restProps}
61
- ref={forwardedRef}
62
- className={clsx("tab-list", className)}
63
- data-variant={resolvedVariant}
64
- data-scale={resolvedScale}
65
- data-full-width={fullWidth ? "true" : undefined}
66
- data-color={resolvedColor}
67
- style={listStyle}
50
+ <TabContext.Provider
51
+ value={{
52
+ variant: resolvedVariant,
53
+ color: resolvedColor,
54
+ scale: resolvedScale,
55
+ }}
68
56
  >
69
- {children}
70
- </TabsPrimitive.List>
57
+ <TabsPrimitive.List
58
+ {...restProps}
59
+ ref={forwardedRef}
60
+ className={clsx("tab-list", className)}
61
+ data-variant={resolvedVariant}
62
+ data-scale={resolvedScale}
63
+ data-full-width={fullWidth ? "true" : undefined}
64
+ style={listStyle}
65
+ >
66
+ {children}
67
+ </TabsPrimitive.List>
68
+ </TabContext.Provider>
71
69
  );
72
70
  },
73
71
  );
@@ -1,31 +1,10 @@
1
1
  import * as TabsPrimitive from "@radix-ui/react-tabs";
2
2
  import clsx from "clsx";
3
- import { forwardRef, useEffect, useMemo, useState } from "react";
3
+ import { forwardRef } from "react";
4
4
  import type { CSSProperties } from "react";
5
- import type { TabRootProps, TabScale } from "../types";
5
+ import type { TabRootProps } from "../types";
6
6
  import { TabContext, DEFAULT_TAB_CONTEXT_VALUE } from "../utils";
7
7
 
8
- const TAB_SCALE_STYLES: Record<TabScale, Record<string, string>> = {
9
- small: {
10
- "--tab-label-font-size": "var(--font-heading-xxsmall-size, 15px)",
11
- "--tab-label-font-weight": "var(--font-heading-xxsmall-weight, 600)",
12
- "--tab-height": "40px",
13
- "--tab-padding-x": "var(--spacing-padding-4, 8px)",
14
- },
15
- medium: {
16
- "--tab-label-font-size": "var(--font-heading-xsmall-size, 17px)",
17
- "--tab-label-font-weight": "var(--font-heading-xsmall-weight, 600)",
18
- "--tab-height": "48px",
19
- "--tab-padding-x": "var(--spacing-padding-8, 24px)",
20
- },
21
- large: {
22
- "--tab-label-font-size": "var(--font-heading-small-size, 19px)",
23
- "--tab-label-font-weight": "var(--font-heading-small-weight, 600)",
24
- "--tab-height": "56px",
25
- "--tab-padding-x": "var(--spacing-padding-8, 24px)",
26
- },
27
- };
28
-
29
8
  /**
30
9
  * TabRoot: TabsPrimitive.Root thin wrapper with tab data context.
31
10
  * @component
@@ -43,9 +22,9 @@ const TAB_SCALE_STYLES: Record<TabScale, Record<string, string>> = {
43
22
  const TabRoot = forwardRef<HTMLDivElement, TabRootProps>(
44
23
  (
45
24
  {
46
- variant: variantProp = DEFAULT_TAB_CONTEXT_VALUE.variant,
47
- scale: scaleProp = DEFAULT_TAB_CONTEXT_VALUE.scale,
48
- color: colorProp = DEFAULT_TAB_CONTEXT_VALUE.color,
25
+ variant: variantProp,
26
+ scale: scaleProp,
27
+ color: colorProp,
49
28
  className,
50
29
  children,
51
30
  style,
@@ -53,53 +32,19 @@ const TabRoot = forwardRef<HTMLDivElement, TabRootProps>(
53
32
  },
54
33
  forwardedRef,
55
34
  ) => {
56
- const [variant, setVariant] = useState(variantProp);
57
- const [color, setColor] = useState(colorProp);
58
- const [scale, setScale] = useState(scaleProp);
59
-
60
- useEffect(() => {
61
- setVariant(variantProp);
62
- }, [variantProp]);
63
-
64
- useEffect(() => {
65
- setColor(colorProp);
66
- }, [colorProp]);
67
-
68
- useEffect(() => {
69
- setScale(scaleProp);
70
- }, [scaleProp]);
71
-
72
- const contextValue = useMemo(
73
- () => ({
74
- variant,
75
- color,
76
- scale,
77
- setSharedConfig: (
78
- nextVariant: typeof variant,
79
- nextColor: typeof color,
80
- nextScale: typeof scale,
81
- ) => {
82
- setVariant(nextVariant);
83
- setColor(nextColor);
84
- setScale(nextScale);
85
- },
86
- }),
87
- [variant, color, scale],
88
- );
89
-
90
- const resolvedScaleStyle =
91
- TAB_SCALE_STYLES[scale] ?? TAB_SCALE_STYLES.medium;
92
- const rootStyle = useMemo<CSSProperties>(
93
- () => ({
94
- ...(style ?? {}),
95
- "--tab-color-active": color,
96
- ...resolvedScaleStyle,
97
- }),
98
- [style, color, resolvedScaleStyle],
99
- );
35
+ const variant = variantProp ?? DEFAULT_TAB_CONTEXT_VALUE.variant;
36
+ const scale = scaleProp ?? DEFAULT_TAB_CONTEXT_VALUE.scale;
37
+ const color = colorProp ?? DEFAULT_TAB_CONTEXT_VALUE.color;
38
+ // 변경: runtime color prop만 CSS 변수로 주입하고, size 토큰은 styles/variables.scss에서 관리한다.
39
+ const rootStyle = colorProp
40
+ ? ({
41
+ ...(style ?? {}),
42
+ "--tab-color-active": colorProp,
43
+ } as CSSProperties)
44
+ : style;
100
45
 
101
46
  return (
102
- <TabContext.Provider value={contextValue}>
47
+ <TabContext.Provider value={{ variant, color, scale }}>
103
48
  <TabsPrimitive.Root
104
49
  {...restProps}
105
50
  ref={forwardedRef}
@@ -1,21 +1,9 @@
1
1
  import * as TabsPrimitive from "@radix-ui/react-tabs";
2
2
  import clsx from "clsx";
3
3
  import { forwardRef } from "react";
4
- import type { ReactNode } from "react";
5
4
  import type { TabTriggerProps } from "../types";
6
5
  import { useTabContext } from "../utils";
7
-
8
- const wrapLabel = (children: ReactNode) => {
9
- if (children === null || children === undefined) {
10
- return null;
11
- }
12
-
13
- if (typeof children === "string" || typeof children === "number") {
14
- return <span className="tab-trigger-label">{children}</span>;
15
- }
16
-
17
- return children;
18
- };
6
+ import { TabLabel } from "./Label";
19
7
 
20
8
  /**
21
9
  * TabTrigger: 개별 탭 버튼. icon slot을 지원한다.
@@ -31,7 +19,6 @@ const TabTrigger = forwardRef<HTMLButtonElement, TabTriggerProps>(
31
19
  ({ icon, children, className, ...restProps }, forwardedRef) => {
32
20
  const { variant, scale } = useTabContext();
33
21
  const hasIcon = Boolean(icon);
34
- const normalizedChildren = wrapLabel(children);
35
22
 
36
23
  return (
37
24
  <TabsPrimitive.Trigger
@@ -44,7 +31,7 @@ const TabTrigger = forwardRef<HTMLButtonElement, TabTriggerProps>(
44
31
  data-disabled={restProps.disabled ? "true" : undefined}
45
32
  >
46
33
  {icon ? <span className="tab-trigger-icon">{icon}</span> : null}
47
- {normalizedChildren}
34
+ <TabLabel>{children}</TabLabel>
48
35
  </TabsPrimitive.Trigger>
49
36
  );
50
37
  },
@@ -1,198 +1,2 @@
1
- .tab-root {
2
- /* Figma node 694:4619 측정값을 CSS 변수로 고정해 Storybook과 실 서비스 간 시각 편차를 줄인다. */
3
- --tab-label-font-size: var(--font-heading-xsmall-size, 17px);
4
- --tab-label-font-weight: var(--font-heading-xsmall-weight, 600);
5
- --tab-label-line-height: 1.4;
6
- --tab-label-letter-spacing: 0px;
7
- --tab-gap: var(--spacing-gap-2, 8px);
8
- --tab-padding-y: 10px;
9
- --tab-padding-x: var(--spacing-padding-8, 24px);
10
- --tab-icon-gap: 6px;
11
- --tab-line-track-color: var(--color-border-divider, #f2f2f3);
12
- --tab-line-track-height: 1px;
13
- --tab-line-indicator-height: 2px;
14
- --tab-color-active-default: #1a6aff;
15
- --tab-color-active: var(--tab-color-active-default);
16
- --tab-color-hover: color-mix(in srgb, var(--tab-color-active), #000 15%);
17
- --tab-line-hover-color: var(--tab-color-hover, var(--tab-color-active));
18
- --tab-fill-hover-bg: var(--color-bg-alternative-cool-gray, #f2f2f3);
19
- --tab-fill-active-color: var(--color-common-100, #ffffff);
20
- --tab-inactive-color: var(--color-label-alternative, #afb1b6);
21
- --tab-disabled-opacity: 0.4;
22
- --tab-height: 48px;
23
- width: 100%;
24
- display: flex;
25
- flex-direction: column;
26
- gap: var(--spacing-gap-3);
27
- }
28
-
29
- .tab-root:where([data-scale="small"]) {
30
- --tab-label-font-size: var(--font-heading-xxsmall-size, 15px);
31
- --tab-label-font-weight: var(--font-heading-xxsmall-weight, 600);
32
- --tab-height: 40px;
33
- --tab-padding-x: var(--spacing-padding-4, 8px);
34
- }
35
-
36
- .tab-root:where([data-scale="medium"]) {
37
- --tab-label-font-size: var(--font-heading-xsmall-size, 17px);
38
- --tab-label-font-weight: var(--font-heading-xsmall-weight, 600);
39
- --tab-height: 48px;
40
- }
41
-
42
- .tab-root:where([data-scale="large"]) {
43
- --tab-label-font-size: var(--font-heading-small-size, 19px);
44
- --tab-label-font-weight: var(--font-heading-small-weight, 600);
45
- --tab-height: 56px;
46
- --tab-padding-x: var(--spacing-padding-8, 24px);
47
- }
48
-
49
- .tab-list {
50
- display: flex;
51
- align-items: stretch;
52
- gap: var(--tab-gap);
53
- width: fit-content;
54
- overflow-x: auto;
55
- scrollbar-width: none;
56
- }
57
-
58
- .tab-list::-webkit-scrollbar {
59
- display: none;
60
- }
61
-
62
- .tab-list:where([data-full-width="true"]) {
63
- width: 100%;
64
- }
65
-
66
- .tab-trigger {
67
- position: relative;
68
- display: flex;
69
- align-items: center;
70
- justify-content: center;
71
- gap: var(--tab-icon-gap);
72
- min-height: var(--tab-height);
73
- padding: var(--tab-padding-y) var(--tab-padding-x);
74
- background: transparent;
75
- border: none;
76
- cursor: pointer;
77
- transition: background-color 0.2s ease;
78
- }
79
-
80
- .tab-trigger:where(:focus-visible) {
81
- outline: 2px solid var(--color-focus-ring, var(--color-primary-default));
82
- outline-offset: 2px;
83
- }
84
-
85
- .tab-trigger:where([data-disabled="true"]) {
86
- cursor: not-allowed;
87
- opacity: var(--tab-disabled-opacity);
88
- }
89
-
90
- .tab-trigger-icon {
91
- display: flex;
92
- align-items: center;
93
- justify-content: center;
94
- }
95
-
96
- .tab-trigger-label {
97
- display: flex;
98
- align-items: center;
99
- justify-content: center;
100
- font-size: var(--tab-label-font-size);
101
- font-weight: var(--tab-label-font-weight);
102
- line-height: var(--tab-label-line-height);
103
- letter-spacing: var(--tab-label-letter-spacing);
104
- color: var(--tab-inactive-color);
105
- transition: color 0.2s ease;
106
- }
107
-
108
- .tab-list:where([data-variant="line"]) {
109
- position: relative;
110
- width: 100%;
111
- }
112
-
113
- .tab-list:where([data-variant="line"])::before {
114
- content: "";
115
- position: absolute;
116
- inset: auto 0 0;
117
- height: var(--tab-line-track-height, 1px);
118
- background: var(--tab-line-track-color);
119
- z-index: 0;
120
- }
121
-
122
- .tab-list:where([data-variant="line"][data-full-width="true"]) > .tab-trigger {
123
- flex: 1;
124
- }
125
-
126
- .tab-trigger:where([data-variant="line"])::after {
127
- content: "";
128
- position: absolute;
129
- left: 0;
130
- right: 0;
131
- bottom: -1px;
132
- height: var(--tab-line-indicator-height, 2px);
133
- background: transparent;
134
- transform: scaleX(0);
135
- transform-origin: center;
136
- z-index: 1;
137
- transition:
138
- transform 0.2s ease,
139
- background-color 0.2s ease;
140
- }
141
-
142
- .tab-trigger:where([data-variant="line"][data-state="active"])
143
- .tab-trigger-label {
144
- color: var(--tab-color-active);
145
- }
146
-
147
- .tab-trigger:where([data-variant="line"][data-state="active"])::after {
148
- background: var(--tab-color-active);
149
- transform: scaleX(1);
150
- }
151
-
152
- .tab-trigger:where([data-variant="line"]):where(
153
- :not([data-state="active"])
154
- ):hover
155
- .tab-trigger-label {
156
- color: var(--tab-line-hover-color);
157
- }
158
-
159
- .tab-list:where([data-variant="fill"]) {
160
- width: fit-content;
161
- border: none;
162
- background: transparent;
163
- border-radius: 0;
164
- gap: 0;
165
- }
166
-
167
- .tab-list:where([data-variant="fill"][data-full-width="true"]) {
168
- width: 100%;
169
- }
170
-
171
- .tab-list:where([data-variant="fill"][data-full-width="true"]) > .tab-trigger {
172
- flex: 1;
173
- }
174
-
175
- .tab-trigger:where([data-variant="fill"]) {
176
- border-radius: 12px;
177
- min-width: 0;
178
- }
179
-
180
- .tab-trigger:where([data-variant="fill"][data-state="active"]) {
181
- background: var(--tab-color-active);
182
- }
183
-
184
- .tab-trigger:where([data-variant="fill"][data-state="active"])
185
- .tab-trigger-label {
186
- color: var(--tab-fill-active-color);
187
- }
188
-
189
- .tab-trigger:where([data-variant="fill"]):where(
190
- :not([data-state="active"])
191
- ):hover {
192
- background: var(--tab-fill-hover-bg);
193
- }
194
-
195
- .tab-content {
196
- display: block;
197
- padding: var(--spacing-padding-6) 0;
198
- }
1
+ @use "./variables";
2
+ @use "./tab";
@@ -0,0 +1,190 @@
1
+ .tab-root {
2
+ --tab-height: var(--tab-height-medium);
3
+ --tab-label-font-size: var(--tab-label-font-size-medium);
4
+ --tab-label-font-weight: var(--tab-label-font-weight-medium);
5
+ --tab-label-line-height: var(--tab-label-line-height-medium);
6
+ --tab-label-letter-spacing: var(--tab-label-letter-spacing-medium);
7
+ width: 100%;
8
+ display: flex;
9
+ flex-direction: column;
10
+ gap: var(--tab-root-gap);
11
+ }
12
+
13
+ .tab-root:where([data-scale="small"]) {
14
+ --tab-height: var(--tab-height-small);
15
+ --tab-label-font-size: var(--tab-label-font-size-small);
16
+ --tab-label-font-weight: var(--tab-label-font-weight-small);
17
+ --tab-label-line-height: var(--tab-label-line-height-small);
18
+ --tab-label-letter-spacing: var(--tab-label-letter-spacing-small);
19
+ --tab-padding-x: var(--tab-padding-x-small);
20
+ }
21
+
22
+ .tab-root:where([data-scale="medium"]) {
23
+ --tab-height: var(--tab-height-medium);
24
+ --tab-label-font-size: var(--tab-label-font-size-medium);
25
+ --tab-label-font-weight: var(--tab-label-font-weight-medium);
26
+ --tab-label-line-height: var(--tab-label-line-height-medium);
27
+ --tab-label-letter-spacing: var(--tab-label-letter-spacing-medium);
28
+ --tab-padding-x: var(--spacing-padding-8);
29
+ }
30
+
31
+ .tab-root:where([data-scale="large"]) {
32
+ --tab-height: var(--tab-height-large);
33
+ --tab-label-font-size: var(--tab-label-font-size-large);
34
+ --tab-label-font-weight: var(--tab-label-font-weight-large);
35
+ --tab-label-line-height: var(--tab-label-line-height-large);
36
+ --tab-label-letter-spacing: var(--tab-label-letter-spacing-large);
37
+ --tab-padding-x: var(--spacing-padding-8);
38
+ }
39
+
40
+ .tab-list {
41
+ display: flex;
42
+ align-items: stretch;
43
+ gap: var(--tab-gap);
44
+ width: fit-content;
45
+ overflow-x: auto;
46
+ scrollbar-width: none;
47
+ }
48
+
49
+ .tab-list::-webkit-scrollbar {
50
+ display: none;
51
+ }
52
+
53
+ .tab-list:where([data-full-width="true"]) {
54
+ width: 100%;
55
+ }
56
+
57
+ .tab-trigger {
58
+ position: relative;
59
+ display: flex;
60
+ align-items: center;
61
+ justify-content: center;
62
+ gap: var(--tab-icon-gap);
63
+ min-height: var(--tab-height);
64
+ padding: var(--tab-padding-y) var(--tab-padding-x);
65
+ background: transparent;
66
+ border: none;
67
+ cursor: pointer;
68
+ transition: background-color 0.2s ease;
69
+ }
70
+
71
+ .tab-trigger:where(:focus-visible) {
72
+ outline: 2px solid var(--color-primary-default);
73
+ outline-offset: 2px;
74
+ }
75
+
76
+ .tab-trigger:where([data-disabled="true"]) {
77
+ cursor: not-allowed;
78
+ opacity: var(--tab-disabled-opacity);
79
+ }
80
+
81
+ .tab-trigger-icon {
82
+ display: flex;
83
+ align-items: center;
84
+ justify-content: center;
85
+ }
86
+
87
+ .tab-trigger-label {
88
+ display: flex;
89
+ align-items: center;
90
+ justify-content: center;
91
+ font-size: var(--tab-label-font-size);
92
+ font-weight: var(--tab-label-font-weight);
93
+ line-height: var(--tab-label-line-height);
94
+ letter-spacing: var(--tab-label-letter-spacing);
95
+ color: var(--tab-inactive-color);
96
+ transition: color 0.2s ease;
97
+ }
98
+
99
+ .tab-list:where([data-variant="line"]) {
100
+ position: relative;
101
+ width: 100%;
102
+ }
103
+
104
+ .tab-list:where([data-variant="line"])::before {
105
+ content: "";
106
+ position: absolute;
107
+ inset: auto 0 0;
108
+ height: var(--tab-line-track-height);
109
+ background: var(--tab-line-track-color);
110
+ z-index: 0;
111
+ }
112
+
113
+ .tab-list:where([data-variant="line"][data-full-width="true"]) > .tab-trigger {
114
+ flex: 1;
115
+ }
116
+
117
+ .tab-trigger:where([data-variant="line"])::after {
118
+ content: "";
119
+ position: absolute;
120
+ left: 0;
121
+ right: 0;
122
+ /* 변경: scroll container에서 vertical overflow clip 리스크를 피하기 위해 indicator를 내부 바닥에 붙인다. */
123
+ bottom: 0;
124
+ height: var(--tab-line-indicator-height);
125
+ background: transparent;
126
+ transform: scaleX(0);
127
+ transform-origin: center;
128
+ z-index: 1;
129
+ transition:
130
+ transform 0.2s ease,
131
+ background-color 0.2s ease;
132
+ }
133
+
134
+ .tab-trigger:where([data-variant="line"][data-state="active"])
135
+ .tab-trigger-label {
136
+ color: var(--tab-color-active);
137
+ }
138
+
139
+ .tab-trigger:where([data-variant="line"][data-state="active"])::after {
140
+ background: var(--tab-color-active);
141
+ transform: scaleX(1);
142
+ }
143
+
144
+ .tab-trigger:where([data-variant="line"]):where(
145
+ :not([data-state="active"])
146
+ ):hover
147
+ .tab-trigger-label {
148
+ color: var(--tab-color-hover);
149
+ }
150
+
151
+ .tab-list:where([data-variant="fill"]) {
152
+ width: fit-content;
153
+ border: none;
154
+ background: transparent;
155
+ border-radius: 0;
156
+ gap: 0;
157
+ }
158
+
159
+ .tab-list:where([data-variant="fill"][data-full-width="true"]) {
160
+ width: 100%;
161
+ }
162
+
163
+ .tab-list:where([data-variant="fill"][data-full-width="true"]) > .tab-trigger {
164
+ flex: 1;
165
+ }
166
+
167
+ .tab-trigger:where([data-variant="fill"]) {
168
+ min-width: 0;
169
+ border-radius: 12px;
170
+ }
171
+
172
+ .tab-trigger:where([data-variant="fill"][data-state="active"]) {
173
+ background: var(--tab-color-active);
174
+ }
175
+
176
+ .tab-trigger:where([data-variant="fill"][data-state="active"])
177
+ .tab-trigger-label {
178
+ color: var(--tab-fill-active-color);
179
+ }
180
+
181
+ .tab-trigger:where([data-variant="fill"]):where(
182
+ :not([data-state="active"])
183
+ ):hover {
184
+ background: var(--tab-fill-hover-bg);
185
+ }
186
+
187
+ .tab-content {
188
+ display: block;
189
+ padding: var(--spacing-padding-6) 0;
190
+ }
@@ -0,0 +1,39 @@
1
+ :root {
2
+ --tab-height-small: 40px;
3
+ --tab-height-medium: 48px;
4
+ --tab-height-large: 56px;
5
+
6
+ /* 변경: Figma node 1176:834/781/739 기준으로 tab label typography를 exact spec으로 다시 고정한다. */
7
+ --tab-label-font-size-small: var(--font-label-medium-size);
8
+ --tab-label-font-weight-small: 700;
9
+ --tab-label-line-height-small: 1.4;
10
+ --tab-label-letter-spacing-small: 0px;
11
+
12
+ --tab-label-font-size-medium: var(--font-label-large-size);
13
+ --tab-label-font-weight-medium: 700;
14
+ --tab-label-line-height-medium: 1.4;
15
+ --tab-label-letter-spacing-medium: 0px;
16
+
17
+ --tab-label-font-size-large: var(--font-heading-small-size);
18
+ --tab-label-font-weight-large: 700;
19
+ --tab-label-line-height-large: 1.4;
20
+ --tab-label-letter-spacing-large: 0px;
21
+
22
+ --tab-gap: var(--spacing-gap-2);
23
+ --tab-root-gap: var(--spacing-gap-3);
24
+ --tab-padding-y: 10px;
25
+ --tab-padding-x: var(--spacing-padding-8);
26
+ --tab-padding-x-small: var(--spacing-padding-4);
27
+ --tab-icon-gap: 6px;
28
+ /* 변경: line track은 foundation에 존재하는 assistive border token(#f2f2f3)을 사용한다. */
29
+ --tab-line-track-color: var(--color-border-assistive);
30
+ --tab-line-track-height: 1px;
31
+ --tab-line-indicator-height: 2px;
32
+ --tab-color-active-default: var(--color-primary-default);
33
+ --tab-color-active: var(--tab-color-active-default);
34
+ --tab-color-hover: color-mix(in srgb, var(--tab-color-active), #000 15%);
35
+ --tab-fill-hover-bg: var(--color-bg-alternative-cool-gray);
36
+ --tab-fill-active-color: var(--color-common-100);
37
+ --tab-inactive-color: var(--color-label-alternative);
38
+ --tab-disabled-opacity: 0.4;
39
+ }