Skip to content

Commit

Permalink
feat: migrate DropdownMenu component
Browse files Browse the repository at this point in the history
  • Loading branch information
theo-mesnil committed Jul 24, 2023
1 parent 3d64b9d commit f69d6de
Show file tree
Hide file tree
Showing 15 changed files with 94 additions and 224 deletions.
18 changes: 12 additions & 6 deletions docs/components/Header/ThemeSelector.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import { DropdownMenu, useDropdownMenuState } from '@welcome-ui/dropdown-menu'
import { DropdownMenu, useDropdownMenu } from '@welcome-ui/dropdown-menu'
import { Box } from '@welcome-ui/box'
import { CrescentMoonIcon, StarIcon, StarOutlineIcon, SunIcon } from '@welcome-ui/icons'
import { Button } from '@welcome-ui/button'
Expand All @@ -9,12 +9,12 @@ import { useSetThemeContext, useThemeContext } from '../../context/theme'

export const ThemeSelector = props => {
const setTheme = useSetThemeContext()
const menuState = useDropdownMenuState({ gutter: 10 })
const dropdownMenu = useDropdownMenu()
const theme = useThemeContext()

const handleSetTheme = theme => {
setTheme(theme)
menuState.hide()
dropdownMenu.hide()
}

const options = [
Expand All @@ -26,17 +26,23 @@ export const ThemeSelector = props => {

return (
<>
<DropdownMenu.Trigger as={Button} h={30} shape="circle" state={menuState} w={30} {...props}>
<DropdownMenu.Trigger
as={Button}
h={30}
shape="circle"
store={dropdownMenu}
w={30}
{...props}
>
<SunIcon />
</DropdownMenu.Trigger>
<DropdownMenu aria-label="Theme selector" state={menuState}>
<DropdownMenu aria-label="Theme selector" store={dropdownMenu}>
{options?.map(({ icon: Icon, isBeta, label, value }) => (
<DropdownMenu.Item
color={theme === value ? 'dark-900' : undefined}
fontWeight={theme === value ? 'bold' : undefined}
key={value}
onClick={() => handleSetTheme(value)}
state={menuState}
>
<Icon mr="md" size="sm" />
<Box>{label}</Box>
Expand Down
5 changes: 1 addition & 4 deletions docs/pages/_app.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* eslint-disable react/display-name */
import React from 'react'
import { Provider } from 'reakit'

import { ThemeProvider } from '../context/theme'
import { App } from '../components/App'
Expand All @@ -10,9 +9,7 @@ require('@welcome-ui/icons.font/fonts/welcome-icon-font-2.css')
const NextApp = ({ Component, pageProps }) => {
return (
<ThemeProvider>
<Provider>
<App component={Component} pageProps={pageProps} />
</Provider>
<App component={Component} pageProps={pageProps} />
</ThemeProvider>
)
}
Expand Down
58 changes: 27 additions & 31 deletions docs/pages/components/dropdown-menu.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,38 +18,36 @@ import {

## About

Menu from [Reakit](https://reakit.io/docs/menu/) with a really nice theme 👀
Menu from [Ariakit menu](https://ariakit.org/components/menu) with a really nice theme 👀

## Usage

```jsx
function() {
const dropdownMenuState = useDropdownMenuState({
gutter: 10
})
const dropdownMenu = useDropdownMenu()

const handleClick = e => {
console.log(`Clicked on ${e.target.innerText}`)
dropdownMenuState.hide()
dropdownMenu.hide()
}

return (
<>
<DropdownMenu.Trigger state={dropdownMenuState} as={Button}>
<DropdownMenu.Trigger store={dropdownMenu} as={Button}>
Dropdown Menu
</DropdownMenu.Trigger>
<DropdownMenu state={dropdownMenuState} aria-label="Example">
<DropdownMenu.Item state={dropdownMenuState} onClick={handleClick}>
<DropdownMenu store={dropdownMenu} aria-label="Example">
<DropdownMenu.Item store={dropdownMenu} onClick={handleClick}>
Twitter
</DropdownMenu.Item>
<DropdownMenu.Item state={dropdownMenuState} onClick={handleClick} disabled>
<DropdownMenu.Item store={dropdownMenu} onClick={handleClick} disabled>
Facebook
</DropdownMenu.Item>
<DropdownMenu.Item state={dropdownMenuState} onClick={handleClick}>
<DropdownMenu.Item store={dropdownMenu} onClick={handleClick}>
Instagram
</DropdownMenu.Item>
<DropdownMenu.Separator state={dropdownMenuState} />
<DropdownMenu.Item state={dropdownMenuState} onClick={handleClick}>
<DropdownMenu.Separator store={dropdownMenu} />
<DropdownMenu.Item store={dropdownMenu} onClick={handleClick}>
Github
</DropdownMenu.Item>
</DropdownMenu>
Expand All @@ -62,11 +60,11 @@ function() {

```jsx
function() {
const dropdownMenuState = useDropdownMenuState({ gutter: 10, placement: 'bottom-end' })
const dropdownMenu = useDropdownMenu({ placement: 'bottom-end' })

const handleClick = e => {
console.log(`Clicked on ${e.target.innerText}`)
dropdownMenuState.hide()
dropdownMenu.hide()
}

return (
Expand All @@ -76,16 +74,16 @@ function() {
<AddIcon />
<span>First Action</span>
</Button>
<DropdownMenu.Trigger state={dropdownMenuState} as={Button}>
{dropdownMenuState.open ? <UpIcon /> : <DownIcon />}
<DropdownMenu.Trigger store={dropdownMenu} as={Button}>
{dropdownMenu.open ? <UpIcon /> : <DownIcon />}
</DropdownMenu.Trigger>
</ButtonGroup>
<DropdownMenu state={dropdownMenuState} aria-label="Complexity">
<DropdownMenu.Item state={dropdownMenuState} onClick={handleClick}>
<DropdownMenu store={dropdownMenu} aria-label="Complexity">
<DropdownMenu.Item store={dropdownMenu} onClick={handleClick}>
<TrashIcon mr="sm" size="sm" />
<Box>Second Action</Box>
</DropdownMenu.Item>
<DropdownMenu.Item state={dropdownMenuState} onClick={handleClick}>
<DropdownMenu.Item store={dropdownMenu} onClick={handleClick}>
<AttachmentIcon mr="sm" size="sm" />
<Box>Third Action</Box>
</DropdownMenu.Item>
Expand All @@ -101,33 +99,31 @@ Use `DropdownMenu.Arrow` to add an arrow to the dropdown menu

```jsx
function() {
const dropdownMenuState = useDropdownMenuState({
gutter: 10
})
const dropdownMenu = useDropdownMenu()

const handleClick = e => {
console.log(`Clicked on ${e.target.innerText}`)
dropdownMenuState.hide()
dropdownMenu.hide()
}

return (
<>
<DropdownMenu.Trigger state={dropdownMenuState} as={Button}>
<DropdownMenu.Trigger store={dropdownMenu} as={Button}>
Dropdown Menu
</DropdownMenu.Trigger>
<DropdownMenu state={dropdownMenuState} aria-label="Example">
<DropdownMenu.Arrow state={dropdownMenuState} />
<DropdownMenu.Item state={dropdownMenuState} onClick={handleClick}>
<DropdownMenu store={dropdownMenu} aria-label="Example">
<DropdownMenu.Arrow store={dropdownMenu} />
<DropdownMenu.Item onClick={handleClick}>
Twitter
</DropdownMenu.Item>
<DropdownMenu.Item state={dropdownMenuState} onClick={handleClick} disabled>
<DropdownMenu.Item onClick={handleClick} disabled>
Facebook
</DropdownMenu.Item>
<DropdownMenu.Item state={dropdownMenuState} onClick={handleClick}>
<DropdownMenu.Item onClick={handleClick}>
Instagram
</DropdownMenu.Item>
<DropdownMenu.Separator state={dropdownMenuState} />
<DropdownMenu.Item state={dropdownMenuState} onClick={handleClick}>
<DropdownMenu.Separator />
<DropdownMenu.Item onClick={handleClick}>
Github
</DropdownMenu.Item>
</DropdownMenu>
Expand Down
2 changes: 1 addition & 1 deletion packages/DropdownMenu/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The [DropdownMenu](https://welcome-ui.com/components/dropdown-menu) component fr

## Import

import { DropdownMenu, useDropdownMenuState } from '@welcome-ui/dropdown-menu'
import { DropdownMenu, useDropdownMenu } from '@welcome-ui/dropdown-menu'

## Documentation

Expand Down
4 changes: 2 additions & 2 deletions packages/DropdownMenu/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@
"url": "https://github.com/WTTJ/welcome-ui/issues"
},
"dependencies": {
"@ariakit/react": "^0.2.12",
"@welcome-ui/box": "^5.0.0-alpha.40",
"@welcome-ui/system": "^5.0.0-alpha.40",
"@welcome-ui/utils": "^5.0.0-alpha.37",
"reakit": "^1.3.11"
"@welcome-ui/utils": "^5.0.0-alpha.37"
},
"peerDependencies": {
"@xstyled/styled-components": "^3.7.3",
Expand Down
4 changes: 2 additions & 2 deletions packages/DropdownMenu/src/Arrow.styled.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import styled, { css, th } from '@xstyled/styled-components'
import { MenuArrow } from 'reakit'

export const Arrow = styled(MenuArrow)`
export const Arrow = styled.divBox`
display: flex;
z-index: 2;
color: ${th('defaultCards.backgroundColor')};
stroke-width: 0 !important;
#stroke {
color: ${th('defaultCards.borderColor')};
Expand Down
24 changes: 8 additions & 16 deletions packages/DropdownMenu/src/Arrow.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,26 @@
import React from 'react'
import { MenuArrowOptions } from 'reakit'
import * as Ariakit from '@ariakit/react'
import { CreateWuiProps, forwardRef } from '@welcome-ui/system'

import * as S from './Arrow.styled'

import { DropdownMenuOptions } from '.'

const transformMap: Record<string, string> = {
top: 'rotateZ(180deg)',
right: 'rotateZ(-90deg)',
bottom: 'rotateZ(360deg)',
left: 'rotateZ(90deg)',
}

export type ArrowProps = CreateWuiProps<
'div',
MenuArrowOptions & { state: DropdownMenuOptions['state'] }
>
export type ArrowProps = CreateWuiProps<'div', Ariakit.MenuArrowProps>

export const Arrow = forwardRef<'div', ArrowProps>(({ state, ...rest }, ref) => {
// get the correct transform style for arrow
const { placement } = state
// get the parent placement (top, bottom...)
const [parentPlacement] = placement.split('-')
const transform = transformMap[parentPlacement]
export const Arrow = forwardRef<'div', ArrowProps>(({ store }, ref) => {
const currentPlacement = store?.useState('currentPlacement')
const [placement] = currentPlacement.split('-')

return (
<S.Arrow {...state} {...rest} ref={ref}>
<Ariakit.MenuArrow ref={ref} render={<S.Arrow />}>
<S.ArrowItem
$transform={transform}
$transform={transformMap[placement]}
h={30}
viewBox="0 0 30 30"
w={30}
Expand All @@ -37,7 +29,7 @@ export const Arrow = forwardRef<'div', ArrowProps>(({ state, ...rest }, ref) =>
<path d="M7 30L15 22L23 30H7Z" fill="currentColor" fillRule="nonzero" id="stroke" />
<path d="M8 30L15 23L22 30H8Z" fill="currentColor" fillRule="nonzero" />
</S.ArrowItem>
</S.Arrow>
</Ariakit.MenuArrow>
)
})

Expand Down
5 changes: 0 additions & 5 deletions packages/DropdownMenu/src/Item.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,6 @@ export const Item = styled.button`
text-decoration: none;
padding: md;
&[type='button'] {
appearance: none;
}
&:hover,
&:focus {
outline: none !important; /* important for firefox */
}
Expand Down
23 changes: 4 additions & 19 deletions packages/DropdownMenu/src/Item.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,13 @@
import React from 'react'
import { MenuItem, MenuItemProps } from 'reakit'
import * as Ariakit from '@ariakit/react'
import { CreateWuiProps, forwardRef } from '@welcome-ui/system'

import * as S from './Item.styled'

import { DropdownMenuOptions } from '.'
export type ItemProps = CreateWuiProps<'button', Ariakit.MenuItemProps>

type ItemOptions = Pick<DropdownMenuOptions, 'state'> &
Partial<Omit<MenuItemProps, keyof DropdownMenuOptions['state']>>

export type ItemProps = CreateWuiProps<'button', ItemOptions>

export const Item = forwardRef<'button', ItemProps>(({ as, children, state, ...rest }, ref) => {
return (
<MenuItem as={undefined} type="button" {...state} {...rest} ref={ref}>
{menuItemProps => {
return (
<S.Item as={as} {...menuItemProps}>
{children}
</S.Item>
)
}}
</MenuItem>
)
export const Item = forwardRef<'button', ItemProps>(({ as, ...rest }, ref) => {
return <Ariakit.MenuItem ref={ref} type="button" {...rest} render={<S.Item as={as} />} />
})

Item.displayName = 'Item'
13 changes: 4 additions & 9 deletions packages/DropdownMenu/src/Separator.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
import React from 'react'
import { MenuSeparator, MenuSeparatorProps } from 'reakit'
import * as Ariakit from '@ariakit/react'
import { CreateWuiProps, forwardRef } from '@welcome-ui/system'

import * as S from './Separator.styled'

import { DropdownMenuOptions } from '.'
export type SeparatorProps = CreateWuiProps<'div', Ariakit.MenuSeparatorProps>

export type SeparatorProps = CreateWuiProps<
'div',
MenuSeparatorProps & { state: DropdownMenuOptions['state'] }
>

export const Separator = forwardRef<'div', SeparatorProps>(({ state, ...rest }, ref) => {
return <MenuSeparator as={S.Separator} ref={ref} {...state} {...rest} />
export const Separator = forwardRef<'div', SeparatorProps>((props, ref) => {
return <Ariakit.MenuSeparator as={S.Separator} ref={ref} {...props} />
})
Loading

0 comments on commit f69d6de

Please sign in to comment.