Skip to content
This repository has been archived by the owner on Mar 13, 2024. It is now read-only.

Commit

Permalink
[GH-12457] Migrate 'components/widgets/menu' module and associated te…
Browse files Browse the repository at this point in the history
…sts to TypeScript (#4118)

* Fix Menu Group references.

* Migrate 'components/widgets/menu/menu_group.jsx' and associated tests to Typescript.

* Fix references to components/widgets/menu/menu_wrapper_animation.jsx

* Migrate 'components/widgets/menu/menu_wrapper_animation.jsx' to Typescript

* Fix references to 'components/widgets/menu/menu_wrapper.jsx'

* Migrate 'components/widgest/menu/menu_wrapper.jsx' and related test to Typescript

* Change back 'components/widgets/menu/menu_group.tsx' to PureComponent

* Fix 'components/widgets/menu/menu_items/menu_item.jsx' references

* Migrate 'components/widgets/menu/menu_items/menu_item.jsx' and related test to typescript

* Fix references to 'components/widgets/menu/menu_items/menu_item_action.jsx'

* Migrate 'components/widgets/menu/menu_items/menu_item_action.jsx' and related test to Typescript. Also added "displayName" property to MenuItem.

* Fix references to 'components/widgets/menu/menu_items/menu_item_external_link.jsx'

* Migrate 'components/widgets/menu/menu_items/menu_item_external_link.jsx' and related test to Typescript.

* Fix 'components/widgets/menu/menu_items/menu_item_link.jsx' references

* Migrate 'components/widgets/menu/menu_items/menu_item_link.jsx' and related test to Typescript.

* Fix references to 'components/widgets/menu/menu_items/menu_item_toggle_modal_redux.jsx'

* Migrate 'components/widgets/menu/menu_items/menu_item_toggle_modal_redux.jsx' and related test to Typescript

* Fix 'components/widgets/menu/menu_items/submenu_item.jsx' references

* Migrate 'components/widgets/menu/menu_items/submenu_item.jsx' and related tests to Typescript

* Fix 'components/widgets/menu/menu.jsx' references.

* Migrate 'components/widgets/menu/menu.jsx' and related tests to Typescript

* Fix problem with modal tests by adding again the 'show' prop.

* Fix 'components/widgets/menu/menu_modals/submenu_modal/submenu_modal.jsx' references

* Migrate 'components/widgets/menu/menu_modals/submenu_modal/submenu_modal.jsx' and related tests to Typescript.

* Place again the ref prop on the 'ul' element instead of the 'div' element.

* Add the properties of the original component to the MenuItem class

* Migrate 'components/widgets/menu/menu.stories.tsx' to Typescript

* Rename new snapshot for 'menu_item_toggle_modal_redux.jsx' to consider typescript migration

* Fix 'menu_item_toggle_modal_redux.test.tsx' snapshot to expect a MockFunction instead of a Function.
  • Loading branch information
larkox authored and devinbinnie committed Nov 11, 2019
1 parent 96fa1bf commit 9c6e5d9
Show file tree
Hide file tree
Showing 30 changed files with 241 additions and 217 deletions.
2 changes: 1 addition & 1 deletion components/channel_header/channel_header.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import ArchiveIcon from 'components/widgets/icons/archive_icon';
import ChannelPermissionGate from 'components/permissions_gates/channel_permission_gate';
import QuickSwitchModal from 'components/quick_switch_modal';
import {ChannelHeaderDropdown} from 'components/channel_header_dropdown';
import MenuWrapper from 'components/widgets/menu/menu_wrapper.jsx';
import MenuWrapper from 'components/widgets/menu/menu_wrapper';
import GuestBadge from 'components/widgets/badges/guest_badge';
import BotBadge from 'components/widgets/badges/bot_badge';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import React from 'react';

import {localizeMessage} from 'utils/utils';
import {ChannelHeaderDropdownItems} from 'components/channel_header_dropdown';
import Menu from 'components/widgets/menu/menu.jsx';
import Menu from 'components/widgets/menu/menu';

export default class ChannelHeaderDropdown extends React.PureComponent {
render() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import ChannelGroupsManageModal from 'components/channel_groups_manage_modal';
import ChannelPermissionGate from 'components/permissions_gates/channel_permission_gate';
import TeamPermissionGate from 'components/permissions_gates/team_permission_gate';

import Menu from 'components/widgets/menu/menu.jsx';
import Menu from 'components/widgets/menu/menu';

import MenuItemLeaveChannel from './menu_items/leave_channel';
import MenuItemCloseChannel from './menu_items/close_channel';
Expand Down
4 changes: 2 additions & 2 deletions components/dot_menu/dot_menu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import ChannelPermissionGate from 'components/permissions_gates/channel_permissi

import Pluggable from 'plugins/pluggable';

import Menu from 'components/widgets/menu/menu.jsx';
import MenuWrapper from 'components/widgets/menu/menu_wrapper.jsx';
import Menu from 'components/widgets/menu/menu';
import MenuWrapper from 'components/widgets/menu/menu_wrapper';

const MENU_BOTTOM_MARGIN = 80;

Expand Down
2 changes: 1 addition & 1 deletion components/main_menu/main_menu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import AboutBuildModal from 'components/about_build_modal';
import AddGroupsToTeamModal from 'components/add_groups_to_team_modal';
import MarketplaceModal from 'components/plugin_marketplace';

import Menu from 'components/widgets/menu/menu.jsx';
import Menu from 'components/widgets/menu/menu';
import TeamGroupsManageModal from 'components/team_groups_manage_modal';

class MainMenu extends React.PureComponent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import SidebarHeaderDropdownButton from '../sidebar_header_dropdown_button.jsx';

import UserSettingsModal from 'components/user_settings/modal';

import MenuWrapper from 'components/widgets/menu/menu_wrapper.jsx';
import MenuWrapper from 'components/widgets/menu/menu_wrapper';

import MainMenu from 'components/main_menu';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import {action} from '@storybook/addon-actions';
import InfoIcon from '../icons/info_icon';
import MenuIcon from '../icons/menu_icon';

import Menu from './menu.jsx';
import MenuWrapper from './menu_wrapper.jsx';
import Menu from './menu';
import MenuWrapper from './menu_wrapper';

storiesOf('Menus', module).
addDecorator(withKnobs).
Expand All @@ -20,7 +20,7 @@ storiesOf('Menus', module).
() => {
const txt = text('Text', 'Text');
const extraText = text('Extra Text', 'Extra text');
const icon = boolean('Show Icon');
const icon = boolean('Show Icon', false);
const showEntry1 = boolean('Show entry 1', true);
const showEntry2 = boolean('Show entry 2', true);
const showEntry3 = boolean('Show entry 3', true);
Expand All @@ -30,7 +30,7 @@ storiesOf('Menus', module).
const onClick3 = action('clicked entry 3');
return (
<div style={{position: 'relative'}}>
<Menu>
<Menu ariaLabel={ariaLabel}>
<Menu.ItemAction
onClick={onClick1}
ariaLabel={ariaLabel}
Expand Down Expand Up @@ -65,7 +65,7 @@ storiesOf('Menus', module).
() => {
const txt = text('Text', 'Text');
const extraText = text('Extra Text', 'Extra text');
const icon = boolean('Show Icon');
const icon = boolean('Show Icon', false);
const showEntry1 = boolean('Show entry 1', true);
const showEntry2 = boolean('Show entry 2', true);
const showEntry3 = boolean('Show entry 3', true);
Expand All @@ -75,7 +75,7 @@ storiesOf('Menus', module).
const onClick3 = action('clicked entry 3');
return (
<div style={{position: 'relative'}}>
<Menu>
<Menu ariaLabel={ariaLabel}>
<Menu.Group>
<Menu.ItemAction
onClick={onClick1}
Expand Down Expand Up @@ -115,7 +115,7 @@ storiesOf('Menus', module).
const title = text('Title', 'Open Menu');
const txt = text('Text', 'Text');
const extraText = text('Extra Text', 'Extra text');
const icon = boolean('Show Icon');
const icon = boolean('Show Icon', false);
const showEntry1 = boolean('Show entry 1', true);
const showEntry2 = boolean('Show entry 2', true);
const showEntry3 = boolean('Show entry 3', true);
Expand All @@ -130,7 +130,7 @@ storiesOf('Menus', module).
<span>{title}</span>
<MenuIcon/>
</strong>
<Menu>
<Menu ariaLabel={ariaLabel}>
<Menu.ItemAction
onClick={onClick1}
ariaLabel={ariaLabel}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
import React from 'react';
import {shallow} from 'enzyme';

import Menu from './menu.jsx';
import Menu from './menu';

global.MutationObserver = class {
disconnect() {}
observe() {}
(global as any).MutationObserver = class {
public disconnect() {}
public observe() {}
};

jest.mock('utils/utils', () => {
Expand Down Expand Up @@ -152,9 +152,9 @@ describe('components/Menu', () => {
pseudoMenu.append(element);
}

const wrapper = shallow(<Menu ariaLabel='test-label'>{'text'}</Menu>);
const wrapper = shallow<Menu>(<Menu ariaLabel='test-label'>{'text'}</Menu>);
const instance = wrapper.instance();
instance.node.current = pseudoMenu;
Object.assign(instance.node, {current: pseudoMenu});
instance.hideUnneededDividers();

expect(instance.node.current).toMatchInlineSnapshot(`
Expand Down Expand Up @@ -252,9 +252,9 @@ describe('components/Menu', () => {
pseudoMenu.append(element);
}

const wrapper = shallow(<Menu ariaLabel='test-label'>{'text'}</Menu>);
const wrapper = shallow<Menu>(<Menu ariaLabel='test-label'>{'text'}</Menu>);
const instance = wrapper.instance();
instance.node.current = pseudoMenu;
Object.assign(instance.node, {current: pseudoMenu});
instance.hideUnneededDividers();

expect(instance.node.current).toMatchInlineSnapshot(`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import PropTypes from 'prop-types';
import React from 'react';

import {isMobile} from 'utils/utils';

import SubMenuItem from './menu_items/submenu_item.jsx';
import SubMenuItem from './menu_items/submenu_item';

import MenuGroup from './menu_group';
import MenuItemAction from './menu_items/menu_item_action';
Expand All @@ -16,36 +15,39 @@ import MenuItemToggleModalRedux from './menu_items/menu_item_toggle_modal_redux'

import './menu.scss';

export default class Menu extends React.PureComponent {
static Group = MenuGroup
static ItemAction = MenuItemAction
static ItemExternalLink = MenuItemExternalLink
static ItemLink = MenuItemLink
static ItemToggleModalRedux = MenuItemToggleModalRedux
static ItemSubMenu = SubMenuItem

static propTypes = {
children: PropTypes.node,
openLeft: PropTypes.bool,
openUp: PropTypes.bool,
id: PropTypes.string,
ariaLabel: PropTypes.string.isRequired,
customStyles: PropTypes.object,
};

constructor(props) {
type Props = {
children?: React.ReactNode;
openLeft?: boolean;
openUp?: boolean;
id?: string;
ariaLabel: string;
customStyles?: object;
}

export default class Menu extends React.PureComponent<Props> {
public static Group = MenuGroup
public static ItemAction = MenuItemAction
public static ItemExternalLink = MenuItemExternalLink
public static ItemLink = MenuItemLink
public static ItemToggleModalRedux = MenuItemToggleModalRedux
public static ItemSubMenu = SubMenuItem

public node: React.RefObject<HTMLUListElement>; //Public because it is used by tests
private observer: MutationObserver;

public constructor(props: Props) {
super(props);
this.node = React.createRef();
this.observer = new MutationObserver(this.hideUnneededDividers);
}

hideUnneededDividers = () => {
public hideUnneededDividers = () => { //Public because it is used by tests
if (this.node.current === null) {
return;
}

this.observer.disconnect();
const children = Object.values(this.node.current.children).slice(0, this.node.current.children.length);
const children = Object.values(this.node.current.children).slice(0, this.node.current.children.length) as HTMLElement[];

// Hiding dividers at beginning and duplicated ones
let prevWasDivider = false;
Expand Down Expand Up @@ -74,29 +76,29 @@ export default class Menu extends React.PureComponent {
this.observer.observe(this.node.current, {attributes: true, childList: true, subtree: true});
}

componentDidMount() {
public componentDidMount() {
this.hideUnneededDividers();
}

componentDidUpdate() {
public componentDidUpdate() {
this.hideUnneededDividers();
}

componentWillUnmount() {
public componentWillUnmount() {
this.observer.disconnect();
}

// Used from DotMenu component to know in which direction show the menu
rect() {
public rect() {
if (this.node && this.node.current) {
return this.node.current.getBoundingClientRect();
}
return null;
}

render() {
public render() {
const {children, openUp, openLeft, id, ariaLabel, customStyles} = this.props;
let styles = {};
let styles: React.CSSProperties = {};
if (customStyles) {
styles = customStyles;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import React from 'react';
import {shallow} from 'enzyme';

import MenuGroup from './menu_group.jsx';
import MenuGroup from './menu_group';

describe('components/MenuItem', () => {
test('should match snapshot with default divider', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.

import PropTypes from 'prop-types';
import React from 'react';

import './menu_group.scss';

export default class MenuGroup extends React.PureComponent {
static propTypes = {
divider: PropTypes.node,
children: PropTypes.node,
};
type Props = {
divider?: React.ReactNode;
children?: React.ReactNode;
}

render() {
export default class MenuGroup extends React.PureComponent<Props> {
public render() {
const {children} = this.props;

const divider = this.props.divider || <li className='MenuGroup menu-divider'/>;
Expand All @@ -24,4 +23,4 @@ export default class MenuGroup extends React.PureComponent {
</React.Fragment>
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ exports[`components/MenuItemToggleModalRedux should match snapshot 1`] = `
"test": "test",
}
}
dialogType={[Function]}
dialogType={[MockFunction]}
modalId="test"
>
Whatever
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import React from 'react';
import {shallow} from 'enzyme';

import menuItem from './menu_item.jsx';
import menuItem from './menu_item';

describe('components/MenuItem', () => {
const TestComponent = menuItem(() => null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,30 @@
// See LICENSE.txt for license information.

import React from 'react';
import PropTypes from 'prop-types';

import './menu_item.scss';

export default function menuItem(Component) {
class MenuItem extends React.PureComponent {
static propTypes= {
show: PropTypes.bool,
id: PropTypes.string,
icon: PropTypes.node,
text: PropTypes.string,
};
static defaultProps = {
export default function menuItem(Component: React.ComponentType<any>) {
type Props = {
show: boolean;
id?: string;
icon?: React.ReactNode;
text?: string;
}
class MenuItem extends React.PureComponent<Props|React.ComponentProps<typeof Component>> {
public static defaultProps = {
show: true,
};

render() {
public static displayName?: string;

public render() {
const {id, show, icon, text, ...props} = this.props;
if (!show) {
return null;
}

let textProp = text;
let textProp: React.ReactNode = text;
if (icon) {
textProp = (
<React.Fragment>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import React from 'react';
import {shallow} from 'enzyme';

import {MenuItemActionImpl} from './menu_item_action.jsx';
import {MenuItemActionImpl} from './menu_item_action';

describe('components/MenuItemAction', () => {
test('should match snapshot', () => {
Expand Down
Loading

0 comments on commit 9c6e5d9

Please sign in to comment.