Componente de tema Tabbis

Olá! Estou tentando criar um componente de tema para usar o script externo tabbis.js para que eu possa criar abas em posts. Segui o tutorial aqui: Embed widget within text in a topic - #2 by Johani

Aqui está o que meu componente de tema parece até agora.

Comum > Cabeçalho

<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";

// usamos a biblioteca Discourse Load script para garantir que os scripts sejam carregados
// corretamente. Não se preocupe, isso é inteligente o suficiente para não duplicar o script
// se ele já estiver carregado
const loadScript = require("discourse/lib/load-script").default;

// cria um decorador de post
api.decorateCookedElement(
  post => {
    // este post tem abas tabbis?
    const tabbisTabs = post.querySelectorAll('[data-wrap="tabbis"]');

    // Sim, então vamos fazer um trabalho.
    if (tabbisTabs.length) {
      // para cada widget tabbis
      tabbisTabs.forEach(tabbisTab => {

        // carrega o script tabbis.
        loadScript(TABBIS_SCRIPT_SRC).then(() => {

          // tudo está pronto, vamos chamar o script tabbis
          tabbis();
        });
      });
    }
  },
  // adiciona um id ao decorador para evitar vazamentos de memória
  { id: "render-tabbis-tabs" }
);

</script>

Comum > CSS (copiado diretamente do repositório 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: adicionado https://cdn.jsdelivr.net

Marcação do post

[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]

O script parece carregar por uma fração de segundo depois que edito o post, mas assim que ele carrega completamente, ele fica inutilizável.

Isso aparece no console, mas não tenho ideia de como consertar. Existe um conflito com outras abas no Discourse?

Como posso fazer isso funcionar? Estou perdido!

1 curtida

Acho que você precisará de um plugin para fazer isso, mas posso estar enganado.

Você pode procurar pelo plugin de matemática ou pelos guias de plugins.

Por que este script requer um plugin em vez de um componente de tema? A estrutura de aplicativo de página única ainda é muito nova para mim.

Por favor, compartilhe todo o seu código-fonte do componente de tema (preferencialmente como um repositório do GitHub) para que possamos ajudá-lo com ele facilmente.

A propósito, este parece ser um componente de tema bem útil!

6 curtidas

Obrigado! Fiquei surpreso ao ver que ainda não havia nenhum tipo de plugin ou componente de abas por aqui; é algo que eu realmente quero para minha comunidade, então estou tentando. Sou bem novo em qualquer coisa além de javascript muito básico, mas estou tentando aprender.

2 curtidas

Alterando a marcação da postagem para

[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]

faz com que funcione :tada:

Há algumas observações que você poderia usar para melhorá-lo ainda mais:

  1. Não chame loadScript várias vezes. Verifique se ele já foi carregado antes de chamá-lo, caso contrário, ele será chamado várias vezes.

  2. Passe um seletor mais específico para a chamada tabbis(), para que você inicialize o que você especificamente selecionou.

6 curtidas