Navigation
Le chemin entre vos écrans : retour, remplacement, séquences paginées.
Description
Chaque vue que vous servez est un écran. La navigation, c'est la façon dont vous décidez de ce que ces écrans se font les uns aux autres : sur lequel le geste de retour atterrit, si un résultat remplace le formulaire qui l'a produit, et comment un lecteur feuillette d'une page à l'autre.
Le partage des responsabilités est délibéré :
- Le parcours vous appartient. Vous seul savez qu'un formulaire est consommé, qu'une étape est franchie, qu'un dossier est clos. Pour le client, un reçu est une vue comme une autre.
- Les conventions de la plateforme appartiennent au client. Un geste de retour mène toujours quelque part, une vue en surimpression ne devient jamais un écran, et l'entrée de votre service reste toujours atteignable.
Le protocole porte donc votre *intention*, et le client la traduit en comportement de pile. Vous ne manipulez jamais une pile : vous n'en connaissez pas l'état, et deux clients (mobile, web) n'ont pas la même.
Description des champs
Toute la navigation vit sous la clé nav de la vue servie.
nav.nextstringoptionnelnav.prevstringoptionnelnav.entrystringoptionnel"push" (défaut) ou "replace"Un jeton nu (step-two) est refusé : sur le fil, rien ne le distingue d'un chemin relatif, et aucun client ne tient d'annuaire d'identifiants de vue pour le résoudre. Écrivez /step-two — ou l'URL complète.
Méthodes
setNext(url)→ thisurl- URL ou chemin de la vue suivante
setPrev(url)→ thisurl- URL ou chemin de la vue précédente
setEntry(entry)→ thisentry-'push','replace', ou un entier <= 1
setPage(current, total?)→ thiscurrent- position, à partir de 1total- longueur de la séquence, si connue
Comment une vue entre dans la pile
entry répond à une seule question : l'utilisateur doit-il pouvoir revenir à l'écran qui l'a mené ici ?
| Valeur | Effet |
|---|---|
push (défaut) | La vue s'empile sur l'écran qui y a mené. Le retour revient à cet écran. |
replace ou 0 | La vue prend la place de cet écran. Le retour l'enjambe. |
-1, -2… | Elle prend aussi la place des écrans en dessous : -n en efface n+1. Le retour mène à ce qui restait dessous. |
Une vue rendue en réponse à une soumission de formulaire remplace ce formulaire, sans que vous ayez à le déclarer. C'est le cas de loin le plus fréquent — un reçu, une confirmation — et l'oublier produit un défaut discret : l'utilisateur retombe sur un formulaire qui a déjà fait son travail, et personne ne s'en aperçoit au développement.
L'étape suivante d'un assistant doit donc déclarer push. Une valeur déclarée l'emporte toujours sur ce défaut. L'oublier se voit immédiatement, dès le premier essai : on ne peut plus remonter d'une étape. Des deux oublis possibles, celui-ci se rattrape ; l'autre passe inaperçu.
Partout ailleurs — une vue atteinte par une action, un lien, une entrée profonde — le défaut reste push. Déclarez replace sur ce qui acquitte une action accomplie hors formulaire.
Le nombre se compte depuis l'écran courant, en écrans qui sont les vôtres — jamais en profondeur absolue. La même vue se trouve à des hauteurs différentes selon le chemin parcouru (votre catalogue, ou un lien profond), et vous ne savez pas lequel l'utilisateur a pris. Si le sommet porte l'index T, la vue qui arrive se pose à T + entry.
Le recul s'arrête toujours à la racine de votre service, quel que soit le nombre. Ce n'est pas un rattrapage : c'est ce qui rend un recul relatif sûr, puisqu'une même vue peut être servie depuis plusieurs chemins sans jamais emporter plus que ce qui existe. Depuis la racine seule, un recul empile simplement.
Une valeur supérieure à 1 est refusée : empiler est empiler, et rien de plus ne se dirait.
entry place une vue nouvelle. Pour revenir sur un écran déjà visité — sans le recharger, et en retrouvant l'état où il était — c'est back, porté par l'action d'une MessageView.
Le client ne peut pas distinguer « voici votre reçu » de « voici l'étape 2 » : il applique le défaut de la situation — remplacer après une soumission, empiler ailleurs — et s'efface dès que vous déclarez une valeur.
1// L'étape 2 d'un assistant : elle vient d'une soumission, donc elle
2// remplacerait l'étape 1. On déclare `push` pour pouvoir y remonter.
3const step2 = YeriaUI
4 .createFormView('signup-step-2', 'Vos coordonnées')
5 .addTextField('city', 'Ville', true)
6 .submitButton('Continuer')
7 .setEntry('push');Séquences paginées
next et prev sont des frères : les deux flèches d'une séquence, dessinées par le client lui-même. Vous écrivez deux chemins et obtenez la même pagination sur tous les écrans, sans code d'interface de votre côté.
Ils ne sont jamais liés au geste de retour. Le retour défait le temps ; la pagination se déplace de côté.
setPage(current, total?) dit où se situe la vue, et le client dessine l'indicateur entre les deux contrôles — Page 2 / 4. Envoyez des nombres, pas une phrase : le client les met en forme dans la langue du lecteur. Omettez total quand la séquence n'a pas de fin connue, le client n'affiche alors que la position. C'est purement informatif — le déplacement passe toujours par setNext / setPrev, et une vue qui ne déclare aucune position n'obtient simplement pas d'indicateur.
Une page atteinte par ces contrôles remplace la courante. Feuilleter quarante pages empilerait sinon quarante écrans et transformerait le geste de retour en tunnel. Une page qui déclare entry: "push" s'empile malgré tout, si vous tenez vraiment à un retour page à page.
1const page = YeriaUI
2 .createReaderView('report-p2', 'Rapport annuel — page 2')
3 .addParagraph('…')
4 .setPrev('/reports/annual/1')
5 .setNext('/reports/annual/3')
6 .setPage(2, 3);Ce que le client garantit
Ces règles ne sont pas les vôtres à changer ; comptez dessus.
- La racine ne bouge jamais. La vue servie par l'URL de base de votre service reste au fond de la pile et n'en sort pas, si bien que l'entrée de votre service demeure atteignable. Un
replacesans rien dessous s'empile. - Un geste de retour mène toujours quelque part. Depuis la racine, il quitte le service. Aucun écran ne piège l'utilisateur.
- Une surimpression n'est pas un écran. Une
MessageViewest rendue en boîte de dialogue : elle n'occupe aucune entrée de pile et sa fermeture ne navigue nulle part. - Une entrée profonde reçoit sa racine. Un lien qui ouvre directement une de vos sous-vues (
yeria://dl/v/{serviceId}?p=/orders/123, ou le même lien porté par une notification) monte votre vue de base en dessous avant d'afficher la vue demandée. Attendez-vous à une requête de plus, celle de votre racine. - Les cibles restent dans votre service.
next,prevet les cibles d'action sont résolus contre l'URL de base de votre service ; tout ce qui en sort est refusé.
Non honoré aujourd'hui
setProcess() / belongsToProcess() — processId, processName, currentStep, totalSteps, stepName, canGoBack, canSkip — voyagent sur le fil et aucun client n'en fait rien. Aucun fil d'étapes n'est affiché, et canGoBack ne change pas le geste de retour.
Ces champs sont conservés pour que le code fournisseur existant continue de fonctionner, et cette section disparaîtra une fois qu'ils seront implémentés ou retirés. Ne bâtissez pas un parcours multi-étapes sur canGoBack : servez-vous d'entry et de vos propres cibles de navigation.
Exemple de code Python
1from yeriasdk import YeriaUI
2
3receipt = (
4 YeriaUI.create_card_view('order-receipt', 'Commande confirmée')
5 .set_description('La commande 4718 a bien été enregistrée.')
6 .set_entry('replace')
7)
8
9page = (
10 YeriaUI.create_reader_view('report-p2', 'Rapport annuel - page 2')
11 .add_paragraph('...')
12 .set_prev('/reports/annual/1')
13 .set_next('/reports/annual/3')
14)