CardView
Fiche compacte d'un élément unique, avec stats et actions.
Description
Le composant CardView est une vue « fiche produit » compacte qui met en avant un élément unique avec ses statistiques, ses sections et ses actions. Elle convient à la présentation d'un produit, d'un profil utilisateur, du détail d'un événement, ou de toute entité unique demandant un affichage détaillé.
La carte comprend :
- Titre et intro
- Description
- Badge (facultatif)
- Image principale (facultative)
- Statistiques (paires clé-valeur)
- Sections (titre + texte)
- Éléments de mise en page parmi les sections — paragraphe, espaceur, séparateur, les trois mêmes que le formulaire
- Boutons d'action
- Métadonnées personnalisées
Le client dessine la carte comme une surface unique en quatre zones — en-tête, statistiques, sections, actions — séparées par un filet pleine largeur ; une zone vide n'est pas dessinée. Les statistiques sont une liste libellé / valeur, jamais cliquable. Actions : la primary en bouton plein, les deux premières secondary en boutons contour, toute autre action (secondary au-delà, puis link) en ligne de liste avec chevron, dans l'ordre donné.
Description des champs
idstringrequistypestringrequis"Card"contentCardContentrequiscontent.titlestringrequiscontent.introstringoptionnelintro de toutes les autres vues. S'appelait subtitle.content.descriptionstringoptionnelcontent.badgestringoptionnelcontent.imageCardImageoptionnelcontent.image.urlstringrequis*content.image.altstringoptionnelcontent.statsHeadingstringoptionnelcontent.statsCardStat[]optionnelcontent.stats[].labelstringrequiscontent.stats[].valuestringrequiscontent.sectionsCardBlock[]optionneltype ; une section jamaiscontent.sections[].headingstringrequis*content.sections[].bodystringrequis*content.sections[].typestringoptionnel"paragraph", "spacer" ou "separator" — un élément de mise en page, dessiné exactement comme dans un formulairecontent.sections[].textstringrequis*paragraph seulement)content.sections[].sizestringoptionnelparagraph : "xl", "lg", "md" (défaut), "sm". spacer : "sm", "md" (défaut), "lg"content.sections[].boldbooleanoptionnelcontent.sections[].italicbooleanoptionnelcontent.sections[].labelstringoptionnelseparator seulement)content.actionsCardAction[]optionnelcontent.actions[].textstringrequiscontent.actions[].methodHttpMethodoptionnelcontent.actions[].confirmMessagestringoptionnelcontent.actions[].hrefstringoptionnelcontent.actions[].iconstringoptionnelcontent.actions[].variantstringoptionnel"primary", "secondary", "link"content.metaRecord<string, unknown>optionnelprocessIdstringoptionnelmetadataobjectoptionnelNote : une vue carte doit comporter au moins une description, une statistique ou une section pour être valide.
Méthodes
setIntro(intro)→ thisintro- Texte d'introduction
setSubtitle(subtitle)→ thissetIntro, conservé. Écrit la même clésubtitle- Texte d'introduction
setDescription(description)→ thisdescription- Texte de la description
setBadge(badge)→ thisbadge- Texte du badge, ou undefined
setImage(url, alt?)→ thisurl- URL de l'imagealt- Texte alternatif
clearImage()→ thissetStatsHeading(heading)→ thisheading- Texte de l'intitulé
addStat(label, value)→ thislabel- Libellé de la statistiquevalue- Valeur de la statistique
clearStats()→ thisaddSection(heading, body)→ thisheading- Titre de la sectionbody- Texte de la section ; « • » sépare les puces
addParagraph(text, options?)→ thisaddParagraph du formulaire, dessiné de la même façon. Refuse un texte vide ou une taille inconnuetext- Texte à afficheroptions-size('xl','lg','md','sm'),bold,italic
addSpacer(size?)→ thissize-'sm','md'(défaut) ou'lg'
addSeparator(label?)→ thislabel- Libellé facultatif
clearSections()→ thisaddAction(text, method?, options?)→ thistext- Texte du boutonmethod- Méthode HTTP (par défaut : POST)options- Options de l'action (confirmMessage, href, icon, variant)
clearActions()→ thissetMetadata(meta)→ thismeta- Objet de métadonnées
getContent()→ CardContentserve()→ Record<string, unknown>toJSON()→ Record<string, unknown>setState(key, value)→ voidkey- Clé d'étatvalue- Valeur d'état
getState(key)→ unknownkey- Clé d'état
setNext(url)→ thisurl- URL ou chemin de la vue suivante
setPrev(url)→ thisurl- URL ou chemin de la vue précédente
setEntry(entry)→ thispush) — voir Navigationentry-'push','replace', ou un entier <= 1
setPage(current, total?)→ thiscurrent- position, à partir de 1total- longueur de la séquence, si connue
setProcess(processId, context?)→ thisprocessId- Identifiant du processuscontext- Contexte du processus
Exemples de code JavaScript
Carte simple
1import { YeriaApp } from '@numerum-tech/yeriasdk';
2
3const yeriaApp = new YeriaApp({ appId: 'my-app' });
4
5const card = yeriaApp
6 .createCardView('product-card', 'Super Gadget')
7 .setIntro('Boost your day')
8 .setDescription('A compact companion to organize your tasks and automate your daily routines.')
9 .addStat('Price', '49 €')
10 .addSection('Key Points', 'Voice assistant, 48h battery life, multi-device sync.')
11 .addAction('Buy Now', 'POST', { confirmMessage: 'Confirm your purchase?' });
12
13const response = yeriaApp.serve(card);Carte avec image
1const card = yeriaApp
2 .createCardView('product', 'Product Name')
3 .setIntro('Product Category')
4 .setDescription('Product description goes here.')
5 .setImage('https://example.com/product.jpg', 'Product Image')
6 .addStat('Price', '$99')
7 .addStat('Rating', '4.5/5')
8 .addAction('View Details', 'GET', { href: '/products/123' });Carte avec badge
1const card = yeriaApp
2 .createCardView('featured-product', 'Featured Product')
3 .setBadge('New')
4 .setIntro('Limited Edition')
5 .setDescription('Exclusive product available for a limited time.')
6 .setImage('https://example.com/product.jpg', 'Product')
7 .addStat('Price', '$199')
8 .addStat('Stock', 'Only 5 left')
9 .addAction('Purchase', 'POST');Carte avec plusieurs statistiques
1const card = yeriaApp
2 .createCardView('user-profile', 'John Doe')
3 .setIntro('Premium Member')
4 .setDescription('Active user since 2020')
5 .addStat('Posts', '125')
6 .addStat('Followers', '1.2K')
7 .addStat('Following', '450')
8 .addStat('Rating', '4.8/5')
9 .addAction('View Profile', 'GET', { href: '/users/john-doe' });Carte avec plusieurs sections
1const card = yeriaApp
2 .createCardView('event', 'Tech Conference 2025')
3 .setIntro('March 15-17, 2025')
4 .setDescription('Join us for the biggest tech conference of the year.')
5 .addStat('Date', 'March 15-17')
6 .addStat('Location', 'San Francisco')
7 .addStat('Price', '$299')
8 .addSection('About', 'Three days of talks, workshops, and networking.')
9 .addSection('Speakers', 'Industry leaders from Google, Apple, and Microsoft.')
10 .addSection('Schedule', 'Day 1: Keynotes, Day 2: Workshops, Day 3: Networking')
11 .addAction('Register', 'POST')
12 .addAction('View Schedule', 'GET', { href: '/events/schedule' });Carte avec éléments de mise en page
Les trois éléments de mise en page du formulaire prennent place parmi les sections, dans l'ordre des appels. Une carte dont le seul corps est un paragraphe est valide ; un espaceur ou un séparateur seul n'est pas un contenu.
1const card = yeriaApp
2 .createCardView('laptop', 'MacBook Pro 16"')
3 .addSection('Fonctionnalités', 'Processeur avancé • Écran haute résolution • Longue autonomie')
4 .addSeparator('Détails techniques')
5 .addSection('Spécifications', 'Puce M3 Pro • 18 Go RAM • 512 Go SSD')
6 .addParagraph('Les caractéristiques peuvent varier selon la configuration choisie.', { size: 'sm', italic: true })
7 .addSpacer('lg')
8 .addSection('Garantie', 'Garantie limitée 1 an • 90 jours de support gratuit')
9 .addAction('Acheter maintenant', 'POST', { variant: 'primary' });Carte avec plusieurs actions
1const card = yeriaApp
2 .createCardView('item', 'Item Name')
3 .setDescription('Item description')
4 .addStat('Price', '$49')
5 .addAction('Buy Now', 'POST', {
6 confirmMessage: 'Confirm purchase?',
7 variant: 'primary'
8 })
9 .addAction('Add to Cart', 'POST', { variant: 'secondary' })
10 .addAction('View Details', 'GET', {
11 href: '/items/123',
12 variant: 'link'
13 });Carte avec variantes d'action
1const card = yeriaApp
2 .createCardView('article', 'Article Title')
3 .setDescription('Article description')
4 .addStat('Views', '1.2K')
5 .addStat('Likes', '89')
6 .addAction('Read More', 'GET', {
7 href: '/articles/123',
8 variant: 'primary'
9 })
10 .addAction('Share', 'POST', { variant: 'secondary' })
11 .addAction('Bookmark', 'POST', { variant: 'link' });Carte avec métadonnées
1const card = yeriaApp
2 .createCardView('custom-card', 'Custom Card')
3 .setDescription('Card with custom metadata')
4 .addStat('Value', '100')
5 .setMetadata({
6 category: 'premium',
7 tags: ['featured', 'popular'],
8 createdAt: new Date().toISOString()
9 })
10 .addAction('View', 'GET');Réinitialisation des éléments d'une carte
1const card = yeriaApp
2 .createCardView('dynamic-card', 'Dynamic Card')
3 .setDescription('Card with dynamic content')
4 .addStat('Stat 1', 'Value 1')
5 .addStat('Stat 2', 'Value 2')
6 .addSection('Section 1', 'Body 1')
7 .addAction('Action 1', 'POST');
8
9// Clear stats
10card.clearStats();
11
12// Clear sections
13card.clearSections();
14
15// Clear actions
16card.clearActions();
17
18// Clear image
19card.clearImage();Carte dans un parcours en plusieurs étapes
1const card = yeriaApp
2 .createCardView('step-summary', 'Step Summary')
3 .setProcess('onboarding', {
4 processName: 'User Onboarding',
5 currentStep: 2,
6 totalSteps: 3
7 })
8 .setDescription('Review your information before proceeding')
9 .addStat('Completed', 'Step 1')
10 .addStat('Current', 'Step 2')
11 .addStat('Remaining', 'Step 3')
12 .addAction('Continue', 'POST');Exemple de carte complexe
1const card = yeriaApp
2 .createCardView('product-detail', 'Premium Headphones')
3 .setBadge('Best Seller')
4 .setIntro('Wireless Audio')
5 .setDescription('High-quality wireless headphones with noise cancellation and 30-hour battery life.')
6 .setImage('https://example.com/headphones.jpg', 'Premium Headphones')
7 .addStat('Price', '$299')
8 .addStat('Rating', '4.8/5')
9 .addStat('Reviews', '1,234')
10 .addStat('In Stock', 'Yes')
11 .addSection('Features', 'Noise cancellation, 30h battery, wireless charging, premium materials.')
12 .addSection('Specifications', 'Driver: 40mm, Frequency: 20Hz-20kHz, Weight: 250g.')
13 .addSection('Warranty', '2-year manufacturer warranty included.')
14 .addAction('Add to Cart', 'POST', {
15 confirmMessage: 'Add to cart?',
16 variant: 'primary'
17 })
18 .addAction('Buy Now', 'POST', { variant: 'primary' })
19 .addAction('Compare', 'GET', { href: '/compare', variant: 'secondary' })
20 .addAction('Share', 'POST', { variant: 'link' });Exemple JSON complet
1{
2 "id": "product-detail",
3 "type": "Card",
4 "content": {
5 "title": "Premium Headphones",
6 "badge": "Best Seller",
7 "intro": "Wireless Audio",
8 "description": "High-quality wireless headphones with noise cancellation and 30-hour battery life.",
9 "image": {
10 "url": "https://example.com/headphones.jpg",
11 "alt": "Premium Headphones"
12 },
13 "stats": [
14 {
15 "label": "Price",
16 "value": "$299"
17 },
18 {
19 "label": "Rating",
20 "value": "4.8/5"
21 },
22 {
23 "label": "Reviews",
24 "value": "1,234"
25 },
26 {
27 "label": "In Stock",
28 "value": "Yes"
29 }
30 ],
31 "sections": [
32 {
33 "title": "Features",
34 "content": "Noise cancellation, 30h battery, wireless charging, premium materials."
35 },
36 {
37 "title": "Specifications",
38 "content": "Driver: 40mm, Frequency: 20Hz-20kHz, Weight: 250g."
39 },
40 {
41 "title": "Warranty",
42 "content": "2-year manufacturer warranty included."
43 }
44 ],
45 "actions": [
46 {
47 "code": "add-to-cart",
48 "title": "Add to Cart",
49 "method": "POST",
50 "confirmMessage": "Add to cart?",
51 "variant": "primary"
52 },
53 {
54 "code": "buy-now",
55 "title": "Buy Now",
56 "method": "POST",
57 "variant": "primary"
58 },
59 {
60 "code": "compare",
61 "title": "Compare",
62 "method": "GET",
63 "href": "/compare",
64 "variant": "secondary"
65 },
66 {
67 "code": "share",
68 "title": "Share",
69 "method": "POST",
70 "variant": "link"
71 }
72 ]
73 },
74 "metadata": {
75 "version": "1.0.0",
76 "createdAt": "2025-01-28T10:00:00.000Z"
77 }
78}