@@ -29,9 +29,9 @@ const MORPHEME_BOX_STRING_KEYS = [
2929 *
3030 * The whole forms row is a single accessible "edit breakdown" control rather than one labeled
3131 * button per morpheme: every form cell opens the same whole-breakdown editor, so per-cell labels
32- * would be redundant for assistive tech. Hovering any form cell tints the whole forms row (the
33- * action is breakdown-wide, not per-morpheme), tracked with local hover state. While the editor
34- * popover is open the box takes an accent ring so it reads as the one being edited.
32+ * would be redundant for assistive tech. Hovering anywhere in the box tints the whole forms row
33+ * (the action is breakdown-wide, not per-morpheme), tracked with local hover state. While the
34+ * editor popover is open the box takes an accent ring so it reads as the one being edited.
3535 *
3636 * Renders the {@link PopoverAnchor} the editor popover is positioned from; the caller owns the
3737 * `Popover` root and the popover content.
@@ -65,8 +65,10 @@ export function MorphemeBox({
6565 onEditBreakdown : ( ) => void ;
6666} > ) {
6767 const [ localizedStrings ] = useLocalizedStrings ( MORPHEME_BOX_STRING_KEYS ) ;
68- // Hovering any form cell tints the whole forms row: clicking any cell opens the same
69- // whole-breakdown editor, so the affordance is breakdown-wide, not per-morpheme.
68+ // Hovering anywhere in the box tints the whole forms row: clicking any cell opens the same
69+ // whole-breakdown editor, so the affordance is breakdown-wide, not per-morpheme. Tracking hover
70+ // on the container (rather than per cell) avoids a one-frame un-tint as the pointer crosses the
71+ // gap between adjacent form cells.
7072 const [ isFormsHovered , setIsFormsHovered ] = useState ( false ) ;
7173
7274 const editLabel = localizedStrings [ '%interlinearizer_tokenChip_editMorphemes%' ] . replace (
@@ -79,6 +81,8 @@ export function MorphemeBox({
7981 < div
8082 className = { `tw:inline-grid tw:w-fit tw:items-center tw:gap-x-0.5 tw:gap-y-0.5 tw:rounded tw:border tw:border-border tw:bg-background tw:p-0.5${ popoverOpen ? ' tw:ring-1 tw:ring-ring' : '' } ` }
8183 style = { { gridTemplateColumns : `repeat(${ morphemes . length } , minmax(1ch, auto))` } }
84+ onMouseEnter = { ( ) => setIsFormsHovered ( true ) }
85+ onMouseLeave = { ( ) => setIsFormsHovered ( false ) }
8286 >
8387 { /* Forms row. The first cell is the single accessible "edit breakdown" control (a real
8488 button); the rest are presentational form cells that share its click and hover behavior
@@ -91,8 +95,6 @@ export function MorphemeBox({
9195 const handleClick = ( ) => {
9296 if ( ! disabled ) onEditBreakdown ( ) ;
9397 } ;
94- const handleMouseEnter = ( ) => setIsFormsHovered ( true ) ;
95- const handleMouseLeave = ( ) => setIsFormsHovered ( false ) ;
9698
9799 if ( i === 0 )
98100 return (
@@ -106,8 +108,6 @@ export function MorphemeBox({
106108 e . preventDefault ( ) ;
107109 handleClick ( ) ;
108110 } }
109- onMouseEnter = { handleMouseEnter }
110- onMouseLeave = { handleMouseLeave }
111111 >
112112 { m . form }
113113 </ button >
@@ -120,8 +120,6 @@ export function MorphemeBox({
120120 className = { formClassName }
121121 style = { formStyle }
122122 onClick = { handleClick }
123- onMouseEnter = { handleMouseEnter }
124- onMouseLeave = { handleMouseLeave }
125123 >
126124 { m . form }
127125 </ span >
0 commit comments