From 8da281d17172343b6bd28567a351a3f66c7d97f5 Mon Sep 17 00:00:00 2001 From: Mishnya Date: Fri, 20 Jan 2023 12:47:16 +0300 Subject: [PATCH] feat(eventBroker): eventBroker acts in the bubbling phase --- src/components/Button/Button.tsx | 10 +++---- src/components/Link/Link.tsx | 16 ++++++++---- src/components/List/components/ListItem.tsx | 6 +++-- src/components/Menu/MenuItem.tsx | 19 +++++++++----- src/components/utils/useCheckbox.ts | 7 +++-- src/components/utils/useRadio.ts | 26 ++++++------------- .../utils/withEventBrokerDomHandlers.tsx | 2 +- 7 files changed, 44 insertions(+), 42 deletions(-) diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index f504f828e8..7d9ba1eb4a 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -104,8 +104,8 @@ const ButtonWithHandlers = React.forwardRef(function B }, ref, ) { - const handleClick = React.useCallback( - (event: React.MouseEvent) => { + const handleClickCapture = React.useCallback( + (event: React.SyntheticEvent) => { eventBroker.publish({ componentId: 'Button', eventId: 'click', @@ -115,15 +115,15 @@ const ButtonWithHandlers = React.forwardRef(function B view, }, }); - onClick?.(event); }, - [view, onClick], + [view], ); const commonProps = { title, tabIndex, - onClick: handleClick, + onClick, + onClickCapture: handleClickCapture, onMouseEnter, onMouseLeave, onFocus, diff --git a/src/components/Link/Link.tsx b/src/components/Link/Link.tsx index dc3d3b3191..3a50169ee6 100644 --- a/src/components/Link/Link.tsx +++ b/src/components/Link/Link.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {DOMProps, QAProps} from '../types'; import {block} from '../utils/cn'; -import {withEventBrokerDomHandlers} from '../utils/withEventBrokerDomHandlers'; +import {eventBroker} from '../utils/event-broker'; import './Link.scss'; @@ -25,7 +25,7 @@ export interface LinkProps extends DOMProps, QAProps { const b = block('link'); -const PureLink = React.forwardRef(function Link( +export const Link = React.forwardRef(function Link( { view = 'normal', href, @@ -44,10 +44,19 @@ const PureLink = React.forwardRef { + eventBroker.publish({ + componentId: 'Link', + eventId: 'click', + domEvent: event, + }); + }, []); + const commonProps = { title, children, onClick, + onClickCapture: handleClickCapture, onFocus, onBlur, id, @@ -80,6 +89,3 @@ const PureLink = React.forwardRef extends React.Component> { )} style={style} onClick={item.disabled ? undefined : this.onClick} + onClickCapture={item.disabled ? undefined : this.onClickCapture} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} ref={this.ref} @@ -75,12 +76,13 @@ export class ListItem extends React.Component> { return
{renderItem(item, active, itemIndex)}
; } - private onClick: React.MouseEventHandler = (event) => { + private onClick = () => this.props.onClick?.(this.props.item, this.props.itemIndex); + + private onClickCapture: React.MouseEventHandler = (event) => { ListItem.publishEvent({ domEvent: event, eventId: 'click', }); - this.props.onClick?.(this.props.item, this.props.itemIndex); }; private onMouseEnter = () => diff --git a/src/components/Menu/MenuItem.tsx b/src/components/Menu/MenuItem.tsx index 43c5211dad..32ba808e28 100644 --- a/src/components/Menu/MenuItem.tsx +++ b/src/components/Menu/MenuItem.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {block} from '../utils/cn'; import {DOMProps, QAProps} from '../types'; -import {withEventBrokerDomHandlers} from '../utils/withEventBrokerDomHandlers'; +import {eventBroker} from '../utils/event-broker'; const b = block('menu'); @@ -21,7 +21,7 @@ export interface MenuItemProps extends DOMProps, QAProps { children?: React.ReactNode; } -const PureMenuItem = React.forwardRef(function MenuItem( +export const MenuItem = React.forwardRef(function MenuItem( { icon, title, @@ -40,9 +40,18 @@ const PureMenuItem = React.forwardRef(function Men }, ref, ) { + const handleClickCapture = React.useCallback((event: React.SyntheticEvent) => { + eventBroker.publish({ + componentId: 'MenuItem', + eventId: 'click', + domEvent: event, + }); + }, []); + const commonProps = { title, onClick: disabled ? undefined : onClick, + onClickCapture: disabled ? undefined : handleClickCapture, style, tabIndex: disabled ? -1 : 0, className: b('item', {disabled, active, theme}, className), @@ -81,12 +90,8 @@ const PureMenuItem = React.forwardRef(function Men } return ( -
  • +
  • } className={b('list-item')}> {item}
  • ); }); - -export const MenuItem = withEventBrokerDomHandlers(PureMenuItem, ['onClick'], { - componentId: 'MenuItem', -}); diff --git a/src/components/utils/useCheckbox.ts b/src/components/utils/useCheckbox.ts index 7a5dc10c81..217afa3170 100644 --- a/src/components/utils/useCheckbox.ts +++ b/src/components/utils/useCheckbox.ts @@ -48,7 +48,7 @@ export function useCheckbox({ } }; - const handleClick = React.useCallback( + const handleClickCapture = React.useCallback( (event: React.MouseEvent & {target: {checked?: boolean}}) => { eventBroker.publish({ componentId: 'Checkbox', @@ -58,9 +58,8 @@ export function useCheckbox({ checked: event.target.checked, }, }); - controlProps?.onClick?.(event); }, - [controlProps?.onClick], + [], ); const inputProps: React.InputHTMLAttributes & @@ -74,7 +73,7 @@ export function useCheckbox({ disabled, type: 'checkbox', onChange: handleChange, - onClick: handleClick, + onClickCapture: handleClickCapture, defaultChecked: defaultChecked, checked: inputChecked, 'aria-checked': inputAriaChecked, diff --git a/src/components/utils/useRadio.ts b/src/components/utils/useRadio.ts index b95c565ba5..c99c37cc9f 100644 --- a/src/components/utils/useRadio.ts +++ b/src/components/utils/useRadio.ts @@ -28,12 +28,6 @@ export function useRadio({ const handleRef = useForkRef(controlRef, innerControlRef); const handleChange = (event: React.ChangeEvent) => { - eventBroker.publish({ - componentId: 'Radio', - eventId: 'click', - domEvent: event, - }); - if (!isControlled) { setCheckedState(event.target.checked); } @@ -47,17 +41,13 @@ export function useRadio({ } }; - const handleClick = React.useCallback( - (event: React.MouseEvent) => { - eventBroker.publish({ - componentId: 'Radio', - eventId: 'click', - domEvent: event, - }); - controlProps?.onClick?.(event); - }, - [controlProps?.onClick], - ); + const onChangeCapture = (event: React.ChangeEvent) => { + eventBroker.publish({ + componentId: 'Radio', + eventId: 'click', + domEvent: event, + }); + }; const inputProps: React.InputHTMLAttributes & React.RefAttributes = { @@ -70,7 +60,7 @@ export function useRadio({ disabled, type: 'radio', onChange: handleChange, - onClick: handleClick, + onChangeCapture: onChangeCapture, checked, defaultChecked: defaultChecked, 'aria-checked': isChecked, diff --git a/src/components/utils/withEventBrokerDomHandlers.tsx b/src/components/utils/withEventBrokerDomHandlers.tsx index 41a866a075..29c3a1527f 100644 --- a/src/components/utils/withEventBrokerDomHandlers.tsx +++ b/src/components/utils/withEventBrokerDomHandlers.tsx @@ -2,7 +2,7 @@ import React, {SyntheticEvent} from 'react'; import {eventBroker, EventBrokerData} from './event-broker'; import {getComponentName} from './getComponentName'; -type SupportedEvents = 'onClick'; +type SupportedEvents = 'onClick' | 'onClickCapture'; export function withEventBrokerDomHandlers< T extends Partial<{[k in SupportedEvents]: React.EventHandler}>,