primocms/primo

Explicitly set editable fields should be excluded from implicit editing

rallisf1 opened this issue · 3 comments

I have an accordion module with a somewhat complex structure:

<section class="page-container" id="faq">
  <h2 class="heading">{heading}</h2>
  <div class="accordion">
    {#each items as item, i (i)}
    <div class="item article" class:active={activeItem === i}>
      <button on:click={() => setActiveItem(i)}>
        <Icon icon="material-symbols:expand-{ activeItem === i ? 'less' : 'more'}" style="color:var(--primary);" height=32 />
        <h4 data-key="items[{i}].title">{item.title}</h4>
      </button>
      {#if activeItem === i}
      <article data-key="items[{i}].description" class="description" transition:slide>{@html item.description.html}</article>
      {/if} 
      <noscript>
        <article class="description">{@html item.description.html}</article>
      </noscript>
    </div>
    {/each}
  </div>
</section>

When clicking in the description it adds it to the title every time.

Edit: removed video, you can use the json provided to recreate.

Here's the whole symbol

FAQ.json.zip

Yeah I've noticed that happening on Accordions but haven't filed a bug for it yet, will look into it

I'm suffering this too.

I discover make_content_editable() function on src/lib/views/editor/Layout/ComponentNode.svelte search the text to find which element is to add the data-key to bind the element with the data. Since the rest of the content is hidden, it fails to bind the correct element and bind to a parent.

In your case, check if this element <div class="item article" class:active={activeItem === i}> get the data-key for the title in the visual editor.

I have a workaround, editing ComponentNode.svelte and adding the possibility to avoid to make editable some elements with data-noeditable.

async function make_content_editable() {
	if (!node) return
	const valid_elements = Array.from(node.querySelectorAll('*')).filter((element) => {
		if (['STYLE', 'TITLE'].includes(element.tagName)) return false
		if (Object.keys(element.dataset).includes('noeditable')) return false;
		....

Maybe @mateomorris can find a more elegant solution for this.