Skip to content
This repository has been archived by the owner on Mar 4, 2020. It is now read-only.

feat(MenuButton): add component #1696

Merged
merged 17 commits into from
Aug 8, 2019
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const unsupportedComponents = [
'ItemLayout',
'Layout',
'List',
'MenuButton',
'Portal',
'Provider',
'RadioGroup',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Button } from '@stardust-ui/react'

const config: ScreenerTestsConfig = {
steps: [builder => builder.click(`.${Button.className}`).snapshot('RTL: Shows menuButton')],
}

export default config
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react'
import { Button, MenuButton } from '@stardust-ui/react'

const ContextMenuExampleRtl = () => (
<MenuButton
trigger={<Button content="ا يجلبه إلينا الأس" />}
menu={{ items: ['English text!', 'غالباً ونرفض الشعور'] }}
jurokapsiar marked this conversation as resolved.
Show resolved Hide resolved
/>
)

export default ContextMenuExampleRtl
jurokapsiar marked this conversation as resolved.
Show resolved Hide resolved
12 changes: 12 additions & 0 deletions docs/src/examples/components/MenuButton/Rtl/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import * as React from 'react'

import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import NonPublicSection from 'docs/src/components/ComponentDoc/NonPublicSection'

const Rtl = () => (
<NonPublicSection title="Rtl">
<ComponentExample examplePath="components/MenuButton/Rtl/MenuButtonExample.rtl" />
</NonPublicSection>
)

export default Rtl
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useBooleanKnob } from '@stardust-ui/docs-components'
import * as React from 'react'
import { Button, MenuButton } from '@stardust-ui/react'

const items = ['1', '2', '3', { content: 'submenu', menu: { items: ['4', '5'] } }]

const MenuButtonControlledExample = () => {
const [open, setOpen] = useBooleanKnob({ name: 'open', initialValue: true })

return (
<MenuButton
open={open}
onOpenChange={(e, { open }) => setOpen(open)}
trigger={<Button icon="expand" title="Open MenuButton" />}
menu={{ items }}
jurokapsiar marked this conversation as resolved.
Show resolved Hide resolved
/>
)
}

export default MenuButtonControlledExample
jurokapsiar marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import * as React from 'react'
import { Alert, Button, Flex, MenuButton } from '@stardust-ui/react'

const items = ['1', '2', '3', { content: 'submenu', menu: { items: ['4', '5'] } }]

class MenuButtonExampleOn extends React.Component {
state = { alert: false }

showAlert = () => {
this.setState({ alert: true })
setTimeout(() => this.setState({ alert: false }), 2000)
}

render() {
return (
<>
<Flex gap="gap.smaller">
<MenuButton
trigger={<Button icon="expand" content="Click" aria-label="Click button" />}
menu={{ items }}
on="click"
/>
<MenuButton
trigger={<Button icon="expand" content="Hover" aria-label="Hover button" />}
menu={{ items }}
on="hover"
/>
<MenuButton
trigger={<Button icon="expand" content="Focus" aria-label="Focus button" />}
menu={{ items }}
on="focus"
/>
<MenuButton
trigger={
<Button
icon="expand"
content="Context"
aria-label="Context button"
onClick={this.showAlert}
/>
}
menu={{ items }}
on="context"
/>
</Flex>
{this.state.alert && (
<Alert
warning
content="Right, you can still click the button! Right click opens the MenuButton."
/>
)}
</>
)
}
}

export default MenuButtonExampleOn
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import * as React from 'react'
import { Alert, Button, MenuButton } from '@stardust-ui/react'

const items = ['1', '2', '3', { content: 'submenu', menu: { items: ['4', '5'] } }]

class MenuButtonOnElement extends React.Component {
state = { alert: false }

showAlert = () => {
this.setState({ alert: true })
setTimeout(() => this.setState({ alert: false }), 2000)
}

render() {
return (
<>
<MenuButton
trigger={
<div style={{ padding: '4rem', border: 'red dashed' }}>
<Button content="Random button" onClick={this.showAlert} />
</div>
}
shouldTriggerBeTabbable={false}
menu={{ items }}
jurokapsiar marked this conversation as resolved.
Show resolved Hide resolved
contextMenu
/>
{this.state.alert && <Alert warning content="Click!" />}
</>
)
}
}

export default MenuButtonOnElement
26 changes: 26 additions & 0 deletions docs/src/examples/components/MenuButton/Usage/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import * as React from 'react'

import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'

const Usage = () => (
<ExampleSection title="Usage">
<ComponentExample
title="Triggering menu on different actions"
description="A context menu can be triggered on click, hover or focus."
jurokapsiar marked this conversation as resolved.
Show resolved Hide resolved
examplePath="components/MenuButton/Usage/MenuButtonExampleOn"
/>
<ComponentExample
title="Context menu"
description="A menu button can be attached to any element to create a context menu."
examplePath="components/MenuButton/Usage/MenuButtonExampleOnElement"
/>
<ComponentExample
title="Controlled"
description="Note that if MenuButton is controlled, then its 'open' prop value could be changed either by parent component, or by user actions (e.g. key press) - thus it is necessary to handle 'onOpenChange' event."
examplePath="components/MenuButton/Usage/MenuButtonExampleControlled"
jurokapsiar marked this conversation as resolved.
Show resolved Hide resolved
/>
</ExampleSection>
)

export default Usage
13 changes: 13 additions & 0 deletions docs/src/examples/components/MenuButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as React from 'react'

import Rtl from './Rtl'
import Usage from './Usage'

const MenuButtonExamples = () => (
<>
<Usage />
<Rtl />
</>
)

export default MenuButtonExamples
Loading