@@ -12,9 +12,8 @@ import React, {
12
12
forwardRef ,
13
13
CSSProperties ,
14
14
Fragment ,
15
- ComponentType ,
15
+ FunctionComponent ,
16
16
ComponentPropsWithRef ,
17
- PropsWithChildren ,
18
17
MutableRefObject ,
19
18
} from 'react' ;
20
19
import classnames from 'classnames' ;
@@ -28,7 +27,7 @@ import {
28
27
throttle ,
29
28
} from '../../services' ;
30
29
31
- import { CommonProps , keysOf } from '../common' ;
30
+ import { CommonProps , keysOf , PropsOfElement } from '../common' ;
32
31
import { EuiFocusTrap } from '../focus_trap' ;
33
32
import { EuiOverlayMask , EuiOverlayMaskProps } from '../overlay_mask' ;
34
33
import { EuiButtonIcon , EuiButtonIconPropsForButton } from '../button' ;
@@ -153,32 +152,26 @@ type _EuiFlyoutProps = {
153
152
style ?: React . CSSProperties ;
154
153
} ;
155
154
156
- // Using ReactHTML rather than JSX.IntrinsicElements here because it does not include
157
- // SVG element types which cause errors because they do not have all the attributes needed.
158
- type ComponentTypes =
159
- | 'div'
160
- | 'span'
161
- | 'nav'
162
- | 'aside'
163
- | 'section'
164
- | 'article'
165
- | 'header'
166
- | ComponentType ;
167
-
168
- export type EuiFlyoutProps < T extends ComponentTypes = 'div' > = CommonProps &
169
- ComponentPropsWithRef < T > & {
170
- /**
171
- * Sets the HTML element for `EuiFlyout`
172
- */
173
- as ?: T ;
174
- } & _EuiFlyoutProps ;
155
+ const defaultElement = 'div' ;
156
+
157
+ type Props < T extends React . ElementType > = CommonProps & {
158
+ /**
159
+ * Sets the HTML element for `EuiFlyout`
160
+ */
161
+ as ?: T ;
162
+ } & _EuiFlyoutProps &
163
+ Omit < PropsOfElement < T > , keyof _EuiFlyoutProps > ;
164
+
165
+ export type EuiFlyoutProps <
166
+ T extends React . ElementType = typeof defaultElement
167
+ > = Props < T > & Omit < ComponentPropsWithRef < T > , keyof Props < T > > ;
175
168
176
169
const EuiFlyout = forwardRef (
177
- < T extends ComponentTypes > (
170
+ < T extends React . ElementType = typeof defaultElement > (
178
171
{
179
172
className,
180
173
children,
181
- as : Element = 'div' as T ,
174
+ as,
182
175
hideCloseButton = false ,
183
176
closeButtonProps,
184
177
closeButtonAriaLabel,
@@ -196,12 +189,13 @@ const EuiFlyout = forwardRef(
196
189
role = 'dialog' ,
197
190
pushMinBreakpoint = 'l' ,
198
191
...rest
199
- } : PropsWithChildren < EuiFlyoutProps < T > > ,
192
+ } : EuiFlyoutProps < T > ,
200
193
ref :
201
194
| ( ( instance : ComponentPropsWithRef < T > | null ) => void )
202
195
| MutableRefObject < ComponentPropsWithRef < T > | null >
203
196
| null
204
197
) => {
198
+ const Element = as || defaultElement ;
205
199
/**
206
200
* Setting the initial state of pushed based on the `type` prop
207
201
* and if the current window size is large enough (larger than `pushMinBreakpoint`)
@@ -345,7 +339,6 @@ const EuiFlyout = forwardRef(
345
339
}
346
340
347
341
const flyoutContent = (
348
- // @ts -expect-error JSX element without construct
349
342
< Element
350
343
{ ...( rest as ComponentPropsWithRef < T > ) }
351
344
role = { role }
@@ -399,8 +392,13 @@ const EuiFlyout = forwardRef(
399
392
</ Fragment >
400
393
) ;
401
394
}
402
- ) ;
403
-
404
- EuiFlyout . displayName = 'EuiFlyout' ;
395
+ // React.forwardRef interferes with the inferred element type
396
+ // Casting to ensure correct element prop type checking for `as`
397
+ // e.g., `href` is not on a `div`
398
+ ) as < E extends React . ElementType = typeof defaultElement > (
399
+ props : EuiFlyoutProps < E >
400
+ ) => JSX . Element ;
401
+ // Recast to allow `displayName`
402
+ ( EuiFlyout as FunctionComponent ) . displayName = 'EuiFlyout' ;
405
403
406
404
export { EuiFlyout } ;
0 commit comments