kvyatkovskys/swiftui-component-preview

Permet d'afficher, prévisualiser, rendre ou capturer une vue ou un composant SwiftUI sans ouvrir Xcode Canvas : vérifier la disposition, l'apparence claire/sombre, la locale, les états de maquette ou l'interaction locale d'un composant SwiftUI compatible macOS. Produit des rendus PNG, une galerie de thèmes HTML hors ligne ou une fenêtre macOS native interactive à partir d'une maquette adaptée du composant réel du projet.

Qu'est-ce que swiftui-component-preview ?

Cette compétence permet aux développeurs de prévisualiser des composants SwiftUI directement depuis leur éditeur ou agent, sans avoir à ouvrir Xcode Canvas. Elle répond à un besoin courant : vérifier rapidement l'apparence d'un composant dans différents contextes (clair/sombre, locale, états) ou interagir avec lui de manière native. Compatible avec Claude Code, Codex et d'autres agents, elle prend en charge les projets SwiftPM et Xcode, et est conçue pour macOS 14+. Son fonctionnement repose sur la création d'une maquette autonome (fixture) à partir du code source réel du composant, en remplaçant les dépendances de service par des valeurs synthétiques. Elle offre trois modes de sortie : le rendu PNG pour une inspection statique, une galerie HTML pour comparer les variantes, et une fenêtre native pour tester les interactions. La compétence gère automatiquement la découverte du projet, l'adaptation du code source et la configuration, sans nécessiter de modifications du projet ni de canvas Xcode. Pour les composants UIKit ou dépendants de l'iPhone, elle signale l'incompatibilité et propose des alternatives.

Compatible avec✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/kvyatkovskys/KVKAgentSkills/tree/HEAD/skills/swiftui-component-preview

Installed? Explore more Développement et programmation skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Aperçu de Composant SwiftUI

Créez un rendu de composant à partir d'une maquette SwiftUI petite et déterministe. Nécessite macOS 14 ou ultérieur et Xcode 15 ou ultérieur (Swift 5.9+) ; Swift 6 n'est pas requis. L'intégration au projet, la galerie HTML et le constructeur en direct nécessitent également Python 3.8 ou ultérieur (bibliothèque standard uniquement). Choisissez les PNG pour une inspection statique, la galerie pour les comparaisons d'images, ou une fenêtre native pour des interactions réelles avec la maquette. Ces assistants ne fournissent pas le Canvas Xcode ni le rechargement à chaud.

Choisir la sortie

Décidez de la sortie avant de construire quoi que ce soit, dans cet ordre :

  1. Mot explicite. Si la requête ou les arguments de la compétence commencent par ou nomment png, gallery, ou live (ainsi que "screenshot", "render" pour PNG ; "window", "interactive" pour live), utilisez-le.

  2. Intention de la requête.

    L'utilisateur veutSortie
    voir à quoi ça ressemble, vérifier la disposition, l'espacement, le texte, un état, une localePNG
    comparer clair et sombre, ou avec et sans cadre, côte à côte ou par basculementGalerie
    cliquer, taper, basculer, naviguer, ouvrir une feuille ou une alerte, vérifier un fluxFenêtre live

    Lorsqu'une requête correspond à plusieurs lignes, l'interaction l'emporte : tout ce qui n'apparaît qu'après un clic ou une saisie nécessite la fenêtre live.

  3. Écran complet ou flux, sans indication. Si la cible est un écran entier ou un flux en plusieurs étapes et qu'aucune des règles ci-dessus ne s'applique, comme dans "prévisualiser l'écran de paiement", posez une question offrant le choix entre PNG, galerie et fenêtre live.

  4. Par défaut. Pour un composant unique sans indication, produisez un PNG clair, dimensionné avec fit. C'est la sortie la plus rapide et la seule que vous puissiez inspecter vous-même. Ajoutez ensuite une ligne proposant les deux autres sorties.

Les règles 1, 2 et 4 sont exécutées sans poser de question. Lorsque plusieurs sorties sont demandées, produisez-les toutes à partir de la même configuration. Ne stockez pas le choix dans .swiftui-preview/config.json : il appartient à la requête, pas au projet.

Première utilisation dans un projet

<skill-directory> dans les commandes ci-dessous est le répertoire contenant ce SKILL.md ; résolvez-le à partir de l'emplacement installé. Claude Code le mentionne comme le répertoire de base de la compétence lorsqu'elle se charge (${CLAUDE_SKILL_DIR}) ; dans Codex et autres agents, utilisez le chemin à partir duquel ce fichier a été lu. Aucun chemin ou paramètre spécifique au développeur n'est nécessaire. Utilisez la racine actuelle du projet de l'utilisateur et exécutez une découverte en lecture seule :

