chore: Migrating dashboard/components/menu from jsx to tsx (#13361)

* fix: constant icon size

* clean up

* dashboard/components/menu jsx -> tsx

* more types

* package-lock.json sync

* package-lock fix

* fix

* lint fix

* added comment about event type
This commit is contained in:
Ayan Ginet 2021-03-04 21:40:42 +05:00 committed by GitHub
parent 95809e5e60
commit 483405fff9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 112 additions and 112 deletions

View File

@ -17,19 +17,21 @@
* under the License.
*/
import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import backgroundStyleOptions from '../../util/backgroundStyleOptions';
import PopoverDropdown from './PopoverDropdown';
import PopoverDropdown, {
OptionProps,
OnChangeHandler,
} from './PopoverDropdown';
const propTypes = {
id: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
};
interface BackgroundStyleDropdownProps {
id: string;
value: string;
onChange: OnChangeHandler;
}
function renderButton(option) {
function renderButton(option: OptionProps) {
return (
<div className={cx('background-style-option', option.className)}>
{`${option.label} background`}
@ -37,7 +39,7 @@ function renderButton(option) {
);
}
function renderOption(option) {
function renderOption(option: OptionProps) {
return (
<div className={cx('background-style-option', option.className)}>
{option.label}
@ -45,7 +47,7 @@ function renderOption(option) {
);
}
export default class BackgroundStyleDropdown extends React.PureComponent {
export default class BackgroundStyleDropdown extends React.PureComponent<BackgroundStyleDropdownProps> {
render() {
const { id, value, onChange } = this.props;
return (
@ -60,5 +62,3 @@ export default class BackgroundStyleDropdown extends React.PureComponent {
);
}
}
BackgroundStyleDropdown.propTypes = propTypes;

View File

@ -16,23 +16,22 @@
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import PropTypes from 'prop-types';
import React, { RefObject } from 'react';
import cx from 'classnames';
const propTypes = {
position: PropTypes.oneOf(['left', 'top']),
innerRef: PropTypes.func,
children: PropTypes.node,
};
interface HoverMenuProps {
position: 'left' | 'top';
innerRef: RefObject<HTMLDivElement>;
children: React.ReactNode;
}
const defaultProps = {
position: 'left',
innerRef: null,
children: null,
};
export default class HoverMenu extends React.PureComponent<HoverMenuProps> {
static defaultProps = {
position: 'left',
innerRef: null,
children: null,
};
export default class HoverMenu extends React.PureComponent {
render() {
const { innerRef, position, children } = this.props;
return (
@ -49,6 +48,3 @@ export default class HoverMenu extends React.PureComponent {
);
}
}
HoverMenu.propTypes = propTypes;
HoverMenu.defaultProps = defaultProps;

View File

@ -17,16 +17,15 @@
* under the License.
*/
import React from 'react';
import PropTypes from 'prop-types';
import { t } from '@superset-ui/core';
import PopoverDropdown from './PopoverDropdown';
import PopoverDropdown, { OnChangeHandler } from './PopoverDropdown';
const propTypes = {
id: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
};
interface MarkdownModeDropdownProps {
id: string;
value: string;
onChange: OnChangeHandler;
}
const dropdownOptions = [
{
@ -39,7 +38,7 @@ const dropdownOptions = [
},
];
export default class MarkdownModeDropdown extends React.PureComponent {
export default class MarkdownModeDropdown extends React.PureComponent<MarkdownModeDropdownProps> {
render() {
const { id, value, onChange } = this.props;
@ -53,5 +52,3 @@ export default class MarkdownModeDropdown extends React.PureComponent {
);
}
}
MarkdownModeDropdown.propTypes = propTypes;

View File

@ -17,33 +17,29 @@
* under the License.
*/
import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import { styled, withTheme } from '@superset-ui/core';
import { styled, withTheme, SupersetThemeProps } from '@superset-ui/core';
import { Dropdown, Menu } from 'src/common/components';
import Icon from 'src/components/Icon';
const propTypes = {
id: PropTypes.string.isRequired,
options: PropTypes.arrayOf(
PropTypes.shape({
value: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
className: PropTypes.string,
}),
).isRequired,
onChange: PropTypes.func.isRequired,
value: PropTypes.string.isRequired,
renderButton: PropTypes.func,
renderOption: PropTypes.func,
};
export interface OptionProps {
value: string;
label: string;
className?: string;
}
const defaultProps = {
renderButton: option => option.label,
renderOption: option => (
<div className={option.className}>{option.label}</div>
),
};
export type OnChangeHandler = (key: React.Key) => void;
export type RenderElementHandler = (option: OptionProps) => JSX.Element;
interface PopoverDropdownProps {
id: string;
options: OptionProps[];
onChange: OnChangeHandler;
value: string;
theme: SupersetThemeProps['theme'];
renderButton: RenderElementHandler;
renderOption: RenderElementHandler;
}
const MenuItem = styled(Menu.Item)`
&.ant-menu-item {
@ -75,31 +71,34 @@ const MenuItem = styled(Menu.Item)`
}
`;
class PopoverDropdown extends React.PureComponent {
constructor(props) {
interface HandleSelectProps {
key: React.Key;
}
class PopoverDropdown extends React.PureComponent<PopoverDropdownProps> {
constructor(props: PopoverDropdownProps) {
super(props);
this.handleSelect = this.handleSelect.bind(this);
}
handleSelect({ key }) {
handleSelect({ key }: HandleSelectProps) {
this.props.onChange(key);
}
static defaultProps = {
renderButton: (option: OptionProps) => option.label,
renderOption: (option: OptionProps) => (
<div className={option.className}>{option.label}</div>
),
};
render() {
const {
id,
value,
options,
renderButton,
renderOption,
theme,
} = this.props;
const { value, options, renderButton, renderOption, theme } = this.props;
const selected = options.find(opt => opt.value === value);
return (
<Dropdown
id={id}
trigger="click"
trigger={['click']}
overlayStyle={{ zIndex: theme.zIndex.max }}
overlay={
<Menu onClick={this.handleSelect}>
@ -118,7 +117,7 @@ class PopoverDropdown extends React.PureComponent {
}
>
<div role="button" css={{ display: 'flex', alignItems: 'center' }}>
{renderButton(selected)}
{selected && renderButton(selected)}
<Icon name="caret-down" css={{ marginTop: 4 }} />
</div>
</Dropdown>
@ -126,7 +125,4 @@ class PopoverDropdown extends React.PureComponent {
}
}
PopoverDropdown.propTypes = propTypes;
PopoverDropdown.defaultProps = defaultProps;
export default withTheme(PopoverDropdown);

View File

@ -17,44 +17,59 @@
* under the License.
*/
import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
const propTypes = {
children: PropTypes.node,
disableClick: PropTypes.bool,
menuItems: PropTypes.arrayOf(PropTypes.node),
onChangeFocus: PropTypes.func,
isFocused: PropTypes.bool,
shouldFocus: PropTypes.func,
editMode: PropTypes.bool.isRequired,
style: PropTypes.object,
type ShouldFocusContainer = HTMLDivElement & {
contains: (event_target: EventTarget & HTMLElement) => Boolean;
};
const defaultProps = {
children: null,
disableClick: false,
onChangeFocus: null,
menuItems: [],
isFocused: false,
shouldFocus: (event, container) =>
container?.contains(event.target) ||
event.target.id === 'menu-item' ||
event.target.parentNode?.id === 'menu-item',
style: null,
};
interface WithPopoverMenuProps {
children: React.ReactNode;
disableClick: Boolean;
menuItems: React.ReactNode[];
onChangeFocus: (focus: Boolean) => void;
isFocused: Boolean;
// Event argument is left as "any" because of the clash. In defaultProps it seems
// like it should be React.FocusEvent<>, however from handleClick() we can also
// derive that type is EventListenerOrEventListenerObject.
shouldFocus: (event: any, container: ShouldFocusContainer) => Boolean;
editMode: Boolean;
style: React.CSSProperties;
}
class WithPopoverMenu extends React.PureComponent {
constructor(props) {
interface WithPopoverMenuState {
isFocused: Boolean;
}
export default class WithPopoverMenu extends React.PureComponent<
WithPopoverMenuProps,
WithPopoverMenuState
> {
container: ShouldFocusContainer;
static defaultProps = {
children: null,
disableClick: false,
onChangeFocus: null,
menuItems: [],
isFocused: false,
shouldFocus: (event: any, container: ShouldFocusContainer) =>
container?.contains(event.target) ||
event.target.id === 'menu-item' ||
event.target.parentNode?.id === 'menu-item',
style: null,
};
constructor(props: WithPopoverMenuProps) {
super(props);
this.state = {
isFocused: props.isFocused,
isFocused: props.isFocused!,
};
this.setRef = this.setRef.bind(this);
this.handleClick = this.handleClick.bind(this);
}
UNSAFE_componentWillReceiveProps(nextProps) {
UNSAFE_componentWillReceiveProps(nextProps: WithPopoverMenuProps) {
if (nextProps.editMode && nextProps.isFocused && !this.state.isFocused) {
document.addEventListener('click', this.handleClick);
document.addEventListener('drag', this.handleClick);
@ -71,11 +86,11 @@ class WithPopoverMenu extends React.PureComponent {
document.removeEventListener('drag', this.handleClick);
}
setRef(ref) {
setRef(ref: ShouldFocusContainer) {
this.container = ref;
}
handleClick(event) {
handleClick(event: any) {
if (!this.props.editMode) {
return;
}
@ -84,6 +99,7 @@ class WithPopoverMenu extends React.PureComponent {
shouldFocus: shouldFocusFunc,
disableClick,
} = this.props;
const shouldFocus = shouldFocusFunc(event, this.container);
if (!disableClick && shouldFocus && !this.state.isFocused) {
@ -121,9 +137,9 @@ class WithPopoverMenu extends React.PureComponent {
style={style}
>
{children}
{editMode && isFocused && menuItems.length > 0 && (
{editMode && isFocused && (menuItems?.length ?? 0) > 0 && (
<div className="popover-menu">
{menuItems.map((node, i) => (
{menuItems.map((node: React.ReactNode, i: Number) => (
<div className="menu-item" key={`menu-item-${i}`}>
{node}
</div>
@ -134,8 +150,3 @@ class WithPopoverMenu extends React.PureComponent {
);
}
}
WithPopoverMenu.propTypes = propTypes;
WithPopoverMenu.defaultProps = defaultProps;
export default WithPopoverMenu;