Shared:Components:HelpButton: rewrite to typescript

This commit is contained in:
Timofey Boyko 2023-12-18 16:21:33 +03:00
parent ab84ac19a4
commit a577f86135
12 changed files with 266 additions and 295 deletions

View File

@ -1,70 +0,0 @@
import React from "react";
import Text from "../text";
import Link from "../link";
import HelpButton from ".";
export default {
title: "Components/HelpButton",
component: HelpButton,
subcomponents: { Text, Link },
argTypes: {},
parameters: {
docs: {
description: {
component: "HelpButton is used for a action on a page",
},
},
},
};
const Template = (args: any) => {
return (
<div>
<HelpButton {...args} />
</div>
);
};
export const Default = Template.bind({});
// @ts-expect-error TS(2339): Property 'args' does not exist on type '(args: any... Remove this comment to see the full error message
Default.args = {
offsetTop: 0,
offsetRight: 0,
offsetBottom: 0,
offsetLeft: 0,
// @ts-expect-error TS(2322): Type '{ children: string; fontSize: string; }' is ... Remove this comment to see the full error message
tooltipContent: <Text fontSize="13px">Paste you tooltip content here</Text>,
place: "right",
};
const AutoTemplate = (args: any) => {
return (
<div style={{ marginTop: "20px", marginLeft: "100px" }}>
<HelpButton
style={{ left: "20px" }}
helpButtonHeaderContent="Auto position HelpButton"
tooltipContent={
<>
<p>You can put every thing here</p>
<ul style={{ marginBottom: 0 }}>
<li>Word</li>
<li>Chart</li>
<li>Else</li>
</ul>
</>
}
{...args}
/>
</div>
);
};
export const AutoPosition = AutoTemplate.bind({});
// @ts-expect-error TS(2339): Property 'args' does not exist on type '(args: any... Remove this comment to see the full error message
AutoPosition.args = {
offsetTop: 0,
offsetRight: 0,
offsetBottom: 0,
offsetLeft: 0,
};

View File

@ -1,79 +0,0 @@
import React from "react";
// @ts-expect-error TS(7016): Could not find a declaration file for module 'enzy... Remove this comment to see the full error message
import { mount, shallow } from "enzyme";
import HelpButton from ".";
const tooltipContent = "You tooltip content";
// @ts-expect-error TS(2582): Cannot find name 'describe'. Do you need to instal... Remove this comment to see the full error message
describe("<HelpButton />", () => {
// @ts-expect-error TS(2582): Cannot find name 'it'. Do you need to install type... Remove this comment to see the full error message
it("HelpButton renders without error", () => {
// @ts-expect-error TS(2322): Type '{ tooltipContent: string; }' is not assignab... Remove this comment to see the full error message
const wrapper = mount(<HelpButton tooltipContent={tooltipContent} />);
// @ts-expect-error TS(2304): Cannot find name 'expect'.
expect(wrapper).toExist();
});
// @ts-expect-error TS(2582): Cannot find name 'it'. Do you need to install type... Remove this comment to see the full error message
it("HelpButton componentWillUnmount test", () => {
// @ts-expect-error TS(2322): Type '{ tooltipContent: string; }' is not assignab... Remove this comment to see the full error message
const wrapper = mount(<HelpButton tooltipContent={tooltipContent} />);
// @ts-expect-error TS(2708): Cannot use namespace 'jest' as a value.
const componentWillUnmount = jest.spyOn(
wrapper.instance(),
"componentWillUnmount"
);
wrapper.unmount();
// @ts-expect-error TS(2304): Cannot find name 'expect'.
expect(componentWillUnmount).toHaveBeenCalled();
});
// @ts-expect-error TS(2582): Cannot find name 'it'. Do you need to install type... Remove this comment to see the full error message
it("HelpButton test afterHide function", () => {
const wrapper = shallow(
// @ts-expect-error TS(2322): Type '{ tooltipContent: string; }' is not assignab... Remove this comment to see the full error message
<HelpButton tooltipContent={tooltipContent} />
).instance();
wrapper.afterHide();
// @ts-expect-error TS(2304): Cannot find name 'expect'.
expect(wrapper.state.hideTooltip).toEqual(false);
wrapper.setState({ hideTooltip: false });
wrapper.afterHide();
// @ts-expect-error TS(2304): Cannot find name 'expect'.
expect(wrapper.state.hideTooltip).toEqual(false);
});
// @ts-expect-error TS(2582): Cannot find name 'it'. Do you need to install type... Remove this comment to see the full error message
it("accepts id", () => {
const wrapper = mount(
// @ts-expect-error TS(2322): Type '{ tooltipContent: string; id: string; }' is ... Remove this comment to see the full error message
<HelpButton tooltipContent={tooltipContent} id="testId" />
);
// @ts-expect-error TS(2304): Cannot find name 'expect'.
expect(wrapper.prop("id")).toEqual("testId");
});
// @ts-expect-error TS(2582): Cannot find name 'it'. Do you need to install type... Remove this comment to see the full error message
it("accepts className", () => {
const wrapper = mount(
// @ts-expect-error TS(2322): Type '{ tooltipContent: string; className: string;... Remove this comment to see the full error message
<HelpButton tooltipContent={tooltipContent} className="test" />
);
// @ts-expect-error TS(2304): Cannot find name 'expect'.
expect(wrapper.prop("className")).toEqual("test");
});
// @ts-expect-error TS(2582): Cannot find name 'it'. Do you need to install type... Remove this comment to see the full error message
it("accepts style", () => {
const wrapper = mount(
// @ts-expect-error TS(2322): Type '{ tooltipContent: string; style: { color: st... Remove this comment to see the full error message
<HelpButton tooltipContent={tooltipContent} style={{ color: "red" }} />
);
// @ts-expect-error TS(2304): Cannot find name 'expect'.
expect(wrapper.getDOMNode().style).toHaveProperty("color", "red");
});
});

