npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@intside/accessibility

v1.1.0

Published

Module d'accessibilité ACSBLT (profils + réglages) avec installeur pour Next.js/React et WordPress/vanilla.

Readme

Module d'accessibilité ACSBLT

Widget d'accessibilité réutilisable, extrait du prototype ACSBLT. Il propose :

  • Profils d'assistance (vision réduite, dyslexie, TDAH, sensibilité aux animations, daltonisme, senior) + rappel des standards toujours actifs (lecteur d'écran, clavier).
  • Réglages personnalisés : taille du texte, interligne, police lisible, contraste, mode sombre, niveaux de gris, focus renforcé, grandes cibles, curseur agrandi, etc.
  • Persistance via localStorage (clé acsblt_a11y_v1) et application de classes sur <html>.
  • Autonome : aucune dépendance UI (pas de Tailwind, pas de jQuery requis). Couleur d'accent personnalisable via --a11y-accent.

Deux implémentations interchangeables, même clé de stockage et mêmes classes CSS :

| Dossier | Pour | Format | |---|---|---| | react/ | Next.js (App ou Pages Router), React 18+ | TypeScript / TSX | | vanilla/ | WordPress, sites statiques, tout HTML | JS + CSS, zéro dépendance |


0. Installation rapide (CLI)

Un installeur copie le bon build dans un projet cible et affiche les étapes de câblage. Il ne modifie jamais votre code (il copie des fichiers et imprime le snippet à coller).

# Next.js / React
npx @intside/accessibility install --target nextjs --dest ../mon-app --accent '#112337'

# WordPress (thème)
npx @intside/accessibility install --target wordpress \
  --dest wp-content/themes/mon-theme --accent '#0A2240' --position left

# Sans options : mode interactif
npx @intside/accessibility install

# Forcer la récupération des fichiers depuis le dépôt git (et non la copie locale)
node bin/cli.mjs install --target nextjs --dest ../mon-app --from-git --ref main

Depuis un clone du repo, sans publication : node bin/cli.mjs install … (ou npm link puis acsblt-a11y install …).

D'où viennent les fichiers copiés ? Par défaut, des fichiers livrés à côté de la CLI : ceux du clone si vous lancez node bin/cli.mjs, ou ceux du tarball téléchargé si vous lancez npx <url-git> (npm clone le dépôt et exécute le bin depuis ce clone — donc déjà la version du dépôt). Pour forcer une récupération explicite depuis le dépôt distant à une réf donnée — utile si votre clone local est ancien — passez --from-git [--ref <branche|tag>] [--repo <url>] : la CLI clone le dépôt dans un dossier temporaire, copie, puis le supprime.

| Option | Défaut | Rôle | |---|---|---| | --target | (demandé) | nextjs ou wordpress | | --dest | dossier courant | Racine du projet cible | | --subdir | components/accessibility / assets/a11y | Sous-dossier de destination | | --accent | #006828 | Couleur d'accent (--a11y-accent) | | --position | left | Coin du bouton (WordPress) | | --label | Accessibilité | Libellé / aria-label | | --report-email | [email protected] | Lien « Signaler un problème » (WordPress) | | --cookie-domain | — | Partage cross-sous-domaine : auto ou .exemple.com | | --from-git | — | Récupère les fichiers depuis le dépôt distant | | --ref | main | Réf git à récupérer (avec --from-git) | | --repo | GitLab packages/accessibility | URL du dépôt (avec --from-git) | | -y, --yes | — | Valeurs par défaut, sans prompt |

Les deux sections ci-dessous détaillent le câblage manuel produit par la CLI.

Mettre à jour un projet existant

L'installeur copie les fichiers du module dans le projet (il ne les lie pas). Pour récupérer une nouvelle version, relancez la même commande : elle réécrit les fichiers du module avec la version à jour.

# Cas standard : fichiers copiés par la CLI
# Le @latest évite le cache npx et force la dernière version publiée
npx @intside/accessibility@latest install --target nextjs --dest .
npx @intside/accessibility@latest install --target wordpress --dest .

