@bpmn-io/properties-panel 3.46.0 → 3.48.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/assets/properties-panel.css +37 -11
- package/dist/index.esm.js +259 -52
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +259 -52
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -4104,6 +4104,7 @@ function resizeToContents(element) {
|
|
|
4104
4104
|
function TextArea(props) {
|
|
4105
4105
|
const {
|
|
4106
4106
|
id,
|
|
4107
|
+
element,
|
|
4107
4108
|
label,
|
|
4108
4109
|
debounce,
|
|
4109
4110
|
onInput: commitValue,
|
|
@@ -4116,10 +4117,21 @@ function TextArea(props) {
|
|
|
4116
4117
|
autoResize = true,
|
|
4117
4118
|
placeholder,
|
|
4118
4119
|
rows = autoResize ? 1 : 2,
|
|
4119
|
-
tooltip
|
|
4120
|
+
tooltip,
|
|
4121
|
+
translate = translateFallback
|
|
4120
4122
|
} = props;
|
|
4121
4123
|
const [localValue, setLocalValue] = hooks.useState(value);
|
|
4122
4124
|
const ref = useShowEntryEvent(id);
|
|
4125
|
+
const containerRef = hooks.useRef();
|
|
4126
|
+
|
|
4127
|
+
// keep a live reference to the current value so callbacks captured by the
|
|
4128
|
+
// popup (frozen at open time) can compare against the latest value
|
|
4129
|
+
const localValueRef = hooks.useRef(localValue);
|
|
4130
|
+
localValueRef.current = localValue;
|
|
4131
|
+
const {
|
|
4132
|
+
eventBus
|
|
4133
|
+
} = hooks.useContext(EventContext);
|
|
4134
|
+
const [isPopupOpen, setIsPopupOpen] = hooks.useState(false);
|
|
4123
4135
|
const onInput = hooks.useCallback(newValue => {
|
|
4124
4136
|
const newModelValue = newValue === '' ? undefined : newValue;
|
|
4125
4137
|
commitValue(newModelValue);
|
|
@@ -4131,7 +4143,6 @@ function TextArea(props) {
|
|
|
4131
4143
|
*/
|
|
4132
4144
|
const handleInput = useDebounce(onInput, debounce);
|
|
4133
4145
|
const handleLocalInput = e => {
|
|
4134
|
-
autoResize && resizeToContents(e.target);
|
|
4135
4146
|
if (e.target.value === localValue) {
|
|
4136
4147
|
return;
|
|
4137
4148
|
}
|
|
@@ -4176,9 +4187,40 @@ function TextArea(props) {
|
|
|
4176
4187
|
handleInput.flush?.();
|
|
4177
4188
|
}
|
|
4178
4189
|
};
|
|
4190
|
+
const handlePopupInput = newValue => {
|
|
4191
|
+
if (newValue === localValueRef.current) {
|
|
4192
|
+
return;
|
|
4193
|
+
}
|
|
4194
|
+
setLocalValue(newValue);
|
|
4195
|
+
handleInput(newValue);
|
|
4196
|
+
};
|
|
4197
|
+
const handleOpenPopup = () => {
|
|
4198
|
+
const isOpen = eventBus.fire('propertiesPanel.openPopup', {
|
|
4199
|
+
element,
|
|
4200
|
+
entryId: id,
|
|
4201
|
+
label,
|
|
4202
|
+
onInput: handlePopupInput,
|
|
4203
|
+
sourceElement: ref.current,
|
|
4204
|
+
value: localValue
|
|
4205
|
+
});
|
|
4206
|
+
if (isOpen) {
|
|
4207
|
+
eventBus.once('propertiesPanelPopup.close', () => {
|
|
4208
|
+
handleInput.flush?.();
|
|
4209
|
+
setIsPopupOpen(false);
|
|
4210
|
+
});
|
|
4211
|
+
}
|
|
4212
|
+
setIsPopupOpen(isOpen === true);
|
|
4213
|
+
};
|
|
4214
|
+
hooks.useEffect(() => {
|
|
4215
|
+
return () => {
|
|
4216
|
+
eventBus && eventBus.fire('propertiesPanel.closePopup');
|
|
4217
|
+
};
|
|
4218
|
+
}, []);
|
|
4219
|
+
|
|
4220
|
+
// auto-resize on any value change (typing, popup edits, external updates)
|
|
4179
4221
|
hooks.useLayoutEffect(() => {
|
|
4180
4222
|
autoResize && resizeToContents(ref.current);
|
|
4181
|
-
}, []);
|
|
4223
|
+
}, [localValue]);
|
|
4182
4224
|
hooks.useLayoutEffect(() => {
|
|
4183
4225
|
visible && autoResize && resizeToContents(ref.current);
|
|
4184
4226
|
}, [visible]);
|
|
@@ -4196,25 +4238,35 @@ function TextArea(props) {
|
|
|
4196
4238
|
children: jsxRuntime.jsx(TooltipWrapper, {
|
|
4197
4239
|
value: tooltip,
|
|
4198
4240
|
forId: id,
|
|
4199
|
-
element:
|
|
4241
|
+
element: element,
|
|
4200
4242
|
children: label
|
|
4201
4243
|
})
|
|
4202
|
-
}), jsxRuntime.
|
|
4203
|
-
|
|
4204
|
-
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4244
|
+
}), jsxRuntime.jsxs("div", {
|
|
4245
|
+
class: classnames('bio-properties-panel-textarea-container', isPopupOpen ? 'popupOpen' : null),
|
|
4246
|
+
ref: containerRef,
|
|
4247
|
+
children: [isPopupOpen && jsxRuntime.jsx("div", {
|
|
4248
|
+
class: "bio-properties-panel-textarea__open-popup-placeholder",
|
|
4249
|
+
children: translate('Opened in editor')
|
|
4250
|
+
}), jsxRuntime.jsx("textarea", {
|
|
4251
|
+
ref: ref,
|
|
4252
|
+
id: prefixId$2(id),
|
|
4253
|
+
name: id,
|
|
4254
|
+
spellCheck: "false",
|
|
4255
|
+
class: classnames('bio-properties-panel-input', monospace ? 'bio-properties-panel-input-monospace' : '', autoResize ? 'auto-resize' : ''),
|
|
4256
|
+
onInput: handleLocalInput,
|
|
4257
|
+
onFocus: onFocus,
|
|
4258
|
+
onKeyDown: handleOnKeyDown,
|
|
4259
|
+
onBlur: handleOnBlur,
|
|
4260
|
+
onPaste: handleOnPaste,
|
|
4261
|
+
placeholder: placeholder,
|
|
4262
|
+
rows: rows,
|
|
4263
|
+
value: localValue,
|
|
4264
|
+
disabled: disabled,
|
|
4265
|
+
"data-gramm": "false"
|
|
4266
|
+
}), eventBus && !disabled && jsxRuntime.jsx(OpenPopupButton, {
|
|
4267
|
+
onClick: handleOpenPopup,
|
|
4268
|
+
translate: translate
|
|
4269
|
+
})]
|
|
4218
4270
|
})]
|
|
4219
4271
|
});
|
|
4220
4272
|
}
|
|
@@ -4235,6 +4287,7 @@ function TextArea(props) {
|
|
|
4235
4287
|
* @param {boolean} props.monospace
|
|
4236
4288
|
* @param {Function} [props.validate]
|
|
4237
4289
|
* @param {boolean} [props.disabled]
|
|
4290
|
+
* @param {Function} [props.translate]
|
|
4238
4291
|
*/
|
|
4239
4292
|
function TextAreaEntry(props) {
|
|
4240
4293
|
const {
|
|
@@ -4254,7 +4307,8 @@ function TextAreaEntry(props) {
|
|
|
4254
4307
|
onPaste,
|
|
4255
4308
|
placeholder,
|
|
4256
4309
|
autoResize,
|
|
4257
|
-
tooltip
|
|
4310
|
+
tooltip,
|
|
4311
|
+
translate
|
|
4258
4312
|
} = props;
|
|
4259
4313
|
const globalError = useError(id);
|
|
4260
4314
|
const [localError, setLocalError] = hooks.useState(null);
|
|
@@ -4295,6 +4349,7 @@ function TextAreaEntry(props) {
|
|
|
4295
4349
|
placeholder: placeholder,
|
|
4296
4350
|
autoResize: autoResize,
|
|
4297
4351
|
tooltip: tooltip,
|
|
4352
|
+
translate: translate,
|
|
4298
4353
|
element: element
|
|
4299
4354
|
}, element), error && jsxRuntime.jsx("div", {
|
|
4300
4355
|
class: "bio-properties-panel-error",
|
|
@@ -4636,6 +4691,9 @@ const noop = () => {};
|
|
|
4636
4691
|
* @param {Function} [props.onPostDeactivate]
|
|
4637
4692
|
* @param {boolean} [props.returnFocus]
|
|
4638
4693
|
* @param {boolean} [props.closeOnEscape]
|
|
4694
|
+
* @param {(event: KeyboardEvent) => boolean} [props.allowFocusMove] -
|
|
4695
|
+
* Whether a Tab keypress may move focus. Return false to leave the keypress
|
|
4696
|
+
* to the focused element, e.g. an editor navigating snippet placeholders.
|
|
4639
4697
|
* @param {string} props.title
|
|
4640
4698
|
* @param {Ref} [ref]
|
|
4641
4699
|
*/
|
|
@@ -4651,6 +4709,7 @@ function PopupComponent(props, globalRef) {
|
|
|
4651
4709
|
onPostDeactivate = noop,
|
|
4652
4710
|
returnFocus = true,
|
|
4653
4711
|
closeOnEscape = true,
|
|
4712
|
+
allowFocusMove = () => true,
|
|
4654
4713
|
title
|
|
4655
4714
|
} = props;
|
|
4656
4715
|
const focusTrapRef = hooks.useRef(null);
|
|
@@ -4700,6 +4759,8 @@ function PopupComponent(props, globalRef) {
|
|
|
4700
4759
|
clickOutsideDeactivates: true,
|
|
4701
4760
|
delayInitialFocus,
|
|
4702
4761
|
fallbackFocus: popupRef.current,
|
|
4762
|
+
isKeyForward: event => isTab(event) && !event.shiftKey && allowFocusMove(event),
|
|
4763
|
+
isKeyBackward: event => isTab(event) && event.shiftKey && allowFocusMove(event),
|
|
4703
4764
|
onPostActivate,
|
|
4704
4765
|
onPostDeactivate,
|
|
4705
4766
|
returnFocusOnDeactivate: returnFocus
|
|
@@ -4719,10 +4780,10 @@ function PopupComponent(props, globalRef) {
|
|
|
4719
4780
|
children: props.children
|
|
4720
4781
|
});
|
|
4721
4782
|
}
|
|
4722
|
-
const Popup = compat.forwardRef(PopupComponent);
|
|
4723
|
-
Popup.Title = Title;
|
|
4724
|
-
Popup.Body = Body;
|
|
4725
|
-
Popup.Footer = Footer;
|
|
4783
|
+
const Popup$1 = compat.forwardRef(PopupComponent);
|
|
4784
|
+
Popup$1.Title = Title;
|
|
4785
|
+
Popup$1.Body = Body;
|
|
4786
|
+
Popup$1.Footer = Footer;
|
|
4726
4787
|
function Title(props) {
|
|
4727
4788
|
const {
|
|
4728
4789
|
children,
|
|
@@ -4833,6 +4894,9 @@ function Footer(props) {
|
|
|
4833
4894
|
|
|
4834
4895
|
// helpers //////////////////////
|
|
4835
4896
|
|
|
4897
|
+
function isTab(event) {
|
|
4898
|
+
return event.key === 'Tab';
|
|
4899
|
+
}
|
|
4836
4900
|
function getPopupParent(node) {
|
|
4837
4901
|
return node.closest('.bio-properties-panel-popup');
|
|
4838
4902
|
}
|
|
@@ -4860,13 +4924,13 @@ function cancel(event) {
|
|
|
4860
4924
|
*/
|
|
4861
4925
|
|
|
4862
4926
|
const FEEL_POPUP_WIDTH = 700;
|
|
4863
|
-
const FEEL_POPUP_HEIGHT =
|
|
4927
|
+
const FEEL_POPUP_HEIGHT = 400;
|
|
4864
4928
|
|
|
4865
4929
|
/**
|
|
4866
4930
|
* FEEL expression editor popup component
|
|
4867
4931
|
* @param {FeelPopupProps} props
|
|
4868
4932
|
*/
|
|
4869
|
-
function FeelPopup
|
|
4933
|
+
function FeelPopup(props) {
|
|
4870
4934
|
const {
|
|
4871
4935
|
entryId,
|
|
4872
4936
|
onInput,
|
|
@@ -4911,18 +4975,19 @@ function FeelPopup$1(props) {
|
|
|
4911
4975
|
editorRef.current.focus();
|
|
4912
4976
|
}
|
|
4913
4977
|
}, [editorRef]);
|
|
4914
|
-
return jsxRuntime.jsxs(Popup, {
|
|
4978
|
+
return jsxRuntime.jsxs(Popup$1, {
|
|
4915
4979
|
className: "bio-properties-panel-feel-popup",
|
|
4916
4980
|
position: position,
|
|
4917
4981
|
title: title,
|
|
4918
4982
|
returnFocus: false,
|
|
4919
4983
|
closeOnEscape: false,
|
|
4920
4984
|
delayInitialFocus: false,
|
|
4985
|
+
allowFocusMove: event => !isSnippetNavigation(event),
|
|
4921
4986
|
onPostDeactivate: handleSetReturnFocus,
|
|
4922
4987
|
height: FEEL_POPUP_HEIGHT,
|
|
4923
4988
|
width: FEEL_POPUP_WIDTH,
|
|
4924
4989
|
ref: popupRef,
|
|
4925
|
-
children: [jsxRuntime.jsx(Popup.Title, {
|
|
4990
|
+
children: [jsxRuntime.jsx(Popup$1.Title, {
|
|
4926
4991
|
title: title,
|
|
4927
4992
|
eventBus: eventBus,
|
|
4928
4993
|
showCloseButton: true,
|
|
@@ -4940,14 +5005,13 @@ function FeelPopup$1(props) {
|
|
|
4940
5005
|
}, index);
|
|
4941
5006
|
})
|
|
4942
5007
|
})
|
|
4943
|
-
}), jsxRuntime.jsx(Popup.Body, {
|
|
5008
|
+
}), jsxRuntime.jsx(Popup$1.Body, {
|
|
4944
5009
|
children: jsxRuntime.jsxs("div", {
|
|
4945
5010
|
onKeyDownCapture: onKeyDownCapture,
|
|
4946
5011
|
onKeyDown: onKeyDown,
|
|
4947
5012
|
class: "bio-properties-panel-feel-popup__body",
|
|
4948
5013
|
children: [type === 'feel' && jsxRuntime.jsx(FeelEditor, {
|
|
4949
5014
|
enableGutters: true,
|
|
4950
|
-
id: prefixId(entryId),
|
|
4951
5015
|
name: entryId,
|
|
4952
5016
|
onInput: onInput,
|
|
4953
5017
|
value: value,
|
|
@@ -4956,7 +5020,6 @@ function FeelPopup$1(props) {
|
|
|
4956
5020
|
ref: editorRef,
|
|
4957
5021
|
tooltipContainer: tooltipContainer
|
|
4958
5022
|
}), type === 'feelers' && jsxRuntime.jsx(TemplatingEditor, {
|
|
4959
|
-
id: prefixId(entryId),
|
|
4960
5023
|
contentAttributes: {
|
|
4961
5024
|
'aria-label': title
|
|
4962
5025
|
},
|
|
@@ -4973,14 +5036,17 @@ function FeelPopup$1(props) {
|
|
|
4973
5036
|
})]
|
|
4974
5037
|
});
|
|
4975
5038
|
}
|
|
4976
|
-
function prefixId(id) {
|
|
4977
|
-
return `bio-properties-panel-${id}`;
|
|
4978
|
-
}
|
|
4979
5039
|
function autoCompletionOpen(element) {
|
|
4980
5040
|
const editor = element.closest('.cm-editor');
|
|
4981
5041
|
return editor ? editor.querySelector('.cm-tooltip-autocomplete') : null;
|
|
4982
5042
|
}
|
|
4983
5043
|
|
|
5044
|
+
// while a snippet is active, Tab navigates its placeholders inside the editor
|
|
5045
|
+
function isSnippetNavigation(event) {
|
|
5046
|
+
const editor = event.target.closest('.cm-editor');
|
|
5047
|
+
return !!(editor && editor.querySelector('.cm-snippetField'));
|
|
5048
|
+
}
|
|
5049
|
+
|
|
4984
5050
|
function getPopupTitle({
|
|
4985
5051
|
element,
|
|
4986
5052
|
label
|
|
@@ -5001,7 +5067,102 @@ function getPopupPosition() {
|
|
|
5001
5067
|
}
|
|
5002
5068
|
|
|
5003
5069
|
/**
|
|
5004
|
-
*
|
|
5070
|
+
* @typedef {Object} TextPopupProps
|
|
5071
|
+
* @property {string} entryId
|
|
5072
|
+
* @property {Function} onInput
|
|
5073
|
+
* @property {Function} onClose
|
|
5074
|
+
* @property {string} title
|
|
5075
|
+
* @property {string} value
|
|
5076
|
+
* @property {Object} [position]
|
|
5077
|
+
* @property {HTMLElement} [sourceElement]
|
|
5078
|
+
* @property {Object} [eventBus]
|
|
5079
|
+
*/
|
|
5080
|
+
|
|
5081
|
+
const TEXT_POPUP_WIDTH = 700;
|
|
5082
|
+
const TEXT_POPUP_HEIGHT = 400;
|
|
5083
|
+
|
|
5084
|
+
/**
|
|
5085
|
+
* Plain text editor popup component.
|
|
5086
|
+
*
|
|
5087
|
+
* Intentionally kept separate from the FEEL popup: the two are expected to
|
|
5088
|
+
* diverge as we add FEEL-specific capabilities that do not apply to plain text.
|
|
5089
|
+
*
|
|
5090
|
+
* @param {TextPopupProps} props
|
|
5091
|
+
*/
|
|
5092
|
+
function TextPopup(props) {
|
|
5093
|
+
const {
|
|
5094
|
+
entryId,
|
|
5095
|
+
onInput,
|
|
5096
|
+
onClose,
|
|
5097
|
+
title,
|
|
5098
|
+
value,
|
|
5099
|
+
position,
|
|
5100
|
+
sourceElement,
|
|
5101
|
+
eventBus
|
|
5102
|
+
} = props;
|
|
5103
|
+
const editorRef = hooks.useRef();
|
|
5104
|
+
const popupRef = hooks.useRef();
|
|
5105
|
+
const handleSetReturnFocus = () => {
|
|
5106
|
+
sourceElement && sourceElement.focus();
|
|
5107
|
+
};
|
|
5108
|
+
hooks.useEffect(() => {
|
|
5109
|
+
// set focus on editor when popup is opened
|
|
5110
|
+
if (editorRef.current) {
|
|
5111
|
+
editorRef.current.focus();
|
|
5112
|
+
}
|
|
5113
|
+
}, [editorRef]);
|
|
5114
|
+
return jsxRuntime.jsxs(Popup$1, {
|
|
5115
|
+
className: "bio-properties-panel-text-popup",
|
|
5116
|
+
position: position,
|
|
5117
|
+
title: title,
|
|
5118
|
+
returnFocus: false,
|
|
5119
|
+
closeOnEscape: true,
|
|
5120
|
+
delayInitialFocus: false,
|
|
5121
|
+
onClose: onClose,
|
|
5122
|
+
onPostDeactivate: handleSetReturnFocus,
|
|
5123
|
+
height: TEXT_POPUP_HEIGHT,
|
|
5124
|
+
width: TEXT_POPUP_WIDTH,
|
|
5125
|
+
ref: popupRef,
|
|
5126
|
+
children: [jsxRuntime.jsx(Popup$1.Title, {
|
|
5127
|
+
title: title,
|
|
5128
|
+
eventBus: eventBus,
|
|
5129
|
+
showCloseButton: true,
|
|
5130
|
+
closeButtonTooltip: "Save and close",
|
|
5131
|
+
onClose: onClose,
|
|
5132
|
+
draggable: true
|
|
5133
|
+
}), jsxRuntime.jsx(Popup$1.Body, {
|
|
5134
|
+
children: jsxRuntime.jsx("textarea", {
|
|
5135
|
+
id: prefixId(entryId),
|
|
5136
|
+
name: entryId,
|
|
5137
|
+
class: "bio-properties-panel-input",
|
|
5138
|
+
ref: editorRef,
|
|
5139
|
+
onInput: e => onInput(e.target.value),
|
|
5140
|
+
value: value || '',
|
|
5141
|
+
spellCheck: "false",
|
|
5142
|
+
autoComplete: "off",
|
|
5143
|
+
"aria-label": title,
|
|
5144
|
+
"data-gramm": "false"
|
|
5145
|
+
})
|
|
5146
|
+
})]
|
|
5147
|
+
});
|
|
5148
|
+
}
|
|
5149
|
+
|
|
5150
|
+
// The in-panel field stays mounted (hidden) while the popup is open, so we
|
|
5151
|
+
// scope the popup editor id to keep it unique in the DOM.
|
|
5152
|
+
function prefixId(id) {
|
|
5153
|
+
return `bio-properties-panel-popup-${id}`;
|
|
5154
|
+
}
|
|
5155
|
+
|
|
5156
|
+
const DEFAULT_POPUP_TYPE = 'text';
|
|
5157
|
+
|
|
5158
|
+
// consumers registering via #registerProvider default to DEFAULT_PRIORITY,
|
|
5159
|
+
// so their providers take precedence over the LOW_PRIORITY built-ins.
|
|
5160
|
+
const DEFAULT_PRIORITY = 1000;
|
|
5161
|
+
const LOW_PRIORITY = 500;
|
|
5162
|
+
|
|
5163
|
+
/**
|
|
5164
|
+
* Popup manager, built as a singleton. Renders the registered provider for a
|
|
5165
|
+
* given popup type; consumers may plug in their own via #registerProvider.
|
|
5005
5166
|
*
|
|
5006
5167
|
* In order to implement a custom replacement, handle the following events:
|
|
5007
5168
|
* - `propertiesPanel.openPopup`
|
|
@@ -5014,16 +5175,19 @@ function getPopupPosition() {
|
|
|
5014
5175
|
* - `feelPopup.close` - fired before the popup is unmounted. Event context contains the DOM node of the popup as `domNode`
|
|
5015
5176
|
* - `feelPopup.closed` - fired after the popup is unmounted
|
|
5016
5177
|
*/
|
|
5017
|
-
class
|
|
5178
|
+
class Popup {
|
|
5018
5179
|
constructor(eventBus, config = {}) {
|
|
5019
5180
|
this._eventBus = eventBus;
|
|
5020
5181
|
this._config = config;
|
|
5021
5182
|
this._isOpen = false;
|
|
5022
|
-
eventBus.on('propertiesPanel.openPopup', (_, context) => {
|
|
5023
|
-
this.open(context.entryId, context, context.sourceElement);
|
|
5024
5183
|
|
|
5025
|
-
|
|
5026
|
-
|
|
5184
|
+
// built-in providers, registered at LOW_PRIORITY so consumers can
|
|
5185
|
+
// override them via #registerProvider using the default priority
|
|
5186
|
+
this.registerProvider('feel', LOW_PRIORITY, FeelPopup);
|
|
5187
|
+
this.registerProvider('feelers', LOW_PRIORITY, FeelPopup);
|
|
5188
|
+
this.registerProvider('text', LOW_PRIORITY, TextPopup);
|
|
5189
|
+
eventBus.on('propertiesPanel.openPopup', (_, context) => {
|
|
5190
|
+
return this.open(context.entryId, context, context.sourceElement);
|
|
5027
5191
|
});
|
|
5028
5192
|
eventBus.on(['propertiesPanel.closePopup', 'propertiesPanel.detach'], () => {
|
|
5029
5193
|
this.close();
|
|
@@ -5031,7 +5195,43 @@ class FeelPopup {
|
|
|
5031
5195
|
}
|
|
5032
5196
|
|
|
5033
5197
|
/**
|
|
5034
|
-
*
|
|
5198
|
+
* Register a popup provider (component) for a given type.
|
|
5199
|
+
*
|
|
5200
|
+
* A higher `priority` wins when multiple providers are registered for the
|
|
5201
|
+
* same type; the built-in providers use a low priority so consumers override
|
|
5202
|
+
* them by default.
|
|
5203
|
+
*
|
|
5204
|
+
* @param {string} type
|
|
5205
|
+
* @param {number} [priority=DEFAULT_PRIORITY]
|
|
5206
|
+
* @param {Function|import('preact').Component} provider
|
|
5207
|
+
*/
|
|
5208
|
+
registerProvider(type, priority, provider) {
|
|
5209
|
+
if (!provider) {
|
|
5210
|
+
provider = priority;
|
|
5211
|
+
priority = DEFAULT_PRIORITY;
|
|
5212
|
+
}
|
|
5213
|
+
this._eventBus.on('propertiesPanelPopup.getProviders.' + type, priority, function (event) {
|
|
5214
|
+
event.providers.push(provider);
|
|
5215
|
+
});
|
|
5216
|
+
}
|
|
5217
|
+
|
|
5218
|
+
/**
|
|
5219
|
+
* Get the popup providers registered for a type.
|
|
5220
|
+
*
|
|
5221
|
+
* @param {string} type
|
|
5222
|
+
* @return {Array<Function|import('preact').Component>}
|
|
5223
|
+
*/
|
|
5224
|
+
_getProviders(type) {
|
|
5225
|
+
const event = this._eventBus.createEvent({
|
|
5226
|
+
type: 'propertiesPanelPopup.getProviders.' + type,
|
|
5227
|
+
providers: []
|
|
5228
|
+
});
|
|
5229
|
+
this._eventBus.fire(event);
|
|
5230
|
+
return event.providers;
|
|
5231
|
+
}
|
|
5232
|
+
|
|
5233
|
+
/**
|
|
5234
|
+
* Check if the popup is open.
|
|
5035
5235
|
* @return {Boolean}
|
|
5036
5236
|
*/
|
|
5037
5237
|
isOpen() {
|
|
@@ -5039,7 +5239,7 @@ class FeelPopup {
|
|
|
5039
5239
|
}
|
|
5040
5240
|
|
|
5041
5241
|
/**
|
|
5042
|
-
* Open the
|
|
5242
|
+
* Open the popup.
|
|
5043
5243
|
*
|
|
5044
5244
|
* @param {String} entryId
|
|
5045
5245
|
* @param {Object} popupConfig
|
|
@@ -5048,7 +5248,7 @@ class FeelPopup {
|
|
|
5048
5248
|
open(entryId, popupConfig, sourceElement) {
|
|
5049
5249
|
// close before opening a new one
|
|
5050
5250
|
this.close();
|
|
5051
|
-
this._openPopup({
|
|
5251
|
+
return this._openPopup({
|
|
5052
5252
|
...popupConfig,
|
|
5053
5253
|
entryId,
|
|
5054
5254
|
sourceElement
|
|
@@ -5056,7 +5256,7 @@ class FeelPopup {
|
|
|
5056
5256
|
}
|
|
5057
5257
|
|
|
5058
5258
|
/**
|
|
5059
|
-
* Close the
|
|
5259
|
+
* Close the popup.
|
|
5060
5260
|
*/
|
|
5061
5261
|
close() {
|
|
5062
5262
|
this._closePopup();
|
|
@@ -5066,13 +5266,18 @@ class FeelPopup {
|
|
|
5066
5266
|
element,
|
|
5067
5267
|
label,
|
|
5068
5268
|
sourceElement,
|
|
5069
|
-
type
|
|
5269
|
+
type = DEFAULT_POPUP_TYPE
|
|
5070
5270
|
} = context;
|
|
5271
|
+
const component = this._getProviders(type)[0];
|
|
5272
|
+
if (!component) {
|
|
5273
|
+
return false;
|
|
5274
|
+
}
|
|
5071
5275
|
this._isOpen = true;
|
|
5072
5276
|
this._eventBus.fire('propertiesPanelPopup.open', {
|
|
5073
5277
|
container: this._config.feelPopupContainer,
|
|
5074
5278
|
config: {
|
|
5075
5279
|
...context,
|
|
5280
|
+
component,
|
|
5076
5281
|
links: this._config.getFeelPopupLinks?.(type) || [],
|
|
5077
5282
|
onClose: () => {
|
|
5078
5283
|
this._closePopup();
|
|
@@ -5089,6 +5294,7 @@ class FeelPopup {
|
|
|
5089
5294
|
})
|
|
5090
5295
|
}
|
|
5091
5296
|
});
|
|
5297
|
+
return true;
|
|
5092
5298
|
}
|
|
5093
5299
|
_closePopup() {
|
|
5094
5300
|
if (this._isOpen) {
|
|
@@ -5097,9 +5303,9 @@ class FeelPopup {
|
|
|
5097
5303
|
}
|
|
5098
5304
|
}
|
|
5099
5305
|
}
|
|
5100
|
-
|
|
5306
|
+
Popup.$inject = ['eventBus', 'config.propertiesPanel'];
|
|
5101
5307
|
|
|
5102
|
-
class
|
|
5308
|
+
class PopupRenderer {
|
|
5103
5309
|
constructor(eventBus) {
|
|
5104
5310
|
this._eventBus = eventBus;
|
|
5105
5311
|
this._container = null;
|
|
@@ -5125,7 +5331,8 @@ class FeelPopupRenderer {
|
|
|
5125
5331
|
// a custom renderer would have to use that context provider as well to have
|
|
5126
5332
|
// access to the event bus and other services
|
|
5127
5333
|
this._emit('feelPopup.open');
|
|
5128
|
-
|
|
5334
|
+
const Component = config.component;
|
|
5335
|
+
preact.render(jsxRuntime.jsx(Component, {
|
|
5129
5336
|
...config,
|
|
5130
5337
|
eventBus: this._eventBus
|
|
5131
5338
|
}), element);
|
|
@@ -5149,7 +5356,7 @@ class FeelPopupRenderer {
|
|
|
5149
5356
|
this._eventBus.fire(event, context);
|
|
5150
5357
|
}
|
|
5151
5358
|
}
|
|
5152
|
-
|
|
5359
|
+
PopupRenderer.$inject = ['eventBus'];
|
|
5153
5360
|
|
|
5154
5361
|
// helpers /////////////////
|
|
5155
5362
|
|
|
@@ -5167,8 +5374,8 @@ function getContainer(container) {
|
|
|
5167
5374
|
|
|
5168
5375
|
var index = {
|
|
5169
5376
|
__init__: ['feelPopup', 'feelPopupRenderer'],
|
|
5170
|
-
feelPopup: ['type',
|
|
5171
|
-
feelPopupRenderer: ['type',
|
|
5377
|
+
feelPopup: ['type', Popup],
|
|
5378
|
+
feelPopupRenderer: ['type', PopupRenderer]
|
|
5172
5379
|
};
|
|
5173
5380
|
|
|
5174
5381
|
exports.ArrowIcon = Arrow;
|