mirror of
https://github.com/lux-tel/websites.git
synced 2026-10-30 20:31:36 +00:00
125 lines
4.6 KiB
TypeScript
125 lines
4.6 KiB
TypeScript
'use client';
|
|
|
|
import { collapseString } from '@session/util-crypto/string';
|
|
import { type HTMLAttributes, forwardRef, useCallback, useEffect, useMemo, useState } from 'react';
|
|
import { ButtonDataTestId } from '../data-test-ids';
|
|
import { cn } from '../lib/utils';
|
|
import { CopyToClipboardButton } from './CopyToClipboardButton';
|
|
import { Tooltip } from './ui/tooltip';
|
|
|
|
type CollapseStringsParams = Parameters<typeof collapseString>;
|
|
|
|
export type PubKeyProps = HTMLAttributes<HTMLDivElement> & {
|
|
pubKey: string;
|
|
pubKeyDisplayedOverride?: string;
|
|
leadingChars?: CollapseStringsParams[1];
|
|
trailingChars?: CollapseStringsParams[2];
|
|
expandOnHover?: boolean;
|
|
expandOnHoverDesktopOnly?: boolean;
|
|
alwaysShowCopyButton?: boolean;
|
|
force?: 'expand' | 'collapse';
|
|
copyToClipboardAriaLabel?: string;
|
|
copyToClipboardToastMessage?: string;
|
|
};
|
|
|
|
export const PubKey = forwardRef<HTMLDivElement, PubKeyProps>((props, ref) => {
|
|
const {
|
|
className,
|
|
pubKey,
|
|
pubKeyDisplayedOverride,
|
|
leadingChars = 6,
|
|
trailingChars = 6,
|
|
expandOnHover,
|
|
expandOnHoverDesktopOnly,
|
|
alwaysShowCopyButton,
|
|
copyToClipboardAriaLabel,
|
|
copyToClipboardToastMessage,
|
|
force,
|
|
...rest
|
|
} = props;
|
|
const [isExpanded, setIsExpanded] = useState(force === 'expand');
|
|
const collapsedPubKey = useMemo(
|
|
() => (pubKey ? collapseString(pubKey, leadingChars, trailingChars) : ''),
|
|
[pubKey, leadingChars, trailingChars]
|
|
);
|
|
|
|
const collapsedPubKeyOverride = useMemo(
|
|
() => (pubKeyDisplayedOverride ? collapseString(pubKeyDisplayedOverride, leadingChars, trailingChars) : ''),
|
|
[pubKeyDisplayedOverride, leadingChars, trailingChars]
|
|
)
|
|
|
|
const handleSelectionChange = useCallback(() => {
|
|
if (force === 'expand' || force === 'collapse') return;
|
|
setIsExpanded(window.getSelection()?.toString() === pubKey);
|
|
}, [pubKey, force]);
|
|
|
|
useEffect(() => {
|
|
/**
|
|
* Keeps the full pubkey visible when selected.
|
|
*/
|
|
document.addEventListener('selectionchange', handleSelectionChange);
|
|
return () => {
|
|
document.removeEventListener('selectionchange', handleSelectionChange);
|
|
};
|
|
}, [handleSelectionChange]);
|
|
|
|
const tooltipContent = <div className='flex text-wrap break-all align-middle'>
|
|
{pubKey}
|
|
{pubKeyDisplayedOverride ? <CopyToClipboardButton
|
|
className={cn(
|
|
'-mt-0.5 mx-1 p-0.5 opacity-100 duration-0 hover:bg-session-green hover:text-session-black hover:opacity-100 *:hover:fill-session-black'
|
|
)}
|
|
textToCopy={pubKey}
|
|
data-testid={ButtonDataTestId.Copy_Pub_Key_To_Clipboard}
|
|
aria-label={copyToClipboardAriaLabel ?? 'Copy to Clipboard'}
|
|
copyToClipboardToastMessage={copyToClipboardToastMessage ?? 'Copied to clipboard!'}
|
|
/> : null}
|
|
</div>
|
|
|
|
return (
|
|
<span ref={ref} className={cn('group flex select-all items-center', className)} {...rest}>
|
|
{!isExpanded ? (
|
|
<Tooltip tooltipContent={tooltipContent} triggerProps={{ disabled: expandOnHover }} >
|
|
<span
|
|
className={cn(
|
|
'select-all break-all',
|
|
force !== 'collapse' && expandOnHover && 'group-hover:hidden',
|
|
force !== 'collapse' && expandOnHover && isExpanded ? 'hidden' : 'block',
|
|
force !== 'collapse' && expandOnHoverDesktopOnly && 'md:group-hover:hidden',
|
|
force !== 'collapse' && expandOnHoverDesktopOnly && isExpanded
|
|
? 'md:hidden'
|
|
: 'md:block'
|
|
)}
|
|
>
|
|
{collapsedPubKeyOverride || collapsedPubKey}
|
|
</span>
|
|
</Tooltip>
|
|
) : null}
|
|
<div
|
|
className={cn(
|
|
'select-all break-all',
|
|
force !== 'collapse' && expandOnHover && 'group-hover:block',
|
|
(force !== 'collapse' && expandOnHover && isExpanded) || isExpanded ? 'block' : 'hidden',
|
|
force !== 'collapse' && expandOnHoverDesktopOnly && 'md:group-hover:block',
|
|
(force !== 'collapse' && expandOnHoverDesktopOnly && isExpanded) || isExpanded
|
|
? 'md:block'
|
|
: 'md:hidden'
|
|
)}
|
|
>
|
|
{pubKeyDisplayedOverride || pubKey}
|
|
</div>
|
|
<CopyToClipboardButton
|
|
className={cn(
|
|
'mx-1 p-0.5 duration-0 group-hover:bg-session-green group-hover:text-session-black group-hover:opacity-100 *:group-hover:fill-session-black',
|
|
alwaysShowCopyButton || isExpanded ? 'opacity-100' : 'opacity-0'
|
|
)}
|
|
textToCopy={pubKeyDisplayedOverride || pubKey}
|
|
data-testid={ButtonDataTestId.Copy_Pub_Key_To_Clipboard}
|
|
aria-label={copyToClipboardAriaLabel ?? 'Copy to Clipboard'}
|
|
copyToClipboardToastMessage={copyToClipboardToastMessage ?? 'Copied to clipboard!'}
|
|
/>
|
|
</span>
|
|
);
|
|
});
|
|
PubKey.displayName = 'PubKey';
|