0

I’m designing an input component with a small indicator icon that shows a tooltip (with feedback for the user). The tooltip can be opened by pressing ?, F1, or hovering over the icon, and closed with Esc.

However, when the user presses Tab to move from the input field to the next button, I don’t want the tooltip trigger (the icon) to receive focus and add an intermediate step. Right now, pressing Tab highlights the tooltip icon before moving on to the next element.

Here’s the relevant part of my component:

<div class="relative flex ...">
  <input
    class="..."
    bind:this={userInputRef}
  />

  {#if mode === "draft"}
    <span
      class={`absolute -top-1 -right-1 flex h-4 w-4 ...`}
    >
      {#if feedback !== ""}
        <Tooltip.Provider>
          <MyTooltip
            open={showTooltip}
            onOpenChange={(open) => (showTooltip = open)}
            contentProps={{
              side: "top",
              sideOffset: 5,
              class: "...",
            }}
          >
            {#snippet trigger()}
              <div class="cursor-pointer p-2">
                <InputFieldIcon {mode} />
              </div>
            {/snippet}
            some text
          </MyTooltip>
        </Tooltip.Provider>
      {:else}
        <InputFieldIcon {mode} />
      {/if}
    </span>
  {/if}
</div>

And here’s my custom Tooltip component (small adjustment to bits-ui):

<script lang="ts">
  import { Tooltip } from "bits-ui"
  import type { Snippet } from "svelte"

  type Props = Tooltip.RootProps & {
    trigger: Snippet
    rootProps?: Tooltip.RootProps
    triggerProps?: Tooltip.TriggerProps
    contentProps?: Tooltip.ContentProps
  }

  let {
    open = $bindable(false),
    trigger,
    children,
    rootProps = {},
    triggerProps = {},
    contentProps = {},
  }: Props = $props()
</script>

<Tooltip.Root delayDuration={50} disableHoverableContent={true} bind:open {...rootProps}>
  <Tooltip.Trigger {...triggerProps}>
    {@render trigger()}
  </Tooltip.Trigger>
  <Tooltip.Portal>
    <Tooltip.Content {...contentProps}>
      <div
        class="z-0 outline-hidden ..."
      >
        {@render children?.()}
      </div>
    </Tooltip.Content>
  </Tooltip.Portal>
</Tooltip.Root>

I want that if the user enters text in the input component and presses tab to jump to the next input field or a button, i don't want the intermediate state jumping to the Tooltip.

If the user presses Tab while typing in the input, I want focus to skip the tooltip icon entirely and go to the next focusable element (e.g. a button).

What I’ve tried

  • Setting tabindex="-1" on:
    • The <MyTooltip> component
    • The <div> containing the icon Didn’t work — the tooltip still gets focus.
  • Using onOpenChange to block keyboard-based openings, allowing only mouse interactions. -Didn’t help either._

How can I prevent the tooltip trigger from being focusable via Tab, but still allow it to be opened with ?, F1, or hover?

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.