@elyra/canvas 12.41.0 → 12.42.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/dist/{_baseIteratee-05ccf6a8.js → _baseIteratee-148093b7.js} +3 -3
- package/dist/{_baseIteratee-05ccf6a8.js.map → _baseIteratee-148093b7.js.map} +1 -1
- package/dist/{canvas-constants-079172c0.js → canvas-constants-13b58448.js} +2 -2
- package/dist/{canvas-constants-079172c0.js.map → canvas-constants-13b58448.js.map} +1 -1
- package/dist/canvas-controller-a53943e4.js +2 -0
- package/dist/canvas-controller-a53943e4.js.map +1 -0
- package/dist/canvas-controller-cb1d7420.js +2 -0
- package/dist/canvas-controller-cb1d7420.js.map +1 -0
- package/dist/common-canvas-42027a3f.js +2 -0
- package/dist/common-canvas-42027a3f.js.map +1 -0
- package/dist/common-canvas-f758ff42.js +2 -0
- package/dist/common-canvas-f758ff42.js.map +1 -0
- package/dist/common-canvas.es.js +1 -1
- package/dist/common-canvas.es.js.map +1 -1
- package/dist/common-canvas.js +1 -1
- package/dist/common-canvas.js.map +1 -1
- package/dist/common-properties-2e1b7ec7.js +2 -0
- package/dist/common-properties-2e1b7ec7.js.map +1 -0
- package/dist/common-properties-5e8870e3.js +2 -0
- package/dist/common-properties-5e8870e3.js.map +1 -0
- package/dist/context-menu-wrapper-49f9a1af.js +2 -0
- package/dist/context-menu-wrapper-49f9a1af.js.map +1 -0
- package/dist/context-menu-wrapper-5d6a399f.js +2 -0
- package/dist/context-menu-wrapper-5d6a399f.js.map +1 -0
- package/dist/{datarecord-metadata-v3-schema-59505bc5.js → datarecord-metadata-v3-schema-98ec66e9.js} +2 -2
- package/dist/{datarecord-metadata-v3-schema-59505bc5.js.map → datarecord-metadata-v3-schema-98ec66e9.js.map} +1 -1
- package/dist/{flexible-table-43e2d052.js → flexible-table-35e9922a.js} +2 -2
- package/dist/{flexible-table-43e2d052.js.map → flexible-table-35e9922a.js.map} +1 -1
- package/dist/{flexible-table-63ffd573.js → flexible-table-7c7de0f9.js} +1 -1
- package/dist/{flexible-table-63ffd573.js.map → flexible-table-7c7de0f9.js.map} +1 -1
- package/dist/{icon-0390f1fe.js → icon-9edff40c.js} +2 -2
- package/dist/{icon-0390f1fe.js.map → icon-9edff40c.js.map} +1 -1
- package/dist/{index-57503b50.js → index-94fec521.js} +2 -2
- package/dist/{index-57503b50.js.map → index-94fec521.js.map} +1 -1
- package/dist/{index-1cd54914.js → index-e2f8a935.js} +2 -2
- package/dist/{index-1cd54914.js.map → index-e2f8a935.js.map} +1 -1
- package/dist/{isArrayLikeObject-36898fcb.js → isArrayLikeObject-7a30aa4b.js} +2 -2
- package/dist/{isArrayLikeObject-36898fcb.js.map → isArrayLikeObject-7a30aa4b.js.map} +1 -1
- package/dist/lib/canvas-controller.es.js +1 -1
- package/dist/lib/canvas-controller.js +1 -1
- package/dist/lib/canvas.es.js +1 -1
- package/dist/lib/canvas.js +1 -1
- package/dist/lib/context-menu.es.js +1 -1
- package/dist/lib/context-menu.js +1 -1
- package/dist/lib/properties/field-picker.es.js +1 -1
- package/dist/lib/properties/field-picker.js +1 -1
- package/dist/lib/properties/flexible-table.es.js +1 -1
- package/dist/lib/properties/flexible-table.js +1 -1
- package/dist/lib/properties.es.js +1 -1
- package/dist/lib/properties.js +1 -1
- package/dist/lib/tooltip.es.js +1 -1
- package/dist/lib/tooltip.es.js.map +1 -1
- package/dist/lib/tooltip.js +1 -1
- package/dist/lib/tooltip.js.map +1 -1
- package/dist/styles/common-canvas.min.css +1 -1
- package/dist/styles/common-canvas.min.css.map +1 -1
- package/dist/toolbar-6acda0a2.js +2 -0
- package/dist/toolbar-6acda0a2.js.map +1 -0
- package/dist/toolbar-d5647da2.js +2 -0
- package/dist/toolbar-d5647da2.js.map +1 -0
- package/package.json +12 -4
- package/src/color-picker/color-picker.jsx +92 -17
- package/src/command-actions/arrangeLayoutAction.js +7 -6
- package/src/command-actions/attachNodeToLinksAction.js +4 -4
- package/src/command-actions/collapseSuperNodeInPlaceAction.js +5 -5
- package/src/command-actions/colorSelectedObjectsAction.js +4 -4
- package/src/command-actions/commonPropertiesAction.js +1 -1
- package/src/command-actions/convertSuperNodeExternalToLocalAction.js +4 -4
- package/src/command-actions/convertSuperNodeLocalToExternalAction.js +4 -4
- package/src/command-actions/createAutoNodeAction.js +14 -5
- package/src/command-actions/createCommentAction.js +4 -10
- package/src/command-actions/createCommentLinkAction.js +4 -4
- package/src/command-actions/createNodeAction.js +13 -4
- package/src/command-actions/createNodeAttachLinksAction.js +4 -4
- package/src/command-actions/createNodeLinkAction.js +13 -4
- package/src/command-actions/createNodeLinkDetachedAction.js +4 -4
- package/src/command-actions/createNodeOnLinkAction.js +4 -4
- package/src/command-actions/createSuperNodeAction.js +7 -7
- package/src/command-actions/deconstructSuperNodeAction.js +5 -5
- package/src/command-actions/deleteLinkAction.js +4 -4
- package/src/command-actions/deleteObjectsAction.js +15 -6
- package/src/command-actions/disconnectObjectsAction.js +13 -4
- package/src/command-actions/displayPreviousPipelineAction.js +4 -4
- package/src/command-actions/displaySubPipelineAction.js +4 -4
- package/src/command-actions/editCommentAction.js +4 -4
- package/src/command-actions/editDecorationLabelAction.js +4 -4
- package/src/command-actions/expandSuperNodeInPlaceAction.js +5 -5
- package/src/command-actions/insertNodeIntoLinkAction.js +4 -4
- package/src/command-actions/moveObjectsAction.js +4 -4
- package/src/command-actions/pasteAction.js +16 -7
- package/src/command-actions/saveToPaletteAction.js +4 -4
- package/src/command-actions/setLinksStyleAction.js +4 -4
- package/src/command-actions/setNodeLabelAction.js +4 -4
- package/src/command-actions/setObjectsStyleAction.js +4 -4
- package/src/command-actions/sizeAndPositionObjectsAction.js +4 -4
- package/src/command-actions/updateLinkAction.js +4 -4
- package/src/common-canvas/canvas-controller-menu-utils.js +1 -1
- package/src/common-canvas/canvas-controller.js +78 -62
- package/src/common-canvas/cc-central-items.jsx +1 -1
- package/src/common-canvas/cc-context-toolbar.jsx +9 -13
- package/src/common-canvas/cc-toolbar.jsx +2 -0
- package/src/common-canvas/svg-canvas-renderer.js +6 -2
- package/src/common-canvas/svg-canvas-utils-drag-det-link.js +8 -1
- package/src/common-canvas/svg-canvas-utils-drag-new-link.js +1 -1
- package/src/common-properties/components/table-buttons/table-buttons.scss +0 -1
- package/src/common-properties/controls/expression/expression-builder/expression-builder.jsx +32 -26
- package/src/common-properties/controls/expression/expression.jsx +146 -117
- package/src/common-properties/controls/expression/expression.scss +43 -45
- package/src/common-properties/controls/expression/languages/CLEM-hint.js +86 -159
- package/src/common-properties/controls/expression/languages/python-hint.js +53 -104
- package/src/common-properties/controls/expression/languages/r-hint.js +55 -130
- package/src/common-properties/properties-controller.js +5 -0
- package/src/context-menu/common-context-menu.jsx +4 -1
- package/src/index.js +12 -2
- package/src/object-model/redux/canvas-store.js +4 -3
- package/src/toolbar/toolbar-action-item.jsx +90 -314
- package/src/toolbar/toolbar-button-item.jsx +354 -0
- package/src/toolbar/toolbar-divider-item.jsx +3 -4
- package/src/toolbar/toolbar-overflow-item.jsx +82 -36
- package/src/toolbar/toolbar-sub-menu-item.jsx +235 -0
- package/src/toolbar/toolbar-sub-menu.jsx +254 -0
- package/src/toolbar/toolbar-sub-panel.jsx +81 -0
- package/src/toolbar/toolbar-sub-utils.js +77 -0
- package/src/toolbar/toolbar.jsx +330 -146
- package/src/toolbar/toolbar.scss +22 -15
- package/src/tooltip/tooltip.jsx +9 -2
- package/stats.html +1 -1
- package/dist/canvas-controller-1e71b405.js +0 -2
- package/dist/canvas-controller-1e71b405.js.map +0 -1
- package/dist/canvas-controller-4bed5320.js +0 -2
- package/dist/canvas-controller-4bed5320.js.map +0 -1
- package/dist/common-canvas-097c5169.js +0 -2
- package/dist/common-canvas-097c5169.js.map +0 -1
- package/dist/common-canvas-e13c0858.js +0 -2
- package/dist/common-canvas-e13c0858.js.map +0 -1
- package/dist/common-properties-706cef87.js +0 -2
- package/dist/common-properties-706cef87.js.map +0 -1
- package/dist/common-properties-9bd69b61.js +0 -2
- package/dist/common-properties-9bd69b61.js.map +0 -1
- package/dist/context-menu-wrapper-3a7fdec8.js +0 -2
- package/dist/context-menu-wrapper-3a7fdec8.js.map +0 -1
- package/dist/context-menu-wrapper-fc85d853.js +0 -2
- package/dist/context-menu-wrapper-fc85d853.js.map +0 -1
- package/dist/toolbar-918ab52e.js +0 -2
- package/dist/toolbar-918ab52e.js.map +0 -1
- package/dist/toolbar-fdb750f9.js +0 -2
- package/dist/toolbar-fdb750f9.js.map +0 -1
- package/src/toolbar/toolbar-action-sub-area.jsx +0 -126
- package/src/toolbar/toolbar-overflow-menu.jsx +0 -77
- package/src/toolbar/toolbar-utils.js +0 -33
package/src/toolbar/toolbar.jsx
CHANGED
|
@@ -22,31 +22,110 @@ import ToolbarActionItem from "./toolbar-action-item.jsx";
|
|
|
22
22
|
import ToolbarOverflowItem from "./toolbar-overflow-item.jsx";
|
|
23
23
|
import ToolbarDividerItem from "./toolbar-divider-item.jsx";
|
|
24
24
|
|
|
25
|
+
const ESC_KEY = 27;
|
|
26
|
+
const LEFT_ARROW_KEY = 37;
|
|
27
|
+
const RIGHT_ARROW_KEY = 39;
|
|
28
|
+
|
|
25
29
|
class Toolbar extends React.Component {
|
|
26
30
|
constructor(props) {
|
|
27
31
|
super(props);
|
|
28
32
|
|
|
33
|
+
// this.state.focusAction keeps track of which item has focus.
|
|
34
|
+
// This is used to ensure the focus goes to the same item that was
|
|
35
|
+
// previously focused when focus was lost (blurred) from the toolbar
|
|
36
|
+
// Index values (leftOverflowIndex and rightOverflowIndex) are used
|
|
37
|
+
// to keep track of how the left and right bar arrays
|
|
38
|
+
// should be split to be able to create the overflow menu.
|
|
39
|
+
this.state = {
|
|
40
|
+
focusAction: "toolbar",
|
|
41
|
+
leftOverflowIndex: null,
|
|
42
|
+
rightOverflowIndex: null,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// Keeps track of whether the focus is on the toolbar or not. We should
|
|
46
|
+
// not call focus() on any item in the toolbar if this.isFocusInToolbar
|
|
47
|
+
// is false, otherwise focus will be moved incorrectly to the toolbar
|
|
48
|
+
// and away from its current location.
|
|
49
|
+
this.isFocusInToolbar = false;
|
|
50
|
+
|
|
51
|
+
// Arrays to hold the left and right bar configurations
|
|
29
52
|
this.leftBar = [];
|
|
30
53
|
this.rightBar = [];
|
|
31
54
|
|
|
32
|
-
|
|
55
|
+
// Arrays to store references to React objects in toolbar for the
|
|
56
|
+
// the left bar, right bar and current set of overflow items.
|
|
57
|
+
this.leftItemRefs = [];
|
|
58
|
+
this.rightItemRefs = [];
|
|
59
|
+
this.overflowItemRefs = [];
|
|
60
|
+
|
|
61
|
+
// Reference for the toolbar <div>
|
|
62
|
+
this.toolbarRef = React.createRef();
|
|
63
|
+
|
|
33
64
|
this.onFocus = this.onFocus.bind(this);
|
|
65
|
+
this.onBlur = this.onBlur.bind(this);
|
|
66
|
+
this.onKeyDown = this.onKeyDown.bind(this);
|
|
34
67
|
this.onToolbarResize = this.onToolbarResize.bind(this);
|
|
35
|
-
this.
|
|
68
|
+
this.setOverflowIndex = this.setOverflowIndex.bind(this);
|
|
36
69
|
this.generateToolbarItems = this.generateToolbarItems.bind(this);
|
|
37
|
-
this.
|
|
70
|
+
this.setFocusAction = this.setFocusAction.bind(this);
|
|
71
|
+
this.setFocusOnItem = this.setFocusOnItem.bind(this);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// If, after updating, we are left in a situation where this.state.focusAction
|
|
75
|
+
// is for an item that is NOT focusable, then set the focus on the first focusable
|
|
76
|
+
// item. This might happen when an item with focus is activated and the action it
|
|
77
|
+
// performs causes itself to become disabled. For example, if the delete item is
|
|
78
|
+
// activated the selected objects are deleted and since no objects are now selected
|
|
79
|
+
// the delete item (which has focus) will become disabled.
|
|
80
|
+
componentDidUpdate() {
|
|
81
|
+
if (this.isFocusInToolbar) {
|
|
82
|
+
const index = this.getFocusableItemRefs().findIndex((item) => this.getRefAction(item) === this.state.focusAction);
|
|
83
|
+
if (index === -1) {
|
|
84
|
+
this.setFocusOnFirstItem();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// When the toolbar is initially focused, this.state.focusAction
|
|
90
|
+
// will be set to the default of "toolbar". In that case we set the
|
|
91
|
+
// focus on the first focusable toolbar item.
|
|
92
|
+
onFocus(evt) {
|
|
93
|
+
this.isFocusInToolbar = true;
|
|
94
|
+
|
|
95
|
+
// If focus occurs because of a click on the toolbar body
|
|
96
|
+
// (not on a button) and no button has focus move focus to
|
|
97
|
+
// the first item otherwise just keep focus the same.
|
|
98
|
+
if (evt.target?.classList?.contains("toolbar-div")) {
|
|
99
|
+
if (this.state.focusAction === "toolbar") {
|
|
100
|
+
this.setFocusOnFirstItem();
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
} else {
|
|
104
|
+
this.setFocusOnItem(); // Reset focus on current focusAction.
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// When focus leaves the toolbar make sure we record it so we don't
|
|
110
|
+
// accidentally set focus on a toolbar item when re-rendering with
|
|
111
|
+
// the focus elsewhere.
|
|
112
|
+
onBlur() {
|
|
113
|
+
this.isFocusInToolbar = false;
|
|
38
114
|
}
|
|
39
115
|
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
116
|
+
// This is called when the user presses a key with focus on one of the
|
|
117
|
+
// toolbar items. We set the focusAction appropriately based on which
|
|
118
|
+
// key is pressed.
|
|
119
|
+
onKeyDown(evt) {
|
|
120
|
+
if (evt.keyCode === ESC_KEY) {
|
|
121
|
+
this.setFocusOnItem(); // Reset focus on current focusAction.
|
|
122
|
+
|
|
123
|
+
} else if (evt.keyCode === LEFT_ARROW_KEY) {
|
|
124
|
+
this.setFocusOnPreviousItem();
|
|
125
|
+
|
|
126
|
+
} else if (evt.keyCode === RIGHT_ARROW_KEY) {
|
|
127
|
+
this.setFocusOnNextItem();
|
|
128
|
+
}
|
|
50
129
|
}
|
|
51
130
|
|
|
52
131
|
// Prevents the inline-block elements of the left bar being scrolled to
|
|
@@ -56,166 +135,257 @@ class Toolbar extends React.Component {
|
|
|
56
135
|
evt.preventDefault();
|
|
57
136
|
}
|
|
58
137
|
|
|
59
|
-
//
|
|
60
|
-
//
|
|
138
|
+
// When the toolbar resizes, check each toolbar item to see if it has
|
|
139
|
+
// a sub-menu open and, if it does, close it.
|
|
61
140
|
onToolbarResize() {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
141
|
+
this.leftItemRefs.forEach((ref) => this.closeSubMenuOnRef(ref));
|
|
142
|
+
this.rightItemRefs.forEach((ref) => this.closeSubMenuOnRef(ref));
|
|
143
|
+
this.overflowItemRefs.forEach((ref) => this.closeOverflowMenuOnRef(ref));
|
|
65
144
|
|
|
66
|
-
this.
|
|
67
|
-
|
|
145
|
+
if (this.isFocusInToolbar) {
|
|
146
|
+
this.setFocusOnFirstItem();
|
|
147
|
+
}
|
|
68
148
|
}
|
|
69
149
|
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
// is
|
|
73
|
-
|
|
74
|
-
|
|
150
|
+
// Either sets the focus on the item for the action passed in or, if
|
|
151
|
+
// no action is passed in, set the focus on the current focusAction.
|
|
152
|
+
// Setting the current focusAction is used to return focus back to an
|
|
153
|
+
// item after focus has been moved elsewhere, such as onto a sub-menu
|
|
154
|
+
// or out of the toolbar completely.
|
|
155
|
+
setFocusOnItem(action) {
|
|
156
|
+
const actionToSet = action || this.state.focusAction;
|
|
157
|
+
const focusableItemRefs = this.getFocusableItemRefs();
|
|
158
|
+
if (focusableItemRefs.length > 0) {
|
|
159
|
+
this.setFocusAction(actionToSet);
|
|
160
|
+
}
|
|
75
161
|
}
|
|
76
162
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// Note: We detect the y coordinate of the 'top row' by using the top of
|
|
83
|
-
// the first overflow icon. This is because the toolbar might be compressed
|
|
84
|
-
// to the extent that the first overflow icon is the only item on the left
|
|
85
|
-
// of the toolbar.
|
|
86
|
-
setLeftBarItemsTabIndex() {
|
|
87
|
-
const bar = this.getBar("left");
|
|
88
|
-
if (!bar) {
|
|
89
|
-
return;
|
|
163
|
+
setFocusOnFirstItem() {
|
|
164
|
+
const focusableItemRefs = this.getFocusableItemRefs();
|
|
165
|
+
if (focusableItemRefs.length > 0) {
|
|
166
|
+
const firstFocusAction = this.getRefAction(focusableItemRefs[0]);
|
|
167
|
+
this.setFocusAction(firstFocusAction);
|
|
90
168
|
}
|
|
169
|
+
}
|
|
91
170
|
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
|
|
171
|
+
setFocusOnPreviousItem() {
|
|
172
|
+
const focusableItemRefs = this.getFocusableItemRefs();
|
|
173
|
+
const previousRef = this.getPreviousItemRef(focusableItemRefs);
|
|
174
|
+
if (previousRef) {
|
|
175
|
+
const previousFocusAction = this.getRefAction(previousRef);
|
|
176
|
+
this.setFocusAction(previousFocusAction);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
95
179
|
|
|
96
|
-
|
|
97
|
-
|
|
180
|
+
setFocusOnNextItem() {
|
|
181
|
+
const focusableItemRefs = this.getFocusableItemRefs();
|
|
182
|
+
const nextRef = this.getNextItemRef(focusableItemRefs);
|
|
183
|
+
if (nextRef) {
|
|
184
|
+
const nextFocusAction = this.getRefAction(nextRef);
|
|
185
|
+
this.setFocusAction(nextFocusAction);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
98
188
|
|
|
99
|
-
|
|
189
|
+
setFocusAction(focusAction) {
|
|
190
|
+
this.setState({ focusAction });
|
|
191
|
+
}
|
|
100
192
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
this.setToolbarItemButtonTabIndex(items[i], -1);
|
|
106
|
-
}
|
|
193
|
+
getPreviousItemRef(focusableItemRefs) {
|
|
194
|
+
const index = focusableItemRefs.findIndex((item) => this.getRefAction(item) === this.state.focusAction);
|
|
195
|
+
if (index > 0) {
|
|
196
|
+
return focusableItemRefs[index - 1];
|
|
107
197
|
}
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
108
200
|
|
|
109
|
-
|
|
110
|
-
|
|
201
|
+
getNextItemRef(focusableItemRefs) {
|
|
202
|
+
const index = focusableItemRefs.findIndex((item) => this.getRefAction(item) === this.state.focusAction);
|
|
203
|
+
if (index < focusableItemRefs.length - 1) {
|
|
204
|
+
return focusableItemRefs[index + 1];
|
|
111
205
|
}
|
|
206
|
+
return null;
|
|
112
207
|
}
|
|
113
208
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
setRightBarItemsTabIndex() {
|
|
118
|
-
const items = this.getRightBarItems();
|
|
119
|
-
let topRow = 0;
|
|
209
|
+
getRefAction(ref) {
|
|
210
|
+
return ref.current.getAction();
|
|
211
|
+
}
|
|
120
212
|
|
|
121
|
-
|
|
122
|
-
|
|
213
|
+
// Returns an array of references to focusable (that is enabled)
|
|
214
|
+
// toolbar items that are on the top (visible) row of the toolbar.
|
|
215
|
+
getFocusableItemRefs() {
|
|
216
|
+
return this.getLeftBarFocusableItemRefs().concat(this.getRightBarFocusableItemRefs());
|
|
217
|
+
}
|
|
123
218
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
219
|
+
// Returns an array of references to left bar items that are
|
|
220
|
+
// on the top (visible) row of the toolbar and are focusable.
|
|
221
|
+
// That is, not disabled. In addition, there may also be a
|
|
222
|
+
// reference to an overflow item if one is visible on the
|
|
223
|
+
// top (visible) row of the toolbar.
|
|
224
|
+
getLeftBarFocusableItemRefs() {
|
|
225
|
+
const focusableItemRefs = [];
|
|
127
226
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
227
|
+
if (this.leftItemRefs.length === 0) {
|
|
228
|
+
return focusableItemRefs;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const topRowY = this.findToolbarTopYCoordinate();
|
|
232
|
+
let overflowItemRef = null;
|
|
233
|
+
|
|
234
|
+
for (let i = 0; i < this.leftItemRefs.length; i++) {
|
|
235
|
+
const itemRect = this.leftItemRefs[i].current.getBoundingRect();
|
|
236
|
+
|
|
237
|
+
if (itemRect.top === topRowY) {
|
|
238
|
+
if (this.leftItemRefs[i].current.isEnabled()) {
|
|
239
|
+
focusableItemRefs.push(this.leftItemRefs[i]);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
} else if (!overflowItemRef) {
|
|
243
|
+
const leftRefAction = this.getRefAction(this.leftItemRefs[i]);
|
|
244
|
+
const overflowAction = this.getOverflowAction(leftRefAction);
|
|
245
|
+
overflowItemRef = this.overflowItemRefs.find((oRef) => oRef.current.getAction() === overflowAction);
|
|
246
|
+
if (overflowItemRef) {
|
|
247
|
+
focusableItemRefs.push(overflowItemRef);
|
|
248
|
+
}
|
|
132
249
|
}
|
|
133
250
|
}
|
|
134
|
-
}
|
|
135
251
|
|
|
136
|
-
|
|
137
|
-
const id = this.props.instanceId;
|
|
138
|
-
const part = document.querySelector(`.toolbar-div[instanceid='${id}'] > .toolbar-${side}-bar`) || [];
|
|
139
|
-
return part;
|
|
252
|
+
return focusableItemRefs;
|
|
140
253
|
}
|
|
141
254
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
255
|
+
// Returns an array of references to right bar items that are
|
|
256
|
+
// on the top (visible) row of the toolbar and are focusable.
|
|
257
|
+
// That is, not disabled.
|
|
258
|
+
getRightBarFocusableItemRefs() {
|
|
259
|
+
const focusableItemRefs = [];
|
|
260
|
+
|
|
261
|
+
if (this.rightItemRefs === 0) {
|
|
262
|
+
return focusableItemRefs;
|
|
146
263
|
}
|
|
147
|
-
return bar.querySelectorAll("[data-toolbar-item=true]") || [];
|
|
148
|
-
}
|
|
149
264
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
265
|
+
const topRowY = this.findToolbarTopYCoordinate();
|
|
266
|
+
|
|
267
|
+
for (let i = 0; i < this.rightItemRefs.length; i++) {
|
|
268
|
+
if (this.rightItemRefs[i].current.isEnabled()) {
|
|
269
|
+
const refRect = this.rightItemRefs[i].current.getBoundingRect();
|
|
270
|
+
|
|
271
|
+
if (refRect.top === topRowY) {
|
|
272
|
+
focusableItemRefs.push(this.rightItemRefs[i]);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
155
275
|
}
|
|
156
|
-
return
|
|
276
|
+
return focusableItemRefs.reverse();
|
|
157
277
|
}
|
|
158
278
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
279
|
+
// Items that appear in the overflow menu need unique action names because
|
|
280
|
+
// the original action item to which they are related will still exist, but
|
|
281
|
+
// hidden, in the toolbar.
|
|
282
|
+
getOverflowAction(action) {
|
|
283
|
+
return "overflow_" + action;
|
|
162
284
|
}
|
|
163
285
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
286
|
+
// Sets two index values: one for the left bar and one for the right that
|
|
287
|
+
// indicate which elements in each array should be put in the overflow menu.
|
|
288
|
+
// That is, those elements that do not appear on the top (visible) row of the
|
|
289
|
+
// toolbar.
|
|
290
|
+
setOverflowIndex(leftIndex) {
|
|
291
|
+
if (leftIndex === null) {
|
|
292
|
+
this.setState({
|
|
293
|
+
leftOverflowIndex: null,
|
|
294
|
+
rightOverflowIndex: null
|
|
295
|
+
});
|
|
296
|
+
} else {
|
|
297
|
+
this.setState({
|
|
298
|
+
leftOverflowIndex: leftIndex,
|
|
299
|
+
rightOverflowIndex: this.getRightOverflowIndex()
|
|
300
|
+
});
|
|
168
301
|
}
|
|
169
302
|
}
|
|
170
303
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
304
|
+
// Returns the index of the first item in the right bar that is
|
|
305
|
+
// not on the top (visible) row of the toolbar.
|
|
306
|
+
getRightOverflowIndex() {
|
|
307
|
+
const ref = this.findFirstRightItemRefNotOnTopRow();
|
|
308
|
+
|
|
309
|
+
const index = ref === null
|
|
310
|
+
? this.rightBar.length - 1
|
|
311
|
+
: this.rightBar.findIndex((ri) => ri.action === this.getRefAction(ref));
|
|
312
|
+
|
|
313
|
+
return index;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Returns a reference to the first item that is not on the
|
|
317
|
+
// top (visible) row of the toolbar.
|
|
318
|
+
findFirstRightItemRefNotOnTopRow() {
|
|
319
|
+
const topRowY = this.findToolbarTopYCoordinate();
|
|
320
|
+
|
|
321
|
+
let rightItemRef = null;
|
|
322
|
+
|
|
323
|
+
for (let i = 0; i < this.rightItemRefs.length; i++) {
|
|
324
|
+
const itemRect = this.rightItemRefs[i].current.getBoundingRect();
|
|
325
|
+
if (itemRect.top !== topRowY && rightItemRef === null) {
|
|
326
|
+
rightItemRef = this.rightItemRefs[i];
|
|
177
327
|
}
|
|
178
328
|
}
|
|
329
|
+
return rightItemRef;
|
|
179
330
|
}
|
|
180
331
|
|
|
181
|
-
|
|
332
|
+
// Returns the Y coordinate of the top of the toolbar. This is
|
|
333
|
+
// used to detecg which toolbar items are on the top (visible)
|
|
334
|
+
// row and which are wrapped onto other rows.
|
|
335
|
+
findToolbarTopYCoordinate() {
|
|
336
|
+
const rect = this.toolbarRef.current.getBoundingClientRect();
|
|
337
|
+
return rect.top;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Generates an array of toolbar items from the toolbarActions array passed in. When
|
|
341
|
+
// withOverflowItem is true, which it is for the left bar, we also add an overflow item,
|
|
342
|
+
// inside an overflow item container, for each left toolbar action. As the canvas is made
|
|
343
|
+
// narrower the regular action items wrap onto a second (hidden) row of the toolbar and
|
|
344
|
+
// the overflow item, associated with the last wrapped action item, is revealed.
|
|
345
|
+
generateToolbarItems(toolbarActions, withOverflowItem, refs) {
|
|
182
346
|
const newItems = [];
|
|
183
347
|
|
|
184
|
-
for (let i = 0; i <
|
|
185
|
-
const actionObj =
|
|
348
|
+
for (let i = 0; i < toolbarActions.length; i++) {
|
|
349
|
+
const actionObj = toolbarActions[i];
|
|
186
350
|
if (actionObj) {
|
|
187
|
-
if (
|
|
188
|
-
newItems.push(this.
|
|
351
|
+
if (!actionObj.divider && withOverflowItem) {
|
|
352
|
+
newItems.push(this.generateOverflowItem(i, actionObj.action));
|
|
189
353
|
}
|
|
190
|
-
newItems.push(this.generateToolbarItem(actionObj, i,
|
|
354
|
+
newItems.push(this.generateToolbarItem(actionObj, i, refs));
|
|
191
355
|
}
|
|
192
356
|
}
|
|
193
357
|
return newItems;
|
|
194
358
|
}
|
|
195
359
|
|
|
196
|
-
|
|
360
|
+
// Returns JSX for a toolbar item based on the actionObj passed in.
|
|
361
|
+
generateToolbarItem(actionObj, i, refs) {
|
|
197
362
|
let jsx = null;
|
|
363
|
+
|
|
198
364
|
if (actionObj) {
|
|
199
365
|
if (actionObj.divider) {
|
|
200
366
|
jsx = (
|
|
201
367
|
<ToolbarDividerItem
|
|
202
368
|
key={"toolbar-item-key-" + i}
|
|
203
|
-
|
|
369
|
+
isInMenu={false}
|
|
204
370
|
/>
|
|
205
371
|
);
|
|
206
372
|
} else {
|
|
373
|
+
const ref = React.createRef();
|
|
374
|
+
if (refs) {
|
|
375
|
+
refs.push(ref);
|
|
376
|
+
}
|
|
207
377
|
jsx = (
|
|
208
378
|
<ToolbarActionItem
|
|
379
|
+
ref={ref}
|
|
209
380
|
key={"toolbar-item-key-" + i}
|
|
210
381
|
actionObj={actionObj}
|
|
211
382
|
tooltipDirection={this.props.tooltipDirection}
|
|
212
383
|
toolbarActionHandler={this.props.toolbarActionHandler}
|
|
213
|
-
generateToolbarItems={this.generateToolbarItems}
|
|
214
|
-
setResizeHandler={this.setResizeHandler}
|
|
215
|
-
overflow={overflow}
|
|
216
384
|
instanceId={this.props.instanceId}
|
|
217
385
|
containingDivId={this.props.containingDivId}
|
|
218
|
-
|
|
386
|
+
toolbarFocusAction={this.state.focusAction}
|
|
387
|
+
setToolbarFocusAction={this.setFocusOnItem}
|
|
388
|
+
isFocusInToolbar={this.isFocusInToolbar}
|
|
219
389
|
size={this.props.size}
|
|
220
390
|
/>
|
|
221
391
|
);
|
|
@@ -224,57 +394,62 @@ class Toolbar extends React.Component {
|
|
|
224
394
|
return jsx;
|
|
225
395
|
}
|
|
226
396
|
|
|
227
|
-
|
|
397
|
+
// Returns JSX for an overflow toolbar item based on the index and action passed in.
|
|
398
|
+
generateOverflowItem(index, action) {
|
|
228
399
|
const label = this.props.additionalText ? this.props.additionalText.overflowMenuLabel : "";
|
|
400
|
+
const overflowAction = this.getOverflowAction(action);
|
|
401
|
+
const subMenuActions = index === this.state.leftOverflowIndex ? this.createSubMenuActions() : [];
|
|
402
|
+
|
|
403
|
+
// Create a ref for the overflow item to add to array of references to
|
|
404
|
+
// all overflow items.
|
|
405
|
+
const ref = React.createRef();
|
|
406
|
+
this.overflowItemRefs.push(ref);
|
|
407
|
+
|
|
229
408
|
const jsx = (
|
|
230
409
|
<ToolbarOverflowItem
|
|
410
|
+
ref={ref}
|
|
231
411
|
key={"toolbar-overflow-item-key-" + index}
|
|
232
412
|
index={index}
|
|
233
|
-
|
|
234
|
-
setResizeHandler={this.setResizeHandler}
|
|
235
|
-
containingDivId={this.props.containingDivId}
|
|
236
|
-
onFocus={this.onFocus}
|
|
413
|
+
action={overflowAction}
|
|
237
414
|
label={label}
|
|
238
415
|
size={this.props.size}
|
|
416
|
+
subMenuActions={subMenuActions}
|
|
417
|
+
setOverflowIndex={this.setOverflowIndex}
|
|
418
|
+
toolbarActionHandler={this.props.toolbarActionHandler}
|
|
419
|
+
instanceId={this.props.instanceId}
|
|
420
|
+
containingDivId={this.props.containingDivId}
|
|
421
|
+
toolbarFocusAction={this.state.focusAction}
|
|
422
|
+
setToolbarFocusAction={this.setFocusOnItem}
|
|
423
|
+
isFocusInToolbar={this.isFocusInToolbar}
|
|
239
424
|
/>
|
|
240
425
|
);
|
|
241
426
|
|
|
242
427
|
return jsx;
|
|
243
428
|
}
|
|
244
429
|
|
|
245
|
-
//
|
|
246
|
-
//
|
|
247
|
-
//
|
|
248
|
-
//
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
return extensionItems;
|
|
430
|
+
// Returns an array of overflow menu actions that should be displayed in
|
|
431
|
+
// the overflow menu for the overflow item indicated by the index passed in.
|
|
432
|
+
// This uses this.state.leftOverflowIndex and this.state.rightOverflowIndex which are
|
|
433
|
+
// set when the user clicks on a particular overflow item in the toolbar.
|
|
434
|
+
createSubMenuActions() {
|
|
435
|
+
let subMenuActions = [];
|
|
436
|
+
const l = this.leftBar.slice(this.state.leftOverflowIndex);
|
|
437
|
+
const r = this.rightBar.slice(this.state.rightOverflowIndex).reverse();
|
|
438
|
+
subMenuActions = l.concat(r);
|
|
439
|
+
|
|
440
|
+
return subMenuActions;
|
|
257
441
|
}
|
|
258
442
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
let topRow = 0;
|
|
265
|
-
|
|
266
|
-
for (let i = 0; i < items.length; i++) {
|
|
267
|
-
const rect = items[i].getBoundingClientRect();
|
|
268
|
-
|
|
269
|
-
if (i === 0) {
|
|
270
|
-
topRow = rect.top;
|
|
271
|
-
}
|
|
443
|
+
closeSubMenuOnRef(ref) {
|
|
444
|
+
if (ref.current.state.subAreaDisplayed) {
|
|
445
|
+
ref.current.closeSubArea();
|
|
446
|
+
}
|
|
447
|
+
}
|
|
272
448
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
449
|
+
closeOverflowMenuOnRef(ref) {
|
|
450
|
+
if (ref.current.state.showExtendedMenu) {
|
|
451
|
+
ref.current.closeSubMenu();
|
|
276
452
|
}
|
|
277
|
-
return newDefItems;
|
|
278
453
|
}
|
|
279
454
|
|
|
280
455
|
render() {
|
|
@@ -282,13 +457,22 @@ class Toolbar extends React.Component {
|
|
|
282
457
|
this.rightBar = this.props.config.rightBar || [];
|
|
283
458
|
this.rightBar = [...this.rightBar].reverse() || [];
|
|
284
459
|
|
|
285
|
-
|
|
286
|
-
|
|
460
|
+
// Arrays to store references to React objects in toolbar.
|
|
461
|
+
this.leftItemRefs = [];
|
|
462
|
+
this.rightItemRefs = [];
|
|
463
|
+
this.overflowItemRefs = [];
|
|
464
|
+
|
|
465
|
+
const leftItems = this.generateToolbarItems(this.leftBar, true, this.leftItemRefs);
|
|
466
|
+
const rightItems = this.generateToolbarItems(this.rightBar, false, this.rightItemRefs);
|
|
287
467
|
|
|
288
468
|
const toolbarSizeClass = this.props.size === "sm" ? "toolbar-div toolbar-size-small" : "toolbar-div";
|
|
469
|
+
const tabIndex = this.state.focusAction === "toolbar" ? 0 : -1;
|
|
470
|
+
|
|
289
471
|
const canvasToolbar = (
|
|
290
472
|
<ReactResizeDetector handleWidth onResize={this.onToolbarResize}>
|
|
291
|
-
<div className={toolbarSizeClass} instanceid={this.props.instanceId}
|
|
473
|
+
<div ref={this.toolbarRef} className={toolbarSizeClass} instanceid={this.props.instanceId}
|
|
474
|
+
tabIndex={tabIndex} onFocus={this.onFocus} onBlur={this.onBlur} onKeyDown={this.onKeyDown}
|
|
475
|
+
>
|
|
292
476
|
<div className="toolbar-left-bar" onScroll={this.onScroll}>
|
|
293
477
|
{leftItems}
|
|
294
478
|
</div>
|