@patternfly/react-core 5.0.0-alpha.109 → 5.0.0-alpha.110

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.
Files changed (270) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/esm/components/AboutModal/package.json +1 -1
  3. package/dist/esm/components/Accordion/package.json +1 -1
  4. package/dist/esm/components/ActionList/package.json +1 -1
  5. package/dist/esm/components/Alert/package.json +1 -1
  6. package/dist/esm/components/Avatar/package.json +1 -1
  7. package/dist/esm/components/BackToTop/package.json +1 -1
  8. package/dist/esm/components/Backdrop/package.json +1 -1
  9. package/dist/esm/components/BackgroundImage/package.json +1 -1
  10. package/dist/esm/components/Badge/package.json +1 -1
  11. package/dist/esm/components/Banner/package.json +1 -1
  12. package/dist/esm/components/Brand/package.json +1 -1
  13. package/dist/esm/components/Breadcrumb/package.json +1 -1
  14. package/dist/esm/components/Button/package.json +1 -1
  15. package/dist/esm/components/CalendarMonth/package.json +1 -1
  16. package/dist/esm/components/Card/package.json +1 -1
  17. package/dist/esm/components/Checkbox/package.json +1 -1
  18. package/dist/esm/components/Chip/package.json +1 -1
  19. package/dist/esm/components/ClipboardCopy/package.json +1 -1
  20. package/dist/esm/components/CodeBlock/package.json +1 -1
  21. package/dist/esm/components/DataList/package.json +1 -1
  22. package/dist/esm/components/DatePicker/package.json +1 -1
  23. package/dist/esm/components/DescriptionList/package.json +1 -1
  24. package/dist/esm/components/Divider/package.json +1 -1
  25. package/dist/esm/components/DragDrop/package.json +1 -1
  26. package/dist/esm/components/Drawer/package.json +1 -1
  27. package/dist/esm/components/Dropdown/Dropdown.d.ts +3 -1
  28. package/dist/esm/components/Dropdown/Dropdown.d.ts.map +1 -1
  29. package/dist/esm/components/Dropdown/Dropdown.js +3 -4
  30. package/dist/esm/components/Dropdown/Dropdown.js.map +1 -1
  31. package/dist/esm/components/Dropdown/package.json +1 -1
  32. package/dist/esm/components/DualListSelector/package.json +1 -1
  33. package/dist/esm/components/EmptyState/package.json +1 -1
  34. package/dist/esm/components/ExpandableSection/package.json +1 -1
  35. package/dist/esm/components/FileUpload/package.json +1 -1
  36. package/dist/esm/components/Form/package.json +1 -1
  37. package/dist/esm/components/FormSelect/package.json +1 -1
  38. package/dist/esm/components/HelperText/package.json +1 -1
  39. package/dist/esm/components/Hint/package.json +1 -1
  40. package/dist/esm/components/Icon/package.json +1 -1
  41. package/dist/esm/components/InputGroup/package.json +1 -1
  42. package/dist/esm/components/JumpLinks/package.json +1 -1
  43. package/dist/esm/components/Label/package.json +1 -1
  44. package/dist/esm/components/List/package.json +1 -1
  45. package/dist/esm/components/LoginPage/package.json +1 -1
  46. package/dist/esm/components/Masthead/package.json +1 -1
  47. package/dist/esm/components/Menu/Menu.js +7 -4
  48. package/dist/esm/components/Menu/Menu.js.map +1 -1
  49. package/dist/esm/components/Menu/MenuContainer.d.ts +42 -0
  50. package/dist/esm/components/Menu/MenuContainer.d.ts.map +1 -0
  51. package/dist/esm/components/Menu/MenuContainer.js +47 -0
  52. package/dist/esm/components/Menu/MenuContainer.js.map +1 -0
  53. package/dist/esm/components/Menu/index.d.ts +1 -0
  54. package/dist/esm/components/Menu/index.d.ts.map +1 -1
  55. package/dist/esm/components/Menu/index.js +1 -0
  56. package/dist/esm/components/Menu/index.js.map +1 -1
  57. package/dist/esm/components/Menu/package.json +1 -1
  58. package/dist/esm/components/MenuToggle/package.json +1 -1
  59. package/dist/esm/components/Modal/package.json +1 -1
  60. package/dist/esm/components/MultipleFileUpload/package.json +1 -1
  61. package/dist/esm/components/Nav/package.json +1 -1
  62. package/dist/esm/components/NotificationBadge/package.json +1 -1
  63. package/dist/esm/components/NotificationDrawer/package.json +1 -1
  64. package/dist/esm/components/NumberInput/package.json +1 -1
  65. package/dist/esm/components/OverflowMenu/package.json +1 -1
  66. package/dist/esm/components/Page/package.json +1 -1
  67. package/dist/esm/components/Pagination/package.json +1 -1
  68. package/dist/esm/components/Panel/package.json +1 -1
  69. package/dist/esm/components/Popover/package.json +1 -1
  70. package/dist/esm/components/Progress/package.json +1 -1
  71. package/dist/esm/components/ProgressStepper/package.json +1 -1
  72. package/dist/esm/components/Radio/package.json +1 -1
  73. package/dist/esm/components/SearchInput/package.json +1 -1
  74. package/dist/esm/components/Select/package.json +1 -1
  75. package/dist/esm/components/Sidebar/package.json +1 -1
  76. package/dist/esm/components/SimpleList/package.json +1 -1
  77. package/dist/esm/components/Skeleton/package.json +1 -1
  78. package/dist/esm/components/SkipToContent/package.json +1 -1
  79. package/dist/esm/components/Slider/package.json +1 -1
  80. package/dist/esm/components/Spinner/package.json +1 -1
  81. package/dist/esm/components/Switch/package.json +1 -1
  82. package/dist/esm/components/Tabs/package.json +1 -1
  83. package/dist/esm/components/Text/package.json +1 -1
  84. package/dist/esm/components/TextArea/package.json +1 -1
  85. package/dist/esm/components/TextInput/package.json +1 -1
  86. package/dist/esm/components/TextInputGroup/package.json +1 -1
  87. package/dist/esm/components/Tile/package.json +1 -1
  88. package/dist/esm/components/TimePicker/package.json +1 -1
  89. package/dist/esm/components/Timestamp/package.json +1 -1
  90. package/dist/esm/components/Title/package.json +1 -1
  91. package/dist/esm/components/ToggleGroup/package.json +1 -1
  92. package/dist/esm/components/Toolbar/package.json +1 -1
  93. package/dist/esm/components/Tooltip/package.json +1 -1
  94. package/dist/esm/components/TreeView/package.json +1 -1
  95. package/dist/esm/components/Truncate/package.json +1 -1
  96. package/dist/esm/components/Wizard/hooks/package.json +1 -1
  97. package/dist/esm/components/Wizard/package.json +1 -1
  98. package/dist/esm/components/package.json +1 -1
  99. package/dist/esm/deprecated/components/ApplicationLauncher/package.json +1 -1
  100. package/dist/esm/deprecated/components/ContextSelector/package.json +1 -1
  101. package/dist/esm/deprecated/components/Dropdown/package.json +1 -1
  102. package/dist/esm/deprecated/components/OptionsMenu/package.json +1 -1
  103. package/dist/esm/deprecated/components/PageHeader/package.json +1 -1
  104. package/dist/esm/deprecated/components/Select/package.json +1 -1
  105. package/dist/esm/deprecated/components/Wizard/package.json +1 -1
  106. package/dist/esm/deprecated/components/package.json +1 -1
  107. package/dist/esm/deprecated/package.json +1 -1
  108. package/dist/esm/helpers/Popper/thirdparty/popper-core/package.json +1 -1
  109. package/dist/esm/helpers/package.json +1 -1
  110. package/dist/esm/layouts/Bullseye/package.json +1 -1
  111. package/dist/esm/layouts/Flex/package.json +1 -1
  112. package/dist/esm/layouts/Gallery/package.json +1 -1
  113. package/dist/esm/layouts/Grid/package.json +1 -1
  114. package/dist/esm/layouts/Level/package.json +1 -1
  115. package/dist/esm/layouts/Split/package.json +1 -1
  116. package/dist/esm/layouts/Stack/package.json +1 -1
  117. package/dist/esm/layouts/package.json +1 -1
  118. package/dist/esm/next/components/package.json +1 -1
  119. package/dist/esm/next/package.json +1 -1
  120. package/dist/esm/package.json +1 -1
  121. package/dist/js/components/AboutModal/package.json +1 -1
  122. package/dist/js/components/Accordion/package.json +1 -1
  123. package/dist/js/components/ActionList/package.json +1 -1
  124. package/dist/js/components/Alert/package.json +1 -1
  125. package/dist/js/components/Avatar/package.json +1 -1
  126. package/dist/js/components/BackToTop/package.json +1 -1
  127. package/dist/js/components/Backdrop/package.json +1 -1
  128. package/dist/js/components/BackgroundImage/package.json +1 -1
  129. package/dist/js/components/Badge/package.json +1 -1
  130. package/dist/js/components/Banner/package.json +1 -1
  131. package/dist/js/components/Brand/package.json +1 -1
  132. package/dist/js/components/Breadcrumb/package.json +1 -1
  133. package/dist/js/components/Button/package.json +1 -1
  134. package/dist/js/components/CalendarMonth/package.json +1 -1
  135. package/dist/js/components/Card/package.json +1 -1
  136. package/dist/js/components/Checkbox/package.json +1 -1
  137. package/dist/js/components/Chip/package.json +1 -1
  138. package/dist/js/components/ClipboardCopy/package.json +1 -1
  139. package/dist/js/components/CodeBlock/package.json +1 -1
  140. package/dist/js/components/DataList/package.json +1 -1
  141. package/dist/js/components/DatePicker/package.json +1 -1
  142. package/dist/js/components/DescriptionList/package.json +1 -1
  143. package/dist/js/components/Divider/package.json +1 -1
  144. package/dist/js/components/DragDrop/package.json +1 -1
  145. package/dist/js/components/Drawer/package.json +1 -1
  146. package/dist/js/components/Dropdown/Dropdown.d.ts +3 -1
  147. package/dist/js/components/Dropdown/Dropdown.d.ts.map +1 -1
  148. package/dist/js/components/Dropdown/Dropdown.js +3 -4
  149. package/dist/js/components/Dropdown/Dropdown.js.map +1 -1
  150. package/dist/js/components/Dropdown/package.json +1 -1
  151. package/dist/js/components/DualListSelector/package.json +1 -1
  152. package/dist/js/components/EmptyState/package.json +1 -1
  153. package/dist/js/components/ExpandableSection/package.json +1 -1
  154. package/dist/js/components/FileUpload/package.json +1 -1
  155. package/dist/js/components/Form/package.json +1 -1
  156. package/dist/js/components/FormSelect/package.json +1 -1
  157. package/dist/js/components/HelperText/package.json +1 -1
  158. package/dist/js/components/Hint/package.json +1 -1
  159. package/dist/js/components/Icon/package.json +1 -1
  160. package/dist/js/components/InputGroup/package.json +1 -1
  161. package/dist/js/components/JumpLinks/package.json +1 -1
  162. package/dist/js/components/Label/package.json +1 -1
  163. package/dist/js/components/List/package.json +1 -1
  164. package/dist/js/components/LoginPage/package.json +1 -1
  165. package/dist/js/components/Masthead/package.json +1 -1
  166. package/dist/js/components/Menu/Menu.js +7 -4
  167. package/dist/js/components/Menu/Menu.js.map +1 -1
  168. package/dist/js/components/Menu/MenuContainer.d.ts +42 -0
  169. package/dist/js/components/Menu/MenuContainer.d.ts.map +1 -0
  170. package/dist/js/components/Menu/MenuContainer.js +52 -0
  171. package/dist/js/components/Menu/MenuContainer.js.map +1 -0
  172. package/dist/js/components/Menu/index.d.ts +1 -0
  173. package/dist/js/components/Menu/index.d.ts.map +1 -1
  174. package/dist/js/components/Menu/index.js +1 -0
  175. package/dist/js/components/Menu/index.js.map +1 -1
  176. package/dist/js/components/Menu/package.json +1 -1
  177. package/dist/js/components/MenuToggle/package.json +1 -1
  178. package/dist/js/components/Modal/package.json +1 -1
  179. package/dist/js/components/MultipleFileUpload/package.json +1 -1
  180. package/dist/js/components/Nav/package.json +1 -1
  181. package/dist/js/components/NotificationBadge/package.json +1 -1
  182. package/dist/js/components/NotificationDrawer/package.json +1 -1
  183. package/dist/js/components/NumberInput/package.json +1 -1
  184. package/dist/js/components/OverflowMenu/package.json +1 -1
  185. package/dist/js/components/Page/package.json +1 -1
  186. package/dist/js/components/Pagination/package.json +1 -1
  187. package/dist/js/components/Panel/package.json +1 -1
  188. package/dist/js/components/Popover/package.json +1 -1
  189. package/dist/js/components/Progress/package.json +1 -1
  190. package/dist/js/components/ProgressStepper/package.json +1 -1
  191. package/dist/js/components/Radio/package.json +1 -1
  192. package/dist/js/components/SearchInput/package.json +1 -1
  193. package/dist/js/components/Select/package.json +1 -1
  194. package/dist/js/components/Sidebar/package.json +1 -1
  195. package/dist/js/components/SimpleList/package.json +1 -1
  196. package/dist/js/components/Skeleton/package.json +1 -1
  197. package/dist/js/components/SkipToContent/package.json +1 -1
  198. package/dist/js/components/Slider/package.json +1 -1
  199. package/dist/js/components/Spinner/package.json +1 -1
  200. package/dist/js/components/Switch/package.json +1 -1
  201. package/dist/js/components/Tabs/package.json +1 -1
  202. package/dist/js/components/Text/package.json +1 -1
  203. package/dist/js/components/TextArea/package.json +1 -1
  204. package/dist/js/components/TextInput/package.json +1 -1
  205. package/dist/js/components/TextInputGroup/package.json +1 -1
  206. package/dist/js/components/Tile/package.json +1 -1
  207. package/dist/js/components/TimePicker/package.json +1 -1
  208. package/dist/js/components/Timestamp/package.json +1 -1
  209. package/dist/js/components/Title/package.json +1 -1
  210. package/dist/js/components/ToggleGroup/package.json +1 -1
  211. package/dist/js/components/Toolbar/package.json +1 -1
  212. package/dist/js/components/Tooltip/package.json +1 -1
  213. package/dist/js/components/TreeView/package.json +1 -1
  214. package/dist/js/components/Truncate/package.json +1 -1
  215. package/dist/js/components/Wizard/hooks/package.json +1 -1
  216. package/dist/js/components/Wizard/package.json +1 -1
  217. package/dist/js/components/package.json +1 -1
  218. package/dist/js/deprecated/components/ApplicationLauncher/package.json +1 -1
  219. package/dist/js/deprecated/components/ContextSelector/package.json +1 -1
  220. package/dist/js/deprecated/components/Dropdown/package.json +1 -1
  221. package/dist/js/deprecated/components/OptionsMenu/package.json +1 -1
  222. package/dist/js/deprecated/components/PageHeader/package.json +1 -1
  223. package/dist/js/deprecated/components/Select/package.json +1 -1
  224. package/dist/js/deprecated/components/Wizard/package.json +1 -1
  225. package/dist/js/deprecated/components/package.json +1 -1
  226. package/dist/js/deprecated/package.json +1 -1
  227. package/dist/js/helpers/Popper/thirdparty/popper-core/package.json +1 -1
  228. package/dist/js/helpers/package.json +1 -1
  229. package/dist/js/layouts/Bullseye/package.json +1 -1
  230. package/dist/js/layouts/Flex/package.json +1 -1
  231. package/dist/js/layouts/Gallery/package.json +1 -1
  232. package/dist/js/layouts/Grid/package.json +1 -1
  233. package/dist/js/layouts/Level/package.json +1 -1
  234. package/dist/js/layouts/Split/package.json +1 -1
  235. package/dist/js/layouts/Stack/package.json +1 -1
  236. package/dist/js/layouts/package.json +1 -1
  237. package/dist/js/next/components/package.json +1 -1
  238. package/dist/js/next/package.json +1 -1
  239. package/dist/js/package.json +1 -1
  240. package/dist/umd/react-core.min.js +2 -2
  241. package/package.json +2 -2
  242. package/src/components/Dropdown/Dropdown.tsx +6 -4
  243. package/src/components/Menu/Menu.tsx +2 -2
  244. package/src/components/Menu/MenuContainer.tsx +109 -0
  245. package/src/components/Menu/examples/Menu.md +13 -1
  246. package/src/components/Menu/index.ts +1 -0
  247. package/src/demos/CustomMenus/ApplicationLauncher.md +30 -0
  248. package/src/demos/CustomMenus/ContextSelector.md +30 -0
  249. package/src/demos/CustomMenus/CustomMenus.md +84 -0
  250. package/src/demos/CustomMenus/OptionsMenu.md +17 -0
  251. package/src/demos/{ComposableMenu/examples/ComposableActionsMenu.tsx → CustomMenus/examples/ActionsMenuDemo.tsx} +25 -57
  252. package/src/demos/{ComposableMenu/examples/ComposableApplicationLauncher.tsx → CustomMenus/examples/ApplicationLauncherDemo.tsx} +72 -99
  253. package/src/demos/{ComposableMenu/examples/ComposableContextSelector.tsx → CustomMenus/examples/ContextSelectorDemo.tsx} +43 -80
  254. package/src/demos/CustomMenus/examples/DateSelectDemo.tsx +84 -0
  255. package/src/demos/{ComposableMenu/examples/ComposableDrilldownMenu.tsx → CustomMenus/examples/DrilldownMenuDemo.tsx} +14 -36
  256. package/src/demos/CustomMenus/examples/FavoritesDemo.tsx +120 -0
  257. package/src/demos/{ComposableMenu/examples/ComposableFlyout.tsx → CustomMenus/examples/FlyoutDemo.tsx} +14 -39
  258. package/src/demos/CustomMenus/examples/OptionsMenuDemo.tsx +59 -0
  259. package/src/demos/{ComposableMenu/examples/ComposableTreeViewMenu.tsx → CustomMenus/examples/TreeViewMenuDemo.tsx} +15 -52
  260. package/src/demos/ComposableMenu/ComposableMenu.md +0 -118
  261. package/src/demos/ComposableMenu/examples/ComposableMultipleTypeaheadSelect.tsx +0 -253
  262. package/src/demos/ComposableMenu/examples/ComposableOptionsMenuVariants.tsx +0 -96
  263. package/src/demos/ComposableMenu/examples/ComposableSimpleCheckboxSelect.tsx +0 -101
  264. package/src/demos/ComposableMenu/examples/ComposableSimpleDropdown.tsx +0 -70
  265. package/src/demos/ComposableMenu/examples/ComposableSimpleSelect.tsx +0 -83
  266. package/src/demos/ComposableMenu/examples/ComposableTypeaheadSelect.tsx +0 -234
  267. /package/src/demos/{ComposableMenu → CustomMenus}/examples/ComposableDateSelect.tsx +0 -0
  268. /package/src/demos/{ComposableMenu → CustomMenus}/examples/ComposableDropdwnVariants.tsx +0 -0
  269. /package/src/demos/{ComposableMenu → CustomMenus}/examples/avatarImg.svg +0 -0
  270. /package/src/demos/{ComposableMenu → CustomMenus}/examples/pf-logo-small.svg +0 -0
