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

feat(ToolbarMenuItem): add menu prop #1984

Merged
merged 43 commits into from
Oct 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
23a3f64
-init
Sep 30, 2019
de4473c
-cleanups
Sep 30, 2019
1e05ec7
-fixed styles for submenu indicator
Sep 30, 2019
bea7d36
-fixed tests
Oct 1, 2019
95e74fb
-added submenuIndicator defaultProp
Oct 1, 2019
ce99d4f
-added example
Oct 1, 2019
63ee471
-fixed issues
Oct 1, 2019
1652fef
-added onItemClick in the example
Oct 1, 2019
b0f7006
-fixes
Oct 1, 2019
6906d21
-fixed broken popup
Oct 1, 2019
1f45b7d
-fixed popup
Oct 1, 2019
2870ab1
-updated changelog
Oct 1, 2019
dcc9ea6
-fix test
Oct 1, 2019
e568d0e
-fixed popup issues
Oct 1, 2019
58fef76
-fixed issues
Oct 1, 2019
6ae0267
Merge branch 'master' into feat/toolbar-menu-submenu
Oct 18, 2019
332e80a
-fixed closing of the menu when enter/spacebar is pressed
Oct 18, 2019
26db261
-added toolbarMenuBehavior
Oct 18, 2019
7ad7377
-added test
Oct 18, 2019
bddd58a
-fixed click on popup closing menus
Oct 18, 2019
0a0155b
-reverted inline popup in ToolbarItem
Oct 18, 2019
b2a7d0b
-removed inline popups
Oct 18, 2019
e0ed631
-disabled non-working tests
Oct 18, 2019
b3976eb
-fixed popups onClick and onKeyDown
Oct 18, 2019
148e70f
-reverted disabled tests
Oct 18, 2019
fab1cab
-fixed not closing first open menu
Oct 19, 2019
7ece426
-fixed typings
Oct 21, 2019
bc8ae00
-fixed typings
Oct 21, 2019
a1b54ab
-fixed typings
Oct 21, 2019
5f42073
-reverted typings changes
Oct 21, 2019
2bacbcc
-addressed PR comments
Oct 22, 2019
6aa486e
-added e2e tests
Oct 22, 2019
6b4c800
Merge branch 'master' into feat/toolbar-menu-submenu
Oct 22, 2019
95a7fd5
-added more e2e for popups in submenus
Oct 22, 2019
3463080
-fixed typing errors
Oct 22, 2019
13a1ef6
-reverted changes
Oct 22, 2019
fe39d82
fix typings
layershifter Oct 22, 2019
299d8f7
Merge branch 'feat/toolbar-menu-submenu' of https://github.com/stardu…
layershifter Oct 22, 2019
b9a6c8e
Merge branch 'master' into feat/toolbar-menu-submenu
Oct 22, 2019
87429ca
-updated test-cirtucalrs/config
Oct 22, 2019
f4d5cd6
add circulars snapshot
layershifter Oct 22, 2019
ea82d17
Merge branch 'feat/toolbar-menu-submenu' of https://github.com/stardu…
layershifter Oct 22, 2019
3dddd90
Merge branch 'feat/toolbar-menu-submenu' of https://github.com/micros…
Oct 22, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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