View File

@ -1,143 +0,0 @@
import React from "react";
import PropTypes from "prop-types";
import IconButton from "../icon-button";
import Tooltip from "../tooltip";
import uniqueId from "lodash/uniqueId";
import { classNames } from "../utils/classNames";
// @ts-expect-error TS(2307): Cannot find module 'PUBLIC_DIR/images/info.react.s... Remove this comment to see the full error message
import InfoReactSvgUrl from "PUBLIC_DIR/images/info.react.svg?url";
class HelpButton extends React.Component {
id: any;
ref: any;
constructor(props: any) {
super(props);
// @ts-expect-error TS(2339): Property 'id' does not exist on type 'Readonly<{}>... Remove this comment to see the full error message
this.id = this.props.id || uniqueId();
}
render() {
const {
// @ts-expect-error TS(2339): Property 'tooltipContent' does not exist on type '... Remove this comment to see the full error message
tooltipContent,
// @ts-expect-error TS(2339): Property 'place' does not exist on type 'Readonly<... Remove this comment to see the full error message
place,
// @ts-expect-error TS(2339): Property 'offset' does not exist on type 'Readonly... Remove this comment to see the full error message
offset,
// @ts-expect-error TS(2339): Property 'iconName' does not exist on type 'Readon... Remove this comment to see the full error message
iconName,
// @ts-expect-error TS(2339): Property 'color' does not exist on type 'Readonly<... Remove this comment to see the full error message
color,
// @ts-expect-error TS(2339): Property 'getContent' does not exist on type 'Read... Remove this comment to see the full error message
getContent,
// @ts-expect-error TS(2339): Property 'className' does not exist on type 'Reado... Remove this comment to see the full error message
className,
// @ts-expect-error TS(2339): Property 'dataTip' does not exist on type 'Readonl... Remove this comment to see the full error message
dataTip,
// @ts-expect-error TS(2339): Property 'tooltipMaxWidth' does not exist on type ... Remove this comment to see the full error message
tooltipMaxWidth,
// @ts-expect-error TS(2339): Property 'style' does not exist on type 'Readonly<... Remove this comment to see the full error message
style,
// @ts-expect-error TS(2339): Property 'size' does not exist on type 'Readonly<{... Remove this comment to see the full error message
size,
// @ts-expect-error TS(2339): Property 'afterShow' does not exist on type 'Reado... Remove this comment to see the full error message
afterShow,
// @ts-expect-error TS(2339): Property 'afterHide' does not exist on type 'Reado... Remove this comment to see the full error message
afterHide,
} = this.props;
const anchorSelect = `div[id='${this.id}'] svg`;
return (
<div ref={this.ref} style={style}>
<IconButton
// @ts-expect-error TS(2322): Type '{ id: any; theme: any; className: any; isCli... Remove this comment to see the full error message
id={this.id}
// @ts-expect-error TS(2339): Property 'theme' does not exist on type 'Readonly<... Remove this comment to see the full error message
theme={this.props.theme}
className={classNames(className, "help-icon")}
isClickable={true}
iconName={iconName}
size={size}
color={color}
data-for={this.id}
dataTip={dataTip}
/>
{getContent ? (
<Tooltip
clickable
openOnClick
place={place}
offset={offset}
afterShow={afterShow}
afterHide={afterHide}
maxWidth={tooltipMaxWidth}
getContent={getContent}
anchorSelect={anchorSelect}
/>
) : (
<Tooltip
clickable
openOnClick
place={place}
offset={offset}
afterShow={afterShow}
afterHide={afterHide}
maxWidth={tooltipMaxWidth}
anchorSelect={anchorSelect}
>
{tooltipContent}
</Tooltip>
)}
</div>
);
}
}
// @ts-expect-error TS(2339): Property 'propTypes' does not exist on type 'typeo... Remove this comment to see the full error message
HelpButton.propTypes = {
/** Displays the child elements */
children: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.node),
PropTypes.node,
]),
/** Sets the tooltip content */
tooltipContent: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
/** Required to set additional properties of the tooltip */
tooltipProps: PropTypes.object,
/** Sets the maximum width of the tooltip */
tooltipMaxWidth: PropTypes.string,
/** Sets the tooltip id */
tooltipId: PropTypes.string,
/** Global tooltip placement */
place: PropTypes.string,
/** Specifies the icon name */
iconName: PropTypes.string,
/** Icon color */
color: PropTypes.string,
/** The data-* attribute is used to store custom data private to the page or application. Required to display a tip over the hovered element */
dataTip: PropTypes.string,
/** Sets a callback function that generates the tip content dynamically */
getContent: PropTypes.func,
/** Accepts class */
className: PropTypes.string,
/** Accepts id */
id: PropTypes.string,
/** Accepts css style */
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
/** Button height and width value */
size: PropTypes.number,
};
// @ts-expect-error TS(2339): Property 'defaultProps' does not exist on type 'ty... Remove this comment to see the full error message
HelpButton.defaultProps = {
iconName: InfoReactSvgUrl,
place: "top",
className: "icon-button",
size: 12,
};
export default HelpButton;