@@ -0,0 +1,120 @@
1
+ import React from 'react';
2
+ import { MenuToggle, Divider, Dropdown, DropdownGroup, DropdownList, DropdownItem } from '@patternfly/react-core';
3
+
4
+ export const FavoritesDemo: React.FunctionComponent = () => {
5
+ const [isOpen, setIsOpen] = React.useState<boolean>(false);
6
+ const [favorites, setFavorites] = React.useState<string[]>([]);
7
+ const menuRef = React.useRef<HTMLDivElement>(null);
8
+
9
+ const onToggleClick = () => {
10
+ setIsOpen(!isOpen);
11
+ };
12
+
13
+ const menuItems = [
14
+ <DropdownGroup key="group1" label="Group 1">
15
+ <DropdownList>
16
+ <DropdownItem itemId="0" id="0" isFavorited={favorites.includes('0')}>
17
+ Item 1
18
+ </DropdownItem>
19
+ <DropdownItem itemId="1" id="1" isFavorited={favorites.includes('1')}>
20
+ Item 2
21
+ </DropdownItem>
22
+ <DropdownItem itemId="2" id="2" isFavorited={favorites.includes('2')}>
23
+ Item 3
24
+ </DropdownItem>
25
+ <DropdownItem itemId="3" id="3" isFavorited={favorites.includes('3')}>
26
+ Item 4
27
+ </DropdownItem>
28
+ </DropdownList>
29
+ </DropdownGroup>,
30
+ <Divider key="group1-divider" />,
31
+ <DropdownGroup key="group2" label="Group 2">
32
+ <DropdownList>
33
+ <DropdownItem itemId="4" id="4" isFavorited={favorites.includes('4')}>
34
+ Item 5
35
+ </DropdownItem>
36
+ <DropdownItem itemId="5" id="5" isFavorited={favorites.includes('5')}>
37
+ Item 6
38
+ </DropdownItem>
39
+ <DropdownItem itemId="6" id="6" isFavorited={favorites.includes('6')}>
40
+ Item 7
41
+ </DropdownItem>
42
+ <DropdownItem itemId="7" id="7" isFavorited={favorites.includes('7')}>
43
+ Item 8
44
+ </DropdownItem>
45
+ </DropdownList>
46
+ </DropdownGroup>
47
+ ];
48
+
49
+ const createFavorites = (favIds: string[]) => {
50
+ const favorites: JSX.Element[] = [];
51
+
52
+ menuItems.forEach((item) => {
53
+ if (item.type === DropdownList) {
54
+ item.props.children.filter((child) => {
55
+ if (favIds.includes(child.props.itemId)) {
56
+ favorites.push(child);
57
+ }
58
+ });
59
+ } else if (item.type === DropdownGroup) {
60
+ item.props.children.props.children.filter((child) => {
61
+ if (favIds.includes(child.props.itemId)) {
62
+ favorites.push(child);
63
+ }
64
+ });
65
+ } else {
66
+ if (favIds.includes(item.props.itemId)) {
67
+ favorites.push(item);
68
+ }
69
+ }
70
+ });
71
+
72
+ return favorites;
73
+ };
74
+
75
+ React.useEffect(() => {
76
+ if (favorites.length === 0) {
77
+ const firstElement = menuRef?.current?.querySelector('li > button:not(:disabled)');
78
+ firstElement && (firstElement as HTMLElement).focus();
79
+ }
80
+ }, [favorites]);
81
+
82
+ const onFavorite = (event: any, itemId: string, actionId: string) => {
83
+ event.stopPropagation();
84
+ if (actionId === 'fav') {
85
+ const isFavorite = favorites.includes(itemId);
86
+ if (isFavorite) {
87
+ setFavorites(favorites.filter((fav) => fav !== itemId));
88
+ } else {
89
+ setFavorites([...favorites, itemId]);
90
+ }
91
+ }
92
+ };
93
+
94
+ return (
95
+ // eslint-disable-next-line no-console
96
+ <Dropdown
97
+ isOpen={isOpen}
98
+ onOpenChange={(isOpen) => setIsOpen(isOpen)}
99
+ toggle={(toggleRef) => (
100
+ <MenuToggle ref={toggleRef} onClick={onToggleClick} isExpanded={isOpen}>
101
+ {isOpen ? 'Expanded' : 'Collapsed'}
102
+ </MenuToggle>
103
+ )}
104
+ ref={menuRef}
105
+ onActionClick={onFavorite}
106
+ // eslint-disable-next-line no-console
107
+ onSelect={(_ev, itemId) => console.log('selected', itemId)}
108
+ >
109
+ {favorites.length > 0 && (
110
+ <React.Fragment>
111
+ <DropdownGroup key="favorites-group" label="Favorites">
112
+ <DropdownList>{createFavorites(favorites)}</DropdownList>
113
+ </DropdownGroup>
114
+ <Divider key="favorites-divider" />
115
+ </React.Fragment>
116
+ )}
117
+ {menuItems}
118
+ </Dropdown>
119
+ );
120
+ };
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { MenuToggle, Menu, MenuContent, MenuList, MenuItem, Popper } from '@patternfly/react-core';
2
+ import { MenuToggle, Menu, MenuContent, MenuList, MenuItem, MenuContainer } from '@patternfly/react-core';
3
3
 
