@patternfly/react-core 5.3.0-prerelease.3 → 5.3.0-prerelease.4

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 (251) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/components/package.json +1 -1
  3. package/deprecated/package.json +1 -1
  4. package/dist/dynamic/components/AboutModal/package.json +1 -1
  5. package/dist/dynamic/components/Accordion/package.json +1 -1
  6. package/dist/dynamic/components/ActionList/package.json +1 -1
  7. package/dist/dynamic/components/Alert/package.json +1 -1
  8. package/dist/dynamic/components/Avatar/package.json +1 -1
  9. package/dist/dynamic/components/BackToTop/package.json +1 -1
  10. package/dist/dynamic/components/Backdrop/package.json +1 -1
  11. package/dist/dynamic/components/BackgroundImage/package.json +1 -1
  12. package/dist/dynamic/components/Badge/package.json +1 -1
  13. package/dist/dynamic/components/Banner/package.json +1 -1
  14. package/dist/dynamic/components/Brand/package.json +1 -1
  15. package/dist/dynamic/components/Breadcrumb/package.json +1 -1
  16. package/dist/dynamic/components/Button/package.json +1 -1
  17. package/dist/dynamic/components/CalendarMonth/package.json +1 -1
  18. package/dist/dynamic/components/Card/package.json +1 -1
  19. package/dist/dynamic/components/Checkbox/package.json +1 -1
  20. package/dist/dynamic/components/Chip/package.json +1 -1
  21. package/dist/dynamic/components/ClipboardCopy/package.json +1 -1
  22. package/dist/dynamic/components/CodeBlock/package.json +1 -1
  23. package/dist/dynamic/components/DataList/package.json +1 -1
  24. package/dist/dynamic/components/DatePicker/package.json +1 -1
  25. package/dist/dynamic/components/DescriptionList/package.json +1 -1
  26. package/dist/dynamic/components/Divider/package.json +1 -1
  27. package/dist/dynamic/components/DragDrop/package.json +1 -1
  28. package/dist/dynamic/components/Drawer/package.json +1 -1
  29. package/dist/dynamic/components/Dropdown/package.json +1 -1
  30. package/dist/dynamic/components/DualListSelector/package.json +1 -1
  31. package/dist/dynamic/components/EmptyState/package.json +1 -1
  32. package/dist/dynamic/components/ExpandableSection/package.json +1 -1
  33. package/dist/dynamic/components/FileUpload/package.json +1 -1
  34. package/dist/dynamic/components/Form/package.json +1 -1
  35. package/dist/dynamic/components/FormSelect/package.json +1 -1
  36. package/dist/dynamic/components/HelperText/package.json +1 -1
  37. package/dist/dynamic/components/Hint/package.json +1 -1
  38. package/dist/dynamic/components/Icon/package.json +1 -1
  39. package/dist/dynamic/components/InputGroup/package.json +1 -1
  40. package/dist/dynamic/components/JumpLinks/package.json +1 -1
  41. package/dist/dynamic/components/Label/package.json +1 -1
  42. package/dist/dynamic/components/List/package.json +1 -1
  43. package/dist/dynamic/components/LoginPage/package.json +1 -1
  44. package/dist/dynamic/components/Masthead/package.json +1 -1
  45. package/dist/dynamic/components/Menu/package.json +1 -1
  46. package/dist/dynamic/components/MenuToggle/package.json +1 -1
  47. package/dist/dynamic/components/Modal/package.json +1 -1
  48. package/dist/dynamic/components/MultipleFileUpload/package.json +1 -1
  49. package/dist/dynamic/components/Nav/package.json +1 -1
  50. package/dist/dynamic/components/NotificationBadge/package.json +1 -1
  51. package/dist/dynamic/components/NotificationDrawer/package.json +1 -1
  52. package/dist/dynamic/components/NumberInput/package.json +1 -1
  53. package/dist/dynamic/components/OverflowMenu/package.json +1 -1
  54. package/dist/dynamic/components/Page/package.json +1 -1
  55. package/dist/dynamic/components/Pagination/package.json +1 -1
  56. package/dist/dynamic/components/Panel/package.json +1 -1
  57. package/dist/dynamic/components/Popover/package.json +1 -1
  58. package/dist/dynamic/components/Progress/package.json +1 -1
  59. package/dist/dynamic/components/ProgressStepper/package.json +1 -1
  60. package/dist/dynamic/components/Radio/package.json +1 -1
  61. package/dist/dynamic/components/SearchInput/package.json +1 -1
  62. package/dist/dynamic/components/Select/package.json +1 -1
  63. package/dist/dynamic/components/Sidebar/package.json +1 -1
  64. package/dist/dynamic/components/SimpleList/package.json +1 -1
  65. package/dist/dynamic/components/Skeleton/package.json +1 -1
  66. package/dist/dynamic/components/SkipToContent/package.json +1 -1
  67. package/dist/dynamic/components/Slider/package.json +1 -1
  68. package/dist/dynamic/components/Spinner/package.json +1 -1
  69. package/dist/dynamic/components/Switch/package.json +1 -1
  70. package/dist/dynamic/components/Tabs/package.json +1 -1
  71. package/dist/dynamic/components/Text/package.json +1 -1
  72. package/dist/dynamic/components/TextArea/package.json +1 -1
  73. package/dist/dynamic/components/TextInput/package.json +1 -1
  74. package/dist/dynamic/components/TextInputGroup/package.json +1 -1
  75. package/dist/dynamic/components/Tile/package.json +1 -1
  76. package/dist/dynamic/components/TimePicker/package.json +1 -1
  77. package/dist/dynamic/components/Timestamp/package.json +1 -1
  78. package/dist/dynamic/components/Title/package.json +1 -1
  79. package/dist/dynamic/components/ToggleGroup/package.json +1 -1
  80. package/dist/dynamic/components/Toolbar/package.json +1 -1
  81. package/dist/dynamic/components/Tooltip/package.json +1 -1
  82. package/dist/dynamic/components/TreeView/package.json +1 -1
  83. package/dist/dynamic/components/Truncate/package.json +1 -1
  84. package/dist/dynamic/components/Wizard/hooks/package.json +1 -1
  85. package/dist/dynamic/components/Wizard/package.json +1 -1
  86. package/dist/dynamic/deprecated/components/ApplicationLauncher/package.json +1 -1
  87. package/dist/dynamic/deprecated/components/ContextSelector/package.json +1 -1
  88. package/dist/dynamic/deprecated/components/Dropdown/package.json +1 -1
  89. package/dist/dynamic/deprecated/components/OptionsMenu/package.json +1 -1
  90. package/dist/dynamic/deprecated/components/PageHeader/package.json +1 -1
  91. package/dist/dynamic/deprecated/components/Select/package.json +1 -1
  92. package/dist/dynamic/deprecated/components/Wizard/package.json +1 -1
  93. package/dist/dynamic/deprecated/components/package.json +1 -1
  94. package/dist/dynamic/helpers/FocusTrap/FocusTrap/package.json +1 -1
  95. package/dist/dynamic/helpers/GenerateId/GenerateId/package.json +1 -1
  96. package/dist/dynamic/helpers/KeyboardHandler/package.json +1 -1
  97. package/dist/dynamic/helpers/OUIA/ouia/package.json +1 -1
  98. package/dist/dynamic/helpers/Popper/Popper/package.json +1 -1
  99. package/dist/dynamic/helpers/constants/package.json +1 -1
  100. package/dist/dynamic/helpers/datetimeUtils/package.json +1 -1
  101. package/dist/dynamic/helpers/favorites/package.json +1 -1
  102. package/dist/dynamic/helpers/fileUtils/package.json +1 -1
  103. package/dist/dynamic/helpers/htmlConstants/package.json +1 -1
  104. package/dist/dynamic/helpers/package.json +1 -1
  105. package/dist/dynamic/helpers/resizeObserver/package.json +1 -1
  106. package/dist/dynamic/helpers/typeUtils/package.json +1 -1
  107. package/dist/dynamic/helpers/useInterval/package.json +1 -1
  108. package/dist/dynamic/helpers/useIsomorphicLayout/package.json +1 -1
  109. package/dist/dynamic/helpers/useUnmountEffect/package.json +1 -1
  110. package/dist/dynamic/helpers/util/package.json +1 -1
  111. package/dist/dynamic/layouts/Bullseye/package.json +1 -1
  112. package/dist/dynamic/layouts/Flex/package.json +1 -1
  113. package/dist/dynamic/layouts/Gallery/package.json +1 -1
  114. package/dist/dynamic/layouts/Grid/package.json +1 -1
  115. package/dist/dynamic/layouts/Level/package.json +1 -1
  116. package/dist/dynamic/layouts/Split/package.json +1 -1
  117. package/dist/dynamic/layouts/Stack/package.json +1 -1
  118. package/dist/dynamic/next/components/DualListSelector/package.json +1 -0
  119. package/dist/dynamic/next/components/Modal/package.json +1 -1
  120. package/dist/dynamic/next/components/package.json +1 -1
  121. package/dist/dynamic/styles/package.json +1 -1
  122. package/dist/esm/next/components/DualListSelector/DualListSelector.d.ts +23 -0
  123. package/dist/esm/next/components/DualListSelector/DualListSelector.d.ts.map +1 -0
  124. package/dist/esm/next/components/DualListSelector/DualListSelector.js +23 -0
  125. package/dist/esm/next/components/DualListSelector/DualListSelector.js.map +1 -0
  126. package/dist/esm/next/components/DualListSelector/DualListSelectorContext.d.ts +19 -0
  127. package/dist/esm/next/components/DualListSelector/DualListSelectorContext.d.ts.map +1 -0
  128. package/dist/esm/next/components/DualListSelector/DualListSelectorContext.js +5 -0
  129. package/dist/esm/next/components/DualListSelector/DualListSelectorContext.js.map +1 -0
  130. package/dist/esm/next/components/DualListSelector/DualListSelectorControl.d.ts +25 -0
  131. package/dist/esm/next/components/DualListSelector/DualListSelectorControl.d.ts.map +1 -0
  132. package/dist/esm/next/components/DualListSelector/DualListSelectorControl.js +18 -0
  133. package/dist/esm/next/components/DualListSelector/DualListSelectorControl.js.map +1 -0
  134. package/dist/esm/next/components/DualListSelector/DualListSelectorControlsWrapper.d.ts +15 -0
  135. package/dist/esm/next/components/DualListSelector/DualListSelectorControlsWrapper.d.ts.map +1 -0
  136. package/dist/esm/next/components/DualListSelector/DualListSelectorControlsWrapper.js +35 -0
  137. package/dist/esm/next/components/DualListSelector/DualListSelectorControlsWrapper.js.map +1 -0
  138. package/dist/esm/next/components/DualListSelector/DualListSelectorList.d.ts +8 -0
  139. package/dist/esm/next/components/DualListSelector/DualListSelectorList.d.ts.map +1 -0
  140. package/dist/esm/next/components/DualListSelector/DualListSelectorList.js +26 -0
  141. package/dist/esm/next/components/DualListSelector/DualListSelectorList.js.map +1 -0
  142. package/dist/esm/next/components/DualListSelector/DualListSelectorListItem.d.ts +29 -0
  143. package/dist/esm/next/components/DualListSelector/DualListSelectorListItem.d.ts.map +1 -0
  144. package/dist/esm/next/components/DualListSelector/DualListSelectorListItem.js +38 -0
  145. package/dist/esm/next/components/DualListSelector/DualListSelectorListItem.js.map +1 -0
  146. package/dist/esm/next/components/DualListSelector/DualListSelectorListWrapper.d.ts +24 -0
  147. package/dist/esm/next/components/DualListSelector/DualListSelectorListWrapper.d.ts.map +1 -0
  148. package/dist/esm/next/components/DualListSelector/DualListSelectorListWrapper.js +59 -0
  149. package/dist/esm/next/components/DualListSelector/DualListSelectorListWrapper.js.map +1 -0
  150. package/dist/esm/next/components/DualListSelector/DualListSelectorPane.d.ts +31 -0
  151. package/dist/esm/next/components/DualListSelector/DualListSelectorPane.d.ts.map +1 -0
  152. package/dist/esm/next/components/DualListSelector/DualListSelectorPane.js +27 -0
  153. package/dist/esm/next/components/DualListSelector/DualListSelectorPane.js.map +1 -0
  154. package/dist/esm/next/components/DualListSelector/DualListSelectorTree.d.ts +48 -0
  155. package/dist/esm/next/components/DualListSelector/DualListSelectorTree.d.ts.map +1 -0
  156. package/dist/esm/next/components/DualListSelector/DualListSelectorTree.js +15 -0
  157. package/dist/esm/next/components/DualListSelector/DualListSelectorTree.js.map +1 -0
  158. package/dist/esm/next/components/DualListSelector/DualListSelectorTreeItem.d.ts +32 -0
  159. package/dist/esm/next/components/DualListSelector/DualListSelectorTreeItem.d.ts.map +1 -0
  160. package/dist/esm/next/components/DualListSelector/DualListSelectorTreeItem.js +75 -0
  161. package/dist/esm/next/components/DualListSelector/DualListSelectorTreeItem.js.map +1 -0
  162. package/dist/esm/next/components/DualListSelector/index.d.ts +8 -0
  163. package/dist/esm/next/components/DualListSelector/index.d.ts.map +1 -0
  164. package/dist/esm/next/components/DualListSelector/index.js +8 -0
  165. package/dist/esm/next/components/DualListSelector/index.js.map +1 -0
  166. package/dist/esm/next/components/DualListSelector/treeUtils.d.ts +8 -0
  167. package/dist/esm/next/components/DualListSelector/treeUtils.d.ts.map +1 -0
  168. package/dist/esm/next/components/DualListSelector/treeUtils.js +68 -0
  169. package/dist/esm/next/components/DualListSelector/treeUtils.js.map +1 -0
  170. package/dist/esm/next/components/index.d.ts +1 -0
  171. package/dist/esm/next/components/index.d.ts.map +1 -1
  172. package/dist/esm/next/components/index.js +1 -0
  173. package/dist/esm/next/components/index.js.map +1 -1
  174. package/dist/js/next/components/DualListSelector/DualListSelector.d.ts +23 -0
  175. package/dist/js/next/components/DualListSelector/DualListSelector.d.ts.map +1 -0
  176. package/dist/js/next/components/DualListSelector/DualListSelector.js +26 -0
  177. package/dist/js/next/components/DualListSelector/DualListSelector.js.map +1 -0
  178. package/dist/js/next/components/DualListSelector/DualListSelectorContext.d.ts +19 -0
  179. package/dist/js/next/components/DualListSelector/DualListSelectorContext.d.ts.map +1 -0
  180. package/dist/js/next/components/DualListSelector/DualListSelectorContext.js +9 -0
  181. package/dist/js/next/components/DualListSelector/DualListSelectorContext.js.map +1 -0
  182. package/dist/js/next/components/DualListSelector/DualListSelectorControl.d.ts +25 -0
  183. package/dist/js/next/components/DualListSelector/DualListSelectorControl.d.ts.map +1 -0
  184. package/dist/js/next/components/DualListSelector/DualListSelectorControl.js +22 -0
  185. package/dist/js/next/components/DualListSelector/DualListSelectorControl.js.map +1 -0
  186. package/dist/js/next/components/DualListSelector/DualListSelectorControlsWrapper.d.ts +15 -0
  187. package/dist/js/next/components/DualListSelector/DualListSelectorControlsWrapper.d.ts.map +1 -0
  188. package/dist/js/next/components/DualListSelector/DualListSelectorControlsWrapper.js +39 -0
  189. package/dist/js/next/components/DualListSelector/DualListSelectorControlsWrapper.js.map +1 -0
  190. package/dist/js/next/components/DualListSelector/DualListSelectorList.d.ts +8 -0
  191. package/dist/js/next/components/DualListSelector/DualListSelectorList.d.ts.map +1 -0
  192. package/dist/js/next/components/DualListSelector/DualListSelectorList.js +30 -0
  193. package/dist/js/next/components/DualListSelector/DualListSelectorList.js.map +1 -0
  194. package/dist/js/next/components/DualListSelector/DualListSelectorListItem.d.ts +29 -0
  195. package/dist/js/next/components/DualListSelector/DualListSelectorListItem.d.ts.map +1 -0
  196. package/dist/js/next/components/DualListSelector/DualListSelectorListItem.js +42 -0
  197. package/dist/js/next/components/DualListSelector/DualListSelectorListItem.js.map +1 -0
  198. package/dist/js/next/components/DualListSelector/DualListSelectorListWrapper.d.ts +24 -0
  199. package/dist/js/next/components/DualListSelector/DualListSelectorListWrapper.d.ts.map +1 -0
  200. package/dist/js/next/components/DualListSelector/DualListSelectorListWrapper.js +63 -0
  201. package/dist/js/next/components/DualListSelector/DualListSelectorListWrapper.js.map +1 -0
  202. package/dist/js/next/components/DualListSelector/DualListSelectorPane.d.ts +31 -0
  203. package/dist/js/next/components/DualListSelector/DualListSelectorPane.d.ts.map +1 -0
  204. package/dist/js/next/components/DualListSelector/DualListSelectorPane.js +31 -0
  205. package/dist/js/next/components/DualListSelector/DualListSelectorPane.js.map +1 -0
  206. package/dist/js/next/components/DualListSelector/DualListSelectorTree.d.ts +48 -0
  207. package/dist/js/next/components/DualListSelector/DualListSelectorTree.d.ts.map +1 -0
  208. package/dist/js/next/components/DualListSelector/DualListSelectorTree.js +19 -0
  209. package/dist/js/next/components/DualListSelector/DualListSelectorTree.js.map +1 -0
  210. package/dist/js/next/components/DualListSelector/DualListSelectorTreeItem.d.ts +32 -0
  211. package/dist/js/next/components/DualListSelector/DualListSelectorTreeItem.d.ts.map +1 -0
  212. package/dist/js/next/components/DualListSelector/DualListSelectorTreeItem.js +78 -0
  213. package/dist/js/next/components/DualListSelector/DualListSelectorTreeItem.js.map +1 -0
  214. package/dist/js/next/components/DualListSelector/index.d.ts +8 -0
  215. package/dist/js/next/components/DualListSelector/index.d.ts.map +1 -0
  216. package/dist/js/next/components/DualListSelector/index.js +11 -0
  217. package/dist/js/next/components/DualListSelector/index.js.map +1 -0
  218. package/dist/js/next/components/DualListSelector/treeUtils.d.ts +8 -0
  219. package/dist/js/next/components/DualListSelector/treeUtils.d.ts.map +1 -0
  220. package/dist/js/next/components/DualListSelector/treeUtils.js +77 -0
  221. package/dist/js/next/components/DualListSelector/treeUtils.js.map +1 -0
  222. package/dist/js/next/components/index.d.ts +1 -0
  223. package/dist/js/next/components/index.d.ts.map +1 -1
  224. package/dist/js/next/components/index.js +1 -0
  225. package/dist/js/next/components/index.js.map +1 -1
  226. package/helpers/package.json +1 -1
  227. package/layouts/package.json +1 -1
  228. package/next/package.json +1 -1
  229. package/package.json +2 -2
  230. package/src/next/components/DualListSelector/DualListSelector.tsx +50 -0
  231. package/src/next/components/DualListSelector/DualListSelectorContext.ts +21 -0
  232. package/src/next/components/DualListSelector/DualListSelectorControl.tsx +66 -0
  233. package/src/next/components/DualListSelector/DualListSelectorControlsWrapper.tsx +87 -0
  234. package/src/next/components/DualListSelector/DualListSelectorList.tsx +57 -0
  235. package/src/next/components/DualListSelector/DualListSelectorListItem.tsx +105 -0
  236. package/src/next/components/DualListSelector/DualListSelectorListWrapper.tsx +124 -0
  237. package/src/next/components/DualListSelector/DualListSelectorPane.tsx +94 -0
  238. package/src/next/components/DualListSelector/DualListSelectorTree.tsx +110 -0
  239. package/src/next/components/DualListSelector/DualListSelectorTreeItem.tsx +184 -0
  240. package/src/next/components/DualListSelector/__tests__/DualListSelector.test.tsx +26 -0
  241. package/src/next/components/DualListSelector/__tests__/__snapshots__/DualListSelector.test.tsx.snap +122 -0
  242. package/src/next/components/DualListSelector/examples/DualListSelector.md +99 -0
  243. package/src/next/components/DualListSelector/examples/DualListSelectorBasic.tsx +157 -0
  244. package/src/next/components/DualListSelector/examples/DualListSelectorBasicSearch.tsx +214 -0
  245. package/src/next/components/DualListSelector/examples/DualListSelectorBasicTooltips.tsx +165 -0
  246. package/src/next/components/DualListSelector/examples/DualListSelectorComplexOptionsActions.tsx +347 -0
  247. package/src/next/components/DualListSelector/examples/DualListSelectorDragDrop.tsx +184 -0
  248. package/src/next/components/DualListSelector/examples/DualListSelectorTree.tsx +380 -0
  249. package/src/next/components/DualListSelector/index.ts +7 -0
  250. package/src/next/components/DualListSelector/treeUtils.ts +81 -0
  251. package/src/next/components/index.ts +1 -0
