Компонент темы Tabbis

Привет! Я пытаюсь создать компонент темы для использования внешнего скрипта tabbis.js, чтобы можно было создавать вкладки в постах. Я следовал руководству здесь: Embed widget within text in a topic - #2 by Johani

Вот как выглядит мой компонент темы на данный момент.

Common > Header

// options
const TABBIS_SCRIPT_SRC = "https://cdn.jsdelivr.net/gh/jenstornell/tabbis.js/assets/js/src/tabbis.es6.js";

// мы используем библиотеку Discourse Load script для корректной загрузки скриптов
// не волнуйтесь, она достаточно умна, чтобы не дублировать скрипт,
// если он уже загружен
const loadScript = require("discourse/lib/load-script").default;

// создаем декоратор поста
api.decorateCookedElement(
  post => {
    // есть ли в этом посте вкладки tabbis?
    const tabbisTabs = post.querySelectorAll('[data-wrap="tabbis"]');

    // Да, тогда приступим к работе.
    if (tabbisTabs.length) {
      // для каждого виджета tabbis
      tabbisTabs.forEach(tabbisTab => {

        // загружаем скрипт tabbis.
        loadScript(TABBIS_SCRIPT_SRC).then(() => {

          // всё готово, вызываем скрипт tabbis
          tabbis();
        });
      });
    }
  },
  // добавляем id декоратору, чтобы избежать утечек памяти
  { id: "render-tabbis-tabs" }
);

</script>

Common > CSS (скопировано напрямую из репозитория tabbis.js)

[data-panes] {
  --color: #000; }

[data-tabs] {
  background: var(--color);
  border: 2px solid var(--color);
  border-bottom: none;
  overflow-x: auto;
  display: flex; }
  [data-tabs] > [role="tab"] {
    all: unset;
    padding: .75rem 1.5rem;
    -webkit-user-select: none;
       -moz-user-select: none;
        -ms-user-select: none;
            user-select: none;
    font-weight: 600;
    color: #fff;
    border: 1px solid transparent;
    outline: none; }
    [data-tabs] > [role="tab"]:hover {
      background: rgba(255, 255, 255, 0.2); }
    [data-tabs] > [role="tab"]:active {
      background: rgba(255, 255, 255, 0.3); }
    [data-tabs] > [role="tab"]:focus {
      border: 1px dotted rgba(255, 255, 255, 0.5); }
    [data-tabs] > [role="tab"][aria-selected="true"] {
      background: #fff;
      color: #000; }
      [data-tabs] > [role="tab"][aria-selected="true"]:focus {
        border: 1px dotted rgba(0, 0, 0, 0.5); }

[data-panes] {
  border: 2px solid var(--color);
  border-top: none; }
  [data-panes] > * {
    background: #fff;
    padding: 2rem;
    font-weight: 600;
    outline: none;
    border: 1px solid transparent; }
    [data-panes] > *:focus {
      border: 1px dotted rgba(0, 0, 0, 0.5); }
    @media screen and (max-width: 460px) {
      [data-panes] > * {
        padding: 1rem; } }

Content Security Policy Script src: добавлен https://cdn.jsdelivr.net

Разметка поста

[wrap="tabbis"]<div data-tabs>
<button>Вкладка1</button>
<button>Вкладка2</button>
<button>Вкладка3</button>
</div>

<div data-panes>
<div>Панель1</div>
<div>Панель2</div>
<div>Панель3</div>
</div>[/wrap]

Скрипт, кажется, загружается на мгновение после редактирования поста, но как только он полностью загружается, он становится нерабочим.

В консоли появляется следующее сообщение, но я не знаю, как это исправить. Возможно, есть конфликт с другими вкладками в Discourse?

Как мне заставить это работать? Я в тупике!

Думаю, для этого понадобится плагин, но я могу ошибаться.

Может, стоит посмотреть плагин для математики или руководства по плагинам.

Почему этот скрипт требует плагина, а не компонента темы? Структура одностраничного приложения всё ещё очень нова для меня.

Пожалуйста, предоставьте полный исходный код вашего компонента темы (желательно в виде репозитория GitHub), чтобы мы могли легко помочь вам с этим.

Кстати, это звучит как довольно полезный компонент темы!

Спасибо! Я удивился, что здесь ещё нет какого-либо плагина или компонента для вкладок; это именно то, что мне нужно для моего сообщества, поэтому я решил попробовать. Я довольно новичок во всём, кроме самого базового JavaScript, но стараюсь учиться.

Изменение разметки поста на

[wrap="tabbis"]
  <div data-tabs>
    <span>Tab1</span>
    <span>Tab2</span>
    <span>Tab3</span>
  </div>

  <div data-panes>
    <div>Pane1</div>
    <div>Pane2</div>
    <div>Pane3</div>
  </div>
[/wrap]

решает проблему :tada:

Вот несколько советов, которые помогут улучшить его:

  1. Не вызывайте loadScript несколько раз. Проверяйте, загружен ли он уже, прежде чем вызывать его, иначе он будет вызван многократно.

  2. Передавайте более специфичный селектор в вызов tabbis(), чтобы инициализировать именно тот, который вы выбрали.