@elyra/canvas 12.31.2 → 12.32.1
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-e1311552.js +8 -0
- package/dist/_baseIteratee-e1311552.js.map +1 -0
- package/dist/_baseIteratee-eabd2a94.js +7 -0
- package/dist/_baseIteratee-eabd2a94.js.map +1 -0
- package/dist/canvas-constants-72222288.js +2 -0
- package/dist/{canvas-constants-187a30d5.js.map → canvas-constants-72222288.js.map} +1 -1
- package/dist/{canvas-constants-5fb4e9b8.js → canvas-constants-903046ab.js} +2 -2
- package/dist/{canvas-constants-5fb4e9b8.js.map → canvas-constants-903046ab.js.map} +1 -1
- package/dist/canvas-controller-69928ea7.js +2 -0
- package/dist/canvas-controller-69928ea7.js.map +1 -0
- package/dist/canvas-controller-978f3e99.js +2 -0
- package/dist/canvas-controller-978f3e99.js.map +1 -0
- package/dist/common-canvas-159fb083.js +2 -0
- package/dist/common-canvas-159fb083.js.map +1 -0
- package/dist/common-canvas-318d3486.js +2 -0
- package/dist/common-canvas-318d3486.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-96c9c88a.js +2 -0
- package/dist/common-properties-96c9c88a.js.map +1 -0
- package/dist/common-properties-c5292c66.js +2 -0
- package/dist/common-properties-c5292c66.js.map +1 -0
- package/dist/context-menu-wrapper-5846a20e.js +2 -0
- package/dist/context-menu-wrapper-5846a20e.js.map +1 -0
- package/dist/context-menu-wrapper-ac5e8c7a.js +2 -0
- package/dist/context-menu-wrapper-ac5e8c7a.js.map +1 -0
- package/dist/datarecord-metadata-v3-schema-64329ae4.js +2 -0
- package/dist/datarecord-metadata-v3-schema-64329ae4.js.map +1 -0
- package/dist/datarecord-metadata-v3-schema-dd7370da.js +2 -0
- package/dist/datarecord-metadata-v3-schema-dd7370da.js.map +1 -0
- package/dist/flexible-table-23d61157.js +2 -0
- package/dist/flexible-table-23d61157.js.map +1 -0
- package/dist/flexible-table-4259d869.js +2 -0
- package/dist/flexible-table-4259d869.js.map +1 -0
- package/dist/icon-04f858ce.js +2 -0
- package/dist/{icon-111fe072.js.map → icon-04f858ce.js.map} +1 -1
- package/dist/icon-8cc7816d.js +2 -0
- package/dist/{icon-590f8eb3.js.map → icon-8cc7816d.js.map} +1 -1
- package/dist/index-101f9560.js +2 -0
- package/dist/{index-157d4b89.js.map → index-101f9560.js.map} +1 -1
- package/dist/index-2788d55d.js +2 -0
- package/dist/{index-463d0c73.js.map → index-2788d55d.js.map} +1 -1
- package/dist/{isArrayLikeObject-6a001191.js → isArrayLikeObject-c0bf3ab6.js} +2 -2
- package/dist/{isArrayLikeObject-6a001191.js.map → isArrayLikeObject-c0bf3ab6.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-12f6def6.js +2 -0
- package/dist/toolbar-12f6def6.js.map +1 -0
- package/dist/toolbar-55e2020e.js +2 -0
- package/dist/toolbar-55e2020e.js.map +1 -0
- package/locales/common-properties/locales/de.json +1 -1
- package/locales/common-properties/locales/es.json +1 -1
- package/locales/common-properties/locales/fr.json +1 -1
- package/locales/common-properties/locales/it.json +1 -1
- package/locales/common-properties/locales/ja.json +1 -1
- package/locales/common-properties/locales/ko.json +1 -1
- package/locales/common-properties/locales/pt-br.json +1 -1
- package/locales/common-properties/locales/sv.json +1 -1
- package/locales/common-properties/locales/zh-CN.json +1 -1
- package/locales/common-properties/locales/zh-TW.json +1 -1
- package/package.json +1 -1
- package/src/color-picker/color-picker.jsx +30 -7
- package/src/color-picker/color-picker.scss +1 -1
- package/src/color-picker/index.js +18 -0
- package/src/command-actions/colorSelectedObjectsAction.js +2 -1
- package/src/common-canvas/canvas-controller-menu-utils.js +2 -2
- package/src/common-canvas/cc-context-toolbar.jsx +54 -33
- package/src/common-canvas/cc-text-toolbar.jsx +8 -15
- package/src/common-canvas/common-canvas.scss +8 -15
- package/src/common-canvas/constants/canvas-constants.js +1 -0
- package/src/common-canvas/svg-canvas-d3.js +1 -1
- package/src/common-canvas/svg-canvas-renderer.js +26 -10
- package/src/common-canvas/svg-canvas-utils-textarea.js +1 -1
- package/src/common-properties/components/flexible-table/flexible-table.jsx +8 -5
- package/src/common-properties/ui-conditions/conditions-utils.js +9 -0
- package/src/context-menu/common-context-menu.jsx +2 -2
- package/src/object-model/config-utils.js +20 -1
- package/src/object-model/pipeline-out-handler.js +3 -0
- package/src/toolbar/toolbar-action-item.jsx +122 -40
- package/src/toolbar/toolbar-action-sub-area.jsx +126 -0
- package/src/toolbar/toolbar-overflow-item.jsx +61 -14
- package/src/toolbar/toolbar-overflow-menu.jsx +77 -0
- package/src/toolbar/toolbar-utils.js +33 -0
- package/src/toolbar/toolbar.jsx +17 -24
- package/src/toolbar/toolbar.scss +44 -21
- package/src/tooltip/tooltip.jsx +5 -7
- package/stats.html +1 -1
- package/dist/_baseForOwn-33edf1a0.js +0 -8
- package/dist/_baseForOwn-33edf1a0.js.map +0 -1
- package/dist/_baseForOwn-721741a9.js +0 -7
- package/dist/_baseForOwn-721741a9.js.map +0 -1
- package/dist/canvas-constants-187a30d5.js +0 -2
- package/dist/canvas-controller-3edea15e.js +0 -2
- package/dist/canvas-controller-3edea15e.js.map +0 -1
- package/dist/canvas-controller-896694e3.js +0 -2
- package/dist/canvas-controller-896694e3.js.map +0 -1
- package/dist/common-canvas-88479b3e.js +0 -2
- package/dist/common-canvas-88479b3e.js.map +0 -1
- package/dist/common-canvas-df45ad40.js +0 -2
- package/dist/common-canvas-df45ad40.js.map +0 -1
- package/dist/common-properties-11732433.js +0 -2
- package/dist/common-properties-11732433.js.map +0 -1
- package/dist/common-properties-57768e63.js +0 -2
- package/dist/common-properties-57768e63.js.map +0 -1
- package/dist/context-menu-wrapper-8f68be70.js +0 -2
- package/dist/context-menu-wrapper-8f68be70.js.map +0 -1
- package/dist/context-menu-wrapper-d1ff456a.js +0 -2
- package/dist/context-menu-wrapper-d1ff456a.js.map +0 -1
- package/dist/datarecord-metadata-v3-schema-36dfc3cd.js +0 -2
- package/dist/datarecord-metadata-v3-schema-36dfc3cd.js.map +0 -1
- package/dist/datarecord-metadata-v3-schema-9e9ba30d.js +0 -2
- package/dist/datarecord-metadata-v3-schema-9e9ba30d.js.map +0 -1
- package/dist/flexible-table-2dc48a79.js +0 -2
- package/dist/flexible-table-2dc48a79.js.map +0 -1
- package/dist/flexible-table-9e66f95d.js +0 -2
- package/dist/flexible-table-9e66f95d.js.map +0 -1
- package/dist/icon-111fe072.js +0 -2
- package/dist/icon-590f8eb3.js +0 -2
- package/dist/index-157d4b89.js +0 -2
- package/dist/index-463d0c73.js +0 -2
- package/dist/toolbar-3affe026.js +0 -2
- package/dist/toolbar-3affe026.js.map +0 -1
- package/dist/toolbar-7140292d.js +0 -2
- package/dist/toolbar-7140292d.js.map +0 -1
- package/src/color-picker/color-picker-panel.jsx +0 -61
|
@@ -28,11 +28,13 @@ import ZoomToFit from "./../../assets/images/zoom_to_fit.svg";
|
|
|
28
28
|
import { Button } from "carbon-components-react";
|
|
29
29
|
import SVG from "react-inlinesvg";
|
|
30
30
|
import classNames from "classnames";
|
|
31
|
-
import
|
|
31
|
+
import ToolbarActionSubArea from "./toolbar-action-sub-area.jsx";
|
|
32
|
+
import { StopFilledAlt16, Play16, Undo16, Redo16, Chat16, ChatOff16, Result16,
|
|
32
33
|
Cut16, Copy16, Paste16, Edit16, ColorPalette16, Maximize16, Minimize16,
|
|
33
|
-
Launch16, AddComment16, TrashCan16, ZoomIn16, ZoomOut16,
|
|
34
|
+
Launch16, AddComment16, TrashCan16, ZoomIn16, ZoomOut16,
|
|
35
|
+
ChevronRight16, ChevronDown16, ChevronUp16 } from "@carbon/icons-react";
|
|
34
36
|
import { TOOLBAR_STOP, TOOLBAR_RUN, TOOLBAR_UNDO, TOOLBAR_REDO,
|
|
35
|
-
TOOLBAR_CUT, TOOLBAR_COPY, TOOLBAR_PASTE,
|
|
37
|
+
TOOLBAR_CUT, TOOLBAR_COPY, TOOLBAR_PASTE, TOOLBAR_CLIPBOARD,
|
|
36
38
|
TOOLBAR_CREATE_COMMENT, TOOLBAR_CREATE_AUTO_COMMENT, TOOLBAR_COLOR_BACKGROUND,
|
|
37
39
|
TOOLBAR_DELETE_SELECTED_OBJECTS, TOOLBAR_DELETE_LINK,
|
|
38
40
|
TOOLBAR_ZOOM_IN, TOOLBAR_ZOOM_OUT, TOOLBAR_ZOOM_FIT,
|
|
@@ -47,20 +49,39 @@ class ToolbarActionItem extends React.Component {
|
|
|
47
49
|
constructor(props) {
|
|
48
50
|
super(props);
|
|
49
51
|
|
|
52
|
+
this.state = {
|
|
53
|
+
subAreaDisplayed: false
|
|
54
|
+
};
|
|
55
|
+
|
|
50
56
|
this.actionClickHandler = this.actionClickHandler.bind(this);
|
|
51
57
|
this.onMouseEnter = this.onMouseEnter.bind(this);
|
|
52
58
|
this.onMouseLeave = this.onMouseLeave.bind(this);
|
|
59
|
+
this.openSubArea = this.openSubArea.bind(this);
|
|
60
|
+
this.closeSubArea = this.closeSubArea.bind(this);
|
|
61
|
+
this.clickOutside = this.clickOutside.bind(this);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
componentDidMount() {
|
|
65
|
+
if (this.props.actionObj.getSubPanelCloseFn) {
|
|
66
|
+
this.props.actionObj.getSubPanelCloseFn(this.closeSubArea);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// We must remove the eventListener in case this class is unmounted due
|
|
71
|
+
// to the toolbar getting redrawn.
|
|
72
|
+
componentWillUnmount() {
|
|
73
|
+
document.removeEventListener("click", this.clickOutside, false);
|
|
53
74
|
}
|
|
54
75
|
|
|
55
76
|
onMouseEnter(evt) {
|
|
56
|
-
if (this.props.actionObj.subMenu || this.props.actionObj.subPanel) {
|
|
57
|
-
this.
|
|
77
|
+
if ((this.props.actionObj.subMenu || this.props.actionObj.subPanel) && this.props.overflow) {
|
|
78
|
+
this.openSubArea();
|
|
58
79
|
}
|
|
59
80
|
}
|
|
60
81
|
|
|
61
82
|
onMouseLeave(evt) {
|
|
62
|
-
if (this.props.actionObj.subMenu || this.props.actionObj.subPanel) {
|
|
63
|
-
this.
|
|
83
|
+
if ((this.props.actionObj.subMenu || this.props.actionObj.subPanel) && this.props.overflow) {
|
|
84
|
+
this.closeSubArea();
|
|
64
85
|
}
|
|
65
86
|
}
|
|
66
87
|
|
|
@@ -84,6 +105,8 @@ class ToolbarActionItem extends React.Component {
|
|
|
84
105
|
return <Undo16 disabled={disabled} />;
|
|
85
106
|
case (TOOLBAR_REDO):
|
|
86
107
|
return <Redo16 disabled={disabled} />;
|
|
108
|
+
case (TOOLBAR_CLIPBOARD):
|
|
109
|
+
return <Result16 disabled={disabled} />;
|
|
87
110
|
case (TOOLBAR_CUT):
|
|
88
111
|
return <Cut16 disabled={disabled} />;
|
|
89
112
|
case (TOOLBAR_COPY):
|
|
@@ -173,8 +196,45 @@ class ToolbarActionItem extends React.Component {
|
|
|
173
196
|
return null;
|
|
174
197
|
}
|
|
175
198
|
|
|
199
|
+
clickOutside(evt) {
|
|
200
|
+
if (this.state.subAreaDisplayed) {
|
|
201
|
+
const items = document.getElementsByClassName(this.generateActionName());
|
|
202
|
+
const isOver = items && items.length > 0 ? items[0].contains(evt.target) : false;
|
|
203
|
+
|
|
204
|
+
if (!isOver) {
|
|
205
|
+
this.closeSubArea();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
openSubArea() {
|
|
211
|
+
this.setState({ subAreaDisplayed: true });
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
closeSubArea() {
|
|
215
|
+
this.setState({ subAreaDisplayed: false });
|
|
216
|
+
}
|
|
217
|
+
|
|
176
218
|
actionClickHandler(evt) {
|
|
177
|
-
if (
|
|
219
|
+
if (this.props.actionObj.subMenu || this.props.actionObj.subPanel) {
|
|
220
|
+
if (this.state.showExtendedMenu) {
|
|
221
|
+
document.removeEventListener("click", this.clickOutside, false);
|
|
222
|
+
} else {
|
|
223
|
+
document.addEventListener("click", this.clickOutside, false);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
if (this.props.setResizeHandler) {
|
|
227
|
+
if (this.state.subAreaDisplayed) {
|
|
228
|
+
this.props.setResizeHandler(null);
|
|
229
|
+
} else {
|
|
230
|
+
this.props.setResizeHandler(this.closeSubArea);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (!this.props.overflow) {
|
|
235
|
+
this.setState({ subAreaDisplayed: !this.state.subAreaDisplayed });
|
|
236
|
+
}
|
|
237
|
+
} else {
|
|
178
238
|
this.props.toolbarActionHandler(this.props.actionObj.action, evt);
|
|
179
239
|
}
|
|
180
240
|
}
|
|
@@ -204,10 +264,10 @@ class ToolbarActionItem extends React.Component {
|
|
|
204
264
|
// If no 'kind' is set, use ghost and then override colors using the "default" class in innerDivClassName.
|
|
205
265
|
const kind = actionObj.kind || "ghost";
|
|
206
266
|
|
|
207
|
-
const chevronIcon =
|
|
267
|
+
const chevronIcon = this.generateChevronIcon(actionObj);
|
|
208
268
|
|
|
209
269
|
let buttonContent = (
|
|
210
|
-
<div className={itemContentClassName}>
|
|
270
|
+
<div id={"open-action-item"} className={itemContentClassName}>
|
|
211
271
|
{labelBefore}
|
|
212
272
|
{icon}
|
|
213
273
|
{labelAfter}
|
|
@@ -237,6 +297,41 @@ class ToolbarActionItem extends React.Component {
|
|
|
237
297
|
return buttonContent;
|
|
238
298
|
}
|
|
239
299
|
|
|
300
|
+
// Returns a chevron icon if the action icon is displaying a sub-menu or
|
|
301
|
+
// sub-panel. The chevron will:
|
|
302
|
+
// * point right if this action item is in a drop down menu
|
|
303
|
+
// * point down if this action item is displayed with text in the toolbar
|
|
304
|
+
// and the menu isn't displayed
|
|
305
|
+
// * point up if this action item is displayed with text in the toolbar
|
|
306
|
+
// and the menu is displayed
|
|
307
|
+
// * be a mini-chevron (small triangle in the bottom right of icon) if this
|
|
308
|
+
// action item isn't displayed with text.
|
|
309
|
+
generateChevronIcon(actionObj) {
|
|
310
|
+
if (actionObj.subMenu || actionObj.subPanel) {
|
|
311
|
+
if (this.props.overflow) {
|
|
312
|
+
return (<ChevronRight16 />);
|
|
313
|
+
}
|
|
314
|
+
if (actionObj.incLabelWithIcon === "before" ||
|
|
315
|
+
actionObj.incLabelWithIcon === "after") {
|
|
316
|
+
const chev = this.state.subAreaDisplayed ? (<ChevronUp16 />) : (<ChevronDown16 />);
|
|
317
|
+
return (<div className={"toolbar-up-down-chevron"}>{chev}</div>);
|
|
318
|
+
}
|
|
319
|
+
return this.generateChevronMini();
|
|
320
|
+
}
|
|
321
|
+
return null;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Returns an svg to display the little triangle that appears in the bottom
|
|
325
|
+
// right corner of icons that, when clicked, show a drop down menu.
|
|
326
|
+
generateChevronMini() {
|
|
327
|
+
const path = this.props.size === "sm" ? "M 29 29 L 29 23 23 29 Z" : "M 37 37 L 37 30 30 37 Z";
|
|
328
|
+
return (
|
|
329
|
+
<svg className="toolbar-tick-svg">
|
|
330
|
+
<path d={path} className="toolbar-tick-mark" />
|
|
331
|
+
</svg>
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
|
|
240
335
|
generateActionName(actionObj) {
|
|
241
336
|
return this.props.actionObj.action + "-action";
|
|
242
337
|
}
|
|
@@ -277,34 +372,19 @@ class ToolbarActionItem extends React.Component {
|
|
|
277
372
|
// supPanel field OR a sub-menu which is a list of options which is created
|
|
278
373
|
// from the array of items the caller passes in the subMenu field.
|
|
279
374
|
generateSubArea() {
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
if (this.props.actionObj.subPanel) {
|
|
284
|
-
return (
|
|
285
|
-
<div style={style} className={"toolbar-popover-list subpanel"}>
|
|
286
|
-
{this.props.actionObj.subPanel}
|
|
287
|
-
</div>
|
|
288
|
-
);
|
|
289
|
-
}
|
|
290
|
-
const subMenuItems = this.props.generateToolbarItems(this.props.actionObj.subMenu, true, false);
|
|
291
|
-
|
|
292
|
-
return (
|
|
293
|
-
<div style={style} className={"toolbar-popover-list submenu"}>
|
|
294
|
-
{subMenuItems}
|
|
295
|
-
</div>
|
|
296
|
-
);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
return null;
|
|
300
|
-
}
|
|
375
|
+
const elements = document.getElementsByClassName(this.generateActionName());
|
|
376
|
+
const actionItemRect = elements && elements.length > 0 ? elements[0].getBoundingClientRect() : { top: 0, left: 0, width: 120 };
|
|
301
377
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
378
|
+
return (
|
|
379
|
+
<ToolbarActionSubArea
|
|
380
|
+
actionObj={this.props.actionObj}
|
|
381
|
+
generateToolbarItems={this.props.generateToolbarItems}
|
|
382
|
+
closeSubArea={this.props.actionObj.closeSubAreaOnClick ? this.closeSubArea : null}
|
|
383
|
+
actionItemRect={actionItemRect}
|
|
384
|
+
containingDivId={this.props.containingDivId}
|
|
385
|
+
expandDirection={this.props.overflow ? "horizontal" : "vertical" }
|
|
386
|
+
/>
|
|
387
|
+
);
|
|
308
388
|
}
|
|
309
389
|
|
|
310
390
|
render() {
|
|
@@ -330,7 +410,7 @@ class ToolbarActionItem extends React.Component {
|
|
|
330
410
|
kindAsClass,
|
|
331
411
|
actionName);
|
|
332
412
|
|
|
333
|
-
const subArea = this.generateSubArea();
|
|
413
|
+
const subArea = this.state.subAreaDisplayed ? this.generateSubArea() : null;
|
|
334
414
|
|
|
335
415
|
return (
|
|
336
416
|
<div className={itemClassName} data-toolbar-item={isToolbarItem} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}>
|
|
@@ -362,6 +442,8 @@ ToolbarActionItem.propTypes = {
|
|
|
362
442
|
textContent: PropTypes.string,
|
|
363
443
|
isSelected: PropTypes.bool,
|
|
364
444
|
kind: PropTypes.string,
|
|
445
|
+
closeSubAreaOnClick: PropTypes.bool,
|
|
446
|
+
getSubPanelCloseFn: PropTypes.func,
|
|
365
447
|
subMenu: PropTypes.array,
|
|
366
448
|
subPanel: PropTypes.object,
|
|
367
449
|
jsx: PropTypes.object,
|
|
@@ -373,10 +455,10 @@ ToolbarActionItem.propTypes = {
|
|
|
373
455
|
}),
|
|
374
456
|
tooltipDirection: PropTypes.oneOf(["top", "bottom"]),
|
|
375
457
|
toolbarActionHandler: PropTypes.func.isRequired,
|
|
376
|
-
subMenuActionHandler: PropTypes.func.isRequired,
|
|
377
458
|
generateToolbarItems: PropTypes.func.isRequired,
|
|
459
|
+
setResizeHandler: PropTypes.func,
|
|
378
460
|
instanceId: PropTypes.number.isRequired,
|
|
379
|
-
|
|
461
|
+
containingDivId: PropTypes.string,
|
|
380
462
|
overflow: PropTypes.bool,
|
|
381
463
|
onFocus: PropTypes.func,
|
|
382
464
|
size: PropTypes.oneOf(["md", "sm"])
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 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
|
+
import { genElementByClass, genRectByClass } from "./toolbar-utils.js";
|
|
20
|
+
|
|
21
|
+
class ToolbarActionSubArea extends React.Component {
|
|
22
|
+
constructor(props) {
|
|
23
|
+
super(props);
|
|
24
|
+
|
|
25
|
+
this.onClick = this.onClick.bind(this);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
componentDidMount() {
|
|
29
|
+
if (this.props.containingDivId) {
|
|
30
|
+
this.adjustSubAreaPosition();
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// If we are given a closeSubArea function then call it. We will only have
|
|
35
|
+
// such a function if the user has specified the closeSubAreaOnClick prop for
|
|
36
|
+
// the parent action AND provided the user has not stopped event propogation.
|
|
37
|
+
onClick() {
|
|
38
|
+
if (this.props.closeSubArea) {
|
|
39
|
+
this.props.closeSubArea();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Adjust the position of the sub-area to make sure it doesn't extend
|
|
44
|
+
// outside the containing divs boundary. We need to do this after the subarea
|
|
45
|
+
// has been mounted so we can query its size and position.
|
|
46
|
+
adjustSubAreaPosition() {
|
|
47
|
+
const containingDiv = document.getElementById(this.props.containingDivId);
|
|
48
|
+
const containingDivRect = containingDiv.getBoundingClientRect();
|
|
49
|
+
|
|
50
|
+
const classToGet = this.props.actionObj.subPanel ? "subpanel" : "submenu";
|
|
51
|
+
|
|
52
|
+
const thisArea = genElementByClass(classToGet, containingDiv);
|
|
53
|
+
const thisAreaRect = genRectByClass(classToGet, containingDiv);
|
|
54
|
+
|
|
55
|
+
const outsideBottom = thisAreaRect.bottom - containingDivRect.bottom;
|
|
56
|
+
const outsideRight = thisAreaRect.right - containingDivRect.right;
|
|
57
|
+
|
|
58
|
+
if (this.props.expandDirection === "vertical") {
|
|
59
|
+
if (outsideBottom > 0) {
|
|
60
|
+
const newTop = this.props.actionItemRect.top - thisAreaRect.height;
|
|
61
|
+
thisArea.style.top = newTop + "px";
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (outsideRight > 0) {
|
|
65
|
+
const newLeft = this.props.actionItemRect.left - outsideRight - 2;
|
|
66
|
+
thisArea.style.left = newLeft + "px";
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
} else {
|
|
70
|
+
if (outsideBottom > 0) {
|
|
71
|
+
const newTop = thisAreaRect.top - outsideBottom - 2;
|
|
72
|
+
thisArea.style.top = newTop + "px";
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (outsideRight > 0) {
|
|
76
|
+
const newLeft = this.props.actionItemRect.left - thisAreaRect.width;
|
|
77
|
+
thisArea.style.left = newLeft + "px";
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
generateSubAreaStyle() {
|
|
83
|
+
if (this.props.expandDirection === "vertical") {
|
|
84
|
+
return {
|
|
85
|
+
top: this.props.actionItemRect.bottom + 1,
|
|
86
|
+
left: this.props.actionItemRect.left
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
top: this.props.actionItemRect.top - 1,
|
|
91
|
+
left: this.props.actionItemRect.left + this.props.actionItemRect.width
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
render() {
|
|
96
|
+
const style = this.generateSubAreaStyle();
|
|
97
|
+
|
|
98
|
+
if (this.props.actionObj.subPanel) {
|
|
99
|
+
return (
|
|
100
|
+
<div style={style} className={"toolbar-popover-list subpanel"} onClick={this.onClick}>
|
|
101
|
+
{this.props.actionObj.subPanel}
|
|
102
|
+
</div>
|
|
103
|
+
);
|
|
104
|
+
} else if (this.props.actionObj.subMenu) {
|
|
105
|
+
const subMenuItems = this.props.generateToolbarItems(this.props.actionObj.subMenu, true, false);
|
|
106
|
+
|
|
107
|
+
return (
|
|
108
|
+
<div style={style} className={"toolbar-popover-list submenu"} onClick={this.onClick}>
|
|
109
|
+
{subMenuItems}
|
|
110
|
+
</div>
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
ToolbarActionSubArea.propTypes = {
|
|
118
|
+
actionObj: PropTypes.object.isRequired,
|
|
119
|
+
generateToolbarItems: PropTypes.func.isRequired,
|
|
120
|
+
closeSubArea: PropTypes.func,
|
|
121
|
+
actionItemRect: PropTypes.object.isRequired,
|
|
122
|
+
expandDirection: PropTypes.string.isRequired,
|
|
123
|
+
containingDivId: PropTypes.string
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export default ToolbarActionSubArea;
|
|
@@ -17,36 +17,83 @@
|
|
|
17
17
|
import React from "react";
|
|
18
18
|
import PropTypes from "prop-types";
|
|
19
19
|
|
|
20
|
+
import { v4 as uuid4 } from "uuid";
|
|
20
21
|
import { Button } from "carbon-components-react";
|
|
21
22
|
import { OverflowMenuVertical16 } from "@carbon/icons-react";
|
|
23
|
+
import ToolbarOverflowMenu from "./toolbar-overflow-menu.jsx";
|
|
22
24
|
|
|
23
25
|
class ToolbarOverflowItem extends React.Component {
|
|
24
26
|
constructor(props) {
|
|
25
27
|
super(props);
|
|
28
|
+
|
|
29
|
+
this.state = {
|
|
30
|
+
showExtendedMenu: false
|
|
31
|
+
};
|
|
32
|
+
this.uuid = uuid4();
|
|
26
33
|
this.toggleExtendedMenu = this.toggleExtendedMenu.bind(this);
|
|
34
|
+
this.clickOutside = this.clickOutside.bind(this);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// We must remove the eventListener in case this class is unmounted due
|
|
38
|
+
// to the toolbar getting redrawn.
|
|
39
|
+
componentWillUnmount() {
|
|
40
|
+
document.removeEventListener("click", this.clickOutside, false);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
genOverflowButtonClass() {
|
|
44
|
+
return "toolbar-spacer toolbar-index-" + this.props.index + " toolbar-uuid-" + this.uuid;
|
|
27
45
|
}
|
|
28
46
|
|
|
29
47
|
toggleExtendedMenu() {
|
|
30
|
-
|
|
48
|
+
if (this.state.showExtendedMenu) {
|
|
49
|
+
document.removeEventListener("click", this.clickOutside, false);
|
|
50
|
+
} else {
|
|
51
|
+
document.addEventListener("click", this.clickOutside, false);
|
|
52
|
+
}
|
|
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
|
+
}
|
|
66
|
+
|
|
67
|
+
clickOutside(evt) {
|
|
68
|
+
if (this.state.showExtendedMenu) {
|
|
69
|
+
const items = document.getElementsByClassName("toolbar-uuid-" + this.uuid);
|
|
70
|
+
const isOver = items && items.length > 0 ? items[0].contains(evt.target) : false;
|
|
71
|
+
|
|
72
|
+
if (!isOver) {
|
|
73
|
+
this.setState({ showExtendedMenu: false });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
31
76
|
}
|
|
32
77
|
|
|
33
78
|
render() {
|
|
79
|
+
if (this.props.setResizeHandler && !this.state.showExtendedMenu) {
|
|
80
|
+
this.props.setResizeHandler(null);
|
|
81
|
+
}
|
|
82
|
+
|
|
34
83
|
let overflowMenu = null;
|
|
35
|
-
if (this.
|
|
84
|
+
if (this.state.showExtendedMenu) {
|
|
36
85
|
const menuItems = this.props.generateExtensionMenuItems(this.props.index);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
86
|
+
overflowMenu = (
|
|
87
|
+
<ToolbarOverflowMenu
|
|
88
|
+
menuItems={menuItems}
|
|
89
|
+
containingDivId={this.props.containingDivId}
|
|
90
|
+
buttonClass={"toolbar-uuid-" + this.uuid}
|
|
91
|
+
/>
|
|
92
|
+
);
|
|
44
93
|
}
|
|
45
94
|
|
|
46
|
-
const className = "toolbar-spacer toolbar-index-" + this.props.index;
|
|
47
|
-
|
|
48
95
|
return (
|
|
49
|
-
<div className={
|
|
96
|
+
<div className={this.genOverflowButtonClass()} >
|
|
50
97
|
<div className={"toolbar-overflow-item"}>
|
|
51
98
|
<Button kind="ghost"
|
|
52
99
|
tabIndex={-1}
|
|
@@ -69,10 +116,10 @@ class ToolbarOverflowItem extends React.Component {
|
|
|
69
116
|
}
|
|
70
117
|
|
|
71
118
|
ToolbarOverflowItem.propTypes = {
|
|
72
|
-
showExtendedMenu: PropTypes.bool.isRequired,
|
|
73
|
-
toggleExtendedMenu: PropTypes.func.isRequired,
|
|
74
119
|
index: PropTypes.number.isRequired,
|
|
75
120
|
generateExtensionMenuItems: PropTypes.func,
|
|
121
|
+
setResizeHandler: PropTypes.func,
|
|
122
|
+
containingDivId: PropTypes.string,
|
|
76
123
|
onFocus: PropTypes.func,
|
|
77
124
|
label: PropTypes.string,
|
|
78
125
|
size: PropTypes.oneOf(["md", "sm"])
|
|
@@ -0,0 +1,77 @@
|
|
|
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
|
+
import { genElementByClass, genRectByClass } from "./toolbar-utils.js";
|
|
20
|
+
|
|
21
|
+
class ToolbarOverflowMenu extends React.Component {
|
|
22
|
+
|
|
23
|
+
componentDidMount() {
|
|
24
|
+
if (this.props.containingDivId) {
|
|
25
|
+
this.setSubAreaStyle();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
setSubAreaStyle() {
|
|
30
|
+
const containingDiv = document.getElementById(this.props.containingDivId);
|
|
31
|
+
const containingDivRect = containingDiv.getBoundingClientRect();
|
|
32
|
+
|
|
33
|
+
const mainMenu = genElementByClass("toolbar-popover-list", containingDiv);
|
|
34
|
+
const mainMenuRect = genRectByClass("toolbar-popover-list", containingDiv);
|
|
35
|
+
|
|
36
|
+
if (mainMenuRect) {
|
|
37
|
+
const overflowButtonRect = genRectByClass(this.props.buttonClass, containingDiv);
|
|
38
|
+
|
|
39
|
+
if (overflowButtonRect) {
|
|
40
|
+
const contextToolbaRect = genRectByClass("context-toolbar", containingDiv);
|
|
41
|
+
|
|
42
|
+
if (contextToolbaRect) {
|
|
43
|
+
const outsideRight = mainMenuRect.right - containingDivRect.right;
|
|
44
|
+
if (outsideRight > 0) {
|
|
45
|
+
const overflowIconOffsetX = overflowButtonRect.left - contextToolbaRect.left;
|
|
46
|
+
mainMenu.style.left = (overflowIconOffsetX - outsideRight - 2) + "px";
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const outsideBottom = mainMenuRect.bottom - containingDivRect.bottom;
|
|
50
|
+
if (outsideBottom > 0) {
|
|
51
|
+
mainMenu.style.top = -mainMenuRect.height + "px";
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
render() {
|
|
59
|
+
let overflowMenu = null;
|
|
60
|
+
if (this.props.menuItems.length > 0) {
|
|
61
|
+
overflowMenu = (
|
|
62
|
+
<div className={"toolbar-popover-list"}>
|
|
63
|
+
{this.props.menuItems}
|
|
64
|
+
</div>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
return overflowMenu;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
ToolbarOverflowMenu.propTypes = {
|
|
72
|
+
menuItems: PropTypes.array.isRequired,
|
|
73
|
+
containingDivId: PropTypes.string,
|
|
74
|
+
buttonClass: PropTypes.string
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export default ToolbarOverflowMenu;
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
export const genElementByClass = (className, containingDiv) => {
|
|
18
|
+
const elements = containingDiv.getElementsByClassName(className);
|
|
19
|
+
|
|
20
|
+
if (elements && elements.length > 0) {
|
|
21
|
+
return elements[0];
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const genRectByClass = (className, containingDiv) => {
|
|
27
|
+
const element = genElementByClass(className, containingDiv);
|
|
28
|
+
|
|
29
|
+
if (element) {
|
|
30
|
+
return element.getBoundingClientRect();
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
};
|