# Si le module est en dépendance dans package.json
npm install @intside/accessibility@latest

⚠️ La mise à jour écrase les fichiers du module (AccessibilityModal.tsx, acsblt-accessibility.js/.css, …). Commitez avant de relancer, puis vérifiez le git diff. Gardez vos personnalisations hors des fichiers du module — via les options (--accent, --position, …) ou la config window.ACSBLT_A11Y — pour qu'elles survivent aux mises à jour.


1. Version React / Next.js (react/)

Copiez le dossier react/ dans votre projet (ex. src/components/accessibility/) et importez.

Bouton prêt à l'emploi

// app/layout.tsx (ou un header/footer)
import { AccessibilityButton } from '@/components/accessibility';

export default function Layout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="fr">
      <body>
        {children}
        <AccessibilityButton label="Accessibilité" />
      </body>
    </html>
  );
}

AccessibilityButton accepte label, className, style, hideIcon. Sans className, il est neutre (hérite de la couleur du parent) — placez-le dans votre top-bar, votre footer, etc.

Deux déclencheurs au choix

Le module fournit deux points d'entrée interchangeables (ils ouvrent le même modal) — choisissez l'un ou l'autre :

| Composant | Usage | Rendu | |---|---|---| | AccessibilityButton | Lien inline dans une barre (top-bar, footer, menu) | Hérite du style du parent | | AccessibilityFab | Bouton flottant ancré dans un coin | Pastille ronde autonome (icône seule) |

import { AccessibilityFab } from '@/components/accessibility';

// Bouton flottant rond en bas à gauche (défaut)
<AccessibilityFab />

// Autres coins + variantes
<AccessibilityFab position="bottom-right" />
<AccessibilityFab hideLabel={false} label="Accès." />   // pilule avec libellé
<AccessibilityFab offset={16} />

AccessibilityFab accepte position ('bottom-left' défaut, 'bottom-right', 'top-left', 'top-right'), label, hideLabel (défaut true → pastille ronde ; false → pilule avec texte), offset (px depuis les bords), className, style. Par défaut : pastille ronde, couleur --a11y-accent, léger agrandissement au survol. Avec className, le style par défaut est entièrement remplacé par le vôtre.

Côté vanilla (WordPress), le bouton flottant est déjà géré : window.ACSBLT_A11Y = { fab: true, position: 'left' } l'ancre en bas à gauche.

Contrôle manuel (votre propre déclencheur)

'use client';
import { useState } from 'react';
import { AccessibilityModal } from '@/components/accessibility';

export function MyTrigger() {
  const [open, setOpen] = useState(false);
  return (
    <>
      <button onClick={() => setOpen(true)}>Accessibilité</button>
      {open && <AccessibilityModal onClose={() => setOpen(false)} />}
    </>
  );
}

Éviter le flash au chargement (recommandé)

Appliquez les préférences avant le premier paint avec le script exporté :

// app/layout.tsx — App Router
import Script from 'next/script';
import { A11Y_INIT_SCRIPT } from '@/components/accessibility';

// dans <head> ou juste après <body>
<Script id="a11y-init" strategy="beforeInteractive">
  {A11Y_INIT_SCRIPT}
</Script>

Personnalisation du thème

Le modal lit des CSS variables avec valeurs par défaut. Surchargez-les au niveau :root :

:root {
  --a11y-accent: #0a66c2;          /* couleur principale */
  --a11y-accent-soft: #0a66c21a;
  --a11y-surface: #fff;
  --a11y-text: #111;
  /* … voir A11Y_TOKENS dans react/engine.ts */
}

API exportée

AccessibilityModal, AccessibilityButton, A11YIcon, et le moteur : loadA11y, saveA11y, applyA11yClasses, ensureA11yStyles, les données ACC_PROFILES / ACC_SETTINGS / ACC_STANDARDS, et les constantes A11Y_CSS, A11Y_TOKENS, A11Y_INIT_SCRIPT, STORAGE_KEY.

Composants en 'use client' : ils utilisent les hooks React, localStorage et document. SSR-safe (les accès navigateur sont dans useEffect).


