Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add copy button for code blocks #7509

Open
TusharThakur04 opened this issue Dec 31, 2024 · 2 comments
Open

Add copy button for code blocks #7509

TusharThakur04 opened this issue Dec 31, 2024 · 2 comments

Comments

@TusharThakur04
Copy link

  • This feature will add a copy button on every code block in the documentation.
  • It will help readers to easily copy and test the code.
@TusharThakur04
Copy link
Author

@snitin315 Could you please assign this issue to me.

@TusharThakur04
Copy link
Author

TusharThakur04 commented Jan 17, 2025

@alexander-akait could you help me getting through this issue.
So far i have created an copybutton component , integrated it with pre tag and replaced pre element with the integrated one using mdxProvider. But its not working

import { useState } from 'react';
import PropTypes from 'prop-types';

function CopyButton({ text }) {
  const [copied, setCopied] = useState(false);

  const handleCopy = () => {
    navigator.clipboard.writeText(text).then(() => {
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    });
  };

  const buttonStyle = {
    position: 'absolute',
    top: '0.5rem',
    right: '0.5rem',
    backgroundColor: '#e5e7eb',
    fontSize: '0.875rem',
    padding: '0.25rem 0.5rem',
    borderRadius: '0.25rem',
    cursor: 'pointer',
    transition: 'background-color 0.3s ease',
  };

  const handleMouseOver = (e) => {
    e.target.style.backgroundColor = '#d1d5db';
  };

  const handleMouseOut = (e) => {
    e.target.style.backgroundColor = '#e5e7eb';
  };

  return (
    <button
      className="copy-button"
      style={buttonStyle}
      onClick={handleCopy}
      onMouseOver={handleMouseOver}
      onMouseOut={handleMouseOut}
    >
      {copied ? 'Copied!' : 'Copy'}
    </button>
  );
}
CopyButton.propTypes = {
  text: PropTypes.string.isRequired,
};

//integrating the CopyButton component into the CodeBlock component

export default function CodeBlock({ children }) {
  const codeText = children?.props?.children?.toString() || '';

  return (
    <div style={{ position: 'relative',}}>
      <CopyButton text={codeText} />
      <pre>{children}</pre>
    </div>
  );
}

CodeBlock.propTypes = {
  children: PropTypes.node.isRequired,
};

Code added into page.jsx:

// Import External Dependencies
import { useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import { useLocation } from 'react-router-dom';
import { MDXProvider } from '@mdx-js/react';

// Import Components
import PageLinks from '../PageLinks/PageLinks';
import Markdown from '../Markdown/Markdown';
import Contributors from '../Contributors/Contributors';
import { PlaceholderString } from '../Placeholder/Placeholder';
import AdjacentPages from './AdjacentPages';
import CodeBlock from '../CodeBlock/CodeBlock';

// Load Styling
import './Page.scss';
import Link from '../Link/Link';


//  **change**
const components = { pre: CodeBlock };


export default function Page(props) {
  const {
    title,
    contributors = [],
    related = [],........  rest of code 
.......

 <Markdown>
        <h1>{title}</h1>

        {rest.thirdParty ? (
          <div className="italic my-[20px]">
            <strong className="font-bold">Disclaimer:</strong> {title} is a
            third-party package maintained by community members, it potentially
            does not have the same support, security policy or license as
            webpack, and it is not maintained by webpack.
          </div>
        ) : null}

// **change** 

        <MDXProvider components={components}>
          <div id="md-content">{contentRender}</div>
        </MDXProvider>

        {loadRelated && (
          <div className="print:hidden">......... code continues

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant