Aller au contenu principal

Prévisualiser une story sur mobile et desktop

DevicePreview permet de rendre une même story dans un appareil mobile ou une fenêtre desktop simulée. Il est utile pour vérifier un écran responsive sans créer une story distincte pour chaque format.

import io.cstories.runtime.DevicePreview

@CStory(collection = "Screens", group = "Profile", name = "Responsive")
@Composable
fun ResponsiveProfileStory() {
DevicePreview {
ProfileScreen()
}
}

Preview mobile with switch

Changer le format de prévisualisation​

Lorsqu'une story contenant DevicePreview est affichée dans le catalogue CStories, celui-ci ajoute automatiquement un switch Mobile/Desktop dans la barre d'outils de la story, à côté des contrôles de l'aperçu. Le switch n'est affiché que pour les stories qui utilisent DevicePreview.

Le format sélectionné change le viewport sans modifier le contenu de la story :

  • Mobile rend le contenu dans MobileDevicePreview.
  • Desktop rend le contenu dans DesktopDevicePreview, avec une barre de titre de fenêtre simulée.

En dehors du catalogue CStories, DevicePreview affiche le même switch au-dessus de l'aperçu afin de rester utilisable dans un écran Compose autonome.

Configurer le format initial​

Le format par défaut est mobile. Utilisez initialDevice pour ouvrir la story en mode desktop :

import io.cstories.runtime.DevicePreview
import io.cstories.runtime.PreviewDevice

DevicePreview(
initialDevice = PreviewDevice.Desktop,
) {
DashboardScreen()
}

PreviewDevice possède deux valeurs :

  • PreviewDevice.Mobile
  • PreviewDevice.Desktop

Configurer les viewports simulés​

Les viewports mobile et desktop peuvent être configurés indépendamment :

import androidx.compose.ui.unit.dp
import io.cstories.runtime.DesktopDevice
import io.cstories.runtime.DevicePreview
import io.cstories.runtime.MobileDevice

DevicePreview(
mobileDevice = MobileDevice(
width = 390.dp,
height = 844.dp,
),
desktopDevice = DesktopDevice(
width = 1280.dp,
height = 800.dp,
title = "Dashboard",
),
) {
DashboardScreen()
}

Les dimensions par défaut sont 390.dp x 844.dp pour le mobile et 1280.dp x 800.dp pour le desktop.

Hauteur fixe ou contenu défilant​

Par défaut, le contenu reçoit la hauteur finie de l'écran simulé, comme sur un vrai appareil. Les layouts qui occupent toute la hauteur, comme Scaffold, fillMaxSize, LazyColumn ou Modifier.weight, s'affichent correctement.

Passez scrollable = true lorsque le contenu est une simple colonne plus haute que l'écran et doit défiler verticalement :

DevicePreview(scrollable = true) {
LongFormScreen()
}

Avec scrollable = true, le contenu est mesuré avec une hauteur non bornée : il ne doit pas chercher à remplir la hauteur disponible (Scaffold, fillMaxSize, LazyColumn…), sinon Compose lève Size(… x 2147483647) is out of range.

MobileDevicePreview et DesktopDevicePreview acceptent le même paramètre scrollable.

Utiliser le catalogue mobile intégré​

Le runtime fournit un catalogue JSON versionné contenant des appareils mobiles courants. DevicePreview l'utilise automatiquement lorsque le format mobile est actif ; aucune configuration n'est donc nécessaire dans une story.

Le catalogue intégré contient actuellement :

  • iPhone SE (2e génération), iPhone 13 à iPhone 18 et iPhone DUO ;
  • Pixel 7 à Pixel 10 ;
  • les variantes a, Pro, XL, Pro Fold et Fold des Pixel présentes dans le catalogue.

Le catalogue fait partie du runtime CStories et peut évoluer avec les nouvelles versions de CStories.

Ajouter des appareils en Kotlin​

Un projet peut compléter le catalogue intégré avec une liste Kotlin. Aucun fichier JSON n'est nécessaire dans le projet consommateur :

import androidx.compose.ui.unit.dp
import io.cstories.runtime.DevicePreview
import io.cstories.runtime.MobileDevice

DevicePreview(
additionalMobileDevices = listOf(
MobileDevice(
id = "company-phone",
name = "Company Phone",
width = 393.dp,
height = 852.dp,
cornerRadius = 34.dp,
),
),
) {
DashboardScreen()
}

