Skip to content

Commit

Permalink
Update Button typing to use React.FC (#657)
Browse files Browse the repository at this point in the history
also removed the PropsType and DefaultProps in favor of native TypeScript solution
  • Loading branch information
benoit-sy authored Oct 9, 2024
1 parent 0793122 commit 51c5499
Showing 1 changed file with 68 additions and 65 deletions.
133 changes: 68 additions & 65 deletions packages/components/src/components/button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
/* eslint-disable react/prop-types */
import * as React from 'react';
import * as PropTypes from 'prop-types';
import { clsx } from 'clsx';

const prefix = 'tk-button';

export interface ButtonProps extends Omit<React.HTMLProps<HTMLButtonElement>, 'size'> {
export interface ButtonProps
extends Omit<React.HTMLProps<HTMLButtonElement>, 'size'> {
/** If true, add an Icon component as children */
iconButton?: boolean;
/** Content of the button*/
Expand All @@ -17,77 +18,79 @@ export interface ButtonProps extends Omit<React.HTMLProps<HTMLButtonElement>, 's
type?: 'button' | 'reset' | 'submit';
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
/** Color variant of the button*/
variant?: 'primary' | 'secondary' | 'tertiary' | 'destructive' | 'primary-destructive' | 'secondary-destructive' | 'tertiary-destructive' | 'tertiary-accent';
variant?:
| 'primary'
| 'secondary'
| 'tertiary'
| 'destructive'
| 'primary-destructive'
| 'secondary-destructive'
| 'tertiary-destructive'
| 'tertiary-accent';
/** Size of the button */
size?: 'large' | 'small' | 'medium';
iconRight?: React.ReactNode;
iconLeft?: React.ReactNode;
}

export const Button = React.forwardRef(({
children,
className,
iconButton,
variant,
loading,
disabled,
type,
size,
iconRight,
iconLeft,
...rest
}: ButtonProps, ref?: React.Ref<HTMLButtonElement>) => {
const classes = clsx(
className,
prefix,
`${prefix}--${variant}`,
`${prefix}--${size}`,
{ [`${prefix}--icon`]: iconButton, 'loading': loading, [`${prefix}--icon-left`]: iconLeft, [`${prefix}--icon-right`]: iconRight },
);
export const Button: React.FC<
ButtonProps & React.RefAttributes<HTMLButtonElement>
> = React.forwardRef(
(
{
children,
className,
iconButton = false,
variant = 'primary',
loading = false,
disabled = false,
type = 'button',
size = 'medium',
iconRight,
iconLeft,
...rest
},
ref
) => {
const classes = clsx(
className,
prefix,
`${prefix}--${variant}`,
`${prefix}--${size}`,
{
[`${prefix}--icon`]: iconButton,
loading: loading,
[`${prefix}--icon-left`]: iconLeft,
[`${prefix}--icon-right`]: iconRight,
}
);

if (variant === 'destructive') {
console.warn('The button variant: \'destructive\' will be deprecated.\n Please use: \'primary-destructive\' instead')
}

return (
<button
aria-label={loading ? 'loading' : null}
className={classes}
disabled={loading || disabled}
ref={ ref }
style={{ color: loading ? 'transparent' : null }}
/* eslint-disable react/button-has-type */
type={type}
{...rest}
>
{loading && <i className="tk-button-icon--loading animate-spin tk-icon-loading" />}
{iconLeft}{children}{iconRight}
</button >
);
});
if (variant === 'destructive') {
console.warn(
"The button variant: 'destructive' will be deprecated.\n Please use: 'primary-destructive' instead"
);
}

Button.defaultProps = {
iconButton: false,
className: '',
disabled: false,
loading: false,
type: 'button',
variant: 'primary',
size: 'medium',
};
return (
<button
aria-label={loading ? 'loading' : null}
className={classes}
disabled={loading || disabled}
ref={ref}
style={{ color: loading ? 'transparent' : null }}
type={type}
{...rest}
>
{loading && (
<i className="tk-button-icon--loading animate-spin tk-icon-loading" />
)}
{iconLeft}
{children}
{iconRight}
</button>
);
}
);

Button.propTypes = {
iconButton: PropTypes.bool,
children: PropTypes.any,
className: PropTypes.string,
disabled: PropTypes.bool,
loading: PropTypes.bool,
type: PropTypes.oneOf(['button', 'reset', 'submit']),
variant: PropTypes.oneOf(['primary', 'secondary', 'tertiary', 'destructive', 'primary-destructive', 'secondary-destructive', 'tertiary-destructive', 'tertiary-accent']),
onClick: PropTypes.func,
size: PropTypes.oneOf(['small', 'large', 'medium']),
iconLeft: PropTypes.node,
iconRight: PropTypes.node,
}
Button.displayName = 'Button';
export default Button;

0 comments on commit 51c5499

Please sign in to comment.