
Security News
Axios Maintainer Confirms Social Engineering Attack Behind npm Compromise
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.
@19h47/tabs
Advanced tools
Tabulation partout, tabulation nulle part
yarn add @19h47/tabs
import Tabs from '@19h47/tabs';
const $element = document.querySelector('.js-tabs');
const tabs = new Tabs($element);
tabs.init();
The element that serves as a container for the set of tabs. The role="tablist" attribute is required.
The aria-label="" attribute provides a label that describes the purpose of the set of tabs.
The role="tablist"needs to be on a container element such as a <div>, <nav>, or <section>. It should not be placed on a <ul> element. Direct children of the tablist must be the tab elements with role="tab".
<div role="tablist" aria-label="navigation">
<button
type="button"
class="is-active"
role="tab"
aria-selected="true"
aria-controls="home-tab"
id="home"
>
Home
</button>
<button
type="button"
role="tab"
aria-selected="false"
aria-controls="project-tab"
id="project"
tabindex="-1"
>
Project
</button>
<button
type="button"
role="tab"
aria-selected="false"
aria-controls="contact-tab"
id="contact"
tabindex="-1"
data-deletable=""
>
Contact
</button>
</div>
An element in the tab list that serves as a label for one of the tab panels and can be activated to display that panel.
<button
type="button"
role="tab"
aria-selected="false"
aria-controls="foo-tab"
id="foo"
tabindex="-1"
>
Project
</button>
The role="tab" attribute is required.
The aria-controls="foo-tab" refers to the id of the tabpanel element associated with the tab.
Since an HTML button element is used for the tab, it is not necessary to set tabindex="0" on the selected (active) tab element.
Is the tabulation deletable? You can set up this option by adding the data-deletable attribute on button.
To active the button on first load, add a is-active class to the button, remove the tabindex attribute and switch to true the aria-selected attribute.
The element that contains the content associated with a tab.
<section tabindex="0" role="tabpanel" aria-labelledby="foo" id="foo-tab">
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nihil hic, vero. Fugiat voluptas
ex consequatur hic nemo officia iure placeat non, pariatur, dolore natus nobis, tempore
dolores dicta nisi inventore.
</p>
</section>
To active panel on first load, add a is-active class to it.
| Key | Function |
|---|---|
| Tab |
|
| Enter Space | When a tab has focus, activates the tab, causing its associated panel to be displayed. |
| Right Arrow | When a tab has focus:
|
| Left Arrow | When a tab has focus:
|
Homefn + left arrow | When a tab has focus, moves focus to the first tab. |
Endfn + right arrow | When a tab has focus, moves focus to the last tab. |
| Delete | When focus is on the Contact tab, removes the tab from the tab list and places focus on the previous tab. |
| Option | Type | Default | Description |
|---|---|---|---|
| delay | integer | 0 | Determine whether there should be a delay when user navigates with the arrow keys |
| hash | boolean | true | |
| callback | function | () => {} | A callback fired right before Tab.activate event. Useful for animation or to fetch data for instance. Don't use arrow function if you need to access this. |
import Tabs from '@19h47/tabs';
const $element = document.querySelector('.js-tabs');
const tabs = new Tabs($el, {
callback() {
return new Promise(resolve => {
// animate, fetch data, use this, do your stuff, etc.
resolve();
});
},
});
tabs.init();
| Event | Arguments | Description |
|---|---|---|
| Tab.activate | event | Detail object containing current controls id, and current DOM element |
| Tab.delete | event | Detail object containing current controls id, and current DOM element |
import Tabs from '@19h47/tabs';
const $element = document.querySelector('.js-tabs');
const tabs = new Tabs($element);
tabs.init();
tabs.tabs.forEach($tab => {
$tab.el.addEventListener('Tab.activate', ({ detail }) => {
const { controls, element } = detail;
console.log(controls, element);
});
$tab.el.addEventListener('Tab.delete', ({ detail }) => {
const { controls, element } = detail;
console.log(controls, element);
});
});
| Method | |
|---|---|
destroy() | Destroy |
init() | Create |
create() | Create |
# install dependencies
$ yarn install
# serve with hot reload at localhost:3000
$ yarn start
# build for production
$ yarn prod
An example is located right here, see sources.
FAQs
Tabs
We found that @19h47/tabs demonstrated a healthy version release cadence and project activity because the last version was released less than 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.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.