2. Version WordPress / vanilla JS (vanilla/)

Trois fichiers, aucune dépendance (fonctionne avec ou sans jQuery) :

  • acsblt-accessibility.css — effets runtime + styles du widget
  • acsblt-accessibility.js — logique + UI (bouton flottant + modal), auto-init
  • acsblt-accessibility-head.js — script pré-paint optionnel (anti-flash, à mettre dans <head>)

Intégration HTML minimale

<link rel="stylesheet" href="/a11y/acsblt-accessibility.css">
<!-- dans <head>, avant le rendu (optionnel mais recommandé) -->
<script src="/a11y/acsblt-accessibility-head.js"></script>
<!-- config optionnelle AVANT le script principal -->
<script>window.ACSBLT_A11Y = { fab: true, position: 'right', accent: '#006828' };</script>
<!-- en fin de <body> -->
<script src="/a11y/acsblt-accessibility.js" defer></script>

Un bouton flottant apparaît automatiquement (bas-droite). Pour utiliser votre propre déclencheur à la place :

<script>window.ACSBLT_A11Y = { fab: false };</script>
<a href="#" data-acsblt-a11y-open>Accessibilité</a>

WordPress

Voir vanilla/wordpress-example.php : enqueue propre via wp_enqueue_scripts, config injectée avec wp_add_inline_script, et script pré-paint dans wp_head. À coller dans functions.php (thème enfant) ou dans un mu-plugin.

Options de configuration (window.ACSBLT_A11Y)

| Clé | Défaut | Description | |---|---|---| | fab | true | Affiche le bouton flottant automatique | | position | 'right' | 'right' ou 'left' | | label | 'Accessibilité' | Libellé du bouton flottant | | accent | #006828 | Couleur d'accent (équivaut à --a11y-accent) | | reportEmail | [email protected] | Adresse du lien « Signaler un problème » |

API JS publique

AcsbltA11y.open();      // ouvre le modal
AcsbltA11y.close();
AcsbltA11y.toggle();
AcsbltA11y.reset();     // réinitialise les préférences
AcsbltA11y.getState();  // copie de l'état courant

