@patternfly/react-core 4.245.0 → 4.247.0

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 (51) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/esm/components/DualListSelector/DualListSelectorPane.d.ts +2 -0
  3. package/dist/esm/components/DualListSelector/DualListSelectorPane.d.ts.map +1 -1
  4. package/dist/esm/components/DualListSelector/DualListSelectorPane.js +4 -5
  5. package/dist/esm/components/DualListSelector/DualListSelectorPane.js.map +1 -1
  6. package/dist/esm/components/SearchInput/SearchInput.d.ts +2 -0
  7. package/dist/esm/components/SearchInput/SearchInput.d.ts.map +1 -1
  8. package/dist/esm/components/SearchInput/SearchInput.js +2 -2
  9. package/dist/esm/components/SearchInput/SearchInput.js.map +1 -1
  10. package/dist/esm/components/TreeView/TreeView.d.ts.map +1 -1
  11. package/dist/esm/components/TreeView/TreeView.js +1 -1
  12. package/dist/esm/components/TreeView/TreeView.js.map +1 -1
  13. package/dist/esm/components/TreeView/TreeViewListItem.d.ts.map +1 -1
  14. package/dist/esm/components/TreeView/TreeViewListItem.js +2 -2
  15. package/dist/esm/components/TreeView/TreeViewListItem.js.map +1 -1
  16. package/dist/esm/components/TreeView/TreeViewRoot.d.ts +5 -3
  17. package/dist/esm/components/TreeView/TreeViewRoot.d.ts.map +1 -1
  18. package/dist/esm/components/TreeView/TreeViewRoot.js +26 -17
  19. package/dist/esm/components/TreeView/TreeViewRoot.js.map +1 -1
  20. package/dist/js/components/DualListSelector/DualListSelectorPane.d.ts +2 -0
  21. package/dist/js/components/DualListSelector/DualListSelectorPane.d.ts.map +1 -1
  22. package/dist/js/components/DualListSelector/DualListSelectorPane.js +4 -5
  23. package/dist/js/components/DualListSelector/DualListSelectorPane.js.map +1 -1
  24. package/dist/js/components/SearchInput/SearchInput.d.ts +2 -0
  25. package/dist/js/components/SearchInput/SearchInput.d.ts.map +1 -1
  26. package/dist/js/components/SearchInput/SearchInput.js +2 -2
  27. package/dist/js/components/SearchInput/SearchInput.js.map +1 -1
  28. package/dist/js/components/TreeView/TreeView.d.ts.map +1 -1
  29. package/dist/js/components/TreeView/TreeView.js +1 -1
  30. package/dist/js/components/TreeView/TreeView.js.map +1 -1
  31. package/dist/js/components/TreeView/TreeViewListItem.d.ts.map +1 -1
  32. package/dist/js/components/TreeView/TreeViewListItem.js +2 -2
  33. package/dist/js/components/TreeView/TreeViewListItem.js.map +1 -1
  34. package/dist/js/components/TreeView/TreeViewRoot.d.ts +5 -3
  35. package/dist/js/components/TreeView/TreeViewRoot.d.ts.map +1 -1
  36. package/dist/js/components/TreeView/TreeViewRoot.js +26 -17
  37. package/dist/js/components/TreeView/TreeViewRoot.js.map +1 -1
  38. package/dist/umd/react-core.min.css +3370 -3370
  39. package/dist/umd/react-core.min.js +2 -2
  40. package/package.json +2 -2
  41. package/src/components/Dropdown/examples/Dropdown.md +79 -55
  42. package/src/components/DualListSelector/DualListSelectorPane.tsx +11 -7
  43. package/src/components/DualListSelector/__tests__/__snapshots__/DualListSelector.test.tsx.snap +70 -10
  44. package/src/components/SearchInput/SearchInput.tsx +15 -0
  45. package/src/components/TreeView/TreeView.tsx +8 -1
  46. package/src/components/TreeView/TreeViewListItem.tsx +4 -3
  47. package/src/components/TreeView/TreeViewRoot.tsx +38 -18
  48. package/src/components/TreeView/__tests__/__snapshots__/TreeView.test.tsx.snap +0 -51
  49. package/src/demos/ComposableMenu/ComposableMenu.md +7 -2
  50. package/src/demos/ComposableMenu/examples/ComposableMultipleTypeaheadSelect.tsx +220 -0
  51. package/src/components/Dropdown/examples/DropdownSplitButtonIndeterminate.tsx +0 -78