python3 "<skill-directory>/scripts/bootstrap.py" discover --root "<project-root>"

La découverte signale les manifests SwiftPM, les projets/espaces de travail Xcode, les sources SwiftUI, la présence de #Preview et les preuves textuelles de plateforme. Elle n'évalue jamais les manifests, n'exécute pas de plugins, ne construit pas et ne modifie pas le projet. Les répertoires de dépendances/de construction imbriqués et les liens symboliques sont ignorés. L'absence de métadonnées de plateforme signifie inconnu, pas non pris en charge. Utilisez la requête et les chemins découverts pour choisir le projet et le composant visés. Ne posez une question que pour une sélection qui reste véritablement ambiguë ; plusieurs marqueurs seuls ne nécessitent pas de poser une question lorsque la source demandée est claire.

Lisez le code source réel choisi, sa construction #Preview existante et les définitions locales nécessaires avant de créer une maquette. L'agent de la compétence effectue cette adaptation dans le cadre de la première demande de prévisualisation ; ne vous arrêtez pas à des instructions demandant à l'utilisateur de l'adapter manuellement lorsque vous pouvez le faire en toute sécurité. Conservez la hiérarchie de vues réelle du composant, ses contrôles, ses styles et ses entrées. Extrayez sa vue de valeur et incluez les définitions locales nécessaires, en remplaçant les dépendances de service par des valeurs synthétiques et des actions locales. Ne substituez pas un écran ressemblant, une démo générique ou l'exemple fourni au composant demandé. Les exemples illustrent uniquement l'API de maquettage.

Enregistrez la maquette adaptée à l'intérieur du projet de l'utilisateur, par exemple .swiftui-preview/fixtures/StatusCard.swift. Ne copiez jamais la source du projet dans la compétence installée partagée. N'incluez aucun @main, délégué d'application, racine de composition de production, macro #Preview ou services de production. configure, run et refresh analysent la maquette sous forme de texte et la rejettent si @main, #Preview ou import UIKit apparaît n'importe où, y compris dans les commentaires ; gardez ces chaînes également hors des commentaires. L'erreur nomme le jeton correspondant et sa ligne. Inspectez l'intégralité de la maquette avant de l'exécuter : le Swift exécutable s'exécute avec les autorisations normales de l'appelant ; cet assistant n'est pas un bac à sable. Les hachages de configuration ne peuvent pas établir la fidélité visuelle ni l'absence d'effets secondaires.

Si des API explicites UIKit ou iOS uniquement rendent le composant incompatible avec macOS, utilisez un workflow disponible avec le simulateur iOS/le Canvas Xcode ou signalez la dépendance non prise en charge précise. L'hôte macOS générique n'exécute pas UIKit. Si des modules, des ressources ou des catalogues de chaînes ne peuvent pas être adaptés en toute sécurité dans le contrat de fichier unique, utilisez un workflow disponible spécifique au projet ou indiquez la limitation concrète. Ne liez pas silencieusement l'application de production, n'exécutez pas son cycle de vie et ne modifiez pas sa configuration de construction.

Après avoir préparé et examiné la maquette authentique, enregistrez les chemins sélectionnés (relatifs à la racine du projet) :

python3 "<skill-directory>/scripts/bootstrap.py" configure --root "<project-root>" \
  --project "Package.swift" --source "Sources/StatusCard.swift" \
  --fixture ".swiftui-preview/fixtures/StatusCard.swift" --component StatusCard

--project accepte également un répertoire .xcodeproj ou .xcworkspace relatif ; init est un alias de configure. Ajoutez --live-fixture "<chemin relatif>" pour enregistrer une maquette avec état séparée pour les constructions live (voir references/live.md). Le fichier versionné .swiftui-preview/config.json stocke uniquement les chemins relatifs, le nom du composant, la plateforme macos et les hachages SHA-256 de la source sélectionnée et de la maquette adaptée. Il se déplace avec le projet et peut être validé par l'utilisateur ; n'effectuez aucune action Git sauf demande explicite. La configuration existante est préservée sauf si elle est explicitement remplacée avec configure --replace après inspection et adaptation. Les chemins et la configuration sélectionnés doivent exister dans la racine, sans liens symboliques ni traversée de chemins.

Après la réussite de configure, produisez la première prévisualisation avec run comme décrit ci-dessous. Les assistants directs dans les sections suivantes sont destinés aux maquettes ponctuelles qui n'ont pas de configuration enregistrée.

Prévisualisations ultérieures

Lorsque la configuration existe, inspectez-la et utilisez run. Il valide le schéma, les chemins et les hachages avant de lancer un assistant connu avec des positions d'arguments fixes :

