Replies: 9 comments 32 replies
-
You are 100% correct, this is a clash because they both use The easy solution is to namespace the state attributes but that would be a huge restriction on DX for all of the most common use cases. We'll need to think about this a lot more I think. In the meantime if you have some ideas/suggestions feel free to let us know! |
Beta Was this translation helpful? Give feedback.
-
@PhilGarb As you have realised, you can control all of our components to work around these sorts of issues in the meantime. export default function App() {
const [open, setOpen] = React.useState<boolean>();
return (
<Collapsible.Root open={open} onOpenChange={setOpen}>
<Tooltip.Root>
<Tooltip.Trigger
as={Collapsible.Button}
className={open ? 'open' : 'closed'} // or use `data-collapsible-state` if that's preferred :)
>
Open
</Tooltip.Trigger>
<Tooltip.Content>Tooltip</Tooltip.Content>
</Tooltip.Root>
<Collapsible.Content>Content</Collapsible.Content>
</Collapsible.Root>
);
} https://codesandbox.io/s/adoring-grass-xtukv?file=/src/App.tsx @benoitgrelard This has made me realise though that I had to do export default function App() {
const [open, setOpen] = React.useState<boolean>();
return (
<Collapsible.Root open={open} onOpenChange={setOpen}>
<Tooltip.Root>
- <Tooltip.Trigger
+ <Collapsible.Button
- as={Collapsible.Button}
+ as={Tooltip.Trigger}
className={open ? 'open' : 'closed'}
>
Open
- </Tooltip.Trigger>
+ </Collapsible.Button>
<Tooltip.Content>Tooltip</Tooltip.Content>
</Tooltip.Root>
<Collapsible.Content>Content</Collapsible.Content>
</Collapsible.Root>
);
} Something to investigate perhaps? |
Beta Was this translation helpful? Give feedback.
-
So i also encountered this issue. cannot combine a toggle with a tooltip. am i missing something? a resulting element could look like:
it fixes everything, the DX is far better than having to manage the state and it's a far more standard way of doing things IMO. |
Beta Was this translation helpful? Give feedback.
-
I'm having the similar issue with Popover + Tooltip. To get the Popover + Tooltip to work I has to use const MixerButton = () => (
<Tooltip>
<TooltipTrigger asChild>
<IconButton aria-label="Update dimensions">
<MixerHorizontalIcon />
</IconButton>
</TooltipTrigger>
<TooltipContent sideOffset={5}>Add to library</TooltipContent>
</Tooltip>
);
const PopoverDemo = () => (
<Popover>
<PopoverTrigger as="div">
<MixerButton />
</PopoverTrigger>
<PopoverContent sideOffset={5}>
<Tooltip>
<TooltipTrigger>here</TooltipTrigger>
<TooltipContent sideOffset={5}>Testing</TooltipContent>
</Tooltip>
</PopoverContent>
</Popover>
); If I restructure the markup to the following:
It works (I.e the tooltip and popover both work) but then that means I can't use an API like the example given in the docs
So to get it to work I'd have to change my components API to match Radix's exactly. The |
Beta Was this translation helpful? Give feedback.
-
I ran into this with Toolbar ToggleItems/Buttons, solution was to add a span around the trigger to prevent it creating two nested button OR mangling data-state
|
Beta Was this translation helpful? Give feedback.
-
Has any progress been made on resolving the |
Beta Was this translation helpful? Give feedback.
-
Just chiming in with a solution I settled on when using multiple Radix components on the same trigger, like a tooltip and a dropdown menu on the same button. My use case is that I have custom design system components like // Problem
function MyButtonWithTooltipAndDropdown() {
return (
// ↓ MyDropdownMenu passes Radix props onto MyTooltip instead of intended Button
<MyDropdownMenu>
<MyTooltip>
<Button>Click me!</Button>
</MyTooltip>
</MyDropdownMenu>
)
} The problem here is that For this I created a import { Slot } from '@radix-ui/react-slot'
import { cloneElement, forwardRef } from 'react'
interface ForwardPropsToChildProps {
children: React.ReactElement<{ children: React.ReactNode }>
}
export const ForwardPropsToChild = forwardRef<HTMLElement, ForwardPropsToChildProps>(
function ForwardPropsToChild({ children, ...props }, ref) {
return cloneElement(
children,
undefined,
// Slot used so that callbacks, className, style, etc. are composed together instead of replaced.
<Slot ref={ref} {...props}>
{children.props.children}
</Slot>,
)
},
) This then can be used like the following code snippet to forward props to the intended component. // Solution
function MyButtonWithTooltipAndDropdown() {
return (
// ↓ MyDropdownMenu passes Radix props onto ForwardPropsToChild
<MyDropdownMenu>
{/* ↓ ForwardPropsToChild forwards Radix props to Button */}
<ForwardPropsToChild>
<MyTooltip>
<Button>Click me!</Button>
</MyTooltip>
</ForwardPropsToChild>
</MyDropdownMenu>
)
} I think it would be nicer to be able to get the props with a Side note: This doesn't solve the issue with clashing states like |
Beta Was this translation helpful? Give feedback.
-
To avoid collisions, |
Beta Was this translation helpful? Give feedback.
-
Is there still no progress on this? I wanted to have tooltip for toggle component and I was faced with the same problem. Toggle's "data-state" property doesn't update therefor classes based on data-state don't apply. <TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Toggle pressed={pressed} onPressedChange={setPressed}>
<FontItalicIcon />
</Toggle>
</TooltipTrigger>
<TooltipContent>
<p>Tooltip</p>
</TooltipContent>
</Tooltip>
</TooltipProvider> |
Beta Was this translation helpful? Give feedback.
-
Hi everyone,
I have a problem when using the Tooltip together with the Collapsible Trigger. I am styling the trigger based on data-state="open" to signal the open state to the user. When wrapping the Trigger in a custom Tooltip component, as described here: Radix Docs, the data-state attribute is overwritten by the Tooltips data-state.
I think a Tooltip should not really interfere in this way. I have tried to remove the Slot, but then I have two buttons both with their own data-state. This does however interfere with styling since in this case I have to change my styling to accommodate the deeper nesting.
I think the root cause is that all state is represented by only one attribute data-state and no way to distinguish states of different elements. Is there any way to make this work? Please let me know if you need a reproduction.
Beta Was this translation helpful? Give feedback.
All reactions