@@ -75,7 +75,6 @@ exports[`renders compact no background successfully 1`] = `
75
75
  >
76
76
  <button
77
77
  class="pf-c-tree-view__node"
78
- tabindex="-1"
79
78
  >
80
79
  <span
81
80
  class="pf-c-tree-view__node-container"
@@ -126,7 +125,6 @@ exports[`renders compact no background successfully 1`] = `
126
125
  >
127
126
  <button
128
127
  class="pf-c-tree-view__node"
129
- tabindex="-1"
130
128
  >
131
129
  <span
132
130
  class="pf-c-tree-view__node-container"
@@ -179,7 +177,6 @@ exports[`renders compact no background successfully 1`] = `
179
177
  >
180
178
  <button
181
179
  class="pf-c-tree-view__node"
182
- tabindex="-1"
183
180
  >
184
181
  <span
185
182
  class="pf-c-tree-view__node-container"
@@ -230,7 +227,6 @@ exports[`renders compact no background successfully 1`] = `
230
227
  >
231
228
  <button
232
229
  class="pf-c-tree-view__node"
233
- tabindex="-1"
234
230
  >
235
231
  <span
236
232
  class="pf-c-tree-view__node-container"
@@ -281,7 +277,6 @@ exports[`renders compact no background successfully 1`] = `
281
277
  >
282
278
  <button
283
279
  class="pf-c-tree-view__node"
284
- tabindex="-1"
285
280
  >
286
281
  <span
287
282
  class="pf-c-tree-view__node-container"
@@ -401,7 +396,6 @@ exports[`renders compact successfully 1`] = `
401
396
  >
402
397
  <button
403
398
  class="pf-c-tree-view__node"
404
- tabindex="-1"
405
399
  >
406
400
  <span
407
401
  class="pf-c-tree-view__node-container"
@@ -452,7 +446,6 @@ exports[`renders compact successfully 1`] = `
452
446
  >
453
447
  <button
454
448
  class="pf-c-tree-view__node"
455
- tabindex="-1"
456
449
  >
457
450
  <span
458
451
  class="pf-c-tree-view__node-container"
@@ -505,7 +498,6 @@ exports[`renders compact successfully 1`] = `
505
498
  >
506
499
  <button
507
500
  class="pf-c-tree-view__node"
508
- tabindex="-1"
509
501
  >
510
502
  <span
511
503
  class="pf-c-tree-view__node-container"
@@ -556,7 +548,6 @@ exports[`renders compact successfully 1`] = `
556
548
  >
557
549
  <button
558
550
  class="pf-c-tree-view__node"
559
- tabindex="-1"
560
551
  >
561
552
  <span
562
553
  class="pf-c-tree-view__node-container"
@@ -607,7 +598,6 @@ exports[`renders compact successfully 1`] = `
607
598
  >
608
599
  <button
609
600
  class="pf-c-tree-view__node"
610
- tabindex="-1"
611
601
  >
612
602
  <span
613
603
  class="pf-c-tree-view__node-container"
@@ -723,7 +713,6 @@ exports[`renders guides successfully 1`] = `
723
713
  >
724
714
  <button
725
715
  class="pf-c-tree-view__node"
726
- tabindex="-1"
727
716
  >
728
717
  <span
729
718
  class="pf-c-tree-view__node-container"
@@ -770,7 +759,6 @@ exports[`renders guides successfully 1`] = `
770
759
  >
