Field

.field e un câmp — etichetă, control, ajutor, eroare. .fieldset e colecția. Controlul în sine e documentat la componenta lui; aici e ce-l ține în pagină. Structura urmează documentația Field din shadcn.

Trei nume, o singură graniță — bordura controlului.
Input · .input e controlul: cutia în care scrii. Nu știe de etichetă, ajutor sau eroare.
Field · .field e tot ce e în afara bordurii: etichetă, ajutor, eroare, orientare. Agnostic la control.
Input group · .input-group e tot ce e în interiorul bordurii: iconiță, text, buton, scurtătură — sau eticheta însăși. Nu e o pagină, e același control cu ceva în el.
Se cuibăresc, nu concurează: .field > .input-group > .input. Împărțirea e a lui shadcn — Input e controlul, Field „combines labels, controls, and help text”, InputGroup „adds addons, buttons, and helper content to inputs”.

Cele patru straturi

.input          CONTROLUL — cutia în care scrii
  .input-group  ÎN interiorul bordurii: iconiță, text, buton, scurtătură
.field          CÂMPUL — ÎN AFARA bordurii: etichetă, ajutor, eroare
.fieldset       GRUPUL cu titlu   ·   .field-row  grupul pe orizontală
ÎntrebareaRăspunsul
Unde stă eticheta?În .field, ca .field-label. Niciodată ca addon — addon-ul e o bară, nu o etichetă.
Unde stă eroarea?Mesajul în .field-help.error; conturul pe control, prin .error.
Unde pun iconița?În .input-group. În .field ar fi lângă câmp, nu în el.
Îmi trebuie .field?Doar dacă ai etichetă, ajutor sau eroare. Căutarea din topbar n-are niciuna.

Markup canonic · components/field.json

sursa = JSON · generat de scripts/build-catalog.py
Date de facturare

Apar pe factură exact așa cum le scrii aici.

Numele din Registrul Comerțului.

Trimite factura pe emailCătre adresa din profilul clientului

Părțile

BonoCe eSpecificațieshadcn
.fieldUN câmp: etichetă + control + ajutorcoloană · gap 4Field
.field-labeleticheta câmpului, DEASUPRA lui12/16 · 500 · 0.04em · fog
sentence case · pad-left 16
FieldLabel
.field-helptextul de sub control12/16 · 400 · fog · pad-left 16FieldDescription
.field-help.erroracelași loc, mesaj de eroare--c-error-textFieldError
.field-contentcoloana de text a unui câmp orizontalcoloană · gap 2 · min-width 0
anulează pad-left pe label și help
FieldContent
.field-titletitlul unui câmp care nu e <label>alias al lui .label
15/22 · 400 · ink
FieldTitle
.fieldsetGRUPUL de câmpuri, cu titlucoloană · gap 18
fără contur, fără padding
FieldSet
.fieldset-legendtitlul grupului13/18 · 600 · ink · mb 2FieldLegend
.fieldset-helpdescrierea grupului13/18 · fog · ancorat sub legendFieldDescription
.field-rowcâmpuri înrudite pe același rândgrid egal · gap 12
.cols-2 · .cols-3 · .grow-last
FieldGroup orizontal
.separator.softlinia dintre două câmpuri din grup1px --c-rule-softFieldSeparator
.labeleticheta unui CONTROL, lângă el15/22 · 400 · inkLabel

Trei dintre ele se numeau „label" sau „field" în conversație — de acolo a apărut al șaselea, în aplicație. .field-label e sentence case: „Denumire firmă", nu „DENUMIRE FIRMĂ". Uppercase apare doar pe eticheta din interiorul bordurii (.input-group cu block-start).

Spațiere

Banda roz e distanța, la scară 1:1 — nu o notează, o arată.

vertical · în câmp și între câmpuri

.field — gap 4px

.field-label
4
.input
4
.field-help

.fieldset — gap 18px

.field
18
.field
orizontal · rând, câmp orizontal, addon

.field-row — gap 12px

.field
12
.field

.field.horizontal — gap 16px

.field-content
16
switch

.input-group — gap 8px, în bordură

svg
8
.input

Pe orizontală câmpurile stau mai aproape decât pe verticală — 12 față de 18. Cu același gap, un rând de două câmpuri s-ar citi ca două grupuri separate. Cei 16px de padding-left pe .field-label și .field-help aliniază textul cu interiorul inputului; într-un .field-content nu există input dedesubt, deci acolo sunt 0.

