MM-53999 Fix keyboard support for Menu components (#24282)
* Cherry-pick test changes from #24243 * Add required change from Saturn's PR to make reminder menu accessible * MM-53999 Flip provider order so that MUI props are passed * MM-53999 Pass MUI props through custom MenuItem components * Address feedback * Update snapshots
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
e48efdc5da
Коммит
e2a5293e2e
@@ -184,15 +184,6 @@ exports[`components/dot_menu/DotMenu should match snapshot, on Center 1`] = `
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Connect(ChannelPermissionGate)
|
||||
channelId=""
|
||||
permissions={
|
||||
Array [
|
||||
"add_reaction",
|
||||
]
|
||||
}
|
||||
teamId="team_id_1"
|
||||
/>
|
||||
<MenuItem
|
||||
data-testid="follow_post_thread_post_id_1"
|
||||
id="follow_post_thread_post_id_1"
|
||||
|
||||
@@ -508,12 +508,12 @@ export class DotMenuClass extends React.PureComponent<Props, State> {
|
||||
onClick={this.handleForwardMenuItemActivated}
|
||||
/>
|
||||
}
|
||||
<ChannelPermissionGate
|
||||
channelId={this.props.post.channel_id}
|
||||
teamId={this.props.teamId}
|
||||
permissions={[Permissions.ADD_REACTION]}
|
||||
>
|
||||
{Boolean(isMobile && !isSystemMessage && !this.props.isReadOnly && this.props.enableEmojiPicker) &&
|
||||
{Boolean(isMobile && !isSystemMessage && !this.props.isReadOnly && this.props.enableEmojiPicker) &&
|
||||
<ChannelPermissionGate
|
||||
channelId={this.props.post.channel_id}
|
||||
teamId={this.props.teamId}
|
||||
permissions={[Permissions.ADD_REACTION]}
|
||||
>
|
||||
<Menu.Item
|
||||
id={`post_reaction_${this.props.post.id}`}
|
||||
data-testid={`post_reaction_${this.props.post.id}`}
|
||||
@@ -526,8 +526,8 @@ export class DotMenuClass extends React.PureComponent<Props, State> {
|
||||
leadingElement={<EmoticonPlusOutlineIcon size={18}/>}
|
||||
onClick={this.handleAddReactionMenuItemActivated}
|
||||
/>
|
||||
}
|
||||
</ChannelPermissionGate>
|
||||
</ChannelPermissionGate>
|
||||
}
|
||||
{Boolean(
|
||||
!isSystemMessage &&
|
||||
this.props.isCollapsedThreadsEnabled &&
|
||||
|
||||
@@ -144,6 +144,10 @@ function PostReminderSubmenu(props: Props) {
|
||||
return (
|
||||
<Menu.SubMenu
|
||||
id={`remind_post_${props.post.id}`}
|
||||
menuAriaLabel={formatMessage({
|
||||
id: 'post_info.post_reminder.sub_menu.header',
|
||||
defaultMessage: 'Set a reminder for:',
|
||||
})}
|
||||
labels={
|
||||
<FormattedMessage
|
||||
id='post_info.post_reminder.menu'
|
||||
|
||||
@@ -226,32 +226,32 @@ export function Menu(props: Props) {
|
||||
return (
|
||||
<CompassDesignProvider theme={theme}>
|
||||
{renderMenuButton()}
|
||||
<MuiMenuStyled
|
||||
anchorEl={anchorElement}
|
||||
open={isMenuOpen}
|
||||
onClose={handleMenuClose}
|
||||
onClick={handleMenuClick}
|
||||
onKeyDown={handleMenuKeyDown}
|
||||
className={A11yClassNames.POPUP}
|
||||
width={props.menu.width}
|
||||
disableAutoFocusItem={disableAutoFocusItem} // This is not anti-pattern, see handleMenuButtonMouseDown
|
||||
MenuListProps={{
|
||||
id: props.menu.id,
|
||||
'aria-label': props.menu?.['aria-label'] ?? '',
|
||||
}}
|
||||
TransitionProps={{
|
||||
mountOnEnter: true,
|
||||
unmountOnExit: true,
|
||||
timeout: {
|
||||
enter: MENU_OPEN_ANIMATION_DURATION,
|
||||
exit: MENU_CLOSE_ANIMATION_DURATION,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<MenuContext.Provider value={providerValue}>
|
||||
<MenuContext.Provider value={providerValue}>
|
||||
<MuiMenuStyled
|
||||
anchorEl={anchorElement}
|
||||
open={isMenuOpen}
|
||||
onClose={handleMenuClose}
|
||||
onClick={handleMenuClick}
|
||||
onKeyDown={handleMenuKeyDown}
|
||||
className={A11yClassNames.POPUP}
|
||||
width={props.menu.width}
|
||||
disableAutoFocusItem={disableAutoFocusItem} // This is not anti-pattern, see handleMenuButtonMouseDown
|
||||
MenuListProps={{
|
||||
id: props.menu.id,
|
||||
'aria-label': props.menu?.['aria-label'] ?? '',
|
||||
}}
|
||||
TransitionProps={{
|
||||
mountOnEnter: true,
|
||||
unmountOnExit: true,
|
||||
timeout: {
|
||||
enter: MENU_OPEN_ANIMATION_DURATION,
|
||||
exit: MENU_CLOSE_ANIMATION_DURATION,
|
||||
},
|
||||
}}
|
||||
>
|
||||
{props.children}
|
||||
</MenuContext.Provider>
|
||||
</MuiMenuStyled>
|
||||
</MuiMenuStyled>
|
||||
</MenuContext.Provider>
|
||||
</CompassDesignProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -93,10 +93,19 @@ export interface Props extends MuiMenuItemProps {
|
||||
* To be used as a child of Menu component.
|
||||
* Checkout Compass's Menu Item(compass.mattermost.com) for terminology, styling and usage guidelines.
|
||||
*
|
||||
* @example
|
||||
* @example <caption>Using a menu in a component</caption>
|
||||
* <Menu.Container>
|
||||
* <Menu.Item/>
|
||||
* <Menu.Item/>
|
||||
* </Menu.Container>
|
||||
* @example <caption>Wrapping a menu item in another component</caption>
|
||||
* // Remember to pass all unused props into the Menu.Item to ensure MUI props for a11y are passed properly
|
||||
* const ConsoleLogItem = ({message, ...otherProps}) => ({
|
||||
* <Menu.Item
|
||||
* onClick={() => console.log(message)}
|
||||
* {...otherProps}
|
||||
* />
|
||||
* });
|
||||
*
|
||||
*/
|
||||
export function MenuItem(props: Props) {
|
||||
const {
|
||||
@@ -107,7 +116,7 @@ export function MenuItem(props: Props) {
|
||||
isLabelsRowLayout,
|
||||
children,
|
||||
onClick,
|
||||
...restProps
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
const menuContext = useContext(MenuContext);
|
||||
@@ -181,7 +190,7 @@ export function MenuItem(props: Props) {
|
||||
isLabelsRowLayout={isLabelsRowLayout}
|
||||
onKeyDown={handleClick}
|
||||
onMouseDown={handleClick}
|
||||
{...restProps}
|
||||
{...otherProps}
|
||||
>
|
||||
{leadingElement && <div className='leading-element'>{leadingElement}</div>}
|
||||
<div className='label-elements'>{labels}</div>
|
||||
@@ -240,7 +249,7 @@ const MenuItemStyled = styled(MuiMenuItem, {
|
||||
'&.Mui-focusVisible .label-elements>:last-child, &.Mui-focusVisible .label-elements>:first-child, &.Mui-focusVisible .label-elements>:only-child': {
|
||||
color: isDestructive && 'var(--button-color)',
|
||||
},
|
||||
'&.Mui-focusVisible .leading-element': {
|
||||
'&.Mui-focusVisible .leading-element, &.Mui-focusVisible .trailing-elements': {
|
||||
color: isDestructive && 'var(--button-color)',
|
||||
},
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ type Props = {
|
||||
|
||||
const CreateNewCategoryMenuItem = ({
|
||||
id,
|
||||
...otherProps
|
||||
}: Props) => {
|
||||
const dispatch = useDispatch();
|
||||
const handleCreateCategory = useCallback(() => {
|
||||
@@ -41,6 +42,7 @@ const CreateNewCategoryMenuItem = ({
|
||||
defaultMessage='Create New Category'
|
||||
/>
|
||||
)}
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -11,16 +11,17 @@ import {openModal} from 'actions/views/modals';
|
||||
import {ModalIdentifiers} from 'utils/constants';
|
||||
import MarkAsReadConfirmModal from './mark_as_read_confirm_modal';
|
||||
|
||||
type Props = ({
|
||||
type Props = {
|
||||
id: string;
|
||||
handleViewCategory: () => void;
|
||||
numChannels: number;
|
||||
})
|
||||
}
|
||||
|
||||
const MarkAsUnreadItem = ({
|
||||
id,
|
||||
handleViewCategory,
|
||||
numChannels,
|
||||
...otherProps
|
||||
}: Props) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
@@ -56,6 +57,7 @@ const MarkAsUnreadItem = ({
|
||||
defaultMessage='Mark category as read'
|
||||
/>
|
||||
)}
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
Ссылка в новой задаче
Block a user