Skip to content

Commit

Permalink
feat(eventBroker): eventBroker acts in the bubbling phase (#489)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mishnya authored Jan 25, 2023
1 parent f22384b commit ef2c901
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 42 deletions.
10 changes: 5 additions & 5 deletions src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ const ButtonWithHandlers = React.forwardRef<HTMLElement, ButtonProps>(function B
},
ref,
) {
const handleClick = React.useCallback(
(event: React.MouseEvent<HTMLButtonElement | HTMLAnchorElement>) => {
const handleClickCapture = React.useCallback(
(event: React.SyntheticEvent) => {
eventBroker.publish({
componentId: 'Button',
eventId: 'click',
Expand All @@ -115,15 +115,15 @@ const ButtonWithHandlers = React.forwardRef<HTMLElement, ButtonProps>(function B
view,
},
});
onClick?.(event);
},
[view, onClick],
[view],
);

const commonProps = {
title,
tabIndex,
onClick: handleClick,
onClick,
onClickCapture: handleClickCapture,
onMouseEnter,
onMouseLeave,
onFocus,
Expand Down
16 changes: 11 additions & 5 deletions src/components/Link/Link.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -25,7 +25,7 @@ export interface LinkProps extends DOMProps, QAProps {

const b = block('link');

const PureLink = React.forwardRef<HTMLAnchorElement | HTMLSpanElement, LinkProps>(function Link(
export const Link = React.forwardRef<HTMLElement, LinkProps>(function Link(
{
view = 'normal',
href,
Expand All @@ -44,10 +44,19 @@ const PureLink = React.forwardRef<HTMLAnchorElement | HTMLSpanElement, LinkProps
},
ref,
) {
const handleClickCapture = React.useCallback((event: React.SyntheticEvent) => {
eventBroker.publish({
componentId: 'Link',
eventId: 'click',
domEvent: event,
});
}, []);

const commonProps = {
title,
children,
onClick,
onClickCapture: handleClickCapture,
onFocus,
onBlur,
id,
Expand Down Expand Up @@ -80,6 +89,3 @@ const PureLink = React.forwardRef<HTMLAnchorElement | HTMLSpanElement, LinkProps
);
}
});

PureLink.displayName = 'Link';
export const Link = withEventBrokerDomHandlers(PureLink, ['onClick'], {componentId: 'Link'});
6 changes: 4 additions & 2 deletions src/components/List/components/ListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export class ListItem<T = unknown> extends React.Component<ListItemProps<T>> {
)}
style={style}
onClick={item.disabled ? undefined : this.onClick}
onClickCapture={item.disabled ? undefined : this.onClickCapture}
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}
ref={this.ref}
Expand All @@ -75,12 +76,13 @@ export class ListItem<T = unknown> extends React.Component<ListItemProps<T>> {
return <div className={b('item-content')}>{renderItem(item, active, itemIndex)}</div>;
}

private onClick: React.MouseEventHandler<HTMLDivElement> = (event) => {
private onClick = () => this.props.onClick?.(this.props.item, this.props.itemIndex);

private onClickCapture: React.MouseEventHandler<HTMLDivElement> = (event) => {
ListItem.publishEvent({
domEvent: event,
eventId: 'click',
});
this.props.onClick?.(this.props.item, this.props.itemIndex);
};

private onMouseEnter = () =>
Expand Down
19 changes: 12 additions & 7 deletions src/components/Menu/MenuItem.tsx
Original file line number Diff line number Diff line change
@@ -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');

Expand All @@ -21,7 +21,7 @@ export interface MenuItemProps extends DOMProps, QAProps {
children?: React.ReactNode;
}

const PureMenuItem = React.forwardRef<HTMLLIElement, MenuItemProps>(function MenuItem(
export const MenuItem = React.forwardRef<HTMLElement, MenuItemProps>(function MenuItem(
{
icon,
title,
Expand All @@ -40,9 +40,18 @@ const PureMenuItem = React.forwardRef<HTMLLIElement, MenuItemProps>(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),
Expand Down Expand Up @@ -81,12 +90,8 @@ const PureMenuItem = React.forwardRef<HTMLLIElement, MenuItemProps>(function Men
}

return (
<li ref={ref} className={b('list-item')}>
<li ref={ref as React.ForwardedRef<HTMLLIElement>} className={b('list-item')}>
{item}
</li>
);
});

export const MenuItem = withEventBrokerDomHandlers(PureMenuItem, ['onClick'], {
componentId: 'MenuItem',
});
7 changes: 3 additions & 4 deletions src/components/utils/useCheckbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function useCheckbox({
}
};

const handleClick = React.useCallback(
const handleClickCapture = React.useCallback(
(event: React.MouseEvent<HTMLInputElement> & {target: {checked?: boolean}}) => {
eventBroker.publish({
componentId: 'Checkbox',
Expand All @@ -58,9 +58,8 @@ export function useCheckbox({
checked: event.target.checked,
},
});
controlProps?.onClick?.(event);
},
[controlProps?.onClick],
[],
);

const inputProps: React.InputHTMLAttributes<HTMLInputElement> &
Expand All @@ -74,7 +73,7 @@ export function useCheckbox({
disabled,
type: 'checkbox',
onChange: handleChange,
onClick: handleClick,
onClickCapture: handleClickCapture,
defaultChecked: defaultChecked,
checked: inputChecked,
'aria-checked': inputAriaChecked,
Expand Down
26 changes: 8 additions & 18 deletions src/components/utils/useRadio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,6 @@ export function useRadio({
const handleRef = useForkRef(controlRef, innerControlRef);

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
eventBroker.publish({
componentId: 'Radio',
eventId: 'click',
domEvent: event,
});

if (!isControlled) {
setCheckedState(event.target.checked);
}
Expand All @@ -47,17 +41,13 @@ export function useRadio({
}
};

const handleClick = React.useCallback(
(event: React.MouseEvent<HTMLInputElement>) => {
eventBroker.publish({
componentId: 'Radio',
eventId: 'click',
domEvent: event,
});
controlProps?.onClick?.(event);
},
[controlProps?.onClick],
);
const onChangeCapture = (event: React.ChangeEvent<HTMLInputElement>) => {
eventBroker.publish({
componentId: 'Radio',
eventId: 'click',
domEvent: event,
});
};

const inputProps: React.InputHTMLAttributes<HTMLInputElement> &
React.RefAttributes<HTMLInputElement> = {
Expand All @@ -70,7 +60,7 @@ export function useRadio({
disabled,
type: 'radio',
onChange: handleChange,
onClick: handleClick,
onChangeCapture: onChangeCapture,
checked,
defaultChecked: defaultChecked,
'aria-checked': isChecked,
Expand Down
2 changes: 1 addition & 1 deletion src/components/utils/withEventBrokerDomHandlers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<SyntheticEvent>}>,
Expand Down

0 comments on commit ef2c901

Please sign in to comment.