diff --git a/apps/storybook-react/stories/Popover.stories.jsx b/apps/storybook-react/stories/Popover.stories.tsx similarity index 75% rename from apps/storybook-react/stories/Popover.stories.jsx rename to apps/storybook-react/stories/Popover.stories.tsx index 7462b28f4f..0ec12fe2a8 100644 --- a/apps/storybook-react/stories/Popover.stories.jsx +++ b/apps/storybook-react/stories/Popover.stories.tsx @@ -1,18 +1,13 @@ import React from 'react' -import { withKnobs, select, text } from '@storybook/addon-knobs' import styled from 'styled-components' import { Typography, Button, - Avatar, - Chip, - TextField, - Search, - Icon, Popover, + PopoverProps, Card, } from '@equinor/eds-core-react' -import catImg from '../images/cat.jpg' +import { Meta, Story } from '@storybook/react' const { PopoverAnchor, PopoverTitle, PopoverContent } = Popover const { CardActions } = Card @@ -36,18 +31,70 @@ const TextWrapper = styled.div` export default { title: 'Components/Popover', component: Popover, - decorators: [withKnobs], + subcomponents: { + PopoverAnchor, + PopoverTitle, + PopoverContent, + CardActions, + }, + argTypes: { + placement: { + control: { + type: 'select', + options: [ + 'topLeft', + 'top', + 'topRight', + 'rightTop', + 'right', + 'rightBottom', + 'bottomLeft', + 'bottom', + 'bottomRight', + 'leftTop', + 'left', + 'leftBottom', + ], + }, + }, + }, +} as Meta + +export const Default: Story = (args) => { + const [active, setActive] = React.useState(false) + const handleToggle = () => { + setActive(!active) + } + return ( +
+ + + + + Title + + Content + + + + + + +
+ ) } -export function Placement() { - const [active, setActive] = React.useState(null) +export const Placements: Story = () => { + const [active, setActive] = React.useState('') - const handleClick = (event) => { + const handleClick = (event: React.SyntheticEvent) => { setActive(event.currentTarget.id) } const handleClose = () => { - setActive(null) + setActive('') } const Content = () => ( @@ -227,14 +274,14 @@ export function Placement() { ) } -export function ActivationTypes() { - const [active, setActive] = React.useState(null) +export const ActivationTypes: Story = () => { + const [active, setActive] = React.useState('') - const handleClick = (event) => { + const handleClick = (event: React.SyntheticEvent) => { setActive(event.currentTarget.id) } - const handleHover = (event) => { + const handleHover = (event: React.SyntheticEvent) => { const current = event.currentTarget.id setTimeout(() => { setActive(current) @@ -242,7 +289,7 @@ export function ActivationTypes() { } const handleClose = () => { - setActive(null) + setActive('') } const Content = () => ( @@ -298,86 +345,3 @@ export function ActivationTypes() { ) } - -const ANCHOR_CHOICES = { - button: , - avatar: , - chip: Chip, - search: ( - - ), - textfield: ( - - ), - typography: Typography, - icon: , -} - -const ACTIONS_CHOICES = { - none: '', - default: ( - - - - - ), - alignRight: ( - - - - - ), - meta: ( - - - - ), -} - -export const WithKnobs = () => { - const anchor = select('Anchor', Object.keys(ANCHOR_CHOICES), 'avatar') - const title = text('Title', 'Title') - const content = text('Content', 'Content') - const action = select('Actions', Object.keys(ACTIONS_CHOICES), 'default') - const placement = select( - 'Placement', - [ - 'topLeft', - 'top', - 'topRight', - 'rightTop', - 'right', - 'rightBottom', - 'bottomLeft', - 'bottom', - 'bottomRight', - 'leftTop', - 'left', - 'leftBottom', - ], - 'bottom', - ) - - return ( - - - With knobs - - - - {title} - {ANCHOR_CHOICES[anchor]} - - {content} - - {ACTIONS_CHOICES[action]} - - - - ) -} diff --git a/libraries/core-react/src/Popover/Popover.test.tsx b/libraries/core-react/src/Popover/Popover.test.tsx index a91a0b9686..0c2c97460c 100644 --- a/libraries/core-react/src/Popover/Popover.test.tsx +++ b/libraries/core-react/src/Popover/Popover.test.tsx @@ -9,7 +9,7 @@ import { popover as tokens } from './Popover.tokens' import { Popover } from '.' import { Button } from '../Button' import { Typography } from '../Typography' -import type { Props } from './Popover' +import type { PopoverProps } from './Popover' const { PopoverTitle, PopoverContent, PopoverAnchor } = Popover @@ -24,7 +24,10 @@ const { afterEach(cleanup) -const SimplePopover = ({ open = false, placement = 'bottom' }: Props) => ( +const SimplePopover = ({ + open = false, + placement = 'bottom', +}: PopoverProps) => ( @@ -61,7 +64,7 @@ describe('Popover', () => { expect(arrow).toHaveStyleRule('right', `${topRight.arrowRight}`) expect(arrow).toHaveStyleRule('bottom', `${topRight.arrowBottom}`) }) - it('Has provided necessary props', () => { + it('Has provided necessary PopoverProps', () => { const placement = 'topRight' const { queryByText } = render() expect(queryByText(placement)).toBeDefined() diff --git a/libraries/core-react/src/Popover/Popover.tsx b/libraries/core-react/src/Popover/Popover.tsx index 0526e893a0..258e68d2d4 100644 --- a/libraries/core-react/src/Popover/Popover.tsx +++ b/libraries/core-react/src/Popover/Popover.tsx @@ -25,8 +25,8 @@ type PopoverSplit = { childArray: ReactNode[] } -export type Props = { - /* Popover placement relative to anchor */ +export type PopoverProps = { + /** Popover placement relative to anchor */ placement?: | 'topLeft' | 'top' @@ -42,58 +42,59 @@ export type Props = { | 'leftBottom' /** On Close function */ onClose?: () => void - /** Open activates */ + /** Open activates Popover */ open?: boolean } & HTMLAttributes // Controller Component for PopoverItem -export const Popover = forwardRef(function Popover( - { open, children, placement = 'bottom', ...rest }, - ref, -) { - const props = { - ...rest, - placement, - ref, - } - if (!children) { - return - } - const anchorRef = useRef(null) +export const Popover = forwardRef( + function Popover({ open, children, placement = 'bottom', ...rest }, ref) { + const props = { + ...rest, + placement, + ref, + } + if (!children) { + return + } + const anchorRef = useRef(null) - const { anchorElement, childArray } = React.Children.toArray(children).reduce( - (acc: PopoverSplit, child): PopoverSplit => { - if (isValidElement(child) && child.type === PopoverAnchor) { + const { anchorElement, childArray } = React.Children.toArray( + children, + ).reduce( + (acc: PopoverSplit, child): PopoverSplit => { + if (isValidElement(child) && child.type === PopoverAnchor) { + return { + ...acc, + anchorElement: child, + } + } return { ...acc, - anchorElement: child, + childArray: [...acc.childArray, child], } - } - return { - ...acc, - childArray: [...acc.childArray, child], - } - }, - { anchorElement: null, childArray: [] }, - ) + }, + { anchorElement: null, childArray: [] }, + ) - if (open && anchorRef.current) { - anchorRef.current.focus() - } + if (open && anchorRef.current) { + anchorRef.current.focus() + } - return ( - - - {anchorElement} - + return ( + + + {anchorElement} + - {open && ( - - {childArray} - - )} - - ) -}) + {open && ( + + {childArray} + + )} + + ) + }, +) // Popover.displayName = 'eds-popover' diff --git a/libraries/core-react/src/Popover/PopoverItem.tsx b/libraries/core-react/src/Popover/PopoverItem.tsx index 4fdd63ad61..43b2caa558 100644 --- a/libraries/core-react/src/Popover/PopoverItem.tsx +++ b/libraries/core-react/src/Popover/PopoverItem.tsx @@ -81,7 +81,7 @@ const StyledCloseButton = styled(Button)` } ` -type Props = { +type PopoverItemProps = { /* Popover placement relative to anchor */ placement?: | 'topLeft' @@ -98,12 +98,12 @@ type Props = { | 'leftBottom' /** On Close function */ onClose?: () => void - /** Open activates */ + /** Anchor reference */ anchorRef: React.MutableRefObject } & HTMLAttributes -export const PopoverItem = forwardRef( - function EdsPopoverItem( +export const PopoverItem = forwardRef( + function PopoverItem( { children, onClose = () => {}, diff --git a/libraries/core-react/src/Popover/index.ts b/libraries/core-react/src/Popover/index.ts index f49821e67f..82f3e3c823 100644 --- a/libraries/core-react/src/Popover/index.ts +++ b/libraries/core-react/src/Popover/index.ts @@ -2,20 +2,17 @@ import { Popover as BaseComponent } from './Popover' import { PopoverTitle } from './PopoverTitle' import { PopoverAnchor } from './PopoverAnchor' import { PopoverContent } from './PopoverContent' -import { PopoverItem } from './PopoverItem' -type PopoverTypes = typeof BaseComponent & { +type PopoverProps = typeof BaseComponent & { PopoverTitle: typeof PopoverTitle PopoverAnchor: typeof PopoverAnchor PopoverContent: typeof PopoverContent - PopoverItem: typeof PopoverItem } -const Popover = BaseComponent as PopoverTypes +const Popover = BaseComponent as PopoverProps Popover.PopoverTitle = PopoverTitle Popover.PopoverAnchor = PopoverAnchor Popover.PopoverContent = PopoverContent -Popover.PopoverItem = PopoverItem -export { Popover } +export { Popover, PopoverProps } diff --git a/libraries/core-react/src/index.ts b/libraries/core-react/src/index.ts index 46d6d94ddf..1bc8546fd5 100644 --- a/libraries/core-react/src/index.ts +++ b/libraries/core-react/src/index.ts @@ -20,7 +20,7 @@ export * from './Search' export { Slider } from './Slider' export { Tooltip } from './Tooltip' export { Snackbar } from './Snackbar' -export { Popover } from './Popover' +export * from './Popover' export * from './Banner' export { Radio, Checkbox, Switch } from './SelectionControls' export * from './Progress'