Xyphyn / photon

A replacement for lemmy-ui with more features, a better design, and more customizability.
https://phtn.app
GNU Affero General Public License v3.0
344 stars 38 forks source link

Improve codeblocks #296

Open 8ullyMaguire opened 4 months ago

8ullyMaguire commented 4 months ago

Is your feature request related to a problem? Please describe.

Describe the solution you'd like I'd like to see color and a copy to clipboard icon in the codeblocks.

Screenshot from 2024-04-06 03-21-15 Screenshot from 2024-04-06 03-27-06

Describe alternatives you've considered

Additional context Here is a first draft from the AI to make sure you like the idea before I try to add it.

Creating a Svelte component to format code with a one dark theme and a clipboard icon to copy the content involves several steps. We'll use Prism.js for syntax highlighting, which is a popular choice for code formatting. Additionally, we'll use the Clipboard.js library to handle the clipboard functionality.

First, ensure you have Prism.js and Clipboard.js included in your project. You can install them via npm or include them directly in your HTML file. For this example, we'll assume you're using npm.

  1. Install Prism.js and Clipboard.js:
npm install prismjs clipboard
  1. Create the Svelte Component:

Create a new Svelte component, for example, CodeBlock.svelte.

<script>
 import { onMount } from 'svelte';
 import Prism from 'prismjs';
 import 'prismjs/themes/prism-one-dark.css'; // Import the one dark theme
 import ClipboardJS from 'clipboard';

 export let code = ''; // The code to be formatted

 let codeElement;

 onMount(() => {
    Prism.highlightElement(codeElement);

    const clipboard = new ClipboardJS('.copy-button', {
      text: () => code,
    });

    clipboard.on('success', () => {
      alert('Copied to clipboard!');
    });
 });
</script>

<style>
 .code-block {
    position: relative;
    border-radius: 4px;
    overflow: hidden;
    background-color: #282c34;
    padding: 1rem;
    margin-bottom: 1rem;
 }

 .copy-button {
    position: absolute;
    top: 10px;
    right: 10px;
    cursor: pointer;
 }
</style>

<div class="code-block">
 <pre><code bind:this={codeElement} class="language-js">{code}</code></pre>
 <button class="copy-button" title="Copy to clipboard">
    <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" class="h-6 w-6">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h12a2 2 0 002-2V7a2 2 0 00-2-2h-2m-4 0h-4"></path>
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 17a2 2 0 01-2 2H6a2 2 0 01-2-2V7a2 2 0 012-2h12a2 2 0 012 2v10a2 2 0 01-2 2z"></path>
    </svg>
 </button>
</div>

This component does the following:

  1. Usage:

To use this component, simply import it into your Svelte application and pass the code prop with the code you want to display and format.

<script>
 import CodeBlock from './CodeBlock.svelte';
 let code = `function helloWorld() {
    console.log("Hello, world!");
 }`;
</script>

<CodeBlock {code} />

This setup provides a basic implementation. Depending on your project's needs, you might want to customize the styles further or add more features, such as language selection for syntax highlighting.