Web: added dropdown functionality for Link component
This commit is contained in:
parent
1ad03ec6d8
commit
4aa656d3c7
@ -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>
|
||||
|
@ -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>
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -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>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user