@@ -10,12 +10,12 @@ import type { Component } from "solid-js";
1010import type { ArrowPosition , SelectionLabelProps } from "../../types.js" ;
1111import {
1212 VIEWPORT_MARGIN_PX ,
13- ARROW_HEIGHT_PX ,
1413 ARROW_CENTER_PERCENT ,
1514 ARROW_LABEL_MARGIN_PX ,
1615 LABEL_GAP_PX ,
1716 PANEL_STYLES ,
1817} from "../../constants.js" ;
18+ import { getArrowSize } from "../../utils/get-arrow-size.js" ;
1919import { isKeyboardEventTriggeredByInput } from "../../utils/is-keyboard-event-triggered-by-input.js" ;
2020import { cn } from "../../utils/cn.js" ;
2121import { getTagDisplay } from "../../utils/get-tag-display.js" ;
@@ -40,6 +40,7 @@ const DEFAULT_OFFSCREEN_POSITION = {
4040
4141export const SelectionLabel : Component < SelectionLabelProps > = ( props ) => {
4242 let containerRef : HTMLDivElement | undefined ;
43+ let panelRef : HTMLDivElement | undefined ;
4344 let inputRef : HTMLTextAreaElement | undefined ;
4445 let isTagCurrentlyHovered = false ;
4546 let lastValidPosition : {
@@ -53,6 +54,7 @@ export const SelectionLabel: Component<SelectionLabelProps> = (props) => {
5354
5455 const [ measuredWidth , setMeasuredWidth ] = createSignal ( 0 ) ;
5556 const [ measuredHeight , setMeasuredHeight ] = createSignal ( 0 ) ;
57+ const [ panelWidth , setPanelWidth ] = createSignal ( 0 ) ;
5658 const [ arrowPosition , setArrowPosition ] =
5759 createSignal < ArrowPosition > ( "bottom" ) ;
5860 const [ viewportVersion , setViewportVersion ] = createSignal ( 0 ) ;
@@ -89,6 +91,9 @@ export const SelectionLabel: Component<SelectionLabelProps> = (props) => {
8991 setMeasuredWidth ( rect . width ) ;
9092 setMeasuredHeight ( rect . height ) ;
9193 }
94+ if ( panelRef ) {
95+ setPanelWidth ( panelRef . getBoundingClientRect ( ) . width ) ;
96+ }
9297 } ;
9398
9499 const handleTagHoverChange = ( hovered : boolean ) => {
@@ -215,11 +220,13 @@ export const SelectionLabel: Component<SelectionLabelProps> = (props) => {
215220 const selectionBottom = bounds . y + bounds . height ;
216221 const selectionTop = bounds . y ;
217222
223+ const actualArrowHeight = getArrowSize ( panelWidth ( ) ) ;
224+
218225 // HACK: Use cursorX as anchor point, CSS transform handles centering via translateX(-50%)
219226 // This avoids the flicker when content changes because centering doesn't depend on JS measurement
220227 const anchorX = cursorX ;
221228 let edgeOffsetX = 0 ;
222- let positionTop = selectionBottom + ARROW_HEIGHT_PX + LABEL_GAP_PX ;
229+ let positionTop = selectionBottom + actualArrowHeight + LABEL_GAP_PX ;
223230
224231 // Calculate edge clamping offset (only applied when we have valid measurements)
225232 if ( labelWidth > 0 ) {
@@ -234,7 +241,7 @@ export const SelectionLabel: Component<SelectionLabelProps> = (props) => {
234241 }
235242 }
236243
237- const totalHeightNeeded = labelHeight + ARROW_HEIGHT_PX + LABEL_GAP_PX ;
244+ const totalHeightNeeded = labelHeight + actualArrowHeight + LABEL_GAP_PX ;
238245 const fitsBelow =
239246 positionTop + labelHeight <= viewportHeight - VIEWPORT_MARGIN_PX ;
240247
@@ -371,6 +378,7 @@ export const SelectionLabel: Component<SelectionLabelProps> = (props) => {
371378 position = { arrowPosition ( ) }
372379 leftPercent = { computedPosition ( ) . arrowLeftPercent }
373380 leftOffsetPx = { computedPosition ( ) . arrowLeftOffset }
381+ labelWidth = { panelWidth ( ) }
374382 />
375383
376384 < Show when = { isCompletedStatus ( ) && ! props . error } >
@@ -394,6 +402,7 @@ export const SelectionLabel: Component<SelectionLabelProps> = (props) => {
394402 </ Show >
395403
396404 < div
405+ ref = { panelRef }
397406 class = { cn (
398407 "contain-layout flex items-center gap-[5px] rounded-[10px] antialiased w-fit h-fit p-0 [font-synthesis:none] [corner-shape:superellipse(1.25)]" ,
399408 PANEL_STYLES ,
0 commit comments