@xh/hoist 74.0.0 → 74.1.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.
@@ -0,0 +1,57 @@
1
+ import {isMenuItem, MenuItemLike} from '@xh/hoist/core';
2
+ import {menuDivider, menuItem} from '@xh/hoist/kit/blueprint';
3
+ import {MenuItemProps} from '@blueprintjs/core';
4
+ import {wait} from '@xh/hoist/promise';
5
+ import {isOmitted} from '@xh/hoist/utils/impl/IsOmitted';
6
+ import {filterConsecutiveMenuSeparators} from '@xh/hoist/utils/impl/Separators';
7
+ import {clone, isEmpty} from 'lodash';
8
+ import {ReactNode} from 'react';
9
+
10
+ /**
11
+ * Parse MenuItem configs into Blueprint MenuItems.
12
+ *
13
+ * Note this is currently used in a few limited places and is not generally applied to all menu-
14
+ * like components in Hoist. In particular, it is not used by the `menu` component re-exported from
15
+ * Blueprint. See https://github.com/xh/hoist-react/issues/2400 covering TBD work to more fully
16
+ * standardize a Hoist menu component that might then incorporate this processing.
17
+ *
18
+ * @internal
19
+ */
20
+ export function parseMenuItems(items: MenuItemLike[]): ReactNode[] {
21
+ items = items.map(item => {
22
+ if (!isMenuItem(item)) return item;
23
+
24
+ item = clone(item);
25
+ item.items = clone(item.items);
26
+ item.prepareFn?.(item);
27
+ return item;
28
+ });
29
+
30
+ return items
31
+ .filter(it => !isMenuItem(it) || (!it.hidden && !isOmitted(it)))
32
+ .filter(filterConsecutiveMenuSeparators())
33
+ .map(item => {
34
+ if (item === '-') return menuDivider();
35
+ if (!isMenuItem(item)) return item;
36
+
37
+ const {actionFn} = item;
38
+
39
+ // Create menuItem from config
40
+ const cfg: MenuItemProps = {
41
+ text: item.text,
42
+ icon: item.icon,
43
+ intent: item.intent,
44
+ className: item.className,
45
+ onClick: actionFn ? e => wait().then(() => actionFn(e)) : null, // do async to allow menu to close
46
+ disabled: item.disabled
47
+ };
48
+
49
+ // Recursively parse any submenus
50
+ if (!isEmpty(item.items)) {
51
+ cfg.children = parseMenuItems(item.items);
52
+ cfg.popoverProps = {openOnTargetFocus: false};
53
+ }
54
+
55
+ return menuItem(cfg);
56
+ });
57
+ }
@@ -8,3 +8,4 @@ export * from './Separators';
8
8
  export * from './TimeZone';
9
9
  export * from './Equals';
10
10
  export * from './IsOmitted';
11
+ export * from './MenuItems';