Skip to content
1 change: 1 addition & 0 deletions src/components/codeBlock/code-blocks.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,5 @@
border: none;
color: var(--white);
transition: opacity 150ms;
z-index: 10000;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is really necessary, but should not interfere with anything else I think

}
29 changes: 28 additions & 1 deletion src/components/codeBlock/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,31 @@ export interface CodeBlockProps {
title?: string;
}

/**
*
* Copy `element`'s text children as long as long as they are not `.no-copy`
*/
function getCopiableText(element: HTMLDivElement) {
let text = '';
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT, {
acceptNode: function (node) {
// Skip if parent has .no-copy class
if (node.parentElement?.classList.contains('no-copy')) {
return NodeFilter.FILTER_REJECT;
}
return NodeFilter.FILTER_ACCEPT;
},
});

let node: Node | null;
// eslint-disable-next-line no-cond-assign
while ((node = walker.nextNode())) {
text += node.textContent;
}

return text.trim();
}

export function CodeBlock({filename, language, children}: CodeBlockProps) {
const [showCopied, setShowCopied] = useState(false);
const codeRef = useRef<HTMLDivElement>(null);
Expand All @@ -32,7 +57,9 @@ export function CodeBlock({filename, language, children}: CodeBlockProps) {
return;
}

const code = cleanCodeSnippet(codeRef.current.innerText, {language});
const code = cleanCodeSnippet(getCopiableText(codeRef.current), {
language,
});

try {
await navigator.clipboard.writeText(code);
Expand Down
7 changes: 7 additions & 0 deletions src/components/codeKeywords/keywordSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
KeywordIndicator,
KeywordSearchInput,
PositionWrapper,
ProejectPreview,
Selections,
} from './styles.css';
import {dropdownPopperOptions} from './utils';
Expand Down Expand Up @@ -137,6 +138,7 @@ export function KeywordSelector({keyword, group, index}: KeywordSelectorProps) {
// correctly overlap during animations, but this must be removed
// after so copy-paste correctly works.
display: isAnimating ? 'inline-grid' : undefined,
position: 'relative',
}}
>
<AnimatePresence initial={false}>
Expand All @@ -148,6 +150,11 @@ export function KeywordSelector({keyword, group, index}: KeywordSelectorProps) {
{currentSelection[keyword]}
</Keyword>
</AnimatePresence>
{!isOpen && currentSelection?.title && (
<ProejectPreview className="no-copy">
{currentSelection.title}
</ProejectPreview>
)}
</span>
</KeywordDropdown>
{isMounted &&
Expand Down
22 changes: 20 additions & 2 deletions src/components/codeKeywords/styles.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,22 @@ import {ArrowDown} from 'react-feather';
import styled from '@emotion/styled';
import {motion} from 'framer-motion';

export const ProejectPreview = styled('div')`
position: absolute;
top: -24px;
left: 50%;
transform: translateX(-50%);
font-size: 12px;
background-color: rgba(51, 51, 51, 1);
color: #fff;
padding: 2px 6px;
border-radius: 3px;
pointer-events: none;
white-space: nowrap;
opacity: 0.9;
user-select: none;
`;

export const PositionWrapper = styled('div')`
z-index: 100;
`;
Expand Down Expand Up @@ -92,8 +108,8 @@ export const ItemButton = styled('button')<{dark: boolean; isActive: boolean}>`
color: #EBE6EF;
`
: `


&:focus {
outline: none;
background-color: ${p.dark ? 'var(--gray-a4)' : 'var(--accent-purple-light)'};
Expand Down Expand Up @@ -141,6 +157,8 @@ export const KeywordIndicator = styled(ArrowDown, {
export const KeywordSpan = styled(motion.span)`
grid-row: 1;
grid-column: 1;
display: inline-block;
margin-top: 24px;
`;

export const KeywordSearchInput = styled('input')<{dark: boolean}>`
Expand Down
Loading