État des actions (ce qui s'applique réellement)

Toutes les actions persistent la préférence ; voici ce qu'elles produisent visuellement :

  • Profils (vision réduite, dyslexie, TDAH, animations, daltonisme, senior) : ✅ effet CSS immédiat.
  • Texte : taille du texte ✅ (agit désormais seule, pas seulement avec un profil), interligne ✅, espacement ✅, police lisible ✅, alignement à gauche ✅, largeur max ✅ (cible main / .entry-content / article).
  • Couleurs & contraste : contraste ✅, mode sombre ✅, niveaux de gris ✅, souligner les liens ✅, boutons en évidence ✅.
  • Mouvement : réduire les animations ✅, désactiver les transitions ✅.
  • Navigation : focus renforcé ✅, grandes cibles ✅, curseur agrandi ✅.
  • Dépendants de votre application (la préférence est stockée mais l'effet exige du markup spécifique à votre site) :
    • showShortcuts (afficher les raccourcis clavier), fieldHints (aides sous les champs), errorSummary (résumé des erreurs en haut).
    • Lisez ces drapeaux dans votre code via getState() (vanilla) ou loadA11y() (React) pour les implémenter selon votre UI.

Le mode sombre utilise filter: invert() sur <html> (approche simple, imparfaite sur images/embeds — celles-ci sont ré-inversées). Pour un vrai dark-mode à base de tokens, prévoir un chantier dédié.

Notes

  • Les deux versions partagent la même clé acsblt_a11y_v1 et les mêmes classes a11y-* sur <html> : un utilisateur garde ses préférences s'il passe d'un site React à un site WordPress sur la même origine. Pour partager entre sous-domaines, voir « Partager les préférences entre sous-domaines » ci-dessous (cookie de domaine parent).
  • Les données (profils, réglages, CSS runtime) sont dupliquées dans chaque version pour rester totalement autonomes. En cas de modification, répercutez-la dans react/engine.ts et vanilla/acsblt-accessibility.js + .css.
  • Certains effets reposent sur des sélecteurs génériques (main, button, a, [aria-invalid]). Adaptez A11Y_CSS / le .css à vos classes spécifiques si besoin (ex. .entry-content pour WordPress est déjà inclus).

Publier une nouvelle version (mainteneurs)

Le script npm run release enchaîne tout : bump de version, commit + tag, push dev, fast-forward de main, puis npm publish.

export NPM_TOKEN=npm_xxx          # token « Automation » (contourne le 2FA) — voir .env.example
npm run release -- patch          # 1.0.1 -> 1.0.2
npm run release -- minor          # nouvelle fonctionnalité rétro-compatible
npm run release -- major          # changement cassant

Le token est lu depuis NPM_TOKEN (ou un .env local non versionné) et n'est jamais écrit dans un fichier suivi par git. Le script refuse de tourner si le working tree n'est pas propre ou si tu n'es pas sur la branche dev.

Partager les préférences entre sous-domaines

Par défaut, les préférences sont stockées dans localStorage, cloisonné par origine : cocreation.bj et app.cocreation.bj ne les partagent donc pas.

Pour les partager entre sous-domaines d'un même domaine parent, configurez un cookieDomain : le module écrit alors un cookie sur ce domaine (lisible par tous les sous-domaines), en plus du localStorage.

WordPress / vanilla — avant le chargement du script :

<script>window.ACSBLT_A11Y = { cookieDomain: '.cocreation.bj' };</script>

Next.js / React — via la prop du modal :

<AccessibilityModal onClose={() => setOpen(false)} cookieDomain=".cocreation.bj" />

(ou par programme : configureA11y({ cookieDomain: '.cocreation.bj' })).

'auto' : déduire le domaine tout seul

Au lieu d'écrire le domaine en dur, passez 'auto' : le module le déduit de l'URL courante (app.cocreation.bj.cocreation.bj, manage.intside.com.intside.com). Pratique pour installer le même code sur plusieurs sous-domaines sans rien adapter.

<script>window.ACSBLT_A11Y = { cookieDomain: 'auto' };</script>
<AccessibilityModal onClose={() => setOpen(false)} cookieDomain="auto" />

Résolution exacte (Public Suffix List). En mode 'auto', l'installeur embarque un module de données PSL (acsblt-accessibility-psl.js côté WordPress, psl-data.ts côté React) et le charge avant le script principal. La dérivation est alors exacte : suffixes multi-niveaux (example.co.uk.example.co.uk, site.com.au.site.com.au, co.jp, gov.za…), wildcards (*.ck) et exceptions (!www.ck) gérés selon l'algorithme officiel de la Public Suffix List.

  • Le fichier de données (~128 KB, ~37 KB gzip) n'est chargé que sur les sites en mode 'auto' ; les autres installations n'en paient pas le coût.
  • Régénérez-le quand la PSL évolue : npm run build:psl (récupère la liste officielle et réécrit les fichiers de données).

Sans le module PSL (si vous activez cookieDomain: 'auto' à la main sans charger psl-data), le module retombe sur une heuristique des ccTLD à deux niveaux (co, com, org, gov, ac… sous un TLD pays) — correcte pour l'immense majorité des cas, mais pas exhaustive. 'auto' renvoie vide (localStorage seul) sur localhost et les adresses IP.

  • Le cookie est petit (< 1 KB), Path=/, SameSite=Lax, Secure en HTTPS, expiration 1 an. Le point initial (.cocreation.bj) le rend valable pour tous les sous-domaines.
  • La synchro est effective au prochain chargement / navigation sur l'autre site (les cookies n'émettent pas d'événement entre onglets déjà ouverts).
  • Ne fonctionne que pour un domaine parent commun. Pour deux domaines totalement distincts, il faudrait un partage côté serveur ou une iframe + postMessage.

⚠️ Ça ne marche que si les deux sites sont réellement sur le même domaine parent. cocreation.bj + app.cocreation.bj ✅ ; cocreation.bj + cocreation.com ❌.