Skip to content

Commit 44ec81c

Browse files
committed
feat: add support for link component in button
1 parent 69fab6d commit 44ec81c

File tree

4 files changed

+98
-10
lines changed

4 files changed

+98
-10
lines changed

src/Common/Tooltip/Tooltip.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const Tooltip = ({
2828
arrow={false}
2929
placement="top"
3030
{...rest}
31-
className={`default-tt ${wordBreak ? 'dc__word-break-all' : ''} dc__mxw-200 ${rest.className}`}
31+
className={`default-tt ${wordBreak ? 'dc__word-break-all' : ''} dc__mxw-200-imp ${rest.className}`}
3232
>
3333
{cloneElement(child, { ...child.props, ref: refCallback })}
3434
</TippyJS>

src/Shared/Components/Button/Button.component.tsx

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,59 @@
1+
import { ButtonHTMLAttributes, PropsWithChildren } from 'react'
2+
import { Link, LinkProps } from 'react-router-dom'
13
import { Progressing } from '@Common/Progressing'
24
import { Tooltip } from '@Common/Tooltip'
35
import { ComponentSizeType } from '@Shared/constants'
4-
import { ButtonProps, ButtonStyleType, ButtonVariantType } from './types'
6+
import { ButtonComponentType, ButtonProps, ButtonStyleType, ButtonVariantType } from './types'
57
import { BUTTON_SIZE_TO_ICON_CLASS_NAME_MAP, BUTTON_SIZE_TO_LOADER_SIZE_MAP } from './constants'
68
import { getButtonDerivedClass } from './utils'
79
import './button.scss'
810

11+
const ButtonElement = ({
12+
component = ButtonComponentType.button,
13+
linkProps,
14+
buttonProps,
15+
onClick,
16+
...props
17+
}: PropsWithChildren<
18+
Omit<
19+
ButtonProps,
20+
| 'text'
21+
| 'variant'
22+
| 'size'
23+
| 'style'
24+
| 'startIcon'
25+
| 'endIcon'
26+
| 'showTooltip'
27+
| 'tooltipProps'
28+
| 'dataTestId'
29+
| 'isLoading'
30+
> & {
31+
className: string
32+
'data-testid': ButtonProps['dataTestId']
33+
}
34+
>) => {
35+
if (component === ButtonComponentType.link) {
36+
return (
37+
<Link
38+
{...linkProps}
39+
{...props}
40+
className={`${props.className} ${props.disabled ? 'dc__disable-click' : ''}`}
41+
onClick={onClick as LinkProps['onClick']}
42+
/>
43+
)
44+
}
45+
46+
return (
47+
<button
48+
{...buttonProps}
49+
{...props}
50+
// eslint-disable-next-line react/button-has-type
51+
type={buttonProps?.type || 'button'}
52+
onClick={onClick as ButtonHTMLAttributes<HTMLButtonElement>['onClick']}
53+
/>
54+
)
55+
}
56+
957
/**
1058
* Generic component for Button.
1159
* Should be used in combination of variant, size and style.
@@ -68,7 +116,6 @@ const Button = ({
68116
isLoading = false,
69117
showTooltip = false,
70118
tooltipProps = {},
71-
type = 'button',
72119
...props
73120
}: ButtonProps) => {
74121
const isDisabled = disabled || isLoading
@@ -77,19 +124,17 @@ const Button = ({
77124
return (
78125
<Tooltip {...tooltipProps} alwaysShowTippyOnHover={showTooltip && !!tooltipProps?.content}>
79126
<div>
80-
<button
127+
<ButtonElement
81128
{...props}
82129
disabled={isDisabled}
83-
// eslint-disable-next-line react/button-has-type
84-
type={type}
85130
className={`br-4 flex cursor dc__mnw-100 dc__tab-focus dc__position-rel dc__capitalize ${getButtonDerivedClass({ size, variant, style, isLoading })} ${isDisabled ? 'dc__disabled' : ''}`}
86131
data-testid={dataTestId}
87132
>
88133
{startIcon && <span className={iconClass}>{startIcon}</span>}
89134
<span className="dc__mxw-150 dc__align-left dc__truncate">{text}</span>
90135
{endIcon && <span className={iconClass}>{endIcon}</span>}
91136
{isLoading && <Progressing size={BUTTON_SIZE_TO_LOADER_SIZE_MAP[size]} />}
92-
</button>
137+
</ButtonElement>
93138
</div>
94139
</Tooltip>
95140
)

src/Shared/Components/Button/button.scss

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@
2626
@mixin pseudo-states($hover-bg-color, $active-bg-color, $hover-border-color: null) {
2727
$parent-selector: &;
2828

29-
&:hover:enabled {
29+
&:hover:not([disabled]) {
3030
background: $hover-bg-color;
3131

3232
@if ($hover-border-color) {
3333
border-color: $hover-border-color;
3434
}
3535
}
3636

37-
&:active:enabled {
37+
&:active:not([disabled]) {
3838
background: $active-bg-color;
3939
}
4040
}
@@ -45,6 +45,7 @@
4545
color: inherit;
4646
border: none;
4747
outline: inherit;
48+
text-decoration: none;
4849

4950
&__primary {
5051
$border-color: transparent;

src/Shared/Components/Button/types.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { TooltipProps } from '@Common/Tooltip/types'
22
import { ComponentSizeType } from '@Shared/constants'
33
import { ButtonHTMLAttributes, ReactElement } from 'react'
4+
import { LinkProps } from 'react-router-dom'
45

56
// Using the same for BEM class elements
67
export enum ButtonVariantType {
@@ -18,7 +19,39 @@ export enum ButtonStyleType {
1819
neutral = 'neutral',
1920
}
2021

21-
export type ButtonProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'styles' | 'className'> & {
22+
export enum ButtonComponentType {
23+
button = 'button',
24+
link = 'link',
25+
}
26+
27+
export type ButtonProps = (
28+
| {
29+
/**
30+
* Component to be rendered from the available options
31+
*
32+
* @default ButtonComponentType.button
33+
*/
34+
component?: ButtonComponentType.button | never
35+
/**
36+
* Props for the button component
37+
*/
38+
buttonProps?: Omit<
39+
ButtonHTMLAttributes<HTMLButtonElement>,
40+
'children' | 'styles' | 'className' | 'disabled' | 'onClick'
41+
>
42+
linkProps?: never
43+
onClick?: ButtonHTMLAttributes<HTMLButtonElement>['onClick']
44+
}
45+
| {
46+
component: ButtonComponentType.link
47+
/**
48+
* Props for the link component
49+
*/
50+
linkProps: Omit<LinkProps, 'children' | 'styles' | 'className' | 'onClick'>
51+
buttonProps?: never
52+
onClick?: LinkProps['onClick']
53+
}
54+
) & {
2255
/**
2356
* Variant of the button
2457
*
@@ -53,7 +86,16 @@ export type ButtonProps = Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'childre
5386
* If true, the loading state is shown for the button with disabled
5487
*/
5588
isLoading?: boolean
89+
/**
90+
* Test id for the component
91+
*/
5692
dataTestId: string
93+
/**
94+
* If true, the button is disabled
95+
*
96+
* @default false
97+
*/
98+
disabled?: boolean
5799
} & (
58100
| {
59101
/**

0 commit comments

Comments
 (0)