Appearance
Schéma et présentation des préférences
Voir préférences au runtime pour lire les valeurs. Le schéma décrit le formulaire du streamer ; il ne contient pas ses réglages enregistrés.
Source et compilation
Écris preferences.config.js, avec module.exports = { ... }. Le DEV HUB compile le JavaScript en config/preferences.config.json via transpile ou watch, puis synchronise les configurations du brouillon. Le backend valide le schéma. Le JSON compilé est régénéré : ne le corrige pas à la main.
L'objet suivant est un schéma complet. Dans le fichier JS, préfixe-le par module.exports =. Il est aussi du JSON valide, sans commentaires ni virgules finales.
json
{
"type": "group",
"appearance": { "wrap": "tabs" },
"groupItems": {
"theme": {
"type": "group",
"label": { "fr": "Apparence", "en": "Appearance" },
"groupItems": {
"color": {
"type": "color",
"label": { "fr": "Couleur", "en": "Color" },
"default": "#9146FF"
}
}
}
}
}La racine explicite type: 'group' permet d'utiliser appearance. La forme courte { theme: {...}, autreChamp: {...} } est aussi acceptée et devient un groupe racine. Les clés de champs ne doivent pas contenir de point. Réserve les clés techniques injectées par la plateforme (_version, _uuid, _index, _deleted, _isScalarCollection).
Un champ déclare type. Un groupe exige groupItems (objet de champs nommés), une collection exige collectionItems (une définition d'élément). Les types déterminent les options et la forme de la valeur.
Propriétés communes
| Propriété | Usage |
|---|---|
label, tooltip | Texte simple ou objet localisé { fr, en }. |
required | Champ obligatoire ; généralement faux par défaut, vrai pour choice et multipleChoice. Certains types imposent leurs propres règles. |
default, defaults | Valeur initiale générale / par langue, selon les règles des défauts. |
wuOptions | Options propres au type ; ne pas y placer les propriétés communes. |
hideIf, disableIf, requiredIf | Expressions de formulaire. |
conditionalLabel | Libellé construit à partir de valeurs ; remplace label lorsqu'il est défini. |
appearance | Présentation, décrite ci-dessous. |
migration | Conversion depuis la version publiée précédente ; contrat dédié. |
flag est une option avancée des champs compatibles avec les arguments de lancement ; elle ne remplace pas le schéma d'arguments d'un trigger. Voir modes de lancement.
Présentation
Clé de appearance | Valeurs / effet |
|---|---|
wrap | list ou tabs pour un groupe ou une collection. |
tabsStyle | underline ou pills pour un groupe en onglets. Sans option : underline à la racine, pills dans les groupes imbriqués. |
choicesStyle | cards ou select pour multipleChoice à choix statiques. Les cartes sont ignorées avec avertissement pour des choix dynamiques. |
folded | Démarrer replié pour les groupes et éléments de collection affichés en liste. |
hidden | Masquer dans le formulaire ; ce n'est pas une donnée secrète ni une suppression de valeur. |
handle | Afficher la poignée de pli/tri. |
lineBreak, lineBreakText | Séparateur avant le champ, avec texte facultatif. |
color, form | Anciennes options dépréciées et ignorées ; ne plus les ajouter. |
Libellés dynamiques
Dans un libellé, @self désigne la valeur du champ ; sur un groupe, @self.title désigne son enfant. @parent.title vise le groupe ancêtre selon les règles des chemins.
@self.mode->toStringaffiche le libellé du choix, alors que@self.moderend sa clé.@self.title->editablepropose une édition rapide d'un champstringounumber.->get(clé)descend d'un niveau : index d'une collection (->get(0)) ou clé d'un groupe (->get(name)). Les appels s'enchaînent :@self.animals->get(0)->get(name).- Un groupe ou une collection est toujours rendu sous forme de texte. Pour une collection, ce texte est son nombre d'éléments non supprimés :
@self.animals->toStringaffiche2, et unswitchsur ce chemin peut traiter"0","1"puis_default. - Une expression ternaire peut traiter une valeur vide ; exemple ci-dessous.
conditionalLabelaccepte, par langue, une liste de textes et de blocs{ if: expression, then, else }ou{ switch: chemin, case: { valeur: texte, _default: texte } }. Les blocs peuvent être imbriqués : une valeur dethen,elseou d'uncasepeut elle-même être une liste de textes et de blocs. Les morceaux sont concaténés sans séparateur.
text
{{@self.title==?Sans titre:@self.title->toString}}Exemple d'élément de groupe, à placer dans collectionItems :
json
{
"type": "group",
"conditionalLabel": {
"fr": [
{ "if": ["@self.enabled", "==", true], "then": "Actif — ", "else": "Inactif — " },
"@self.title->editable"
],
"en": [
{ "if": ["@self.enabled", "==", true], "then": "Enabled — ", "else": "Disabled — " },
"@self.title->editable"
]
},
"groupItems": {
"enabled": { "type": "boolean", "default": true },
"title": { "type": "string", "default": "Titre" }
}
}Libellé qui choisit selon un mode, puis selon le nombre d'éléments d'une collection, et lit un élément précis :
json
{
"type": "group",
"conditionalLabel": {
"fr": [
{
"switch": "@self.mode",
"case": {
"single": "Un seul animal",
"list": [
{
"switch": "@self.animals->toString",
"case": {
"0": "Aucun animal",
"1": "Animal : @self.animals->get(0)->get(name)",
"_default": "@self.animals->toString animaux, dont @self.animals->get(0)->get(name)"
}
}
],
"_default": "@self.mode->toString"
}
}
]
},
"groupItems": {
"mode": {
"type": "choice",
"default": "list",
"wuOptions": { "choices": { "single": "Un animal", "list": "Liste d'animaux" } }
},
"animals": {
"type": "collection",
"collectionItems": {
"type": "group",
"groupItems": { "name": { "type": "string", "default": "Chat" } }
},
"default": [{ "name": "Chat" }]
}
}
}Réutiliser un modèle
Pour du code source JS, réutilise les modules du bootstrap (par exemple modules/Model.js) selon leurs exports réels. Le format de préférences possède aussi ses propres modèles déclaratifs :
json
{
"textModel": {
"isModel": true,
"type": "group",
"groupItems": {
"title": { "type": "string", "default": "Titre" },
"size": { "type": "number", "default": 24 }
}
},
"header": {
"useModel": "textModel",
"groupItems": {
"title": { "label": { "fr": "Titre principal", "en": "Main title" } }
}
}
}isModel: true retire la définition du formulaire. useModel fusionne le modèle avec les propriétés locales, prioritaires. Les objets sont fusionnés récursivement ; hideIf est remplacé en bloc. Un modèle peut en réutiliser un autre, mais garde des dépendances simples et sans cycle. Le résultat ci-dessus contient header.title et header.size, pas textModel.