Skip to content

Commit

Permalink
Masterbar: fix invalid HTML markup (#98510)
Browse files Browse the repository at this point in the history
* Reorganize and simplify markup:
- avoid nesting a inside button: render one or the other
- always render wrapper div for consistency
- render subitems as siblings of the parent menuitem (and not nested)
- less forks in the logic
- tweak styles to follow the new markup

* Add back subitems, tweak CSS selectors to match new markup

* Remove code comments

* Revert to && instead of ternary

* Keep submenu opened while hovering
  • Loading branch information
ciampo authored Jan 21, 2025
1 parent 9b8a087 commit ff8b5a2
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 133 deletions.
56 changes: 16 additions & 40 deletions client/layout/masterbar/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ class MasterbarItem extends Component< MasterbarItemProps > {
isOpenForNonMouseFlow: false,
};

componentButtonRef = React.createRef< HTMLButtonElement >();
componentDivRef = React.createRef< HTMLDivElement >();
wrapperRef = React.createRef< HTMLDivElement >();

_preloaded = false;

Expand Down Expand Up @@ -191,12 +190,8 @@ class MasterbarItem extends Component< MasterbarItemProps > {
}

// Check refs to see if the touch event started inside our component, if it didn't, close the menu.
const isInComponentButtonRef = this.componentButtonRef.current?.contains(
event.target as Node
);
const isInComponentDivRef = this.componentDivRef.current?.contains( event.target as Node );

if ( ! isInComponentButtonRef && ! isInComponentDivRef ) {
const isInWrapper = this.wrapperRef.current?.contains( event.target as Node );
if ( ! isInWrapper ) {
this.setState( { isOpenForNonMouseFlow: false } );
}
};
Expand All @@ -221,49 +216,30 @@ class MasterbarItem extends Component< MasterbarItemProps > {
disabled: this.props.disabled,
};

if ( this.props.url && ! this.props.subItems ) {
return (
const MenuItem = ( props: React.HTMLAttributes< HTMLElement > ) =>
this.props.url ? (
<a
{ ...attributes }
href={ this.props.url }
ref={ this.props.innerRef as LegacyRef< HTMLAnchorElement > }
>
{ this.renderChildren() }
</a>
{ ...props }
/>
) : (
<button ref={ this.props.innerRef as LegacyRef< HTMLButtonElement > } { ...props } />
);
}

if ( this.props.url && this.props.subItems ) {
return (
<button
{ ...attributes }
ref={ this.componentButtonRef }
onKeyDown={ this.toggleMenuByKey }
>
<a
href={ this.props.url }
ref={ this.props.innerRef as LegacyRef< HTMLAnchorElement > }
onTouchEnd={ this.toggleMenuByTouch }
tabIndex={ -1 }
>
{ this.renderChildren() }
</a>
{ this.renderSubItems() }
</button>
);
}

return (
<div className={ this.props.wrapperClassName } ref={ this.componentDivRef }>
<button
<div
className={ clsx( 'masterbar__item-wrapper', this.props.wrapperClassName ) }
ref={ this.wrapperRef }
>
<MenuItem
{ ...attributes }
ref={ this.props.innerRef as LegacyRef< HTMLButtonElement > }
onKeyDown={ this.props.subItems && this.toggleMenuByKey }
onTouchEnd={ this.props.subItems && this.toggleMenuByTouch }
>
{ this.renderChildren() }
{ this.renderSubItems() }
</button>
</MenuItem>
{ this.renderSubItems() }
</div>
);
}
Expand Down
Loading

0 comments on commit ff8b5a2

Please sign in to comment.