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

@lifechangers/ui

v0.9.0

Published

Design system LIFE CHANGERS : tokens clair/sombre, polices, texture « alvéoles », logos, icônes et composants du shell pour les applications du LIFE Hub.

Downloads

579

Readme

@lifechangers/ui — design system LIFE CHANGERS

Le socle visuel commun des applications du LIFE Hub : tokens clair et sombre, polices, texture de marque « alvéoles iridescentes », logos et icônes (apps, domaines, sections) en composants React. Direction « D · Épurée » validée par Redouane le 2026-09-05 sur les maquettes DonCollect (_DOCS/DESIGN-SYSTEM/maquettes/).

Ce dépôt est l'étape 1 du chantier C3 du plan _DOCS/DESIGN-SYSTEM/00-PLAN-HARMONISATION-DA-NAVIGATION.md. Le suivi est dans ROADMAP-TODOLIST.md.

Ce que contient le package

| Chemin | Rôle | |---|---| | src/tokens/tokens.css | Toutes les variables --lc-* : couleurs (clair, sombre, accent par organisation), rayons, ombres, typographie, espacements, mouvement | | src/tokens/tailwind-preset.cjs | Preset Tailwind 3 pour les 10 apps Lovable (React 18) | | src/tokens/theme.tailwind4.css | Thème Tailwind 4 (@theme inline) pour les 6 apps TanStack Start (React 19) | | src/fonts/fonts.css | Jeu libre actif (Anton, Archivo, JetBrains Mono) et emplacements du jeu officiel (Agharti, Acumin) | | src/brand/texture.css | Surface de marque texturée, bouton principal, tuiles, médaillons, avatars (généré) | | src/brand/logos/ | Emblème, logo application, principal, horizontal, vertical — dégradé et monochromes, SVG | | src/tokens/shadcn-bridge.css | Le pont : donne aux variables de thème shadcn les valeurs des --lc-*. Une app l'importe et change de direction artistique sans qu'un composant soit modifié. Généré | | src/react/ | Marque et icônes (BrandMark, AppIcon, DomainIcon, SectionIcon, HexAvatar), shell (AppShell, Sidebar, Topbar, PageHeader, DetailDrawer), primitives (Button, Pill, Card, StatCard, Segmented, FilterChip, EmptyState), données (DataTable, Honeycomb, SmoothAreaChart, DailyBars), et le style validé du 12/09 (SidebarRail, AiBar, HeroTitle, MiniTile, IconTile) | | scripts/shadcn_bridge.py | Génère le pont, le pose dans une app (--to), dit s'il a dérivé (--check) | | scripts/apply_to_app.py | Branche une app entière en une commande, ou vérifie qu'elle l'est (--check) | | check/render.check.tsx | Contrôle de rendu sans framework (npm run check) | | dist/ | JavaScript transpilé + déclarations de types, construits par npm run build (tsup). Une app ne compile jamais le TypeScript d'une dépendance | | scripts/glyphs.py | Source de vérité des glyphes d'icônes ; scripts/build.py régénère CSS, TSX et vitrine | | showcase/index.html | Page vitrine autonome : tout le package dans les deux thèmes |

Comment la bibliothèque arrive dans les applications (décision du 2026-09-12)

Le hub compte 14 applications, une par dépôt, réparties en deux familles, et elles ne se branchent pas pareil.

| Famille | Apps | Ce qu'elles reçoivent | |---|---|---| | Tailwind 3 + shadcn (Vite, déployées par Lovable) | 10 : Center, Bridge, CRM, DonCollect, Engage, People, Pilot, Projects, Studio, Tasks | shadcn-bridge.css posé par commande dans l'app | | Tailwind 4 + TanStack Start | 4 : Drive, Finance, RGPD, Video | shadcn-bridge-tw4.css posé par la même commande, polices chargées par lien |

Pourquoi un fichier posé et non une dépendance pour la première famille, alors qu'une dépendance serait plus élégante :

  1. Ces apps sont construites par Lovable. Un fichier déjà présent dans le dépôt n'a rien à installer, rien à authentifier, rien à construire au moment du déploiement. Une dépendance ajoute trois points de panne dans un environnement qu'on ne contrôle pas.
  2. Lovable réécrit du code. Le pont agit sur les variables de thème de shadcn : tout composant que Lovable régénère hérite de la direction artistique sans rien savoir d'elle. Une bibliothèque de composants React, elle, se ferait écraser.
  3. Une copie posée ne dérive pas. Elle porte la version, la commande qui la régénère, et --check la compare à la bibliothèque. Ce n'est pas une copie recopiée, c'est une copie vérifiée.

La deuxième famille reçoit elle aussi une copie posée, par la même commande : un seul mécanisme pour tout le hub. Ses polices sont chargées par un lien dans __root.tsx et non par un @import url() dans la feuille, que la chaîne CSS de Tailwind 4 prend pour un fichier local.

La cible reste npm. Le jour où l'organisation @lifechangers existe sur npm, npm publish suffit : le champ files n'embarque ni la démo ni ses chiffres réels. D'ici là le dépôt git fait le travail pour la seconde famille, et la copie posée pour la première.

Brancher une application

Aujourd'hui — la bibliothèque n'est pas encore publiée

