Skip to content

Commit 5b79a29

Browse files
authored
feat: Update CSS for keyboard navigation (#9674)
1 parent 05af6b6 commit 5b79a29

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

packages/blockly/core/css.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,4 +536,126 @@ input[type=number] {
536536
height: 1px;
537537
overflow: hidden;
538538
}
539+
540+
.injectionDiv {
541+
--blockly-active-node-color: #fff200;
542+
--blockly-active-tree-color: #60a5fa;
543+
--blockly-selection-width: 3px;
544+
}
545+
546+
/* Active focus cases: */
547+
/* Blocks with active focus. */
548+
.blocklyKeyboardNavigation
549+
.blocklyActiveFocus:is(.blocklyPath, .blocklyHighlightedConnectionPath),
550+
/* Fields with active focus, */
551+
.blocklyKeyboardNavigation
552+
.blocklyActiveFocus.blocklyField
553+
> .blocklyFieldRect,
554+
/* Icons with active focus. */
555+
.blocklyKeyboardNavigation
556+
.blocklyActiveFocus.blocklyIconGroup
557+
> .blocklyIconShape:first-child {
558+
stroke: var(--blockly-active-node-color);
559+
stroke-width: var(--blockly-selection-width);
560+
}
561+
562+
/* Passive focus cases: */
563+
/* Blocks with passive focus except when widget/dropdown div in use. */
564+
.blocklyKeyboardNavigation:not(
565+
:has(
566+
.blocklyDropDownDiv:focus-within,
567+
.blocklyWidgetDiv:focus-within
568+
)
569+
)
570+
.blocklyPassiveFocus:is(
571+
.blocklyPath:not(.blocklyFlyout .blocklyPath),
572+
.blocklyHighlightedConnectionPath
573+
),
574+
/* Fields with passive focus except when widget/dropdown div in use. */
575+
.blocklyKeyboardNavigation:not(
576+
:has(
577+
.blocklyDropDownDiv:focus-within,
578+
.blocklyWidgetDiv:focus-within
579+
)
580+
)
581+
.blocklyPassiveFocus.blocklyField
582+
> .blocklyFieldRect,
583+
/* Icons with passive focus except when widget/dropdown div in use. */
584+
.blocklyKeyboardNavigation:not(
585+
:has(
586+
.blocklyDropDownDiv:focus-within,
587+
.blocklyWidgetDiv:focus-within
588+
)
589+
)
590+
.blocklyPassiveFocus.blocklyIconGroup
591+
> .blocklyIconShape:first-child {
592+
stroke: var(--blockly-active-node-color);
593+
stroke-dasharray: 5px 3px;
594+
stroke-width: var(--blockly-selection-width);
595+
}
596+
597+
/* Workaround for unexpectedly hidden connection path due to core style. */
598+
.blocklyKeyboardNavigation
599+
.blocklyPassiveFocus.blocklyHighlightedConnectionPath {
600+
display: unset !important;
601+
}
602+
603+
/* Different ways for toolbox/flyout to be the active tree: */
604+
/* Active focus in the flyout. */
605+
.blocklyKeyboardNavigation .blocklyFlyout:has(.blocklyActiveFocus),
606+
/* Active focus in the toolbox. */
607+
.blocklyKeyboardNavigation .blocklyToolbox:has(.blocklyActiveFocus),
608+
/* Active focus on the toolbox/flyout. */
609+
.blocklyKeyboardNavigation
610+
.blocklyActiveFocus:is(.blocklyFlyout, .blocklyToolbox) {
611+
outline-offset: calc(var(--blockly-selection-width) * -1);
612+
outline: var(--blockly-selection-width) solid
613+
var(--blockly-active-tree-color);
614+
}
615+
616+
/* Suppress default outline. */
617+
.blocklyKeyboardNavigation
618+
.blocklyToolboxCategoryContainer:focus-visible {
619+
outline: none;
620+
}
621+
622+
/* Different ways for the workspace to be the active tree: */
623+
/* Active focus within workspace. */
624+
.blocklyKeyboardNavigation
625+
.blocklyWorkspace:has(.blocklyActiveFocus)
626+
.blocklyWorkspaceFocusRing,
627+
/* Active focus within drag layer. */
628+
.blocklyKeyboardNavigation
629+
.blocklySvg:has(~ .blocklyBlockDragSurface .blocklyActiveFocus)
630+
.blocklyWorkspaceFocusRing,
631+
/* Active focus on workspace. */
632+
.blocklyKeyboardNavigation
633+
.blocklyWorkspace.blocklyActiveFocus
634+
.blocklyWorkspaceFocusRing,
635+
/* Focus in widget/dropdown div considered to be in workspace. */
636+
.blocklyKeyboardNavigation:has(
637+
.blocklyWidgetDiv:focus-within,
638+
.blocklyDropDownDiv:focus-within
639+
)
640+
.blocklyWorkspace
641+
.blocklyWorkspaceFocusRing {
642+
stroke: var(--blockly-active-tree-color);
643+
stroke-width: calc(var(--blockly-selection-width) * 2);
644+
}
645+
646+
/* The workspace itself is the active node. */
647+
.blocklyKeyboardNavigation
648+
.blocklyWorkspace.blocklyActiveFocus
649+
.blocklyWorkspaceSelectionRing {
650+
stroke: var(--blockly-active-node-color);
651+
stroke-width: var(--blockly-selection-width);
652+
}
653+
654+
/* The workspace itself is the active node. */
655+
.blocklyKeyboardNavigation
656+
.blocklyBubble.blocklyActiveFocus
657+
.blocklyDraggable {
658+
stroke: var(--blockly-active-node-color);
659+
stroke-width: var(--blockly-selection-width);
660+
}
539661
`;

packages/blockly/core/renderers/common/constants.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,9 @@ export class ConstantProvider {
11531153
protected getCSS_(selector: string): string[] {
11541154
// prettier-ignore
11551155
return [
1156+
`${selector}.injectionDiv {`,
1157+
`--blockly-active-node-color: #fc3;`,
1158+
`}`,
11561159
// Text.
11571160
`${selector} .blocklyText, `,
11581161
`${selector} .blocklyFlyoutLabelText {`,

0 commit comments

Comments
 (0)