metonym / svelte-highlight

Syntax Highlighting for Svelte using highlight.js
https://svhe.onrender.com
MIT License
253 stars 13 forks source link

Wipe out default styling #268

Closed Ddupasquier closed 1 year ago

Ddupasquier commented 1 year ago

Is there currently a way to override ALL of the default styling of the Highlight component? I was hoping that this may be something that just returns strings, but instead I'm getting a pre and code element with style that I can't seem to override in my scss.

If not then this is an official feature request.

metonym commented 1 year ago

By default styling, do you mean the highlight.js styles?

You can always not import the style and just use the Highlight component. Then, you could write your own CSS targeting the .hljs classes.

<script>
  import Highlight from "svelte-highlight";
  import typescript from "svelte-highlight/languages/typescript";

  const code = "const add = (a: number, b: number) => a + b;";
</script>

<Highlight language={typescript} {code} />

<style>
  :global(.hljs-keyword) {
    color: red;
  }
</style>
Ddupasquier commented 1 year ago

Hmmm, what are the other classes? Because this does nothing:

<script lang="ts">
  import Highlight from 'svelte-highlight';
  import typescript from 'svelte-highlight/languages/typescript';

  import { copyToClipboard } from '$lib/utils';

  export let code: string;

  let copyShown = false;
</script>

{#if code}
<div
class="code"
on:mouseenter={() => (copyShown = true)}
on:mouseleave={() => (copyShown = false)}
>
<Highlight language={typescript} {code} />
    <!-- {code} -->
    {#if copyShown}
      <button class="copy" on:click={() => copyToClipboard(code)}>
        Copy
      </button>
    {/if}
  </div>
{/if}

<style lang="scss">
  .copy {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    background: none;
    border: none;
    font-size: 1rem;
    color: #ccc;
    cursor: pointer;
    z-index: 1;
    transition: color 0.2s ease-in-out;
    &:hover {
      color: #000;
    }
  }

  .code {
    position: relative;
    font-size: 0.875rem;
    color: #333;
    padding: .5rem;
    border-bottom: 3px solid #f6f8fa;
    transition: 0.5s;
    &:hover {
      border-bottom: 3px solid #d8dcdf;
    }
  }

  :global(.hljs-keyword) {
    background: red;
  }
</style>

image Still just these big, bulky bois with a hard coded overflow-x.

metonym commented 1 year ago

Note that the correct language grammar should be supplied for highlight.js to use to highlight the text. Your example seems to use typescript, when the text provided resembles xml or Svelte.

It's helpful to use the browser console to inspect the rendered markup to see which .hljs-* classes are applied, and target those specifically.

Screen Shot 2023-02-16 at 9 38 04 PM
Ddupasquier commented 1 year ago

Oh I should have thought of that lol. I'll give it a try in the morning and let you know if/when it pans out.

A nice feature would be to have a bool that nullifies default styling. Obviously this is your brain baby and you can raise it how you want, but my gut says this isn't something that should have styling outside the highlighting. Maybe some better way of passing a style prop or something.

Are you open to a PR on this?

Ddupasquier commented 1 year ago

Hmmm, what are the other classes? Because this does nothing:

<script lang="ts">
  import Highlight from 'svelte-highlight';
  import typescript from 'svelte-highlight/languages/typescript';

  import { copyToClipboard } from '$lib/utils';

  export let code: string;

  let copyShown = false;
</script>

{#if code}
<div
class="code"
on:mouseenter={() => (copyShown = true)}
on:mouseleave={() => (copyShown = false)}
>
<Highlight language={typescript} {code} />
    <!-- {code} -->
    {#if copyShown}
      <button class="copy" on:click={() => copyToClipboard(code)}>
        Copy
      </button>
    {/if}
  </div>
{/if}

<style lang="scss">
  .copy {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    background: none;
    border: none;
    font-size: 1rem;
    color: #ccc;
    cursor: pointer;
    z-index: 1;
    transition: color 0.2s ease-in-out;
    &:hover {
      color: #000;
    }
  }

  .code {
    position: relative;
    font-size: 0.875rem;
    color: #333;
    padding: .5rem;
    border-bottom: 3px solid #f6f8fa;
    transition: 0.5s;
    &:hover {
      border-bottom: 3px solid #d8dcdf;
    }
  }

  :global(.hljs-keyword) {
    background: red;
  }
</style>

image Still just these big, bulky bois with a hard coded overflow-x.

Hey, that worked! That's dope.

Also though, that's a lot of unneeded work to get some purple text with no defaulted styles forced on you. Are you open to some PRs?

Ddupasquier commented 1 year ago

Also, alterations aren't working on the hljs class? image image

Hoping to get that overflow gone as heck.

metonym commented 1 year ago

In some cases, you'll need to increase the selector specificity to override the style.

:global(pre code.hljs) {
  overflow-x: hidden;
}