Web: added dropdown functionality for Link component

This commit is contained in:
Daniil Senkiv 2019-07-09 13:30:58 +03:00
parent 1ad03ec6d8
commit 4aa656d3c7
3 changed files with 135 additions and 14 deletions

View File

@ -1,6 +1,6 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import { Link } from 'asc-web-components';
import { Link, DropDownItem } from 'asc-web-components';
import { Container, Row, Col } from 'reactstrap';
const rowStyle = {
@ -33,7 +33,20 @@ storiesOf('Components|Link', module)
<Col>
<Link type = "action" color = "black" isBold = {true} text = 'Bold black action link' />
</Col>
<Col><Link type = "action" color = "black" dropdownType = 'alwaysDotted' text = 'Simple dropdown' /></Col>
<Col>
<Link type = "action" color = "black" dropdownType = 'alwaysDotted' text = 'Simple dropdown'>
<DropDownItem
key= 'key1'
onClick={() => console.log('Base button clicked')}
label='Base button'
/>
<DropDownItem
key= 'key2'
onClick={() => console.log('Base button2 clicked')}
label='Base button2'
/>
</Link>
</Col>
</Row>
<Row style={rowStyle}>
<Col>
@ -42,7 +55,37 @@ storiesOf('Components|Link', module)
<Col>
<Link type = "action" color = "black" text = 'Black action link' />
</Col>
<Col> <Link type = "action" color = "gray" dropdownType = 'appearDottedAfterHover' text = 'Gray dropdown and dotted appear after hover' /></Col>
<Col>
<Link type = "action" color = "gray" dropdownType = 'appearDottedAfterHover' text = 'Gray dropdown and dotted appear after hover'>
<DropDownItem
key= 'key1'
onClick={() => console.log('Base button clicked')}
label='Base button'
/>
<DropDownItem
key= 'key2'
onClick={() => console.log('Base button2 clicked')}
label='Base button2'
/>
<DropDownItem
key= 'key3'
isSeparator = {true}
/>
<DropDownItem
key= 'key4'
onClick={() => console.log('Base button3 clicked')}
label='Base button3'
/>
<DropDownItem
key= 'key5'
onClick={() => console.log('Base button4 clicked')}
label='Base button4'
/>
</Link>
</Col>
</Row>
<Row style={rowStyle}>
<Col>

View File

@ -1,10 +1,11 @@
import React from 'react';
import { storiesOf } from '@storybook/react';
import { Link, DropDown } from 'asc-web-components';
import { Link, DropDownItem } from 'asc-web-components';
import Readme from './README.md';
import {text, boolean, withKnobs, select, number } from '@storybook/addon-knobs/react';
import withReadme from 'storybook-readme/with-readme';
import Section from '../../../.storybook/decorators/section';
import {Col} from 'reactstrap';
const type = ['action', 'page'];
const colors = ['black', 'gray', 'blue'];
@ -16,6 +17,28 @@ function clickActionLink(e) {
console.log('Clicked action link', e);
}
const dropdownItems = [
{
key: 'key1',
label: 'Button 1',
onClick: () => console.log('Button1 action'),
},
{
key: 'key2',
label: 'Button 2',
onClick: () => console.log('Button2 action'),
},
{
key: 'key3',
isSeparator: true
},
{
key: 'key4',
label: 'Button 3',
onClick: () => console.log('Button2 action'),
},
];
storiesOf('Components|Link', module)
.addDecorator(withKnobs)
.addDecorator(withReadme(Readme))
@ -27,6 +50,7 @@ const userProps = linkType === "action" ? {
} : {};
return (
<Section>
<Col>
<Link
type={linkType}
color={select('color', colors, 'black')}
@ -40,8 +64,19 @@ return (
isSemitransparent={boolean('isSemitransparent', false)}
text={text('text', 'Simple link')}
{...userProps}
>
{dropdownItems.map(dropdownItem =>{
return (
<DropDownItem
key={dropdownItem.key}
isSeparator={dropdownItem.isSeparator}
onClick={dropdownItem.onClick}
label={dropdownItem.label}
/>
);
})}
</Link>
</Col>
</Section>
);
});

View File

@ -2,8 +2,10 @@ import React, {useState, useRef, useEffect} from 'react';
import styled, { css } from 'styled-components';
import PropTypes from 'prop-types';
import { Icons } from '../icons'
import DropDown from '../drop-down'
const SimpleLink = ({ rel, isBold, fontSize, isTextOverflow, isHovered, isSemitransparent, type, color, text, target, dropdownType, ...props }) => <a {...props}>{text}</a>;
const ClearCaret = ({ rel, isBold, fontSize, isTextOverflow, isHovered, type, color, text, target, dropdownType, ...props }) => <Caret {...props}/>;
const getDropdownColor = color => {
switch (color) {
@ -43,7 +45,9 @@ const dottedCss = css`
border-bottom: 1px dotted;
`;
const Caret = styled(Icons.ExpanderDownIcon)`
const Caret = styled(Icons.ExpanderDownIcon).attrs((props) => ({
isSemitransparent: props.isSemitransparent
}))`
width: 10px;
margin-left: 5px;
margin-top: -4px;
@ -111,16 +115,55 @@ ${props => (props.isTextOverflow &&
`;
const useOuterClickNotifier = (onOuterClick, ref) => {
useEffect(() => {
const handleClick = (e) => !ref.current.contains(e.target) && onOuterClick(e);
if (ref.current) {
document.addEventListener("click", handleClick);
}
return () => document.removeEventListener("click", handleClick);
},
[onOuterClick, ref]
);
}
const Link = props => {
let isDropdown;
const [isHovered, toggle] = useState(false);
const [isOpen, toggleDropdown] = useState(0);
const dropMenu = <DropDown isOpen={isOpen} {...props}>
{props.children}
</DropDown>;
const ref = useRef(null);
props.dropdownType != 'none' ? isDropdown = true : isDropdown = false;
function stopAction(e) {
if (props.href === ''){
e.preventDefault();
}
}
useOuterClickNotifier((e) => toggleDropdown(false), ref);
return (
<span
<span ref={ref}
onMouseEnter={() => {props.dropdownType === 'appearDottedAfterHover' && toggle(!isHovered)}}
onMouseLeave={() => {props.dropdownType === 'appearDottedAfterHover' && toggle(!isHovered)}}>
<StyledLink {...props} />
{(props.dropdownType === 'alwaysDotted' || (isHovered && props.dropdownType === 'appearDottedAfterHover')) && <Caret {...props} size='small' isfill={true} color={getDropdownColor(props.color)} /> }
<StyledLink {...props} onClick={
isDropdown ?
() => { toggleDropdown(!isOpen) }
: stopAction}/>
{(props.dropdownType === 'alwaysDotted' || (isHovered && props.dropdownType === 'appearDottedAfterHover')) && <ClearCaret {...props} size='small' isfill={true} color={getDropdownColor(props.color)} /> }
{isDropdown && dropMenu }
</span>
);
}