--- /dev/null
+<template>
+ <section v-show="isActive"
+ class="tabs-content-panel"
+ :data-id="computedId"
+ :aria-hidden="! isActive"
+ role="tabpanel">
+ <slot></slot>
+ </section>
+</template>
+
+<script>
+ export default {
+ name: 'Tab',
+
+ props: {
+ id: { default: null },
+ name: { required: true },
+ selected: { default: false },
+ },
+
+ data() {
+ return {
+ isActive: false,
+ };
+ },
+
+ computed: {
+ computedId() {
+ return this.id ? this.id : this.name.toLowerCase().replace(/ /g, '-');
+ },
+ hash() {
+ return '#' + this.computedId;
+ },
+ },
+
+ mounted() {
+ this.isActive = this.selected;
+ },
+ }
+</script>
\ No newline at end of file
--- /dev/null
+<template>
+ <div class="tabs">
+ <ul role="tablist" class="tabs-list" :class="{ 'flex': this.currentMode === 'tabs' }">
+ <li v-for="(tab, i) in tabs"
+ :key="i"
+ :class="{ 'bg-grey-100': tab.isActive, 'is-disabled': tab.isDisabled }"
+ role="presentation"
+ >
+ <a class="block font-display text-lg text-navy py-4 px-8 mr-1"
+ :aria-controls="tab.hash"
+ :aria-selected="tab.isActive"
+ @click="selectTab(tab.hash, $event)"
+ :href="tab.hash"
+ role="tab"
+ >
+ {{ tab.name }}
+ </a>
+ <div v-show="currentMode === 'accordion' && tab.isActive">
+ <!--<slide-toggle :active="tab.isActive" :duration="300">-->
+ {{ tab.$el.innerHTML }}
+ <!--</slide-toggle>-->
+ </div>
+ </li>
+ </ul>
+
+ <div v-show="currentMode === 'tabs'" class="tabs-content bg-grey-100 p-6">
+ <slot></slot>
+ </div>
+ </div>
+</template>
+
+<script>
+
+ import SlideToggle from 'vue-slide-up-down'
+
+ export default {
+
+ components: {
+ SlideToggle
+ },
+
+ props: {
+ options: {
+ type: Object,
+ required: false,
+ default: () => ({
+ defaultTabHash: null,
+ }),
+ },
+ mode: { default: 'tabs' }, // Tabs mode and responsive by default
+ responsive: { default: true },
+ breakpoint: {
+ type: Number,
+ required: false,
+ default: 768,
+ }
+ },
+ data: () => ({
+ tabs: [],
+ activeTabHash: '',
+ activeTabIndex: 0,
+ width: 0,
+ }),
+
+ computed: {
+ currentMode() {
+ if (!this.responsive) {
+ return this.mode;
+ }
+
+ // Switch to accordion mode when below the breakpoint
+ return (this.width < this.breakpoint) ? 'accordion' : 'tabs';
+
+ }
+ },
+
+ created() {
+ this.tabs = this.$children;
+ },
+
+ mounted() {
+
+ this.handleResize();
+ window.addEventListener('resize', () => this.handleResize());
+
+ // Change tabs when URL hash changes
+ window.addEventListener('hashchange', () => this.selectTab(window.location.hash));
+
+ // Pre-select tab based on hash
+ if (this.findTab(window.location.hash)) {
+ this.selectTab(window.location.hash);
+ return;
+ }
+
+ // Allow default tab to be set in options
+ if (this.options.defaultTabHash !== null && this.findTab("#" + this.options.defaultTabHash)) {
+ this.selectTab("#" + this.options.defaultTabHash);
+ return;
+ }
+
+ // If we get this far and nothing has been selected, select the first tab
+ if (this.tabs.length) {
+ this.selectTab(this.tabs[0].hash);
+ }
+ },
+
+ methods: {
+
+ handleResize() {
+ // Keep track of width internally
+ // Triggers the computed property currentMode
+ // to change based on window size...
+ this.width = window.innerWidth;
+ },
+
+ findTab(hash) {
+ return this.tabs.find(tab => tab.hash === hash);
+ },
+
+ selectTab(selectedTabHash, event) {
+
+ const selectedTab = this.findTab(selectedTabHash);
+
+ if (! selectedTab) {
+ return;
+ }
+
+ this.tabs.forEach(tab => {
+ tab.isActive = (tab.hash === selectedTab.hash);
+ });
+
+ this.$emit('changed', { tab: selectedTab });
+ this.activeTabHash = selectedTab.hash;
+ this.activeTabIndex = this.getTabIndex(selectedTabHash);
+
+ // If we're coming from a click event, prevent default behaviour to get rid of jump in page
+ // if (event) {
+ // event.preventDefault();
+ // }
+ },
+
+ getTabIndex(hash){
+ const tab = this.findTab(hash);
+
+ return this.tabs.indexOf(tab);
+ },
+
+ getTabHash(index){
+ const tab = this.tabs.find(tab => this.tabs.indexOf(tab) === index);
+
+ if (!tab) {
+ return;
+ }
+
+ return tab.hash;
+ },
+
+ getActiveTab(){
+ return this.findTab(this.activeTabHash);
+ },
+
+ getActiveTabIndex() {
+ return this.getTabIndex(this.activeTabHash);
+ },
+ },
+
+ }
+</script>