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

Commit

Permalink
feat(ToolbarMenuItem): add menu prop (#1984)
Browse files Browse the repository at this point in the history
* -init

* -cleanups
-added TODO

* -fixed styles for submenu indicator

* -fixed tests
-added example

* -added submenuIndicator defaultProp

* -added example
-fixed typings

* -fixed issues

* -added onItemClick in the example

* -fixes
-refactorings on the behavior

* -fixed broken popup

* -fixed popup

* -updated changelog

* -fix test

* -fixed popup issues

* -fixed issues

* -fixed closing of the menu when enter/spacebar is pressed

* -added toolbarMenuBehavior

* -added test

* -fixed click on popup closing menus

* -reverted inline popup in ToolbarItem

* -removed inline popups

* -disabled non-working tests

* -fixed popups onClick and onKeyDown

* -reverted disabled tests

* -fixed not closing first open menu

* -fixed typings

* -fixed typings

* -fixed typings

* -reverted typings changes

* -addressed PR comments

* -added e2e tests

* -added more e2e for popups in submenus
-fixed typing errors

* -fixed typing errors

* -reverted changes

* fix typings

* -updated test-cirtucalrs/config

* add circulars snapshot
  • Loading branch information
mnajdova authored Oct 22, 2019
1 parent f0e8508 commit 69a4383
Show file tree
Hide file tree
Showing 21 changed files with 857 additions and 56 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm

## [Unreleased]

### Features
- Add `menu` prop on `ToolbarMenuItem` component @mnajdova ([#1984](https://github.com/stardust-ui/react/pull/1984))

<!--------------------------------[ v0.40.1 ]------------------------------- -->
## [v0.40.1](https://github.com/stardust-ui/react/tree/v0.40.1) (2019-10-18)
[Compare changes](https://github.com/stardust-ui/react/compare/v0.40.0...v0.40.1)
Expand Down
18 changes: 18 additions & 0 deletions build/gulp/tasks/test-circulars/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,22 @@ export const cyclesToSkip = [
reactPackageDist('components/Reaction/Reaction.js'),
reactPackageDist('components/Reaction/ReactionGroup.js'),
],
[
reactPackageDist('components/Toolbar/ToolbarMenu.js'),
reactPackageDist('components/Toolbar/ToolbarMenuRadioGroup.js'),
reactPackageDist('components/Toolbar/ToolbarMenuItem.js'),
reactPackageDist('components/Toolbar/ToolbarMenu.js'),
],
[
reactPackageDist('components/Toolbar/ToolbarMenuItem.js'),
reactPackageDist('components/Toolbar/ToolbarMenu.js'),
reactPackageDist('components/Toolbar/ToolbarMenuRadioGroup.js'),
reactPackageDist('components/Toolbar/ToolbarMenuItem.js'),
],
[
reactPackageDist('components/Toolbar/ToolbarMenuRadioGroup.js'),
reactPackageDist('components/Toolbar/ToolbarMenuItem.js'),
reactPackageDist('components/Toolbar/ToolbarMenu.js'),
reactPackageDist('components/Toolbar/ToolbarMenuRadioGroup.js'),
],
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ToolbarItem, ToolbarMenuItem } from '@stardust-ui/react'

const config: ScreenerTestsConfig = {
themes: ['teams', 'teamsDark', 'teamsHighContrast'],
steps: [
(builder, keys) =>
builder
.click(`.${ToolbarItem.className}:nth-child(1)`)
.snapshot('Shows menu')
.keys(`.${ToolbarMenuItem.className}:nth-child(1)`, keys.rightArrow)
.snapshot('Opens submenu'),
],
}

export default config
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { createCallbackLogFormatter } from '@stardust-ui/code-sandbox'
import { useLogKnob } from '@stardust-ui/docs-components'
import { Toolbar } from '@stardust-ui/react'
import * as React from 'react'

const ToolbarExampleMenuWithSubmenuShorthand = () => {
const [menuOpen, setMenuOpen] = React.useState(false)

const onMenuOpenChange = useLogKnob(
'onMenuOpenChange',
(e, { menuOpen }) => setMenuOpen(menuOpen),
createCallbackLogFormatter(['menuOpen']),
)

return (
<Toolbar
items={[
{
key: 'more',
icon: 'more',
active: menuOpen,
menu: [
{
key: 'play',
content: 'Play',
icon: 'play',
menu: {
items: [
'Play with audio',
{ content: 'Play with video', key: 'playVideo', menu: ['HD', 'Full HD'] },
],
},
},
{ key: 'pause', content: 'Pause', icon: 'pause' },
{ key: 'divider', kind: 'divider' },
'Without icon',
],
menuOpen,
onMenuOpenChange,
},
]}
/>
)
}

export default ToolbarExampleMenuWithSubmenuShorthand
5 changes: 5 additions & 0 deletions docs/src/examples/components/Toolbar/Content/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@ const Content = () => (
description="Toolbar item can open a menu which can contain radio groups."
examplePath="components/Toolbar/Content/ToolbarExampleMenuRadioGroup"
/>
<ComponentExample
title="Toolbar can contain a submenu in a menu"
description="Toolbar item can open a menu with submenu."
examplePath="components/Toolbar/Content/ToolbarExampleMenuWithSubmenu"
/>
<ComponentExample
title="Toolbar can contain custom content"
toolbarAriaLabel="Example Toolbar can contain custom content"
Expand Down
68 changes: 68 additions & 0 deletions e2e/tests/popupInSubmenuInToolbarMenu-example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import * as React from 'react'
import { Toolbar, ToolbarItemShorthandKinds, Input } from '@stardust-ui/react'

export const selectors = {
toolbarMenuId: 'toolbarMenu',
menuButtonId: 'menuButton',
popupTriggerId: 'popupTrigger',
popupElementId: 'popupElement',
submenuTriggerId: 'submenuTrigger',
dummyButtonId: 'dummyButton',
}

const ToolbarExamplePopupInMenu = () => {
const [menuOpen, setMenuOpen] = React.useState(false)

return (
<>
<Toolbar
items={[
{
id: selectors.menuButtonId,
key: 'menu',
icon: 'more',
active: menuOpen,
menu: {
id: selectors.toolbarMenuId,
items: [
{
id: selectors.submenuTriggerId,
key: 'submenu',
content: 'Open Submenu',
menu: [
{
content: 'Open Popup',
id: selectors.popupTriggerId,
key: 'popup',
popup: {
content: (
<Input
id={selectors.popupElementId}
icon="search"
placeholder="Search..."
/>
),
},
},
],
},
],
},
menuOpen,
onMenuOpenChange: (e, { menuOpen }) => {
setMenuOpen(menuOpen)
},
},
{
id: selectors.dummyButtonId,
key: 'italic',
kind: 'toggle' as ToolbarItemShorthandKinds,
icon: { name: 'italic', outline: true },
},
]}
/>
</>
)
}

export default ToolbarExamplePopupInMenu
132 changes: 132 additions & 0 deletions e2e/tests/popupInSubmenuInToolbarMenu-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import { selectors } from './popupInSubmenuInToolbarMenu-example'

const toolbarMenuId = `#${selectors.toolbarMenuId}`
const menuButtonId = `#${selectors.menuButtonId}`
const popupTriggerId = `#${selectors.popupTriggerId}`
const submenuTriggerId = `#${selectors.submenuTriggerId}`
const popupElementId = `#${selectors.popupElementId}`
const dummyButtonId = `#${selectors.dummyButtonId}`

describe('Popup in ToolbarMenu', () => {
beforeEach(async () => {
await e2e.gotoTestCase(__filename, menuButtonId)
})

it('Popup can be opened using mouse', async () => {
// opens menu
await e2e.clickOn(menuButtonId)
expect(await e2e.exists(toolbarMenuId)).toBe(true)

// opens submenu
await e2e.clickOn(submenuTriggerId)
expect(await e2e.exists(popupTriggerId)).toBe(true)

// opens Popup
await e2e.clickOn(popupTriggerId)

expect(await e2e.exists(popupElementId)).toBe(true)
})

it('Popup can be opened using keyboard', async () => {
// focuses menu button
await e2e.pressKey('Tab')

// opens menu
await e2e.pressKey('Enter')
expect(await e2e.exists(toolbarMenuId)).toBe(true)

// opens submenu
await e2e.pressKey('Enter')
expect(await e2e.exists(popupTriggerId)).toBe(true)

// opens Popup
await e2e.pressKey('Enter')

expect(await e2e.exists(popupElementId)).toBe(true)
})

it('Opening Popup results in first element to be focused', async () => {
// opens menu
await e2e.clickOn(menuButtonId)
expect(await e2e.exists(toolbarMenuId)).toBe(true)

// opens submenu
await e2e.clickOn(submenuTriggerId)
expect(await e2e.exists(popupTriggerId)).toBe(true)

// opens Popup
await e2e.clickOn(popupTriggerId)

expect(await e2e.isFocused(popupElementId)).toBe(true)
})

it('Tab when Popup is focused does not result in hiding the Popup', async () => {
// opens menu
await e2e.clickOn(menuButtonId)
expect(await e2e.exists(toolbarMenuId)).toBe(true)

// opens submenu
await e2e.clickOn(submenuTriggerId)
expect(await e2e.exists(popupTriggerId)).toBe(true)

// opens Popup
await e2e.clickOn(popupTriggerId)

await e2e.pressKey('Tab')

expect(await e2e.exists(popupElementId)).toBe(true)
})

it('Click inside Popup does not hide Popup', async () => {
// opens menu
await e2e.clickOn(menuButtonId)
expect(await e2e.exists(toolbarMenuId)).toBe(true)

// opens submenu
await e2e.clickOn(submenuTriggerId)
expect(await e2e.exists(popupTriggerId)).toBe(true)

// opens Popup
await e2e.clickOn(popupTriggerId)

await e2e.clickOn(popupElementId)

expect(await e2e.exists(popupElementId)).toBe(true)
})

it('Popup is closed when clicking outside of menu and popup', async () => {
// opens menu
await e2e.clickOn(menuButtonId)
expect(await e2e.exists(toolbarMenuId)).toBe(true)

// opens submenu
await e2e.clickOn(submenuTriggerId)
expect(await e2e.exists(popupTriggerId)).toBe(true)

// opens Popup
await e2e.clickOn(popupTriggerId)

await e2e.clickOn(dummyButtonId)

expect(await e2e.exists(popupElementId)).toBe(false)
expect(await e2e.exists(popupTriggerId)).toBe(false)
})

it('Click outside of Popup but inside of Menu closes Popup but leaves Menu open', async () => {
// opens menu
await e2e.clickOn(menuButtonId)
expect(await e2e.exists(toolbarMenuId)).toBe(true)

// opens submenu
await e2e.clickOn(submenuTriggerId)
expect(await e2e.exists(popupTriggerId)).toBe(true)

// opens Popup
await e2e.clickOn(popupTriggerId)

await e2e.clickOn(popupTriggerId)

expect(await e2e.exists(popupElementId)).toBe(false)
expect(await e2e.exists(popupTriggerId)).toBe(true)
})
})
60 changes: 60 additions & 0 deletions e2e/tests/submenuInToolbarMenu-example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import * as React from 'react'
import { Toolbar } from '@stardust-ui/react'

export const selectors = {
toolbarMenuId: 'toolbarMenu',
toolbarMenuSubmenuId: 'toolbarMenuSubmenu',
moreButtonId: 'moreButton',
playId: 'play',
playVideoId: 'playVideo',
hdId: 'hd',
}

const ToolbarExampleMenuWithSubmenuShorthand = () => {
const [menuOpen, setMenuOpen] = React.useState(false)

const onMenuOpenChange = (e, { menuOpen }) => setMenuOpen(menuOpen)

return (
<Toolbar
items={[
{
id: selectors.moreButtonId,
key: 'more',
icon: 'more',
active: menuOpen,
menu: {
id: selectors.toolbarMenuId,
items: [
{
key: 'play',
content: 'Play',
icon: 'play',
id: selectors.playId,
menu: {
id: selectors.toolbarMenuSubmenuId,
items: [
'Play with audio',
{
content: 'Play with video',
key: 'playVideo',
id: selectors.playVideoId,
menu: [{ content: 'HD', id: selectors.hdId, key: 'HD' }, 'Full HD'],
},
],
},
},
{ key: 'pause', content: 'Pause', icon: 'pause' },
{ key: 'divider', kind: 'divider' },
'Without icon',
],
},
menuOpen,
onMenuOpenChange,
},
]}
/>
)
}

export default ToolbarExampleMenuWithSubmenuShorthand
Loading

0 comments on commit 69a4383

Please sign in to comment.