Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restore canvas focus on properties panel focus change #1094

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion src/render/BpmnPropertiesPanelRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,12 @@ export default class BpmnPropertiesPanelRenderer {
this._getFeelPopupLinks = getFeelPopupLinks;

this._container = domify(
'<div style="height: 100%" class="bio-properties-panel-container"></div>'
'<div style="height: 100%" tabindex="-1" class="bio-properties-panel-container"></div>'
);

domEvent.bind(this._container, 'focusin', (event) => this._checkFocus(event));
domEvent.bind(this._container, 'focusout', (event) => this._checkFocus(event));

var commandStack = injector.get('commandStack', false);

commandStack && setupKeyboard(this._container, eventBus, commandStack);
Expand All @@ -61,13 +64,45 @@ export default class BpmnPropertiesPanelRenderer {
this.detach();
});

const canvas = this._injector.get('canvas', false);

// attempt to restore canvas focus when properties panel
// supports diagram-js@15+
if (canvas && canvas.restoreFocus) {
eventBus.on('propertiesPanel.focus.changed', ({ focused }) => {
if (!focused) {
canvas.restoreFocus();
}
});
}

eventBus.on('root.added', (event) => {
const { element } = event;

this._render(element);
});
}

/**
* @param {FocusEvent} event
*/
_checkFocus(event) {

const container = this._container;

const {
relatedTarget
} = event;

// ignore focus changes within the properties panel
if (relatedTarget && container.contains(relatedTarget)) {
return;
}

const focused = event.type === 'focusin';

this._eventBus.fire('propertiesPanel.focus.changed', { focused });
}

/**
* Attach the properties panel to a parent node.
Expand Down
89 changes: 88 additions & 1 deletion test/spec/BpmnPropertiesPanelRenderer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -816,6 +816,85 @@ describe('<BpmnPropertiesPanelRenderer>', function() {
expect(spy).to.have.been.calledOnce;
});


describe('should emit <propertiesPanel.focus.changed>', function() {

const diagramXml = require('test/fixtures/simple.bpmn').default;

let modeler;
let eventBus;

let generalGroupEl;
let nameInputEl;
let versionTagInputEl;

beforeEach(async function() {
const result = await createModeler(diagramXml);

modeler = result.modeler;

eventBus = modeler.get('eventBus');

generalGroupEl = getGroupHeader(propertiesContainer, 'general');
nameInputEl = getInput(propertiesContainer, 'name');
versionTagInputEl = getInput(propertiesContainer, 'versionTag');
});


it('on focusin', async function() {

// given
let focused;

const focusSpy = sinon.spy(function(event) {
focused = event.focused;
});

eventBus.on('propertiesPanel.focus.changed', focusSpy);

// when
// we initially focus
await act(() => generalGroupEl.click());
await act(() => nameInputEl.focus());

// then
expect(focusSpy).to.have.been.calledOnce;
expect(focused).to.be.true;

// but when
// we focus another element within the panel
await act(() => versionTagInputEl.focus());

// then
// we do not emit the focus change again
expect(focusSpy).to.have.been.calledOnce;
});


it('on focusout', async function() {

// given
let focused;

const focusSpy = sinon.spy(function(event) {
focused = event.focused;
});

act(() => generalGroupEl.click());
act(() => nameInputEl.focus());

// when
eventBus.on('propertiesPanel.focus.changed', focusSpy);

nameInputEl.blur();

// then
expect(focusSpy).to.have.been.calledOnce;
expect(focused).to.be.false;
});

});

});


Expand Down Expand Up @@ -1209,7 +1288,15 @@ describe('<BpmnPropertiesPanelRenderer>', function() {
// helpers /////////////////////

function getGroup(container, id) {
return domQuery(`[data-group-id="group-${id}"`, container);
return domQuery(`[data-group-id="group-${id}"]`, container);
}

function getGroupHeader(container, id) {
return domQuery(`[data-group-id="group-${id}"] > .bio-properties-panel-group-header`, container);
}

function getInput(container, id) {
return domQuery(`[data-entry-id="${id}"] .bio-properties-panel-input`, container);
}

function getHeaderName(container) {
Expand Down