Le dépôt est local et n'a pas de dépôt distant. En attendant, une app reçoit une copie posée par la bibliothèque, pas une copie recopiée à la main : elle porte le numéro de version et la commande qui la régénère, et une commande dit si elle a dérivé.

cd DESIGN-SYSTEM/life-design-system
python3 scripts/apply_to_app.py ../../CENTER/life-suite-hub          # brancher
python3 scripts/apply_to_app.py ../../CENTER/life-suite-hub --check  # vérifier

La commande fait trois choses et ne touche aucun composant de l'app : elle pose src/styles/lifechangers-da.css, l'importe dans src/main.tsx après ./index.css, et fait lire var(--font-sans) / var(--font-display) à tailwind.config.ts. Elle est idempotente : la relancer après un changement de couleur met la copie à jour.

Retour arrière dans une app : supprimer la ligne d'import dans src/main.tsx. Rien d'autre.

Deux pièges, vérifiés sur le CSS construit :

  1. le pont doit être importé après index.css, depuis main.tsx. Tailwind 3 retire les at-rules @layer au build : seul l'ordre des règles dans le bundle décide. Importé depuis le haut d'index.css, il passe avant le thème d'origine et n'a aucun effet ;
  2. si tailwind.config.ts code les polices en dur, elles ne changent pas, quoi que disent les tokens.

Pour s'en assurer, la nouvelle valeur doit arriver en dernier :

npx vite build && grep -bo -- "--primary: [0-9][^;]*" dist/assets/*.css

Ajouter une application qui n'existe pas encore

Rien de particulier : apply_to_app.py <chemin> suffit dès que l'app a un package.json, un src/main.tsx qui importe ./index.css, et un tailwind.config.ts. C'est le cas du modèle d'app du hub. La commande refuse et dit ce qui manque plutôt que de deviner.

Garde-fou

apply_to_app.py --check sort en erreur si le pont est absent, s'il a dérivé, s'il est importé au mauvais endroit ou si les polices sont codées en dur. C'est la commande à mettre en intégration continue sur chaque app du hub.

Après publication

npm install @lifechangers/ui   # dans le dossier de l'APPLICATION, jamais dans celui de la bibliothèque

Lancée depuis DESIGN-SYSTEM/life-design-system, cette commande ajoute la bibliothèque comme dépendance d'elle-même. Sans gravité, mais à annuler : npm uninstall @lifechangers/ui.

/* src/index.css */
@import "@lifechangers/ui/index.css";
// src/main.tsx — après "./index.css"
import "@lifechangers/ui/shadcn-bridge.css";

App Lovable (React 18, Tailwind 3)

// tailwind.config.ts
import preset from "@lifechangers/ui/tailwind-preset";
export default { presets: [preset], content: ["./index.html", "./src/**/*.{ts,tsx}"] };

App TanStack Start (React 19, Tailwind 4)

/* src/styles.css */
@import "tailwindcss";
@import "@lifechangers/ui/index.css";
@import "@lifechangers/ui/theme.tailwind4.css";

Composants

import { AppIcon, DomainIcon, SectionIcon, BrandMark, HexAvatar } from "@lifechangers/ui";

<AppIcon app="doncollect" size={40} />
<DomainIcon domain="eau" size={32} />
<SectionIcon name="dons" />
<HexAvatar initials="RB" brand />

Poser data-lc (ou la classe lc-root) sur le conteneur racine pour hériter du fond, de la couleur et de la police. Le thème sombre suit prefers-color-scheme ; data-theme="dark" ou "light" sur <html> force un thème.

Règles d'emploi

  1. Une surface texturée par écran au maximum (.lc-surface-brand, .lc-btn-brand, AppIcon, HexAvatar brand) : bouton principal, tuile d'app, avatar d'équipe, panneau de connexion, en-tête d'email, progression. Jamais derrière un tableau, un formulaire ou un texte long.
  2. Violet en clair, turquoise en sombre : l'accent change de couleur avec le thème pour rester lisible. Le turquoise #00B5BC de la charte n'est jamais utilisé en texte sur fond clair (contraste 2,2:1).
  3. Couleur par organisation (décision D1) : une organisation cliente pose data-org-accent et --lc-org-accent sur ses surfaces publiques (page de don, widget, email). LIFE garde le violet.
  4. Aucune couleur en dur dans les apps : tout passe par --lc-* ou les utilitaires Tailwind lc-*.
  5. Polices : rôles fixes (display, corps, condensé, mono). Le jeu officiel (Agharti + Acumin) remplace le jeu libre par les tokens, sans toucher aux apps, quand les licences sont achetées.

Changer une couleur, une icône, une police

Toujours au même endroit, jamais dans une app :

| Quoi | Où | Puis | |---|---|---| | une couleur, un rayon, une ombre | src/tokens/tokens.css | npm run build:bridge, puis apply_to_app.py <app> sur chaque app branchée | | une icône | scripts/glyphs.py | python3 scripts/build.py | | la texture | scripts/texture.py | python3 scripts/build.py | | un composant | src/react/*.tsx | npm run typecheck && npm run check && npm run build |

Les fichiers marqués « généré » en en-tête ne s'éditent pas à la main : ils seront écrasés.

Régénérer les fichiers dérivés

python3 scripts/build.py

Modifie scripts/glyphs.py pour les icônes et scripts/texture.py pour la texture ; ne touche pas aux fichiers marqués « généré ».