Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 69 additions & 31 deletions src/components/CodeWithCopyButton.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
'use client';

import { ContentCopy } from '@mui/icons-material';
import { Button, styled, Tooltip, useTheme } from '@mui/material';
import ViewHeadlineIcon from '@mui/icons-material/ViewHeadline';
import WrapTextIcon from '@mui/icons-material/WrapText';
import { Box, IconButton, styled, Tooltip } from '@mui/material';
import { message } from 'mui-message';
import { JSX, useRef } from 'react';

import { JSX, useRef, useState } from 'react';
const StyledCode = styled('code')(() => {
return {
'.copy-to-clipboard': {
'.code-tools': {
display: 'none',
},
'&:hover .copy-to-clipboard': {
display: 'flex',
'&:hover .code-tools': {
display: 'inline-flex',
},
};
});

export default function CodeWithCopyButton(
props: JSX.IntrinsicElements['code'],
) {
const theme = useTheme();
const ref = useRef(null);
const [breakWord, setBreakWord] = useState<boolean>(false);

const onCopy = async () => {
const text = (ref.current as unknown as HTMLElement)?.innerText || '';
Expand All @@ -38,30 +39,67 @@ export default function CodeWithCopyButton(
}

return (
<StyledCode {...props} ref={ref}>
<Tooltip title="Copy" placement="top">
<Button
variant="outlined"
className="copy-to-clipboard"
sx={{
position: 'absolute',
right: 8,
top: 8,
padding: 0.8,
minWidth: 'auto',
color: 'rgba(255, 255, 255, 0.5)',
borderColor: 'rgba(255, 255, 255, 0.3)',
background: '#1A1E22',
borderWidth: 1,
'&:hover': {
borderColor: theme.palette.primary.main,
},
}}
onClick={onCopy}
>
<ContentCopy fontSize="small" />
</Button>
</Tooltip>
<StyledCode
{...props}
style={{
whiteSpace: breakWord ? 'break-spaces' : undefined,
}}
ref={ref}
>
<Box
sx={{
position: 'absolute',
right: 8,
top: 8,
display: 'flex',
flexDirection: 'row',
gap: 1,
}}
>
<Tooltip title="Word break" placement="top" arrow>
<IconButton
className="code-tools"
size="small"
sx={{
color: breakWord ? '#FFF' : 'rgba(255, 255, 255, 0.5)',
background: '#1A1E22',
border: '1px solid rgba(255, 255, 255, 0.3)',
borderRadius: 2,
'&:hover': {
color: '#FFF',
background: '#1A1E22',
},
}}
onClick={() => setBreakWord(!breakWord)}
>
{breakWord ? (
<ViewHeadlineIcon sx={{ transform: 'scale(0.8)' }} />
) : (
<WrapTextIcon sx={{ transform: 'scale(0.8)' }} />
)}
</IconButton>
</Tooltip>
<Tooltip title="Copy" placement="top" arrow>
<IconButton
className="code-tools"
size="small"
sx={{
color: 'rgba(255, 255, 255, 0.5)',
background: '#1A1E22',
border: '1px solid rgba(255, 255, 255, 0.3)',
borderRadius: 2,
'&:hover': {
color: '#FFF',
background: '#1A1E22',
},
}}
color="inherit"
onClick={onCopy}
>
<ContentCopy sx={{ transform: 'scale(0.8)' }} />
</IconButton>
</Tooltip>
</Box>
{props.children}
</StyledCode>
);
Expand Down