${this.__renderDragHandle()}
${this.sectionTitle}
diff --git a/packages/dashboard/src/vaadin-dashboard-widget.js b/packages/dashboard/src/vaadin-dashboard-widget.js
index 28e3afbb37..8a53ebd88e 100644
--- a/packages/dashboard/src/vaadin-dashboard-widget.js
+++ b/packages/dashboard/src/vaadin-dashboard-widget.js
@@ -209,9 +209,11 @@ class DashboardWidget extends DashboardItemMixin(ElementMixin(ThemableMixin(Poly
/** @protected */
render() {
return html`
- ${this.__renderFocusButton('selectWidget')} ${this.__renderMoveControls()} ${this.__renderResizeControls()}
+ ${this.__renderMoveControls()} ${this.__renderResizeControls()}
+ ${this.__renderFocusButton('selectWidget')}
+
${this.__renderDragHandle()}
${this.__nestedHeadingLevel
diff --git a/packages/dashboard/src/vaadin-dashboard.js b/packages/dashboard/src/vaadin-dashboard.js
index 67514154c8..46c4baf398 100644
--- a/packages/dashboard/src/vaadin-dashboard.js
+++ b/packages/dashboard/src/vaadin-dashboard.js
@@ -259,7 +259,7 @@ class Dashboard extends DashboardLayoutMixin(ElementMixin(ThemableMixin(PolylitM
let wrappers = [...hostElement.children].filter((el) => el.localName === WRAPPER_LOCAL_NAME);
let previousWrapper = null;
- const focusedWrapper = wrappers.find((wrapper) => wrapper.querySelector('[focused]'));
+ const focusedWrapper = wrappers.find((wrapper) => wrapper.querySelector(':focus'));
const focusedWrapperWillBeRemoved = focusedWrapper && !this.__isActiveWrapper(focusedWrapper);
const wrapperClosestToRemovedFocused =
focusedWrapperWillBeRemoved && this.__getClosestActiveWrapper(focusedWrapper);
@@ -320,7 +320,7 @@ class Dashboard extends DashboardLayoutMixin(ElementMixin(ThemableMixin(PolylitM
this.__focusWrapperContent(wrapperClosestToRemovedFocused || this.querySelector(WRAPPER_LOCAL_NAME));
}
- const focusedItem = this.querySelector('[focused]');
+ const focusedItem = this.querySelector(':focus');
if (focusedItem && this.__outsideViewport(focusedItem)) {
// If the focused wrapper is not in the viewport, scroll it into view
focusedItem.scrollIntoView();
diff --git a/packages/dashboard/test/dashboard-keyboard.test.ts b/packages/dashboard/test/dashboard-keyboard.test.ts
index bd865511c4..112b21efd5 100644
--- a/packages/dashboard/test/dashboard-keyboard.test.ts
+++ b/packages/dashboard/test/dashboard-keyboard.test.ts
@@ -79,11 +79,29 @@ describe('dashboard - keyboard interaction', () => {
const widget = getElementFromCell(dashboard, 0, 0)!;
await sendKeys({ press: 'Tab' });
await sendKeys({ press: 'Space' });
- expect(widget.hasAttribute('focused')).to.be.true;
+ expect(widget.hasAttribute('focused')).to.be.false;
expect(widget.hasAttribute('selected')).to.be.true;
expect(dashboard.hasAttribute('item-selected')).to.be.true;
});
+ it('should unselect the widget on focus button click', async () => {
+ const widget = getElementFromCell(dashboard, 0, 0)!;
+ await sendKeys({ press: 'Tab' });
+ await sendKeys({ press: 'Space' });
+
+ // Focus the focus-button with shift + tab
+ await sendKeys({ down: 'Shift' });
+ await sendKeys({ press: 'Tab' });
+ await sendKeys({ up: 'Shift' });
+
+ // Click the focus-button
+ await sendKeys({ press: 'Space' });
+
+ expect(widget.hasAttribute('focused')).to.be.true;
+ expect(widget.hasAttribute('selected')).to.be.false;
+ expect(dashboard.hasAttribute('item-selected')).to.be.false;
+ });
+
it('should dispatch a selection event', async () => {
const spy = sinon.spy();
dashboard.addEventListener('dashboard-item-selected-changed', spy);
@@ -448,7 +466,7 @@ describe('dashboard - keyboard interaction', () => {
// Enter move mode
await sendKeys({ press: 'Space' });
- expect(widget.hasAttribute('focused')).to.be.true;
+ expect(widget.hasAttribute('focused')).to.be.false;
expect(widget.hasAttribute('selected')).to.be.true;
expect(widget.hasAttribute('move-mode')).to.be.true;
});
@@ -471,7 +489,7 @@ describe('dashboard - keyboard interaction', () => {
(getDraggable(widget) as HTMLElement).click();
await nextFrame();
- expect(widget.hasAttribute('focused')).to.be.true;
+ expect(widget.hasAttribute('focused')).to.be.false;
expect(widget.hasAttribute('selected')).to.be.true;
expect(widget.hasAttribute('move-mode')).to.be.true;
});
@@ -501,7 +519,7 @@ describe('dashboard - keyboard interaction', () => {
await sendKeys({ press: 'Escape' });
expect(widget.hasAttribute('move-mode')).to.be.false;
expect(widget.hasAttribute('selected')).to.be.true;
- expect(widget.hasAttribute('focused')).to.be.true;
+ expect(widget.hasAttribute('focused')).to.be.false;
});
it('should dispatch a move mode event', async () => {
@@ -519,7 +537,7 @@ describe('dashboard - keyboard interaction', () => {
await sendKeys({ press: 'Space' });
expect(widget.hasAttribute('move-mode')).to.be.false;
expect(widget.hasAttribute('selected')).to.be.true;
- expect(widget.hasAttribute('focused')).to.be.true;
+ expect(widget.hasAttribute('focused')).to.be.false;
});
it('should focus drag handle on exit move mode', async () => {
@@ -594,7 +612,7 @@ describe('dashboard - keyboard interaction', () => {
expect(widget.hasAttribute('move-mode')).to.be.true;
expect(widget.hasAttribute('selected')).to.be.true;
- expect(widget.hasAttribute('focused')).to.be.true;
+ expect(widget.hasAttribute('focused')).to.be.false;
});
it('should not lose move mode when the focused forward button is hidden', async () => {
@@ -624,7 +642,7 @@ describe('dashboard - keyboard interaction', () => {
expect(widget.hasAttribute('move-mode')).to.be.true;
expect(widget.hasAttribute('selected')).to.be.true;
- expect(widget.hasAttribute('focused')).to.be.true;
+ expect(widget.hasAttribute('focused')).to.be.false;
});
it('should deselect the section on blur', async () => {
@@ -678,7 +696,7 @@ describe('dashboard - keyboard interaction', () => {
const widget = getElementFromCell(dashboard, 0, 0)!;
expect(widget.contains(document.activeElement)).to.be.true;
expect(widget.hasAttribute('selected')).to.be.true;
- expect(widget.hasAttribute('focused')).to.be.true;
+ expect(widget.hasAttribute('focused')).to.be.false;
dashboard.editable = false;
await nextFrame();
expect(widget.contains(document.activeElement)).to.be.false;
@@ -697,7 +715,7 @@ describe('dashboard - keyboard interaction', () => {
await sendKeys({ press: 'Tab' });
await sendKeys({ press: 'Space' });
- expect(widget.hasAttribute('focused')).to.be.true;
+ expect(widget.hasAttribute('focused')).to.be.false;
expect(widget.hasAttribute('selected')).to.be.true;
expect(widget.hasAttribute('resize-mode')).to.be.true;
});
@@ -707,7 +725,7 @@ describe('dashboard - keyboard interaction', () => {
(getResizeHandle(widget) as HTMLElement).click();
await nextFrame();
- expect(widget.hasAttribute('focused')).to.be.true;
+ expect(widget.hasAttribute('focused')).to.be.false;
expect(widget.hasAttribute('selected')).to.be.true;
expect(widget.hasAttribute('resize-mode')).to.be.true;
});
@@ -739,7 +757,7 @@ describe('dashboard - keyboard interaction', () => {
await sendKeys({ press: 'Escape' });
expect(widget.hasAttribute('resize-mode')).to.be.false;
expect(widget.hasAttribute('selected')).to.be.true;
- expect(widget.hasAttribute('focused')).to.be.true;
+ expect(widget.hasAttribute('focused')).to.be.false;
});
it('should dispatch a resize mode event', async () => {
@@ -756,7 +774,7 @@ describe('dashboard - keyboard interaction', () => {
await sendKeys({ press: 'Space' });
expect(widget.hasAttribute('resize-mode')).to.be.false;
expect(widget.hasAttribute('selected')).to.be.true;
- expect(widget.hasAttribute('focused')).to.be.true;
+ expect(widget.hasAttribute('focused')).to.be.false;
});
it('should focus resize handle on exit resize mode', async () => {
diff --git a/packages/dashboard/test/dashboard-widget-reordering.test.ts b/packages/dashboard/test/dashboard-widget-reordering.test.ts
index 23adc00c84..ade35e4724 100644
--- a/packages/dashboard/test/dashboard-widget-reordering.test.ts
+++ b/packages/dashboard/test/dashboard-widget-reordering.test.ts
@@ -474,7 +474,7 @@ describe('dashboard - widget reordering', () => {
(getDraggable(widget) as HTMLElement).click();
await nextFrame();
expect(widget.hasAttribute('selected')).to.be.true;
- expect(widget.hasAttribute('focused')).to.be.true;
+ expect(widget.hasAttribute('focused')).to.be.false;
expect(widget.hasAttribute('move-mode')).to.be.true;
fireDragStart(widget);
diff --git a/packages/dashboard/theme/lumo/vaadin-dashboard-widget-styles.js b/packages/dashboard/theme/lumo/vaadin-dashboard-widget-styles.js
index d6497f6933..bde5410b51 100644
--- a/packages/dashboard/theme/lumo/vaadin-dashboard-widget-styles.js
+++ b/packages/dashboard/theme/lumo/vaadin-dashboard-widget-styles.js
@@ -40,6 +40,10 @@ const dashboardWidgetAndSection = css`
margin: calc(var(--_focus-ring-spacing-offset) * -1);
}
+ :host([selected])::before {
+ outline: 1px solid var(--_focus-ring-color);
+ }
+
:host([focused])::before {
outline: var(--_focus-ring-width) solid var(--_focus-ring-color);
}