@bitrise/bitkit 10.10.0-alpha-dropdown-release.2 → 10.10.0-alpha-dropdown-release.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bitrise/bitkit",
|
|
3
3
|
"description": "Bitrise React component library",
|
|
4
|
-
"version": "10.10.0-alpha-dropdown-release.
|
|
4
|
+
"version": "10.10.0-alpha-dropdown-release.3",
|
|
5
5
|
"repository": "git@github.com:bitrise-io/bitkit.git",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"license": "UNLICENSED",
|
|
@@ -2,6 +2,9 @@ import { ReactNode, useState } from 'react';
|
|
|
2
2
|
import { ComponentStoryFn } from '@storybook/react';
|
|
3
3
|
import Notification from '../Notification/Notification';
|
|
4
4
|
import Avatar from '../Avatar/Avatar';
|
|
5
|
+
import Provider from '../Provider/Provider';
|
|
6
|
+
import Dialog from '../Dialog/Dialog';
|
|
7
|
+
import DialogBody from '../Dialog/DialogBody';
|
|
5
8
|
import Dropdown, {
|
|
6
9
|
DropdownGroup,
|
|
7
10
|
DropdownOption,
|
|
@@ -108,3 +111,16 @@ export const Default: ComponentStoryFn<typeof Dropdown> = (args) => {
|
|
|
108
111
|
</form>
|
|
109
112
|
);
|
|
110
113
|
};
|
|
114
|
+
export const InsideDialog = () => {
|
|
115
|
+
return (
|
|
116
|
+
<Provider>
|
|
117
|
+
<Dialog isOpen isClosable>
|
|
118
|
+
<DialogBody>
|
|
119
|
+
<Dropdown search={false}>
|
|
120
|
+
<DropdownOption value="x">Test Opt1</DropdownOption>
|
|
121
|
+
</Dropdown>
|
|
122
|
+
</DialogBody>
|
|
123
|
+
</Dialog>
|
|
124
|
+
</Provider>
|
|
125
|
+
);
|
|
126
|
+
};
|
|
@@ -5,7 +5,7 @@ import userEvent from '@testing-library/user-event';
|
|
|
5
5
|
import { useForm } from 'react-hook-form';
|
|
6
6
|
import Avatar from '../Avatar/Avatar';
|
|
7
7
|
import Dropdown, { DropdownGroup, DropdownOption } from './Dropdown';
|
|
8
|
-
import { CustomSearch } from './Dropdown.stories';
|
|
8
|
+
import { CustomSearch, InsideDialog } from './Dropdown.stories';
|
|
9
9
|
import { DropdownDetailedOption } from './DropdownOption';
|
|
10
10
|
|
|
11
11
|
const render = (ui: React.ReactElement) => {
|
|
@@ -519,5 +519,34 @@ describe('Dropdown', () => {
|
|
|
519
519
|
await userEvent.keyboard('{Enter}');
|
|
520
520
|
expect(handler).toHaveBeenCalledWith('x');
|
|
521
521
|
});
|
|
522
|
+
|
|
523
|
+
describe('dismiss with esc', () => {
|
|
524
|
+
it('works', async () => {
|
|
525
|
+
const Test = () => {
|
|
526
|
+
return (
|
|
527
|
+
<Dropdown>
|
|
528
|
+
<DropdownOption value="x">Test Opt1</DropdownOption>
|
|
529
|
+
</Dropdown>
|
|
530
|
+
);
|
|
531
|
+
};
|
|
532
|
+
render(<Test />);
|
|
533
|
+
|
|
534
|
+
const button = await screen.findByRole('combobox');
|
|
535
|
+
await userEvent.click(button);
|
|
536
|
+
const list = await screen.findByRole('listbox');
|
|
537
|
+
await userEvent.keyboard('{Escape}');
|
|
538
|
+
expect(list).not.toBeInTheDocument();
|
|
539
|
+
});
|
|
540
|
+
it('works in dialog', async () => {
|
|
541
|
+
render(<InsideDialog />);
|
|
542
|
+
|
|
543
|
+
const button = await screen.findByRole('combobox');
|
|
544
|
+
await userEvent.click(button);
|
|
545
|
+
const list = await screen.findByRole('listbox');
|
|
546
|
+
await userEvent.keyboard('{Escape}');
|
|
547
|
+
expect(list).not.toBeVisible();
|
|
548
|
+
expect(button).toBeVisible();
|
|
549
|
+
});
|
|
550
|
+
});
|
|
522
551
|
});
|
|
523
552
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RefObject, useEffect, useRef, useState } from 'react';
|
|
1
|
+
import { KeyboardEvent, RefObject, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
autoUpdate,
|
|
4
4
|
useFloating,
|
|
@@ -21,17 +21,6 @@ const useFloatingDropdown = ({ enabled, optionsRef }: { enabled: boolean; option
|
|
|
21
21
|
useEffect(() => {
|
|
22
22
|
setKeyboardControlled(true);
|
|
23
23
|
}, [isOpen]);
|
|
24
|
-
const keyboardControlledHandlers = {
|
|
25
|
-
onPointerEnter() {
|
|
26
|
-
setKeyboardControlled(false);
|
|
27
|
-
},
|
|
28
|
-
onPointerMove() {
|
|
29
|
-
setKeyboardControlled(false);
|
|
30
|
-
},
|
|
31
|
-
onKeyDown() {
|
|
32
|
-
setKeyboardControlled(true);
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
24
|
|
|
36
25
|
const { context, reference, floating, strategy, x, y } = useFloating({
|
|
37
26
|
open: enabled && isOpen,
|
|
@@ -52,6 +41,22 @@ const useFloatingDropdown = ({ enabled, optionsRef }: { enabled: boolean; option
|
|
|
52
41
|
flip(),
|
|
53
42
|
],
|
|
54
43
|
});
|
|
44
|
+
|
|
45
|
+
const keyboardControlledHandlers = {
|
|
46
|
+
onPointerEnter() {
|
|
47
|
+
setKeyboardControlled(false);
|
|
48
|
+
},
|
|
49
|
+
onPointerMove() {
|
|
50
|
+
setKeyboardControlled(false);
|
|
51
|
+
},
|
|
52
|
+
onKeyDown(ev: KeyboardEvent) {
|
|
53
|
+
if (ev.key === 'Escape') {
|
|
54
|
+
ev.stopPropagation();
|
|
55
|
+
setOpen(false);
|
|
56
|
+
}
|
|
57
|
+
setKeyboardControlled(true);
|
|
58
|
+
},
|
|
59
|
+
};
|
|
55
60
|
const { getReferenceProps, getFloatingProps, getItemProps } = useInteractions([
|
|
56
61
|
useClick(context, { enabled }),
|
|
57
62
|
useRole(context, { role: 'listbox' }),
|
|
@@ -66,6 +71,7 @@ const useFloatingDropdown = ({ enabled, optionsRef }: { enabled: boolean; option
|
|
|
66
71
|
onNavigate: setActiveIndex,
|
|
67
72
|
}),
|
|
68
73
|
{
|
|
74
|
+
reference: { onKeyDown: keyboardControlledHandlers.onKeyDown },
|
|
69
75
|
floating: keyboardControlledHandlers,
|
|
70
76
|
},
|
|
71
77
|
]);
|