From c1234c983b895f55d9e33e29293aa610616990a8 Mon Sep 17 00:00:00 2001 From: Grace Date: Mon, 7 Jul 2025 16:35:28 +0100 Subject: [PATCH 1/5] Update field editing focus outline style When editing a field, workspace focus outline does not disappear and the field does not show passive focus outline. --- test/index.html | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/test/index.html b/test/index.html index 6fca8c38..58c39d8b 100644 --- a/test/index.html +++ b/test/index.html @@ -115,15 +115,30 @@ stroke: var(--blockly-active-node-color); stroke-width: var(--blockly-selection-width); } - .blocklyKeyboardNavigation + .blocklyKeyboardNavigation:not( + :has( + .blocklyDropDownDiv > .blocklyDropDownContent > *, + .blocklyWidgetDiv > * + ) + ) .blocklyPassiveFocus:is( .blocklyPath:not(.blocklyFlyout .blocklyPath), .blocklyHighlightedConnectionPath ), - .blocklyKeyboardNavigation + .blocklyKeyboardNavigation:not( + :has( + .blocklyDropDownDiv > .blocklyDropDownContent > *, + .blocklyWidgetDiv > * + ) + ) .blocklyPassiveFocus.blocklyField > .blocklyFieldRect, - .blocklyKeyboardNavigation + .blocklyKeyboardNavigation:not( + :has( + .blocklyDropDownDiv > .blocklyDropDownContent > *, + .blocklyWidgetDiv > * + ) + ) .blocklyPassiveFocus.blocklyIconGroup > .blocklyIconShape:first-child { stroke: var(--blockly-active-node-color); @@ -154,6 +169,17 @@ .blocklyWorkspaceFocusRing, .blocklyKeyboardNavigation .blocklyWorkspace.blocklyActiveFocus + .blocklyWorkspaceFocusRing, + .blocklyKeyboardNavigation + .blocklyWorkspace.blocklyActiveFocus + .blocklyWorkspaceFocusRing, + .blocklyKeyboardNavigation:has( + .blocklyDropDownDiv > .blocklyDropDownContent > * + ):focus-within + .blocklyWorkspace + .blocklyWorkspaceFocusRing, + .blocklyKeyboardNavigation:has(.blocklyWidgetDiv > *):focus-within + .blocklyWorkspace .blocklyWorkspaceFocusRing { stroke: var(--blockly-active-tree-color); stroke-width: calc(var(--blockly-selection-width) * 2); From 478cf40aa93332345e83655a790d95f1be0d2836 Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Tue, 8 Jul 2025 14:23:02 +0100 Subject: [PATCH 2/5] chore: comment CSS, remove readded duplicate selector --- src/index.ts | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/index.ts b/src/index.ts index 041dbfb9..ab17a99e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -164,19 +164,28 @@ export class KeyboardNavigation { // // This should be moved to core, being integrated into the // existing styling of renderers in core/renderers/*/constants.ts. + // + // Many selectors include .blocklyKeyboardNavigation to ensure keyboard + // nav is on (via the heuristic). This class is added/removed from body. Blockly.Css.register(` - /* Blocks, connections and fields. */ + /* Active focus cases: */ + /* Blocks with active focus. */ .blocklyKeyboardNavigation .blocklyActiveFocus:is(.blocklyPath, .blocklyHighlightedConnectionPath), + /* Fields with active focus, */ .blocklyKeyboardNavigation .blocklyActiveFocus.blocklyField > .blocklyFieldRect, + /* Icons with active focus. */ .blocklyKeyboardNavigation .blocklyActiveFocus.blocklyIconGroup > .blocklyIconShape:first-child { stroke: var(--blockly-active-node-color); stroke-width: var(--blockly-selection-width); } + + /* Passive focus cases: */ + /* Blocks with passive focus except when widget/dropdown div in use. */ .blocklyKeyboardNavigation:not( :has( .blocklyDropDownDiv > .blocklyDropDownContent > *, @@ -187,6 +196,7 @@ export class KeyboardNavigation { .blocklyPath:not(.blocklyFlyout .blocklyPath), .blocklyHighlightedConnectionPath ), + /* Fields with passive focus except when widget/dropdown div in use. */ .blocklyKeyboardNavigation:not( :has( .blocklyDropDownDiv > .blocklyDropDownContent > *, @@ -195,6 +205,7 @@ export class KeyboardNavigation { ) .blocklyPassiveFocus.blocklyField > .blocklyFieldRect, + /* Icons with passive focus except when widget/dropdown div in use. */ .blocklyKeyboardNavigation:not( :has( .blocklyDropDownDiv > .blocklyDropDownContent > *, @@ -207,9 +218,10 @@ export class KeyboardNavigation { stroke-dasharray: 5px 3px; stroke-width: var(--blockly-selection-width); } + + /* Workaround for unexpectedly hidden connection path due to core style. */ .blocklyKeyboardNavigation .blocklyPassiveFocus.blocklyHighlightedConnectionPath { - /* The connection path is being unexpectedly hidden in core */ display: unset !important; } `); @@ -219,14 +231,20 @@ export class KeyboardNavigation { // This should be moved to core, to core/css.ts if not to somewhere // more specific in core/toolbox/. Blockly.Css.register(` + /* Different ways for toolbox/flyout to be the active tree: */ + /* Active focus in the flyout. */ .blocklyKeyboardNavigation .blocklyFlyout:has(.blocklyActiveFocus), + /* Active focus in the toolbox. */ .blocklyKeyboardNavigation .blocklyToolbox:has(.blocklyActiveFocus), + /* Active focus on the toolbox/flyout. */ .blocklyKeyboardNavigation .blocklyActiveFocus:is(.blocklyFlyout, .blocklyToolbox) { outline-offset: calc(var(--blockly-selection-width) * -1); outline: var(--blockly-selection-width) solid var(--blockly-active-tree-color); } + + /* Suppress default outline. */ .blocklyKeyboardNavigation .blocklyToolboxCategoryContainer:focus-visible { outline: none; @@ -237,29 +255,34 @@ export class KeyboardNavigation { // // This should be move to core, probably to core/css.ts. Blockly.Css.register(` + /* Different ways for the workspace to be the active tree: */ + /* Active focus within workspace. */ .blocklyKeyboardNavigation .blocklyWorkspace:has(.blocklyActiveFocus) .blocklyWorkspaceFocusRing, + /* Active focus within drag layer. */ .blocklyKeyboardNavigation .blocklySvg:has(~ .blocklyBlockDragSurface .blocklyActiveFocus) .blocklyWorkspaceFocusRing, + /* Active focus on workspace. */ .blocklyKeyboardNavigation .blocklyWorkspace.blocklyActiveFocus .blocklyWorkspaceFocusRing, - .blocklyKeyboardNavigation - .blocklyWorkspace.blocklyActiveFocus - .blocklyWorkspaceFocusRing, + /* Focus in dropdown div considered to be in workspace. */ .blocklyKeyboardNavigation:has( .blocklyDropDownDiv > .blocklyDropDownContent > * ):focus-within .blocklyWorkspace .blocklyWorkspaceFocusRing, + /* Focus in widget div considered to be in workspace. */ .blocklyKeyboardNavigation:has(.blocklyWidgetDiv > *):focus-within .blocklyWorkspace .blocklyWorkspaceFocusRing { stroke: var(--blockly-active-tree-color); stroke-width: calc(var(--blockly-selection-width) * 2); } + + /* The workspace itself is the active node. */ .blocklyKeyboardNavigation .blocklyWorkspace.blocklyActiveFocus .blocklyWorkspaceSelectionRing { From 250494c0065326a8de51be02007f9b276ad952c9 Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Tue, 8 Jul 2025 16:01:06 +0100 Subject: [PATCH 3/5] fix: correct use of focus-within --- src/index.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/index.ts b/src/index.ts index ab17a99e..57456583 100644 --- a/src/index.ts +++ b/src/index.ts @@ -269,13 +269,11 @@ export class KeyboardNavigation { .blocklyWorkspace.blocklyActiveFocus .blocklyWorkspaceFocusRing, /* Focus in dropdown div considered to be in workspace. */ - .blocklyKeyboardNavigation:has( - .blocklyDropDownDiv > .blocklyDropDownContent > * - ):focus-within + .blocklyKeyboardNavigation:has(.blocklyDropDownDiv:focus-within) .blocklyWorkspace .blocklyWorkspaceFocusRing, /* Focus in widget div considered to be in workspace. */ - .blocklyKeyboardNavigation:has(.blocklyWidgetDiv > *):focus-within + .blocklyKeyboardNavigation:has(.blocklyWidgetDiv:focus-within) .blocklyWorkspace .blocklyWorkspaceFocusRing { stroke: var(--blockly-active-tree-color); From 39dbe818f9a1426cc98fff857b37bc0f41ca10a0 Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Tue, 8 Jul 2025 16:26:15 +0100 Subject: [PATCH 4/5] chore: consistently use focus-within I think this behaves more or less the same but is easier to follow. --- src/index.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/index.ts b/src/index.ts index 57456583..8a53d470 100644 --- a/src/index.ts +++ b/src/index.ts @@ -188,8 +188,8 @@ export class KeyboardNavigation { /* Blocks with passive focus except when widget/dropdown div in use. */ .blocklyKeyboardNavigation:not( :has( - .blocklyDropDownDiv > .blocklyDropDownContent > *, - .blocklyWidgetDiv > * + .blocklyDropDownDiv:focus-within, + .blocklyWidgetDiv:focus-within ) ) .blocklyPassiveFocus:is( @@ -199,8 +199,8 @@ export class KeyboardNavigation { /* Fields with passive focus except when widget/dropdown div in use. */ .blocklyKeyboardNavigation:not( :has( - .blocklyDropDownDiv > .blocklyDropDownContent > *, - .blocklyWidgetDiv > * + .blocklyDropDownDiv:focus-within, + .blocklyWidgetDiv:focus-within ) ) .blocklyPassiveFocus.blocklyField @@ -208,8 +208,8 @@ export class KeyboardNavigation { /* Icons with passive focus except when widget/dropdown div in use. */ .blocklyKeyboardNavigation:not( :has( - .blocklyDropDownDiv > .blocklyDropDownContent > *, - .blocklyWidgetDiv > * + .blocklyDropDownDiv:focus-within, + .blocklyWidgetDiv:focus-within ) ) .blocklyPassiveFocus.blocklyIconGroup @@ -273,7 +273,10 @@ export class KeyboardNavigation { .blocklyWorkspace .blocklyWorkspaceFocusRing, /* Focus in widget div considered to be in workspace. */ - .blocklyKeyboardNavigation:has(.blocklyWidgetDiv:focus-within) + .blocklyKeyboardNavigation:has( + .blocklyWidgetDiv:focus-within, + .blocklyDropDownDiv:focus-within + ) .blocklyWorkspace .blocklyWorkspaceFocusRing { stroke: var(--blockly-active-tree-color); From 3ea518ad5def334dc2ee6a364252fa4d05e3c94c Mon Sep 17 00:00:00 2001 From: Matt Hillsdon Date: Tue, 8 Jul 2025 16:29:57 +0100 Subject: [PATCH 5/5] chore: remove redundant case --- src/index.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/index.ts b/src/index.ts index 8a53d470..09d6c33e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -268,11 +268,7 @@ export class KeyboardNavigation { .blocklyKeyboardNavigation .blocklyWorkspace.blocklyActiveFocus .blocklyWorkspaceFocusRing, - /* Focus in dropdown div considered to be in workspace. */ - .blocklyKeyboardNavigation:has(.blocklyDropDownDiv:focus-within) - .blocklyWorkspace - .blocklyWorkspaceFocusRing, - /* Focus in widget div considered to be in workspace. */ + /* Focus in widget/dropdown div considered to be in workspace. */ .blocklyKeyboardNavigation:has( .blocklyWidgetDiv:focus-within, .blocklyDropDownDiv:focus-within