View File

@ -0,0 +1,72 @@
import React from "react";
import { Meta, StoryObj } from "@storybook/react";
import { Text } from "../text";
// import { Link } from "../link";
import { HelpButton } from "./HelpButton";
import { HelpButtonProps } from "./HelpButton.types";
const meta = {
title: "Components/HelpButton",
component: HelpButton,
// subcomponents: { Text, Link },
argTypes: {},
parameters: {
docs: {
description: {
component: "HelpButton is used for a action on a page",
},
},
},
} satisfies Meta<typeof HelpButton>;
type Story = StoryObj<typeof meta>;
export default meta;
const Template = (args: HelpButtonProps) => {
return (
<div>
<HelpButton {...args} />
</div>
);
};
export const Default: Story = {
render: (args) => <Template {...args} />,
args: {
offset: 0,
tooltipContent: <Text fontSize="13px">Paste you tooltip content here</Text>,
place: "right",
},
};
const AutoTemplate = (args: HelpButtonProps) => {
return (
<div style={{ marginTop: "20px", marginLeft: "100px" }}>
<HelpButton
{...args}
style={{ left: "20px" }}
tooltipContent={
<>
<p>You can put every thing here</p>
<ul style={{ marginBottom: 0 }}>
<li>Word</li>
<li>Chart</li>
<li>Else</li>
</ul>
</>
}
/>
</div>
);
};
export const AutoPosition: Story = {
render: (args) => <AutoTemplate {...args} />,
args: {
offset: 0,
tooltipContent: <Text fontSize="13px">Paste you tooltip content here</Text>,
place: "right",
},
};

View File

