[MM-58402] Migrate tooltips of 'components/emoji_picker_skin.tsx' & 'components/emoji_picker_category' to WithTooltip (#27146)

This commit is contained in:
M-ZubairAhmed 2024-06-03 18:03:36 +00:00 committed by GitHub
parent 76774e61b6
commit 11c2951afa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 92 additions and 40 deletions

View File

@ -0,0 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`EmojiPickerCategory should match snapshot 1`] = `
<DocumentFragment>
<a
aria-label="categoryId"
class="emoji-picker__category"
href="#"
>
<i
class="categoryClass"
/>
</a>
</DocumentFragment>
`;

View File

@ -0,0 +1,58 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {act, screen} from '@testing-library/react';
import React from 'react';
import type {Category} from 'components/emoji_picker/types';
import {renderWithContext, userEvent} from 'tests/react_testing_utils';
import EmojiPickerCategory from './emoji_picker_category';
import type {Props} from './emoji_picker_category';
const categoryMessage = 'categoryMessage';
const defaultProps: Props = {
category: {
className: 'categoryClass',
emojiIds: ['emojiId'],
id: 'categoryId',
message: categoryMessage,
name: 'recent',
} as Category,
categoryRowIndex: 0,
selected: false,
enable: true,
onClick: jest.fn(),
};
describe('EmojiPickerCategory', () => {
test('should match snapshot', () => {
const {asFragment} = renderWithContext(<EmojiPickerCategory {...defaultProps}/>);
expect(asFragment()).toMatchSnapshot();
});
test('should be disabled when prop is passed disabled', () => {
const props = {
...defaultProps,
enable: false,
};
renderWithContext(<EmojiPickerCategory {...props}/>);
// TODO: Change when we actually disabled the element when enable is false
expect(screen.getByRole('link')).toHaveClass('emoji-picker__category disable');
});
test('should have tooltip on hover', async () => {
renderWithContext(<EmojiPickerCategory {...defaultProps}/>);
await act(async () => {
const emojiPickerCategory = screen.getByRole('link');
userEvent.hover(emojiPickerCategory);
await new Promise((resolve) => setTimeout(resolve, 1000));
});
expect(screen.getByText(categoryMessage)).toBeVisible();
});
});

View File

@ -8,12 +8,9 @@ import {FormattedMessage} from 'react-intl';
import type {EmojiCategory} from '@mattermost/types/emojis';
import type {Category, CategoryOrEmojiRow} from 'components/emoji_picker/types';
import OverlayTrigger from 'components/overlay_trigger';
import Tooltip from 'components/tooltip';
import WithTooltip from 'components/with_tooltip';
import {Constants} from 'utils/constants';
interface Props {
export interface Props {
category: Category;
categoryRowIndex: CategoryOrEmojiRow['index'];
selected: boolean;
@ -38,20 +35,14 @@ function EmojiPickerCategory({category, categoryRowIndex, selected, enable, onCl
});
return (
<OverlayTrigger
trigger={['hover', 'focus']}
delayShow={Constants.OVERLAY_TIME_DELAY}
<WithTooltip
id={`emojiPickerCategoryTooltip-${category.name}`}
placement='bottom'
overlay={
<Tooltip
id='skinTooltip'
className='emoji-tooltip'
>
<FormattedMessage
id={`emoji_picker.${category.name}`}
defaultMessage={category.message}
/>
</Tooltip>
title={
<FormattedMessage
id={`emoji_picker.${category.name}`}
defaultMessage={category.message}
/>
}
>
<a
@ -62,7 +53,7 @@ function EmojiPickerCategory({category, categoryRowIndex, selected, enable, onCl
>
<i className={category.className}/>
</a>
</OverlayTrigger>
</WithTooltip>
);
}

View File

@ -9,11 +9,9 @@ import {CSSTransition} from 'react-transition-group';
import {CloseIcon} from '@mattermost/compass-icons/components';
import OverlayTrigger from 'components/overlay_trigger';
import Tooltip from 'components/tooltip';
import WithTooltip from 'components/with_tooltip';
import imgTrans from 'images/img_trans.gif';
import {Constants} from 'utils/constants';
import * as Emoji from 'utils/emoji';
const skinsList = [
@ -27,7 +25,7 @@ const skinsList = [
const skinToneEmojis = new Map(skinsList.map((pair) => [pair[1], Emoji.Emojis[Emoji.EmojiIndicesByAlias.get(pair[0])!]]));
type Props = {
export type Props = {
userSkinTone: string;
onSkinSelected: (skin: string) => void;
intl: IntlShape;
@ -117,31 +115,20 @@ export class EmojiPickerSkin extends React.PureComponent<Props, State> {
</>
);
}
collapsed() {
const emoji = skinToneEmojis.get(this.props.userSkinTone)!;
const spriteClassName = classNames('emojisprite', `emoji-category-${emoji.category}`, `emoji-${emoji.unified.toLowerCase()}`);
const spriteClassName = classNames('emojisprite', `emoji-category-${emoji?.category}`, `emoji-${emoji?.unified.toLowerCase()}`);
const expandButtonLabel = this.props.intl.formatMessage({
id: 'emoji_picker.skin_tone',
defaultMessage: 'Skin tone',
});
const tooltip = (
<Tooltip
id='skinTooltip'
className='emoji-tooltip'
>
<span>
{expandButtonLabel}
</span>
</Tooltip>
);
return (
<OverlayTrigger
trigger={['hover', 'focus']}
delayShow={Constants.OVERLAY_TIME_DELAY}
<WithTooltip
id='emojiPickerSkinTooltip'
placement='top'
overlay={tooltip}
title={expandButtonLabel}
>
<button
data-testid={`skin-picked-${this.props.userSkinTone}`}
@ -155,7 +142,7 @@ export class EmojiPickerSkin extends React.PureComponent<Props, State> {
className={spriteClassName}
/>
</button>
</OverlayTrigger>
</WithTooltip>
);
}

View File

@ -1,6 +1,7 @@
@charset 'UTF-8';
.tooltip {
z-index: 2000;
max-width: 220px;
font-family: inherit;
pointer-events: none;