Skip to content

Commit 4566125

Browse files
committed
feat: add implicit keyboard binding
This updates the library to diagram-js@15 which ships breaking changes. BREAKING CHANGES: * Keyboard is now implicitly bound to the container element. Calls to `keyboard.bind` with `node` and `keyboard.bindTo` now result with a descriptive console error and have no effect. Related to bpmn-io/diagram-js#662
1 parent 997b2cd commit 4566125

File tree

8 files changed

+81
-63
lines changed

8 files changed

+81
-63
lines changed

package-lock.json

Lines changed: 36 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@
9191
"cross-env": "^7.0.3",
9292
"css-loader": "^7.1.2",
9393
"del-cli": "^5.1.0",
94-
"diagram-js": "^14.11.3",
94+
"diagram-js": "^15.2.2",
9595
"didi": "^10.2.2",
9696
"eslint": "^8.57.0",
9797
"eslint-config-prettier": "^9.1.0",

packages/form-js-editor/src/FormEditor.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ export class FormEditor {
6363
*/
6464
this._container = createFormContainer();
6565

66-
this._container.setAttribute('input-handle-modified-keys', 'z,y');
66+
this._container.setAttribute('tabindex', '0');
6767

6868
const { container, exporter, injector = this._createInjector(options, this._container), properties = {} } = options;
6969

packages/form-js-editor/src/features/keyboard/FormEditorKeyboardBindings.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import { isCmd, isKey, isShift } from 'diagram-js/lib/features/keyboard/KeyboardUtil';
2-
3-
import { KEYS_REDO, KEYS_UNDO } from 'diagram-js/lib/features/keyboard/KeyboardBindings';
1+
import { isUndo, isRedo } from 'diagram-js/lib/features/keyboard/KeyboardUtil';
42

53
const LOW_PRIORITY = 500;
64

@@ -25,7 +23,7 @@ export class FormEditorKeyboardBindings {
2523
addListener('undo', (context) => {
2624
const { keyEvent } = context;
2725

28-
if (isCmd(keyEvent) && !isShift(keyEvent) && isKey(KEYS_UNDO, keyEvent)) {
26+
if (isUndo(keyEvent)) {
2927
editorActions.trigger('undo');
3028

3129
return true;
@@ -38,7 +36,7 @@ export class FormEditorKeyboardBindings {
3836
addListener('redo', (context) => {
3937
const { keyEvent } = context;
4038

41-
if (isCmd(keyEvent) && (isKey(KEYS_REDO, keyEvent) || (isKey(KEYS_UNDO, keyEvent) && isShift(keyEvent)))) {
39+
if (isRedo(keyEvent)) {
4240
editorActions.trigger('redo');
4341

4442
return true;

packages/form-js-editor/src/render/Renderer.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,31 @@ export class Renderer {
2222
constructor(renderConfig, eventBus, formEditor, injector) {
2323
const { container, compact = false } = renderConfig;
2424

25+
eventBus.on('form.init', function () {
26+
// emit <canvas.init> so dependent components can hook in
27+
// this is required to register keyboard bindings
28+
eventBus.fire('canvas.init', {
29+
svg: container,
30+
viewport: null,
31+
});
32+
});
33+
34+
// focus container on over if no selection
35+
container.addEventListener('mouseover', function () {
36+
if (document.activeElement === document.body) {
37+
container.focus({ preventScroll: true });
38+
}
39+
});
40+
41+
// ensure we focus the container if the users clicks
42+
// inside; this follows input focus handling closely
43+
container.addEventListener('click', function (event) {
44+
// force focus when clicking container
45+
if (!container.contains(document.activeElement)) {
46+
container.focus({ preventScroll: true });
47+
}
48+
});
49+
2550
const App = () => {
2651
const [state, setState] = useState(formEditor._getState());
2752

packages/form-js-editor/src/render/components/FormEditor.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -121,14 +121,23 @@ function Element(props) {
121121
}
122122
}, [selection, field]);
123123

124-
function onClick(event) {
125-
event.stopPropagation();
124+
const onClick = useCallback(
125+
(event) => {
126+
// TODO(nikku): refactor this to use proper DOM delegation
127+
const fieldEl = event.target.closest('[data-id]');
126128

127-
selection.toggle(field);
129+
if (!fieldEl) {
130+
return;
131+
}
128132

129-
// properly focus on field
130-
ref.current.focus();
131-
}
133+
const id = fieldEl.dataset.id;
134+
135+
if (id === field.id) {
136+
selection.toggle(field);
137+
}
138+
},
139+
[field, selection],
140+
);
132141

133142
const isSelected = selection.isSelected(field);
134143

packages/form-js-editor/test/spec/FormEditor.spec.js

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,6 @@ describe('FormEditor', function () {
5252
await bootstrapFormEditor({
5353
container,
5454
schema,
55-
keyboard: {
56-
bindTo: document,
57-
},
5855
});
5956

6057
formEditor.on('changed', (event) => {
@@ -70,9 +67,6 @@ describe('FormEditor', function () {
7067
await bootstrapFormEditor({
7168
container,
7269
schema: schemaRows,
73-
keyboard: {
74-
bindTo: document,
75-
},
7670
debugColumns: true,
7771
});
7872

@@ -93,9 +87,6 @@ describe('FormEditor', function () {
9387
await bootstrapFormEditor({
9488
container,
9589
schema,
96-
keyboard: {
97-
bindTo: document,
98-
},
9990
});
10091

10192
// then
@@ -111,9 +102,6 @@ describe('FormEditor', function () {
111102
await bootstrapFormEditor({
112103
container,
113104
schema,
114-
keyboard: {
115-
bindTo: document,
116-
},
117105
});
118106

119107
// when
@@ -132,9 +120,6 @@ describe('FormEditor', function () {
132120
renderer: {
133121
compact: true,
134122
},
135-
keyboard: {
136-
bindTo: document,
137-
},
138123
});
139124

140125
// then
@@ -153,9 +138,6 @@ describe('FormEditor', function () {
153138
type: 'default',
154139
},
155140
debounce: true,
156-
keyboard: {
157-
bindTo: document,
158-
},
159141
});
160142

161143
// then
@@ -181,9 +163,6 @@ describe('FormEditor', function () {
181163
],
182164
},
183165
debounce: true,
184-
keyboard: {
185-
bindTo: document,
186-
},
187166
});
188167

189168
// then

packages/form-js-viewer/test/spec/Form.spec.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -208,9 +208,6 @@ describe('Form', function () {
208208
await bootstrapForm({
209209
container,
210210
schema,
211-
keyboard: {
212-
bindTo: document,
213-
},
214211
});
215212

216213
// when

0 commit comments

Comments
 (0)