@wishket/design-system 1.11.2 → 1.12.0
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/Components/DataDisplays/Avatar/Avatar.js +1 -1
- package/dist/Components/Inputs/MultiColumnList/MultiColumnList.parts.js +5 -1
- package/dist/Components/Navigations/BoxTab/BoxTab.d.ts +3 -3
- package/dist/Components/Navigations/BoxTab/BoxTab.js +2 -2
- package/dist/Components/Navigations/BoxTab/BoxTab.parts.d.ts +1 -1
- package/dist/Components/Navigations/BoxTab/BoxTab.parts.js +27 -12
- package/dist/Components/Navigations/BoxTab/BoxTab.types.d.ts +1 -0
- package/dist/Components/Navigations/TextTab/TextTab.d.ts +2 -2
- package/dist/Components/Navigations/TextTab/TextTab.js +1 -1
- package/dist/Components/Navigations/TextTab/TextTab.parts.d.ts +1 -1
- package/dist/Components/Navigations/TextTab/TextTab.parts.js +68 -37
- package/dist/Components/Navigations/TextTab/TextTab.types.d.ts +1 -0
- package/package.json +1 -1
|
@@ -19,7 +19,7 @@ const AvatarContent = ({ size = 'md', name, imgUrl, isMonogram, avatarStyle })=>
|
|
|
19
19
|
alt: "",
|
|
20
20
|
width: 80,
|
|
21
21
|
height: 80,
|
|
22
|
-
className: "h-full w-full",
|
|
22
|
+
className: "h-full w-full object-cover",
|
|
23
23
|
"data-testid": "design-system-avatar--image",
|
|
24
24
|
onError: handleImageError
|
|
25
25
|
});
|
|
@@ -45,11 +45,15 @@ const MultiColumnListContext = react.createContext({
|
|
|
45
45
|
]);
|
|
46
46
|
const [activeCategory, setActiveCategory] = react.useState(currentActiveCategory);
|
|
47
47
|
const handleCategoryClick = (index)=>{
|
|
48
|
+
if (index === activeCategory) return; // 현재 카테고리를 다시 클릭하는 경우 방지
|
|
48
49
|
onCategoryChange === null || onCategoryChange === void 0 ? void 0 : onCategoryChange(index);
|
|
49
50
|
setActiveCategory(index);
|
|
50
51
|
};
|
|
51
52
|
react.useEffect(()=>{
|
|
52
|
-
|
|
53
|
+
if (currentActiveCategory !== activeCategory) {
|
|
54
|
+
setActiveCategory(currentActiveCategory);
|
|
55
|
+
}
|
|
56
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
53
57
|
}, [
|
|
54
58
|
currentActiveCategory
|
|
55
59
|
]);
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
* return (
|
|
16
16
|
* <BoxTab.Root>
|
|
17
17
|
* <BoxTab.Tabs>
|
|
18
|
-
* <BoxTab.Tab index={0}>첫 번째 탭</BoxTab.Tab>
|
|
19
|
-
* <BoxTab.Tab index={1}>두 번째 탭</BoxTab.Tab>
|
|
18
|
+
* <BoxTab.Tab index={0} href="/">첫 번째 탭</BoxTab.Tab>
|
|
19
|
+
* <BoxTab.Tab index={1} href="/">두 번째 탭</BoxTab.Tab>
|
|
20
20
|
* </BoxTab.Tabs>
|
|
21
21
|
* <BoxTab.Panel index={0}>첫 번째 패널 내용</BoxTab.Panel>
|
|
22
22
|
* <BoxTab.Panel index={1}>두 번째 패널 내용</BoxTab.Panel>
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
declare const BoxTab: {
|
|
29
29
|
Root: ({ children, currentActiveTab, onChange, }: import("./BoxTab.types").BoxTabRootProps) => import("react/jsx-runtime").JSX.Element;
|
|
30
30
|
Tabs: ({ children, className }: import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>) => import("react/jsx-runtime").JSX.Element;
|
|
31
|
-
Tab: ({ children, index, className, isFirst, isLast, disabled, }: import("./BoxTab.types").BoxTabProps) => import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
Tab: ({ children, index, className, isFirst, isLast, disabled, href, }: import("./BoxTab.types").BoxTabProps) => import("react/jsx-runtime").JSX.Element;
|
|
32
32
|
Panel: ({ children, index }: import("./BoxTab.types").BoxTabPanelProps) => false | import("react/jsx-runtime").JSX.Element;
|
|
33
33
|
};
|
|
34
34
|
export default BoxTab;
|
|
@@ -19,8 +19,8 @@ var BoxTab_parts = require('./BoxTab.parts.js');
|
|
|
19
19
|
* return (
|
|
20
20
|
* <BoxTab.Root>
|
|
21
21
|
* <BoxTab.Tabs>
|
|
22
|
-
* <BoxTab.Tab index={0}>첫 번째 탭</BoxTab.Tab>
|
|
23
|
-
* <BoxTab.Tab index={1}>두 번째 탭</BoxTab.Tab>
|
|
22
|
+
* <BoxTab.Tab index={0} href="/">첫 번째 탭</BoxTab.Tab>
|
|
23
|
+
* <BoxTab.Tab index={1} href="/">두 번째 탭</BoxTab.Tab>
|
|
24
24
|
* </BoxTab.Tabs>
|
|
25
25
|
* <BoxTab.Panel index={0}>첫 번째 패널 내용</BoxTab.Panel>
|
|
26
26
|
* <BoxTab.Panel index={1}>두 번째 패널 내용</BoxTab.Panel>
|
|
@@ -56,7 +56,7 @@ declare const Tabs: ({ children, className }: ComponentProps<'div'>) => import("
|
|
|
56
56
|
* </BoxTab.Tab>
|
|
57
57
|
* ```
|
|
58
58
|
*/
|
|
59
|
-
declare const Tab: ({ children, index, className, isFirst, isLast, disabled, }: BoxTabProps) => import("react/jsx-runtime").JSX.Element;
|
|
59
|
+
declare const Tab: ({ children, index, className, isFirst, isLast, disabled, href, }: BoxTabProps) => import("react/jsx-runtime").JSX.Element;
|
|
60
60
|
/**
|
|
61
61
|
* 탭 패널 컴포넌트입니다.
|
|
62
62
|
* 해당 인덱스의 탭이 선택되었을 때만 내용을 표시합니다.
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var tailwindMerge = require('tailwind-merge');
|
|
7
|
+
var Link = require('next/link');
|
|
7
8
|
var Typography = require('../../Base/Typography/Typography.js');
|
|
8
9
|
var Box = require('../../Base/Layouts/Box/Box.js');
|
|
9
10
|
require('../../Base/Layouts/FullBleed/FullBleed.js');
|
|
@@ -36,11 +37,15 @@ const BoxTabContext = react.createContext({
|
|
|
36
37
|
*/ const Root = ({ children, currentActiveTab = 0, onChange })=>{
|
|
37
38
|
const [activeTab, setActiveTab] = react.useState(currentActiveTab);
|
|
38
39
|
const handleTabClick = (index)=>{
|
|
40
|
+
if (index === activeTab) return;
|
|
39
41
|
onChange === null || onChange === void 0 ? void 0 : onChange(index);
|
|
40
42
|
setActiveTab(index);
|
|
41
43
|
};
|
|
42
44
|
react.useEffect(()=>{
|
|
43
|
-
|
|
45
|
+
if (currentActiveTab !== activeTab) {
|
|
46
|
+
setActiveTab(currentActiveTab);
|
|
47
|
+
}
|
|
48
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
44
49
|
}, [
|
|
45
50
|
currentActiveTab
|
|
46
51
|
]);
|
|
@@ -105,25 +110,35 @@ const BoxTabContext = react.createContext({
|
|
|
105
110
|
* 탭 1
|
|
106
111
|
* </BoxTab.Tab>
|
|
107
112
|
* ```
|
|
108
|
-
*/ const Tab = ({ children, index, className, isFirst, isLast, disabled = false })=>{
|
|
113
|
+
*/ const Tab = ({ children, index, className, isFirst, isLast, disabled = false, href })=>{
|
|
109
114
|
const { handleTabClick, activeTab } = react.useContext(BoxTabContext);
|
|
110
115
|
const isSelected = index === activeTab;
|
|
111
|
-
|
|
116
|
+
const sharedProps = {
|
|
112
117
|
tabIndex: 0,
|
|
113
|
-
|
|
118
|
+
'data-testid': `design-system-boxTab--item-${index}`,
|
|
114
119
|
className: tailwindMerge.twMerge('group flex w-full cursor-pointer items-center border border-w-gray-200 bg-w-white px-6 py-4 hover:bg-w-gray-10', 'relative', '-ml-px', isSelected && 'z-[1] border-primary bg-primary-10 hover:bg-primary-10', isFirst && 'ml-0 rounded-l-xl', isLast && 'rounded-r-xl', className),
|
|
115
120
|
onClick: ()=>{
|
|
116
121
|
!disabled && handleTabClick(index);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
const content = jsxRuntime.jsx(Box, {
|
|
125
|
+
className: tailwindMerge.twMerge('relative flex w-full flex-row items-center justify-center font-normal text-w-gray-600', isSelected && 'font-medium text-primary'),
|
|
126
|
+
children: jsxRuntime.jsx(Typography, {
|
|
127
|
+
variant: "body1",
|
|
128
|
+
className: "relative",
|
|
129
|
+
children: children
|
|
125
130
|
})
|
|
126
131
|
});
|
|
132
|
+
if (href) {
|
|
133
|
+
return jsxRuntime.jsx(Link, Object.assign({
|
|
134
|
+
href: href
|
|
135
|
+
}, sharedProps, {
|
|
136
|
+
children: content
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
return jsxRuntime.jsx(Box, Object.assign({}, sharedProps, {
|
|
140
|
+
children: content
|
|
141
|
+
}));
|
|
127
142
|
};
|
|
128
143
|
/**
|
|
129
144
|
* 탭 패널 컴포넌트입니다.
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* <TextTab.Root defaultValue="tab1">
|
|
16
16
|
* <TextTab.Tabs>
|
|
17
17
|
* <TextTab.Tab value="tab1">첫 번째 탭</TextTab.Tab>
|
|
18
|
-
* <TextTab.Tab value="tab2">두 번째 탭</TextTab.Tab>
|
|
18
|
+
* <TextTab.Tab value="tab2" href="/">두 번째 탭</TextTab.Tab>
|
|
19
19
|
* </TextTab.Tabs>
|
|
20
20
|
*
|
|
21
21
|
* <TextTab.Panel value="tab1">
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
declare const TextTab: {
|
|
32
32
|
Root: ({ children, currentActiveTab, isFit, hasPadding, isFull, barColor, onChange, }: import("./TextTab.types").TextTabRootProps) => import("react/jsx-runtime").JSX.Element;
|
|
33
33
|
Tabs: ({ children, className }: import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>) => import("react/jsx-runtime").JSX.Element;
|
|
34
|
-
Tab: ({ children, index, className, disabled, badgeNumber, iconName, }: import("./TextTab.types").TextTabProps) => import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
Tab: ({ children, index, className, disabled, badgeNumber, iconName, href, }: import("./TextTab.types").TextTabProps) => import("react/jsx-runtime").JSX.Element;
|
|
35
35
|
Panel: ({ children, index }: import("./TextTab.types").TextTabPanelProps) => false | import("react/jsx-runtime").JSX.Element;
|
|
36
36
|
};
|
|
37
37
|
export default TextTab;
|
|
@@ -19,7 +19,7 @@ var TextTab_parts = require('./TextTab.parts.js');
|
|
|
19
19
|
* <TextTab.Root defaultValue="tab1">
|
|
20
20
|
* <TextTab.Tabs>
|
|
21
21
|
* <TextTab.Tab value="tab1">첫 번째 탭</TextTab.Tab>
|
|
22
|
-
* <TextTab.Tab value="tab2">두 번째 탭</TextTab.Tab>
|
|
22
|
+
* <TextTab.Tab value="tab2" href="/">두 번째 탭</TextTab.Tab>
|
|
23
23
|
* </TextTab.Tabs>
|
|
24
24
|
*
|
|
25
25
|
* <TextTab.Panel value="tab1">
|
|
@@ -59,7 +59,7 @@ declare const Tabs: ({ children, className }: ComponentProps<'div'>) => import("
|
|
|
59
59
|
* 홈
|
|
60
60
|
* </TextTab.Tab>
|
|
61
61
|
*/
|
|
62
|
-
declare const Tab: ({ children, index, className, disabled, badgeNumber, iconName, }: TextTabProps) => import("react/jsx-runtime").JSX.Element;
|
|
62
|
+
declare const Tab: ({ children, index, className, disabled, badgeNumber, iconName, href, }: TextTabProps) => import("react/jsx-runtime").JSX.Element;
|
|
63
63
|
/**
|
|
64
64
|
* 탭 패널 컴포넌트입니다.
|
|
65
65
|
* 해당 탭이 선택되었을 때만 내용을 표시합니다.
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var tailwindMerge = require('tailwind-merge');
|
|
7
|
+
var Link = require('next/link');
|
|
7
8
|
var Typography = require('../../Base/Typography/Typography.js');
|
|
8
9
|
var Box = require('../../Base/Layouts/Box/Box.js');
|
|
9
10
|
require('../../Base/Layouts/FullBleed/FullBleed.js');
|
|
@@ -46,11 +47,15 @@ const TextTabContext = react.createContext({
|
|
|
46
47
|
*/ const Root = ({ children, currentActiveTab = 0, isFit = true, hasPadding = false, isFull = false, barColor = 'bg-w-gray-900', onChange })=>{
|
|
47
48
|
const [activeTab, setActiveTab] = react.useState(currentActiveTab);
|
|
48
49
|
const handleTabClick = (index)=>{
|
|
50
|
+
if (index === activeTab) return;
|
|
49
51
|
onChange === null || onChange === void 0 ? void 0 : onChange(index);
|
|
50
52
|
setActiveTab(index);
|
|
51
53
|
};
|
|
52
54
|
react.useEffect(()=>{
|
|
53
|
-
|
|
55
|
+
if (currentActiveTab !== activeTab) {
|
|
56
|
+
setActiveTab(currentActiveTab);
|
|
57
|
+
}
|
|
58
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
54
59
|
}, [
|
|
55
60
|
currentActiveTab
|
|
56
61
|
]);
|
|
@@ -83,41 +88,57 @@ const TextTabContext = react.createContext({
|
|
|
83
88
|
const { activeTab, hasPadding, isFull, barColor } = react.useContext(TextTabContext);
|
|
84
89
|
const tabRefs = react.useRef([]);
|
|
85
90
|
const underbarRef = react.useRef(null);
|
|
91
|
+
const containerRef = react.useRef(null);
|
|
86
92
|
const childrenArray = react.Children.toArray(children);
|
|
93
|
+
const [isScrolling, setIsScrolling] = react.useState(false);
|
|
94
|
+
// 터치 이벤트 핸들러
|
|
95
|
+
const handleTouchStart = ()=>{
|
|
96
|
+
setIsScrolling(true);
|
|
97
|
+
};
|
|
98
|
+
const handleTouchEnd = ()=>{
|
|
99
|
+
setIsScrolling(false);
|
|
100
|
+
};
|
|
87
101
|
react.useEffect(()=>{
|
|
88
|
-
if (!tabRefs.current[activeTab] || !underbarRef.current) return;
|
|
102
|
+
if (!tabRefs.current[activeTab] || !underbarRef.current || isScrolling) return;
|
|
89
103
|
const activeTabElement = tabRefs.current[activeTab];
|
|
90
104
|
const underbarElement = underbarRef.current;
|
|
91
|
-
const containerElement =
|
|
105
|
+
const containerElement = containerRef.current;
|
|
92
106
|
if (activeTabElement && underbarElement && containerElement) {
|
|
93
107
|
const { offsetLeft, offsetWidth } = activeTabElement;
|
|
94
108
|
const { scrollLeft, clientWidth } = containerElement;
|
|
95
109
|
underbarElement.style.width = `${offsetWidth}px`;
|
|
96
110
|
underbarElement.style.transform = `translateX(${offsetLeft}px)`;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
111
|
+
const isVisible = scrollLeft <= offsetLeft && scrollLeft + clientWidth >= offsetLeft + offsetWidth;
|
|
112
|
+
if (!isVisible) {
|
|
113
|
+
const scrollTimeout = setTimeout(()=>{
|
|
100
114
|
activeTabElement.scrollIntoView({
|
|
101
115
|
behavior: 'smooth',
|
|
102
116
|
block: 'nearest',
|
|
103
117
|
inline: 'center'
|
|
104
118
|
});
|
|
105
|
-
}
|
|
106
|
-
|
|
119
|
+
}, 0);
|
|
120
|
+
return ()=>clearTimeout(scrollTimeout);
|
|
121
|
+
}
|
|
107
122
|
}
|
|
108
123
|
}, [
|
|
109
|
-
activeTab
|
|
124
|
+
activeTab,
|
|
125
|
+
isScrolling
|
|
110
126
|
]);
|
|
111
127
|
return jsxRuntime.jsxs(Box, {
|
|
112
|
-
|
|
128
|
+
ref: containerRef,
|
|
129
|
+
className: tailwindMerge.twJoin('relative block w-full touch-pan-x items-start overflow-x-scroll border-b border-w-gray-200 scrollbar-hide', hasPadding && 'px-9', className),
|
|
113
130
|
"data-testid": "design-system-textTab--container",
|
|
131
|
+
onTouchStart: handleTouchStart,
|
|
132
|
+
onTouchEnd: handleTouchEnd,
|
|
114
133
|
children: [
|
|
115
134
|
jsxRuntime.jsx(Box, {
|
|
116
135
|
className: tailwindMerge.twMerge('inline-flex w-max gap-10', isFull && 'w-full gap-0'),
|
|
117
136
|
children: childrenArray.map((child, index)=>{
|
|
118
137
|
return jsxRuntime.jsx(Box, {
|
|
119
138
|
className: tailwindMerge.twMerge(isFull && 'w-full'),
|
|
120
|
-
ref: (el)=>
|
|
139
|
+
ref: (el)=>{
|
|
140
|
+
tabRefs.current[index] = el;
|
|
141
|
+
},
|
|
121
142
|
children: child
|
|
122
143
|
}, index);
|
|
123
144
|
})
|
|
@@ -150,40 +171,50 @@ const TextTabContext = react.createContext({
|
|
|
150
171
|
* >
|
|
151
172
|
* 홈
|
|
152
173
|
* </TextTab.Tab>
|
|
153
|
-
*/ const Tab = ({ children, index, className, disabled = false, badgeNumber, iconName })=>{
|
|
174
|
+
*/ const Tab = ({ children, index, className, disabled = false, badgeNumber, iconName, href })=>{
|
|
154
175
|
const { isFit, handleTabClick, activeTab, isFull } = react.useContext(TextTabContext);
|
|
155
176
|
const isSelected = index === activeTab;
|
|
156
|
-
|
|
177
|
+
const sharedProps = {
|
|
157
178
|
tabIndex: 0,
|
|
158
|
-
|
|
179
|
+
'data-testid': `design-system-textTab--item-${index}`,
|
|
159
180
|
className: tailwindMerge.twMerge('group flex w-max cursor-pointer items-center rounded-xl hover:font-medium', disabled && 'cursor-not-allowed', isFull && `w-full`, className),
|
|
160
181
|
onClick: ()=>{
|
|
161
182
|
!disabled && handleTabClick(index);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}),
|
|
173
|
-
jsxRuntime.jsx(Typography, {
|
|
174
|
-
variant: "body1",
|
|
175
|
-
className: "relative",
|
|
176
|
-
children: children
|
|
177
|
-
}),
|
|
178
|
-
badgeNumber !== undefined && jsxRuntime.jsx(CountBadge, {
|
|
179
|
-
text: badgeNumber,
|
|
180
|
-
showZero: true,
|
|
181
|
-
className: "relative",
|
|
182
|
-
variant: "gray"
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
const content = jsxRuntime.jsxs(Box, {
|
|
186
|
+
className: tailwindMerge.twMerge('relative flex w-full flex-row items-center justify-center gap-2 py-4 font-normal text-w-gray-600 group-hover:text-w-gray-900', !isFit && 'px-[33.5px]', isFull && 'w-full px-0', isSelected && 'font-medium text-w-gray-900'),
|
|
187
|
+
children: [
|
|
188
|
+
iconName && jsxRuntime.jsx(Box, {
|
|
189
|
+
className: "flex size-4 flex-shrink-0 items-center justify-center",
|
|
190
|
+
children: jsxRuntime.jsx(SystemIcon, {
|
|
191
|
+
name: iconName,
|
|
192
|
+
className: tailwindMerge.twMerge('size-4 text-w-gray-600 group-hover:text-w-gray-900', isSelected && 'text-w-gray-900')
|
|
183
193
|
})
|
|
184
|
-
|
|
185
|
-
|
|
194
|
+
}),
|
|
195
|
+
jsxRuntime.jsx(Typography, {
|
|
196
|
+
variant: "body1",
|
|
197
|
+
className: "relative",
|
|
198
|
+
children: children
|
|
199
|
+
}),
|
|
200
|
+
badgeNumber !== undefined && jsxRuntime.jsx(CountBadge, {
|
|
201
|
+
text: badgeNumber,
|
|
202
|
+
showZero: true,
|
|
203
|
+
className: "relative",
|
|
204
|
+
variant: "gray"
|
|
205
|
+
})
|
|
206
|
+
]
|
|
186
207
|
});
|
|
208
|
+
if (href) {
|
|
209
|
+
return jsxRuntime.jsx(Link, Object.assign({
|
|
210
|
+
href: href
|
|
211
|
+
}, sharedProps, {
|
|
212
|
+
children: content
|
|
213
|
+
}));
|
|
214
|
+
}
|
|
215
|
+
return jsxRuntime.jsx(Box, Object.assign({}, sharedProps, {
|
|
216
|
+
children: content
|
|
217
|
+
}));
|
|
187
218
|
};
|
|
188
219
|
/**
|
|
189
220
|
* 탭 패널 컴포넌트입니다.
|