diff --git a/src/components/Icon/Icon.react.js b/src/components/Icon/Icon.react.js index bcaeb4fb..4b3ab321 100644 --- a/src/components/Icon/Icon.react.js +++ b/src/components/Icon/Icon.react.js @@ -3,7 +3,12 @@ import * as React from "react"; import cn from "classnames"; +import type { MouseEvents, PointerEvents, FocusEvents } from "../../"; + type Props = {| + ...MouseEvents, + ...PointerEvents, + ...FocusEvents, +className?: string, /** * Should this icon be rendered within an tag @@ -40,6 +45,13 @@ function Icon({ isAriaHidden, payment, flag, + onClick, + onMouseEnter, + onMouseLeave, + onPointerEnter, + onPointerLeave, + onFocus, + onBlur, }: Props): React.Node { const prefix = (payment && "payment") || (flag && "flag") || prefixFromProps; const classes = cn( @@ -55,10 +67,20 @@ function Icon({ } : null; + const eventProps = { + onClick, + onMouseEnter, + onMouseLeave, + onPointerEnter, + onPointerLeave, + onFocus, + onBlur, + }; + return !link ? ( - + ) : ( - + ); diff --git a/src/components/Tag/Tag.react.js b/src/components/Tag/Tag.react.js index cc252786..6a3809f6 100644 --- a/src/components/Tag/Tag.react.js +++ b/src/components/Tag/Tag.react.js @@ -5,16 +5,23 @@ import cn from "classnames"; import TagList from "./TagList.react"; import TagAddOn from "./TagAddOn.react"; +import type { MouseEvents, PointerEvents, FocusEvents } from "../../"; + type PropsForAll = {| + ...MouseEvents, + ...PointerEvents, + ...FocusEvents, +children?: React.Node, +className?: string, +rounded?: boolean, +color?: string, +avatar?: string, +remove?: boolean, + +onRemoveClick?: Function, +addOn?: React.Node, +addOnIcon?: string, +addOnColor?: string, + +onAddOnClick?: Function, |}; type DefaultProps = {| @@ -35,69 +42,118 @@ type ReactRouterProps = {| type Props = DefaultProps | LinkComponentProps | ReactRouterProps; -function Tag(props: Props): React.Node { - const { - children, - className, - rounded, - color = "", - avatar, - remove, - addOn, - addOnIcon, - addOnColor, - } = props; - const classes = cn( - { - tag: true, - expanded: true, - "tag-rounded": rounded, - [`tag-${color}`]: color, - }, - className - ); - const childrenForAll = ( - - {avatar && ( - - )} - {children} - {(addOn || addOnIcon) && ( - - {addOn} - - )} - {remove && } - - ); - - if (props.RootComponent) { - const { RootComponent: Component, to } = props; - return ( - - {childrenForAll} - +type State = {| + isDeleted: boolean, +|}; + +class Tag extends React.Component { + state = { + isDeleted: false, + }; + + static List = TagList; + static AddOn = TagAddOn; + + handleOnRemoveClick = (): void => { + this.setState(s => ({ + isDeleted: true, + })); + }; + + render(): React.Node { + const { + children, + className, + rounded, + color = "", + avatar, + remove, + addOn, + addOnIcon, + addOnColor, + onClick, + onMouseEnter, + onMouseLeave, + onPointerEnter, + onPointerLeave, + onFocus, + onBlur, + onRemoveClick, + onAddOnClick, + } = this.props; + + const classes = cn( + { + tag: true, + expanded: true, + "tag-rounded": rounded, + [`tag-${color}`]: color, + }, + className ); - } - if (props.link) { - const { href } = props; + const eventProps = { + onClick, + onMouseEnter, + onMouseLeave, + onPointerEnter, + onPointerLeave, + onFocus, + onBlur, + }; + + if (this.state.isDeleted) { + return null; + } + + const childrenForAll = ( + + {avatar && ( + + )} + {children} + {(addOn || addOnIcon) && ( + + {addOn} + + )} + {remove && onRemoveClick ? ( + + ) : ( + remove && ( + + ) + )} + + ); + + if (this.props.RootComponent) { + const { to } = this.props; + return ( + + {childrenForAll} + + ); + } + + if (this.props.link) { + const { href } = this.props; + return ( + + {childrenForAll} + + ); + } + return ( - + {childrenForAll} - + ); } - - return {childrenForAll}; } -Tag.displayName = "Tag"; - -Tag.List = TagList; -Tag.AddOn = TagAddOn; - export default Tag; diff --git a/src/components/Tag/TagAddOn.react.js b/src/components/Tag/TagAddOn.react.js index c675931d..e36b28a6 100644 --- a/src/components/Tag/TagAddOn.react.js +++ b/src/components/Tag/TagAddOn.react.js @@ -4,7 +4,12 @@ import * as React from "react"; import cn from "classnames"; import { Icon } from "../"; +import type { MouseEvents, PointerEvents, FocusEvents } from "../../"; + type PropsForAll = {| + ...MouseEvents, + ...PointerEvents, + ...FocusEvents, +children?: React.Node, +className?: string, +icon?: string, @@ -17,7 +22,6 @@ type PropsForLink = {| ...PropsForAll, link: true, +href?: string, - +onClick?: (event: SyntheticMouseEvent) => mixed, |}; type PropsForReactRouter = {| @@ -29,9 +33,32 @@ type PropsForReactRouter = {| type Props = DefaultProps | PropsForLink | PropsForReactRouter; function TagAddOn(props: Props): React.Node { - const { children, className, icon, color = "" } = props; + const { + children, + className, + icon, + color = "", + onClick, + onMouseEnter, + onMouseLeave, + onPointerEnter, + onPointerLeave, + onFocus, + onBlur, + } = props; + const classes = cn("tag-addon", { [`tag-${color}`]: color }, className); + const eventProps = { + onClick, + onMouseEnter, + onMouseLeave, + onPointerEnter, + onPointerLeave, + onFocus, + onBlur, + }; + const childrenForAll = ( {icon && } @@ -40,9 +67,9 @@ function TagAddOn(props: Props): React.Node { ); if (props.link) { - const { href, onClick } = props; + const { href } = props; return ( - + {childrenForAll} ); @@ -50,10 +77,18 @@ function TagAddOn(props: Props): React.Node { if (props.RootComponent) { const { RootComponent: Component, to } = props; - return {childrenForAll}; + return ( + + {childrenForAll} + + ); } - return {childrenForAll}; + return ( + + {childrenForAll} + + ); } TagAddOn.displayName = "Tag.AddOn";