Skip to content

Commit

Permalink
feat(core-components-button): fix button types (#138)
Browse files Browse the repository at this point in the history
* feat(core-components-button): fix button types

* feat(core-components-button): add export button props

* test(core-components-button): add event target types tests

* docs(core-components-button): add test description
  • Loading branch information
dmitrsavk committed Jun 5, 2020
1 parent b4a5ce1 commit 6af3a2c
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 9 deletions.
38 changes: 37 additions & 1 deletion packages/button/src/Component.test.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { MouseEvent } from 'react';
import { render, fireEvent } from '@testing-library/react';

import { Button } from './index';
Expand Down Expand Up @@ -96,6 +96,42 @@ describe('Button', () => {

expect(cb).not.toBeCalled();
});

/**
* Тест нужен для проверки типа eventTarget (HTMLButtonElement/HTMLAnchorElement).
* Если тест скомпилился - то все ок.
*/
it('target should contain button element', () => {
const dataTestId = 'test-id';
const { getByTestId } = render(<Button onClick={cb} dataTestId={dataTestId} />);

const buttonNode = getByTestId(dataTestId);

function cb(event: MouseEvent<HTMLButtonElement>) {
expect(event.target).toBe(buttonNode);
}

fireEvent.click(buttonNode, { target: buttonNode });
});

/**
* Тест нужен для проверки типа eventTarget (HTMLButtonElement/HTMLAnchorElement).
* Если тест скомпилился - то все ок.
*/
it('target should contain anchor element', () => {
const dataTestId = 'test-id';
const { getByTestId } = render(
<Button onClick={cb} dataTestId={dataTestId} href='#' />,
);

const anchorNode = getByTestId(dataTestId);

function cb(event: MouseEvent<HTMLAnchorElement>) {
expect(event.target).toBe(anchorNode);
}

fireEvent.click(anchorNode, { target: anchorNode });
});
});

it('should unmount without errors', () => {
Expand Down
28 changes: 20 additions & 8 deletions packages/button/src/Component.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React, { AnchorHTMLAttributes, ButtonHTMLAttributes } from 'react';
import React, { AnchorHTMLAttributes, ButtonHTMLAttributes, Ref } from 'react';
import cn from 'classnames';

import { Loader } from '@alfalab/core-components-loader';

import styles from './index.module.css';

type ComponentProps = {
export type ComponentProps = {
/**
* Тип кнопки
*/
Expand Down Expand Up @@ -54,9 +54,9 @@ type ComponentProps = {

type AnchorButtonProps = ComponentProps & AnchorHTMLAttributes<HTMLAnchorElement>;
type NativeButtonProps = ComponentProps & ButtonHTMLAttributes<HTMLButtonElement>;
type ButtonProps = Partial<AnchorButtonProps & NativeButtonProps>;
type ButtonProps = Partial<AnchorButtonProps | NativeButtonProps>;

export const Button = React.forwardRef<HTMLAnchorElement & HTMLButtonElement, ButtonProps>(
export const Button = React.forwardRef<HTMLAnchorElement | HTMLButtonElement, ButtonProps>(
(
{
children,
Expand All @@ -69,7 +69,6 @@ export const Button = React.forwardRef<HTMLAnchorElement & HTMLButtonElement, Bu
dataTestId,
href,
loading = false,
disabled = false,
...restProps
},
ref,
Expand All @@ -87,7 +86,6 @@ export const Button = React.forwardRef<HTMLAnchorElement & HTMLButtonElement, Bu
className,
),
'data-test-id': dataTestId || null,
disabled: disabled || loading,
};

const buttonChildren = (
Expand All @@ -100,15 +98,29 @@ export const Button = React.forwardRef<HTMLAnchorElement & HTMLButtonElement, Bu

if (href) {
return (
<a {...componentProps} {...restProps} href={href} ref={ref}>
<a
{...componentProps}
{...(restProps as AnchorHTMLAttributes<HTMLAnchorElement>)}
href={href}
ref={ref as Ref<HTMLAnchorElement>}
>
{buttonChildren}
</a>
);
}

const { disabled, ...restButtonProps } = restProps as ButtonHTMLAttributes<
HTMLButtonElement
>;

return (
// eslint-disable-next-line react/button-has-type
<button {...componentProps} {...restProps} ref={ref}>
<button
{...componentProps}
{...restButtonProps}
disabled={disabled || loading}
ref={ref as Ref<HTMLButtonElement>}
>
{buttonChildren}
{loading && <Loader className={cn(styles.loader)} />}
</button>
Expand Down

0 comments on commit 6af3a2c

Please sign in to comment.