@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.
- package/CHANGELOG.md +22 -4
- package/build/types/cmp/grouping/GroupingChooserModel.d.ts +7 -4
- package/build/types/cmp/viewmanager/ViewInfo.d.ts +7 -3
- package/build/types/desktop/cmp/grouping/GroupingChooser.d.ts +4 -4
- package/build/types/desktop/cmp/viewmanager/ViewManager.d.ts +26 -10
- package/build/types/mobile/cmp/grouping/GroupingChooser.d.ts +2 -6
- package/build/types/utils/impl/MenuItems.d.ts +13 -0
- package/build/types/utils/impl/index.d.ts +1 -0
- package/cmp/grouping/GroupingChooserModel.ts +20 -12
- package/cmp/viewmanager/ViewInfo.ts +7 -3
- package/core/HoistAppModel.ts +1 -0
- package/desktop/cmp/button/AppMenuButton.ts +3 -46
- package/desktop/cmp/grouping/GroupingChooser.scss +28 -39
- package/desktop/cmp/grouping/GroupingChooser.ts +72 -82
- package/desktop/cmp/viewmanager/ViewManager.ts +58 -16
- package/desktop/cmp/viewmanager/ViewMenu.ts +9 -2
- package/mobile/appcontainer/FeedbackDialog.ts +4 -0
- package/mobile/appcontainer/OptionsDialog.ts +3 -1
- package/mobile/cmp/grid/impl/ColChooser.ts +3 -2
- package/mobile/cmp/grouping/GroupingChooser.scss +41 -20
- package/mobile/cmp/grouping/GroupingChooser.ts +60 -89
- package/mobile/cmp/panel/DialogPanel.scss +5 -0
- package/package.json +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/utils/impl/MenuItems.ts +57 -0
- package/utils/impl/index.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,22 +1,40 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v74.1.0 - 2025-06-30
|
|
4
|
+
|
|
5
|
+
### 🎁 New Features
|
|
6
|
+
|
|
7
|
+
* Updated the `GroupingChooser` UI to use a single popover for both updating the value and
|
|
8
|
+
selecting/managing favorite groupings (if enabled).
|
|
9
|
+
* Adjusted `GroupingChooserModel` API and some CSS class names and testIds of `GroupingChooser`
|
|
10
|
+
internals, although those changes are very unlikely to require app-level adjustments.
|
|
11
|
+
* Adjusted/removed (rarely used) desktop and mobile `GroupingChooser` props related to popover
|
|
12
|
+
sizing and titling.
|
|
13
|
+
* Updated the mobile UI to use a full-screen dialog, similar to `ColumnChooser`.
|
|
14
|
+
* Added props to `ViewManager` to customize icons used for different types of views, and modified
|
|
15
|
+
default icons for Global and Shared views.
|
|
16
|
+
* Added `ViewManager.extraMenuItems` prop to allow insertion of custom, app-specific items into the
|
|
17
|
+
component's standard menu.
|
|
18
|
+
|
|
3
19
|
## v74.0.0 - 2025-06-11
|
|
4
20
|
|
|
5
21
|
### 💥 Breaking Changes (upgrade difficulty: 🟢 LOW - minor changes to ViewManagerModel, ChartModel)
|
|
6
22
|
|
|
7
23
|
* Removed `ViewManagerModel.settleTime`. Now set via individual `PersistOptions.settleTime` instead.
|
|
8
|
-
* ️Removed `ChartModel.showContextMenu`.
|
|
9
|
-
property instead.
|
|
24
|
+
* ️Removed `ChartModel.showContextMenu`. Use a setting of `false` for the new
|
|
25
|
+
`ChartModel.contextMenu` property instead.
|
|
10
26
|
|
|
11
27
|
### 🎁 New Features
|
|
28
|
+
|
|
12
29
|
* Added `ViewManagerModel.preserveUnsavedChanges` flag to opt-out of that behaviour.
|
|
13
30
|
* Added `PersistOptions.settleTime` to configure time to wait for state to settle before persisting.
|
|
14
31
|
* Support for grid column level `onCellClicked` events.
|
|
15
32
|
* General improvements to `MenuItem` api
|
|
16
|
-
|
|
17
|
-
|
|
33
|
+
* New `MenuContext` object now sent as 2nd arg to `actionFn` and `prepareFn`.
|
|
34
|
+
* New `ChartModel.contextMenu` property provides a fully customizable context menu for charts.
|
|
18
35
|
|
|
19
36
|
### 🐞 Bug Fixes
|
|
37
|
+
|
|
20
38
|
* Improved `ViewManagerModel.settleTime` by delegating to individual `PersistenceProviders`.
|
|
21
39
|
* Fixed bug where grid column state could become unintentionally dirty when columns were hidden.
|
|
22
40
|
* Improved `WebsocketService` heartbeat detection to auto-reconnect when the socket reports as open
|
|
@@ -8,7 +8,10 @@ export interface GroupingChooserConfig {
|
|
|
8
8
|
dimensions?: (DimensionSpec | string)[];
|
|
9
9
|
/** Initial value as an array of dimension names, or a function to produce such an array. */
|
|
10
10
|
initialValue?: string[] | (() => string[]);
|
|
11
|
-
/**
|
|
11
|
+
/**
|
|
12
|
+
* Initial favorites as an array of dim name arrays, or a function to produce such an array.
|
|
13
|
+
* Ignored if `persistWith.persistFavorites: false`.
|
|
14
|
+
*/
|
|
12
15
|
initialFavorites?: string[][] | (() => string[][]);
|
|
13
16
|
/** Options governing persistence. */
|
|
14
17
|
persistWith?: GroupingChooserPersistOptions;
|
|
@@ -47,7 +50,6 @@ export declare class GroupingChooserModel extends HoistModel {
|
|
|
47
50
|
persistFavorites: boolean;
|
|
48
51
|
pendingValue: string[];
|
|
49
52
|
editorIsOpen: boolean;
|
|
50
|
-
favoritesIsOpen: boolean;
|
|
51
53
|
popoverRef: import("react").RefObject<HTMLElement> & import("react").RefCallback<HTMLElement>;
|
|
52
54
|
private dimensions;
|
|
53
55
|
private dimensionNames;
|
|
@@ -55,12 +57,12 @@ export declare class GroupingChooserModel extends HoistModel {
|
|
|
55
57
|
get dimensionSpecs(): DimensionSpec[];
|
|
56
58
|
get isValid(): boolean;
|
|
57
59
|
get isAddEnabled(): boolean;
|
|
60
|
+
get isAddFavoriteEnabled(): boolean;
|
|
58
61
|
constructor({ dimensions, initialValue, initialFavorites, persistWith, allowEmpty, maxDepth, commitOnChange }: GroupingChooserConfig);
|
|
59
62
|
setDimensions(dimensions: Array<DimensionSpec | string>): void;
|
|
60
63
|
setValue(value: string[]): void;
|
|
61
64
|
toggleEditor(): void;
|
|
62
|
-
|
|
63
|
-
closePopover(): void;
|
|
65
|
+
closeEditor(): void;
|
|
64
66
|
addPendingDim(dimName: string): void;
|
|
65
67
|
replacePendingDimAtIdx(dimName: string, idx: number): void;
|
|
66
68
|
removePendingDimAtIdx(idx: number): void;
|
|
@@ -76,6 +78,7 @@ export declare class GroupingChooserModel extends HoistModel {
|
|
|
76
78
|
}[];
|
|
77
79
|
setFavorites(favorites: string[][]): void;
|
|
78
80
|
addFavorite(value: string[]): void;
|
|
81
|
+
addPendingAsFavorite(): void;
|
|
79
82
|
removeFavorite(value: string[]): void;
|
|
80
83
|
isFavorite(value: string[]): boolean;
|
|
81
84
|
private initPersist;
|
|
@@ -15,15 +15,19 @@ export declare class ViewInfo {
|
|
|
15
15
|
readonly description: string;
|
|
16
16
|
/** User owning this view. Null if the view is global.*/
|
|
17
17
|
readonly owner: string;
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* True if the owner (which can be the current user) has made this view accessible to all other
|
|
20
|
+
* users. Note always `false` for global views, to better distinguish the two sharing models.
|
|
21
|
+
*/
|
|
19
22
|
readonly isShared: boolean;
|
|
20
23
|
/** True if this view is global and visible to all users. */
|
|
21
24
|
readonly isGlobal: boolean;
|
|
22
25
|
/** Optional group name used for bucketing this view in display. */
|
|
23
26
|
readonly group: string;
|
|
24
27
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
28
|
+
* True if this view should be pinned by default to all users' menus, where it will appear
|
|
29
|
+
* unless the user has explicitly unpinned it. Only applicable for global views, can be enabled
|
|
30
|
+
* by view managers to promote especially important global views and ensure users see them.
|
|
27
31
|
*/
|
|
28
32
|
readonly isDefaultPinned: boolean;
|
|
29
33
|
/**
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { GroupingChooserModel } from '@xh/hoist/cmp/grouping';
|
|
2
2
|
import { ButtonProps } from '@xh/hoist/desktop/cmp/button';
|
|
3
3
|
import '@xh/hoist/desktop/register';
|
|
4
|
-
import { ReactElement } from 'react';
|
|
5
4
|
import './GroupingChooser.scss';
|
|
6
5
|
export interface GroupingChooserProps extends ButtonProps<GroupingChooserModel> {
|
|
7
6
|
/** Text to represent empty state (i.e. value = null or []) */
|
|
@@ -12,12 +11,13 @@ export interface GroupingChooserProps extends ButtonProps<GroupingChooserModel>
|
|
|
12
11
|
popoverPosition?: 'bottom' | 'top';
|
|
13
12
|
/** Title for popover (default "GROUP BY") or null to suppress. */
|
|
14
13
|
popoverTitle?: string;
|
|
15
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Width in pixels of the popover menu itself.
|
|
16
|
+
* If unspecified, will default based on whether favorites are enabled.
|
|
17
|
+
*/
|
|
16
18
|
popoverWidth?: number;
|
|
17
19
|
/** True (default) to style target button as an input field - blends better in toolbars. */
|
|
18
20
|
styleButtonAsInput?: boolean;
|
|
19
|
-
/** Icon clicked to launch favorites menu. Defaults to Icon.favorite() */
|
|
20
|
-
favoritesIcon?: ReactElement;
|
|
21
21
|
}
|
|
22
22
|
/**
|
|
23
23
|
* Control for selecting a list of dimensions for grouping APIs, with built-in support for
|
|
@@ -1,26 +1,42 @@
|
|
|
1
|
-
import { HoistProps } from '@xh/hoist/core';
|
|
1
|
+
import { HoistProps, MenuItemLike } from '@xh/hoist/core';
|
|
2
2
|
import { ViewManagerModel } from '@xh/hoist/cmp/viewmanager';
|
|
3
3
|
import { ButtonProps } from '@xh/hoist/desktop/cmp/button';
|
|
4
|
+
import { ReactElement } from 'react';
|
|
4
5
|
import './ViewManager.scss';
|
|
5
|
-
/**
|
|
6
|
-
* Visibility options for save/revert button.
|
|
7
|
-
*
|
|
8
|
-
* 'never' to hide button.
|
|
9
|
-
* 'whenDirty' to only show when persistence state is dirty and button is therefore enabled.
|
|
10
|
-
* 'always' will always show button.
|
|
11
|
-
*/
|
|
12
|
-
export type ViewManagerStateButtonMode = 'whenDirty' | 'always' | 'never';
|
|
13
6
|
export interface ViewManagerProps extends HoistProps<ViewManagerModel> {
|
|
14
7
|
menuButtonProps?: Partial<ButtonProps>;
|
|
15
8
|
saveButtonProps?: Partial<ButtonProps>;
|
|
16
9
|
revertButtonProps?: Partial<ButtonProps>;
|
|
10
|
+
/** Button icon when on the default (in-code state) view. Default `Icon.bookmark`. */
|
|
11
|
+
defaultViewIcon?: ReactElement;
|
|
12
|
+
/** Button icon when the selected view is owned by the current user. Default `Icon.bookmark`. */
|
|
13
|
+
ownedViewIcon?: ReactElement;
|
|
14
|
+
/** Button icon when the selected view is shared by another user. Default `Icon.users`. */
|
|
15
|
+
sharedViewIcon?: ReactElement;
|
|
16
|
+
/** Button icon when the selected view is globally shared. Default `Icon.globe`. */
|
|
17
|
+
globalViewIcon?: ReactElement;
|
|
17
18
|
/** Default 'whenDirty' */
|
|
18
19
|
showSaveButton?: ViewManagerStateButtonMode;
|
|
19
20
|
/** Default 'never' */
|
|
20
21
|
showRevertButton?: ViewManagerStateButtonMode;
|
|
21
|
-
/** Side the
|
|
22
|
+
/** Side relative to the menu on which save/revert buttons should render. Default 'right'. */
|
|
22
23
|
buttonSide?: 'left' | 'right';
|
|
24
|
+
/**
|
|
25
|
+
* Array of extra menu items. Can contain:
|
|
26
|
+
* + `MenuItems` or configs to create them.
|
|
27
|
+
* + `MenuDividers` or the special string token '-'.
|
|
28
|
+
* + React Elements or strings, which will be interpreted as the `text` property for a MenuItem.
|
|
29
|
+
*/
|
|
30
|
+
extraMenuItems?: MenuItemLike[];
|
|
23
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Visibility options for save/revert buttons inlined next to the ViewManager menu:
|
|
34
|
+
* 'never' to always hide - user must save/revert via menu.
|
|
35
|
+
* 'whenDirty' (default) to show only when view state is dirty and the button is enabled.
|
|
36
|
+
* 'always' to always show, including when view not dirty and the button is disabled.
|
|
37
|
+
* Useful to avoid jumpiness in toolbar layouts.
|
|
38
|
+
*/
|
|
39
|
+
export type ViewManagerStateButtonMode = 'whenDirty' | 'always' | 'never';
|
|
24
40
|
/**
|
|
25
41
|
* Desktop ViewManager component - a button-based menu for saving and swapping between named
|
|
26
42
|
* bundles of persisted component state (e.g. grid views, dashboards, and similar).
|
|
@@ -3,14 +3,10 @@ import { ButtonProps } from '@xh/hoist/mobile/cmp/button';
|
|
|
3
3
|
import '@xh/hoist/mobile/register';
|
|
4
4
|
import './GroupingChooser.scss';
|
|
5
5
|
export interface GroupingChooserProps extends ButtonProps<GroupingChooserModel> {
|
|
6
|
+
/** Custom title for editor dialog, or null to suppress. */
|
|
7
|
+
dialogTitle?: string;
|
|
6
8
|
/** Text to represent empty state (i.e. value = null or [])*/
|
|
7
9
|
emptyText?: string;
|
|
8
|
-
/** Title for popover (default "GROUP BY") or null to suppress. */
|
|
9
|
-
popoverTitle?: string;
|
|
10
|
-
/** Min height in pixels of the popover inner content (excl. header & toolbar). */
|
|
11
|
-
popoverMinHeight?: number;
|
|
12
|
-
/** Width in pixels of the popover menu itself. */
|
|
13
|
-
popoverWidth?: number;
|
|
14
10
|
}
|
|
15
11
|
/**
|
|
16
12
|
* Control for selecting a list of dimensions for grouping APIs.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { MenuItemLike } from '@xh/hoist/core';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Parse MenuItem configs into Blueprint MenuItems.
|
|
5
|
+
*
|
|
6
|
+
* Note this is currently used in a few limited places and is not generally applied to all menu-
|
|
7
|
+
* like components in Hoist. In particular, it is not used by the `menu` component re-exported from
|
|
8
|
+
* Blueprint. See https://github.com/xh/hoist-react/issues/2400 covering TBD work to more fully
|
|
9
|
+
* standardize a Hoist menu component that might then incorporate this processing.
|
|
10
|
+
*
|
|
11
|
+
* @internal
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseMenuItems(items: MenuItemLike[]): ReactNode[];
|
|
@@ -23,7 +23,10 @@ export interface GroupingChooserConfig {
|
|
|
23
23
|
/** Initial value as an array of dimension names, or a function to produce such an array. */
|
|
24
24
|
initialValue?: string[] | (() => string[]);
|
|
25
25
|
|
|
26
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Initial favorites as an array of dim name arrays, or a function to produce such an array.
|
|
28
|
+
* Ignored if `persistWith.persistFavorites: false`.
|
|
29
|
+
*/
|
|
27
30
|
initialFavorites?: string[][] | (() => string[][]);
|
|
28
31
|
|
|
29
32
|
/** Options governing persistence. */
|
|
@@ -74,7 +77,6 @@ export class GroupingChooserModel extends HoistModel {
|
|
|
74
77
|
// Implementation fields for Control
|
|
75
78
|
@observable.ref pendingValue: string[] = [];
|
|
76
79
|
@observable editorIsOpen: boolean = false;
|
|
77
|
-
@observable favoritesIsOpen: boolean = false;
|
|
78
80
|
popoverRef = createObservableRef<HTMLElement>();
|
|
79
81
|
|
|
80
82
|
// Internal state
|
|
@@ -105,6 +107,15 @@ export class GroupingChooserModel extends HoistModel {
|
|
|
105
107
|
return !atMaxDepth && !isEmpty(availableDims);
|
|
106
108
|
}
|
|
107
109
|
|
|
110
|
+
@computed
|
|
111
|
+
get isAddFavoriteEnabled(): boolean {
|
|
112
|
+
return (
|
|
113
|
+
this.persistFavorites &&
|
|
114
|
+
!isEmpty(this.pendingValue) &&
|
|
115
|
+
!this.isFavorite(this.pendingValue)
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
108
119
|
constructor({
|
|
109
120
|
dimensions,
|
|
110
121
|
initialValue = [],
|
|
@@ -169,21 +180,13 @@ export class GroupingChooserModel extends HoistModel {
|
|
|
169
180
|
toggleEditor() {
|
|
170
181
|
this.pendingValue = this.value;
|
|
171
182
|
this.editorIsOpen = !this.editorIsOpen;
|
|
172
|
-
this.favoritesIsOpen = false;
|
|
173
183
|
}
|
|
174
184
|
|
|
175
185
|
@action
|
|
176
|
-
|
|
177
|
-
this.favoritesIsOpen = !this.favoritesIsOpen;
|
|
186
|
+
closeEditor() {
|
|
178
187
|
this.editorIsOpen = false;
|
|
179
188
|
}
|
|
180
189
|
|
|
181
|
-
@action
|
|
182
|
-
closePopover() {
|
|
183
|
-
this.editorIsOpen = false;
|
|
184
|
-
this.favoritesIsOpen = false;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
190
|
//-------------------------
|
|
188
191
|
// Value handling
|
|
189
192
|
//-------------------------
|
|
@@ -224,7 +227,7 @@ export class GroupingChooserModel extends HoistModel {
|
|
|
224
227
|
if (!isEqual(value, pendingValue) && this.validateValue(pendingValue)) {
|
|
225
228
|
this.setValue(pendingValue);
|
|
226
229
|
}
|
|
227
|
-
this.
|
|
230
|
+
this.closeEditor();
|
|
228
231
|
}
|
|
229
232
|
|
|
230
233
|
validateValue(value: string[]) {
|
|
@@ -274,6 +277,11 @@ export class GroupingChooserModel extends HoistModel {
|
|
|
274
277
|
this.favorites = [...this.favorites, value];
|
|
275
278
|
}
|
|
276
279
|
|
|
280
|
+
@action
|
|
281
|
+
addPendingAsFavorite() {
|
|
282
|
+
this.addFavorite(this.pendingValue);
|
|
283
|
+
}
|
|
284
|
+
|
|
277
285
|
@action
|
|
278
286
|
removeFavorite(value: string[]) {
|
|
279
287
|
this.favorites = this.favorites.filter(v => !isEqual(v, value));
|
|
@@ -29,7 +29,10 @@ export class ViewInfo {
|
|
|
29
29
|
/** User owning this view. Null if the view is global.*/
|
|
30
30
|
readonly owner: string;
|
|
31
31
|
|
|
32
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* True if the owner (which can be the current user) has made this view accessible to all other
|
|
34
|
+
* users. Note always `false` for global views, to better distinguish the two sharing models.
|
|
35
|
+
*/
|
|
33
36
|
readonly isShared: boolean;
|
|
34
37
|
|
|
35
38
|
/** True if this view is global and visible to all users. */
|
|
@@ -39,8 +42,9 @@ export class ViewInfo {
|
|
|
39
42
|
readonly group: string;
|
|
40
43
|
|
|
41
44
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
45
|
+
* True if this view should be pinned by default to all users' menus, where it will appear
|
|
46
|
+
* unless the user has explicitly unpinned it. Only applicable for global views, can be enabled
|
|
47
|
+
* by view managers to promote especially important global views and ensure users see them.
|
|
44
48
|
*/
|
|
45
49
|
readonly isDefaultPinned: boolean;
|
|
46
50
|
|
package/core/HoistAppModel.ts
CHANGED
|
@@ -4,17 +4,13 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Copyright © 2025 Extremely Heavy Industries Inc.
|
|
6
6
|
*/
|
|
7
|
-
import {
|
|
8
|
-
import {hoistCmp, isMenuItem, MenuItemLike, XH} from '@xh/hoist/core';
|
|
7
|
+
import {hoistCmp, MenuItemLike, XH} from '@xh/hoist/core';
|
|
9
8
|
import {ButtonProps, button} from '@xh/hoist/desktop/cmp/button';
|
|
10
9
|
import '@xh/hoist/desktop/register';
|
|
11
10
|
import {Icon} from '@xh/hoist/icon';
|
|
12
|
-
import {menu,
|
|
13
|
-
import {
|
|
14
|
-
import {filterConsecutiveMenuSeparators, isOmitted} from '@xh/hoist/utils/impl';
|
|
11
|
+
import {menu, popover} from '@xh/hoist/kit/blueprint';
|
|
12
|
+
import {parseMenuItems} from '@xh/hoist/utils/impl';
|
|
15
13
|
import {withDefault} from '@xh/hoist/utils/js';
|
|
16
|
-
import {clone, isEmpty} from 'lodash';
|
|
17
|
-
import {ReactNode} from 'react';
|
|
18
14
|
|
|
19
15
|
export interface AppMenuButtonProps extends ButtonProps {
|
|
20
16
|
/**
|
|
@@ -176,42 +172,3 @@ function buildMenuItems(props: AppMenuButtonProps) {
|
|
|
176
172
|
|
|
177
173
|
return parseMenuItems([...extraItems, '-', ...defaultItems]);
|
|
178
174
|
}
|
|
179
|
-
|
|
180
|
-
function parseMenuItems(items: MenuItemLike[]): ReactNode[] {
|
|
181
|
-
items = items.map(item => {
|
|
182
|
-
if (!isMenuItem(item)) return item;
|
|
183
|
-
|
|
184
|
-
item = clone(item);
|
|
185
|
-
item.items = clone(item.items);
|
|
186
|
-
item.prepareFn?.(item);
|
|
187
|
-
return item;
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
return items
|
|
191
|
-
.filter(it => !isMenuItem(it) || (!it.hidden && !isOmitted(it)))
|
|
192
|
-
.filter(filterConsecutiveMenuSeparators())
|
|
193
|
-
.map(item => {
|
|
194
|
-
if (item === '-') return menuDivider();
|
|
195
|
-
if (!isMenuItem(item)) return item;
|
|
196
|
-
|
|
197
|
-
const {actionFn} = item;
|
|
198
|
-
|
|
199
|
-
// Create menuItem from config
|
|
200
|
-
const cfg: MenuItemProps = {
|
|
201
|
-
text: item.text,
|
|
202
|
-
icon: item.icon,
|
|
203
|
-
intent: item.intent,
|
|
204
|
-
className: item.className,
|
|
205
|
-
onClick: actionFn ? e => wait().then(() => actionFn(e)) : null, // do async to allow menu to close
|
|
206
|
-
disabled: item.disabled
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
// Recursively parse any submenus
|
|
210
|
-
if (!isEmpty(item.items)) {
|
|
211
|
-
cfg.children = parseMenuItems(item.items);
|
|
212
|
-
cfg.popoverProps = {openOnTargetFocus: false};
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
return menuItem(cfg);
|
|
216
|
-
});
|
|
217
|
-
}
|
|
@@ -22,11 +22,6 @@
|
|
|
22
22
|
color: var(--xh-text-color-muted);
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
// We must account for the favorites icon when eliding text
|
|
27
|
-
&--with-favorites {
|
|
28
|
-
padding-right: 30px !important;
|
|
29
|
-
}
|
|
30
25
|
}
|
|
31
26
|
|
|
32
27
|
// Outer box is sized via layoutSupport - all nested inner elements should stretch to fill.
|
|
@@ -39,6 +34,10 @@
|
|
|
39
34
|
position: relative;
|
|
40
35
|
}
|
|
41
36
|
|
|
37
|
+
&__editor {
|
|
38
|
+
flex: 1;
|
|
39
|
+
}
|
|
40
|
+
|
|
42
41
|
&__list {
|
|
43
42
|
margin-bottom: var(--xh-pad-half-px);
|
|
44
43
|
background-color: var(--xh-bg-alt);
|
|
@@ -121,48 +120,38 @@
|
|
|
121
120
|
padding: 2px var(--xh-tbar-item-pad-px);
|
|
122
121
|
}
|
|
123
122
|
|
|
124
|
-
&
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
justify-content: center;
|
|
128
|
-
width: 30px;
|
|
129
|
-
height: 20px;
|
|
130
|
-
position: absolute;
|
|
131
|
-
top: 0;
|
|
132
|
-
right: 0;
|
|
133
|
-
cursor: pointer;
|
|
134
|
-
color: var(--xh-text-color-muted);
|
|
135
|
-
|
|
136
|
-
&:hover {
|
|
137
|
-
color: var(--xh-text-color);
|
|
138
|
-
}
|
|
123
|
+
&__favorites {
|
|
124
|
+
flex: 1;
|
|
125
|
+
border-left: 1px solid var(--xh-popup-border-color);
|
|
139
126
|
|
|
140
|
-
|
|
141
|
-
height: 15px;
|
|
142
|
-
}
|
|
127
|
+
--xh-menu-border: none;
|
|
143
128
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
width: 12px;
|
|
129
|
+
.bp5-menu {
|
|
130
|
+
padding: 0;
|
|
147
131
|
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
&__favorite {
|
|
151
|
-
align-items: center;
|
|
152
|
-
max-width: 50vw;
|
|
153
132
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
min-height: 20px !important;
|
|
158
|
-
visibility: hidden;
|
|
133
|
+
&__add-btn {
|
|
134
|
+
flex: none;
|
|
135
|
+
margin: var(--xh-pad-px) auto;
|
|
159
136
|
}
|
|
160
137
|
|
|
161
|
-
|
|
162
|
-
|
|
138
|
+
&__favorite {
|
|
139
|
+
align-items: center;
|
|
140
|
+
max-width: 50vw;
|
|
163
141
|
|
|
164
142
|
.xh-button {
|
|
165
|
-
|
|
143
|
+
padding: 0 !important;
|
|
144
|
+
min-width: 20px !important;
|
|
145
|
+
min-height: 20px !important;
|
|
146
|
+
visibility: hidden;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
&:hover {
|
|
150
|
+
background-color: var(--xh-bg-highlight);
|
|
151
|
+
|
|
152
|
+
.xh-button {
|
|
153
|
+
visibility: unset;
|
|
154
|
+
}
|
|
166
155
|
}
|
|
167
156
|
}
|
|
168
157
|
}
|