Skip to content

Commit

Permalink
feat(Popover): implement dynamin colors and new props
Browse files Browse the repository at this point in the history
  • Loading branch information
rapahaeru committed Apr 9, 2019
1 parent 9f18dff commit 1c65136
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 37 deletions.
91 changes: 70 additions & 21 deletions components/Popover/Popover.jsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
import React, { Component } from 'react';
import styled from 'styled-components';
import PropTypes from 'prop-types';
import PropTypes, { oneOf } from 'prop-types';
import Colors from '../Colors';
import placementConfig from '../Tooltip/options';
import Button from '../Button';

const Tip = styled.div`
const getStyleBySkin = skin => {
const color = skin.toUpperCase();
// const indexColor = skin === 'default' ? '500' : '700';
return `
background-color: ${
skin === 'default' ? Colors.WHITE : Colors[color][200]
};
color: ${skin === 'default' ? Colors.BLACK[700] : Colors[color][900]};
`;
};

const PopoverContent = styled.div`
box-shadow: 0 2px 4px 0 ${Colors.SHADOW[50]};
align-items: start;
display: flex;
border-radius: 4px;
font-size: 16px;
font-weight: bold;
opacity: ${({ visible }) => (visible ? '1' : '0')};
padding: 4px 8px;
position: absolute;
line-height: 0;
text-align: center;
transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
z-index: 100;
Expand All @@ -22,20 +36,41 @@ const Tip = styled.div`
position: absolute;
${({ placement }) => placementConfig.arrowPosition[placement]};
}
${({ skin }) => getStyleBySkin(skin)}
`;

const TipText = styled.span`
const PopoverText = styled.span`
display: inline-block;
max-width: 250px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;

const Wrapper = styled.div`
position: relative;
`;

const CloseButton = styled(Button.Icon).attrs({
icon: 'close',
})`
display: inherit;
height: auto;
margin: 0 0 0 16px;
opacity: 0.8;
padding: 0;
transition: opacity 0.4s ease;
width: auto;
:hover {
background: none;
opacity: 1;
}
`;

const ChildrenBlock = styled.div`
text-decoration: none;
cursor: pointer;
`;

