feat(system): add ref to popover and tooltip triggers

This commit is contained in:
Pavel Prichodko 2022-04-06 10:37:53 +02:00
parent 12b0e9d715
commit 2dbc20f7a8
No known key found for this signature in database
GPG Key ID: 8E4C82D464215E83
2 changed files with 33 additions and 17 deletions

View File

@ -1,40 +1,45 @@
import React, { forwardRef } from 'react' import React, { cloneElement, forwardRef } from 'react'
import * as Primitive from '@radix-ui/react-popover' import * as Primitive from '@radix-ui/react-popover'
import { Content } from './styles' import { Content } from './styles'
import type { PopoverContentProps } from '@radix-ui/react-popover'
import type { Ref } from 'react'
interface TriggerProps { interface TriggerProps {
children: [React.ReactElement, React.ReactElement] children: [React.ReactElement, React.ReactElement]
} }
const PopoverTrigger = (props: TriggerProps) => { const PopoverTrigger = (props: TriggerProps, ref: Ref<HTMLButtonElement>) => {
const { children } = props const { children, ...triggerProps } = props
const [trigger, content] = children const [trigger, content] = children
return ( return (
<Primitive.Root> <Primitive.Root>
<Primitive.Trigger asChild>{trigger}</Primitive.Trigger> <Primitive.Trigger asChild>
{cloneElement(trigger, { ref, ...triggerProps })}
</Primitive.Trigger>
{content} {content}
</Primitive.Root> </Primitive.Root>
) )
} }
interface PopoverProps { const _PopoverTrigger = forwardRef(PopoverTrigger)
interface PopoverProps extends PopoverContentProps {
children: React.ReactNode children: React.ReactNode
} }
const Popover = (props: PopoverProps, ref) => { const Popover = (props: PopoverProps) => {
const { children } = props const { children, ...contentProps } = props
return ( return (
<Content as={Primitive.Content} portalled={true} ref={ref}> <Content as={Primitive.Content} {...contentProps}>
{children} {children}
</Content> </Content>
) )
} }
const _Popover = forwardRef(Popover) export { Popover, _PopoverTrigger as PopoverTrigger }
export { _Popover as Popover, PopoverTrigger }

View File

@ -1,24 +1,33 @@
import React from 'react' import React, { cloneElement, forwardRef } from 'react'
import * as Primitive from '@radix-ui/react-tooltip' import * as Primitive from '@radix-ui/react-tooltip'
import { Arrow, Content } from './styles' import { Arrow, Content } from './styles'
import type { TooltipContentProps } from '@radix-ui/react-tooltip' import type { TooltipContentProps } from '@radix-ui/react-tooltip'
import type { Ref } from 'react'
interface Props { interface Props {
label: string label: string
children: React.ReactNode children: React.ReactElement
side?: TooltipContentProps['side'] side?: TooltipContentProps['side']
sideOffset?: TooltipContentProps['sideOffset'] sideOffset?: TooltipContentProps['sideOffset']
} }
const Tooltip = (props: Props) => { const Tooltip = (props: Props, ref: Ref<HTMLButtonElement>) => {
const { children, label, side = 'top', sideOffset = 5 } = props const {
children,
label,
side = 'top',
sideOffset = 5,
...triggerProps
} = props
return ( return (
<Primitive.Root delayDuration={500}> <Primitive.Root delayDuration={500}>
<Primitive.Trigger asChild>{children}</Primitive.Trigger> <Primitive.Trigger asChild>
{cloneElement(children, { ref, ...triggerProps })}
</Primitive.Trigger>
<Content side={side} sideOffset={sideOffset}> <Content side={side} sideOffset={sideOffset}>
{label} {label}
<Arrow /> <Arrow />
@ -27,5 +36,7 @@ const Tooltip = (props: Props) => {
) )
} }
export { Tooltip } const _Tooltip = forwardRef(Tooltip)
export { _Tooltip as Tooltip }
export type { Props as TooltipProps } export type { Props as TooltipProps }