@ -1,5 +1,5 @@
import styled from "styled-components";
import Base from "../themes/base";
import { Base } from "../../themes";
const Content = styled.div`
box-sizing: border-box;

View File

@ -0,0 +1,64 @@
import React from "react";
import { render, screen } from "@testing-library/react";
import "@testing-library/jest-dom";
import { HelpButton } from "./HelpButton";
const tooltipContent = "You tooltip content";
describe("<HelpButton />", () => {
it("HelpButton renders without error", () => {
render(<HelpButton tooltipContent={tooltipContent} />);
expect(screen.getByTestId("help-button")).toBeInTheDocument();
});
// it("HelpButton componentWillUnmount test", () => {
// const wrapper = mount(<HelpButton tooltipContent={tooltipContent} />);
// // @ts-expect-error TS(2708): Cannot use namespace 'jest' as a value.
// const componentWillUnmount = jest.spyOn(
// wrapper.instance(),
// "componentWillUnmount",
// );
// wrapper.unmount();
// expect(componentWillUnmount).toHaveBeenCalled();
// });
// it("HelpButton test afterHide function", () => {
// const wrapper = shallow(
// <HelpButton tooltipContent={tooltipContent} />,
// ).instance();
// wrapper.afterHide();
// expect(wrapper.state.hideTooltip).toEqual(false);
// wrapper.setState({ hideTooltip: false });
// wrapper.afterHide();
// expect(wrapper.state.hideTooltip).toEqual(false);
// });
// it("accepts id", () => {
// const wrapper = mount(
// // @ts-expect-error TS(2322): Type '{ tooltipContent: string; id: string; }' is ... Remove this comment to see the full error message
// <HelpButton tooltipContent={tooltipContent} id="testId" />,
// );
// expect(wrapper.prop("id")).toEqual("testId");
// });
// it("accepts className", () => {
// const wrapper = mount(
// // @ts-expect-error TS(2322): Type '{ tooltipContent: string; className: string;... Remove this comment to see the full error message
// <HelpButton tooltipContent={tooltipContent} className="test" />,
// );
// expect(wrapper.prop("className")).toEqual("test");
// });
// it("accepts style", () => {
// const wrapper = mount(
// // @ts-expect-error TS(2322): Type '{ tooltipContent: string; style: { color: st... Remove this comment to see the full error message
// <HelpButton tooltipContent={tooltipContent} style={{ color: "red" }} />,
// );
// expect(wrapper.getDOMNode().style).toHaveProperty("color", "red");
// });
});

View File

@ -0,0 +1,85 @@
import React from "react";
import uniqueId from "lodash/uniqueId";
import InfoReactSvgUrl from "PUBLIC_DIR/images/info.react.svg?url";
import { classNames } from "../../utils";
import { IconButton } from "../icon-button";
import { Tooltip } from "../tooltip";
import { HelpButtonProps } from "./HelpButton.types";
const HelpButton = (props: HelpButtonProps) => {
const {
id,
className,
iconName,
size,
color,
dataTip,
getContent,
place,
offset,
style,
afterShow,
afterHide,
tooltipMaxWidth,
tooltipContent,
} = props;
const currentId = id || uniqueId();
const ref = React.useRef(null);
const anchorSelect = `div[id='${currentId}'] svg`;
return (
<div ref={ref} style={style} data-testid="help-button">
<IconButton
id={currentId}
className={classNames([className], "help-icon") || "help-icon"}
isClickable
iconName={iconName || InfoReactSvgUrl}
size={size}
color={color}
data-for={currentId}
dataTip={dataTip}
/>
{getContent ? (
<Tooltip
clickable
openOnClick
place={place || "top"}
offset={offset}
afterShow={afterShow}
afterHide={afterHide}
maxWidth={tooltipMaxWidth}
getContent={getContent}
anchorSelect={anchorSelect}
/>
) : (
<Tooltip
clickable
openOnClick
place={place}
offset={offset}
afterShow={afterShow}
afterHide={afterHide}
maxWidth={tooltipMaxWidth}
anchorSelect={anchorSelect}
>
{tooltipContent}
</Tooltip>
)}
</div>
);
};
HelpButton.defaultProps = {
iconName: InfoReactSvgUrl,
// place: "top",
className: "icon-button",
size: 12,
};
export { HelpButton };

View File

@ -0,0 +1,39 @@
import { TTooltipPlace, TooltipProps } from "../tooltip/Tooltip.types";
export interface HelpButtonProps {
/** Displays the child elements */
children?: React.ReactNode;
/** Sets the tooltip content */
tooltipContent: string | React.ReactNode;
/** Required to set additional properties of the tooltip */
tooltipProps?: TooltipProps;
/** Sets the maximum width of the tooltip */
tooltipMaxWidth?: string;
/** Sets the tooltip id */
tooltipId?: string;
/** Global tooltip placement */
place?: TTooltipPlace;
/** Specifies the icon name */
iconName?: string;
/** Icon color */
color?: string;
/** The data-* attribute is used to store custom data private to the page or application. Required to display a tip over the hovered element */
dataTip?: string;
/** Sets a callback function that generates the tip content dynamically */
getContent?: () => string | React.ReactNode;
/** Accepts class */
className?: string;
/** Accepts id */
id?: string;
/** Accepts css style */
style?: React.CSSProperties;
/** Button height and width value */
size?: number;
offset?: number;
afterShow?: () => void;
afterHide?: () => void;
offsetTop?: number;
offsetRight?: number;
offsetBottom?: number;
offsetLeft?: number;
}

View File

@ -0,0 +1 @@
export { HelpButton } from "./HelpButton";

View File

@ -54,6 +54,7 @@ import {
ContextMenuButtonDisplayType,
} from "./context-menu-button";
import { Selector } from "./selector";
import { HelpButton } from "./help-button";
export type {
TFallbackAxisSideDirection,
@ -63,6 +64,7 @@ export type {
};
export {
HelpButton,
Selector,
ContextMenuButton,
ContextMenuButtonDisplayType,

View File

@ -32,9 +32,9 @@ export interface TooltipProps {
activeAnchor,
}: TGetTooltipContent) => React.ReactNode | string;
/** A function to be called after the tooltip is hidden */
afterHide?: () => {};
afterHide?: () => void;
/** A function to be called after the tooltip is shown */
afterShow?: () => {};
afterShow?: () => void;
/** Space between the tooltip element and anchor element (arrow not included in calculation) */
offset?: number;
/** Child elements */