Skip to content

Commit

Permalink
[FX-5652] Migrate Dropdown to TailwindCSS (#4499)
Browse files Browse the repository at this point in the history
  • Loading branch information
AdrianContiu authored Aug 29, 2024
1 parent c4e1931 commit 3a0125d
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 135 deletions.
7 changes: 7 additions & 0 deletions .changeset/weak-pumas-enjoy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@toptal/picasso-dropdown': minor
---

### Dropdown

- change the ClickAwayListener component to be imported from @mui/base
10 changes: 5 additions & 5 deletions packages/base/Button/src/ButtonSplit/__snapshots__/test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

exports[`ButtonSplit closes menu on click to the item 1`] = `
<svg
class="PicassoSvgArrowDownMinor24-root-29"
class="PicassoSvgArrowDownMinor24-root-24"
style="min-width: 24px; min-height: 24px;"
viewBox="0 0 24 24"
>
Expand Down Expand Up @@ -35,10 +35,10 @@ exports[`ButtonSplit default render 1`] = `
</span>
</button>
<div
class="PicassoDropdown-root block cursor-pointer"
class="items-center block cursor-pointer"
>
<div
class="PicassoDropdown-anchor"
class="inline-flex items-center cursor-pointer"
>
<button
aria-disabled="false"
Expand Down Expand Up @@ -71,7 +71,7 @@ exports[`ButtonSplit default render 1`] = `

exports[`ButtonSplit renders arrow down icon for a closed menu 1`] = `
<svg
class="PicassoSvgArrowDownMinor16-root-29"
class="PicassoSvgArrowDownMinor16-root-24"
style="min-width: 16px; min-height: 16px;"
viewBox="0 0 16 16"
>
Expand All @@ -83,7 +83,7 @@ exports[`ButtonSplit renders arrow down icon for a closed menu 1`] = `

exports[`ButtonSplit renders arrow up icon for an opened menu 1`] = `
<svg
class="PicassoSvgArrowDownMinor16-root-29 rotate-180"
class="PicassoSvgArrowDownMinor16-root-24 rotate-180"
style="min-width: 16px; min-height: 16px;"
viewBox="0 0 16 16"
>
Expand Down
3 changes: 2 additions & 1 deletion packages/base/Dropdown/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
},
"homepage": "https://github.com/toptal/picasso/tree/master/packages/picasso#readme",
"dependencies": {
"@mui/base": "5.0.0-beta.40",
"@toptal/picasso-paper": "4.0.0",
"@toptal/picasso-popper": "1.0.3",
"@toptal/picasso-utils": "1.0.3",
Expand All @@ -39,8 +40,8 @@
},
"devDependencies": {
"@toptal/picasso-provider": "5.0.0",
"@toptal/picasso-test-utils": "1.1.1",
"@toptal/picasso-tailwind-merge": "2.0.0",
"@toptal/picasso-test-utils": "1.1.1",
"popper.js": "^1.16.1"
},
"exports": {
Expand Down
51 changes: 30 additions & 21 deletions packages/base/Dropdown/src/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import type { HTMLAttributes, ReactElement, ReactNode, Ref } from 'react'
import React, { forwardRef, useContext, useRef, useState } from 'react'
import ClickAwayListener from '@material-ui/core/ClickAwayListener'
import Grow from '@material-ui/core/Grow'
import type { PopperPlacementType } from '@material-ui/core/Popper'
import type { PopperOptions } from 'popper.js'
import type { Theme } from '@material-ui/core/styles'
import { makeStyles } from '@material-ui/core/styles'
import cx from 'classnames'
import type { StandardProps } from '@toptal/picasso-shared'
import type {
DeprecatedSpacingType,
Expand All @@ -16,12 +12,21 @@ import { makeResponsiveSpacingProps } from '@toptal/picasso-provider'
import { Popper } from '@toptal/picasso-popper'
import { Paper } from '@toptal/picasso-paper'
import { noop } from '@toptal/picasso-utils'
import { twJoin, twMerge } from '@toptal/picasso-tailwind-merge'
import { ClickAwayListener } from '@mui/base/ClickAwayListener'

import type { StyleProps } from './styles'
import styles from './styles'
import { contentClass } from './styles'

type ContentOverflowType = 'scroll' | 'visible'

type StyleProps = {
/** Control content element style */
contentStyle?: {
height?: string
maxHeight?: string
}
}

interface InternalProps
extends StandardProps,
HTMLAttributes<HTMLDivElement>,
Expand Down Expand Up @@ -49,6 +54,8 @@ interface InternalProps
/** Sets the desired behavior for an element's overflow */
contentOverflow?: ContentOverflowType
popperContainer?: HTMLElement
/** Sets styles for the inner wrapper */
classes?: { popper?: string; content?: string }
}

type PropsWithBaseSpacing = InternalProps & {
Expand Down Expand Up @@ -94,13 +101,6 @@ export const useDropdownContext = () => {
return context
}

const useStyles = makeStyles<
Theme,
PropsWithBaseSpacing | PropsWithDeprecatedSpacing
>(styles, {
name: 'PicassoDropdown',
})

const useResponsiveProps = makeResponsiveSpacingProps(
['margin-top', 'margin-bottom', 'margin-left', 'margin-right'] as const,
'PicassoDropdown-Responsive'
Expand Down Expand Up @@ -147,7 +147,6 @@ export const Dropdown: DropdownProps = forwardRef<
contentOverflow = 'scroll',
...rest
} = props
const classes = useStyles(props)

const contentRef = useRef<HTMLDivElement>(null)
const [anchorEl, setAnchorEl] = useState<HTMLDivElement | undefined>()
Expand Down Expand Up @@ -238,7 +237,7 @@ export const Dropdown: DropdownProps = forwardRef<
close: () => forceClose(),
}

const handleClickAway = (event: React.MouseEvent<Document>) => {
const handleClickAway = (event: MouseEvent | TouchEvent) => {
const target = event.target

const isAnchorTapEvent =
Expand All @@ -255,16 +254,23 @@ export const Dropdown: DropdownProps = forwardRef<
<div
{...rest}
ref={ref}
className={cx(classes.root, className)}
className={twMerge('flex items-center', className)}
style={style}
>
<div className={classes.anchor} onClick={handleAnchorClick}>
<div
className='inline-flex items-center cursor-pointer'
onClick={handleAnchorClick}
>
{typeof children === 'function' ? children({ isOpen }) : children}
</div>

{(isOpen || keepMounted) && (
<Popper
className={cx(classes.popper, responsiveClasses)}
className={twJoin(
'shadow-2',
externalClasses?.popper,
responsiveClasses
)}
anchorEl={anchorEl ?? null}
popperOptions={{
onCreate: focus,
Expand Down Expand Up @@ -293,9 +299,12 @@ export const Dropdown: DropdownProps = forwardRef<
<Grow in={isOpen} appear>
<Paper
style={contentStyle}
className={cx(classes.content, {
[classes.contentVisible]: contentOverflow === 'visible',
})}
className={twMerge(
contentOverflow === 'visible'
? contentClass.contentVisible
: contentClass.content,
externalClasses?.content
)}
onKeyDown={handleContentKeyDown}
elevation={0}
>
Expand Down
20 changes: 10 additions & 10 deletions packages/base/Dropdown/src/Dropdown/__snapshots__/test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ exports[`Dropdown renders 1`] = `
class="Picasso-root"
>
<div
class="PicassoDropdown-root"
class="flex items-center"
>
<div
class="PicassoDropdown-anchor"
class="inline-flex items-center cursor-pointer"
>
Open Dropdown
<span
Expand Down Expand Up @@ -37,10 +37,10 @@ exports[`Dropdown should render menu 1`] = `
class="Picasso-root"
>
<div
class="PicassoDropdown-root"
class="flex items-center"
>
<div
class="PicassoDropdown-anchor"
class="inline-flex items-center cursor-pointer"
>
Open Dropdown
<span
Expand All @@ -58,14 +58,14 @@ exports[`Dropdown should render menu 1`] = `
</div>
</div>
<div
class="PicassoPopper-root PicassoDropdown-popper"
class="PicassoPopper-root shadow-2"
role="tooltip"
style="position: absolute; top: 0px; left: 0px;"
x-placement="bottom-end"
>
<div>
<div
class="bg-white shadow-0 transition-shadow duration-300 delay-0 PicassoDropdown-content"
class="bg-white shadow-0 transition-shadow duration-300 delay-0 overflow-y max-h [@media(max-height:585px)]:max-h-[calc(50vh [@media(max-height:585px)]:md:max-h-[calc(50vh"
style="opacity: 1; transform: scale(1, 1); transition: opacity 0ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,transform 0ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;"
>
<div>
Expand Down Expand Up @@ -166,10 +166,10 @@ exports[`Dropdown should render menu with focus 1`] = `
class=""
>
<div
class="PicassoDropdown-root"
class="flex items-center"
>
<div
class="PicassoDropdown-anchor"
class="inline-flex items-center cursor-pointer"
>
Open Dropdown
<span
Expand All @@ -188,14 +188,14 @@ exports[`Dropdown should render menu with focus 1`] = `
</div>
</div>
<div
class="PicassoPopper-root PicassoDropdown-popper"
class="PicassoPopper-root shadow-2"
role="tooltip"
style="position: absolute; top: 0px; left: 0px; transform: translate3d(NaNpx, NaNpx, 0); will-change: transform;"
x-placement="bottom-end"
>
<div>
<div
class="bg-white shadow-0 transition-shadow duration-300 delay-0 PicassoDropdown-content"
class="bg-white shadow-0 transition-shadow duration-300 delay-0 overflow-y max-h [@media(max-height:585px)]:max-h-[calc(50vh [@media(max-height:585px)]:md:max-h-[calc(50vh"
style="opacity: 1; transform: scale(1, 1); transition: opacity 0ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,transform 0ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;"
>
<div>
Expand Down
69 changes: 14 additions & 55 deletions packages/base/Dropdown/src/Dropdown/styles.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,17 @@
import type { Theme } from '@material-ui/core/styles'
import { createStyles } from '@material-ui/core/styles'
export const contentClass: Record<'content' | 'contentVisible', string[]> = {
content: [
'overflow-y-auto',

export type StyleProps = {
/** Control content element style */
contentStyle?: {
height?: string
maxHeight?: string
}
}

export default ({ screens, shadows, palette }: Theme) =>
createStyles({
root: {
display: 'flex',
alignItems: 'center',
},
anchor: {
display: 'inline-flex',
alignItems: 'center',
cursor: 'pointer',
},
content: {
fontSize: 'inherit',
background: palette.common.white,

maxHeight: '14.75rem', // 6.5 lines of menu to show
overflowY: 'auto',
'max-h-[14.75rem]',
'[@media(max-height:585px)]:max-h-[calc(50vh-3rem)]',
'[@media(max-height:585px)]:md:max-h-[calc(50vh-3.5rem)]',
],
contentVisible: [
'max-h-screen md:max-h-none ',

// height under which maxHeight menu starts to overflow
// and needs to reduce height dynamically to avoid overflow
'@media screen and (max-height: 585px)': {
maxHeight: 'calc(50vh - 3rem)', // half of viewport minus header and anchor
'overflow-y-scroll md:overflow-y-hidden',

[screens('md', 'lg', 'xl')]: {
maxHeight: 'calc(50vh - 3.5rem)', // half of screen minus header and anchor
},
},
},
popper: {
boxShadow: shadows[2],
},
contentVisible: {
// Basically a whole content of a dropdown will be shown without a vertical scrollbar inside the dropdown
maxHeight: 'none',

// Will show a whole content on the `xs` and `sm` screens with a vertical scrollbar if needed
// For non desktop devices better if we have a scrollbar when a dropdown content is pretty long
[screens('xs', 'sm')]: {
overflowY: 'scroll',
maxHeight: '100vh',
},
'@media screen and (max-height: 585px)': {
overflowY: 'scroll',
maxHeight: '100vh',
},
},
})
'[@media(max-height:585px)]:max-h-screen',
'[@media(max-height:585px)]:overflow-y-scroll',
],
}
6 changes: 4 additions & 2 deletions packages/base/Page/src/PageHamburger/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ export default () => {
return createStyles({
root: {
[headerBreakingPointXL]: {
display: 'none',
//TODO: add important property here to overwrite the styles in Dropdown component. Should be removed after migrating to TailwindCSS in task https://toptal-core.atlassian.net/browse/FX-5688
display: 'none !important',
},
},
popper: {
Expand All @@ -16,7 +17,8 @@ export default () => {
pointerEvents: 'none',
},
hidden: {
display: 'none',
//TODO: add important property here to overwrite the styles in Dropdown component. Should be removed after migrating to TailwindCSS in task https://toptal-core.atlassian.net/browse/FX-5688
display: 'none !important',
},
})
}
Loading

0 comments on commit 3a0125d

Please sign in to comment.