@bpmn-io/properties-panel 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/assets/properties-panel.css +5 -0
- package/dist/index.esm.js +987 -230
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +990 -226
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,32 +1,131 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { isFunction,
|
|
1
|
+
import { useContext, useEffect, useRef, useMemo, useState, useCallback } from '../preact/hooks';
|
|
2
|
+
import { isArray, isFunction, isNumber, bind, assign, get, set, sortBy, find, debounce } from 'min-dash';
|
|
3
3
|
import classnames from 'classnames';
|
|
4
|
-
import
|
|
4
|
+
import '../preact/compat';
|
|
5
|
+
import { jsx, jsxs } from '../preact/jsx-runtime';
|
|
5
6
|
import { query } from 'min-dom';
|
|
6
7
|
import { createContext, createElement } from '../preact';
|
|
7
|
-
import '../preact/compat';
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
var ArrowIcon = function ArrowIcon(props) {
|
|
10
|
+
return jsx("svg", { ...props,
|
|
11
|
+
children: jsx("path", {
|
|
12
|
+
fillRule: "evenodd",
|
|
13
|
+
d: "m11.657 8-4.95 4.95a1 1 0 0 1-1.414-1.414L8.828 8 5.293 4.464A1 1 0 1 1 6.707 3.05L11.657 8z"
|
|
14
|
+
})
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
ArrowIcon.defaultProps = {
|
|
19
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
20
|
+
width: "16",
|
|
21
|
+
height: "16"
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
var CreateIcon = function CreateIcon(props) {
|
|
25
|
+
return jsx("svg", { ...props,
|
|
26
|
+
children: jsx("path", {
|
|
27
|
+
fillRule: "evenodd",
|
|
28
|
+
d: "M9 13V9h4a1 1 0 0 0 0-2H9V3a1 1 0 1 0-2 0v4H3a1 1 0 1 0 0 2h4v4a1 1 0 0 0 2 0z"
|
|
29
|
+
})
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
CreateIcon.defaultProps = {
|
|
34
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
35
|
+
width: "16",
|
|
36
|
+
height: "16"
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
var DeleteIcon = function DeleteIcon(props) {
|
|
40
|
+
return jsx("svg", { ...props,
|
|
41
|
+
children: jsx("path", {
|
|
42
|
+
fillRule: "evenodd",
|
|
43
|
+
d: "M12 6v7c0 1.1-.4 1.55-1.5 1.55h-5C4.4 14.55 4 14.1 4 13V6h8zm-1.5 1.5h-5v4.3c0 .66.5 1.2 1.111 1.2H9.39c.611 0 1.111-.54 1.111-1.2V7.5zM13 3h-2l-1-1H6L5 3H3v1.5h10V3z"
|
|
44
|
+
})
|
|
45
|
+
});
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
DeleteIcon.defaultProps = {
|
|
49
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
50
|
+
width: "16",
|
|
51
|
+
height: "16"
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
var ExternalLinkIcon = function ExternalLinkIcon(props) {
|
|
55
|
+
return jsx("svg", { ...props,
|
|
56
|
+
children: jsx("path", {
|
|
57
|
+
fillRule: "evenodd",
|
|
58
|
+
clipRule: "evenodd",
|
|
59
|
+
d: "M12.637 12.637v-4.72h1.362v4.721c0 .36-.137.676-.411.95-.275.275-.591.412-.95.412H3.362c-.38 0-.703-.132-.967-.396A1.315 1.315 0 0 1 2 12.638V3.362c0-.38.132-.703.396-.967S2.982 2 3.363 2h4.553v1.363H3.363v9.274h9.274zM14 2H9.28l-.001 1.362h2.408L5.065 9.984l.95.95 6.622-6.622v2.409H14V2z",
|
|
60
|
+
fill: "#818798"
|
|
61
|
+
})
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
ExternalLinkIcon.defaultProps = {
|
|
66
|
+
width: "16",
|
|
67
|
+
height: "16",
|
|
68
|
+
fill: "none",
|
|
69
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
var FeelRequiredIcon = function FeelRequiredIcon(props) {
|
|
73
|
+
return jsxs("svg", { ...props,
|
|
74
|
+
children: [jsx("path", {
|
|
75
|
+
d: "M5.8 7.06V5.95h4.307v1.11H5.8zm0 3.071v-1.11h4.307v1.11H5.8z",
|
|
76
|
+
fill: "#505562"
|
|
77
|
+
}), jsx("path", {
|
|
78
|
+
fillRule: "evenodd",
|
|
79
|
+
clipRule: "evenodd",
|
|
80
|
+
d: "M8 3.268A4.732 4.732 0 1 0 12.732 8H14a6 6 0 1 1-6-6v1.268z",
|
|
81
|
+
fill: "#505562"
|
|
82
|
+
}), jsx("path", {
|
|
83
|
+
d: "m11.28 6.072-.832-.56 1.016-1.224L10 3.848l.312-.912 1.392.584L11.632 2h1.032l-.072 1.52 1.392-.584.312.912-1.464.44 1.008 1.224-.832.552-.864-1.296-.864 1.304z",
|
|
84
|
+
fill: "#505562"
|
|
85
|
+
})]
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
FeelRequiredIcon.defaultProps = {
|
|
90
|
+
viewBox: "0 0 16 16",
|
|
91
|
+
fill: "none",
|
|
92
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
var FeelOptionalIcon = function FeelOptionalIcon(props) {
|
|
96
|
+
return jsxs("svg", { ...props,
|
|
97
|
+
children: [jsx("path", {
|
|
98
|
+
d: "M5.845 7.04V5.93h4.307v1.11H5.845zm0 3.07V9h4.307v1.11H5.845z",
|
|
99
|
+
fill: "#505562"
|
|
100
|
+
}), jsx("path", {
|
|
101
|
+
fillRule: "evenodd",
|
|
102
|
+
clipRule: "evenodd",
|
|
103
|
+
d: "M3.286 8a4.714 4.714 0 1 0 9.428 0 4.714 4.714 0 0 0-9.428 0zM8 2a6 6 0 1 0 0 12A6 6 0 0 0 8 2z",
|
|
104
|
+
fill: "#505562"
|
|
105
|
+
})]
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
FeelOptionalIcon.defaultProps = {
|
|
110
|
+
viewBox: "0 0 16 16",
|
|
111
|
+
fill: "none",
|
|
112
|
+
xmlns: "http://www.w3.org/2000/svg"
|
|
113
|
+
};
|
|
12
114
|
|
|
13
|
-
/**
|
|
14
|
-
* @param {Object} props
|
|
15
|
-
* @param {Object} props.element,
|
|
16
|
-
* @param {HeaderProvider} props.headerProvider
|
|
17
|
-
*/
|
|
18
115
|
function Header(props) {
|
|
19
116
|
const {
|
|
20
117
|
element,
|
|
21
118
|
headerProvider
|
|
22
119
|
} = props;
|
|
23
120
|
const {
|
|
121
|
+
getElementIcon,
|
|
122
|
+
getDocumentationRef,
|
|
24
123
|
getElementLabel,
|
|
25
|
-
getTypeLabel
|
|
26
|
-
getElementIcon
|
|
124
|
+
getTypeLabel
|
|
27
125
|
} = headerProvider;
|
|
28
126
|
const label = getElementLabel(element);
|
|
29
127
|
const type = getTypeLabel(element);
|
|
128
|
+
const documentationRef = getDocumentationRef && getDocumentationRef(element);
|
|
30
129
|
const ElementIcon = getElementIcon(element);
|
|
31
130
|
return jsxs("div", {
|
|
32
131
|
class: "bio-properties-panel-header",
|
|
@@ -43,28 +142,624 @@ function Header(props) {
|
|
|
43
142
|
title: type,
|
|
44
143
|
class: "bio-properties-panel-header-type",
|
|
45
144
|
children: type
|
|
46
|
-
}),
|
|
145
|
+
}), label ? jsx("div", {
|
|
47
146
|
title: label,
|
|
48
147
|
class: "bio-properties-panel-header-label",
|
|
49
148
|
children: label
|
|
50
149
|
}) : null]
|
|
150
|
+
}), jsx("div", {
|
|
151
|
+
class: "bio-properties-panel-header-actions",
|
|
152
|
+
children: documentationRef ? jsx("a", {
|
|
153
|
+
rel: "noopener",
|
|
154
|
+
class: "bio-properties-panel-header-link",
|
|
155
|
+
href: documentationRef,
|
|
156
|
+
target: "_blank",
|
|
157
|
+
children: jsx(ExternalLinkIcon, {})
|
|
158
|
+
}) : null
|
|
51
159
|
})]
|
|
52
160
|
});
|
|
53
161
|
}
|
|
54
162
|
|
|
163
|
+
const DescriptionContext = createContext({
|
|
164
|
+
description: {},
|
|
165
|
+
getDescriptionForId: () => {}
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
var FN_REF = '__fn';
|
|
169
|
+
var DEFAULT_PRIORITY$1 = 1000;
|
|
170
|
+
var slice = Array.prototype.slice;
|
|
171
|
+
/**
|
|
172
|
+
* A general purpose event bus.
|
|
173
|
+
*
|
|
174
|
+
* This component is used to communicate across a diagram instance.
|
|
175
|
+
* Other parts of a diagram can use it to listen to and broadcast events.
|
|
176
|
+
*
|
|
177
|
+
*
|
|
178
|
+
* ## Registering for Events
|
|
179
|
+
*
|
|
180
|
+
* The event bus provides the {@link EventBus#on} and {@link EventBus#once}
|
|
181
|
+
* methods to register for events. {@link EventBus#off} can be used to
|
|
182
|
+
* remove event registrations. Listeners receive an instance of {@link Event}
|
|
183
|
+
* as the first argument. It allows them to hook into the event execution.
|
|
184
|
+
*
|
|
185
|
+
* ```javascript
|
|
186
|
+
*
|
|
187
|
+
* // listen for event
|
|
188
|
+
* eventBus.on('foo', function(event) {
|
|
189
|
+
*
|
|
190
|
+
* // access event type
|
|
191
|
+
* event.type; // 'foo'
|
|
192
|
+
*
|
|
193
|
+
* // stop propagation to other listeners
|
|
194
|
+
* event.stopPropagation();
|
|
195
|
+
*
|
|
196
|
+
* // prevent event default
|
|
197
|
+
* event.preventDefault();
|
|
198
|
+
* });
|
|
199
|
+
*
|
|
200
|
+
* // listen for event with custom payload
|
|
201
|
+
* eventBus.on('bar', function(event, payload) {
|
|
202
|
+
* console.log(payload);
|
|
203
|
+
* });
|
|
204
|
+
*
|
|
205
|
+
* // listen for event returning value
|
|
206
|
+
* eventBus.on('foobar', function(event) {
|
|
207
|
+
*
|
|
208
|
+
* // stop event propagation + prevent default
|
|
209
|
+
* return false;
|
|
210
|
+
*
|
|
211
|
+
* // stop event propagation + return custom result
|
|
212
|
+
* return {
|
|
213
|
+
* complex: 'listening result'
|
|
214
|
+
* };
|
|
215
|
+
* });
|
|
216
|
+
*
|
|
217
|
+
*
|
|
218
|
+
* // listen with custom priority (default=1000, higher is better)
|
|
219
|
+
* eventBus.on('priorityfoo', 1500, function(event) {
|
|
220
|
+
* console.log('invoked first!');
|
|
221
|
+
* });
|
|
222
|
+
*
|
|
223
|
+
*
|
|
224
|
+
* // listen for event and pass the context (`this`)
|
|
225
|
+
* eventBus.on('foobar', function(event) {
|
|
226
|
+
* this.foo();
|
|
227
|
+
* }, this);
|
|
228
|
+
* ```
|
|
229
|
+
*
|
|
230
|
+
*
|
|
231
|
+
* ## Emitting Events
|
|
232
|
+
*
|
|
233
|
+
* Events can be emitted via the event bus using {@link EventBus#fire}.
|
|
234
|
+
*
|
|
235
|
+
* ```javascript
|
|
236
|
+
*
|
|
237
|
+
* // false indicates that the default action
|
|
238
|
+
* // was prevented by listeners
|
|
239
|
+
* if (eventBus.fire('foo') === false) {
|
|
240
|
+
* console.log('default has been prevented!');
|
|
241
|
+
* };
|
|
242
|
+
*
|
|
243
|
+
*
|
|
244
|
+
* // custom args + return value listener
|
|
245
|
+
* eventBus.on('sum', function(event, a, b) {
|
|
246
|
+
* return a + b;
|
|
247
|
+
* });
|
|
248
|
+
*
|
|
249
|
+
* // you can pass custom arguments + retrieve result values.
|
|
250
|
+
* var sum = eventBus.fire('sum', 1, 2);
|
|
251
|
+
* console.log(sum); // 3
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
254
|
+
|
|
255
|
+
function EventBus() {
|
|
256
|
+
this._listeners = {}; // cleanup on destroy on lowest priority to allow
|
|
257
|
+
// message passing until the bitter end
|
|
258
|
+
|
|
259
|
+
this.on('diagram.destroy', 1, this._destroy, this);
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Register an event listener for events with the given name.
|
|
263
|
+
*
|
|
264
|
+
* The callback will be invoked with `event, ...additionalArguments`
|
|
265
|
+
* that have been passed to {@link EventBus#fire}.
|
|
266
|
+
*
|
|
267
|
+
* Returning false from a listener will prevent the events default action
|
|
268
|
+
* (if any is specified). To stop an event from being processed further in
|
|
269
|
+
* other listeners execute {@link Event#stopPropagation}.
|
|
270
|
+
*
|
|
271
|
+
* Returning anything but `undefined` from a listener will stop the listener propagation.
|
|
272
|
+
*
|
|
273
|
+
* @param {string|Array<string>} events
|
|
274
|
+
* @param {number} [priority=1000] the priority in which this listener is called, larger is higher
|
|
275
|
+
* @param {Function} callback
|
|
276
|
+
* @param {Object} [that] Pass context (`this`) to the callback
|
|
277
|
+
*/
|
|
278
|
+
|
|
279
|
+
EventBus.prototype.on = function (events, priority, callback, that) {
|
|
280
|
+
events = isArray(events) ? events : [events];
|
|
281
|
+
|
|
282
|
+
if (isFunction(priority)) {
|
|
283
|
+
that = callback;
|
|
284
|
+
callback = priority;
|
|
285
|
+
priority = DEFAULT_PRIORITY$1;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (!isNumber(priority)) {
|
|
289
|
+
throw new Error('priority must be a number');
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
var actualCallback = callback;
|
|
293
|
+
|
|
294
|
+
if (that) {
|
|
295
|
+
actualCallback = bind(callback, that); // make sure we remember and are able to remove
|
|
296
|
+
// bound callbacks via {@link #off} using the original
|
|
297
|
+
// callback
|
|
298
|
+
|
|
299
|
+
actualCallback[FN_REF] = callback[FN_REF] || callback;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
var self = this;
|
|
303
|
+
events.forEach(function (e) {
|
|
304
|
+
self._addListener(e, {
|
|
305
|
+
priority: priority,
|
|
306
|
+
callback: actualCallback,
|
|
307
|
+
next: null
|
|
308
|
+
});
|
|
309
|
+
});
|
|
310
|
+
};
|
|
311
|
+
/**
|
|
312
|
+
* Register an event listener that is executed only once.
|
|
313
|
+
*
|
|
314
|
+
* @param {string} event the event name to register for
|
|
315
|
+
* @param {number} [priority=1000] the priority in which this listener is called, larger is higher
|
|
316
|
+
* @param {Function} callback the callback to execute
|
|
317
|
+
* @param {Object} [that] Pass context (`this`) to the callback
|
|
318
|
+
*/
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
EventBus.prototype.once = function (event, priority, callback, that) {
|
|
322
|
+
var self = this;
|
|
323
|
+
|
|
324
|
+
if (isFunction(priority)) {
|
|
325
|
+
that = callback;
|
|
326
|
+
callback = priority;
|
|
327
|
+
priority = DEFAULT_PRIORITY$1;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (!isNumber(priority)) {
|
|
331
|
+
throw new Error('priority must be a number');
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
function wrappedCallback() {
|
|
335
|
+
wrappedCallback.__isTomb = true;
|
|
336
|
+
var result = callback.apply(that, arguments);
|
|
337
|
+
self.off(event, wrappedCallback);
|
|
338
|
+
return result;
|
|
339
|
+
} // make sure we remember and are able to remove
|
|
340
|
+
// bound callbacks via {@link #off} using the original
|
|
341
|
+
// callback
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
wrappedCallback[FN_REF] = callback;
|
|
345
|
+
this.on(event, priority, wrappedCallback);
|
|
346
|
+
};
|
|
347
|
+
/**
|
|
348
|
+
* Removes event listeners by event and callback.
|
|
349
|
+
*
|
|
350
|
+
* If no callback is given, all listeners for a given event name are being removed.
|
|
351
|
+
*
|
|
352
|
+
* @param {string|Array<string>} events
|
|
353
|
+
* @param {Function} [callback]
|
|
354
|
+
*/
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
EventBus.prototype.off = function (events, callback) {
|
|
358
|
+
events = isArray(events) ? events : [events];
|
|
359
|
+
var self = this;
|
|
360
|
+
events.forEach(function (event) {
|
|
361
|
+
self._removeListener(event, callback);
|
|
362
|
+
});
|
|
363
|
+
};
|
|
364
|
+
/**
|
|
365
|
+
* Create an EventBus event.
|
|
366
|
+
*
|
|
367
|
+
* @param {Object} data
|
|
368
|
+
*
|
|
369
|
+
* @return {Object} event, recognized by the eventBus
|
|
370
|
+
*/
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
EventBus.prototype.createEvent = function (data) {
|
|
374
|
+
var event = new InternalEvent();
|
|
375
|
+
event.init(data);
|
|
376
|
+
return event;
|
|
377
|
+
};
|
|
378
|
+
/**
|
|
379
|
+
* Fires a named event.
|
|
380
|
+
*
|
|
381
|
+
* @example
|
|
382
|
+
*
|
|
383
|
+
* // fire event by name
|
|
384
|
+
* events.fire('foo');
|
|
385
|
+
*
|
|
386
|
+
* // fire event object with nested type
|
|
387
|
+
* var event = { type: 'foo' };
|
|
388
|
+
* events.fire(event);
|
|
389
|
+
*
|
|
390
|
+
* // fire event with explicit type
|
|
391
|
+
* var event = { x: 10, y: 20 };
|
|
392
|
+
* events.fire('element.moved', event);
|
|
393
|
+
*
|
|
394
|
+
* // pass additional arguments to the event
|
|
395
|
+
* events.on('foo', function(event, bar) {
|
|
396
|
+
* alert(bar);
|
|
397
|
+
* });
|
|
398
|
+
*
|
|
399
|
+
* events.fire({ type: 'foo' }, 'I am bar!');
|
|
400
|
+
*
|
|
401
|
+
* @param {string} [name] the optional event name
|
|
402
|
+
* @param {Object} [event] the event object
|
|
403
|
+
* @param {...Object} additional arguments to be passed to the callback functions
|
|
404
|
+
*
|
|
405
|
+
* @return {boolean} the events return value, if specified or false if the
|
|
406
|
+
* default action was prevented by listeners
|
|
407
|
+
*/
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
EventBus.prototype.fire = function (type, data) {
|
|
411
|
+
var event, firstListener, returnValue, args;
|
|
412
|
+
args = slice.call(arguments);
|
|
413
|
+
|
|
414
|
+
if (typeof type === 'object') {
|
|
415
|
+
data = type;
|
|
416
|
+
type = data.type;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (!type) {
|
|
420
|
+
throw new Error('no event type specified');
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
firstListener = this._listeners[type];
|
|
424
|
+
|
|
425
|
+
if (!firstListener) {
|
|
426
|
+
return;
|
|
427
|
+
} // we make sure we fire instances of our home made
|
|
428
|
+
// events here. We wrap them only once, though
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
if (data instanceof InternalEvent) {
|
|
432
|
+
// we are fine, we alread have an event
|
|
433
|
+
event = data;
|
|
434
|
+
} else {
|
|
435
|
+
event = this.createEvent(data);
|
|
436
|
+
} // ensure we pass the event as the first parameter
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
args[0] = event; // original event type (in case we delegate)
|
|
440
|
+
|
|
441
|
+
var originalType = event.type; // update event type before delegation
|
|
442
|
+
|
|
443
|
+
if (type !== originalType) {
|
|
444
|
+
event.type = type;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
try {
|
|
448
|
+
returnValue = this._invokeListeners(event, args, firstListener);
|
|
449
|
+
} finally {
|
|
450
|
+
// reset event type after delegation
|
|
451
|
+
if (type !== originalType) {
|
|
452
|
+
event.type = originalType;
|
|
453
|
+
}
|
|
454
|
+
} // set the return value to false if the event default
|
|
455
|
+
// got prevented and no other return value exists
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
if (returnValue === undefined && event.defaultPrevented) {
|
|
459
|
+
returnValue = false;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
return returnValue;
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
EventBus.prototype.handleError = function (error) {
|
|
466
|
+
return this.fire('error', {
|
|
467
|
+
error: error
|
|
468
|
+
}) === false;
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
EventBus.prototype._destroy = function () {
|
|
472
|
+
this._listeners = {};
|
|
473
|
+
};
|
|
474
|
+
|
|
475
|
+
EventBus.prototype._invokeListeners = function (event, args, listener) {
|
|
476
|
+
var returnValue;
|
|
477
|
+
|
|
478
|
+
while (listener) {
|
|
479
|
+
// handle stopped propagation
|
|
480
|
+
if (event.cancelBubble) {
|
|
481
|
+
break;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
returnValue = this._invokeListener(event, args, listener);
|
|
485
|
+
listener = listener.next;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
return returnValue;
|
|
489
|
+
};
|
|
490
|
+
|
|
491
|
+
EventBus.prototype._invokeListener = function (event, args, listener) {
|
|
492
|
+
var returnValue;
|
|
493
|
+
|
|
494
|
+
if (listener.callback.__isTomb) {
|
|
495
|
+
return returnValue;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
try {
|
|
499
|
+
// returning false prevents the default action
|
|
500
|
+
returnValue = invokeFunction(listener.callback, args); // stop propagation on return value
|
|
501
|
+
|
|
502
|
+
if (returnValue !== undefined) {
|
|
503
|
+
event.returnValue = returnValue;
|
|
504
|
+
event.stopPropagation();
|
|
505
|
+
} // prevent default on return false
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
if (returnValue === false) {
|
|
509
|
+
event.preventDefault();
|
|
510
|
+
}
|
|
511
|
+
} catch (error) {
|
|
512
|
+
if (!this.handleError(error)) {
|
|
513
|
+
console.error('unhandled error in event listener', error);
|
|
514
|
+
throw error;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
return returnValue;
|
|
519
|
+
};
|
|
520
|
+
/*
|
|
521
|
+
* Add new listener with a certain priority to the list
|
|
522
|
+
* of listeners (for the given event).
|
|
523
|
+
*
|
|
524
|
+
* The semantics of listener registration / listener execution are
|
|
525
|
+
* first register, first serve: New listeners will always be inserted
|
|
526
|
+
* after existing listeners with the same priority.
|
|
527
|
+
*
|
|
528
|
+
* Example: Inserting two listeners with priority 1000 and 1300
|
|
529
|
+
*
|
|
530
|
+
* * before: [ 1500, 1500, 1000, 1000 ]
|
|
531
|
+
* * after: [ 1500, 1500, (new=1300), 1000, 1000, (new=1000) ]
|
|
532
|
+
*
|
|
533
|
+
* @param {string} event
|
|
534
|
+
* @param {Object} listener { priority, callback }
|
|
535
|
+
*/
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
EventBus.prototype._addListener = function (event, newListener) {
|
|
539
|
+
var listener = this._getListeners(event),
|
|
540
|
+
previousListener; // no prior listeners
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
if (!listener) {
|
|
544
|
+
this._setListeners(event, newListener);
|
|
545
|
+
|
|
546
|
+
return;
|
|
547
|
+
} // ensure we order listeners by priority from
|
|
548
|
+
// 0 (high) to n > 0 (low)
|
|
549
|
+
|
|
550
|
+
|
|
551
|
+
while (listener) {
|
|
552
|
+
if (listener.priority < newListener.priority) {
|
|
553
|
+
newListener.next = listener;
|
|
554
|
+
|
|
555
|
+
if (previousListener) {
|
|
556
|
+
previousListener.next = newListener;
|
|
557
|
+
} else {
|
|
558
|
+
this._setListeners(event, newListener);
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
previousListener = listener;
|
|
565
|
+
listener = listener.next;
|
|
566
|
+
} // add new listener to back
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
previousListener.next = newListener;
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
EventBus.prototype._getListeners = function (name) {
|
|
573
|
+
return this._listeners[name];
|
|
574
|
+
};
|
|
575
|
+
|
|
576
|
+
EventBus.prototype._setListeners = function (name, listener) {
|
|
577
|
+
this._listeners[name] = listener;
|
|
578
|
+
};
|
|
579
|
+
|
|
580
|
+
EventBus.prototype._removeListener = function (event, callback) {
|
|
581
|
+
var listener = this._getListeners(event),
|
|
582
|
+
nextListener,
|
|
583
|
+
previousListener,
|
|
584
|
+
listenerCallback;
|
|
585
|
+
|
|
586
|
+
if (!callback) {
|
|
587
|
+
// clear listeners
|
|
588
|
+
this._setListeners(event, null);
|
|
589
|
+
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
while (listener) {
|
|
594
|
+
nextListener = listener.next;
|
|
595
|
+
listenerCallback = listener.callback;
|
|
596
|
+
|
|
597
|
+
if (listenerCallback === callback || listenerCallback[FN_REF] === callback) {
|
|
598
|
+
if (previousListener) {
|
|
599
|
+
previousListener.next = nextListener;
|
|
600
|
+
} else {
|
|
601
|
+
// new first listener
|
|
602
|
+
this._setListeners(event, nextListener);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
previousListener = listener;
|
|
607
|
+
listener = nextListener;
|
|
608
|
+
}
|
|
609
|
+
};
|
|
610
|
+
/**
|
|
611
|
+
* A event that is emitted via the event bus.
|
|
612
|
+
*/
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
function InternalEvent() {}
|
|
616
|
+
|
|
617
|
+
InternalEvent.prototype.stopPropagation = function () {
|
|
618
|
+
this.cancelBubble = true;
|
|
619
|
+
};
|
|
620
|
+
|
|
621
|
+
InternalEvent.prototype.preventDefault = function () {
|
|
622
|
+
this.defaultPrevented = true;
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
InternalEvent.prototype.init = function (data) {
|
|
626
|
+
assign(this, data || {});
|
|
627
|
+
};
|
|
628
|
+
/**
|
|
629
|
+
* Invoke function. Be fast...
|
|
630
|
+
*
|
|
631
|
+
* @param {Function} fn
|
|
632
|
+
* @param {Array<Object>} args
|
|
633
|
+
*
|
|
634
|
+
* @return {Any}
|
|
635
|
+
*/
|
|
636
|
+
|
|
637
|
+
|
|
638
|
+
function invokeFunction(fn, args) {
|
|
639
|
+
return fn.apply(null, args);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* @typedef {Function} <propertiesPanel.showEntry> callback
|
|
644
|
+
*
|
|
645
|
+
* @example
|
|
646
|
+
*
|
|
647
|
+
* useEvent('propertiesPanel.showEntry', ({ focus = false, ...rest }) => {
|
|
648
|
+
* // ...
|
|
649
|
+
* });
|
|
650
|
+
*
|
|
651
|
+
* @param {Object} context
|
|
652
|
+
* @param {boolean} [context.focus]
|
|
653
|
+
*
|
|
654
|
+
* @returns void
|
|
655
|
+
*/
|
|
656
|
+
const eventBus = new EventBus();
|
|
657
|
+
const EventContext = createContext({
|
|
658
|
+
eventBus
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
const LayoutContext = createContext({
|
|
662
|
+
layout: {},
|
|
663
|
+
setLayout: () => {},
|
|
664
|
+
getLayoutForKey: () => {},
|
|
665
|
+
setLayoutForKey: () => {}
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* Accesses the global DescriptionContext and returns a description for a given id and element.
|
|
670
|
+
*
|
|
671
|
+
* @example
|
|
672
|
+
* ```jsx
|
|
673
|
+
* function TextField(props) {
|
|
674
|
+
* const description = useDescriptionContext('input1', element);
|
|
675
|
+
* }
|
|
676
|
+
* ```
|
|
677
|
+
*
|
|
678
|
+
* @param {string} id
|
|
679
|
+
* @param {djs.model.Base} element
|
|
680
|
+
*
|
|
681
|
+
* @returns {string}
|
|
682
|
+
*/
|
|
683
|
+
|
|
684
|
+
function useDescriptionContext(id, element) {
|
|
685
|
+
const {
|
|
686
|
+
getDescriptionForId
|
|
687
|
+
} = useContext(DescriptionContext);
|
|
688
|
+
return getDescriptionForId(id, element);
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
const DEFAULT_PRIORITY = 1000;
|
|
692
|
+
/**
|
|
693
|
+
* Subscribe to an event.
|
|
694
|
+
*
|
|
695
|
+
* @param {string} event
|
|
696
|
+
* @param {Function} callback
|
|
697
|
+
* @param {number} [priority]
|
|
698
|
+
*
|
|
699
|
+
* @returns {import('preact').Ref}
|
|
700
|
+
*/
|
|
701
|
+
|
|
702
|
+
function useEvent(event, callback, priority = DEFAULT_PRIORITY) {
|
|
703
|
+
const {
|
|
704
|
+
eventBus
|
|
705
|
+
} = useContext(EventContext);
|
|
706
|
+
useEffect(() => {
|
|
707
|
+
eventBus.on(event, priority, callback);
|
|
708
|
+
return () => eventBus.off(event, callback);
|
|
709
|
+
}, [event, eventBus, callback, priority]);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
const HIGH_PRIORITY = 10000;
|
|
55
713
|
/**
|
|
56
|
-
*
|
|
57
|
-
* state on updates.
|
|
714
|
+
* Buffer events and re-fire during passive effect phase.
|
|
58
715
|
*
|
|
59
|
-
*
|
|
716
|
+
* @param {string[]} bufferedEvents
|
|
717
|
+
* @param {Object} [eventBus]
|
|
60
718
|
*/
|
|
61
719
|
|
|
62
|
-
function
|
|
63
|
-
const
|
|
720
|
+
function useEventBuffer(bufferedEvents, eventBus) {
|
|
721
|
+
const buffer = useRef([]),
|
|
722
|
+
buffering = useRef(true);
|
|
723
|
+
|
|
724
|
+
const createCallback = event => data => {
|
|
725
|
+
if (buffering.current === true) {
|
|
726
|
+
buffer.current.unshift([event, data]);
|
|
727
|
+
}
|
|
728
|
+
}; // (1) buffer events
|
|
729
|
+
|
|
730
|
+
|
|
64
731
|
useEffect(() => {
|
|
65
|
-
|
|
732
|
+
if (!eventBus) {
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
const listeners = bufferedEvents.map(event => {
|
|
737
|
+
return [event, createCallback(event)];
|
|
738
|
+
});
|
|
739
|
+
listeners.forEach(([event, callback]) => {
|
|
740
|
+
eventBus.on(event, HIGH_PRIORITY, callback);
|
|
741
|
+
});
|
|
742
|
+
return () => {
|
|
743
|
+
listeners.forEach(([event, callback]) => {
|
|
744
|
+
eventBus.off(event, callback);
|
|
745
|
+
});
|
|
746
|
+
};
|
|
747
|
+
}, [bufferedEvents, eventBus]); // (2) re-fire events
|
|
748
|
+
|
|
749
|
+
useEffect(() => {
|
|
750
|
+
if (!eventBus) {
|
|
751
|
+
return;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
buffering.current = false;
|
|
755
|
+
|
|
756
|
+
while (buffer.current.length) {
|
|
757
|
+
const [event, data] = buffer.current.pop();
|
|
758
|
+
eventBus.fire(event, data);
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
buffering.current = true;
|
|
66
762
|
});
|
|
67
|
-
return ref.current;
|
|
68
763
|
}
|
|
69
764
|
|
|
70
765
|
const KEY_LENGTH = 6;
|
|
@@ -105,18 +800,6 @@ function useKeyFactory(dependencies = []) {
|
|
|
105
800
|
return getKey;
|
|
106
801
|
}
|
|
107
802
|
|
|
108
|
-
const DescriptionContext = createContext({
|
|
109
|
-
description: {},
|
|
110
|
-
getDescriptionForId: () => {}
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
const LayoutContext = createContext({
|
|
114
|
-
layout: {},
|
|
115
|
-
setLayout: () => {},
|
|
116
|
-
getLayoutForKey: () => {},
|
|
117
|
-
setLayoutForKey: () => {}
|
|
118
|
-
});
|
|
119
|
-
|
|
120
803
|
/**
|
|
121
804
|
* Creates a state that persists in the global LayoutContext.
|
|
122
805
|
*
|
|
@@ -152,124 +835,101 @@ function useLayoutState(path, defaultValue) {
|
|
|
152
835
|
}
|
|
153
836
|
|
|
154
837
|
/**
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
* @example
|
|
158
|
-
* ```jsx
|
|
159
|
-
* function TextField(props) {
|
|
160
|
-
* const description = useDescriptionContext('input1', element);
|
|
161
|
-
* }
|
|
162
|
-
* ```
|
|
163
|
-
*
|
|
164
|
-
* @param {string} id
|
|
165
|
-
* @param {djs.model.Base} element
|
|
838
|
+
* @pinussilvestrus: we need to introduce our own hook to persist the previous
|
|
839
|
+
* state on updates.
|
|
166
840
|
*
|
|
167
|
-
*
|
|
841
|
+
* cf. https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
|
|
168
842
|
*/
|
|
169
843
|
|
|
170
|
-
function
|
|
171
|
-
const
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
return getDescriptionForId(id, element);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
var ArrowIcon = function ArrowIcon(props) {
|
|
178
|
-
return jsx("svg", { ...props,
|
|
179
|
-
children: jsx("path", {
|
|
180
|
-
fillRule: "evenodd",
|
|
181
|
-
d: "m11.657 8-4.95 4.95a1 1 0 0 1-1.414-1.414L8.828 8 5.293 4.464A1 1 0 1 1 6.707 3.05L11.657 8z"
|
|
182
|
-
})
|
|
183
|
-
});
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
ArrowIcon.defaultProps = {
|
|
187
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
188
|
-
width: "16",
|
|
189
|
-
height: "16"
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
var CreateIcon = function CreateIcon(props) {
|
|
193
|
-
return jsx("svg", { ...props,
|
|
194
|
-
children: jsx("path", {
|
|
195
|
-
fillRule: "evenodd",
|
|
196
|
-
d: "M9 13V9h4a1 1 0 0 0 0-2H9V3a1 1 0 1 0-2 0v4H3a1 1 0 1 0 0 2h4v4a1 1 0 0 0 2 0z"
|
|
197
|
-
})
|
|
844
|
+
function usePrevious(value) {
|
|
845
|
+
const ref = useRef();
|
|
846
|
+
useEffect(() => {
|
|
847
|
+
ref.current = value;
|
|
198
848
|
});
|
|
199
|
-
|
|
849
|
+
return ref.current;
|
|
850
|
+
}
|
|
200
851
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
852
|
+
/**
|
|
853
|
+
* Subscribe to `propertiesPanel.showEntry`.
|
|
854
|
+
*
|
|
855
|
+
* @param {Function} show
|
|
856
|
+
*
|
|
857
|
+
* @returns {import('preact').Ref}
|
|
858
|
+
*/
|
|
206
859
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
860
|
+
function useShowEntryEvent(show) {
|
|
861
|
+
const {
|
|
862
|
+
onShow
|
|
863
|
+
} = useContext(LayoutContext);
|
|
864
|
+
const ref = useRef();
|
|
865
|
+
const [focus, setFocus] = useState(false);
|
|
866
|
+
const onShowEntry = useCallback(event => {
|
|
867
|
+
if (show(event)) {
|
|
868
|
+
if (isFunction(onShow)) {
|
|
869
|
+
onShow();
|
|
870
|
+
}
|
|
215
871
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
};
|
|
872
|
+
if (event.focus && !focus) {
|
|
873
|
+
setFocus(true);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
}, [show]);
|
|
877
|
+
useEffect(() => {
|
|
878
|
+
if (focus && ref.current) {
|
|
879
|
+
if (isFunction(ref.current.focus)) {
|
|
880
|
+
ref.current.focus();
|
|
881
|
+
}
|
|
221
882
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
d: "M5.8 7.06V5.95h4.307v1.11H5.8zm0 3.071v-1.11h4.307v1.11H5.8z",
|
|
226
|
-
fill: "#505562"
|
|
227
|
-
}), jsx("path", {
|
|
228
|
-
fillRule: "evenodd",
|
|
229
|
-
clipRule: "evenodd",
|
|
230
|
-
d: "M8 3.268A4.732 4.732 0 1 0 12.732 8H14a6 6 0 1 1-6-6v1.268z",
|
|
231
|
-
fill: "#505562"
|
|
232
|
-
}), jsx("path", {
|
|
233
|
-
d: "m11.28 6.072-.832-.56 1.016-1.224L10 3.848l.312-.912 1.392.584L11.632 2h1.032l-.072 1.52 1.392-.584.312.912-1.464.44 1.008 1.224-.832.552-.864-1.296-.864 1.304z",
|
|
234
|
-
fill: "#505562"
|
|
235
|
-
})]
|
|
236
|
-
});
|
|
237
|
-
};
|
|
883
|
+
if (isFunction(ref.current.select)) {
|
|
884
|
+
ref.current.select();
|
|
885
|
+
}
|
|
238
886
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
887
|
+
setFocus(false);
|
|
888
|
+
}
|
|
889
|
+
}, [focus]);
|
|
890
|
+
useEvent('propertiesPanel.showEntry', onShowEntry);
|
|
891
|
+
return ref;
|
|
892
|
+
}
|
|
244
893
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
fill: "#505562"
|
|
255
|
-
})]
|
|
256
|
-
});
|
|
257
|
-
};
|
|
894
|
+
/**
|
|
895
|
+
* Subscribe to `propertiesPanel.showError`. On `propertiesPanel.showError` set
|
|
896
|
+
* temporary error. Fire `propertiesPanel.showEntry` for temporary error to be
|
|
897
|
+
* visible. Unset error on `propertiesPanel.updated`.
|
|
898
|
+
*
|
|
899
|
+
* @param {Function} show
|
|
900
|
+
*
|
|
901
|
+
* @returns {import('preact').Ref}
|
|
902
|
+
*/
|
|
258
903
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
904
|
+
function useShowErrorEvent(show) {
|
|
905
|
+
const {
|
|
906
|
+
eventBus
|
|
907
|
+
} = useContext(EventContext);
|
|
908
|
+
const [temporaryError, setTemporaryError] = useState(null);
|
|
909
|
+
const onPropertiesPanelUpdated = useCallback(() => setTemporaryError(null), []);
|
|
910
|
+
useEvent('propertiesPanel.updated', onPropertiesPanelUpdated);
|
|
911
|
+
const onShowError = useCallback(event => {
|
|
912
|
+
setTemporaryError(null);
|
|
913
|
+
|
|
914
|
+
if (show(event)) {
|
|
915
|
+
eventBus.fire('propertiesPanel.showEntry', event);
|
|
916
|
+
setTemporaryError(event.message);
|
|
917
|
+
}
|
|
918
|
+
}, [show]);
|
|
919
|
+
useEvent('propertiesPanel.showError', onShowError);
|
|
920
|
+
return temporaryError;
|
|
921
|
+
}
|
|
264
922
|
|
|
265
923
|
function Group(props) {
|
|
266
924
|
const {
|
|
267
925
|
element,
|
|
268
926
|
entries = [],
|
|
269
927
|
id,
|
|
270
|
-
label
|
|
928
|
+
label,
|
|
929
|
+
shouldOpen = false
|
|
271
930
|
} = props;
|
|
272
|
-
const [open, setOpen] = useLayoutState(['groups', id, 'open'],
|
|
931
|
+
const [open, setOpen] = useLayoutState(['groups', id, 'open'], shouldOpen);
|
|
932
|
+
const onShow = useCallback(() => setOpen(true), [setOpen]);
|
|
273
933
|
|
|
274
934
|
const toggleOpen = () => setOpen(!open);
|
|
275
935
|
|
|
@@ -292,6 +952,9 @@ function Group(props) {
|
|
|
292
952
|
});
|
|
293
953
|
setEdited(hasOneEditedEntry);
|
|
294
954
|
}, [entries]);
|
|
955
|
+
const propertiesPanelContext = { ...useContext(LayoutContext),
|
|
956
|
+
onShow
|
|
957
|
+
};
|
|
295
958
|
return jsxs("div", {
|
|
296
959
|
class: "bio-properties-panel-group",
|
|
297
960
|
"data-group-id": 'group-' + id,
|
|
@@ -314,15 +977,18 @@ function Group(props) {
|
|
|
314
977
|
})]
|
|
315
978
|
}), jsx("div", {
|
|
316
979
|
class: classnames('bio-properties-panel-group-entries', open ? 'open' : ''),
|
|
317
|
-
children:
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
980
|
+
children: jsx(LayoutContext.Provider, {
|
|
981
|
+
value: propertiesPanelContext,
|
|
982
|
+
children: entries.map(entry => {
|
|
983
|
+
const {
|
|
984
|
+
component: Component,
|
|
985
|
+
id
|
|
986
|
+
} = entry;
|
|
987
|
+
return createElement(Component, { ...entry,
|
|
988
|
+
element: element,
|
|
989
|
+
key: id
|
|
990
|
+
});
|
|
991
|
+
})
|
|
326
992
|
})
|
|
327
993
|
})]
|
|
328
994
|
});
|
|
@@ -339,6 +1005,7 @@ const DEFAULT_LAYOUT = {
|
|
|
339
1005
|
open: true
|
|
340
1006
|
};
|
|
341
1007
|
const DEFAULT_DESCRIPTION = {};
|
|
1008
|
+
const bufferedEvents = ['propertiesPanel.showEntry', 'propertiesPanel.showError'];
|
|
342
1009
|
/**
|
|
343
1010
|
* @typedef { {
|
|
344
1011
|
* component: import('preact').Component,
|
|
@@ -370,7 +1037,8 @@ const DEFAULT_DESCRIPTION = {};
|
|
|
370
1037
|
* component?: import('preact').Component,
|
|
371
1038
|
* entries: Array<EntryDefinition>,
|
|
372
1039
|
* id: String,
|
|
373
|
-
* label: String
|
|
1040
|
+
* label: String,
|
|
1041
|
+
* shouldOpen?: Boolean
|
|
374
1042
|
* } } GroupDefinition
|
|
375
1043
|
*
|
|
376
1044
|
* @typedef { {
|
|
@@ -407,7 +1075,8 @@ function PropertiesPanel(props) {
|
|
|
407
1075
|
layoutConfig = {},
|
|
408
1076
|
layoutChanged,
|
|
409
1077
|
descriptionConfig = {},
|
|
410
|
-
descriptionLoaded
|
|
1078
|
+
descriptionLoaded,
|
|
1079
|
+
eventBus
|
|
411
1080
|
} = props; // set-up layout context
|
|
412
1081
|
|
|
413
1082
|
const [layout, setLayout] = useState(createLayout(layoutConfig));
|
|
@@ -448,6 +1117,13 @@ function PropertiesPanel(props) {
|
|
|
448
1117
|
description,
|
|
449
1118
|
getDescriptionForId
|
|
450
1119
|
};
|
|
1120
|
+
useEventBuffer(bufferedEvents, eventBus);
|
|
1121
|
+
const eventContext = {
|
|
1122
|
+
eventBus
|
|
1123
|
+
};
|
|
1124
|
+
const propertiesPanelContext = {
|
|
1125
|
+
element
|
|
1126
|
+
};
|
|
451
1127
|
|
|
452
1128
|
if (!element) {
|
|
453
1129
|
return jsx("div", {
|
|
@@ -456,28 +1132,34 @@ function PropertiesPanel(props) {
|
|
|
456
1132
|
});
|
|
457
1133
|
}
|
|
458
1134
|
|
|
459
|
-
return jsx(
|
|
460
|
-
value:
|
|
461
|
-
children: jsx(
|
|
462
|
-
value:
|
|
463
|
-
children:
|
|
464
|
-
|
|
465
|
-
children:
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
1135
|
+
return jsx(LayoutContext.Provider, {
|
|
1136
|
+
value: propertiesPanelContext,
|
|
1137
|
+
children: jsx(DescriptionContext.Provider, {
|
|
1138
|
+
value: descriptionContext,
|
|
1139
|
+
children: jsx(LayoutContext.Provider, {
|
|
1140
|
+
value: layoutContext,
|
|
1141
|
+
children: jsx(EventContext.Provider, {
|
|
1142
|
+
value: eventContext,
|
|
1143
|
+
children: jsxs("div", {
|
|
1144
|
+
class: classnames('bio-properties-panel', layout.open ? 'open' : ''),
|
|
1145
|
+
children: [jsx(Header, {
|
|
1146
|
+
element: element,
|
|
1147
|
+
headerProvider: headerProvider
|
|
1148
|
+
}), jsx("div", {
|
|
1149
|
+
class: "bio-properties-panel-scroll-container",
|
|
1150
|
+
children: groups.map(group => {
|
|
1151
|
+
const {
|
|
1152
|
+
component: Component = Group,
|
|
1153
|
+
id
|
|
1154
|
+
} = group;
|
|
1155
|
+
return createElement(Component, { ...group,
|
|
1156
|
+
key: id,
|
|
1157
|
+
element: element
|
|
1158
|
+
});
|
|
1159
|
+
})
|
|
1160
|
+
})]
|
|
479
1161
|
})
|
|
480
|
-
})
|
|
1162
|
+
})
|
|
481
1163
|
})
|
|
482
1164
|
})
|
|
483
1165
|
});
|
|
@@ -617,8 +1299,20 @@ function CollapsibleEntry(props) {
|
|
|
617
1299
|
} = props;
|
|
618
1300
|
const [open, setOpen] = useState(shouldOpen);
|
|
619
1301
|
|
|
620
|
-
const toggleOpen = () => setOpen(!open);
|
|
1302
|
+
const toggleOpen = () => setOpen(!open);
|
|
1303
|
+
|
|
1304
|
+
const {
|
|
1305
|
+
onShow
|
|
1306
|
+
} = useContext(LayoutContext);
|
|
1307
|
+
const propertiesPanelContext = { ...useContext(LayoutContext),
|
|
1308
|
+
onShow: useCallback(() => {
|
|
1309
|
+
setOpen(true);
|
|
621
1310
|
|
|
1311
|
+
if (isFunction(onShow)) {
|
|
1312
|
+
onShow();
|
|
1313
|
+
}
|
|
1314
|
+
}, [onShow, setOpen])
|
|
1315
|
+
}; // todo(pinussilvestrus): translate once we have a translate mechanism for the core
|
|
622
1316
|
|
|
623
1317
|
const placeholderLabel = '<empty>';
|
|
624
1318
|
return jsxs("div", {
|
|
@@ -645,15 +1339,18 @@ function CollapsibleEntry(props) {
|
|
|
645
1339
|
}) : null]
|
|
646
1340
|
}), jsx("div", {
|
|
647
1341
|
class: classnames('bio-properties-panel-collapsible-entry-entries', open ? 'open' : ''),
|
|
648
|
-
children:
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
1342
|
+
children: jsx(LayoutContext.Provider, {
|
|
1343
|
+
value: propertiesPanelContext,
|
|
1344
|
+
children: entries.map(entry => {
|
|
1345
|
+
const {
|
|
1346
|
+
component: Component,
|
|
1347
|
+
id
|
|
1348
|
+
} = entry;
|
|
1349
|
+
return createElement(Component, { ...entry,
|
|
1350
|
+
element: element,
|
|
1351
|
+
key: id
|
|
1352
|
+
});
|
|
1353
|
+
})
|
|
657
1354
|
})
|
|
658
1355
|
})]
|
|
659
1356
|
});
|
|
@@ -687,7 +1384,7 @@ function ListItem(props) {
|
|
|
687
1384
|
});
|
|
688
1385
|
}
|
|
689
1386
|
|
|
690
|
-
const noop = () => {};
|
|
1387
|
+
const noop$3 = () => {};
|
|
691
1388
|
/**
|
|
692
1389
|
* @param {import('../PropertiesPanel').ListGroupDefinition} props
|
|
693
1390
|
*/
|
|
@@ -704,6 +1401,7 @@ function ListGroup(props) {
|
|
|
704
1401
|
shouldSort = true
|
|
705
1402
|
} = props;
|
|
706
1403
|
const [open, setOpen] = useLayoutState(['groups', id, 'open'], false);
|
|
1404
|
+
const onShow = useCallback(() => setOpen(true), [setOpen]);
|
|
707
1405
|
const [ordering, setOrdering] = useState([]);
|
|
708
1406
|
const [newItemAdded, setNewItemAdded] = useState(false);
|
|
709
1407
|
const prevItems = usePrevious(items);
|
|
@@ -778,12 +1476,15 @@ function ListGroup(props) {
|
|
|
778
1476
|
const toggleOpen = () => setOpen(!open);
|
|
779
1477
|
|
|
780
1478
|
const hasItems = !!items.length;
|
|
1479
|
+
const propertiesPanelContext = { ...useContext(LayoutContext),
|
|
1480
|
+
onShow
|
|
1481
|
+
};
|
|
781
1482
|
return jsxs("div", {
|
|
782
1483
|
class: "bio-properties-panel-group",
|
|
783
1484
|
"data-group-id": 'group-' + id,
|
|
784
1485
|
children: [jsxs("div", {
|
|
785
1486
|
class: classnames('bio-properties-panel-group-header', hasItems ? '' : 'empty', hasItems && open ? 'open' : ''),
|
|
786
|
-
onClick: hasItems ? toggleOpen : noop,
|
|
1487
|
+
onClick: hasItems ? toggleOpen : noop$3,
|
|
787
1488
|
children: [jsx("div", {
|
|
788
1489
|
title: label,
|
|
789
1490
|
class: "bio-properties-panel-group-header-title",
|
|
@@ -812,23 +1513,27 @@ function ListGroup(props) {
|
|
|
812
1513
|
})]
|
|
813
1514
|
}), jsx("div", {
|
|
814
1515
|
class: classnames('bio-properties-panel-list', open && hasItems ? 'open' : ''),
|
|
815
|
-
children:
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
,
|
|
830
|
-
|
|
831
|
-
|
|
1516
|
+
children: jsx(LayoutContext.Provider, {
|
|
1517
|
+
value: propertiesPanelContext,
|
|
1518
|
+
children: ordering.map((o, index) => {
|
|
1519
|
+
const item = getItem(items, o);
|
|
1520
|
+
|
|
1521
|
+
if (!item) {
|
|
1522
|
+
return;
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
const {
|
|
1526
|
+
id
|
|
1527
|
+
} = item; // if item was added, open first or last item based on ordering
|
|
1528
|
+
|
|
1529
|
+
const autoOpen = newItemAdded && (shouldSort ? index === 0 : index === ordering.length - 1);
|
|
1530
|
+
return createElement(ListItem, { ...item,
|
|
1531
|
+
autoOpen: autoOpen,
|
|
1532
|
+
element: element,
|
|
1533
|
+
index: index,
|
|
1534
|
+
key: id
|
|
1535
|
+
});
|
|
1536
|
+
})
|
|
832
1537
|
})
|
|
833
1538
|
})]
|
|
834
1539
|
});
|
|
@@ -867,13 +1572,16 @@ function Description(props) {
|
|
|
867
1572
|
}
|
|
868
1573
|
}
|
|
869
1574
|
|
|
1575
|
+
const noop$2 = () => {};
|
|
1576
|
+
|
|
870
1577
|
function Checkbox(props) {
|
|
871
1578
|
const {
|
|
872
1579
|
id,
|
|
873
1580
|
label,
|
|
874
1581
|
onChange,
|
|
875
1582
|
disabled,
|
|
876
|
-
value = false
|
|
1583
|
+
value = false,
|
|
1584
|
+
show = noop$2
|
|
877
1585
|
} = props;
|
|
878
1586
|
|
|
879
1587
|
const handleChange = ({
|
|
@@ -882,9 +1590,11 @@ function Checkbox(props) {
|
|
|
882
1590
|
onChange(target.checked);
|
|
883
1591
|
};
|
|
884
1592
|
|
|
1593
|
+
const ref = useShowEntryEvent(show);
|
|
885
1594
|
return jsxs("div", {
|
|
886
1595
|
class: "bio-properties-panel-checkbox",
|
|
887
1596
|
children: [jsx("input", {
|
|
1597
|
+
ref: ref,
|
|
888
1598
|
id: prefixId$6(id),
|
|
889
1599
|
name: id,
|
|
890
1600
|
type: "checkbox",
|
|
@@ -919,18 +1629,24 @@ function CheckboxEntry(props) {
|
|
|
919
1629
|
label,
|
|
920
1630
|
getValue,
|
|
921
1631
|
setValue,
|
|
922
|
-
disabled
|
|
1632
|
+
disabled,
|
|
1633
|
+
show = noop$2
|
|
923
1634
|
} = props;
|
|
924
1635
|
const value = getValue(element);
|
|
1636
|
+
const error = useShowErrorEvent(show);
|
|
925
1637
|
return jsxs("div", {
|
|
926
1638
|
class: "bio-properties-panel-entry bio-properties-panel-checkbox-entry",
|
|
927
1639
|
"data-entry-id": id,
|
|
928
1640
|
children: [jsx(Checkbox, {
|
|
1641
|
+
disabled: disabled,
|
|
929
1642
|
id: id,
|
|
930
1643
|
label: label,
|
|
931
1644
|
onChange: setValue,
|
|
932
|
-
|
|
933
|
-
|
|
1645
|
+
show: show,
|
|
1646
|
+
value: value
|
|
1647
|
+
}), error && jsx("div", {
|
|
1648
|
+
class: "bio-properties-panel-error",
|
|
1649
|
+
children: error
|
|
934
1650
|
}), jsx(Description, {
|
|
935
1651
|
forId: id,
|
|
936
1652
|
element: element,
|
|
@@ -1237,6 +1953,25 @@ function prefixId$5(id) {
|
|
|
1237
1953
|
return `bio-properties-panel-${id}`;
|
|
1238
1954
|
}
|
|
1239
1955
|
|
|
1956
|
+
const noop$1 = () => {};
|
|
1957
|
+
/**
|
|
1958
|
+
* @typedef { { value: string, label: string, disabled: boolean } } Option
|
|
1959
|
+
*/
|
|
1960
|
+
|
|
1961
|
+
/**
|
|
1962
|
+
* Provides basic select input.
|
|
1963
|
+
*
|
|
1964
|
+
* @param {object} props
|
|
1965
|
+
* @param {string} props.id
|
|
1966
|
+
* @param {string[]} props.path
|
|
1967
|
+
* @param {string} props.label
|
|
1968
|
+
* @param {Function} props.onChange
|
|
1969
|
+
* @param {Array<Option>} [props.options]
|
|
1970
|
+
* @param {string} props.value
|
|
1971
|
+
* @param {boolean} [props.disabled]
|
|
1972
|
+
*/
|
|
1973
|
+
|
|
1974
|
+
|
|
1240
1975
|
function Select(props) {
|
|
1241
1976
|
const {
|
|
1242
1977
|
id,
|
|
@@ -1244,8 +1979,10 @@ function Select(props) {
|
|
|
1244
1979
|
onChange,
|
|
1245
1980
|
options = [],
|
|
1246
1981
|
value,
|
|
1247
|
-
disabled
|
|
1982
|
+
disabled,
|
|
1983
|
+
show = noop$1
|
|
1248
1984
|
} = props;
|
|
1985
|
+
const ref = useShowEntryEvent(show);
|
|
1249
1986
|
|
|
1250
1987
|
const handleChange = ({
|
|
1251
1988
|
target
|
|
@@ -1260,6 +1997,7 @@ function Select(props) {
|
|
|
1260
1997
|
class: "bio-properties-panel-label",
|
|
1261
1998
|
children: label
|
|
1262
1999
|
}), jsx("select", {
|
|
2000
|
+
ref: ref,
|
|
1263
2001
|
id: prefixId$4(id),
|
|
1264
2002
|
name: id,
|
|
1265
2003
|
class: "bio-properties-panel-input",
|
|
@@ -1298,12 +2036,14 @@ function SelectEntry(props) {
|
|
|
1298
2036
|
getValue,
|
|
1299
2037
|
setValue,
|
|
1300
2038
|
getOptions,
|
|
1301
|
-
disabled
|
|
2039
|
+
disabled,
|
|
2040
|
+
show = noop$1
|
|
1302
2041
|
} = props;
|
|
1303
2042
|
const value = getValue(element);
|
|
1304
2043
|
const options = getOptions(element);
|
|
2044
|
+
const error = useShowErrorEvent(show);
|
|
1305
2045
|
return jsxs("div", {
|
|
1306
|
-
class:
|
|
2046
|
+
class: classnames('bio-properties-panel-entry', error ? 'has-error' : ''),
|
|
1307
2047
|
"data-entry-id": id,
|
|
1308
2048
|
children: [jsx(Select, {
|
|
1309
2049
|
id: id,
|
|
@@ -1311,7 +2051,11 @@ function SelectEntry(props) {
|
|
|
1311
2051
|
value: value,
|
|
1312
2052
|
onChange: setValue,
|
|
1313
2053
|
options: options,
|
|
1314
|
-
disabled: disabled
|
|
2054
|
+
disabled: disabled,
|
|
2055
|
+
show: show
|
|
2056
|
+
}), error && jsx("div", {
|
|
2057
|
+
class: "bio-properties-panel-error",
|
|
2058
|
+
children: error
|
|
1315
2059
|
}), jsx(Description, {
|
|
1316
2060
|
forId: id,
|
|
1317
2061
|
element: element,
|
|
@@ -1482,6 +2226,8 @@ function prefixId$2(id) {
|
|
|
1482
2226
|
return `bio-properties-panel-${id}`;
|
|
1483
2227
|
}
|
|
1484
2228
|
|
|
2229
|
+
const noop = () => {};
|
|
2230
|
+
|
|
1485
2231
|
function Textfield(props) {
|
|
1486
2232
|
const {
|
|
1487
2233
|
debounce,
|
|
@@ -1490,8 +2236,10 @@ function Textfield(props) {
|
|
|
1490
2236
|
label,
|
|
1491
2237
|
onInput,
|
|
1492
2238
|
feel = false,
|
|
1493
|
-
value = ''
|
|
2239
|
+
value = '',
|
|
2240
|
+
show = noop
|
|
1494
2241
|
} = props;
|
|
2242
|
+
const ref = useShowEntryEvent(show);
|
|
1495
2243
|
const handleInput = useMemo(() => {
|
|
1496
2244
|
return debounce(({
|
|
1497
2245
|
target
|
|
@@ -1507,6 +2255,7 @@ function Textfield(props) {
|
|
|
1507
2255
|
label: label
|
|
1508
2256
|
})]
|
|
1509
2257
|
}), jsx("input", {
|
|
2258
|
+
ref: ref,
|
|
1510
2259
|
id: prefixId$1(id),
|
|
1511
2260
|
type: "text",
|
|
1512
2261
|
name: id,
|
|
@@ -1546,53 +2295,61 @@ function TextfieldEntry(props) {
|
|
|
1546
2295
|
label,
|
|
1547
2296
|
getValue,
|
|
1548
2297
|
setValue,
|
|
1549
|
-
validate
|
|
2298
|
+
validate,
|
|
2299
|
+
show = noop
|
|
1550
2300
|
} = props;
|
|
1551
|
-
const [
|
|
1552
|
-
const [
|
|
2301
|
+
const [cachedInvalidValue, setCachedInvalidValue] = useState(null);
|
|
2302
|
+
const [validationError, setValidationError] = useState(null);
|
|
1553
2303
|
let value = getValue(element);
|
|
1554
|
-
const
|
|
1555
|
-
|
|
2304
|
+
const previousValue = usePrevious(value);
|
|
1556
2305
|
useEffect(() => {
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
2306
|
+
if (isFunction(validate)) {
|
|
2307
|
+
const newValidationError = validate(value) || null;
|
|
2308
|
+
setValidationError(newValidationError);
|
|
2309
|
+
}
|
|
2310
|
+
}, [value]);
|
|
1560
2311
|
|
|
1561
|
-
const
|
|
1562
|
-
|
|
2312
|
+
const onInput = newValue => {
|
|
2313
|
+
let newValidationError = null;
|
|
2314
|
+
|
|
2315
|
+
if (isFunction(validate)) {
|
|
2316
|
+
newValidationError = validate(newValue) || null;
|
|
2317
|
+
}
|
|
1563
2318
|
|
|
1564
|
-
if (
|
|
1565
|
-
|
|
2319
|
+
if (newValidationError) {
|
|
2320
|
+
setCachedInvalidValue(newValue);
|
|
1566
2321
|
} else {
|
|
1567
2322
|
setValue(newValue);
|
|
1568
2323
|
}
|
|
1569
2324
|
|
|
1570
|
-
|
|
1571
|
-
};
|
|
1572
|
-
|
|
2325
|
+
setValidationError(newValidationError);
|
|
2326
|
+
};
|
|
1573
2327
|
|
|
1574
|
-
if (
|
|
1575
|
-
value =
|
|
2328
|
+
if (previousValue === value && validationError) {
|
|
2329
|
+
value = cachedInvalidValue;
|
|
1576
2330
|
}
|
|
1577
2331
|
|
|
2332
|
+
const temporaryError = useShowErrorEvent(show);
|
|
2333
|
+
const error = temporaryError || validationError;
|
|
1578
2334
|
return jsxs("div", {
|
|
1579
2335
|
class: classnames('bio-properties-panel-entry', error ? 'has-error' : ''),
|
|
1580
2336
|
"data-entry-id": id,
|
|
1581
2337
|
children: [jsx(Textfield, {
|
|
1582
|
-
id: id,
|
|
1583
|
-
label: label,
|
|
1584
|
-
value: value,
|
|
1585
|
-
onInput: handleChange,
|
|
1586
2338
|
debounce: debounce,
|
|
1587
2339
|
disabled: disabled,
|
|
1588
|
-
feel: feel
|
|
2340
|
+
feel: feel,
|
|
2341
|
+
id: id,
|
|
2342
|
+
label: label,
|
|
2343
|
+
onInput: onInput,
|
|
2344
|
+
show: show,
|
|
2345
|
+
value: value
|
|
2346
|
+
}), error && jsx("div", {
|
|
2347
|
+
class: "bio-properties-panel-error",
|
|
2348
|
+
children: error
|
|
1589
2349
|
}), jsx(Description, {
|
|
1590
2350
|
forId: id,
|
|
1591
2351
|
element: element,
|
|
1592
2352
|
value: description
|
|
1593
|
-
}), error && jsx("div", {
|
|
1594
|
-
class: "bio-properties-panel-error",
|
|
1595
|
-
children: error
|
|
1596
2353
|
})]
|
|
1597
2354
|
});
|
|
1598
2355
|
}
|
|
@@ -1708,5 +2465,5 @@ var index = {
|
|
|
1708
2465
|
debounceInput: ['factory', debounceInput]
|
|
1709
2466
|
};
|
|
1710
2467
|
|
|
1711
|
-
export { ArrowIcon, CheckboxEntry, CollapsibleEntry, CreateIcon, index as DebounceInputModule, DeleteIcon, DescriptionContext, Description as DescriptionEntry, DropdownButton, FeelOptionalIcon, FeelRequiredIcon, Group, Header, HeaderButton, LayoutContext, List as ListEntry, ListGroup, ListItem, NumberFieldEntry, PropertiesPanel, SelectEntry, Simple as SimpleEntry, TextAreaEntry, TextfieldEntry as TextFieldEntry, ToggleSwitchEntry, isEdited$6 as isCheckboxEntryEdited, isEdited$5 as isNumberFieldEntryEdited, isEdited$4 as isSelectEntryEdited, isEdited$3 as isSimpleEntryEdited, isEdited$2 as isTextAreaEntryEdited, isEdited$1 as isTextFieldEntryEdited, isEdited as isToggleSwitchEntryEdited, useDescriptionContext, useKeyFactory, useLayoutState, usePrevious };
|
|
2468
|
+
export { ArrowIcon, CheckboxEntry, CollapsibleEntry, CreateIcon, index as DebounceInputModule, DeleteIcon, DescriptionContext, Description as DescriptionEntry, DropdownButton, EventContext, ExternalLinkIcon, FeelOptionalIcon, FeelRequiredIcon, Group, Header, HeaderButton, LayoutContext, List as ListEntry, ListGroup, ListItem, NumberFieldEntry, PropertiesPanel, LayoutContext as PropertiesPanelContext, SelectEntry, Simple as SimpleEntry, TextAreaEntry, TextfieldEntry as TextFieldEntry, ToggleSwitchEntry, isEdited$6 as isCheckboxEntryEdited, isEdited$5 as isNumberFieldEntryEdited, isEdited$4 as isSelectEntryEdited, isEdited$3 as isSimpleEntryEdited, isEdited$2 as isTextAreaEntryEdited, isEdited$1 as isTextFieldEntryEdited, isEdited as isToggleSwitchEntryEdited, useDescriptionContext, useEvent, useEventBuffer, useKeyFactory, useLayoutState, usePrevious, useShowEntryEvent, useShowErrorEvent };
|
|
1712
2469
|
//# sourceMappingURL=index.esm.js.map
|