4
4
  /* eslint-disable no-console */
5
5
  const onSelect = (event: React.MouseEvent | undefined, itemId: string | number | undefined) =>
@@ -30,56 +30,22 @@ const FlyoutMenu: React.FunctionComponent<FlyoutMenuProps> = ({ depth, children
30
30
  </Menu>
31
31
  );
32
32
 
33
- export const ComposableFlyout: React.FunctionComponent = () => {
33
+ export const FlyoutDemo: React.FunctionComponent = () => {
34
34
  const [isOpen, setIsOpen] = React.useState<boolean>(false);
35
35
  const menuRef = React.useRef<HTMLDivElement>(null);
36
36
  const toggleRef = React.useRef<HTMLButtonElement>(null);
37
37
 
38
- const handleMenuKeys = (event: KeyboardEvent) => {
39
- if (!isOpen) {
40
- return;
41
- }
42
- if (menuRef.current?.contains(event.target as Node) || toggleRef.current?.contains(event.target as Node)) {
43
- if (event.key === 'Escape' || event.key === 'Tab') {
44
- setIsOpen(!isOpen);
45
- toggleRef.current?.focus();
46
- }
47
- }
48
- };
49
-
50
- const handleClickOutside = (event: MouseEvent) => {
51
- if (isOpen && !menuRef.current?.contains(event.target as Node)) {
52
- setIsOpen(false);
53
- }
54
- };
55
-
56
- React.useEffect(() => {
57
- window.addEventListener('keydown', handleMenuKeys);
58
- window.addEventListener('click', handleClickOutside);
59
- return () => {
60
- window.removeEventListener('keydown', handleMenuKeys);
61
- window.removeEventListener('click', handleClickOutside);
62
- };
63
- }, [isOpen, menuRef]);
64
-
65
38
  let curFlyout = <FlyoutMenu depth={1} />;
66
39
  for (let i = 2; i < 14; i++) {
67
40
  curFlyout = <FlyoutMenu depth={i}>{curFlyout}</FlyoutMenu>;
68
41
  }
69
42
 
70
- const onToggleClick = (ev: React.MouseEvent) => {
71
- ev.stopPropagation(); // Stop handleClickOutside from handling
72
- setTimeout(() => {
73
- if (menuRef.current) {
74
- const firstElement = menuRef.current.querySelector('li > button:not(:disabled), li > a:not(:disabled)');
75
- firstElement && (firstElement as HTMLElement).focus();
76
- }
77
- }, 0);
43
+ const onToggleClick = () => {
78
44
  setIsOpen(!isOpen);
79
45
  };
80
46
 
81
47
  const toggle = (
82
- <MenuToggle onClick={onToggleClick} isExpanded={isOpen}>
48
+ <MenuToggle ref={toggleRef} onClick={onToggleClick} isExpanded={isOpen}>
83
49
  {isOpen ? 'Expanded' : 'Collapsed'}
84
50
  </MenuToggle>
85
51
  );
@@ -100,5 +66,14 @@ export const ComposableFlyout: React.FunctionComponent = () => {
100
66
  </Menu>
101
67
  );
102
68
 
103
- return <Popper trigger={toggle} triggerRef={toggleRef} popper={menu} popperRef={menuRef} isVisible={isOpen} />;
69
+ return (
70
+ <MenuContainer
71
+ isOpen={isOpen}
72
+ onOpenChange={(isOpen) => setIsOpen(isOpen)}
73
+ menu={menu}
74
+ menuRef={menuRef}
75
+ toggle={toggle}
76
+ toggleRef={toggleRef}
77
+ />
78
+ );
104
79
  };
@@ -0,0 +1,59 @@
1
+ import React from 'react';
2
+ import { MenuToggle, Divider, Select, SelectList, SelectOption, SelectGroup } from '@patternfly/react-core';
3
+
4
+ export const OptionsMenuDemo: React.FunctionComponent = () => {
5
+ const [isOpen, setIsOpen] = React.useState<boolean>(false);
6
+ const [selected, setSelected] = React.useState<string>('');
7
+ const menuRef = React.useRef<HTMLDivElement>();
8
+
9
+ const onToggleClick = () => {
10
+ setIsOpen(!isOpen);
11
+ };
12
+
13
+ return (
14
+ <Select
15
+ isOpen={isOpen}
16
+ onOpenChange={(isOpen) => setIsOpen(isOpen)}
17
+ toggle={(toggleRef) => (
18
+ <MenuToggle ref={toggleRef} onClick={onToggleClick} isExpanded={isOpen}>
19
+ Options menu
20
+ </MenuToggle>
21
+ )}
22
+ ref={menuRef}
23
+ id="options-menu"
24
+ selected={selected}
25
+ onSelect={(_ev, itemId) => itemId && setSelected(itemId.toString())}
26
+ >
27
+ <SelectList>
28
+ <SelectOption itemId="0" isSelected={selected === '0'}>
29
+ Option 1
30
+ </SelectOption>
31
+ <SelectOption itemId="1" isSelected={selected === '1'} isDisabled>
32
+ Disabled Option
33
+ </SelectOption>
34
+ <Divider key="group1-divider" />
35
+ <SelectGroup label="Group 1">
36
+ <SelectList>
37
+ <SelectOption itemId="2" isSelected={selected === '2'}>
38
+ Option 1
39
+ </SelectOption>
40
+ <SelectOption itemId="3" isSelected={selected === '3'}>
41
+ Option 2
42
+ </SelectOption>
43
+ </SelectList>
44
+ </SelectGroup>
45
+ <Divider key="group2-divider" />
46
+ <SelectGroup label="Group 2">
47
+ <SelectList>
48
+ <SelectOption itemId="4" isSelected={selected === '4'}>
49
+ Option 1
50
+ </SelectOption>
51
+ <SelectOption itemId="5" isSelected={selected === '5'}>
52
+ Option 2
53
+ </SelectOption>
54
+ </SelectList>
55
+ </SelectGroup>
56
+ </SelectList>
57
+ </Select>
58
+ );
59
+ };
@@ -5,12 +5,12 @@ import {
5
5
  PanelMain,
6
6
  PanelMainBody,
7
7
  Title,
8
- Popper,
8
+ MenuContainer,
9
9
  TreeView,
10
10
  TreeViewDataItem
11
11
  } from '@patternfly/react-core';
12
12
 
13
- export const ComposableTreeViewMenu: React.FunctionComponent = () => {
13
+ export const TreeViewMenuDemo: React.FunctionComponent = () => {
14
14
  const [isOpen, setIsOpen] = React.useState<boolean>(false);
15
15
  const [checkedItems, setCheckedItems] = React.useState<TreeViewDataItem[]>([]);
16
16
  const toggleRef = React.useRef<HTMLButtonElement>(null);
@@ -166,55 +166,7 @@ export const ComposableTreeViewMenu: React.FunctionComponent = () => {
166
166
  );
167
167
  };
168
168
 
169
- // Controls keys that should open/close the menu
170
- const handleMenuKeys = (event: KeyboardEvent) => {
171
- if (!isOpen) {
172
- return;
173
- }
174
- if (menuRef.current?.contains(event.target as Node) || toggleRef.current?.contains(event.target as Node)) {
175
- // The escape key when pressed while inside the menu should close the menu and refocus the toggle
176
- if (event.key === 'Escape') {
177
- setIsOpen(!isOpen);
178
- toggleRef.current?.focus();
179
- }
180
-
181
- // The tab key when pressed while inside the menu and on the contained last tree view should close the menu and refocus the toggle
182
- // Shift tab should keep the default behavior to return to a previous tree view
183
- if (event.key === 'Tab' && !event.shiftKey) {
184
- const treeList = menuRef.current?.querySelectorAll('.pf-c-tree-view') || [];
185
- if (treeList[treeList.length - 1].contains(event.target as Node)) {
186
- event.preventDefault();
187
- setIsOpen(!isOpen);
188
- toggleRef.current?.focus();
189
- }
190
- }
191
- }
192
- };
193
-
194
- // Controls that a click outside the menu while the menu is open should close the menu
195
- const handleClickOutside = (event: MouseEvent) => {
196
- if (isOpen && !menuRef.current?.contains(event.target as Node)) {
197
- setIsOpen(false);
198
- }
199
- };
200
-
201
- React.useEffect(() => {
202
- window.addEventListener('keydown', handleMenuKeys);
203
- window.addEventListener('click', handleClickOutside);
204
- return () => {
205
- window.removeEventListener('keydown', handleMenuKeys);
206
- window.removeEventListener('click', handleClickOutside);
207
- };
208
- }, [isOpen, menuRef]);
209
-
210
- const onToggleClick = (ev: React.MouseEvent) => {
211
- ev.stopPropagation(); // Stop handleClickOutside from handling
212
- setTimeout(() => {
213
- if (menuRef.current) {
214
- const firstElement = menuRef.current.querySelector('li > button:not(:disabled), li > a:not(:disabled)');
215
- firstElement && (firstElement as HTMLElement).focus();
216
- }
217
- }, 0);
169
+ const onToggleClick = () => {
218
170
  setIsOpen(!isOpen);
219
171
  };
220
172
 
@@ -267,5 +219,16 @@ export const ComposableTreeViewMenu: React.FunctionComponent = () => {
267
219
  </PanelMain>
268
220
  </Panel>
269
221
  );
270
- return <Popper trigger={toggle} triggerRef={toggleRef} popper={menu} popperRef={menuRef} isVisible={isOpen} />;
222
+
223
+ return (
224
+ <MenuContainer
225
+ isOpen={isOpen}
226
+ onOpenChange={(isOpen) => setIsOpen(isOpen)}
227
+ onOpenChangeKeys={['Escape']}
228
+ menu={menu}
229
+ menuRef={menuRef}
230
+ toggle={toggle}
231
+ toggleRef={toggleRef}
232
+ />
233
+ );
271
234
  };
@@ -1,118 +0,0 @@
1
- ---
2
- id: Custom menus
3
- section: components
4
- subsection: menus
5
- ---
6
-
7
- import { Link } from '@reach/router';
8
-
9
- import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
10
- import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
11
- import TableIcon from '@patternfly/react-icons/dist/esm/icons/table-icon';
12
- import StorageDomainIcon from '@patternfly/react-icons/dist/esm/icons/storage-domain-icon';
13
- import CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-icon';
14
- import LayerGroupIcon from '@patternfly/react-icons/dist/esm/icons/layer-group-icon';
15
- import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';
16
- import BarsIcon from '@patternfly/react-icons/dist/esm/icons/bars-icon';
17
- import ClipboardIcon from '@patternfly/react-icons/dist/esm/icons/clipboard-icon';
18
- import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';
19
- import ThIcon from '@patternfly/react-icons/dist/esm/icons/th-icon';
20
- import pfIcon from './examples/pf-logo-small.svg';
21
- import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
22
- import CaretDownIcon from '@patternfly/react-icons/dist/esm/icons/caret-down-icon';
23
- import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
24
- import avatarImg from './examples/avatarImg.svg';
25
- import { css } from '@patternfly/react-styles';
26
- import styles from '@patternfly/react-styles/css/components/Menu/menu';
27
-
28
- ## Demos
29
-
30
- Custom menus can be constructed using a composable approach by combining the [Menu](/components/menus/menu) and [Menu toggle](/components/menus/menu-toggle) components in unique ways. Composable menus currently require consumer keyboard handling and use of our undocumented [popper.js](https://popper.js.org/) wrapper component called Popper. We understand this is inconvientent boilerplate and these examples will be updated to use [Dropdown](/components/dropdown) in a future release.
31
-
32
- ### Composable simple dropdown
33
-
34
- ```ts file="./examples/ComposableSimpleDropdown.tsx"
35
-
36
- ```
37
-
38
- ### Composable actions menu
39
-
40
- ```ts file="./examples/ComposableActionsMenu.tsx"
41
-
42
- ```
43
-
44
- ### Composable simple select
45
-
46
- ```ts file="./examples/ComposableSimpleSelect.tsx"
47
-
48
- ```
49
-
50
- ### Composable simple checkbox select
51
-
52
- ```ts file="./examples/ComposableSimpleCheckboxSelect.tsx"
53
-
54
- ```
55
-
56
- ### Composable typeahead select
57
-
58
- ```ts file="./examples/ComposableTypeaheadSelect.tsx"
59
-
60
- ```
61
-
62
- ### Composable multiple typeahead select
63
-
64
- ```ts file="./examples/ComposableMultipleTypeaheadSelect.tsx"
65
-
66
- ```
67
-
68
- ### Composable drilldown menu
69
-
70
- ```ts isBeta file="./examples/ComposableDrilldownMenu.tsx"
71
-
72
- ```
73
-
74
- ### Composable tree view menu
75
-
76
- When rendering a menu-like element that does not contain MenuItem components, [Panel](/components/panel) allows more flexible control and customization.
77
-
78
- ```ts file="./examples/ComposableTreeViewMenu.tsx"
79
-
80
- ```
81
-
82
- ### Composable flyout
83
-
84
- The flyout will automatically position to the left or top if it would otherwise go outside the window. The menu must be placed in a container outside the main content like Popper, [Popover](/components/popover) or [Tooltip](/components/tooltip) since it may go over the side nav.
85
-
86
- ```ts isBeta file="./examples/ComposableFlyout.tsx"
87
-
88
- ```
89
-
90
- ### Composable application launcher
91
-
92
- ```ts file="./examples/ComposableApplicationLauncher.tsx"
93
-
94
- ```
95
-
96
- ### Composable context selector
97
-
98
- ```ts file="./examples/ComposableContextSelector.tsx"
99
-
100
- ```
101
-
102
- ### Composable options menu variants
103
-
104
- ```ts file="./examples/ComposableOptionsMenuVariants.tsx"
105
-
106
- ```
107
-
108
- ### Composable dropdown variants
109
-
110
- ```ts file="./examples/ComposableDropdwnVariants.tsx"
111
-
112
- ```
113
-
114
- ### Composable date select
115
-
116
- ```ts file="./examples/ComposableDateSelect.tsx"
117
-
118
- ```