771
760
  <button
772
761
  class="pf-c-tree-view__node"
773
- tabindex="-1"
774
762
  >
775
763
  <span
776
764
  class="pf-c-tree-view__node-container"
@@ -819,7 +807,6 @@ exports[`renders guides successfully 1`] = `
819
807
  >
820
808
  <button
821
809
  class="pf-c-tree-view__node"
822
- tabindex="-1"
823
810
  >
824
811
  <span
825
812
  class="pf-c-tree-view__node-container"
@@ -866,7 +853,6 @@ exports[`renders guides successfully 1`] = `
866
853
  >
867
854
  <button
868
855
  class="pf-c-tree-view__node"
869
- tabindex="-1"
870
856
  >
871
857
  <span
872
858
  class="pf-c-tree-view__node-container"
@@ -913,7 +899,6 @@ exports[`renders guides successfully 1`] = `
913
899
  >
914
900
  <button
915
901
  class="pf-c-tree-view__node"
916
- tabindex="-1"
917
902
  >
918
903
  <span
919
904
  class="pf-c-tree-view__node-container"
@@ -1025,7 +1010,6 @@ exports[`tree view renders active successfully 1`] = `
1025
1010
  >
1026
1011
  <button
1027
1012
  class="pf-c-tree-view__node"
1028
- tabindex="-1"
1029
1013
  >
1030
1014
  <span
1031
1015
  class="pf-c-tree-view__node-container"
@@ -1072,7 +1056,6 @@ exports[`tree view renders active successfully 1`] = `
1072
1056
  >
1073
1057
  <button
1074
1058
  class="pf-c-tree-view__node"
1075
- tabindex="-1"
1076
1059
  >
1077
1060
  <span
1078
1061
  class="pf-c-tree-view__node-container"
@@ -1121,7 +1104,6 @@ exports[`tree view renders active successfully 1`] = `
1121
1104
  >
1122
1105
  <button
1123
1106
  class="pf-c-tree-view__node"
1124
- tabindex="-1"
1125
1107
  >
1126
1108
  <span
1127
1109
  class="pf-c-tree-view__node-container"
@@ -1168,7 +1150,6 @@ exports[`tree view renders active successfully 1`] = `
1168
1150
  >
1169
1151
  <button
1170
1152
  class="pf-c-tree-view__node"
1171
- tabindex="-1"
1172
1153
  >
1173
1154
  <span
1174
1155
  class="pf-c-tree-view__node-container"
@@ -1215,7 +1196,6 @@ exports[`tree view renders active successfully 1`] = `
1215
1196
  >
1216
1197
  <button
1217
1198
  class="pf-c-tree-view__node"
1218
- tabindex="-1"
1219
1199
  >
1220
1200
  <span
1221
1201
  class="pf-c-tree-view__node-container"
@@ -1336,7 +1316,6 @@ exports[`tree view renders badges successfully 1`] = `
1336
1316
  >
1337
1317
  <button
1338
1318
  class="pf-c-tree-view__node"
1339
- tabindex="-1"
1340
1319
  >
1341
1320
  <span
1342
1321
  class="pf-c-tree-view__node-container"
@@ -1392,7 +1371,6 @@ exports[`tree view renders badges successfully 1`] = `
1392
1371
  >
1393
1372
  <button
1394
1373
  class="pf-c-tree-view__node"
1395
- tabindex="-1"
1396
1374
  >
1397
1375
  <span
1398
1376
  class="pf-c-tree-view__node-container"
@@ -1450,7 +1428,6 @@ exports[`tree view renders badges successfully 1`] = `
1450
1428
  >
1451
1429
  <button
1452
1430
  class="pf-c-tree-view__node"
1453
- tabindex="-1"
1454
1431
  >
1455
1432
  <span
1456
1433
  class="pf-c-tree-view__node-container"
@@ -1506,7 +1483,6 @@ exports[`tree view renders badges successfully 1`] = `
1506
1483
  >