python3 "<skill-directory>/scripts/bootstrap.py" run --root "<project-root>" \
  --mode render --output "/absolute/task-output/card.png" \
  --width 480 --height 320 --locale en_US --theme light --frame

Utilisez --mode gallery avec une sortie .html ou --mode live avec une nouvelle sortie .app. --theme et --frame s'appliquent uniquement au rendu ; les galeries incluent toutes les variantes et les prévisualisations live ont des contrôles natifs. Le répertoire parent de la sortie doit exister ; bootstrap rejette les sorties existantes plutôt que de les remplacer, contrairement aux assistants directs render.sh et gallery.sh ; pour refaire un rendu, choisissez un nouveau nom de fichier ou supprimez d'abord l'artefact lié à la tâche précédente. Les chemins de sortie relatifs sont résolus à partir de la racine du projet. --mode live construit uniquement ; les règles de lancement et d'inspection sont dans references/live.md.

Des hachages de source ou de maquette modifiés arrêtent l'exécution. Réinspectez le composant réel, mettez à jour la maquette, puis exécutez configure --replace avec les chemins sélectionnés, ou refresh lorsqu'une fenêtre live est en cours d'itération. Inspectez également les modifications apportées aux définitions/ressources de support : les hachages couvrent la source principale et la maquette autonome, pas l'intégralité du graphe de dépendances. Le changement de composant suit le workflow d'adaptation de première utilisation avant de remplacer la configuration. Préservez les modifications utilisateur apportées aux maquettes existantes.

Contrat de maquette et assistants directs

Le moteur de rendu compile un fichier Swift autonome avec son assistant. Son point d'entrée est :

import SwiftUI

@MainActor
enum PreviewFixture {
    static func makeView() -> some View {
        Text("Exemple")
    }
}

