Skip to content

Commit

Permalink
[FX-5528] Migrate Dropzone to Tailwind (#4428)
Browse files Browse the repository at this point in the history
  • Loading branch information
sashuk authored Jul 31, 2024
1 parent 1391fba commit 3c57cb2
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 66 deletions.
5 changes: 5 additions & 0 deletions .changeset/calm-cooks-dream.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@toptal/picasso-dropzone': patch
---

- migrate Dropzone to Tailwind
2 changes: 1 addition & 1 deletion packages/base/Dropzone/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
"**/styles.js"
],
"peerDependencies": {
"@material-ui/core": "4.12.4",
"@toptal/picasso-tailwind-merge": "^1.0.1",
"@toptal/picasso-tailwind": ">=2.7",
"react": ">=16.12.0 < 19.0.0"
},
Expand Down
99 changes: 80 additions & 19 deletions packages/base/Dropzone/src/Dropzone/Dropzone.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import React, { forwardRef } from 'react'
import React, { forwardRef, useMemo } from 'react'
import { useDropzone } from 'react-dropzone'
import cx from 'classnames'
import type { Theme } from '@material-ui/core/styles'
import { makeStyles } from '@material-ui/core/styles'
import { twJoin } from '@toptal/picasso-tailwind-merge'
import type { BaseProps } from '@toptal/picasso-shared'
import { Upload24 } from '@toptal/picasso-icons'
import { FormHint } from '@toptal/picasso-form'
import { Container } from '@toptal/picasso-container'
import { FileList } from '@toptal/picasso-file-input'
import { Typography } from '@toptal/picasso-typography'
import { SPACING_6 } from '@toptal/picasso-utils'

import type { FileUpload, DropzoneOptions } from './types'
import styles from './styles'

export interface Props extends BaseProps {
/**
Expand Down Expand Up @@ -46,7 +44,51 @@ export interface Props extends BaseProps {
hovered?: boolean
}

const useStyles = makeStyles<Theme>(styles, { name: 'Dropzone' })
type DropzoneState = {
isDisabled?: boolean
isHovered?: boolean
isFocused?: boolean
isDragActive?: boolean
}

type StateToClassMatcher = (currentState: DropzoneState) => string

const getCursorClasses: StateToClassMatcher = ({
isDisabled,
isHovered,
isFocused,
isDragActive,
}) => {
if (isDisabled) {
return 'cursor-not-allowed'
}

if (isHovered || isFocused || isDragActive) {
return 'cursor-pointer'
}

return 'hover:cursor-pointer focus:cursor-pointer'
}

const getBorderColorClasses: StateToClassMatcher = ({
isDisabled,
isHovered,
isFocused,
isDragActive,
}) => {
if (isDisabled) {
return 'border-gray-400 hover:border-gray-400'
}

if (isHovered || isFocused || isDragActive) {
return 'border-blue-500'
}

return 'border-gray-400 hover:border-blue-500 focus:border-blue-500'
}

const getBackgroundColorClasses: StateToClassMatcher = ({ isDisabled }) =>
isDisabled ? 'bg-gray-100' : 'bg-white'

export const Dropzone = forwardRef<HTMLInputElement, Props>(function Dropzone(
props,
Expand All @@ -60,8 +102,8 @@ export const Dropzone = forwardRef<HTMLInputElement, Props>(function Dropzone(
className,
style,
'data-testid': dataTestId,
focused,
hovered,
focused: isFocused,
hovered: isHovered,

// dropzoneOptions
accept,
Expand Down Expand Up @@ -91,32 +133,51 @@ export const Dropzone = forwardRef<HTMLInputElement, Props>(function Dropzone(
validator,
})

const classes = useStyles()
const componentState = useMemo(
() => ({
isDisabled,
isHovered,
isFocused,
isDragActive,
}),
[isDisabled, isHovered, isFocused, isDragActive]
)

return (
<Container style={style} ref={ref} className={className}>
<Container
flex
direction='column'
alignItems='center'
rounded
aria-disabled={isDisabled}
padded={SPACING_6}
data-testid={dataTestId}
{...getRootProps({
className: cx(classes.root, {
[classes.dragActive]: isDragActive,
[classes.hovered]: hovered,
[classes.disabled]: isDisabled,
[classes.focused]: focused,
}),
})}
{...getRootProps({})}
className={twJoin(
'border border-dashed',
'box-border',
'text-graphite-700',
'gap-2',
'transition-all ease-out duration-350',
getCursorClasses(componentState),
getBorderColorClasses(componentState),
getBackgroundColorClasses(componentState),
isDisabled && 'hover:no-drop'
)}
>
<input {...getInputProps({ className: classes.nativeInput })} />
<input {...getInputProps()} />
<Upload24 color='darkGrey' />
{!hideContentText && (
<Typography size='medium' color='black' weight='semibold'>
Click or drag to upload
</Typography>
)}
{hint && <FormHint className={cx(classes.hint)}>{hint}</FormHint>}
{hint && (
<FormHint className={twJoin('m-0', '[&>*]:leading-4')}>
{hint}
</FormHint>
)}
</Container>
{value && value.length > 0 && (
<Container top='xsmall'>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ exports[`Dropzone renders 1`] = `
class=""
>
<div
class="items-center flex flex-col Dropzone-root"
aria-disabled="false"
class="p-6 items-center rounded-md flex flex-col border border-dashed box-border text-graphite gap-2 transition-all ease-out duration-350 hover:cursor-pointer focus:cursor-pointer border-gray hover:border-blue focus:border-blue bg-white"
role="presentation"
tabindex="0"
>
Expand Down
44 changes: 0 additions & 44 deletions packages/base/Dropzone/src/Dropzone/styles.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/base/Dropzone/src/Dropzone/test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe('Dropzone', () => {
],
})

expect(getByTestId('dropzone').className).toContain('disabled')
expect(getByTestId('dropzone').getAttribute('aria-disabled')).toBe('true')
})
})

Expand Down
1 change: 1 addition & 0 deletions packages/base/Dropzone/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"include": ["src"],
"references": [
{ "path": "../../picasso-tailwind" },
{ "path": "../../picasso-tailwind-merge" },
{ "path": "../Container" },
{ "path": "../FileInput" },
{ "path": "../Form" },
Expand Down

0 comments on commit 3c57cb2

Please sign in to comment.