@@ -2,24 +2,21 @@ import classNames from 'classnames';
2
2
import PropTypes from 'prop-types' ;
3
3
import * as React from 'react' ;
4
4
import { useContext , useMemo } from 'react' ;
5
- import BaseDropdown from 'react-overlays/Dropdown' ;
6
- import { DropDirection } from 'react-overlays/DropdownContext' ;
5
+ import BaseDropdown , {
6
+ DropdownProps as BaseDropdownProps ,
7
+ ToggleMetadata ,
8
+ } from '@restart/ui/Dropdown' ;
7
9
import { useUncontrolled } from 'uncontrollable' ;
8
10
import useEventCallback from '@restart/hooks/useEventCallback' ;
9
- import DropdownContext from './DropdownContext' ;
11
+ import DropdownContext , { DropDirection } from './DropdownContext' ;
10
12
import DropdownItem from './DropdownItem' ;
11
13
import DropdownMenu from './DropdownMenu' ;
12
14
import DropdownToggle from './DropdownToggle' ;
13
15
import InputGroupContext from './InputGroupContext' ;
14
- import SelectableContext from './SelectableContext' ;
15
16
import { useBootstrapPrefix } from './ThemeProvider' ;
16
17
import createWithBsPrefix from './createWithBsPrefix' ;
17
- import {
18
- BsPrefixProps ,
19
- BsPrefixRefForwardingComponent ,
20
- SelectCallback ,
21
- } from './helpers' ;
22
- import { AlignType , alignPropType } from './types' ;
18
+ import { BsPrefixProps , BsPrefixRefForwardingComponent } from './helpers' ;
19
+ import { AlignType , alignPropType , Placement } from './types' ;
23
20
24
21
const DropdownHeader = createWithBsPrefix ( 'dropdown-header' , {
25
22
defaultProps : { role : 'heading' } ,
@@ -33,19 +30,13 @@ const DropdownItemText = createWithBsPrefix('dropdown-item-text', {
33
30
} ) ;
34
31
35
32
export interface DropdownProps
36
- extends BsPrefixProps ,
37
- Omit < React . HTMLAttributes < HTMLElement > , 'onSelect' > {
38
- drop ?: 'up' | 'start' | 'end' | 'down' ;
33
+ extends BaseDropdownProps ,
34
+ BsPrefixProps ,
35
+ Omit < React . HTMLAttributes < HTMLElement > , 'onSelect' | 'children' > {
36
+ drop ?: DropDirection ;
39
37
align ?: AlignType ;
40
- show ?: boolean ;
41
38
flip ?: boolean ;
42
- onToggle ?: (
43
- isOpen : boolean ,
44
- event : React . SyntheticEvent ,
45
- metadata : { source : 'select' | 'click' | 'rootClose' | 'keydown' } ,
46
- ) => void ;
47
39
focusFirstItemOnShow ?: boolean | 'keyboard' ;
48
- onSelect ?: SelectCallback ;
49
40
navbar ?: boolean ;
50
41
autoClose ?: boolean | 'outside' | 'inside' ;
51
42
}
@@ -156,7 +147,6 @@ const Dropdown: BsPrefixRefForwardingComponent<'div', DropdownProps> =
156
147
...props
157
148
} = useUncontrolled ( pProps , { show : 'onToggle' } ) ;
158
149
159
- const onSelectCtx = useContext ( SelectableContext ) ;
160
150
const isInputGroup = useContext ( InputGroupContext ) ;
161
151
const prefix = useBootstrapPrefix ( bsPrefix , 'dropdown' ) ;
162
152
@@ -174,67 +164,60 @@ const Dropdown: BsPrefixRefForwardingComponent<'div', DropdownProps> =
174
164
} ;
175
165
176
166
const handleToggle = useEventCallback (
177
- ( nextShow , event , source = event . type ) => {
167
+ ( nextShow : boolean , meta : ToggleMetadata ) => {
178
168
if (
179
- event . currentTarget === document &&
180
- ( source !== 'keydown' || event . key === 'Escape' )
169
+ meta . originalEvent ! . currentTarget === document &&
170
+ ( meta . source !== 'keydown' ||
171
+ ( meta . originalEvent as any ) . key === 'Escape' )
181
172
)
182
- source = 'rootClose' ;
173
+ meta . source = 'rootClose' ;
183
174
184
- if ( isClosingPermitted ( source ) ) onToggle ?.( nextShow , event , { source } ) ;
175
+ if ( isClosingPermitted ( meta . source ! ) ) onToggle ?.( nextShow , meta ) ;
185
176
} ,
186
177
) ;
187
178
188
- const handleSelect = useEventCallback ( ( key , event ) => {
189
- onSelectCtx ?.( key , event ) ;
190
- onSelect ?.( key , event ) ;
191
- handleToggle ( false , event , 'select' ) ;
192
- } ) ;
193
-
194
179
// TODO RTL: Flip directions based on RTL setting.
195
- let direction : DropDirection = drop as DropDirection ;
196
- if ( drop === 'start' ) {
197
- direction = 'left' ;
198
- } else if ( drop === 'end' ) {
199
- direction = 'right' ;
200
- }
180
+ const alignEnd = align === 'end' ;
181
+ let placement : Placement = alignEnd ? 'bottom-end' : 'bottom-start' ;
182
+ if ( drop === 'up' ) placement = alignEnd ? 'top-end' : 'top-start' ;
183
+ else if ( drop === 'end' ) placement = alignEnd ? 'right-end' : 'right-start' ;
184
+ else if ( drop === 'start' ) placement = alignEnd ? 'left-end' : 'left-start' ;
201
185
202
186
const contextValue = useMemo (
203
187
( ) => ( {
204
188
align,
189
+ drop,
205
190
} ) ,
206
- [ align ] ,
191
+ [ align , drop ] ,
207
192
) ;
208
193
209
194
return (
210
195
< DropdownContext . Provider value = { contextValue } >
211
- < SelectableContext . Provider value = { handleSelect } >
212
- < BaseDropdown
213
- drop = { direction }
214
- show = { show }
215
- alignEnd = { align === 'end' }
216
- onToggle = { handleToggle }
217
- focusFirstItemOnShow = { focusFirstItemOnShow }
218
- itemSelector = { `.${ prefix } -item:not(.disabled):not(:disabled)` }
219
- >
220
- { isInputGroup ? (
221
- props . children
222
- ) : (
223
- < Component
224
- { ...props }
225
- ref = { ref }
226
- className = { classNames (
227
- className ,
228
- show && 'show' ,
229
- ( ! drop || drop === 'down' ) && prefix ,
230
- drop === 'up' && 'dropup' ,
231
- drop === 'end' && 'dropend' ,
232
- drop === 'start' && 'dropstart' ,
233
- ) }
234
- />
235
- ) }
236
- </ BaseDropdown >
237
- </ SelectableContext . Provider >
196
+ < BaseDropdown
197
+ placement = { placement }
198
+ show = { show }
199
+ onSelect = { onSelect }
200
+ onToggle = { handleToggle }
201
+ focusFirstItemOnShow = { focusFirstItemOnShow }
202
+ itemSelector = { `.${ prefix } -item:not(.disabled):not(:disabled)` }
203
+ >
204
+ { isInputGroup ? (
205
+ props . children
206
+ ) : (
207
+ < Component
208
+ { ...props }
209
+ ref = { ref }
210
+ className = { classNames (
211
+ className ,
212
+ show && 'show' ,
213
+ ( ! drop || drop === 'down' ) && prefix ,
214
+ drop === 'up' && 'dropup' ,
215
+ drop === 'end' && 'dropend' ,
216
+ drop === 'start' && 'dropstart' ,
217
+ ) }
218
+ />
219
+ ) }
220
+ </ BaseDropdown >
238
221
</ DropdownContext . Provider >
239
222
) ;
240
223
} ) ;
0 commit comments