-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add a possibility to use button component as link #327
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,10 @@ | ||
import { ForwardedRef, forwardRef } from 'react' | ||
import React, { ForwardedRef, forwardRef } from 'react' | ||
import { | ||
ButtonStyle, | ||
ButtonContentStyle, | ||
ButtonLoaderStyle, | ||
} from './ButtonStyles' | ||
import { ButtonProps } from './types' | ||
import { ButtonButtonProps, ButtonProps } from './types' | ||
import { useRipple } from './useRipple' | ||
|
||
const loaderSizes = { | ||
|
@@ -15,7 +15,10 @@ const loaderSizes = { | |
lg: 'medium', | ||
} as const | ||
|
||
function Button(props: ButtonProps, ref?: ForwardedRef<HTMLButtonElement>) { | ||
function Button( | ||
props: ButtonProps, | ||
ref?: ForwardedRef<HTMLButtonElement | HTMLAnchorElement> | ||
) { | ||
const { | ||
size = 'md', | ||
variant = 'filled', | ||
|
@@ -27,14 +30,16 @@ function Button(props: ButtonProps, ref?: ForwardedRef<HTMLButtonElement>) { | |
onClick, | ||
disabled, | ||
children, | ||
href, | ||
...rest | ||
} = props | ||
} = props as ButtonButtonProps | ||
|
||
const { handleClick, ripple } = useRipple(props) | ||
const loaderSize = loaderSizes[size] | ||
|
||
return ( | ||
<ButtonStyle | ||
as={href ? ('a' as React.ElementType) : undefined} | ||
$size={size} | ||
$variant={variant} | ||
$fullwidth={fullwidth} | ||
|
@@ -46,6 +51,7 @@ function Button(props: ButtonProps, ref?: ForwardedRef<HTMLButtonElement>) { | |
disabled={disabled || loading} | ||
type='button' | ||
ref={ref} | ||
href={href} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not the best way from types standpoint, because <button> props and <a> props are different: So basically we need that button should accept button props, and link should accept link props cc @Jabher for discussion There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What do you suggest in this situation? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I personally like this approach, it is nice and minimal - by providing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yep, links and buttons have different props, and we probably should be able to specify which to use with link, otherwise there may be more prs and more if statements |
||
{...rest} | ||
> | ||
<ButtonContentStyle $hidden={loading}>{children}</ButtonContentStyle> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
|
||
exports[`renders correctly 1`] = ` | ||
.c0 { | ||
display: inline-block; | ||
box-sizing: border-box; | ||
margin: 0; | ||
border: none; | ||
|
@@ -12,6 +13,8 @@ exports[`renders correctly 1`] = ` | |
background: transparent; | ||
font-family: inherit; | ||
font-weight: 700; | ||
-webkit-text-decoration: none; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't we have any prefixer for this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a test snapshot, tests see prefixed code:) |
||
text-decoration: none; | ||
width: auto; | ||
line-height: 1em; | ||
font-size: 14px; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,10 @@ export const useRipple: UseRipple = ({ onClick }) => { | |
const [ripple, setRipple] = useState<React.ReactNode | null>(null) | ||
|
||
const handleClick = useCallback( | ||
(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => { | ||
( | ||
event: React.MouseEvent<HTMLAnchorElement, MouseEvent> & | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is it & here? It's probably anchor element | button element There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It works only with & |
||
React.MouseEvent<HTMLButtonElement, MouseEvent> | ||
) => { | ||
const button = event.currentTarget | ||
const rect = button.getBoundingClientRect() | ||
const diameter = Math.max(button.clientWidth, button.clientHeight) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can add validator which type it is, so we don't cast it, it may help to use proper args further
https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgEIFcxgPYg13ZAbwChlkZsoBbALmThAE8SBfEk0SWRFfHEABlQAa2JlkACygQY9AM5gooAOZsOYJgAc+mAcgC8aPbn6EAPsYJDRHBLkXJg84SDFGAFACMTIemZAASnofayd5KwFXdwA+ZFCBADpJOHkAeQB3EAAFKGwdKE0PAHJpWWLAoA
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a disabled appearance of a button even if it is a link
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ButtonButton
feels like this, maybe better naming can be here (e.g. NativeButton):