1507
1484
  <button
1508
1485
  class="pf-c-tree-view__node"
1509
- tabindex="-1"
1510
1486
  >
1511
1487
  <span
1512
1488
  class="pf-c-tree-view__node-container"
@@ -1562,7 +1538,6 @@ exports[`tree view renders badges successfully 1`] = `
1562
1538
  >
1563
1539
  <button
1564
1540
  class="pf-c-tree-view__node"
1565
- tabindex="-1"
1566
1541
  >
1567
1542
  <span
1568
1543
  class="pf-c-tree-view__node-container"
@@ -1683,7 +1658,6 @@ exports[`tree view renders basic successfully 1`] = `
1683
1658
  >
1684
1659
  <button
1685
1660
  class="pf-c-tree-view__node"
1686
- tabindex="-1"
1687
1661
  >
1688
1662
  <span
1689
1663
  class="pf-c-tree-view__node-container"
@@ -1730,7 +1704,6 @@ exports[`tree view renders basic successfully 1`] = `
1730
1704
  >
1731
1705
  <button
1732
1706
  class="pf-c-tree-view__node"
1733
- tabindex="-1"
1734
1707
  >
1735
1708
  <span
1736
1709
  class="pf-c-tree-view__node-container"
@@ -1779,7 +1752,6 @@ exports[`tree view renders basic successfully 1`] = `
1779
1752
  >
1780
1753
  <button
1781
1754
  class="pf-c-tree-view__node"
1782
- tabindex="-1"
1783
1755
  >
1784
1756
  <span
1785
1757
  class="pf-c-tree-view__node-container"
@@ -1826,7 +1798,6 @@ exports[`tree view renders basic successfully 1`] = `
1826
1798
  >
1827
1799
  <button
1828
1800
  class="pf-c-tree-view__node"
1829
- tabindex="-1"
1830
1801
  >
1831
1802
  <span
1832
1803
  class="pf-c-tree-view__node-container"
@@ -1873,7 +1844,6 @@ exports[`tree view renders basic successfully 1`] = `
1873
1844
  >
1874
1845
  <button
1875
1846
  class="pf-c-tree-view__node"
1876
- tabindex="-1"
1877
1847
  >
1878
1848
  <span
1879
1849
  class="pf-c-tree-view__node-container"
@@ -1937,7 +1907,6 @@ exports[`tree view renders checkboxes successfully 1`] = `
1937
1907
  class="pf-c-tree-view__node pf-m-selectable"
1938
1908
  for="checkbox-id18"
1939
1909
  id="label-checkbox-id18"
1940
- tabindex="-1"
1941
1910
  >
1942
1911
  <span
1943
1912
  class="pf-c-tree-view__node-container"
@@ -1999,7 +1968,6 @@ exports[`tree view renders checkboxes successfully 1`] = `
1999
1968
  class="pf-c-tree-view__node pf-m-selectable"
2000
1969
  for="checkbox-id19"
2001
1970
  id="label-checkbox-id19"
2002
- tabindex="-1"
2003
1971
  >
2004
1972
  <span
2005
1973
  class="pf-c-tree-view__node-container"
@@ -2058,7 +2026,6 @@ exports[`tree view renders checkboxes successfully 1`] = `
2058
2026
  class="pf-c-tree-view__node pf-m-selectable"
2059
2027
  for="checkbox-id20"
2060
2028
  id="label-checkbox-id20"
2061
- tabindex="-1"
2062
2029
  >
2063
2030
  <span
2064
2031
  class="pf-c-tree-view__node-container"
@@ -2119,7 +2086,6 @@ exports[`tree view renders checkboxes successfully 1`] = `
2119
2086
  class="pf-c-tree-view__node pf-m-selectable"
2120
2087
  for="checkbox-id21"
2121
2088
  id="label-checkbox-id21"
2122
- tabindex="-1"
2123
2089
  >
