
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
@agencecinq/tabs
Advanced tools
Tabulation partout, tabulation nulle part
pnpm add @agencecinq/tabs
<cinq-tabs>)<cinq-tabs class="js-tabs" data-tabs-hash="true">
<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>
<section tabindex="0" role="tabpanel" aria-labelledby="home" id="home-tab">
…
</section>
<section tabindex="0" role="tabpanel" aria-labelledby="project" id="project-tab">
…
</section>
<section tabindex="0" role="tabpanel" aria-labelledby="contact" id="contact-tab">
…
</section>
</cinq-tabs>
import "@agencecinq/tabs";
When you import @agencecinq/tabs, the module registers the Web Component in the
Custom Elements Registry:
customElements.define('cinq-tabs', Tabs);
The browser then automatically “upgrades” every existing <cinq-tabs> in the DOM:
it instantiates the Tabs class, calls its connectedCallback, which in turn
calls init().
You don’t need to do new Tabs(...) or call init() manually – writing the
markup and importing the module is enough.
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>
The galeb duhr is a curious boulder-like creature with appendages that act as hands and feet.
These intelligent beings are very large and slow-moving. They live in rocky or mountainous
areas where they can feel the earth power and control the rocks around them.
</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 (LTR): moves focus to the next tab (wraps to first on last). In RTL, Right Arrow moves to the previous tab. |
| Left Arrow | When a tab has focus (LTR): moves focus to the previous tab (wraps to last on first). In RTL, Left Arrow moves to the next tab. |
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. |
Navigation with Left/Right arrow keys follows the reading direction. If the tablist (or a parent) has dir="rtl" or inherits a right-to-left direction from CSS, "next" tab is triggered by Left Arrow and "previous" by Right Arrow, so keyboard behavior matches the visual order (e.g. Arabic, Hebrew).
Options are configured via data attributes on the Web Component:
| Attribute | Type | Default | Description |
|---|---|---|---|
data-tabs-hash | boolean | true | Enables or disables synchronization of the active tab with location.hash. |
data-tabs-delay | number | 0 | Delay in ms before automatic activation when the user navigates with arrow keys (0 = no delay, i.e. manual mode). |
Events are dispatched on the tab element (the button with role="tab"). Listen on the tab, or use event delegation from <cinq-tabs>.
| Event | Cancelable | Detail | Description |
|---|---|---|---|
tab-before-activate | Yes | { index, controls, element } | Fired before activation. Call preventDefault() to cancel. For async work, cancel then call tabs.activateTab(index) when ready. |
tab-activate | No | { controls, element } | Fired when the tab is activated. |
tab-delete | No | { controls, element } | Fired when the tab is removed. |
activateTab(index)On the <cinq-tabs> element (or the Tabs instance). Call after preventing tab-before-activate to complete activation (e.g. after loading data).
const tabsEl = document.querySelector('cinq-tabs');
tabsEl.addEventListener('tab-before-activate', (e) => {
const { index, controls, element } = e.detail;
// Optional: cancel and activate later (e.g. after async work)
e.preventDefault();
fetchData(controls).then(() => {
tabsEl.activateTab(index);
});
});
// Or: just listen to tab-activate (no cancel)
tabsEl.querySelectorAll('[role="tab"]').forEach((tab) => {
tab.addEventListener('tab-activate', ({ detail }) => {
console.log('activated', detail.controls, detail.element);
});
});
# depuis la racine du monorepo CINQ
pnpm -C packages/tabs build
FAQs
Accessible, WAI-ARIA compliant tabs as a lightweight Web Component.
We found that @agencecinq/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.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.