Composant de thème Tabbis

Bonjour ! J’essaie de créer un composant de thème pour utiliser le script externe tabbis.js afin de pouvoir créer des onglets dans les publications. J’ai suivi le tutoriel ici : Embed widget within text in a topic - #2 by Johani

Voici à quoi ressemble mon composant de thème jusqu’à présent.

Commun > En-tête

<script type="text/discourse-plugin" version="0.8">
// options
const TABBIS_SCRIPT_SRC = "https://cdn.jsdelivr.net/gh/jenstornell/tabbis.js/assets/js/src/tabbis.es6.js";

// nous utilisons la bibliothèque Discourse Load script pour nous assurer que les scripts sont chargés
// correctement. Ne vous inquiétez pas, c'est assez intelligent pour ne pas dupliquer le script
// s'il est déjà chargé
const loadScript = require("discourse/lib/load-script").default;

// créer un décorateur de publication
api.decorateCookedElement(
  post => {
    // cette publication a-t-elle des onglets tabbis ?
    const tabbisTabs = post.querySelectorAll('[data-wrap="tabbis"]');

    // Oui, alors faisons un peu de travail.
    if (tabbisTabs.length) {
      // pour chaque widget tabbis
      tabbisTabs.forEach(tabbisTab => {

        // charger le script tabbis.
        loadScript(TABBIS_SCRIPT_SRC).then(() => {

          // tout est prêt, appelons le script tabbis
          tabbis();
        });
      });
    }
  },
  // ajouter un id au décorateur pour éviter les fuites de mémoire
  { id: "render-tabbis-tabs" }
);

</script>

Commun > CSS (copié directement du dépôt tabbis.js)

[data-tabs],
[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: 0.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 : ajouté https://cdn.jsdelivr.net

Marquage de la publication

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

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

Le script semble se charger pendant une fraction de seconde après que j’ai modifié la publication, mais une fois qu’il est complètement chargé, il est inutilisable.

Ceci apparaît dans la console, mais je n’ai aucune idée de comment le résoudre. Y a-t-il un conflit avec d’autres onglets dans Discourse ?

Comment puis-je faire fonctionner cela ? Je suis perdu !

1 « J'aime »

Je pense que vous aurez besoin d’un plugin pour faire cela, mais je pourrais me tromper.

Vous pourriez consulter le plugin math ou les guides de plugins.

Pourquoi ce script nécessite-t-il un plugin au lieu d’un composant de thème ? La structure des applications monopages m’est encore très nouvelle.

Veuillez partager le code source complet de votre composant de thème (de préférence sous forme de dépôt GitHub) afin que nous puissions vous aider plus facilement.\n\nAu fait, cela ressemble à un composant de thème assez utile !

6 « J'aime »

Merci ! J’ai été surpris de constater qu’il n’existait pas déjà de plugin ou de composant d’onglets ici ; c’est quelque chose que je veux vraiment pour ma communauté, alors je me lance. Je suis assez nouveau dans tout sauf le JavaScript très basique, mais j’essaie d’apprendre.

2 « J'aime »

Changer le balisage du message en

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

  <div>
    <div>Pane1</div>
    <div>Pane2</div>
    <div>Pane3</div>
  </div>
[/wrap]

le fait fonctionner :tada:

Il y a quelques remarques que vous pourriez utiliser pour l’améliorer davantage :

  1. N’appelez pas loadScript plusieurs fois. Vérifiez s’il est déjà chargé avant de l’appeler, sinon il sera appelé plusieurs fois.

  2. Passez un sélecteur plus spécifique à l’appel tabbis(), afin d’initialiser celui que vous avez spécifiquement sélectionné.

6 « J'aime »