2124
2090
  <span
2125
2091
  class="pf-c-tree-view__node-container"
@@ -2178,7 +2144,6 @@ exports[`tree view renders checkboxes successfully 1`] = `
2178
2144
  class="pf-c-tree-view__node pf-m-selectable"
2179
2145
  for="checkbox-id22"
2180
2146
  id="label-checkbox-id22"
2181
- tabindex="-1"
2182
2147
  >
2183
2148
  <span
2184
2149
  class="pf-c-tree-view__node-container"
@@ -2237,7 +2202,6 @@ exports[`tree view renders checkboxes successfully 1`] = `
2237
2202
  class="pf-c-tree-view__node pf-m-selectable"
2238
2203
  for="checkbox-id23"
2239
2204
  id="label-checkbox-id23"
2240
- tabindex="-1"
2241
2205
  >
2242
2206
  <span
2243
2207
  class="pf-c-tree-view__node-container"
@@ -2376,7 +2340,6 @@ exports[`tree view renders icons successfully 1`] = `
2376
2340
  >
2377
2341
  <button
2378
2342
  class="pf-c-tree-view__node"
2379
- tabindex="-1"
2380
2343
  >
2381
2344
  <span
2382
2345
  class="pf-c-tree-view__node-container"
@@ -2440,7 +2403,6 @@ exports[`tree view renders icons successfully 1`] = `
2440
2403
  >
2441
2404
  <button
2442
2405
  class="pf-c-tree-view__node"
2443
- tabindex="-1"
2444
2406
  >
2445
2407
  <span
2446
2408
  class="pf-c-tree-view__node-container"
@@ -2506,7 +2468,6 @@ exports[`tree view renders icons successfully 1`] = `
2506
2468
  >
2507
2469
  <button
2508
2470
  class="pf-c-tree-view__node"
2509
- tabindex="-1"
2510
2471
  >
2511
2472
  <span
2512
2473
  class="pf-c-tree-view__node-container"
@@ -2570,7 +2531,6 @@ exports[`tree view renders icons successfully 1`] = `
2570
2531
  >
2571
2532
  <button
2572
2533
  class="pf-c-tree-view__node"
2573
- tabindex="-1"
2574
2534
  >
2575
2535
  <span
2576
2536
  class="pf-c-tree-view__node-container"
@@ -2634,7 +2594,6 @@ exports[`tree view renders icons successfully 1`] = `
2634
2594
  >
2635
2595
  <button
2636
2596
  class="pf-c-tree-view__node"
2637
- tabindex="-1"
2638
2597
  >
2639
2598
  <span
2640
2599
  class="pf-c-tree-view__node-container"
@@ -2792,7 +2751,6 @@ exports[`tree view renders individual flag options successfully 1`] = `
2792
2751
  >
2793
2752
  <button
2794
2753
  class="pf-c-tree-view__node"
2795
- tabindex="-1"
2796
2754
  >
2797
2755
  <span
2798
2756
  class="pf-c-tree-view__node-container"
@@ -2839,7 +2797,6 @@ exports[`tree view renders individual flag options successfully 1`] = `
2839
2797
  >
2840
2798
  <button
2841
2799
  class="pf-c-tree-view__node"
2842
- tabindex="-1"
2843
2800
  >
2844
2801
  <span
2845
2802
  class="pf-c-tree-view__node-container"
@@ -2897,7 +2854,6 @@ exports[`tree view renders individual flag options successfully 1`] = `
2897
2854
  >
2898
2855
  <button
2899
2856
  class="pf-c-tree-view__node"
2900
- tabindex="-1"
2901
2857
  >
2902
2858
  <span
2903
2859
  class="pf-c-tree-view__node-container"
