quasarframework / quasar-ui-qmarkdown

A Quasar UI App Extension to display inline markdown
https://quasarframework.github.io/quasar-ui-qmarkdown/
MIT License
157 stars 29 forks source link

add copy button to code blocks #389

Open yeus opened 1 year ago

yeus commented 1 year ago

Is your feature request related to a problem? Please describe. I would like to have an optional copy button for code blocks.

Describe the solution you'd like When a code block e.g. like this:

image

appears, there should be a copy button next to the code block

Describe alternatives you've considered I tried showCopy, but it only works for the entire document.

Additional context

it works in github :). see:

print("you can copy this!!")
yeus commented 10 months ago

as an update:

this is what I am using right now: I am injecting the copy button as a plugin:

function addCopyButtons(md: MarkdownIt) {
  const defaultFenceRenderer =
    md.renderer.rules.fence ||
    ((tokens, idx, options, env, self) => {
      return self.renderToken(tokens, idx, options);
    });

  md.renderer.rules.fence = (tokens, idx, options, env, self) => {
    // Original rendered HTML of the code block
    const originalRenderedHtml = defaultFenceRenderer(
      tokens,
      idx,
      options,
      env,
      self
    );

    // Custom HTML for the button
    const customHtml = `
        <div class="code-block-with-overlay">
          ${originalRenderedHtml}
          <button class="copy-button q-btn q-btn-item non-selectable transparent q-btn--flat q-btn--rectangle
            q-btn--actionable q-focusable q-hoverable q-btn--dense copy-button print-hide">
            <span class="q-focus-helper"></span>
            <span class="q-btn__content text-center col items-center q-anchor--skip justify-center row">
              <i class="q-icon notranslate material-icons" aria-hidden="true" role="img">content_copy</i>
            </span>
          </button>
        </div>
      `;

    return customHtml;
  };
}

function handleMarkdownClick(event: MouseEvent) {
  const target = (event.target as HTMLElement).closest('.copy-button');
  if (target) {
    // Find the closest .code-block-with-overlay and then find the <code> element inside it
    const codeBlockContainer = target.closest('.code-block-with-overlay');
    if (codeBlockContainer) {
      const codeElement = codeBlockContainer.querySelector('code');
      if (codeElement) {
        const codeText = codeElement.textContent || ''; // Get the text content of the <code> element
        copyToClipboard(codeText);
      }
    }
  }
}

and then add it like this:

      <q-markdown
        :plugins="[addCopyButtons]"
        :src="mytext"
        @click="handleMarkdownClick"
      />

will create a copy button like this:

image

you can test it out here in my app: taskyon.space :)

yeus commented 10 months ago

would be great though, to have this "built-in" :)