fix(stammbaum): SVG node font 14→16px and reliable keyboard focus ring
CSS box-shadow rings (focus-visible:ring-*) are invisible inside SVG. Replace with a conditional <rect> drawn at -3px offset that renders in all browsers. Name font-size bumped from 14 to 16px for the 60+ transcriber audience (WCAG readability, Leonie medium concerns). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -286,6 +286,8 @@ function nodeCenter(id: string): { x: number; y: number } | null {
|
||||
return { x: p.x + NODE_W / 2, y: p.y + NODE_H / 2 };
|
||||
}
|
||||
|
||||
let focusedId = $state<string | null>(null);
|
||||
|
||||
function handleNodeKey(event: KeyboardEvent, id: string) {
|
||||
if (event.key === 'Enter' || event.key === ' ') {
|
||||
event.preventDefault();
|
||||
@@ -479,6 +481,7 @@ const parentLinks = $derived.by<ParentLinks>(() => {
|
||||
{@const pos = layout.positions.get(node.id)}
|
||||
{#if pos}
|
||||
{@const isSelected = selectedId === node.id}
|
||||
{@const isFocused = focusedId === node.id}
|
||||
<g
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@@ -489,8 +492,22 @@ const parentLinks = $derived.by<ParentLinks>(() => {
|
||||
transform="translate({pos.x}, {pos.y})"
|
||||
onclick={() => onSelect(node.id)}
|
||||
onkeydown={(e) => handleNodeKey(e, node.id)}
|
||||
class="cursor-pointer focus:outline-none focus-visible:ring-2 focus-visible:ring-primary"
|
||||
onfocus={() => (focusedId = node.id)}
|
||||
onblur={() => (focusedId = null)}
|
||||
class="cursor-pointer focus:outline-none"
|
||||
>
|
||||
{#if isFocused}
|
||||
<rect
|
||||
x="-3"
|
||||
y="-3"
|
||||
width={NODE_W + 6}
|
||||
height={NODE_H + 6}
|
||||
rx="6"
|
||||
fill="none"
|
||||
stroke="var(--c-focus-ring)"
|
||||
stroke-width="2"
|
||||
/>
|
||||
{/if}
|
||||
<rect
|
||||
width={NODE_W}
|
||||
height={NODE_H}
|
||||
@@ -504,10 +521,10 @@ const parentLinks = $derived.by<ParentLinks>(() => {
|
||||
{/if}
|
||||
<text
|
||||
x={NODE_W / 2}
|
||||
y={NODE_H / 2 - 4}
|
||||
y={NODE_H / 2 - 6}
|
||||
text-anchor="middle"
|
||||
font-family="serif"
|
||||
font-size="14"
|
||||
font-size="16"
|
||||
fill={isSelected ? 'var(--c-primary-fg)' : 'var(--c-ink)'}
|
||||
>
|
||||
{node.displayName}
|
||||
|
||||
Reference in New Issue
Block a user