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

// we use the Discourse Load script lib to ensure scripts are loaded
// properly. Don't worry, this is smart enough to not duplicate the script
// if it's already loaded
const loadScript = require("discourse/lib/load-script").default;

// create a post decorator
api.decorateCookedElement(
  post => {
    // does this post have tabbis tabs?
    const tabbisTabs = post.querySelectorAll('[data-wrap="tabbis"]');

    // Yes, so let's do some work.
    if (tabbisTabs.length) {
      // for each tabbis widget
      tabbisTabs.forEach(tabbisTab => {

        // load the tabbis script.
        loadScript(TABBIS_SCRIPT_SRC).then(() => {

          // everything is ready, let's call the tabbis script
          tabbis();
        });
      });
    }
  },
  // add an id to the decorator to avoid memory leaks
  { 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>Tab1</button>
<button>Tab2</button>
<button>Tab3</button>
</div>

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

게시글을 수정한 후 스크립트가 잠시 로드되는 것 같지만, 완전히 로드된 후에는 사용할 수 없습니다.

콘솔에 아래 오류가 표시되는데, 어떻게 수정해야 할지 모르겠습니다. Discourse의 다른 탭과 충돌이 있는 건가요?

이 문제를 어떻게 해결할 수 있을까요? 막막합니다!

그 작업을 하려면 플러그인이 필요할 것 같은데, 제가 틀린 걸 수도 있어요.

수학 플러그인이나 플러그인 가이드를 참고해 보세요.

왜 이 스크립트는 테마 컴포넌트가 아니라 플러그인을 요구하나요? 싱글 페이지 앱 구조는 저에게 아직 매우 낯설어서요.

테마 컴포넌트의 전체 소스 코드를 공유해 주세요(가급적이면 GitHub 저장소로). 그러면 더 쉽게 도움을 드릴 수 있습니다.

참고로, 꽤 유용한 테마 컴포넌트인 것 같습니다!

감사합니다! 여기 탭 플러그인이나 컴포넌트가 이미 있는지 몰라서 놀랐어요. 제 커뮤니티에 꼭 필요한 기능이라 직접 만들어 보기로 했어요. 아주 기본적인 자바스크립트 외에는 잘 모르지만, 배우려고 노력하고 있습니다.

게시글 마크업을 다음으로 변경하면 동작합니다 :tada:

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

더 개선할 수 있는 몇 가지 참고 사항이 있습니다:

  1. loadScript를 여러 번 호출하지 마세요. 호출하기 전에 이미 로드되었는지 확인하지 않으면 여러 번 호출됩니다.

  2. tabbis() 호출에 더 구체적인 셀렉터를 전달하여, 특정하게 선택한 탭만 초기화하도록 하세요.