From 1c65136422e6f94310edac8041884ae4f60d584e Mon Sep 17 00:00:00 2001 From: Raphael Oliveira Date: Tue, 9 Apr 2019 17:15:48 -0300 Subject: [PATCH] feat(Popover): implement dynamin colors and new props --- components/Popover/Popover.jsx | 91 ++++++++++++++----- components/Popover/Popover.unit.test.jsx | 4 +- .../__snapshots__/Popover.unit.test.jsx.snap | 2 +- stories/Popover/Popover.story.jsx | 65 ++++++++++--- stories/Popover/examples/PopoverExample.jsx | 32 +++++++ 5 files changed, 157 insertions(+), 37 deletions(-) create mode 100644 stories/Popover/examples/PopoverExample.jsx diff --git a/components/Popover/Popover.jsx b/components/Popover/Popover.jsx index 6aa9f3026..d8582eb43 100644 --- a/components/Popover/Popover.jsx +++ b/components/Popover/Popover.jsx @@ -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; @@ -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); @@ -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 ( - this.isVisible(true)} - onMouseLeave={() => this.isVisible(false)} - > - - - {text} {onClick} - - - {children} + + + {text} + this.isVisible(false)} /> + + this.isVisible(true)}> + {children} + ); } @@ -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; diff --git a/components/Popover/Popover.unit.test.jsx b/components/Popover/Popover.unit.test.jsx index e1241feda..881faf395 100644 --- a/components/Popover/Popover.unit.test.jsx +++ b/components/Popover/Popover.unit.test.jsx @@ -8,9 +8,7 @@ describe('Popover component ', () => { describe('All positions', () => { it('Should match the snapshot when place is top', () => { const popover = mount( - - Hover Me - , + popover here, ); expect(popover.html()).toMatchSnapshot(); }); diff --git a/components/Popover/__snapshots__/Popover.unit.test.jsx.snap b/components/Popover/__snapshots__/Popover.unit.test.jsx.snap index 99ddcfcf6..f37fba1f2 100644 --- a/components/Popover/__snapshots__/Popover.unit.test.jsx.snap +++ b/components/Popover/__snapshots__/Popover.unit.test.jsx.snap @@ -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`] = `"
This is a hint
Hover Me
"`; +exports[`Popover component All positions Should match the snapshot when place is top 1`] = `"
This is a hint
popover here
"`; diff --git a/stories/Popover/Popover.story.jsx b/stories/Popover/Popover.story.jsx index 58db7568a..de50f9d52 100644 --- a/stories/Popover/Popover.story.jsx +++ b/stories/Popover/Popover.story.jsx @@ -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', () => ( - + <> + + A Popover can be used to display some content on top of another + + + + Popover me

, + text: + 'Lorem ipsum dolor avec Lorem ipsum dolor avec Lorem ipsum dolor avec Lorem ipsum dolor avec.', + }} + /> +
+ + + + + + + + Popover +

+ Here you can check a simple implamentation using SnackBar component. +

+ + + + {PopoverExample.code} + + + + Popover action + + + +
+
+
+ )); diff --git a/stories/Popover/examples/PopoverExample.jsx b/stories/Popover/examples/PopoverExample.jsx new file mode 100644 index 000000000..6c74ab93a --- /dev/null +++ b/stories/Popover/examples/PopoverExample.jsx @@ -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 here + + ); + } +} + +PopoverExample.code = ` + +`; + +export default PopoverExample;