Ovski4/jekyll-tabs

Rendering lists within tabs not working

Closed this issue · 6 comments

When I use an ordered list as a child of a tab, the active class is not assigned to the second tab when it is active:

broken-tabs

broken-tabs-dom

And here is the markdown for it:

### Lists ❌

{% tabs lists %}

{% tab lists List A %}
It doesn't like lists -- click the second tab and you won't see any text. It looks like it parses the HTML incorrectly.

1. Do this.
1. Then this.
1. Then then this.

{% endtab %}

{% tab lists List B %}
Does it work with a para first?

1. You don't see this under List B.
1. some more lists
1. moar
{% endtab %}

{% endtabs %}

Looks like my syntax is correct, not sure how to fix

Ok so I found the culprit here:

https://github.com/Ovski4/jekyll-tabs/blob/master/docs/tabs.js#L39

If you have list items within your tab content, this selector will grab them all regardless of depth. When it tries to apply .active to the 2nd tab (for example) it applies it to the first nested tab instead of the one you'd expect.

You go from something like this:

<ul class="tab-content">
  <li class="active">...</li>
  <li>...</li>
</ul>

To something like this:

<ul class="tab-content">
  <li>
    <ul>
      <li class="active"></li>
      <li></li>
    </ul>
  </li>
  <li>...</li>
</ul>

The way I fixed this was by adding a class specifically to direct children of ul.tab-content so that I can select those and ignore any nested <li> elements:

window.addEventListener('load', function () {
    const tabLinks = document.querySelectorAll('ul.tab > li a');
    // Ensure <li> els that are direct descendents of ul.tab-content have a queryable classname
    const tabEls = document.querySelectorAll('ul.tab-content > li')
    tabEls.forEach(tab => tab.classList.add('tab-content-item'))

    Array.prototype.forEach.call(tabLinks, function(link) {
      link.addEventListener('click', function (event) {
        event.preventDefault();

        liTab = link.parentNode;
        ulTab = liTab.parentNode;
        position = getChildPosition(liTab);
        if (liTab.className.includes('active')) {
          return;
        }

        removeActiveClasses(ulTab);
        tabContentId = ulTab.getAttribute('data-tab');
        tabContentElement = document.getElementById(tabContentId);
        removeActiveClasses(tabContentElement);

        tabContentElement.querySelectorAll('li.tab-content-item')[position].classList.add('active');
        liTab.classList.add('active');
      }, false);
    });
});

Hi!

Thanks for looking into this issue, that's a good find.

I see you have a pretty good workaround. I'm thinking it would be nice to have the class tab-content-item set by default on <li> tags, without relying on javascript to add it to the DOM.

I'll work on patching this.

Ovski4 commented

I pushed some changes to the tabs.js file and it's working fine now:

Screenshot 2023-03-23 at 6 14 18 PM

You can update the javascript with the latest version.

I'll close this issue. Feel free the reopen it or create a new one if that does not work for you.

Hi @Ovski4
We're using this plugin on our site (thank you!) but are also having this problem when trying to render lists within the tabs. I've confirmed we have latest version of the tabs.js file.
A sample of the code we are using, which is causing the 2nd tab to render without any content:

{% tabs Example %}
{% tab Example Developers %}
My list:
- Item one
- Item two
- Item three
{% endtab %}
{% tab Example Users %}
Some content that is not rendering.
{% endtab %}
{% endtabs %}

Hello 👋

Sorry for the very long time to unblock this one.

I went down the rabbit hole since I coudn't reproduce your issue at first, then I realized I was using the redcarpet markdown converter that has been deprecated and removed years from now.

I assume you are using kramdown?

TL;DR to fix this issue, update the javascript at line 87 by adding .tab-content to the ul selector:

tabContentElement.querySelectorAll('ul.tab-content > li')[liPositionInUl].classList.add('active');

I can push this fix, but I'd rather make sure it works for you first. Let me know 🙏

Fixed by 4497df4