@qhuy/react
v0.1.1
Published
Composants React FXP — primitives + composites + patterns UX. Lib NPM compilée.
Readme
@qhuy/react
Composants React du design system FanXP.
Le package est compile en ESM, CJS et types TypeScript. Il est concu pour etre consomme par des apps React 18 ou 19, notamment Next.js, Vite, Remix et Astro.
Installation
pnpm add @qhuy/react @qhuy/tokensAvec npm :
npm install @qhuy/react @qhuy/tokensreact et react-dom sont des peer dependencies. L'application consommatrice doit les installer.
CSS obligatoire
Importer les CSS une seule fois, au root de l'application, dans cet ordre :
import '@qhuy/react/styles.css'
import '@qhuy/tokens/css/fxp.css'
import '@qhuy/tokens/css/fxp.dark.css'Sans ces imports, les composants fonctionnent techniquement mais ne portent pas le theme FXP.
Usage rapide
import { Button, Spinner } from '@qhuy/react'
export function Example() {
return (
<div>
<Button onClick={() => console.log('click')}>Continuer</Button>
<Button variant="secondary" iconLeft={<span aria-hidden>+</span>}>
Ajouter
</Button>
<Spinner label="Chargement en cours" />
</div>
)
}Next.js App Router
Dans app/layout.tsx :
import type { ReactNode } from 'react'
import '@qhuy/react/styles.css'
import '@qhuy/tokens/css/fxp.css'
import '@qhuy/tokens/css/fxp.dark.css'
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="fr" data-theme="light" data-tenant="acme">
<body>{children}</body>
</html>
)
}Les composants exportes sont des composants client. Dans une app Next.js, utilisez-les dans un fichier avec "use client" si vous attachez des handlers comme onClick.
Vite / React
Dans src/main.tsx ou src/App.tsx :
import '@qhuy/react/styles.css'
import '@qhuy/tokens/css/fxp.css'
import '@qhuy/tokens/css/fxp.dark.css'Puis utilisez les composants normalement :
import { Button } from '@qhuy/react'
export function App() {
return <Button>Action</Button>
}Astro
Dans un layout Astro ou dans le point d'entree React :
---
import '@qhuy/react/styles.css'
import '@qhuy/tokens/css/fxp.css'
import '@qhuy/tokens/css/fxp.dark.css'
---Les composants React interactifs doivent etre rendus avec une directive client Astro (client:load, client:visible, etc.).
Theming et tenants
Les composants ne connaissent jamais le tenant actif. Le theming passe uniquement par les variables CSS --fxp-* fournies par @qhuy/tokens et par les CSS tenant de l'application.
Exemple :
<html data-tenant="acme">
<head>
<link rel="stylesheet" href="/_fxp/tenants/acme.css" />
</head>
</html>Regles cote application :
- Ne pas modifier le markup interne des composants.
- Ne pas copier/coller le code source du package.
- Ne pas surcharger les classes internes comme
.fxp-button. - Personnaliser via les variables
--fxp-*.
API actuelle
Button
import { Button } from '@qhuy/react'Variants :
primarysecondaryoutlinedestructiveghostlink
Tailles :
xssmmdlgiconicon-xsicon-smicon-lg
Props utiles :
- Toutes les props natives de
button, dontonClick,onFocus,onBlur,disabled,aria-*. asChildpour composer avec un lien ou une primitive compatible Radix Slot.iconLeft,iconRight.loading, qui desactive le bouton et exposearia-busy.refcomme prop React 19.
Exemples :
<Button onClick={save}>Sauvegarder</Button>
<Button variant="destructive" loading>
Suppression
</Button>
<Button asChild>
<a href="/billing">Facturation</a>
</Button>Spinner
import { Spinner } from '@qhuy/react'Tailles :
smmdlg
Props utiles :
labelpour le nom accessible.- Props natives de
spansaufrole, qui restestatus. refcomme prop React 19.
<Spinner size="sm" label="Chargement" />Accessibilite
Buttonconserve les comportements natifs clavier : Tab, Enter, Space.disabledetloadingdesactivent l'action.loadingexposearia-busy="true".Spinnerexposerole="status"et un label accessible.- Les textes visibles sont fournis par l'application consommatrice.
Troubleshooting
Les boutons n'ont pas le bon style
Verifiez que les trois CSS sont importes au root, dans cet ordre :
import '@qhuy/react/styles.css'
import '@qhuy/tokens/css/fxp.css'
import '@qhuy/tokens/css/fxp.dark.css'Le theme tenant ne s'applique pas
Verifiez que :
<html data-tenant="...">correspond au selector du CSS tenant.- Le CSS tenant est charge apres les CSS de base.
- Le CSS tenant redefinit bien des variables
--fxp-*.
Next.js indique un probleme serveur/client
Les composants interactifs doivent etre utilises dans un composant client si vous passez des handlers :
'use client'
import { Button } from '@qhuy/react'Versioning
Le package suit SemVer :
- patch : correction compatible
- minor : ajout compatible
- major : changement breaking
Ne pas utiliser de deep imports. Toute API publique passe par :
import { Button, Spinner } from '@qhuy/react'