@@ -2980,7 +2936,6 @@ exports[`tree view renders individual flag options successfully 1`] = `
2980
2936
  >
2981
2937
  <button
2982
2938
  class="pf-c-tree-view__node"
2983
- tabindex="-1"
2984
2939
  >
2985
2940
  <span
2986
2941
  class="pf-c-tree-view__node-container"
@@ -3027,7 +2982,6 @@ exports[`tree view renders individual flag options successfully 1`] = `
3027
2982
  >
3028
2983
  <button
3029
2984
  class="pf-c-tree-view__node"
3030
- tabindex="-1"
3031
2985
  >
3032
2986
  <span
3033
2987
  class="pf-c-tree-view__node-container"
@@ -3161,7 +3115,6 @@ exports[`tree view renders toolbar successfully 1`] = `
3161
3115
  >
3162
3116
  <button
3163
3117
  class="pf-c-tree-view__node"
3164
- tabindex="-1"
3165
3118
  >
3166
3119
  <span
3167
3120
  class="pf-c-tree-view__node-container"
@@ -3208,7 +3161,6 @@ exports[`tree view renders toolbar successfully 1`] = `
3208
3161
  >
3209
3162
  <button
3210
3163
  class="pf-c-tree-view__node"
3211
- tabindex="-1"
3212
3164
  >
3213
3165
  <span
3214
3166
  class="pf-c-tree-view__node-container"
@@ -3257,7 +3209,6 @@ exports[`tree view renders toolbar successfully 1`] = `
3257
3209
  >
3258
3210
  <button
3259
3211
  class="pf-c-tree-view__node"
3260
- tabindex="-1"
3261
3212
  >
3262
3213
  <span
3263
3214
  class="pf-c-tree-view__node-container"
@@ -3304,7 +3255,6 @@ exports[`tree view renders toolbar successfully 1`] = `
3304
3255
  >
3305
3256
  <button
3306
3257
  class="pf-c-tree-view__node"
3307
- tabindex="-1"
3308
3258
  >
3309
3259
  <span
3310
3260
  class="pf-c-tree-view__node-container"
@@ -3351,7 +3301,6 @@ exports[`tree view renders toolbar successfully 1`] = `
3351
3301
  >
3352
3302
  <button
3353
3303
  class="pf-c-tree-view__node"
3354
- tabindex="-1"
3355
3304
  >
3356
3305
  <span
3357
3306
  class="pf-c-tree-view__node-container"
@@ -19,8 +19,8 @@ import ThIcon from '@patternfly/react-icons/dist/esm/icons/th-icon';
19
19
  import pfIcon from './examples/pf-logo-small.svg';
20
20
  import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon';
21
21
  import CaretDownIcon from '@patternfly/react-icons/dist/esm/icons/caret-down-icon';
22
- import avatarImg from './examples/avatarImg.svg';
23
22
  import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
23
+ import avatarImg from './examples/avatarImg.svg';
24
24
  import { css } from '@patternfly/react-styles';
25
25
  import styles from '@patternfly/react-styles/css/components/Menu/menu';
26
26
 
@@ -50,7 +50,12 @@ Composable menus currently require consumer keyboard handling and use of our und
50
50
 
51
51
  ### Composable typeahead select
52
52
 
53
- ```ts file="./examples/ComposableTypeaheadSelect.tsx"
53
+ ```ts isBeta file="./examples/ComposableTypeaheadSelect.tsx"
54
+ ```
55
+
56
+ ### Composable multiple typeahead select
57
+
58
+ ```ts isBeta file="./examples/ComposableMultipleTypeaheadSelect.tsx"
54
59
  ```
55
60
 
56
61
  ### Composable drilldown menu