Orientare

Vertical e implicit. Orizontal e pentru controalele care își spun starea singure — switch, checkbox. Orientarea schimbă axa, nu vocabularul: eticheta trecută lângă control nu mai e .field-label, e .label.

vertical (implicit) · .field
Numele din Registrul Comerțului.
orizontal · .field.horizontal + .field-content
Notificări pe emailRezumat zilnic cu activitatea contului
responsive · .field.responsive — orizontal peste 1024px, vertical dedesubt (îngustează fereastra)
Auto-clasificare AIVox sortează automat documentele noi din SPV
Monedă implicităSe aplică la facturile noi
Nou în v8-dev. .field.horizontal, .field.responsive, .field-content și .field-title înlocuiesc rândurile scrise cu style inline — lista de setări din Switch avea același layout copiat de trei ori. De validat pe un ecran de setări real.

Ajutor, eroare, confirmare

Un singur slot sub control, trei sensuri. Un câmp nu are două locuri unde să scrie ceva.

.field-help · .field-help.error · .field-help.success
24 de caractere, fără spații.
IBAN invalid. Verifică numărul de caractere (24).
Validat în Registrul Comerțului.

Label-ul nu se înroșește: bordura, tintul și mesajul spun deja același lucru. Confirmarea se folosește doar când aduce informație, nu ca bifă pe fiecare câmp completat.

Care etichetă, la care control

Ce se schimbă de la un control la altul e unde stă eticheta — și de acolo, cum se numește.

ControlulEtichetaClasa
input, select, textareadeasupra, în afara controlului.field-label într-un .field
un singur checkbox sau switchlângă control, e propoziția lui.check-label într-un .check-item
grup de radio sau checkboxdeasupra grupului, dar nu e <label>.field-title + .radio-group
1 · control cu conținut — .field + .field-label
2 · un singur checkbox — .check-item, fără .field-label
3 · grup de opțiuni — .field + .field-title + .radio-group
Cum trimitem facturaSe poate schimba la fiecare emitere

Titlul grupului nu poate fi un <label>: un for="" ar alege una dintre opțiuni, deci titlul ar deveni clicabil pe prima. Opțiunile stau în .radio-group (gap 10px), nu direct în .field (gap 4px) — aia e distanța dintre etichetă și controlul ei, nu dintre două opțiuni.

Grupul · .fieldset

Un <fieldset> real cu <legend> real — cititorul de ecran anunță legenda la fiecare câmp din grup. Fără contur și fără padding: conturul îl dă cardul din jur.

.fieldset · .fieldset-legend · .fieldset-help
Adresa de livrare

Doar dacă diferă de adresa de facturare.

Maxim un nivel de imbricare. Un formular care cere al treilea nivel are nevoie de un pas în plus, nu de grupuri mai adânci — la fel peste ~8 câmpuri într-un grup.

Separator în grup

Când două câmpuri din același grup nu vorbesc despre același lucru: <hr class="separator soft">, direct copil de .fieldset. Gap-ul de 18px cade de ambele părți, deci linia stă centrată fără margini proprii. .separator tare separă secțiuni, nu câmpuri.

.fieldset > hr.separator.soft
Facturare

Facturare automată lunarÎn prima zi lucrătoare a lunii

Câmpuri înrudite pe un rând

Testul: dacă utilizatorul le citește ca o informație — perioada, data, suma — e un .field-row. Dacă nu, sunt două câmpuri într-un .fieldset.

.field-row.cols-2 — gap 12px · .cols-3 și .grow-last cad la două coloane sub 1024px
Redenumit în v8: rândul se numea .input-group. Numele a trecut la stratul de dedesubt — Input group, secțiune pe pagina Input — fiindcă asta înseamnă InputGroup în shadcn, iar rândul de câmpuri e FieldGroup. Fără alias: pe un nume reutilizat, un alias ar face chiar greșeala pe care redenumirea o repară.

De revizuit

De decis pe un formular real: dacă .fieldset merită contur propriu când e imbricat; cum arată un legend pe două rânduri; dacă 18px ține peste ~8 câmpuri; și dacă un câmp orizontal cu eroare ține mesajul în .field-content sau pe tot rândul.