code-input icon indicating copy to clipboard operation
code-input copied to clipboard

Problems using code-input in Vue.js

Open Bowrna opened this issue 1 year ago • 2 comments

I want to use the syntax highlighter for my editor, and see the content only with syntax highlighted and in editable mode. But currently I see it in two different modes like below. Is there any possibility to do it that way? Screenshot 2024-11-04 at 5 30 37 PM

I am using this in VueJS and this is the code I have right now.

<template>
  <div ref="htmlEditor" class="html-editor">
    <textarea
      ref="editor"
      :value="value"
      @input="handleInput"
      is="code-input"
      data-language="html"
      :data-readonly="disabled"
      spellcheck="false"
    ></textarea>
  </div>
</template>

<script>
import Prism from 'prismjs';

export default {
  props: {
    value: { type: String, default: '' },
    language: { type: String, default: 'html' },
    disabled: Boolean,
  },

  methods: {
    handleInput(event) {
      this.$emit('input', event.target.value);
    },

    initializeEditor() {
      const textarea = this.$refs.editor;
      textarea.setAttribute('is', 'code-input');
      textarea.setAttribute('data-language', this.language);

      // Register Prism for syntax highlighting if needed
      if (window.codeInput) {
        window.codeInput.registerTemplate(
          'syntax-highlighted',
          window.codeInput.templates.prism(Prism, [])
        );
        window.codeInput.setDefaultTemplate('syntax-highlighted');
      }
    },
  },

  mounted() {
    this.initializeEditor();
  },
};
</script>

<style>
/* Hide the non-editable preview content */
.code-input pre[aria-hidden="true"] {
  display: none !important;
}

/* Additional styling */
.html-editor {
  width: 100%;
  position: relative;
}

.html-editor textarea {
  font-size: 15px;
  min-height: 200px;
  width: 100%;
  padding: 8px;
  border: none;
  resize: none;
}

.token.tag { font-weight: bold; }
.token.attr-name { color: #111; }
.token.attr-value { color: #0066cc; }

.html-editor textarea:focus {
  outline: none;
  border-color: #0066cc;
}
</style>

Bowrna avatar Nov 04 '24 12:11 Bowrna

Thanks for asking here, @Bowrna !

General Problems

There are several problems in this code (perhaps from my unclear documentation) that are making it not work. Please note that I know very little about Vue except that it is very similar to vanilla HTML/CSS/JavaScript so you may have problems in Vue code I haven't identified, or I might think something is a problem when it isn't:

  • You are not using code-input in the correct way: you are using a <textarea is="code-input"> element while the code-input library expects a <code-input> element, and does not expect any elements to be inside this element initially (just the initial text value). You can use the input event and value property of the <code-input> element instead of that of a textarea, and if you really need to access the <textarea> once code-input has created it you can use (code-input element).getElementByTagName("textarea").
  • I'm also unsure of the purpose of the template element: code-input doesn't require it (maybe it's a Vue thing) and code-input.registerTemplate("syntax-highlighted", codeInput.templates.Prism(Prism, []) will set up all <code-input template="syntax-highlighted"> elements, with template being an HTML attribute not an element.
  • The data-language attribute should be language without the "data-" part.
  • Your textarea and token CSS will also be unnecessary when you import code-input and Prism.JS' CSS. You must import code-input's CSS for the editor to work, but Prism.JS' CSS doesn't need to be imported if you style its tokens yourself.

For more information, you should look at example code. ~~The demo code (vanilla HTML/CSS/JS) strangely doesn't seem to have Prism highlighting work now -~~ the more complicated but similar demo does. If needed, read through the README documentation and follow all of the steps that apply to you, especially the "Using the component" section. My labelling of the CSS-Tricks article will not be helpful since it explains the behind the scenes functioning but not the library usage - I have added a clarification to the documentation.

Changing language

You can use (code-input element).setAttribute("language", "HTML"), (code-input element).setAttribute("language", "Markdown"), and (code-input element).setAttribute("language", "plaintext"), and it should hopefully work.

Please let me know if you get it working, or if you have any further questions / it still doesn't work.

WebCoder49 avatar Nov 04 '24 17:11 WebCoder49

Anyone who knows Vue better, please feel free to help! (edit: I meant better than me)

WebCoder49 avatar Nov 04 '24 17:11 WebCoder49

@Bowrna This is likely related to #133, and will be easier to fix when code-input ships as ECMAScript .mjs modules, which is planned to be shipped this month. Thanks for waiting!

WebCoder49 avatar Jul 07 '25 11:07 WebCoder49

Also, I should apologise for only starting to develop support for Vue more recently when someone else first mentioned ECMAScript Module support. I hadn't used Vue when you opened this issue, so I did not realise it required changes on the code-input side to support ECMAScript Modules; also I was a lot busier then than I am now. Documented Vue support should be available this week!

WebCoder49 avatar Jul 29 '25 15:07 WebCoder49

It's almost certainly getting formally released today. Thanks for waiting!

WebCoder49 avatar Aug 09 '25 13:08 WebCoder49

@Bowrna Sorry for the wait: the documentation to use code-input (with Prism.js) in Vue is at https://github.com/WebCoder49/code-input/tree/main/docs/modules-and-frameworks/prism/_index.md, which refers to https://github.com/WebCoder49/code-input/tree/main/docs/modules-and-frameworks/hljs/_index.md.

(Edit: give more specific links)

Please do let me know if anything is still not working; I will try to respond quickly and the fixes will help everyone!

WebCoder49 avatar Aug 12 '25 11:08 WebCoder49

Thanks @WebCoder49 Let me check this one.

Bowrna avatar Aug 13 '25 08:08 Bowrna