Skip to content
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

fix(Button): render disabled button as span #1540

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 11 additions & 7 deletions packages/picasso/src/Button/Button.tsx
Expand Up @@ -84,7 +84,7 @@ export interface StaticProps {
}

const getVariantType = (variant: VariantType) => {
const [type] = variant!.split('-')
const [type] = variant!.split('-') // eslint-disable-line @typescript-eslint/no-non-null-assertion
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this eslint disable necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason precommit hook started complaining to me yesterday, maybe it started happening when Davinci dependency version was bumped recently, not sure TBH.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is pretty strange, can you please figure out why this error started to happen?


return type
}
Expand All @@ -93,6 +93,7 @@ const useStyles = makeStyles<Theme, Props>(styles, { name: 'PicassoButton' })

const defaultOnClick = () => {}

// eslint-disable-next-line complexity
export const Button = forwardRef<HTMLButtonElement, Props>(function Button(
props,
ref
Expand Down Expand Up @@ -152,11 +153,11 @@ export const Button = forwardRef<HTMLButtonElement, Props>(function Button(
}
}

const variantType = getVariantType(variant!)
const variantType = getVariantType(variant!) // eslint-disable-line @typescript-eslint/no-non-null-assertion
const variantClassName = disabled
? classes[`${variantType}Disabled`]
: classes[kebabToCamelCase(variant!)]
const sizeClassName = classes[size!]
: classes[kebabToCamelCase(variant!)] // eslint-disable-line @typescript-eslint/no-non-null-assertion
const sizeClassName = classes[size!] // eslint-disable-line @typescript-eslint/no-non-null-assertion

const rootClassName = cx(
{
Expand All @@ -171,22 +172,25 @@ export const Button = forwardRef<HTMLButtonElement, Props>(function Button(
rootClass
)

const renderAsSpan = disabled && as === 'button'

return (
<ButtonBase
// eslint-disable-next-line react/jsx-props-no-spreading
{...rest}
ref={ref}
classes={{
root: rootClassName
root: rootClassName,
disabled: classes.disabled
}}
onClick={loading ? defaultOnClick : onClick}
onClick={loading || disabled ? defaultOnClick : onClick}
className={className}
style={style}
disabled={disabled}
title={title}
value={value}
type={type}
component={as!}
component={renderAsSpan ? 'span' : as!} // eslint-disable-line @typescript-eslint/no-non-null-assertion
>
<Container
as='span'
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 5 additions & 5 deletions packages/picasso/src/Button/__snapshots__/test.tsx.snap
Expand Up @@ -5,18 +5,18 @@ exports[`disabled button renders disabled version 1`] = `
<div
class="Picasso-root"
>
<button
class="MuiButtonBase-root PicassoButton-medium PicassoButton-primaryDisabled PicassoButton-root Mui-disabled"
disabled=""
<span
aria-disabled="true"
class="MuiButtonBase-root PicassoButton-medium PicassoButton-primaryDisabled PicassoButton-root Mui-disabled PicassoButton-disabled"
role="button"
tabindex="-1"
type="button"
>
<span
class="Container-centerAlignItems Container-flex Container-inline PicassoButton-content"
>
Click me!
</span>
</button>
</span>
</div>
</div>
`;
@@ -0,0 +1,40 @@
import React from 'react'
import { Container, Button, Tooltip, Typography } from '@toptal/picasso'
import { useNotifications } from '@toptal/picasso/utils'

const Example = () => {
const { showSuccess } = useNotifications()
const handleClick = () => showSuccess('I was clicked')

return (
<div>
<Typography variant='heading' size='small'>
Disabled button with the tooltip:
</Typography>
<Container top='small' bottom='large'>
<Button onClick={handleClick}>Enabled</Button>
<Tooltip content='Action is disabled'>
<Button disabled onClick={handleClick}>
Disabled With Tooltip
</Button>
</Tooltip>
</Container>

<Typography variant='heading' size='small'>
Disabled button with the tooltip inside the button group:
</Typography>
<Container top='small'>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add some text above each of these examples so it's more obvious that the top example is two buttons and the bottom is a button group

<Button.Group>
<Button onClick={handleClick}>Enabled</Button>
<Tooltip content='Action is disabled'>
<Button disabled onClick={handleClick}>
Disabled With Tooltip
</Button>
</Tooltip>
</Button.Group>
</Container>
</div>
)
}

export default Example
6 changes: 5 additions & 1 deletion packages/picasso/src/Button/story/index.jsx
Expand Up @@ -188,10 +188,14 @@ page
.addExample('Button/story/Basic.example.jsx', 'Basic')
.addExample('Button/story/Variants.example.jsx', 'Variants')
.addExample('Button/story/States.example.jsx', 'States')
.addExample('Button/story/Disabled.example.jsx', {
.addExample('Button/story/Disabled.example.tsx', {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

title: 'Disabled',
description: 'The button shows that currently unable to be interacted with'
})
.addExample(
'Button/story/DisabledWithTooltip.example.tsx',
'Disabled with tooltip'
)
.addExample('Button/story/Sizes.example.jsx', 'Sizes')
.addExample('Button/story/FullWidth.example.jsx', 'Full width')
.addExample('Button/story/IconButtons.example.jsx', 'Button with Icon')
Expand Down
43 changes: 32 additions & 11 deletions packages/picasso/src/Button/styles.ts
Expand Up @@ -3,39 +3,47 @@ import { lighten, darken, alpha } from '@toptal/picasso-shared'

const ICON_SPACING = '0.4em'

const primary = (mainColor: string, secondaryColor: string) => ({
const primary = (
mainColor: string,
secondaryColor: string,
disabled = false
) => ({
border: 'none',
color: secondaryColor,
backgroundColor: mainColor,

'&:focus, &focused': {
'&:focus, &focused': !disabled && {
backgroundColor: darken(mainColor, 0.2)
},

'&:hover, &$hovered': {
'&:hover, &$hovered': !disabled && {
backgroundColor: darken(mainColor, 0.2)
},

'&:active, &$active': {
'&:active, &$active': !disabled && {
backgroundColor: darken(mainColor, 0.2)
}
})

const secondary = (mainColor: string, secondaryColor: string) => ({
const secondary = (
mainColor: string,
secondaryColor: string,
disabled = false
) => ({
color: mainColor,
backgroundColor: secondaryColor,

'&:focus, &focused': {
'&:focus, &focused': !disabled && {
backgroundColor: lighten(mainColor, 0.84),
borderColor: mainColor
},

'&:hover, &$hovered': {
'&:hover, &$hovered': !disabled && {
backgroundColor: lighten(mainColor, 0.84),
borderColor: mainColor
},

'&:active, &$active': {
'&:active, &$active': !disabled && {
backgroundColor: lighten(mainColor, 0.84),
borderColor: mainColor
}
Expand Down Expand Up @@ -69,6 +77,15 @@ export default ({ palette, sizes, transitions, typography }: Theme) =>
marginLeft: '0.5em'
}
},
disabled: {
'&$disabled': {
pointerEvents: 'inherit',

'&:focus, &focused': {
textDecoration: 'none'
}
}
},
content: {
lineHeight: '1.5em',
fontWeight: typography.fontWeights.semibold,
Expand Down Expand Up @@ -182,10 +199,14 @@ export default ({ palette, sizes, transitions, typography }: Theme) =>
transparentGreen: {
...transparent(palette.green.main)
},
primaryDisabled: primary(palette.grey.light!, palette.common.white),
secondaryDisabled: secondary(palette.grey.light!, palette.common.white),
primaryDisabled: primary(palette.grey.light!, palette.common.white, true),
secondaryDisabled: secondary(
palette.grey.light!,
palette.common.white,
true
),
flatDisabled: {
...secondary(palette.grey.light!, palette.common.white),
...secondary(palette.grey.light!, palette.common.white, true),
border: 'none'
},

Expand Down
24 changes: 19 additions & 5 deletions packages/picasso/src/ButtonGroup/ButtonGroup.tsx
@@ -1,9 +1,15 @@
import React, { ReactNode, HTMLAttributes, forwardRef } from 'react'
import { withStyles } from '@material-ui/core/styles'
import cx from 'classnames'
import { StandardProps, withClasses } from '@toptal/picasso-shared'
import {
StandardProps,
withClasses,
Classes,
OverridableComponent
} from '@toptal/picasso-shared'

import Button from '../Button'
import Tooltip from '../Tooltip'
import styles from './styles'

export interface Props extends StandardProps, HTMLAttributes<HTMLDivElement> {
Expand Down Expand Up @@ -35,12 +41,20 @@ ButtonGroup.displayName = 'ButtonGroup'

export default withStyles(styles)(
withClasses(classes => [
[
Button,
{
{
componentType: Button,
classes: {
root: classes.button,
active: classes.active
} as Classes
},
{
componentType: Tooltip as OverridableComponent,
classes: {} as Classes,
childrenClasses: {
root: classes.button,
active: classes.active
}
]
}
])(ButtonGroup)
)