mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
feat(site): tabs (#144)
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
import { useRef, useState } from 'react';
|
||||
import useIsHydrated from '@/utils/useIsHydrated';
|
||||
|
||||
export interface CopyButtonProps {
|
||||
children: React.ReactNode;
|
||||
copied?: React.ReactNode; // Optional, passed via slot="copied" in Astro
|
||||
copyFrom: {
|
||||
container: string; // CSS selector for parent container (e.g., 'starlight-tabs')
|
||||
target: string; // CSS selector for content element (e.g., '[role="tabpanel"]:not([hidden])')
|
||||
};
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
timeout?: number;
|
||||
}
|
||||
|
||||
export default function CopyButton({
|
||||
children,
|
||||
copied,
|
||||
copyFrom,
|
||||
className,
|
||||
style,
|
||||
timeout = 2000,
|
||||
}: CopyButtonProps) {
|
||||
const buttonRef = useRef<HTMLButtonElement>(null);
|
||||
const [isCopied, setIsCopied] = useState(false);
|
||||
const isHydrated = useIsHydrated();
|
||||
const disabled = !isHydrated;
|
||||
|
||||
const handleCopy = async () => {
|
||||
try {
|
||||
let text = '';
|
||||
|
||||
if (buttonRef.current) {
|
||||
// Find the closest container
|
||||
const container = buttonRef.current.closest(copyFrom.container);
|
||||
if (container) {
|
||||
// Find the target within that container
|
||||
const target = container.querySelector(copyFrom.target);
|
||||
text = target?.textContent || '';
|
||||
}
|
||||
}
|
||||
if (text) {
|
||||
await navigator.clipboard.writeText(text.trim());
|
||||
setIsCopied(true);
|
||||
setTimeout(() => {
|
||||
setIsCopied(false);
|
||||
}, timeout);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to copy text:', error);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<button
|
||||
ref={buttonRef}
|
||||
type="button"
|
||||
disabled={disabled}
|
||||
onClick={handleCopy}
|
||||
className={className}
|
||||
style={style}
|
||||
aria-label={isCopied ? 'Copied' : 'Copy to clipboard'}
|
||||
>
|
||||
{isCopied ? (copied || children) : children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user