Cadence Mini-Programs
Coloration, diagnostics, complétion et navigation pour les mini-programmes Cadence.
L'extension agit sur deux sortes de fichiers :
- les templates :
pages/<nom>/template.html et components/<nom>/template.html ;
- le manifeste :
manifest.json.
Dans un template, la barre d'état affiche le langage « Cadence Template ».
Templates
Coloration
- Interpolations
{{ … }} : le contenu est coloré comme du JavaScript.
- Blocs :
@if, @else if, @else, @for avec of et track, @switch, @case, @default.
- Liaisons
[prop]="…" et événements (tap)="…" : la valeur est colorée comme du code.
Commentaires et indentation fonctionnent comme en HTML. Taper {{ insère aussi les }} de
fermeture.
Diagnostics
Les erreurs de template sont soulignées pendant la frappe, par exemple :
- une balise non fermée ;
- une interpolation dans une valeur d'attribut ;
- un
@for sans track.
Deux avertissements s'ajoutent, pour des fautes que personne ne signale — ni le compilateur,
ni le runtime :
- une balise à trait d'union qu'aucun catalogue ne connaît : le runtime en fera un élément nu,
sans un mot. Une balise sans trait, comme
<br>, reste votre choix ;
- un nom d'icône introuvable dans
<icon name="…"> : rien ne sera dessiné. Un [name] lié
n'est pas vérifié, sa valeur ne se connaît qu'à l'exécution.
L'extension utilise le parseur du compilateur. Une erreur soulignée sera aussi refusée par
npx mini build.
Complétion
Balises. Après <, la liste propose les éléments et composants du moteur (view, text,
switch, picker…) et les composants du mini-programme, avec leur documentation.
Props. Dans une balise ouvrante, la liste propose les props de la balise, en attribut ou après
[. Un attribut littéral alimente la prop du même nom : <cell title="Réglages"> équivaut à
[title]="'Réglages'".
Événements. Après (, la liste propose les événements de la balise, puis tap, que le
moteur pose sur tout élément : change sur <switch>, input et confirm sur <search-bar>,
les trois événements de bord sur <scroll-view>. Un composant du mini-programme n'offre que
tap : ses CustomEvent viennent de sa logique, que l'extension ne lit pas.
Emplacements. Dans slot="…", la liste propose les emplacements nommés du composant qui
entoure l'enfant — before et after dans un <cell>, ceux que déclarent les <slot name="…"> d'un composant du mini-programme. L'emplacement par défaut ne s'y écrit pas : il
reçoit ce qui ne choisit rien.
Icônes. Dans <icon name="…">, la liste s'ouvre dès le guillemet ouvrant. Elle propose les
icônes du moteur et celles du mini-programme : les fichiers .svg du dossier icons/ qui
commencent par <svg. Une icône du mini-programme remplace l'icône du moteur de même nom.
Expressions. Dans {{ … }}, dans la valeur d'une liaison ou d'un événement, et dans l'en-tête
d'un bloc, la liste propose :
- les noms de l'objet retourné par le
logic.ts ;
- les props, dans un composant ;
- la variable de boucle et
$index, à l'intérieur d'un @for ;
- la variable de boucle, sans
$index, dans track ;
$event, dans un événement.
Une variable de boucle masque un nom du logic.ts qui porte le même nom, comme à la compilation.
Navigation
⌘-clic (Ctrl-clic sous Windows et Linux) :
- sur un composant, comme
<product-card> : ouvre components/product-card/template.html ;
- sur une variable de boucle : va à son
@for ;
- sur un nom retourné par le
logic.ts : va à sa clé dans l'objet retourné ;
- sur une prop : va à son nom dans
props.
Sur la clé, un second ⌘-clic mène à sa déclaration TypeScript.
Ordre de la liste
Les propositions gardent l'ordre choisi : composants du mini-programme, puis composants du
moteur, puis éléments de base. Pour un événement, ceux de la balise passent avant tap. Dans une expression, une variable de boucle passe avant un nom du
logic.ts — c'est l'ordre dans lequel le compilateur les résout.
Le curseur au milieu d'un nom, valider remplace le nom entier ; maintenir ⌥ n'insère que
devant ce qui suit.
Blocs
Taper @ propose les blocs que le parseur accepte à cet endroit, et rien d'autre :
- dans du contenu :
@if, @for, @switch ;
- juste après le
} d'un @if ou d'un @else if : @else if et @else s'y ajoutent ;
- dans le corps d'un
@switch : @case et @default, seuls — c'est tout ce qu'il admet ;
- dans le corps d'un
@case : de nouveau les trois premiers.
Le corps arrive écrit, avec des valeurs à remplacer par tabulation. Celui du @for porte déjà
son track, que le compilateur exige.
Survol
Poser le curseur sur un nom en dit l'origine, sans quitter le template :
- sur une balise : d'où elle vient — élément du moteur, composant du moteur, composant du
mini-programme — sa glose et la liste de ses props ;
- sur un attribut déclaré : la prop, et le composant qui la déclare ;
- sur un attribut non déclaré : le rappel qu'il se pose sur l'élément hôte, et n'atteint
pas le composant ;
- sur un événement : la balise qui le publie, ou
tap qui vaut partout. Un nom qu'aucune balise
ne publie est signalé comme tel : rien ne le déclenchera. Sur un composant du mini-programme,
l'extension s'abstient — sa logique peut l'émettre ;
- sur
slot : le rappel qu'il projette l'élément dans le composant qui l'entoure, au lieu de se
poser sur l'élément ;
- sur un nom d'expression : sa provenance — variable de
@for, $index, $event, prop, ou
nom retourné par le logic.ts.
Feuilles de style
Dans un style.scss du mini-programme, écrire var(-- propose les 222 propriétés du thème,
avec leur valeur, et une pastille sur les couleurs. La documentation d'un item dit ce que le mode
sombre y substitue, quand il y substitue quelque chose.
S'y ajoutent les propriétés que le conteneur écrit sur la racine à l'amorçage — --cadence-safe-*,
la pastille d'actions, la hauteur d'en-tête. Elles n'ont pas de valeur ici : elle vient de
l'appareil.
Hors d'un mini-programme, l'extension se tait : une feuille de style quelconque ne lit pas ces
noms.
Lecture du logic.ts
L'extension lit le logic.ts sans l'exécuter. Elle reconnaît la forme de la documentation, comme
dans ce composant :
import { navigateBack } from '@cadence/router';
export const props = ['title', 'canGoBack'];
export default function PageHeader(): Record<string, unknown> {
return { goBack: () => navigateBack() };
}
- Props : une liste de chaînes littérales. Ici,
title et canGoBack.
- Noms : l'objet retourné par la fonction exportée par défaut. Ici,
goBack.
Dans cet objet, les clés courtes ({ total }), les paires ({ total: … }) et les méthodes
({ submit() {} }) sont reconnues. Un étalement (...autres) n'ajoute aucun nom.
Écrit autrement (fonction fléchée, objet construit ailleurs, liste de props calculée), le fichier
ne donne aucun nom : l'extension ne devine pas.
Seul le fichier enregistré compte. Un nom ajouté apparaît après l'enregistrement.
Manifeste
Le manifest.json est validé pendant la frappe : clés connues, types, valeurs autorisées, deux à
cinq onglets, code de langue bien formé (fr, fr-FR). Une clé mal orthographiée est signalée,
alors que le compilateur l'ignore sans prévenir.
La validation ne concerne que les manifestes qui contiennent entry ou pages. Le manifeste
d'une application web n'est pas touché.
Dans le tabBar, les champs icon et activeIcon proposent les noms d'icônes.
Limites
- Diagnostics : une seule erreur est soulignée à la fois. Le soulignement peut tomber juste
après l'erreur. Les erreurs dans une expression ou dans les styles n'apparaissent qu'au build.
- Manifeste : les règles entre deux champs ne sont vérifiées qu'au build (entrée absente des
pages, onglet vers une page inconnue, page de sous-package hors de sa racine).
- Complétion : rien n'est proposé après un point (
line.), pour les globaux (Math,
JSON…), ni dans une balise fermante.
- Blocs : un
} écrit comme texte dans un élément, à l'intérieur d'un bloc, est lu comme la
fin du bloc. La variable de boucle n'est plus proposée après lui.
- Navigation : le ⌘-clic ne part pas d'une prop écrite dans une balise (
[title] dans
<page-header>).
- Icônes : un nom d'icône inconnu est averti dans le template, jamais au build.
- Événements et emplacements : un nom qu'aucune balise ne publie, ou un
slot qui ne
correspond à rien, n'est pas souligné. Le survol le dit ; rien d'autre ne le dira.
Licence
MIT. La configuration d'édition des templates reprend celle du HTML de VS Code, sous licence MIT.