Les appareils additionnels sont ajoutés au catalogue intégré. Si un appareil additionnel utilise un id déjà présent, il remplace l'entrée intégrée correspondante.

Utiliser directement la preview mobile​

Utilisez MobileDevicePreview lorsqu'une story doit toujours être rendue comme un écran mobile et n'a pas besoin d'un switch de format :

import io.cstories.runtime.MobileDevicePreview

MobileDevicePreview {
ProfileScreen()
}

MobileDevicePreview rend un viewport en forme de téléphone avec des coins arrondis, un cadre et une encoche de caméra supérieure. Sa taille par défaut est 390.dp x 844.dp. Configurez l'appareil lorsqu'un autre format mobile est utile :

import androidx.compose.ui.unit.dp
import io.cstories.runtime.MobileDevice
import io.cstories.runtime.MobileDevicePreview

MobileDevicePreview(
device = MobileDevice(
width = 375.dp,
height = 812.dp,
cornerRadius = 32.dp,
),
) {
ProfileScreen()
}

Le contenu reçoit la hauteur de l'écran simulé. Passez scrollable = true pour le faire défiler verticalement (voir Hauteur fixe ou contenu défilant).

Le contenu est entouré d'une marge intérieure par défaut. Passez contentPadding = PaddingValues(0.dp) pour un contenu plein écran comme un Scaffold :

MobileDevicePreview(contentPadding = PaddingValues(0.dp)) {
Scaffold(topBar = { ProfileTopBar() }) { innerPadding ->
ProfileContent(Modifier.padding(innerPadding))
}
}

Lorsque MobileDevicePreview est utilisé directement dans une story du catalogue, la barre d'outils affiche automatiquement le sélecteur de modèle mobile. Celui-ci affiche le modèle sélectionné et ouvre le catalogue intégré, sans afficher le switch Mobile/Desktop, puisque la story est déjà limitée au format mobile.

@CStory(collection = "Screens", group = "Profile", name = "Mobile")
@Composable
fun MobileProfileStory() {
MobileDevicePreview {
ProfileScreen()
}
}

Pour ajouter des appareils propres au projet dans ce sélecteur, fournissez-les avec additionalMobileDevices :

MobileDevicePreview(
additionalMobileDevices = listOf(
MobileDevice(
id = "company-phone",
name = "Company Phone",
width = 393.dp,
height = 852.dp,
),
),
) {
ProfileScreen()
}

Preview mobile

Utiliser directement la preview desktop​

Utilisez DesktopDevicePreview lorsqu'une story doit toujours être rendue comme une fenêtre desktop et n'a pas besoin d'un switch de format :

import io.cstories.runtime.DesktopDevicePreview

DesktopDevicePreview {
DashboardScreen()
}

DesktopDevicePreview rend une fenêtre desktop avec une barre de titre, des contrôles de fenêtre décoratifs et un viewport de contenu de taille fixe. Sa taille par défaut est 1280.dp x 800.dp. Configurez la taille et le titre de la fenêtre si nécessaire :

import androidx.compose.ui.unit.dp
import io.cstories.runtime.DesktopDevice
import io.cstories.runtime.DesktopDevicePreview

DesktopDevicePreview(
device = DesktopDevice(
width = 1440.dp,
height = 900.dp,
title = "Analytics",
),
) {
DashboardScreen()
}

Les contrôles de la fenêtre sont uniquement décoratifs. Ils ne redimensionnent pas et ne ferment pas la fenêtre native de l'application CStories.

Preview desktop

Réagir aux changements de format​

Utilisez onDeviceChanged lorsque la story doit observer le format actif :

var activeDevice by remember { mutableStateOf(PreviewDevice.Mobile) }

DevicePreview(
onDeviceChanged = { activeDevice = it },
) {
DashboardScreen()
}

Text("Prévisualisation : ${activeDevice.name}")

Le callback est appelé une première fois avec initialDevice, puis à chaque sélection d'un format différent. Il n'est pas appelé lorsque l'utilisateur sélectionne le format déjà actif.

Utiliser une seule preview par story​

Une story devrait normalement contenir un seul DevicePreview. La barre d'outils du catalogue expose un switch Mobile/Desktop par story ; plusieurs instances rendraient ce contrôle ambigu.