@@ -0,0 +1,220 @@
1
+ import React from 'react';
2
+ import {
3
+ Menu,
4
+ MenuContent,
5
+ MenuList,
6
+ MenuItem,
7
+ MenuItemProps,
8
+ MenuToggle,
9
+ MenuToggleElement,
10
+ Popper,
11
+ TextInputGroup,
12
+ TextInputGroupMain,
13
+ TextInputGroupUtilities,
14
+ ChipGroup,
15
+ Chip,
16
+ Button
17
+ } from '@patternfly/react-core';
18
+ import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
19
+
20
+ const intitalMenuItems = [
21
+ { itemId: 'Option 1', children: 'Option 1' },
22
+ { itemId: 'Option 2', children: 'Option 2' },
23
+ { itemId: 'Option 3', children: 'Option 3' }
24
+ ];
25
+
26
+ export const ComposableMultipleTypeaheadSelect: React.FunctionComponent = () => {
27
+ const [isMenuOpen, setIsMenuOpen] = React.useState(false);
28
+ const [inputValue, setInputValue] = React.useState<string>('');
29
+ const [menuItems, setMenuItems] = React.useState<MenuItemProps[]>(intitalMenuItems);
30
+ const [focusedItemIndex, setFocusedItemIndex] = React.useState<number | null>(null);
31
+ const [selected, setSelected] = React.useState<string[]>([]);
32
+ const containerRef = React.useRef<HTMLDivElement>();
33
+ const menuToggleRef = React.useRef<MenuToggleElement>({} as MenuToggleElement);
34
+ const textInputRef = React.useRef<HTMLInputElement>();
35
+ const menuRef = React.useRef<HTMLDivElement>();
36
+
37
+ React.useEffect(() => {
38
+ let newMenuItems: MenuItemProps[] = intitalMenuItems;
39
+
40
+ // Filter menu items based on the text input value when one exists
41
+ if (inputValue) {
42
+ newMenuItems = intitalMenuItems.filter(menuItem =>
43
+ String(menuItem.children)
44
+ .toLowerCase()
45
+ .includes(inputValue.toLowerCase())
46
+ );
47
+
48
+ // When no options are found after filtering, display 'No results found'
49
+ if (!newMenuItems.length) {
50
+ newMenuItems = [{ isDisabled: true, children: 'No results found' }];
51
+ }
52
+ }
53
+
54
+ setMenuItems(newMenuItems);
55
+ }, [inputValue]);
56
+
57
+ const handleMenuArrowKeys = (key: string) => {
58
+ let indexToFocus;
59
+
60
+ if (isMenuOpen) {
61
+ if (key === 'ArrowUp') {
62
+ // When no index is set or at the first index, focus to the last, otherwise decrement focus index
63
+ if (focusedItemIndex === null || focusedItemIndex === 0) {
64
+ indexToFocus = menuItems.length - 1;
65
+ } else {
66
+ indexToFocus = focusedItemIndex - 1;
67
+ }
68
+ }
69
+
70
+ if (key === 'ArrowDown') {
71
+ // When no index is set or at the last index, focus to the first, otherwise increment focus index
72
+ if (focusedItemIndex === null || focusedItemIndex === menuItems.length - 1) {
73
+ indexToFocus = 0;
74
+ } else {
75
+ indexToFocus = focusedItemIndex + 1;
76
+ }
77
+ }
78
+
79
+ setFocusedItemIndex(indexToFocus);
80
+ }
81
+ };
82
+
83
+ const onInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
84
+ const enabledMenuItems = menuItems.filter(menuItem => !menuItem.isDisabled);
85
+ const [firstMenuItem] = enabledMenuItems;
86
+ const focusedItem = focusedItemIndex ? enabledMenuItems[focusedItemIndex] : firstMenuItem;
87
+
88
+ switch (event.key) {
89
+ // Select the first available option
90
+ case 'Enter':
91
+ if (!isMenuOpen) {
92
+ setIsMenuOpen(prevIsOpen => !prevIsOpen);
93
+ } else {
94
+ onMenuSelect(focusedItem.itemId as string);
95
+ }
96
+ break;
97
+ case 'Tab':
98
+ case 'Escape':
99
+ setIsMenuOpen(false);
100
+ break;
101
+ case 'ArrowUp':
102
+ case 'ArrowDown':
103
+ handleMenuArrowKeys(event.key);
104
+ break;
105
+ default:
106
+ !isMenuOpen && setIsMenuOpen(true);
107
+ }
108
+ };
109
+
110
+ // Close the menu when a click occurs outside of the menu toggle content
111
+ const onDocumentClick = (event: MouseEvent) => {
112
+ if (
113
+ isMenuOpen &&
114
+ !menuToggleRef.current?.contains(event?.target as HTMLElement) &&
115
+ !menuRef?.current?.contains(event.target as Node)
116
+ ) {
117
+ setIsMenuOpen(false);
118
+ }
119
+ };
120
+
121
+ const toggleMenuOpen = () => {
122
+ setIsMenuOpen(!isMenuOpen);
123
+ textInputRef.current?.focus();
124
+ };
125
+
126
+ const onTextInputChange = (value: string) => {
127
+ setInputValue(value);
128
+ };
129
+
130
+ const onMenuSelect = (itemId: string) => {
131
+ if (itemId) {
132
+ setSelected(
133
+ selected.includes(itemId) ? selected.filter(selection => selection !== itemId) : [...selected, itemId]
134
+ );
135
+ }
136
+ };
137
+
138
+ const toggle = (
139
+ <MenuToggle
140
+ variant="typeahead"
141
+ onClick={toggleMenuOpen}
142
+ innerRef={menuToggleRef}
143
+ isExpanded={isMenuOpen}
144
+ isFullWidth
145
+ >
146
+ <TextInputGroup isPlain>
147
+ <TextInputGroupMain
148
+ value={inputValue}
149
+ onClick={toggleMenuOpen}
150
+ onChange={onTextInputChange}
151
+ onKeyDown={onInputKeyDown}
152
+ id="typeahead-select-input"
153
+ autoComplete="off"
154
+ innerRef={textInputRef}
155
+ >
156
+ <ChipGroup>
157
+ {selected.map((selection, index) => (
158
+ <Chip
159
+ key={index}
160
+ onClick={ev => {
161
+ ev.stopPropagation();
162
+ onMenuSelect(selection);
163
+ }}
164
+ >
165
+ {selection}
166
+ </Chip>
167
+ ))}
168
+ </ChipGroup>
169
+ </TextInputGroupMain>
170
+ <TextInputGroupUtilities>
171
+ {selected.length > 0 && (
172
+ <Button
173
+ variant="plain"
174
+ onClick={() => {
175
+ setInputValue('');
176
+ setSelected([]);
177
+ }}
178
+ aria-label="Clear input value"
179
+ >
180
+ <TimesIcon aria-hidden />
181
+ </Button>
182
+ )}
183
+ </TextInputGroupUtilities>
184
+ </TextInputGroup>
185
+ </MenuToggle>
186
+ );
187
+ const menu = (
188
+ <Menu
189
+ ref={menuRef as React.Ref<HTMLDivElement>}
190
+ id="multiple-typeahead-select-menu"
191
+ onSelect={(_ev, itemId) => onMenuSelect(itemId?.toString() as string)}
192
+ selected={selected}
193
+ >
194
+ <MenuContent>
195
+ <MenuList>
196
+ {menuItems.map((itemProps, index) => (
197
+ <MenuItem
198
+ key={itemProps.itemId || itemProps.children}
199
+ isFocused={focusedItemIndex === index}
200
+ className={itemProps.className}
201
+ {...itemProps}
202
+ ref={null}
203
+ />
204
+ ))}
205
+ </MenuList>
206
+ </MenuContent>
207
+ </Menu>
208
+ );
209
+ return (
210
+ <div ref={containerRef as React.Ref<HTMLDivElement>}>
211
+ <Popper
212
+ trigger={toggle}
213
+ popper={menu}
214
+ appendTo={containerRef.current}
215
+ isVisible={isMenuOpen}
216
+ onDocumentClick={onDocumentClick}
217
+ />
218
+ </div>
219
+ );
220
+ };