-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 🚚 Rename to typescript extension * 🏷️ Some more types and typescript support * 🏷️ Add types for anchor, content and title * ♻️ Fix imports for test * ♻️ DRY and placement token * 🎨 Better readability * 🐛 Add clode-icon explicit * ♻️ Another approach for popover children * Remove empty line * Add icon with data attr * Make @mimarz happy by extending the component * Add support for missing children as React's native functionality
- Loading branch information
Showing
13 changed files
with
474 additions
and
395 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import React, { forwardRef, useRef, HTMLAttributes, ReactNode } from 'react' | ||
import styled from 'styled-components' | ||
import { PopoverItem } from './PopoverItem' | ||
|
||
const Container = styled.div` | ||
position: relative; | ||
display: inline-flex; | ||
justify-content: center; | ||
` | ||
|
||
const Anchor = styled.div` | ||
&:focus { | ||
outline: none; | ||
} | ||
` | ||
type PopoverChild = { | ||
type?: { displayName?: string } | ||
} & ReactNode | ||
|
||
export type Props = { | ||
/* Popover placement relative to anchor */ | ||
placement?: | ||
| 'topLeft' | ||
| 'top' | ||
| 'topRight' | ||
| 'rightTop' | ||
| 'right' | ||
| 'rightBottom' | ||
| 'bottomLeft' | ||
| 'bottom' | ||
| 'bottomRight' | ||
| 'leftTop' | ||
| 'left' | ||
| 'leftBottom' | ||
/** On Close function */ | ||
onClose?: () => void | ||
/** Open activates <PopoverItem/> */ | ||
open?: boolean | ||
} & HTMLAttributes<HTMLDivElement> | ||
|
||
// Controller Component for PopoverItem | ||
export const Popover = forwardRef<HTMLDivElement, Props>(function Popover( | ||
{ open, children, placement = 'bottom', ...rest }, | ||
ref, | ||
) { | ||
const props = { | ||
...rest, | ||
placement, | ||
ref, | ||
} | ||
if (!children) { | ||
return <Container {...props} /> | ||
} | ||
const anchorRef = useRef<HTMLDivElement>(null) | ||
const popoverChildren: PopoverChild | PopoverChild[] = children | ||
let anchorElement: PopoverChild | ||
const childArray = [] | ||
if (Array.isArray(popoverChildren)) { | ||
for (let i = 0; i < popoverChildren.length; i += 1) { | ||
/* | ||
Find anchor element in children to wrap the element together with <PopoverItem/>. | ||
Children is required, but user has to wrap the actual anchor with <PopoverAnchor /> | ||
*/ | ||
const child = popoverChildren[i] as PopoverChild | ||
if (child.type && child.type.displayName === 'eds-popover-anchor') { | ||
anchorElement = child | ||
} else { | ||
// Add the remaining children to a new array to display inside <PopoverItem/> | ||
childArray.push(child) | ||
} | ||
} | ||
} else if ( | ||
!Array.isArray(popoverChildren) && | ||
popoverChildren.type && | ||
popoverChildren.type.displayName === 'eds-popover-anchor' | ||
) { | ||
anchorElement = popoverChildren | ||
} | ||
|
||
if (open && anchorRef.current) { | ||
anchorRef.current.focus() | ||
} | ||
|
||
return ( | ||
<Container {...props}> | ||
<Anchor aria-haspopup="true" ref={anchorRef}> | ||
{anchorElement} | ||
</Anchor> | ||
|
||
{open && ( | ||
<PopoverItem {...props} anchorRef={anchorRef}> | ||
{childArray} | ||
</PopoverItem> | ||
)} | ||
</Container> | ||
) | ||
}) | ||
|
||
Popover.displayName = 'eds-popover' |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import React, { forwardRef, HTMLAttributes } from 'react' | ||
|
||
type Props = HTMLAttributes<HTMLDivElement> | ||
|
||
export const PopoverAnchor = forwardRef<HTMLDivElement, Props>( | ||
function PopoverAnchor({ children, ...rest }, ref) { | ||
const props = { | ||
...rest, | ||
ref, | ||
} | ||
return <div {...props}>{children}</div> | ||
}, | ||
) | ||
|
||
PopoverAnchor.displayName = 'eds-popover-anchor' |
Oops, something went wrong.