mat-tab-swiper
v1.1.16
Published
Material Tab Swiper
Downloads
2,484
Maintainers
Readme
Material Tab Swiper
First complete material tab swiper that works as a web component, which means that it can be embedded into React, Angular, Vue, Ember and most importantly, simple VanillaJS extremely easily.
The API to use this is very straightforward. Default tab background and highlighter has a color. But you can change them easily according to your need with input. The tabs' minimum width is (container-width / number of tabs), but they can be as wide as they require. They don't have to be the same width. The highlighter animation will work in its own way.
This component is made with Stencil, a fast, robust, easy to use web-component generation tool.
Demo
Please visit this link to see a working demo of Material Tab Swiper.
Installation
NPM: npm i mat-tab-swiper
CDN: <script src="https://unpkg.com/mat-tab-swiper/dist/mattabswiper.js"></script>
Framework Integration
React
Install the component with npm i mat-tab-swiper
.
In your 'index.js' file, you have to do the following:
import { applyPolyfills, defineCustomElements } from 'mat-tab-swiper/loader';
...
applyPolyfills().then(() => {
defineCustomElements();
});
Angular
Install the component with npm i mat-tab-swiper
. For angular you have to do the following in app.module.ts
import { applyPolyfills, defineCustomElements } from 'mat-tab-swiper/loader';
...
applyPolyfills().then(() => {
defineCustomElements();
});
Then you can import 'CUSTOM_ELEMENTS_SCHEMA' like following in your lazy loaded module where you will use it.
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
Then you need to add it to 'schemas' array inside NgModule like following
@NgModule({
declarations: [...],
imports: [...],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
Then you are ready to use it as an angular custom element
Vue
Install the component with npm i mat-tab-swiper
Then do the following in 'main.js' file
import { applyPolyfills, defineCustomElements } from 'test-components/loader';
...
applyPolyfills().then(() => {
defineCustomElements();
});
Now the 'mat-tab-swiper' should be available to use in any component.
Ember
It is really easy to integrate with Ember. Ember even has an add-on to integrate with Stencil components. Go to this page to know how to integrate with Ember.
Javascript
Getting started in VanillaJS is very easy. Just add the script tag at top and get started.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Swiper</title>
<script src="https://unpkg.com/mat-tab-swiper/dist/mattabswiper.js"></script>
</head>
<body>
<mat-tab-swiper>
<mat-swiper tab="Tab1">
...
</mat-swiper>
<mat-swiper tab="Tab2">
...
</mat-swiper>
<mat-swiper tab="Tab3">
...
</mat-swiper>
</mat-tab-swiper>
</body>
</html>
For more on this, please read in detail about how to integrate web-components in your framework.
How To Use
After you install it with npm i mat-tab-swiper
or use script tag like,<script src="https://unpkg.com/mat-tab-swiper/dist/mattabswiper.js"></script>
, just add the following html to get your tabswiper up and running.
<mat-tab-swiper>
<mat-swiper tab="Tab1">
...
</mat-swiper>
<mat-swiper tab="Tab2">
...
</mat-swiper>
<mat-swiper tab="Tab3">
...
</mat-swiper>
</mat-tab-swiper>
You are done!!
The tabswiper has a few inputs and events to help you out with your custom needs be it css or functional. Following shows the advanced use in various frameworks.
React
You can pass the inputs to this component exactly the way you do in any other component. But to access events, you assign eventlistener to the element like following.
<mat-tab-swiper ref={(ref)=> this.tabSwiperRef = ref}>
<mat-swiper tab="Tab1">
...
</mat-swiper>
<mat-swiper tab="Tab2">
...
</mat-swiper>
<mat-swiper tab="Tab3">
...
</mat-swiper>
</mat-tab-swiper>
...
componentDidMount() {
this.tabSwiperRef.addEventListener('slidemove', (e) => {
// 'slidemove' gives the moving direction as output
})
}
Angular
The input and output event work exactly the same way it does in normal angular component. If you want to access the element in the ts file, use '@ViewChild' as ElementRef.
Vue
If you want to access the TabSwiper's element, you can use 'ref'. For passing input data and accessing output events, it works in the exact way as any other custom components.
Javascript
For VanillaJS, you can pass input and access event in following way.
let matTabSwiper = document.querySelector('mat-tab-swiper')
The default initial slide index is 0 but you can also initialize with an input property 'activeIndex',
matTabSwiper.activeIndex = 1
You can pass tab's css properties the same way. The input's name is 'tabCssProperties'. It has an interface as,
{
background: string
highlighterBackground: string
textColor: string
}
You can pass the properties the same way,
matTabSwiper.tabCssProperties = {
background: '#fc3535',
highlighterBackground: '#000',
textColor: '#000'
}
The events are simple js events. So, you can access events in normal js way. The below code shows accessing 'slidechanged' event.
matTabSwiper.addEventListener('slidechanged', (e) => {
// e.detail.index is a valid slide index
})
Input Properties
activeIndex
Active slide index as initial slide. It takes a valid number as slide index. Defaults to 0.
sliderSpeed
Slider animation speed in ms. Speed for slide and tab transition is denoted by this. It takes a number. Default is 300.
tabCssProperties
Css properties for tabs container. It has an interface as following,
{
background: string
highlighterBackground: string
textColor: string
}
Defaults to,
{
background: '#bad97d',
highlighterBackground: '#000',
textColor: '#000'
}
Events
All the events are js events. So you can access value through 'event.detail' if value is provided with event.
slidechanged
Fires after slide changed. It also emits the slide index. The index of the slide can be accessed through 'event.detail.index'
transitionend
Fired after transition ends
tabclicked
Fires when a tab is clicked. The index of the tab can be accessed through 'event.detail.index'
slidevisited
Fires when a slide changes. It shows whether the tab is already visited or not. You can make use of it if you are doing differential loading. If you are looking for 'Tab1', 'event.detail.Tab1' returns boolean. It also gives 'currentTab' property which you can access through 'event.detail.currentTab'. Visit Differential Loading section of this page to read in detail.
slidemove
Fired when slide moves, emits direction as 'right' or 'left'. You can access it through 'event.detail.direction'.
receiveswiper
Fires when 'swiper' object is fired. You can use this to manipulate swiper's behaviour. Visit SwiperJS for detailed API.
receiveswiperelement
Fires the swiper-wrapper html-element when ready
receivetabelement
Fires the tab-container html-element when ready
If you want to manipulate the tabs, you can do it through the 'receivetabelement' event by accessing the tab elements. It is using shadowdom so you can not easily access it through normal js. You can do it this way,
let matTabSwiper = document.querySelector('mat-tab-swiper')
matTabSwiper.addEventListener('receivetabelement', (e) => {
let tabContainer = e.detail
// If you want to change the fontsize of the tabs, the class of each tab is 'inner-tab'
let tabs = tabContainer.querySelectorAll('.inner-tab')
tabs.forEach(element => {
element.style.fontSize = '20px'
});
})
Methods
You have to access the element in your framework in order to call any methods.
let matTabSwiper = document.querySelector('mat-tab-swiper')
Use 'ref' for React and Vue and 'Viewchild' for Angular
slideNext
Slides to next slide. Takes no argument.
slidePrevious
Slides to preveious slide. Takes no argument.
slideTo
Slides to the index passed. Suppose you want to slide to 3rd slide. You have to call
matTabSwiper.slideTo(2)
lockSwipe
For locking and unlocking the swipe. Takes a boolean. If you want to lock, you have to pass true
. Or false
if you want to unlock.
EG: matTabSwiper.lockSwipe(true)
lockNextSwipe
For locking and unlocking the swipe to go to next slide. Takes a boolean. If you want to lock, you have to pass true
. Or false
if you want to unlock.
lockPrevSwipe
For locking and unlocking the swipe to go to preveious slide. Takes a boolean. If you want to lock, you have to pass true
. Or false
if you want to unlock.
Differential Loading
Differential loading here means that you load the content inside specific 'mat-swiper' if that slide is at all visited once by the user. Otherwise you end up calling unnecessary API's that user need not see content of and DOM loads unnecesary contents which resides in another slide which user did not visit.
This is not done by default, however you can make use of 'slidevisited' EventListener to achieve this. You can check whether the current swiper if at all visited atleast once. If not visited once, then content inside can be loaded and then thereafter it maintains the state be it the scroll position or other things for succeeding visits. The 'slidevisited' event holds the given tab names as properties and values as boolean whether they have been visited already. It also gives 'currentTab' property which provides the active swipe's tab name.
For a swiper with tab name "Tab1", you can load the content inside it in the following manner.
Suppose you have a variable 'slideVisitedObject' which stores last event data emitted by 'slidevisited' event.
If you are using templating mechanism that conditionally renders content, like simple 'if' for React or '*ngIf' for Angular or 'v-if' for Vue, you can do it in following way:
let matTabSwiper = document.querySelector('mat-tab-swiper')
matTabSwiper.addEventListener('slidevisited', (e) => {
this.slideVisitedObject = e.detail
})
<mat-swiper tab='Tab1'>
{ if (this.slideVisitedObject.currentTab == 'Tab1' || this.slideVisitedObject['Tab1']) == true } // React
*ngIf="this.slideVisitedObject.currentTab == 'Tab1' || this.slideVisitedObject['Tab1']) == true" // Angular
v-if="this.slideVisitedObject.currentTab == 'Tab1' || this.slideVisitedObject['Tab1']) == true" // Vue
</mat-swiper>
*** Do not put the condition on 'mat-swiper' element itself.
If you are using Vanilla JS or DOM manipulation in any framework where you inject the content later, you do the following way:
<mat-tab-swiper>
<mat-swiper tab="Tab1">
</mat-swiper>
<mat-swiper tab="Tab2">
</mat-swiper>
<mat-swiper tab="Tab3">
</mat-swiper>
</mat-tab-swiper>
let matTabSwiper = document.querySelector('mat-tab-swiper')
matTabSwiper.addEventListener('slidevisited', (e) => {
let slideVisitedObject = e.detail
if(!slideVisitedObject[slideVisitedObject.currentTab]) { // Truthy checking
let currentTab = document.querySelector([tab="Tab1"])
currentTab.innerHTML = <Your Content>
}
})
For a particular slide, !slideVisitedObject[slideVisitedObject.currentTab]
condition will yield only once in its entire lifecycle. So the above code ensures that a tab which is in focus currently but not visited yet once gets loaded and stays in the DOM for succeeding visits without further loading.
Further help
For further help contact [email protected] if you need help with integration.