Passer au contenu principal

ResponsiveFieldGroup

Implemented

Horizontal form fields that auto-stack on narrow viewports. Wraps each child in a min-w-0 flex slot so flex children can shrink below their intrinsic content width — fixes the 129-167% horizontal overflow on 375 px viewports.

Categorymolecules
Sourcepatterns/molecules/responsivefieldgroup.html
AI HintMobile-first form rows: stacks under the breakpoint, rows above it. Prefer over FormRow for anything that must survive 375px viewports (FormRow wraps but never stacks). RichTextEditor integration rule: single child only. asGroup + ariaLabel for named regions.

Rangée de champs de formulaire qui passe automatiquement en pile verticale sous le breakpoint configuré (sm = 640 px par défaut) et en rangée horizontale au-dessus. Chaque enfant est enveloppé dans un FieldWrapper `min-w-0 flex-1` — le contrat qui empêche le débordement horizontal (« overflow ») que produisait `flex flex-wrap` avec des enfants `min-width: 160px` sur les viewports de 375 px.

ResponsiveFieldGroup

Molecule — Form family (Family 3)

Mise en page mobile-first : `flex-col` sous le breakpoint, `{bp}:flex-row` au-dessus, écart sur l'échelle d'espacement DS (`gap-ep-*`). Le composant ne rend aucun texte — il est invariant par thème et n'a aucune surface i18n.

Ex. H2X 1L8

This component supports light and dark mode.

ResponsiveFieldGroup (asGroup)

Molecule — Form family (Family 3)

Forme de production : atomes portant leur propre label (Input, Select) passés directement, avec `asGroup` + `ariaLabel` pour exposer la région et `breakpoint="md"` pour empiler jusqu'à 768 px.

This component supports light and dark mode.

Props

Prop
Type
Default
Description
children*
React.ReactNode
—

Champs à disposer. Chaque enfant est enveloppé dans un FieldWrapper `min-w-0 flex-1` qui autorise le rétrécissement — c’est ce qui supprime le débordement horizontal.

breakpoint
"sm" | "md" | "lg" | "xl" | "2xl"
sm

Largeur de viewport minimale (préfixe Tailwind) à partir de laquelle le groupe passe de la pile (`flex-col`) à la rangée (`flex-row`). `sm` = 640 px.

gap
"none" | "ep-1" | "ep-2" | "ep-3" | "ep-4" | "ep-5" | "ep-6" | "ep-8"
ep-4

Écart entre les enfants, sur l’échelle d’espacement DS (utilitaires `gap-ep-*` → tokens `--ep-spacing-*`).

asGroup
boolean
false

Rend `<div role="group">` au lieu d’un `<div>` neutre — pour une région logique de formulaire (ex. « adresse de facturation »).

ariaLabel
string
—

Nom accessible du groupe quand `asGroup` est vrai (requis par WAI-ARIA 1.2). Ignéré silencieusement sans `asGroup`.

id
string
—

Transmis à l’élément racine — hooks de test et ancres de formulaire.

className
string
—

Classes additionnelles ajoutées à la racine. Le composant possède ses classes de mise en page ; inutile de les surcharger.

Props

Preview

ResponsiveFieldGroup

Prop
Type
Required
Default
Description
children
React.ReactNode
Required
—

The form fields — each child is wrapped in a min-w-0 FieldWrapper so flex children can actually shrink (RichTextEditor must be the SINGLE child: it owns its label/hint stack).

breakpoint
'sm' | 'md' | 'lg' | 'xl' | '2xl'
Optional
'sm' (640px)

Viewport width where the group flips from vertical stack (flex-col) to horizontal row (flex-row) — maps to a Tailwind prefix.

gap
'none' | 'ep-1'…'ep-6' | 'ep-8'
Optional
'ep-4'

Gap between children on the DS spacing token scale.

asGroup
boolean
Optional
false

Render <div role='group'> instead of a plain div — use when the row is one logical form region (e.g. 'billing address').

ariaLabel
string
Optional
— (required when asGroup)

Accessible label for the group — required by role='group' (WAI-ARIA 1.2); silently dropped when asGroup is false.

id
string
Optional
—

Forwarded to the root — form-level ids and testing hooks.

className
string
Optional
—

Extra classes appended to the root; the component owns its layout classes.

Quick use:<ResponsiveFieldGroup />

Accessibility

ARIA rolegroup (only when asGroup)

ARIA

1 rule

WCAG 1.3.1

role='group' renders only when asGroup=true, and then ariaLabel is required (dropped silently otherwise — pass both together)

Type

1 rule

NASA Rule 5

every child is wrapped in a min-w-0 slot — bare flex-wrap + min-width children is exactly what produced 129-167% overflow at 375px; do not bypass the wrapper

Usage

Import

tsxSnippet
import { ResponsiveFieldGroup } from "@epasslive/design-system"

Example 1

tsxSnippet
<ResponsiveFieldGroup breakpoint="md" gap="ep-4"><FormField label="City" /><FormField label="Postal code" /></ResponsiveFieldGroup>

Example 2

tsxSnippet
<ResponsiveFieldGroup asGroup ariaLabel="Billing address"><Input … /><Select … /></ResponsiveFieldGroup>

Anti-patterns

— Do not pass two children when hosting RichTextEditor — it must be the single child

— Do not pass ariaLabel without asGroup — it is silently dropped

Design System v4.1.0 | ePassLive