diff --git a/docs/pages/components/dropdown-menu.mdx b/docs/pages/components/dropdown-menu.mdx index a410bf5737..9f39c12a9e 100644 --- a/docs/pages/components/dropdown-menu.mdx +++ b/docs/pages/components/dropdown-menu.mdx @@ -35,7 +35,7 @@ function() { Dropdown Menu - + Twitter diff --git a/packages/DropdownMenu/package.json b/packages/DropdownMenu/package.json index 2f2b2d3516..dcf7099fd8 100644 --- a/packages/DropdownMenu/package.json +++ b/packages/DropdownMenu/package.json @@ -48,6 +48,7 @@ "dependencies": { "@ariakit/react": "0.2.17", "@welcome-ui/box": "^5.0.0", + "@welcome-ui/core": "^5.0.0", "@welcome-ui/system": "^5.0.0", "@welcome-ui/utils": "^5.0.0" }, diff --git a/packages/DropdownMenu/src/index.tsx b/packages/DropdownMenu/src/index.tsx index b9dc3f905c..5919696088 100644 --- a/packages/DropdownMenu/src/index.tsx +++ b/packages/DropdownMenu/src/index.tsx @@ -1,31 +1,47 @@ import React from 'react' import * as Ariakit from '@ariakit/react' import { CreateWuiProps, forwardRef, WuiProps } from '@welcome-ui/system' +import { useTheme } from '@xstyled/styled-components' +import type { WuiTheme } from '@welcome-ui/core' import { Arrow } from './Arrow' import { Item } from './Item' import { Separator } from './Separator' import * as S from './styles' -export interface DropdownMenuOptions extends Ariakit.MenuProps { +export interface DropdownMenuOptions extends Omit { /** add custom props from styled system on DropdownMenu inner */ innerProps?: WuiProps + /** default 4px (space.xs) */ + gutter?: keyof WuiTheme['space'] | number } export type DropdownMenuProps = CreateWuiProps<'div', DropdownMenuOptions> const DropdownMenuComponent = forwardRef<'div', DropdownMenuProps>( - ({ children, dataTestId, innerProps = {}, store, gutter = 10, ...rest }, ref) => { + ({ children, dataTestId, innerProps = {}, store, gutter = 'xs', ...rest }, ref) => { + const theme = useTheme() const arrowElement = store.useState('arrowElement') const isOpen = store.useState('open') + let parsedGutter = gutter + if (typeof parsedGutter === 'string') { + // The value from the theme is in rem, e.g: 1.5rem + // So we parse it to float and pass it to theme.toPx that will convert it to px, e.g: 24px + // Since we want a number we parse it to int + parsedGutter = parseInt(theme.toPx(parseFloat(theme.space[gutter])), 10) || 0 + } + if (arrowElement) { + parsedGutter = 0 + } + return ( isOpen && ( } store={store} diff --git a/packages/DropdownMenu/tests/index.test.tsx b/packages/DropdownMenu/tests/index.test.tsx index f5fb06e28f..6ec87afc6b 100644 --- a/packages/DropdownMenu/tests/index.test.tsx +++ b/packages/DropdownMenu/tests/index.test.tsx @@ -1,5 +1,6 @@ import React from 'react' import { renderHook } from '@testing-library/react-hooks' +import userEvent from '@testing-library/user-event' import { render } from '../../../utils/tests' import { DropdownMenu, useDropdownMenu } from '../src' @@ -22,4 +23,37 @@ describe('', () => { expect(dropdown).toHaveTextContent(content) }) + + test.each([ + ['md', 12], + ['xxl', 32], + [10, 10], + ['not a space', 0], + ] as const)('should render the gutter correctly - %s (%i)', async (gutter, expected) => { + const triggerDataTestId = 'trigger' + const dropdownDataTestId = 'menu' + const { + result: { current: dropdownMenu }, + } = renderHook(() => useDropdownMenu({ open: true })) + + const { getByTestId } = render( + <> + + + {content} + + + ) + const trigger = getByTestId(triggerDataTestId) + const dropdown = getByTestId(dropdownDataTestId) + + await userEvent.click(trigger) + + const { transform } = getComputedStyle(dropdown.parentElement) + const y = parseInt( + transform.match(/translate3d\(\d*(?:px)?,(\d*)(?:px)?,\d*(?:px)?\)/)?.[1], + 10 + ) + expect(y).toBe(expected) + }) })