11import { useState , type DragEvent } from 'react' ;
2- import { parseMiniMessage } from '../../editor/miniMessage' ;
32import { ItemIcon } from './ItemIcon' ;
3+ import { ItemTooltip } from './ItemTooltip' ;
44import type { VisualItem } from '../../editor/model' ;
55
66const MATERIAL_DRAG_TYPE = 'application/x-bluemenu-material' ;
@@ -32,6 +32,7 @@ export function MenuCanvas({
3232 onContextMenu,
3333} : MenuCanvasProps ) {
3434 const [ hoveredSlot , setHoveredSlot ] = useState < number | null > ( null ) ;
35+ const [ tooltip , setTooltip ] = useState < { item : VisualItem ; x : number ; y : number } | null > ( null ) ;
3536
3637 const handleDrop = ( event : DragEvent < HTMLDivElement > , slot : number ) : void => {
3738 event . preventDefault ( ) ;
@@ -53,7 +54,10 @@ export function MenuCanvas({
5354 } ;
5455
5556 return (
56- < div className = "menu-canvas" style = { { gridTemplateColumns : 'repeat(9, 60px)' } } >
57+ < >
58+ { tooltip !== null && < ItemTooltip item = { tooltip . item } x = { tooltip . x } y = { tooltip . y } /> }
59+
60+ < div className = "menu-canvas" style = { { gridTemplateColumns : 'repeat(9, 60px)' } } >
5761 { Array . from ( { length : size } , ( _unused , slot ) => {
5862 const item = items [ slot ] ;
5963
@@ -81,7 +85,13 @@ export function MenuCanvas({
8185 onDragEnter = { ( ) => setHoveredSlot ( slot ) }
8286 onDragLeave = { ( ) => setHoveredSlot ( current => ( current === slot ? null : current ) ) }
8387 onDrop = { event => handleDrop ( event , slot ) }
84- title = { tooltipFor ( item , slot ) }
88+ onMouseEnter = { event =>
89+ item !== undefined && setTooltip ( { item, x : event . clientX , y : event . clientY } )
90+ }
91+ onMouseMove = { event =>
92+ item !== undefined && setTooltip ( { item, x : event . clientX , y : event . clientY } )
93+ }
94+ onMouseLeave = { ( ) => setTooltip ( null ) }
8595 aria-label = { item === undefined ? `Empty slot ${ slot } ` : `${ item . material } in slot ${ slot } ` }
8696 >
8797 < span className = "slot-number" > { slot } </ span >
@@ -96,25 +106,7 @@ export function MenuCanvas({
96106 </ div >
97107 ) ;
98108 } ) }
99- </ div >
109+ </ div >
110+ </ >
100111 ) ;
101112}
102-
103- function tooltipFor ( item : VisualItem | undefined , slot : number ) : string {
104- if ( item === undefined ) {
105- return `Slot ${ slot } ` ;
106- }
107-
108- // The name carries MiniMessage tags, which are noise in a native tooltip.
109- const name = typeof item . name === 'string' ? stripMarkup ( item . name ) : item . material ;
110-
111- return `${ name } (slot ${ slot } )` ;
112- }
113-
114- function stripMarkup ( name : string ) : string {
115- const rendered = parseMiniMessage ( name ) ;
116- const container = document . createElement ( 'div' ) ;
117- container . innerHTML = rendered ;
118-
119- return container . textContent ?? name ;
120- }
0 commit comments