Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ Le format suit [Keep a Changelog](https://keepachangelog.com/fr/1.1.0/) et le pr

## [Unreleased]

### Added

- **Alignement vertical réglable sur les rangées icône/titre + action** (FSHSP-214).
`ui-alert`, `ui-toast` et les en-têtes de `ui-modal`, `ui-drawer` et `ui-bottom-sheet`
figeaient `align-items: flex-start`. C'est le bon réglage quand le texte passe sur
plusieurs lignes (l'icône reste sur la première) et le mauvais quand il tient sur une
seule, où la hauteur minimale laisse du vide sous le texte : aucune valeur statique ne
convient aux deux, et les projets en étaient réduits à une surcharge globale sur les
classes internes. Treize poignées, à chaque fois la rangée puis ses enfants, lesquels
valent `auto` (donc suivent la rangée) par défaut : `--ui-alert-align`,
`--ui-alert-icon-align`, `--ui-alert-close-align`, `--ui-toast-align`,
`--ui-toast-icon-align`, `--ui-toast-close-align`, `--ui-toast-icon-padding-top`,
`--ui-modal-header-align`, `--ui-modal-header-actions-align`, `--ui-drawer-header-align`,
`--ui-drawer-action-align`, `--ui-bottom-sheet-header-align` et
`--ui-bottom-sheet-action-align`. Aucun défaut ne change. Le calage optique de l'icône
(`--ui-{alert,toast}-icon-padding-top`) ne sert qu'en alignement haut : à remettre à `0`
quand on centre.

### Changed

- **`ui-input-date` : bouton d'ouverture aligné sur `ui-datepicker`** (FSHSP-214). Le champ
Expand Down
6 changes: 3 additions & 3 deletions figma/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The components' `--ui-*` variables, in the same DTCG shape as
one too. Generated by `pnpm docs:config`; `docs:config:check` fails if it is stale.

**These are not design tokens.** A token belongs to the system (`--units-sm`); a
component variable belongs to one component, and 1261 of the 1418 entries merely _alias_ a
component variable belongs to one component, and 1262 of the 1419 entries merely _alias_ a
token. Hence a **dedicated collection** (`$extensions.com.4sh.ui-kit.figmaCollection`)
rather than adding them to `semantics` or `metrics`.

Expand Down Expand Up @@ -38,9 +38,9 @@ rather than adding them to `semantics` or `metrics`.
variables are `remote`, hence read-only (see `CLAUDE.md`).
- Keep the aliases as aliases: that is what preserves brand, light/dark and responsive.
- Literal values are in `px` (converted from `rem`, base 16), like the token files.
- `$extensions.com.4sh.ui-kit.skipped` lists 66 entries with nothing to create: `calc()`
- `$extensions.com.4sh.ui-kit.skipped` lists 78 entries with nothing to create: `calc()`
expressions, multi-value CSS shorthands, relative units (`em`, `ch`, `%`), duration /
easing / cursor / z-index, and internal plumbing.
easing / cursor / z-index / alignment, and internal plumbing.

## Two flags worth reading

Expand Down
92 changes: 88 additions & 4 deletions figma/component-vars.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
"Mode 1"
],
"counts": {
"tokens": 1418,
"alias": 1261,
"tokens": 1419,
"alias": 1262,
"literal": 157,
"skipped": 66,
"skipped": 78,
"derivedDescriptions": 223
},
"aliasTargets": [
Expand All @@ -24,6 +24,21 @@
"typography"
],
"skipped": [
{
"cssVar": "--ui-alert-align",
"component": "ui-alert",
"reason": "sans équivalent variable Figma (durée, easing, curseur, plan d’empilement, ratio)."
},
{
"cssVar": "--ui-alert-close-align",
"component": "ui-alert",
"reason": "sans équivalent variable Figma (durée, easing, curseur, plan d’empilement, ratio)."
},
{
"cssVar": "--ui-alert-icon-align",
"component": "ui-alert",
"reason": "sans équivalent variable Figma (durée, easing, curseur, plan d’empilement, ratio)."
},
{
"cssVar": "--ui-autocomplete-panel-max-width",
"component": "ui-autocomplete",
Expand All @@ -44,6 +59,16 @@
"component": "ui-avatar",
"reason": "sans équivalent variable Figma (durée, easing, curseur, plan d’empilement, ratio)."
},
{
"cssVar": "--ui-bottom-sheet-action-align",
"component": "ui-bottom-sheet",
"reason": "sans équivalent variable Figma (durée, easing, curseur, plan d’empilement, ratio)."
},
{
"cssVar": "--ui-bottom-sheet-header-align",
"component": "ui-bottom-sheet",
"reason": "sans équivalent variable Figma (durée, easing, curseur, plan d’empilement, ratio)."
},
{
"cssVar": "--ui-bottom-sheet-shadow",
"component": "ui-bottom-sheet",
Expand Down Expand Up @@ -89,6 +114,16 @@
"component": "ui-datepicker",
"reason": "`--shadow-default-md` n'est pas un token du pipeline : rien à aliaser."
},
{
"cssVar": "--ui-drawer-action-align",
"component": "ui-drawer",
"reason": "sans équivalent variable Figma (durée, easing, curseur, plan d’empilement, ratio)."
},
{
"cssVar": "--ui-drawer-header-align",
"component": "ui-drawer",
"reason": "sans équivalent variable Figma (durée, easing, curseur, plan d’empilement, ratio)."
},
{
"cssVar": "--ui-drawer-z-index",
"component": "ui-drawer",
Expand Down Expand Up @@ -219,6 +254,16 @@
"component": "ui-link",
"reason": "unité relative `em` : sa valeur dépend du contexte de rendu, une variable Figma ne peut pas la porter."
},
{
"cssVar": "--ui-modal-header-actions-align",
"component": "ui-modal",
"reason": "sans équivalent variable Figma (durée, easing, curseur, plan d’empilement, ratio)."
},
{
"cssVar": "--ui-modal-header-align",
"component": "ui-modal",
"reason": "sans équivalent variable Figma (durée, easing, curseur, plan d’empilement, ratio)."
},
{
"cssVar": "--ui-modal-z-index",
"component": "ui-modal",
Expand Down Expand Up @@ -349,6 +394,21 @@
"component": "ui-textarea",
"reason": "expression calc() : une variable Figma ne porte pas de calcul."
},
{
"cssVar": "--ui-toast-align",
"component": "ui-toast",
"reason": "sans équivalent variable Figma (durée, easing, curseur, plan d’empilement, ratio)."
},
{
"cssVar": "--ui-toast-close-align",
"component": "ui-toast",
"reason": "sans équivalent variable Figma (durée, easing, curseur, plan d’empilement, ratio)."
},
{
"cssVar": "--ui-toast-icon-align",
"component": "ui-toast",
"reason": "sans équivalent variable Figma (durée, easing, curseur, plan d’empilement, ratio)."
},
{
"cssVar": "--ui-toast-z-index",
"component": "ui-toast-container",
Expand Down Expand Up @@ -1002,7 +1062,7 @@
"padding-top": {
"$value": "{metrics.units.2xs}",
"$type": "dimension",
"$description": "Décalage vertical de l'icône, pour l'aligner sur la première ligne de texte.",
"$description": "Décalage vertical de l'icône, pour l'aligner sur la première ligne de texte ; à remettre à `0` en alignement centré.",
"$extensions": {
"com.figma": {
"resolvedType": "FLOAT",
Expand Down Expand Up @@ -30113,6 +30173,30 @@
}
}
},
"icon": {
"padding-top": {
"$value": "{metrics.units.2xs}",
"$type": "dimension",
"$description": "Décalage vertical de l'icône, pour l'aligner sur la première ligne de texte ; à remettre à `0` en alignement centré.",
"$extensions": {
"com.figma": {
"resolvedType": "FLOAT",
"scopes": [
"GAP"
],
"codeSyntax": {
"WEB": "var(--ui-toast-icon-padding-top)"
}
},
"com.4sh.ui-kit": {
"cssVar": "--ui-toast-icon-padding-top",
"component": "ui-toast",
"entryPoint": "@4sh/ui-kit/informative/ui-toast",
"descriptionSource": "scss"
}
}
}
},
"stack": {
"gap": {
"$value": "{metrics.units.sm}",
Expand Down
10 changes: 8 additions & 2 deletions projects/ui-kit/informative/ui-alert/src/lib/ui-alert.scss
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ $padding-x: var(--ui-alert-padding-x, var(--units-md)); /// Inset ho
$radius: var(--ui-alert-radius, var(--radius-default)); /// Rayon des coins.
$stroke-width: var(--ui-alert-stroke-width, var(--stroke-default)); /// Épaisseur de la bordure.

$icon-padding-top: var(--ui-alert-icon-padding-top, var(--units-2xs)); /// Décalage vertical de l'icône, pour l'aligner sur la première ligne de texte.
$align: var(--ui-alert-align, flex-start); /// Alignement vertical de la rangée (icône, contenu, fermeture) ; le mode titre seul reste centré.
$icon-align: var(--ui-alert-icon-align, auto); /// Alignement vertical de l'icône seule ; `auto` suit l'alignement de la rangée.
$close-align: var(--ui-alert-close-align, auto);/// Alignement vertical de la fermeture seule ; `auto` suit l'alignement de la rangée.

$icon-padding-top: var(--ui-alert-icon-padding-top, var(--units-2xs)); /// Décalage vertical de l'icône, pour l'aligner sur la première ligne de texte ; à remettre à `0` en alignement centré.
$content-gap: var(--ui-alert-content-gap, var(--units-2xs)); /// Espacement titre ↔ message.
$content-padding-right: var(--ui-alert-content-padding-right, var(--units-sm)); /// Réserve à droite du contenu, avant la fermeture.

Expand Down Expand Up @@ -62,7 +66,7 @@ $focus-ring-offset: var(--ui-alert-focus-ring-offset, #{utils.rem-calc(2)});
.ui-alert {
// --- Base ----------------------------------------------------------
display: flex;
align-items: flex-start;
align-items: $align;
gap: $gap;
box-sizing: border-box;
width: 100%;
Expand All @@ -80,6 +84,7 @@ $focus-ring-offset: var(--ui-alert-focus-ring-offset, #{utils.rem-calc(2)});
flex: 0 0 auto;
display: flex;
align-items: center;
align-self: $icon-align;
padding-top: $icon-padding-top;
line-height: 0;
}
Expand Down Expand Up @@ -112,6 +117,7 @@ $focus-ring-offset: var(--ui-alert-focus-ring-offset, #{utils.rem-calc(2)});
flex: 0 0 auto;
display: inline-flex;
align-items: center;
align-self: $close-align;
justify-content: center;
padding: 0;
border: 0;
Expand Down
34 changes: 34 additions & 0 deletions projects/ui-kit/informative/ui-alert/ui-alert.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,40 @@ Les erreurs de validation d'un formulaire s'affichent en sévérité `error`.
</tbody>
</table>

## Alignement vertical

La rangée `icône | contenu | fermeture` est calée en haut, parce que c'est le seul réglage
juste quand le texte passe sur plusieurs lignes : l'icône doit rester sur la première. Sur un
message court, la hauteur minimale laisse alors du vide sous le texte, et c'est là qu'un
projet veut centrer. Aucun réglage statique ne convient aux deux cas, d'où trois poignées, de
la plus large à la plus fine :

| Variable | Porte sur |
| --- | --- |
| `--ui-alert-align` | toute la rangée |
| `--ui-alert-icon-align` | l'icône seule (`auto` = suit la rangée) |
| `--ui-alert-close-align` | la fermeture seule (`auto` = suit la rangée) |

```css
/* tout centrer */
ui-alert {
--ui-alert-align: center;
--ui-alert-icon-padding-top: 0; /* le calage optique ne sert qu'en haut */
}

/* contenu centré, icône et fermeture posées sur la première ligne */
ui-alert {
--ui-alert-align: center;
--ui-alert-icon-align: flex-start;
--ui-alert-close-align: flex-start;
}
```

Le mode titre seul reste centré par construction : une seule ligne, rien à décaler. Les mêmes
poignées existent sur [`ui-toast`](?path=/docs/components-ui-informative-ui-toast--docs), et
sur les en-têtes de `ui-modal`, `ui-drawer` et `ui-bottom-sheet`.


## Theming

<ConfigTable of="ui-alert" />
12 changes: 10 additions & 2 deletions projects/ui-kit/informative/ui-toast/src/lib/ui-toast.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,19 @@
$levels: default, highlight, success, warning, error; /// Niveaux sémantiques générant les modifiers `._<niveau>`.
$sublevels: high, low; /// Intensités générant les modifiers `._<intensité>`.

$align: var(--ui-toast-align, flex-start); /// Alignement vertical de la rangée (icône, contenu, fermeture).
$icon-align: var(--ui-toast-icon-align, auto); /// Alignement vertical de l'icône seule ; `auto` suit l'alignement de la rangée.
$close-align: var(--ui-toast-close-align, auto); /// Alignement vertical de la fermeture seule ; `auto` suit l'alignement de la rangée.

$icon-padding-top: var(--ui-toast-icon-padding-top, var(--units-2xs)); /// Décalage vertical de l'icône, pour l'aligner sur la première ligne de texte ; à remettre à `0` en alignement centré.

// Reused structural constant (kit-wide focus ring). Local alias, never copied.
$focus-ring-width: var(--ui-toast-focus-ring-width, #{utils.$focus-ring-width}); /// Épaisseur de l'anneau de focus.

.ui-toast {
// --- Base ----------------------------------------------------------
display: inline-flex;
align-items: flex-start;
align-items: $align;
gap: var(--units-sm);
box-sizing: border-box;
width: auto;
Expand All @@ -45,8 +51,9 @@ $focus-ring-width: var(--ui-toast-focus-ring-width, #{utils.$focus-ring-width});
flex: 0 0 auto;
display: flex;
align-items: center;
align-self: $icon-align;
// Nudge the icon down so it lines up with the title cap-height.
padding-top: var(--units-2xs);
padding-top: $icon-padding-top;
line-height: 0;
}

Expand Down Expand Up @@ -80,6 +87,7 @@ $focus-ring-width: var(--ui-toast-focus-ring-width, #{utils.$focus-ring-width});
flex: 0 0 auto;
display: inline-flex;
align-items: center;
align-self: $close-align;
justify-content: center;
padding: 0;
border: 0;
Expand Down
20 changes: 20 additions & 0 deletions projects/ui-kit/informative/ui-toast/ui-toast.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,26 @@ respectés automatiquement.
</tbody>
</table>

## Alignement vertical

Même contrat que sur [`ui-alert`](?path=/docs/components-ui-informative-ui-alert--docs) : la
rangée `icône | contenu | fermeture` est calée en haut, ce qui est juste sur un texte qui
passe à la ligne et laisse du vide sur un texte court.

| Variable | Porte sur |
| --- | --- |
| `--ui-toast-align` | toute la rangée |
| `--ui-toast-icon-align` | l'icône seule (`auto` = suit la rangée) |
| `--ui-toast-close-align` | la fermeture seule (`auto` = suit la rangée) |

```css
ui-toast {
--ui-toast-align: center;
--ui-toast-icon-padding-top: 0; /* le calage optique ne sert qu'en haut */
}
```


## Theming

Constantes locales à `ui-toast-container.scss` (structurelles, jamais de couleur : les couleurs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ $safe-area: var(--ui-bottom-sheet-safe-area-offset, env(safe-area-inset-bottom,
$panel-padding: var(--ui-bottom-sheet-padding, var(--units-default)); /// Inset horizontal du panneau et inset haut du corps.
$panel-padding-bottom: var(--ui-bottom-sheet-padding-bottom, var(--units-lg)); /// Inset bas de la dernière zone du panneau.
$header-gap: var(--ui-bottom-sheet-header-gap, var(--units-sm)); /// Espacement entre le titre et le bouton de fermeture.
$header-align: var(--ui-bottom-sheet-header-align, flex-start); /// Alignement vertical de l'en-tête (titre, fermeture).
$action-align: var(--ui-bottom-sheet-action-align, auto); /// Alignement vertical de la fermeture seule ; `auto` suit l'alignement de l'en-tête.
$footer-gap: var(--ui-bottom-sheet-footer-gap, var(--units-default)); /// Espacement entre les actions du pied.
$footer-padding-top: var(--ui-bottom-sheet-footer-padding-top, var(--units-sm)); /// Inset haut du pied.
$action-size: var(--ui-bottom-sheet-action-size, #{utils.rem-calc(32)}); /// Taille de la cible tactile du bouton de fermeture.
Expand Down Expand Up @@ -225,7 +227,7 @@ $focus-ring-width: var(--ui-bottom-sheet-focus-ring-width, #{utils.$focus-ring-w
&-header {
flex: 0 0 auto;
display: flex;
align-items: flex-start;
align-items: $header-align;
gap: $header-gap;
padding-top: $grab-padding-y;
}
Expand All @@ -251,6 +253,7 @@ $focus-ring-width: var(--ui-bottom-sheet-focus-ring-width, #{utils.$focus-ring-w
flex: 0 0 auto;
display: inline-flex;
align-items: center;
align-self: $action-align;
justify-content: center;
box-sizing: border-box;
width: $action-size;
Expand Down
17 changes: 17 additions & 0 deletions projects/ui-kit/layout/ui-bottom-sheet/ui-bottom-sheet.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,23 @@ Trois écarts assumés, notés ici pour qu'ils ne passent pas pour des oublis :
</tbody>
</table>

## Alignement vertical de l'en-tête

L'en-tête (titre et bouton de fermeture) est calé en haut, ce qui est juste quand le titre passe sur deux lignes
et laisse du vide quand il tient sur une. Deux poignées plutôt qu'une surcharge globale :

| Variable | Porte sur |
| --- | --- |
| `--ui-bottom-sheet-header-align` | toute la rangée |
| `--ui-bottom-sheet-action-align` | la fermeture seule (`auto` = suit la rangée) |

```css
ui-bottom-sheet {
--ui-bottom-sheet-header-align: center;
}
```


## Theming

Variables locales en tête de `ui-bottom-sheet.scss`. Voir le
Expand Down
Loading
Loading