11import type { Meta , StoryObj } from '@storybook/react' ;
2- import { Tooltip } from '@sopt-makers/ui' ;
3- import { IconAlertCircle } from '@sopt-makers/icons' ;
2+ import { Button , Tag , Tooltip } from '@sopt-makers/ui' ;
3+ import { IconAlertCircle , IconChevronRight } from '@sopt-makers/icons' ;
4+ import type { ReactNode , CSSProperties } from 'react' ;
5+ import { colors } from '@sopt-makers/colors' ;
6+ import { fontsObject } from '@sopt-makers/fonts' ;
47
5- const meta = {
8+ const Placement = [
9+ 'top' ,
10+ 'bottom' ,
11+ 'left' ,
12+ 'right' ,
13+ 'topLeft' ,
14+ 'topRight' ,
15+ 'bottomLeft' ,
16+ 'bottomRight' ,
17+ 'leftTop' ,
18+ 'leftBottom' ,
19+ 'rightTop' ,
20+ 'rightBottom' ,
21+ ] as const ;
22+
23+ interface TooltipStoryArgs {
24+ placement ?: ( typeof Placement ) [ number ] ;
25+ isOpen ?: boolean ;
26+ size ?: 'small' | 'large' ;
27+ title ?: ReactNode ;
28+ bodyText ?: ReactNode ;
29+ closeButton ?: boolean ;
30+ secondaryButton ?: ReactNode ;
31+ style ?: CSSProperties ;
32+ }
33+
34+ const meta : Meta < TooltipStoryArgs > = {
635 title : 'Components/Tooltip' ,
7- component : Tooltip . Root ,
836 tags : [ 'autodocs' ] ,
937 parameters : {
1038 layout : 'centered' ,
1139 } ,
1240 argTypes : {
41+ size : {
42+ control : 'radio' ,
43+ options : [ 'small' , 'large' ] ,
44+ description : '툴팁 크기를 설정합니다.' ,
45+ table : {
46+ type : {
47+ summary : 'small | large' ,
48+ } ,
49+ } ,
50+ } ,
51+ placement : {
52+ control : 'select' ,
53+ options : Placement ,
54+ description : '툴팁 위치를 설정합니다.' ,
55+ table : {
56+ type : {
57+ summary :
58+ 'top | bottom | left | right | topLeft | topRight | bottomLeft | bottomRight | leftTop | leftBottom | rightTop | rightBottom' ,
59+ } ,
60+ } ,
61+ } ,
62+ title : {
63+ control : 'text' ,
64+ description : '툴팁 제목을 설정합니다.' ,
65+ table : {
66+ type : {
67+ summary : 'ReactNode' ,
68+ } ,
69+ } ,
70+ } ,
71+ bodyText : {
72+ control : 'text' ,
73+ description : '툴팁 내용을 설정합니다.' ,
74+ table : {
75+ type : {
76+ summary : 'ReactNode' ,
77+ } ,
78+ } ,
79+ } ,
80+ closeButton : {
81+ control : 'boolean' ,
82+ description : '툴팁 닫기 버튼을 설정합니다. <br />`large` 크기일 때만 표시됩니다.' ,
83+ table : {
84+ type : {
85+ summary : 'boolean' ,
86+ } ,
87+ } ,
88+ } ,
89+ secondaryButton : {
90+ control : false ,
91+ description : '툴팁 보조 버튼을 설정합니다.' ,
92+ table : {
93+ type : {
94+ summary : 'ReactNode' ,
95+ } ,
96+ } ,
97+ } ,
1398 isOpen : {
1499 control : 'boolean' ,
100+ description : '툴팁 열림 여부를 설정합니다.' ,
101+ table : {
102+ type : {
103+ summary : 'boolean' ,
104+ } ,
105+ } ,
15106 } ,
16107 } ,
17108 decorators : [
@@ -28,35 +119,140 @@ const meta = {
28119 </ div >
29120 ) ,
30121 ] ,
31- } satisfies Meta < typeof Tooltip . Root > ;
122+ } ;
32123
33124export default meta ;
34- type Story = StoryObj < typeof meta > ;
125+ type Story = StoryObj < TooltipStoryArgs > ;
35126
36127export const Default : Story = {
37128 render : ( args ) => (
38- < Tooltip . Root { ...args } >
129+ < Tooltip . Root placement = { args . placement } isOpen = { args . isOpen } >
130+ < Tooltip . Trigger > 호버해보세요</ Tooltip . Trigger >
131+ < Tooltip . Content
132+ title = { args . title }
133+ bodyText = { args . bodyText }
134+ size = { args . size }
135+ closeButton = { args . closeButton }
136+ secondaryButton = { args . secondaryButton }
137+ >
138+ { ! args . title && ! args . bodyText && '툴팁 내용입니다.' }
139+ </ Tooltip . Content >
140+ </ Tooltip . Root >
141+ ) ,
142+ args : {
143+ title : '' ,
144+ bodyText : '' ,
145+ size : 'small' ,
146+ closeButton : false ,
147+ secondaryButton : undefined ,
148+ } ,
149+ } ;
150+
151+ export const SmallWithTag : Story = {
152+ render : ( args ) => (
153+ < Tooltip . Root placement = { args . placement } isOpen = { args . isOpen } >
39154 < Tooltip . Trigger > 호버해보세요</ Tooltip . Trigger >
40- < Tooltip . Content > 툴팁 내용입니다. </ Tooltip . Content >
155+ < Tooltip . Content bodyText = { args . bodyText } style = { { width : '272px' } } / >
41156 </ Tooltip . Root >
42157 ) ,
43- args : { } ,
158+ args : {
159+ bodyText : (
160+ < div style = { { display : 'flex' , gap : '8px' } } >
161+ < Tag style = { { backgroundColor : colors . orangeAlpha200 , color : colors . secondary , whiteSpace : 'nowrap' } } > New</ Tag >
162+ Small Tooltip은 본문을 두 줄 이상 작성하면 요런 모습이에요.
163+ </ div >
164+ ) ,
165+ size : 'small' ,
166+ } ,
44167} ;
45168
46- export const CustomContent : Story = {
169+ export const SmallWithPrefixIcon : Story = {
47170 render : ( args ) => (
48- < Tooltip . Root { ...args } >
171+ < Tooltip . Root placement = { args . placement } isOpen = { args . isOpen } >
172+ < Tooltip . Trigger > 호버해보세요</ Tooltip . Trigger >
173+ < Tooltip . Content
174+ prefixIcon = { < IconAlertCircle style = { { width : '16px' , height : '16px' } } /> }
175+ bodyText = { args . bodyText }
176+ style = { { width : 'fit-content' } }
177+ />
178+ </ Tooltip . Root >
179+ ) ,
180+ args : {
181+ bodyText : 'min-width은 160px로 설정되어있어요.' ,
182+ size : 'small' ,
183+ } ,
184+ } ;
185+
186+ export const LargeWithPrefixIcon : Story = {
187+ render : ( args ) => (
188+ < Tooltip . Root placement = { args . placement } isOpen = { args . isOpen } >
49189 < Tooltip . Trigger >
50190 호버해보세요
51191 < IconAlertCircle style = { { width : '15px' , height : '15px' } } />
52192 </ Tooltip . Trigger >
53- < Tooltip . Content >
54- < div style = { { display : 'flex' , alignItems : 'center' , gap : '4px' } } >
55- < IconAlertCircle style = { { width : '15px' , height : '15px' } } />
56- < span > 툴팁 내용입니다.</ span >
57- </ div >
58- </ Tooltip . Content >
193+ < Tooltip . Content
194+ size = 'large'
195+ prefixIcon = { < IconAlertCircle style = { { width : '15px' , height : '15px' } } /> }
196+ title = { args . title }
197+ bodyText = { args . bodyText }
198+ closeButton = { args . closeButton }
199+ secondaryButton = { args . secondaryButton }
200+ style = { { width : '272px' } }
201+ />
59202 </ Tooltip . Root >
60203 ) ,
61- args : { } ,
204+ args : {
205+ title : '제목 텍스트입니다.' ,
206+ bodyText : '이곳에 본문 텍스트를 작성해주세요.' ,
207+ size : 'large' ,
208+ closeButton : true ,
209+ secondaryButton : (
210+ < button
211+ style = { {
212+ display : 'flex' ,
213+ width : 'fit-content' ,
214+ padding : '0' ,
215+ alignItems : 'center' ,
216+ border : 'none' ,
217+ backgroundColor : 'transparent' ,
218+ color : colors . gray30 ,
219+ ...fontsObject . LABEL_4_12_SB ,
220+ } }
221+ >
222+ Text Button
223+ < IconChevronRight style = { { width : '16px' , height : '16px' } } />
224+ </ button >
225+ ) ,
226+ } ,
227+ } ;
228+
229+ export const LargeWithTitleAndBody : Story = {
230+ render : ( args ) => (
231+ < Tooltip . Root placement = { args . placement } isOpen = { args . isOpen } >
232+ < Tooltip . Trigger > 호버해보세요</ Tooltip . Trigger >
233+ < Tooltip . Content
234+ title = { args . title }
235+ bodyText = { args . bodyText }
236+ size = { args . size }
237+ closeButton = { args . closeButton }
238+ secondaryButton = { args . secondaryButton }
239+ style = { { width : '272px' } }
240+ />
241+ </ Tooltip . Root >
242+ ) ,
243+ args : {
244+ title : (
245+ < div style = { { display : 'flex' , alignItems : 'center' , gap : '4px' } } >
246+ 제목 텍스트입니다.< Tag style = { { backgroundColor : colors . orangeAlpha200 , color : colors . secondary } } > New</ Tag >
247+ </ div >
248+ ) ,
249+ bodyText : '이곳에 본문 텍스트를 작성해주세요.' ,
250+ size : 'large' ,
251+ closeButton : false ,
252+ secondaryButton : (
253+ < Button theme = 'black' style = { { width : '100%' } } >
254+ Button
255+ </ Button >
256+ ) ,
257+ } ,
62258} ;
0 commit comments