Replies: 8 comments
-
Can you provide an example with the code of what you're trying to do? Happy to help. |
Beta Was this translation helpful? Give feedback.
-
I'm not really able to understand exactly what you're trying to do. Do you mean something like this? @jjones315 <script lang="ts">
import { Button } from '$lib/components/ui/button'
import { Tooltip } from 'bits-ui'
</script>
<Tooltip.Root>
<Tooltip.Trigger>
{#snippet child({ props })}
<Button variant="ghost" {...props}>
Hover to open
</Button>
{/snippet}
</Tooltip.Trigger>
</Tooltip.Root> |
Beta Was this translation helpful? Give feedback.
-
Sorry, i meant to add an example. brain isn't working today 😅. yes that is effectively what i have. Button is an internal based of next-ui styles, but shadcn works fine as a substitute, its using tallwind-variants to create classes from variants. Toolstip.svelte <script lang="ts">
import { cn } from "$ui/utils";
import { Tooltip } from "bits-ui";
import type { TooltipProps } from ".";
let {
delayDuration = 300,
skipDelayDuration,
disableHoverableContent,
disableCloseOnTriggerClick,
disabled,
ignoreNonKeyboardFocus,
// root
open = $bindable(false),
onOpenChange,
portal = "body",
// content
content,
contentProps,
side = "bottom",
sideOffset = 10,
transition,
// trigger
triggerRef = $bindable(),
class: className,
classes,
...otherProps
}: TooltipProps = $props();
</script>
<Tooltip.Provider
{delayDuration}
{disableCloseOnTriggerClick}
{disableHoverableContent}
{disabled}
{ignoreNonKeyboardFocus}
{skipDelayDuration}
>
<Tooltip.Root
{delayDuration}
{disableCloseOnTriggerClick}
{disableHoverableContent}
{disabled}
{ignoreNonKeyboardFocus}
{onOpenChange}
bind:open
>
<Tooltip.Trigger class={cn("outline-none", className, classes?.trigger)} tabindex={-1} {...otherProps} />
{#if content}
<Tooltip.Portal to={portal}>
<Tooltip.Content
style="transform: translate({open ? 0 : 8}px);"
class={cn(
"z-[100000] rounded-lg border bg-content1 p-2 text-sm text-foreground shadow-md transition-all",
classes?.content,
{
"scale-80 opacity-0": !open,
"translate-x-4": !open && side === "left",
"-translate-x-4": !open && side === "right",
"translate-y-4": !open && side === "top",
"-translate-y-4": !open && side === "bottom",
}
)}
{...contentProps}
forceMount
{side}
{sideOffset}
>
{#if typeof content === "string"}
{content}
{:else}
{@render content()}
{/if}
</Tooltip.Content>
</Tooltip.Portal>
{/if}
</Tooltip.Root>
</Tooltip.Provider> example usage <!-- works fine, but has type errors from button variants on Tooltip -->
<Tooltip
class="text-neutral-500"
color="default"
content="Edit Email"
isIconOnly
onclick={handleEditEmail}
radius="full"
size="sm"
variant="light"
>
{#snippet child({ props })}
<Button {...props}>
<Icon name="material-symbols/edit" class="text-xl" />
</Button>
{/snippet}
</Tooltip>
<!-- works fine, but have to modify every delegated component type to use mergeProps Internally -->
<Tooltip
class="text-neutral-500"
content={showPasswordText ? "Hide Password" : "Show Password"}
>
{#snippet child({ props })}
<Button
class="text-neutral-500"
as="span"
delegateProps={props}
isIconOnly
onclick={() => (showPasswordText = !showPasswordText)}
radius="full"
size="sm"
variant="light"
>
{#if showPasswordText}
<Icon
name="material-symbols/visibility-off"
class="pointer-events-none text-xl"
/>
{:else}
<Icon name="material-symbols/visibility" class="pointer-events-none text-xl" />
{/if}
</Button>
{/snippet}
</Tooltip>
<!-- this was the initial conversion i had after updating bits-ui. onclick and class are obviously broken. -->
<Tooltip
class="text-neutral-500"
content={showPasswordText ? "Hide Password" : "Show Password"}
>
{#snippet child({ props })}
<Button
class="text-neutral-500"
as="span"
isIconOnly
onclick={() => (showPasswordText = !showPasswordText)}
radius="full"
size="sm"
variant="light"
{...props}
>
{#if showPasswordText}
<Icon
name="material-symbols/visibility-off"
class="pointer-events-none text-xl"
/>
{:else}
<Icon name="material-symbols/visibility" class="pointer-events-none text-xl" />
{/if}
</Button>
{/snippet}
</Tooltip> One other approach would be to put attributers on the thanks for any advice |
Beta Was this translation helpful? Give feedback.
-
Oh, here you just need to modify the type you're accepting at the top level: <script lang="ts">
import { cn } from "$ui/utils";
import { Tooltip } from "bits-ui";
import type { TooltipProps } from ".";
import type { ButtonVariants } from '$ui/somewhere'
type MyTooltipProps = TooltipProps & {
variant?: ButtonVariants;
// any other props you want to be typed...
}
// or you could do something like this
type MyTooltipProps = TooltipProps & ButtonProps
let {
// all your props
...otherProps
}: MyTooltipProps = $props();
</script> |
Beta Was this translation helpful? Give feedback.
-
You're combining several different components into one. Why not just inside the If you can link me a repo with some minimal code for this I'm happy to help make it click. |
Beta Was this translation helpful? Give feedback.
-
Yes, we use a lot of different components as triggers. Buttons, chips, styled links, avatars, etc… if we always used a button I would just embed it as you mentioned. I know you mentioned the fact I bundled the tooltip in to a component, not sure that changes the paradigm here? The same issues would arise with them separate? Not sure if I’m missing something there |
Beta Was this translation helpful? Give feedback.
-
I could make my tooltip generic and to get type safe props at the tooltip level. Any thought about adding generics at a library level or do you think it’s best to leave it to user land? |
Beta Was this translation helpful? Give feedback.
-
Can you elaborate on what mean by generics at the library level? What would these generics be applied to? |
Beta Was this translation helpful? Give feedback.
-
Change Type
Addition
Proposed Changes
While testing the bits-ui@next i ran in to some speed bumps i wanted to clarify, and also possibly improve guidance in docs.
When using the tooltip with the child snippet for example, i want to have a pre-styled button as the trigger. for example a shadcn button where variants create a set of classes and they are not directly passed. but the child props are overriding the styling since they are spreading. My 2 solutions are to put the variants on the Tooltip Trigger and loose types since the render delegation is not generic, or modify my button component to receive "delegateProps" and use the mergeProps utility internally. i dont think either of those soltutions are ideal, since on one hand i have to modify all of my possible delegates, or lose my variant types. was wondering if you had guidance or plan to address situtions like these.
Thanks for any guidance (and this library) :)
Beta Was this translation helpful? Give feedback.
All reactions