مجموعة الحقول
تسمّي مجموعة من عناصر التحكم تجيب عن سؤال واحد، من خانات اختيار أو مفاتيح تبديل أو حقول ينتمي بعضها إلى بعض: بتسمية تستطيع أن تقول إن المجموعة مطلوبة أو اختيارية، ووصف، وخطأ واحد للمجموعة، وترتّب عناصر التحكم في عمود أو في صف.
- الفئة
- الاختيار
- الرموز
comp.field-group- المستوى
- أساسي
- يُستخدم في
- Checkbox group, Radio group
- Web
tanrei-field-groupschedule - SwiftUI
TanreiFieldGroupradio_button_unchecked - Jetpack Compose
TanreiFieldGroupradio_button_unchecked - Flutter
TanreiFieldGroupradio_button_unchecked - React Native
FieldGroupradio_button_unchecked
مولَّد من docs/status/status.json, specs/field-group.spec.json
مجموعة من خانات الاختيار لها اسم ووصف وعلامة المطلوب
بعض الأسئلة يُجاب عنها بعدة عناصر تحكم: أيّ هذه، أو هذه الإعدادات، أو عنوان في خمسة حقول. ومجموعة الحقول تعطي تلك العناصر اسمًا واحدًا، وسطرًا يقول كيف يُجاب، وكلمة تقول هل تجب الإجابة، وسببًا واحدًا حين تُرفض الإجابة. فهي حقل عنصر التحكم فيه مجموعة.
المجموعة تؤطّر عناصر التحكم وترتّبها. لا تحدّد شيئًا، ولا تحمل قيمة، ولا تنقل تركيزًا، ولا تعالج مفتاحًا: فكل عنصر تحكم يحتفظ بما له.
على الويب هي <tanrei-field-group>. والمنصات الأخرى لم تنفّذها بعد.
<tanrei-field-group label="أرسلوا لي الإشعارات عبر" supporting-text="اختر كل ما ينطبق." required required-text="مطلوب"
error error-text="اختر طريقة واحدة على الأقل للتواصل معك.">
<tanrei-checkbox name="notify" value="email" label="البريد الإلكتروني"></tanrei-checkbox>
<tanrei-checkbox name="notify" value="text" label="رسالة نصية"></tanrei-checkbox>
<tanrei-checkbox name="notify" value="push" label="إشعار فوري"></tanrei-checkbox>
</tanrei-field-group>
<!-- حقول ينتمي بعضها إلى بعض. -->
<tanrei-field-group label="عنوان الشحن" spacing="fields">
<tanrei-text-field label="الشارع" required required-text="مطلوب"></tanrei-text-field>
<tanrei-text-field label="المدينة" required required-text="مطلوب"></tanrei-text-field>
</tanrei-field-group>
<script type="module">
import '@tanrei/web/components/field-group';
</script>import { Checkbox, FieldGroup } from '@tanrei/react';
<FieldGroup label="أرسلوا لي الإشعارات عبر" supportingText="اختر كل ما ينطبق." error={none} errorText="اختر طريقة واحدة على الأقل للتواصل معك.">
<Checkbox label="البريد الإلكتروني" checked={email} onChange={(event) => setEmail(event.detail.checked)} />
<Checkbox label="رسالة نصية" checked={text} onChange={(event) => setText(event.detail.checked)} />
</FieldGroup>خطأ للمجموعة، وترتيب في صف، ومفاتيح تبديل، وحقول ينتمي بعضها إلى بعض
البنية
| الجزء | الوصف |
|---|---|
1 label | Names the set (a legend on the web): above the controls, from the start edge, in the style of a field's label, and never cut. The requirement mark follows it. |
2 requirement-label · اختياري | After the label: the Tag component at its small size, drawn as every small tag is and never a control, saying the set is required or optional; or, for required, an asterisk after the label. |
3 supporting-text · اختياري | The description: a line under the label, before the controls, that says how to answer. It stays while the group is in error. |
4 controls | The controls of the set, in the order given, in a column or in a row that wraps: checkboxes or switches, each with its own label beside it, the radio buttons of one group while kind is radio-group, or fields (a radio group or a checkbox group among them is one member, as a field is). Each keeps its own tokens, states, keyboard, events and value. |
5 error-text · اختياري | The reason the set as a whole was refused, below the last control, where a field's error text is. |
الخصائص
| الخاصية | النوع | القيمة الافتراضية | الوصف |
|---|---|---|---|
label | string | "" | Names the set, visibly and to assistive technology: the question its controls answer ("Notify me by"). Required. |
labelHidden | boolean | false | Does not draw the label, which stays the accessible name of the group. For a set whose visible heading is elsewhere. |
supportingText | string | "" | The description: how to answer ("Choose all that apply"), drawn under the label and given to assistive technology as the group's description. |
errorText | string | "" | What is wrong with the set as a whole and how to put it right ("Choose at least one"), drawn below the controls while error is true. |
error | boolean | false | Puts the set in the error condition: the error text is drawn, and each selection control that has an error condition of its own (a checkbox, a radio button) is drawn in it. What an answer means is the product's to validate; the group never sets this itself. One control of a valid group may still be in error by itself. |
disabled | boolean | false | Disables every control of the set and draws the frame as disabled. |
required | boolean | false | What the form asks of the set: true exposes it as required and draws the required mark beside the label. It never validates: a missing answer is the product's to report with error. |
optional | boolean | false | Draws the optional tag after the label and adds optionalText to the group's description, because assistive technology has no state for it. Ignored while required is true: a set is never both. |
requiredMark | auto | tag | asterisk | none | "auto" | How this set shows that it is required: tag is a small filled Tag with requiredText, asterisk is "*" after the label, none draws nothing and keeps the semantics. Auto takes comp.field-group.requirement.mark, which follows sys.behavior.requirement-mark, the system's one answer. Ignored unless required is true. |
requiredText | string | "" | The text of the required tag, in the product's language ("Required", "必須"). The product's: Tanrei has no word for it. Empty reads the product's words; with neither, FGR-24 says what is drawn. |
optionalText | string | "" | The text of the optional tag, in the product's language ("Optional", "任意"); also read to assistive technology as part of the description. The product's: Tanrei has no word for it. Empty reads the product's words. |
orientation | vertical | horizontal | "vertical" | vertical stacks the controls in one column, the default and the form to prefer: every label starts on one edge and is read down. horizontal lays them out in a row that wraps, for two or three short options or a row of fields. |
spacing | controls | fields | "controls" | What the set holds, which decides the distance between its members. controls: checkboxes or switches, a touch target apart. fields: text fields and other fields that belong together (an address, a date in parts), the distance a form keeps between two fields. A design system may add values. |
kind | group | radio-group | "group" | What the set is to assistive technology. group: a named group of controls that each answer for themselves. radio-group: the radio group of the radio buttons it holds, which is required and invalid as a whole and says its orientation. It changes what is exposed and nothing that is drawn, and the field group still holds no value: the radio buttons keep their selection, their arrow keys and their tab stop, which their own group gives them — the Radio group they stand in, or their name. The Radio group sets it; a product sets it where it writes that set by hand. |
العناصر
أنواع العناصر التي يكررها المكوّن. يسرد كل نموذج اختبار عناصره بالترتيب، وتسمّي كل منصة كل نوع بأسلوبها.
checkbox
A Checkbox of the set: the checkbox component with its own label, placed and spaced by the group, put in its error condition and disabled with the group, otherwise drawn and behaving as it does anywhere.
| الخاصية | النوع | القيمة الافتراضية | الوصف |
|---|---|---|---|
checked | boolean | false | Whether it is on, as the Checkbox's checked. |
label | string | "" | Its own label, as the Checkbox's label. |
disabled | boolean | false | As the Checkbox's disabled: one control of an enabled group may be disabled by itself. |
indeterminate | boolean | false | As the Checkbox's indeterminate: a parent checkbox written by hand over a set that is partly checked. |
| المواصفة | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
|---|---|---|---|---|---|
| العنصر | tanrei-checkbox | TanreiCheckbox | TanreiCheckbox | TanreiCheckbox | Checkbox |
checked · الخاصية | checked | isOn | checked | value | value |
label · الخاصية | label | title | label | label | label |
disabled · الخاصية | disabled | disabled | enabled | onChanged | disabled |
indeterminate · الخاصية | indeterminate | isIndeterminate | state | tristate | indeterminate |
switch
A Switch of the set: the switch component with its own label, placed, spaced and disabled by the group.
| الخاصية | النوع | القيمة الافتراضية | الوصف |
|---|---|---|---|
checked | boolean | false | Whether it is on, as the Switch's checked. |
label | string | "" | Its own label, as the Switch's label. |
disabled | boolean | false | As the Switch's disabled. |
| المواصفة | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
|---|---|---|---|---|---|
| العنصر | tanrei-switch | TanreiSwitch | TanreiSwitch | TanreiSwitch | Switch |
checked · الخاصية | checked | isOn | checked | value | value |
label · الخاصية | label | title | label | label | label |
disabled · الخاصية | disabled | disabled | enabled | onChanged | disabled |
text-field
A Text field of the set, with its own label, help and error: the group places it, spaces it as a field and disables it, and leaves its error to it.
| الخاصية | النوع | القيمة الافتراضية | الوصف |
|---|---|---|---|
label | string | "" | Its own label, as the Text field's label. |
value | string | "" | Its value, as the Text field's value. |
supportingText | string | "" | Its own help, as the Text field's supportingText. |
required | boolean | false | As the Text field's required. |
optional | boolean | false | As the Text field's optional. |
requiredText | string | "" | The Text field's requiredText: the words of its requirement tag, the product's. |
optionalText | string | "" | The Text field's optionalText: the words of its requirement tag, the product's. |
| المواصفة | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
|---|---|---|---|---|---|
| العنصر | tanrei-text-field | TanreiTextField | TanreiTextField | TanreiTextField | TextField |
label · الخاصية | label | label | label | labelText | label |
value · الخاصية | value | text | value | controller | value |
supportingText · الخاصية | supportingText | supportingText | supportingText | helperText | supportingText |
required · الخاصية | required | isRequired | required | required | required |
optional · الخاصية | optional | isOptional | optional | optional | optional |
requiredText · الخاصية | requiredText | requiredText | requiredText | requiredText | requiredText |
optionalText · الخاصية | optionalText | optionalText | optionalText | optionalText | optionalText |
radio-button
A Radio button of the set, while kind is radio-group: the radio button component with its own label, placed, spaced and disabled by the group. Its selection, its arrow keys, its tab stop and its position stay its own group's — the Radio group it stands in, or its name.
| الخاصية | النوع | القيمة الافتراضية | الوصف |
|---|---|---|---|
checked | boolean | false | Whether it is the chosen one, as the Radio button's checked. |
value | string | "" | What it stands for, as the Radio button's value. |
name | string | "" | The group it belongs to, as the Radio button's name. Every radio button of one field group carries one name; inside a Radio group it carries none. |
label | string | "" | Its own label, as the Radio button's label. |
disabled | boolean | false | As the Radio button's disabled: one option of an enabled group may be disabled by itself. |
| المواصفة | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
|---|---|---|---|---|---|
| العنصر | tanrei-radio-button | TanreiRadioButton | TanreiRadioButton | TanreiRadioButton | RadioButton |
checked · الخاصية | checked | selection | selected | groupValue | selected |
value · الخاصية | value | value | onClick | value | value |
name · الخاصية | name | TanreiRadioGroup | selectableGroup | TanreiRadioGroup | RadioGroup |
label · الخاصية | label | title | label | label | label |
disabled · الخاصية | disabled | disabled | enabled | enabled | disabled |
الحالات
السلوك
متطلبات بصيغة EARS. يُختبر تنفيذ كل منصة مقابل هذه المعرّفات. يُعرض نص المتطلبات كما ورد في ملف المواصفة، بالإنجليزية.
| المعرّف | المتطلب |
|---|---|
FGR-1 | THE field group SHALL lay out, from top to bottom and from its start edge: its label row (FGR-2), its description (FGR-7) comp.field-group.supporting-text.gap below the last line of the label row, its controls (FGR-3, FGR-13) comp.field-group.label.gap below whichever of the two is drawn last, and its error text (FGR-8) comp.field-group.error-text.gap below the last control. It SHALL be as wide as its layout gives it and as tall as its rows and its controls together, SHALL draw no container, edge, fill or elevation of its own, SHALL add no padding around its rows, and SHALL place each control by the control's own bounds: it SHALL NOT shift, restyle or change the behaviour of a control. |
FGR-2 | WHILE label is not empty and labelHidden is false THE field group SHALL draw label above its controls, from the group's start edge, in comp.field-group.label.typescale and comp.field-group.standard.label.color (comp.field-group.standard.error.label.color WHILE error is true). The label SHALL wrap onto as many lines as it needs, and SHALL never be cut with an ellipsis or drawn over a control, because text enlarged to 200% must lose no content. WHILE labelHidden is true or label is empty THE field group SHALL draw neither the label row nor a gap below it, and SHALL draw no requirement mark (FGR-6). |
FGR-3 | WHILE orientation is vertical THE field group SHALL lay out its controls in one column in the order given, each from the group's start edge and given the group's whole width to lay itself out in — a field fills it; a checkbox, a radio button or a switch takes what its mark and its label need and wraps its label inside it — comp.field-group.gap.controls apart WHILE spacing is controls and comp.field-group.gap.fields apart WHILE spacing is fields. |
FGR-4 | THE field group SHALL take from required and optional what the form asks of the set: WHILE required is true it draws the required mark (FGR-5, FGR-6) and exposes the requirement (FGR-10, FGR-11); WHILE optional is true it draws the optional tag (FGR-5) and adds optionalText to the group's description (FGR-11), because assistive technology has no state for it; WHILE both are false it says nothing and draws nothing. THE field group SHALL NOT validate because of required: it SHALL NOT set the error condition for a missing answer or show an error text of its own; what a missing answer means is the product's to say with error and errorText. WHILE disabled is true THE field group SHALL keep its mark: an asterisk drawn from the group's disabled tokens (FGR-14), a requirement tag drawn as a tag inside something disabled (FGR-5, TAG-21). |
FGR-5 | WHILE the label is drawn and optional is true, or required is true and the required mark is tag (FGR-6), THE field group SHALL draw after the label's text, comp.field-group.requirement.gap from it and centred on the label's last line, a requirement tag: the Tag component, drawn as every tag is — size small, variant filled for required and tonal for optional, status default, no glyph and no dot, its label requiredText or optionalText on one line (TAG-1, TAG-2, TAG-5) — from the Tag's own tokens (comp.tag.container.height.small, comp.tag.label.typescale.small, comp.tag.filled.container.color, comp.tag.tonal.container.color and the others those sentences name). THE field group SHALL have no token for the requirement tag's fill, lettering, text style, paddings or corners and SHALL set none of the Tag's for it, so that a design system or a product that restyles its small tags restyles the requirement tag with them and nothing restyles the requirement tag alone. THE field group SHALL draw the requirement tag the same at rest and WHILE error is true, because a tag has no states (TAG-9) and what the form asks has not changed; WHILE disabled is true THE field group SHALL have it drawn as a tag inside something disabled (TAG-21), from the Tag's own disabled tokens, so that it fades with the label it follows. The requirement tag is text, never a control: it SHALL take no focus and no hover, focus or press answer of its own (FGR-12). It SHALL NOT make the label's row taller: where it is taller than the label's line it SHALL reach equally above and below that line. WHEN the label and the requirement tag do not fit on one line THE field group SHALL wrap the label (FGR-2) and move the tag whole to a line of its own after the label's last line, never cutting or splitting it. WHILE requiredText or optionalText is empty THE field group SHALL NOT draw the tag of that kind and in debug builds SHALL report it. THE field group SHALL keep both tags from assistive technology as drawn parts: what they say reaches it as FGR-10 and FGR-11 say. |
FGR-6 | WHILE required is true and the label is drawn THE field group SHALL draw the required mark that requiredMark names — tag (FGR-5), asterisk or none — and WHILE requiredMark is auto, the one comp.field-group.requirement.mark names: that token follows sys.behavior.requirement-mark, the design system's one answer for every field and every set of controls, unless a layer gives comp.field-group.requirement.mark a value of its own. As asterisk it SHALL draw the character "*" after the label's text, comp.field-group.requirement.asterisk-gap from it, in the label's text style, in comp.field-group.standard.required-asterisk.color (comp.field-group.standard.error.required-asterisk.color WHILE error is true), and SHALL keep it from assistive technology; as none it SHALL draw no mark. Whichever mark is drawn, and WHILE the label is not drawn, THE field group SHALL still expose the requirement (FGR-10, FGR-11). |
FGR-7 | WHILE supportingText is not empty THE field group SHALL draw it below the label row — at the group's top WHILE the label is not drawn — and above the controls, from the start edge, in comp.field-group.supporting-text.typescale and comp.field-group.standard.supporting-text.color (comp.field-group.standard.error.supporting-text.color WHILE error is true), wrapping onto as many lines as it needs and never cut. It SHALL keep its place and its words WHILE error is true, because it says how to answer; WHILE supportingText is empty THE field group SHALL draw neither the row nor its gap. |
FGR-8 | WHILE error is true THE field group SHALL draw errorText, WHILE it is not empty, in a row below its last control, from the start edge, in comp.field-group.supporting-text.typescale and comp.field-group.standard.error-text.color, wrapping and never cut; SHALL draw its label, its asterisk and its description from the error parts of its tokens (FGR-2, FGR-6, FGR-7); and SHALL put each selection control it holds in that control's own error condition where the control has one (a checkbox's error, CHK-4; a radio button's error form, RAD-26), so that the controls themselves are marked and not only the text. A control with no error condition (a switch) SHALL stay as it is drawn, and a control that reports its own errors in words (a text field, a field) SHALL keep the error the product gave it. WHILE error is false THE field group SHALL draw no error row and keep no room for it, and SHALL leave each control the error condition the product gave it: one control of a valid group may be in error by itself. THE field group SHALL never set error itself. |
FGR-9 | WHEN error becomes true, or errorText changes while error is true, and focus is inside the field group THE field group SHALL have assistive technology announce errorText once, politely; an error set while focus is elsewhere SHALL be read as part of the group's description when focus next enters the group (FGR-11). THE field group SHALL NOT move focus because of an error, and SHALL announce no other change of its texts. |
FGR-10 | THE field group SHALL expose itself to assistive technology as a group that contains its controls and is named by label, whether or not the label is drawn. WHILE kind is radio-group it SHALL be exposed as a radio group in that group's place, with a radio group's states (FGR-25). WHILE kind is group the group has neither a required nor an invalid state: each checkbox the field group put in its error condition (FGR-8) is exposed as invalid by that checkbox, and the requirement is given in words (FGR-11). WHILE label is empty THE field group SHALL still render and in debug builds report that the set has no accessible name. |
FGR-11 | THE field group SHALL make these the description of the group, in this order: supportingText; errorText WHILE error is true; requiredText WHILE required is true and kind is group, because a group has no required state to carry it and a radio group has one; optionalText WHILE optional is true. WHILE error is true it SHALL also make errorText part of the description of each control it put in its error condition (FGR-8) that is exposed as invalid by itself (a checkbox), after any description the control has of its own, so that a control exposed as invalid says why; a radio button in its error form SHALL be given neither the state nor the words, because its radio group carries both (FGR-25, RAD-26). WHEN one of these texts changes THE field group SHALL expose the new text at once. The requirement tag and the asterisk SHALL NOT be exposed as drawn parts. |
FGR-12 | THE field group SHALL NOT answer a press: a press on its label, its requirement mark, its description or its error text SHALL do nothing, and SHALL NOT move focus, because a set has no one control to receive it. THE field group SHALL add no stop to the focus order and handle no key: Tab reaches its controls as it would outside the group, and each control's keys are that control's. |
FGR-13 | WHILE orientation is horizontal THE field group SHALL lay out its controls in a row from the start edge in the order given, comp.field-group.gap-inline apart, their first lines aligned — each selection control as wide as its mark and its label need WHILE spacing is controls; each field given an equal share of the row, never less than comp.field-group.field.min-width nor than its content needs, WHILE spacing is fields, the fields aligned at their tops so that their labels start on one line. WHEN the controls do not fit in one row THE field group SHALL wrap the row onto further lines, comp.field-group.gap.controls apart WHILE spacing is controls and comp.field-group.gap.fields apart WHILE spacing is fields, and SHALL NOT cut, scroll or narrow a control below what its content needs; a control wider than the group SHALL take a line of its own and wrap its own label. |
FGR-14 | WHILE disabled is true THE field group SHALL draw its label, its asterisk, its description and its error text from its disabled tokens and its requirement tag as a tag inside something disabled (FGR-5, TAG-21), SHALL make every control it holds disabled as that control's own disabled does — not focusable, not operable, exposed as disabled — and SHALL expose the group as disabled where the platform has that state for a group; WHILE disabled is false THE field group SHALL NOT enable a control the product disabled itself. A disabled group SHALL keep its texts readable by assistive technology. |
FGR-15 | IF the field group holds radio buttons WHILE kind is group THEN THE field group SHALL frame them as it frames any control and SHALL add nothing that a set of radio buttons needs — no value, no required or invalid state, no radio group for assistive technology — and in debug builds SHALL report that a set of radio buttons is a radio group (RGP-1), or, written by hand, a field group whose kind is radio-group (FGR-25). WHERE a control it holds is a radio group or a checkbox group THE field group SHALL treat it as one member, as it treats a field group inside it (FGR-20): place and space it as a field, pass it disabled (FGR-14), and pass it neither its error nor its requirement. THE field group SHALL select nothing, hold no value, move no focus and emit no event. |
FGR-16 | WHILE the text size is enlarged THE field group SHALL grow with its texts: the label, the description and the error text wrap and never clip, the requirement tag grows with its text and keeps its paddings, a horizontal row wraps (FGR-13), and the rows keep their order and their gaps; at 200% no text SHALL be lost, lie over another part or need scrolling in two directions. |
FGR-17 | WHERE the platform draws with a person's own forced colors (the web's forced-colors mode, and a platform's equivalent where it has one) THE field group SHALL draw its label, its asterisk, its description and its error text in the platform's text color and its requirement tag as a tag is drawn there (an edge and a label in the text color, TAG-14), and SHALL rely on no color of its own to show an error: the error is carried by the words of errorText, by the invalid state (FGR-10) and by each control's own error condition. |
FGR-18 | WHERE the layout direction is right-to-left THE field group SHALL mirror its layout: the label row, the description, the controls and the error text start at the right edge, the requirement mark stands at the left of the label, and a horizontal row runs from right to left, the first control at the right. A column keeps its order from top to bottom in either direction. |
FGR-19 | THE field group SHALL take its layout direction from where it is used — the direction of the nearest ancestor that sets one, and the platform's own where none does — and SHALL have no direction setting of its own; WHEN that direction changes while the field group is shown THE field group SHALL draw itself for the new direction at once, without a motion of its own, keeping its controls, with their values, their selection and their focus. |
FGR-20 | IF the field group holds no control THE field group SHALL draw its rows without one and in debug builds report it. WHERE a control it holds is itself a field group THE field group SHALL treat it as one member: place and space it as a field, expose it as a group inside the group, pass it disabled (FGR-14), and pass it nothing else — neither its error nor its requirement. |
FGR-21 | THE field group SHALL lay out its label, its description, its error text and the text of its requirement tag as text of its own direction, isolated from the text around it: each takes the base direction of its first strong character, or the layout direction where it has none, so that a left-to-right word, a number with its sign or unit, a telephone number and an address keep their own order in a right-to-left layout and reorder nothing beside them; THE field group SHALL still place each and align its lines by the layout direction, not by the text's own. |
FGR-22 | WHEN requiredMark, orientation or kind names a value it does not know THE field group SHALL render with that prop's default (auto, vertical, group); WHEN spacing names a value that the active design system does not have THE field group SHALL render with the default value's tokens; and in debug builds THE field group SHALL report the unknown value. |
FGR-23 | THE field group SHALL leave its controls what they are: each keeps its own tokens, states, keyboard, events, value and place in a form, and THE field group SHALL emit no event, hold no value and take no part in form submission. WHEN a control is added, removed or moved while the group is shown THE field group SHALL lay out its controls again at once, without a motion, give the error condition and the disabled state it holds (FGR-8, FGR-14) to a control that came, take back from one that left everything it gave it, and leave focus on the control that has it. |
FGR-24 | THE field group SHALL have no words of its own: it SHALL take requiredText and optionalText from the instance's prop and, WHILE that is empty, from the product's words of the same name — the words a product sets once for all its components — and from nowhere else. IF neither gives requiredText WHILE required is true THE field group SHALL draw the asterisk of FGR-6 in the tag's place WHILE the required mark is tag, so that the requirement is still shown without a word, SHALL say nothing of the requirement to assistive technology WHILE kind is group, because a group has no required state and FGR-11 has no words to give it, whichever mark is drawn — WHILE kind is radio-group the required state says it without a word (FGR-25) — and in debug builds SHALL report the missing words once. IF neither gives optionalText WHILE optional is true THE field group SHALL draw no tag, SHALL add nothing to the description for it, and in debug builds SHALL report the missing words once. |
FGR-25 | WHILE kind is radio-group THE field group SHALL be exposed to assistive technology as one radio group in the place of the group of FGR-10 — never a radio group inside a group, nor a group inside a radio group — that contains its radio buttons: named by label, whether or not the label is drawn; required WHILE required is true; invalid WHILE error is true; disabled WHILE disabled is true (FGR-14); saying its orientation where the platform's radio group has one; and described as FGR-11 says, without requiredText, because the required state carries it. It SHALL change nothing that is drawn: its rows, its tokens, its measures and its layout are those of the same field group whose kind is group (FGR-1 to FGR-8, FGR-13). It SHALL hold the radio buttons of one group and no other control, and in debug builds SHALL report another control, radio buttons of more than one group, and a spacing other than controls. The radio buttons SHALL keep what their own group gives them — exclusion, the arrow keys, the single tab stop and each one's position in the set (RAD-3, RAD-4, RAD-5, RAD-16), from the radio group they stand in (RGP-3 to RGP-6) or, written by hand, from their name (RAD-25) — and THE field group SHALL still select nothing, hold no value, move no focus, handle no key and emit no event (FGR-12, FGR-15). WHERE the platform forms a radio group with a container of its own THE field group SHALL be the frame of that container and SHALL NOT expose a second group around it. |
FGR-26 | IF required and optional are both true THEN THE field group SHALL behave as WHILE required alone is true — it draws the required mark and no optional tag, and says no optionalText — and in debug builds SHALL report that optional is ignored, because a set is never both required and optional. |
FGR-27 | WHERE the platform has ARIA attributes (the web), WHEN the product sets an aria- attribute on the host, by the attribute or by the ARIA property that reflects it, THE field group SHALL move it to the data-aria- attribute of the same name, so that the host is no second node with its name, description or state, and SHALL expose it on the element that carries its role, its group (its radio group WHILE kind is radio-group) — an id reference by the elements it names in the host's tree or a tree around it, a description after its own — except those the field group owns (aria-label, aria-labelledby, aria-disabled, aria-required, aria-invalid, aria-errormessage), which it SHALL move and not expose: its name is label (FGR-10), its disabled, required and invalid states are its props (FGR-14, FGR-25) and its error message is errorText. WHEN the product removes the aria- attribute or its data-aria- twin, or sets the ARIA property that reflects it (ariaLabel, ariaDescribedByElements…) to null, THE field group SHALL take it off that element. WHEN the product sets an aria- attribute the field group owns THE field group SHALL report it in debug builds. |
مطابقة الأسماء بين المنصات
التكافؤ لا يعني واجهات برمجية متطابقة. تعبّر كل منصة عن العقد نفسه بأسلوبها.
| المواصفة | Web | SwiftUI | Jetpack Compose | Flutter | React Native |
|---|---|---|---|---|---|
| المكوّن | tanrei-field-group | TanreiFieldGroup | TanreiFieldGroup | TanreiFieldGroup | FieldGroup |
label · الخاصية | label | label | label | labelText | label |
labelHidden · الخاصية | labelHidden | labelsHidden | labelHidden | labelHidden | labelHidden |
supportingText · الخاصية | supportingText | supportingText | supportingText | helperText | supportingText |
errorText · الخاصية | errorText | errorText | errorText | errorText | errorText |
error · الخاصية | error | error | isError | isError | error |
disabled · الخاصية | disabled | disabled | enabled | enabled | disabled |
required · الخاصية | required | isRequired | required | required | required |
optional · الخاصية | optional | isOptional | optional | optional | optional |
requiredMark · الخاصية | requiredMark | requiredMark | requiredMark | requiredMark | requiredMark |
requiredText · الخاصية | requiredText | requiredText | requiredText | requiredText | requiredText |
optionalText · الخاصية | optionalText | optionalText | optionalText | optionalText | optionalText |
orientation · الخاصية | orientation | orientation | orientation | orientation | orientation |
spacing · الخاصية | spacing | spacing | spacing | spacing | spacing |
kind · الخاصية | kind | kind | kind | kind | kind |
| ملاحظات | <tanrei-field-group label="Notify me by"><tanrei-checkbox label="Email"></tanrei-checkbox>…</tanrei-field-group>: the controls are the elements of the default slot. They stay in the product's light DOM, so each keeps its place in a <form>, its name and value and its events; the group is not form-associated and holds no value. The shadow root holds a <fieldset> with a <legend> around the slot — the accessibility tree is built from the flattened tree, so the slotted controls are inside the group it names; every id it refers to is in the same shadow root. The description and the error text are referenced by aria-describedby on the fieldset, with visually hidden text for requiredText or optionalText where FGR-11 asks for them; labelHidden hides the legend visually and keeps it as the name. A disabled attribute on a fieldset in a shadow root does not reach slotted controls, so the group gives disabled, the error condition and the error text to each control itself: a Tanrei control asks for them with the composed tanrei-field-connect event a field answers, and any other element receives disabled, aria-invalid and aria-description; the group removes exactly what it set when an element leaves the slot (slotchange, FGR-23). The announcement of FGR-9 is a visually hidden aria-live="polite" element in the shadow root, written only while :focus-within holds. The controls are laid out by a flex container with gap, flex-direction by orientation and flex-wrap: wrap in a row. Attributes are kebab-case: label-hidden, supporting-text, error-text, required-mark, required-text, optional-text. The requirement tag is a <tanrei-tag size="small">, filled or tonal, with nothing set on it: it reads the Tag's tokens as every tag where the group stands does. The host is display: block. Words: the element has no words of its own. required-text and optional-text left empty read the product's words, set once with setWords() from @tanrei/web; the element draws again when they change. While kind="radio-group" the element that is the group — the same fieldset, with its legend — carries role="radiogroup", aria-labelledby the legend (which stays in the tree while label-hidden), aria-required while required, aria-invalid while error, and aria-orientation as orientation says; the hidden text for requiredText is left out of aria-describedby. The states are attributes on that element and not ElementInternals, which the accessibility checks cannot see. Nothing else in the shadow root differs, so the two kinds are the same picture; whether an engine takes the role on a fieldset, or the build puts a div in its place for this kind, is held by the test that reads one radio group in the accessibility tree in three engines. kind is reflected. The radio buttons are slotted as any control: those of a tanrei-radio-group around the field group reach it through that element's slot, and those a product writes by hand carry one name (RAD-25). A tanrei-radio-button asks the group as a checkbox does and says that it draws an error condition; while error the group gives it invalid and nothing else — no description — and the radio button draws its error form and writes no aria-invalid (FGR-8, FGR-11, RAD-26). The radio group's aria-invalid stays on the fieldset. The tag's element carries no custom property and is centred on the label's line without its height being read; required-mark takes tag; and --tanrei-comp-field-group-requirement-mark is var(--tanrei-sys-behavior-requirement-mark) until a layer sets it. | TanreiFieldGroup("Notify me by", supportingText:, errorText:, error:, required:, optional:, orientation:, spacing:) { TanreiCheckbox(…) … }. labelHidden follows the .labelsHidden() environment and disabled follows .disabled(_:), which disables the content. The content is laid out by a custom Layout (a column, or a row that wraps); the container is .accessibilityElement(children: .contain) with the label and the description as its label and hint, and the error condition reaches the controls through the environment (\.tanreiField). The product's words are read from the \.tanreiWords environment value. kind: .radioGroup makes the same container the radio group of the TanreiRadioButtons in it: iOS has no radio group trait, so the container keeps .accessibilityElement(children: .contain) with the label and the description, and required and invalid are added to its hint in words (FGR-25). Not built on this platform yet: in error it also puts each TanreiRadioButton it holds in its error form (FGR-8, RAD-26). Not built on this platform yet: the requirement tag as this platform's Tag at its small size with nothing of the field group's set on it (FGR-5); generated tokens with none of the field group's values for it and with the system's choice of mark, which the field group's own token follows (FGR-6); the first mark named tag. | TanreiFieldGroup(label = "Notify me by", supportingText = …, isError = …, required = …, optional = …, orientation = …, spacing = …) { TanreiCheckbox(…) … }. enabled is the inverse flag and reaches the content through LocalTanreiFieldState, with isError and the error text. A Column or a FlowRow; the container sets semantics { contentDescription; stateDescription } without merging its descendants. The product's words are read from LocalTanreiWords. kind = TanreiFieldGroupKind.RadioGroup applies Modifier.selectableGroup() to the container and adds the error to its semantics (FGR-25); the bare TanreiRadioButton(selected, onClick) is what stands in it one level down. Not built on this platform yet: in error it also puts each TanreiRadioButton it holds in its error form (FGR-8, RAD-26). Not built on this platform yet: the requirement tag as this platform's Tag at its small size with nothing of the field group's set on it (FGR-5); generated tokens with none of the field group's values for it and with the system's choice of mark, which the field group's own token follows (FGR-6); the first mark named tag. | TanreiFieldGroup(labelText: 'Notify me by', helperText: …, errorText: …, isError: …, required: …, optional: …, orientation: …, spacing: …, children: […]). enabled is the inverse flag. A Column or a Wrap; a Semantics(container: true, label:, hint:) node around the children, and an inherited TanreiFieldScope that gives the children the error condition and the disabled state. The product's words are read from the TanreiWords inherited widget, which the app fills from its own localizations. kind: TanreiFieldGroupKind.radioGroup makes the Semantics node the radio group of the radio buttons in it (FGR-25). Not built on this platform yet: in error it also puts each TanreiRadioButton it holds in its error form (FGR-8, RAD-26). Not built on this platform yet: the requirement tag as this platform's Tag at its small size with nothing of the field group's set on it (FGR-5); generated tokens with none of the field group's values for it and with the system's choice of mark, which the field group's own token follows (FGR-6); the first mark named tag. | <FieldGroup label="Notify me by" supportingText="…">{children}</FieldGroup>. A View with no role (React Native has no group role on iOS; the label is read as a header before the controls), accessibilityLabel and accessibilityHint; the children receive the error condition and the disabled state through FieldContext. A column, or a row with flexWrap. Follows the app's direction where an ancestor's is not known. The product's words are read from the TanreiWordsProvider context. kind="radio-group" gives the View accessibilityRole="radiogroup"; required and invalid are said in the hint, because React Native has neither state for a group (FGR-25). Not built on this platform yet: in error it also puts each RadioButton it holds in its error form (FGR-8, RAD-26). Not built on this platform yet: the requirement tag as this platform's Tag at its small size with nothing of the field group's set on it (FGR-5); generated tokens with none of the field group's values for it and with the system's choice of mark, which the field group's own token follows (FGR-6); the first mark named tag. |
الرموز
| الرمز | يشير إلى | القيمة المحلولة (فاتح) |
|---|---|---|
--tanrei-comp-field-group-error-text-gap | sys.space.space50 | 4px |
--tanrei-comp-field-group-field-min-width | — | 144px |
--tanrei-comp-field-group-gap-inline | sys.space.space200 | 16px |
--tanrei-comp-field-group-gap-controls | sys.space.space100 | 8px |
--tanrei-comp-field-group-gap-fields | sys.space.space300 | 24px |
--tanrei-comp-field-group-label-gap | sys.space.space100 | 8px |
--tanrei-comp-field-group-requirement-asterisk-gap | sys.space.space25 | 2px |
--tanrei-comp-field-group-requirement-gap | sys.space.space100 | 8px |
--tanrei-comp-field-group-requirement-mark | sys.behavior.requirement-mark | 0 |
--tanrei-comp-field-group-standard-disabled-error-text-color | — | |
--tanrei-comp-field-group-standard-disabled-error-label-color | — | |
--tanrei-comp-field-group-standard-disabled-error-required-asterisk-color | — | |
--tanrei-comp-field-group-standard-disabled-error-supporting-text-color | — | |
--tanrei-comp-field-group-standard-disabled-label-color | — | |
--tanrei-comp-field-group-standard-disabled-required-asterisk-color | — | |
--tanrei-comp-field-group-standard-disabled-supporting-text-color | — | |
--tanrei-comp-field-group-standard-error-text-color | sys.color.error | |
--tanrei-comp-field-group-standard-error-label-color | sys.color.on-surface | |
--tanrei-comp-field-group-standard-error-required-asterisk-color | sys.color.primary | |
--tanrei-comp-field-group-standard-error-supporting-text-color | sys.color.on-surface-variant | |
--tanrei-comp-field-group-standard-label-color | sys.color.on-surface | |
--tanrei-comp-field-group-standard-required-asterisk-color | sys.color.primary | |
--tanrei-comp-field-group-standard-supporting-text-color | sys.color.on-surface-variant | |
--tanrei-comp-field-group-supporting-text-gap | sys.space.space50 | 4px |
--tanrei-comp-field-group-label-typescale | sys.typescale.label | 500 14px/1.4286 |
--tanrei-comp-field-group-supporting-text-typescale | sys.typescale.label-small | 500 12px/1.3333 |
نماذج الاختبار
عروض مرجعية. تلتقط كل المنصات لقطة لكل نموذج بالمعرّف نفسه حتى يمكن مقارنة النتائج.
spacing: controls (43)
checkboxes
label: Notify me by items: 3 checkboxes-supporting
label: Notify me by supportingText: Choose all that apply. items: 3 checkboxes-required
label: Notify me by supportingText: Choose all that apply. required: true requiredText: Required items: 3 checkboxes-optional
label: Notify me by optional: true optionalText: Optional items: 3 checkboxes-required-asterisk
label: Notify me by required: true requiredMark: asterisk requiredText: Required items: 3 checkboxes-error
label: Notify me by supportingText: Choose all that apply. errorText: Choose at least one way to reach you. error: true required: true requiredText: Required items: 3 checkboxes-horizontal
label: Notify me by orientation: horizontal items: 3 checkboxes-horizontal-many
label: Days supportingText: The days the report is sent. orientation: horizontal items: 10 checkboxes-disabled
label: Notify me by supportingText: Choose all that apply. disabled: true required: true requiredText: Required items: 3 checkboxes-one-disabled
label: Notify me by items: 3 checkboxes-label-hidden
label: Notify me by labelHidden: true supportingText: Choose all that apply. items: 3 switches
label: Privacy supportingText: These apply to this device only. items: 3 switches-optional
label: Privacy optional: true optionalText: Optional items: 2 long-label
label: Which of these ways may we use to reach… supportingText: Choose all that apply. We use the first… errorText: Choose at least one way to reach you, or… error: true required: true requiredText: Required items: 3 checkboxes-required-ja
label: 連絡方法 supportingText: 当てはまるものをすべて選んでください。 required: true requiredText: 必須 items: 3 checkboxes-rtl
label: طرق الإشعار supportingText: اختر كل ما ينطبق. required: true requiredText: مطلوب direction: rtl items: 3 checkboxes-horizontal-rtl
label: ימים errorText: יש לבחור יום אחד לפחות. error: true orientation: horizontal direction: rtl items: 3 ltr-label-rtl
label: Wi-Fi 6E supportingText: 2.4 GHz, 5 GHz, 6 GHz direction: rtl items: 3 checkboxes-error-selected
label: Notify me by supportingText: Choose all that apply. errorText: This number cannot receive text messages… error: true required: true requiredText: Required items: 3 checkboxes-parent-none
label: Notify me by items: 4 checkboxes-parent-some
label: Notify me by items: 4 checkboxes-parent-all
label: Notify me by items: 4 checkboxes-parent-one-disabled
label: Notify me by items: 4 radio-buttons-default
label: Delivery kind: radio-group items: 3 radio-buttons-none-selected
label: Delivery kind: radio-group items: 3 radio-buttons-supporting
label: Delivery supportingText: You can change this until the order ship… kind: radio-group items: 3 radio-buttons-label-hidden
label: Delivery labelHidden: true supportingText: You can change this until the order ship… kind: radio-group items: 3 radio-buttons-required
label: Delivery supportingText: You can change this until the order ship… required: true requiredText: Required kind: radio-group items: 3 radio-buttons-optional
label: Delivery optional: true optionalText: Optional kind: radio-group items: 3 radio-buttons-required-asterisk
label: Delivery required: true requiredMark: asterisk kind: radio-group items: 3 radio-buttons-required-error
label: Delivery errorText: Choose how the order reaches you. error: true required: true requiredText: Required kind: radio-group items: 3 radio-buttons-error-selected
label: Delivery supportingText: You can change this until the order ship… errorText: Express delivery does not reach this add… error: true required: true requiredText: Required kind: radio-group items: 3 radio-buttons-error-one-disabled
label: Delivery supportingText: You can change this until the order ship… errorText: Express delivery does not reach this add… error: true required: true requiredText: Required kind: radio-group items: 3 radio-buttons-horizontal
label: Size orientation: horizontal kind: radio-group items: 3 radio-buttons-horizontal-many
label: Send the report supportingText: One report, on the day you choose. orientation: horizontal kind: radio-group items: 9 radio-buttons-disabled
label: Delivery supportingText: You can change this until the order ship… disabled: true required: true requiredText: Required kind: radio-group items: 3 radio-buttons-one-disabled
label: Delivery kind: radio-group items: 3 radio-buttons-long-label
label: How should we deliver the parts of this… supportingText: You can change this until the first parc… errorText: Choose how the order reaches you, or go… error: true required: true requiredText: Required kind: radio-group items: 3 radio-buttons-required-ja
label: 配送方法 supportingText: 発送されるまで変更できます。 required: true requiredText: 必須 kind: radio-group items: 3 radio-buttons-error-ja
label: 配送方法 errorText: 配送方法を選んでください。 error: true required: true requiredText: 必須 kind: radio-group items: 3 radio-buttons-rtl
label: طريقة التوصيل supportingText: يمكنك تغيير هذا حتى يُشحن الطلب. required: true requiredText: مطلوب kind: radio-group direction: rtl items: 3 radio-buttons-horizontal-rtl
label: גודל errorText: יש לבחור גודל. error: true required: true requiredText: חובה orientation: horizontal kind: radio-group direction: rtl items: 3 radio-buttons-ltr-label-rtl
label: Wi-Fi 6E supportingText: 2.4 GHz, 5 GHz, 6 GHz kind: radio-group direction: rtl items: 3 spacing: fields (4)
fields
label: Shipping address spacing: fields items: 3 fields-horizontal
label: City and postal code orientation: horizontal spacing: fields items: 2 fields-supporting
label: Billing address supportingText: Where the invoice is sent. optional: true optionalText: Optional spacing: fields items: 2 fields-optional-ja
label: お届け先 optional: true optionalText: 任意 spacing: fields items: 2 مولَّد من specs/field-group.spec.json, tokens/comp/field-group.tokens.json, design/tokens/
| المجموعة | استخدم |
|---|---|
| خانات اختيار تجيب عن سؤال واحد، أو مفاتيح تبديل هي مجموعة واحدة من الإعدادات | مجموعة حقول. |
| حقول ينتمي بعضها إلى بعض: عنوان، أو تاريخ في أجزاء | مجموعة حقول مع spacing="fields". |
| أزرار اختيار | مجموعة أزرار اختيار، وهي مجموعة حقول حولها تحمل كذلك قيمتها الواحدة. ومكتوبةً باليد: مجموعة حقول مع kind="radio-group" (أدناه). |
| عنصر تحكم واحد | حقلًا. |
ليست للمجموعة حالة المطلوب ولا حالة عدم الصلاحية، ولذلك تقول مجموعة الحقول المطلوب بالكلمات وتعلّم خانات الاختيار فيها غير صالحة واحدة واحدة. ومجموعة أزرار الاختيار تختلف: فهي مطلوبة وغير صالحة بكاملها. القيمة kind="radio-group" تخبر مجموعة الحقول بأن ما فيها هو أزرار الاختيار لمجموعة واحدة، فتصير عندئذ مجموعة أزرار الاختيار لها عند التقنيات المساعدة: مطلوبة ما دامت required معيَّنة، وغير صالحة ما دامت error بالقيمة true، وتقول اتجاهها. ولا يبقى requiredText جزءًا من وصفها، لأن الحالة تقوله.
<tanrei-field-group kind="radio-group" label="التوصيل" required required-text="مطلوب">
<tanrei-radio-button name="delivery" value="standard" label="عادي، من 3 إلى 5 أيام" checked></tanrei-radio-button>
<tanrei-radio-button name="delivery" value="express" label="سريع، في اليوم التالي"></tanrei-radio-button>
</tanrei-field-group>مجموعة حقول نوعها radio-group، حول أزرار اختيار لها اسم واحد
الخاصية kind تغيّر ما يُعرض للتقنيات المساعدة ولا تغيّر شيئًا مما يُرسم، وتبقى مجموعة الحقول بلا قيمة، لا تنقل تركيزًا ولا تعالج مفتاحًا: فأزرار الاختيار تحتفظ بتحديدها ومفاتيح الأسهم وموضع توقفها الواحد بحسب name. وهذه هي مجموعة أزرار الاختيار في المستوى الأدنى. استخدم مجموعة أزرار الاختيار إلا إذا احتجت إلى ترتيب للمجموعة لا تقدّمه: فهي تضيف القيمة الواحدة، وحدث change واحدًا، ومكانًا في النموذج بصفتها عنصر تحكم واحدًا.
في هذا النوع تحمل المجموعة أزرار الاختيار لمجموعة واحدة ولا شيء غيرها مما يمكن تشغيله، وتبقى spacing بالقيمة controls. وبنية التنقيح (debug) تبلّغ عن عنصر تحكم آخر، وعن أزرار اختيار باسمين، وعن تباعد آخر.
المجموعة طويلة وتُقرأ من أعلاها، ولذلك يقف شيئان في غير موضعهما من الحقل:
- الوصف تحت التسمية، قبل عناصر التحكم، ويبقى ما دامت المجموعة في حالة خطأ. فالعبارة «اختر كل ما ينطبق» يجب أن تُقرأ قبل الخيارات، وهي ما يحتاج إليه الشخص من جديد حين تُرفض الإجابة.
- نص الخطأ صف قائم بذاته، تحت آخر عنصر تحكم.
أما التسمية ووسم المطلوب أو الاختياري والنجمة فهي ما للحقل. وكذلك الخاصيتان required و optional اللتان تقولان ما يطلبه النموذج من المجموعة: فإن عُيِّنتا كلتاهما كانت المجموعة مطلوبة.
- القيمة
orientation="vertical"(الافتراضية) ترصّ عناصر التحكم في عمود واحد. فضِّلها: كل تسمية تبدأ من حافة واحدة وتُقرأ نزولًا. - القيمة
orientation="horizontal"ترتّبها في صف يلتفّ. خُصَّها بخيارين قصيرين أو ثلاثة، أو بحقول تُقرأ سطرًا واحدًا، كمدينة ورمزها البريدي. فالصف الملتفّ يُخفي أيّ تسمية تتبع أيّ علامة. - الحقول في صف تتقاسمه بالتساوي، ولا يقل عرض أيٍّ منها عن
comp.field-group.field.min-width(144 في النظام الافتراضي): ففي نافذة ضيقة ينتقل الحقل التالي إلى سطر خاص به بدلًا من أن يُضغط حتى يُقتطع ما يُكتب فيه. عيِّن هذا الرمز حيث تحتاج حقولك إلى أكثر. - الخاصية
spacingتقول ما الذي تحمله المجموعة. القيمةcontrolsتجعل بين خانات الاختيار ومفاتيح التبديل بُعد هدف لمس واحد؛ والقيمةfieldsتجعل بين الحقول المسافة التي يتركها النموذج بين حقلين، وتدع كلًّا منها يملأ العرض. ويستطيع نظام تصميم أن يضيف قيمًا.
علامة خانة الاختيار أو مفتاح التبديل تقف داخل حاويتها، فتبدأ أبعد قليلًا إلى الداخل من تسمية المجموعة. والمجموعة لا تسحبها إلى الخارج: فالحاوية هي حيث يرسم عنصر التحكم تحويمه وحلقة تركيزه.
الخاصية error تضع المجموعة في حالة الخطأ: يُرسم نص الخطأ، وتُرسم كل خانة اختيار في هيئة الخطأ الخاصة بها وتُعرض على أنها غير صالحة، ويُرسم كل زر اختيار في هيئة الخطأ الخاصة به. وزر الاختيار لا يُعرض على أنه غير صالح: فدوره ليست له هذه الحالة، ومجموعة أزرار الاختيار هي التي تقولها. ومفتاح التبديل ليست له هيئة خطأ ويبقى كما هو مرسوم. والحقل الذي في المجموعة يحتفظ بالخطأ الذي أعطيته إياه: كل حقل يقول خطأه بالكلمات، وخطأ المجموعة هو للمجموعة كلها («اختر واحدًا على الأقل»).
وقد يكون عنصر تحكم واحد من مجموعة صالحة في حالة خطأ بمفرده.
- سمِّ المجموعة بالسؤال الذي تجيب عنه عناصر التحكم فيها: «أرسلوا لي الإشعارات عبر».
- أعطِ كل عنصر تحكم تسميته الخاصة. تسمية المجموعة لا تحلّ محلها.
- استخدم مجموعة من الحقول للتفريق بين مجموعتين لهما التسميات نفسها: «عنوان الشحن» و«عنوان الفوترة».
- لا تضع أزرار اختيار في مجموعة حقول من دون أن تقول ذلك: استخدم مجموعة أزرار اختيار، أو عيِّن
kind="radio-group". ففي المجموعة العادية ليست لها حالة المطلوب ولا حالة عدم الصلاحية، وبنية التنقيح تبلّغ عن ذلك. - لا تستخدم مجموعة الحقول للتخطيط وحده. من دون اسم مشترك رتِّب الحقول بنفسك، برمز التباعد نفسه (
comp.field-group.gap.fields). - لا تجعل المجموعات متداخلة أكثر من مستوى واحد. المجموعة التي داخل مجموعة عضو واحد فيها، وتُقرأ مجموعةً داخل مجموعة.
- الدور
group- التسمية
- label names the group, drawn or not (labelHidden). Each control keeps its own name, its own label beside it. The group's description is supportingText, then errorText while error is true, then requiredText while the group is required, then optionalText while it is optional. A checkbox the group put in its error condition is exposed as invalid by itself and is described by errorText; a radio button is drawn in its error form and says neither, because the radio group it is in says both. The requirement tag and the asterisk are hidden. While kind is radio-group the group is a radio group: it carries the required and the invalid state itself, so requiredText is not said in its description (FGR-25).
- الحد الأدنى للهدف
- تستوفي مساحة اللمس الحد الأدنى لحجم الهدف حتى لو كان الحجم المرئي أصغر. minimum 32px · pointer 44px · spacing 8px · touch 48px
لوحة المفاتيح
| المفاتيح | الإجراء |
|---|---|
| Tab / Shift+Tab | Moves focus to each enabled control of the set in the order given, and once into a radio group it holds and out of it (RGP-6). The group itself is not a stop. |
| Space, the arrow keys and every other key | The focused control's own, as its spec says: the group handles none (FGR-12, FGR-15). |
ملاحظات
- Not interactive by itself: the group takes no focus, no key and no press (FGR-12), so it has no target of its own and minimumTarget holds through its controls. The distance between two selection controls (FGR-3) leaves each a whole touch target.
- The frame is the field's, for a set: the label (FGR-2), the requirement (FGR-4 to FGR-6) and the error (FGR-8, FGR-9) carry the numbers and the token names of FLD-2, FLD-4 to FLD-6, FLD-8 and FLD-9, with the same values. Two things differ, and both because a set is tall and is read from the top: the description stands under the label, before the controls, and stays while the group is in error; and the error text is a row of its own below the controls.
- On the web the group is a `fieldset` with a `legend`. A group role has no required and no invalid state, which is why the group says requiredText in its description and marks its checkboxes invalid one by one. A set of radio buttons has both states: kind radio-group makes the same element their radio group (FGR-25). It also has a value, which a field group never holds: the Radio group does.
- A set of radio buttons is the Radio group component: this field group in its radio-group kind, around the radio buttons, with what a frame cannot have added — the chosen value, one change event, the arrow keys and the single tab stop kept for the set, and a place in a form as one control (RGP-3 to RGP-9). The same set written by hand, one level down, is a field group whose kind is radio-group around radio buttons of one name: the same picture and the same radio group, without the value (FGR-25). A radio group may stand in a field group among fields, as one member (FGR-15). A set of checkboxes that is one answer under one name is a checkbox group, which holds the list of what is checked (CKG-1); checkboxes that each have a name of their own, and switches, need none of that and are a field group.
- Prefer a column. A row of options is read across and then down once it wraps, and a wrapped row hides which label belongs to which mark; keep horizontal for two or three short options and for fields that are read as one line (a city and its postal code).
- Errors are words (WCAG 3.3.1, 1.4.1): errorText says what is wrong with the set and how to put it right. It is announced when it appears under the person's focus and is otherwise read with the group and with each control marked invalid (FGR-9, FGR-11); it never takes focus away. A summary of every refused answer above the form is a live Callout in its error status, built by the product.
- A group of fields (spacing fields) gives the fields a shared name — "Shipping address" before "Street" — which matters where two sets repeat the same labels. It passes them no error: each field says its own.
- Heights are the texts' and the controls': at 200% text size every text wraps, a row becomes a column, and nothing is cut (WCAG 1.4.4, 1.4.10).
- How a state looks is a value decision of the active design system; components read the state's tokens and never compute the effect themselves.
مولَّد من specs/field-group.spec.json, tokens/sys/measure.tokens.json
- على الويب المجموعة عنصر
fieldsetمع عنصرlegend: مجموعة تحتوي عناصر التحكم التي لها وتسمّيها الخاصيةlabel، سواء رُسمت أم أُخفيت بالخاصيةlabelHidden. - وصف المجموعة هو
supportingText، ثمerrorTextما دامتerrorبالقيمة true، ثمrequiredTextأوoptionalText. وليست للمجموعة حالة المطلوب ولا حالة عدم الصلاحية، ولهذا يُقال المطلوب بالكلمات. - كل خانة اختيار وضعتها المجموعة في حالة خطأ تُعرض على أنها غير صالحة بمفردها، ونص الخطأ وصفها.
- مع
kind="radio-group"يكون العنصر نفسه مجموعة أزرار اختيار: يحمل حالة المطلوب وحالة عدم الصلاحية واتجاهه بنفسه، ويُتركrequiredTextخارج وصفه. وعلى الويب هو عنصرfieldsetنفسه، بدور مجموعة أزرار الاختيار. - الخاصية
disabledتعطّل كل عنصر تحكم وتعرض المجموعة على أنها معطَّلة. والمجموعة غير المعطَّلة لا تفعّل أبدًا عنصر تحكم عطّلته أنت. - الخطأ الذي يظهر، أو تتغيّر كلماته، والتركيز داخل المجموعة يُعلَن مرة واحدة، بتهذيب. ولا ينتقل التركيز أبدًا بسبب خطأ.
- المجموعة ليست موضع توقف في ترتيب التركيز، ولا تأخذ مفتاحًا ولا تستجيب لضغط: المفتاح Tab يبلغ كل عنصر تحكم غير معطَّل بالترتيب المعطى.
- وسم المطلوب أو الاختياري والنجمة مخفيّان عن التقنيات المساعدة.
- عند تكبير النص إلى 200% يلتفّ كل نص، ويصير الصف عمودًا، ولا يُقصّ شيء.
- في الألوان المفروضة (forced colors) يأخذ كل نص لون نص النظام ويكتسب وسم المطلوب أو الاختياري حدًّا.
- في تخطيط من اليمين إلى اليسار تبدأ الصفوف من اليمين، ويجري صف عناصر التحكم من اليمين، ويحتفظ كل نص باتجاهه.
- أزرار الاختيار في مجموعة حقول قيمة
kindفيهاgroup، والمجموعة التي بلا عنصر تحكم، والمجموعة التي بلا تسمية يُبلَّغ عنها في بنيات التنقيح (debug).
فجوات معروفة على الويب:
- يُعطى وصف خانة الاختيار بالخاصية
aria-description، وهي لم تُختبر مع كل قارئ شاشة. - قبل أن يُعرَّف العنصر، تكون عناصر التحكم في الصفحة بلا تسمية المجموعة ولا وصفها ولا تخطيطها.
- أعطِ المجموعة
label. - تحقق من الإجابة بنفسك، وعيِّن
error، واكتبerrorTextبحيث يقول كيف تُصحَّح الإجابة. - أعطِ كلمات المطلوب والاختياري:
required-textوoptional-textعلى المجموعة، أو مرة واحدة للمنتج كله بالاستدعاءsetWords({ requiredText, optionalText }). فهي تُقرأ جزءًا من وصف المجموعة، وليست للمجموعة حالة المطلوب: من دونrequiredTextلا شيء يخبر التقنيات المساعدة بأن الإجابة مطلوبة. لا يتضمن Tanrei أي كلمة، والكلمة الناقصة يُبلَّغ عنها أثناء التطوير. انظر كلمات المنتج. - بعد إرسال أخفق، قل كذلك فوق النموذج ما الذي رُفض واربط بكل عنصر تحكم: تنويه حيّ في حالة الخطأ.