vue-tabs-with-active-line
vue-tabs-with-active-line copied to clipboard
Support for vue3
Hi, are you still maintaining this project?
Hi, I'll try to support the new version this week
cool, $children
was removed, now this is how it's done
Tabs.vue
<template>
<div>
<div class="tabs">
<ul>
<li v-for="tab in tabs" :class="{ 'is-active': tab.isActive }">
<a :href="tab.href" @click="selectTab(tab)">{{ tab.name }}</a>
</li>
</ul>
</div>
<div class="tabs-details">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
name: "Tabs",
data() {
return {tabs: [] };
},
created() {
},
methods: {
selectTab(selectedTab) {
this.tabs.forEach(tab => {
tab.isActive = (tab.name == selectedTab.name);
});
}
}
}
</script>
<style scoped>
</style>
Tab.vue
<template>
<div v-show="isActive"><slot></slot></div>
</template>
<script>
export default {
name: "Tab",
props: {
name: { required: true },
selected: { default: false}
},
data() {
return {
isActive: false
};
},
computed: {
href() {
return '#' + this.name.toLowerCase().replace(/ /g, '-');
}
},
mounted() {
this.isActive = this.selected;
},
created() {
this.$parent.tabs.push(this);
},
}
</script>
<style scoped>
</style>
App.js
<template>
<Tabs>
<Tab :selected="true"
:name="'a'">
aa
</Tab>
<Tab :name="'b'">
bb
</Tab>
<Tab :name="'c'">
cc
</Tab>
</Tabs>
<template/>
and this is pretty cool scss for tabs
.tabs-component-tabs {
padding-inline-start: 0;
border: solid 1px #ddd;
border-radius: 6px;
margin-bottom: 5px;
}
@media (min-width: 700px) {
.tabs-component-tabs {
border: 0;
align-items: stretch;
display: flex;
justify-content: flex-start;
margin-bottom: -1px;
z-index: 30;
}
}
.tabs-component-tab {
flex: 1;
color: #999;
font-size: 16px;
font-weight: 600;
margin-right: 0;
list-style: none;
background: #e9e9e9;
.tabs-component-tab-a{
color: $text-gray;
font-weight: 400;
}
}
.tabs-component-tab:not(:last-child) {
border-bottom: dotted 1px #ddd;
}
.tabs-component-tab:hover {
color: #666;
}
.tabs-component-tab.is-active {
background: white;
color: #000;
.tabs-component-tab-a{
color: $theme-orange;
}
}
.tabs-component-tab.is-disabled * {
color: #cdcdcd;
cursor: not-allowed !important;
}
@media (min-width: 700px) {
.tabs-component-tab {
border: solid 1px #ddd;
border-radius: 3px 3px 0 0;
transform: translateY(2px);
transition: transform .3s ease;
}
.tabs-component-tab.is-active {
border-bottom: solid 1px #fff;
z-index: 35;
transform: translateY(0);
}
}
.tabs-component-tab-a {
align-items: center;
display: flex;
padding: .75em 1em;
text-decoration: none;
color: $theme-orange;
justify-content: center;
&:hover{
color: lighten($theme-orange, 15);
text-decoration: none!important;
}
}
.tabs-component-panels {
padding: 4em 0;
}
@media (min-width: 700px) {
.tabs-component-panels {
background-color: #fff;
border: solid 1px #ddd;
border-radius: 0 0 6px 6px;
box-shadow: 0 0 10px rgba(0, 0, 0, .05);
padding: 16px 1em 27px;
}
}