Chapitre 4 : Affichage
Composants de formatage
SmartCommon fournit des composants pour afficher les données de manière formatée et cohérente.
String
Affichage de texte court.
import { String } from '@cap-rel/smartcommon';
<String value="Jean Dupont" />
<String value={user.name} fallback="Non renseigné" />
// Avec troncature
<String value={longText} maxLength={50} />
Text
Affichage de texte long avec préservation des sauts de ligne.
import { Text } from '@cap-rel/smartcommon';
<Text value={product.description} />
// Avec limite de lignes
<Text value={description} maxLines={3} />
Number
Affichage de nombre formaté selon la locale.
import { Number } from '@cap-rel/smartcommon';
// Nombre simple
<Number value={1234.56} />
// Affiche : 1 234,56
// Avec décimales fixées
<Number value={99.9} decimals={2} />
// Affiche : 99,90
// Prix
<Number value={29.99} suffix=" €" />
// Affiche : 29,99 €
// Pourcentage
<Number value={0.156} format="percent" />
// Affiche : 15,6 %
Datetime
Affichage de date et heure formatées.
import { Datetime } from '@cap-rel/smartcommon';
// Date complète
<Datetime value="2024-03-15T14:30:00" />
// Affiche : 15 mars 2024 à 14:30
// Date seule
<Datetime value="2024-03-15" format="date" />
// Affiche : 15 mars 2024
// Heure seule
<Datetime value="2024-03-15T14:30:00" format="time" />
// Affiche : 14:30
// Format court
<Datetime value="2024-03-15" format="short" />
// Affiche : 15/03/2024
// Format relatif
<Datetime value="2024-03-15T14:30:00" format="relative" />
// Affiche : il y a 2 jours
Duration
Affichage de durée.
import { Duration } from '@cap-rel/smartcommon';
// Durée en secondes
<Duration value={3661} />
// Affiche : 1h 1min 1s
// Durée en minutes
<Duration value={90} unit="minutes" />
// Affiche : 1h 30min
// Format compact
<Duration value={3600} format="compact" />
// Affiche : 1:00:00
Affichage d'email avec lien cliquable.
import { Email } from '@cap-rel/smartcommon';
<Email value="contact@example.com" />
// Crée un lien mailto:
<Email value={user.email} showIcon />
Url
Affichage d'URL avec lien cliquable.
import { Url } from '@cap-rel/smartcommon';
<Url value="https://example.com" />
<Url value={product.website} label="Voir le site" />
<Url value={link} openInNewTab />
PhoneNumber
Affichage de numéro de téléphone cliquable.
import { PhoneNumber } from '@cap-rel/smartcommon';
<PhoneNumber value="+33612345678" />
// Affiche : +33 6 12 34 56 78 (formaté)
// Crée un lien tel:
<PhoneNumber value={contact.phone} showIcon />
Address
Affichage d'adresse formatée.
import { Address } from '@cap-rel/smartcommon';
<Address
value={{
street: '15 rue de la Paix',
city: 'Paris',
zip: '75002',
country: 'France'
}}
/>
// Avec lien vers Google Maps
<Address value={customer.address} showMap />
Coordinates
Affichage de coordonnées GPS.
import { Coordinates } from '@cap-rel/smartcommon';
<Coordinates value={{ lat: 48.8566, lng: 2.3522 }} />
// Avec lien vers carte
<Coordinates value={location} showMap />
Color
Affichage d'une couleur.
import { Color } from '@cap-rel/smartcommon';
<Color value="#FF5733" />
// Affiche un carré de couleur + le code
<Color value={product.color} showCode={false} />
// Affiche uniquement le carré
Icon
Affichage d'icône.
import { Icon } from '@cap-rel/smartcommon';
<Icon name="home" />
<Icon name="check" size={24} color="green" />
// Avec react-icons
import { FiCheck, FiX } from 'react-icons/fi';
<Icon component={FiCheck} color="green" />
<Icon component={FiX} color="red" />
Tags
Affichage d'étiquettes.
import { Tags } from '@cap-rel/smartcommon';
<Tags value={['React', 'JavaScript', 'TypeScript']} />
<Tags
value={product.categories}
color="blue"
/>
Tag
Étiquette unique.
import { Tag } from '@cap-rel/smartcommon';
<Tag>Nouveau</Tag>
<Tag color="green">Actif</Tag>
<Tag color="red">Urgent</Tag>
// Avec icône
<Tag icon={FiCheck} color="green">Validé</Tag>
Files
Affichage de fichiers avec téléchargement.
import { Files } from '@cap-rel/smartcommon';
<Files
value={[
{ name: 'document.pdf', url: '/files/doc.pdf', size: 1024000 },
{ name: 'image.jpg', url: '/files/img.jpg', size: 512000 }
]}
/>
Signature
Affichage d'une signature.
import { Signature } from '@cap-rel/smartcommon';
<Signature value={contract.signature} />
List et ListItem
Affichage de listes.
import { List, ListItem } from '@cap-rel/smartcommon';
import { useNavigation } from '@cap-rel/smartcommon';
function ProductsList({ products }) {
const nav = useNavigation();
return (
<List>
{products.map(product => (
<ListItem
key={product.id}
title={product.label}
subtitle={`${product.price} €`}
image={product.thumbnail}
onClick={() => nav.navigate(`/products/${product.id}`)}
chevron
/>
))}
</List>
);
}
Props ListItem
| Prop | Type | Description |
|---|---|---|
| title | string | Titre principal |
| subtitle | string | Sous-titre |
| image | string | URL de l'image |
| icon | Component | Icône à gauche |
| onClick | function | Action au clic |
| chevron | boolean | Afficher flèche droite |
| actions | ReactNode | Actions à droite |
Button
Bouton d'action.
import { Button } from '@cap-rel/smartcommon';
// Variantes
<Button>Défaut</Button>
<Button variant="primary">Primaire</Button>
<Button variant="secondary">Secondaire</Button>
<Button variant="outline">Contour</Button>
<Button variant="danger">Danger</Button>
<Button variant="ghost">Ghost</Button>
// Tailles
<Button size="sm">Petit</Button>
<Button size="md">Normal</Button>
<Button size="lg">Grand</Button>
// États
<Button loading>Chargement</Button>
<Button disabled>Désactivé</Button>
// Avec icône
<Button icon={FiPlus}>Ajouter</Button>
Spinner
Indicateur de chargement.
import { Spinner } from '@cap-rel/smartcommon';
<Spinner />
<Spinner size="sm" />
<Spinner size="lg" />
// Page de chargement
function LoadingPage() {
return (
<div className="flex items-center justify-center h-screen">
<Spinner size="lg" />
</div>
);
}
Exemple complet : Fiche produit
import {
Page,
Block,
String,
Text,
Number,
Datetime,
Tags,
Tag,
Files,
Button,
Carousel,
CarouselItem
} from '@cap-rel/smartcommon';
import { useNavigation } from '@cap-rel/smartcommon';
export const ProductDetailPage = ({ product }) => {
const nav = useNavigation();
return (
<Page title={product.label}>
{/* Photos */}
{product.photos?.length > 0 && (
<Carousel>
{product.photos.map((photo, index) => (
<CarouselItem key={index}>
<img src={photo.url} alt={`Photo ${index + 1}`} />
</CarouselItem>
))}
</Carousel>
)}
{/* Informations principales */}
<Block>
<div className="flex justify-between items-start">
<div>
<h1 className="text-2xl font-bold">
<String value={product.label} />
</h1>
<Tags value={product.categories} />
</div>
<Tag color={product.isActive ? 'green' : 'gray'}>
{product.isActive ? 'Actif' : 'Inactif'}
</Tag>
</div>
<div className="mt-4 text-3xl font-bold text-primary">
<Number value={product.price} suffix=" €" />
</div>
</Block>
{/* Description */}
<Block title="Description">
<Text value={product.description} />
</Block>
{/* Détails */}
<Block title="Détails">
<dl className="space-y-2">
<div className="flex justify-between">
<dt className="text-gray-500">Référence</dt>
<dd><String value={product.ref} /></dd>
</div>
<div className="flex justify-between">
<dt className="text-gray-500">Stock</dt>
<dd><Number value={product.stock} /></dd>
</div>
<div className="flex justify-between">
<dt className="text-gray-500">Créé le</dt>
<dd><Datetime value={product.createdAt} format="date" /></dd>
</div>
<div className="flex justify-between">
<dt className="text-gray-500">Modifié le</dt>
<dd><Datetime value={product.updatedAt} format="relative" /></dd>
</div>
</dl>
</Block>
{/* Documents */}
{product.documents?.length > 0 && (
<Block title="Documents">
<Files value={product.documents} />
</Block>
)}
{/* Actions */}
<Block>
<div className="flex gap-2">
<Button
variant="outline"
onClick={() => nav.navigate(`/products/${product.id}/edit`)}
>
Modifier
</Button>
<Button variant="primary">
Commander
</Button>
</div>
</Block>
</Page>
);
};
Points clés à retenir
- Composants de format pour affichage cohérent
- Number avec locale française automatique
- Datetime avec formats relatifs pratiques
- List/ListItem pour les listes navigables
- Button avec variantes et états
← Chapitre précédent | Retour au module | Module suivant : SmartCommon Hooks ->