({
value,
side = "bottom",
children,
className,
role,
tabIndex,
onClick,
onKeyDown,
onKeyUp,
...attrs
})
| 16 | } |
| 17 | |
| 18 | export const CopyableValue: FC<CopyableValueProps> = ({ |
| 19 | value, |
| 20 | side = "bottom", |
| 21 | children, |
| 22 | className, |
| 23 | role, |
| 24 | tabIndex, |
| 25 | onClick, |
| 26 | onKeyDown, |
| 27 | onKeyUp, |
| 28 | ...attrs |
| 29 | }) => { |
| 30 | const { showCopiedSuccess, copyToClipboard } = useClipboard(); |
| 31 | const [tooltipOpen, setTooltipOpen] = useState(false); |
| 32 | const [isFocused, setIsFocused] = useState(false); |
| 33 | const clickableProps = useClickable<HTMLSpanElement>(() => { |
| 34 | copyToClipboard(value); |
| 35 | setTooltipOpen(true); |
| 36 | }); |
| 37 | |
| 38 | return ( |
| 39 | <Tooltip |
| 40 | open={tooltipOpen} |
| 41 | onOpenChange={(shouldBeOpen) => { |
| 42 | // Always keep the tooltip open when in focus to handle issues when onOpenChange is unexpectedly false |
| 43 | if (!shouldBeOpen && isFocused) return; |
| 44 | setTooltipOpen(shouldBeOpen); |
| 45 | }} |
| 46 | > |
| 47 | <TooltipTrigger asChild> |
| 48 | <span |
| 49 | ref={clickableProps.ref} |
| 50 | {...attrs} |
| 51 | className={cn("cursor-pointer", className)} |
| 52 | role={role ?? clickableProps.role} |
| 53 | tabIndex={tabIndex ?? clickableProps.tabIndex} |
| 54 | onClick={(event) => { |
| 55 | clickableProps.onClick(event); |
| 56 | onClick?.(event); |
| 57 | }} |
| 58 | onKeyDown={(event) => { |
| 59 | clickableProps.onKeyDown(event); |
| 60 | onKeyDown?.(event); |
| 61 | }} |
| 62 | onKeyUp={(event) => { |
| 63 | clickableProps.onKeyUp(event); |
| 64 | onKeyUp?.(event); |
| 65 | }} |
| 66 | onMouseEnter={() => { |
| 67 | setIsFocused(true); |
| 68 | setTooltipOpen(true); |
| 69 | }} |
| 70 | onMouseLeave={() => { |
| 71 | setTooltipOpen(false); |
| 72 | }} |
| 73 | onFocus={() => { |
| 74 | setIsFocused(true); |
| 75 | }} |
nothing calls this directly
no test coverage detected