Skip to content

Commit

Permalink
refactor: to function component
Browse files Browse the repository at this point in the history
  • Loading branch information
dnlkoch authored and simonseyock committed May 6, 2024
1 parent 9a2d062 commit 4e25f56
Show file tree
Hide file tree
Showing 33 changed files with 1,599 additions and 2,159 deletions.
54 changes: 26 additions & 28 deletions src/Button/SimpleButton/SimpleButton.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,45 +1,43 @@
import TestUtil from '../../Util/TestUtil';
import SimpleButton, {SimpleButtonProps} from './SimpleButton';
import { fireEvent,render, screen } from '@testing-library/react';
import React from 'react';

import SimpleButton from './SimpleButton';

describe('<SimpleButton />', () => {

it('is defined', () => {
expect(SimpleButton).not.toBeUndefined();
expect(SimpleButton).toBeDefined();
});

it('can be rendered', () => {
const wrapper = TestUtil.mountComponent(SimpleButton);
expect(wrapper).not.toBeUndefined();
it('can rendered', () => {
render(<SimpleButton />);
expect(screen.getByRole('button')).toBeVisible();
});

it('allows to set some props', () => {
const wrapper = TestUtil.mountComponent(SimpleButton);

wrapper.setProps({
type: 'secondary',
shape: 'circle',
size: 'small',
disabled: true
});

const props = wrapper.props() as SimpleButtonProps;
expect(props.type).toBe('secondary');
expect(props.shape).toBe('circle');
expect(props.size).toBe('small');
expect(props.disabled).toBe(true);

expect(wrapper.find('button.ant-btn-secondary').length).toBe(1);
expect(wrapper.find('button.ant-btn-circle').length).toBe(1);
expect(wrapper.find('button.ant-btn-sm').length).toBe(1);
expect(wrapper.find('button').length).toBe(1);
render(
<SimpleButton
type="default"
shape="circle"
size="small"
disabled={true}
/>
);

const button = screen.getByRole('button');
expect(button).toHaveClass('ant-btn-default');
expect(button).toHaveClass('ant-btn-circle');
expect(button).toHaveClass('ant-btn-sm');
expect(button).toBeDisabled();
});

it('calls a given click callback method onClick', () => {
const onClick = jest.fn();
const wrapper = TestUtil.mountComponent(SimpleButton, {onClick});
render(<SimpleButton onClick={onClick} />);

wrapper.find('button').simulate('click');
const button = screen.getByRole('button');
fireEvent.click(button);

expect(onClick).toHaveBeenCalledTimes(1);
});

});
104 changes: 38 additions & 66 deletions src/Button/SimpleButton/SimpleButton.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
import { Button, Tooltip } from 'antd';
import { ButtonProps } from 'antd/lib/button';
import { AbstractTooltipProps,TooltipPlacement } from 'antd/lib/tooltip';
import { AbstractTooltipProps, TooltipPlacement } from 'antd/lib/tooltip';
import * as React from 'react';

import { CSS_PREFIX } from '../../constants';

interface DefaultProps {
type: 'default' | 'primary' | 'ghost' | 'dashed' | 'danger' | 'link';
export type OwnProps = {
/**
* Additional [antd tooltip](https://ant.design/components/tooltip/)
* properties to pass to the tooltip component. Note: The props `title`
* and `placement` will override the props `tooltip` and `tooltipPlacement`
* of this component!
*/
tooltipProps: AbstractTooltipProps;
}

interface BaseProps {
tooltipProps?: AbstractTooltipProps;
/**
* The tooltip to be shown on hover.
*/
Expand All @@ -25,65 +21,41 @@ interface BaseProps {
* The position of the tooltip.
*/
tooltipPlacement?: TooltipPlacement;
}

export type SimpleButtonProps = BaseProps & Partial<DefaultProps> & ButtonProps;

/**
* The SimpleButton.
*
* @class The SimpleButton
* @extends React.Component
*/
class SimpleButton extends React.Component<SimpleButtonProps> {

/**
* The default properties.
*/
static defaultProps: DefaultProps = {
type: 'primary',
tooltipProps: {
mouseEnterDelay: 1.5
}
};

/**
* The className added to this component.
* @private
*/
className = `${CSS_PREFIX}simplebutton`;

/**
* The render function.
*/
render() {
const {
className,
tooltip,
tooltipPlacement,
tooltipProps,
...antBtnProps
} = this.props;

const finalClassName = className
? `${className} ${this.className}`
: this.className;

return (
<Tooltip
title={tooltip}
placement={tooltipPlacement}
{...tooltipProps}
};

export type SimpleButtonProps = OwnProps & ButtonProps;

const defaultClassName = `${CSS_PREFIX}simplebutton`;

const SimpleButton: React.FC<SimpleButtonProps> = ({
className,
type = 'primary',
tooltip,
tooltipPlacement,
tooltipProps = {
mouseEnterDelay: 1.5
},
...passThroughProps
}) => {

const finalClassName = className
? `${className} ${defaultClassName}`
: `${defaultClassName}`;

return (
<Tooltip
title={tooltip}
placement={tooltipPlacement}
{...tooltipProps}
>
<Button
className={finalClassName}
{...passThroughProps}
>
<Button
className={finalClassName}
{...antBtnProps}
>
{antBtnProps.children}
</Button>
</Tooltip>
);
}
}
{passThroughProps.children}
</Button>
</Tooltip>
);
};

export default SimpleButton;
46 changes: 29 additions & 17 deletions src/Button/UploadButton/UploadButton.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,48 @@
import TestUtil from '../../Util/TestUtil';
import { fireEvent,render, screen } from '@testing-library/react';
import * as React from 'react';

import UploadButton from './UploadButton';

describe('<UploadButton />', () => {
it('is defined', () => {
expect(UploadButton).not.toBeUndefined();
expect(UploadButton).toBeDefined();
});

it('can be rendered', () => {
const wrapper = TestUtil.mountComponent(UploadButton);
expect(wrapper).not.toBeUndefined();
const { container } = render(<UploadButton />);
expect(container).toBeVisible();
});

it('renders an inputfield', () => {
const wrapper = TestUtil.mountComponent(UploadButton);
expect(wrapper.find('input').length).toBe(1);
});
it('applies inputProps to the input field', () => {
render(
<UploadButton
inputProps={{
role: 'test'
}}
/>
);

it('applies inputProps to the inputfield', () => {
const wrapper = TestUtil.mountComponent(UploadButton, {inputProps: {multiple: true}});
expect(wrapper.find('input[multiple=true]').length).toBe(1);
expect(screen.getByRole('test')).toBeInTheDocument();
});

it('renders a simplebutton if no children are given', () => {
const wrapper = TestUtil.mountComponent(UploadButton);
expect(wrapper.find('button').length).toBe(1);
it('renders a simple button if no children are given', () => {
render(<UploadButton />);
expect(screen.getByRole('button')).toBeInTheDocument();
});

it('calls a given click callback method onChange', () => {
const onChange = jest.fn();
const wrapper = TestUtil.mountComponent(UploadButton, {onChange});
wrapper.find('input').simulate('change');
render(
<UploadButton
onChange={onChange}
inputProps={{
role: 'test'
}}
/>
);

fireEvent.change(screen.getByRole('test'));

expect(onChange).toHaveBeenCalledTimes(1);
});

});
72 changes: 31 additions & 41 deletions src/Button/UploadButton/UploadButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as React from 'react';
import { CSS_PREFIX } from '../../constants';
import SimpleButton, { SimpleButtonProps } from '../SimpleButton/SimpleButton';

interface BaseProps {
export type OwnProps = {
/**
* The className which should be added.
*/
Expand All @@ -18,55 +18,45 @@ interface BaseProps {
* The onChange handler for the upload input field.
*/
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
}
};

export type UploadButtonProps = BaseProps & SimpleButtonProps;
export type UploadButtonProps = OwnProps & SimpleButtonProps;

/**
* Class representing an upload button. Can be used as wrapper if children
* Component representing an upload button. Can be used as wrapper if children
* are given. Otherwise a Simplebutton will be rendered.
*
* To use a text with the UploadButton provide a SimpleButton as children.
*
* This automatically supports uploads via drag and drop from the operating
* system.
*
* @class The UploadButton
* @extends React.Component
*/
class UploadButton extends React.Component<UploadButtonProps> {

/**
* The className added to this component.
* @private
*/
_className = `${CSS_PREFIX}uploadbutton`;

/**
* The render function.
*/
render() {
const {
className,
children,
onChange,
inputProps,
...passThroughProps
} = this.props;

const finalClassName = className
? `${className} ${this._className}`
: this._className;

const button = <SimpleButton {...passThroughProps} />;

return (
<div className={finalClassName}>
{children || button}
<input type="file" onChange={onChange} {...inputProps} />
</div>
);
}
}
const UploadButton: React.FC<UploadButtonProps> = ({
className,
children,
onChange,
inputProps,
...passThroughProps
}) => {

const finalClassName = className
? `${className} ${CSS_PREFIX}uploadbutton`
: `${CSS_PREFIX}uploadbutton`;

const button = <SimpleButton {...passThroughProps} />;

return (
<div
className={finalClassName}
>
{children || button}
<input
type="file"
onChange={onChange}
{...inputProps}
/>
</div>
);
};

export default UploadButton;
Loading

0 comments on commit 4e25f56

Please sign in to comment.