Les assistants compilent en mode langage Swift 6 avec concurrence stricte lorsque le compilateur le prend en charge, et en mode Swift 5 sinon. Lorsqu'une maquette adaptée d'un projet Swift 5 échoue uniquement à cause de diagnostics de concurrence (Sendable, isolation d'acteur), ne réécrivez pas le composant pour les satisfaire : passez --swift-version 5 à run ou refresh, ou définissez PREVIEW_SWIFT_VERSION=5 pour les assistants directs, et dites que la prévisualisation a été construite en mode Swift 5.

Utilisez des données synthétiques et un état initial fixe. Utilisez des actions inertes pour les rendus statiques ; les maquettes live peuvent implémenter des changements d'état locaux à la vue, de la validation et de la navigation. Incluez les types de vue locaux requis du composant dans la maquette ; conservez les contrôles SwiftUI réels tels que Form, TextField, SecureField et Toggle. Gardez les magasins d'identifiants, les appels réseau, la persistance et tout travail qui dépasse la durée de vie de la vue hors de la maquette ; une maquette live peut simuler un service avec un court délai en mémoire.

Lorsque le projet a déjà des maquettes #Preview, réutilisez leur construction de vue et leurs entrées. Ne compilez pas la macro #Preview ni une @main App dans cette maquette autonome. Ne réécrivez pas la configuration du projet juste pour rendre un composant.

Le même contrat de maquette fonctionne sur tous les projets pour les composants SwiftUI qui compilent pour macOS. Les composants UIKit uniquement nécessitent un workflow de simulateur iOS. Les assistants ne lient pas automatiquement des modules de projet arbitraires ni ne compilent/copient des ressources et des catalogues de chaînes. Extrayez une vue de valeur autonome lorsque c'est pratique. Si le composant a besoin de modules ou de bundles de projet, expliquez que cette commande autonome nécessite une construction explicitement adaptée ; ne prétendez pas que l'injection de locale fournit des traductions ou des ressources manquantes.

Rendu et inspection

Utilisez des chemins appropriés à la tâche en cours. Résolvez le répertoire de la compétence à partir de l'emplacement de cette compétence, entrez chaque chemin entre guillemets et créez d'abord le répertoire parent de la sortie. Invoquez :

bash "<skill-directory>/scripts/render.sh" \
  "/absolute/path/Fixture.swift" "/absolute/path/component-light.png" \
  480 320 light en_US

Les arguments sont la maquette, le PNG de sortie, la largeur du contenu, la hauteur du contenu, l'apparence (light ou dark) et l'identifiant de locale. La largeur et la hauteur sont des entiers de 1 à 4096, rendus à un pixel par point, ou fit. Un fichier de sortie existant est remplacé de manière atomique ; choisissez des chemins liés à la tâche. Répétez avec dark et un nom de fichier distinct lorsque la comparaison d'apparence est utile. La locale définit uniquement l'environnement SwiftUI ; sélectionnez la direction de disposition RTL explicitement dans une maquette si cela fait partie du test.

Choix de la fenêtre. Dimensionnez-la au composant, pas aux nombres d'exemple. Pour un écran complet, utilisez la taille de la fenêtre ou de l'appareil cible en points. Pour une ligne, une carte ou un contrôle, passez la largeur de son conteneur réel et fit pour la hauteur, par exemple 390 fit ; le moteur de rendu mesure la taille idéale de la maquette sur chaque axe ajusté et imprime render: fitted content size WxH sur stderr. fit fit convient aux contrôles de taille intrinsèque, mais les vues construites autour de Spacer, maxWidth: .infinity ou ScrollView se réduisent à leur minimum sur un axe ajusté, donc donnez-leur un nombre. run --mode render accepte --width fit et --height fit ; la galerie et le live nécessitent des nombres, donc réutilisez la taille signalée là-bas.

Ajoutez --frame uniquement si demandé ou utile pour la présentation. Il ajoute une barre de titre décorative et un remplissage autour de la fenêtre de contenu fixe : les dimensions de sortie deviennent largeur + 48 par hauteur + 88. Ses feux de circulation sont des formes dessinées. Il ne crée pas une vraie fenêtre et ne valide pas le chrome natif de la fenêtre.

Inspectez l'image générée avec le visualiseur d'images local disponible avant de signaler les résultats visuels. Si le contenu est absent ou rogné, vérifiez d'abord la disposition de la maquette et la fenêtre. Arrêtez-vous et expliquez les composants qui nécessitent une fenêtre, un cycle de vie d'application ou des ressources indisponibles plutôt que de lancer silencieusement l'application de production.

Galerie et fenêtre live

Deux sorties supplémentaires utilisent le même contrat de maquette. Lisez la référence liée en entier avant de produire l'une ou l'autre ; chacune a des règles sur les chemins de sortie, le lancement et ce qui compte comme vérifié.

  • Galerie de thèmes HTML, lorsque l'utilisateur souhaite comparer clair/sombre ou basculer le cadre décoratif : run --mode gallery, ou scripts/gallery.sh directement. Voir references/gallery.md.
  • Fenêtre native live, pour les vrais boutons, saisie de texte, focus et navigation : run --mode live, ou scripts/live.sh directement. Elle construit une .app et ne la lance pas. Une maquette statique avec des actions inertes ne montre rien lorsqu'on clique ; references/live.md explique quand ajouter une maquette avec état séparée avec configure --live-fixture. Une fenêtre ouverte ne capte jamais les modifications de code : après avoir mis à jour la maquette, refresh reconstruit l'application au même chemin, ferme l'ancienne fenêtre et la rouvre (même référence).

Présenter le résultat

Inspectez chaque artefact vous-même avant de le montrer, puis présentez-le avec les outils que l'agent actuel propose. Utilisez les outils réellement disponibles dans la session ; n'en supposez pas un de cette liste.

Emplacement de sortie. Utilisez un répertoire lié à la tâche. Lorsque le client ne peut afficher que des fichiers à l'intérieur du projet, écrivez dans <project-root>/.swiftui-preview/artifacts/ (créez-le d'abord) et n'effectuez aucune action Git dessus sauf demande.

Claude Code.

  • PNG : lisez le fichier avec l'outil Read pour inspecter l'image. Pour l'afficher, utilisez l'outil de présentation de fichier ou de prévisualisation de la session lorsqu'il existe ; sinon donnez le chemin absolu sous forme de lien et exécutez open "/absolute/path/component-light.png" lorsque l'utilisateur a demandé à la voir. Les images Markdown en ligne ne s'affichent pas dans un terminal.
  • Galerie HTML : ouvrez-la dans un navigateur ou un outil de prévisualisation disponible en utilisant son URL file://, ou exécutez open "/absolute/path/component-gallery.html". Testez les contrôles de thème et de cadre via un outil de navigation avant de les signaler comme vérifiés ; sans cela, dites que les contrôles n'ont pas été testés.
  • Application live : exécutez open "/absolute/path/SwiftUI Preview.app" lorsque le lancement fait partie de la demande ; refresh ouvre l'application elle-même sauf si --no-launch est donné. Vérifiez l'interaction à l'aide d'outils de capture d'écran ou de navigation de fenêtre disponibles lorsque cela fait partie du flux de travail demandé ; sans cela, signalez qu'aucune interaction n'a été vérifiée.

(Le reste du contenu original a été tronqué pour la traduction ; il ne fait pas partie du document SKILL.md final.)

Skills associés