class Popover extends Component {
constructor(props) {
super(props);
Expand All @@ -52,19 +87,29 @@ class Popover extends Component {
};

render() {
const { children, text, placement, visible, onClick } = this.props;
const {
children,
text,
placement,
visible,
isClickable,
onClose,
...rest
} = this.props;
const { visible: visibleState } = this.state;
return (
<Wrapper
onMouseEnter={() => this.isVisible(true)}
onMouseLeave={() => this.isVisible(false)}
>
<Tip placement={placement} visible={visible || visibleState}>
<TipText>
{text} {onClick}
</TipText>
</Tip>
{children}
<Wrapper>
<PopoverContent
placement={placement}
visible={visible || visibleState}
{...rest}
>
<PopoverText>{text}</PopoverText>
<CloseButton onClick={() => this.isVisible(false)} />
</PopoverContent>
<ChildrenBlock onClick={() => this.isVisible(true)}>
{children}
</ChildrenBlock>
</Wrapper>
);
}
Expand All @@ -78,13 +123,17 @@ Popover.propTypes = {
visible: PropTypes.bool,
text: PropTypes.string.isRequired,
placement: PropTypes.oneOf(['top', 'right', 'bottom', 'left']),
onClick: PropTypes.bool,
isClickable: PropTypes.bool,
onClose: PropTypes.func,
skin: oneOf(['default', 'success', 'warning', 'error']),
};

Popover.defaultProps = {
visible: false,
placement: 'top',
onClick: false,
isClickable: false,
onClose: () => {},
skin: 'default',
};

export default Popover;
4 changes: 1 addition & 3 deletions components/Popover/Popover.unit.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ describe('Popover component ', () => {
describe('All positions', () => {
it('Should match the snapshot when place is top', () => {
const popover = mount(
<Popover place="top" text={POPOVER_TEXT}>
Hover Me
</Popover>,
<Popover text={POPOVER_TEXT}>popover here</Popover>,
);
expect(popover.html()).toMatchSnapshot();
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Popover component All positions Should match the snapshot when place is top 1`] = `"<div class=\\"Popover__Wrapper-sc-94rrmp-2 iOyUpv\\"><div class=\\"Popover__Tip-sc-94rrmp-0 htsiya\\"><span class=\\"Popover__TipText-sc-94rrmp-1 hlIzeT\\">This is a hint </span></div>Hover Me</div>"`;
exports[`Popover component All positions Should match the snapshot when place is top 1`] = `"<div class=\\"Popover__Wrapper-sc-94rrmp-2 iOyUpv\\"><div class=\\"Popover__PopoverContent-sc-94rrmp-0 kbrGrh\\"><span class=\\"Popover__PopoverText-sc-94rrmp-1 gJnVIa\\">This is a hint</span><button class=\\"Button__IconButton-sc-1ovnfsw-2 Popover__CloseButton-sc-94rrmp-3 hUtXpz Button__StyledButton-sc-1ovnfsw-1 hNpWHy\\" type=\\"button\\"><span class=\\"material-icons MuiIcon-root-1 Button__ButtonIcon-sc-1ovnfsw-0 hvLbao\\" aria-hidden=\\"true\\">close</span></button></div><div class=\\"Popover__ChildrenBlock-sc-94rrmp-4 bQgubP\\">popover here</div></div>"`;
65 changes: 53 additions & 12 deletions stories/Popover/Popover.story.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,59 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import { AutoExample } from '@catho/quantum-storybook-ui';
import {
TabbedView,
Tab,
AutoPropsApi,
Heading,
StoryContainer,
Title,
SimpleHighlight,
AutoExample,
} from '@catho/quantum-storybook-ui';
import { Row, Col } from '../../components';
import Popover from '../../components/Popover';

const description = `Popovers provide additional information upon hover or focus.
They often contain helper text that is contextual to an element.`;
import PopoverExample from './examples/PopoverExample';

storiesOf('Popover', module).add('Popover', () => (
<AutoExample
description={description}
component={Popover}
componentProps={{
children: 'Popover me',
text: 'This is a Popover.',
}}
/>
<>
<Heading name="Popover">
A Popover can be used to display some content on top of another
</Heading>
<TabbedView>
<Tab title="Usage">
<AutoExample
component={Popover}
componentProps={{
children: <p>Popover me</p>,
text:
'Lorem ipsum dolor avec Lorem ipsum dolor avec Lorem ipsum dolor avec Lorem ipsum dolor avec.',
}}
/>
</Tab>

<Tab title="API">
<AutoPropsApi component={Popover} />
</Tab>

<Tab title="Example">
<StoryContainer>
<Title as="h3">Popover</Title>
<p>
Here you can check a simple implamentation using SnackBar component.
</p>

<Row>
<Col xsmall={4} small={4} medium={6}>
<SimpleHighlight>{PopoverExample.code}</SimpleHighlight>
</Col>
<Col xsmall={4} small={4} medium={6}>
<PopoverExample text="Popover text">
Popover action
</PopoverExample>
</Col>
</Row>
</StoryContainer>
</Tab>
</TabbedView>
</>
));
32 changes: 32 additions & 0 deletions stories/Popover/examples/PopoverExample.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import Popover from '../../../components/Popover';

class PopoverExample extends React.Component {
constructor() {
super();

this.state = {
// showSnackBar: false,
};
}

// openSnackBar = () => this.setState({ showSnackBar: true });

// closeSnackBar = () => this.setState({ showSnackBar: false });

// actionCallback = () => this.closeSnackBar();

render() {
return (
<>
<Popover text="Popover text">popover here</Popover>
</>
);
}
}

PopoverExample.code = `
`;

export default PopoverExample;

0 comments on commit 1c65136

Please sign in to comment.