# Widgets d’intégration externe : choisir la disposition des cases et leur donner une couleur d’accent

**URL:** <https://community.gladysassistant.com/t/widgets-d-integration-externe-choisir-la-disposition-des-cases-et-leur-donner-une-couleur-d-accent/10996>\
**Category:** Demandes livrées\
**Created:** [Octobre 9, 2026, 7:24 UTC](https://community.gladysassistant.com/t/widgets-d-integration-externe-choisir-la-disposition-des-cases-et-leur-donner-une-couleur-d-accent/10996 "2026-10-09T07:24:12Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![prohand](https://gladys-assistant-community.b-cdn.net/user_avatar/community.gladysassistant.com/prohand/32/15713_2.png) [@prohand](https://community.gladysassistant.com/u/prohand)\
**Post date:** [Octobre 9, 2026, 7:24 UTC](https://community.gladysassistant.com/t/widgets-d-integration-externe-choisir-la-disposition-des-cases-et-leur-donner-une-couleur-d-accent/10996/1 "2026-10-09T07:24:12Z")

</div>

**Titre : Widgets d’intégration externe : choisir la disposition des cases et leur donner une couleur d’accent**

Bonjour,

Je développe l’intégration externe **Prix Carburants**. Un utilisateur m’a fait deux remarques sur la carte « Ma station » que je ne peux pas régler côté intégration, car elles dépendent de l’affichage des widgets dans Gladys.

### 1. Disposition des cases

Aujourd’hui, les cases (`value` / `gauge`) passent à la ligne quand la place manque (`flex-wrap`, largeur mini 96 px). Avec **3 cases** sur une carte étroite, on obtient **2 cases à mi-largeur et 1 case en pleine largeur** en dessous. L’utilisateur trouverait plus clair d’avoir 3 cases de même largeur, l’une sous l’autre.

Gladys n’envoie pas la largeur de l’écran à l’intégration, donc l’intégration ne peut pas choisir.

**Proposition** : un champ optionnel dans le contenu du widget, par exemple `tiles_layout` :

- `auto` : comme aujourd’hui (par défaut) ;
- `row` : toutes les cases sur une seule ligne, même largeur ;
- `stack` : une case par ligne, en pleine largeur.

Une valeur inconnue revient à `auto`, donc rien ne change pour les intégrations existantes.

### 2. Couleur d’accent par case

Les couleurs autorisées sont des couleurs « de sens » : `neutral`, `primary`, `success`, `warning`, `danger`, `info`. C’est très bien pour dire « ok / attention / erreur », mais on ne peut pas s’en servir pour **repérer une case d’un coup d’œil**. Par exemple, l’utilisateur aimerait retrouver les couleurs des pistolets de carburant. Et l’orange (`warning`) sert déjà, dans ma carte, à signaler une rupture : utiliser les mêmes couleurs pour les deux mélangerait les deux sens.

**Proposition** : un champ optionnel `accent` sur les cases, affiché comme une petite barre ou un point de couleur, **séparé** de `color` (qui garde son rôle actuel sur la valeur). Deux options possibles :

- une couleur libre `#RRGGBB`, vérifiée par Gladys ;
- ou, pour rester cohérent avec les thèmes clair et sombre, une petite liste de couleurs nommées : `green`, `yellow`, `blue`, `orange`, `red`, `purple`, `gray`.

### Pour finir

Les deux ajouts sont optionnels et ne changent rien aux widgets existants. Je peux proposer une PR si l’idée vous convient.

Merci !

---

<div class="post-metadata">

**Author:** ![Lokkye](https://gladys-assistant-community.b-cdn.net/user_avatar/community.gladysassistant.com/lokkye/32/5881_2.png) [@Lokkye](https://community.gladysassistant.com/u/Lokkye)\
**Post date:** [Octobre 9, 2026, 1:44 UTC](https://community.gladysassistant.com/t/widgets-d-integration-externe-choisir-la-disposition-des-cases-et-leur-donner-une-couleur-d-accent/10996/2 "2026-10-09T13:44:49Z")

</div>

Ce sujet tombe a point, j’ai eu cette problématique aujourd’hui 👍

---

<div class="post-metadata">

**Author:** ![pierre-gilles](https://gladys-assistant-community.b-cdn.net/user_avatar/community.gladysassistant.com/pierre-gilles/32/5886_2.png) [@pierre-gilles](https://community.gladysassistant.com/u/pierre-gilles)\
**Post date:** [Octobre 9, 2026, 1:56 UTC](https://community.gladysassistant.com/t/widgets-d-integration-externe-choisir-la-disposition-des-cases-et-leur-donner-une-couleur-d-accent/10996/3 "2026-10-09T13:56:20Z")

</div>

Salut @prohand,

Merci pour ce retour très bien documenté (et merci @Lokkye pour la confirmation) !

Les deux problèmes sont réels. Mais dans les deux cas, je pense que la solution doit venir de Gladys plutôt que d’un nouveau champ côté intégration. C’est le principe de base des widgets d’intégration : **l’intégration décrit _quoi_ afficher, Gladys décide _comment_**. C’est ce qui nous permet de garantir que tous les widgets restent cohérents en thème clair, en thème sombre, avec Horizon, et à toutes les largeurs d’écran.

### 1. La disposition des cases

Tu mets le doigt sur un vrai bug, et ton propre argument donne la clé : l’intégration ne connaît pas la largeur de l’écran, elle est donc la plus mal placée pour choisir la disposition. Le même widget s’affiche sur un téléphone et sur une tablette murale. `row` avec 6 cases sur un téléphone donnerait des valeurs tronquées, et `stack` sur une carte large donnerait une carte très haute pour rien. Un choix figé sera forcément faux quelque part.

Le problème vient de notre rendu : quand la place manque, une case passe à la ligne et s’étire sur toute la largeur. Avec 3 cases dans une carte étroite, ça donne exactement le « 2 + 1 » que tu décris, et ça touche toutes les intégrations, pas seulement la tienne.

On va donc corriger ça directement dans Gladys, sans nouveau champ : une grille équilibrée, qui choisit le nombre de colonnes selon le nombre de cases **et** la largeur réelle de la carte, et qui n’étire plus jamais une case isolée. Ton widget en profitera sans rien changer, comme tous les autres.

### 2. La couleur d’accent

**Couleur hexadécimale libre : non.** C’est un choix assumé depuis le départ : on ne pourrait plus garantir le contraste en mode sombre ou avec Horizon, et ce serait la porte ouverte aux couleurs de marque.

**Une palette nommée, en revanche, c’est une vraie question.** Tu as raison de ne pas détourner `warning` : `color` exprime un **état** (ok / attention / problème), alors que toi tu veux exprimer une **identité** (quel carburant). Et le besoin dépasse les carburants : les bacs de collecte des déchets (jaune, vert, bleu…) sont typiquement dans le même cas.

J’ai quand même deux réserves :

- Pour l’utilisateur, une couleur reste une couleur : une barre rouge ou orange sera lue comme une alerte, quel que soit le nom du champ. La confusion que tu veux éviter (orange = rupture) reviendrait visuellement.
- Le risque « arc-en-ciel » : six cases de six couleurs, c’est exactement l’encombrement qu’on cherche à éviter.

Si on y va, ce serait à ces conditions :

- une liste fermée de couleurs, que Gladys adapte elle-même au thème clair, au thème sombre et à Horizon (contraste compris : un jaune sur fond blanc n’est pas lisible tel quel) ;
- affichée uniquement comme une petite pastille d’identité, jamais comme couleur de la valeur ou du fond (ça reste le rôle de `color`) ;
- disponible partout où une pastille identifie quelque chose : les cases, mais aussi les lignes de `status` (un widget de collecte des déchets utiliserait plutôt une liste) ;
- simplement ignorée par une ancienne version de Gladys.

Comme ce serait un second système de couleurs qui concerne tous les widgets, je préfère traiter ce point à part et le spécifier avant de coder, plutôt que de l’ajouter en même temps que le correctif de disposition. Si d’autres ont des cas d’usage, n’hésitez pas à les partager ici, ça aidera à trancher 🙂

En attendant, pour Prix Carburants, le libellé et l’icône de chaque case suffisent à identifier le carburant, et tu as bien raison de garder `warning` pour les ruptures.

Merci encore pour la proposition et pour l’offre de PR ! Pour l’accent, attendons d’avoir tranché ici avant de partir sur du code.

---

<div class="post-metadata">

**Author:** ![pierre-gilles](https://gladys-assistant-community.b-cdn.net/user_avatar/community.gladysassistant.com/pierre-gilles/32/5886_2.png) [@pierre-gilles](https://community.gladysassistant.com/u/pierre-gilles)\
**Post date:** [Octobre 9, 2026, 1:59 UTC](https://community.gladysassistant.com/t/widgets-d-integration-externe-choisir-la-disposition-des-cases-et-leur-donner-une-couleur-d-accent/10996/4 "2026-10-09T13:59:08Z")

</div>

Ticket :

> <https://github.com/GladysAssistant/Gladys/issues/3180>
>
> \### Describe the bug
> 
> In an external integration widget (\`external-widget\` box),… the tiles (\`value\` / \`gauge\` components) are laid out as one flex row that wraps (\`front/src/components/boxs/external-widget/style.css\`, \`.tiles\` + \`.tile { flex: 1 1 96px }\`). When the tiles don't all fit on one line, the ones pushed to the next row grow to fill it. A single leftover tile ends up spanning the \*\*full width\*\* of the card, under a row of narrower tiles.
> 
> Reported on the forum by the author of the "Prix Carburants" integration, whose "Ma station" card shows three prices: two tiles at half width, then one full-width tile below. This affects every integration that puts tiles in a widget, not just that one.
> 
> Measured in Chromium with the real \`style.css\`, by width of the tile area (the card body's inner width):
> 
> | Tiles | Area width | Tile widths per row |
> |---|---|---|
> | 3 | 240–300 px | \`116+116 / 240\` … \`146+146 / 300\` |
> | 3 | ≥ 304 px | \`96+96+96\` (OK) |
> | 4 | 320–360 px | \`101+101+101 / 320\`, \`115+115+115 / 360\` |
> | 5 | 320–360 px | \`101+101+101 / 156+156\`, \`115+115+115 / 176+176\` |
> | 5 | 420 px | \`99+99+99+99 / 420\` |
> | 6 | 420 px | \`99+99+99+99 / 206+206\` |
> | 6 | 520 px | \`98+98+98+98+98 / 520\` |
> 
> Below 304 px, three tiles can never share a row (3 × 96 px + 2 × 8 px gaps = 304 px), so the third one always wraps and stretches.
> 
> \### To reproduce
> 
> 1. Install an external integration that declares a widget, or stub one (see the Cypress journey of the external widget).
> 2. Make \`widget.get\` return content with 3 \`value\` tiles, for example 3 fuel prices.
> 3. Add the widget to a dashboard in a narrow column, such as a 4-column layout or a phone, so that the tile area is under 304 px wide.
> 4. See two half-width tiles, then one full-width tile below.
> 
> The same happens with 4, 5 or 6 tiles at the widths in the table above.
> 
> \### Expected behavior
> 
> Tiles stay balanced at every width: a tile that wraps keeps the width of the tile above it, and the row split is chosen by Gladys from the tile count and the actual width. For example, 3 tiles stay on one row by tightening padding and font, 4 tiles show as 4 or 2 × 2, and 5 or 6 tiles as rows of 3 or 2.
> 
> This must stay a core rendering decision, with \*\*no new field\*\* in the widget content. The integration doesn't know the screen width, and one widget is shown on both phones and wall tablets. This follows the "the integration describes \*what\*, Gladys decides \*how\*" principle and the rejection of layout containers in \`docs/specs/external-integrations/capabilities/dashboard-widgets.md\`.
> 
> Implementation notes:
> \- \*\*No stretched leftover tile:\*\* a CSS grid instead of \`flex-grow\` makes a wrapped tile keep its column's width.
> \- \*\*Adapt to the card width:\*\* \`@container\` queries are already used in the front (\`routes/dashboard/style.css\`, \`components/device/ShutterButtons.css\`).
> \- \*\*Gauge width:\*\* the gauge SVG has a fixed width of 88 px (\`.gauge\`), so tighter tiles need it to scale down.
> \- \*\*Spec in the same diff:\*\* the "Tiles" row of section 5 of \`dashboard-widgets.md\` says "rendered as one wrapping row". Update it in the same diff (living-spec rule in \`AGENTS.md\`).
> 
> \### Gladys Assistant version
> 
> \`master\` at 79555c3 (external integration widgets)
> 
> \### Installation type
> 
> Other (reproduced from source, \`front/src/components/boxs/external-widget/style.css\`)
> 
> \### Relevant logs
> 
> None: this is a pure CSS layout issue, with no server or console error.
> 
> \### Additional context
> 
> Forum: \`\`https://community.gladysassistant.com/t/widgets-d-integration-externe-choisir-la-disposition-des-cases-et-leur-donner-une-couleur-d-accent\`\`/10996
> 
> The same topic also proposes a per-tile accent color. That is a feature request, discussed on the forum, and is deliberately not part of this issue.

---

<div class="post-metadata">

**Author:** ![NineStars](https://gladys-assistant-community.b-cdn.net/user_avatar/community.gladysassistant.com/ninestars/32/22836_2.png) [@NineStars](https://community.gladysassistant.com/u/NineStars)\
**Post date:** [Octobre 9, 2026, 6:16 UTC](https://community.gladysassistant.com/t/widgets-d-integration-externe-choisir-la-disposition-des-cases-et-leur-donner-une-couleur-d-accent/10996/5 "2026-10-09T18:16:21Z")

</div>

Merci d’avoir créé le sujet prohand, c’est traité à une vitesse les tickets ici ! (Plus vite qu’au boulot en tout cas haha).

Élégante solution la grille «&nbsp;équilibrée&nbsp;» @pierre-gilles merci 🙂

---

<div class="post-metadata">

**Author:** ![cursor-bot](https://gladys-assistant-community.b-cdn.net/user_avatar/community.gladysassistant.com/cursor-bot/32/22252_2.png) [@cursor-bot](https://community.gladysassistant.com/u/cursor-bot)\
**Post date:** [Octobre 10, 2026, 12:16 UTC](https://community.gladysassistant.com/t/widgets-d-integration-externe-choisir-la-disposition-des-cases-et-leur-donner-une-couleur-d-accent/10996/6 "2026-10-10T00:16:07Z")

</div>

Salut tout le monde !

Ce sujet est désormais **en cours de développement**.

Une PR a été ouverte pour équilibrer la grille des cases des widgets d’intégration externe :

> <https://github.com/GladysAssistant/Gladys/pull/3183>
>
> Fixes #3180
> 
> Forum: \`\`https://community.gladysassistant.com/t/widgets-d-integrat…ion-externe-choisir-la-disposition-des-cases-et-leur-donner-une-couleur-d-accent\`\`/10996
> 
> \> This PR was produced by an automated routine and has not been reviewed by a human.
> 
> \## What changed and why
> \- \`external-widget/style.css\`: tiles now use a CSS grid instead of a flex row with \`flex-grow\`, so a wrapped tile keeps its column width instead of stretching to the full card width.
> \- The column count is chosen by the core from the tile count (a \`tilesCountN\` class set in \`WidgetComponents.jsx\`) and from the width of the tile area (\`@container\` query on a new \`.tilesBox\` wrapper): 3 tiles stay on one row (tighter padding, font and gauge below 304 px); 4 tiles show as 4 columns (\>= 408 px) or 2 x 2; 5 or 6 tiles as rows of 3 (\>= 304 px) or 2.
> \- The gauge SVG now scales down (\`max-width: 100%\`, aspect-ratio) instead of a fixed 88 px.
> \- No new field in the widget content.
> \- Spec \`dashboard-widgets.md\` section 5 ("Tiles" row) updated in the same diff.
> 
> \## What I verified locally
> \- \`npm run prettier-check\`, \`npm run eslint\` (0 errors), \`npm run compare-translations\`, \`npm run build\` in \`front/\`: all pass.
> \- I did NOT visually check the layout in a browser and did not run Cypress.
> 
> \## What a human must check before merge
> \- Visually check 1 to 6 tiles (value and gauge) at the widths in the issue table (about 240, 300, 360, 420, 520 px), including the Horizon glass theme and dark mode.
> \- Check that the 3-tile tightened style below 304 px looks acceptable, and that the 5-tile case at narrow width (2 + 2 + 1) is acceptable.
> \- Run the Cypress external widget journey.
> 
> 🤖 Generated with \[Claude Code\](https://claude.com/claude-code)
> 
> https://claude.ai/code/session\_011yjM7iuKS3kp4LLGxoy9ZF
> 
> \---
> \_Generated by \[Claude Code\](https://claude.ai/code/session\_011yjM7iuKS3kp4LLGxoy9ZF)\_

N’hésitez pas à suivre la PR, à tester (optionnel, surtout pour les petites demandes) et à faire vos retours ici si besoin.

---

<div class="post-metadata">

**Author:** ![cursor-bot](https://gladys-assistant-community.b-cdn.net/user_avatar/community.gladysassistant.com/cursor-bot/32/22252_2.png) [@cursor-bot](https://community.gladysassistant.com/u/cursor-bot)\
**Post date:** [Octobre 12, 2026, 5:08 UTC](https://community.gladysassistant.com/t/widgets-d-integration-externe-choisir-la-disposition-des-cases-et-leur-donner-une-couleur-d-accent/10996/7 "2026-10-12T17:08:40Z")

</div>


