
Research
2025 Report: Destructive Malware in Open Source Packages
Destructive malware is rising across open source registries, using delays and kill switches to wipe code, break builds, and disrupt CI/CD.
mat-tab-swiper
Advanced tools
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.
Please visit this link to see a working demo of Material Tab Swiper.
NPM: npm i mat-tab-swiper
CDN: <script src="https://unpkg.com/mat-tab-swiper/dist/mattabswiper.js"></script>
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();
});
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
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.
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.
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.
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.
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
})
}
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.
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.
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
})
Active slide index as initial slide. It takes a valid number as slide index. Defaults to 0.
Slider animation speed in ms. Speed for slide and tab transition is denoted by this. It takes a number. Default is 300.
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'
}
All the events are js events. So you can access value through 'event.detail' if value is provided with event.
Fires after slide changed. It also emits the slide index. The index of the slide can be accessed through 'event.detail.index'
Fired after transition ends
Fires when a tab is clicked. The index of the tab can be accessed through 'event.detail.index'
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.
Fired when slide moves, emits direction as 'right' or 'left'. You can access it through 'event.detail.direction'.
Fires when 'swiper' object is fired. You can use this to manipulate swiper's behaviour. Visit SwiperJS for detailed API.
Fires the swiper-wrapper html-element when ready
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'
});
})
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
Slides to next slide. Takes no argument.
Slides to preveious slide. Takes no argument.
Slides to the index passed. Suppose you want to slide to 3rd slide. You have to call
matTabSwiper.slideTo(2)
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)
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.
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 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.
For further help contact juny.ss91@gmail.com if you need help with integration.
FAQs
Material Tab Swiper
We found that mat-tab-swiper demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
Destructive malware is rising across open source registries, using delays and kill switches to wipe code, break builds, and disrupt CI/CD.

Security News
Socket CTO Ahmad Nassri shares practical AI coding techniques, tools, and team workflows, plus what still feels noisy and why shipping remains human-led.

Research
/Security News
A five-month operation turned 27 npm packages into durable hosting for browser-run lures that mimic document-sharing portals and Microsoft sign-in, targeting 25 organizations across manufacturing, industrial automation, plastics, and healthcare for credential theft.