<template>
  <div>
    <button type="button">外の要素</button>
    <div id="tab">
      <div
        class="tablist"
        aria-label="タブのリスト"
        role="tablist">
        <button
          v-for="(tab, index) in tabs"
          type="button"
          ref="tab"
          role="tab"
          :id="`tab-${tab.id}`"
          class="tab"
          :tabIndex="tab.selected ? '0': '-1'"
          :aria-controls="`tabpanel-${tab.id}`"
          :aria-selected="tab.selected? 'true': 'false'"
          @click="handleOnClick(index)"
          @keydown.left="handleOnLeft(index)"
          @keydown.right="handleOnRight(index)">
          {{ tab.label }}
        </button>
      </div>
      <div
        v-for="tab in tabs"
        role="tabpanel"
        :id="`tabpanel-${tab.id}`"
        :class="`tabpanel ${tab.selected ? '': 'hidden'}`"
        :aria-labelledby="`tab-${tab.id}`"
        tabindex="0"
      >
        {{ tab.tabpanel }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      tabs: [
        { 
          id: "tab1",
          label: "Tab 1",
          selected: true,
          tabpanel: "Tab Panel 1",
        },
        {
          id: "tab1",
          label: "Tab 2",
          selected: false,
          tabpanel: "Tab Panel 2",
        },
        {
          id: "tab1",
          label: "Tab 3",
          selected: false,
          tabpanel: "Tab Panel 3",
        },
      ]
    };
  },
  methods: {
    handleOnClick(index) {
      this.tabs = this.tabs.map((v, vIndex) => ({
        ...v,
        selected: vIndex === index
      }));
    },
    handleOnLeft(index) {
      let nextIndex = index - 1;
      if (index === 0) {
        nextIndex = this.tabs.length - 1
      }
      this.$refs.tab[nextIndex].focus();
    },
    handleOnRight(index) {
      let nextIndex = index + 1;
      if (index === this.tabs.length - 1) {
        nextIndex = 0
      }
      this.$refs.tab[nextIndex].focus();
    }
  }
};
</script>

<style lang="scss">
  .tablist {
    display: flex;
    gap: 4px;
  }
  button.tab {
    width: 200px;
    padding: 16px 0;
    background: #ddd;
    border: solid 4px #ddd;
    border-radius: 4px 4px 0 0;
    font-size: 24px;
    
    &[aria-selected="true"] {
      position: relative;
      color: #FF7A00;
      font-weight: bold;
      background: #fff;

      &:before {
        position: absolute;
        left: 0;
        bottom: -4px;
        content: "";
        width: 100%;
        height: 4px;
        background: #fff;
      }
    }
  }
  .tabpanel {
    display: grid;
    place-items: center;
    height: 300px;
    margin-top: -4px;
    border: solid 4px #ddd;
    border-radius: 0 4px 4px 4px;
    
    &.hidden {
      display: none;
    }
  }
</style>

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.