@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
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2017-2023 Elyra Authors
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import React from "react";
|
|
18
|
+
import PropTypes from "prop-types";
|
|
19
|
+
|
|
20
|
+
import Tooltip from "../tooltip/tooltip.jsx";
|
|
21
|
+
import ArrangeHorizontally from "./../../assets/images/arrange_horizontally.svg";
|
|
22
|
+
import ArrangeVertically from "./../../assets/images/arrange_vertically.svg";
|
|
23
|
+
import ToggleNotificationPanel from "./../../assets/images/notification_counter_icon.svg";
|
|
24
|
+
import PaletteClose from "./../../assets/images/palette/palette_close.svg";
|
|
25
|
+
import PaletteOpen from "./../../assets/images/palette/palette_open.svg";
|
|
26
|
+
import ZoomToFit from "./../../assets/images/zoom_to_fit.svg";
|
|
27
|
+
|
|
28
|
+
import { Button } from "carbon-components-react";
|
|
29
|
+
import SVG from "react-inlinesvg";
|
|
30
|
+
import classNames from "classnames";
|
|
31
|
+
import { StopFilledAlt16, Play16, Undo16, Redo16, Chat16, ChatOff16, Result16,
|
|
32
|
+
Cut16, Copy16, Paste16, Edit16, ColorPalette16, Maximize16, Minimize16,
|
|
33
|
+
Launch16, AddComment16, TrashCan16, ZoomIn16, ZoomOut16,
|
|
34
|
+
ChevronRight16, ChevronDown16, ChevronUp16 } from "@carbon/icons-react";
|
|
35
|
+
import { TOOLBAR_STOP, TOOLBAR_RUN, TOOLBAR_UNDO, TOOLBAR_REDO,
|
|
36
|
+
TOOLBAR_CUT, TOOLBAR_COPY, TOOLBAR_PASTE, TOOLBAR_CLIPBOARD,
|
|
37
|
+
TOOLBAR_CREATE_COMMENT, TOOLBAR_CREATE_AUTO_COMMENT, TOOLBAR_COLOR_BACKGROUND,
|
|
38
|
+
TOOLBAR_DELETE_SELECTED_OBJECTS, TOOLBAR_DELETE_LINK,
|
|
39
|
+
TOOLBAR_ZOOM_IN, TOOLBAR_ZOOM_OUT, TOOLBAR_ZOOM_FIT,
|
|
40
|
+
TOOLBAR_ARRANGE_HORIZONALLY, TOOLBAR_ARRANGE_VERTICALLY,
|
|
41
|
+
TOOLBAR_OPEN_PALETTE, TOOLBAR_CLOSE_PALETTE, TOOLBAR_TOGGLE_NOTIFICATION_PANEL,
|
|
42
|
+
TOOLBAR_SHOW_COMMENTS, TOOLBAR_HIDE_COMMENTS,
|
|
43
|
+
TOOLBAR_EXPAND_SUPERNODE_IN_PLACE, TOOLBAR_COLLAPSE_SUPERNODE_IN_PLACE,
|
|
44
|
+
TOOLBAR_EXPAND_SUPERNODE_FULL_PAGE, TOOLBAR_SET_NODE_LABEL_EDIT, TOOLBAR_SET_COMMENT_EDIT_MODE }
|
|
45
|
+
from "../common-canvas/constants/canvas-constants.js";
|
|
46
|
+
|
|
47
|
+
class ToolbarButtonItem extends React.Component {
|
|
48
|
+
constructor(props) {
|
|
49
|
+
super(props);
|
|
50
|
+
|
|
51
|
+
this.buttonRef = React.createRef();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
componentDidUpdate() {
|
|
55
|
+
if (this.props.isFocusInToolbar &&
|
|
56
|
+
this.props.buttonFocusAction === this.props.actionObj.action) {
|
|
57
|
+
this.buttonRef.current.focus();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Returns a default icon, if there is one, for the action passed in.
|
|
62
|
+
// It also may be set to disabled state.
|
|
63
|
+
getDefaultIcon(actionObj) {
|
|
64
|
+
const disabled = !actionObj.enable;
|
|
65
|
+
|
|
66
|
+
switch (actionObj.action) {
|
|
67
|
+
case (TOOLBAR_STOP):
|
|
68
|
+
return <StopFilledAlt16 disabled={disabled} />;
|
|
69
|
+
case (TOOLBAR_RUN):
|
|
70
|
+
return <Play16 disabled={disabled} />;
|
|
71
|
+
case (TOOLBAR_EXPAND_SUPERNODE_IN_PLACE):
|
|
72
|
+
return <Maximize16 disabled={disabled} />;
|
|
73
|
+
case (TOOLBAR_COLLAPSE_SUPERNODE_IN_PLACE):
|
|
74
|
+
return <Minimize16 disabled={disabled} />;
|
|
75
|
+
case (TOOLBAR_EXPAND_SUPERNODE_FULL_PAGE):
|
|
76
|
+
return <Launch16 disabled={disabled} />;
|
|
77
|
+
case (TOOLBAR_UNDO):
|
|
78
|
+
return <Undo16 disabled={disabled} />;
|
|
79
|
+
case (TOOLBAR_REDO):
|
|
80
|
+
return <Redo16 disabled={disabled} />;
|
|
81
|
+
case (TOOLBAR_CLIPBOARD):
|
|
82
|
+
return <Result16 disabled={disabled} />;
|
|
83
|
+
case (TOOLBAR_CUT):
|
|
84
|
+
return <Cut16 disabled={disabled} />;
|
|
85
|
+
case (TOOLBAR_COPY):
|
|
86
|
+
return <Copy16 disabled={disabled} />;
|
|
87
|
+
case (TOOLBAR_PASTE):
|
|
88
|
+
return <Paste16 disabled={disabled} />;
|
|
89
|
+
case (TOOLBAR_CREATE_COMMENT):
|
|
90
|
+
case (TOOLBAR_CREATE_AUTO_COMMENT):
|
|
91
|
+
return <AddComment16 disabled={disabled} />;
|
|
92
|
+
case (TOOLBAR_SHOW_COMMENTS):
|
|
93
|
+
return <Chat16 disabled={disabled} />;
|
|
94
|
+
case (TOOLBAR_HIDE_COMMENTS):
|
|
95
|
+
return <ChatOff16 disabled={disabled} />;
|
|
96
|
+
case (TOOLBAR_COLOR_BACKGROUND):
|
|
97
|
+
return <ColorPalette16 disabled={disabled} />;
|
|
98
|
+
case (TOOLBAR_DELETE_LINK):
|
|
99
|
+
case (TOOLBAR_DELETE_SELECTED_OBJECTS):
|
|
100
|
+
return <TrashCan16 disabled={disabled} />;
|
|
101
|
+
case (TOOLBAR_SET_COMMENT_EDIT_MODE):
|
|
102
|
+
case (TOOLBAR_SET_NODE_LABEL_EDIT):
|
|
103
|
+
return <Edit16 disabled={disabled} />;
|
|
104
|
+
case (TOOLBAR_ZOOM_IN):
|
|
105
|
+
return <ZoomIn16 disabled={disabled} />;
|
|
106
|
+
case (TOOLBAR_ZOOM_OUT):
|
|
107
|
+
return <ZoomOut16 disabled={disabled} />;
|
|
108
|
+
|
|
109
|
+
case (TOOLBAR_ZOOM_FIT):
|
|
110
|
+
return <SVG src={ZoomToFit} disabled={disabled} />;
|
|
111
|
+
case (TOOLBAR_ARRANGE_HORIZONALLY):
|
|
112
|
+
return <SVG src={ArrangeHorizontally} disabled={disabled} />;
|
|
113
|
+
case (TOOLBAR_ARRANGE_VERTICALLY):
|
|
114
|
+
return <SVG src={ArrangeVertically} disabled={disabled} />;
|
|
115
|
+
case (TOOLBAR_OPEN_PALETTE):
|
|
116
|
+
return <SVG src={PaletteOpen} disabled={disabled} />;
|
|
117
|
+
case (TOOLBAR_CLOSE_PALETTE):
|
|
118
|
+
return <SVG src={PaletteClose} disabled={disabled} />;
|
|
119
|
+
case (TOOLBAR_TOGGLE_NOTIFICATION_PANEL):
|
|
120
|
+
return <SVG src={ToggleNotificationPanel} disabled={disabled} />;
|
|
121
|
+
|
|
122
|
+
default:
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
generateLabel(label, disable, isInMenu, incLabelWithIcon) {
|
|
128
|
+
let className = "toolbar-icon-label";
|
|
129
|
+
className += this.generateLabelType(isInMenu, incLabelWithIcon);
|
|
130
|
+
className += disable ? " disabled" : "";
|
|
131
|
+
return (<div className={className}>{label}</div>);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
generateLabelType(isInMenu, inLabelWithIcon) {
|
|
135
|
+
if (isInMenu) {
|
|
136
|
+
return " overflow";
|
|
137
|
+
} else if (inLabelWithIcon === "before") {
|
|
138
|
+
return " before";
|
|
139
|
+
} else if (inLabelWithIcon === "after") {
|
|
140
|
+
return " after";
|
|
141
|
+
}
|
|
142
|
+
return "";
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
generateIcon(actionObj) {
|
|
146
|
+
let icon = this.getDefaultIcon(actionObj);
|
|
147
|
+
|
|
148
|
+
// Host application provided icon. This will override any default icon.
|
|
149
|
+
if (actionObj.iconEnabled) {
|
|
150
|
+
const iconEnabled = actionObj.iconEnabled;
|
|
151
|
+
const iconDisabled = actionObj.iconDisabled || actionObj.iconEnabled;
|
|
152
|
+
const customIcon = actionObj.enable ? iconEnabled : iconDisabled;
|
|
153
|
+
const id = "toolbar-icon-" + this.props.instanceId + " -" + actionObj.action;
|
|
154
|
+
|
|
155
|
+
if (typeof customIcon === "string") {
|
|
156
|
+
icon = (<SVG id={id} src={customIcon} disabled={!actionObj.enable} />);
|
|
157
|
+
} else {
|
|
158
|
+
icon = customIcon;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (icon) {
|
|
163
|
+
return (
|
|
164
|
+
<div className={"toolbar-icon"}>
|
|
165
|
+
{icon}
|
|
166
|
+
</div>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
generateButton(actionObj) {
|
|
173
|
+
let labelBefore = null;
|
|
174
|
+
let labelAfter = null;
|
|
175
|
+
|
|
176
|
+
if (this.props.isInMenu) {
|
|
177
|
+
labelAfter = this.generateLabel(actionObj.label, !actionObj.enable, true);
|
|
178
|
+
|
|
179
|
+
} else if (actionObj.incLabelWithIcon === "before") {
|
|
180
|
+
labelBefore = this.generateLabel(actionObj.label, !actionObj.enable, false, actionObj.incLabelWithIcon);
|
|
181
|
+
|
|
182
|
+
} else if (actionObj.incLabelWithIcon === "after") {
|
|
183
|
+
labelAfter = this.generateLabel(actionObj.label, !actionObj.enable, false, actionObj.incLabelWithIcon);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const icon = this.generateIcon(actionObj);
|
|
187
|
+
const textContent = actionObj.textContent ? (<div className="toolbar-text-content"> {actionObj.textContent} </div>) : null;
|
|
188
|
+
|
|
189
|
+
const itemContentClassName = classNames(
|
|
190
|
+
"toolbar-item-content",
|
|
191
|
+
actionObj.className ? actionObj.className : null,
|
|
192
|
+
{ "overflow": this.props.isInMenu, "disabled": !actionObj.enable, "default": !actionObj.kind });
|
|
193
|
+
|
|
194
|
+
// If no 'kind' is set, use ghost and then override colors using the "default" class in innerDivClassName.
|
|
195
|
+
const kind = actionObj.kind || "ghost";
|
|
196
|
+
|
|
197
|
+
const chevronIcon = this.generateChevronIcon(actionObj);
|
|
198
|
+
|
|
199
|
+
let buttonContent = (
|
|
200
|
+
<div className={itemContentClassName}>
|
|
201
|
+
{labelBefore}
|
|
202
|
+
{icon}
|
|
203
|
+
{labelAfter}
|
|
204
|
+
{textContent}
|
|
205
|
+
{chevronIcon}
|
|
206
|
+
</div>
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
buttonContent = this.wrapInTooltip(buttonContent);
|
|
210
|
+
|
|
211
|
+
// Only specify an aria label for the button if a label is not displayed
|
|
212
|
+
// with the button icon.
|
|
213
|
+
const ariaLabel = actionObj.incLabelWithIcon ? null : actionObj.label;
|
|
214
|
+
const tabIndex = this.props.buttonFocusAction === actionObj.action ? 0 : -1;
|
|
215
|
+
|
|
216
|
+
const button = (
|
|
217
|
+
<Button kind={kind}
|
|
218
|
+
ref={this.buttonRef}
|
|
219
|
+
onClick={this.props.actionClickHandler}
|
|
220
|
+
disabled={!actionObj.enable}
|
|
221
|
+
aria-label={ariaLabel}
|
|
222
|
+
size={this.props.size}
|
|
223
|
+
tabIndex={tabIndex}
|
|
224
|
+
>
|
|
225
|
+
{buttonContent}
|
|
226
|
+
</Button>
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
return button;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Returns a chevron icon if the action icon is displaying a sub-menu or
|
|
233
|
+
// sub-panel. The chevron will:
|
|
234
|
+
// * point right if this action item is in a drop down menu
|
|
235
|
+
// * point down if this action item is displayed with text in the toolbar
|
|
236
|
+
// and the menu isn't displayed
|
|
237
|
+
// * point up if this action item is displayed with text in the toolbar
|
|
238
|
+
// and the menu is displayed
|
|
239
|
+
// * be a mini-chevron (small triangle in the bottom right of icon) if this
|
|
240
|
+
// action item isn't displayed with text.
|
|
241
|
+
generateChevronIcon(actionObj) {
|
|
242
|
+
if (actionObj.subMenu || actionObj.subPanel) {
|
|
243
|
+
if (this.props.isInMenu) {
|
|
244
|
+
return (<ChevronRight16 />);
|
|
245
|
+
}
|
|
246
|
+
if (actionObj.incLabelWithIcon === "before" ||
|
|
247
|
+
actionObj.incLabelWithIcon === "after") {
|
|
248
|
+
const chev = this.props.subAreaDisplayed ? (<ChevronUp16 />) : (<ChevronDown16 />);
|
|
249
|
+
return (<div className={"toolbar-up-down-chevron"}>{chev}</div>);
|
|
250
|
+
}
|
|
251
|
+
return this.generateChevronMini();
|
|
252
|
+
}
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Returns an svg to display the little triangle that appears in the bottom
|
|
257
|
+
// right corner of icons that, when clicked, show a drop down menu.
|
|
258
|
+
generateChevronMini() {
|
|
259
|
+
const path = this.props.size === "sm" ? "M 29 29 L 29 23 23 29 Z" : "M 37 37 L 37 30 30 37 Z";
|
|
260
|
+
return (
|
|
261
|
+
<svg className="toolbar-tick-svg">
|
|
262
|
+
<path d={path} className="toolbar-tick-mark" />
|
|
263
|
+
</svg>
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
wrapInTooltip(content) {
|
|
268
|
+
if (!this.props.isInMenu && (this.showLabelAsTip(this.props.actionObj) || this.props.actionObj.tooltip)) {
|
|
269
|
+
const tip = this.props.actionObj.tooltip ? this.props.actionObj.tooltip : this.props.actionObj.label;
|
|
270
|
+
const tooltipId = this.props.actionName + "-" + this.props.instanceId + "-tooltip";
|
|
271
|
+
const enableTooltip = this.props.actionObj.enable || this.props.actionObj.jsx; // JSX 'tools' don't have enable attr so always display a tooltip for them.
|
|
272
|
+
const direction = this.props.tooltipDirection ? this.props.tooltipDirection : "bottom";
|
|
273
|
+
|
|
274
|
+
return (
|
|
275
|
+
<Tooltip id={tooltipId} tip={tip} disable={!enableTooltip} className="icon-tooltip" direction={direction}>
|
|
276
|
+
{content}
|
|
277
|
+
</Tooltip>
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
return content;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Returns true if the label should be shown as a tooltip or false if not.
|
|
284
|
+
// We do not show the label as a tooltip if it is already shown in the
|
|
285
|
+
// toolbar next to the icon (i.e. incLabelWithIcon is set to something).
|
|
286
|
+
showLabelAsTip(actionObj) {
|
|
287
|
+
if (actionObj.label) {
|
|
288
|
+
if (actionObj.incLabelWithIcon === "before" ||
|
|
289
|
+
actionObj.incLabelWithIcon === "after") {
|
|
290
|
+
return false;
|
|
291
|
+
}
|
|
292
|
+
return true;
|
|
293
|
+
}
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
render() {
|
|
298
|
+
const actionObj = this.props.actionObj;
|
|
299
|
+
let divContent = null;
|
|
300
|
+
|
|
301
|
+
if (actionObj.jsx) {
|
|
302
|
+
divContent = this.wrapInTooltip(actionObj.jsx);
|
|
303
|
+
} else {
|
|
304
|
+
divContent = this.generateButton(actionObj);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return divContent;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
ToolbarButtonItem.propTypes = {
|
|
312
|
+
actionObj: PropTypes.shape({
|
|
313
|
+
action: PropTypes.string.isRequired,
|
|
314
|
+
label: PropTypes.oneOfType([
|
|
315
|
+
PropTypes.string,
|
|
316
|
+
PropTypes.object
|
|
317
|
+
]),
|
|
318
|
+
incLabelWithIcon: PropTypes.oneOf(["no", "before", "after"]),
|
|
319
|
+
enable: PropTypes.bool,
|
|
320
|
+
iconEnabled: PropTypes.oneOfType([
|
|
321
|
+
PropTypes.string,
|
|
322
|
+
PropTypes.object
|
|
323
|
+
]),
|
|
324
|
+
iconDisabled: PropTypes.oneOfType([
|
|
325
|
+
PropTypes.string,
|
|
326
|
+
PropTypes.object
|
|
327
|
+
]),
|
|
328
|
+
className: PropTypes.string,
|
|
329
|
+
textContent: PropTypes.string,
|
|
330
|
+
isSelected: PropTypes.bool,
|
|
331
|
+
kind: PropTypes.string,
|
|
332
|
+
closeSubAreaOnClick: PropTypes.bool,
|
|
333
|
+
subMenu: PropTypes.array,
|
|
334
|
+
subPanel: PropTypes.any,
|
|
335
|
+
subPanelData: PropTypes.object,
|
|
336
|
+
jsx: PropTypes.object,
|
|
337
|
+
tooltip: PropTypes.oneOfType([
|
|
338
|
+
PropTypes.string,
|
|
339
|
+
PropTypes.object,
|
|
340
|
+
PropTypes.func
|
|
341
|
+
])
|
|
342
|
+
}),
|
|
343
|
+
actionName: PropTypes.string.isRequired,
|
|
344
|
+
tooltipDirection: PropTypes.oneOf(["top", "bottom"]),
|
|
345
|
+
instanceId: PropTypes.number.isRequired,
|
|
346
|
+
isInMenu: PropTypes.bool,
|
|
347
|
+
subAreaDisplayed: PropTypes.bool,
|
|
348
|
+
actionClickHandler: PropTypes.func,
|
|
349
|
+
buttonFocusAction: PropTypes.string,
|
|
350
|
+
isFocusInToolbar: PropTypes.bool,
|
|
351
|
+
size: PropTypes.oneOf(["md", "sm"])
|
|
352
|
+
};
|
|
353
|
+
|
|
354
|
+
export default ToolbarButtonItem;
|
|
@@ -18,21 +18,20 @@ import React from "react";
|
|
|
18
18
|
import PropTypes from "prop-types";
|
|
19
19
|
|
|
20
20
|
class ToolbarDividerItem extends React.Component {
|
|
21
|
-
|
|
22
21
|
render() {
|
|
23
|
-
const dividerClassName = this.props.
|
|
22
|
+
const dividerClassName = this.props.isInMenu ? "toolbar-divider-overflow" : "toolbar-divider";
|
|
24
23
|
|
|
25
24
|
// Add a space as content. When using display: inline-block the div needs
|
|
26
25
|
// some content so it is displayed inline with the other elements of the
|
|
27
26
|
// toolbar. With no content it is displayed above (!) the other elements.
|
|
28
27
|
return (
|
|
29
|
-
<div className={dividerClassName}
|
|
28
|
+
<div className={dividerClassName} tabIndex={-1} aria-hidden > </div>
|
|
30
29
|
);
|
|
31
30
|
}
|
|
32
31
|
}
|
|
33
32
|
|
|
34
33
|
ToolbarDividerItem.propTypes = {
|
|
35
|
-
|
|
34
|
+
isInMenu: PropTypes.bool
|
|
36
35
|
};
|
|
37
36
|
|
|
38
37
|
export default ToolbarDividerItem;
|
|
@@ -20,7 +20,7 @@ import PropTypes from "prop-types";
|
|
|
20
20
|
import { v4 as uuid4 } from "uuid";
|
|
21
21
|
import { Button } from "carbon-components-react";
|
|
22
22
|
import { OverflowMenuVertical16 } from "@carbon/icons-react";
|
|
23
|
-
import
|
|
23
|
+
import ToolbarSubMenu from "./toolbar-sub-menu.jsx";
|
|
24
24
|
|
|
25
25
|
class ToolbarOverflowItem extends React.Component {
|
|
26
26
|
constructor(props) {
|
|
@@ -29,9 +29,19 @@ class ToolbarOverflowItem extends React.Component {
|
|
|
29
29
|
this.state = {
|
|
30
30
|
showExtendedMenu: false
|
|
31
31
|
};
|
|
32
|
+
|
|
33
|
+
this.buttonRef = React.createRef();
|
|
34
|
+
|
|
32
35
|
this.uuid = uuid4();
|
|
33
36
|
this.toggleExtendedMenu = this.toggleExtendedMenu.bind(this);
|
|
34
37
|
this.clickOutside = this.clickOutside.bind(this);
|
|
38
|
+
this.closeSubMenu = this.closeSubMenu.bind(this);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
componentDidUpdate() {
|
|
42
|
+
if (this.props.toolbarFocusAction === this.props.action && this.props.isFocusInToolbar && !this.state.showExtendedMenu) {
|
|
43
|
+
this.buttonRef.current.focus();
|
|
44
|
+
}
|
|
35
45
|
}
|
|
36
46
|
|
|
37
47
|
// We must remove the eventListener in case this class is unmounted due
|
|
@@ -40,65 +50,96 @@ class ToolbarOverflowItem extends React.Component {
|
|
|
40
50
|
document.removeEventListener("click", this.clickOutside, false);
|
|
41
51
|
}
|
|
42
52
|
|
|
43
|
-
|
|
44
|
-
|
|
53
|
+
// Called by toolbar.jsx
|
|
54
|
+
getAction() {
|
|
55
|
+
return this.props.action;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
closeSubMenu() {
|
|
59
|
+
this.setState({ showExtendedMenu: false });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
openSubMenu() {
|
|
63
|
+
this.setState({ showExtendedMenu: true });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
genOverflowButtonClassName() {
|
|
67
|
+
return "toolbar-overflow-container " + this.genIndexClassName() + " " + this.genUuidClassName();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
genIndexClassName() {
|
|
71
|
+
return "toolbar-index-" + this.props.index;
|
|
45
72
|
}
|
|
46
73
|
|
|
74
|
+
genUuidClassName() {
|
|
75
|
+
return "toolbar-uuid-" + this.uuid;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// When the overflow item is clicked to open the overflow menu we must set the
|
|
79
|
+
// index of the overflow items so the overflow menu can be correctly constructed.
|
|
80
|
+
// The overflow index values are used to split out the overflow menu action items
|
|
81
|
+
// from the left bar and right bar.
|
|
82
|
+
// When the overflow menu is closed we set the overflow index values to null.
|
|
47
83
|
toggleExtendedMenu() {
|
|
48
84
|
if (this.state.showExtendedMenu) {
|
|
49
85
|
document.removeEventListener("click", this.clickOutside, false);
|
|
86
|
+
this.props.setOverflowIndex(null); // Clear the indexes
|
|
87
|
+
this.closeSubMenu();
|
|
88
|
+
this.props.setToolbarFocusAction(this.props.action); // This will not set focus on this item
|
|
89
|
+
|
|
50
90
|
} else {
|
|
51
91
|
document.addEventListener("click", this.clickOutside, false);
|
|
92
|
+
this.props.setOverflowIndex(this.props.index);
|
|
93
|
+
this.openSubMenu();
|
|
94
|
+
this.props.setToolbarFocusAction(this.props.action);
|
|
52
95
|
}
|
|
53
|
-
|
|
54
|
-
if (this.props.setResizeHandler) {
|
|
55
|
-
if (this.state.showExtendedMenu) {
|
|
56
|
-
this.props.setResizeHandler(null);
|
|
57
|
-
} else {
|
|
58
|
-
this.props.setResizeHandler(() => {
|
|
59
|
-
this.setState({ showExtendedMenu: false });
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
this.setState({ showExtendedMenu: !this.state.showExtendedMenu });
|
|
65
96
|
}
|
|
66
97
|
|
|
67
98
|
clickOutside(evt) {
|
|
68
99
|
if (this.state.showExtendedMenu) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
100
|
+
// Selector for the overflow-container that contains the overflow icon
|
|
101
|
+
// and submenu (if submenu is open).
|
|
102
|
+
const selector = "." + this.genIndexClassName();
|
|
103
|
+
const isClickInOverflowContainer = evt.target.closest(selector);
|
|
104
|
+
if (!isClickInOverflowContainer) {
|
|
73
105
|
this.setState({ showExtendedMenu: false });
|
|
74
106
|
}
|
|
75
107
|
}
|
|
76
108
|
}
|
|
77
109
|
|
|
78
110
|
render() {
|
|
79
|
-
if (this.props.setResizeHandler && !this.state.showExtendedMenu) {
|
|
80
|
-
this.props.setResizeHandler(null);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
111
|
let overflowMenu = null;
|
|
84
112
|
if (this.state.showExtendedMenu) {
|
|
85
|
-
const
|
|
113
|
+
const actionItemRect = this.buttonRef.current.getBoundingClientRect();
|
|
86
114
|
overflowMenu = (
|
|
87
|
-
<
|
|
88
|
-
|
|
115
|
+
<ToolbarSubMenu
|
|
116
|
+
ref={this.subMenuRef}
|
|
117
|
+
subMenuActions={this.props.subMenuActions}
|
|
118
|
+
instanceId={this.props.instanceId}
|
|
119
|
+
toolbarActionHandler={this.props.toolbarActionHandler}
|
|
120
|
+
closeSubArea={this.closeSubMenu}
|
|
121
|
+
setToolbarFocusAction={this.props.setToolbarFocusAction}
|
|
122
|
+
actionItemRect={actionItemRect}
|
|
123
|
+
expandDirection={"vertical"}
|
|
89
124
|
containingDivId={this.props.containingDivId}
|
|
90
|
-
|
|
125
|
+
parentSelector={".toolbar-overflow-container"}
|
|
126
|
+
isOverflowMenu
|
|
127
|
+
isCascadeMenu={false}
|
|
128
|
+
size={this.props.size}
|
|
91
129
|
/>
|
|
92
130
|
);
|
|
93
131
|
}
|
|
94
132
|
|
|
133
|
+
const tabIndex = this.props.toolbarFocusAction === this.props.action ? 0 : -1;
|
|
134
|
+
|
|
95
135
|
return (
|
|
96
|
-
<div className={this.
|
|
136
|
+
<div className={this.genOverflowButtonClassName()} data-toolbar-action={this.props.action}>
|
|
97
137
|
<div className={"toolbar-overflow-item"}>
|
|
98
|
-
<Button
|
|
99
|
-
|
|
138
|
+
<Button
|
|
139
|
+
ref={this.buttonRef}
|
|
140
|
+
kind="ghost"
|
|
141
|
+
tabIndex={tabIndex}
|
|
100
142
|
onClick={this.toggleExtendedMenu}
|
|
101
|
-
onFocus={this.props.onFocus}
|
|
102
143
|
aria-label={this.props.label}
|
|
103
144
|
size={this.props.size}
|
|
104
145
|
>
|
|
@@ -117,12 +158,17 @@ class ToolbarOverflowItem extends React.Component {
|
|
|
117
158
|
|
|
118
159
|
ToolbarOverflowItem.propTypes = {
|
|
119
160
|
index: PropTypes.number.isRequired,
|
|
120
|
-
|
|
121
|
-
setResizeHandler: PropTypes.func,
|
|
122
|
-
containingDivId: PropTypes.string,
|
|
123
|
-
onFocus: PropTypes.func,
|
|
161
|
+
action: PropTypes.string,
|
|
124
162
|
label: PropTypes.string,
|
|
125
|
-
size: PropTypes.oneOf(["md", "sm"])
|
|
163
|
+
size: PropTypes.oneOf(["md", "sm"]),
|
|
164
|
+
subMenuActions: PropTypes.array,
|
|
165
|
+
setOverflowIndex: PropTypes.func,
|
|
166
|
+
toolbarActionHandler: PropTypes.func,
|
|
167
|
+
instanceId: PropTypes.number.isRequired,
|
|
168
|
+
containingDivId: PropTypes.string,
|
|
169
|
+
toolbarFocusAction: PropTypes.string,
|
|
170
|
+
setToolbarFocusAction: PropTypes.func,
|
|
171
|
+
isFocusInToolbar: PropTypes.bool
|
|
126
172
|
};
|
|
127
173
|
|
|
128
174
|
export default ToolbarOverflowItem;
|