@@ -106,6 +106,21 @@ defmodule Corex.Tooltip do
106106 end
107107 ```
108108
109+ ### Inside menu (or other roving-focus containers)
110+
111+ When a tooltip trigger sits inside a menu item, set `focusable={false}` on `<:trigger>` so
112+ open focus does not land on the trigger and open the tooltip. Prefer `trigger_tag={:span}`
113+ to avoid nested `<button>` elements inside `role="menuitem"`.
114+
115+ ```heex
116+ <.menu_item disabled value="support">
117+ <.tooltip class="tooltip tooltip--sm" trigger_tag={:span}>
118+ <:trigger focusable={false}>Support</:trigger>
119+ <:content>Coming soon</:content>
120+ </.tooltip>
121+ </.menu_item>
122+ ```
123+
109124 <!-- tabs-close -->
110125
111126 ## Style
@@ -271,6 +286,16 @@ defmodule Corex.Tooltip do
271286 "Trigger element content. Use :let={tooltip} for assigns such as disabled. With more than one <:trigger>, each must set value=\" …\" (unique, stable across LiveView patches)." do
272287 attr ( :class , :string , required: false )
273288 attr ( :value , :string , required: false )
289+
290+ attr ( :focusable , :boolean ,
291+ doc:
292+ "When false, the trigger is not tabbable (tabindex -1). Use inside menus or other roving-focus containers so focus does not open the tooltip. Defaults to true."
293+ )
294+
295+ attr ( :tabindex , :integer ,
296+ doc:
297+ "Explicit tabindex for the trigger. Overrides focusable when set. Tooltip disabled still forces -1."
298+ )
274299 end
275300
276301 slot :content ,
@@ -317,52 +342,16 @@ defmodule Corex.Tooltip do
317342 <%= if @ trigger_tag == :span do %>
318343 < span
319344 class = { Map . get ( t , :class , nil ) }
320- phx-mounted = {
321- Connect . ignore_trigger ( % Trigger {
322- id: @ id ,
323- dir: @ dir ,
324- open: false ,
325- disabled: @ disabled ,
326- orientation: @ orientation ,
327- tag: @ trigger_tag ,
328- value: Map . get ( t , :value )
329- } )
330- }
331- { Connect . trigger ( % Trigger {
332- id: @ id ,
333- dir: @ dir ,
334- open: false ,
335- disabled: @ disabled ,
336- orientation: @ orientation ,
337- tag: @ trigger_tag ,
338- value: Map . get ( t , :value )
339- } ) }
345+ phx-mounted = { Connect . ignore_trigger ( trigger_connect_assigns ( @ id , @ dir , @ orientation , @ disabled , @ trigger_tag , t ) ) }
346+ { Connect . trigger ( trigger_connect_assigns ( @ id , @ dir , @ orientation , @ disabled , @ trigger_tag , t ) ) }
340347 >
341348 { render_slot ( t , @ slot_assigns ) }
342349 </ span >
343350 <% else %>
344351 < button
345352 class = { Map . get ( t , :class , nil ) }
346- phx-mounted = {
347- Connect . ignore_trigger ( % Trigger {
348- id: @ id ,
349- dir: @ dir ,
350- open: false ,
351- disabled: @ disabled ,
352- orientation: @ orientation ,
353- tag: @ trigger_tag ,
354- value: Map . get ( t , :value )
355- } )
356- }
357- { Connect . trigger ( % Trigger {
358- id: @ id ,
359- dir: @ dir ,
360- open: false ,
361- disabled: @ disabled ,
362- orientation: @ orientation ,
363- tag: @ trigger_tag ,
364- value: Map . get ( t , :value )
365- } ) }
353+ phx-mounted = { Connect . ignore_trigger ( trigger_connect_assigns ( @ id , @ dir , @ orientation , @ disabled , @ trigger_tag , t ) ) }
354+ { Connect . trigger ( trigger_connect_assigns ( @ id , @ dir , @ orientation , @ disabled , @ trigger_tag , t ) ) }
366355 >
367356 { render_slot ( t , @ slot_assigns ) }
368357 </ button >
@@ -445,6 +434,20 @@ defmodule Corex.Tooltip do
445434 } )
446435 end
447436
437+ defp trigger_connect_assigns ( id , dir , orientation , disabled , trigger_tag , trigger_slot ) do
438+ % Trigger {
439+ id: id ,
440+ dir: dir ,
441+ open: false ,
442+ disabled: disabled ,
443+ orientation: orientation ,
444+ tag: trigger_tag ,
445+ value: Map . get ( trigger_slot , :value ) ,
446+ focusable: Map . get ( trigger_slot , :focusable , true ) ,
447+ tabindex: Map . get ( trigger_slot , :tabindex )
448+ }
449+ end
450+
448451 defp validate_triggers! ( triggers ) when is_list ( triggers ) do
449452 case triggers do
450453 [ ] ->
0 commit comments