@coreui/react 4.9.0-beta.0 → 4.9.0-beta.2
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/README.md +1 -1
- package/dist/components/dropdown/CDropdown.d.ts +8 -1
- package/dist/components/dropdown/CDropdownMenu.d.ts +3 -4
- package/dist/components/dropdown copy/CDropdown.d.ts +89 -0
- package/dist/components/dropdown copy/CDropdownDivider.d.ts +8 -0
- package/dist/components/dropdown copy/CDropdownHeader.d.ts +12 -0
- package/dist/components/dropdown copy/CDropdownItem.d.ts +13 -0
- package/dist/components/dropdown copy/CDropdownItemPlain.d.ts +12 -0
- package/dist/components/dropdown copy/CDropdownMenu.d.ts +13 -0
- package/dist/components/dropdown copy/CDropdownToggle.d.ts +24 -0
- package/dist/components/dropdown copy/index.d.ts +8 -0
- package/dist/components/popover/CPopover.d.ts +22 -1
- package/dist/components/progress/CProgress.d.ts +6 -0
- package/dist/components/progress/CProgressStacked.d.ts +12 -0
- package/dist/components/progress/index.d.ts +2 -1
- package/dist/components/tooltip/CTooltip.d.ts +22 -1
- package/dist/hooks/index.d.ts +2 -1
- package/dist/hooks/useColorModes.d.ts +4 -2
- package/dist/hooks/usePopper.d.ts +8 -0
- package/dist/index.es.js +1527 -1915
- package/dist/index.es.js.map +1 -1
- package/dist/index.js +1312 -1716
- package/dist/index.js.map +1 -1
- package/dist/props.d.ts +1 -0
- package/dist/utils/getRTLPlacement.d.ts +3 -0
- package/dist/utils/index.d.ts +2 -1
- package/package.json +5 -5
- package/src/components/dropdown/CDropdown.tsx +130 -45
- package/src/components/dropdown/CDropdownMenu.tsx +41 -138
- package/src/components/dropdown/CDropdownToggle.tsx +6 -15
- package/src/components/dropdown/__tests__/__snapshots__/CDropdownMenu.spec.tsx.snap +0 -1
- package/src/components/popover/CPopover.tsx +76 -51
- package/src/components/popover/__tests__/__snapshots__/CPopover.spec.tsx.snap +0 -21
- package/src/components/progress/CProgress.tsx +43 -8
- package/src/components/progress/CProgressBar.tsx +5 -6
- package/src/components/progress/CProgressStacked.tsx +39 -0
- package/src/components/progress/index.ts +2 -1
- package/src/components/tooltip/CTooltip.tsx +77 -52
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useColorModes.ts +23 -11
- package/src/hooks/usePopper.ts +31 -0
- package/src/props.ts +5 -0
- package/src/utils/getRTLPlacement.ts +18 -0
- package/src/utils/index.ts +2 -1
package/dist/props.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
2
|
import type { Placements, Triggers } from './types';
|
|
3
3
|
export declare const colorPropType: PropTypes.Requireable<string>;
|
|
4
|
+
export declare const fallbackPlacementsPropType: PropTypes.Requireable<NonNullable<Placements | NonNullable<Placements>[] | null>>;
|
|
4
5
|
export declare const placementPropType: PropTypes.Requireable<Placements>;
|
|
5
6
|
export declare const shapePropType: PropTypes.Requireable<string>;
|
|
6
7
|
export declare const textColorsPropType: PropTypes.Requireable<string>;
|
package/dist/utils/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coreui/react",
|
|
3
|
-
"version": "4.9.0-beta.
|
|
3
|
+
"version": "4.9.0-beta.2",
|
|
4
4
|
"description": "UI Components Library for React.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"@rollup/plugin-typescript": "^11.1.1",
|
|
44
44
|
"@testing-library/jest-dom": "^5.16.5",
|
|
45
45
|
"@testing-library/react": "^14.0.0",
|
|
46
|
-
"@types/react": "18.2.
|
|
47
|
-
"@types/react-dom": "^18.2.
|
|
46
|
+
"@types/react": "18.2.12",
|
|
47
|
+
"@types/react-dom": "^18.2.5",
|
|
48
48
|
"@types/react-transition-group": "^4.4.6",
|
|
49
49
|
"classnames": "^2.3.2",
|
|
50
50
|
"jest": "^29.5.0",
|
|
@@ -54,9 +54,9 @@
|
|
|
54
54
|
"react-dom": "^18.2.0",
|
|
55
55
|
"react-popper": "^2.3.0",
|
|
56
56
|
"react-transition-group": "^4.4.5",
|
|
57
|
-
"rollup": "^3.25.
|
|
58
|
-
"tslib": "^2.5.3",
|
|
57
|
+
"rollup": "^3.25.1",
|
|
59
58
|
"ts-jest": "^29.1.0",
|
|
59
|
+
"tslib": "^2.5.3",
|
|
60
60
|
"typescript": "^4.9.5"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
@@ -3,7 +3,6 @@ import React, {
|
|
|
3
3
|
ElementType,
|
|
4
4
|
forwardRef,
|
|
5
5
|
HTMLAttributes,
|
|
6
|
-
ReactNode,
|
|
7
6
|
RefObject,
|
|
8
7
|
useEffect,
|
|
9
8
|
useRef,
|
|
@@ -11,11 +10,11 @@ import React, {
|
|
|
11
10
|
} from 'react'
|
|
12
11
|
import PropTypes from 'prop-types'
|
|
13
12
|
import classNames from 'classnames'
|
|
14
|
-
import { Manager } from 'react-popper'
|
|
15
13
|
|
|
16
|
-
import { useForkedRef } from '../../hooks'
|
|
14
|
+
import { useForkedRef, usePopper } from '../../hooks'
|
|
17
15
|
import { placementPropType } from '../../props'
|
|
18
16
|
import type { Placements } from '../../types'
|
|
17
|
+
import { isRTL } from '../../utils'
|
|
19
18
|
|
|
20
19
|
export type Directions = 'start' | 'end'
|
|
21
20
|
|
|
@@ -60,8 +59,14 @@ export interface CDropdownProps extends HTMLAttributes<HTMLDivElement | HTMLLIEl
|
|
|
60
59
|
* Sets a specified direction and location of the dropdown menu.
|
|
61
60
|
*/
|
|
62
61
|
direction?: 'center' | 'dropup' | 'dropup-center' | 'dropend' | 'dropstart'
|
|
62
|
+
/**
|
|
63
|
+
* Offset of the dropdown menu relative to its target.
|
|
64
|
+
*/
|
|
65
|
+
offset?: [number, number]
|
|
63
66
|
/**
|
|
64
67
|
* Callback fired when the component requests to be hidden.
|
|
68
|
+
*
|
|
69
|
+
* @since 4.9.0-beta.2
|
|
65
70
|
*/
|
|
66
71
|
onHide?: () => void
|
|
67
72
|
/**
|
|
@@ -94,17 +99,45 @@ export interface CDropdownProps extends HTMLAttributes<HTMLDivElement | HTMLLIEl
|
|
|
94
99
|
visible?: boolean
|
|
95
100
|
}
|
|
96
101
|
|
|
97
|
-
const PopperManagerWrapper = ({ children, popper }: { children: ReactNode; popper: boolean }) => {
|
|
98
|
-
return popper ? <Manager>{children}</Manager> : <>{children}</>
|
|
99
|
-
}
|
|
100
|
-
|
|
101
102
|
interface ContextProps extends CDropdownProps {
|
|
102
103
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
103
|
-
dropdownToggleRef: RefObject<any
|
|
104
|
+
dropdownToggleRef: RefObject<any | undefined>
|
|
105
|
+
dropdownMenuRef: RefObject<HTMLDivElement | HTMLUListElement | undefined>
|
|
104
106
|
setVisible: React.Dispatch<React.SetStateAction<boolean | undefined>>
|
|
105
107
|
portal: boolean
|
|
106
108
|
}
|
|
107
109
|
|
|
110
|
+
const getPlacement = (
|
|
111
|
+
placement: Placements,
|
|
112
|
+
direction: CDropdownProps['direction'],
|
|
113
|
+
alignment: CDropdownProps['alignment'],
|
|
114
|
+
isRTL: boolean,
|
|
115
|
+
): Placements => {
|
|
116
|
+
let _placement = placement
|
|
117
|
+
|
|
118
|
+
if (direction === 'dropup') {
|
|
119
|
+
_placement = isRTL ? 'top-end' : 'top-start'
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (direction === 'dropup-center') {
|
|
123
|
+
_placement = 'top'
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (direction === 'dropend') {
|
|
127
|
+
_placement = isRTL ? 'left-start' : 'right-start'
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (direction === 'dropstart') {
|
|
131
|
+
_placement = isRTL ? 'right-start' : 'left-start'
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (alignment === 'end') {
|
|
135
|
+
_placement = isRTL ? 'bottom-start' : 'bottom-end'
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return _placement
|
|
139
|
+
}
|
|
140
|
+
|
|
108
141
|
export const CDropdownContext = createContext({} as ContextProps)
|
|
109
142
|
|
|
110
143
|
export const CDropdown = forwardRef<HTMLDivElement | HTMLLIElement, CDropdownProps>(
|
|
@@ -116,6 +149,7 @@ export const CDropdown = forwardRef<HTMLDivElement | HTMLLIElement, CDropdownPro
|
|
|
116
149
|
className,
|
|
117
150
|
dark,
|
|
118
151
|
direction,
|
|
152
|
+
offset = [0, 2],
|
|
119
153
|
onHide,
|
|
120
154
|
onShow,
|
|
121
155
|
placement = 'bottom-start',
|
|
@@ -129,9 +163,12 @@ export const CDropdown = forwardRef<HTMLDivElement | HTMLLIElement, CDropdownPro
|
|
|
129
163
|
ref,
|
|
130
164
|
) => {
|
|
131
165
|
const dropdownRef = useRef<HTMLDivElement>(null)
|
|
132
|
-
|
|
166
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
167
|
+
const dropdownToggleRef = useRef<any>(null)
|
|
168
|
+
const dropdownMenuRef = useRef<HTMLDivElement | HTMLUListElement>(null)
|
|
133
169
|
const forkedRef = useForkedRef(ref, dropdownRef)
|
|
134
170
|
const [_visible, setVisible] = useState(visible)
|
|
171
|
+
const { initPopper, destroyPopper } = usePopper()
|
|
135
172
|
|
|
136
173
|
const Component = variant === 'nav-item' ? 'li' : component
|
|
137
174
|
|
|
@@ -142,52 +179,100 @@ export const CDropdown = forwardRef<HTMLDivElement | HTMLLIElement, CDropdownPro
|
|
|
142
179
|
|
|
143
180
|
const contextValues = {
|
|
144
181
|
alignment,
|
|
145
|
-
autoClose,
|
|
146
182
|
dark,
|
|
147
|
-
direction: direction,
|
|
148
183
|
dropdownToggleRef,
|
|
149
|
-
|
|
184
|
+
dropdownMenuRef,
|
|
150
185
|
popper,
|
|
151
|
-
portal
|
|
186
|
+
portal,
|
|
152
187
|
variant,
|
|
153
188
|
visible: _visible,
|
|
154
189
|
setVisible,
|
|
155
190
|
}
|
|
156
191
|
|
|
192
|
+
const popperConfig = {
|
|
193
|
+
modifiers: [
|
|
194
|
+
{
|
|
195
|
+
name: 'offset',
|
|
196
|
+
options: {
|
|
197
|
+
offset: offset,
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
placement: getPlacement(placement, direction, alignment, isRTL(dropdownMenuRef.current)),
|
|
202
|
+
}
|
|
203
|
+
|
|
157
204
|
useEffect(() => {
|
|
158
205
|
setVisible(visible)
|
|
159
206
|
}, [visible])
|
|
160
207
|
|
|
161
208
|
useEffect(() => {
|
|
162
|
-
_visible &&
|
|
163
|
-
|
|
209
|
+
if (_visible && dropdownToggleRef.current && dropdownMenuRef.current) {
|
|
210
|
+
popper && initPopper(dropdownToggleRef.current, dropdownMenuRef.current, popperConfig)
|
|
211
|
+
window.addEventListener('mouseup', handleMouseUp)
|
|
212
|
+
window.addEventListener('keyup', handleKeyup)
|
|
213
|
+
onShow && onShow()
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
return () => {
|
|
217
|
+
popper && destroyPopper()
|
|
218
|
+
window.removeEventListener('mouseup', handleMouseUp)
|
|
219
|
+
window.removeEventListener('keyup', handleKeyup)
|
|
220
|
+
onHide && onHide()
|
|
221
|
+
}
|
|
164
222
|
}, [_visible])
|
|
165
223
|
|
|
224
|
+
const handleKeyup = (event: KeyboardEvent) => {
|
|
225
|
+
if (autoClose === false) {
|
|
226
|
+
return
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (event.key === 'Escape') {
|
|
230
|
+
setVisible(false)
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const handleMouseUp = (event: Event) => {
|
|
235
|
+
if (!dropdownToggleRef.current || !dropdownMenuRef.current) {
|
|
236
|
+
return
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (dropdownToggleRef.current.contains(event.target as HTMLElement)) {
|
|
240
|
+
return
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (
|
|
244
|
+
autoClose === true ||
|
|
245
|
+
(autoClose === 'inside' && dropdownMenuRef.current.contains(event.target as HTMLElement)) ||
|
|
246
|
+
(autoClose === 'outside' && !dropdownMenuRef.current.contains(event.target as HTMLElement))
|
|
247
|
+
) {
|
|
248
|
+
setTimeout(() => setVisible(false), 1)
|
|
249
|
+
return
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
166
253
|
return (
|
|
167
254
|
<CDropdownContext.Provider value={contextValues}>
|
|
168
|
-
|
|
169
|
-
{
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
)}
|
|
190
|
-
</PopperManagerWrapper>
|
|
255
|
+
{variant === 'input-group' ? (
|
|
256
|
+
<>{children}</>
|
|
257
|
+
) : (
|
|
258
|
+
<Component
|
|
259
|
+
className={classNames(
|
|
260
|
+
variant === 'nav-item' ? 'nav-item dropdown' : variant,
|
|
261
|
+
{
|
|
262
|
+
'dropdown-center': direction === 'center',
|
|
263
|
+
'dropup dropup-center': direction === 'dropup-center',
|
|
264
|
+
[`${direction}`]:
|
|
265
|
+
direction && direction !== 'center' && direction !== 'dropup-center',
|
|
266
|
+
show: _visible,
|
|
267
|
+
},
|
|
268
|
+
className,
|
|
269
|
+
)}
|
|
270
|
+
{...rest}
|
|
271
|
+
ref={forkedRef}
|
|
272
|
+
>
|
|
273
|
+
{children}
|
|
274
|
+
</Component>
|
|
275
|
+
)}
|
|
191
276
|
</CDropdownContext.Provider>
|
|
192
277
|
)
|
|
193
278
|
},
|
|
@@ -196,15 +281,14 @@ export const CDropdown = forwardRef<HTMLDivElement | HTMLLIElement, CDropdownPro
|
|
|
196
281
|
const alignmentDirection = PropTypes.oneOf<Directions>(['start', 'end'])
|
|
197
282
|
|
|
198
283
|
CDropdown.propTypes = {
|
|
199
|
-
// @ts-expect-error TODO: we have to find a solution
|
|
200
284
|
alignment: PropTypes.oneOfType([
|
|
201
285
|
alignmentDirection,
|
|
202
|
-
PropTypes.shape({ xs: alignmentDirection }),
|
|
203
|
-
PropTypes.shape({ sm: alignmentDirection }),
|
|
204
|
-
PropTypes.shape({ md: alignmentDirection }),
|
|
205
|
-
PropTypes.shape({ lg: alignmentDirection }),
|
|
206
|
-
PropTypes.shape({ xl: alignmentDirection }),
|
|
207
|
-
PropTypes.shape({ xxl: alignmentDirection }),
|
|
286
|
+
PropTypes.shape({ xs: alignmentDirection.isRequired }),
|
|
287
|
+
PropTypes.shape({ sm: alignmentDirection.isRequired }),
|
|
288
|
+
PropTypes.shape({ md: alignmentDirection.isRequired }),
|
|
289
|
+
PropTypes.shape({ lg: alignmentDirection.isRequired }),
|
|
290
|
+
PropTypes.shape({ xl: alignmentDirection.isRequired }),
|
|
291
|
+
PropTypes.shape({ xxl: alignmentDirection.isRequired }),
|
|
208
292
|
]),
|
|
209
293
|
autoClose: PropTypes.oneOfType([
|
|
210
294
|
PropTypes.bool,
|
|
@@ -215,6 +299,7 @@ CDropdown.propTypes = {
|
|
|
215
299
|
component: PropTypes.elementType,
|
|
216
300
|
dark: PropTypes.bool,
|
|
217
301
|
direction: PropTypes.oneOf(['center', 'dropup', 'dropup-center', 'dropend', 'dropstart']),
|
|
302
|
+
offset: PropTypes.any, // TODO: find good proptype
|
|
218
303
|
onHide: PropTypes.func,
|
|
219
304
|
onShow: PropTypes.func,
|
|
220
305
|
placement: placementPropType,
|
|
@@ -1,27 +1,13 @@
|
|
|
1
|
-
import React, { ElementType,
|
|
1
|
+
import React, { ElementType, forwardRef, HTMLAttributes, useContext } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import classNames from 'classnames'
|
|
4
|
-
import { Popper, PopperChildrenProps } from 'react-popper'
|
|
5
4
|
|
|
6
5
|
import { Alignments, CDropdownContext } from './CDropdown'
|
|
7
6
|
import { CConditionalPortal } from '../conditional-portal'
|
|
8
7
|
|
|
9
|
-
import
|
|
10
|
-
import { isRTL } from '../../utils'
|
|
8
|
+
import { useForkedRef } from '../../hooks'
|
|
11
9
|
|
|
12
|
-
export interface CDropdownMenuProps
|
|
13
|
-
extends HTMLAttributes<HTMLDivElement | HTMLUListElement>,
|
|
14
|
-
Omit<
|
|
15
|
-
PopperChildrenProps,
|
|
16
|
-
| 'arrowProps'
|
|
17
|
-
| 'forceUpdate'
|
|
18
|
-
| 'hasPopperEscaped'
|
|
19
|
-
| 'isReferenceHidden'
|
|
20
|
-
| 'placement'
|
|
21
|
-
| 'ref'
|
|
22
|
-
| 'style'
|
|
23
|
-
| 'update'
|
|
24
|
-
> {
|
|
10
|
+
export interface CDropdownMenuProps extends HTMLAttributes<HTMLDivElement | HTMLUListElement> {
|
|
25
11
|
/**
|
|
26
12
|
* A string of all className you want applied to the base component.
|
|
27
13
|
*/
|
|
@@ -47,127 +33,44 @@ const alignmentClassNames = (alignment: Alignments) => {
|
|
|
47
33
|
return classNames
|
|
48
34
|
}
|
|
49
35
|
|
|
50
|
-
export const CDropdownMenu
|
|
51
|
-
children,
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const handleMouseUp = (event: Event) => {
|
|
92
|
-
if (dropdownToggleRef && dropdownToggleRef.current.contains(event.target as HTMLElement)) {
|
|
93
|
-
return
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (
|
|
97
|
-
autoClose === true ||
|
|
98
|
-
(autoClose === 'inside' && dropdownMenuRef.current?.contains(event.target as HTMLElement)) ||
|
|
99
|
-
(autoClose === 'outside' && !dropdownMenuRef.current?.contains(event.target as HTMLElement))
|
|
100
|
-
) {
|
|
101
|
-
setTimeout(() => setVisible(false), 1)
|
|
102
|
-
return
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
let _placement: Placements = placement
|
|
107
|
-
|
|
108
|
-
if (direction === 'center') {
|
|
109
|
-
_placement = 'bottom'
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (direction === 'dropup') {
|
|
113
|
-
_placement = isRTL(dropdownMenuRef.current) ? 'top-end' : 'top-start'
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (direction === 'dropup-center') {
|
|
117
|
-
_placement = 'top'
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (direction === 'dropend') {
|
|
121
|
-
_placement = isRTL(dropdownMenuRef.current) ? 'left-start' : 'right-start'
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (direction === 'dropstart') {
|
|
125
|
-
_placement = isRTL(dropdownMenuRef.current) ? 'right-start' : 'left-start'
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (alignment === 'end') {
|
|
129
|
-
_placement = isRTL(dropdownMenuRef.current) ? 'bottom-start' : 'bottom-end'
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const dropdownMenuComponent = (style?: React.CSSProperties, ref?: React.Ref<HTMLDivElement>) => (
|
|
133
|
-
<CConditionalPortal portal={portal ?? false}>
|
|
134
|
-
<Component
|
|
135
|
-
className={classNames(
|
|
136
|
-
'dropdown-menu',
|
|
137
|
-
{
|
|
138
|
-
'dropdown-menu-dark': dark,
|
|
139
|
-
show: visible,
|
|
140
|
-
},
|
|
141
|
-
alignment && alignmentClassNames(alignment),
|
|
142
|
-
className,
|
|
143
|
-
)}
|
|
144
|
-
ref={ref}
|
|
145
|
-
style={style}
|
|
146
|
-
role="menu"
|
|
147
|
-
aria-hidden={!visible}
|
|
148
|
-
{...(!popper && { 'data-coreui-popper': 'static' })}
|
|
149
|
-
{...rest}
|
|
150
|
-
>
|
|
151
|
-
{Component === 'ul'
|
|
152
|
-
? React.Children.map(children, (child, index) => {
|
|
153
|
-
if (React.isValidElement(child)) {
|
|
154
|
-
return <li key={index}>{React.cloneElement(child)}</li>
|
|
155
|
-
}
|
|
156
|
-
return
|
|
157
|
-
})
|
|
158
|
-
: children}
|
|
159
|
-
</Component>
|
|
160
|
-
</CConditionalPortal>
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
return popper && visible ? (
|
|
164
|
-
<Popper innerRef={dropdownMenuRef} placement={_placement}>
|
|
165
|
-
{({ ref, style }) => dropdownMenuComponent(style, ref)}
|
|
166
|
-
</Popper>
|
|
167
|
-
) : (
|
|
168
|
-
dropdownMenuComponent()
|
|
169
|
-
)
|
|
170
|
-
}
|
|
36
|
+
export const CDropdownMenu = forwardRef<HTMLDivElement | HTMLUListElement, CDropdownMenuProps>(
|
|
37
|
+
({ children, className, component: Component = 'ul', ...rest }, ref) => {
|
|
38
|
+
const { alignment, dark, dropdownMenuRef, popper, portal, visible } =
|
|
39
|
+
useContext(CDropdownContext)
|
|
40
|
+
|
|
41
|
+
const forkedRef = useForkedRef(ref, dropdownMenuRef)
|
|
42
|
+
|
|
43
|
+
return (
|
|
44
|
+
<CConditionalPortal portal={portal ?? false}>
|
|
45
|
+
<Component
|
|
46
|
+
className={classNames(
|
|
47
|
+
'dropdown-menu',
|
|
48
|
+
{
|
|
49
|
+
'dropdown-menu-dark': dark,
|
|
50
|
+
show: visible,
|
|
51
|
+
},
|
|
52
|
+
alignment && alignmentClassNames(alignment),
|
|
53
|
+
className,
|
|
54
|
+
)}
|
|
55
|
+
ref={forkedRef}
|
|
56
|
+
role="menu"
|
|
57
|
+
aria-hidden={!visible}
|
|
58
|
+
{...(!popper && { 'data-coreui-popper': 'static' })}
|
|
59
|
+
{...rest}
|
|
60
|
+
>
|
|
61
|
+
{Component === 'ul'
|
|
62
|
+
? React.Children.map(children, (child, index) => {
|
|
63
|
+
if (React.isValidElement(child)) {
|
|
64
|
+
return <li key={index}>{React.cloneElement(child)}</li>
|
|
65
|
+
}
|
|
66
|
+
return
|
|
67
|
+
})
|
|
68
|
+
: children}
|
|
69
|
+
</Component>
|
|
70
|
+
</CConditionalPortal>
|
|
71
|
+
)
|
|
72
|
+
},
|
|
73
|
+
)
|
|
171
74
|
|
|
172
75
|
CDropdownMenu.propTypes = {
|
|
173
76
|
children: PropTypes.node,
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
import React, { FC, useContext } from 'react'
|
|
2
2
|
import PropTypes from 'prop-types'
|
|
3
3
|
import classNames from 'classnames'
|
|
4
|
-
import { Reference } from 'react-popper'
|
|
5
4
|
|
|
6
5
|
import { CButton, CButtonProps } from '../button/CButton'
|
|
7
6
|
|
|
8
7
|
import { CDropdownContext } from './CDropdown'
|
|
9
8
|
|
|
10
|
-
import { useForkedRef } from '../../hooks'
|
|
11
9
|
import { triggerPropType } from '../../props'
|
|
12
10
|
import type { Triggers } from '../../types'
|
|
13
11
|
|
|
@@ -41,7 +39,7 @@ export const CDropdownToggle: FC<CDropdownToggleProps> = ({
|
|
|
41
39
|
trigger = 'click',
|
|
42
40
|
...rest
|
|
43
41
|
}) => {
|
|
44
|
-
const { dropdownToggleRef,
|
|
42
|
+
const { dropdownToggleRef, variant, visible, setVisible } = useContext(CDropdownContext)
|
|
45
43
|
|
|
46
44
|
const triggers = {
|
|
47
45
|
...((trigger === 'click' || trigger.includes('click')) && {
|
|
@@ -70,15 +68,14 @@ export const CDropdownToggle: FC<CDropdownToggleProps> = ({
|
|
|
70
68
|
}
|
|
71
69
|
|
|
72
70
|
// We use any because Toggler can be `a` as well as `button`.
|
|
73
|
-
|
|
74
|
-
const Toggler = (ref?: React.Ref<any>) => {
|
|
71
|
+
const Toggler = () => {
|
|
75
72
|
if (custom && React.isValidElement(children)) {
|
|
76
73
|
return (
|
|
77
74
|
<>
|
|
78
75
|
{React.cloneElement(children as React.ReactElement<any>, {
|
|
79
76
|
'aria-expanded': visible,
|
|
80
77
|
...(!rest.disabled && { ...triggers }),
|
|
81
|
-
ref:
|
|
78
|
+
ref: dropdownToggleRef,
|
|
82
79
|
})}
|
|
83
80
|
</>
|
|
84
81
|
)
|
|
@@ -86,27 +83,21 @@ export const CDropdownToggle: FC<CDropdownToggleProps> = ({
|
|
|
86
83
|
|
|
87
84
|
if (variant === 'nav-item') {
|
|
88
85
|
return (
|
|
89
|
-
<a href="#" {...togglerProps} ref={
|
|
86
|
+
<a href="#" {...togglerProps} ref={dropdownToggleRef}>
|
|
90
87
|
{children}
|
|
91
88
|
</a>
|
|
92
89
|
)
|
|
93
90
|
}
|
|
94
91
|
|
|
95
92
|
return (
|
|
96
|
-
<CButton
|
|
97
|
-
type="button"
|
|
98
|
-
{...togglerProps}
|
|
99
|
-
tabIndex={0}
|
|
100
|
-
{...rest}
|
|
101
|
-
ref={useForkedRef(ref, dropdownToggleRef)}
|
|
102
|
-
>
|
|
93
|
+
<CButton type="button" {...togglerProps} tabIndex={0} {...rest} ref={dropdownToggleRef}>
|
|
103
94
|
{children}
|
|
104
95
|
{split && <span className="visually-hidden">Toggle Dropdown</span>}
|
|
105
96
|
</CButton>
|
|
106
97
|
)
|
|
107
98
|
}
|
|
108
99
|
|
|
109
|
-
return
|
|
100
|
+
return <Toggler />
|
|
110
101
|
}
|
|
111
102
|
|
|
112
103
|
CDropdownToggle.propTypes = {
|