@@ -14,11 +14,16 @@ import {
14
14
Popover ,
15
15
Size ,
16
16
Elevation ,
17
+ Message ,
18
+ FlexBox ,
19
+ IconButtonProps ,
17
20
} from '@lumx/react' ;
18
21
import range from 'lodash/range' ;
19
22
import { withCombinations } from '@lumx/react/stories/decorators/withCombinations' ;
20
23
import { getSelectArgType } from '@lumx/react/stories/controls/selectArgType' ;
21
24
import { withChromaticForceScreenSize } from '@lumx/react/stories/decorators/withChromaticForceScreenSize' ;
25
+ import { FitAnchorWidth } from '@lumx/react/components/popover/constants' ;
26
+ import { withUndefined } from '@lumx/react/stories/controls/withUndefined' ;
22
27
23
28
export default {
24
29
title : 'LumX components/popover/Popover' ,
@@ -110,164 +115,150 @@ export const Placements = {
110
115
] ,
111
116
} ;
112
117
113
- export const WithUpdatingChildren = ( ) => {
114
- const anchorRef = useRef ( null ) ;
115
- const [ isOpen , setIsOpen ] = useState ( false ) ;
116
-
117
- const toggleOpen = ( ) => setIsOpen ( ! isOpen ) ;
118
-
119
- const [ text , setText ] = useState ( 'Long loading text with useless words' ) ;
120
- useEffect ( ( ) => {
121
- if ( isOpen ) {
122
- const timer = setTimeout ( ( ) => {
123
- setText ( 'Text' ) ;
124
- } , 1000 ) ;
125
- return ( ) => clearTimeout ( timer ) ;
126
- }
127
- setText ( 'Long loading text with useless words' ) ;
128
- return undefined ;
129
- } , [ isOpen ] ) ;
130
-
131
- return (
132
- < div style = { { float : 'right' } } className = "lumx-spacing-margin-right-huge" >
133
- < IconButton
134
- label = "Notifications"
135
- className = "lumx-spacing-margin-right-huge"
136
- ref = { anchorRef }
137
- emphasis = { Emphasis . low }
138
- icon = { mdiBell }
139
- size = { Size . m }
140
- onClick = { toggleOpen }
141
- />
142
- < Popover
143
- closeOnClickAway
144
- closeOnEscape
145
- isOpen = { isOpen }
146
- anchorRef = { anchorRef }
147
- placement = { Placement . BOTTOM_END }
148
- onClose = { toggleOpen }
149
- fitWithinViewportHeight
150
- >
151
- < List >
152
- < ListItem before = { < Icon icon = { mdiAccount } /> } className = "lumx-spacing-margin-right-huge" >
153
- < span > { text } </ span >
154
- </ ListItem >
155
- </ List >
156
- </ Popover >
157
- </ div >
158
- ) ;
118
+ /**
119
+ * Demo all fitAnchorWidth configurations
120
+ */
121
+ export const FitToAnchorWidth = {
122
+ render ( { anchorText, fitAnchorWidth } : any ) {
123
+ const anchorRef = useRef ( null ) ;
124
+ return (
125
+ < >
126
+ < Chip className = "lumx-spacing-margin-huge" ref = { anchorRef } size = "s" >
127
+ { anchorText }
128
+ </ Chip >
129
+ < Popover
130
+ isOpen
131
+ className = "lumx-spacing-padding"
132
+ placement = "top"
133
+ anchorRef = { anchorRef }
134
+ fitToAnchorWidth = { fitAnchorWidth }
135
+ >
136
+ Popover { fitAnchorWidth }
137
+ </ Popover >
138
+ </ >
139
+ ) ;
140
+ } ,
141
+ decorators : [
142
+ withCombinations ( {
143
+ combinations : {
144
+ cols : {
145
+ 'Small Anchor' : { anchorText : 'Small' } ,
146
+ 'Large Anchor' : { anchorText : 'Very very very very large anchor' } ,
147
+ } ,
148
+ rows : { key : 'fitAnchorWidth' , options : withUndefined ( Object . values ( FitAnchorWidth ) ) } ,
149
+ } ,
150
+ cellStyle : { padding : 16 } ,
151
+ } ) ,
152
+ ] ,
159
153
} ;
160
154
161
- export const WithScrollingPopover = ( ) => {
162
- const anchorRef = useRef ( null ) ;
163
- const [ isOpen , setIsOpen ] = useState ( false ) ;
155
+ /**
156
+ * Testing update of the popover on anchor and popover resize and move
157
+ */
158
+ export const TestUpdatingChildrenAndMovingAnchor = {
159
+ render ( ) {
160
+ const anchorRef = useRef ( null ) ;
161
+ const [ isOpen , setIsOpen ] = useState ( false ) ;
162
+
163
+ const toggleOpen = ( ) => setIsOpen ( ! isOpen ) ;
164
164
165
- const toggleOpen = ( ) => setIsOpen ( ! isOpen ) ;
165
+ const [ text , setText ] = useState ( 'Initial large span of text' ) ;
166
+ const [ anchorSize , setAnchorSize ] = useState < IconButtonProps [ 'size' ] > ( 'm' ) ;
167
+ useEffect ( ( ) => {
168
+ if ( isOpen ) {
169
+ const timers = [
170
+ // Update popover size
171
+ setTimeout ( ( ) => setText ( 'Text' ) , 1000 ) ,
172
+ // Update anchor size
173
+ setTimeout ( ( ) => setAnchorSize ( 's' ) , 1000 ) ,
174
+ ] ;
175
+ return ( ) => timers . forEach ( clearTimeout ) ;
176
+ }
177
+ setText ( 'Initial large span of text' ) ;
178
+ setAnchorSize ( 'm' ) ;
179
+ return undefined ;
180
+ } , [ isOpen ] ) ;
166
181
167
- return (
168
- < div style = { { float : 'right' } } className = "lumx-spacing-margin-right-huge" >
169
- < IconButton
170
- label = "Notifications"
171
- className = "lumx-spacing-margin-right-huge"
172
- ref = { anchorRef }
173
- emphasis = { Emphasis . low }
174
- icon = { mdiBell }
175
- size = { Size . m }
176
- onClick = { toggleOpen }
177
- />
178
- < Popover
179
- closeOnClickAway
180
- closeOnEscape
181
- isOpen = { isOpen }
182
- anchorRef = { anchorRef }
183
- placement = { Placement . BOTTOM }
184
- onClose = { toggleOpen }
185
- fitWithinViewportHeight
186
- >
187
- < List style = { { overflowY : 'auto' } } >
188
- { range ( 100 ) . map ( ( n : number ) => {
189
- return (
190
- < ListItem
191
- key = { `key-${ n } ` }
192
- before = { < Icon icon = { mdiAccount } /> }
193
- className = "lumx-spacing-margin-right-huge"
194
- >
195
- < span > { `List item ${ n } and some text` } </ span >
196
- </ ListItem >
197
- ) ;
198
- } ) }
199
- </ List >
200
- </ Popover >
201
- </ div >
202
- ) ;
182
+ return (
183
+ < FlexBox orientation = "vertical" gap = "huge" >
184
+ < Message kind = "info" > Test popover text resize (after 1sec) and anchor resize (after 1.5sec)</ Message >
185
+ < FlexBox orientation = "horizontal" vAlign = "center" >
186
+ < IconButton
187
+ label = "Notifications"
188
+ className = "lumx-spacing-margin-right-huge"
189
+ ref = { anchorRef }
190
+ emphasis = { Emphasis . low }
191
+ icon = { mdiBell }
192
+ size = { anchorSize }
193
+ onClick = { toggleOpen }
194
+ />
195
+ < Popover
196
+ closeOnClickAway
197
+ closeOnEscape
198
+ isOpen = { isOpen }
199
+ anchorRef = { anchorRef }
200
+ placement = { Placement . BOTTOM_END }
201
+ onClose = { toggleOpen }
202
+ fitWithinViewportHeight
203
+ hasArrow
204
+ >
205
+ < Text as = "p" className = "lumx-spacing-padding-huge" >
206
+ { text }
207
+ </ Text >
208
+ </ Popover >
209
+ </ FlexBox >
210
+ </ FlexBox >
211
+ ) ;
212
+ } ,
213
+ parameters : { chromatic : { disable : true } } ,
203
214
} ;
204
215
205
- export const FitToAnchorWidth = ( ) => {
206
- const demoPopperStyle = {
207
- alignItems : 'center' ,
208
- display : 'flex' ,
209
- height : 100 ,
210
- justifyContent : 'center' ,
211
- width : 200 ,
212
- } ;
213
-
214
- const container = {
215
- alignItems : 'center' ,
216
- display : 'flex' ,
217
- justifyContent : 'center' ,
218
- flexDirection : 'column' ,
219
- gap : 150 ,
220
- marginTop : 150 ,
221
- } as const ;
216
+ /**
217
+ * Testing popover with scroll inside
218
+ */
219
+ export const TestScrollingPopover = {
220
+ render ( ) {
221
+ const anchorRef = useRef ( null ) ;
222
+ const [ isOpen , setIsOpen ] = useState ( false ) ;
222
223
223
- const maxWidthAnchorRef = useRef ( null ) ;
224
- const widthSmallAnchorRef = useRef ( null ) ;
225
- const widthLargeAnchorRef = useRef ( null ) ;
226
- const minWidthAnchorRef = useRef ( null ) ;
227
- const defaultWidthAnchorRef = useRef ( null ) ;
224
+ const toggleOpen = ( ) => setIsOpen ( ! isOpen ) ;
228
225
229
- return (
230
- < div style = { container } >
231
- < div >
232
- < Chip ref = { maxWidthAnchorRef } size = { Size . s } >
233
- Anchor
234
- </ Chip >
235
- </ div >
236
- < Popover anchorRef = { maxWidthAnchorRef } fitToAnchorWidth = "maxWidth" isOpen placement = "top" >
237
- < div style = { demoPopperStyle } > Popover maxWidth</ div >
238
- </ Popover >
239
- < div >
240
- < Chip ref = { widthSmallAnchorRef } size = { Size . s } >
241
- Anchor
242
- </ Chip >
243
- </ div >
244
- < Popover anchorRef = { widthSmallAnchorRef } fitToAnchorWidth = "width" isOpen placement = "top" >
245
- < div style = { demoPopperStyle } > Popover width small anchor</ div >
246
- </ Popover >
247
- < div >
248
- < Chip ref = { widthLargeAnchorRef } size = { Size . s } >
249
- VeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLargeAnchor
250
- </ Chip >
251
- </ div >
252
- < Popover anchorRef = { widthLargeAnchorRef } fitToAnchorWidth = "width" isOpen placement = "top" >
253
- < div style = { demoPopperStyle } > Popover width large anchor</ div >
254
- </ Popover >
255
- < div >
256
- < Chip ref = { minWidthAnchorRef } size = { Size . s } >
257
- VeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLargeAnchor
258
- </ Chip >
259
- </ div >
260
- < Popover anchorRef = { minWidthAnchorRef } fitToAnchorWidth = "minWidth" isOpen placement = "top" >
261
- < div style = { demoPopperStyle } > Popover minWidth</ div >
262
- </ Popover >
263
- < div >
264
- < Chip ref = { defaultWidthAnchorRef } size = { Size . s } >
265
- VeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryVeryLargeAnchor
266
- </ Chip >
226
+ return (
227
+ < div style = { { float : 'right' } } className = "lumx-spacing-margin-right-huge" >
228
+ < IconButton
229
+ label = "Notifications"
230
+ className = "lumx-spacing-margin-right-huge"
231
+ ref = { anchorRef }
232
+ emphasis = { Emphasis . low }
233
+ icon = { mdiBell }
234
+ size = { Size . m }
235
+ onClick = { toggleOpen }
236
+ />
237
+ < Popover
238
+ closeOnClickAway
239
+ closeOnEscape
240
+ isOpen = { isOpen }
241
+ anchorRef = { anchorRef }
242
+ placement = { Placement . BOTTOM_END }
243
+ onClose = { toggleOpen }
244
+ fitWithinViewportHeight
245
+ >
246
+ < List style = { { overflowY : 'auto' } } >
247
+ { range ( 100 ) . map ( ( n : number ) => {
248
+ return (
249
+ < ListItem
250
+ key = { `key-${ n } ` }
251
+ before = { < Icon icon = { mdiAccount } /> }
252
+ className = "lumx-spacing-margin-right-huge"
253
+ >
254
+ < span > { `List item ${ n } and some text` } </ span >
255
+ </ ListItem >
256
+ ) ;
257
+ } ) }
258
+ </ List >
259
+ </ Popover >
267
260
</ div >
268
- < Popover anchorRef = { defaultWidthAnchorRef } isOpen placement = "top" >
269
- < div style = { demoPopperStyle } > Popover default</ div >
270
- </ Popover >
271
- </ div >
272
- ) ;
261
+ ) ;
262
+ } ,
263
+ parameters : { chromatic : { disable : true } } ,
273
264
} ;
0 commit comments