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

Commit 0a00d34

Browse files
kolaps33mnajdova
authored andcommitted
fix(Popup): Adding toggle functionality if trigger element is not button (#758)
* adding toggle functionality if trigger element is not button * adding tests for toggle popover with enter/space key * adressing comment from PR * adding open popup * reverting downshift version package * first refactor of the test * refactoring tests 2 * -revert yarn.lock changes * -improved test namings and typings * -update changelog * -fixed type name
1 parent ef4fc21 commit 0a00d34

File tree

4 files changed

+88
-1
lines changed

4 files changed

+88
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
2727
- Add `create` shorthand factory to `Header` component @layershifter ([#809](https://github.com/stardust-ui/react/pull/809))
2828
- Add `keyframeParams` prop in the `Animation` component and the `animation` prop @mnajdova ([#794](https://github.com/stardust-ui/react/pull/794))
2929
- Add `Dialog` component @layershifter ([#790](https://github.com/stardust-ui/react/pull/790))
30+
- Add toggle functionality in the `Popoup` even if the `trigger` is not button @kolaps33 ([#758](https://github.com/stardust-ui/react/pull/758))
3031

3132
### Fixes
3233
- Handle `onClick` and `onFocus` on ListItems correctly @layershifter ([#779](https://github.com/stardust-ui/react/pull/779))

src/components/Popup/Popup.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,14 @@ export default class Popup extends AutoControlledComponent<ReactProps<PopupProps
176176
e.stopPropagation()
177177
},
178178
close: e => this.close(e),
179+
toggle: e => {
180+
e.preventDefault()
181+
this.trySetOpen(!this.state.open, e)
182+
},
183+
open: e => {
184+
e.preventDefault()
185+
this.setPopupOpen(true, e)
186+
},
179187
}
180188

181189
public componentDidMount() {

src/lib/accessibility/Behaviors/Popup/popupBehavior.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import * as _ from 'lodash'
1010
* Adds attribute 'aria-disabled=true' to 'trigger' component's part if 'disabled' property is true. Does not set the attribute otherwise.
1111
*/
1212
const popupBehavior: Accessibility = (props: any) => {
13+
const onAsArray = _.isArray(props.on) ? props.on : [props.on]
1314
return {
1415
attributes: {
1516
trigger: {
@@ -31,6 +32,18 @@ const popupBehavior: Accessibility = (props: any) => {
3132
close: {
3233
keyCombinations: [{ keyCode: keyboardKey.Escape }],
3334
},
35+
toggle: {
36+
keyCombinations: _.includes(onAsArray, 'click') && [
37+
{ keyCode: keyboardKey.Enter },
38+
{ keyCode: keyboardKey.Spacebar },
39+
],
40+
},
41+
open: {
42+
keyCombinations: _.includes(onAsArray, 'hover') && [
43+
{ keyCode: keyboardKey.Enter },
44+
{ keyCode: keyboardKey.Spacebar },
45+
],
46+
},
3447
},
3548
},
3649
}

test/specs/components/Popup/Popup-test.tsx

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import {
77
Position,
88
Alignment,
99
} from 'src/components/Popup/positioningHelper'
10-
import Popup from 'src/components/Popup/Popup'
10+
import Popup, { PopupEvents } from 'src/components/Popup/Popup'
1111
import { mountWithProvider } from '../../../utils'
12+
import * as keyboardKey from 'keyboard-key'
13+
import { ReactWrapper } from 'enzyme'
1214

1315
type PositionTestInput = {
1416
align: Alignment
@@ -18,6 +20,8 @@ type PositionTestInput = {
1820
}
1921

2022
describe('Popup', () => {
23+
const triggerId = 'triggerElement'
24+
const contentId = 'contentId'
2125
const testPopupPosition = ({
2226
align,
2327
position,
@@ -36,6 +40,36 @@ describe('Popup', () => {
3640
}: PositionTestInput & { rtl?: never }) =>
3741
testPopupPosition({ align, position, expectedPlacement, rtl: true })
3842

43+
const getPopupContent = (popup: ReactWrapper) => {
44+
return popup.find(`#${contentId}`)
45+
}
46+
47+
type ExpectPopupToOpenAndCloseParams = {
48+
onProp: PopupEvents
49+
keyboardKeyToOpen: keyboardKey
50+
keyboardKeyToClose: keyboardKey
51+
}
52+
53+
const expectPopupToOpenAndClose = ({
54+
onProp,
55+
keyboardKeyToOpen,
56+
keyboardKeyToClose,
57+
}: ExpectPopupToOpenAndCloseParams) => {
58+
const popup = mountWithProvider(
59+
<Popup
60+
trigger={<span id={triggerId}> text to trigger popup </span>}
61+
content={<span id={contentId} />}
62+
on={onProp}
63+
/>,
64+
)
65+
const popupTriggerElement = popup.find(`#${triggerId}`)
66+
popupTriggerElement.simulate('keydown', { keyCode: keyboardKeyToOpen })
67+
expect(getPopupContent(popup).length).toBe(1)
68+
69+
popupTriggerElement.simulate('keydown', { keyCode: keyboardKeyToClose })
70+
expect(getPopupContent(popup).length).toBe(0)
71+
}
72+
3973
describe('handles Popup position correctly in ltr', () => {
4074
testPopupPosition({ position: 'above', align: 'start', expectedPlacement: 'top-start' })
4175
testPopupPosition({ position: 'above', align: 'center', expectedPlacement: 'top' })
@@ -131,4 +165,35 @@ describe('Popup', () => {
131165
expect(spy.mock.calls[0][1]).toMatchObject({ open: true })
132166
})
133167
})
168+
169+
describe('open/close popup by keyboard', () => {
170+
test(`toggle popup with Enter key`, () => {
171+
expectPopupToOpenAndClose({
172+
onProp: 'click',
173+
keyboardKeyToOpen: keyboardKey.Enter,
174+
keyboardKeyToClose: keyboardKey.Enter,
175+
})
176+
})
177+
test(`toggle popup with Space key`, () => {
178+
expectPopupToOpenAndClose({
179+
onProp: 'click',
180+
keyboardKeyToOpen: keyboardKey.Spacebar,
181+
keyboardKeyToClose: keyboardKey.Spacebar,
182+
})
183+
})
184+
test(`open popup with Enter key and close it with escape key`, () => {
185+
expectPopupToOpenAndClose({
186+
onProp: 'hover',
187+
keyboardKeyToOpen: keyboardKey.Enter,
188+
keyboardKeyToClose: keyboardKey.Escape,
189+
})
190+
})
191+
test(`open popup with Space key and close it with escape key`, () => {
192+
expectPopupToOpenAndClose({
193+
onProp: 'hover',
194+
keyboardKeyToOpen: keyboardKey.Spacebar,
195+
keyboardKeyToClose: keyboardKey.Escape,
196+
})
197+
})
198+
})
134199
})

0 commit comments

Comments
 (0)