@@ -0,0 +1,122 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`DualListSelector basic 1`] = `
4
+ <DocumentFragment>
5
+ <div
6
+ class="pf-v5-c-dual-list-selector__pane pf-m-available"
7
+ >
8
+ <div
9
+ class="pf-v5-c-dual-list-selector__menu"
10
+ tabindex="0"
11
+ >
12
+ <ul
13
+ class="pf-v5-c-dual-list-selector__list"
14
+ />
15
+ </div>
16
+ </div>
17
+ </DocumentFragment>
18
+ `;
19
+
20
+ exports[`DualListSelector basic with disabled controls 1`] = `
21
+ <DocumentFragment>
22
+ <div
23
+ class="pf-v5-c-dual-list-selector__pane pf-m-available"
24
+ >
25
+ <div
26
+ class="pf-v5-c-dual-list-selector__menu"
27
+ tabindex="0"
28
+ >
29
+ <ul
30
+ class="pf-v5-c-dual-list-selector__list"
31
+ />
32
+ </div>
33
+ </div>
34
+ </DocumentFragment>
35
+ `;
36
+
37
+ exports[`DualListSelector with custom status 1`] = `
38
+ <DocumentFragment>
39
+ <div
40
+ class="pf-v5-c-dual-list-selector__pane pf-m-available"
41
+ >
42
+ <div
43
+ class="pf-v5-c-dual-list-selector__status"
44
+ >
45
+ <div
46
+ class="pf-v5-c-dual-list-selector__status-text"
47
+ id="statusTest-status"
48
+ >
49
+ Test status1
50
+ </div>
51
+ </div>
52
+ <div
53
+ class="pf-v5-c-dual-list-selector__menu"
54
+ tabindex="0"
55
+ >
56
+ <ul
57
+ class="pf-v5-c-dual-list-selector__list"
58
+ />
59
+ </div>
60
+ </div>
61
+ </DocumentFragment>
62
+ `;
63
+
64
+ exports[`DualListSelector with search inputs 1`] = `
65
+ <DocumentFragment>
66
+ <div
67
+ class="pf-v5-c-dual-list-selector__pane pf-m-available"
68
+ >
69
+ <div
70
+ class="pf-v5-c-dual-list-selector__tools"
71
+ >
72
+ <div
73
+ class="pf-v5-c-dual-list-selector__tools-filter"
74
+ >
75
+ <div
76
+ class="pf-v5-c-text-input-group"
77
+ >
78
+ <div
79
+ class="pf-v5-c-text-input-group__main pf-m-icon"
80
+ >
81
+ <span
82
+ class="pf-v5-c-text-input-group__text"
83
+ >
84
+ <span
85
+ class="pf-v5-c-text-input-group__icon"
86
+ >
87
+ <svg
88
+ aria-hidden="true"
89
+ class="pf-v5-svg"
90
+ fill="currentColor"
91
+ height="1em"
92
+ role="img"
93
+ viewBox="0 0 512 512"
94
+ width="1em"
95
+ >
96
+ <path
97
+ d="M505 442.7L405.3 343c-4.5-4.5-10.6-7-17-7H372c27.6-35.3 44-79.7 44-128C416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c48.3 0 92.7-16.4 128-44v16.3c0 6.4 2.5 12.5 7 17l99.7 99.7c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.6.1-34zM208 336c-70.7 0-128-57.2-128-128 0-70.7 57.2-128 128-128 70.7 0 128 57.2 128 128 0 70.7-57.2 128-128 128z"
98
+ />
99
+ </svg>
100
+ </span>
101
+ <input
102
+ aria-label="Search input"
103
+ class="pf-v5-c-text-input-group__text-input"
104
+ type="text"
105
+ value=""
106
+ />
107
+ </span>
108
+ </div>
109
+ </div>
110
+ </div>
111
+ </div>
112
+ <div
113
+ class="pf-v5-c-dual-list-selector__menu"
114
+ tabindex="0"
115
+ >
116
+ <ul
117
+ class="pf-v5-c-dual-list-selector__list"
118
+ />
119
+ </div>
120
+ </div>
121
+ </DocumentFragment>
122
+ `;
@@ -0,0 +1,99 @@
1
+ ---
2
+ id: Dual list selector
3
+ section: components
4
+ cssPrefix: 'pf-v5-c-dual-list-selector'
5
+ propComponents:
6
+ [
7
+ 'DualListSelector',
8
+ 'DualListSelectorPane',
9
+ 'DualListSelectorList',
10
+ 'DualListSelectorListItem',
11
+ 'DualListSelectorControlsWrapper',
12
+ 'DualListSelectorControl',
13
+ 'DualListSelectorTree',
14
+ 'DualListSelectorTreeItemData'
15
+ ]
16
+ beta: true
17
+ ---
18
+
19
+ import AngleDoubleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-left-icon';
20
+ import AngleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-left-icon';
21
+ import AngleDoubleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-right-icon';
22
+ import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-icon';
23
+ import PficonSortCommonAscIcon from '@patternfly/react-icons/dist/esm/icons/pficon-sort-common-asc-icon';
24
+ import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
25
+ import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
26
+
27
+ ## Examples
28
+
29
+ The dual list selector is built in a composable manner to make customization easier. The standard sub-component relationships are arranged as follows:
30
+
31
+ ```noLive
32
+ <DualListSelector>
33
+ <DualListSelectorPane>
34
+ <DualListSelectorList>
35
+ <DualListSelectorListItem />
36
+ </DualListSelectorList>
37
+ </DualListSelectorPane>
38
+
39
+ <DualListSelectorControlsWrapper>
40
+ <DualListSelectorControl /> /* A standard Dual list selector has 4 controls */
41
+ </DualListSelectorControlsWrapper>
42
+
43
+ <DualListSelectorPane isChosen>
44
+ <DualListSelectorList>
45
+ <DualListSelectorListItem />
46
+ </DualListSelectorList>
47
+ </DualListSelectorPane>
48
+ </DualListSelector>
49
+ ```
50
+
51
+ ### Basic
52
+
53
+ ```ts file="./DualListSelectorBasic.tsx"
54
+
55
+ ```
56
+
57
+ ### Basic with tooltips
58
+
59
+ ```ts file="./DualListSelectorBasicTooltips.tsx"
60
+
61
+ ```
62
+
63
+ ### Basic with search
64
+
65
+ ```ts file="./DualListSelectorBasicSearch.tsx"
66
+
67
+ ```
68
+
69
+ ### Using more complex options with actions
70
+
71
+ ```ts file="./DualListSelectorComplexOptionsActions.tsx"
72
+
73
+ ```
74
+
75
+ ### With tree
76
+
77
+ ```ts file="DualListSelectorTree.tsx"
78
+
79
+ ```
80
+
81
+ ### Drag and drop
82
+
83
+ This example only allows reordering the contents of the "chosen" pane with drag and drop. To make a pane able to be reordered:
84
+
85
+ - wrap the `DualListSelectorPane` in a `DragDrop` component
86
+ - wrap the `DualListSelectorList` in a `Droppable` component
87
+ - wrap the `DualListSelectorListItem` components in a `Draggable` component
88
+ - define an `onDrop` callback which reorders the sortable options.
89
+ - The `onDrop` function provides the starting location and destination location for a dragged item. It should return
90
+ true to enable the 'drop' animation in the new location and false to enable the 'drop' animation back to the item's
91
+ old position.
92
+ - define an `onDrag` callback which ensures that the drag event will not cross hairs with the `onOptionSelect` click
93
+ event set on the option. Note: the `ignoreNextOptionSelect` state value is used to prevent selection while dragging.
94
+
95
+ Note: Keyboard accessibility and screen reader accessibility for the `DragDrop` component are still in development.
96
+
97
+ ```ts file="DualListSelectorDragDrop.tsx"
98
+
99
+ ```
@@ -0,0 +1,157 @@
1
+ import React from 'react';
2
+ import {
3
+ DualListSelector,
4
+ DualListSelectorPane,
5
+ DualListSelectorList,
6
+ DualListSelectorListItem,
7
+ DualListSelectorControlsWrapper,
8
+ DualListSelectorControl
9
+ } from '@patternfly/react-core';
10
+ import AngleDoubleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-left-icon';
11
+ import AngleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-left-icon';
12
+ import AngleDoubleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-right-icon';
13
+ import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-icon';
14
+
15
+ interface Option {
16
+ text: string;
17
+ selected: boolean;
18
+ isVisible: boolean;
19
+ }
20
+
21
+ export const DualListSelectorBasic: React.FunctionComponent = () => {
22
+ const [availableOptions, setAvailableOptions] = React.useState<Option[]>([
23
+ { text: 'Option 1', selected: false, isVisible: true },
24
+ { text: 'Option 2', selected: false, isVisible: true },
25
+ { text: 'Option 3', selected: false, isVisible: true },
26
+ { text: 'Option 4', selected: false, isVisible: true }
27
+ ]);
28
+ const [chosenOptions, setChosenOptions] = React.useState<Option[]>([]);
29
+
30
+ // callback for moving selected options between lists
31
+ const moveSelected = (fromAvailable: boolean) => {
32
+ const sourceOptions = fromAvailable ? availableOptions : chosenOptions;
33
+ const destinationOptions = fromAvailable ? chosenOptions : availableOptions;
34
+ for (let i = 0; i < sourceOptions.length; i++) {
35
+ const option = sourceOptions[i];
36
+ if (option.selected && option.isVisible) {
37
+ sourceOptions.splice(i, 1);
38
+ destinationOptions.push(option);
39
+ option.selected = false;
40
+ i--;
41
+ }
42
+ }
43
+ if (fromAvailable) {
44
+ setAvailableOptions([...sourceOptions]);
45
+ setChosenOptions([...destinationOptions]);
46
+ } else {
47
+ setChosenOptions([...sourceOptions]);
48
+ setAvailableOptions([...destinationOptions]);
49
+ }
50
+ };
51
+
52
+ // callback for moving all options between lists
53
+ const moveAll = (fromAvailable: boolean) => {
54
+ if (fromAvailable) {
55
+ setChosenOptions([...availableOptions.filter((option) => option.isVisible), ...chosenOptions]);
56
+ setAvailableOptions([...availableOptions.filter((option) => !option.isVisible)]);
57
+ } else {
58
+ setAvailableOptions([...chosenOptions.filter((option) => option.isVisible), ...availableOptions]);
59
+ setChosenOptions([...chosenOptions.filter((option) => !option.isVisible)]);
60
+ }
61
+ };
62
+
63
+ // callback when option is selected
64
+ const onOptionSelect = (
65
+ event: React.MouseEvent | React.ChangeEvent | React.KeyboardEvent,
66
+ index: number,
67
+ isChosen: boolean
68
+ ) => {
69
+ if (isChosen) {
70
+ const newChosen = [...chosenOptions];
71
+ newChosen[index].selected = !chosenOptions[index].selected;
72
+ setChosenOptions(newChosen);
73
+ } else {
74
+ const newAvailable = [...availableOptions];
75
+ newAvailable[index].selected = !availableOptions[index].selected;
76
+ setAvailableOptions(newAvailable);
77
+ }
78
+ };
79
+
80
+ return (
81
+ <DualListSelector>
82
+ <DualListSelectorPane
83
+ title="Available options"
84
+ status={`${availableOptions.filter((option) => option.selected && option.isVisible).length} of ${
85
+ availableOptions.filter((option) => option.isVisible).length
86
+ } options selected`}
87
+ >
88
+ <DualListSelectorList>
89
+ {availableOptions.map((option, index) =>
90
+ option.isVisible ? (
91
+ <DualListSelectorListItem
92
+ key={index}
93
+ isSelected={option.selected}
94
+ id={`basic-available-option-${index}`}
95
+ onOptionSelect={(e) => onOptionSelect(e, index, false)}
96
+ >
97
+ {option.text}
98
+ </DualListSelectorListItem>
99
+ ) : null
100
+ )}
101
+ </DualListSelectorList>
102
+ </DualListSelectorPane>
103
+ <DualListSelectorControlsWrapper>
104
+ <DualListSelectorControl
105
+ isDisabled={!availableOptions.some((option) => option.selected)}
106
+ onClick={() => moveSelected(true)}
107
+ aria-label="Add selected"
108
+ >
109
+ <AngleRightIcon />
110
+ </DualListSelectorControl>
111
+ <DualListSelectorControl
112
+ isDisabled={availableOptions.length === 0}
113
+ onClick={() => moveAll(true)}
114
+ aria-label="Add all"
115
+ >
116
+ <AngleDoubleRightIcon />
117
+ </DualListSelectorControl>
118
+ <DualListSelectorControl
119
+ isDisabled={chosenOptions.length === 0}
120
+ onClick={() => moveAll(false)}
121
+ aria-label="Remove all"
122
+ >
123
+ <AngleDoubleLeftIcon />
124
+ </DualListSelectorControl>
125
+ <DualListSelectorControl
126
+ onClick={() => moveSelected(false)}
127
+ isDisabled={!chosenOptions.some((option) => option.selected)}
128
+ aria-label="Remove selected"
129
+ >
130
+ <AngleLeftIcon />
131
+ </DualListSelectorControl>
132
+ </DualListSelectorControlsWrapper>
133
+ <DualListSelectorPane
134
+ title="Chosen options"
135
+ status={`${chosenOptions.filter((option) => option.selected && option.isVisible).length} of ${
136
+ chosenOptions.filter((option) => option.isVisible).length
137
+ } options selected`}
138
+ isChosen
139
+ >
140
+ <DualListSelectorList>
141
+ {chosenOptions.map((option, index) =>
142
+ option.isVisible ? (
143
+ <DualListSelectorListItem
144
+ key={index}
145
+ isSelected={option.selected}
146
+ id={`composable-basic-chosen-option-${index}`}
147
+ onOptionSelect={(e) => onOptionSelect(e, index, true)}
148
+ >
149
+ {option.text}
150
+ </DualListSelectorListItem>
151
+ ) : null
152
+ )}
153
+ </DualListSelectorList>
154
+ </DualListSelectorPane>
155
+ </DualListSelector>
156
+ );
157
+ };
@@ -0,0 +1,214 @@
1
+ import React from 'react';
2
+ import {
3
+ Button,
4
+ DualListSelector,
5
+ DualListSelectorPane,
6
+ DualListSelectorList,
7
+ DualListSelectorListItem,
8
+ DualListSelectorControlsWrapper,
9
+ DualListSelectorControl,
10
+ SearchInput,
11
+ EmptyState,
12
+ EmptyStateVariant,
13
+ EmptyStateHeader,
14
+ EmptyStateFooter,
15
+ EmptyStateBody,
16
+ EmptyStateIcon,
17
+ EmptyStateActions
18
+ } from '@patternfly/react-core';
19
+ import AngleDoubleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-left-icon';
20
+ import AngleLeftIcon from '@patternfly/react-icons/dist/esm/icons/angle-left-icon';
21
+ import AngleDoubleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-double-right-icon';
22
+ import AngleRightIcon from '@patternfly/react-icons/dist/esm/icons/angle-right-icon';
23
+ import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
24
+
25
+ interface Option {
26
+ text: string;
27
+ selected: boolean;
28
+ isVisible: boolean;
29
+ }
30
+
31
+ export const DualListSelectorSearch: React.FunctionComponent = () => {
32
+ const [availableOptions, setAvailableOptions] = React.useState<Option[]>([
33
+ { text: 'Option 1', selected: false, isVisible: true },
34
+ { text: 'Option 2', selected: false, isVisible: true },
35
+ { text: 'Option 3', selected: false, isVisible: true },
36
+ { text: 'Option 4', selected: false, isVisible: true }
37
+ ]);
38
+
39
+ const [chosenOptions, setChosenOptions] = React.useState<Option[]>([]);
40
+ const [availableFilter, setAvailableFilter] = React.useState('');
41
+ const [chosenFilter, setChosenFilter] = React.useState('');
42
+
43
+ // callback for moving selected options between lists
44
+ const moveSelected = (fromAvailable: boolean) => {
45
+ const sourceOptions = fromAvailable ? availableOptions : chosenOptions;
46
+ const destinationOptions = fromAvailable ? chosenOptions : availableOptions;
47
+ for (let i = 0; i < sourceOptions.length; i++) {
48
+ const option = sourceOptions[i];
49
+ if (option.selected && option.isVisible) {
50
+ sourceOptions.splice(i, 1);
51
+ destinationOptions.push(option);
52
+ option.selected = false;
53
+ i--;
54
+ }
55
+ }
56
+ if (fromAvailable) {
57
+ setAvailableOptions([...sourceOptions]);
58
+ setChosenOptions([...destinationOptions]);
59
+ } else {
60
+ setChosenOptions([...sourceOptions]);
61
+ setAvailableOptions([...destinationOptions]);
62
+ }
63
+ };
64
+
65
+ // callback for moving all options between lists
66
+ const moveAll = (fromAvailable: boolean) => {
67
+ if (fromAvailable) {
68
+ setChosenOptions([...availableOptions.filter((option) => option.isVisible), ...chosenOptions]);
69
+ setAvailableOptions([...availableOptions.filter((option) => !option.isVisible)]);
70
+ } else {
71
+ setAvailableOptions([...chosenOptions.filter((option) => option.isVisible), ...availableOptions]);
72
+ setChosenOptions([...chosenOptions.filter((option) => !option.isVisible)]);
73
+ }
74
+ };
75
+
76
+ // callback when option is selected
77
+ const onOptionSelect = (
78
+ event: React.MouseEvent | React.ChangeEvent | React.KeyboardEvent,
79
+ index: number,
80
+ isChosen: boolean
81
+ ) => {
82
+ if (isChosen) {
83
+ const newChosen = [...chosenOptions];
84
+ newChosen[index].selected = !chosenOptions[index].selected;
85
+ setChosenOptions(newChosen);
86
+ } else {
87
+ const newAvailable = [...availableOptions];
88
+ newAvailable[index].selected = !availableOptions[index].selected;
89
+ setAvailableOptions(newAvailable);
90
+ }
91
+ };
92
+
93
+ const onFilterChange = (value: string, isAvailable: boolean) => {
94
+ isAvailable ? setAvailableFilter(value) : setChosenFilter(value);
95
+ const toFilter = isAvailable ? [...availableOptions] : [...chosenOptions];
96
+ toFilter.forEach((option) => {
97
+ option.isVisible = value === '' || option.text.toLowerCase().includes(value.toLowerCase());
98
+ });
99
+ };
100
+
101
+ // builds a search input - used in each dual list selector pane
102
+ const buildSearchInput = (isAvailable: boolean) => (
103
+ <SearchInput
104
+ value={isAvailable ? availableFilter : chosenFilter}
105
+ onChange={(_event, value) => onFilterChange(value, isAvailable)}
106
+ onClear={() => onFilterChange('', isAvailable)}
107
+ />
108
+ );
109
+
110
+ const buildEmptyState = (isAvailable: boolean) => (
111
+ <EmptyState variant={EmptyStateVariant.sm}>
112
+ <EmptyStateHeader headingLevel="h4" titleText="No results found" icon={<EmptyStateIcon icon={SearchIcon} />} />
113
+ <EmptyStateBody>No results match the filter criteria. Clear all filters and try again.</EmptyStateBody>
114
+ <EmptyStateFooter>
115
+ <EmptyStateActions>
116
+ <Button variant="link" onClick={() => onFilterChange('', isAvailable)}>
117
+ Clear all filters
118
+ </Button>
119
+ </EmptyStateActions>
120
+ </EmptyStateFooter>
121
+ </EmptyState>
122
+ );
123
+
124
+ return (
125
+ <DualListSelector>
126
+ <DualListSelectorPane
127
+ title="Available options"
128
+ status={`${availableOptions.filter((option) => option.selected && option.isVisible).length} of ${
129
+ availableOptions.filter((option) => option.isVisible).length
130
+ } options selected`}
131
+ searchInput={buildSearchInput(true)}
132
+ listMinHeight="300px"
133
+ >
134
+ {availableFilter !== '' &&
135
+ availableOptions.filter((option) => option.isVisible).length === 0 &&
136
+ buildEmptyState(true)}
137
+
138
+ <DualListSelectorList>
139
+ {availableOptions.map((option, index) =>
140
+ option.isVisible ? (
141
+ <DualListSelectorListItem
142
+ key={index}
143
+ isSelected={option.selected}
144
+ id={`search-available-option-${index}`}
145
+ onOptionSelect={(e) => onOptionSelect(e, index, false)}
146
+ >
147
+ {option.text}
148
+ </DualListSelectorListItem>
149
+ ) : null
150
+ )}
151
+ </DualListSelectorList>
152
+ </DualListSelectorPane>
153
+ <DualListSelectorControlsWrapper>
154
+ <DualListSelectorControl
155
+ isDisabled={!availableOptions.some((option) => option.selected)}
156
+ onClick={() => moveSelected(true)}
157
+ aria-label="Add selected"
158
+ >
159
+ <AngleRightIcon />
160
+ </DualListSelectorControl>
161
+ <DualListSelectorControl
162
+ isDisabled={availableOptions.length === 0}
163
+ onClick={() => moveAll(true)}
164
+ aria-label="Add all"
165
+ >
166
+ <AngleDoubleRightIcon />
167
+ </DualListSelectorControl>
168
+ <DualListSelectorControl
169
+ isDisabled={chosenOptions.length === 0}
170
+ onClick={() => moveAll(false)}
171
+ aria-label="Remove all"
172
+ >
173
+ <AngleDoubleLeftIcon />
174
+ </DualListSelectorControl>
175
+ <DualListSelectorControl
176
+ onClick={() => moveSelected(false)}
177
+ isDisabled={!chosenOptions.some((option) => option.selected)}
178
+ aria-label="Remove selected"
179
+ >
180
+ <AngleLeftIcon />
181
+ </DualListSelectorControl>
182
+ </DualListSelectorControlsWrapper>
183
+ <DualListSelectorPane
184
+ title="Chosen options"
185
+ status={`${chosenOptions.filter((option) => option.selected && option.isVisible).length} of ${
186
+ chosenOptions.filter((option) => option.isVisible).length
187
+ } options selected`}
188
+ searchInput={buildSearchInput(false)}
189
+ listMinHeight="300px"
190
+ isChosen
191
+ >
192
+ {chosenFilter !== '' &&
193
+ chosenOptions.filter((option) => option.isVisible).length === 0 &&
194
+ buildEmptyState(false)}
195
+ {chosenOptions.filter((option) => option.isVisible).length > 0 && (
196
+ <DualListSelectorList>
197
+ {chosenOptions.map((option, index) =>
198
+ option.isVisible ? (
199
+ <DualListSelectorListItem
200
+ key={index}
201
+ isSelected={option.selected}
202
+ id={`composable-search-chosen-option-${index}`}
203
+ onOptionSelect={(e) => onOptionSelect(e, index, true)}
204
+ >
205
+ {option.text}
206
+ </DualListSelectorListItem>
207
+ ) : null
208
+ )}
209
+ </DualListSelectorList>
210
+ )}
211
+ </DualListSelectorPane>
212
+ </DualListSelector>
213
+ );
214
+ };